/*
 * Shop / category / tag archive (Phase 2, Milestone 1 cleanup pass) — restyles WooCommerce's
 * own default markup (still WooCommerce's real template + hooks, see woocommerce.php) using the
 * site's existing tokens/spacing scale. No new grid system: reuses the same column-count
 * breakpoints already established for the Homepage Best Sellers rail (.product-grid,
 * homepage.css) for visual consistency between the two.
 */

/* Bug fix: found the actual cause of the "too much air before the grid" report — it wasn't the
   title-to-toolbar gap (that measured 0px live), it was nav.woocommerce-pagination's own
   margin-top (below) leaking into the *nested* pagination instance inside .storefront-sorting,
   pushing that whole row down by 32px inside its own box. Fixed at the source, see the
   Pagination section. shop-page's own top padding also trimmed slightly as part of the same
   "reduce ~30-40%" request. */
.shop-page { padding-top: var(--space-7); }

/* ================= Breadcrumb =================
 * Art-direction pass 2026-08-13: restored (see woocommerce.php/inc/woocommerce-hooks.php for the
 * real bug that was silently removing it) and styled as a quiet editorial wayfinding line — small,
 * muted, generous top clearance so it reads as "you are here" rather than a UI chrome element. */
.woocommerce-breadcrumb {
  display: block;
  margin: 0 0 var(--space-6);
  font-size: var(--font-size-ui-label);
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.woocommerce-breadcrumb a { color: var(--color-text-muted); text-decoration: none; }
.woocommerce-breadcrumb a:hover { color: var(--color-text-primary); text-decoration: underline; }

/* ================= Page title =================
 * Bug fix: `.woocommerce-products-header` was assumed to wrap the title (a common Storefront/WC
 * pattern) but this WC version prints a bare `h1.page-title` with NO wrapper at all — confirmed
 * live via DOM inspection (querySelector returned null, h1 is a direct child of .shop-page).
 * Eyebrow label ("КАТЕГОРІЯ" via ::before) and the breadcrumb above it (woocommerce.php) both
 * removed 2026-09-11 per explicit request — the H1 is now the first thing between the header and
 * the archive intro paragraph. */
h1.page-title {
  position: relative;
  font-family: var(--font-heading);
  font-weight: var(--font-weight-heading);
  /* Explicit request: half the size of the site's usual H1 — this title reads as a quiet
     section label here, not a full editorial headline. */
  font-size: calc(var(--font-size-h1) / 2);
  margin: 0 0 var(--space-4);
}
/* Archive intro paragraph — WooCommerce's own woocommerce_archive_description() output (already
   correctly wired, do_action inside woocommerce_content()). `.term-description` is the category/
   tag archive version (term's own description field); `.page-description` is the base Shop page
   version (the Shop Page's own post_content, WC's own class name for that specific case) — same
   editorial typography treatment either way since both play the same role: one short intro
   paragraph under the H1, before the grid. Editorial pass 2026-08-14: generous bottom margin is
   deliberate (Flamingo Estate reference — "large whitespace" before products start), not a gap
   to close. */
.term-description,
.page-description {
  max-width: 62ch;
  /* !important verified necessary: without it this computes to ~26px instead of the 60px set
     here — same unidentified-source Storefront/WC margin leak already documented elsewhere in
     this project (.site-header, .comment-respond, .storefront-sorting), not a guess this time. */
  margin-bottom: var(--space-9) !important;
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: color-mix(in srgb, var(--color-text-muted) 90%, transparent);
}
.term-description p,
.page-description p { margin: 0 0 var(--space-3); }
.term-description p:last-child,
.page-description p:last-child { margin-bottom: 0; }

/* ================= Sorting + result count row =================
 * Quiet metadata row, not a UI toolbar — small uppercase tracked label for the count (matching
 * the site's --font-size-ui-label eyebrow language elsewhere), a borderless/underlined select so
 * it reads as a text control rather than a boxy form widget, a thin rule underneath to separate
 * it from the title above instead of relying on spacing alone.
 */
.storefront-sorting {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-2);
  /* Bug fix: computed margin-bottom was a fractional ~34px regardless of the value set here —
     the same unidentified-source Storefront leak already documented on .site-header
     (header.css) and .comment-respond (product.css), same !important fix. */
  margin-bottom: var(--space-2) !important;
}
/* Real bug, found live: Storefront's own float-layout clearfix (`content:""; display:table` on
   ::before/::after) is still attached to this element even though it's `display:flex` here — a
   generated-content pseudo-element becomes a real (zero-width) flex item, so the container was
   silently laying out FOUR items (::before, notices-wrapper, count, ordering, ::after) instead of
   two, throwing off `justify-content: space-between` (the count sat ~340px from the left edge
   instead of flush against it). Neutralizing the pseudo-elements only on this element — Storefront
   still needs its own clearfix elsewhere. `!important` verified necessary — same unidentified-
   source Storefront leak already documented elsewhere in this project (.site-header,
   .comment-respond, this element's own margin-bottom above): the plain (non-!important) version of
   this exact rule was confirmed live to have zero effect despite no other stylesheet rule
   matching this selector by any specificity/cascade check. */
.storefront-sorting::before,
.storefront-sorting::after { content: none !important; }
/* WooCommerce also renders an empty <div class="woocommerce-notices-wrapper"> as the first real
   child (no notice active on a plain category browse) — kept out of the flex layout while empty so
   it can't claim a flex slot; still renders normally the moment a real notice needs to show. */
.storefront-sorting .woocommerce-notices-wrapper:empty { display: none; }
.woocommerce-result-count {
  margin: 0;
  order: 1;
  font-size: var(--font-size-ui-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.woocommerce-ordering { margin: 0; order: 2; }
.woocommerce-ordering select.orderby {
  font-family: var(--font-body);
  font-size: var(--font-size-nav);
  color: var(--color-text-primary);
  background: none;
  border: none;
  border-bottom: 1px solid var(--color-border-default);
  border-radius: 0;
  padding: 0 var(--space-5) var(--space-1) 0;
  cursor: pointer;
}
.woocommerce-ordering select.orderby:hover { border-bottom-color: var(--color-text-primary); }

/* ================= Product grid ================= */
/* `ul.products` is WooCommerce's own list — content-product.php (theme override) renders our
   real ProductCard (.product-card) inside each `<li>`, so the `<li>` itself just needs to behave
   as a plain, unstyled grid cell. */
/* Fine-tuning pass: row gap opened up further (--space-6 -> --space-8) — cards read as objects
   with room around them, not tiles packed into a mechanical grid; column gap left tighter since
   it's the row rhythm that reads as "dense" at a glance. */
/* Strict-grid pass 2026-09-11 (explicit request) reverses the density fix below: every zone in
   the card now has its own reserved, content-independent height (see .product-card and its
   children further down), so a row's tallest card is no longer "artificial" — it's just the real,
   deterministic height every card in that row already has. align-items reverted to the grid
   default (stretch) so cards genuinely share one row height, with the CTA landing at the bottom
   of that shared height by construction, not by absorbing leftover space.
 * Editorial pass 2026-08-14: gaps opened further (row space-8->space-9, column space-6->space-7)
   and the max column count dropped from 5 to 4 (removed the 1400px breakpoint below) — cards read
   as objects with real room around them, gallery-like, rather than a dense catalog grid. */
.shop-page ul.products {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-9) var(--space-7);
  align-items: stretch;
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Editorial interruption block (art-direction pass 2026-08-14) — a real <li> inside the same
   grid (see gb_maybe_render_product_grid_editorial(), inc/woocommerce-integration.php), spanning
   every column via grid-column so it breaks the product rows into "chapters" every 7 products,
   Flamingo Estate-style, instead of an unbroken wall of cards. */
/* Editorial Phase 2 (2026-08-14): "editorial sections should breathe... some should occupy
   almost a full viewport... let users pause before continuing shopping" — margin widened well
   past the surrounding card gap (was --space-4, barely more than the grid's own row gap, so it
   didn't read as a pause at all) and the image given real height instead of a fixed 16/9 crop. */
.shop-page ul.products li.product-grid-editorial {
  grid-column: 1 / -1;
  margin: var(--space-9) 0;
}
.product-grid-editorial__image .responsive-image {
  aspect-ratio: auto;
  height: min(85vh, 900px);
}
.product-grid-editorial__quote {
  max-width: 44ch;
  margin: 0 auto;
  padding: var(--space-9) var(--space-5);
  text-align: center;
  font-family: var(--font-heading);
  font-style: italic;
  font-size: var(--font-size-h2);
  line-height: 1.35;
  color: var(--color-text-primary);
}

/* Grid rhythm (editorial Phase 2, 2026-08-14 — "controlled asymmetry" via per-product aspect-ratio
 * + a 2-column-spanning "featured" card) removed 2026-09-11, explicit request: it directly
 * conflicted with the new strict-alignment requirement that every image container (and therefore
 * every column) share exactly the same dimensions. content-product.php no longer assigns the
 * gb-rhythm-* classes this targeted — see that file's own comment. Every card now uses the site's
 * frozen default productCard ratio (.responsive-image--product, 3/4, components.css) uniformly.
 */

/* Bug fix: WooCommerce/Storefront's default `ul.products` carries a classic float-era clearfix
   (::before/::after { content:""; display:table }) — harmless under float, but once the parent
   is display:grid those pseudo-elements become real grid items (content isn't `none`), silently
   shifting every real product by one cell. Caught via live QA at the mobile 2-col breakpoint —
   the first product rendered alone in column 2 with an empty column 1, and the whole grid was
   off by one cell from there on. */
.shop-page ul.products::before,
.shop-page ul.products::after { content: none; }
.shop-page ul.products li.product {
  width: auto;
  margin: 0;
  padding: 0;
  float: none;
  clear: none;
}
@media (min-width: 640px) { .shop-page ul.products { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1100px) { .shop-page ul.products { grid-template-columns: repeat(4, 1fr); } }

/* ================= Load more =================
 * Replaces numbered pagination (explicit request, 2026-09-22) — see inc/shop-load-more.php.
 * One quiet outlined button, centered under the grid; matches the site's other secondary buttons
 * (border + text, no fill) rather than the primary Add to Cart treatment.
 */
.shop-load-more {
  display: flex;
  justify-content: center;
  margin-top: var(--space-7);
}
.shop-load-more__button {
  font-family: var(--font-body);
  font-size: var(--font-size-nav);
  color: var(--color-text-primary);
  background: none;
  border: var(--border-width) solid var(--color-border-default);
  border-radius: var(--radius-pill);
  padding: var(--space-3) var(--space-6);
  cursor: pointer;
  transition: border-color var(--animation-duration) var(--animation-easing), background var(--animation-duration) var(--animation-easing);
}
.shop-load-more__button:hover { border-color: var(--color-text-primary); background: color-mix(in srgb, var(--color-text-primary) 4%, transparent); }
.shop-load-more__button:disabled { cursor: default; opacity: 0.6; }

/* ================= ProductCard — Editorial tile (2026-09-12) =================
 * Full redesign per an explicit visual reference — see homepage.css's own version of this same
 * pass for the full reasoning (flat, no card surface, no CTA, portrait image, tight left-aligned
 * text stack). Kept as an independent, separately-tuned copy here rather than a shared base rule,
 * per this file's own established "independent, not shared" convention — the values are now
 * identical to homepage.css/product.css (this redesign collapsed what used to be genuinely
 * different padding models into one shared flat layout), but the rule stays duplicated per file.
 */
.shop-page .product-card {
  display: grid;
  grid-template-rows: auto auto auto auto auto;
  text-decoration: none;
  color: inherit;
  /* Real bug found live (editorial-tile pass, 2026-09-12): Storefront's own default
     `ul.products li.product { text-align: center }` (woocommerce/woocommerce.css) was inherited
     straight down into every text row here — invisible while this card's own rules also centered
     things, but left every row visibly center-aligned instead of matching the reference's
     left-aligned rating/title/descriptor/price now that those rules don't set it themselves. */
  text-align: left;
}
/* Vertical-rhythm pass (2026-09-12, explicit request, reference: "Бестселери" screenshot) — see
   homepage.css's own version of this same fix: image -> title target is 16-20px total, this
   margin is the only source of it now that the empty rating box below collapses via :empty. */
.shop-page .product-card__image { position: relative; margin-bottom: var(--space-4); }
/* Real bug found live (editorial-tile pass follow-up, 2026-09-12) — see homepage.css's own
   version of this same fix: .responsive-image's base border-radius/background (components.css)
   need explicitly squaring off/clearing now that this card has no surface of its own. */
.shop-page .product-card__image .responsive-image { aspect-ratio: 4 / 5; border-radius: 0; background: none; }
/* Explicit request: every product image fits inside the same fixed 4/5 box instead of being
   cropped to fill it — `cover` zoomed each PNG differently depending on its own proportions/
   transparent margin, so bottles read at visibly different scales card to card. Never stretches
   (object-fit keeps the aspect ratio). Same rule lives in homepage.css/product.css for the
   Homepage and Related/Up-Sells cards, which don't load this stylesheet. */
.shop-page .product-card__image .responsive-image img { object-fit: contain; }
/* Landscape/square source canvas (see gb_map_product_to_card()): `contain` would fit it by width and
   leave the product tiny in the middle of empty sides — fit by height instead, cropping the sides. */
.shop-page .product-card__image--wide .responsive-image img { object-fit: cover; }
.shop-page .product-card__image .responsive-image,
.shop-page .product-card__image .responsive-image img {
  transition: transform var(--animation-duration-slow) var(--animation-easing);
}
.shop-page .product-card:hover .product-card__image .responsive-image img { transform: scale(1.035); }
.shop-page .product-card__badge { position: absolute; top: var(--space-3); left: var(--space-3); z-index: 1; }
.shop-page .product-card__badge--sold-out { top: var(--space-3); left: var(--space-3); }
.shop-page .product-card--sold-out .product-card__image .responsive-image { opacity: 0.5; }
.shop-page .product-card--sold-out .product-card__name,
.shop-page .product-card--sold-out .product-card__descriptor,
.shop-page .product-card--sold-out .product-card__price { opacity: 0.5; }
/* Rating slot — collapses to zero footprint when empty (see homepage.css's own version of this
   same fix) so image -> title stays a fixed 16-20px for an unrated product. */
.shop-page .product-card__rating {
  display: flex;
  align-items: center;
  margin-bottom: var(--space-1);
}
.shop-page .product-card__rating:empty { display: none; margin: 0; }
/* Real bug fixed live (compaction pass, 2026-09-12, explicit request) — see homepage.css's own
   version of this same fix: `min-height: calc(1.1em * 2)` reserved 2 lines regardless of actual
   title length, leaving dead space below any real 1-line name before the descriptor started.
   Dropped; -webkit-line-clamp:2 alone still caps a long name at 2 lines. */
/* Real bug fixed live (2026-09-15, explicit request) — see homepage.css's own version of this
   same fix for the full measurement: line-height:1.1 clipped descenders (g/y/p/q/j) against this
   rule's own overflow:hidden (needed for -webkit-line-clamp). 1.2 is the smallest bump that fully
   clears it, confirmed live at 4x zoom on "Fig Milk". +2.1px per rendered line only. */
.shop-page .product-card__name {
  font-family: var(--font-heading);
  font-weight: var(--font-weight-body);
  font-size: var(--font-size-product-card-title);
  line-height: 1.2;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--color-text-primary);
  /* Vertical-rhythm pass (2026-09-12, explicit request): title -> descriptor target is 4-6px. */
  margin-bottom: var(--space-1);
}
/* Scent/botanical descriptor ("Матча · лайм · мак") — a short phrase that fits one line at every
   column width this card renders at, so both the reservation and the line-clamp ceiling stay at
   1 line. */
.shop-page .product-card__descriptor {
  min-height: calc(1.3em * 1);
  font-size: var(--font-size-product-card-descriptor);
  font-weight: var(--font-weight-body);
  color: color-mix(in srgb, var(--color-text-muted) 85%, transparent);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Vertical-rhythm pass (2026-09-12, explicit request): descriptor -> price target is 12-16px. */
  margin: 0 0 var(--space-3);
}
/* Price — one explicit single-line typography rule, not inherited: identical height whether the
   text is "450 ₴" or a struck-through "1 200 ₴ 950 ₴". Last element in the card now (no CTA below
   it) — no margin-bottom of its own; `ul.products`'s own row-gap controls the gap to the next row. */
.shop-page .product-card__price {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-emphasis);
  line-height: 1.4;
}

/* ================= Badges (premium visual pass) =================
 * Unifies New / Bestseller / Sold Out into one quiet, editorial tag language — same pill shape
 * and size for all three, differing only in fill (solid for the two "hard facts" — new arrival,
 * unavailable — outline for the marketing tag). Replaces the frozen homepage Badge primitive's
 * "illustrated sticker" sold-out treatment (components.css, DESIGN_RULES §2 exception) — that
 * primitive stays exactly as-is on the homepage; this only overrides its rendering within
 * .shop-page via higher selector specificity, no shared file touched.
 */
/* Fine-tuning pass: smaller in every dimension (padding, font-size) than the first pass — Le
   Labo-style, present but easy to overlook rather than a call-out. */
.shop-page .badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: var(--font-weight-emphasis);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  line-height: 1;
}
.shop-page .badge--new { background: var(--color-background-accent); color: var(--color-text-on-accent); border: none; }
/* Outline weight faded via color-mix instead of a thinner border (sub-pixel borders render
   inconsistently across browsers) — the line reads lighter without literally changing width. */
.shop-page .badge--bestseller {
  background: var(--color-background-primary);
  color: var(--color-background-accent);
  border: 1px solid color-mix(in srgb, var(--color-background-accent) 55%, transparent);
  padding: 2px 8px;
}
.shop-page .badge--sold-out {
  position: static;
  width: auto;
  height: auto;
  border-radius: var(--radius-pill);
  background: var(--color-border-default);
  border: none;
  color: var(--color-text-muted);
  padding: 3px 9px;
  font-size: 9px;
}
.shop-page .badge--sold-out::before { content: none; }

/* ================= Empty state ================= */
.woocommerce-info {
  font-size: var(--font-size-body);
  color: var(--color-text-muted);
  border: var(--border-width) solid var(--color-border-default);
  border-radius: var(--radius-medium);
  padding: var(--space-6);
  list-style: none;
  margin: 0;
}
