/*
Theme Name: PetFly (Astra Child)
Theme URI: https://petfly.pl
Description: Child theme Astra dla sklepu PetFly — design system, wzorce bloków i style WooCommerce.
Author: PetFly
Template: astra
Version: 0.2.250
Text Domain: petfly
*/

/* ==========================================================================
   1. Design tokens
   ========================================================================== */
:root {
  /* Creams re-tuned to the v2 mockup 2026-08-28: less yellow, softer panel
     contrast. --pf-bg stays within 3/255 of the band-art gain target
     (250,244,233), so the baked art still dissolves into it (gotcha 96). */
  --pf-bg: #FAF4EC;
  --pf-bg-alt: #F5EDDF;
  --pf-paper: #FFFDF8;
  --pf-ink: #3A2B1D;
  --pf-ink-2: #71604C;
  --pf-line: #E9DECC;
  --pf-terra: #BC5A20;
  --pf-terra-dark: #9A4514;
  --pf-terra-soft: #F6E2CF;
  --pf-gold: #D9A05B;
  --pf-navy: #2E4A66;
  --pf-navy-dark: #233A52;
  --pf-olive: #5F6F3A;
  --pf-olive-dark: #4B5A2C;
  --pf-r: 18px;
  --pf-shadow: 0 10px 30px -12px rgba(88, 60, 32, .18);
  /* Shared icon masks. The bowl-with-heart (v2 icon sheet) rides RIGHT of the
     label on every forward-motion and add-to-cart button (Tomek, 2026-08-30 —
     replaces the tilted paw of 0.2.162). .pf-btn-bowl keeps its name: it is
     baked into page content. */
  --pf-mask-hcheck: url('assets/img/icons/check.webp');
  --pf-mask-hbowl: url('assets/img/icons/bowl-heart.webp');
  --pf-mask-check: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222.4%22%3E%3Cpath%20d=%22m4%2012%205%205L20%206%22/%3E%3C/svg%3E');
  --pf-mask-chev: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222.4%22%3E%3Cpath%20d=%22m6%209.5%206%206%206-6%22/%3E%3C/svg%3E');
  /* Woo's notice icons come from an icon FONT that cannot be recoloured, so
     the glyph is suppressed and ours are masked in (§3g.4). [css-001] */
  --pf-mask-info: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%229%22/%3E%3Cpath%20d=%22M12%2011v5.5%22/%3E%3Cpath%20d=%22M12%207.6v.1%22/%3E%3C/svg%3E');
  --pf-mask-alert: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%3E%3Cpath%20d=%22M12%204.2%2021%2019.5H3Z%22/%3E%3Cpath%20d=%22M12%2010.4v4.2%22/%3E%3Cpath%20d=%22M12%2017.2v.1%22/%3E%3C/svg%3E');
  /* Woo's show/hide-password toggle, same problem as the notices: it is drawn
     from the WooCommerce icon font, which is not loaded here, so it rendered as
     a tofu square inside the password field on every login form. */
  --pf-mask-eye: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%221.9%22%20stroke-linecap=%22round%22%3E%3Cpath%20d=%22M2.5%2012S6%205.5%2012%205.5%2021.5%2012%2021.5%2012%2018%2018.5%2012%2018.5%202.5%2012%202.5%2012Z%22/%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%223%22/%3E%3C/svg%3E');
  --pf-mask-eye-off: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%221.9%22%20stroke-linecap=%22round%22%3E%3Cpath%20d=%22M4%208.2C2.9%209.7%202.5%2012%202.5%2012s3.5%206.5%209.5%206.5c1.6%200%203-.4%204.2-1%22/%3E%3Cpath%20d=%22M8.6%205.9A9.6%209.6%200%200%201%2012%205.5c6%200%209.5%206.5%209.5%206.5s-1%201.9-2.8%203.6%22/%3E%3Cpath%20d=%22M3.5%203.5l17%2017%22/%3E%3C/svg%3E');
  /* The delivery-point pin, §3l. Furgonetka ships no icon of its own — the
     chosen Paczkomat arrived as a bare text node on a #eee block — so the pin
     that marks it, and the one on the picker link, come from here. */
  --pf-mask-pin: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M12%2021.5s7-6.6%207-11.5a7%207%200%201%200-14%200c0%204.9%207%2011.5%207%2011.5Z%22/%3E%3Ccircle%20cx=%2212%22%20cy=%229.8%22%20r=%222.6%22/%3E%3C/svg%3E');
  --pf-mask-pencil: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M16.5%203.5a2.1%202.1%200%200%201%203%203L7%2019l-4%201%201-4Z%22/%3E%3Cpath%20d=%22M14%206l4%204%22/%3E%3C/svg%3E');
  --pf-font-serif: 'Lora', Georgia, serif;
}

body, button, input, select, textarea {
  font-family: 'Inter', system-ui, sans-serif;
}
/* .entry-content variants needed: Astra's dynamic CSS targets
   `.entry-content hN` (0-1-1), which out-ranks bare element selectors. */
h1, h2, h3, h4, h5, h6,
.entry-content h1, .entry-content h2, .entry-content h3,
.entry-content h4, .entry-content h5, .entry-content h6,
.site-title {
  font-family: var(--pf-font-serif);
}
body {
  background: var(--pf-bg);
  color: var(--pf-ink);
}
.wp-block-button .wp-block-button__link { text-transform: none; } /* beats Astra's `capitalize` */

/* Header logo size (Astra's inline width limit uses #masthead specificity) */
#masthead .site-logo-img .custom-logo-link img { max-width: none; width: auto; height: 72px; }

/* Astra ships `#primary { margin: 4em 0 }` (~55px). Our patterns each carry their
   own section padding, so that margin only adds dead space — most visibly a blank
   band between the last section and the footer. `body #primary` outranks Astra's
   bare id selector without needing !important. */
body #primary { margin-top: 0; margin-bottom: 0; }

/* ==========================================================================
   2. Generic components
   ========================================================================== */

/* --- sections --- */
.pf-section { padding-block: 72px; }
.pf-section-tight { padding-block: 64px 0; }
/* Astra's `.entry-content > .wp-block-group` padding (0-1-1) beats every
   bare `.pf-*`; its inline half squeezed the text column to ~226px at 400px.
   gotcha 10 [css-002] */
.entry-content > [class*="pf-"] { padding-inline: 0; }
/* ...and then the components that legitimately own an inline gutter restore it. Same
   0-2-0 specificity as the reset above, so these must stay AFTER it in the file. */
.pf-alt {
  background: var(--pf-bg-alt); border: 1px solid var(--pf-line);
  width: min(1180px, calc(100% - 32px)); margin-inline: auto;
  border-radius: 24px; padding-inline: 40px;
}
/* That reset also out-ranks `.pf-alt`, so a group that is both lost the
   card's own inner padding. Restored here. [css-003] */
.entry-content > .pf-alt { padding-inline: 40px; }
.pf-rel { position: relative; overflow: hidden; }

.pf-sec-head { text-align: center; max-width: 640px; margin-inline: auto; margin-bottom: 44px; }
.pf-sec-head h2 { font-size: clamp(25px, 2.7vw, 31px); margin-bottom: 12px; }
.pf-sec-head p { color: var(--pf-ink-2); }

/* Leafed branch flanking centred headings (mockup v2, sheet's "gałąź").
   Homepage only until the other pages take the rustic pass. */
.home .pf-sec-head h2::before,
.home .pf-sec-head h2::after {
  content: ""; display: inline-block; width: 38px; height: 22px;
  background: var(--pf-olive); opacity: .55; vertical-align: -2px; margin-right: 13px;
  -webkit-mask: url('assets/img/icons/branch.webp') center / contain no-repeat;
          mask: url('assets/img/icons/branch.webp') center / contain no-repeat;
}
.home .pf-sec-head h2::before { transform: scaleX(-1); }
.home .pf-sec-head h2::after { margin: 0 0 0 13px; }
@media (max-width: 700px) {
  .home .pf-sec-head h2::before,
  .home .pf-sec-head h2::after { display: none; }
}

.pf-kicker {
  display: inline-block; font-size: 12.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--pf-terra-dark); margin-bottom: 14px;
}

/* --- sprig divider (wp:html snippet) ---
   Olive branch glyph (Tomek's pick C); the lines are subtle and take the
   page's leading colour — terra everywhere, the shelf accent on product
   pages (--pf-div-line, set on Woo's accent wrapper below). */
.pf-divider { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 0 0 16px; color: var(--pf-olive); }
.pf-divider .dline { height: 1px; width: 56px; opacity: .45; background: linear-gradient(to right, transparent, var(--pf-div-line, var(--pf-terra))); }
.pf-divider .dline:last-child { background: linear-gradient(to left, transparent, var(--pf-div-line, var(--pf-terra))); }
body.woocommerce div.product.pf-acc-navy { --pf-div-line: var(--pf-navy); }
body.woocommerce div.product.pf-acc-olive { --pf-div-line: var(--pf-olive-dark); }

/* --- background art ---
   The sibling rule must exclude `.pf-bgart` or the artwork drops into flow.
   These are background-images on empty divs, so `display:none` costs no
   request. [css-004] */
.pf-bgart {
  position: absolute; opacity: .14; pointer-events: none; z-index: 0;
  background: var(--pf-bgart) center / contain no-repeat;
}
.pf-rel > :not(.pf-bgart) { position: relative; z-index: 1; }

.pf-bgart--flower   { --pf-bgart: url('assets/img/bot-flower.webp'); }
.pf-bgart--rosemary { --pf-bgart: url('assets/img/bot-rosemary.webp'); }
/* Square 460px sources (the 0.2.111 icon-sheet slices) — give them square
   boxes or `contain` letterboxes them small inside the 2:3 placements. */
.pf-bgart--leaf     { --pf-bgart: url('assets/img/bot-leaf.webp'); }
.pf-bgart--branch   { --pf-bgart: url('assets/img/bot-branch.webp'); }
/* A placement rule may re-set --pf-bgart: the shared pattern keeps its species
   class while one page varies the plant. The home right rail was rosemary
   three times over (Tomek, 2026-08-28) — now branch/leaf, and the plasma
   sprig is gone: the bowl art carries its own botanicals. [css-191] */

.pf-bgart--home-hero    { left: -60px; bottom: -40px; width: 230px; height: 345px; transform: rotate(14deg); }
.pf-bgart--home-plasma  { display: none; }
/* Behind the hero copy (like odkrywaj's odk-hero-l) — lower opacity so the text
   stays readable over it. */
.pf-bgart--obw-hero-copy { left: -45px; top: 0; width: 215px; height: 322px; transform: rotate(10deg); opacity: .1; }
.pf-bgart--obw-story-r  { right: -70px; bottom: -20px; width: 190px; height: 285px; transform: rotate(-150deg); }
.pf-bgart--obw-dogs-l   { left: -70px;  bottom: -30px; width: 210px; height: 315px; transform: rotate(16deg); }
.pf-bgart--obw-team-r   { right: -55px; top: 30px;     width: 200px; height: 300px; transform: rotate(-150deg); }
/* top never negative here: the opaque header paints over the band, so a bleed
   above the band's top edge is decapitated flat (and the 12° rotation lifts the
   art ~19px above its own box — 30px keeps the rotated top inside the band). */
.pf-bgart--odk-hero-l   { left: -60px; top: 30px;     width: 220px; height: 330px; transform: rotate(12deg); }
/* Lives in the freed right cream once the hero art's bleed is capped — so
   wide screens only (the cap and the viewport meet at 1520, see the plasma
   band below). Below that the art owns the band's right half. */
.pf-bgart--odk-hero-r   { display: none; }
.pf-bgart--odk-why-r    { right: -55px; bottom: -30px; width: 235px; height: 235px; transform: rotate(-12deg); }
.pf-bgart--odk-process  { left: -60px; bottom: -50px; width: 210px; height: 315px; transform: rotate(18deg); }
.pf-bgart--odk-science  { right: -40px; bottom: -40px; width: 235px; height: 235px; transform: rotate(20deg); }
.pf-bgart--zlap-hero-l    { left: -75px;  top: 10px;     width: 200px; height: 300px; transform: rotate(10deg); }
.pf-bgart--zlap-hero-r    { right: -45px; bottom: -40px; width: 195px; height: 293px; transform: rotate(-152deg); }
.pf-bgart--zlap-contact-l { left: -60px;  bottom: -30px; width: 200px; height: 200px; transform: rotate(16deg); }
.pf-bgart--zlap-faq-r     { right: -55px; top: 10px;     width: 190px; height: 285px; transform: rotate(-150deg); }
/* Inset from the measure, never negative: `.pf-catnav` does not clip, so an
   offset would push the page sideways. The art bleeds down under the opaque
   cards. [css-005] */
.pf-bgart--catnav-l     { left: 10px;  top: -30px;    width: 200px; height: 300px; transform: rotate(16deg); }
.pf-bgart--catnav-r     { right: 5px;  bottom: -40px; width: 190px; height: 285px; transform: rotate(-158deg); }
.pf-bgart--home-products {
  --pf-bgart: url('assets/img/bot-branch.webp');
  right: -45px; bottom: -20px; width: 240px; height: 240px; transform: rotate(-8deg);
}
.home .pf-bgart--manu-r {
  --pf-bgart: url('assets/img/bot-leaf.webp');
  width: 200px; height: 200px; transform: rotate(-10deg);
}
/* Inside the tinted .pf-manu panel, so its overflow clips the bleed at the
   rounded edge instead of the viewport. */
.pf-bgart--manu-l       { left: -55px;  bottom: -50px; width: 200px; height: 300px; transform: rotate(18deg); }
.pf-bgart--manu-r       { right: -50px; top: -30px;    width: 190px; height: 285px; transform: rotate(-158deg); }
/* No left-hand botanical on this hero: the text is left-aligned and full-measure there,
   so art on the left would sit behind it. Only the right side keeps free cream. */

@media (max-width: 960px) { .pf-bgart { display: none; } }

/* Wide screens: the homepage botanicals move out of the copy's shadow into the
   free side cream. Un-clipping is safe here only because a LEFT bleed never
   scrolls and every right bleed below stays under the 200px of cream a 1600px
   viewport guarantees — rotation widens the box ~45px (gotcha 17). [css-190] */
@media (min-width: 1600px) {
  .home .pf-rel { overflow: visible; }
  .pf-bgart--home-hero     { left: -180px; }
  .pf-bgart--home-products { right: -150px; }
  /* .home-scoped: on /obwachaj-nas/ these two stay clipped, so a bigger
     offset there only buries them deeper in the clip. */
  .home .pf-bgart--manu-l  { left: -170px; }
  .home .pf-bgart--manu-r  { right: -140px; }
  /* Odkrywaj (item 21, Tomek 2026-08-29): same move-out. Left bleeds never
     scroll; the right ones stay inside this block's guaranteed side cream. */
  .page-id-2126 .pf-rel     { overflow: visible; }
  .pf-bgart--odk-hero-l     { left: -170px; }
  .pf-bgart--odk-why-r      { right: -150px; }
  .pf-bgart--odk-process    { left: -160px; }
  .pf-bgart--odk-science    { right: -140px; }
  .pf-bgart--odk-hero-r     {
    display: block; right: calc(50% - 50vw + 36px); bottom: 36px;
    width: 200px; height: 300px; transform: rotate(-150deg);
  }
  /* Obwąchaj-nas (item 21): same move-out. Left bleeds never scroll; the
     right ones stay inside the guaranteed side cream. */
  .page-id-2127 .pf-rel     { overflow: visible; }
  .pf-bgart--obw-hero-copy  { left: -150px; }
  .pf-bgart--obw-story-r    { right: -150px; }
  .pf-bgart--obw-dogs-l     { left: -165px; }
  .pf-bgart--obw-team-r     { right: -145px; }
  /* Złap-nas (item 21): same move-out. */
  .page-id-2128 .pf-rel     { overflow: visible; }
  .pf-bgart--zlap-hero-l    { left: -170px; }
  .pf-bgart--zlap-hero-r    { right: -145px; }
  .pf-bgart--zlap-contact-l { left: -165px; }
  .pf-bgart--zlap-faq-r     { right: -145px; }
}

/* --- circled icons --- */
.pf-cicon {
  width: 64px; height: 64px; border: 1.5px solid var(--pf-gold); border-radius: 50%;
  display: grid; place-items: center; color: var(--pf-terra);
  background: rgba(255, 253, 248, .6); flex: none; margin-inline: auto;
}

/* --- hand-drawn icons (petfly_hicon) ---
   Alpha baked into the webp, NOT mix-blend-mode: the pf-rel/artband z-index
   ancestors are stacking contexts, and inside one a blend sees only a
   transparent backdrop, so multiply silently no-ops. */
.pf-hicon { flex: none; }

/* --- icons: CSS masks ---
   Icons are CSS masks, not inline `<svg>`: `wp_kses_post()` strips svg on
   any save by a user without `unfiltered_html`. gotcha 15 [css-006] */
.pf-i {
  display: inline-block; flex: none;
  width: var(--pf-i-size, 24px); height: var(--pf-i-size, 24px);
  background-color: currentColor;
  -webkit-mask: var(--pf-i) center / contain no-repeat;
          mask: var(--pf-i) center / contain no-repeat;
}
.pf-i--s14 { --pf-i-size: 14px; }
.pf-i--s16 { --pf-i-size: 16px; }
.pf-i--s18 { --pf-i-size: 18px; }
.pf-i--s20 { --pf-i-size: 20px; }
.pf-i--s22 { --pf-i-size: 22px; }
.pf-i--s24 { --pf-i-size: 24px; }
.pf-i--s26 { --pf-i-size: 26px; }
.pf-i--s28 { --pf-i-size: 28px; }
.pf-i--s30 { --pf-i-size: 30px; }
.pf-i--s32 { --pf-i-size: 32px; }
.pf-i--s36 { --pf-i-size: 36px; }

.pf-i--paw { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22%23000%22%3E%3Cellipse%20cx=%2212%22%20cy=%2215.5%22%20rx=%224.4%22%20ry=%223.6%22/%3E%3Cellipse%20cx=%225.2%22%20cy=%2210.5%22%20rx=%222%22%20ry=%222.6%22/%3E%3Cellipse%20cx=%2218.8%22%20cy=%2210.5%22%20rx=%222%22%20ry=%222.6%22/%3E%3Cellipse%20cx=%229%22%20cy=%226.8%22%20rx=%222%22%20ry=%222.7%22/%3E%3Cellipse%20cx=%2215%22%20cy=%226.8%22%20rx=%222%22%20ry=%222.7%22/%3E%3C/svg%3E'); }
/* Hand-drawn webps as masks (the .pf-i--branch mechanism): currentColor
   tinting survives, only the glyph changes. Rustic swaps land here one by one
   as the sheet grows — the geometric data-URIs below are the interim set. */
.pf-i--leaf { --pf-i: url('assets/img/icons/leaf.webp'); }
.pf-i--bowl { --pf-i: url('assets/img/icons/bowl.webp'); }
.pf-i--shield { --pf-i: url('assets/img/icons/shield.webp'); }
.pf-i--poland { --pf-i: url('assets/img/icons/poland.webp'); }
.pf-i--molecule { --pf-i: url('assets/img/icons/molecule.webp'); }
.pf-i--heart { --pf-i: url('assets/img/icons/heart.webp'); }
.pf-i--smile { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%229%22/%3E%3Cpath%20d=%22M7.5%2013.5c1.3%202%203%203%204.5%203s3.2-1%204.5-3%22/%3E%3Ccircle%20cx=%229%22%20cy=%229.5%22%20r=%22.7%22%20fill=%22%23000%22/%3E%3Ccircle%20cx=%2215%22%20cy=%229.5%22%20r=%22.7%22%20fill=%22%23000%22/%3E%3C/svg%3E'); }
.pf-i--check { --pf-i: url('assets/img/icons/check.webp'); }
.pf-i--pin { --pf-i: url('assets/img/icons/pin.webp'); }
.pf-i--truck { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.8%22%3E%3Cpath%20d=%22M4%208h9v9H4zM13%2011h4l3%203v3h-7z%22/%3E%3Ccircle%20cx=%227.5%22%20cy=%2219%22%20r=%221.6%22/%3E%3Ccircle%20cx=%2216.5%22%20cy=%2219%22%20r=%221.6%22/%3E%3C/svg%3E'); }
.pf-i--drop { --pf-i: url('assets/img/icons/drop.webp'); }
.pf-i--heartf { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22%23000%22%3E%3Cpath%20d=%22M12%2021s-7-4.6-9.5-9A5.5%205.5%200%200%201%2012%206.5%205.5%205.5%200%200%201%2021.5%2012C19%2016.4%2012%2021%2012%2021Z%22/%3E%3C/svg%3E'); }
.pf-i--gut { --pf-i: url('assets/img/icons/gut.webp'); }
.pf-i--microbe { --pf-i: url('assets/img/icons/microbe.webp'); }
.pf-i--funnel { --pf-i: url('assets/img/icons/funnel.webp'); }
.pf-i--spray { --pf-i: url('assets/img/icons/spray.webp'); }
.pf-i--flask { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Cpath%20d=%22M9.5%203h5v4.2l4%208.3a3%203%200%200%201-2.7%204.5H8.2a3%203%200%200%201-2.7-4.5l4-8.3V3Z%22/%3E%3Cpath%20d=%22M7.2%2014h9.6%22/%3E%3Cpath%20d=%22M8.5%203h7%22/%3E%3C/svg%3E'); }
.pf-i--scales { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Cpath%20d=%22M12%204v16M8%2020h8M5%208h14%22/%3E%3Cpath%20d=%22M5%208%202.5%2013.5a2.6%202.6%200%200%200%205%200L5%208Z%22/%3E%3Cpath%20d=%22M19%208l-2.5%205.5a2.6%202.6%200%200%200%205%200L19%208Z%22/%3E%3Ccircle%20cx=%2212%22%20cy=%224%22%20r=%221.4%22/%3E%3C/svg%3E'); }
.pf-i--mountain { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Cpath%20d=%22M2%2019h20L14.5%206%2011%2012l-2-3-7%2010Z%22/%3E%3Cpath%20d=%22M12.2%209.6%2014.5%206%22/%3E%3Ccircle%20cx=%2218%22%20cy=%225.5%22%20r=%221.6%22/%3E%3C/svg%3E'); }
.pf-i--megaphone { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Cpath%20d=%22M4%2010.5%2017%205v13L4%2012.5v-2Z%22/%3E%3Cpath%20d=%22M7%2012v5.5a2%202%200%200%200%204%200V13.6%22/%3E%3Cpath%20d=%22M20%208.5c1.2%201%201.2%205.9%200%207%22/%3E%3C/svg%3E'); }
.pf-i--gauge { --pf-i: url('assets/img/icons/gauge.webp'); }
.pf-i--lens { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Ccircle%20cx=%2210.5%22%20cy=%2210.5%22%20r=%226.5%22/%3E%3Cpath%20d=%22m15.4%2015.4%204.6%204.6%22/%3E%3Cpath%20d=%22M8%2010.5a2.5%202.5%200%200%201%202.5-2.5%22/%3E%3C/svg%3E'); }
.pf-i--pot { --pf-i: url('assets/img/icons/pot.webp'); }
.pf-i--arrow { --pf-i: url('assets/img/icons/arrow.webp'); }
.pf-i--mail { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Crect%20x=%223%22%20y=%225.5%22%20width=%2218%22%20height=%2213%22%20rx=%222.5%22/%3E%3Cpath%20d=%22m4.2%207.4%207.8%205.9%207.8-5.9%22/%3E%3C/svg%3E'); }
.pf-i--clock { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%228.5%22/%3E%3Cpath%20d=%22M12%207.2V12l3.6%202.2%22/%3E%3C/svg%3E'); }
/* Added for the product page (mockups 05a-c). "antibody" is the Y that stands for
   immunoglobulins in all three mockups; "sparkle" is their smak/aromat mark. */
.pf-i--antibody { --pf-i: url('assets/img/icons/antibody.webp'); }
.pf-i--sparkle { --pf-i: url('assets/img/icons/sparkle.webp'); }
.pf-i--dog { --pf-i: url('assets/img/icons/dog.webp'); }
.pf-i--bag { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Cpath%20d=%22M7%208.2h10l1.5%209.8a2%202%200%200%201-2%202.3H7.5a2%202%200%200%201-2-2.3Z%22/%3E%3Cpath%20d=%22M9.3%208.2V6.5A2.7%202.7%200%200%201%2012%203.8a2.7%202.7%200%200%201%202.7%202.7v1.7%22/%3E%3C/svg%3E'); }
.pf-i--can { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.7%22%3E%3Cellipse%20cx=%2212%22%20cy=%226.8%22%20rx=%226.8%22%20ry=%222.6%22/%3E%3Cpath%20d=%22M5.2%206.8v10.4c0%201.4%203%202.6%206.8%202.6s6.8-1.2%206.8-2.6V6.8%22/%3E%3C/svg%3E'); }
/* Sheet handset as a mask, so it recolours to the contact list's terra. */
.pf-i--hphone { --pf-i: url('assets/img/icons/phone.webp'); }
.pf-i--branch { --pf-i: url('assets/img/icons/branch.webp'); }
/* Crossed-out flask ("bez sztucznych dodatków") — pairs with the crossed
   wheat, so both "Bez…" claims negate the same way (Tomek, 2026-08-28). */
.pf-i--noadd { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%222%22%3E%3Cpath%20d=%22M10%203.5h4v3.7l3.8%207.9a2.8%202.8%200%200%201-2.5%204.2H8.7a2.8%202.8%200%200%201-2.5-4.2L10%207.2V3.5Z%22/%3E%3Cpath%20d=%22M9%203.5h6%22/%3E%3Cpath%20d=%22m4%204%2016%2016%22/%3E%3C/svg%3E'); }
/* Crossed-out wheat ear ("bez zbóż"). Simple strokes, not the sheet art: at
   the topbar's 16px the hand-drawn hatching is illegible (Tomek, 2026-08-28). */
.pf-i--nograin { --pf-i: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%222%22%3E%3Cpath%20d=%22M12%2021v-5%22/%3E%3Cpath%20d=%22M12%2016c0-3-1.7-4.5-4.2-4.5C7.8%2014.3%209.5%2016%2012%2016Z%22/%3E%3Cpath%20d=%22M12%2016c0-3%201.7-4.5%204.2-4.5C16.2%2014.3%2014.5%2016%2012%2016Z%22/%3E%3Cpath%20d=%22M12%2011c0-3-1.7-4.5-4.2-4.5C7.8%209.3%209.5%2011%2012%2011Z%22/%3E%3Cpath%20d=%22M12%2011c0-3%201.7-4.5%204.2-4.5C16.2%209.3%2014.5%2011%2012%2011Z%22/%3E%3Cpath%20d=%22M12%206c-1.3-1-1.3-3%200-4%201.3%201%201.3%203%200%204Z%22/%3E%3Cpath%20d=%22m4%204%2016%2016%22/%3E%3C/svg%3E'); }

/* --- buttons ------------------------------------------------------------
   Applied to core button blocks via className: pf-btn-primary / pf-btn-ghost /
   pf-btn-navy / pf-btn-olive. The bowl icon is a CSS mask, so button text
   stays plain and editable. */
.wp-block-button.pf-btn-primary .wp-block-button__link,
.wp-block-button.pf-btn-navy .wp-block-button__link,
.wp-block-button.pf-btn-olive .wp-block-button__link,
.wp-block-button.pf-btn-ghost .wp-block-button__link {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-weight: 600; font-size: 14px; padding: 11px 22px;
  border-radius: 11px; border: 2px solid transparent; transition: .15s;
}
.wp-block-button.pf-btn-primary .wp-block-button__link { background: var(--pf-terra); color: #fff; }
.wp-block-button.pf-btn-primary .wp-block-button__link:hover { background: var(--pf-terra-dark); }
.wp-block-button.pf-btn-navy .wp-block-button__link { background: var(--pf-navy); color: #fff; }
.wp-block-button.pf-btn-navy .wp-block-button__link:hover { background: var(--pf-navy-dark); }
.wp-block-button.pf-btn-olive .wp-block-button__link { background: var(--pf-olive); color: #fff; }
.wp-block-button.pf-btn-olive .wp-block-button__link:hover { background: var(--pf-olive-dark); }
.wp-block-button.pf-btn-ghost .wp-block-button__link { border-color: var(--pf-line); background: var(--pf-paper); color: var(--pf-ink); }
.wp-block-button.pf-btn-ghost .wp-block-button__link:hover { border-color: var(--pf-terra-dark); color: var(--pf-terra-dark); }

.wp-block-button.pf-btn-bowl .wp-block-button__link::after {
  content: ""; width: 25px; height: 25px; background: currentColor; flex: none;
  /* Negative block margin caps the flex contribution at the old 18px, so the
     bigger icon does not grow the padding-sized button (Tomek, 2026-08-30). */
  margin-block: -3.5px;
  -webkit-mask: var(--pf-mask-hbowl) center / contain no-repeat;
          mask: var(--pf-mask-hbowl) center / contain no-repeat;
}

/* --- text link --- */
.pf-textlink a, a.pf-textlink {
  font-weight: 700; color: var(--pf-terra-dark); text-decoration: none;
  border-bottom: 2px solid var(--pf-terra-soft);
}
.pf-textlink a:hover, a.pf-textlink:hover { border-bottom-color: var(--pf-terra); }

/* Generic content-link fallback: any plain block-editor link (a future FAQ or
   policy paragraph, outside a pf wrapper) is on-brand, not Astra's default blue.
   Scoped to prose so it never recolours buttons; the more-specific .pf-legal and
   .pf-textlink rules still win. Replaces the DB-side Astra global (roadmap item 9). */
.entry-content p a, .entry-content li a { color: var(--pf-terra-dark); }
.entry-content p a:hover, .entry-content li a:hover { color: var(--pf-terra); }

/* ==========================================================================
   3. Homepage sections (patterns)
   ========================================================================== */

/* --- hero --- */
.pf-hero { padding-block: 56px 24px; }
/* `.pf-hero` lands on a top-level group, so Astra's padding beat it. This
   reclaims the block half. [css-007] */
.entry-content > .pf-hero { padding-block: 56px 24px; }
.pf-hero h1 { font-size: clamp(38px, 5vw, 58px); font-weight: 700; margin-bottom: 18px; }
.pf-hero .pf-lead { font-size: 18px; color: var(--pf-ink-2); max-width: 46ch; margin-bottom: 28px; }
.pf-hero .wp-block-buttons { margin-bottom: 26px; }
.pf-hero-img { position: relative; }
.pf-hero-img img {
  border-radius: 28px 28px 28px 120px; box-shadow: var(--pf-shadow);
  object-fit: cover; object-position: 22% center; aspect-ratio: 4 / 3; width: 100%;
}
.pf-stamp {
  position: absolute; left: -14px; bottom: 22px; background: var(--pf-paper);
  border: 1px solid var(--pf-line); border-radius: 14px; padding: 10px 16px;
  font-size: 13px; font-weight: 600; box-shadow: var(--pf-shadow);
  display: flex; gap: 9px; align-items: center; margin: 0;
}
.pf-stamp .pf-i { color: var(--pf-terra); }
/* --- full-bleed illustration bands (homepage v2) --- */
/* A ::after, not an <img>: kses strips <picture>/<source>/srcset from page
   content, so markup cannot serve this responsively (gotcha 15). The fade and
   the cream match are baked into the file — never overlay a gradient. gotcha 96 */
/* Own `position`, not borrowed from .pf-rel: the ::after is absolute and would
   escape to the page box if a future edit dropped that class. */
/* The band group uses a FLOW layout, not `constrained`: WP emits a per-container
   rule for constrained groups that sets `margin-inline: auto !important` on
   every child, which centred the copy back onto the animals. Flow emits none. */
/* clamp, not 520px: the art is sized by band HEIGHT and anchored to the
   viewport's right edge, so on a fixed-height band a wide screen opens dead
   cream between copy and art. Growing the band grows the art toward the copy.
   36vw = 520px at 1444, so nothing changes below that. [css-189] */
.pf-artband {
  position: relative; min-height: clamp(520px, 36vw, 880px);
  display: flex; align-items: center; padding-inline: 16px;
}
/* Block half only. Astra supplies the inline padding on a top-level group
   (gotcha 10) and a partial override leaves the properties you did not name
   (gotcha 53) — which is the intent here. */
.pf-artband, .entry-content > .pf-artband { padding-block: 52px; }
/* `alignfull` does not escape Astra's 1200px container on a page template, so
   the band is 1200 wide and the art's own right edge was landing on-screen as a
   card edge. Only the ART bleeds: the right inset reaches the viewport edge and
   the band keeps its measure. Do not add .pf-rel, whose overflow clips this. */
.pf-artband::after {
  content: ''; position: absolute; inset: 0 calc(50% - 50vw) 0 0; z-index: 0;
  pointer-events: none;
  /* 108%, not 100%: at exactly 100% the file's own top and bottom edges land on
     the band boundary and read as two hairlines. Oversizing pushes them outside
     the box, where a background is clipped anyway. Not more than ~108% — the
     team art's "Baks" label sits 9% down and would be cropped away. */
  background: var(--pf-artband-art) right center / auto 108% no-repeat;
}
.pf-artband--hero { --pf-artband-art: url('assets/img/hero-meadow2.webp'); }
.pf-artband--team { --pf-artband-art: url('assets/img/team-meadow2.webp'); }
/* Odkrywaj hero (roadmap item 21): the art is a TRANSPARENT watercolor still,
   not a baked-in scene, so the band paints its own ground — an olive wash
   fading out at the bottom. color-mix degrades to plain cream, nothing broken. */
.pf-artband--plasma {
  --pf-artband-art: url('assets/img/plasma-still.webp');
  min-height: clamp(480px, 36vw, 720px);
}
.pf-artband--plasma::before {
  content: ""; position: absolute; inset: 0 calc(50% - 50vw); pointer-events: none;
  /* -1, not paint order: below 1100 the art ::after goes STATIC, and a static
     box paints under every positioned sibling — the opaque wash sat on top of
     the art and ghosted it. Behind the band's (transparent) background is fine. */
  z-index: -1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--pf-olive) 8%, var(--pf-bg)) 0%,
    color-mix(in srgb, var(--pf-olive) 8%, var(--pf-bg)) 72%, transparent 100%);
}
/* Content-anchored like the product hero photo: the bleed is capped 160px past
   the container (cap meets the viewport at 1520px), so on wider screens the
   art stays beside the copy and .pf-bgart--odk-hero-r takes the freed cream.
   No 108% oversize — transparent alpha has no file edges to hide. */
/* The box STARTS where the copy ends and the art centres in it, so the cream
   splits evenly around the art instead of pooling between copy and art
   (Tomek, 2026-08-30). Right-anchoring suited home's wide meadow, not a
   square still. */
.pf-artband--plasma::after {
  inset: 0 clamp(-160px, calc(600px - 50vw), 0px) 0 550px;
  background-size: auto 94%;
  background-position: center;
}
.pf-artband--plasma .pf-artband-copy { max-width: 520px; }
/* The art's own baked ramp still leaves a wash under the copy's right edge;
   this widens the fade so the text column sits on clean cream. Desktop only —
   below 1100 the art is full-width under the copy and must not fade. */
@media (min-width: 1100px) {
  .pf-artband--hero::after {
    -webkit-mask: linear-gradient(to right, transparent 430px, #000 720px);
            mask: linear-gradient(to right, transparent 430px, #000 720px);
  }
}
/* The copy stays inside the art's transparent ramp, and left — WP's constrained
   layout centres every child, which put the headline on top of the dogs. */
/* z-index is load-bearing: the ::after is positioned, so it paints above
   in-flow text and washed out everything it overlapped. */
.pf-artband .pf-artband-copy { max-width: 460px; margin-inline: 0; position: relative; z-index: 1; }
/* Wider than the team band's: the hero has a three-across USP row. */
.pf-artband--hero .pf-artband-copy { max-width: 560px; }
/* Wide screens: the copy walks LEFT toward the viewport edge instead of
   sitting at the centered container's start while the art owns the right half
   (Tomek, 2026-08-28). Continuous: 0 at ≤1369px, easing to rest 5vw+32px from
   the edge — proportional, not flush (his second note); min() can't push RIGHT. */
/* :not(--plasma): that band's art bleed is capped, so walking copy only opens
   a cream gulf mid-band — scoped here per gotcha 105, not re-asserted there. */
.pf-artband:not(.pf-artband--plasma) .pf-artband-copy,
.pf-mband .pf-mband-copy { margin-left: min(0px, calc(616px - 45vw)); }

/* Hero USP trio — icon beside two short lines. */
.pf-hero-usps { display: flex; flex-wrap: wrap; gap: 18px; margin: 26px 0 0; }
/* Full ink, not --pf-ink-2: this row sits over the edge of the illustration. */
.pf-hero-usp {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; line-height: 1.3; color: var(--pf-ink); font-weight: 500;
}
/* Two classes, or Astra's `.entry-content p` margin survives on all but the
   last chip (gotcha 20) — the taller flex line then centred the last chip
   ~10px below its siblings. */
.pf-hero-usps > .pf-hero-usp { margin: 0; }
/* In the plasma column the same trio needs air on both sides of itself. */
.pf-edu-usps { margin: 22px 0 26px; }

/* Sized to the band's HEIGHT the art keeps a near-constant pixel width, so by
   ~800px the copy sits on the black dog — and nothing overflows, so a
   desktop-and-400 pass misses it. Stack below 1100; do NOT instead shrink the
   art, which pulls its baked fades inside the band. gotcha 95 */
@media (max-width: 1099px) {
  .pf-artband { min-height: 0; display: block; }
  .pf-artband-copy { width: 100%; }
  /* `display: block` is load-bearing: a static ::after is inline, and padding
     on an inline box creates no height, so the art vanished entirely. */
  /* Full-bleed like .pf-mband's mobile art: negative margins reach the
     viewport edges, so the box is 100vw — which is why the ratios are vw, not %
     (% padding tracks the CONTAINING block, still the padded band). 87/78 =
     each -sm file's own height/width. */
  .pf-artband::after {
    position: static; display: block; height: 0; padding-top: 87vw;
    margin-inline: calc(50% - 50vw);
    background-size: 100% auto; background-position: center bottom;
  }
  .pf-artband--hero { --pf-artband-art: url('assets/img/hero-meadow2-sm.webp'); }
  .pf-artband--team { --pf-artband-art: url('assets/img/team-meadow2-sm.webp'); }
  .pf-artband--team::after { padding-top: 78vw; }
  /* Square transparent art: 100%-auto would size it taller than the box and
     crop it — contain fits the whole still. The position re-set matters: the
     desktop variant's `right 12px center` beats the base mobile rule's `center
     bottom`. No bleed: alpha edges make one invisible; the boxed art stays. */
  .pf-artband--plasma::after {
    background-size: contain; background-position: center bottom;
    padding-top: 92%; margin-inline: 0;
  }
  .pf-artband .pf-artband-copy { max-width: none; }
}

/* The names are painted into the team art. At 800px they render near 1:1 and
   read; at 400 the role lines are a grey smudge, so below 600 they arrive as
   real text instead — editable, and the art turns decorative. */
.pf-artband-names { display: none; }
@media (max-width: 600px) {
  .pf-artband-names { display: block; margin-top: 22px; }
  .pf-artband-names .pf-artband-name {
    margin: 0 0 8px; font-size: 14px; color: var(--pf-ink-2); line-height: 1.35;
  }
  .pf-artband-names .pf-artband-name strong {
    font-family: 'Vujahday Script', Georgia, serif; font-size: 26px;
    font-weight: 400; color: var(--pf-terra); margin-right: 8px;
  }
}

/* 1.55em: the face is light and sits small on the baseline. */
.pf-script {
  display: block; font-family: 'Vujahday Script', Georgia, serif;
  font-weight: 400; font-size: 1.55em; line-height: .95;
  color: var(--pf-terra);
}

/* --- top trust strip --- */
/* Muted olive tint since 0.2.153 (Tomek picked it from qa/topbar-compare.png):
   the dark #3E4718 slab was the odd strong hue on every screen. The hairline
   keeps the strip reading as a bar rather than dissolving into the header. */
.pf-topbar {
  background: var(--pf-bg-alt); color: #3E4718;
  border-bottom: 1px solid var(--pf-line); font-size: 12.5px;
}
.pf-topbar-in {
  width: min(1180px, calc(100% - 32px)); margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  padding-block: 9px; row-gap: 5px;
}
/* Margins, not column-gap: on a wrap container a trailing column-gap gets
   mis-charged to the first line and shifts the items. gotcha 87 */
.pf-topbar-item { display: inline-flex; align-items: center; gap: 7px; }
.pf-topbar-item + .pf-topbar-item { margin-left: 24px; }
.pf-topbar .pf-i { color: var(--pf-olive); }
@media (max-width: 600px) {
  .pf-topbar-item + .pf-topbar-item { margin-left: 16px; }
  /* Item 3 (today: the shipping line — Customizer slot 1 is empty) wraps to
     its own centred line instead of vanishing (Tomek, 2026-08-28). */
  .pf-topbar-item:nth-child(3) { flex-basis: 100%; justify-content: center; margin-left: 0; }
}

/* --- product cards (static) --- */
.pf-card {
  background: var(--pf-paper); border: 1px solid var(--pf-line); border-radius: var(--pf-r);
  overflow: hidden; transition: .18s; position: relative; height: 100%;
  display: flex; flex-direction: column;
}
.pf-card:hover { transform: translateY(-4px); box-shadow: var(--pf-shadow); }
.pf-card .wp-block-image { margin: 0; }
.pf-card .wp-block-image img { aspect-ratio: 1; object-fit: cover; width: 100%; }
.pf-tag {
  /* pointer-events: none for the same reason as .pf-band .pf-paw — it's a
     non-interactive label sitting at z-index 2 over a product card, so it must
     never swallow a click meant for the card. */
  position: absolute; top: 14px; left: 14px; z-index: 2; pointer-events: none;
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 8px; color: #fff; margin: 0;
  /* The pill names EVERY category, so it must be free to wrap: `.pf-card` sets
     `overflow:hidden` and would clip it silently. gotcha 57 [css-010] */
  max-width: calc(100% - 28px);
}
.pf-card-body { padding: 22px 22px 24px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.pf-card-body h3 { font-size: 20px; margin: 0; }
.pf-card-body .pf-desc { font-size: 14px; color: var(--pf-ink-2); flex: 1; margin: 0; }
.pf-price { font-size: 20px; font-weight: 700; font-family: var(--pf-font-serif); margin: 6px 0 0; }
.pf-price small { font-size: 12.5px; color: var(--pf-ink-2); font-weight: 400; font-family: inherit; }
.pf-card .wp-block-buttons { margin-top: 12px; }
.pf-card .wp-block-button { width: 100%; }
/* Outline in the shelf accent (--pf-acc), per the v2 mockup — the filled
   buttons overpowered the pack shots. Border colour rides on currentColor. */
/* --pf-acc-text is the TEXT half of the accent, split off because terracotta
   #BC5A20 is 4.16:1 on the cream and fails WCAG 1.4.3 as body-size text; the
   fill and the border keep the brighter hue. Navy and olive need no split.
   [css-196] */
.pf-card.pf-acc-navy { --pf-acc: var(--pf-navy); --pf-acc-dark: var(--pf-navy-dark); }
.pf-card.pf-acc-terra { --pf-acc: var(--pf-terra); --pf-acc-dark: var(--pf-terra-dark); --pf-acc-text: var(--pf-terra-dark); }
.pf-card.pf-acc-olive { --pf-acc: var(--pf-olive-dark); --pf-acc-dark: var(--pf-olive-dark); }
.pf-card .wp-block-button .wp-block-button__link {
  width: 100%; background: none; border: 1px solid; color: var(--pf-acc-text, var(--pf-acc, var(--pf-ink)));
  /* Sentence case, not caps (Tomek, 2026-08-28) — `none` still has to be said,
     or Astra's `capitalize` wins (gotcha 23). */
  font-size: 13.5px; letter-spacing: .02em; text-transform: none;
  padding: 10px 14px; box-shadow: none;
  /* 44px tap floor (gotcha 54) — qa-mobile-hazards flagged these at 35-38px. */
  min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
}
.pf-card .wp-block-button .wp-block-button__link:hover {
  background: var(--pf-acc, var(--pf-terra)); border-color: var(--pf-acc, var(--pf-terra)); color: #fff;
}
/* The right-side icon is a filled-button flourish; on an outline button it
   reads as a stray glyph. Real add-to-cart links get the bowl left instead. */
.pf-card .pf-btn-bowl .wp-block-button__link::after { display: none; }
.pf-card .pf-btn-bowl a.add_to_cart_button::before {
  content: ""; display: inline-block; width: 25px; height: 25px;
  background: currentColor; flex: none; margin-block: -4.5px;
  -webkit-mask: var(--pf-mask-hbowl) center / contain no-repeat;
          mask: var(--pf-mask-hbowl) center / contain no-repeat;
}
/* Scoped to `.pf-card`, not a bare `.pf-acc-*` ancestor: the product page
   puts the accent on Woo's wrapper, and it leaked into related products.
   gotcha 30 [css-011] */
.pf-card.pf-acc-navy .pf-tag { background: var(--pf-navy); }
.pf-card.pf-acc-terra .pf-tag { background: var(--pf-terra); }
.pf-card.pf-acc-olive .pf-tag { background: var(--pf-olive); }
.pf-card[class*="pf-acc-"] .pf-card-body h3 a { color: var(--pf-acc-text, var(--pf-acc)); }

/* --- edu / plasma teaser --- */
.pf-edu-img img {
  width: 100%; max-width: 560px; margin-inline: auto; display: block;
  object-fit: contain;
  filter: drop-shadow(0 24px 30px rgba(88, 60, 32, .25));
}
.pf-edu h2 { font-size: clamp(28px, 3.2vw, 36px); margin-bottom: 16px; }
/* A sub-heading under the page h1. It used to be an <h3>, which skipped a level
   (h1 -> h3) for both screen readers and search engines; it is an <h2> now, and
   this rule keeps the size it always rendered at (Astra's h3 = 30px desktop)
   instead of inheriting .pf-edu h2's 36px. */
.pf-edu h2.pf-subhead { font-size: clamp(24px, 2.6vw, 30px); margin-bottom: 12px; }
.pf-edu p { color: var(--pf-ink-2); }
.pf-checks { list-style: none; display: grid; gap: 12px; margin: 0 0 26px; padding: 0; }
.pf-checks li { font-weight: 500; padding-left: 28px; position: relative; }
.pf-checks li::before {
  content: ""; position: absolute; left: 0; top: 2px; width: 20px; height: 20px;
  background: var(--pf-olive);
  /* The hand-drawn tick, not --pf-mask-check: this list is only on Odkrywaj,
     where the item-21 pass swapped every SVG that has a drawn sibling. */
  -webkit-mask: url('assets/img/icons/check.webp') center / contain no-repeat;
          mask: url('assets/img/icons/check.webp') center / contain no-repeat;
}

/* --- about --- */
.pf-about h2 { font-size: clamp(28px, 3.2vw, 36px); margin-bottom: 16px; }
.pf-about p { color: var(--pf-ink-2); }
.pf-quip {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-left: 4px solid var(--pf-gold); border-radius: 12px;
  padding: 14px 18px; font-size: 14.5px; margin: 0 0 26px;
}
.pf-quip strong { font-family: var(--pf-font-serif); }
.pf-about-photo img { border-radius: 24px; box-shadow: var(--pf-shadow); object-fit: cover; aspect-ratio: 16 / 10; width: 100%; }
.pf-dcard { margin: 0; border-radius: 16px; overflow: hidden; background: var(--pf-paper); border: 1px solid var(--pf-line);
  display: flex; flex-direction: column; height: 100%; }
.pf-dcard img { aspect-ratio: 1.25; object-fit: cover; width: 100%; }
.pf-dcard figcaption { flex: 1; padding: 9px 14px 11px; color: #fff; font-size: 12.5px; line-height: 1.35; text-align: left; margin: 0; }
.pf-dcard figcaption strong { font-family: var(--pf-font-serif); font-size: 15px; display: block; }
.pf-dc-olive figcaption { background: var(--pf-olive); }
.pf-dc-terra figcaption { background: var(--pf-terra); }
.pf-dc-navy figcaption { background: var(--pf-navy); }

/* --- FAQ (core details block) ---
   Bare hairline rows, not bordered cards — subtler, per Tomek 2026-08-28. */
.pf-faq { max-width: 760px; margin-inline: auto; }
.pf-faq .wp-block-details {
  background: none; border: 0; border-bottom: 1px solid var(--pf-line);
  border-radius: 0; margin-bottom: 0; overflow: hidden; padding: 0;
}
.pf-faq .wp-block-details summary {
  list-style: none; cursor: pointer; padding: 15px 2px; font-weight: 600;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
}
.pf-faq .wp-block-details summary::-webkit-details-marker { display: none; }
.pf-faq .wp-block-details summary::after {
  content: ""; width: 18px; height: 18px; flex: none; transition: .2s; background: var(--pf-terra);
  -webkit-mask: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222.4%22%3E%3Cpath%20d%3D%22m6%209%206%206%206-6%22%2F%3E%3C%2Fsvg%3E') center/contain no-repeat;
          mask: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222.4%22%3E%3Cpath%20d%3D%22m6%209%206%206%206-6%22%2F%3E%3C%2Fsvg%3E') center/contain no-repeat;
}
.pf-faq .wp-block-details[open] summary::after { transform: rotate(180deg); }
.pf-faq .wp-block-details > :not(summary) { padding: 0 2px 16px; color: var(--pf-ink-2); font-size: 15px; margin: 0; }

/* --- help band: FAQ + contact + guarantees (homepage v2) --- */
.pf-help-grid { gap: 40px; }
.pf-help-head {
  font-size: 21px; margin: 0 0 18px;
  font-family: var(--pf-font-serif); font-weight: 700;
}
/* The `> *` margin reset is gotcha 11: the group is a flow layout, so WP gives
   every child `margin-block-start: 24px`, which stacks on top of the grid gap. */
.pf-help .pf-faq { display: grid; gap: 0; border-top: 1px solid var(--pf-line); }
.pf-help .pf-faq > * { margin-block: 0; }
.pf-help .pf-cline { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.pf-help .pf-cline .pf-i { color: var(--pf-terra); flex: none; }
.pf-help .pf-cval { margin: 0; font-weight: 600; }
/* The guarantees sit on their own tint, as in the mockup — the one panel in this
   band, so it reads as a summary rather than a third list. */
.pf-guarantees {
  background: var(--pf-bg-alt); border-radius: 16px; padding: 22px 20px;
  display: grid; gap: 16px;
}
.pf-guarantee {
  display: flex; align-items: center; gap: 11px; margin: 0;
  font-size: 13px; line-height: 1.35; color: var(--pf-ink-2);
}
.pf-guarantee strong { color: var(--pf-ink); font-weight: 600; }
@media (max-width: 900px) {
  .pf-help-grid { gap: 28px; }
}

/* --- CTA band --- */
/* Kept, not deleted to match the mockup: it is the only bottom-of-page CTA. */
.pf-band {
  background: var(--pf-bg-alt); color: var(--pf-ink);
  border: 1px solid var(--pf-line);
  text-align: center; border-radius: 28px; padding: 56px 32px;
  position: relative; overflow: hidden;
}
.pf-band h2 { font-size: clamp(28px, 3.4vw, 38px); margin-bottom: 12px; color: var(--pf-ink); }
.pf-band p { max-width: 52ch; margin: 0 auto 26px; color: var(--pf-ink-2); }
/* Paw geometry lives here so the pattern emits only classes — raw `<svg>`
   would be kses-stripped on save. gotcha 15 [css-012] */
/* `pointer-events:none` is load-bearing: paw-b sits on the CTA button and
   killed clicks on its right half. gotcha 17 [css-013] */
.pf-band .pf-paw { position: absolute; opacity: .09; pointer-events: none; }
.pf-band .pf-paw-a { top: -30px; left: 4%; width: 150px; height: 150px; transform: rotate(-18deg); }
.pf-band .pf-paw-b { bottom: -40px; right: 5%; width: 170px; height: 170px; transform: rotate(22deg); }

/* ==========================================================================
   3b. Odkrywaj page (patterns odkrywaj-*)
   ========================================================================== */

/* anchored scroll target (sticky header offset) */
.pf-anchor { scroll-margin-top: 110px; }

/* --- benefit rows (centered icon above text, 2×2 grid) ---
   OPEN since the item-21 airy pass — no paper, no border, the .pf-pcard
   precedent (Tomek: closed boxes read as "analytical"). */
.pf-hcard {
  padding: 10px 18px; height: 100%;
  display: flex; flex-direction: column; gap: 14px; align-items: center; text-align: center;
}
.pf-hcard .pf-cicon { width: 56px; height: 56px; }
/* Accent-wash discs instead of the gold ring — the product page's why-row
   look. Scoped: home-plasma's small chips keep their rings. */
.pf-benefits .pf-cicon, .pf-steps .pf-cicon {
  border: 0; background: color-mix(in srgb, var(--pf-olive) 10%, var(--pf-bg));
}
/* No `font-family` on purpose — `.entry-content h3` supplies Lora. This rule
   used to override it to uppercase Inter. [css-014] */
.pf-hcard h3 { font-size: 17px; font-weight: 600; margin: 4px 0 8px; }
.pf-hcard p { font-size: 14px; color: var(--pf-ink-2); margin: 0; }
.pf-benefits .wp-block-columns { margin-bottom: 20px; }
.pf-benefits .wp-block-columns:last-of-type { margin-bottom: 0; }

/* --- footnote (legal disclaimer under claims) --- */
.pf-footnote { text-align: center; font-size: 12.5px; color: var(--pf-ink-2); margin-top: 26px; }

/* --- quote card (science section) --- */
/* Borderless paper + shadow since item 21 — a pull-quote earns a surface,
   but the gold ring was one bordered box too many for the page. */
.pf-qcard {
  background: var(--pf-paper); border-radius: 20px;
  box-shadow: var(--pf-shadow);
  padding: 32px 28px; text-align: center;
}
/* Watercolor magnifier under the quote — the science section's own botanical. */
.pf-sci-art { margin: 30px auto 0; }
.pf-sci-art img { width: 100%; max-width: 200px; display: block; margin-inline: auto; }
.pf-qcard .pf-qmark {
  font-family: var(--pf-font-serif); font-size: 54px; line-height: .6;
  color: var(--pf-terra); display: block; margin-bottom: 14px;
}
.pf-qcard .pf-qlead {
  font-family: var(--pf-font-serif);
  font-weight: 600; color: var(--pf-terra-dark); font-size: 19px; line-height: 1.55; margin: 0;
}
.pf-qcard .pf-qnote {
  font-size: 13px; color: var(--pf-ink-2); margin: 18px 0 0;
  border-top: 1px solid var(--pf-line); padding-top: 16px;
}

/* --- process steps strip --- */
.pf-steps {
  display: flex; justify-content: center; align-items: flex-start;
  gap: 6px; flex-wrap: wrap; margin-top: 8px;
}
.pf-step {
  flex: 1; min-width: 150px; max-width: 220px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  font-family: var(--pf-font-serif); font-size: 15px; font-weight: 600;
  line-height: 1.4; margin: 0;
}
/* padding, not margin: .pf-steps carries blockGap 0, and WP's per-container
   margin reset zeroed the old margin-top (gotcha 59) — the arrows rode 18px
   above the disc centres. 18px puts the 28px line box's middle on the 64px
   disc's 32px centre. */
.pf-step-arrow { color: var(--pf-gold); padding-top: 18px; flex: none; }
.pf-process-note { text-align: center; font-weight: 600; color: var(--pf-terra-dark); max-width: 56ch; margin: 34px auto 0; }
@media (max-width: 760px) {
  .pf-step-arrow { display: none; }
  .pf-steps { gap: 18px; }
  .pf-step { flex-basis: 40%; }
}
@media (max-width: 600px) {
  .pf-edu .wp-block-buttons { flex-direction: column; align-items: stretch; }
  .pf-edu .wp-block-button, .pf-edu .wp-block-button__link { width: 100%; }
  /* text first, image after — a bare image above the H1 reads as blank filler.
     Only reverse when the FIRST column is the illustration (home-plasma). On
     odkrywaj-science the text leads and the quote card is column 2, so reversing
     hoisted a pull-quote above its own heading. */
  .pf-edu > .wp-block-columns:has(> .pf-edu-img) { flex-direction: column-reverse; }
  .pf-edu .pf-edu-img img { max-width: 340px; }
  /* Odkrywaj's "Dlaczego" scoop: the reverse above put it directly under the
     hero band's bowls and the pair read as a duplicate render (Tomek, 390px,
     2026-08-30). Both illustrations show plasma-in-a-bowl, so on a phone one
     is enough — home-plasma keeps its image via .pf-alt. */
  .pf-edu:not(.pf-alt) .pf-edu-img { display: none; }
}

/* ==========================================================================
   3c. "Obwąchaj nas" page sections (patterns)
   ========================================================================== */

/* --- hero band: copy left on cream, the trio photo as a right-hand band
   bleeding to the viewport edge (pf-mband mechanism) --- */
/* The photo occupies the right half and its left edge is feathered into the
   cream, so all three dogs sit CLEAR of the copy — a full-bleed cover band has
   no horizontal slack to shift them out from under the text (Tomek, 2026-08-31).
   Higher specificity than the base + the ≥1450 rule, so this holds everywhere. */
/* left:50% = the art starts at the band's mid-line; right bleeds to the viewport
   edge. The band is the 1200 container (only the art bleeds), so ±44px top/bottom
   overrides the band's block padding and the photo fills the full band height
   instead of floating in a cream frame. */
.pf-obwhero .pf-mband-art {
  inset: -44px calc(45% - 55vw) -44px 40%;
  background: url('assets/img/obw-band.webp') center / cover no-repeat;
  -webkit-mask: linear-gradient(to right, transparent 0, #000 20%);
          mask: linear-gradient(to right, transparent 0, #000 20%);
}
.pf-obwhero .pf-mband-art::after { content: none; }   /* the mask feathers; no diagonal scrim */
/* Terra wash behind the copy, the odkrywaj olive-wash move in the brand's warm
   hue. Full-bleed, fades out down the band; z-index:-1 so it sits behind the
   copy, the art and the botanical (and behind the art once it goes static on
   mobile — gotcha 108). color-mix degrades to plain cream. */
.pf-obwhero::before {
  content: ""; position: absolute; inset: -44px calc(50% - 50vw); pointer-events: none;
  z-index: -1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--pf-terra) 7%, var(--pf-bg)) 0%,
    color-mix(in srgb, var(--pf-terra) 7%, var(--pf-bg)) 70%, transparent 100%);
}
/* Copy sits at the band's left, capped to the left half — no walk-left (the band
   is 1200, not full-bleed, so the base walk rule would push it under the art). */
.pf-obwhero .pf-mband-copy { max-width: 480px; margin-left: 0; }
.pf-obwhero .pf-script { color: var(--pf-terra); margin-top: 2px; }
/* Mobile stacks copy over a full-width photo (the pf-mband rule): cropped file,
   no feather, full measure. Higher specificity than the base shorthand. */
@media (max-width: 899px) {
  .pf-obwhero .pf-mband-art {
    background-image: url('assets/img/obw-band-sm.webp');
    -webkit-mask: none; mask: none;
    /* Match the band ratio to the 820×562 crop (68.5%) and anchor to the top so
       `cover` trims the path at the bottom, never the dogs' ears. */
    padding-top: 68.5%;
    background-position: center top;
  }
  .pf-obwhero .pf-mband-copy { max-width: none; }
}

/* --- our story (prose under the hero band) --- */
.pf-story { padding-block: 40px 8px; }
.pf-story p { color: var(--pf-ink-2); }
.pf-story .pf-quip { color: var(--pf-ink); margin-bottom: 0; margin-top: 22px; }

/* --- role line: breed / job title / department. Shared by dogs, people, QC. --- */
.pf-role {
  font-family: var(--pf-font-serif); font-style: italic;
  color: var(--pf-terra-dark); margin: 2px 0 10px;
}

/* --- Fly, Baks & Mila (psi zespół) — open columns, no card (item 21 airy) --- */
.pf-dogs { padding-block: 24px 8px; }
.pf-dogs .wp-block-columns { margin-bottom: 0; }
.pf-dogbox { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 0 6px; }
.pf-dog-avatar { margin: 0; flex: none; }
.pf-dog-avatar img {
  width: 128px; height: 128px; border-radius: 50%; object-fit: cover;
  border: 4px solid var(--pf-bg); box-shadow: var(--pf-shadow);
}
.pf-dog-olive .pf-dog-avatar img { outline: 2px solid var(--pf-olive); outline-offset: 2px; }
.pf-dog-terra .pf-dog-avatar img { outline: 2px solid var(--pf-terra); outline-offset: 2px; }
.pf-dog-navy .pf-dog-avatar img { outline: 2px solid var(--pf-navy); outline-offset: 2px; }
.pf-dog-olive .pf-role { color: var(--pf-olive); }
.pf-dog-navy .pf-role { color: var(--pf-navy); }
/* Handwritten name, colour-matched to the avatar ring (item 21: script accents
   on the short things — a name is the safest place for it). */
.pf-dogbox-body { width: 100%; }
.pf-dogbox-body h2, .pf-dogbox-body .pf-role { text-align: center; }
/* Scoped with the parent (0,2,0) so the margin outranks `.woocommerce-js h2
   { margin-bottom: .7em }` (0,1,1) — a site-wide Woo rule that pinned this h2 to
   28px and silently ate every gap edit. Bottom margin in em so it tracks the
   name size (the script face leaves a tall line-box; -0.3em closes it). */
.pf-dogbox-body .pf-dogname {
  font-family: 'Vujahday Script', Georgia, serif; font-weight: 400;
  font-size: 40px; line-height: 1; margin: 6px 0 0.3em; color: var(--pf-terra);
}
.pf-dog-olive .pf-dogname { color: var(--pf-olive); }
.pf-dog-navy .pf-dogname { color: var(--pf-navy); }
.pf-dogbox-body .pf-role { font-size: 15px; margin: 0 0 12px; }
.pf-dogbox-body p:last-child { font-size: 14.5px; color: var(--pf-ink-2); margin: 0; }
@media (max-width: 959px) {
  /* core only stacks at 782px, but three cards need more room than that. core
     holds the row with `flex-wrap:nowrap!important` + `flex-basis:0!important`
     above 782px, so !important is the only way over it (verified in served CSS). */
  .pf-dogs .wp-block-columns { flex-wrap: wrap !important; gap: 30px; }
  .pf-dogs .wp-block-columns > .wp-block-column { flex-basis: 100% !important; }
}

/* --- people (2-up grid; Piotrek's card is the tall one) — open rows, no card,
   accent-wash disc icon (item 21 airy) --- */
.pf-people-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px 36px; align-items: start; }
/* Resets WP block-gap, which shifts grid item 2 down and stacks on top of a
   card's own flex `gap`. gotcha 11 [css-015] */
.pf-people-grid > *, .pf-manu-grid > *,
.pf-person > *, .pf-person-body > *,
.pf-manu-item > *, .pf-manu-text > *,
.pf-dogbox > *, .pf-dogbox-body > * { margin-block-start: 0; }
.pf-person { display: flex; gap: 20px; align-items: flex-start; }
.pf-person .pf-cicon {
  width: 62px; height: 62px; margin-inline: 0; flex: none;
  border: 0; background: color-mix(in srgb, var(--pf-terra) 12%, var(--pf-bg));
}
.pf-person-body { flex: 1; min-width: 0; }
.pf-person-body h3 {
  font-family: 'Vujahday Script', Georgia, serif; font-weight: 400;
  font-size: 33px; line-height: 1.05; color: var(--pf-terra); margin: 0;
}
.pf-person-body .pf-role { font-size: 15px; margin: 2px 0 12px; }
.pf-person-body p { font-size: 14.5px; color: var(--pf-ink-2); margin: 0 0 10px; }
.pf-person-body p:last-child { margin-bottom: 0; }

/* --- manufaktura strip (5 across; own section, not a sidebar — the people
   column is far taller than this content, so a sidebar left a dead zone) --- */
.pf-manu-sec { padding-block: 0 0; }
.pf-manu { padding-block: 40px 36px; }
.pf-manu .pf-sec-head { max-width: 720px; margin-bottom: 34px; }
.pf-manu .pf-sec-head h2 { text-wrap: balance; }
.pf-manu-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
}
/* Shared by the homepage and /obwachaj-nas/ — both get the open-column form. */
.pf-manu-item {
  padding: 8px 18px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
/* Only while the grid is one row. Once it wraps to 2 columns the first item
   of each later row would carry a divider with nothing to its left. */
@media (min-width: 1081px) {
  .pf-manu-item + .pf-manu-item { border-left: 1px solid var(--pf-line); }
}
.pf-manu-text { display: flex; flex-direction: column; gap: 7px; }
/* see .pf-hcard h3 — same override removed, same reason */
.pf-manu-item h3 { font-size: 16px; font-weight: 600; margin: 0; text-wrap: balance; }
.pf-manu-item p { font-size: 13.5px; color: var(--pf-ink-2); margin: 0; }

/* --- dział kontroli jakości zapachu — full-width hero band (pf-mband, the same
   mechanism as the top hero): copy left on cream, the drawn trio bleeding to the
   right viewport edge, feathered left. Dogs face left = inward (Tomek 2026-09-01) --- */
/* padding on the copy (not the band) + art inset 0 = the trio fills the band's
   full height with no vertical bleed, so it can't spill onto the CTA box below;
   margin-block spaces the band from its neighbours. */
.pf-qc.pf-mband { padding-block: 0; margin-block: 48px; }
.pf-qc .pf-mband-art {
  inset: 0 calc(46% - 54vw) 0 44%;
  background: url('assets/img/team-trio.webp') center / cover no-repeat;
  -webkit-mask: linear-gradient(to right, transparent 0, #000 22%);
          mask: linear-gradient(to right, transparent 0, #000 22%);
}
.pf-qc .pf-mband-art::after { content: none; }
.pf-qc .pf-mband-copy { max-width: 500px; margin-left: 0; padding-block: 44px; }
.pf-qc .pf-mband-copy h2 { font-size: clamp(28px, 3.4vw, 38px); font-weight: 700; margin-bottom: 6px; }
.pf-qc .pf-role { font-size: 16.5px; margin: 2px 0 16px; }
.pf-qc .pf-mband-copy p { color: var(--pf-ink-2); }
.pf-qc .pf-quip { margin: 18px 0 0; color: var(--pf-ink); }
@media (max-width: 899px) {
  .pf-qc .pf-mband-art {
    order: -1;  /* image ABOVE the title on mobile (Tomek) */
    -webkit-mask: none; mask: none;
    padding-top: 56.3%; margin-top: 0;
    background-image: url('assets/img/team-trio.webp');
    background-position: center;
  }
  .pf-qc .pf-mband-copy { max-width: none; }
}

/* --- responsive --- */
@media (max-width: 1080px) {
  .pf-manu-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  .pf-people-grid { grid-template-columns: 1fr; gap: 26px; }
}
@media (max-width: 600px) {
  .pf-story { padding-block: 26px 0; }
  .pf-person { flex-direction: column; gap: 14px; }
  .pf-person .pf-cicon { width: 58px; height: 58px; }
  /* Stacked rows centre their icon + name. Body copy stays left-aligned:
     centred paragraphs are hard to read at ~300px (same call as .pf-qc-body below). */
  .pf-person { align-items: center; }
  .pf-person .pf-cicon { margin-inline: auto; }
  .pf-person-body { width: 100%; }
  .pf-person-body h3, .pf-person-body .pf-role { text-align: center; }
  .pf-manu { padding-block: 30px 26px; }
  .pf-manu .pf-sec-head { margin-bottom: 24px; }
  .pf-manu-grid { grid-template-columns: 1fr; gap: 12px; }
  /* Same shape as .pf-dogbox / .pf-person: centred icon + title, body copy left.
     Icon-left/text-right left the icon with an empty column under it. */
  .pf-manu-item { flex-direction: column; align-items: center; text-align: left; padding: 22px 20px; gap: 14px; }
  .pf-manu-item h3 { text-align: center; }
  .pf-manu-text { width: 100%; min-width: 0; }
}

/* ==========================================================================
   3d. "Zlap nas" page sections (patterns zlap-*)
   ========================================================================== */

/* --- hero (left-aligned) ---
   Airy pass (item 21): script accent + a left divider under the h1. This
   supersedes the 2026-08-22 "no divider in the hero" call — the whole site now
   marks its heros this way (odkrywaj/obwachaj/sklep). [css-016] */
.pf-zhero h1 { font-size: clamp(34px, 4.6vw, 52px); font-weight: 700; margin-bottom: 4px; }
.pf-zhero .pf-script { color: var(--pf-terra); margin-top: 2px; }
.pf-zhero .pf-divider { justify-content: flex-start; margin: 12px 0 18px; }
/* `margin-inline` needs `!important`: WP's constrained layout ships `margin-
   left/right:auto!important`, which re-centres the lead. [css-017] */
.pf-zhero .pf-lead {
  font-size: 18px; color: var(--pf-ink-2); max-width: 62ch;
  margin-block: 0; margin-inline: 0 !important;
}

/* --- contact details column ---
   Each row is a class-only icon span (gotcha 15, so kses cannot eat it) plus a label
   and a value that are REAL paragraph blocks -- the address, phone and e-mail have to
   be editable in the block editor without a deploy. */
.pf-zdetails h2 { font-size: clamp(22px, 2.4vw, 28px); margin-bottom: 24px; }
.pf-cline { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 20px; }
/* Resets WP block-gap. The column is a flow group too, so the rows need it
   as much as their children. gotcha 11 [css-018] */
.pf-zdetails > *, .pf-cline > *, .pf-cline-body > * { margin-block-start: 0; }
/* Hand-drawn icon (item 21), aligned to the label baseline. */
.pf-cline > .pf-hicon { margin-top: 1px; flex: none; }
.pf-cline-body { display: flex; flex-direction: column; gap: 3px; }
/* Scoped under `.pf-cline`, not bare: Astra's `.entry-content p { margin-
   bottom:1.6em }` (0-1-1) beats any single-class paragraph rule. gotcha 20
   [css-019] */
.pf-cline .pf-clabel { font-size: 12.5px; font-weight: 600; color: var(--pf-ink-2); margin: 0; }
.pf-cline .pf-cval { font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600; line-height: 1.45; margin: 0; }
.pf-cline .pf-cval a { color: var(--pf-terra-dark); text-decoration: none; border-bottom: 2px solid var(--pf-terra-soft); }
.pf-cline .pf-cval a:hover { border-bottom-color: var(--pf-terra); }
.pf-cline .pf-cval-plain { font-weight: 500; font-size: 16px; color: var(--pf-ink-2); }
.pf-zdetails .pf-quip { margin-top: 30px; }

/* --- form card --- */
/* Borderless paper + shadow (item 21 airy) — a form earns a surface, but not a
   hard ring. */
.pf-formcard {
  background: var(--pf-paper); border-radius: 24px; padding: 34px;
  box-shadow: var(--pf-shadow);
}
.pf-formcard > * { margin-block-start: 0; }
.pf-formcard h2 { font-size: clamp(22px, 2.4vw, 28px); margin: 0 0 8px; }
.pf-formcard .pf-formnote { color: var(--pf-ink-2); font-size: 14.5px; margin: 0 0 24px; }
.pf-formcard .pf-formfoot { color: var(--pf-ink-2); font-size: 12.5px; margin: 20px 0 0; }

/* --- SureForms (form 2035, embedded via wp:srfm/form) ---
   SureForms is CSS-custom-property driven, so restyle it by overriding its
   vars. Only its hard-coded fonts and button chrome need real selectors.
   [css-020] */
.pf-formcard .srfm-form-container {
  --srfm-color-scheme-primary: var(--pf-terra);
  --srfm-color-scheme-text: var(--pf-ink);
  --srfm-color-scheme-text-on-primary: #fff;
  --srfm-color-input-background: #fff;
  --srfm-color-input-background-hover: #fff;
  --srfm-color-input-border: var(--pf-line);
  --srfm-color-input-border-hover: var(--pf-gold);
  --srfm-color-input-border-focus-glow: rgba(188, 90, 32, .16);
  --srfm-color-input-text: var(--pf-ink);
  --srfm-color-input-label: var(--pf-ink);
  --srfm-label-text-color: var(--pf-ink);
  --srfm-color-input-placeholder: var(--pf-ink-2);
  --srfm-color-input-description: var(--pf-ink-2);
  --srfm-color-input-selected: var(--pf-terra);
  --srfm-dropdown-icon-color: var(--pf-ink-2);
  --srfm-dropdown-menu-border-color: var(--pf-line);
  --srfm-dropdown-option-text-color: var(--pf-ink);
  --srfm-dropdown-placeholder-color: var(--pf-ink-2);
  --srfm-input-field-border-radius: 12px;
  --srfm-checkbox-input-border-radius: 5px;
  --srfm-btn-border-radius: 12px;
  --srfm-label-font-weight: 600;
  background: transparent; padding: 0; max-width: none;
}
.pf-formcard .srfm-form-container,
.pf-formcard .srfm-block-label,
.pf-formcard .srfm-input-common,
.pf-formcard .srfm-button { font-family: 'Inter', system-ui, sans-serif; }
.pf-formcard .srfm-input-textarea { min-height: 132px; }
/* Row rhythm (Tomek, 2026-08-22). Each field cost 114px, 16px of it a
   permanently reserved but empty error strip. [css-021] */
.pf-formcard .srfm-form-container { --srfm-input-height: 44px; }
/* It is `height`, not `min-height`, that reserves the error strip, so a
   `min-height:0` override looks right and does nothing. [css-022] */
.pf-formcard .srfm-form-container .srfm-block:not(.srfm-error) .srfm-error-wrap { height: 0; }
.pf-formcard form.srfm-form { row-gap: 14px; }
/* Match .pf-btn-primary exactly -- same padding, weight, radius, shadow and hover. */
.pf-formcard .srfm-button.srfm-btn-frontend {
  background: var(--pf-terra); color: #fff; border: 2px solid transparent;
  font-weight: 600; font-size: 15px; padding: 14px 26px; border-radius: 12px;
  box-shadow: var(--pf-shadow); transition: .15s; text-transform: none;
}
.pf-formcard .srfm-button.srfm-btn-frontend:hover { background: var(--pf-terra-dark); }
.pf-formcard .srfm-gdpr-block .srfm-block-label { font-weight: 400; font-size: 13.5px; color: var(--pf-ink-2); }
.pf-formcard .srfm-success-box { background: var(--pf-bg-alt); border: 1px solid var(--pf-line); border-radius: 16px; }

/* Stack at 900px, not core's 782px. Core holds the row with `!important`, so
   beating it needs `!important` too. [css-023] */
@media (max-width: 900px) {
  .pf-zcontact .wp-block-columns { flex-wrap: wrap !important; gap: 34px; }
  .pf-zcontact .wp-block-columns > .wp-block-column { flex-basis: 100% !important; }
}
/* Side by side, the form card's own 34px top padding drops "Napisz do nas" below
   "Nasze namiary"; match it so the two column headings share a baseline. Only while
   the columns are actually side by side -- stacked, it would just be a dead gap. */
@media (min-width: 901px) {
  .pf-zdetails { padding-top: 34px; }
}
@media (max-width: 600px) {
  .pf-formcard { padding: 22px 20px 24px; border-radius: 18px; }
  .pf-cline { gap: 12px; margin-bottom: 18px; }
  .pf-zdetails .pf-quip { margin-top: 24px; }
  /* Full-width submit, same call as the hero buttons (gotcha 5). */
  .pf-formcard .srfm-submit-container,
  .pf-formcard .srfm-submit-wrap { width: 100%; }
  .pf-formcard .srfm-button.srfm-btn-frontend { width: 100%; }
}

/* ==========================================================================
   3e. "Pełna Micha" — sklep (WooCommerce: archiwum sklepu i kategorii)
   ========================================================================== */

/* The shop archive is NOT a page template, so nothing in §2/§3 arrives for
   free; page content reaches it only via `woocommerce_archive_description`.
   gotcha 24 [css-024] */

/* Astra sizes this container from its own Customizer to ~1300px — 100px
   wider than an `alignfull` section's 1200px, so the two disagree by 60px a
   side. [css-025] */
.ast-woo-shop-archive .ast-woocommerce-container,
.tax-product_cat .ast-woocommerce-container,
.tax-product_tag .ast-woocommerce-container { max-width: 1200px; margin-inline: auto; }

/* On the shop, the description renders inside `.woocommerce-products-
   header`, so that header must add no spacing. Category archives do need it.
   [css-026] */
.woocommerce-shop .woocommerce-products-header { margin: 0; padding: 0; }

/* Category archives keep Woo's `<h1>`, treated as a section head. NO bottom
   padding: 36px stacked with `.pf-catnav`'s 40px to make 76px. [css-027] */
.tax-product_cat .woocommerce-products-header,
.tax-product_tag .woocommerce-products-header {
  padding: 34px 0 0; margin: 0; text-align: center;
}

/* On a category archive the chips sit directly under the title and belong WITH it,
   so they are pulled close. On the shop page the same row follows a 370px photo
   hero and needs the full 40px above to separate from it — hence the override
   rather than a smaller value for both. */
.tax-product_cat .pf-catnav,
.tax-product_tag .pf-catnav { padding-top: 20px; }
.woocommerce-products-header__title {
  font-size: clamp(28px, 3.4vw, 38px); margin: 0;
}
.tax-product_cat .term-description,
.tax-product_tag .term-description {
  max-width: 640px; margin: 12px auto 0; color: var(--pf-ink-2);
}
.tax-product_cat .term-description p:last-child,
.tax-product_tag .term-description p:last-child { margin-bottom: 0; }

/* Puts `alignfull` back on the measure. Astra's full-bleed rule (0-4-0)
   matches here but never on the four page templates. gotcha 24 [css-028] */
.ast-plain-container.ast-no-sidebar .entry-content.pf-shop-intro > .alignfull {
  margin-left: 0; width: auto; max-width: 100%;
}

/* --- hero band (pattern petfly/sklep-hero, mockup 2026-08-28) ---
   A full-bleed cover PHOTO with a CSS cream scrim — NOT the artband and NOT a
   baked alpha ramp; both were rejected on measurement, not taste. [css-192] */
.pf-mband {
  position: relative; min-height: clamp(430px, 34vw, 800px);
  display: flex; align-items: center; padding-inline: 16px;
}
.pf-mband, .entry-content > .pf-mband { padding-block: 44px; }
.pf-mband-art {
  position: absolute; inset: 0 calc(50% - 50vw); z-index: 0; pointer-events: none;
  background: url('assets/img/micha-band.webp') right 62% / cover no-repeat;
}
/* Solid page cream under the copy column, gone by 55% so pouches + dog stay
   photographic. Literal 250,244,233 = --pf-bg (a var() cannot take alpha). */
/* Stops track the COPY (which walks left on wide screens), not a fixed
   fraction: calc(5vw + 520px) stays just past the copy's right edge at every
   width, so on a wide monitor the scrim retreats and the photo shows
   (Tomek: 46% flat was too aggressive). Derivation in css-192. */
/* 112deg, not to-right: the boundary slants like a "/" — firmer at the top
   (over the copy), forgiving at the bottom where the table scene lives
   (Tomek, 2026-08-28). */
.pf-mband-art::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(112deg,
    var(--pf-bg) 0, var(--pf-bg) calc(5vw + 500px), rgba(250, 244, 233, .85) calc(5vw + 580px), rgba(250, 244, 233, 0) calc(5vw + 760px));
}
/* From 1450px there is room to stop covering the photo at all: the art turns
   height-sized and right-anchored (the artband mechanism), the pouches sit
   clear of the copy, and the scrim's only job is fading the file's hard left
   edge — 65.26vw = band-height (34vw) x aspect (1.7773) x 108%. css-192 */
@media (min-width: 1450px) {
  .pf-mband { min-height: 34vw; }
  .pf-mband-art { background-size: auto 108%; background-position: right center; }
  .pf-mband-art::after {
    background: linear-gradient(112deg,
      var(--pf-bg) calc(100% - 62vw), rgba(250, 244, 233, 0) calc(100% - 62vw + 220px));
  }
}
.pf-mband-copy { position: relative; z-index: 1; max-width: 460px; margin-inline: 0; }
.pf-mband h1 { font-size: clamp(38px, 4.6vw, 58px); font-weight: 700; margin-bottom: 10px; }
.pf-mband .pf-divider { margin: 0 0 18px; justify-content: flex-start; }
.pf-mband .pf-lead { font-size: 18px; color: var(--pf-ink-2); max-width: 40ch; margin-bottom: 26px; }
@media (max-width: 899px) {
  /* Stack, headline BEFORE image (the house mobile-hero rule, gotcha 5): the
     art div precedes the copy in the DOM, so a column flex reorders it. */
  /* align-items: stretch is load-bearing — the desktop rule's `center` makes
     the width-less art div shrink-wrap to 0 as a column flex item (measured). */
  .pf-mband { min-height: 0; display: flex; flex-direction: column; align-items: stretch; padding-block: 34px 0; }
  .entry-content > .pf-mband { padding-block: 34px 0; }
  .pf-mband-art { order: 2; }
  .pf-mband-copy { max-width: none; }
  .pf-mband-art {
    position: static; display: block; height: 0; padding-top: 62%;
    margin: 26px calc(50% - 50vw) 0;
    background: url('assets/img/micha-band-sm.webp') center / cover no-repeat;
  }
  .pf-mband-art::after { content: none; }
}

/* --- plasma intro strip (same pattern) --- */
/* Every top-level group's real vertical padding is Astra's, fed by these
   :root vars (gotcha 10's padding-block half) — 2em SITEWIDE since 0.2.131
   (Tomek: tighter, globally). Wins on source order: Astra re-declares 3em at
   :root in three media blocks, all before this sheet. */
:root {
  --wp--custom--ast-default-block-top-padding: 2em;
  --wp--custom--ast-default-block-bottom-padding: 2em;
}
.pf-shop-plasma { max-width: 720px; margin-inline: auto; padding: 34px 16px 0; text-align: center; }
.pf-shop-plasma p { font-size: 16px; line-height: 1.7; color: var(--pf-ink-2); margin: 0; }
.pf-hl-olive { color: var(--pf-olive-dark); }
.pf-hl-terra { color: var(--pf-terra-dark); }

/* --- "Nasze produkty" head (petfly_shop_products_head(), shop only) ---
   scroll-margin: the hero CTA jumps here; without it the sticky-less header
   still clips the heading's breathing room. */
/* Chips render directly under this head since 0.2.131 (Tomek), so the gap to
   them is small and the chips' own bottom padding spaces the grid. */
.pf-shop-prodhead { margin-bottom: 4px; scroll-margin-top: 24px; }
.pf-shop-prodhead h2 { margin-bottom: 10px; }
.woocommerce-shop .pf-catnav { padding-top: 6px; }

/* --- category chips (petfly_render_shop_catnav(), on shop + /kategoria/*) ---
   Category chips replace the old section head. Centred at desktop, one
   horizontally scrollable row on a phone. [css-032] */
/* The 40px above is the whole point of the rule (Tomek, 2026-08-22): 10px
   read as part of the hero instead of as the grid's control strip. [css-033] */
.pf-catnav {
  position: relative;
  width: min(1180px, 100%); margin: 0 auto; padding: 40px 0 28px;
  display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;
}
.pf-catnav > .pf-chipnav { position: relative; z-index: 1; }
.pf-chipnav {
  display: inline-flex; align-items: center; min-height: 38px; padding: 0 18px;
  border: 1px solid var(--pf-line); border-radius: 999px;
  background: var(--pf-paper); color: var(--pf-ink-2);
  font-size: 14px; font-weight: 600; text-decoration: none;
  transition: .15s; white-space: nowrap;
}
.pf-chipnav:hover { border-color: var(--pf-terra); color: var(--pf-terra-dark); }
.pf-chipnav.is-current {
  background: var(--pf-terra); border-color: var(--pf-terra); color: #fff;
}
.pf-chipnav.is-current:hover { background: var(--pf-terra-dark); color: #fff; }

/* --- result count + sort dropdown ---
   Hidden by PHP while the catalogue fits one page, so style them now rather
   than the first time someone adds a twelfth product. [css-034] */
.woocommerce-result-count,
.woocommerce-ordering {
  margin: 0 0 18px; font-size: 14px; color: var(--pf-ink-2);
}
.woocommerce-ordering select.orderby {
  font-family: 'Inter', system-ui, sans-serif; font-size: 14px;
  padding: 9px 14px; border: 1px solid var(--pf-line); border-radius: 10px;
  background: var(--pf-paper); color: var(--pf-ink);
}
.woocommerce-ordering select.orderby:focus-visible {
  outline: 2px solid var(--pf-terra); outline-offset: 2px;
}

/* --- pagination (renders itself once there is a page 2) ---
   Woo and Astra both style pagination with FOUR element selectors (0-2-4 and
   0-3-4), so the obvious rule loses. [css-035] */
.woocommerce-pagination { width: min(1180px, 100%); margin: 0 auto 72px; text-align: center; }
.woocommerce nav.woocommerce-pagination ul.page-numbers {
  display: inline-flex; flex-wrap: wrap; gap: 8px;
  list-style: none; margin: 0; padding: 0; border: 0;
}
.woocommerce nav.woocommerce-pagination ul.page-numbers li {
  margin: 0; border: 0; overflow: visible;
}
.woocommerce nav.woocommerce-pagination ul.page-numbers li a.page-numbers,
.woocommerce nav.woocommerce-pagination ul.page-numbers li span.page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 12px;
  border: 1px solid var(--pf-line); border-radius: 12px;
  background: var(--pf-paper); color: var(--pf-ink-2);
  font-size: 15px; font-weight: 600; text-decoration: none; transition: .15s;
}
.woocommerce nav.woocommerce-pagination ul.page-numbers li a.page-numbers:hover,
.woocommerce nav.woocommerce-pagination ul.page-numbers li a.page-numbers:focus {
  background: var(--pf-paper); border-color: var(--pf-terra); color: var(--pf-terra-dark);
}
.woocommerce nav.woocommerce-pagination ul.page-numbers li span.page-numbers.current,
.woocommerce nav.woocommerce-pagination ul.page-numbers li a.page-numbers.current {
  background: var(--pf-terra); border-color: var(--pf-terra); color: #fff;
}
.woocommerce nav.woocommerce-pagination ul.page-numbers li span.page-numbers.dots {
  border-color: transparent; background: none; min-width: 24px; padding: 0;
}

/* --- product grid ---
   Astra lays the grid out from its Customizer with `(0,4,1)` selectors,
   which beat a plain `.woocommerce ul.products` (0,2,1). gotcha 23 [css-036] */
/* Three selectors because the grid renders in three DOM contexts and the
   competition differs in each. [css-037] */
.woocommerce.pf-products-shortcode ul.products.pf-grid:not(.elementor-grid),
ul.products.pf-grid,
body.woocommerce ul.products.pf-grid:not(.elementor-grid),
body.woocommerce-page ul.products.pf-grid:not(.elementor-grid) {
  width: min(1180px, 100%);
  margin: 0 auto 72px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}
.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product {
  display: flex; width: auto; margin: 0; padding: 0; float: none;
}
.woocommerce ul.products li.product .pf-card { width: 100%; }

/* WooCommerce's own stylesheet ships `.woocommerce ul.products li.product h3
   { font-size: 1em; padding: .5em 0 }` (0-2-1), which out-ranks
   `.pf-card-body h3` (0-1-1) — the card titles came out at 15px desktop /
   13.7px mobile with 7.5px of stray padding, against the approved 20px. */
.woocommerce ul.products li.product .pf-card-body h3 {
  font-size: 20px; padding: 0; margin: 0;
}

/* Astra's `.woocommerce a.button` typography beats the block-button rule and
   capitalised "Dodaj do miski" — so `none` must be restated at THIS
   specificity, not only in §3. gotcha 23 [css-038] */
.woocommerce ul.products li.product .pf-card a.wp-block-button__link {
  font-family: 'Inter', system-ui, sans-serif;
  text-transform: none;
  margin: 0;
}

/* --- the card itself ---
   Structure matches the homepage cards, so §3 does the work. Only the linked
   `<img>` and the title link need rules. [css-039] */
.pf-card-img { display: block; line-height: 0; }
/* The gap under the pack shot was Woo's `li.product a img{margin-bottom:.8em}`
   until php-105 stopped shipping that sheet off the store — the approved card
   height depends on it, so own it here, in `em` because Astra shrinks the body
   font under 420px. Woo pages still win, with the same value. gotcha 53 [css-199] */
.pf-card-img img {
  width: 100%; aspect-ratio: 1; object-fit: cover; display: block;
  margin-bottom: .8em;
}
.pf-card-body h3 a { color: inherit; text-decoration: none; }
.pf-card:hover .pf-card-body h3 a { color: var(--pf-terra-dark); }
/* Woo wraps the amount in .woocommerce-Price-amount > bdi; inherit .pf-price. */
.pf-card .pf-price .woocommerce-Price-amount { font: inherit; color: inherit; }

/* The focus ring is a dotted BORDER, not an outline, so `outline:none` does
   nothing. It matters here because add-to-cart is AJAX. gotcha 14 [css-040] */
/* border-STYLE only: the ring Astra paints is a dotted border, and a full
   border shorthand here would wipe the accent colour set per shelf. */
.woocommerce ul.products li.product .pf-card a.wp-block-button__link:focus {
  border-style: solid; outline: none;
}
.woocommerce ul.products li.product .pf-card a.wp-block-button__link:focus-visible {
  outline: 2px solid var(--pf-terra); outline-offset: 3px;
}

/* Woo hides `.added_to_cart` assuming the header surfaces the cart. Shown
   deliberately: on a phone the header cart is off-screen. [css-041] */
.woocommerce ul.products li.product .pf-card .pf-card-body {
  position: relative; padding-bottom: 46px;
}
.woocommerce ul.products li.product .pf-card a.added_to_cart {
  position: absolute; left: 0; right: 0; bottom: 12px;
  display: block; margin: 0; text-align: center;
  font-size: 13px; font-weight: 700; text-decoration: none;
  color: var(--pf-terra-dark); border-bottom: 0;
}
.woocommerce ul.products li.product .pf-card a.added_to_cart:hover { text-decoration: underline; }

/* --- horizontal archive card (mockup 2026-08-28) ---
   `pf-grid--row` is an opt-in class loop-start.php adds on the shop and
   /kategoria/* archives ONLY — the shortcode contexts keep the stacked card
   (php-096: never restyle .pf-card itself, cart/checkout reuse pieces). */
.pf-grid--row .pf-card { display: grid; grid-template-columns: minmax(0, 45%) 1fr; }
/* Flush, full-height image column. Since 0.2.160/161 the image is the pack
   shot, padded server-side to 600x880 with an edge-matched colour ("zoom out
   a bit", Tomek 2026-08-29): this ~0.47 box's cover window is then ~410px of
   the source — wider than the widest pouch (green, 373px). gotcha 47. */
/* The img is ABSOLUTE in its cell: height:100% in an auto grid row is
   circular — the image's intrinsic height drives the track and the card
   balloons (measured: ~1600px cards). Absolute takes it out of the height
   negotiation; the body column owns the row. */
.pf-grid--row .pf-card-img { align-self: stretch; position: relative; min-height: 250px; }
/* (0,4,3): Astra's archive copy of Woo's `li.product a img { height: auto;
   margin: 0 0 1em }` is (0,2,3) and silently beat the height/margin here —
   the lazy 2nd/3rd images then stretched to 1500px, the 0.2.88 bug reborn. */
.woocommerce ul.products.pf-grid--row li.product .pf-card-img img {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
  aspect-ratio: auto; object-fit: cover;
}
.pf-grid--row .pf-card .pf-card-body {
  padding: 24px 20px 56px; text-align: center; justify-content: center;
}
/* Bigger serif name in the shelf accent; four classes+elements, or the base
   archive title rule (0,3,2) keeps its 20px. */
.woocommerce ul.products.pf-grid--row li.product .pf-card-body h3 { font-size: 23px; line-height: 1.25; }
/* The mockup's little ornament between name and copy — the same olive branch
   the global divider wears (Tomek: branch, not paw). CSS content, so it never
   reaches a screen reader; file mask, so gotcha 101 applies to any harness QA. */
.pf-grid--row .pf-card-body h3::after {
  content: ''; display: block; width: 22px; height: 16px; margin: 8px auto 2px;
  background: var(--pf-olive);
  -webkit-mask: url('assets/img/icons/branch.webp') center / contain no-repeat;
          mask: url('assets/img/icons/branch.webp') center / contain no-repeat;
}
/* Mockup: no price, no weight, no add — the card's one job is the click
   through (Tomek, 2026-08-28). Archives only; every other card keeps them. */
.pf-grid--row .pf-price { display: none; }
/* Filled accent, scoped here only: the homepage keeps the outline treatment
   (0.2.100, Tomek). The *-dark hover tokens ride the base .pf-acc-* rules in §3. */
.pf-grid--row .pf-card .wp-block-button .wp-block-button__link {
  background: var(--pf-acc, var(--pf-terra)); border-color: var(--pf-acc, var(--pf-terra));
  color: #fff;
}
.pf-grid--row .pf-card .wp-block-button .wp-block-button__link:hover {
  background: var(--pf-acc-dark, var(--pf-terra-dark)); border-color: var(--pf-acc-dark, var(--pf-terra-dark));
}
@media (max-width: 600px) {
  /* One column per card: at 400px the 45% image track leaves a ~190px centred
     text column, which reads cramped. Photo banner on top, flush. */
  .pf-grid--row .pf-card { grid-template-columns: 1fr; }
  /* The img goes BACK IN FLOW and carries the ratio itself: an absolute img
     filling a cell sized only by aspect-ratio is 0-tall on iOS Safari — Chrome
     tolerates it, so QA never saw it. In one column the img SHOULD drive its
     row, so the desktop circular-height trap is moot. gotcha 103. */
  .pf-grid--row .pf-card-img { min-height: 0; }
  .woocommerce ul.products.pf-grid--row li.product .pf-card-img img {
    /* 1/1 = the pre-pad pack shot's ratio: cover center-crops the 600x880
       file back to its original square, and any flatter banner cuts pouch. */
    position: static; height: auto; aspect-ratio: 1;
  }
  .pf-grid--row .pf-card .pf-card-body { padding: 18px 20px 52px; }
}

/* --- USP strip under the grid (petfly_shop_usps(), shop only) --- */
.pf-usps {
  width: min(1180px, 100%); margin: -18px auto 72px;
  padding-top: 34px; border-top: 1px solid var(--pf-line);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 26px;
}
.pf-usp { display: flex; gap: 14px; align-items: flex-start; }
.pf-usp .pf-hicon { flex: none; }
.pf-usp h3 { font-size: 16.5px; margin: 0 0 4px; }
.pf-usp p { font-size: 13.5px; line-height: 1.5; color: var(--pf-ink-2); margin: 0; }
@media (max-width: 960px) {
  .pf-usps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .pf-usps { grid-template-columns: 1fr; gap: 20px; margin-bottom: 56px; }
}

/* --- responsive --- */
@media (max-width: 960px) {
  .woocommerce.pf-products-shortcode ul.products.pf-grid:not(.elementor-grid),
  ul.products.pf-grid,
  body.woocommerce ul.products.pf-grid:not(.elementor-grid),
  body.woocommerce-page ul.products.pf-grid:not(.elementor-grid) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  /* One across below 600px. Two would give each card a ~150px text column, and
     these cards carry a description and a button — same reasoning as the dog
     cards stacking at 960px rather than core's 782px. */
  .woocommerce.pf-products-shortcode ul.products.pf-grid:not(.elementor-grid),
  ul.products.pf-grid,
  body.woocommerce ul.products.pf-grid:not(.elementor-grid),
  body.woocommerce-page ul.products.pf-grid:not(.elementor-grid) { grid-template-columns: 1fr; margin-bottom: 56px; }
  /* WRAPS here, does not scroll. The scrollable version read as broken and
     left the gutter behind (Tomek, 2026-08-22). [css-042] */
  .pf-catnav { padding: 30px 0 22px; gap: 8px; }
  .pf-chipnav { font-size: 13.5px; padding: 0 14px; }
  /* Same collapse as at desktop, tightened for the smaller screen. */
  .tax-product_cat .woocommerce-products-header,
  .tax-product_tag .woocommerce-products-header { padding: 24px 0 0; }
  .tax-product_cat .pf-catnav,
  .tax-product_tag .pf-catnav { padding-top: 16px; }
}

/* ==========================================================================
   3f. Strona produktu (WooCommerce single product, mockups 05a-c)
   ========================================================================== */

/* The single product page has no `.entry-content` wrapper, so no §2 gutter
   reset and no `.entry-content hN` rule reaches it. gotchas 28, 45 [css-043] */
.single-product .ast-woocommerce-container {
  max-width: 1200px; margin-inline: auto; padding-top: 30px;
}
body.woocommerce div.product.pf-p {
  /* The hero-band wash, per shelf accent (Tomek, 2026-08-29). Unsupported
     color-mix degrades to no band — cream page, nothing broken. */
  --pf-p-band: color-mix(in srgb, var(--pf-terra) 9%, var(--pf-bg));
  display: grid;
  grid-template-columns: minmax(0, 46fr) minmax(0, 54fr);
  gap: 20px 52px;
  /* center, not start: the hero photo and the copy column share the band's
     vertical middle, like .pf-artband. Sections span the full row, so this
     is a no-op for them. */
  align-items: center;
  position: relative;
}
body.woocommerce div.product.pf-acc-navy  { --pf-p-band: color-mix(in srgb, var(--pf-navy) 7%, var(--pf-bg)); }
body.woocommerce div.product.pf-acc-olive { --pf-p-band: color-mix(in srgb, var(--pf-olive) 10%, var(--pf-bg)); }
/* The full-bleed band behind the media+summary row. Absolute, so not a grid
   item (gotcha 55) — and placed, so its containing block is row 1's grid area
   and the band's height tracks the taller column. Side insets escape the
   1200px container the .pf-artband way; the top one swallows the 30px pad. */
body.woocommerce div.product.pf-p::before {
  content: ""; grid-area: 1 / 1 / 2 / -1;
  position: absolute; inset: -30px calc(50% - 50vw) -52px;
  pointer-events: none;
  background: linear-gradient(180deg, var(--pf-p-band) 0%, var(--pf-p-band) 78%, transparent 100%);
}
body.woocommerce div.product.pf-p > .pf-p-media,
body.woocommerce div.product.pf-p > div.summary {
  float: none; margin: 0;
  /* Above the band ::before, which is a positioned sibling. */
  position: relative; z-index: 1;
}
/* Top-right of the band, where the summary column's ragged right leaves cream.
   Hidden below 960 with every other .pf-bgart. */
.pf-bgart--phero {
  right: calc(50% - 50vw + 28px); top: -8px;
  width: 200px; height: 300px; transform: rotate(-166deg);
}
/* The summary width needs an id to win: Astra ships an `#content` selector
   at (1,4,2), so any number of classes loses. gotcha 36 [css-044] */
#content .ast-woocommerce-container div.product.pf-p > div.summary { width: auto; }

/* The boxed white panel that used to be here is gone a level up: the product
   page now carries `ast-plain-container` instead of `ast-separate-container`,
   set in functions.php's body_class filter — see the long note there for why
   two CSS overrides at this level lost. */
/* Sale badge. Nothing is on sale today, so this is here to stop the first
   discount from dropping Woo's raw yellow oval onto the pack shot. */
body.woocommerce div.product.pf-p > span.onsale {
  position: absolute; top: 14px; left: 14px; z-index: 3; margin: 0;
  min-height: 0; min-width: 0; padding: 5px 11px; border-radius: 8px;
  background: var(--pf-terra); color: #fff; line-height: 1.2;
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
/* Astra's "+ Free Shipping" — English, and it says nothing our own promise row
   does not say in Polish. Astra emits it inside the summary it renders (which we
   remove) AND inside the sticky bar (which we keep). */
.ast-shipping-text { display: none; }

/* --- the pack shot: the band's LEFT HALF, not a framed rectangle ---
   Mirror of .pf-artband: unframed, full row height, bleeding to the viewport's
   left edge, dissolving right and bottom into the wash via gradient masks
   (gotcha 101 is about url() masks; gradients render everywhere). The -30px
   top margin runs the photo flush to the header, like the band. [css-045] */
/* Fixed height, not the css-189 clamp: the photo is CONTENT-anchored (its
   bleed is capped below), so the 1280px proportions Tomek called perfect hold
   at every width — extra viewport goes to the side cream, not the band. */
.pf-p-media { position: relative; align-self: stretch; min-height: 580px; }
.pf-p-media > .pf-p-img { position: relative; z-index: 1; }
/* Fallback for a product with NO gallery: the old capped, framed pack shot —
   a 600px square blown to cover half a band would be mush. */
.pf-p-img { margin: 0; max-width: 440px; margin-inline: auto; }
.pf-p-img img {
  width: 100%; height: auto; display: block;
  border-radius: 24px 24px 24px 100px; box-shadow: var(--pf-shadow);
}
/* The lifestyle shot (gallery-first): unframed, absolute-filling the column
   plus the band's 30px top overhang, bleeding left — but at most 160px past
   the container, so above a 1520px viewport it stays glued to the copy at
   the 1280px spacing instead of drifting to the corner (Tomek, 2026-08-29). */
.pf-p-img--photo {
  position: absolute; max-width: none;
  inset: -30px 0 0 clamp(-160px, calc(600px - 50vw), 0px);
}
.pf-p-img--photo img {
  height: 100%; object-fit: cover; object-position: 40% center;
  border-radius: 0; box-shadow: none;
  /* Two layers INTERSECTED: right fade into the wash + a short bottom fade.
     Keep -webkit-/plain pairs 1:1 (browser-support table in css-and-astra). */
  -webkit-mask-image: linear-gradient(to right, #000 58%, transparent 99%),
                      linear-gradient(to top, transparent 0, #000 90px);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to right, #000 58%, transparent 99%),
                      linear-gradient(to top, transparent 0, #000 90px);
          mask-composite: intersect;
}
/* Above 1520px the capped bleed puts the photo's left edge ON-SCREEN (the cap
   and the viewport meet at exactly 1520): fade that edge into the wash too,
   and let a botanical take the opened left cream. */
.pf-bgart--phero-l { display: none; }
@media (min-width: 1521px) {
  .pf-p-img--photo img {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 110px, #000 58%, transparent 99%),
                        linear-gradient(to top, transparent 0, #000 90px);
            mask-image: linear-gradient(to right, transparent 0, #000 110px, #000 58%, transparent 99%),
                        linear-gradient(to top, transparent 0, #000 90px);
  }
  .pf-bgart--phero-l {
    display: block;
    left: calc(50% - 50vw + 40px); top: 56px;
    width: 210px; height: 320px; transform: rotate(10deg);
  }
}

/* --- summary column ---------------------------------------------------- */
/* Breathing room against the band's top and its bottom fade. */
body.woocommerce div.product.pf-p div.summary { padding-block: 30px 44px; }

.pf-p-crumbs {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  font-family: var(--pf-font-serif); font-size: 14px; font-style: italic;
  color: var(--pf-ink-2); margin-bottom: 10px;
}
.pf-p-crumbs a { color: inherit; text-decoration: none; }
.pf-p-crumbs a:hover { color: var(--pf-terra-dark); text-decoration: underline; }
.pf-p-crumbs span { opacity: .5; }

/* Sentence case, not the mockups' uppercase — see petfly_product_summary(). */
body.woocommerce div.product.pf-p h1.pf-p-title {
  font-size: clamp(34px, 4.6vw, 54px); line-height: 1.08; font-weight: 700;
  margin: 0 0 10px; padding: 0;
}
.pf-acc-terra h1.pf-p-title { color: var(--pf-terra-dark); }
.pf-acc-navy  h1.pf-p-title { color: var(--pf-navy); }
.pf-acc-olive h1.pf-p-title { color: var(--pf-olive-dark); }

/* Eyebrow ABOVE the h1 since 0.2.115 (mockups product1-3) — small caps in the
   shelf accent. One of the four uppercase treatments allowed by php-046's cap:
   the sub it replaces was sentence case, so the count holds at four. */
.pf-p-sub {
  display: flex; align-items: center; gap: 9px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--pf-ink-2); margin: 0 0 10px;
}
/* The mockups' small leaf flourish after the kicker — reuses .pf-i--leaf's
   mask var, hence the extra class on the pseudo's host below. */
.pf-p-sub::after {
  content: ""; width: 15px; height: 15px; flex: none; background: currentColor;
  opacity: .75;
  -webkit-mask: var(--pf-i) center / contain no-repeat;
          mask: var(--pf-i) center / contain no-repeat;
}
.pf-acc-terra .pf-p-sub { color: var(--pf-terra-dark); }
.pf-acc-navy  .pf-p-sub { color: var(--pf-navy); }
.pf-acc-olive .pf-p-sub { color: var(--pf-olive-dark); }
.pf-p-lead { color: var(--pf-ink-2); max-width: 52ch; font-size: 16.5px; }
.pf-p-lead p { margin-bottom: 0; }

/* Inline USP chips above the CTA (mockups product1-3). NO dividers: on a
   border-left chip every wrapped line opened with a stray tick + 20px indent
   (Tomek, 2026-08-29) — a bare gap survives any line break. */
.pf-p-usps {
  list-style: none; margin: 20px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 9px 22px;
}
.pf-p-usps li {
  display: inline-flex; align-items: center; gap: 8px; margin: 0;
  font-family: var(--pf-font-serif); font-size: 14.5px; font-weight: 600;
  color: var(--pf-ink);
}
.pf-p-usps .pf-i { color: var(--pf-terra); }
.pf-acc-navy  .pf-p-usps .pf-i { color: var(--pf-navy); }
.pf-acc-olive .pf-p-usps .pf-i { color: var(--pf-olive); }

/* --- purchase block ---
   OPEN on the band since 0.2.139 (Tomek's call): the bordered paper card read
   as cramped against the mockups' airy hero. Price row, then qty + the two
   buttons in one wrapping row. [css-046] */
.pf-p-buy {
  --pf-buy-h: 52px; /* one pinned height for stepper and both buttons */
  margin-top: 26px;
  display: flex; flex-wrap: wrap; align-items: center;
}
/* Secondary "Zobacz skład" — the mockups' outlined twin beside add-to-cart. */
.pf-p-ghost {
  flex: none; display: inline-flex; align-items: center;
  height: var(--pf-buy-h); margin: 0 0 0 12px; padding: 0 24px;
  border: 1.5px solid currentColor; border-radius: 14px;
  font-size: 15px; font-weight: 700; letter-spacing: .02em;
  color: var(--pf-terra-dark); text-decoration: none; transition: .15s;
}
.pf-acc-navy  .pf-p-ghost { color: var(--pf-navy); }
.pf-acc-olive .pf-p-ghost { color: var(--pf-olive-dark); }
.pf-p-ghost:hover { background: var(--pf-paper); }
/* The two-column band at 961-1240px: the summary column is too narrow for
   stepper + CTA + ghost on one line, so the ghost wrapped with its inline
   12px margin — off-grid and off-margin (Tomek, 2026-08-29). Give it the
   whole second row instead, same as the ≤600 stack. */
@media (min-width: 961px) and (max-width: 1240px) {
  .pf-p-ghost { flex: 1 1 100%; margin: 12px 0 0; justify-content: center; }
}
#sklad { scroll-margin-top: 24px; }
/* iOS Safari does not clip body overflow-x alone: the vw overhang desktop
   clips at Astra's `body{overflow-x:hidden}` widens an iPhone's canvas, so
   full-bleed blocks sit left with dead space at the right (Tomek's device).
   `clip`, not `hidden` — clip makes no scroll container. gotcha 104. */
html { overflow-x: clip; }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
.pf-p-buy-head {
  flex: 1 1 100%;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px 24px; flex-wrap: wrap; margin-bottom: 18px;
}
body.woocommerce div.product.pf-p p.price.pf-p-price {
  font-family: var(--pf-font-serif); font-size: clamp(28px, 3vw, 38px);
  font-weight: 700; margin: 0; color: var(--pf-ink);
}
/* The unit size, beside the price (mockups: "39,90 PLN / 150 g"). */
.pf-p-wt {
  font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600;
  color: var(--pf-ink-2); margin-right: auto;
}
.pf-acc-terra .pf-p-price { color: var(--pf-terra-dark); }
.pf-acc-navy  .pf-p-price { color: var(--pf-navy); }
.pf-acc-olive .pf-p-price { color: var(--pf-olive-dark); }
body.woocommerce div.product.pf-p p.price.pf-p-price del { font-size: 60%; opacity: .6; font-weight: 400; }
body.woocommerce div.product.pf-p p.price.pf-p-price ins { text-decoration: none; }

/* `flex:1` so this block owns the space right of the price. Shrink-wrapped
   it wrapped onto its own line and right-aligned inside a 171px box.
   [css-047] */
.pf-p-promise { flex: 1 1 auto; min-width: 0; text-align: right; }
.pf-p-price { flex: none; }
.pf-p-promise p { margin: 0; }
.pf-p-promise-1 {
  display: flex; align-items: center; justify-content: flex-end; gap: 7px;
  font-size: 14px; font-weight: 600; color: var(--pf-ink);
}
.pf-p-promise-1 .pf-i { color: var(--pf-olive); }
.pf-p-promise-2 { font-size: 13px; color: var(--pf-ink-2); margin-top: 3px; }

/* Inline with the stepper, not above the row. It is now the first flex item in
   form.cart (see the woocommerce_before_add_to_cart_quantity hook), so it labels
   the number beside it rather than appearing to label the whole row including
   the button. */
.pf-p-qtylabel {
  flex: none; align-self: center;
  font-size: 13px; font-weight: 600; color: var(--pf-ink-2);
  margin: 0; text-transform: none;
}
/* ONE pinned height for both controls: Astra's `line-height:1.6em` on bare
   `button` made it 67px against the stepper's 52px. [css-048] */
body.woocommerce div.product.pf-p form.cart {
  /* --pf-buy-h now lives on .pf-p-buy, shared with the ghost button. */
  /* `column-gap:0` plus explicit margins, not `gap`: Woo's template whitespace
     becomes an anonymous flex item that still takes a gap. gotcha 34 [css-049] */
  display: flex; align-items: center; column-gap: 0; row-gap: 12px; margin: 0;
  flex: 1 1 auto; min-width: 0;
}
body.woocommerce div.product.pf-p form.cart > .pf-p-qtylabel { margin-right: 12px; }
/* Woo hides its own quantity label visually; ours is the visible one above. */
body.woocommerce div.product.pf-p form.cart .quantity {
  /* `margin:0` clears the right AND bottom margin Woo's own external
     stylesheet puts on `div.quantity`. gotcha 31 [css-050] */
  /* The 12px right margin IS the gap to the button, because the form runs
     `column-gap:0`. It has to stay in this rule. [css-051] */
  display: inline-flex; align-items: stretch; flex: none; margin: 0 12px 0 0;
  height: var(--pf-buy-h);
  border: 1px solid var(--pf-line); border-radius: 14px;
  /* Paper, not cream: the block sits on the tinted band now. */
  background: var(--pf-paper); overflow: hidden;
}
body.woocommerce div.product.pf-p form.cart .quantity input.qty {
  width: 46px; height: 100%; padding: 0; margin: 0; text-align: center;
  border: 0; background: transparent; box-shadow: none;
  font-family: 'Inter', system-ui, sans-serif; font-size: 16px; font-weight: 700;
  color: var(--pf-ink);
}
body.woocommerce div.product.pf-p form.cart .quantity input.qty:focus-visible {
  outline: 2px solid var(--pf-terra); outline-offset: -2px;
}
.pf-qty-btn {
  width: 42px; height: 100%; flex: none; padding: 0;
  border: 0; background: transparent; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--pf-ink-2); transition: .15s;
}
.pf-qty-btn:hover { background: var(--pf-bg-alt); color: var(--pf-terra-dark); }
.pf-qty-btn:focus-visible { outline: 2px solid var(--pf-terra); outline-offset: -2px; }
/* Native spinners only disappear once JS has actually added the buttons —
   otherwise a no-JS visitor would be left with no way to change the number
   except typing. product.js adds .pf-qty. */
.pf-qty input.qty { -moz-appearance: textfield; appearance: textfield; }
.pf-qty input.qty::-webkit-outer-spin-button,
.pf-qty input.qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* Astra styles `button.button.alt` from its Customizer, including the `text-
   transform:capitalize` that broke the label. gotcha 23 [css-052] */
body.woocommerce div.product.pf-p form.cart button.single_add_to_cart_button {
  flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  /* width: auto beats Astra's `.woocommerce div.product form.cart
     .button.single_add_to_cart_button { width: 50% }` (0,5,2) — harmless while
     flex-grow happens to fill the row, but it makes flex-basis 50% of the form,
     so the button's size depended on a number Astra picked. */
  height: var(--pf-buy-h); min-height: 0; padding: 0 26px; margin: 0; width: auto;
  border: 2px solid transparent; border-radius: 14px;
  font-family: 'Inter', system-ui, sans-serif; font-size: 16px; font-weight: 700;
  text-transform: none; letter-spacing: 0; line-height: 1.2;
  background: var(--pf-terra); color: #fff; box-shadow: var(--pf-shadow);
  transition: .15s;
}
body.woocommerce div.product.pf-p form.cart button.single_add_to_cart_button::after {
  content: ""; width: 25px; height: 25px; flex: none;
  background: currentColor;
  -webkit-mask: var(--pf-mask-hbowl) center / contain no-repeat;
          mask: var(--pf-mask-hbowl) center / contain no-repeat;
}
body.woocommerce div.product.pf-p form.cart button.single_add_to_cart_button:hover { background: var(--pf-terra-dark); }
body.woocommerce div.product.pf-acc-navy form.cart button.single_add_to_cart_button { background: var(--pf-navy); }
body.woocommerce div.product.pf-acc-navy form.cart button.single_add_to_cart_button:hover { background: var(--pf-navy-dark); }
body.woocommerce div.product.pf-acc-olive form.cart button.single_add_to_cart_button { background: var(--pf-olive); }
body.woocommerce div.product.pf-acc-olive form.cart button.single_add_to_cart_button:hover { background: var(--pf-olive-dark); }
/* Same trap as the archive button (gotcha 14/23): the ring Astra leaves is a
   dotted BORDER, so `outline: none` does nothing and the 2px transparent border
   above is what keeps the button from resizing when it gains one. */
body.woocommerce div.product.pf-p form.cart button.single_add_to_cart_button:focus { border-color: transparent; outline: none; }
body.woocommerce div.product.pf-p form.cart button.single_add_to_cart_button:focus-visible { outline: 2px solid var(--pf-terra-dark); outline-offset: 3px; }

/* --- meta strip (składniki / pochodzenie) ------------------------------- */
/* Centred under the buy row (Tomek, 2026-08-29 — reverses css-053's left
   alignment): the full-width CTA above gives the strip a centred axis. */
.pf-p-mrow {
  list-style: none; margin: 20px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 10px 22px;
}
.pf-p-mrow li {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 14px; font-weight: 600; color: var(--pf-ink);
  margin: 0;
}
.pf-p-mrow li + li { border-left: 1px solid var(--pf-line); padding-left: 22px; }
.pf-p-mrow .pf-i { color: var(--pf-terra); }
.pf-acc-navy  .pf-p-mrow .pf-i { color: var(--pf-navy); }
.pf-acc-olive .pf-p-mrow .pf-i { color: var(--pf-olive); }

/* --- sections below the two columns ------------------------------------ */
/* `position: relative` + the z-index sibling rule are what let a section hold a
   botanical. Same shape as `.pf-rel` in §2 but WITHOUT its `overflow: hidden`,
   which would clip the section's own shadows — so every placement below has to
   be inset rather than hung off an edge. */
.pf-p-sec { grid-column: 1 / -1; padding-block: 68px 0; position: relative; }
.pf-p-sec > :not(.pf-bgart) { position: relative; z-index: 1; }
/* Inset beside the section heads, never negative, bleeding down behind the
   opaque cards. Sides alternate. gotcha 35 [css-054] */
.pf-bgart--psec-l { left: 20px;  top: 26px; width: 200px; height: 300px; transform: rotate(14deg); }
.pf-bgart--psec-r { right: 16px; top: 12px; width: 190px; height: 285px; transform: rotate(-158deg); }
.pf-p-sec:last-child { padding-bottom: 72px; }
.pf-p-sec .pf-sec-head { margin-bottom: 34px; }

/* "Dlaczego warto?" — auto-fit so that four cards (05a) and five (05b, 05c)
   both fill the measure without a per-product column count. */
.pf-p-why-grid {
  width: min(1180px, 100%); margin-inline: auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 20px;
}
/* Shared grid rows are the only thing that aligns body copy across sibling
   cards. gotcha 32 [css-055] */
@media (min-width: 1100px) {
  .pf-p-why-grid { grid-template-rows: auto auto 1fr; row-gap: 12px; column-gap: 20px; }
  .pf-p-why-grid.pf-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pf-p-why-grid.pf-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pf-p-why-grid.pf-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .pf-p-why-grid.pf-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .pf-p-why-grid.pf-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .pf-p-why-grid .pf-pcard {
    /* justify-items must be stretch (the default), not start: shrink-wrapped
       children cannot centre their own text inside the card. */
    display: grid; grid-row: span 3; grid-template-rows: subgrid; gap: 0;
  }
}
/* OPEN since 0.2.141 — no paper, no border: the row reads like the homepage's
   "Manufaktura" icon row, not a card wall (Tomek: too many closed boxes).
   Icon and heading centred, body copy left — gotcha 12's convention. [css-056] */
.pf-pcard {
  padding: 6px 10px; height: 100%;
  display: flex; flex-direction: column; align-items: stretch; gap: 12px;
}
.pf-pcard-i { display: flex; justify-content: center; }
/* Accent-wash disc under the icon — warmth without a border. :has(), so a
   card with no icon chosen shows nothing rather than an empty disc; without
   :has() support there is simply no disc. */
.pf-pcard-i:has(.pf-i) {
  width: 58px; height: 58px; margin-inline: auto;
  align-items: center; border-radius: 50%;
  background: var(--pf-p-band, var(--pf-bg-alt));
}
/* Centred body copy too (Tomek, 2026-08-29) — these open rows are short
   two-liners under a centred icon+heading, not gotcha 12's stacked cards. */
.pf-pcard h3 { text-align: center; }
.pf-pcard p { text-align: center; }
.pf-pcard .pf-i { color: var(--pf-terra); }
.pf-acc-navy  .pf-pcard .pf-i { color: var(--pf-navy); }
.pf-acc-olive .pf-pcard .pf-i { color: var(--pf-olive); }
.pf-pcard h3 { font-size: 17px; line-height: 1.3; margin: 0; }
.pf-pcard p { font-size: 13.5px; color: var(--pf-ink-2); margin: 0; }
.pf-p-note {
  width: min(1180px, 100%); margin: 18px auto 0;
  text-align: center; font-size: 12.5px; color: var(--pf-ink-2);
}

/* Four OPEN columns since 0.2.144 (Tomek: even soft paper read as boxes) —
   no paper, no shadow, hairline separators only: vertical between columns
   here, horizontal between stacked rows ≤960. [css-057] */
.pf-p-facts-card {
  width: min(1180px, 100%); margin-inline: auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(225px, 1fr)); gap: 0;
}
.pf-p-panel { min-width: 0; padding: 2px 26px; }
.pf-p-panel:first-child { padding-left: 0; }
.pf-p-panel:last-child { padding-right: 0; }
.pf-p-panel + .pf-p-panel { border-left: 1px solid var(--pf-line); }
/* Transparent panels can no longer hide the section botanical that used to
   tuck under the paper — it would sit behind the last column's text. */
.pf-p-facts .pf-bgart { display: none; }
/* Serif sentence case, not 12px caps — the caps cut (Tomek, 2026-08-29). */
.pf-p-panel > summary {
  list-style: none; cursor: default;
  display: flex; align-items: center; gap: 9px;
  font-family: var(--pf-font-serif); font-size: 18px; font-weight: 700;
  color: var(--pf-ink); margin-bottom: 12px;
}
.pf-p-panel > summary::-webkit-details-marker { display: none; }
.pf-p-panel > summary::marker { content: ""; }
.pf-p-panel-t { display: inline-flex; align-items: center; gap: 9px; }
/* Accent overrides on the two icon rows that only had the terra base — on a
   navy page they read as a mismatch (Tomek, 2026-08-29). */
.pf-p-panel .pf-i { color: var(--pf-terra); }
.pf-acc-navy  .pf-p-panel .pf-i { color: var(--pf-navy); }
.pf-acc-olive .pf-p-panel .pf-i { color: var(--pf-olive); }
.pf-p-panel-b p { font-size: 13.5px; color: var(--pf-ink-2); margin: 0 0 9px; }
.pf-p-panel-b p:last-child { margin-bottom: 0; }

/* Dotted leaders are real markup, so they stretch to whatever gap the two
   strings leave. [css-058] */
.pf-p-an { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.pf-p-an li { display: flex; align-items: flex-end; gap: 6px; margin: 0; font-size: 13.5px; }
.pf-p-an-n { color: var(--pf-ink-2); }
.pf-p-an-d { flex: 1 1 auto; min-width: 10px; border-bottom: 1px dotted var(--pf-line); margin-bottom: 5px; }
.pf-p-an-v { flex: none; font-weight: 700; color: var(--pf-ink); }

/* Dosage table. Wrapped in its own scroller: at 400px a two-column table of
   Polish weight ranges is close to the measure, and a table is the one thing on
   this page allowed to scroll rather than wrap. */
/* `table-layout: fixed` is what removes the horizontal scrollbar: auto
   layout sized the table to its longest cell. [css-059] */
/* NO scroll container: `overflow-x:auto` painted a bar for one rounded-up
   pixel. gotcha 33 [css-060] */
.pf-p-tblwrap { margin-bottom: 12px; }
/* De-bulked 0.2.144 (Tomek): horizontal hairlines only — no outer border, no
   column rules — and the header drops the solid accent slab + caps for the
   band wash (--pf-p-band inherits from div.product) under an accent rule. */
/* `border: 0` on the TABLE too: Astra borders the table element itself, so
   clearing only th/td left a top+left outer edge (Tomek; gotcha 53 shape). */
.pf-p-tbl { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 12.5px; border: 0; }
.pf-p-tbl th, .pf-p-tbl td {
  padding: 7px 10px; text-align: left; border: 0;
  border-bottom: 1px solid var(--pf-line); overflow-wrap: break-word;
}
.pf-p-tbl thead th {
  background: var(--pf-p-band, var(--pf-bg-alt)); color: var(--pf-ink);
  font-family: var(--pf-font-serif); font-weight: 700; font-size: 13.5px;
  border-bottom: 1.5px solid var(--pf-terra);
}
.pf-acc-navy  .pf-p-tbl thead th { border-color: var(--pf-navy); }
.pf-acc-olive .pf-p-tbl thead th { border-color: var(--pf-olive); }
.pf-p-tbl tbody tr:last-child td { border-bottom: 0; }
.pf-p-tbl td { color: var(--pf-ink-2); }

/* "W roli głównej" — the one free-prose block, and the one that overlaps
   /odkrywaj/. Kept short and ended with a link there on purpose. */
.pf-p-star-card {
  padding-block: 26px 30px;
  display: grid; grid-template-columns: 220px minmax(0, 1fr) 260px;
  gap: 24px 34px; align-items: center;
}
.pf-p-star-img img {
  width: 100%; height: auto; display: block; object-fit: contain;
  filter: drop-shadow(0 18px 24px rgba(88, 60, 32, .22));
}
/* Ink heading, handwritten accent star: "W roli głównej:" stays black, the
   part after the colon gets the homepage script face in the shelf accent
   (Tomek, 2026-08-29). The span is emitted by petfly_product_star(). */
.pf-p-star-text h2 { font-size: clamp(24px, 2.6vw, 30px); margin: 0 0 12px; color: var(--pf-ink); }
.pf-p-star-script {
  font-family: 'Vujahday Script', Georgia, serif;
  font-weight: 400; font-size: 1.6em; line-height: .9;
}
.pf-acc-terra .pf-p-star-script { color: var(--pf-terra); }
.pf-acc-navy  .pf-p-star-script { color: var(--pf-navy); }
.pf-acc-olive .pf-p-star-script { color: var(--pf-olive-dark); }
.pf-p-star-text p { font-size: 14.5px; color: var(--pf-ink-2); margin: 0 0 10px; }
.pf-p-star-more { margin-top: 14px !important; }
.pf-p-star-more a {
  font-size: 14px; font-weight: 700; color: var(--pf-terra-dark);
  text-decoration: none; border-bottom: 1.5px solid var(--pf-gold); padding-bottom: 2px;
}
.pf-p-star-more a:hover { color: var(--pf-ink); border-color: var(--pf-terra); }
/* A ticked LIST, not three boxes: bordered cards beside a real link taught
   the eye that a box here is clickable (Tomek). [css-061] */
.pf-p-star-chips { display: grid; grid-template-columns: minmax(0, 1fr); gap: 9px; align-content: center; }
.pf-p-star-chip {
  position: relative; padding-left: 27px; text-align: left;
  font-family: var(--pf-font-serif); font-size: 14px; font-weight: 600; line-height: 1.35;
  color: var(--pf-ink); overflow-wrap: break-word;
}
.pf-p-star-chip::before {
  content: ""; position: absolute; left: 0; top: 2px; width: 18px; height: 18px;
  background: var(--pf-olive);
  -webkit-mask: var(--pf-mask-check) center / contain no-repeat;
          mask: var(--pf-mask-check) center / contain no-repeat;
}

/* --- closing banner + trust row (mockups product1-3) -------------------- */
.pf-p-banner {
  width: min(920px, 100%); margin-inline: auto;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  background: var(--pf-paper); border: 1px solid var(--pf-line); border-radius: 999px;
  padding: 18px 34px;
  /* Serif again — the 0.2.144 handwritten try lacked legibility at a full
     sentence (Tomek). The script face lives in .pf-p-star-script instead. */
  font-family: var(--pf-font-serif); font-size: clamp(15px, 1.6vw, 19px);
  font-weight: 600; color: var(--pf-ink); text-align: center;
}
.pf-p-banner .pf-i { color: var(--pf-terra); }
.pf-acc-navy  .pf-p-banner .pf-i { color: var(--pf-navy); }
.pf-acc-olive .pf-p-banner .pf-i { color: var(--pf-olive); }
/* The strip is the shop page's .pf-usps verbatim; only the shop-archive
   margins (-18px pull-up, 72px tail) are not wanted here. */
.pf-p-trust .pf-usps { margin: 0 auto; }

/* Related products reuse §3e via the `.woocommerce.pf-products-shortcode`
   wrapper, so these cards cannot drift from the shop's. Only the trailing
   margin differs. [css-062] */
/* Five classes, not two: §3e's grid rule is (0,4,2) and a plain `.pf-p-
   related .pf-grid` (0,2,0) loses to it silently. [css-063] */
body.woocommerce .pf-p-related ul.products.pf-grid:not(.elementor-grid) { margin-bottom: 0; }

/* --- Astra's sticky add-to-cart bar ---
   Astra's sticky add-to-cart bar is KEPT — on a page this long it brings the
   buy button back — but it ships in Astra's colours and needs restyling.
   [css-064] */
body div.ast-sticky-add-to-cart {
  background: var(--pf-paper); border-top: 1px solid var(--pf-line);
  box-shadow: 0 -8px 24px -12px rgba(88, 60, 32, .28);
}
body div.ast-sticky-add-to-cart .ast-sticky-add-to-cart-title {
  font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600; color: var(--pf-ink);
}
body div.ast-sticky-add-to-cart .ast-sticky-add-to-cart-title-wrap > img {
  border-radius: 10px; border: 1px solid var(--pf-line);
}
body div.ast-sticky-add-to-cart .ast-sticky-add-to-cart-action-price {
  font-family: var(--pf-font-serif); font-size: 19px; font-weight: 700; color: var(--pf-ink);
}
body div.ast-sticky-add-to-cart form.cart { display: flex; align-items: stretch; gap: 10px; }
/* The "Ilość" label is hooked into every cart form, which includes the sticky
   bar's. It is noise in a compact bar that already shows the product name and
   price, so it only shows in the purchase card. */
body div.ast-sticky-add-to-cart .pf-p-qtylabel { display: none; }
body div.ast-sticky-add-to-cart form.cart .quantity {
  display: inline-flex; align-items: center; flex: none;
  border: 1px solid var(--pf-line); border-radius: 12px; background: var(--pf-bg); overflow: hidden;
}
body div.ast-sticky-add-to-cart form.cart .quantity input.qty {
  width: 54px; height: 44px; padding: 0; border: 0; background: transparent;
  text-align: center; font-weight: 700; color: var(--pf-ink); box-shadow: none;
  /* 16px is the iOS zoom floor, and this rule set weight and colour but never
     size, so it inherited Astra's 13.68px. Found by tools/qa-mobile-
     hazards.py. gotcha 54 [css-065] */
  font-size: 16px;
}
body div.ast-sticky-add-to-cart button.single_add_to_cart_button {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 44px; padding: 10px 22px; margin: 0;
  border: 2px solid transparent; border-radius: 12px;
  font-family: 'Inter', system-ui, sans-serif; font-size: 15px; font-weight: 700;
  text-transform: none; background: var(--pf-terra); color: #fff;
}
body div.ast-sticky-add-to-cart button.single_add_to_cart_button:hover { background: var(--pf-terra-dark); }
body.pf-acc-navy div.ast-sticky-add-to-cart button.single_add_to_cart_button { background: var(--pf-navy); }
body.pf-acc-olive div.ast-sticky-add-to-cart button.single_add_to_cart_button { background: var(--pf-olive); }

/* --- responsive -------------------------------------------------------- */
@media (max-width: 960px) {
  /* Pack shot first, deliberately against the "headline before image" hero
     convention: on a product page the photo is how a shopper confirms the bag.
     [css-066] */
  body.woocommerce div.product.pf-p { grid-template-columns: minmax(0, 1fr); gap: 0; }
  /* One column now: the band must cover BOTH stacked rows (media, summary). */
  body.woocommerce div.product.pf-p::before { grid-area: 1 / 1 / 3 / -1; }
  /* Fallback figure ONLY. Unscoped, this cap also binds --photo: same 0-1-0
     specificity as its `max-width: none` but later in the sheet, so it wins
     per-property — the ≤600 twin of this rule is what held the hero band at
     350px on Tomek's 390px phone (0.2.152 misread that as an auto-width bug). */
  .pf-p-img:not(.pf-p-img--photo) { max-width: 420px; }
  /* Stacked: the photo turns into a full-bleed top band (mirror of
     .pf-artband's mobile state) — back in flow, viewport-wide, capped height,
     bottom fade only. */
  .pf-p-media { min-height: 0; }
  /* Auto width between two viewport-reaching negative margins = full-bleed.
     No `position`: css-045's `.pf-p-media > .pf-p-img` (0-2-0) keeps the figure
     `relative` at every width anyway; `inset: auto` neutralises the desktop
     offsets, which relative would otherwise still apply. */
  .pf-p-img--photo { inset: auto; margin: -30px calc(50% - 50vw) 0; }
  /* Taller band, crop anchored on the SUBJECT: `center 30%` showed the photo's
     empty right half and cut the bowl off the bottom (Tomek, 2026-08-29). The
     bag sits left of centre in all three lifestyle shots, so 38% biases the
     crop onto it and 45% keeps the props below in frame. */
  .pf-p-img--photo img {
    height: min(84vw, 540px); width: 100%; object-position: 38% 45%;
    -webkit-mask-image: linear-gradient(to top, transparent 0, #000 70px);
    -webkit-mask-composite: source-over;
            mask-image: linear-gradient(to top, transparent 0, #000 70px);
            mask-composite: add;
  }
  body.woocommerce div.product.pf-p div.summary { padding-block: 10px 40px; }

  /* One stacked column with HORIZONTAL hairlines — the vertical desktop
     separators cannot survive auto-fit wrapping (a row-2 column-1 panel would
     still carry a border-left). */
  .pf-p-facts-card { grid-template-columns: 1fr; }
  .pf-p-panel { padding: 20px 0; }
  .pf-p-panel:first-child { padding-top: 0; }
  .pf-p-panel + .pf-p-panel { border-left: 0; border-top: 1px solid var(--pf-line); }

  .pf-p-star-card { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .pf-p-star-img { max-width: 260px; margin-inline: auto; }
  /* Stacked in one column at desktop; across the full width once the card is a
     single column there is room for three again. */
  /* Once the card is a single column there is room to run the ticked points
     across it instead of down a narrow rail. */
  .pf-p-star-chips { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
}

@media (max-width: 600px) {
  .single-product .ast-woocommerce-container { padding-top: 20px; }
  .pf-p-sec { padding-block: 44px 0; }
  .pf-p-sec:last-child { padding-bottom: 56px; }
  .pf-p-sec .pf-sec-head { margin-bottom: 26px; }
  /* Fallback figure only (the :not() matters — see the ≤960 cap's comment);
     the --photo hero band stays unframed and full-bleed. */
  .pf-p-img:not(.pf-p-img--photo) { max-width: 100%; }
  .pf-p-img:not(.pf-p-img--photo) img { border-radius: 20px 20px 20px 72px; }
  .pf-p-img--photo img { height: min(96vw, 440px); }

  /* ONE axis for the whole buy block — centred (Tomek, 2026-08-29: price left
     + promises right + stepper left + centred buttons read as chaos; this
     supersedes css-067's left/right split). The full-width CTAs already set a
     centred axis, so everything above them joins it. */
  .pf-p-buy-head { gap: 8px 14px; justify-content: center; margin-bottom: 14px; }
  .pf-p-wt { margin-right: 0; }
  .pf-p-promise { flex: 1 1 100%; text-align: center; }
  .pf-p-promise-1 { justify-content: center; }
  body.woocommerce div.product.pf-p form.cart { flex-wrap: wrap; justify-content: center; }
  /* Full-width button under the stepper: at 345px the two side by side left the
     button ~200px wide for a 13-character label plus its paw icon. */
  body.woocommerce div.product.pf-p form.cart button.single_add_to_cart_button { flex: 1 1 100%; }
  /* The ghost stacks full-width under the filled button. */
  .pf-p-ghost { flex: 1 1 100%; justify-content: center; margin: 12px 0 0; }

  /* The base rule centres the strip; stacked items centre themselves too. */
  .pf-p-mrow { gap: 9px 18px; }
  .pf-p-mrow li + li { border-left: 0; padding-left: 0; }
  .pf-p-mrow li { flex: 1 1 100%; justify-content: center; }

  .pf-p-banner { border-radius: 24px; padding: 15px 22px; flex-wrap: wrap; }

  .pf-p-why-grid { grid-template-columns: 1fr; gap: 22px; }
  .pf-pcard { padding: 0; }

  /* Accordions. product.js closes all but the first below this width — see the
     comment on petfly_product_panel() for why they ship open. The chevron only
     appears here, because this is the only width where they toggle. Boxless:
     the ≤960 horizontal hairlines are the only chrome. */
  .pf-p-panel { padding: 2px 0; }
  .pf-p-panel > summary {
    cursor: pointer; justify-content: space-between; min-height: 48px;
    margin-bottom: 0; padding: 6px 0;
  }
  .pf-p-panel > summary::after {
    content: ""; width: 16px; height: 16px; flex: none; background: var(--pf-terra);
    -webkit-mask: var(--pf-mask-chev) center / contain no-repeat;
            mask: var(--pf-mask-chev) center / contain no-repeat;
    transition: transform .18s;
  }
  .pf-p-panel[open] > summary::after { transform: rotate(180deg); }
  .pf-p-panel-b { padding: 2px 0 16px; }

  .pf-p-star-card { padding-block: 22px 26px; }
  .pf-p-star-chips { grid-template-columns: 1fr; gap: 8px; }
}

/* ==========================================================================
   3g. Ścieżka zakupowa — koszyk, zamówienie, podziękowanie (+ moje konto)
   READ FIRST: the competition is ASTRA, not Woo. Astra substitutes its own Woo
   CSS from external `*-grid.min.css` files, so an inline-CSS dump is blind to
   it. Our sheet loads last, so equal specificity wins. gotchas 31, 36 [css-069]
   ========================================================================== */

/* --- 3g.-1 THE SHARED GEOMETRY OF THE FLOW ---
   The cart and the checkout are two views of ONE panel layout. These shared
   tokens are what stop them drifting apart again (they had: rail 360 vs 380,
   gap 40 vs 44). [css-070] */
body.pf-flow {
  --pf-flow-rail: 380px;   /* the sticky summary column */
  --pf-flow-gap: 44px;     /* between the working column and the rail */
  --pf-flow-card-pad: 22px;
  --pf-flow-card-r: 20px;
  --pf-flow-sticky-top: 24px;
  --pf-flow-cta-h: 58px;
  --pf-flow-cta-fs: 16.5px;
  --pf-flow-cta-pad: 26px;
}

/* --- 3g.0 WooCommerce's clearfix vs every grid in this section ---
   READ BEFORE ADDING `display:grid` TO ANY WOO WRAPPER: Woo's clearfix
   `::before`/`::after` become grid items and shift the whole grid. gotcha 37
   [css-071] */
body.pf-flow .woocommerce .col2-set::before,
body.pf-flow .woocommerce .col2-set::after,
body.pf-flow .woocommerce .cart-collaterals::before,
body.pf-flow .woocommerce .cart-collaterals::after,
body.pf-flow .woocommerce .woocommerce-billing-fields::before,
body.pf-flow .woocommerce .woocommerce-billing-fields::after,
body.pf-flow .woocommerce .woocommerce-shipping-fields::before,
body.pf-flow .woocommerce .woocommerce-shipping-fields::after,
body.pf-flow .woocommerce ul.woocommerce-order-overview::before,
body.pf-flow .woocommerce ul.woocommerce-order-overview::after,
body.pf-flow .woocommerce .woocommerce-columns::before,
body.pf-flow .woocommerce .woocommerce-columns::after,
body.pf-flow .woocommerce .woocommerce-Addresses::before,
body.pf-flow .woocommerce .woocommerce-Addresses::after,
body.pf-flow.woocommerce-account .woocommerce::before,
body.pf-flow.woocommerce-account .woocommerce::after {
  content: none;
}

/* --- 3g.1 the page, and the head we print ourselves ---------------------- */

/* Astra's `.entry-header` is suppressed by a filter (see petfly_flow_step) but
   keep the class hook: Astra has more than one route to that markup depending on
   layout, and a stray h1 above ours would be both a duplicate h1 and a visible
   double heading. */
body.pf-flow .pf-flow-astra-header { display: none; }

/* Astra caps the boxed container with padding, not a width, so the content
   needs its own measure. 1180px is the site-wide one. [css-072] */
body.pf-flow .entry-content > .woocommerce,
body.pf-flow .entry-content > .pf-flow-head,
/* My-account keeps Astra's header, so its `h1` sits outside `.entry-content
   > .woocommerce` and needs the measure applied separately. [css-073] */
body.pf-flow .entry-header {
  width: min(1180px, 100%); margin-inline: auto;
}
/* The kicker used to supply this air and is gone, so 8px left the first
   element — often a tinted notice — too close under the site header.
   [css-074] */
body.pf-flow.pf-flow #primary { padding-block: 24px 72px; }
body.pf-flow .entry-header { margin-bottom: 8px; }
/* My-account opens with a bare h1 and keeps Astra's header, so it wants more. */
body.woocommerce-account.pf-flow.pf-flow #primary { padding-block: 40px 72px; }

/* `min-height` exists to give the botanical room, and that is a real constraint
   rather than padding for its own sake — see .pf-bgart--flow below. The head is
   three short lines plus the step pills, so without it the box is ~150px and the
   art has nowhere to go. */
.pf-flow-head { margin-bottom: 30px; padding-top: 6px; }
@media (min-width: 961px) { .pf-flow-head { min-height: 196px; } }
/* `.entry-content h1` is 0-1-1 in Astra's dynamic CSS (gotcha 3), so the bare
   class would lose the font-size. */
body.pf-flow .entry-content h1.pf-flow-title {
  font-size: clamp(30px, 3.6vw, 42px); line-height: 1.15;
  margin: 0 0 10px; color: var(--pf-ink);
}
/* Scoped under the parent, not bare: Astra's `.entry-content p` carries
   `margin-bottom: 1.6em` at 0-1-1 and beats any single-class paragraph rule
   (gotcha 20). */
.pf-flow-head .pf-flow-lead {
  font-size: 16.5px; color: var(--pf-ink-2); margin: 0 0 22px; max-width: 46ch;
}
.pf-flow-head .pf-kicker { margin-bottom: 10px; }

/* A real `<ol>` with `aria-current="step"`. Named `pf-flow-step*`, not `pf-
   step*`, to avoid a collision. gotcha 42 [css-075] */
.pf-flow-steps {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; justify-content: flex-start;
  flex-wrap: wrap; gap: 10px 0;
}
.pf-flow-step {
  display: flex; align-items: center; gap: 9px; flex: none;
  font-size: 13.5px; font-weight: 600; color: var(--pf-ink-2);
}
/* The connector. A pseudo-element on the item rather than a border on a
   wrapper, so it can sit between the pills and still disappear when the row
   wraps to one item per line on a phone. */
.pf-flow-step + .pf-flow-step::before {
  content: ""; width: clamp(16px, 4vw, 46px); height: 1.5px; flex: none;
  margin: 0 12px 0 2px; background: var(--pf-line);
}
.pf-flow-step-n {
  width: 28px; height: 28px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums;
  border: 1.5px solid var(--pf-line); background: var(--pf-paper); color: var(--pf-ink-2);
}
.pf-flow-step.is-now { color: var(--pf-ink); }
.pf-flow-step.is-now .pf-flow-step-n {
  background: var(--pf-terra); border-color: var(--pf-terra); color: #fff;
}
.pf-flow-step.is-done { color: var(--pf-ink-2); }
.pf-flow-step.is-done .pf-flow-step-n {
  background: var(--pf-olive); border-color: var(--pf-olive); color: transparent;
  position: relative;
}
/* The tick replaces the digit rather than hiding it: the digit stays in the DOM
   (and stays aria-hidden), so nothing about the list's semantics changes. */
.pf-flow-step.is-done .pf-flow-step-n::after {
  content: ""; position: absolute; inset: 6px; background: #fff;
  -webkit-mask: var(--pf-mask-check) center / contain no-repeat;
          mask: var(--pf-mask-check) center / contain no-repeat;
}
/* --pf-ink-2, not the old #9d8d7a: that grey was 2.94:1 on the cream and failed
   the 3:1 floor for meaningful UI text on a checkout the EAA covers. [css-196] */
.pf-flow-step.is-next { color: var(--pf-ink-2); }

/* The botanical MUST FIT INSIDE the head; `.pf-flow-head` does clip, via
   `pf-rel` on the same element. gotcha 35 [css-076] */
.pf-bgart--flow { right: 40px; top: 0; width: 128px; height: 192px; transform: rotate(-158deg); }

/* --- 3g.2 buttons ---
   Astra styles every Woo button from its Customizer — 'Lexend Deca',
   `capitalize`, square corners, and #B25518, which is not our terracotta.
   gotcha 23 [css-077] */
body.pf-flow .woocommerce a.button,
body.pf-flow .woocommerce button.button,
body.pf-flow .woocommerce input.button,
body.pf-flow .woocommerce button.button.alt,
body.pf-flow .woocommerce input.button.alt,
body.pf-flow .woocommerce a.button.alt {
  --pf-buy-h: 52px;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: var(--pf-buy-h); width: auto; padding: 0 26px;
  border: 2px solid transparent; border-radius: 14px;
  background: var(--pf-terra); color: #fff;
  font-family: 'Inter', system-ui, sans-serif; font-size: 15px; font-weight: 600;
  line-height: 1.2; letter-spacing: .01em; text-transform: none; text-decoration: none;
  transition: background .16s, color .16s;
}
body.pf-flow .woocommerce a.button:hover,
body.pf-flow .woocommerce button.button:hover,
body.pf-flow .woocommerce input.button:hover,
body.pf-flow .woocommerce button.button.alt:hover,
body.pf-flow .woocommerce input.button.alt:hover,
body.pf-flow .woocommerce a.button.alt:hover {
  background: var(--pf-terra-dark); color: #fff;
}
/* Astra's focus treatment on Woo buttons is `border: 1px dotted`, not an
   outline — so `outline: none` does nothing at all (gotcha 14/23, both). The 2px
   transparent border above exists so this ring cannot change the button's size. */
body.pf-flow .woocommerce a.button:focus-visible,
body.pf-flow .woocommerce button.button:focus-visible,
body.pf-flow .woocommerce input.button:focus-visible {
  border-style: solid; border-color: var(--pf-ink); outline: none;
}

/* "Zaktualizuj koszyk" repairs a number, it is not a call to action — in
   terracotta the cart showed two equally loud buttons. (0,4,2) via the
   attribute selector. [css-078] */
body.pf-flow .woocommerce button.button[name="update_cart"] {
  background: transparent; color: var(--pf-terra-dark);
  border: 1.5px solid var(--pf-line); font-weight: 600; padding: 0 20px;
  min-height: 44px; font-size: 14px;
}
body.pf-flow .woocommerce button.button[name="update_cart"]:hover {
  background: var(--pf-bg-alt); color: var(--pf-terra-dark); border-color: var(--pf-terra);
}
/* Woo ships this button `disabled` and Astra paints disabled buttons full
   terracotta at 40%, which read as a broken primary. product.js auto-
   submits, so it is mostly invisible. [css-079] */
body.pf-flow .woocommerce button.button[name="update_cart"]:disabled,
body.pf-flow .woocommerce button.button[name="update_cart"]:disabled[disabled] {
  background: transparent; color: #a89680; border-color: var(--pf-line);
  opacity: 1; cursor: default;
}

/* The two buttons that carry the bowl mask: the ones that move you forward.
   ::after (icon right, Tomek 2026-08-28) with a mask rather than an inline
   <svg> — page content is not involved here, but the icon vocabulary is the
   same one everywhere else (gotcha 15), one place to edit the shape. */
body.pf-flow .woocommerce a.checkout-button::after,
body.pf-flow.woocommerce-checkout #payment button#place_order::after {
  content: ""; width: 25px; height: 25px; flex: none; background: currentColor;
  -webkit-mask: var(--pf-mask-hbowl) center / contain no-repeat;
          mask: var(--pf-mask-hbowl) center / contain no-repeat;
}

/* Beats Astra's (0,3,1) `a.checkout-button`, which set 1.25em/1em and made
   this 63px against update-cart's 48px. Metrics come from the shared tokens
   (3g.-1). [css-080] */
body.pf-flow .woocommerce .wc-proceed-to-checkout a.checkout-button {
  display: flex; width: 100%; font-size: var(--pf-flow-cta-fs);
  padding: 0 var(--pf-flow-cta-pad); min-height: var(--pf-flow-cta-h); margin: 0;
}

/* THIS ONE NEEDS THE IDS: Astra has `#payment #place_order` at (2,1,0) and
   (2,2,0), so ours is (2,2,2). [css-081] */
body.pf-flow.woocommerce-checkout #payment button#place_order {
  float: none; display: flex; width: 100%; min-height: var(--pf-flow-cta-h);
  font-size: var(--pf-flow-cta-fs); padding: 0 var(--pf-flow-cta-pad); margin: 0;
}

/* --- 3g.3 form fields (checkout, and every account form) --------------------
   Woo's classic markup is `p.form-row > label + span.woocommerce-input-wrapper
   > input.input-text`. Astra styles the row at (0,2,1) and the label at (0,2,2),
   so `body.pf-flow` + one class clears both. */
body.pf-flow .woocommerce form .form-row {
  padding: 0; margin: 0 0 16px;
}
body.pf-flow .woocommerce form .form-row label {
  display: block; line-height: 1.4; margin-bottom: 7px;
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px; font-weight: 600;
  letter-spacing: .02em; color: var(--pf-ink);
}
/* Woo prints the asterisk as pure #FF0000 — the only saturated red on the
   site, six per screen. Terracotta says "required" as clearly. [css-082] */
body.pf-flow .woocommerce form .form-row .required {
  color: var(--pf-terra-dark); font-weight: 700; border: 0; text-decoration: none;
}
body.pf-flow .woocommerce form .form-row .optional {
  color: var(--pf-ink-2); font-weight: 400; font-size: 12px;
}

/* Cream fill, not white: on this palette a white input reads as a hole.
   FONT-SIZE 16px IS FUNCTIONAL — below it iOS zooms. gotcha 54 [css-083] */
body.pf-flow .woocommerce form .form-row input.input-text,
body.pf-flow .woocommerce form .form-row textarea,
body.pf-flow .woocommerce form .form-row select,
body.pf-flow .woocommerce .woocommerce-Input.input-text,
body.pf-flow .woocommerce input[type="text"],
body.pf-flow .woocommerce input[type="email"],
body.pf-flow .woocommerce input[type="tel"],
body.pf-flow .woocommerce input[type="password"],
body.pf-flow .woocommerce textarea {
  box-sizing: border-box; width: 100%; min-height: 48px;
  padding: 12px 15px; margin: 0;
  border: 1.5px solid var(--pf-line); border-radius: 14px;
  background: var(--pf-bg); color: var(--pf-ink); box-shadow: none;
  font-family: 'Inter', system-ui, sans-serif; font-size: 16px; line-height: 1.4;
  transition: border-color .14s, background .14s;
}
body.pf-flow .woocommerce form .form-row textarea,
body.pf-flow .woocommerce textarea { min-height: 96px; resize: vertical; }
body.pf-flow .woocommerce form .form-row input.input-text::placeholder,
body.pf-flow .woocommerce form .form-row textarea::placeholder { color: #a89680; }
body.pf-flow .woocommerce form .form-row input.input-text:focus,
body.pf-flow .woocommerce form .form-row textarea:focus,
body.pf-flow .woocommerce form .form-row select:focus,
body.pf-flow .woocommerce input[type="text"]:focus,
body.pf-flow .woocommerce input[type="email"]:focus,
body.pf-flow .woocommerce input[type="tel"]:focus,
body.pf-flow .woocommerce input[type="password"]:focus,
body.pf-flow .woocommerce textarea:focus {
  border-color: var(--pf-terra); background: var(--pf-paper); outline: none;
}

/* The country <select> keeps its native arrow on some platforms and loses it on
   others once a background is set, so draw our own with the shared chevron mask
   and suppress the native one. `padding-right` leaves room for it. */
body.pf-flow .woocommerce form .form-row select {
  -webkit-appearance: none; appearance: none; cursor: pointer;
  padding-right: 42px;
  background-image: var(--pf-mask-chev);
  background-repeat: no-repeat;
  background-position: right 15px center;
  background-size: 16px 16px;
}

/* Woo's checkout.js appends a `.checkout-inline-error-message` into each
   offending `.form-row`, so this is real markup we had never styled.
   [css-084] */
body.pf-flow .entry-content .form-row .checkout-inline-error-message {
  margin: 7px 0 0; font-size: 12.5px; line-height: 1.45; font-weight: 500;
  color: #C0563F;
}

/* Woo's own validation colours are #d65d67 / #69bf29 at (0,4,2). Keep the
   semantics, swap the palette for the site's — olive is already the "good" green
   in the ticks and the step indicator. */
body.pf-flow .woocommerce form .form-row.woocommerce-invalid input.input-text,
body.pf-flow .woocommerce form .form-row.woocommerce-invalid select {
  border-color: #C0563F; background: #FBF0EA;
}
body.pf-flow .woocommerce form .form-row.woocommerce-validated input.input-text,
body.pf-flow .woocommerce form .form-row.woocommerce-validated select {
  border-color: var(--pf-olive);
}

/* Astra paints `:checked` with its global #B25518. 18px is the smallest that
   still reads as a control; the 44px label is the tap target. [css-085] */
body.pf-flow .woocommerce input[type="checkbox"] {
  width: 18px; height: 18px; margin: 0 9px 0 0; flex: none;
  accent-color: var(--pf-terra); vertical-align: -3px; cursor: pointer;
}

/* --- 3g.4 notices ---
   Woo's notice icon is an icon FONT, so it is suppressed and re-masked. NOT
   scoped to `.pf-flow`: the same notices appear on the shop and product pages.
   The layout needs the template override — Woo emits bare inline content with
   nothing to select, so `notices/*.php` add `.pf-notice-body`. [css-086] */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
  position: relative; width: auto; word-wrap: break-word;
  padding: 15px 20px; margin: 0 0 22px;
  border: 1px solid var(--pf-line); border-top: 1px solid var(--pf-line);
  border-radius: 16px; background: var(--pf-paper); color: var(--pf-ink);
  font-size: 14.5px; line-height: 1.5;
  list-style: none;
}
.woocommerce-message,
.woocommerce-info {
  /* `flex-start`, not `center`: on a two-line message the tick belongs beside the
     FIRST line, which is what a reader looks at, not floating in the middle of
     the block. A 20px icon against a 21.75px line box is within a pixel of
     centred on a single line, which is the common case. */
  /* `nowrap` overrides Astra's inline woocommerce-general CSS, which sets
     `flex-wrap: wrap` at ≤544px — and a basis-auto flex item WRAPS before it
     shrinks, so the body landed on its own line under the icon on phones.
     Nowrap restores the shrink path `.pf-notice-body`'s min-width:0 enables. */
  display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 14px;
}
.pf-notice-body { flex: 1 1 auto; min-width: 0; }
.woocommerce-message { border-color: #CBD9AE; background: #F7FAEF; }
.woocommerce-info { border-color: var(--pf-line); background: var(--pf-bg-alt); }
.woocommerce-error { border-color: #E4BCAE; background: #FBF0EA; padding-left: 52px; }

/* Replace the icon font with our masks. `content: ""` kills the glyph; background
   + mask draws ours. `flex: none` so it never shrinks; the message/info icons are
   real flex items, the error one is absolutely positioned (see above). */
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before {
  content: ""; width: 20px; height: 20px; padding: 0; flex: none;
  font-family: inherit; font-size: 0;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
/* Nudged down by half the difference between the line box and the icon, so the
   icon's centre sits on the first line's centre rather than its top edge. */
.woocommerce-message::before,
.woocommerce-info::before { position: static; margin-top: 1px; }
.woocommerce-error::before { position: absolute; top: 16px; left: 19px; }
/* The hand-drawn tick (Tomek, 2026-08-29) — the flow-step tick keeps the
   geometric mask: 12px white-on-olive needs the crisp stroke. */
.woocommerce-message::before {
  background: var(--pf-olive);
  -webkit-mask-image: var(--pf-mask-hcheck); mask-image: var(--pf-mask-hcheck);
}
.woocommerce-info::before {
  background: var(--pf-ink-2);
  -webkit-mask-image: var(--pf-mask-info); mask-image: var(--pf-mask-info);
}
.woocommerce-error::before {
  background: #C0563F;
  -webkit-mask-image: var(--pf-mask-alert); mask-image: var(--pf-mask-alert);
}

/* THE BLUE RING: Woo focuses its notices, so Chrome paints its default
   outline on page load, unbidden. gotcha 46 [css-087] */
.woocommerce-message:focus,
.woocommerce-info:focus,
.woocommerce-error:focus,
.woocommerce-message:focus-visible,
.woocommerce-info:focus-visible,
.woocommerce-error:focus-visible { outline: none; }

/* Inline links in the message body — "Cofnij?" after removing a line was
   indistinguishable from the sentence (Tomek). [css-088] */
.pf-notice-body a:not(.button) {
  font-weight: 600; color: var(--pf-terra-dark); text-decoration: none;
  border-bottom: 1.5px solid var(--pf-gold); padding-bottom: 1px;
}
.pf-notice-body a:not(.button):hover { color: var(--pf-ink); border-color: var(--pf-terra); }

/* `body.woocommerce-page …`, NOT `body .woocommerce …`, which matched
   nothing: a product page has no `.woocommerce` DIV. gotcha 45 [css-089] */
body.woocommerce-page .woocommerce-message a.button,
body.woocommerce-page .woocommerce-info a.button,
body.woocommerce-page .woocommerce-error a.button {
  float: right; margin: 0 0 0 16px;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 18px; width: auto;
  border: 2px solid transparent; border-radius: 11px;
  background: var(--pf-terra); color: #fff;
  font-family: 'Inter', system-ui, sans-serif; font-size: 13.5px; font-weight: 600;
  line-height: 1.2; text-transform: none; text-decoration: none;
}
body.woocommerce-page .woocommerce-message a.button:hover,
body.woocommerce-page .woocommerce-info a.button:hover,
body.woocommerce-page .woocommerce-error a.button:hover {
  background: var(--pf-terra-dark); color: #fff;
}
.woocommerce-error li, .woocommerce-info li, .woocommerce-message li { margin: 0; }
/* Woo's clearfix `::after` would become a real flex item now these notices
   are flex, taking a 14px gap after the body. gotcha 37 [css-090] */
.woocommerce-message::after,
.woocommerce-info::after,
.woocommerce-error::after { content: none; }

@media (max-width: 600px) {
  /* Under the sentence, full width. A floated 38px button beside two lines of
     text at 400px leaves the text ~150px wide and reads as cramped; below it,
     the message keeps the full measure and the action is a comfortable target. */
  body.woocommerce-page .woocommerce-message a.button,
  body.woocommerce-page .woocommerce-info a.button,
  body.woocommerce-page .woocommerce-error a.button {
    float: none; display: flex; width: 100%; margin: 12px 0 0;
  }
  /* In the flex notices the body sits BESIDE the icon, so its 100% is the
     text column only; pull the action back across the icon column (20px icon
     + 14px gap) so it spans the whole notice like before 0.2.154's nowrap.
     The error notice indents with padding, not flex — it keeps plain 100%. */
  body.woocommerce-page .woocommerce-message a.button,
  body.woocommerce-page .woocommerce-info a.button {
    width: calc(100% + 34px); margin-left: -34px;
  }
  /* Woo prints the button FIRST in the notice HTML, so the rule above stacked
     it ABOVE the sentence. Column flex + order puts the sentence (an anonymous
     item at order 0) first. `:has(> a.button)` so a notice whose only link is
     inline ("Cofnij?") keeps its link in the sentence. [css-193] */
  .pf-notice-body:has(> a.button) { display: flex; flex-direction: column; }
  .pf-notice-body > a.button { order: 1; }
}

/* --- 3g.5 success toasts ---
   toast.js lifts every .woocommerce-message into this fixed stack; info and
   error notices stay inline on purpose (state, and form context that
   test-checkout-error-placement guards). With JS blocked nothing here ever
   matches and the notices render inline as before. [css-195] */
/* Bottom, thumb-reachable (Tomek). The env() inset clears the iOS home
   indicator and iOS 26 Safari's floating address pill, which overlays the
   bottom edge — no iOS on this machine, verify the clearance on-device. */
#pf-toasts {
  position: fixed; z-index: 99999;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px)); right: 18px;
  width: min(420px, calc(100vw - 36px));
  display: flex; flex-direction: column; gap: 10px;
  pointer-events: none;
}
/* Above Astra's 67px sticky buy bar (css-064), which owns the bottom edge on
   product pages — exactly where the added-to-cart toast appears. */
body.single-product #pf-toasts {
  bottom: calc(88px + env(safe-area-inset-bottom, 0px));
}
#pf-toasts .pf-toast {
  margin: 0; position: relative; pointer-events: auto;
  padding-right: 44px;
  box-shadow: 0 10px 30px rgba(46, 41, 33, .18);
  opacity: 0; transform: translateY(8px);
  transition: opacity .25s ease, transform .25s ease;
}
#pf-toasts .pf-toast-in { opacity: 1; transform: none; }
#pf-toasts .pf-toast-out { opacity: 0; transform: translateY(8px); }
@media (prefers-reduced-motion: reduce) {
  #pf-toasts .pf-toast { transition: none; transform: none; }
}
/* 44px, the qa-mobile-hazards tap-target floor; the glyph stays small. */
.pf-toast-x {
  position: absolute; top: 2px; right: 2px; width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center; padding: 0;
  border: 0; border-radius: 12px; background: transparent; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--pf-ink-2);
}
.pf-toast-x:hover { background: rgba(0, 0, 0, .06); color: var(--pf-ink); }

/* On the product page the hero band + photo pull up -30px into the container
   padding — a notice standing there got its bottom border swallowed (Tomek's
   iPhone, 2026-08-29). Extra bottom margin clears the pull, z-index keeps the
   border above the wash. */
.single-product .woocommerce-notices-wrapper { position: relative; z-index: 2; }
.single-product .woocommerce-notices-wrapper .woocommerce-message,
.single-product .woocommerce-notices-wrapper .woocommerce-info,
.single-product .woocommerce-notices-wrapper .woocommerce-error { margin-bottom: 38px; }

/* THE EMPTY CART is an info notice, which is why cart.js relocated it to the
   top. We print it from `cart/cart-empty.php` instead. gotcha 51 [css-091] */
body.woocommerce-cart.pf-flow .pf-cart-empty {
  width: min(520px, 100%); margin: 0 auto 8px; padding: 36px 28px 32px;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: var(--pf-r); box-shadow: var(--pf-shadow);
  text-align: center;
}
/* Astra's `.entry-content p` is 0-1-1 and carries `margin-bottom: 1.6em`, which
   beats a bare class (gotcha 20) — hence the full qualification. */
body.woocommerce-cart.pf-flow .pf-cart-empty .pf-cart-empty-msg {
  font-family: var(--pf-font-serif); font-size: clamp(20px, 2.4vw, 24px);
  line-height: 1.3; color: var(--pf-ink); margin: 0 0 20px;
}
/* Inside the card the button is part of the block, so it drops the 60px that
   separates it from the footer when it stands alone. */
body.woocommerce-cart.pf-flow .pf-cart-empty .return-to-shop { margin: 0; }

/* The head reserves 196px for the botanical, sized for a head with a lead.
   The empty cart has none, so that showed as 188px of nothing. [css-092] */
@media (min-width: 961px) {
  body.woocommerce-cart.pf-flow .pf-flow-head:has( + .wc-empty-cart-message ) {
    min-height: 132px;
  }
  body.woocommerce-cart.pf-flow .pf-flow-head:has( + .wc-empty-cart-message ) .pf-bgart--flow {
    width: 88px; height: 132px; right: 24px;
  }
}

/* --- 3g.5 cart ---
   Astra floats `.cart_totals` right at 48% under a full-width table, leaving
   a measured 520×443px of dead space. Grid instead. [css-093] */
/* THE RAIL IS 380px AND THE GAP 44px ON BOTH PAGES — see the matching rule
   in §3g.6. At 360/40 here the panel slid 20px sideways between steps.
   [css-094] */
body.woocommerce-cart.pf-flow .entry-content > .woocommerce {
  display: grid; align-items: start;
  grid-template-columns: minmax(0, 1fr) var(--pf-flow-rail); gap: 0 var(--pf-flow-gap);
}
body.woocommerce-cart.pf-flow .entry-content > .woocommerce > * { grid-column: 1 / -1; }
body.woocommerce-cart.pf-flow .entry-content > .woocommerce > form.woocommerce-cart-form { grid-column: 1; }
body.woocommerce-cart.pf-flow .entry-content > .woocommerce > .cart-collaterals { grid-column: 2; }
/* On a FULL cart Woo prints notices at priority 10, after our head at 5, so
   they rendered below the step indicator. `order` normalises it. [css-095] */
body.woocommerce-cart.pf-flow .entry-content > .woocommerce > .woocommerce-notices-wrapper { order: -1; }
/* Beats `.woocommerce .cart-collaterals { width: 100% }` (0,2,0) and the
   `.cart_totals { float: right; width: 48% }` (0,3,0) inside it. */
body.woocommerce-cart.pf-flow .woocommerce .cart-collaterals { width: auto; }
body.woocommerce-cart.pf-flow .woocommerce .cart-collaterals .cart_totals {
  float: none; width: auto; position: sticky; top: var(--pf-flow-sticky-top);
}

/* Kept as a `<table>` (it is tabular data and Woo's AJAX assumes the
   structure) but restyled as a stack of lines. Astra's `border-collapse:
   separate` (0,2,1) has to go. [css-096] */
body.pf-flow .woocommerce table.shop_table {
  width: 100%; border: 0; border-radius: 0; margin: 0 0 24px;
  border-collapse: collapse; background: transparent;
}
/* THE ITEMS TABLE IS A CARD so both screens read [card | card]. A bare table
   becoming a white address card made the page feel rebuilt, not advanced.
   [css-097] */
body.woocommerce-cart.pf-flow .woocommerce table.cart {
  border-collapse: separate; border-spacing: 0;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: var(--pf-flow-card-r); box-shadow: var(--pf-shadow);
  padding: 4px 24px 8px;
}
/* The grey band is painted on `thead`, not the cells (0,2,2), so styling
   `thead th` leaves it exactly where it was. [css-098] */
body.pf-flow .woocommerce table.shop_table thead { background: transparent; }
body.pf-flow .woocommerce table.cart thead th {
  padding: 0 14px 12px; border: 0; border-bottom: 1.5px solid var(--pf-line);
  background: transparent; text-align: left;
  font-family: 'Inter', system-ui, sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--pf-ink-2);
}
body.pf-flow .woocommerce table.cart tbody td {
  padding: 18px 14px; border: 0; border-bottom: 1px solid var(--pf-line);
  vertical-align: middle; background: transparent;
}
body.pf-flow .woocommerce table.cart tbody tr:last-child td { border-bottom: 0; }

/* Thumbnails. Astra caps them at 70px (0,3,2) with `width: auto`, which lets a
   non-square source render as a non-square thumb; ours is a fixed square with
   the paper ground behind, so the four pack shots (all 600×600 with a lot of
   air) sit in a consistent frame. */
body.pf-flow .woocommerce table.cart td.product-thumbnail { width: 84px; }
body.pf-flow .woocommerce table.cart td.product-thumbnail img {
  width: 72px; height: 72px; max-width: 72px; display: block;
  object-fit: contain; border-radius: 14px;
  background: var(--pf-paper); border: 1px solid var(--pf-line); padding: 4px;
}
body.pf-flow .woocommerce table.cart td.product-name a {
  font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600;
  color: var(--pf-ink); text-decoration: none;
}
body.pf-flow .woocommerce table.cart td.product-name a:hover { color: var(--pf-terra-dark); }
body.pf-flow .woocommerce table.cart td.product-price,
body.pf-flow .woocommerce table.cart td.product-subtotal { white-space: nowrap; }
body.pf-flow .woocommerce table.cart td.product-price { color: var(--pf-ink-2); font-size: 14.5px; }
body.pf-flow .woocommerce table.cart td.product-subtotal {
  font-weight: 700; font-size: 15.5px; text-align: right;
}
body.pf-flow .woocommerce table.cart th.product-subtotal { text-align: right; }

/* Astra hands the remove link `-apple-system` at 18px, grey on cream —
   nearly invisible, on the one control that deletes something. [css-099] */
body.pf-flow .woocommerce table.cart td.product-remove { width: 44px; padding-inline: 0; }
/* 40px rather than the 44 the steppers get, and that is deliberate: this one
   deletes a line. It needs to be comfortably hittable when aimed at and slightly
   harder to catch by accident than the control right next to it. Was 32. */
body.pf-flow .woocommerce table.cart a.remove {
  display: grid; place-items: center; width: 40px; height: 40px;
  border-radius: 50%; border: 1px solid transparent;
  color: var(--pf-ink-2); background: transparent; font-size: 0;
  transition: background .14s, color .14s, border-color .14s;
}
body.pf-flow .woocommerce table.cart a.remove:hover {
  background: #FBF0EA; border-color: #E4BCAE; color: var(--pf-terra-dark);
}
body.pf-flow .woocommerce table.cart a.remove svg { width: 15px; height: 15px; }
/* Astra's close icon is a stroked SVG that inherits `currentColor` on some
   paths and hard-codes it on others; force both so the hover colour applies. */
body.pf-flow .woocommerce table.cart a.remove svg path { fill: currentColor; stroke: currentColor; }
body.pf-flow .woocommerce table.cart a.remove:focus-visible {
  outline: 2px solid var(--pf-terra); outline-offset: 1px;
}

/* The stepper, shared with the product page. `.pf-qty` is added by product.js
   only once the buttons exist, so a no-JS visitor keeps a plain number input
   with its native spinner rather than a box with nothing to press. */
body.pf-flow .woocommerce table.cart td.product-quantity .quantity {
  display: inline-flex; align-items: stretch; margin: 0;
  height: 44px; border: 1px solid var(--pf-line); border-radius: 13px;
  background: var(--pf-bg); overflow: hidden;
}
/* Beats `.woocommerce-js .quantity .qty { width: 3.631em; min-height: 35px }`
   (0,3,0). */
body.pf-flow .woocommerce table.cart td.product-quantity .quantity input.qty {
  width: 44px; min-height: 0; height: 100%; padding: 0; margin: 0;
  border: 0; background: transparent; box-shadow: none; text-align: center;
  font-family: 'Inter', system-ui, sans-serif; font-size: 16px; font-weight: 700;
  color: var(--pf-ink);
}
/* 44px, not 36: the container is 44px tall, so a 44px-wide button is a square
   44x44 target — the smallest a thumb hits reliably, and these two are the most
   pressed controls in the whole flow. Measured 36x42 before. */
body.pf-flow .woocommerce table.cart td.product-quantity .quantity .pf-qty-btn {
  width: 44px; font-size: 18px;
}
/* While the debounced auto-update is in flight. Deliberately gentle — a 700ms
   dim that ends in a page load; anything stronger reads as an error. */
.woocommerce-cart-form.pf-cart-updating { opacity: .55; transition: opacity .2s; }

/* Woo's own coupon UI hides for good — php-108's panel replaces it. With JS
   the whole row hides too (`html.pf-js`; auto-update's programmatic .click()
   works on a display:none button); no-JS keeps it for quantity updates. The td
   STAYS table-cell (gotcha 126, css-200). */
body.pf-flow .woocommerce table.cart td.actions {
  padding: 18px 0 0; border: 0; text-align: right;
}
body.pf-flow .woocommerce table.cart td.actions .coupon { display: none; }
html.pf-js body.pf-flow .woocommerce table.cart td.actions { display: none; }

/* --- the coupon panel in the totals card (php-108, toggle in js-007) ---
   Ghost apply button until a code is typed (`.pf-has-code`): filled, it would
   compete with the checkout CTA below. Our own #pf-coupon-code id keeps Astra's
   `#coupon_code:focus` DOTTED-border rule from ever matching (that id outranked
   any class stack here — gotcha 36, count ids first). */
body.pf-flow .woocommerce .cart_totals .pf-coupon {
  display: flex; gap: 8px; margin: 0 0 14px;
}
/* 36px row (Tomek's mockup). min-height must be restated: the flow's input
   rule says 48px and a bare `height` can never shrink past a min. */
body.pf-flow .woocommerce .cart_totals .pf-coupon .input-text {
  flex: 1 1 auto; width: auto; min-width: 0;
  height: 36px; min-height: 36px; padding: 0 12px;
  font-size: 14px; border-radius: 10px;
}
body.pf-flow .woocommerce .cart_totals .pf-coupon .input-text:focus {
  border: 1.5px solid var(--pf-terra); outline: none;
  box-shadow: 0 0 0 3px var(--pf-terra-soft);
}
/* Ghost text is terra-DARK and the boundary terra: the lighter pair failed
   WCAG (4.47:1 text, 1.71:1 border). Filled text is #fff like every primary
   button — #FFFDF8 on terracotta measures under 4.5:1. */
body.pf-flow .woocommerce .cart_totals .pf-coupon button[name="apply_coupon"] {
  flex: 0 0 auto; box-sizing: border-box; height: 36px; min-height: 36px;
  padding: 0 16px; display: inline-flex; align-items: center;
  font-size: 14px; font-weight: 600; border-radius: 8px;
  background: transparent; color: var(--pf-terra-dark); border: 1px solid var(--pf-terra);
  transition: background .15s, color .15s, border-color .15s;
}
body.pf-flow .woocommerce .cart_totals .pf-coupon.pf-has-code button[name="apply_coupon"] {
  background: var(--pf-terra); color: #fff; border-color: var(--pf-terra);
}
body.pf-flow .woocommerce .cart_totals .pf-coupon button[name="apply_coupon"]:focus-visible {
  outline: 2px solid var(--pf-terra-dark); outline-offset: 2px;
}
/* Applied-coupon row: [Usuń] floats to the td's left edge, next to the coupon
   NAME it removes instead of trailing the amount (Tomek 2026-09-10). A label
   filter was tried first and leaked escaped HTML into the phone's data-title
   row label — gotcha 76. */
body.pf-flow .woocommerce .cart_totals tr.cart-discount .woocommerce-remove-coupon,
body.pf-flow .woocommerce #order_review tr.cart-discount .woocommerce-remove-coupon {
  float: left; font-size: 13px; margin-left: 6px;
}
/* Phones: 44px tap targets (qa-mobile-hazards' floor) and 16px input (gotcha
   54 iOS zoom). The 36/14 row is a desktop-density choice. AFTER the base
   rules — source order decides at equal specificity. */
@media (max-width: 600px) {
  body.pf-flow .woocommerce .cart_totals .pf-coupon .input-text,
  body.pf-flow .woocommerce .cart_totals .pf-coupon button[name="apply_coupon"] {
    height: 44px; min-height: 44px;
  }
  body.pf-flow .woocommerce .cart_totals .pf-coupon .input-text { font-size: 16px; }
}

/* The cross-sell heading is deliberately NOT a `.pf-sec-head`: that
   component is centred with a paw divider and belongs to a full-width
   section. [css-100] */
.pf-cart-xsell { margin-top: 42px; padding-top: 26px; border-top: 1px solid var(--pf-line); }
body.pf-flow .entry-content .pf-cart-xsell h2 {
  font-family: var(--pf-font-serif); font-size: 20px; font-weight: 600;
  margin: 0 0 20px; color: var(--pf-ink);
}
/* A FIXED THREE COLUMNS, not `auto-fit`: with one product left, auto-fit
   gave it the whole 780px column and a 780px pack shot. gotcha 47 [css-101] */
body.pf-flow .pf-cart-xsell .woocommerce ul.products.pf-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr)); width: 100%; margin: 0;
}
/* COMPACT VARIANT: at full height two of these made the cart twice as long
   as the thing they footnote. Image cropped to a landscape slot, description
   dropped. [css-102] */
/* `contain`, NOT `cover`: at ~237px `cover` cropped the SIDES and sliced
   "OSOCZE PRO" to "CZE RO". Pack shots must never be cropped horizontally.
   gotcha 47 [css-103] */
body.pf-flow .pf-cart-xsell .pf-card .pf-card-img img {
  aspect-ratio: 16 / 11; object-fit: contain; object-position: center;
  background: var(--pf-bg);
}
body.pf-flow .pf-cart-xsell .pf-card .pf-desc { display: none; }
body.pf-flow .pf-cart-xsell .pf-card .pf-card-body { padding: 16px 18px 18px; }

/* Keeps price and button rows aligned across cards — a two-line name pushed
   that card's price and button a line lower (Tomek, 2026-08-23). gotcha 32
   [css-104] */
body.pf-flow .pf-cart-xsell .woocommerce ul.products li.product .pf-card { height: 100%; }
body.pf-flow .pf-cart-xsell .pf-card .pf-price { margin-top: auto; }
body.pf-flow .entry-content .pf-cart-xsell .pf-card h3 { font-size: 17px; }
body.pf-flow .pf-cart-xsell .pf-card .wp-block-button .wp-block-button__link {
  min-height: 44px; font-size: 14px;
}
/* No icon on this one. The shared card puts `.pf-btn-bowl` on every CTA, which is
   right when the label is "Dodaj do miski" — here the label is "Zobacz produkt"
   and an add-to-cart icon promises an action the link does not perform. */
body.pf-flow .pf-cart-xsell .pf-card .wp-block-button .wp-block-button__link::before {
  content: none;
}

/* The same recipe and tokens as checkout's `#order_review` (3g.-1, 3g.6):
   one even 22px box, heading carrying a plain bottom margin. [css-105] */
body.pf-flow .woocommerce .cart_totals {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: var(--pf-flow-card-r); padding: var(--pf-flow-card-pad);
  box-shadow: var(--pf-shadow);
}
/* Astra paints this heading with a near-white #FBFBFB band and a bottom border
   (`.woocommerce-cart .cart-collaterals .cart_totals > h2`, inline CSS) plus
   negative side margins so the band bleeds to the card edge. All of that has to
   go, or the card opens with a grey slab. */
body.pf-flow .woocommerce .cart_totals > h2 {
  background: transparent; border: 0; padding: 0; margin: 0 0 16px;
  /* Identical to checkout's `#order_review_heading` (3g.6). It was 20px and
     inherited weight 700 from Astra's h2; checkout's was 21px/600. Same panel,
     same title, so: same type. */
  font-family: var(--pf-font-serif); font-size: 21px; font-weight: 600;
  line-height: 1.3; color: var(--pf-ink);
}
body.pf-flow .woocommerce .cart_totals table.shop_table {
  margin: 0; border: 0; border-collapse: collapse;
}
body.pf-flow .woocommerce .cart_totals table.shop_table th,
body.pf-flow .woocommerce .cart_totals table.shop_table td {
  padding: 13px 0; border: 0; border-top: 1px solid var(--pf-line);
  background: transparent; vertical-align: top;
}
body.pf-flow .woocommerce .cart_totals table.shop_table tr:first-child th,
body.pf-flow .woocommerce .cart_totals table.shop_table tr:first-child td { border-top: 0; }
body.pf-flow .woocommerce .cart_totals table.shop_table th {
  width: 40%; font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px; font-weight: 600; color: var(--pf-ink-2); text-align: left;
}
body.pf-flow .woocommerce .cart_totals table.shop_table td {
  text-align: right; font-size: 14.5px; color: var(--pf-ink);
}
/* The total line is the number people came for: serif, and the accent. */
body.pf-flow .woocommerce .cart_totals tr.order-total th,
body.pf-flow .woocommerce .cart_totals tr.order-total td { padding-block: 15px; }
body.pf-flow .woocommerce .cart_totals tr.order-total td strong,
body.pf-flow .woocommerce .cart_totals tr.order-total td .amount {
  font-family: var(--pf-font-serif); font-size: 24px; font-weight: 700;
  color: var(--pf-terra-dark);
}
/* The tax note. Astra's `.cart_totals p small` is #777 at .83em (0,3,2); it is
   a footnote and should read like one rather than like part of the total. */
body.pf-flow .woocommerce .cart_totals tr.order-total small.includes_tax {
  display: block; margin-top: 4px;
  font-size: 11.5px; font-weight: 400; color: var(--pf-ink-2);
}
body.pf-flow .woocommerce .cart_totals tr.order-total small.includes_tax .amount {
  font-family: 'Inter', system-ui, sans-serif; font-size: 11.5px;
  font-weight: 600; color: var(--pf-ink-2);
}
/* The shipping list itself is §3l — it is the same component on this page and on
   the checkout, so it is written once, there. What stays here is the cart-only
   furniture around it: the destination note and the calculator. */
body.pf-flow .woocommerce .cart_totals .woocommerce-shipping-destination {
  font-size: 12px; color: var(--pf-ink-2); margin: 6px 0 0;
}
body.pf-flow .woocommerce .cart_totals .shipping-calculator-button {
  display: inline-block; margin-top: 8px;
  font-size: 13px; font-weight: 600; color: var(--pf-terra-dark);
  text-decoration: none; border-bottom: 1.5px solid var(--pf-gold);
}
body.pf-flow .woocommerce .cart_totals .shipping-calculator-button:hover {
  color: var(--pf-ink); border-color: var(--pf-terra);
}
/* Astra hangs a WooCommerce-icon-font caret off this link at (0,5,0). It is the
   only place on the site that font appears; the link reads fine without it. */
body.pf-flow .woocommerce .cart-collaterals .shipping_calculator .shipping-calculator-button::after {
  content: none;
}
body.pf-flow .woocommerce .cart_totals .shipping-calculator-form { text-align: left; padding-top: 12px; }
body.pf-flow .woocommerce .cart-collaterals .shipping_calculator .button { width: 100%; }
body.pf-flow .woocommerce .wc-proceed-to-checkout { padding: 18px 0 0; }

/* The reassurance list under the CTA, and the way back to the shop. Both come
   from functions.php; the promises are the same Customizer settings the product
   page uses. */
.pf-flow-reassure {
  list-style: none; margin: 18px 0 0; padding: 16px 0 0;
  border-top: 1px solid var(--pf-line);
  display: grid; gap: 9px;
}
.pf-flow-reassure li {
  display: flex; align-items: center; gap: 10px; margin: 0;
  font-size: 13px; color: var(--pf-ink-2);
}
.pf-flow-reassure .pf-i { color: var(--pf-olive); flex: none; }
.pf-flow-back {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 16px;
  font-size: 13.5px; font-weight: 600; color: var(--pf-ink-2); text-decoration: none;
}
.pf-flow-back::before { content: "←"; font-size: 15px; }
.pf-flow-back:hover { color: var(--pf-terra-dark); }

/* The empty cart's own block, card and message included, is in §3g.4. This rule
   only covers `.return-to-shop` standing on its own — Woo prints it from other
   templates too — since inside the card it is centred and margin-less already. */
body.woocommerce-cart.pf-flow .return-to-shop { text-align: center; margin-bottom: 60px; }

/* --- 3g.6 checkout ---
   Astra already floats this two-up, so grid replaces the floats only to make
   the order review STICKY. [css-106] */
body.woocommerce-checkout.pf-flow .woocommerce form.checkout {
  display: grid; align-items: start;
  /* Same two numbers as the cart's grid, from the same tokens — 3g.-1. */
  grid-template-columns: minmax(0, 1fr) var(--pf-flow-rail);
  /* THE `notices` ROW EXISTS BECAUSE WOO INJECTS INTO THIS GRID: checkout.js
     prepends its notice group, and a prepended child with no grid area auto-
     places. [css-107] */
  /* TWO ROWS, NOT THREE. The old `review-head` row left a ~110px hole under
     "Twoje zamówienie" that read as a stray margin. [css-108] */
  grid-template-areas: "notices notices" "fields review";
  gap: 0 var(--pf-flow-gap);
}
/* Anything else that ends up in here — a plugin, a future hook — at least gets the
   full measure rather than being squeezed into the 380px summary column. */
body.woocommerce-checkout.pf-flow .woocommerce form.checkout > * { grid-column: 1 / -1; }
/* Catches `-checkout` (a failed submit) and `-updateOrderReview` (a failed
   shipping/total refresh); both carry the base class. */
body.woocommerce-checkout.pf-flow .woocommerce form.checkout > .woocommerce-NoticeGroup {
  grid-area: notices; margin-bottom: 26px;
}
body.woocommerce-checkout.pf-flow .woocommerce form.checkout > #customer_details { grid-area: fields; }
body.woocommerce-checkout.pf-flow .woocommerce form.checkout > #order_review { grid-area: review; }
/* `float:none; width:auto` IS NOT REDUNDANT: Astra floats these at a
   PERCENTAGE width, and inside a grid the float is ignored but the
   percentage is not. gotcha 71 [css-109] */
body.woocommerce-checkout.pf-flow .woocommerce form.checkout > #order_review,
body.woocommerce-checkout.pf-flow .woocommerce form.checkout #order_review_heading {
  float: none; width: auto; max-width: none;
}
/* NEEDS TWO IDS: Astra draws the heading and the review as ONE bordered box
   split across two elements. [css-110] */
body.pf-flow #content form.checkout #order_review_heading {
  border: 0; padding: 0; background: transparent;
  /* THE SAME THREE VALUES AS THE CART'S `.cart_totals > h2` — 3g.5. This is the
     panel's title on both screens and it was 21px/600 here against 20px/700
     there, which is small enough to look like nothing in a screenshot of either
     page and obvious the moment you click between them. */
  font-family: var(--pf-font-serif); font-size: 21px; font-weight: 600;
  line-height: 1.3; color: var(--pf-ink);
  margin: 0 0 16px;
  /* The size has to live here too — Astra's same (2,1,1) rule sets it, so the
     later heading rule won the family and lost the size. gotcha 53 [css-111] */
}
body.pf-flow #content form.checkout > #order_review {
  border: 1px solid var(--pf-line); border-width: 1px;
  padding: var(--pf-flow-card-pad);
}
/* Astra's own (1,4,1) rules on these two live in its inline CSS; ours are
   (1,4,2) — the extra element is `body` — so they win on specificity. */
body.woocommerce-checkout.pf-flow .woocommerce form #customer_details.col2-set .col-1,
body.woocommerce-checkout.pf-flow .woocommerce form #customer_details.col2-set .col-2 {
  float: none; width: 100%; padding: 0;
}
/* `margin-right:0` is the THIRD thing Astra's float leaves behind: a
   percentage gutter that survives `float:none; width:auto`. gotcha 71
   [css-112] */
body.woocommerce-checkout.pf-flow .woocommerce form #customer_details {
  float: none; width: auto; margin-right: 0;
}

/* Section headings inside the form. Woo emits bare <h3>s (retagged <h2> by
   tpl-012 on checkout), which Astra sizes at 30px 'Lexend' — bigger than our
   own h2s and in the wrong family. */
body.pf-flow .woocommerce .entry-content h3,
body.pf-flow .entry-content .woocommerce-billing-fields > h2,
body.pf-flow .entry-content .woocommerce-shipping-fields > h2,
body.pf-flow .entry-content #order_review_heading {
  font-family: var(--pf-font-serif); font-size: 21px; font-weight: 600;
  line-height: 1.3; color: var(--pf-ink); margin: 0 0 18px;
}
body.pf-flow .entry-content .woocommerce-shipping-fields { margin-top: 30px; }
body.pf-flow .entry-content .woocommerce-additional-fields { margin-top: 26px; }
/* Astra's inline CSS already draws this rule, but in #ddd — nowhere in our
   palette — with 20px of top padding on top of the card's own. [css-113] */
body.pf-flow #customer_details .woocommerce-billing-fields > h2 {
  padding: 0 0 12px; margin-bottom: 16px;
  border-bottom: 1px solid var(--pf-line);
}
/* The three blocks as cards, so the form reads as three steps rather than
   one 900px column. Symmetric padding: the last form-row carries no margin.
   [css-114] */
body.woocommerce-checkout.pf-flow .woocommerce-billing-fields,
body.woocommerce-checkout.pf-flow .woocommerce-shipping-fields,
body.woocommerce-checkout.pf-flow .woocommerce-additional-fields {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 24px;
}
/* `#ship-to-different-address` is a heading (h2 since tpl-012) wrapping a
   checkbox, so it needs the row treatment — and must name EVERY property Astra
   sets on `#customer_details` headings. gotcha 53 [css-115] */
body.pf-flow .entry-content h2#ship-to-different-address {
  display: flex; align-items: center; margin: 0 0 4px; font-size: 17px;
  padding: 0; border-bottom: 0;
}
body.pf-flow h2#ship-to-different-address label {
  display: flex; align-items: center; margin: 0; cursor: pointer;
  font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600;
}
body.pf-flow h2#ship-to-different-address span { font-weight: inherit; }
/* Collapse the heading's own bottom margin when the address block below it is
   hidden, or an unchecked box leaves a 24px hole at the card's foot. */
body.pf-flow .woocommerce-shipping-fields .shipping_address { padding-top: 18px; }

/* Woo's `form-row-first`/`-last` are 47% floats. Flex on the wrapper is
   impossible (they are siblings of full-width rows), so keep the floats and
   even them up. [css-116] */
body.pf-flow .woocommerce form .form-row-first,
body.pf-flow .woocommerce form .form-row-last { width: calc(50% - 8px); }
body.pf-flow .woocommerce form .form-row-first { float: left; clear: both; }
body.pf-flow .woocommerce form .form-row-last { float: right; }
body.pf-flow .woocommerce form .form-row-wide { clear: both; }

/* Sticky, so the total and pay button stay on screen. Written `form.checkout
   >` at (1,4,2) to match the float reset, which would otherwise strip this
   padding. [css-117] */
body.woocommerce-checkout.pf-flow .woocommerce form.checkout > #order_review {
  position: sticky; top: var(--pf-flow-sticky-top);
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: var(--pf-flow-card-r); padding: var(--pf-flow-card-pad);
  box-shadow: var(--pf-shadow);
}
body.woocommerce-checkout.pf-flow .woocommerce table.woocommerce-checkout-review-order-table {
  width: 100%; margin: 0 0 4px; border: 0; border-collapse: collapse;
}
/* Astra zeroes these borders and the left padding at (1,2,2), which is why the
   review table arrived as unseparated rows of text. (1,2,3) here. */
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table th,
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table td {
  padding: 12px 0; border: 0; border-top: 1px solid var(--pf-line);
  background: transparent; vertical-align: top;
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table thead th {
  padding: 0 0 10px; border: 0; border-bottom: 1.5px solid var(--pf-line);
  font-family: 'Inter', system-ui, sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--pf-ink-2);
}
/* The thead's own rule already separates the header, and `td.product-name`
   is `display:block` so its border spans the row while the `th`'s spans one
   column. gotcha 69 [css-118] */
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table tbody tr:first-child th,
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table tbody tr:first-child td {
  border-top: 0;
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table thead th:last-child,
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table td:last-child { text-align: right; }
body.woocommerce-checkout.pf-flow .woocommerce form #order_review td.product-name {
  display: block; font-family: var(--pf-font-serif); font-size: 15.5px;
  font-weight: 600; color: var(--pf-ink); line-height: 1.35;
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review td.product-name .product-quantity {
  display: inline; font-family: 'Inter', system-ui, sans-serif; font-size: 13px;
  font-weight: 600; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review tfoot th {
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px; font-weight: 600;
  color: var(--pf-ink-2); text-align: left;
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review tfoot td { font-size: 14.5px; }
body.woocommerce-checkout.pf-flow .woocommerce form #order_review tfoot tr.order-total td strong,
body.woocommerce-checkout.pf-flow .woocommerce form #order_review tfoot tr.order-total td .amount {
  font-family: var(--pf-font-serif); font-size: 23px; font-weight: 700;
  color: var(--pf-terra-dark);
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review tfoot tr.order-total small.includes_tax {
  display: block; margin-top: 4px; font-size: 11.5px; font-weight: 400; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow .woocommerce form #order_review tfoot tr.order-total small.includes_tax .amount {
  font-family: 'Inter', system-ui, sans-serif; font-size: 11.5px; font-weight: 600; color: var(--pf-ink-2);
}
/* The shipping list is §3l — shared with the cart, written once there. */

/* Written from the real checkout with Paynow BLIK live (roadmap 17). Woo emits
   <li><input><label>logo</label><div.payment_box></li>; the li is the card so
   radio + name + provider logo read as one control, box drops in below. bacs is
   QA scaffolding; card + pay-by-links are enabled but inactive on the account. [css-119] */
body.woocommerce-checkout.pf-flow .woocommerce #payment {
  background: transparent; border: 0; border-radius: 0; padding: 0;
  margin-top: 6px;
}
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods {
  list-style: none; margin: 0 0 16px; padding: 16px 0 0; border: 0;
  border-top: 1px solid var(--pf-line);
}
/* A GRID, like the delivery cards (§3l, css-156): as a wrapping flex row the
   label carried the logo in its min-content, so "Płatność szybkim przelewem"
   dropped to a second flex line under the radio below ~380px (Tomek). All but
   the radio default to column 2; `minmax(0,…)` stops Paynow widening it. [css-170] */
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li {
  position: relative;
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
  column-gap: 11px;
  margin: 0 0 8px; padding: 12px 14px; list-style: none; cursor: pointer;
  border: 1.5px solid var(--pf-line); border-radius: 14px; background: var(--pf-bg);
  transition: border-color .14s, background .14s;
}
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li > * { grid-column: 2; }
/* Hover is a gold hint, selected is a terracotta commitment with a fill — they must
   NOT look alike, and they match the shipping cards above (§3l, css-159). */
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li:hover {
  border-color: var(--pf-gold); background: var(--pf-paper);
}
/* THE CARD'S OWN RADIO, not any radio in it (`> input`): Paynow puts a bank
   radio inside the pay-by-link box, so a chosen bank kept that card filled
   after the shopper moved to BLIK (Tomek). [css-171] */
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li:has(> input[type="radio"]:checked) {
  border-color: var(--pf-terra); background: var(--pf-terra-soft);
}
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li > input[type="radio"] {
  grid-column: 1; grid-row: 1;
  accent-color: var(--pf-terra); width: 17px; height: 17px; margin: 0;
}
/* Name and logo are two COLUMNS, like the delivery label (css-169). The name
   column is `minmax(0, 1fr)` so a long name wraps inside itself and the logo
   keeps its own right column, centred against it. The name is a bare text node,
   so it is an anonymous grid item and takes column 1 by order. [css-119] */
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li > label {
  grid-row: 1; display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; column-gap: 12px; min-width: 0; margin: 0;
  cursor: pointer; font-size: 14.5px; font-weight: 600; color: var(--pf-ink);
  line-height: 1.35;
}
/* `margin: 0` because two stylesheets fight over it: Woo ships `-2px 0 0 .5em`
   and Paynow adds `margin-top: .25rem`. Woo wins, so the logo sat 1px above the
   centre its own `align-items` had computed. */
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li > label img {
  justify-self: end; max-height: 24px; width: auto; display: block; margin: 0;
}
/* THE WHOLE CARD IS THE CONTROL (Tomek): it lit up on hover while only the label
   text answered a click. A stretched label pseudo covers the `<li>`; the box is
   lifted above it so its own content stays clickable (css-158, same as §3l). */
body.woocommerce-checkout.pf-flow .woocommerce #payment ul.payment_methods > li > label::before {
  content: ''; position: absolute; inset: 0; border-radius: 14px;
}
/* The selected method's explainer: inside the card, full width, set off by a
   hairline instead of Woo's hard-coded triangle. z-index keeps it above the label
   overlay so any link in it (future gateways) stays clickable. */
body.woocommerce-checkout.pf-flow .woocommerce #payment div.payment_box {
  grid-column: 2; position: relative; z-index: 1; margin: 12px 0 0; padding: 12px 0 0;
  background: transparent; border: 0; border-top: 1px solid var(--pf-line);
  border-radius: 0; font-size: 13px; line-height: 1.5; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow .woocommerce #payment div.payment_box::before { display: none; }
body.woocommerce-checkout.pf-flow .woocommerce #payment div.payment_box p { margin: 0 0 8px; }
body.woocommerce-checkout.pf-flow .woocommerce #payment div.payment_box p:last-child { margin-bottom: 0; }
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-data-processing-info p { font-size: 11.5px; }
/* The BLIK code input spilled its .col-md-4 by 16px at phone widths — the
   plugin's own 16px right margin on a 100%-wide input (found by qa-overflow
   on the pay page; the same box ships on checkout). [css-203] */
body.woocommerce-checkout.pf-flow .woocommerce #payment .payment_box input.form-control {
  box-sizing: border-box; width: 100%; max-width: 100%; margin: 0;
}
/* --- 3g.6b PAYNOW'S BANK PICKER (pay-by-links) ---
   The plugin's front.css owns this markup; these rules restyle it in place.
   Tomek 2026-08-27 approved: keep it compact, and keep unavailable banks
   visible rather than hiding them. [css-172] */

/* THE GRID IS SIZED FROM THE COLUMN, not the viewport. The plugin gives each
   tile `width:23%`, dropping to 31% under a 576px VIEWPORT — so the 282px
   desktop review column got 4 tiles of 65px while a 390px phone got 3 of 80px,
   the narrow column getting the bigger tiles. Also kills its `margin: 0 -1%`. */
/* The 58px floor is measured, not chosen: it is the largest value that still
   fits FOUR tiles in the 276px desktop column (4×58 + 3×8 = 256) and only three
   in a 390px phone's 254px — the counts the plugin produced, kept on purpose so
   the picker stays as compact as Tomek liked it. */
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbls {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
  gap: 8px; margin: 10px 0 4px;
}
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl {
  width: auto; margin: 0;
}
/* KEYBOARD ACCESS, and this one is a bug: the plugin hides the bank radio with
   `display:none !important`, which takes the whole group out of the tab order —
   and `validate_fields()` REFUSES the order without a bank, so a keyboard or
   screen-reader shopper could not pay by transfer at all. [css-173] */
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl input[type="radio"] {
  display: block !important;
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* The tile. Fixed 48px for a real tap target: the plugin sizes it
   `calc(100vh / 20)`, so it was 42px on a phone and would be 72px on a tall
   monitor — an arbitrary height nobody chose. */
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl label {
  height: 48px; min-height: 48px; padding: 7px; margin: 0;
  border: 1.5px solid var(--pf-line); border-radius: 10px;
  transition: border-color .14s, box-shadow .14s;
}
/* One optical box for logos whose own ratios run from 6.5:1 to 0.86:1. The
   plugin's `max-width: 90%` let the wide ones touch the border. */
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl label img {
  max-height: 24px !important; max-width: 84%; margin: 0 !important;
}
/* Hover gold, chosen terracotta — the same two-state language as the cards
   around them (css-159). The ring is a 1.5px border plus an inset shadow, NOT
   the plugin's 1px→2px border swap: that reflowed the tile and nudged the logo,
   the fault we fixed on the BLIK logo in 0.2.53. */
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl:not(.disabled) label:hover {
  border: 1.5px solid var(--pf-gold); background: #fff;
}
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl input[type="radio"]:checked + label {
  border: 1.5px solid var(--pf-terra); background: #fff;
  box-shadow: inset 0 0 0 1px var(--pf-terra);
}
/* The focus ring the hidden radio could never show. `:focus-visible`, so a mouse
   click does not paint it (gotcha 46). */
body.woocommerce-checkout.pf-flow .woocommerce #payment .paynow-payment-option-pbl input[type="radio"]:focus-visible + label {
  outline: 2px solid var(--pf-terra-dark); outline-offset: 2px;
}
/* "Wybierz bank:" is a field label, not prose — matched to `.pf-ship-heading`.
   The plugin's `margin-top` carries `!important`, so only the rest is set. */
body.woocommerce-checkout.pf-flow .woocommerce #payment div.payment_box.payment_method_pay_by_paynow_pl_pbl > p {
  margin-bottom: 0; font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px; font-weight: 600; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow .woocommerce #payment .place-order { padding: 4px 0 0; }
/* The privacy / terms text above the button. Small, quiet, and it must not look
   like a paragraph of the order. */
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper {
  margin: 0 0 16px; font-size: 12px; line-height: 1.55; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow .woocommerce-privacy-policy-text p { margin: 0; font-size: 12px; }
/* Underlined, not colour alone: at 12px inside a --pf-ink-2 paragraph the link
   contrast against its own surrounding text is 1.07:1, so colour is not a
   distinguishing cue (WCAG 1.4.1). Same for the two links below. [css-196] */
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper a { color: var(--pf-terra-dark); text-decoration: underline; }
/* Woo's noscript block explains the "update totals" button. It is legitimate
   content for a no-JS visitor and pure noise otherwise; leave it, but stop it
   inheriting the review card's type scale. */
body.woocommerce-checkout.pf-flow .woocommerce #payment noscript { font-size: 12.5px; color: var(--pf-ink-2); }

/* Woo's blockUI overlay, which covers the review card during every AJAX totals
   refresh. Its default is a white 0.6-opacity sheet with a hard edge; matched to
   the card's radius it reads as the card thinking rather than as a flash. */
body.pf-flow .blockUI.blockOverlay { border-radius: 20px; background: var(--pf-paper) !important; }

/* --- 3g.6c THE ORDER-PAY PAGE (payment retry) ---
   Woo's form-pay.php: the form ITSELF is #order_review, so every `form
   #order_review` selector above misses here. One centred paper card holds
   table, payment picker and button; the picker rules above already match
   (the body carries woocommerce-checkout too). [css-202] */
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review {
  max-width: 660px; margin: 0 auto;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: var(--pf-flow-card-r); padding: var(--pf-flow-card-pad);
  box-shadow: var(--pf-shadow);
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table {
  width: 100%; margin: 0; border: 0; border-collapse: collapse; background: transparent;
}
/* Same cell treatment as the checkout review table (css-118): Astra zeroes
   borders at (1,2,2), so (1,3,3) here. */
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table th,
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table td {
  padding: 12px 0; border: 0; border-top: 1px solid var(--pf-line);
  background: transparent; vertical-align: top;
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table thead th {
  padding: 0 0 10px; border: 0; border-bottom: 1.5px solid var(--pf-line);
  font-family: 'Inter', system-ui, sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--pf-ink-2);
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table tbody tr:first-child th,
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table tbody tr:first-child td {
  border-top: 0;
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table th:last-child,
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review table.shop_table td:last-child { text-align: right; }
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review td.product-name {
  font-family: var(--pf-font-serif); font-size: 15.5px;
  font-weight: 600; color: var(--pf-ink); line-height: 1.35;
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review tbody .product-quantity {
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px;
  font-weight: 600; color: var(--pf-ink-2);
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review tfoot th {
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px; font-weight: 600;
  color: var(--pf-ink-2); text-align: left; text-transform: none; letter-spacing: 0;
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review tfoot td { font-size: 14.5px; }
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review tfoot small {
  font-size: 11.5px; font-weight: 400; color: var(--pf-ink-2);
}
/* "Razem:" carries no class, but php-111 removes the row after it (the
   redundant payment-method line), so the total is always the last tfoot row.
   `td >` keeps the VAT small-print's own .amount out of the big type. */
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review tfoot tr:last-child td > .amount {
  font-family: var(--pf-font-serif); font-size: 21px; font-weight: 700;
  color: var(--pf-terra-dark);
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review tfoot tr:last-child small .amount {
  font-family: 'Inter', system-ui, sans-serif; font-size: 11.5px; font-weight: 600;
}
body.woocommerce-order-pay.pf-flow .woocommerce form#order_review #payment ul.payment_methods {
  margin-top: 8px;
}

/* --- 3g.7 order received (thank you) ---
   Written from Woo's thankyou.php and verified by placing one real order and
   deleting it. Reachable only with `bacs`, which is QA scaffolding.
   [css-120] */
body.woocommerce-checkout.pf-flow .woocommerce-order p.woocommerce-notice--success {
  padding: 0; margin: 0 0 26px; border: 0; background: transparent;
  font-family: var(--pf-font-serif); font-size: 19px; color: var(--pf-ink);
}
body.woocommerce-checkout.pf-flow .woocommerce-order p.woocommerce-notice--success::before { content: none; }
body.woocommerce-checkout.pf-flow ul.woocommerce-order-overview {
  list-style: none; margin: 0 0 34px; padding: 22px 24px;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; box-shadow: var(--pf-shadow);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 18px 26px;
}
body.woocommerce-checkout.pf-flow ul.woocommerce-order-overview li {
  margin: 0; padding: 0; border: 0; float: none; text-transform: none;
  font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow ul.woocommerce-order-overview li strong {
  display: block; margin-top: 6px;
  font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600;
  letter-spacing: 0; text-transform: none; color: var(--pf-ink);
}
/* The details block gets the same paper card as the overview above it and the
   addresses below it — without one it was the only bare section on the page, so
   the eye read the table as floating loose between two cards. The account-side
   view-order page has the same shape, so it takes the rule, not a copy. */
body.woocommerce-checkout.pf-flow .woocommerce-order-details,
body.woocommerce-account.pf-flow .woocommerce-order-details {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 22px 24px; margin-bottom: 26px;
}
body.woocommerce-checkout.pf-flow .woocommerce-customer-details {
  margin-bottom: 30px;
}
body.pf-flow .woocommerce table.order_details { margin-bottom: 0; }
/* Astra gives all three titles the #FBFBFB band, so it has to be cleared
   here too, not just on the tables. [css-121] */
/* FOUR classes and an element, because Astra's is (0,4,1). The first try at
   (0,3,1) won the serif family and lost everything else. gotcha 53 [css-122] */
body.pf-flow.woocommerce-checkout .woocommerce-order h2.woocommerce-order-details__title,
body.pf-flow.woocommerce-checkout .woocommerce-order h2.woocommerce-column__title,
body.pf-flow.woocommerce-checkout .woocommerce-customer-details h2.woocommerce-column__title {
  font-family: var(--pf-font-serif); font-weight: 600;
  background: transparent; border: 0; padding: 0; margin: 0 0 16px;
}
body.pf-flow.woocommerce-checkout .woocommerce-order h2.woocommerce-order-details__title { font-size: 21px; }
body.pf-flow.woocommerce-checkout .woocommerce-order h2.woocommerce-column__title { font-size: 18px; }

/* The order-details table, styled to match the cart's rather than left on Woo's
   #DDD hairlines — same component, two pages apart, and a customer sees them
   about a minute apart. */
body.pf-flow .woocommerce table.order_details thead th {
  padding: 0 0 12px; border: 0; border-bottom: 1.5px solid var(--pf-line);
  background: transparent; text-align: left;
  font-family: 'Inter', system-ui, sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--pf-ink-2);
}
body.pf-flow .woocommerce table.order_details tbody td,
body.pf-flow .woocommerce table.order_details tbody th,
body.pf-flow .woocommerce table.order_details tfoot td,
body.pf-flow .woocommerce table.order_details tfoot th {
  padding: 13px 0; border: 0; border-top: 1px solid var(--pf-line);
  background: transparent; vertical-align: top;
}
body.pf-flow .woocommerce table.order_details tbody tr:first-child td,
body.pf-flow .woocommerce table.order_details tbody tr:first-child th { border-top: 0; }
body.pf-flow .woocommerce table.order_details td.woocommerce-table__product-name,
body.pf-flow .woocommerce table.order_details tbody th {
  font-family: var(--pf-font-serif); font-size: 15.5px; font-weight: 600; color: var(--pf-ink);
}
body.pf-flow .woocommerce table.order_details tfoot th {
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px; font-weight: 600; color: var(--pf-ink-2);
}
body.pf-flow .woocommerce table.order_details tfoot tr:last-child td .amount {
  font-family: var(--pf-font-serif); font-size: 21px; font-weight: 700; color: var(--pf-terra-dark);
}
/* Zapłać/Anuluj in the details footer (pending orders): Woo prints bare anchors,
   so css-077 painted two identical primaries touching. Margins, not flex on the
   td (gotcha 126); Anuluj demoted to css-078's quiet outline. [css-201] */
body.pf-flow .woocommerce table.order_details .order-actions-button {
  margin: 3px 10px 3px 0; min-height: 44px; padding: 0 20px; font-size: 14px;
}
body.pf-flow .woocommerce table.order_details a.cancel.order-actions-button {
  background: transparent; color: var(--pf-terra-dark);
  border: 1.5px solid var(--pf-line); font-weight: 600;
}
body.pf-flow .woocommerce table.order_details a.cancel.order-actions-button:hover {
  background: var(--pf-bg-alt); border-color: var(--pf-terra);
}

/* One card per address, title inside it — Woo splits the title and the <address>
   into two siblings, and styling them separately gave a banded header box
   floating above a bordered box. The card lives on the column; the address
   itself keeps no chrome. */
body.woocommerce-checkout.pf-flow .woocommerce-columns--addresses {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px;
}
body.woocommerce-checkout.pf-flow .woocommerce-columns--addresses .woocommerce-column {
  width: auto; float: none;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 22px;
}
body.woocommerce-checkout.pf-flow .woocommerce-customer-details address {
  padding: 0; border: 0; border-radius: 0; background: transparent;
  font-style: normal; font-size: 14.5px; line-height: 1.7; color: var(--pf-ink-2);
}
/* Woo prefixes these lines with glyphs from its own icon font, which is not
   loaded here, so both rendered as tofu squares. [css-123] */
body.woocommerce-checkout.pf-flow .woocommerce-customer-details--phone::before,
body.woocommerce-checkout.pf-flow .woocommerce-customer-details--email::before {
  content: none;
}
body.woocommerce-checkout.pf-flow .woocommerce-customer-details--phone,
body.woocommerce-checkout.pf-flow .woocommerce-customer-details--email {
  padding-left: 0; margin: 0;
}

/* Somewhere to go next. Woo ends the flow with a full stop and no exit. */
.pf-flow-done-cta { margin-top: 8px; }

/* --- 3g.7b BLIK "potwierdź w aplikacji" waiting panel ---
   Paynow injects <div.paynow-confirm-blik><h2>+<img> on `before_thankyou` while a
   BLIK order is pending; the img is an off-brand blue phone. Hide it, reframe the
   block as a paper card with a pulsing terracotta phone badge; the instruction
   line is a real <p> from the hook in functions.php. [css-174] */
body.woocommerce-order-received.pf-flow .paynow-confirm-blik {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  max-width: 460px; margin: 4px auto 0; padding: 30px 26px 24px;
  background: var(--pf-paper); border: 1px solid var(--pf-line); border-bottom: 0;
  border-radius: 20px 20px 0 0;
}
body.woocommerce-order-received.pf-flow .paynow-confirm-blik img { display: none; }
/* One element carries the disc fill, the phone (baked terracotta into the
   data-URI) and the pulsing ring — no mask/box-shadow clash. */
body.woocommerce-order-received.pf-flow .paynow-confirm-blik::before {
  content: ""; width: 84px; height: 84px; border-radius: 50%;
  background: var(--pf-terra-soft)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23BC5A20' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='7' y='2' width='10' height='20' rx='2.5'/%3E%3Cline x1='10.5' y1='18' x2='13.5' y2='18'/%3E%3C/svg%3E")
    center / 38px no-repeat;
  animation: pf-blik-pulse 1.8s ease-out infinite;
}
body.woocommerce-order-received.pf-flow .paynow-confirm-blik h2 {
  font-family: var(--pf-font-serif); font-size: 22px; font-weight: 600;
  color: var(--pf-terra-dark); background: none; padding: 0; margin: 18px 0 0;
}
/* The instruction line: a real <p> from petfly_blik_wait_help(), styled as the
   lower half of the same card. A missing <p> just leaves a clean rounded card. */
body.woocommerce-order-received.pf-flow .pf-blik-help {
  max-width: 460px; margin: 0 auto 26px; padding: 12px 26px 24px;
  background: var(--pf-paper); border: 1px solid var(--pf-line); border-top: 0;
  border-radius: 0 0 20px 20px; box-shadow: var(--pf-shadow);
  text-align: center; font-size: 14px; line-height: 1.6; color: var(--pf-ink-2);
}
body.woocommerce-order-received.pf-flow .pf-blik-help strong { color: var(--pf-ink); font-weight: 700; }
@keyframes pf-blik-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(188, 90, 32, .38); }
  70%  { box-shadow: 0 0 0 17px rgba(188, 90, 32, 0); }
  100% { box-shadow: 0 0 0 0 rgba(188, 90, 32, 0); }
}
@media (prefers-reduced-motion: reduce) {
  body.woocommerce-order-received.pf-flow .paynow-confirm-blik::before { animation: none; }
}

/* --- 3g.8 my account (login / register / lost password / the logged-in area) ---
   Same Woo-shortcode-on-a-page shape as the flow, so it takes `pf-flow` and
   inherits every generic rule above. Only the frames are its own. [css-124] */
body.woocommerce-account.pf-flow .entry-content > .woocommerce {
  display: grid; align-items: start;
  grid-template-columns: 250px minmax(0, 1fr); gap: 0 40px;
}
/* Astra floats these at 30%/68% (0,2,0 each). Ours are (0,3,1). */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation,
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content {
  float: none; width: auto;
}
/* Everything spans; only the nav and content pane are placed. Listing what
   should span quietly dropped anything off the list into the 250px nav
   column. gotcha 55 [css-125] */
body.woocommerce-account.pf-flow .entry-content > .woocommerce > * { grid-column: 1 / -1; }
body.woocommerce-account.pf-flow .entry-content > .woocommerce > .woocommerce-MyAccount-navigation { grid-column: 1; }
body.woocommerce-account.pf-flow .entry-content > .woocommerce > .woocommerce-MyAccount-content { grid-column: 2; }

body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 4px;
}
/* Astra's inline `body .woocommerce-MyAccount-navigation-link` (0,1,1) gives
   each item a full border with `border-bottom-width: 0`, which stacks into one
   boxed list with a missing bottom edge. Ours is (0,3,2). */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li {
  margin: 0; border: 0; list-style: none;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li a {
  display: block; padding: 11px 15px; border-radius: 12px;
  font-size: 14px; font-weight: 600; color: var(--pf-ink-2); text-decoration: none;
  transition: background .14s, color .14s;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li a:hover {
  background: var(--pf-bg-alt); color: var(--pf-terra-dark);
}
/* Beats Astra's `body .woocommerce-MyAccount-navigation-link.is-active a`
   (0,2,2), whose #fbfbfb is the same off-brand grey as the address titles. */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li.is-active a {
  background: var(--pf-terra); color: #fff;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li a:focus-visible {
  outline: 2px solid var(--pf-terra); outline-offset: 2px;
}

/* The login and register cards. `#customer_login` only exists in the DOM once
   `woocommerce_enable_myaccount_registration` is on — before that Woo prints the
   login form bare, with no wrapper at all, which is why both shapes are styled. */
body.woocommerce-account.pf-flow form.login,
body.woocommerce-account.pf-flow form.register,
body.woocommerce-account.pf-flow form.woocommerce-ResetPassword,
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content > form {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 26px; margin: 0;
  max-width: 520px;
}
/* Astra's inline `body .woocommerce form.register` (0,2,2) sets its own border,
   20px padding, `margin: 2em 0` and a 5px radius. (0,3,2) here. */
body.woocommerce-account.pf-flow .woocommerce form.register { margin: 0; border-radius: 20px; }
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content > form { max-width: none; }
body.woocommerce-account.pf-flow #customer_login {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 26px;
  align-items: start;
}
/* Astra floats `.col2-set .col-1/.col-2` at 48% (0,3,1); inside a grid the
   floats are ignored but the widths are not. (0,4,2) here. */
body.woocommerce-account.pf-flow #customer_login > .u-column1,
body.woocommerce-account.pf-flow #customer_login > .u-column2 {
  float: none; width: auto;
}
body.woocommerce-account.pf-flow #customer_login > div > form { max-width: none; height: auto; }
/* Woo emits a bare <h2> above each column ("Logowanie" / "Rejestracja") with no
   class of its own, and Astra sizes bare h2 at 40px 'Lexend'. */
body.woocommerce-account.pf-flow .entry-content .woocommerce > h2,
body.woocommerce-account.pf-flow .entry-content #customer_login h2 {
  font-family: var(--pf-font-serif); font-size: 22px; font-weight: 600;
  margin: 0 0 16px; color: var(--pf-ink);
}
/* The remember-me row and the lost-password link. Both are `p.form-row`, so the
   generic row rule already spaces them; they just need to stop looking like
   fields. */
body.woocommerce-account.pf-flow .woocommerce-form-login__rememberme {
  display: inline-flex; align-items: center; margin: 0;
  font-size: 13.5px; font-weight: 500; color: var(--pf-ink-2); cursor: pointer;
}
body.woocommerce-account.pf-flow .woocommerce-LostPassword {
  margin: 14px 0 0; font-size: 13.5px;
}
/* The reset form's one field is Woo's `form-row-first`, a half-width float
   (css-116) — a 244px input in a 520px card. The SET-password form of the same
   class pairs `-first` with `-last`, so both are named or the pair goes 100/50.
   [css-184] */
body.pf-flow form.woocommerce-ResetPassword .form-row-first,
body.pf-flow form.woocommerce-ResetPassword .form-row-last { float: none; width: 100%; }
/* That page prints ONE form, so a 520px card in a 1180px measure reads as a
   half-empty column. Centre the card and the heading over it. [css-186] */
/* `width` IS THE FIX, not `max-width`: the card is a grid item of §3g.8's grid,
   and `margin-inline: auto` suppresses the stretch, so the width resolved to
   fit-content — 265px empty, snapping to 520px when the strength meter injected
   its sentence. gotcha 93 [css-186] */
@media (min-width: 601px) {
  body.woocommerce-lost-password.pf-flow form.woocommerce-ResetPassword {
    width: min(520px, 100%); margin-inline: auto;
  }
  body.woocommerce-lost-password.pf-flow .entry-header { text-align: center; }
}
/* Each auth card holds one action, so the submit takes the card's width; a 130px
   button under a full-width field reads unfinished. [css-185] */
body.woocommerce-account.pf-flow form.login button.button,
body.woocommerce-account.pf-flow form.register button.button,
body.woocommerce-account.pf-flow form.woocommerce-ResetPassword button.button {
  display: flex; width: 100%;
}
/* Woo's JS strength meter (`#password_strength` + a `<small>` hint) lands on the
   set-password and account-details forms. Astra replaces Woo's stylesheet, so it
   arrived in WP-admin pink with a blue border. gotcha 36 [css-187] */
/* A dot and a coloured label, NOT a bordered box: in a card of rounded inputs a
   boxed status message reads as another empty field. Same shape as the order
   status (css-183). */
body.pf-flow .woocommerce .woocommerce-password-strength {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 10px 0 0; padding: 0; border: 0; background: none;
  color: var(--pf-ink-2);
  font-family: 'Inter', system-ui, sans-serif; font-size: 13.5px; font-weight: 700;
  text-align: left; text-transform: none;
}
body.pf-flow .woocommerce .woocommerce-password-strength::before {
  content: ""; flex: none;
  width: 9px; height: 9px; border-radius: 50%; background: currentColor;
}
/* THE BLUE RING AGAIN: the meter is focused programmatically, so Chrome outlines
   it on the spot. Same fix as the notices. gotcha 46 */
body.pf-flow .woocommerce .woocommerce-password-strength:focus,
body.pf-flow .woocommerce .woocommerce-password-strength:focus-visible { outline: none; }
/* `short` doubles as the mismatch state (Woo's case 5), which is also a fault. */
body.pf-flow .woocommerce .woocommerce-password-strength.short,
body.pf-flow .woocommerce .woocommerce-password-strength.bad { color: var(--pf-terra-dark); }
/* Navy, not gold: #D9A05B on cream is too pale for 13.5px text. */
body.pf-flow .woocommerce .woocommerce-password-strength.good { color: var(--pf-navy); }
body.pf-flow .woocommerce .woocommerce-password-strength.strong { color: var(--pf-olive); }
body.pf-flow .woocommerce .woocommerce-password-hint {
  display: block; margin: 8px 0 0;
  font-size: 12.5px; line-height: 1.55; color: var(--pf-ink-2);
}
/* The same script DISABLES the submit below the strength floor. Astra paints that
   pale terracotta with white text, which reads broken rather than blocked, and it
   is the state a shopper meets first. [css-188] */
body.pf-flow .woocommerce button.button.disabled,
body.pf-flow .woocommerce button.button:disabled,
body.pf-flow .woocommerce button.button[disabled] {
  background: var(--pf-bg-alt); color: var(--pf-ink-2);
  border-color: var(--pf-line); cursor: not-allowed;
}


body.woocommerce-account.pf-flow .woocommerce-LostPassword a {
  font-weight: 600; color: var(--pf-terra-dark); text-decoration: none;
  border-bottom: 1.5px solid var(--pf-gold); padding-bottom: 1px;
}
body.woocommerce-account.pf-flow .woocommerce-LostPassword a:hover {
  color: var(--pf-ink); border-color: var(--pf-terra);
}
/* Woo's show/hide-password toggle draws itself from the WooCommerce icon
   font, which is not loaded here — a tofu square on a returning customer's
   first control. [css-126] */
/* Stretched, not centred with `top:50%`: `.password-input` is a SPAN, so its
   height is a line box, not the input's box, and the arithmetic was 20px
   out. [css-127] */
body.pf-flow .woocommerce .show-password-input {
  position: absolute; top: 0; bottom: 0; right: 6px; height: auto;
  width: 40px; padding: 0; margin: 0; cursor: pointer;
  border: 0; background: transparent;
  display: grid; place-items: center; border-radius: 12px;
  /* `translate: none` IS THE FIX: Woo uses the STANDALONE `translate`
     property, so resetting `transform` does nothing and `getComputedStyle`
     reports `none`. gotcha 39 [css-128] */
  translate: none;
  flex: none;
}
body.pf-flow .woocommerce .show-password-input::after {
  content: ""; display: block; width: 20px; height: 20px;
  font-family: inherit; font-size: 0; background: var(--pf-ink-2);
  -webkit-mask: var(--pf-mask-eye) center / contain no-repeat;
          mask: var(--pf-mask-eye) center / contain no-repeat;
}
body.pf-flow .woocommerce .show-password-input.display-password::after {
  background: var(--pf-terra-dark);
  -webkit-mask-image: var(--pf-mask-eye-off); mask-image: var(--pf-mask-eye-off);
}
body.pf-flow .woocommerce .show-password-input:hover { background: var(--pf-bg-alt); }
/* Woo wraps the field in `<span class="password-input">` and relies on it being
   positioned for the toggle above. Leave room so the glyph never sits on text. */
/* Woo's own is `display: flex; flex-direction: column; justify-content: center`,
   so `flex-direction` has to be named explicitly — inheriting `column` here put
   the toggle in a column track rather than beside the field. */
body.pf-flow .woocommerce .password-input {
  position: relative; display: flex; flex-direction: row; align-items: stretch;
}
body.pf-flow .woocommerce .password-input > input { flex: 1 1 auto; min-width: 0; }
body.pf-flow .woocommerce .password-input input.input-text,
body.pf-flow .woocommerce .password-input input.woocommerce-Input { padding-right: 52px; }

/* --- the register form ---
   LIVE since 0.2.63: `woocommerce_enable_myaccount_registration` is on, so Woo
   renders the register column. Turning it off hides everything below.
   [css-129] */
body.woocommerce-account.pf-flow .woocommerce-privacy-policy-text p {
  font-size: 12px; line-height: 1.55; color: var(--pf-ink-2); margin: 0 0 14px;
}
body.woocommerce-account.pf-flow .woocommerce-privacy-policy-text a { color: var(--pf-terra-dark); text-decoration: underline; }
/* Our RODO consent row (petfly_consent_row). A real <label> wrapping
   the box, so the whole line is the target, and `align-items: flex-start`
   because the text wraps to two lines at every width worth supporting. */
.pf-consent-row { margin: 0 0 18px; }
.pf-consent-row label {
  display: flex; align-items: flex-start; gap: 10px; margin: 0; cursor: pointer;
  font-size: 12.5px; line-height: 1.5; font-weight: 400; color: var(--pf-ink-2);
  text-transform: none; letter-spacing: 0;
}
.pf-consent-row input[type="checkbox"] { margin-top: 2px; }
.pf-consent-row .required { color: var(--pf-terra-dark); font-weight: 700; }
.pf-consent-row a { color: var(--pf-terra-dark); text-decoration: underline; }

/* Checkout's "Stwórz konto?" offer, styled to MATCH the "Wysłać na inny adres?"
   card exactly (css-114/115): a sibling card in the same stack, its checkbox the
   serif heading. Woo prints it as a bare checkbox that vanishes into the form. [css-196] */
body.woocommerce-checkout.pf-flow .woocommerce-account-fields {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 24px; margin: 26px 0 0;
}
body.woocommerce-checkout.pf-flow .woocommerce-account-fields p.create-account { margin: 0; }
body.woocommerce-checkout.pf-flow .woocommerce-account-fields p.create-account > label {
  display: flex; align-items: center; margin: 0; cursor: pointer;
  font-family: var(--pf-font-serif); font-size: 17px; font-weight: 600; color: var(--pf-ink);
}
body.woocommerce-checkout.pf-flow .woocommerce-account-fields p.create-account span { font: inherit; }

/* The returning-customer login form, revealed under the "Powracający klient?"
   info box. Woo prints it as raw controls — no wrapper — beside the boxed
   billing fields; the account card (§3g.10) is scoped to .woocommerce-account
   and never reaches here, so give it the same card. [css-197] */
body.woocommerce-checkout.pf-flow form.woocommerce-form-login.login {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 24px 28px; margin: 8px 0 32px;
}
body.woocommerce-checkout.pf-flow form.woocommerce-form-login.login > p:first-of-type {
  margin-top: 0; color: var(--pf-ink-2); font-size: 13.5px;
}
body.woocommerce-checkout.pf-flow form.woocommerce-form-login button.button { display: flex; width: 100%; }
body.woocommerce-checkout.pf-flow .woocommerce-form-login__rememberme {
  display: inline-flex; align-items: center; margin: 0;
  font-size: 13.5px; font-weight: 500; color: var(--pf-ink-2); cursor: pointer;
}
body.woocommerce-checkout.pf-flow .woocommerce-LostPassword { margin: 14px 0 0; font-size: 13.5px; }
body.woocommerce-checkout.pf-flow .woocommerce-LostPassword a {
  font-weight: 600; color: var(--pf-terra-dark); text-decoration: none;
  border-bottom: 1.5px solid var(--pf-gold); padding-bottom: 1px;
}
body.woocommerce-checkout.pf-flow .woocommerce-LostPassword a:hover {
  color: var(--pf-ink); border-color: var(--pf-terra);
}

/* The accept-terms checkbox (Woo's #terms, present once terms_page_id is set).
   It lands in the payment column as a cramped default control; match it to the
   consent rows so the two read as one family. Scoped to the terms wrapper so it
   never touches the ship-to-different toggle sharing its classes. [css-198] */
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper { margin: 2px 0 16px; }
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper .form-row.validate-required {
  margin: 14px 0 0; padding: 0;
}
/* Hanging indent, not flex: Woo prints the `*` as an `<abbr>` SIBLING of the
   text span, so a flex label makes it a third item that jumps to the row end.
   Absolute-positioning the box lets the text and its `*` flow inline. */
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper label.woocommerce-form__label-for-checkbox {
  display: block; position: relative; margin: 0; padding-left: 28px; cursor: pointer;
  font-size: 12.5px; line-height: 1.5; font-weight: 400; color: var(--pf-ink-2);
}
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper label input[type="checkbox"] {
  position: absolute; left: 0; top: 2px; margin: 0;
}
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-checkbox-text a { color: var(--pf-terra-dark); font-weight: 600; text-decoration: underline; }
body.woocommerce-checkout.pf-flow .woocommerce-terms-and-conditions-wrapper .required {
  color: var(--pf-terra-dark); font-weight: 700; border: 0; text-decoration: none;
}

/* The account-benefits list beside the register form, so the column is an
   argument for making an account rather than just a second box. */
.pf-account-why { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 8px; }
.pf-account-why li {
  display: flex; align-items: center; gap: 9px; margin: 0;
  font-size: 13px; color: var(--pf-ink-2);
}
.pf-account-why .pf-i { color: var(--pf-olive); flex: none; }

/* Dashboard quick-actions: three ways on in the shop's card style, so the
   account home is not two lines of bare Woo link-prose. Printed by
   petfly_account_dashboard_cards() on `woocommerce_account_dashboard`. [css-176] */
.pf-dash-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 14px; margin: 22px 0 0;
}
.pf-dash-card {
  display: flex; flex-direction: column; gap: 3px; padding: 18px;
  border: 1px solid var(--pf-line); border-radius: 16px; background: var(--pf-paper);
  text-decoration: none; transition: border-color .14s, transform .14s;
}
.pf-dash-card:hover { border-color: var(--pf-gold); transform: translateY(-2px); }
.pf-dash-card:focus-visible { outline: 2px solid var(--pf-terra); outline-offset: 2px; }
.pf-dash-card .pf-i { color: var(--pf-terra); margin-bottom: 8px; }
.pf-dash-card-t { font-family: var(--pf-font-serif); font-size: 16px; color: var(--pf-ink); }
.pf-dash-card-d { font-size: 12.5px; color: var(--pf-ink-2); }

/* The logged-in area. */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content > p { color: var(--pf-ink-2); }
body.woocommerce-account.pf-flow .entry-content .woocommerce-MyAccount-content h2,
body.woocommerce-account.pf-flow .entry-content .woocommerce-MyAccount-content h3 {
  font-family: var(--pf-font-serif); font-size: 21px; margin: 0 0 16px;
}
/* Astra zeroes the fieldset border and hangs a full-width bottom rule off the
   legend (0,2,1 / 0,2,2). A legend that is a heading should look like one. */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content fieldset {
  border: 0; border-top: 1px solid var(--pf-line);
  margin: 26px 0 0; padding: 22px 0 0;
}
/* `float:left; width:100%` is load-bearing: a `<legend>` renders IN its
   fieldset's top border, so the heading sat on the section rule. [css-130] */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content fieldset legend {
  border: 0; float: left; width: 100%; margin: 0 0 16px; padding: 0;
  font-family: var(--pf-font-serif); font-size: 18px; font-weight: 600; color: var(--pf-ink);
}
/* THE HIGH-WATER MARK: Astra's edit-account focus rule is SIX classes,
   (0,6,0), and beats the generic focus rule outright. [css-131] */
body.pf-flow .woocommerce .woocommerce-MyAccount-content .woocommerce-EditAccountForm .woocommerce-form-row .woocommerce-Input.input-text:focus,
body.pf-flow .woocommerce .woocommerce-address-fields .woocommerce-address-fields__field-wrapper .woocommerce-input-wrapper > .input-text:focus,
body.pf-flow .woocommerce .woocommerce-billing-fields .woocommerce-billing-fields__field-wrapper .woocommerce-input-wrapper > .input-text:focus {
  border: 1.5px solid var(--pf-terra); background: var(--pf-paper); outline: none;
}
/* And the matching one for the submit buttons, whose ring is also a border
   (`.woocommerce .woocommerce-MyAccount-content form button:focus`, 0,2,2). */
body.pf-flow .woocommerce .woocommerce-MyAccount-content form button:focus-visible {
  border-style: solid; border-color: var(--pf-ink);
}
/* Astra pushes this button 1em down and 3px right (0,3,0). */
body.pf-flow .woocommerce-account .woocommerce-EditAccountForm .woocommerce-Button,
body.woocommerce-account.pf-flow .woocommerce-EditAccountForm button.woocommerce-Button {
  margin: 22px 0 0;
}

/* Addresses. Astra paints `.woocommerce-Address-title` with a hard-coded
   #fbfbfb band and a border (0,3,0) — the same cold grey as the cart summary
   heading, and the same fix. */
body.woocommerce-account.pf-flow .woocommerce-Addresses {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px;
}
body.woocommerce-account.pf-flow .woocommerce-Addresses > .woocommerce-Address {
  float: none; width: auto;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 22px;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title {
  background: transparent; border: 0; padding: 0; margin: 0 0 12px;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
/* Astra hangs a clearfix `::before`/`::after` on the title; inside a flex row they
   become items, and the `gap` shoved the h2 16px right of the card edge. gotcha 37 */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title::before,
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title::after {
  content: none;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title h2,
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title h3 {
  float: none; padding: 0; margin: 0; font-size: 18px;
}
/* The edit link as a pencil + "Edytuj": the real "Edytuj Adres…" text is kept as
   the accessible name (font-size:0 hides it visually, screen readers still read
   it), the ::after paints the short visible label. [css-177] */
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title a.edit {
  float: none; padding: 0; flex: none; font-size: 0;
  display: inline-flex; align-items: center; gap: 5px; text-decoration: none;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title a.edit::before {
  content: ""; width: 15px; height: 15px; background: var(--pf-terra-dark);
  -webkit-mask: var(--pf-mask-pencil) center / contain no-repeat;
          mask: var(--pf-mask-pencil) center / contain no-repeat;
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title a.edit::after {
  content: "Edytuj"; font-size: 13px; font-weight: 600; color: var(--pf-terra-dark);
}
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title a.edit:hover::after { color: var(--pf-ink); }
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content .woocommerce-Address-title a.edit:hover::before { background: var(--pf-ink); }
body.woocommerce-account.pf-flow .woocommerce-MyAccount-content address {
  border: 0; padding: 0; border-radius: 0; background: transparent;
  font-style: normal; font-size: 14.5px; line-height: 1.65; color: var(--pf-ink-2);
}

/* The orders table. Astra sets it at .85em with 4px/8px cells (0,2,1 / 0,2,2)
   and forces the actions cell to `display: block` (0,3,2), which on desktop
   drops the buttons onto their own line inside the cell. */
body.woocommerce-account.pf-flow .woocommerce table.my_account_orders,
body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table {
  font-size: 14.5px; border: 0; border-collapse: collapse; width: 100%;
}
body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table th {
  padding: 0 12px 12px; border: 0; border-bottom: 1.5px solid var(--pf-line);
  background: transparent; text-align: left;
  font-family: 'Inter', system-ui, sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--pf-ink-2);
}
body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table td {
  padding: 16px 12px; border: 0; border-bottom: 1px solid var(--pf-line);
  vertical-align: middle;
}
/* The order-number cell is a <th>, so the `td` rule above never reached it and
   Astra's `0 0 12px` row-header padding lifted it ~6px above the rest of the row
   (Tomek's red line, 2026-08-27). Match the data cells. [css-182] */
body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table th.woocommerce-orders-table__cell-order-number {
  padding: 16px 12px; border: 0; border-bottom: 1px solid var(--pf-line);
  vertical-align: middle;
}
body.woocommerce-account.pf-flow .woocommerce table.shop_table td.woocommerce-orders-table__cell-order-actions {
  display: table-cell; text-align: right; white-space: nowrap;
}
body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table a.woocommerce-button {
  min-height: 38px; padding: 0 15px; font-size: 13px; border-radius: 11px;
}
/* Order status in the list is a BARE TEXT NODE (no <mark>), so the colour keys
   off the ROW's `--status-<slug>` class and a ::before dot carries the hue —
   at-a-glance without the loud pill. All tones are legible on paper. [css-175] */
body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-status {
  font-size: 12.5px; font-weight: 700; color: var(--pf-ink-2); white-space: nowrap;
}
body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-status::before {
  content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 7px;
  border-radius: 50%; background: currentColor; vertical-align: middle;
}
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-completed .woocommerce-orders-table__cell-order-status { color: var(--pf-olive); }
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-processing .woocommerce-orders-table__cell-order-status { color: var(--pf-navy); }
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-on-hold .woocommerce-orders-table__cell-order-status,
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-pending .woocommerce-orders-table__cell-order-status { color: var(--pf-terra); }
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-cancelled .woocommerce-orders-table__cell-order-status,
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-failed .woocommerce-orders-table__cell-order-status,
body.woocommerce-account.pf-flow .woocommerce-orders-table__row--status-refunded .woocommerce-orders-table__cell-order-status { color: var(--pf-ink-2); }
body.woocommerce-account.pf-flow mark.order-status,
body.woocommerce-account.pf-flow mark.order-number,
body.woocommerce-account.pf-flow mark.order-date {
  background: var(--pf-bg-alt); color: var(--pf-ink);
  padding: 2px 9px; border-radius: 999px; font-weight: 600;
}

/* Order notes on a single order. */
body.woocommerce-account.pf-flow ol.woocommerce-OrderUpdates {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 12px;
}
body.woocommerce-account.pf-flow li.woocommerce-OrderUpdate {
  margin: 0; padding: 16px 18px; border: 1px solid var(--pf-line);
  border-radius: 16px; background: var(--pf-paper);
}
body.woocommerce-account.pf-flow .woocommerce-OrderUpdate-meta {
  font-size: 12px; color: var(--pf-ink-2); margin: 0 0 6px;
}
body.woocommerce-account.pf-flow .woocommerce-OrderUpdate-description p:last-child { margin-bottom: 0; }

/* Pagination on the orders list — the "without-numbers" variant, so it is two
   buttons rather than the numbered family in gotcha 23. */
body.woocommerce-account.pf-flow .woocommerce-pagination--without-numbers {
  display: flex; gap: 10px; margin-top: 22px;
}

/* --- 3g.8b account refinements (Tomek's 2026-08-27 review) ------------------ */

/* The Furgonetka "Zleć zwrot" button is dropped from the orders LIST in PHP; on
   the single order it stays but must not read as a primary action — a quiet
   text link, not a terracotta button. [css-178] */
body.pf-flow .woocommerce a.furgonetka_return.order-actions-button {
  background: transparent; border: 0; color: var(--pf-ink-2); box-shadow: none;
  min-height: 0; padding: 0; font-size: 13.5px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--pf-line);
}
body.pf-flow .woocommerce a.furgonetka_return.order-actions-button:hover {
  background: transparent; color: var(--pf-terra-dark); text-decoration-color: var(--pf-gold);
}

/* The order-details / addresses titles on the account side are Astra's grey
   `#fbfbfb` band (`.woocommerce-column__title`, 0,3,0). Same fix as the
   order-received page: serif, no band, no border. [css-179] */
body.woocommerce-account.pf-flow .woocommerce-column__title,
body.woocommerce-account.pf-flow .woocommerce-order-details__title {
  font-family: var(--pf-font-serif); font-size: 18px; font-weight: 600;
  color: var(--pf-ink); background: transparent; border: 0; padding: 0; margin: 0 0 12px;
}
/* …and the two section titles inside the details card take the order-received
   size, so the same order reads the same on both pages. */
body.woocommerce-account.pf-flow .woocommerce-order-details__title { font-size: 21px; margin-bottom: 16px; }
body.woocommerce-account.pf-flow .woocommerce-customer-details .woocommerce-column {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 20px; padding: 22px; width: auto; float: none;
}
body.woocommerce-account.pf-flow .woocommerce-customer-details .col2-set {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 22px;
}
body.woocommerce-account.pf-flow .woocommerce-customer-details address {
  border: 0; padding: 0; border-radius: 0; background: transparent;
  font-style: normal; font-size: 14.5px; line-height: 1.7; color: var(--pf-ink-2);
}
body.woocommerce-account.pf-flow .woocommerce-customer-details--phone::before,
body.woocommerce-account.pf-flow .woocommerce-customer-details--email::before { content: none; }
body.woocommerce-account.pf-flow .woocommerce-customer-details--phone,
body.woocommerce-account.pf-flow .woocommerce-customer-details--email { padding-left: 0; margin: 0; }

/* The page heading aligns with the CONTENT column, not the nav. 290px = the
   250px nav track + its 40px gap (§3g.8). Desktop only; the nav is a chip row
   below 921px. Conditional on the nav being in the DOM: login and lost-password
   have none, so the indent hung their h1 over empty paper. [css-180] */
@media (min-width: 1001px) {
  body.woocommerce-account.pf-flow article:has(.woocommerce-MyAccount-navigation) .entry-header {
    padding-left: 290px;
  }
}

/* "Wyświetlana nazwa": hidden. The name shown everywhere is kept equal to first +
   last by petfly's save hook (php-089); the field, its label and its cursive
   caption all sit in one <p>. [css-181] */
body.woocommerce-account.pf-flow .woocommerce-EditAccountForm p.woocommerce-form-row:has(#account_display_name) {
  display: none;
}

/* The dashboard greeting that replaced Woo's two paragraphs of prose (php-087). */
body.woocommerce-account.pf-flow .pf-dash-greet {
  font-family: var(--pf-font-serif); font-size: 20px; color: var(--pf-ink); margin: 0;
  /* The greeting falls back to the e-mail (php-094), and an address has no space
     to break at, so a long one would spill out of the column at 400px. */
  overflow-wrap: anywhere;
}

/* The view-order meta block that replaced the "…złożone DATE jest obecnie
   STATUS." prose (php-091): date and status as two labelled items, the status
   colour-coded exactly like the orders list (css-175). [css-183] */
/* One paper card holding both items, split by a hairline — so the date and
   status read as an order summary, set apart from the details table below. */
body.woocommerce-account.pf-flow .pf-order-meta {
  display: flex; flex-wrap: wrap; width: fit-content; max-width: 100%; margin: 0 0 26px;
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: 16px; box-shadow: var(--pf-shadow); overflow: hidden;
}
.pf-order-meta-item { display: flex; flex-direction: column; gap: 4px; padding: 15px 26px; }
.pf-order-meta-item + .pf-order-meta-item { border-left: 1px solid var(--pf-line); }
.pf-order-meta-label {
  font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--pf-ink-2);
}
.pf-order-meta-val { font-family: var(--pf-font-serif); font-size: 16px; color: var(--pf-ink); }
.pf-order-status {
  font-family: 'Inter', system-ui, sans-serif; font-size: 15px; font-weight: 700;
  display: inline-flex; align-items: center; gap: 8px; color: var(--pf-ink-2);
}
.pf-order-status::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%; background: currentColor;
}
.pf-order-status--completed { color: var(--pf-olive); }
.pf-order-status--processing { color: var(--pf-navy); }
.pf-order-status--on-hold,
.pf-order-status--pending { color: var(--pf-terra); }
.pf-order-status--cancelled,
.pf-order-status--failed,
.pf-order-status--refunded { color: var(--pf-ink-2); }

/* --- 3g.9 responsive ------------------------------------------------------ */

/* The tablet band. The summary column is the first thing to go: at 900px a
   360px sidebar leaves the cart items 480px, which is narrower than the items
   need and wider than the summary deserves. */
@media (max-width: 1000px) {
  body.woocommerce-cart.pf-flow .entry-content > .woocommerce,
  body.woocommerce-checkout.pf-flow .woocommerce form.checkout {
    grid-template-columns: minmax(0, 1fr); gap: 0;
  }
  /* THE PLACEMENTS MUST BE UNDONE, not just the columns: a leftover `grid-
     column: 2` creates an implicit second track and collapsed column 1 to 0px.
     [css-132] */
  body.woocommerce-cart.pf-flow .entry-content > .woocommerce > form.woocommerce-cart-form,
  body.woocommerce-cart.pf-flow .entry-content > .woocommerce > .cart-collaterals {
    grid-column: 1 / -1;
  }
  body.woocommerce-checkout.pf-flow .woocommerce form.checkout {
    /* Three areas, not four — `review-head` went with the heading (3g.6), and
       the stale `grid-template-rows` reset went with it. [css-133] */
    grid-template-areas: "notices" "fields" "review";
  }
  body.woocommerce-cart.pf-flow .woocommerce .cart-collaterals .cart_totals,
  body.woocommerce-checkout.pf-flow .woocommerce #order_review { position: static; }
  /* The air above the summary is now on the CARD, not on a heading that sits
     outside it — same 34px, same place on screen, one element further in. */
  body.woocommerce-checkout.pf-flow .woocommerce form.checkout > #order_review { margin-top: 34px; }
  body.woocommerce-cart.pf-flow .woocommerce .cart-collaterals { margin-top: 8px; }

  /* The account nav becomes a chip row, the same shape `.pf-catnav` uses.
     Astra unfloats these at 921px (0,2,0); this replaces that. It wraps, it
     does not scroll. [css-134] */
  body.woocommerce-account.pf-flow .entry-content > .woocommerce {
    grid-template-columns: minmax(0, 1fr); gap: 0;
  }
  /* Clear the placements too — see the cart's equivalent above for what a
     leftover `grid-column: 2` does to a single-column grid. */
  body.woocommerce-account.pf-flow .entry-content > .woocommerce > .woocommerce-MyAccount-navigation,
  body.woocommerce-account.pf-flow .entry-content > .woocommerce > .woocommerce-MyAccount-content {
    grid-column: 1 / -1;
  }
  body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation {
    margin-bottom: 26px; overflow: visible;
  }
  body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation ul {
    display: flex; gap: 8px; flex-wrap: wrap; width: auto;
  }
  body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li a {
    padding: 9px 13px; font-size: 13.5px; border: 1px solid var(--pf-line);
  }
  body.woocommerce-account.pf-flow .woocommerce-MyAccount-navigation li.is-active a { border-color: var(--pf-terra); }
}

/* --- THE BAND NOBODY WAS LOOKING AT: 601-921px ---
   Astra's stacked-table sheet loads at `max-width:921px` while the card rebuild
   started at 600px, so one cart product became six stacked rows. The fix is the
   card rebuild raised to 921px — putting the real `<table>` back re-enters column
   negotiation and overflows. gotchas 72, 73, 76 [css-135] */
/* SHARED BY BOTH BANDS BELOW 921px — the card-ification itself. Only the
   tracks differ between tablet and phone, so only the tracks are restated. */
@media (max-width: 921px) {
  body.pf-flow .woocommerce table.cart thead { display: none; }
  body.pf-flow .woocommerce table.cart tbody tr.cart_item {
    display: grid; align-items: center;
    padding: 16px 0; border-bottom: 1px solid var(--pf-line);
  }
  body.pf-flow .woocommerce table.cart tbody tr.cart_item:first-child { padding-top: 6px; }
  body.pf-flow .woocommerce table.cart tbody tr.cart_item td {
    display: block; padding: 0; border: 0; width: auto;
    text-align: left !important;
  }
  /* `min-height:0` kills a stagger that only exists once these are grid items
     — Astra ships `#content table.cart td { min-height: 3.25em }` at (1,2,2).
     gotchas 36, 74 [css-136] */
  body.pf-flow #content table.cart tbody tr.cart_item td { min-height: 0; }
  /* Woo's per-cell labels. Redundant the moment the cells are laid out as a
     card — the thumbnail says which product, the stepper says which number. */
  body.pf-flow .woocommerce table.cart tbody tr.cart_item td::before { content: none !important; }
  body.pf-flow .woocommerce table.cart td.product-thumbnail {
    text-align: center !important;
  }
}

@media (min-width: 601px) and (max-width: 921px) {
  body.pf-flow .woocommerce table.cart tbody tr.cart_item {
    grid-template-columns: 44px 84px minmax(0, 1fr) auto auto auto;
    gap: 0 14px;
  }
  body.pf-flow .woocommerce table.cart td.product-subtotal { text-align: right !important; }
  /* Astra's smallscreen sheet left-aligns this one (`table.cart td.actions
     { text-align: left }`); desktop has it right, and at this width the row is
     still wide enough that a left-aligned update button floats away from the
     items it belongs to. */
  body.pf-flow .woocommerce table.cart td.actions { text-align: right !important; }
}

/* The phone: Woo's `shop_table_responsive` made one product six stacked rows
   of ~360px each. gotcha 76 [css-137] */
@media (max-width: 600px) {
  /* Doubled class for the same reason as the desktop rule — Astra's inline
     `.ast-plain-container.ast-no-sidebar #primary { padding: 0 }` lives in a
     `max-width: 921px` block, so on phones it was this declaration it beat. */
  body.pf-flow.pf-flow #primary { padding-block: 16px 48px; }
  .pf-flow-head { margin-bottom: 24px; }
  .pf-flow-head .pf-flow-lead { font-size: 15px; margin-bottom: 18px; }
  /* The step labels go, the pills stay: three words plus two connectors do not
     fit 360px, and the numbers plus the h1 already say where you are. */
  .pf-flow-step .pf-flow-step-l { display: none; }
  .pf-flow-step.is-now .pf-flow-step-l { display: inline; }
  .pf-flow-step + .pf-flow-step::before { width: 22px; margin: 0 8px; }

  /* Card-ification is shared with the tablet band above. Only the TRACKS and
     placements are phone-specific, and the placements are mandatory or these
     cells inherit six columns. [css-138] */
  body.pf-flow .woocommerce table.cart tbody tr.cart_item {
    grid-template-columns: 76px minmax(0, 1fr) auto; gap: 4px 14px;
  }
  body.pf-flow .woocommerce table.cart td.product-thumbnail {
    grid-column: 1; grid-row: 1 / span 3; align-self: start;
  }
  body.pf-flow .woocommerce table.cart td.product-name { grid-column: 2; grid-row: 1; }
  body.pf-flow .woocommerce table.cart td.product-remove {
    grid-column: 3; grid-row: 1; justify-self: end; align-self: start;
  }
  body.pf-flow .woocommerce table.cart td.product-price {
    grid-column: 2 / span 2; grid-row: 2; font-size: 13.5px;
  }
  body.pf-flow .woocommerce table.cart td.product-quantity { grid-column: 2 / -1; grid-row: 3; padding-top: 8px !important; }
  /* Own row: sharing row 3 with the stepper overlapped on a real iPhone SE —
     its wider digits pushed "109,80 zł" under the + button (Tomek 2026-09-10). */
  body.pf-flow .woocommerce table.cart td.product-subtotal {
    grid-column: 2 / -1; grid-row: 4; text-align: right !important; padding-top: 6px !important;
  }
  body.pf-flow .woocommerce table.cart td.actions { text-align: left; }
  /* `margin: 0` is the load-bearing half: Woo/Astra's `margin-left:5px` plus
     `width:100%` spilled 5px all the way up to `#primary`. [css-139] */
  /* `#content` because Astra's is (1,4,2) — the first try at (0,4,4) lost on
     the id alone. gotcha 36 [css-140] */
  body.pf-flow #content table.cart td.actions button.button { width: 100%; margin: 0; }

  /* THE CROSS-SELL GOES HORIZONTAL: at full height two cards cost ~900px on a
     400px screen and pushed the total off the bottom. It is before `.cart-
     collaterals` in the DOM, so CSS cannot reorder it. [css-141] */
  body.pf-flow .pf-cart-xsell { margin-top: 30px; padding-top: 22px; }
  body.pf-flow .entry-content .pf-cart-xsell h2 { font-size: 18px; margin-bottom: 14px; }
  body.pf-flow .pf-cart-xsell .woocommerce ul.products.pf-grid {
    grid-template-columns: 1fr; gap: 10px;
  }
  body.pf-flow .pf-cart-xsell .woocommerce ul.products li.product .pf-card {
    display: grid; grid-template-columns: 72px minmax(0, 1fr);
    align-items: start; gap: 0 14px; padding: 12px;
  }
  body.pf-flow .pf-cart-xsell .woocommerce ul.products li.product .pf-card .pf-card-img {
    margin: 0; display: block; line-height: 0; font-size: 0;
  }
  body.pf-flow .pf-cart-xsell .woocommerce ul.products li.product .pf-card .pf-card-img img {
    width: 72px; height: 72px; aspect-ratio: 1; object-fit: contain;
    object-position: center; border-radius: 12px; background: var(--pf-bg);
  }
  /* (0,6,3) — it has to out-rank the (0,4,3) rule that reserves 46px. */
  body.pf-flow .pf-cart-xsell .woocommerce ul.products li.product .pf-card .pf-card-body {
    padding: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  }
  body.pf-flow .entry-content .pf-cart-xsell .pf-card h3 { font-size: 16px; margin: 0; line-height: 1.25; }
  body.pf-flow .pf-cart-xsell .pf-card .pf-price { margin: 0; font-size: 14px; }
  /* The pill is redundant at this size — the row is 72px tall and the name is
     right there — and it was absolutely positioned over the image. */
  body.pf-flow .pf-cart-xsell .pf-card .pf-tag { display: none; }
  /* Button -> text link, on the same line as nothing else, tight under the price.
     It keeps the accent colour so it still reads as the card's action, without a
     44px block on a 72px row. */
  body.pf-flow .pf-cart-xsell .pf-card .wp-block-buttons { margin: 2px 0 0; }
  body.pf-flow .pf-cart-xsell .woocommerce ul.products li.product .pf-card .wp-block-button .wp-block-button__link {
    background: transparent; color: var(--pf-terra-dark);
    min-height: 0; padding: 0; font-size: 13px; font-weight: 600;
    border: 0; border-bottom: 1.5px solid var(--pf-gold); border-radius: 0;
  }
  body.pf-flow .pf-cart-xsell .pf-card .wp-block-button .wp-block-button__link::before { display: none; }
  body.pf-flow .pf-cart-xsell .pf-acc-navy .wp-block-button .wp-block-button__link { color: var(--pf-navy); }
  body.pf-flow .pf-cart-xsell .pf-acc-olive .wp-block-button .wp-block-button__link { color: var(--pf-olive-dark); }

  /* Retuning the shared tokens (3g.-1), not the rules, is what keeps cart and
     checkout together at this width too. [css-142] */
  body.pf-flow {
    --pf-flow-card-pad: 18px;
    --pf-flow-cta-h: 52px;
    --pf-flow-cta-fs: 15.5px;
    --pf-flow-cta-pad: 20px;
  }
  body.woocommerce-checkout.pf-flow .woocommerce-billing-fields,
  body.woocommerce-checkout.pf-flow .woocommerce-shipping-fields,
  body.woocommerce-checkout.pf-flow .woocommerce-additional-fields { padding: 18px; }

  /* Woo's 47% floats give two ~150px fields side by side at 360px. Stack. */
  body.pf-flow .woocommerce form .form-row-first,
  body.pf-flow .woocommerce form .form-row-last {
    width: 100%; float: none;
  }

  /* ONE REAL BUG FIXED HERE: Woo marks the order number up as `<th
     scope="row">` and Astra's smallscreen CSS hides `tbody th`, so the phone
     lost the cell saying WHICH order. [css-143] */
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table thead { display: none; }
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline; gap: 4px 12px;
    padding: 16px 0; border-bottom: 1px solid var(--pf-line);
  }
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table tbody td,
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table tbody th {
    display: block; padding: 0; border: 0; text-align: left !important;
  }
  /* Woo's per-cell `data-title` labels. Kept only where the value is ambiguous
     on its own — a date and a total are not. */
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table tbody td::before,
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table tbody th::before {
    content: none !important;
  }
  body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-number {
    grid-column: 1; grid-row: 1;
    font-size: 15px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  }
  /* The desktop css-182 rule (`… table.… th.…order-number`, 0,5,3) outranks the
     generic reset above (0,4,4), so the number cell kept its 16px padding and
     border-bottom — a stray hairline and ragged spacing inside the stacked row
     (Tomek's mobile QA, 2026-08-28). gotcha 53 [css-194] */
  body.woocommerce-account.pf-flow .woocommerce table.woocommerce-orders-table th.woocommerce-orders-table__cell-order-number {
    padding: 0; border: 0;
  }
  body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-number a {
    color: var(--pf-ink); text-decoration: none;
  }
  body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-status {
    grid-column: 2; grid-row: 1; text-align: right !important;
    font-size: 12.5px; font-weight: 600; color: var(--pf-terra-dark);
  }
  body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-date {
    grid-column: 1; grid-row: 2; font-size: 13px; color: var(--pf-ink-2);
  }
  body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-total {
    grid-column: 2; grid-row: 2; text-align: right !important; font-size: 13.5px;
  }
  body.woocommerce-account.pf-flow .woocommerce-orders-table__cell-order-actions {
    grid-column: 1 / -1; grid-row: 3; padding-top: 10px !important;
  }
}

/* ==========================================================================
   3h. Strony informacyjne / prawne (dostawa, zwroty, regulamin, prywatność)
   ========================================================================== */

/* The four legal pages are NOT built from patterns, deliberately: build-
   page.sh would overwrite Łukasz's text. Never point it at them. [css-144] */
.entry-content > .pf-legal { padding-block: 52px 76px; }

/* `.pf-legal.pf-legal` is (0,2,1) and beats Astra's `.entry-content <el>`
   rules without naming Astra's classes. Same doubled-class trick as
   `body.pf-flow.pf-flow`. gotchas 10, 20 [css-145] */
.pf-legal.pf-legal h1 { font-size: clamp(31px, 4.2vw, 46px); font-weight: 700; margin-block: 0 14px; }
.pf-legal.pf-legal .pf-lead { font-size: 18px; color: var(--pf-ink-2); margin-block: 0; }
.pf-legal.pf-legal h2 { font-size: clamp(21px, 2.3vw, 26px); margin-block: 44px 14px; }
.pf-legal.pf-legal h3 { font-size: 17.5px; font-weight: 600; margin-block: 28px 8px; }
.pf-legal.pf-legal p { font-size: 16.5px; line-height: 1.7; margin-block: 0 16px; }
.pf-legal.pf-legal a { color: var(--pf-terra-dark); text-decoration: none; border-bottom: 2px solid var(--pf-terra-soft); }
.pf-legal.pf-legal a:hover { border-bottom-color: var(--pf-terra); }
/* Block-gap stacks on the margins above — a paragraph then an h2 measured
   84px. The rhythm on this page IS the design, so take block-gap out
   entirely. gotcha 11 [css-146] */
.pf-legal.pf-legal > * { margin-block-start: 0; }

/* The topic list. `list-style: none` + a hand-drawn dot rather than a check
   mark on purpose: these lists say what the finished document WILL cover, and
   a row of ticks would read as "done". */
.pf-legal.pf-legal ul { margin-block: 0 20px; padding-left: 0; list-style: none; }
.pf-legal.pf-legal ul li { position: relative; padding-left: 24px; margin-bottom: 11px; font-size: 16.5px; line-height: 1.65; color: var(--pf-ink-2); }
.pf-legal.pf-legal ul li::before {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--pf-gold);
}

/* --- the "this is a draft" banner ---
   The draft banner is the whole reason these pages may be published: a stub
   that LOOKS like a policy is worse than a dead link. [css-147] */
.pf-legal .pf-legal-note {
  display: flex; align-items: flex-start; column-gap: 0;
  background: var(--pf-terra-soft); border: 1px solid var(--pf-gold);
  border-radius: var(--pf-r); padding: 18px 22px; margin-block: 30px 8px;
}
/* Block-gap again, and here it lands on a FLEX ITEM, so it offsets the text
   column instead of spacing it. gotcha 59 [css-148] */
.pf-legal .pf-legal-note > * { margin-block-start: 0; }
.pf-legal .pf-legal-note > .pf-i { flex: none; color: var(--pf-terra-dark); margin: 4px 14px 0 0; }
/* (0,3,1) — beats the .pf-legal.pf-legal p rule above, which would otherwise
   leave 16px of dead space under the last line inside the card. */
.pf-legal .pf-legal-note p { font-size: 15.5px; line-height: 1.6; color: var(--pf-ink); margin-block: 0; }
.pf-legal .pf-legal-note p + p { margin-block-start: 10px; }

/* --- closing "ask us instead" block --- */
.pf-legal .pf-legal-help {
  background: var(--pf-paper); border: 1px solid var(--pf-line);
  border-radius: var(--pf-r); padding: 26px 28px; margin-block: 40px 0;
}
.pf-legal .pf-legal-help h2 { font-size: 20px; margin-block: 0 10px; }
.pf-legal .pf-legal-help p { margin-block: 0 18px; }
.pf-legal .pf-legal-help .wp-block-buttons { margin-block: 0; }

@media (max-width: 600px) {
  .entry-content > .pf-legal { padding-block: 34px 52px; }
  .pf-legal.pf-legal h2 { margin-block-start: 34px; }
  .pf-legal .pf-legal-note { padding: 16px 18px; }
  .pf-legal .pf-legal-help { padding: 22px 20px; }
}

/* ==========================================================================
   4. Astra header / footer / global refinements
   (finetuned live in the customizer; these are baseline overrides)
   ========================================================================== */
.ast-site-identity .custom-logo { max-height: 70px; width: auto; }
.main-header-menu .menu-item > .menu-link {
  font-weight: 600; font-size: 13.5px; letter-spacing: .06em; text-transform: uppercase;
}
/* Cream, not Astra's white, so the bar dissolves into the hero (mockup v2).
   No border — the hero band supplies the transition. */
#masthead .ast-primary-header-bar,
#masthead .ast-mobile-header-wrap .ast-primary-header-bar,
#masthead .ast-above-header-bar { background-color: var(--pf-bg); }
.ast-site-header-wrap, .site-header { border-bottom: 0; }

/* Hand-drawn account + cart icons over Astra's SVG set. The ::before carries
   the sheet asset; the badge (astra-icon::after) keeps its own geometry. */
.ast-header-account-link .ahfb-svg-iconset svg,
.ast-site-header-cart .ast-icon.icon-basket svg { display: none; }
.ast-header-account-link .ahfb-svg-iconset::before,
.ast-site-header-cart .ast-icon.icon-basket::before {
  content: ""; display: inline-block; width: 25px; height: 25px;
  background: url('assets/img/icons/person.webp') center / contain no-repeat;
}
.ast-site-header-cart .ast-icon.icon-basket::before {
  background-image: url('assets/img/icons/bag.webp'); width: 26px; height: 27px;
}
/* Astra prints price then icon; Tomek wants person -> bag -> price. The badge
   is the astra-icon's ::after, so it rides along with the icon. */
.ast-site-header-cart .ast-addon-cart-wrap {
  display: inline-flex; align-items: center; flex-direction: row-reverse; gap: 9px;
}

/* --- mobile off-canvas drawer (Astra's #ast-mobile-popup) ---
   The drawer markup is entirely Astra's, so every rule is an override. Its
   `<ul>` also carries `main-header-menu`, so our desktop nav rule was
   uppercasing the drawer. gotcha 9 [css-149] */
#ast-mobile-popup .ast-mobile-popup-overlay { background: rgba(58, 43, 29, .5); }
#ast-mobile-popup .ast-mobile-popup-inner {
  background: var(--pf-bg);
  border-right: 1px solid var(--pf-line);
  box-shadow: 0 0 44px rgba(58, 43, 29, .2);
  /* Astra sizes the panel at 90% of the viewport, which is right on a phone
     but a 707px slab at the top of the hamburger's range (it shows to 921px).
     [css-150] */
  max-width: 420px;
}

/* The button that OPENS the drawer had escaped the 44px rule — measured
   35×35, on the one control every phone visitor must hit first. [css-151] */
body .ast-mobile-menu-trigger-fill,
body .ast-mobile-menu-trigger-minimal,
body .ast-mobile-menu-trigger-outline,
body .main-header-menu-toggle {
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
}
/* Colour ALIGNMENT, not removal (0.2.150's invisible ink trigger was wrong —
   Tomek): terracotta fill everywhere, except an accented product page tints
   it with THAT page's accent — one strong hue family per screen. (0,4,1)
   against Astra's served (0,3,0). */
body.pf-acc-navy .ast-button-wrap .ast-mobile-menu-trigger-fill.ast-mobile-menu-trigger-fill { background: var(--pf-navy); }
body.pf-acc-olive .ast-button-wrap .ast-mobile-menu-trigger-fill.ast-mobile-menu-trigger-fill { background: var(--pf-olive); }

/* close button: terracotta, a 44px tap target, and a real focus ring instead
   of the UA dotted outline Astra leaves visible after a tap. */
#ast-mobile-popup .ast-mobile-popup-header { padding: 12px 12px 4px; }
#ast-mobile-popup .menu-toggle-close {
  width: 44px; height: 44px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  /* the ring Astra leaves round the X is a 1px dotted BORDER, not an outline —
     `outline: none` looks like it should remove it and does nothing. */
  border: 0;
}
#ast-mobile-popup .menu-toggle-close svg { width: 19px; height: 19px; fill: var(--pf-terra); }
#ast-mobile-popup .menu-toggle-close:hover { background: var(--pf-bg-alt); }
#ast-mobile-popup .menu-toggle-close:focus { outline: none; }
#ast-mobile-popup .menu-toggle-close:focus-visible { outline: 2px solid var(--pf-terra); outline-offset: 2px; }

/* items: the site's serif voice at a size that's actually tappable. Sentence
   case is deliberate — it reads as the drawer's own heading scale rather than a
   blown-up copy of the 13.5px uppercase desktop bar, and the menu labels are
   already stored capitalised ("Pełna Micha", "Złap nas!"). */
#ast-mobile-popup .ast-mobile-popup-content { padding-bottom: 20px; }
/* the white panel is painted on the <ul>, NOT on the links or the popup inner —
   cream on .ast-mobile-popup-inner alone leaves a white slab behind the items. */
#ast-mobile-popup #ast-hf-mobile-menu { background: transparent; }
#ast-mobile-popup #ast-hf-mobile-menu .menu-item > .menu-link {
  font-family: var(--pf-font-serif);
  font-size: 19px; font-weight: 500; line-height: 1.35;
  letter-spacing: 0; text-transform: none;
  color: var(--pf-ink); background: transparent;
  padding: 16px 24px;
  border-bottom: 1px solid var(--pf-line);
  box-shadow: inset 0 0 0 0 var(--pf-terra);
  transition: color .15s ease, box-shadow .15s ease, background .15s ease;
}
#ast-mobile-popup #ast-hf-mobile-menu > .menu-item:last-child > .menu-link { border-bottom: 0; }
#ast-mobile-popup #ast-hf-mobile-menu .menu-item > .menu-link:hover {
  color: var(--pf-terra-dark); background: var(--pf-bg-alt);
}
/* current page: an inset bar rather than a real border, so the label doesn't
   shift 3px sideways relative to every other item. */
#ast-mobile-popup #ast-hf-mobile-menu .current-menu-item > .menu-link,
#ast-mobile-popup #ast-hf-mobile-menu .current_page_item > .menu-link {
  color: var(--pf-terra-dark); background: var(--pf-bg-alt);
  box-shadow: inset 3px 0 0 0 var(--pf-terra);
}

/* announcement bar (petfly_render_announce on wp_body_open; off by default) */
.pf-announce, .ast-above-header {
  background: var(--pf-ink); color: #F6E9D6; font-size: 13px; letter-spacing: .02em;
}
.pf-announce { text-align: center; }
.pf-announce-in { max-width: 1180px; margin-inline: auto; padding: 9px 20px; line-height: 1.4; }
.pf-announce b, .ast-above-header b { color: var(--pf-gold); }

/* --- footer (rendered by petfly_render_footer(), replaces Astra footer) --- */
.pf-footer {
  background: var(--pf-bg-alt); color: var(--pf-ink-2); margin-top: 80px;
  font-size: 14.5px; border-top: 1px solid var(--pf-line);
}
.pf-footer-grid {
  max-width: 1180px; margin-inline: auto; padding: 56px 24px 40px;
  display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: 36px;
}
/* h2 since 0.2.215 (h4 until 0.2.214). The level is an accessibility choice, not
   a type choice — every property that made it look like this is pinned here. */
.pf-footer h2 {
  color: var(--pf-ink); font-size: 14px; letter-spacing: .08em; text-transform: uppercase;
  margin: 0 0 16px; font-family: 'Inter', sans-serif;
  line-height: 1.2; /* Astra gives h2 1.25em and h3/h4 1.2em — 1px taller without this */
}
.pf-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.pf-footer a { text-decoration: none; color: var(--pf-ink-2); }
.pf-footer a:hover { color: var(--pf-terra); }
.pf-footer-logo img { height: 64px; width: auto; margin-bottom: 14px; }
/* Packaging claim above the tagline — uppercase here so the Customizer string
   stays words; tracked like the column headings so the two read as one system. */
.pf-footer-claim {
  margin: 0 0 6px; font-weight: 600; font-size: 13px; color: var(--pf-ink);
  text-transform: uppercase; letter-spacing: .08em;
}
.pf-footer-tag { max-width: 30ch; margin: 0; }
.pf-footer-bottom { border-top: 1px solid var(--pf-line); }
.pf-footer-bottom-in {
  max-width: 1180px; margin-inline: auto; padding: 18px 24px;
  display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px; flex-wrap: wrap;
}
/* Seller identification (Łukasz's checkout-texts doc). Full-width so the ©
   and payments spans keep their two-corner row under it. */
.pf-footer-company { flex: 1 0 100%; color: var(--pf-ink-2); }
@media (max-width: 960px) { .pf-footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .pf-footer-grid { grid-template-columns: 1fr; } }

/* ==========================================================================
   5. Responsive
   ========================================================================== */
@media (max-width: 960px) {
  .pf-section { padding-block: 52px; }
}
@media (max-width: 600px) {
  .pf-hero-col-text { text-align: center; }
  .pf-hero .pf-lead { margin-inline: auto; }
  .pf-hero .wp-block-buttons { flex-direction: column; align-items: stretch; }
  .pf-hero .wp-block-button, .pf-hero .wp-block-button__link { width: 100%; }
}

/* The [petfly_products] shortcode reuses the archive grid, but it sits inside a
   pattern section that already owns its bottom rhythm — drop the archive's 72px
   tail so the homepage does not gain a gap the design never asked for. */
.pf-products-shortcode ul.products.pf-grid { margin-bottom: 0; }

/* --- 9. reduced motion ---
   Reduced motion: 16 transitions and no animations, so honouring the system
   setting costs one rule. [css-152] */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   3l. DELIVERY OPTIONS — the shipping list, on the cart AND the checkout.
   3l. DELIVERY OPTIONS, cart AND checkout. Tomek's QA 2026-08-25 found four
   faults with one cause: nothing here had ever been styled, so it was raw
   Woo inside our card. [css-153]
   ========================================================================== */

/* FULL WIDTH, and the obvious way is a trap: `display:block` on the `<tr>`
   inherits the FIRST column's width. Only `colspan` spans. gotcha 69
   [css-154] */
body.woocommerce-checkout.pf-flow .woocommerce form #order_review table tr.woocommerce-shipping-totals > td,
body.pf-flow #content .woocommerce .cart_totals table.shop_table tr.woocommerce-shipping-totals > td {
  padding: 12px 0 13px; text-align: left;
}
/* `text-align:left` is load-bearing: below 921px Astra right-aligns
   `shop_table_responsive` cells, which is right for an amount and wrong for
   a heading. [css-155] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals .pf-ship-heading {
  display: block; padding-bottom: 9px; text-align: left;
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px;
  font-weight: 600; color: var(--pf-ink-2);
}

/* 3l.2 — THE OPTION CARDS. */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method {
  display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; text-align: left;
}
/* TWO IDs on every rule here, and `text-indent` named explicitly: Astra's
   `:not()` smuggles a second id in through its argument. gotchas 36, 70
   [css-156] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li {
  position: relative;
  display: grid; grid-template-columns: auto 1fr; align-items: center;
  column-gap: 11px; margin: 0; padding: 12px 14px; list-style: none;
  text-indent: 0; cursor: pointer;
  border: 1.5px solid var(--pf-line); border-radius: 14px;
  background: var(--pf-bg);
  transition: border-color .14s, background .14s;
}
/* `woocommerce_after_shipping_rate` fires inside the `<li>`, so anything a
   plugin appends becomes a grid item. Default every child to column 2 and
   place only the radio. gotcha 55 [css-157] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li > * { grid-column: 2; }
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li > input.shipping_method {
  grid-column: 1; grid-row: 1; width: 17px; height: 17px; margin: 0;
  accent-color: var(--pf-terra);
}
/* Name + price are two COLUMNS, not a wrapping flex row: a long name
   ("Darmowa dostawa do Paczkomatu (od 149 zł)") used to push the price onto a
   second line (Tomek). The name column wraps inside itself; the price keeps its
   own right-aligned column and is centred against it. [css-169] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li > label {
  grid-row: 1; display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; column-gap: 12px; margin: 0; cursor: pointer; color: var(--pf-ink);
}
/* THE WHOLE CARD IS THE CONTROL (Tomek, 2026-08-25): it lit up on hover
   while only the label text answered a click. A stretched label pseudo-
   element covers the `<li>`. [css-158] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li > label::before {
  content: ''; position: absolute; inset: 0; border-radius: 14px;
}
/* HOVER AND SELECTED MUST NOT LOOK ALIKE (Tomek): both were terra-on-paper.
   Hover is a gold hint, selected is a terracotta commitment with a fill.
   [css-159] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li:hover {
  border-color: var(--pf-gold); background: var(--pf-paper);
}
/* The chosen option. `:has()` rather than a class because nothing adds a class:
   Woo re-renders this list over AJAX on every change (gotcha 49), so any class
   we hung on it client-side would be gone one keystroke later. */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li:has(input.shipping_method:checked) {
  border-color: var(--pf-terra); background: var(--pf-terra-soft);
}
/* The address chip is terra-soft too, so on the filled card it would vanish into
   it. Inside a chosen card it goes to paper and becomes a card within a card,
   which is the reading we want: the option, and the point you picked for it. */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li:has(input.shipping_method:checked) span#selected-point {
  background: var(--pf-paper);
}

/* Woo composes the label as one "Title: 13,99 zł" string;
   `woocommerce_cart_shipping_method_full_label` in functions.php splits it
   into these two spans. [css-160] */
/* SANS (Inter), matching the payment-method labels (Tomek, 2026-08-26, reversing
   the 2026-08-25 serif call — wanted the two card lists to read alike). [css-161] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals .pf-ship-name {
  min-width: 0;
  font-family: 'Inter', system-ui, sans-serif; font-size: 14.5px;
  font-weight: 600; line-height: 1.35;
}
/* 600, not 700 (Tomek, 2026-08-25): at 700 the delivery prices were the
   heaviest thing in the card after the total. [css-162] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals .pf-ship-cost {
  margin-left: auto; white-space: nowrap;
  font-family: 'Inter', system-ui, sans-serif; font-size: 14.5px;
  font-weight: 600; font-variant-numeric: tabular-nums;
}
/* A free rate still prints an amount, so the column stays a column. It reads
   quieter than a real price because it is not a cost the shopper is agreeing to. */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals .pf-ship-cost--free { color: var(--pf-olive); }

/* Furgonetka emits the link first and the chosen address second, both bare.
   The address has to read first, so the container is a flex column and
   `order` swaps them. [css-163] */
/* `position: relative` lifts the picker out from under the stretched label,
   or choosing a Paczkomat becomes impossible. gotcha 17 [css-164] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals p#select-point-container {
  position: relative; z-index: 1;
  grid-column: 2; grid-row: 2;
  display: flex; flex-direction: column; align-items: stretch; gap: 9px;
  margin: 11px 0 1px; padding: 0;
}
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals p#select-point-container > #selected-point { order: 1; }
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals p#select-point-container > #select-point { order: 2; }

/* The link. Terracotta on a gold rule is this site's link idiom — the same one
   the cart's own "Oblicz koszty wysyłki" wears — so the affordance is one the
   shopper has already met, not a new one invented for this block. */
/* Left while it is still an instruction, right once it is an amendment — the
   link's text changes with the state, and so does its job. [css-165] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals a#select-point {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 7px;
  padding-bottom: 1px;
  font-family: 'Inter', system-ui, sans-serif; font-size: 13.5px;
  font-weight: 700; line-height: 1.25; color: var(--pf-terra-dark);
  text-decoration: none; border-bottom: 1.5px solid var(--pf-gold);
  transition: color .14s, border-color .14s;
}
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals a#select-point:hover,
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals a#select-point:focus-visible {
  color: var(--pf-ink); border-color: var(--pf-terra);
}
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals a#select-point::before {
  content: ''; flex: none; width: 15px; height: 15px; background: currentColor;
  -webkit-mask: var(--pf-mask-pin) center / contain no-repeat;
  mask: var(--pf-mask-pin) center / contain no-repeat;
}
/* One pin per option: once the address card carries the pin, a second one
   9px below is noise. Keyed off the sibling's `:empty`. gotcha 80 [css-166] */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals
  p#select-point-container:has(> span#selected-point:not(:empty)) > a#select-point {
  align-self: flex-end;
}
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals
  p#select-point-container:has(> span#selected-point:not(:empty)) > a#select-point::before {
  display: none;
}

/* The chosen point. Empty until one is picked — and it is genuinely empty, not
   whitespace, in both paths that fill it: PHP prints esc_html('') on load and
   the plugin's callback uses .text(). So `:empty` is a reliable state test and
   the block needs no class of its own. */
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals span#selected-point:empty { display: none; }
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals span#selected-point {
  position: relative; display: block;
  margin: 0; padding: 10px 13px 10px 35px;
  background: var(--pf-terra-soft); border-radius: 12px;
  font-family: 'Inter', system-ui, sans-serif; font-size: 13px;
  font-weight: 500; line-height: 1.45; color: var(--pf-ink);
}
body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals span#selected-point::before {
  content: ''; position: absolute; left: 13px; top: 11px;
  width: 15px; height: 15px; background: var(--pf-terra-dark);
  -webkit-mask: var(--pf-mask-pin) center / contain no-repeat;
  mask: var(--pf-mask-pin) center / contain no-repeat;
}

/* Do not re-add `.woocommerce-shipping-destination:empty { display: none }`
   — it never matched, because the template emits whitespace. gotcha 80
   [css-167] */

/* CART only, below 921px: kill the second "Przesyłka". Only the cart totals
   table is `shop_table_responsive`, so this needs the cart AND a narrow
   width — the pair my own pass missed. gotchas 73, 76 [css-168] */
@media (max-width: 921px) {
  body.pf-flow #content .woocommerce .cart_totals tr.woocommerce-shipping-totals > td::before {
    content: none;
  }
  body.pf-flow #content .woocommerce .cart_totals tr.woocommerce-shipping-totals .pf-ship-heading::after {
    content: ':';
  }
}

/* 3l.6 — under ~600px the card is ~330px wide and the longer titles cannot share
   a line with their price. The label already wraps; this keeps the price on the
   right of the second line rather than orphaned under the radio. */
@media (max-width: 600px) {
  body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals ul#shipping_method > li {
    padding: 11px 12px;
  }
  /* On the name, not the label: the type now lives on the two spans, so a
     font-size here would set nothing the child does not immediately override. */
  body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals .pf-ship-name {
    font-size: 14.5px;
  }
  body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals .pf-ship-cost {
    font-size: 14px;
  }
  body.pf-flow #content .woocommerce tr.woocommerce-shipping-totals span#selected-point { font-size: 12.5px; }
}
