/*
Theme Name: O'CCAFFÈ (Blocksy Child)
Theme URI: https://occaffe.sk
Description: Child theme of Blocksy for the O'CCAFFÈ store. Site-specific styling and tweaks live here; Blocksy itself is Composer-managed and configured via the Customizer. Replaces the old Kallyas theme.
Author: Vismek
Template: blocksy
Version: 1.0.0
Requires PHP: 8.2
Text Domain: occaffe
*/

/* =========================================================================
   O'CCAFFÈ — Blocksy is the source of truth for anything it has a native
   Customizer setting for (colors, typography, buttons, cards, badges,
   avatars, hero visibility, card element order, link color). Rules below
   are ONLY for markup/features Blocksy has no equivalent for at all.
   ========================================================================= */

/* ---- Slot 6 conflict: gold lives on slot 6, but Blocksy's own native CSS also uses slot 6 as the
   footer background and the author/category archive hero-band background. Two targeted overrides,
   specificity bumped above Blocksy's own selectors (not just matched) so this doesn't become another
   load-order-dependent tie across customizer/editor/front-end contexts. ---- */
[data-footer*="type-1"] .ct-footer.ct-footer { background-color: var(--theme-palette-color-7); }
[data-prefix="author"] .hero-section.hero-section[data-type="type-2"],
[data-prefix="woo_categories"] .hero-section.hero-section[data-type="type-2"] {
  background-color: var(--theme-palette-color-7);
}

/* ---- Eyebrow label (custom — no Blocksy equivalent) ---- */
.occaffe-eyebrow {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--theme-palette-color-1);
  margin-bottom: 0 !important;
}

/* ---- Content rhythm (spacing between blocks — no Blocksy equivalent) ---- */
.entry-content > * + * { margin-top: 2rem; }
/* A full-bleed band renders its own background edge to edge, so any vertical margin against it shows as
   a stripe of page background — the block above contributes one too, via Blocksy's content spacing.
   Bands carry their own padding instead. */
.entry-content > * + .alignfull { margin-top: 0; }
.entry-content > *:has(+ .alignfull) { margin-bottom: 0; }
.entry-content > h2 { margin-top: 4.5rem; }
.entry-content > .occaffe-eyebrow { margin-top: 4.5rem; }
.entry-content > .occaffe-eyebrow + h2 { margin-top: 0.25rem; }

/* ---- Hero (Cover) — fully custom band, no Blocksy equivalent.
   Sets its own heading/button colors regardless of Typography/Buttons panel
   choices, since it always sits over a dark image and needs to stay legible. */
.occaffe-hero {
  align-items: center;
  text-align: center;
}
.occaffe-hero .wp-block-cover__inner-container {
  max-width: 780px;
  margin-inline: auto;
}
.occaffe-hero .occaffe-eyebrow { color: var(--theme-palette-color-6); }
/* Doubled class: Blocksy injects a same-specificity `:root h1{color}` rule into the block editor
   (its own theme_mod-to-editor typography sync, loaded after ours) — without the bump this wins the
   editor's tie and the heading shows Blocksy's default color there, while the front end is unaffected
   (Blocksy's front-end CSS has no such bare `:root h1` rule). */
.occaffe-hero.occaffe-hero h1 {
  color: #fff;
  font-size: clamp(2.6rem, 5.5vw, 4.2rem);
  margin: 0.4rem 0 1rem;
  text-shadow: 0 2px 28px rgba(0, 0, 0, 0.4);
}
.occaffe-hero p:not(.occaffe-eyebrow) {
  color: var(--theme-palette-color-7);
  font-size: 1.2rem;
  max-width: 36em;
  margin-inline: auto;
}
.occaffe-hero .wp-block-buttons { margin-top: 2rem; }
.occaffe-hero .wp-block-button__link { padding: 1em 2.4em; font-size: 0.9rem; }

/* ---- Hero, split variant (two columns, text + photo) — tools/db/apply-hero-split.php ----
   A different band from .occaffe-hero above: that one is a Cover with text OVER a dimmed image and
   sets its own light-on-dark colors. This one sets text beside the image, so it must undo those
   inherited overrides rather than extend them.
   Band background is slot 5, not slot 7 — Blocksy paints the body with slot 7, so a slot 7 band is
   invisible. Slot 5 is also the border color: a bordered element inside one of these bands disappears. */
.occaffe-hero--split {
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  margin-top: 0;
  background: var(--theme-palette-color-5);
  text-align: start;
}
/* Equal-height CTAs. Core's is-style-outline replaces the button padding with its own (5px against
   Blocksy's 14.4px), so the two differ by 12px until the row is stretched. Stretching rather than
   restating a padding keeps them matched if either padding changes. */
.occaffe-hero--split .wp-block-buttons { align-items: stretch; }
.occaffe-hero--split .wp-block-button { display: flex; }
.occaffe-hero--split .wp-block-button__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.occaffe-hero--split .occaffe-hero__text {
  padding: clamp(2rem, 5vw, 5.5rem) clamp(1.25rem, 4vw, 4.5rem);
}
.occaffe-hero--split.occaffe-hero--split h1 {
  color: var(--theme-palette-color-4);
  margin: 0.5rem 0 1rem;
  text-shadow: none;
}
.occaffe-hero--split p:not(.occaffe-eyebrow) {
  color: var(--theme-palette-color-3);
  margin-inline: 0;
}
.occaffe-hero--split .occaffe-eyebrow { color: var(--theme-palette-color-1); }
.occaffe-hero--split .wp-block-buttons { justify-content: flex-start; }
.occaffe-hero__trust {
  margin-top: 1.75rem;
  font-size: 0.85rem;
  color: var(--theme-palette-color-3);
  opacity: 0.75;
}
/* Pack shot, not a lifestyle photo: contained with room around it, and multiplied onto the band so the
   white background baked into the product photography disappears instead of showing as a white slab. */
.occaffe-hero--split .occaffe-hero__media {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1.5rem, 3vw, 3rem);
}
.occaffe-hero--split .occaffe-hero__media figure {
  margin: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.occaffe-hero--split .occaffe-hero__media img {
  max-height: 60vh;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
  display: block;
}
/* Blocksy stacks columns below 800px; put the photo above the copy and cap it so it can't eat the
   fold on a phone. */
@media (max-width: 800px) {
  .occaffe-hero--split { flex-direction: column-reverse; gap: 0; }
  .occaffe-hero--split .occaffe-hero__media { padding: 1.5rem 1.5rem 0; }
  .occaffe-hero--split .occaffe-hero__media img { max-height: 34vh; }
}

/* ---- "Aký kávovar máte doma?" tiles (tools/db/apply-kavovar-tiles.php) — custom, no Blocksy
   equivalent. Each tile is a whole click target, so the anchor is stretched over the card rather
   than left as a small link at the bottom. ---- */
.occaffe-doors {
  padding: clamp(2.5rem, 6vw, 4.5rem) 0;
}
.occaffe-doors__lede {
  max-width: 34rem;
  margin-inline: 0;
  color: var(--theme-palette-color-3);
  opacity: 0.8;
}
/* Track sizing and gap come from the block's own Grid layout (core generates them from columnCount /
   minimumColumnWidth / blockGap) — only the offset from the heading is ours. */
.occaffe-doors__grid { margin-top: 2rem; }
.occaffe-door {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.6rem 1.5rem 1.4rem;
  background: var(--theme-palette-color-8);
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 8px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.occaffe-door:hover {
  border-color: var(--theme-palette-color-1);
  box-shadow: 0 14px 30px rgba(33, 22, 17, 0.1);
  transform: translateY(-3px);
}
/* Scales with the viewport because a 2x2 tile is ~160px wide: at the full heading size "Automatický"
   is wider than the tile and breaks mid-word. h2 as well as h3 — the blog hub's tiles sit under the
   page h1, so they cannot skip a level. */
.occaffe-door :is(h2, h3) { margin: 0; font-size: clamp(1.05rem, 2.6vw, 1.6rem); }
.occaffe-door p { color: var(--theme-palette-color-3); font-size: 0.92rem; }
.occaffe-door__cta {
  margin-top: auto;
  padding-top: 0.75rem;
  font-weight: 600;
}
.occaffe-door__cta a { text-decoration: none; }
/* Stretch the CTA over the whole tile — keeps one anchor for screen readers and the keyboard,
   while the entire card is clickable for a mouse. */
.occaffe-door__cta a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.occaffe-door--b2b { background: var(--theme-palette-color-7); }
/* 2x2 on a phone: the tile keeps its label, name and count, and drops the supporting sentence, which
   is what pushes four tiles past a screen height. The same copy is on the filtered page it leads to. */
@media (max-width: 800px) {
  .occaffe-door > p:not(.occaffe-eyebrow):not(.occaffe-door__cta) { display: none; }
  /* A 2x2 tile is ~160px wide; the desktop padding leaves ~114px of text, which drops the CTA arrow
     onto its own line. Tighter gutters and a smaller CTA keep every tile a single line. */
  .occaffe-door { padding: 1.1rem 1rem 1rem; }
  .occaffe-door__cta { font-size: 0.85rem; }
}

/* ---- B2B band (tools/db/apply-b2b-band.php) — same split geometry as the hero, sand band ---- */
.occaffe-b2b {
  align-items: center;
  gap: 0;
  background: var(--theme-palette-color-5);
}
.occaffe-b2b__text {
  padding: clamp(2.5rem, 5vw, 4.5rem) clamp(1.25rem, 4vw, 4rem);
}
.occaffe-b2b__text h2 { margin: 0.4rem 0 0.9rem; }
.occaffe-b2b__text p { color: var(--theme-palette-color-3); max-width: 34rem; }
.occaffe-b2b__cta { margin-top: 1.4rem; font-weight: 600; }
.occaffe-b2b__cta a { text-decoration: none; }
/* Doubled class beats the block editor's own .is-vertically-aligned-center align-self on the column. */
.occaffe-b2b__media.occaffe-b2b__media { align-self: stretch; }
.occaffe-b2b__media figure,
.occaffe-b2b__media img {
  height: 100%;
  width: 100%;
  margin: 0;
  object-fit: cover;
  display: block;
}
@media (max-width: 800px) {
  .occaffe-b2b__media img { max-height: 34vh; }
}

/* ---- Trust row (tools/db/apply-trust-row.php) — custom, no Blocksy equivalent ---- */
.occaffe-trust {
  padding: clamp(2.5rem, 5vw, 4rem) 0;
  border-top: 1px solid var(--theme-palette-color-5);
}
.occaffe-trust__grid { gap: clamp(1.5rem, 4vw, 3rem); }
.occaffe-trust__item h3 {
  margin: 0 0 0.5rem;
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
  line-height: 1.25;
}
.occaffe-trust__item p {
  margin: 0;
  font-size: 0.92rem;
  color: var(--theme-palette-color-3);
  opacity: 0.85;
}

/* ---- Header polish — unconfirmed native equivalent for hiding the redundant text site-title
   alongside a custom logo, so left as-is rather than guessed. ---- */
.ct-header .menu-item > a { letter-spacing: 0.04em; }
/* The O'CCAFFÈ custom_logo now carries the brand — hide the redundant text site-title
   (kept in DOM with its alt-bearing logo for a11y/SEO; just visually removed). */
.site-title-container { display: none; }
.site-logo-container .default-logo,
.site-logo-container img { max-height: 58px; height: auto; width: auto; }

/* ---- Unit price + intensity meter (inc/product.php) — custom, no Blocksy equivalent ---- */
.occaffe-perkg {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.78rem;
  color: var(--theme-palette-color-3);
  opacity: 0.75;
}
.occaffe-intensity {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.55rem;
  font-size: 0.72rem;
  color: var(--theme-palette-color-3);
}
.occaffe-intensity__label {
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.occaffe-intensity__track {
  flex: 1 1 auto;
  min-width: 2.5rem;
  max-width: 5rem;
  height: 4px;
  background: rgba(33, 22, 17, 0.1);
  border-radius: 99px;
  overflow: hidden;
}
.occaffe-intensity__track > span {
  display: block;
  height: 100%;
  background: var(--theme-palette-color-1);
  border-radius: 99px;
}
.occaffe-intensity__value {
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

/* Stock-availability cues (functions.php: occaffe_stock_state) — custom, no Blocksy equivalent.
   Sage = available, amber = scarcity — distinct from Blocksy's own sale-badge accent. */
.occ-stock {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.occ-stock--in { color: #5f7a4f; }
.occ-stock--low,
.occ-stock--last { color: #b5651d; }
.occ-stock--last { font-weight: 700; }
/* Orderable but not on the shelf — neither the green of "Skladom" nor the alarm of "Posledný kus!". */
.occ-stock--backorder { color: var(--theme-palette-color-2); }
/* Product-detail availability line (p.stock) when low — override Woo's default green. */
.woocommerce div.product p.stock.occ-stock--low,
.woocommerce div.product p.stock.occ-stock--last { color: #b5651d; font-weight: 700; }

/* Cart line stock note — custom, no Blocksy equivalent. Hidden until it matters (low stock, or qty at the cap). */
.occ-cart-stock {
  display: none;
  margin-top: 0.3rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: #b5651d;
}
.occ-cart-stock--low,
.occ-cart-stock--max { display: block; }
.occ-cart-stock__max { display: none; }
.occ-cart-stock--max .occ-cart-stock__max { display: inline; }

/* ---- WooCommerce product cards: box only (background/border/radius/shadow) — custom, no Blocksy
   equivalent. Confirmed by reading card-product-elements.php: Card Options only exposes per-element
   typography (Title/Price/Taxonomies font+color) and per-button colors, no container-level box style
   at all in the free theme. Title/price TEXT color is left to those native Font Color controls instead
   of duplicated here — only the box itself and the image radius/spacing have nothing native to defer to. */
.woocommerce ul.products li.product {
  background: var(--theme-palette-color-8);
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 8px;
  padding: 16px 16px 20px;
  transition: box-shadow 0.25s ease, transform 0.25s ease, border-color 0.25s ease;
}
.woocommerce ul.products li.product:hover {
  box-shadow: 0 16px 34px rgba(33, 22, 17, 0.12);
  border-color: var(--theme-palette-color-1);
  transform: translateY(-4px);
}
.woocommerce ul.products li.product a img {
  border-radius: 4px;
  margin-bottom: 1rem;
}

/* ---- Category tiles: same story as product cards — the box itself has no Card Options equivalent.
   The title/count-badge colors are custom too, since these are shop_categories tiles, not per-product
   taxonomy labels (the only taxonomy-label typography control the panel exposes). ---- */
.woocommerce ul.products li.product-category {
  background: var(--theme-palette-color-4);
  border-radius: 8px;
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.woocommerce ul.products li.product-category:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 34px rgba(33, 22, 17, 0.22);
}
.woocommerce ul.products li.product-category a { padding: 0; }
.woocommerce ul.products li.product-category img {
  margin: 0 0 0.6rem;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  width: 100%;
}
.woocommerce ul.products li.product-category h2.woocommerce-loop-category__title {
  color: #fff;
  font-size: 1.05rem;
  padding: 0 1rem 1.1rem;
  text-align: center;
}
.woocommerce ul.products li.product-category h2 .count {
  background: rgba(255, 255, 255, 0.12);
  color: var(--theme-palette-color-6);
  font-family: system-ui, sans-serif;
  font-size: 0.72rem;
  font-weight: 600;
}
/* Categories without a thumbnail → clean centered espresso block (no broken placeholder icon) */
.woocommerce ul.products li.product-category:has(img[src*="placeholder"]) {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 232px;
  background: var(--theme-palette-color-4);
}
.woocommerce ul.products li.product-category:has(img[src*="placeholder"]) img { display: none; }
.woocommerce ul.products li.product-category:has(img[src*="placeholder"]) h2.woocommerce-loop-category__title {
  padding: 1.6rem;
  font-size: 1.25rem;
  color: var(--theme-palette-color-6);
}

/* ---- Long-form pages: comfortable reading measure (legal pages, Kontakt) ----
   Blocksy stretches page text to the full ~1240px content column (~150 chars/line). Cap text blocks at
   ~46rem (left-aligned, matching the page title); media/tables/figures stay full width. The static
   front page is full-width by design (excluded via :not(.home)). No Blocksy equivalent — this is
   conditional on page type, not a site-wide content-width setting. */
.page:not(.home) .entry-content > :where(p, ul, ol, h2, h3, h4, h5, blockquote, figcaption) {
  max-width: 46rem;
}

/* ---- Blog index heading (injected via blocksy:loop:before) — custom, no Blocksy equivalent ---- */
.occaffe-blog-header { margin: 0 0 2.5rem; }

/* ---- Archive / blog loop: post-card title size ----
   The loop's h2.entry-title inherits the global heading scale and balloons to 7-8 lines in a 3-column
   grid. Kept as an explicit override — unconfirmed whether Blocksy's Typography panel has a distinct
   archive-card-title size separate from the single-post title, and getting this wrong reintroduces a
   real, previously-documented visual bug. */
.entries .entry-title {
  font-size: clamp(1.3rem, 1.5vw, 1.5rem);
  line-height: 1.22;
}

/* Clamp the card excerpt to 2 lines for an even grid — a CSS truncation safety net, distinct from
   Blocksy's own excerpt-length (word count) setting. */
.entries .entry-excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Accessibility: visible keyboard focus ring (WCAG 2.4.7) — no Blocksy equivalent ----
   Blocksy's default focus state is faint. Give interactive elements a clear bronze ring; flip it to
   cream inside the dark hero and any palette-color-4 band so it stays visible there. Only shows for
   keyboard users (:focus-visible), so mouse clicks are unaffected. */
:where(a, button, input, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--theme-palette-color-2);
  outline-offset: 2px;
  border-radius: 2px;
}
.occaffe-hero :focus-visible,
.has-palette-color-4-background-color :focus-visible {
  outline-color: var(--theme-palette-color-7);
}

/* ---- Free-shipping progress cue (cart, via woocommerce_before_cart) — custom, no Blocksy equivalent ---- */
.occaffe-free-ship {
  background: var(--theme-palette-color-7);
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
}
.occaffe-free-ship__msg { margin: 0 0 0.6rem; color: var(--theme-palette-color-3); }
.occaffe-free-ship__msg--done { color: var(--theme-palette-color-2); }
/* compact variant for the mini-cart drawer — message only, tighter spacing */
.occaffe-free-ship--compact { padding: 0.6rem 0.8rem; margin-bottom: 0.8rem; font-size: 0.85rem; }
.occaffe-free-ship--compact .occaffe-free-ship__msg { margin: 0; }
.occaffe-free-ship__track {
  height: 8px;
  background: rgba(33, 22, 17, 0.08);
  border-radius: 99px;
  overflow: hidden;
}
.occaffe-free-ship__track span {
  display: block;
  height: 100%;
  background: var(--theme-palette-color-1);
  border-radius: 99px;
  transition: width 0.4s ease;
}

/* ---- Cookie consent (Complianz): equal-weight Accept/Reject, on-brand (GDPR — no dark pattern) ----
   Re-skins the COMPLIANZ PLUGIN's own generated classes, not Blocksy — no native equivalent applies.
   Complianz ships a prominent blue "Prijať" and a faint grey "Odmietnuť" / "Zobraziť predvoľby"
   (unequal prominence = a consent dark pattern, and the blue is off-brand). Give Accept + Reject EQUAL
   visual weight as filled brand buttons of the same size; keep "view preferences" as a clear bordered
   secondary. Theme CSS overrides Complianz's generated styles, so it ships via the CI build and survives
   plugin updates without depending on the (unpinned) plugin's CSS regeneration. */
.cmplz-btn.cmplz-accept,
.cmplz-btn.cmplz-accept-all,
.cmplz-btn.cmplz-accept-marketing {
  background-color: var(--theme-palette-color-1) !important;
  color: #fff !important;
  border: 1px solid var(--theme-palette-color-1) !important;
}
.cmplz-btn.cmplz-deny {
  background-color: var(--theme-palette-color-4) !important;
  color: var(--theme-palette-color-7) !important;
  border: 1px solid var(--theme-palette-color-4) !important;
}
.cmplz-btn.cmplz-view-preferences {
  background-color: var(--theme-palette-color-7) !important;
  color: var(--theme-palette-color-2) !important;
  border: 1px solid var(--theme-palette-color-5) !important;
}
.cmplz-cookiebanner a.cmplz-link,
.cmplz-cookiebanner a.cmplz-manage-options {
  color: var(--theme-palette-color-2) !important;
}

/* ---- Product page: compact spec block (above the buy button) — custom, no Blocksy equivalent ---- */
.occaffe-spec { margin: 1.25rem 0 1.5rem; padding: 0; }
.occaffe-spec__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--theme-palette-color-5);
}
.occaffe-spec__row:first-child { border-top: 1px solid var(--theme-palette-color-5); }
.occaffe-spec__row dt {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--theme-palette-color-2);
}
.occaffe-spec__row dd { margin: 0; text-align: right; color: var(--theme-palette-color-3); }

/* ---- Mobile sticky Add-to-Cart bar (product page) — custom, no Blocksy equivalent (incl. in Pro) ---- */
.occaffe-sticky-atc {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem 1rem calc(0.7rem + env(safe-area-inset-bottom));
  background: var(--theme-palette-color-8);
  border-top: 1px solid var(--theme-palette-color-5);
  box-shadow: 0 -6px 20px rgba(33, 22, 17, 0.12);
  transform: translateY(100%);
  transition: transform 0.25s ease;
}
.occaffe-sticky-atc.is-visible { transform: translateY(0); }
.occaffe-sticky-atc__info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.occaffe-sticky-atc__title {
  font-size: 0.82rem;
  color: var(--theme-palette-color-4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.occaffe-sticky-atc__price { font-weight: 700; color: var(--theme-palette-color-2); }
.occaffe-sticky-atc__price del { color: #b7a795; font-weight: 400; margin-right: 0.3rem; }
.occaffe-sticky-atc__btn {
  flex: 0 0 auto;
  background: var(--theme-palette-color-1);
  color: #fff;
  border: 0;
  border-radius: 2px;
  padding: 0.85em 1.5em;
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
}
.occaffe-sticky-atc__btn:hover { background: var(--theme-palette-color-2); }
@media (min-width: 769px) {
  .occaffe-sticky-atc { display: none; }
}

/* Add-to-cart confirmation toast (single product, AJAX add) — custom, no Blocksy equivalent */
.occaffe-cart-toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  transform: translate(-50%, 1rem);
  z-index: 100000;
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: calc(100vw - 2rem);
  padding: 0.85rem 1.15rem;
  background: var(--theme-palette-color-4);
  color: var(--theme-palette-color-8);
  border-radius: 4px;
  box-shadow: 0 10px 30px rgba(33, 22, 17, 0.28);
  font-size: 0.95rem;
  line-height: 1.3;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.occaffe-cart-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.occaffe-cart-toast__msg { font-weight: 600; }
.occaffe-cart-toast__msg::before {
  content: "\2713";          /* ✓ */
  margin-right: 0.5rem;
  font-weight: 700;
  color: var(--theme-palette-color-6);
}
.occaffe-cart-toast__link {
  flex: 0 0 auto;
  color: var(--theme-palette-color-6);
  font-weight: 700;
  text-decoration: underline;
  white-space: nowrap;
}
.occaffe-cart-toast__link:hover { color: var(--theme-palette-color-8); }
/* Lift above the mobile sticky add-to-cart bar so they don't overlap */
@media (max-width: 768px) {
  .occaffe-cart-toast { bottom: 5.5rem; left: 1rem; right: 1rem; transform: translateY(1rem); }
  .occaffe-cart-toast.is-visible { transform: translateY(0); }
}

/* ---- Checkout: on-brand progress bar ----
   Re-skins the FLUID CHECKOUT PLUGIN's own classes, not Blocksy — no native equivalent applies.
   Fluid Checkout defaults to a green that clashes with the brand. */
.fc-progress-bar__step.is-current,
.fc-progress-bar__step.is-complete,
.fc-progress-bar__step.is-current .fc-progress-bar__bar,
.fc-progress-bar__step.is-complete .fc-progress-bar__bar {
  background-color: var(--theme-palette-color-1) !important;
  border-color: var(--theme-palette-color-1) !important;
  color: var(--theme-palette-color-8) !important;
}

/* Shop product filter (custom, code-only) — a compact bar of dropdown selectors above the grid.
   No Blocksy equivalent: its native WooCommerce filter widgets are Companion-Pro-only and not installed. */
.occaffe-shop-filter {
  margin: 0 0 1.75rem;
}
.occ-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.occ-facet {
  position: relative;
}
/* the pill / trigger */
.occ-facet__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55em 1em;
  background: var(--theme-palette-color-8);
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--theme-palette-color-3);
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
  transition: border-color 0.15s, background 0.15s;
}
.occ-facet__toggle::-webkit-details-marker { display: none; }
.occ-facet__toggle::after {
  content: "";
  width: 0.45em;
  height: 0.45em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-1px) rotate(45deg);
  opacity: 0.5;
  transition: transform 0.15s;
}
.occ-facet__toggle:hover { border-color: var(--theme-palette-color-1); }
.occ-facet[open] .occ-facet__toggle {
  border-color: var(--theme-palette-color-1);
  background: var(--theme-palette-color-7);
}
.occ-facet[open] .occ-facet__toggle::after { transform: translateY(1px) rotate(225deg); }
/* selected-count badge */
.occ-facet__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25em;
  height: 1.25em;
  padding: 0 0.35em;
  background: var(--theme-palette-color-1);
  color: #fff;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
}
/* the dropdown panel */
.occ-facet__panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 0.4rem);
  left: 0;
  min-width: 13rem;
  max-height: 17rem;
  overflow-y: auto;
  padding: 0.4rem;
  background: var(--theme-palette-color-8);
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(33, 22, 17, 0.12);
}
.occ-facet__opt {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4em 0.5em;
  border-radius: 5px;
  font-size: 0.9rem;
  color: var(--theme-palette-color-3);
  cursor: pointer;
}
.occ-facet__opt:hover { background: var(--theme-palette-color-7); }
.occ-facet__opt input { accent-color: var(--theme-palette-color-1); flex: none; margin: 0; }
/* price panel */
.occ-facet__panel--price {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  overflow: visible;
}
.occ-facet__panel--price input[type="number"] {
  width: 5rem;
  padding: 0.45em 0.55em;
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 5px;
  font-size: 0.9rem;
}
.occ-facet__dash { color: var(--theme-palette-color-3); }
/* apply + reset */
.occ-facet__apply {
  background: var(--theme-palette-color-1);
  color: #fff;
  border: 0;
  border-radius: 999px;
  padding: 0.62em 1.5em;
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}
.occ-facet__apply:hover { background: var(--theme-palette-color-2); }
/* active-filter chips — visible, removable summary of the current selection */
.occ-active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin: 0.9rem 0 1.1rem;
}
.occ-active-filters__label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--theme-palette-color-3);
  opacity: 0.65;
}
.occ-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3em 0.7em;
  background: var(--theme-palette-color-7);
  border: 1px solid var(--theme-palette-color-5);
  border-radius: 999px;
  font-size: 0.82rem;
  color: var(--theme-palette-color-3);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.occ-chip:hover { background: var(--theme-palette-color-7); border-color: var(--theme-palette-color-1); }
.occ-chip__x { font-size: 1.1em; line-height: 1; color: var(--theme-palette-color-2); }
.occ-chip--clear {
  background: transparent;
  border-color: transparent;
  color: var(--theme-palette-color-2);
  text-decoration: underline;
}
.occ-chip--clear:hover { background: transparent; border-color: transparent; }
@media (max-width: 600px) {
  .occ-facet { flex: 1 1 100%; }
  .occ-facet__toggle { width: 100%; justify-content: space-between; }
  .occ-facet__panel {
    position: static;
    width: 100%;
    min-width: 0;
    max-height: 50vh;
    margin-top: 0.4rem;
    box-shadow: none;
  }
  .occ-facet__apply { flex: 1 1 100%; }
}


/* ---- Product page: taste profile + preparation band — custom, no Blocksy equivalent ----
   Hooked at woocommerce_after_single_product_summary priority 5, which is outside Blocksy's
   is-width-constrained wrapper (it closes at priority 1), so the tint reaches the viewport edges
   without a breakout hack. Band is slot 5 and the shapes inside it slot 7 — slot 7 is the body colour,
   so a slot 7 band is invisible and a slot 5 border inside one disappears. Rules and card borders are
   translucent slot-4 ink: the palette has no step between slot 5 and slot 3 to draw a hairline with. */
.occaffe-profile {
  background: var(--theme-palette-color-5);
  padding: 3.5rem 1.25rem;
  margin-top: 3.5rem;
}
.occaffe-profile__inner {
  max-width: var(--theme-content-width, 1290px);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}
.occaffe-profile__eyebrow {
  margin: 0 0 0.9rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--theme-palette-color-1);
}
.occaffe-profile__notes {
  margin: 0 0 1.4rem;
  font-family: var(--theme-font-family, inherit);
  font-size: 1.5rem;
  line-height: 1.25;
  color: var(--theme-palette-color-4);
  text-wrap: pretty;
}
.occaffe-profile__axes { margin: 0; }
.occaffe-profile__axis {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid rgba(33, 22, 17, 0.12);
}
.occaffe-profile__axis dt { margin: 0; color: var(--theme-palette-color-3); }
.occaffe-profile__axis dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
  color: var(--theme-palette-color-4);
}
.occaffe-profile__brews {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
}
.occaffe-profile__brew {
  background: var(--theme-palette-color-7);
  border: 1px solid rgba(33, 22, 17, 0.12);
  border-radius: 6px;
  padding: 1rem 1.1rem;
}
.occaffe-profile__brew-title {
  margin: 0 0 0.3rem;
  font-weight: 600;
  color: var(--theme-palette-color-4);
}
.occaffe-profile__brew-desc {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--theme-palette-color-3);
  text-wrap: pretty;
}
.occaffe-profile__tip {
  background: var(--theme-palette-color-4);
  border-radius: 6px;
  padding: 1.1rem 1.25rem;
  margin-top: 0.75rem;
}
.occaffe-profile__eyebrow--onDark { color: var(--theme-palette-color-6); }
.occaffe-profile__tip-text {
  margin: 0;
  line-height: 1.6;
  color: var(--theme-palette-color-7);
  text-wrap: pretty;
}
@media (min-width: 768px) {
  .occaffe-profile { padding: 4.5rem 2rem; }
  .occaffe-profile__inner { grid-template-columns: 1fr 1fr; gap: 4rem; }
  .occaffe-profile__brews { grid-template-columns: 1fr 1fr; }
  .occaffe-profile__notes { font-size: 1.85rem; }
}
