/**
 * Coffeeness new product pages (the 6 redesigned cleaning/maintenance products).
 *
 * Ported from the approved produkt-*.html mockups in
 * "HTML Templates/Product Templates/". All component styles are scoped under
 * `.cn-pdp` so the generic class names (.section, .wrap, .stars, .pc, .pdp-*, ...)
 * never leak into the rest of the site or collide with Astra / WooCommerce.
 *
 * Gallery/price/stock/add-to-cart/rating/reviews are the REAL WooCommerce +
 * Customer Reviews for WooCommerce plugin output (see the woocommerce/single-product/*.php
 * overrides and functions.php:cn_render_product_page()) - this stylesheet only
 * re-skins their actual selectors (.price, .stock-and-shipping, .limited, form.cart,
 * .woocommerce-product-rating and the #reviews plugin selectors) to match the mockup design,
 * it never rebuilds their markup or logic.
 *
 * Markup: woocommerce/single-product-{slug}.php -> template-parts/product/content-*.php
 * Behaviour: js/product.js | Enqueued in functions.php (child_enqueue_styles).
 */

.cn-pdp{
  --font-head:"Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background:#f9f9f9;
  color:var(--text);
  font-family:"Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing:antialiased;
  line-height:normal;
}
.cn-pdp *{box-sizing:border-box;}
.cn-pdp a{color:inherit;text-decoration:none;}
.cn-pdp img{max-width:100%;}

/* ===== Browser-default typography restoration (see css/category.css for why) ===== */
.cn-pdp h1{font-size:2em;margin:.67em 0;font-weight:bold;line-height:normal;}
.cn-pdp h2{font-size:1.5em;margin:.83em 0;font-weight:bold;line-height:normal;}
.cn-pdp h3{font-size:1.17em;margin:1em 0;font-weight:bold;line-height:normal;}
.cn-pdp h4{font-size:1em;margin:1.33em 0;font-weight:bold;line-height:normal;}
.cn-pdp p{margin:1em 0;}
.cn-pdp ul,.cn-pdp ol{margin:1em 0;padding-left:40px;}
.cn-pdp input,.cn-pdp textarea{line-height:normal;min-height:0;box-shadow:none;}
.cn-pdp button{line-height:normal;min-height:0;text-transform:none;letter-spacing:normal;}

/* ===== Shared layout/components (mirrors css/category.css) ===== */
.cn-pdp .wrap{max-width:1360px;margin:0 auto;padding:0 24px;}
.cn-pdp .section{padding:62px 0 70px;}
.cn-pdp .cn-pdp-notices .woocommerce-message,
.cn-pdp .cn-pdp-notices .woocommerce-info,
.cn-pdp .cn-pdp-notices .woocommerce-error,
.cn-pdp .cn-pdp-notices .woocommerce-error li{margin-bottom:25px;top:20px;}
.cn-pdp .cn-pdp-notices + .pdp{padding-top:15px;}
.cn-pdp .section-head{text-align:center;max-width:680px;margin:0 auto 36px;padding:0 20px;}
.cn-pdp .section-title{font-family:var(--font-head);font-weight:800;font-size:2.25rem;line-height:1.1;color:var(--dark);margin:0 0 10px;}
.cn-pdp .stars{position:relative;display:inline-block;font-size:15px;line-height:1;letter-spacing:1px;font-family:Arial,sans-serif;}
.cn-pdp .stars::before{content:"\2605\2605\2605\2605\2605";color:#9E9E9E;}
.cn-pdp .stars .fill{position:absolute;top:0;left:0;overflow:hidden;white-space:nowrap;color:#FFBB1E;}
.cn-pdp .stars .fill::before{content:"\2605\2605\2605\2605\2605";}
.cn-pdp .pc-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;}
.cn-pdp .pc{background:#fff;border:1px solid #efecea;border-radius:14px;overflow:hidden;display:flex;flex-direction:column;text-decoration:none;color:var(--text);transition:box-shadow .18s ease, transform .18s ease, border-color .18s ease;}
.cn-pdp .pc:hover{box-shadow:0 14px 30px rgba(3,41,54,.10);border-color:#e3ddd6;}
.cn-pdp .pc-imgwrap{position:relative;aspect-ratio:1/1;background:#efecea;}
.cn-pdp .pc-imgwrap img{width:100%;height:100%;object-fit:cover;display:block;}
.cn-pdp .pc-badge{position:absolute;top:11px;left:11px;background:#285bb8;color:#fff;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:5px 11px;border-radius:30px;}
.cn-pdp .pc-badge--sale{background:#e05858;font-size:.92rem;padding:7px 15px;top:12px;left:12px;letter-spacing:.02em;}
.cn-pdp .pc-body{padding:18px 18px 20px;display:flex;flex-direction:column;gap:9px;flex:1;}
.cn-pdp .pc-rating{display:flex;align-items:center;gap:6px;}
.cn-pdp .pc-rnum{font-weight:700;font-size:.92rem;color:var(--dark);}
.cn-pdp .pc-rcount{font-size:.85rem;color:#9E9E9E;}
.cn-pdp .pc-title{font-size:1.3rem;font-weight:700;line-height:1.28;margin:0;color:var(--dark);}
.cn-pdp .pc-foot{margin-top:auto;display:flex;flex-direction:column;gap:1px;padding-top:4px;}
.cn-pdp .pc-price{font-size:1.4rem;font-weight:700;color:var(--dark);}
.cn-pdp .pc-unit{font-size:.8rem;font-weight:600;color:#9E9E9E;}
.cn-pdp .pc-priceline{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;}
.cn-pdp .pc-old{color:#9E9E9E;text-decoration:line-through;font-size:1rem;font-weight:600;}
.cn-pdp .pc-save{display:inline-block;margin-top:3px;font-size:.85rem;color:#21a54d;font-weight:700;}
.cn-pdp .pc-btn{display:block;text-align:center;background:#285bb8;color:#fff;font-weight:700;font-size:1rem;padding:13px;border-radius:10px;margin-top:13px;transition:background .15s ease;}
.cn-pdp .pc:hover .pc-btn{background:#284985;}
.cn-pdp .pc-btn--notify{background:#fff;color:#285bb8;border:1.6px solid #285bb8;}
.cn-pdp .pc:hover .pc-btn--notify{background:#eef3fb;color:#285bb8;}
.cn-pdp .pc-benefits{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px;}
.cn-pdp .pc-benefits li{display:flex;gap:8px;align-items:flex-start;font-size:1.04rem;line-height:1.45;color:#032936;}
.cn-pdp .pc-benefits li svg{flex:0 0 auto;width:15px;height:15px;margin-top:2px;stroke:#21a54d;fill:none;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;}
.cn-pdp .pc-soldout img{filter:grayscale(.5);opacity:.65;}
.cn-pdp .pc-soldout .pc-badge{filter:grayscale(.45);opacity:.7;z-index:2;}
.cn-pdp .pc-soldout-tag{position:absolute;z-index:3;left:50%;bottom:12px;transform:translateX(-50%);background:#032936;color:#fff;font-size:.8rem;font-weight:700;padding:7px 16px;border-radius:999px;white-space:nowrap;box-shadow:0 4px 12px rgba(3,41,54,.25);}
.cn-pdp .faq{max-width:820px;margin:0 auto;}
.cn-pdp .faq-item{border-bottom:1px solid #efecea;}
.cn-pdp .faq-q{width:100%;text-align:left;background:none;border:0;cursor:pointer;padding:20px 2px;display:flex;justify-content:space-between;align-items:center;gap:16px;font-size:1.08rem;font-weight:600;color:#032936;font-family:inherit;}
.cn-pdp .faq-q .faq-ic{flex:0 0 auto;width:22px;height:22px;stroke:#285bb8;fill:none;stroke-width:2.4;stroke-linecap:round;transition:transform .25s ease;}
.cn-pdp .faq-item.open .faq-q .faq-ic{transform:rotate(45deg);}
.cn-pdp .faq-a{max-height:0;overflow:hidden;transition:max-height .28s ease;}
.cn-pdp .faq-a-inner{padding:0 2px 20px;color:#032936;line-height:1.6;font-size:1.04rem;}
.cn-pdp .abo-final{background:#efecea;padding:60px 0;text-align:center;}
.cn-pdp .abo-final h2{font-family:var(--font-head);font-weight:700;font-size:clamp(1.7rem,2.8vw,2.5rem);margin:0 0 12px;color:#032936;}
.cn-pdp .abo-final p{color:#032936;margin:0 auto 26px;font-size:1.06rem;max-width:54ch;}
.cn-pdp .abo-final .f-cta{display:inline-block;background:#285bb8;color:#fff;font-weight:600;font-size:1.06rem;padding:16px 38px;border-radius:10px;text-decoration:none;transition:background .15s ease;}
.cn-pdp .abo-final .f-cta:hover{background:#284985;}
.cn-pdp .abo-final .cta-buttons{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;}
.cn-pdp .abo-final .abo-cta-ghost{display:inline-flex;align-items:center;gap:8px;background:transparent;border:2px solid #285bb8;color:#285bb8;font-weight:700;font-size:1.02rem;padding:14px 26px;border-radius:10px;text-decoration:none;transition:background .15s ease,color .15s ease;}
.cn-pdp .abo-final .abo-cta-ghost:hover{background:#285bb8;color:#fff;}
.cn-pdp .promise-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:34px;}
.cn-pdp .promise{text-align:center;padding:6px 14px;}
.cn-pdp .promise-ic{width:66px;height:66px;border-radius:50%;background:#efecea;display:flex;align-items:center;justify-content:center;margin:0 auto 18px;}
.cn-pdp .promise-ic svg{width:31px;height:31px;stroke:#285bb8;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.cn-pdp .promise-title{font-family:var(--font-head);font-weight:700;font-size:1.18rem;color:#032936;margin:0 0 11px;}
.cn-pdp .promise-text{font-size:1.04rem;line-height:1.55;color:#032936;margin:0;}
.cn-pdp .promise-text a{color:#285bb8;font-weight:600;text-decoration:underline;text-underline-offset:2px;}
.cn-pdp .promise-text a:hover{color:#284985;}
@media (max-width:760px){ .cn-pdp .promise-grid{grid-template-columns:1fr;gap:32px;} }

/* ===== PDP gallery + buy box ===== */
.cn-pdp .pdp{padding:30px 0 8px;}
.cn-pdp .crumb{font-size:.85rem;color:#9E9E9E;margin:0 0 16px;display:flex;gap:7px;flex-wrap:wrap;}
.cn-pdp .crumb a{color:#9E9E9E;text-decoration:none;}
.cn-pdp .crumb a:hover{color:#285bb8;}
.cn-pdp .pdp-grid{display:grid;grid-template-columns:minmax(0,500px) 1fr;gap:52px;align-items:start;}
.cn-pdp .pdp-gallery{position:static;}
.cn-pdp .pdp-main{position:relative;border:1px solid #efecea;border-radius:14px;overflow:hidden;background:#fff;aspect-ratio:1/1;}
.cn-pdp .pdp-main img{width:100%;height:100%;object-fit:cover;display:block;}
.cn-pdp .pdp-thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:12px;}
.cn-pdp .pdp-thumb{aspect-ratio:1/1;border-radius:10px;overflow:hidden;border:2px solid #efecea;background:#fff;cursor:pointer;padding:0;transition:border-color .15s ease;}
.cn-pdp .pdp-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
.cn-pdp .pdp-thumb.active{border-color:#efecea;}
.cn-pdp .pdp-buy{display:flex;flex-direction:column;}
.cn-pdp .pdp-h1{font-family:var(--font-head);font-weight:700;font-size:clamp(1.5rem,2.5vw,2.05rem);line-height:1.2;color:#032936;margin:0 0 12px;}
.cn-pdp .pdp-sub{font-size:1.04rem;line-height:1.55;color:#032936;margin:0 0 22px;}
.cn-pdp .pdp-benefits{list-style:none;margin:0 0 22px;padding:0;display:flex;flex-direction:column;gap:12px;}
.cn-pdp .pdp-benefits li{display:flex;gap:11px;align-items:flex-start;font-size:1.04rem;line-height:1.5;color:#032936;}
.cn-pdp .pdp-benefits li svg{flex:0 0 auto;width:19px;height:19px;margin-top:1px;stroke:#21a54d;fill:none;stroke-width:2.7;stroke-linecap:round;stroke-linejoin:round;}
.cn-pdp .buy-airy{display:flex;flex-direction:column;}
.cn-pdp .buy-airy .divider{height:1px;background:#efecea;margin:0 0 10px;}
.cn-pdp .pdp-try{font-size:.92rem;color:#9E9E9E;margin:0;line-height:1.55;}
.cn-pdp .pdp-try a{color:#285bb8;font-weight:600;}

/* The EU legal-warranty disclosure that follows .pdp-try in the buy column is
   styled in css/warranty-label.css - it's shared with the old product layout,
   which never loads this file. */
/* Optional per-product purchase-restriction note (e.g. "only available combined
   with a coffee bean order") shown between the benefit list and the buy box. */
.cn-pdp .pdp-hint{font-size:.85rem;color:#8a857f;margin:0 0 12px;line-height:1.5;}
@media (max-width:900px){ .cn-pdp .pdp-grid{grid-template-columns:1fr;gap:24px;} .cn-pdp .pdp-gallery{max-width:500px;} }

/* ---- Rating line above the h1 (live average/count, rendered via cn_pdp_render_rating()
   using the mockup's own .stars/.fill markup instead of WooCommerce's star-rating icon
   font, so it matches the approved design exactly) ---- */
.cn-pdp .pdp-rating{display:inline-flex;align-items:center;gap:8px;text-decoration:none;margin-bottom:12px;align-self:flex-start;}
.cn-pdp .pdp-rating .stars{font-size:17px;}
.cn-pdp .pdp-rating .pr-num{font-weight:700;color:#032936;}
.cn-pdp .pdp-rating .pr-count{font-size:.9rem;color:#285bb8;text-decoration:underline;}
.cn-pdp .pdp-rating:hover .pr-count{color:#284985;}

/* ---- Price/stock/shipping (real markup: woocommerce/single-product/price.php) - the mockup
   has NO background box behind this area (that's only used by a different, unused .buy-box
   variant elsewhere in the shared stylesheet); price/availability/form sit directly on the
   page, spaced with margins instead of a shared flex gap so the tight 3px price-to-tax-line
   rhythm from the mockup survives even though price.php renders them as separate siblings
   rather than the mockup's single wrapping div. ---- */
.cn-pdp .buy-airy > .price{margin:0 0 3px;font-family:var(--font-head);font-weight:700;font-size:1.7rem;color:#032936;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;}
.cn-pdp .buy-airy > .price ins{text-decoration:none;}
.cn-pdp .buy-airy > .price del{font-size:1.05rem;font-weight:600;color:#9E9E9E;order:1;}
.cn-pdp .buy-airy > .price .save-label{font-family:var(--font-head);font-size:.85rem;font-weight:700;color:#21a54d;order:2;}
/* Was 40px - Alex asked for less margin throughout the whole buy box stack (every
   item here had its own bottom margin that added up), this was the single largest
   contributor. The live price template groups tax + availability inside this
   wrapper, unlike the mockup's separate .avail flex item, so the spacing is
   carried here rather than on a shared flex gap. */
.cn-pdp .buy-airy .stock-and-shipping{margin:0 0 16px;}
.cn-pdp .buy-airy .stock-and-shipping p{font-size:.85rem;color:#8a857f;margin:0 0 12px;}
.cn-pdp .buy-airy .stock-and-shipping p:last-child{margin-bottom:0;font-size:.93rem;color:#032936;display:flex;align-items:center;gap:8px;}
.cn-pdp .buy-airy .stock-and-shipping p a{color:#285bb8;}
/* Real markup wraps the checkmark icon + "Verfügbar." in an inline-styled green
   span (woocommerce/single-product/price.php); the mockup instead shows a plain
   CSS dot and bolds "Verfügbar." - re-skinned to match without touching the
   inline color (which is fine to keep, it's the same green). */
.cn-pdp .buy-airy .stock-and-shipping p:last-child > span:first-child{display:inline-flex;align-items:center;gap:8px;font-weight:600;}
.cn-pdp .buy-airy .stock-and-shipping p:last-child > span:first-child i{display:none;}
.cn-pdp .buy-airy .stock-and-shipping p:last-child > span:first-child::before{content:"";width:9px;height:9px;border-radius:50%;background:#21a54d;box-shadow:0 0 0 3px rgba(33,165,77,.18);flex:0 0 auto;}

/* ---- "Versandkostenfrei" + contact box (real markup: woocommerce/single-product/price.php,
   rendered right after .stock-and-shipping and BEFORE the add-to-cart form) - the mockup
   has no separate box here (its own shipping/contact copy is in .pdp-try below the
   add-to-cart button instead), so hide the real one on this template. ---- */
.cn-pdp .buy-airy .limited{display:none;}

/* ---- Add-to-cart form (real markup: woocommerce/single-product/add-to-cart/simple.php) ----
   .stock is the plain wc_get_stock_html() badge; Astra's own WooCommerce compatibility layer
   additionally wraps/replaces it with .ast-stock-detail (adds a "Verfügbarkeit:" label) right
   before the form - both are redundant with the real availability line already shown inside
   .stock-and-shipping above, so both are hidden here. */
.cn-pdp .buy-airy .stock,
.cn-pdp .buy-airy .ast-stock-detail{display:none;}
/* Vertical margin: 0 (was 5px, then 22px in earlier history - the mockup's static
   PayPal anchor doesn't apply to the real, taller PayPal Payments SDK button, so
   that spacing no longer made sense). Horizontal margin: -12px, matching this same
   rule's own gap:12px below - form.cart is the only child of .buy-airy that visibly
   sat inset from the full-width PayPal button beneath it; Alex found live on
   staging that this exact negative margin (not a fix on the children) is what
   makes it reach the same edges. */
.cn-pdp .buy-airy form.cart{margin:0 -12px;display:flex;gap:12px;align-items:stretch;flex-wrap:wrap;}
/* Quantity box vs. add-to-cart button height/width/margin parity. Adding the
   "product" class to .cn-pdp (needed for Astra's sticky-add-to-cart JS - see
   cn_render_product_page()) had a side effect: it activated a whole family of
   astra-child/style.css AND astra/.../compatibility/woocommerce/woocommerce.min.css
   rules scoped to ".woocommerce(-js) div.product form.cart ..." that previously
   never matched this template at all (no element here ever had a plain "product"
   class before). Confirmed via a live "CSS Used" capture from DevTools that this
   family includes: conflicting min-height values on .single_add_to_cart_button at
   several breakpoints, a fixed height on div.quantity at max-width:600px, an
   explicit width:calc(100% - 135px/141px)!important on the button (this file only
   ever had flex:1, which a hard width always overrides), AND - found after the
   height/width fix, when the row was still visibly inset left/right from the
   full-width PayPal button below it, with extra space beneath it too - a legacy,
   pre-flexbox WooCommerce rule this template never had any competing margin
   declaration for at all: ".woocommerce-js div.product form.cart div.quantity
   {float:left;margin:0 1em 1em 0;}" and ".woocommerce-js div.product form.cart
   .button{...margin-bottom:1em;}" (the generic .button class, which
   .single_add_to_cart_button also carries). float is a no-op on a flex item, but
   the 1em right-margin on quantity and 1em bottom-margin on both were real and
   uncontested. Pinning width, padding, height AND margin explicitly here (all with
   matching/higher specificity) removes the guesswork instead of relying on
   padding+line-height happening to add up to the right total. */
.woocommerce div.product.cn-pdp form.cart .button.single_add_to_cart_button{width:auto !important;flex:1 !important;padding:0 22px !important;height:50px !important;min-height:50px !important;margin:0 !important;}
.woocommerce div.product.cn-pdp form.cart div.quantity{height:50px !important;min-height:50px !important;margin:0 !important;}
/* Third-party integrations (PayPal Payments' smart button etc.) rendered via
   cn_pdp_render_third_party_summary_extras() - :empty keeps the margin from
   showing when a given product has nothing to render there, and still reacts
   correctly once PayPal's JS fills the container after page load. */
.cn-pdp .buy-airy .pdp-extras{margin:0 0 8px;}
.cn-pdp .buy-airy .pdp-extras .ppc-button-wrapper,
.cn-pdp .buy-airy .pdp-extras .paypal-buttons{margin-top:0 !important;}
.cn-pdp .buy-airy .pdp-extras:empty{display:none;}
/* .ppc-button-wrapper (PayPal Payments' own wrapper around the smart button) has a
   site-wide rule in astra-child/style.css designed for the OLD boxed buy-area
   (padding + grey background + bottom-only radius, to look like the bottom of that
   box). This template has no such box, so it's overridden here instead of touching
   the global rule, which the old-style product pages still rely on. */
.cn-pdp .buy-airy .ppc-button-wrapper{padding:0;background:none;border-radius:10px;overflow:hidden;margin-bottom:0;}
/* The SDK's real host is .paypal-buttons (there is no .paypal-button-container
   in this integration). PayPal's separate built-in 750px cap is disabled in
   cn_cart_paypal_button_style(); these rules make each real wrapper fill the buy
   column so both edges align with form.cart, whose natural desktop width is 760px. */
.cn-pdp .buy-airy .pdp-extras,
.cn-pdp .buy-airy .ppc-button-wrapper,
.cn-pdp .buy-airy #ppc-button-ppcp-gateway,
.cn-pdp .buy-airy .paypal-buttons{
	width:100% !important;
	max-width:100% !important;
	margin-left:0 !important;
	margin-right:0 !important;
}
/* .woocommerce button.button.alt (astra-child/style.css) has one more type selector
   than a pure-class selector can match, so it out-specifies .single_add_to_cart_button
   on tied class count and silently overrides this button's radius back to 4px -
   !important forces the mockup's 10px pill shape to win regardless. */
.cn-pdp .buy-airy .single_add_to_cart_button{border-radius:10px !important;}
/* .quantity/.minus/.plus/.qty are Astra's real, already-wired quantity stepper (used
   site-wide) - re-skinned here to match the mockup instead of being replaced. Astra/the
   child theme's own CSS sets border-color/color with !important, so matching specificity
   +!important is needed to win; everything else overrides on specificity alone. */
.cn-pdp .buy-airy .quantity{display:flex;align-items:stretch;border:1.5px solid #d9d4cf;border-radius:10px;overflow:hidden;flex:0 0 auto;background:#fff;}
.cn-pdp .buy-airy .quantity .minus,
.cn-pdp .buy-airy .quantity .plus{width:44px;margin:0;padding:0;border:none !important;border-radius:0 !important;background:#fff;font-family:Arial,sans-serif;font-size:1.3rem;color:#032936 !important;cursor:pointer;line-height:1;display:flex;align-items:center;justify-content:center;text-decoration:none;transition:none;}
.cn-pdp .buy-airy .quantity .minus{font-size:0;}
.cn-pdp .buy-airy .quantity .minus::before{content:"\2013";font-size:1.3rem;line-height:1;}
.cn-pdp .buy-airy .quantity .minus:hover,
.cn-pdp .buy-airy .quantity .plus:hover{background:#f4f2f0;text-decoration:none;}
.cn-pdp .buy-airy .quantity input.qty{width:46px;max-width:46px;margin:0;text-align:center;border:none !important;font-family:Arial,sans-serif;font-size:1.05rem;font-weight:600;line-height:1;color:#032936 !important;background:#fff;padding:11px 0;min-height:0;-moz-appearance:textfield;}
.cn-pdp .buy-airy .quantity input.qty::-webkit-outer-spin-button,
.cn-pdp .buy-airy .quantity input.qty::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
.cn-pdp .buy-airy .quantity input.qty:focus{outline:none;box-shadow:none;border:none !important;}
.cn-pdp .buy-airy .single_add_to_cart_button{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:9px;background:#285bb8;color:#fff;font-weight:800 !important;font-size:1.05rem;line-height:1.3 !important;padding:14px 22px !important;border:none;border-radius:10px;cursor:pointer;transition:background .15s ease;}
.cn-pdp .buy-airy .single_add_to_cart_button:hover{background:#284985;color:#fff;}
.cn-pdp .buy-airy .single_add_to_cart_button:focus,
.cn-pdp .buy-airy .single_add_to_cart_button:focus-visible{outline:none !important;box-shadow:none !important;border:none !important;}
.cn-pdp .buy-airy .single_add_to_cart_button svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8;flex-shrink:0;}
/* add-to-cart/simple.php's $useCnPdpCartIcon branch always puts the svg before
   the text in the DOM (wrapped in .cn-atc-label) - PHP can't tell what viewport
   is loading it, so the markup order can't be conditional. Visual order IS
   conditional, via flex `order`: by default (desktop/tablet) this puts the icon
   back on the right exactly like before today's changes - only below the mobile
   breakpoint does it flip to icon-first, which is when the label can actually
   wrap to two lines and needs a leading icon + text-align:left to look right
   (see the media query at the bottom of this file). text-align:left on the label
   is harmless when it isn't wrapping (single line, no visible effect either way). */
.cn-pdp .buy-airy .single_add_to_cart_button svg{order:2;}
.cn-pdp .buy-airy .single_add_to_cart_button .cn-atc-label{order:1;text-align:left;}
/* Astra's sticky add-to-cart bar (inc/compatibility/woocommerce/class-astra-woocommerce.php,
   single_product_sticky_add_to_cart()) echoes its own copy of woocommerce_template_single_add_to_cart()
   at wp_footer - it is NOT nested inside .cn-pdp, so it needs the body class
   (cn-pdp-page, added in cn_render_product_page()) instead. Same custom cart-icon
   swap as the main button (see add-to-cart/simple.php's $useCnPdpCartIcon) - it
   has no fill of its own and is otherwise invisible outside this rule. Same
   desktop-default/mobile-flip icon order as the main button, see above. */
.cn-pdp-page .ast-sticky-add-to-cart .single_add_to_cart_button{font-weight:800 !important;}
.cn-pdp-page .ast-sticky-add-to-cart .single_add_to_cart_button svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8;flex-shrink:0;order:2;}
.cn-pdp-page .ast-sticky-add-to-cart .single_add_to_cart_button .cn-atc-label{order:1;text-align:left;}
/* Icon-first only below this width - matches the breakpoint Astra/WooCommerce's
   own compatibility CSS already uses for this exact button elsewhere (see the
   min-height/quantity overrides above), where the label is realistically at risk
   of wrapping to two lines. */
@media (max-width:600px){
	.cn-pdp .buy-airy .single_add_to_cart_button svg,
	.cn-pdp-page .ast-sticky-add-to-cart .single_add_to_cart_button svg{order:1;}
	.cn-pdp .buy-airy .single_add_to_cart_button .cn-atc-label,
	.cn-pdp-page .ast-sticky-add-to-cart .single_add_to_cart_button .cn-atc-label{order:2;}
}
.cn-pdp .buy-airy .pdp-extras:focus,
.cn-pdp .buy-airy .pdp-extras *:focus,
.cn-pdp .buy-airy .pdp-extras iframe:focus{outline:none !important;box-shadow:none !important;border-style:none !important;}
/* Deluxe (ID 41024) is never purchasable while out of stock, so PayPal Payments' smart
   button never renders here - .pdp-extras:empty already hides it generically, but the
   PayPal Payments plugin apparently leaves non-empty wrapper markup behind even with
   nothing visible inside, so :empty doesn't match. Hidden outright on this one template
   instead (cn-pdp--deluxe, the content-key wrapper class from cn_render_product_page()). */
.cn-pdp--deluxe .buy-airy .pdp-extras{display:none !important;}

/* ---- Out-of-stock status line ("Aktuell nicht verfügbar.") ----
   Real markup: woocommerce/single-product/price.php's is_in_stock()==false branch renders a
   generic <p><span style="color:#e05858;">Aktuell nicht verfügbar. </span></p> shared by every
   out-of-stock product on the site. Trying to reskin that shared line via CSS pseudo-elements
   turned out fragile and never matched the mockup exactly (wrong dot size/color, missing the
   "Streng limitiert..." sentence, which isn't live data - it's static per-product copy). Per
   Alex's direction, this is simpler as static markup matching the mockup exactly: price.php's
   ID-41024 branch now prints its own .avail/.dot block (identical classes/copy/values to
   produkt-deluxe.html's own .avail/.dot, including the box-shadow glow) right after the
   generic line - the rule below just hides that now-redundant generic line on this page only
   (:not(:last-child) isolates it from the in-stock "Verfügbar." line's own already-approved
   dot rule further up this file, which must stay untouched for Klassik/Kräftig/Decaf). */
.cn-pdp .buy-airy .stock-and-shipping > p:last-of-type:not(:last-child){display:none !important;}
/* margin is bottom-only and deliberately the sole contributor to the gap before .notify
   (which has its own top margin zeroed below) - adjacent sibling margins otherwise collapse
   to whichever is larger rather than summing, which was quietly shrinking this gap below the
   mockup's own 16px even though both sides individually matched the mockup's numbers. Making
   one side the single source removes that ambiguity entirely instead of fighting it. */
.cn-pdp .buy-airy .stock-and-shipping .avail{display:flex !important;align-items:center !important;gap:8px !important;font-size:.93rem !important;line-height:normal !important;margin:0 0 32px !important;color:#032936 !important;font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important;}
.cn-pdp .buy-airy .stock-and-shipping .avail .dot{display:block !important;width:9px !important;height:9px !important;min-width:9px !important;border-radius:50% !important;background:#c0392b !important;flex:0 0 auto !important;box-shadow:0 0 0 3px rgba(192,57,43,.18) !important;}
.cn-pdp .buy-airy .stock-and-shipping .avail strong{color:#c0392b !important;font-weight:600 !important;}

/* ---- Deluxe (product ID 41024) out-of-stock waitlist form ----
   woocommerce/single-product/price.php's ID-41024 branch wraps the real, live WPForms form
   ([wpforms id="291508"], title/description disabled there so OUR static .notify-head/
   .notify-sub copy renders instead of WPForms' own wp-admin-configured text) in a .notify
   div - matching the mockup's own class name for this box (produkt-deluxe.html), which never
   had a dedicated CSS rule of its own, just an inline style, reproduced here for real.

   The real computed DOM (pasted by Alex from the live/staging page, 2026-09-03) is what this
   is built against - not WPForms' documented CSS custom properties. An earlier attempt used
   those (mirroring the Siebträger category page's #wpforms-350386 reskin, css/category.css)
   but the field/button box styling silently never applied on this instance/WPForms version,
   confirmed from Alex's screenshot (inputs still rendered underline-only). Rather than keep
   guessing custom-property names (see feedback_verify_before_fixing), this instead targets
   the real classes from that computed HTML directly, with !important to beat WPForms' own
   frontend CSS - same specificity-fighting approach already used against the Customer Reviews
   plugin's CSS elsewhere in this file. Real field classes: Vorname is wpforms-field-small,
   E-Mail-Adresse is wpforms-field-medium - both are styled, not just -medium. Field labels
   ("Vorname *"/"E-Mail-Adresse *") are hidden rather than removed, since WPForms' own
   validation/JS still expects them in the DOM and the approved design shows placeholder text
   only (same as the mockup's own aria-label-only inputs, no visible <label>).

   Follow-up hardening (2026-09-03, after Alex's 2nd screenshot showed the box still off -
   font, dot and form spacing not matching): the base body font isn't --font-head (that's
   heading-only, see .cn-pdp's own rule near the top of this file) but WPForms' own
   frontend CSS sets an explicit font-family on inputs/buttons that a plain "font:inherit"
   apparently loses against, so the real "Public Sans" stack is now spelled out with
   !important instead of relying on inheritance. The margin mismatch traced to two real
   gaps in the first pass: #wpforms-291508 (WPForms' own outer container div, sitting
   between .notify and .wpforms-field-container) was never reset, so its own default
   margin/padding was stacking on top of .notify's; and the honeypot layout wrapper
   (field_3, id ...field_3-container) carries BOTH "wpforms-field" and "wpforms-field-
   layout" classes on the same element, so it was ALSO catching the 10px bottom margin
   meant only for real fields, on top of the real Vorname field (nested inside it)
   getting its own - doubling the gap around Vorname specifically. Reset to 0 below,
   placed after the general .wpforms-field rule so source order lets it win on that
   double-classed element. */
/* margin-top:0 (not 4px like the mockup's own inline style) - deliberately, so .avail's
   margin-bottom above is the sole source of that gap instead of the two collapsing together
   (see the note on .avail). Net visual result is the same 16px the mockup's own two values
   collapse down to, just produced deterministically instead of relying on collapse math. */
.cn-pdp .buy-airy .stock-and-shipping .notify{background:#f3f0ec !important;border:1px solid #efecea !important;border-radius:12px !important;padding:18px 18px 16px !important;margin:0 0 2px !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify-head{font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important;font-weight:700 !important;font-size:1.02rem !important;line-height:normal !important;color:#032936 !important;margin:0 0 4px !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify-sub{font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important;font-size:.92rem !important;line-height:1.5 !important;color:#57606a !important;margin:0 0 12px !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify #wpforms-291508{margin:0 !important;padding:0 !important;background:none !important;border:0 !important;box-shadow:none !important;}
/* style.css (this theme's own site-wide sheet, not WPForms' or WooCommerce's) carries
   pre-redesign rules for the OLD out-of-stock WPForms styling that still apply here since
   the classes are the same real WPForms markup - confirmed from Alex's own computed-CSS
   dump (2026-09-03), not guessed: ".stock-and-shipping .wpforms-form{padding:0px 0 10px
   0!important;}" (style.css:4849) added an unaccounted 10px at the bottom of the real
   <form> itself - a level below #wpforms-291508, which was the only thing reset above - and
   ".stock-and-shipping .wpforms-field-medium,.stock-and-shipping .wpforms-field-small{
   margin:10px 0 0 0!important;}" (style.css:4866) added an unaccounted 10px TOP margin
   directly on each real <input>, on top of (and fighting) the 10px BOTTOM margin already
   set on their wrapping .wpforms-field container below. Both neutralized explicitly here
   instead of just on the wrapping/container elements, closing the gap this was missing. */
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-form{border:0 !important;padding:0 !important;margin:0 !important;border-radius:0 !important;background:none !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-head-container{display:none !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-field-label{display:none !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-field-container{margin:0 !important;padding:0 !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-field{margin:0 0 10px !important;padding:0 !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-field-layout{margin:0 !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-field-layout-columns{margin:0 !important;padding:0 !important;}
/* WPForms' own plugin CSS (fields/layout.min.css) gives the honeypot layout wrapper's
   inner column div - the one Vorname happens to be nested inside, Email isn't - its own
   "padding:0 10px" (no !important, but this repo has no rule overriding it, so it wins by
   default). That insets Vorname 10px further in from both edges than Email, visible in
   Alex's own DevTools screenshot (2026-09-04) as a shorter input + a gap on its right
   edge that Email doesn't have. Zeroed so both real fields sit at the same width/edges. */
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-layout-column{padding:0 !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify input.wpforms-field-small,
.cn-pdp .buy-airy .stock-and-shipping .notify input.wpforms-field-medium{
	margin:0 !important;
	width:100% !important;
	max-width:100% !important;
	height:46px !important;
	padding:13px 14px !important;
	border:1px solid #dcd7d1 !important;
	border-radius:10px !important;
	background:#fff !important;
	font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important;
	font-size:.98rem !important;
	font-weight:400 !important;
	line-height:normal !important;
	color:#032936 !important;
	box-sizing:border-box !important;
}
.cn-pdp .buy-airy .stock-and-shipping .notify input::placeholder{font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important;color:rgba(3,41,54,.54) !important;opacity:1 !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify em.wpforms-error{display:block !important;margin:-4px 0 10px !important;font-style:normal !important;font-size:.85rem !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify .wpforms-submit-container{margin:0 !important;padding:0 !important;}
.cn-pdp .buy-airy .stock-and-shipping .notify button.wpforms-submit{
	width:100% !important;
	display:flex !important;
	align-items:center !important;
	justify-content:center !important;
	background:#285bb8 !important;
	color:#fff !important;
	font-family:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif !important;
	font-weight:800 !important;
	font-size:1.05rem !important;
	line-height:normal !important;
	padding:14px !important;
	margin:0 !important;
	border:none !important;
	border-radius:10px !important;
	cursor:pointer;
	transition:background .15s ease;
}
.cn-pdp .buy-airy .stock-and-shipping .notify button.wpforms-submit:hover{background:#284985 !important;}

/* ===== Details / how-it-works ===== */
.cn-pdp .detail-split{display:grid;grid-template-columns:1.5fr 1fr;gap:32px;align-items:stretch;}
.cn-pdp .detail-photo{border-radius:14px;overflow:hidden;}
.cn-pdp .detail-photo img{width:100%;height:100%;object-fit:cover;display:block;min-height:100%;}
.cn-pdp .spec-wrap{border:1px solid #efecea;border-radius:14px;overflow:hidden;background:#fff;box-shadow:none;}
.cn-pdp .spec-table{width:100%;border-collapse:collapse;border:none;margin:0;box-shadow:none;}
.cn-pdp .spec-table tr{border-bottom:1px solid #efecea;}
.cn-pdp .spec-table tr:last-child{border-bottom:none;}
.cn-pdp .spec-table th,
.cn-pdp .spec-table td{border:none;}
.cn-pdp .spec-table th{text-align:left;width:32%;padding:15px 20px;font-weight:700;color:#032936;vertical-align:top;font-size:.95rem;background:#faf9f8;}
.cn-pdp .spec-table td{padding:15px 20px;color:#032936;font-size:.97rem;}
/* !important needed here: every content-{key}.php template sets
   grid-template-columns inline on .detail-split (e.g. "1fr 1.5fr" for the
   photo+steps sections), and an inline style always beats a media-queried
   stylesheet rule regardless of viewport - without it this breakpoint was
   silently never applying and the photo+steps layout stayed 2-column (and
   cramped) on mobile instead of stacking. */
@media (max-width:820px){ .cn-pdp .detail-split{grid-template-columns:1fr !important;} .cn-pdp .detail-photo{min-height:240px;} }

/* ===== Coffee-bean PDP components (Klassik/Kräftig/Decaf/Deluxe) =====
   New for the 4 coffee-bean products, ported verbatim from each mockup's own <style>
   block (e.g. produkt-klassik.html:556-564, 841-986; the trust bar mirrors css/home.css's
   .trust exactly - same component, reused here), only the bare/.cn-home selectors swapped
   for .cn-pdp. Built once here, reused by all 4 products - not duplicated per product. */

/* Trust-signal bar (3 pills on Klassik/Kräftig/Decaf, 2 on Deluxe with different copy -
   item count/copy is per-product content, not CSS; each product's content-*.php sets its
   own flex-wrap inline style on .trust-grid, same pattern already used by .promise-grid). */
.cn-pdp .trust{background:#efecea;padding:42px 0;}
.cn-pdp .trust-title-row{text-align:center;margin:0 0 28px;font-size:1.55rem;font-weight:800;color:#032936;}
.cn-pdp .trust-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;}
.cn-pdp .trust-item{display:flex;align-items:center;gap:14px;}
.cn-pdp .trust-ic{width:50px;height:50px;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
.cn-pdp .trust-ic svg{width:24px;height:24px;stroke:#285bb8;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.cn-pdp .trust-title{font-weight:700;color:#032936;font-size:.98rem;line-height:1.2;}
.cn-pdp .trust-sub{font-size:.82rem;color:#9E9E9E;margin-top:2px;}
@media (max-width:820px){ .cn-pdp .trust-grid{grid-template-columns:repeat(2,1fr);gap:24px 18px;} }

/* Taste profile (Röstgrad/Säure/Körper/Bitterkeit bars + Aromen chips + "passt perfekt für"
   pairing row). Present on Klassik/Kräftig/Decaf; absent on Deluxe (no fixed taste profile
   for a rotating seasonal blend - its promise-grid covers that ground instead). */
.cn-pdp .taste-grid{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center;}
.cn-pdp .taste-bars{display:flex;flex-direction:column;gap:18px;}
.cn-pdp .taste-bar-label{display:flex;justify-content:space-between;font-size:.94rem;color:#032936;margin-bottom:7px;font-weight:600;}
.cn-pdp .taste-bar-label span:last-child{color:#9E9E9E;}
.cn-pdp .taste-track{height:9px;border-radius:999px;background:#efecea;overflow:hidden;}
.cn-pdp .taste-fill{height:100%;border-radius:999px;background:#c08f6e;}
.cn-pdp .chips{display:flex;flex-wrap:wrap;gap:9px;margin-top:4px;}
.cn-pdp .chip{background:#efecea;color:#032936;font-size:.88rem;font-weight:600;padding:8px 15px;border-radius:999px;}
.cn-pdp .pairs{display:flex;flex-wrap:wrap;gap:9px;margin-top:16px;}
.cn-pdp .pair{display:inline-flex;align-items:center;gap:7px;font-size:.9rem;color:#032936;background:#fff;border:1px solid #efecea;border-radius:999px;padding:8px 15px;}
.cn-pdp .pair svg{width:15px;height:15px;stroke:#285bb8;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
@media (max-width:900px){ .cn-pdp .taste-grid{grid-template-columns:1fr;gap:24px;} }

/* "Beste Einstellungen & Aufbewahrung" (settings + storage). Present in full on
   Klassik/Kräftig/Decaf (.set-hero photo + .set-card with the .set2 settings list, a
   .tip-box, then the .pdp-list storage tips below a .set-sep divider). Deluxe uses only
   the storage half (.pdp-list, reused as-is from the buy-box benefit-list styling above)
   - no fixed grind setting exists for a rotating seasonal blend, so no .set2 table there. */
.cn-pdp .set-hero{display:grid;grid-template-columns:.9fr 1.1fr;gap:30px;align-items:stretch;margin-bottom:24px;}
.cn-pdp .set-photo{border-radius:14px;overflow:hidden;min-height:300px;}
.cn-pdp .set-photo img{width:100%;height:100%;object-fit:cover;display:block;}
.cn-pdp .set-card{background:#fff;border:1px solid #efecea;border-radius:14px;padding:30px 32px;}
.cn-pdp .set-title{font-family:var(--font-head);font-weight:800;font-size:1.28rem;line-height:1.3;color:#032936;margin:0 0 22px;text-align:left;}
.cn-pdp .set2{margin:6px 0 4px;padding-left:14px;}
.cn-pdp .set2-row{display:grid;grid-template-columns:200px 1fr;gap:28px;padding:8px 0;border-bottom:none;align-items:baseline;}
.cn-pdp .set2-row:first-child{padding-top:0;}
.cn-pdp .set2-k{font-weight:700;color:#032936;font-size:1rem;margin:0;}
.cn-pdp .set2-v{color:#57606a;font-size:1.04rem;line-height:1.4;margin:0;}
.cn-pdp .tip-box{background:transparent;border:none;border-top:1px solid #efecea;border-radius:0;padding:18px 0 0;font-size:1rem;color:#57606a;line-height:1.55;margin-top:22px;}
.cn-pdp .tip-box b{color:#c08f6e;font-weight:700;}
.cn-pdp .tip-box a{color:#285bb8;font-weight:600;}
.cn-pdp .set-sep{height:1px;background:#efecea;margin:22px 0;}
.cn-pdp .pdp-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px;max-width:820px;}
.cn-pdp .pdp-list li{display:flex;gap:11px;align-items:flex-start;font-size:1.04rem;line-height:1.5;color:#032936;}
.cn-pdp .pdp-list li svg{flex:0 0 auto;width:19px;height:19px;margin-top:2px;stroke:#21a54d;fill:none;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;}
.cn-pdp .pdp-list strong{font-weight:800;}
@media (max-width:820px){ .cn-pdp .set-hero{grid-template-columns:1fr;} .cn-pdp .set-photo{min-height:220px;} }

/* Subscription (Abo) cross-sell CTA - dark variant, used on Klassik/Kräftig/Decaf, each
   pointing at its own separate Abo product (a distinct WooCommerce Subscriptions product,
   not a variation). None on Deluxe - it has no subscribable Abo variant. */
.cn-pdp .abo-cross{display:grid;grid-template-columns:1.3fr 1fr;gap:44px;align-items:center;}
.cn-pdp .abo-badge{display:inline-block;background:#21a54d;color:#fff;font-weight:600;font-size:.8rem;padding:6px 13px;border-radius:999px;margin-bottom:12px;}
.cn-pdp .abo-cross-text h2{font-family:var(--font-head);font-weight:700;font-size:1.6rem;color:#032936;margin:0 0 10px;line-height:1.2;}
.cn-pdp .abo-cross-text>p{font-size:1.02rem;color:#032936;line-height:1.55;margin:0 0 16px;}
.cn-pdp .abo-cross-benefits{list-style:none;margin:0 0 22px;padding:0;display:flex;flex-direction:column;gap:9px;}
.cn-pdp .abo-cross-benefits li{display:flex;gap:10px;align-items:flex-start;font-size:1rem;color:#032936;}
.cn-pdp .abo-cross-benefits svg{width:18px;height:18px;stroke:#21a54d;fill:none;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto;margin-top:2px;}
.cn-pdp .abo-cta-btn{display:inline-flex;align-items:center;gap:9px;background:#285bb8;color:#fff;font-weight:700;font-size:1.05rem;padding:14px 26px;border:none;border-radius:10px;text-decoration:none;transition:background .15s ease;}
.cn-pdp .abo-cta-btn:hover{background:#284985;}
.cn-pdp .abo-cta-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.cn-pdp .abo-dark{background:#032936;}
.cn-pdp .abo-dark .abo-cross-text h2{color:#fff;}
.cn-pdp .abo-dark .abo-cross-text p{color:#cdd8dd;}
.cn-pdp .abo-dark .abo-cross-benefits li{color:#e8eef1;}
.cn-pdp .abo-dark .abo-badge{background:#c08f6e;color:#fff;}
.cn-pdp .abo-dark .abo-cta-btn{background:#fff;color:#032936;}
.cn-pdp .abo-dark .abo-cta-btn:hover{background:#efecea;}
@media (max-width:820px){ .cn-pdp .abo-cross{grid-template-columns:1fr;gap:24px;} }

/* ===== Reviews (real markup: Customer Reviews for WooCommerce plugin, via comments_template()) ===== */
.cn-pdp #reviews{max-width:none;}
/* Astra's WooCommerce layer targets this heading through #reviews and otherwise
   wins on specificity (including a display:none rule). Match the mockup's
   .section-title while keeping the plugin-generated count and product title. */
.cn-pdp #reviews.cr-reviews-ajax-reviews #comments.cr-reviews-ajax-comments .woocommerce-Reviews-title{display:block!important;clear:none;font-family:var(--font-head)!important;font-weight:800!important;font-size:2.25rem!important;line-height:1.1!important;color:#032936!important;text-align:left;margin:0 0 22px!important;}
/* .cn-rev-summary-row is a wrapper js/product.js adds around the plugin's two
   sibling summary blocks so they can sit side by side like the mockup. */
.cn-pdp .cn-rev-summary-row{display:grid;grid-template-columns:220px 1fr;gap:44px;background:#f9f9f9;border-radius:14px;padding:30px 34px;align-items:center;margin-bottom:26px;}
/* The plugin's own frontend.css scopes its summary-box defaults under the
   #reviews ID, which outranks plain classes regardless of stylesheet order -
   every rule below that needs to win a fight against it is written with the
   same #reviews prefix rather than relying on load order. */
.cn-pdp #reviews .cr-summaryBox-wrap{display:block;text-align:center;padding:0;margin:0;background:transparent;}
.cn-pdp #reviews .cr-summaryBox-wrap .cr-overall-rating-wrap{display:block;width:auto;flex:none;padding:0;margin:0;border:none;text-align:center;}
.cn-pdp #reviews .cr-summaryBox-wrap .cr-average-rating{line-height:1;}
.cn-pdp .cr-average-rating span{font-family:var(--font-head);font-size:3rem;font-weight:800;color:#032936;line-height:1;}
.cn-pdp .cr-average-rating-stars{line-height:normal;margin:8px 0 6px;}
.cn-pdp .cr-average-rating-stars .crstar-rating-svg{margin:0;}
/* The plugin draws an outlined SVG below a filled SVG. The approved mockup
   uses plain Arial stars with a clipped gold foreground, so reproduce that
   exact technique on the plugin containers; their inline percentage remains
   the live rating value. */
.cn-pdp #reviews .crstar-rating-svg{position:relative;display:inline-block;font-family:Arial,sans-serif;font-size:20px;line-height:1;letter-spacing:1px;vertical-align:middle;}
.cn-pdp .crstar-rating-svg .cr-rating-icon-base,
.cn-pdp .crstar-rating-svg .cr-rating-icon-frnt{display:block;height:20px;white-space:nowrap;column-gap:normal;}
.cn-pdp .crstar-rating-svg .cr-rating-icon-frnt{position:absolute;top:0;left:0;overflow:hidden;}
.cn-pdp .crstar-rating-svg .cr-rating-icon-base::before,
.cn-pdp .crstar-rating-svg .cr-rating-icon-frnt::before{content:"\2605\2605\2605\2605\2605";}
.cn-pdp .crstar-rating-svg .cr-rating-icon-base::before{color:#9E9E9E;}
.cn-pdp .crstar-rating-svg .cr-rating-icon-frnt::before{color:#FFBB1E;}
.cn-pdp #reviews .crstar-rating-svg svg{display:none!important;stroke:none!important;}
/* The histogram rows (5★/4★/.../1★ breakdown bars) use a separate plugin icon,
   .cr-histogram-rating-icon, that ships with an unwanted visible stroke outline
   on live - this used to be "fixed" with a blanket ".cn-pdp svg{stroke:none}"
   rule in style.css, which also silently stripped every custom icon's stroke
   on every product page (checkmarks, promise-grid icons, gallery icons, etc.)
   since they all rely on stroke to be visible. Scoped here instead - only this
   specific plugin icon needs it. */
.cn-pdp .cr-histogram-rating-icon{stroke:none!important;}
.cn-pdp #reviews .cr-summaryBox-wrap .cr-total-rating-count{font-size:.88rem;color:#9E9E9E;line-height:1.4;}
.cn-pdp .ivole-summaryBox{margin-bottom:0;}
.cn-pdp .cr-histogramTable{width:100%;max-width:none;table-layout:fixed;border-collapse:collapse;border:none;margin:0;box-shadow:none;}
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow td{font-size:.88rem;color:#032936;vertical-align:middle;padding:0;border:none;background:transparent;}
.cn-pdp .cr-histogramTable tr.ivole-histogramRow .ivole-histogram-a,
.cn-pdp .cr-histogramTable tr.ivole-histogramRow .cr-histogram-a{color:inherit;cursor:pointer;}
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow .ivole-histogramCell1{width:66px;white-space:nowrap;}
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow .ivole-histogramCell2{width:auto;padding-right:12px;padding-left:12px;box-sizing:border-box;}
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow .ivole-histogramCell3{width:40px;text-align:right;color:#9E9E9E;white-space:nowrap;}
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow:not(:first-child) .ivole-histogramCell1,
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow:not(:first-child) .ivole-histogramCell2,
.cn-pdp #reviews .cr-histogramTable tr.ivole-histogramRow:not(:first-child) .ivole-histogramCell3{padding-top:9px;}
.cn-pdp .ivole-meter{height:12px;border-radius:999px;background:#efecea;overflow:hidden;box-shadow:none;}
.cn-pdp .ivole-meter-bar{height:100%;background:#FFBB1E;border-radius:999px;font-size:0;box-shadow:none;float:none;}
.cn-pdp .ivole-meter-bar::before{display:none;}
/* Customer Reviews outputs this only when real review media exists. */
.cn-pdp #reviews.cr-reviews-ajax-reviews .cr-ajax-reviews-cus-images-div{margin:0 0 22px;}
.cn-pdp #reviews.cr-reviews-ajax-reviews .cr-ajax-reviews-cus-images-div .cr-ajax-reviews-cus-images-title{font-size:1rem;font-weight:600;color:#032936;line-height:normal;margin:0 0 10px;}
.cn-pdp #reviews.cr-reviews-ajax-reviews .cr-ajax-reviews-cus-images-div2{display:flex;gap:12px;flex-wrap:wrap;white-space:normal;overflow:visible;}
.cn-pdp #reviews.cr-reviews-ajax-reviews .cr-ajax-reviews-cus-images-div2 .cr-comment-image-top{display:block;flex:0 0 96px;width:96px;height:96px;max-height:none;margin:0;border:1px solid #efecea;border-radius:8px;box-sizing:border-box;}
.cn-pdp #reviews.cr-reviews-ajax-reviews .cr-ajax-reviews-cus-images-div2 .cr-comment-image-top-item{display:block;width:100%;height:100%;object-fit:cover;}
/* Same story below: the AJAX reviews template's own CSS is anchored under
   #reviews.cr-reviews-ajax-reviews #comments.cr-reviews-ajax-comments, which
   beats plain .cn-pdp classes on specificity alone - !important is the only
   reliable way to win without depending on stylesheet load order. */
.cn-pdp .cr-ajax-search{position:relative;margin:0 0 16px!important;}
.cn-pdp .cr-ajax-search > div{position:relative;}
.cn-pdp .cr-ajax-search input{width:100%!important;padding:13px 16px 13px 42px!important;border:1px solid #dcd7d1!important;border-radius:10px!important;font:inherit!important;font-size:.98rem!important;color:#032936!important;background:#fff!important;height:auto!important;line-height:normal!important;}
.cn-pdp .cr-ajax-search-icon{position:absolute;left:15px!important;top:50%;transform:translateY(-50%);width:18px!important;height:18px!important;}
.cn-pdp .cr-ajax-search-icon,
.cn-pdp .cr-clear-input svg{fill:#9E9E9E!important;stroke:none!important;color:#9E9E9E!important;}
.cn-pdp .cr-clear-input{position:absolute;right:12px!important;top:50%;transform:translateY(-50%);width:16px;height:16px;margin-left:0!important;margin-top:0!important;cursor:pointer;}
.cn-pdp .cr-count-row{display:flex;justify-content:space-between;align-items:center;gap:16px;background:#f9f9f9;border-radius:10px;padding:12px 18px!important;margin:0 0 6px!important;font-size:.9rem!important;color:#032936!important;flex-wrap:wrap;}
.cn-pdp #reviews.cr-reviews-ajax-reviews .cr-ajax-reviews-sort{border:none!important;background-color:transparent!important;font-family:inherit!important;font-size:.9rem!important;line-height:normal!important;font-weight:600!important;color:#032936!important;cursor:pointer;}
.cn-pdp #reviews.cr-reviews-ajax-reviews #comments.cr-reviews-ajax-comments .commentlist{list-style:none;margin:0;padding:0;}
.cn-pdp .commentlist li.review,
.cn-pdp .commentlist li.comment{list-style:none;}
.cn-pdp .commentlist > li.review{padding:22px 0!important;border-bottom:1px solid #efecea!important;margin:0!important;}
.cn-pdp .commentlist .comment_container{padding:0;}
.cn-pdp .commentlist .cr-comment-text{border:none!important;padding:0!important;margin:0!important;}
.cn-pdp .commentlist .meta{display:flex;justify-content:space-between;align-items:flex-start!important;gap:16px;margin-bottom:8px;}
.cn-pdp .woocommerce-review__author{font-weight:600!important;color:#032936!important;}
.cn-pdp .woocommerce-review__verified{font-size:.85rem!important;color:#9E9E9E!important;font-style:normal;display:block;margin-top:2px!important;margin-bottom:0!important;}
.cn-pdp .woocommerce-review__published-date{font-size:.85rem;color:#9E9E9E;flex:0 0 auto;white-space:nowrap;}
.cn-pdp .commentlist .crstar-rating-svg .cr-rating-icon-base,
.cn-pdp .commentlist .crstar-rating-svg .cr-rating-icon-frnt{height:16px!important;font-size:16px;}
.cn-pdp .commentlist .cr-comment-head-text{font-size:1rem;font-weight:600;color:#032936;line-height:normal;margin:10px 0 6px;}
.cn-pdp .commentlist .description p{color:#032936;line-height:1.55;margin:8px 0 0!important;font-size:1.04rem;}
/* Shop-owner replies (WordPress core's real threaded-comment markup, ul.children
   under the review it replies to) render in the site's link-blue by default -
   presumably an existing sitewide convention to make store replies stand out,
   which doesn't fit this template's color scheme. Force every text element
   inside a reply back to the normal body color; real links keep working since
   .cn-pdp a{color:inherit} already exists, so an <a> here just inherits this. */
.cn-pdp .commentlist .children,
.cn-pdp .commentlist .children *{color:#032936 !important;}
.cn-pdp .commentlist .cr-voting-cont{margin-top:12px;}
.cn-pdp .commentlist .cr-voting-cont-uni span{font-size:.85rem;line-height:1;}
.cn-pdp .commentlist .cr-voting-cont-uni svg{width:15px!important;height:15px!important;margin:0 5px 0 0!important;}
.cn-pdp .commentlist .cr-voting-cont-uni svg{fill:none!important;stroke:none!important;}
.cn-pdp .commentlist .cr-voting-cont-uni .cr-voting-upvote svg .cr-voting-svg-ext{fill:#21a54d;}
.cn-pdp .commentlist .cr-voting-cont-uni .cr-voting-downvote svg .cr-voting-svg-ext{fill:#e05858;}
.cn-pdp .commentlist .cr-voting-cont-uni .cr-voting-upvote-count{color:#21a54d;margin-right:16px;}
.cn-pdp .commentlist .cr-voting-cont-uni .cr-voting-downvote-count{color:#e05858;}
.cn-pdp .commentlist ul.children{list-style:none;margin:16px 0 4px 36px!important;margin-inline-start:36px!important;padding:0 0 0 20px!important;padding-inline-start:20px!important;border-left:2px solid #efecea!important;}
.cn-pdp .commentlist ul.children > li.comment{margin:0!important;padding:0!important;}
.cn-pdp .commentlist ul.children .description p{color:#284985;}
.cn-pdp .commentlist .cr-meta-author-title svg,
.cn-pdp .commentlist .cr-meta-author-featured-date > svg{width:12px!important;height:12px!important;color:#9E9E9E!important;margin:0 0 0 6px!important;}
.cn-pdp .cr-show-more-review-spinner-cnt{text-align:center;margin-top:30px;}
.cn-pdp .cr-show-more-reviews-prd{display:block;height:auto!important;margin:10px auto;background:#fff;border:1px solid #285bb8;color:#285bb8;font-weight:700;font-size:1rem;padding:13px 26px;border-radius:10px;cursor:pointer;transition:background .15s ease,color .15s ease;}
.cn-pdp .cr-show-more-reviews-prd:hover{background:#285bb8;color:#fff;}
.cn-pdp .cr-search-no-reviews{text-align:center;color:#9E9E9E;}
.cn-pdp .cr-ajax-reviews-review-form{margin-top:34px;border-top:1px solid #efecea;padding-top:28px;}
.cn-pdp .cr-review-form-nav span{font-family:var(--font-head);font-weight:700;font-size:1.1rem;color:#032936;}
.cn-pdp .cr-review-form-not-logged-in{color:#57606a;font-size:.98rem;}
@media (max-width:620px){ .cn-pdp .cn-rev-summary-row{grid-template-columns:1fr;gap:20px;} }

/* ===== Responsive ===== */
@media (max-width:1100px){ .cn-pdp .pc-grid{grid-template-columns:repeat(3,1fr);} }
@media (max-width:720px){
  .cn-pdp .pc-grid{grid-template-columns:1fr;gap:14px;}
  .cn-pdp .section-title{font-size:1.7rem;}
  .cn-pdp #reviews.cr-reviews-ajax-reviews #comments.cr-reviews-ajax-comments .woocommerce-Reviews-title{font-size:1.7rem!important;}
  .cn-pdp .pc-title{font-size:1.02rem;}
}
