/*
Theme Name: ZainabCraft
Theme URI: https://zainabcraft.com.pk
Description: Custom child theme for ZainabCraft, a handmade crafts and embroidery accessories brand. Built on Twenty Twenty-Five.
Author: ZainabCraft
Template: twentytwentyfive
Requires at least: 6.7
Requires PHP: 8.0
Version: 0.1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: zainabcraft
*/

/* =====================================================================
   ZainabCraft Design System
   Color and font-size tokens are defined in theme.json (WordPress
   preset custom properties: --wp--preset--color--*, --wp--preset--
   font-size--*). The aliases below just give the component CSS in
   this file friendlier names — theme.json stays the single source
   of truth for the actual values.
   ===================================================================== */

:root {
	/* Color aliases -> theme.json presets */
	--zc-color-background: var( --wp--preset--color--background );
	--zc-color-surface: var( --wp--preset--color--surface );
	--zc-color-primary: var( --wp--preset--color--primary );
	--zc-color-secondary: var( --wp--preset--color--secondary );
	--zc-color-accent: var( --wp--preset--color--accent );
	--zc-color-accent-gold: var( --wp--preset--color--accent-gold );
	--zc-color-text: var( --wp--preset--color--ink );
	--zc-color-text-muted: var( --wp--preset--color--text-muted );
	--zc-color-border: var( --wp--preset--color--border );
	--zc-color-success: var( --wp--preset--color--success );
	--zc-color-error: var( --wp--preset--color--error );
	--zc-color-sale: var( --wp--preset--color--sale );
	--zc-color-focus: var( --wp--preset--color--accent-4 );

	/* Typography aliases */
	--zc-font-body: var( --wp--preset--font-family--dm-sans );
	--zc-font-heading: var( --wp--preset--font-family--dm-sans );

	/* Radius scale (not natively a theme.json preset) */
	--zc-radius-sm: 6px;
	--zc-radius-md: 10px;
	--zc-radius-lg: 18px;
	--zc-radius-pill: 999px;

	/* Shadow scale */
	--zc-shadow-sm: 0 1px 3px rgba( 59, 47, 42, 0.08 );
	--zc-shadow-md: 0 6px 20px rgba( 59, 47, 42, 0.1 );

	/* Layout */
	--zc-container-padding: clamp( 1rem, 4vw, 2rem );
	--zc-border-width: 1px;
}

/* =====================================================================
   Focus states — one unified treatment, sitewide
   =====================================================================
   Investigated and confirmed (via computed-style checks on real elements,
   not guesswork) three separate, uncoordinated sources of focus styling
   already active on this site, each firing on plain :focus — meaning
   every one of them showed up on an ordinary mouse click, not just
   keyboard navigation:

   1. Twenty Twenty-Five's own parent style.css:
      `:where(.wp-site-blocks *:focus) { outline-width:2px; outline-style:
      solid; }` — no outline-color is set, so it resolves to currentColor
      per element. Confirmed: a plain link inheriting the ink text color
      showed a dark, near-black 2px outline on click; the site logo link
      (primary-colored) showed a brown one. Same rule, different color
      every time depending on what was clicked — this is the main source
      of "different colored outline in different places."

   2. This theme's own theme.json: `styles.elements.button.:focus` sets a
      gold (accent-4) outline. Confirmed on the hero's "Shop Collection"
      button. Consistent in color, but still fires on every mouse click,
      and doesn't match source #1's colors elsewhere on the same page.

   3. WooCommerce Blocks' own bundled CSS sets hard-coded :focus styling
      per component with no theme override existing yet — confirmed via
      computed styles: `.wc-block-components-radio-control__input:focus`
      and `.wc-block-components-checkbox__input:focus` use
      `color-mix(currentColor 80%, transparent)`, which resolved to an
      actual black outline on the checkout's shipping/payment radios and
      checkboxes (these native inputs have no explicit text color of
      their own, so currentColor defaults to black). The quantity
      stepper and the checkout's "order note" textarea have their own
      separate hard-coded :focus treatments too.

   None of these are wrong in isolation, but together they're why focus
   style looked random from one element to the next. The fix below does
   NOT strip focus indicators — it splits each of these sources in two:

   - For keyboard users, :focus-visible reliably reports true only for
     keyboard-driven (and similar non-pointer) focus in every supported
     browser here, so re-declaring one consistent outline on
     :focus-visible, using this site's existing --zc-color-focus token
     (already the intended "this is focused" color — see the WooCommerce
     button rule below, which already got this right), gives every
     interactive element the same accessible ring.
   - For mouse/touch users, a `:focus:not(:focus-visible)` override,
     matching or exceeding each source's own specificity, cancels only
     the non-keyboard case — :focus-visible is left completely alone, so
     nothing here reduces keyboard accessibility.

   Text-style inputs (text/email/tel/search fields, textareas, selects)
   are the deliberate exception: browsers already treat pointer clicks
   into an editable field as genuine :focus-visible cases (confirmed:
   clicking into this site's own text inputs already reports
   :focus-visible true), because knowing you're about to type is useful
   regardless of input method — so their existing plain :focus box-shadow
   ring (above, in the Forms section) is intentionally left as :focus,
   not narrowed to :focus-visible, and only needed its color unified to
   match everything else.
   ===================================================================== */

/* Keyboard-visible ring, one color, applied consistently to every plain
   interactive element. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[role="button"]:focus-visible,
.wp-block-button__link:focus-visible {
	outline: 2px solid var( --zc-color-focus );
	outline-offset: 2px;
}

/* Source #4: success/error notices (e.g. the contact form's confirmation
   message) are auto-focused on load for screen readers via tabindex="-1",
   which browsers treat as a genuine :focus-visible case. WooCommerce's own
   CSS gives this element outline-width/outline-style but never an
   outline-color, so it was falling back to the browser's raw default blue
   ring — confirmed via computed style (#005fcc) — rather than any
   currentColor-driven or theme value. Setting the full outline shorthand
   here (same specificity as WooCommerce's own :focus-visible rule, so
   source order decides the tie) replaces all three sub-properties at once
   with this site's unified color. */
.woocommerce-message:focus-visible,
.woocommerce-error:focus-visible,
.wc-block-components-notice-banner:focus-visible {
	outline: 2px solid var( --zc-color-focus );
	outline-offset: 0;
}

/* Source #1: cancel the parent theme's blanket currentColor outline for
   mouse/touch focus only. A real selector here (vs. the parent's
   zero-specificity :where()) wins regardless of stylesheet order, so no
   !important is needed. */
.wp-site-blocks *:focus:not( :focus-visible ) {
	outline: none;
}

/* Source #2: same cancellation for theme.json's button element style,
   which compiles to a plain (non-:focus-visible) rule on this class. */
.wp-element-button:focus:not( :focus-visible ) {
	outline: none;
}

/* Source #3: WooCommerce Blocks' own hard-coded per-component :focus
   styling — cancelled for mouse/touch, replaced with the same unified
   ring for keyboard via :focus-visible. Selectors matched to WooCommerce's
   own (confirmed via computed styles) so specificity ties resolve
   correctly without !important. */
.wc-block-components-radio-control .wc-block-components-radio-control__input:focus:not( :focus-visible ),
.wc-block-components-checkbox .wc-block-components-checkbox__input[type="checkbox"]:focus:not( :focus-visible ),
.wc-block-components-quantity-selector .wc-block-components-quantity-selector__button:focus:not( :focus-visible ),
.wc-block-components-button:not( .is-link ):focus:not( :focus-visible ) {
	outline: none;
	box-shadow: none;
}

.wc-block-components-radio-control .wc-block-components-radio-control__input:focus-visible,
.wc-block-components-checkbox .wc-block-components-checkbox__input[type="checkbox"]:focus-visible,
.wc-block-components-quantity-selector__button:focus-visible {
	outline: 2px solid var( --zc-color-focus );
	outline-offset: 1px;
}

/* The quantity stepper's number field, unlike the buttons beside it,
   behaves like a genuine text input — clicking into it already reports
   :focus-visible true in every browser tested (confirmed), the same as
   this site's other text inputs, because knowing you're about to type is
   useful regardless of input method. So instead of the click/keyboard
   split above, it gets the same always-on treatment as other text
   inputs: WooCommerce's own hard-coded dark inset box-shadow replaced
   with the unified ring color on any :focus. */
.wc-block-components-quantity-selector input.wc-block-components-quantity-selector__input:focus {
	outline: none;
	box-shadow: 0 0 0 1px var( --zc-color-focus );
}

/* The checkout "order note" textarea (.wc-block-components-textarea) sets
   its own hard-coded dark border/background on :focus in addition to an
   outline; restoring the resting input style here (rather than just
   clearing outline/box-shadow) avoids a mismatched dark flash on click. */
.wc-block-components-textarea:focus:not( :focus-visible ) {
	background-color: var( --zc-color-surface );
	border-color: var( --zc-color-border );
	box-shadow: none;
}

/* WooCommerce sets this one with !important, so only !important can win
   the tie — kept narrowly scoped to the exact notice-dismiss button it
   already targets. */
.wc-block-components-notice-banner > .wc-block-components-button:focus:not( :focus-visible ) {
	outline: none !important;
}

/* =====================================================================
   Base elements
   ===================================================================== */

a {
	transition: color 0.15s ease;
}

/* Removes the browser's default translucent tap-highlight box that
   flashes over links/buttons on touch devices. Keyboard focus rings
   (:focus-visible below) are untouched. */
a,
button,
input,
select,
textarea,
[role="button"] {
	-webkit-tap-highlight-color: transparent;
}

hr {
	border: none;
	border-top: var( --zc-border-width ) solid var( --zc-color-border );
}

/* =====================================================================
   Buttons (core Button block + WooCommerce buttons)
   theme.json already styles core/button; these rules bring
   WooCommerce's own button markup (which doesn't use the block) to
   the same visual language.
   ===================================================================== */

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce-Button,
.wc-block-components-button:not(.is-link) {
	background-color: var( --zc-color-primary );
	color: var( --zc-color-surface );
	border: none;
	border-radius: var( --zc-radius-md );
	padding: 0.85rem 1.75rem;
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--button );
	font-weight: 500;
	letter-spacing: 0.2px;
	line-height: 1;
	cursor: pointer;
	box-shadow: none;
	transition: background-color 0.2s ease, transform 0.15s ease;
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover,
.wc-block-components-button:not(.is-link):hover {
	background-color: var( --zc-color-text );
	color: var( --zc-color-surface );
}

.woocommerce a.button:focus-visible,
.woocommerce button.button:focus-visible,
.woocommerce input.button:focus-visible,
.wc-block-components-button:not(.is-link):focus-visible {
	outline: 2px solid var( --zc-color-focus );
	outline-offset: 2px;
}

.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt {
	background-color: var( --zc-color-secondary );
}

.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover {
	background-color: var( --zc-color-text );
}

.woocommerce a.button.loading,
.woocommerce button.button.loading {
	opacity: 0.6;
}

/* Outline-style core Button block (e.g. "Explore New Arrivals" on the
   homepage hero) had no working hover effect: Twenty Twenty-Five's own
   outline-variation hover CSS references a "contrast" color preset that
   doesn't exist in this theme's palette, so that whole declaration is
   invalid and silently does nothing. Filling on hover to match every
   other button's hover treatment on the site instead. The !important on
   color is required to beat WordPress's own .has-*-color utility class
   (itself emitted with !important), which a custom text color on the
   button — like this one's primary-color text — always carries. */
.wp-block-button.is-style-outline > .wp-block-button__link:hover {
	background-color: var( --zc-color-text );
	border-color: var( --zc-color-text );
	color: var( --zc-color-surface ) !important;
}

/* =====================================================================
   Forms: inputs, selects, textareas, checkboxes, radios
   ===================================================================== */

.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce table.shop_table select,
.woocommerce ul#shipping_method input,
input.input-text,
textarea,
select,
.wc-block-components-text-input input,
.wc-block-components-textarea textarea {
	background-color: var( --zc-color-surface );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-sm );
	color: var( --zc-color-text );
	padding: 0.7rem 0.9rem;
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--medium );
	transition: border-color 0.15s ease;
}

.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus,
input.input-text:focus,
textarea:focus,
select:focus,
.wc-block-product-search__field:focus {
	border-color: var( --zc-color-focus );
	outline: none;
	box-shadow: 0 0 0 1px var( --zc-color-focus );
}

.woocommerce form label,
.wc-block-components-checkbox__label {
	color: var( --zc-color-text );
	font-size: var( --wp--preset--font-size--label );
}

.woocommerce form label.required {
	color: var( --zc-color-error );
}

/* Checkboxes and radios */
.woocommerce input[type="checkbox"],
.woocommerce input[type="radio"],
input[type="checkbox"],
input[type="radio"] {
	accent-color: var( --zc-color-primary );
	width: 1.05rem;
	height: 1.05rem;
}

/* =====================================================================
   WooCommerce notices (classic) + WC Blocks notices
   ===================================================================== */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews,
p.no-comments,
.wc-block-components-notice-banner {
	border-radius: var( --zc-radius-sm );
	border: none;
	border-left-width: 4px;
	border-left-style: solid;
	padding: 1rem 1.25rem;
	font-size: var( --wp--preset--font-size--medium );
	background-color: var( --zc-color-surface );
	box-shadow: var( --zc-shadow-sm );
}

.woocommerce-message,
.wc-block-components-notice-banner.is-success {
	border-left-color: var( --zc-color-success );
}

.woocommerce-error,
.wc-block-components-notice-banner.is-error {
	border-left-color: var( --zc-color-error );
}

.woocommerce-info,
.wc-block-components-notice-banner.is-info {
	border-left-color: var( --zc-color-primary );
}

.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before {
	display: none;
}

/* =====================================================================
   Badges (sale, stock)
   ===================================================================== */

.onsale,
.wc-block-components-product-sale-badge {
	background-color: var( --zc-color-sale );
	color: var( --zc-color-surface );
	border-radius: var( --zc-radius-pill );
	padding: 0.3rem 0.85rem;
	font-size: var( --wp--preset--font-size--label );
	font-weight: 500;
	letter-spacing: 0.3px;
	text-transform: uppercase;
	position: static;
	box-shadow: none;
}

.stock {
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text-muted );
}

.stock.out-of-stock {
	color: var( --zc-color-error );
}

.stock.in-stock {
	color: var( --zc-color-success );
}

/* "Availability: Made to Order" (zainabcraft-core/includes/product-availability.php)
   renders with WooCommerce's own "available-on-backorder" class, since
   backorders are forced on sitewide so out-of-stock items stay
   purchasable — styled on its own rather than falling back to the
   default muted text, since it's a distinct, deliberate status rather
   than an error. */
.stock.available-on-backorder {
	color: var( --zc-color-accent-gold );
}

/* =====================================================================
   Product cards (foundation only — full archive layout comes later)
   ===================================================================== */

ul.products li.product,
.wc-block-grid__product {
	background-color: var( --zc-color-surface );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	overflow: hidden;
}

.woocommerce-loop-product__title,
.wc-block-components-product-name {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--product-title );
	font-weight: 600;
	color: var( --zc-color-text );
}

.price,
.wc-block-components-product-price {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--price );
	color: var( --zc-color-text );
	font-weight: 500;
}

.price del,
.wc-block-components-product-price__regular {
	color: var( --zc-color-text-muted );
	font-weight: 400;
	opacity: 0.8;
	margin-right: 0.4em;
}

.price ins,
.wc-block-components-product-price__value.is-discounted {
	color: var( --zc-color-sale );
	text-decoration: none;
	font-weight: 600;
}

.star-rating {
	color: var( --zc-color-accent-gold );
}

/* WooCommerce's own CSS lays this row out as display:flex with no gap at
   all, so cards sit flush against each other. */
.wc-block-grid__products {
	gap: var( --wp--preset--spacing--40 );
}

/* Best Sellers / New Arrivals are configured for "4 columns" (so the block
   still queries and shows all 4 products — reducing the columns attribute
   itself would also cut the product count, since this legacy block ties
   the two together), but this align:wide row is never actually wide enough
   for 4 real cards plus 3 gaps: the browser wraps the 4th to its own row
   while sizing all of them off WooCommerce's own `flex: 1 0 25%; max-width:
   25%;` (2-class .wc-block-grid.has-4-columns .wc-block-grid__product
   rule) — sized for a row that has 4 items sharing it, not 3 — leaving
   every card narrower than the space actually available and one card
   stranded alone on its own row. Matching that selector's specificity with
   the two section-specific wrapper classes (both genuinely present) and
   resizing both flex-basis and max-width (that max-width is what was
   silently capping the card at the old 25% even once flex-basis alone was
   overridden) to a real 33.333% lets these render as the clean 3-column
   grid the available width actually supports — consistent with the Shop
   page's own 3-column product grid. */
.wc-block-grid.has-4-columns.wp-block-woocommerce-product-best-sellers .wc-block-grid__product,
.wc-block-grid.has-4-columns.wp-block-woocommerce-product-new .wc-block-grid__product {
	flex-basis: calc( 33.333% - var( --wp--preset--spacing--40 ) * 2 / 3 );
	max-width: calc( 33.333% - var( --wp--preset--spacing--40 ) * 2 / 3 );
}

/* Below 480px this row already drops to one card per line (same width the
   container itself starts wrapping at everywhere else in the theme), but
   the 33.333% max-width above is still in effect — so each card was
   rendering at a third of the row's width with two-thirds of the row
   sitting empty beside it, rather than filling the single column it
   actually has. */
@media ( max-width: 480px ) {
	.wc-block-grid.has-4-columns.wp-block-woocommerce-product-best-sellers .wc-block-grid__product,
	.wc-block-grid.has-4-columns.wp-block-woocommerce-product-new .wc-block-grid__product {
		flex-basis: 100%;
		max-width: 100%;
	}
}

/* WooCommerce Blocks product grids (Best Sellers / New Arrivals use these
   class names instead of the classic ul.products ones above). The parent
   <ul> is a flex row that already stretches every <li> to the tallest
   card's height (confirmed: equal heights even when one card's optional
   star-rating row adds extra content). Without flex-direction:column on
   the card itself, that extra stretched height just sits as blank space
   below whichever card's content is shorter, leaving the Add to Cart
   buttons at different vertical positions row to row. flex-column here +
   margin-top:auto on the button (below) pins every button to the same
   bottom edge regardless of whether the rating row is present. */
.wc-block-grid__product {
	background-color: var( --zc-color-surface );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	padding: 0.75rem;
	display: flex;
	flex-direction: column;
}

.wc-block-grid__product-title {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--product-title );
	font-weight: 600;
	color: var( --zc-color-text );
}

/* The title (and image) sit inside one big <a>; without this it inherits
   the browser's default underlined link style. */
.wc-block-grid__product-link {
	text-decoration: none;
}

.wc-block-grid__product-onsale {
	font-weight: 500;
	text-transform: uppercase;
}

/* WooCommerce's own wc-blocks.css sets background/border/border-radius AND
   font-size:0.875em/padding here via a 2-class selector (.wc-block-grid
   .wc-block-grid__product-onsale) — higher specificity than the single-class
   rule this badge originally only had, so the badge was silently rendering
   in WooCommerce's default white/outlined style (and, since font-size is an
   em value, inheriting the page's fluid "large" body size up to 22px)
   instead of the intended solid sale-color pill at a fixed label size.
   Matching with one extra ancestor class (.wc-block-grid__product, genuinely
   present) wins the specificity fight so all of it actually applies. */
.wc-block-grid .wc-block-grid__product .wc-block-grid__product-onsale {
	background-color: var( --zc-color-sale );
	color: var( --zc-color-surface );
	border: none;
	border-radius: var( --zc-radius-pill );
	padding: 0.3rem 0.85rem;
	font-size: var( --wp--preset--font-size--label );
}

/* Direct flex child of the card (see flex-column rule above) — pins the
   button to the same bottom edge on every card in the row. WooCommerce's
   own wc-blocks.css sets `margin: 0 auto 12px` on this element via a
   2-class selector (.wc-block-grid__product .wc-block-grid__product-add-to-cart),
   which otherwise wins over a 1-class selector and resets margin-top back
   to 0; the extra .wc-block-grid ancestor class here (genuinely present)
   gives this rule higher specificity so it applies reliably. */
.wc-block-grid .wc-block-grid__product .wc-block-grid__product-add-to-cart {
	margin-top: auto;
}

/* This button inherits the global wp-element-button size, which is sized
   for standalone CTAs (hero buttons, etc.) and looks oversized inside a
   narrow product card. Scale it down to match the card's own density.
   WooCommerce's own wc-blocks.css sets font-size:1em here via a 3-class
   selector (.wc-block-grid__product-add-to-cart.wp-block-button
   .wp-block-button__link); matching that same specificity (adding the
   .add_to_cart_button class already present on this element) so our
   value wins regardless of stylesheet load order. */
.wc-block-grid__product-add-to-cart .wp-block-button__link {
	padding: 0.6rem 1.25rem;
	height: auto;
}

/* After a successful AJAX add-to-cart, WooCommerce injects a sibling
   "View cart" link into this same wrapper, which pushes it to two lines.
   A theme-wide rule (.wp-block-button__link { height:100% }) then stretches
   the Add to Cart button to match that taller two-line wrapper, producing
   a large square button. height:auto above stops it stretching; this
   fixes the wrapper's own layout so the two links sit on separate lines
   at their natural (small) size instead of overlapping. */
.wc-block-grid__product-add-to-cart {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.4rem;
}

.wc-block-grid__product-add-to-cart.wp-block-button .wp-block-button__link.add_to_cart_button {
	font-size: var( --wp--preset--font-size--label );
}

/* "View cart" is plain text with no button classes to hook into, so it
   inherits the page's body font-size (the fluid "large" preset — up to
   22px), which reads oversized next to the compact Add to Cart button. */
.wc-block-grid__product-add-to-cart .added_to_cart {
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text-muted );
}

/* =====================================================================
   Homepage — brand story section ("Made by Hand. Made with Heart.")
   ===================================================================== */

.zainabcraft-eyebrow {
	text-transform: uppercase;
	letter-spacing: 0.4px;
	color: var( --zc-color-text-muted );
	margin-bottom: 0.5rem;
}

/* The muted text-on-background color above doesn't have enough contrast on
   the pink accent block (Gift Sets section); ink matches the rest of that
   section's already-explicit text color. */
.zainabcraft-eyebrow--on-accent {
	color: var( --zc-color-text );
}

/* Gift Sets section: the full-strength accent pink read too saturated as a
   whole-section fill next to the site's otherwise muted, earthy palette.
   Softened into a blush tint blended toward the page background (same
   color-mix technique already used for .zainabcraft-placeholder-media) so
   it stays on-brand without competing with everything around it. The icon
   keeps the full-strength accent color as the section's one deliberate
   small pop of that pink, instead of losing it entirely. */
.zainabcraft-gift-section {
	background-color: color-mix( in srgb, var( --zc-color-accent ) 35%, var( --zc-color-background ) );
}

.zainabcraft-gift-section .zainabcraft-feature-icon {
	color: var( --zc-color-accent );
}

.zainabcraft-brand-divider.wp-block-separator {
	width: 48px;
	height: 2px;
	border: none;
	background-color: var( --zc-color-accent );
	opacity: 1;
	margin: 1.5rem auto;
}

/* Left-aligned variant: sits under a left-aligned section heading (About
   Us page's "Made in Pakistan"), so it should hug the same left edge as
   the heading above it instead of the default centered auto margins. */
.zainabcraft-brand-divider--left.wp-block-separator {
	margin-left: 0;
	margin-right: auto;
}

/* =====================================================================
   Homepage — "Why Choose ZainabCraft" feature icons
   ===================================================================== */

.zainabcraft-feature-icon {
	display: block;
	width: 36px;
	height: 36px;
	margin: 0 auto 0.75rem;
	color: var( --zc-color-primary );
}

/* =====================================================================
   Featured categories grid (woocommerce/product-categories block)
   ===================================================================== */

.wc-block-product-categories-list {
	display: grid;
	grid-template-columns: repeat( 2, 1fr );
	gap: 1.5rem;
	list-style: none;
	padding: 0;
	margin: var( --wp--preset--spacing--40 ) 0 0;
}

@media ( min-width: 768px ) {
	.wc-block-product-categories-list {
		grid-template-columns: repeat( 4, 1fr );
	}
}

/* Grid items default to min-width:auto, so a track sizes to fit whichever
   item's text/image needs the most space (e.g. "Custom Creations" wrapping
   wider than "Gift Sets"), leaving columns unequal width and overflowing
   the container at narrow widths below the 4-column breakpoint. min-width:0
   lets each item shrink to its track instead.
   Separately, WooCommerce's own product-categories.css ships
   `.wc-block-product-categories-list--has-images .wc-block-product-categories-list-item`
   with `margin: 4px 0 4px 60px` — a leftover from its default "image beside
   text" layout, irrelevant to this theme's image-on-top grid, but never
   reset. That 60px left margin on every item (not just alternating ones)
   is what actually pushed the whole two-column grid visibly off-center —
   each card sat 60px further right than it should, so the last card in a
   row landed flush against the container's right edge with nothing to
   match on the left. Resetting the margin here (2 classes, matching that
   selector's specificity) is the real fix; justify-self:center is kept as
   a safety net so each card also centers within its own track if the
   track and card widths ever differ again. display:block avoids a
   secondary quirk where justify-self is a no-op on this element's default
   list-item display box. */
.wc-block-product-categories-list-item {
	text-align: center;
	min-width: 0;
	width: 100%;
	justify-self: center;
	display: block;
}

.wc-block-product-categories-list--has-images .wc-block-product-categories-list-item {
	margin: 0;
}

.wc-block-product-categories-list-item a {
	display: block;
	text-decoration: none;
	color: var( --zc-color-text );
}

.wc-block-product-categories-list-item__image {
	display: block;
	border-radius: var( --zc-radius-md );
	overflow: hidden;
	margin-bottom: 0.75rem;
}

.wc-block-product-categories-list-item__image img {
	width: 100%;
	height: auto;
	display: block;
}

/*
 * WooCommerce's own product-categories.css ships
 * `.wc-block-product-categories-list--has-images .wc-block-product-categories-list-item__image`
 * (2 classes) for its classic floated-thumbnail layout: `display:inline-block`,
 * `max-width:50px`, a `margin: 0 .5em 0 -60px` pull-left, and a 1px border.
 * That beats the single-class rule above on specificity, shrinking every
 * category image (whether a real uploaded photo or the default WooCommerce
 * placeholder) down to a small thumbnail sitting beside the label instead of
 * a full-width image above it. Re-declaring the same two classes (still no
 * !important needed: this stylesheet loads after WooCommerce's, so the tie
 * in specificity resolves in our favor by source order) restores the
 * block-fills-its-grid-cell card layout intended above, for every category
 * regardless of whether it has a real photo yet.
 */
.wc-block-product-categories-list--has-images .wc-block-product-categories-list-item__image {
	display: block;
	max-width: none;
	margin: 0 0 0.75rem;
	border: none;
	vertical-align: initial;
}

.wc-block-product-categories-list-item__name {
	font-family: var( --zc-font-body );
	font-weight: 500;
	font-size: var( --wp--preset--font-size--product-title );
}

/* =====================================================================
   Shop archive (archive-product.html)
   ===================================================================== */

/* The breadcrumb/title group is a wp-block-group.alignwide, which the
   global rule above (.wp-block-group.alignwide, .wp-block-group.alignfull
   > .wp-block-group) gives extra left/right container padding. The
   columns row below it is a wp-block-columns.alignwide — a different
   block type the same selector doesn't match — so it never gets that
   extra padding, leaving the "Shop" title inset further than the
   Categories sidebar beneath it. Removing the padding here (3 classes,
   beating the global rule's 2) realigns the title with the sidebar. */
.wp-block-group.alignwide.zainabcraft-shop-header {
	padding-left: 0;
	padding-right: 0;
}

.zainabcraft-shop-sidebar {
	border-right: var( --zc-border-width ) solid var( --zc-color-border );
	padding-right: 0.75rem;
}

/* The column's 20% width (set as an inline style by the block, so only
   !important can override it here) is comfortable at desktop widths, but
   in the 782–1023px tablet range — after the columns un-stack but before
   there's much room to spare — 20% of the row is too narrow for a name
   like "Custom Creations" plus its count to fit on one line, splitting the
   count onto its own line away from the name. Reverting to the original
   25% in just that range gives the text enough room again; it's still
   narrower than the pre-existing 25%-everywhere behavior, only now scoped
   to where there's actually space for it. */
@media ( min-width: 782px ) and ( max-width: 1023px ) {
	.zainabcraft-shop-sidebar {
		flex-basis: 25% !important;
	}

	.zainabcraft-shop-sidebar + .wp-block-column {
		flex-basis: 75% !important;
	}
}

.zainabcraft-shop-sidebar h4 {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--label );
	text-transform: uppercase;
	letter-spacing: 0.4px;
	color: var( --zc-color-text-muted );
}

.zainabcraft-shop-sidebar .wc-block-product-categories-list {
	display: block;
	margin-top: 1rem;
}

/* Category name and product count were rendering on separate lines (two
   sibling inline elements with nothing to keep them side by side) at an
   inconsistent, oversized font-size (the count had no font-size of its
   own, so it inherited the page's fluid "large" body size). A flex row
   puts them on one line with the count pushed to the right, and setting
   font-size once here — inherited by both the name and the count — keeps
   them the same fixed, compact size regardless of context. */
.zainabcraft-shop-sidebar .wc-block-product-categories-list-item {
	display: flex;
	align-items: baseline;
	justify-content: flex-start;
	gap: 0.3rem;
	text-align: left;
	margin-bottom: 0.6rem;
	font-size: var( --wp--preset--font-size--nav );
}

.zainabcraft-shop-sidebar .wc-block-product-categories-list-item__name {
	font-weight: 400;
	font-size: inherit;
}

.zainabcraft-shop-sidebar .wc-block-product-categories-list-item-count {
	font-size: inherit;
	color: var( --zc-color-text-muted );
}

.wc-block-breadcrumbs {
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text-muted );
}

.wc-block-breadcrumbs a {
	color: var( --zc-color-text-muted );
	text-decoration: none;
}

.wc-block-breadcrumbs a:hover {
	color: var( --zc-color-primary );
}

.wc-block-product-results-count {
	color: var( --zc-color-text-muted );
	font-size: var( --wp--preset--font-size--label );
}

.wc-block-catalog-sorting select {
	min-width: 160px;
}

/* WooCommerce's own stylesheet puts a 14px margin-bottom on this <form>
   (spacing meant for when sorting sits stacked above a product grid on its
   own line). Here it sits inline next to the results-count text in a flex
   row with align-items:center; that trailing margin makes this wrapper
   taller than the select itself, so centering the wrapper against the
   count text leaves the visible dropdown sitting above center instead of
   level with it. Zeroing it lets the select's own box — not an invisible
   margin — determine centering. */
.wc-block-catalog-sorting .woocommerce-ordering {
	margin-bottom: 0;
}

/* Product card (grid produced by woocommerce/product-collection)
   ---------------------------------------------------------------
   Phase 1 changes:
   - Global padding removed from the card shell. The image now fills
     the card top-edge to left/right edges without inset.
   - Padding is applied selectively to the text/action elements below
     the image so they never touch the card edge at any viewport.
   - Image container gets a 1:1 aspect ratio (all current product
     photography is confirmed square 900×900). object-fit:cover is safe
     because the image fills the full square without cropping content.
   - Hover uses shadow-only (no translateY lift). The lift caused minor
     layout shift and felt visually aggressive; shadow alone reads as
     elegant depth cue.
   - The grid row (a CSS Grid `<ul>`, WooCommerce core) already stretches
     each card's `<li>` slot to a uniform height — confirmed by measuring
     the `<li>` (469px for every card in a row) versus the card itself
     (445–469px, varying with title line count). `height:100%` lets the
     card actually fill that already-equal slot instead of sizing to its
     own shorter content; flex column + margin-top:auto on the button
     (below) then pins the action row to the same bottom edge across
     every card in a row, regardless of title length.
   ---------------------------------------------------------------- */
.zainabcraft-product-card {
	background-color: var( --zc-color-surface );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	padding: 0;
	text-align: center;
	transition: box-shadow 0.2s ease;
	display: flex;
	flex-direction: column;
	height: 100%;
}

.zainabcraft-product-card:hover {
	box-shadow: var( --zc-shadow-md );
}

@media ( prefers-reduced-motion: reduce ) {
	.zainabcraft-product-card {
		transition: none;
	}
}

/* Image container — 1:1 square to match current photography.
   Radius only on the top corners so it flows into the flat card edge. */
.zainabcraft-product-card .wc-block-components-product-image,
.zainabcraft-product-card .wp-block-post-featured-image {
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: var( --zc-radius-md ) var( --zc-radius-md ) 0 0;
	margin-bottom: 0;
}

.zainabcraft-product-card .wc-block-components-product-image img,
.zainabcraft-product-card .wp-block-post-featured-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
}

/* Text content area — padding applied here, not on the card shell.
   Still used by product-search-results.html's card (same
   .zainabcraft-product-card markup, category label kept there) even
   though the Shop archive's card no longer includes this block. */
.zainabcraft-product-card .wp-block-post-terms {
	display: block;
	font-size: var( --wp--preset--font-size--label );
	text-transform: uppercase;
	letter-spacing: 0.3px;
	margin-bottom: 0.25rem;
	padding-left: 0.85rem;
	padding-right: 0.85rem;
	padding-top: 0.75rem;
}

.zainabcraft-product-card .wp-block-post-terms a {
	color: var( --zc-color-text-muted );
	text-decoration: none;
}

/* Measured directly rather than assumed: this card's column is narrower
   than the homepage grid's (the sidebar eats into the Shop archive's
   available width), so titles here commonly wrap to 3 lines, not 2 — "2,000"
   demo titles like "[DEMO] Embroidered Floral Hair Clip" measured 3 lines
   in this column, while a shorter one like "[DEMO] Handmade Embroidery
   Brooch" only needed 2. Reserving just 2 lines (an earlier attempt) left
   that 1-line difference unaccounted for, and — since every card in a row
   stretches to match the tallest one — it showed up as a 74px gap above
   the Add to Cart button on the 2-line card versus 8px on a 3-line one
   with a rating (measured: home's own equivalent worst-case gap is only
   36px). Reserving the full 3 lines here brings every title to the same
   height regardless of whether it happens to need 2 or 3, closing most of
   that gap; min-height only ever adds space, so a genuinely longer title
   is still free to grow past it rather than being clipped. */
.zainabcraft-product-card .wp-block-post-title {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--product-title );
	font-weight: 600;
	color: var( --zc-color-text );
	line-height: 1.3;
	min-height: 3.9em;
	margin: 0 0 0.4rem;
	padding-left: 0.85rem;
	padding-right: 0.85rem;
}

/* Shop archive cards no longer need their own top padding on the title:
   now that the card carries uniform 0.75rem padding and the image has its
   own margin-bottom (both added above to match the homepage grid's inset
   look), that spacing already separates the image from the title.
   No min-height reservation either (overriding the base rule's 3.9em):
   the grid row already stretches every card to the tallest one's height
   (same mechanism the homepage grid relies on, which reserves nothing),
   and margin-top:auto on the button (below) absorbs whatever's left over
   to keep every button pinned to the row's bottom edge regardless of a
   particular card's title/rating footprint. A fixed line-count guess was
   only ever an approximation of that and, now that widening the grid to 3
   columns (below) means titles typically wrap to fewer lines, was reserving
   more space than most cards actually need — inflating every card past the
   homepage grid's own height. */
.zainabcraft-product-card--no-terms .wp-block-post-title {
	min-height: 0;
}

.zainabcraft-product-card--no-terms:not( :has( .wc-block-components-product-rating ) ) .wc-block-components-product-price {
	margin-bottom: 0;
}

.zainabcraft-product-card .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
}

.zainabcraft-product-card .wc-block-components-product-price {
	justify-content: center;
	color: var( --zc-color-text );
	font-weight: 500;
	padding-left: 0.85rem;
	padding-right: 0.85rem;
}

/* The star-rating block only exists in the DOM for products with at least
   one review. With the title now equalized (above), this rating's own
   footprint (~48px) is the only remaining source of height difference
   between cards in a row — reserving it here when absent keeps every
   price/button at the same position regardless of whether that particular
   product happens to have reviews. */
.zainabcraft-product-card:not( :has( .wc-block-components-product-rating ) ) .wc-block-components-product-price {
	margin-bottom: 48px;
}

.zainabcraft-product-card .wc-block-components-product-price del {
	color: var( --zc-color-text-muted );
	font-weight: 400;
	opacity: 0.8;
	text-decoration: line-through;
	margin-right: 0.4em;
}

.zainabcraft-product-card .wc-block-components-product-price ins {
	color: var( --zc-color-sale );
	text-decoration: none;
	font-weight: 600;
}

/* This block draws its stars via the "WooCommerce" icon font with
   color:currentColor, inheriting the card's ink text color instead of the
   same gold used by the homepage grid's classic .star-rating stars. */
.zainabcraft-product-card .wc-block-components-product-rating__stars {
	color: var( --zc-color-accent-gold );
}

.zainabcraft-product-card .wc-block-components-product-rating {
	margin-top: 0.25rem;
}

.zainabcraft-product-card .wc-block-components-product-stock-indicator {
	display: inline-block;
	font-size: var( --wp--preset--font-size--label );
	margin-top: 0.25rem;
	padding-left: 0.85rem;
	padding-right: 0.85rem;
}

.zainabcraft-product-card .wc-block-components-product-stock-indicator--out-of-stock {
	color: var( --zc-color-error );
}

.zainabcraft-product-card .wc-block-components-product-stock-indicator--on-backorder {
	color: var( --zc-color-accent-gold );
}

/* Direct flex child of the card (see the flex-column rule above) — auto
   top-margin pushes it to the same bottom edge on every card in a row,
   independent of how many lines the title/price above it took up. */
.zainabcraft-product-card .wp-block-woocommerce-product-button {
	margin-top: auto;
}

.zainabcraft-product-card .wc-block-components-product-button__button {
	background-color: var( --zc-color-primary );
	color: var( --zc-color-surface );
	border: none;
	border-radius: var( --zc-radius-md );
	padding: 0.6rem 1.25rem;
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--label );
	font-weight: 500;
}

.zainabcraft-product-card .wc-block-components-product-button__button:hover {
	background-color: var( --zc-color-text );
	color: var( --zc-color-surface );
}

/* After an AJAX add-to-cart, WooCommerce injects a plain-text "View cart"
   link next to the button with no button classes to hook into, so it
   inherits the page's fluid "large" body font-size (up to 22px) — the same
   oversized-link bug already fixed for the homepage's classic grid card
   (.wc-block-grid__product-add-to-cart .added_to_cart, above). This is the
   equivalent fix for this block's own button wrapper. */
.zainabcraft-product-card .wp-block-woocommerce-product-button .added_to_cart {
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text-muted );
}

/* Shop archive cards only (--no-terms modifier): match the homepage Best
   Sellers/New Arrivals card's inset-image look. Those classic wc-block-grid
   cards give the whole card 0.75rem of uniform padding (confirmed via
   measurement: 12-13px inset on every side, image included), so the photo
   sits framed inside the card border instead of bleeding edge-to-edge like
   this block's Phase-1 default. Scoped to --no-terms so
   product-search-results.html's card (same base .zainabcraft-product-card
   markup) keeps its existing flush-image treatment untouched. */
.zainabcraft-product-card--no-terms {
	padding: 0.75rem;
}

.zainabcraft-product-card--no-terms .wc-block-components-product-image,
.zainabcraft-product-card--no-terms .wp-block-post-featured-image {
	border-radius: var( --zc-radius-md );
	margin-bottom: 0.75rem;
}

.zainabcraft-product-card--no-terms .wp-block-post-title,
.zainabcraft-product-card--no-terms .wc-block-components-product-price,
.zainabcraft-product-card--no-terms .wc-block-components-product-stock-indicator {
	padding-left: 0;
	padding-right: 0;
}

.zainabcraft-empty-shop {
	padding: var( --wp--preset--spacing--60 ) 0;
	text-align: center;
	color: var( --zc-color-text-muted );
}

/*
 * This must match the width WooCommerce/core's own columns block actually
 * stacks at (wp-includes/blocks/columns/style.css uses max-width:781px),
 * not an arbitrary "mobile" breakpoint — otherwise the sidebar is already
 * full-width at 768-781px but still carries its desktop border-right.
 */
@media ( max-width: 781px ) {
	.zainabcraft-shop-sidebar {
		border-right: none;
		border-bottom: var( --zc-border-width ) solid var( --zc-color-border );
		padding-right: 0;
		padding-bottom: 1.5rem;
		margin-bottom: 1.5rem;
	}
}

/* =====================================================================
   Single product page
   ===================================================================== */

.zainabcraft-single-product {
	gap: 3rem;
}

/* "Description" (the product-details tab heading) and "Related products"
   (from WooCommerce's own related-products pattern) both come from
   WooCommerce with no fontSize of their own, so they render at the
   theme's plain h2 default (heading-2, the same size used for major
   homepage sections like "Shop by Category") — oversized for what are
   really sub-sections of a single product's own page, and part of why
   the whole page read as uniformly big with no heading hierarchy.
   Matched to the product title's own heading-3 above them for a
   consistent scale down the page. Scoped to the single-product body
   class so Home's own (correctly large) section headings are untouched. */
body.single-product .woocommerce-tabs h2,
body.single-product .wp-block-woocommerce-product-collection .wp-block-heading {
	font-size: var( --wp--preset--font-size--heading-3 );
}

/* The tab panel body text (Description/Reviews/Shipping Information/Returns)
   has no fontSize of its own either, so — like the h2 above — it rendered at
   the page's plain-paragraph default (the fluid "large" size, ~22px at wide
   viewports), reading oversized for what's dense informational copy rather
   than editorial homepage text. Matched to the "medium" (1rem) scale already
   used sitewide as the standard body-copy size, scoped the same way as the
   heading fix above. */
body.single-product .woocommerce-tabs .panel {
	font-size: var( --wp--preset--font-size--medium );
}

/* Same fluid-default oversizing as the tab panels above, on the short
   description shown near the top of the page (next to price/availability),
   rendered via the [zainabcraft_product_short_description] shortcode —
   a separate element outside .woocommerce-tabs, so the fix above never
   reached it. */
body.single-product .woocommerce-product-details__short-description {
	font-size: var( --wp--preset--font-size--medium );
}

.wp-block-woocommerce-product-image-gallery img,
.wc-block-woocommerce-product-gallery-large-image img {
	border-radius: var( --zc-radius-lg );
}

.wc-block-components-product-image-gallery__thumbnail {
	border-radius: var( --zc-radius-sm );
	overflow: hidden;
}

.wp-block-woocommerce-product-rating,
.wc-block-components-product-rating {
	margin: 0.5rem 0;
}

.wc-block-components-product-rating .star-rating {
	color: var( --zc-color-accent-gold );
}

.wp-block-post-excerpt {
	color: var( --zc-color-text-muted );
	margin: 1rem 0;
	font-size: var( --wp--preset--font-size--medium );
}

/* The cart form's own submit button, and our injected Buy Now button.
   Both carry WooCommerce's own `button` and `alt` classes alongside these
   (confirmed via rendered class list), and `.woocommerce button.button.alt`
   elsewhere in this file sets a sage-green background at higher
   specificity than either single-class rule below — silently overriding
   both this button's intended solid primary-brown AND the Buy Now
   button's intended transparent/outline look with the same solid green,
   erasing the visual distinction between them. Repeating `.button.alt` in
   each selector (both genuinely present) outranks that rule so the
   colors actually declared here take effect. */
.woocommerce .single_add_to_cart_button.button.alt {
	background-color: var( --zc-color-primary );
	color: var( --zc-color-surface );
	border: none;
	border-radius: var( --zc-radius-md );
	padding: 0.9rem 2rem;
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--button );
	font-weight: 500;
	cursor: pointer;
}

.woocommerce .single_add_to_cart_button.button.alt:hover {
	background-color: var( --zc-color-text );
	color: var( --zc-color-surface );
}

.woocommerce .zainabcraft-buy-now-button.button.alt {
	background-color: transparent;
	color: var( --zc-color-primary );
	border: 2px solid var( --zc-color-primary );
	margin-left: 0.75rem;
}

.woocommerce .zainabcraft-buy-now-button.button.alt:hover {
	background-color: var( --zc-color-primary );
	color: var( --zc-color-surface );
}

@media ( min-width: 481px ) {
	/* Buy Now reuses WooCommerce's own `single_add_to_cart_button` class
	   (for its native form-button styling/submit behavior), but that also
	   means it inherits WooCommerce's own
	   `.single_add_to_cart_button { grid-column: 2/3 }` placement rule —
	   the same rule Add to Cart uses. `form.cart` lays its children out
	   with `grid-auto-flow: column`, so with both buttons explicitly
	   requesting the same column, the second one (Buy Now) can't share
	   row 1 and drops to row 2, stacking the buttons instead of the
	   side-by-side layout `margin-left` above already assumes. Moving
	   Buy Now into the form's third column (already defined by
	   WooCommerce's own `grid-template-columns`) frees column 2 for Add
	   to Cart alone, so both land on row 1. Scoped above the existing
	   480px breakpoint, where the two buttons intentionally stack full
	   width instead. */
	.woocommerce .wp-block-woocommerce-add-to-cart-form form.cart > .zainabcraft-buy-now-button {
		grid-column: 3 / 4;
		justify-self: start;
	}
}

/* Disabled Add to Cart / Buy Now (before a required variation option is
   selected): WooCommerce marks these with a `.disabled` class — there is
   no native `disabled` attribute — and its only styling for that class
   is `opacity:.5`, which just fades whichever background color already
   wins (secondary/sage here, from the `.button.alt` rule both buttons
   also carry), not a clear "disabled" signal. A flat neutral
   background/text and a not-allowed cursor read unambiguously as
   disabled; both buttons carry the shared `button`, `alt` and `disabled`
   classes, so one rule covers both, and it stops applying — reverting to
   the normal styling above with no extra rule needed — the moment
   WooCommerce removes the `disabled` class after a valid selection. The
   selector repeats those same three classes (plus `.woocommerce` and the
   `button` type) to outrank the `.button.alt` background rule elsewhere
   in this file, which is more specific than either button's own rule
   above. */
.woocommerce button.button.alt.disabled,
.woocommerce button.button.alt:disabled {
	background-color: var( --zc-color-border );
	color: var( --zc-color-text-muted );
	opacity: 1;
	cursor: not-allowed;
}

.woocommerce button.button.alt.disabled:hover,
.woocommerce button.button.alt:disabled:hover {
	background-color: var( --zc-color-border );
	color: var( --zc-color-text-muted );
}

.variations select {
	min-width: 180px;
}

.variations td.label {
	font-size: var( --wp--preset--font-size--label );
	text-transform: uppercase;
	color: var( --zc-color-text-muted );
	padding-right: 0.75rem;
}

.woocommerce-variation-price .price {
	color: var( --zc-color-primary );
}

.woocommerce-variation-availability {
	font-size: var( --wp--preset--font-size--label );
}

/* Product Details accordion (Description / Additional Information / Reviews
   / our Care Instructions, Shipping Information, Returns tabs). */
.wp-block-woocommerce-product-details {
	margin-top: var( --wp--preset--spacing--60 );
	border-top: var( --zc-border-width ) solid var( --zc-color-border );
}

.wp-block-woocommerce-product-details .wp-block-accordion-item__toggle {
	font-family: var( --zc-font-body );
	font-weight: 500;
	color: var( --zc-color-text );
	padding: 1rem 0;
}

.wp-block-woocommerce-product-details .wp-block-accordion-item {
	border-bottom: var( --zc-border-width ) solid var( --zc-color-border );
}

/* Related products (uses the default WooCommerce pattern, not our custom
   .zainabcraft-product-card wrapper). */
.wp-block-woocommerce-product-collection h2 {
	font-family: var( --zc-font-heading );
}

/* "Choose Size" selector (zainabcraft-core/includes/product-size-selector.php).
   The radio/text inputs themselves need no rules here — they already pick
   up the sitewide input/radio styling (border, radius, focus ring, accent
   color) defined earlier in this file; only the layout around them is
   custom. */
.zainabcraft-size-selector {
	margin: 1.25rem 0;
}

.zainabcraft-size-selector__heading {
	font-family: var( --zc-font-body );
	font-weight: 500;
	font-size: var( --wp--preset--font-size--medium );
	color: var( --zc-color-text );
	margin: 0 0 0.6rem;
}

.zainabcraft-size-selector__options {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5rem;
	list-style: none;
	margin: 0 0 0.9rem;
	padding: 0;
}

.zainabcraft-size-selector__options label {
	display: flex;
	align-items: center;
	gap: 0.45rem;
	font-size: var( --wp--preset--font-size--medium );
	color: var( --zc-color-text );
	cursor: pointer;
}

/* Hidden via the `hidden` attribute until Custom Size is picked; the
   opacity transition only plays while it's already in the layout (see
   product-size-selector.js for why the two are handled separately — a
   transition can't run on a `display:none` element). */
.zainabcraft-size-selector__custom-wrap {
	margin: 0 0 1rem;
	opacity: 0;
	transition: opacity 0.15s ease;
}

.zainabcraft-size-selector__custom-wrap.is-visible {
	opacity: 1;
}

.zainabcraft-size-selector__custom-wrap label {
	display: block;
	margin-bottom: 0.4rem;
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text );
}

.zainabcraft-size-selector__custom-wrap input[type="text"] {
	width: 100%;
	max-width: 320px;
	display: block;
}

.zainabcraft-size-selector__note {
	margin: -0.4rem 0 0.75rem;
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text-muted );
}

/* =====================================================================
   Cart & Checkout (WooCommerce Blocks)
   ===================================================================== */

.wc-block-cart,
.wc-block-checkout {
	margin-top: var( --wp--preset--spacing--40 );
}

/* Order summary / totals panel reads as a distinct card next to the
   line items, on both cart and checkout — same surface/radius/shadow
   tokens already used for product cards, so it reads as considered
   rather than a plain WooCommerce Blocks default. */
.wc-block-cart .wc-block-components-sidebar,
.wc-block-checkout .wc-block-components-sidebar {
	background-color: var( --zc-color-surface );
	border-radius: var( --zc-radius-md );
	padding: 1.5rem;
	box-shadow: var( --zc-shadow-sm );
}

.wc-block-components-product-metadata,
.wc-block-cart-item__prices,
.wc-block-cart-item__quantity {
	font-family: var( --zc-font-body );
}

.wc-block-cart-items__row {
	border-bottom: var( --zc-border-width ) solid var( --zc-color-border );
	padding-bottom: 1rem;
	margin-bottom: 1rem;
}

.wc-block-components-product-name {
	color: var( --zc-color-text );
	font-weight: 500;
	text-decoration: none;
}

.wc-block-cart-item__remove-link,
.wc-block-components-product-remove-item__button {
	color: var( --zc-color-error );
	font-size: var( --wp--preset--font-size--label );
}

/* Coupon form */
.wc-block-components-totals-coupon__form input {
	background-color: var( --zc-color-surface );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-sm );
}

.wc-block-components-totals-coupon-link {
	color: var( --zc-color-primary );
}

/* Order totals rows */
.wc-block-components-totals-item__label,
.wc-block-components-totals-item__value {
	font-family: var( --zc-font-body );
	color: var( --zc-color-text );
}

.wc-block-components-totals-footer-item .wc-block-components-totals-item__value,
.wc-block-components-totals-footer-item .wc-block-components-totals-item__label {
	font-weight: 600;
	font-size: var( --wp--preset--font-size--price );
	color: var( --zc-color-primary );
}

/* Proceed to checkout / place order */
.wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button {
	background-color: var( --zc-color-primary );
	border-radius: var( --zc-radius-md );
	width: 100%;
}

.wc-block-cart__submit-button:hover,
.wc-block-components-checkout-place-order-button:hover {
	background-color: var( --zc-color-text );
}

/* Shipping / payment method radio options. WooCommerce's own CSS sets
   padding: 16px 16px 16px 48px on this element — the 48px left side isn't
   arbitrary, it's exactly the space the absolutely-positioned 20px radio
   circle (itself positioned at left:16px) needs to clear before the label
   text starts. The uniform 1rem (16px) padding this rule used to set beat
   that on the left side only, leaving the circle drawn directly on top of
   the first couple of characters of every option's label. Matching that
   same 48px here keeps this rule's own top/right/bottom spacing while no
   longer fighting the input's required clearance. */
.wc-block-components-radio-control__option {
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-sm );
	padding: 0.85rem 1rem 0.85rem 3rem;
	margin-bottom: 0.6rem;
}

.wc-block-components-radio-control__option.wc-block-components-radio-control__option-checked {
	border-color: var( --zc-color-primary );
	background-color: color-mix( in srgb, var( --zc-color-primary ) 6%, var( --zc-color-surface ) );
}

.wc-block-components-radio-control__input {
	accent-color: var( --zc-color-primary );
}

/* Checkout form section headings */
.wc-block-components-checkout-step__title {
	font-family: var( --zc-font-heading );
	font-weight: 600;
	color: var( --zc-color-text );
}

.wc-block-components-checkout-step__description {
	color: var( --zc-color-text-muted );
	font-size: var( --wp--preset--font-size--label );
}

/* Empty cart state */
.wc-block-cart__empty-cart__title {
	font-family: var( --zc-font-heading );
}

/* WooCommerce's own cart/checkout layout only stacks main+sidebar below a
   699px *container* width (a @container query, not a viewport one) — above
   that it's a fixed 65%/35% split with no intermediate adjustment. On this
   page's actual container width, that only reaches 699px around 480px
   viewport width, so from roughly 800px up to 1150px the sidebar (order
   summary) was measured shrinking to 250-370px — narrow enough that the
   product name and description wrap to 3-6 short, ragged lines instead of
   reading as a clean card. Re-declaring the exact same rules WooCommerce's
   own container query uses, as a regular (viewport) media query instead,
   stacks the layout earlier — while it's still comfortably above the
   699px container-width the narrower single column needs to avoid
   re-triggering that same cramped math itself. */
@media ( max-width: 1150px ) {
	.wc-block-components-sidebar-layout {
		flex-direction: column;
	}

	.wc-block-components-sidebar-layout .wc-block-components-main,
	.wc-block-components-sidebar-layout .wc-block-components-sidebar {
		width: 100%;
		padding: 0;
	}

	/* Checkout only (not cart — the cart's own product list should still
	   come before its totals/checkout button): main also contains the
	   "Place Order" button as its last element, so simply stacking main
	   above sidebar in DOM order would put the order summary *after* the
	   button a customer just used to submit the order, instead of before
	   it as a final review. Moving the summary ahead of the whole main
	   column restores that review-then-confirm order. */
	.wc-block-checkout .wc-block-components-sidebar {
		order: -1;
	}

	.wc-block-cart .wc-block-components-sidebar,
	.wc-block-checkout .wc-block-components-sidebar {
		margin-top: 1.5rem;
	}
}

/* Below a 778px viewport (measured precisely — 778 still duplicates,
   779 doesn't; driven by WooCommerce's own ~699px container-width
   threshold on this page's actual layout) WooCommerce's checkout block
   starts "filling" a full second copy of the order summary (product,
   coupon form, totals — a complete, independently-functional duplicate,
   confirmed by inspecting the DOM) into the actions area right before
   the Place Order button, while leaving the original summary in place
   too — so the page showed "Order summary" twice: once as a collapsed
   accordion up near the top, and again, fully expanded, right before the
   button. The Fill copy is the more useful of the two (full detail,
   positioned as a natural final review right before confirming), so the
   original sidebar copy is hidden here rather than the other way around.
   This only hides the sidebar's own box — the coupon form and totals
   both still work normally through the Fill copy that remains. */
@media ( max-width: 778px ) {
	.wc-block-checkout .wc-block-components-sidebar {
		display: none;
	}
}

/* =====================================================================
   My Account (classic WooCommerce templates)
   Form inputs, tables and buttons already pick up the sitewide rules
   above (.input-text, .shop_table, primary button styles). Everything
   below addresses two things: none of this page's own text (nav links,
   the dashboard/description paragraphs, the "Billing/Shipping address"
   and "Password change" sub-headings) has a fontSize of its own, so it
   all inherited the ~22px fluid paragraph default — including the
   address/password headings, which inherited the *heading* default
   (48px) instead, since they're real `<h2>`/`<legend>` elements: badly
   oversized either way for what's secondary account-management UI. And
   the content column had no visual treatment at all, floating loose
   next to the nav's own bordered card — giving it a matching card makes
   the two read as one cohesive panel instead.
   ===================================================================== */

.woocommerce-MyAccount-navigation ul {
	list-style: none;
	margin: 0;
	padding: 0;
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	overflow: hidden;
	box-sizing: border-box;
}

.woocommerce-MyAccount-navigation li {
	border-bottom: var( --zc-border-width ) solid var( --zc-color-border );
}

.woocommerce-MyAccount-navigation li:last-child {
	border-bottom: none;
}

/* WooCommerce's own blocktheme CSS pads every `<li>` itself (and
   additionally zeroes out just the *first* one's top padding), on the
   assumption nothing else provides spacing. Our own rule above already
   gives the `<a>` inside full padding on every side as the actual
   clickable row, so the `<li>`'s own padding just stacks on top of
   that — unevenly, since only Dashboard (the first item) loses its
   share of it. That's what left Dashboard's link sitting flush against
   the top of its row instead of centered like every other item
   (Log out included). Removing the `<li>` padding entirely — the `<a>`
   already supplies it — gives every row the same, evenly centered
   spacing. */
body.woocommerce-account .woocommerce-MyAccount-navigation li {
	padding: 0;
}

.woocommerce-MyAccount-navigation a {
	display: block;
	padding: 0.85rem 1.25rem;
	color: var( --zc-color-text );
	text-decoration: none;
	font-size: var( --wp--preset--font-size--medium );
}

.woocommerce-MyAccount-navigation a:hover {
	background-color: var( --zc-color-background );
}

.woocommerce-MyAccount-navigation-link.is-active a {
	background-color: var( --zc-color-primary );
	color: var( --zc-color-surface );
	font-weight: 500;
}

/* WooCommerce's own blocktheme CSS underlines the active link and any
   hovered link (`.woocommerce-account .woocommerce-MyAccount-navigation
   li.is-active a` / `li a:hover`, both more specific than the plain
   `.woocommerce-MyAccount-navigation-link.is-active a` above) as an
   accessibility signal that isn't color alone — here the active state
   already gets a solid background plus bold text, and every row gets a
   background change on hover, so the underline on top just looks like a
   stray mid-last-decade link style. Matches that selector's own shape
   (plus the `body` element) to outrank it. */
body.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a,
body.woocommerce-account .woocommerce-MyAccount-navigation li a:hover {
	text-decoration: none;
}

/* The content column gets the same card treatment as the nav — border,
   radius, background — so the two form one panel instead of a bordered
   list next to bare text. */
.woocommerce-MyAccount-content {
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	background-color: var( --zc-color-surface );
	padding: 2rem;
	box-sizing: border-box;
}

@media ( max-width: 768px ) {
	.woocommerce-MyAccount-content {
		padding: 1.5rem;
	}
}

.woocommerce-MyAccount-content p {
	font-size: var( --wp--preset--font-size--medium );
}

.woocommerce-MyAccount-content h2,
.woocommerce-EditAccountForm fieldset legend {
	font-size: var( --wp--preset--font-size--heading-4 );
	font-weight: 600;
}

/* The "Password change" fieldset had no styling of its own, so it fell
   back to the browser's native fieldset chrome — a 2px grey "groove"
   (3D-beveled) border, jarring next to every flat 1px border used
   everywhere else on the site (inputs, cards, the address boxes above).
   Matches those same tokens instead. */
.woocommerce-EditAccountForm fieldset {
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	padding: 1.5rem;
	margin: 2rem 0 0;
}

.woocommerce-EditAccountForm fieldset legend {
	padding: 0 0.5rem;
	margin-left: -0.5rem;
}

/* Saved-address text is an `<address>` element, not a `<p>`, so the
   paragraph fix above never reached it — it was still rendering at the
   ~22px fluid default (plus the browser's own italic default, on the
   addresses page specifically — the order-view page's billing/shipping
   box already resets that via its own WooCommerce CSS), oversized and
   off-tone next to the rest of this now 16px section. Covers both the
   Addresses page (`.woocommerce-Address`) and a single order's billing/
   shipping box (`.woocommerce-customer-details`). */
.woocommerce-MyAccount-content address {
	font-style: normal;
	font-size: var( --wp--preset--font-size--medium );
	line-height: 1.6;
	color: var( --zc-color-text-muted );
}

/* WooCommerce's own generic `.edit{float:right}` pulls the "Add/Edit
   Billing address" link to the right edge of its ~294px column while
   `display:block` (from WooCommerce's blocktheme CSS) drops it to its
   own line below the heading — the combination lands it floating in the
   middle of the column, aligned with neither the heading above nor the
   address text below. Stacking heading and link as a left-aligned
   column instead gives both a clear, shared left edge. */
.woocommerce-Address-title {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.35rem;
	margin-bottom: 0.75rem;
}

.woocommerce-Address-title h2 {
	margin: 0;
}

body.woocommerce-account .woocommerce-Address-title .edit {
	float: none;
	display: inline-block;
	margin: 0;
	font-size: var( --wp--preset--font-size--small );
}

/* The Orders list table has its own WooCommerce rule,
   `.woocommerce table.my_account_orders { font-size: .85em }`, scaling
   it *relative* to its container instead of setting an absolute size —
   and since the container (`.woocommerce-MyAccount-content`) is itself
   the ~22px fluid default, .85em still lands at ~18.7px, its own
   slightly-off size that matches neither that 22px nor the 16px used
   everywhere else in this section. A single order's own line-items
   table (`.order_details`, a different table with no such rule at all)
   has the opposite problem: no reduction whatsoever, still the full
   22px. Setting an explicit size directly on every table's `<td>`
   sidesteps both — a per-element rule always wins over an inherited
   value, so it doesn't need to out-specificity either table's own CSS. */
.woocommerce-MyAccount-content .shop_table td {
	font-size: var( --wp--preset--font-size--medium );
}

/* The fix above only covers `<td>` — a single order's totals rows
   (Subtotal/Shipping/Total/Payment method) are `<th scope="row">`, a
   different tag the same rule doesn't match, so those labels were still
   inheriting the ~22px fluid default at full weight, next to their own
   18px `<td>` values right beside them. `tfoot` scopes this to just
   those rows, leaving the correctly-small "Product"/"Total" column
   headers in `.shop_table thead th` untouched. */
.woocommerce-MyAccount-content .shop_table tfoot th {
	font-size: var( --wp--preset--font-size--medium );
}

/* Same ~22px fluid default on the "Order #123 was placed on… and is
   currently Processing." line — it's a plain, unclassed `<p>` sitting
   directly in `.woocommerce-MyAccount-content` (myaccount/view-order.php),
   so nothing else in this file was already targeting it. */
.woocommerce-MyAccount-content > p {
	font-size: var( --wp--preset--font-size--medium );
}

/* Order status (Processing/Completed/On-hold/…) read as plain black
   text identical to every other cell, so scanning a list of orders for
   the ones that still need attention meant reading each word. WooCommerce
   already marks each row with a `--status-{slug}` modifier class; color
   just the status cell by it, reusing the same semantic tokens used for
   stock/error states elsewhere on the site. */
.woocommerce-orders-table__cell-order-status {
	font-weight: 600;
}

.woocommerce-orders-table__row--status-completed .woocommerce-orders-table__cell-order-status {
	color: var( --zc-color-success );
}

.woocommerce-orders-table__row--status-processing .woocommerce-orders-table__cell-order-status {
	color: var( --zc-color-primary );
}

.woocommerce-orders-table__row--status-on-hold .woocommerce-orders-table__cell-order-status,
.woocommerce-orders-table__row--status-pending .woocommerce-orders-table__cell-order-status {
	color: var( --zc-color-accent-gold );
}

.woocommerce-orders-table__row--status-cancelled .woocommerce-orders-table__cell-order-status,
.woocommerce-orders-table__row--status-failed .woocommerce-orders-table__cell-order-status,
.woocommerce-orders-table__row--status-refunded .woocommerce-orders-table__cell-order-status {
	color: var( --zc-color-error );
}

/* The orders list's "View"/"Pay"/"Cancel" action buttons otherwise
   inherit the sitewide button size (meant for a page's one primary
   action, e.g. Add to Cart) — oversized for a small action sitting
   inside a table row next to plain text. `.woocommerce a.button` (3
   components: 2 classes + the `a` tag) otherwise beats a plainer
   version of this rule on specificity; the extra (genuinely present)
   `.woocommerce-MyAccount-content` ancestor class here outranks it
   without needing !important, and scopes the change to just this
   column so no other button on the site is affected. */
.woocommerce-MyAccount-content .woocommerce-orders-table__cell-order-actions a.button {
	padding: 0.5rem 1rem;
	font-size: var( --wp--preset--font-size--small );
}

/* My Account -> Custom Orders (zainabcraft-core/includes/custom-order-my-account.php).
   The list/detail tables reuse WooCommerce's own .shop_table /
   .woocommerce-orders-table classes, so their `td`s already inherit the
   correct size from the `.shop_table td` fix elsewhere in this file —
   but that fix only ever covered `td`, not `th` (the earlier bug it
   fixed was specifically about the Orders totals row, which only needed
   `td`). This detail table's row labels are `<th scope="row">`, the
   same unstyled-th gap, just in a table of its own — same ~22px fluid
   default, same fix. Scoped to this one table rather than widening the
   original `.shop_table td` fix to `th` generally, so the Orders list's
   own (correctly small, uppercase) `thead th` column headers stay
   untouched. */
.zainabcraft-custom-order-detail th {
	font-size: var( --wp--preset--font-size--medium );
}

.zainabcraft-custom-order-detail__image {
	border-radius: var( --zc-radius-sm );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	display: block;
}

.zainabcraft-custom-order-detail__color-swatch {
	display: inline-block;
	width: 1.25rem;
	height: 1.25rem;
	border-radius: var( --zc-radius-sm );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	vertical-align: middle;
	margin-right: 0.5rem;
}

/* The order number + "View Order" button were plain inline content
   directly in the cell, which at the table's already-narrow responsive
   value column (mobile) let the full-size button overlap the "#135"
   text next to it instead of wrapping under it. flex-wrap plus a
   smaller button (matching the same compact size already used for
   in-table actions elsewhere) fixes both the overlap and the
   oversized-for-this-context button. */
.zainabcraft-custom-order-detail__wc-order {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem;
}

.zainabcraft-custom-order-detail__wc-order a.button {
	padding: 0.5rem 1rem;
	font-size: var( --wp--preset--font-size--small );
}

/* Login/Register: this pair sits outside `.woocommerce-MyAccount-content`
   (that wrapper only exists once logged in), so neither the "Order
   details"/"Billing address" heading-4 fix nor any other account-page
   fix above reaches it — both headings were still the bare, unstyled
   h2 default (48px), the same oversized-heading bug fixed everywhere
   else on this site. Matched to heading-3, the scale already used for
   other page-level section headings (e.g. the product page's
   "Description" tab). */
#customer_login h2 {
	font-size: var( --wp--preset--font-size--heading-3 );
}

/* The registration form's privacy-policy notice is plain body text at
   the ~22px fluid default — fine print, not a paragraph meant to be
   read at the same size as the form labels above it. Sized down to
   match the muted, small-print treatment used for footer text and
   other fine-print copy sitewide. */
.woocommerce-privacy-policy-text p {
	font-size: var( --wp--preset--font-size--small );
	color: var( --zc-color-text-muted );
}

/* The Login ⇄ Register cross-link (added by the theme's
   woocommerce/myaccount/form-login.php override) reads as a muted
   question with a normal-colored link for the action itself, the same
   "quiet prompt, clear action" pairing used for hint text elsewhere on
   this site — distinguishing it from the form's own labels/buttons
   above it. */
.zainabcraft-auth-switch {
	margin-top: 1rem;
	font-size: var( --wp--preset--font-size--small );
	color: var( --zc-color-text-muted );
}

/* =====================================================================
   WhatsApp
   ===================================================================== */

.zainabcraft-whatsapp-float {
	position: fixed;
	bottom: 1.5rem;
	right: 1.5rem;
	width: 56px;
	height: 56px;
	background-color: #25d366;
	color: #fff;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: var( --zc-shadow-md );
	z-index: 1000;
	transition: transform 0.2s ease;
}

.zainabcraft-whatsapp-float:hover {
	transform: scale( 1.08 );
	color: #fff;
}

@media ( max-width: 480px ) {
	.zainabcraft-whatsapp-float {
		bottom: 1rem;
		right: 1rem;
		width: 50px;
		height: 50px;
	}
}

/* Tertiary treatment: neutral theme tokens rather than WhatsApp's brand
   green, so it reads as a secondary action next to whatever dominant
   button sits near it. The icon's fill is pinned back to WhatsApp's own
   green independently of the button's (now neutral) text color, so the
   action is still instantly recognizable. */
.zainabcraft-whatsapp-contact-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	background-color: transparent;
	color: var( --zc-color-text-muted );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	padding: 0.85rem 1.75rem;
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--button );
	font-weight: 500;
	cursor: pointer;
	text-decoration: none;
	margin-top: 0.75rem;
}

.zainabcraft-whatsapp-contact-button svg {
	color: #25d366;
}

.zainabcraft-whatsapp-contact-button:hover {
	background-color: var( --zc-color-surface );
	border-color: var( --zc-color-primary );
	color: var( --zc-color-text );
}

/* =====================================================================
   Content pages: "needs your input" callout
   ===================================================================== */

.zainabcraft-todo-note {
	background-color: color-mix( in srgb, var( --zc-color-accent-gold ) 10%, var( --zc-color-surface ) );
	border: 1px dashed var( --zc-color-accent-gold );
	border-radius: var( --zc-radius-sm );
	padding: 1rem 1.25rem;
	margin: 1.25rem 0;
}

.zainabcraft-todo-note p {
	margin: 0;
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text );
}

.zainabcraft-todo-note strong {
	color: var( --zc-color-accent-gold );
	text-transform: uppercase;
	letter-spacing: 0.3px;
}

.wp-block-details {
	border-bottom: 1px solid var( --zc-color-border );
	padding: 0.75rem 0;
}

.wp-block-details summary {
	font-family: var( --zc-font-body );
	font-weight: 500;
	color: var( --zc-color-text );
	cursor: pointer;
}

/* FAQ: one level of dropdown, not two. Each category (Ordering, Payment,
   etc.) is still the native <details>/<summary> accordion — collapsed
   until opened, keyboard- and screen-reader-accessible with no JS — but
   its questions are now plain text inside it rather than a second
   nested accordion: once a category is open, all of its answers are
   already visible, no second click needed per question. */
.wp-block-details.zainabcraft-faq-section {
	padding: 1.25rem 0;
}

.wp-block-details.zainabcraft-faq-section > summary {
	font-family: var( --zc-font-heading );
	font-size: var( --wp--preset--font-size--heading-4 );
	font-weight: 600;
}

.zainabcraft-faq-item {
	border-bottom: 1px solid var( --zc-color-border );
	padding: 0.75rem 0;
	margin-left: 1.5rem;
}

.zainabcraft-faq-item:last-child {
	border-bottom: none;
}

/* Questions and answers were inheriting the page's plain-paragraph
   default (the same ~22px used for About Us's and Privacy Policy's own
   flowing prose) — a size tuned for reading paragraphs, not for a
   compact, scannable list where every question and answer sits at that
   size with only font-weight telling them apart from the category
   header above. Sized down to the site's standard UI/body text token
   (the same one inputs and nav use) so the list reads as a list; the
   category summary above keeps its own larger, bolder size so the
   hierarchy (category > question > answer) still reads at a glance. */
.zainabcraft-faq-question {
	font-size: var( --wp--preset--font-size--medium );
	font-weight: 500;
	color: var( --zc-color-text );
	margin: 0 0 0.5rem;
}

.zainabcraft-faq-item p:not( .zainabcraft-faq-question ) {
	font-size: var( --wp--preset--font-size--medium );
}

/* =====================================================================
   Content pages built on the "About Us" alternating-band pattern:
   About Us (page-id-33), Shipping Policy (page-id-23), Return & Refund
   Policy (page-id-11), Privacy Policy (page-id-3), Terms & Conditions
   (page-id-39), FAQ (page-id-35 — the accordion items themselves are
   untouched; only the section headings and band layout follow this
   pattern).
   About's few, widely spaced headings read as narrative pauses, but a
   reference page repeats the same 48px default h2 several times plus a
   dozen-plus 30px h3s down a document people scan for one fact rather
   than read start to end, piling up far more visual weight than About
   ever accumulates. Sized down one step each on every page in this
   list: h2 to heading-3 (matching the h3 sub-headings' old size) and h3
   to heading-4, the same "content-dense page, not a marketing hero"
   adjustment already made for the product page's tabs and the My
   Account pages.
   ===================================================================== */

body.page-id-33 .wp-block-post-content h2,
body.page-id-23 .wp-block-post-content h2,
body.page-id-11 .wp-block-post-content h2,
body.page-id-3 .wp-block-post-content h2,
body.page-id-39 .wp-block-post-content h2,
body.page-id-35 .wp-block-post-content h2,
body.page-id-158 .wp-block-post-content h2 {
	font-size: var( --wp--preset--font-size--heading-3 );
}

body.page-id-33 .wp-block-post-content h3,
body.page-id-23 .wp-block-post-content h3,
body.page-id-11 .wp-block-post-content h3,
body.page-id-3 .wp-block-post-content h3,
body.page-id-39 .wp-block-post-content h3,
body.page-id-35 .wp-block-post-content h3,
body.page-id-158 .wp-block-post-content h3 {
	font-size: var( --wp--preset--font-size--heading-4 );
}

/* Each page's opening heading keeps its own larger, distinct "tagline"
   size (see .zainabcraft-about-tagline) precisely so it still reads as
   the biggest, first thing on the page now that the section headings
   below it are smaller — without this, the h2 rule above would flatten
   it to the same size as every other section title. */
body.page-id-33 .wp-block-post-content h2.zainabcraft-about-tagline,
body.page-id-23 .wp-block-post-content h2.zainabcraft-about-tagline,
body.page-id-11 .wp-block-post-content h2.zainabcraft-about-tagline,
body.page-id-3 .wp-block-post-content h2.zainabcraft-about-tagline,
body.page-id-39 .wp-block-post-content h2.zainabcraft-about-tagline,
body.page-id-35 .wp-block-post-content h2.zainabcraft-about-tagline,
body.page-id-158 .wp-block-post-content h2.zainabcraft-about-tagline {
	font-size: var( --wp--preset--font-size--x-large );
}

/* These pages' own titles: centered on request, unlike the left-aligned
   titles elsewhere on the site (About Us included, which hasn't been
   asked for this and keeps its own left-aligned title). */
body.page-id-23 .wp-block-post-title,
body.page-id-11 .wp-block-post-title,
body.page-id-3 .wp-block-post-title,
body.page-id-39 .wp-block-post-title,
body.page-id-35 .wp-block-post-title {
	text-align: center;
}

/* Custom Order (page-id-117): the generic page template's own
   `wp:post-title` ("Custom Order") duplicated the page's own "Create
   Your Custom Order" heading already in its content — same situation,
   same fix, as the My Account/Login pages' title below. */
body.page-id-117 .wp-block-post-title {
	display: none;
}

/* =====================================================================
   Homepage placeholder elements
   ===================================================================== */

/* aspect-ratio (not a fixed min-height) so this scales proportionally with
   its column's width at every breakpoint. A fixed 320px was measured to
   hold constant while the column narrowed — 2:1 landscape at 1440px, down
   to a near-square 1.37:1 by 1024px purely from the column shrinking
   (before the layout even stacks) — and on mobile, where the hero stacks
   to full page width, that same fixed 320px stayed just as tall as
   desktop despite the column being a third the width, making the hero
   section excessively tall. */
.zainabcraft-placeholder-media {
	aspect-ratio: 16 / 9;
	min-height: 160px;
	border-radius: var( --zc-radius-lg );
	background-color: color-mix( in srgb, var( --zc-color-accent ) 30%, var( --zc-color-surface ) );
	border: 1px dashed var( --zc-color-border );
	color: var( --zc-color-text-muted );
}

/* =====================================================================
   Pagination
   ===================================================================== */

.woocommerce-pagination ul.page-numbers,
.wp-block-query-pagination {
	display: flex;
	gap: 0.4rem;
	list-style: none;
	align-items: center;
}

.woocommerce-pagination .page-numbers li {
	display: inline-flex;
}

.woocommerce-pagination a.page-numbers,
.woocommerce-pagination span.page-numbers,
.wp-block-query-pagination-numbers a,
.wp-block-query-pagination-numbers span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	height: 2.25rem;
	padding: 0 0.5rem;
	border-radius: var( --zc-radius-sm );
	color: var( --zc-color-text );
	font-size: var( --wp--preset--font-size--medium );
	text-decoration: none;
}

.woocommerce-pagination a.page-numbers:hover,
.wp-block-query-pagination-numbers a:hover {
	background-color: var( --zc-color-background );
}

.woocommerce-pagination .page-numbers.current,
.wp-block-query-pagination-numbers span.current {
	background-color: var( --zc-color-primary );
	color: var( --zc-color-surface );
}

/* =====================================================================
   Quantity controls
   ===================================================================== */

.quantity .qty,
.wc-block-components-quantity-selector__input {
	width: 3.5rem;
	text-align: center;
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-sm );
	padding: 0.6rem 0.4rem;
	font-family: var( --zc-font-body );
	color: var( --zc-color-text );
}

.wc-block-components-quantity-selector {
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-sm );
	overflow: hidden;
}

.wc-block-components-quantity-selector__button {
	color: var( --zc-color-text );
}

/* =====================================================================
   Breadcrumbs
   ===================================================================== */

.woocommerce-breadcrumb {
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text-muted );
}

.woocommerce-breadcrumb a {
	color: var( --zc-color-text-muted );
	text-decoration: none;
}

.woocommerce-breadcrumb a:hover {
	color: var( --zc-color-primary );
}

/* =====================================================================
   My account / Login
   ===================================================================== */

/* The generic page template (parent theme's page.html) always renders a
   `wp:post-title` above the page content, which here duplicates the
   "Login"/"Register"/"My account" heading WooCommerce's own account
   templates already render — the checkout page skips this same title
   for the same reason. WooCommerce adds this body class to any page
   whose content includes the [woocommerce_my_account] shortcode (see
   WooCommerce's own is_account_page()), which is also how the
   standalone Register page (zainabcraft-core/includes/my-account.php)
   gets it — not just the canonical My Account page. Scoped to it so
   other pages that want their title (About, Contact, etc.) are
   untouched. */
body.woocommerce-account .wp-block-post-title {
	display: none;
}

/* The Log in button and the "Remember me" checkbox sit in the same row
   as plain inline/block content (WooCommerce ships no flex layout for
   this row), so the checkbox+label — shorter than the button — sits
   slightly below the button's vertical center instead of lining up with
   it. Flexing the row and centering its items aligns them. This row is
   the login form's only direct-child `<p>` without WooCommerce's own
   `.woocommerce-form-row` class (username/password use both classes), so
   `:not()` targets it without touching those. WooCommerce's own
   `.woocommerce-form-login__submit { float: left }` is what puts the
   button before "Remember me" visually despite the button being last in
   the markup — flexing the row drops that float (flex containers ignore
   it), so `order` re-creates the same left-first layout explicitly. */
form.woocommerce-form-login > p.form-row:not( .woocommerce-form-row ) {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 1rem 1.25rem;
}

.woocommerce-form-login__submit {
	order: -1;
}

/* Within "Remember me" itself, the checkbox and its text sit in normal
   inline flow, where a checkbox's default baseline alignment leaves it a
   few pixels above the text's own vertical center. Flexing the label and
   centering its two children (the checkbox input and the text span)
   aligns them to each other regardless of the row-level centering above.
   WooCommerce's own `.woocommerce .woocommerce-form-login
   .woocommerce-form-login__rememberme { display: inline-block }` is more
   specific than the single-class selector this rule started as (which is
   why the fix silently failed to apply the first time); matching that
   same three-class shape, plus the `form` element, outranks it. */
.woocommerce form.woocommerce-form-login .woocommerce-form-login__rememberme {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
}

/* "Lost your password?" has no fontSize of its own either, so — like the
   other default-body-text bugs fixed elsewhere on this site — it renders
   at the fluid ~22px paragraph default, badly out of scale next to the
   13px form labels right above it. Matched to the "small" size already
   used sitewide for this kind of secondary/utility link. */
.woocommerce-LostPassword a {
	font-size: var( --wp--preset--font-size--small );
}

/* =====================================================================
   Tables (cart, checkout review, orders)
   ===================================================================== */

.shop_table,
.woocommerce table.shop_table {
	border-collapse: collapse;
	width: 100%;
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	overflow: hidden;
}

.shop_table th,
.shop_table td {
	padding: 0.9rem 1rem;
	border-bottom: var( --zc-border-width ) solid var( --zc-color-border );
	text-align: left;
}

.shop_table thead th {
	background-color: var( --zc-color-background );
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--label );
	text-transform: uppercase;
	letter-spacing: 0.4px;
	color: var( --zc-color-text-muted );
}

/* =====================================================================
   Header foundation
   ===================================================================== */

header.wp-block-template-part {
	border-bottom: var( --zc-border-width ) solid var( --zc-color-border );
	background-color: var( --zc-color-background );
}

/* Sticky header: `position:sticky` keeps an element pinned only for as
   long as its own parent box is still scrolling through the viewport —
   the logo/nav/search/cart row's parent is the ~125px-tall <header>
   itself, so making just the row sticky let it stick for a moment and
   then scroll away with the rest of the (too-short) header. Making the
   whole <header> sticky instead works throughout the full page scroll
   (its parent is the full-height page body); offsetting it by exactly
   the announcement bar's own height (measured: 40px, from its fixed
   10px/10px padding and fixed label-size line height — not fluid at
   either breakpoint) then lands the bar just above the viewport and
   the row exactly at the top the moment scrolling begins, matching the
   "bar scrolls away, row stays" behavior with no JavaScript. Desktop/
   tablet only — the mobile hamburger row doesn't need this. */
@media ( min-width: 768px ) {
	header.wp-block-template-part {
		position: sticky;
		top: -40px;
		z-index: 100;
	}
}

/* The checkout page's own minimal header (logo + cart only, no nav) has no
   announcement bar above it — that -40px offset above was measured against
   the announcement bar's height specifically so the bar scrolls away first
   and the row lands flush at the top; without a bar to absorb it here, the
   same offset instead scrolled the checkout header 40px past the top edge,
   permanently clipping the top of the logo once sticky engaged. top:0 keeps
   it sticky (still useful during a long address form) without a bar to
   account for. */
header.wp-block-template-part.zainabcraft-checkout-header {
	top: 0;
}

.wp-block-site-logo img {
	border-radius: var( --zc-radius-sm );
}

.zainabcraft-wordmark {
	margin: 0;
}

.zainabcraft-wordmark img {
	height: auto;
	display: block;
}

.wp-block-navigation a.wp-block-navigation-item__content {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--nav );
	color: var( --zc-color-text );
}

.wp-block-navigation a.wp-block-navigation-item__content:hover {
	color: var( --zc-color-primary );
}

/* Mobile navigation overlay (built into core/navigation, no custom JS needed) */
.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var( --zc-color-background );
}

.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	color: var( --zc-color-text );
}

.wc-block-mini-cart__button {
	color: var( --zc-color-text );
}

.wc-block-mini-cart__badge {
	background-color: var( --zc-color-sale );
	color: var( --zc-color-surface );
}

/* Account (user) icon — sits directly beside the Mini Cart in the header's
   actions group; matched to the cart icon's color/hover so the two read as
   one paired control. */
.zainabcraft-header-actions .wc-block-customer-account__link {
	color: var( --zc-color-text );
}

.zainabcraft-header-actions .wc-block-customer-account__link:hover {
	color: var( --zc-color-primary );
}

/* =====================================================================
   Footer foundation
   ===================================================================== */

footer.wp-block-template-part {
	background-color: var( --zc-color-background );
	border-top: var( --zc-border-width ) solid var( --zc-color-border );
}

footer.wp-block-template-part a {
	color: var( --zc-color-text-muted );
	text-decoration: none;
}

footer.wp-block-template-part a:hover {
	color: var( --zc-color-primary );
}

/* Below 900px the 4 footer columns (Brand, Shop, Policies, Newsletter)
   don't divide evenly under flex-wrap with justify-content:space-between —
   exactly which columns share a line depends on each column's own content
   width, so the wrap pattern is inconsistent from one width to the next
   (e.g. Shop+Policies pair up around 375px, but Brand+Shop pair up instead
   around 414px, leaving Policies stranded alone). A fixed grid removes that
   guesswork: 2 columns down to 480px (Brand+Shop, Policies+Newsletter, same
   pairing every time), then a single column below that, where two columns
   would squeeze the email input and its button too narrow to stay usable. */
@media ( min-width: 480px ) and ( max-width: 900px ) {
	/* WordPress's own generated layout rule `body .is-layout-flex { display:
	   flex }` (1 element + 1 class) otherwise beats a single-class override;
	   matching .is-layout-flex here (already present on this element)
	   raises this to 2 classes so the grid override actually applies. */
	.zainabcraft-footer-columns.is-layout-flex {
		display: grid;
		grid-template-columns: repeat( 2, 1fr );
		gap: var( --wp--preset--spacing--50 ) 2rem;
	}
}

@media ( max-width: 479px ) {
	.zainabcraft-footer-columns.is-layout-flex {
		display: grid;
		grid-template-columns: 1fr;
		gap: var( --wp--preset--spacing--40 );
	}
}

/* "Why Choose ZainabCraft": core Columns' own default behavior collapses
   all 4 columns to full width, stacked one per row, below 782px — sensible
   for columns holding substantial content, but these are short (an icon,
   a heading, one line) and stacking all 4 turns a compact section into
   roughly 800px of scrolling at tablet width for no layout benefit. A 2x2
   grid keeps it scannable at a glance at both tablet and mobile sizes;
   unlike the footer above, one tier covers the whole range since each
   item's content is short enough to stay comfortable even at the
   narrowest widths tested (375px). */
@media ( max-width: 781px ) {
	.zainabcraft-features-grid.is-layout-flex {
		display: grid;
		grid-template-columns: repeat( 2, 1fr );
		gap: var( --wp--preset--spacing--50 ) 1.5rem;
	}

	/* At the default heading-3 size, "Thoughtfully" alone is wider than a
	   ~150px column, and the theme's global overflow-wrap:break-word then
	   splits it mid-word ("Thoughtfull/y") rather than wrapping cleanly.
	   Dropping to the next size down gives it enough room to wrap at the
	   word boundary instead. */
	.zainabcraft-features-grid h3 {
		font-size: var( --wp--preset--font-size--large );
	}
}

/* =====================================================================
   Responsive container padding
   Fluid clamp() already scales most spacing continuously; this adjusts
   the outer container gutter at the requested breakpoints.
   ===================================================================== */

.wp-block-group.alignwide,
.wp-block-group.alignfull > .wp-block-group {
	padding-left: var( --zc-container-padding );
	padding-right: var( --zc-container-padding );
}

@media ( max-width: 480px ) {
	:root {
		--zc-container-padding: 1rem;
	}
}

@media ( min-width: 768px ) {
	:root {
		--zc-container-padding: 1.5rem;
	}
}

@media ( min-width: 1024px ) {
	:root {
		--zc-container-padding: 2rem;
	}
}

/* =====================================================================
   Mobile UX audit fixes (320–414px)
   Each rule below addresses a specific issue found by reading the
   actual compiled CSS of the block involved, not guesswork.
   ===================================================================== */

@media ( max-width: 480px ) {
	/* Header: the logo/title, nav, and account+cart groups were set to
	   flex-wrap:nowrap so they render in one row. That plus the nav
	   toggle don't fit in 320–414px without wrapping, which forces the
	   whole page to scroll horizontally. Letting the row wrap keeps
	   every control reachable and tappable instead. */
	header.wp-block-template-part .is-nowrap {
		flex-wrap: wrap !important;
		row-gap: 0.5rem;
	}

	/* Add to Cart / Buy Now: WooCommerce's own add-to-cart-form CSS lays
	   quantity + button(s) out with `grid-auto-flow: column` and no
	   mobile override of its own. With both an Add to Cart and a Buy Now
	   button that's three items forced into one row, which overflows at
	   this width. Stacking them is also easier to tap accurately. */
	.wp-block-woocommerce-add-to-cart-form form.cart,
	.wp-block-woocommerce-add-to-cart-form .variations_button {
		grid-auto-flow: row !important;
		grid-template-columns: 1fr !important;
		gap: 0.6rem;
	}

	/* The rule above only redefines the grid's own explicit columns.
	   WooCommerce also places the purchase button itself in an explicit
	   `grid-column: 2 / 3` (its inline block-support style, not part of
	   any file here) so it sits beside the quantity field — with only
	   one column now defined, that request still creates a 2nd implicit
	   column instead of collapsing, keeping "Add to cart"/"Buy Now"
	   narrow and side-by-side. `grid-column: 1 / -1` (the same span
	   WooCommerce's own inline style already uses for every other child
	   here) lets the button take the full single column, so the
	   `width: 100%` below actually means the row's full width. Repeating
	   WooCommerce's exact selector keeps this at the same specificity;
	   this stylesheet loads after that inline style, so no !important
	   is needed to win the tie. */
	.wp-block-woocommerce-add-to-cart-form .variations_button > .single_add_to_cart_button,
	.wp-block-woocommerce-add-to-cart-form form.cart > .single_add_to_cart_button {
		grid-column: 1 / -1;
		justify-self: stretch;
	}

	.wp-block-woocommerce-add-to-cart-form .quantity {
		margin-right: 0 !important;
	}

	.single_add_to_cart_button,
	.zainabcraft-buy-now-button {
		width: 100%;
		margin-left: 0 !important;
	}

	/* Variation dropdowns: a 180px minimum on a ~280px-wide content
	   column leaves very little breathing room. Let them fill the row
	   instead of holding a fixed minimum. */
	.variations select {
		min-width: 0;
		width: 100%;
	}

	.variations td.value {
		width: 100%;
	}

	/* Pagination links: 36px squares are under the ~44px minimum
	   comfortable tap target size. */
	.woocommerce-pagination a.page-numbers,
	.woocommerce-pagination span.page-numbers,
	.wp-block-query-pagination-numbers a,
	.wp-block-query-pagination-numbers span {
		min-width: 2.75rem;
		height: 2.75rem;
	}

	/* Classic WooCommerce tables (cart totals on the order-received page,
	   account order history) have more columns than fit at this width.
	   Scrolling the table itself, rather than the whole page, keeps the
	   overflow contained instead of breaking the page layout. */
	.shop_table {
		display: block;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* Form inputs: theme.json's fluid "medium" size should already
	   resolve to 16px at these widths, but pin it explicitly for form
	   fields too — iOS Safari auto-zooms on focusing any input under
	   16px, which is a worse experience than a fixed, predictable size. */
	input.input-text,
	textarea,
	select,
	.wc-block-components-text-input input {
		font-size: 16px;
	}

	/* Header hamburger: a 24x24px button is under the ~44px comfortable
	   tap target. The icon itself is a fixed-size (24x24) SVG, so padding
	   grows only the clickable box around it, not the visible icon. */
	.wp-block-navigation__responsive-container-open {
		padding: 10px;
	}

	/* Footer navigation links: each link is its own block-level element
	   at ~24px tall. A little vertical padding raises the tappable
	   height to a more comfortable size without touching the gap the
	   list itself already uses between links. */
	footer.wp-block-template-part .wp-block-navigation-item__content {
		padding-block: 0.5rem;
	}

	/* Cart quantity +/- buttons: WooCommerce's own rule — scoped as
	   `.wc-block-components-quantity-selector .wc-block-components-quantity-selector__button`
	   (2 classes) — sets min-width:30px. Repeating that same selector
	   here ties its specificity (this stylesheet loads after
	   WooCommerce's, so the tie resolves in our favor by source order,
	   no !important needed) rather than the single-class selector below,
	   which a 2-class rule would otherwise keep beating. The stepper is
	   a flex row with default (stretch) alignment, so growing the
	   buttons' min-height also stretches the quantity field to match,
	   keeping the whole control visually balanced. */
	.wc-block-components-quantity-selector .wc-block-components-quantity-selector__button {
		min-width: 44px;
		min-height: 44px;
	}

	/* WooCommerce also hardcodes the stepper's own outer width at 107px
	   (sized for its default 30px buttons) with `overflow:hidden`, which
	   would otherwise clip the enlarged "+" button above. Growing it by
	   exactly the same amount the two buttons grew (44px - 30px, twice)
	   keeps the quantity field at its original width instead of letting
	   it expand to fill newly-freed flex space, which was overflowing
	   the cart table past the viewport. */
	.wc-block-components-quantity-selector {
		width: calc( 107px + 2 * ( 44px - 30px ) );
	}
}

/* The Shop archive's product grid drops to a single column only below
   ~383px — a content-driven flex-wrap point, not a round breakpoint
   (measured directly: 2 columns at 384px, 1 column at 382px and below).
   The title min-height and the no-rating price margin above exist purely
   so every card in the SAME row lines its button up with its neighbours —
   with only one card per row there are no neighbours to line up with, so
   that reserved space is just dead space with no purpose, on the one
   viewport where every pixel of vertical scrolling matters most. 382px
   (not a rounder number like 479px) is used deliberately here to stay
   safely under the confirmed 384px 2-column point — many real phones
   (390, 393, 412, 414, 428px) are already 2-column and still need the
   reserved space for their buttons to align. */
@media ( max-width: 382px ) {
	.zainabcraft-product-card .wp-block-post-title {
		min-height: 0;
	}

	.zainabcraft-product-card:not( :has( .wc-block-components-product-rating ) ) .wc-block-components-product-price {
		margin-bottom: 0;
	}
}

/* Featured-category thumbnails vary in source aspect ratio; cropping
   them to a consistent square keeps the mobile 2-column grid even
   instead of a ragged, uneven layout. */
.wc-block-product-categories-list-item__image {
	aspect-ratio: 1;
}

.wc-block-product-categories-list-item__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* =====================================================================
   About Us page
   ===================================================================== */

/* The page title itself ("About Us", "Contact Us") comes from the parent
   theme's generic page.html template (wp:post-title, no child-theme
   override) and defaults to left-aligned; centering it just for these
   pages is scoped through the page-id body class WordPress already adds,
   rather than duplicating the whole template for one heading. */
.page-id-33 .wp-block-post-title,
.page-id-32 .wp-block-post-title {
	text-align: center;
}

/* The page's own tagline, directly under the post-title "About Us" h1 —
   sized between the h1 and a body heading so it reads as a subtitle
   rather than a second, competing top-level heading. */
.zainabcraft-about-tagline {
	font-size: var( --wp--preset--font-size--x-large );
	margin-bottom: 0;
}

/* Recurring emphasized one-liners throughout the page's copy (e.g. "No two
   handmade pieces need to be exactly the same to be beautiful."). Kept
   visually distinct from a regular paragraph — larger, on-brand accent
   color, generous line-height — without the weight of a full heading, so
   these read as a considered pause in the copy rather than a new section. */
.zainabcraft-pullquote {
	font-family: var( --zc-font-heading );
	font-size: var( --wp--preset--font-size--x-large );
	font-weight: 600;
	line-height: 1.4;
	color: var( --zc-color-primary );
	max-width: 560px;
	margin: var( --wp--preset--spacing--40 ) auto;
}

/* "What We Believe" value cards: flex-wrap + justify-content:center
   (rather than a fixed column-count grid) so 5 cards — a count that
   doesn't divide evenly into 2 or 3 columns — reflow naturally at any
   width and a shorter last row centers itself instead of trailing off
   ragged-left, the same lonely-last-item look already fixed elsewhere on
   this site for the homepage's product grids. */
.zainabcraft-value-grid {
	margin-top: var( --wp--preset--spacing--40 );
	gap: 1.5rem;
	/* The block editor's flex layout defaults unset verticalAlignment to
	   align-items:center, so cards in the same row sit at their own natural
	   height instead of matching their tallest neighbour — stretch gives
	   every card in a row a level top and bottom edge, the same equal-card
	   treatment already used for product cards elsewhere on the site. */
	align-items: stretch;
}

.zainabcraft-value-card {
	flex: 1 1 260px;
	max-width: 320px;
	background-color: var( --zc-color-surface );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-md );
	padding: 1.75rem 1.5rem;
}

.zainabcraft-value-card h3 {
	font-size: var( --wp--preset--font-size--heading-4 );
	margin: 0 0 0.5rem;
}

.zainabcraft-value-card p {
	margin: 0;
}

/* Collection list: a plain bulleted <ul> reads as a generic document list;
   a small accent-colored dot marker (instead of the browser's default
   disc) matches the site's warm, handmade visual language. Now that this
   list runs the section's full wide width rather than a narrow column, 2
   columns would leave each item's short text stranded in a much wider
   track than it needs; 3 columns puts that width to use while keeping
   every item comfortably short. */
.zainabcraft-collection-list {
	display: grid;
	grid-template-columns: repeat( 2, 1fr );
	gap: 0.75rem 2rem;
	list-style: none;
	margin: var( --wp--preset--spacing--30 ) 0 var( --wp--preset--spacing--40 );
	padding: 0;
}

@media ( min-width: 900px ) {
	.zainabcraft-collection-list {
		grid-template-columns: repeat( 3, 1fr );
	}
}

.zainabcraft-collection-list li {
	position: relative;
	padding-left: 1.25rem;
	color: var( --zc-color-text );
}

.zainabcraft-collection-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background-color: var( --zc-color-accent );
}

@media ( max-width: 600px ) {
	.zainabcraft-collection-list {
		grid-template-columns: 1fr;
	}
}

/* =====================================================================
   Contact form ([zainabcraft_contact_form], zainabcraft-core plugin)
   ===================================================================== */

/* No max-width of its own: this shortcode's markup isn't clipped by the
   page's own content-width constraint (only WordPress's own blocks get
   that automatically), so a max-width here wider than the page's actual
   645px content column — 720px was measured actually happening — made the
   form visibly bleed past the edges of the intro text and "Other Ways to
   Reach Us" section around it. Filling 100% of its parent matches that
   column exactly at every width instead of guessing a fixed number. */
.zainabcraft-contact-form {
	width: 100%;
}

/* "Other Ways to Reach Us": a real business email or a long typed-out
   response-time string has no spaces for the browser's normal wrapping to
   break on, so at narrow widths it was measured overflowing the page
   horizontally (769px of scrollable width inside a 375px viewport)
   instead of wrapping. overflow-wrap lets the browser break a single
   too-long token as a last resort, only when it would otherwise overflow —
   normal space-based wrapping is still preferred everywhere it applies. */
.zainabcraft-contact-other-ways {
	overflow-wrap: break-word;
}

/* Honeypot field: kept in the tab order's reach for screen readers is
   unnecessary here (tabindex="-1" already skips it and aria-hidden hides
   it from assistive tech), so it's fine to just push it off-screen —
   display:none is avoided only because some bots skip hidden fields, not
   because of any accessibility need of its own. */
.zainabcraft-contact-form__honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.zainabcraft-contact-form__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1.25rem;
}

.zainabcraft-contact-form__field {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin-bottom: 1.25rem;
}

.zainabcraft-contact-form__field label {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text );
	font-weight: 500;
}

.zainabcraft-contact-form__required {
	color: var( --zc-color-error );
}

.zainabcraft-contact-form__field textarea {
	resize: vertical;
	min-height: 9rem;
}

.zainabcraft-contact-form__actions {
	margin-top: 0.5rem;
}

.zainabcraft-contact-form__actions .wp-element-button {
	cursor: pointer;
	border: none;
}

.zainabcraft-contact-form__notice {
	margin-top: 1.5rem;
	margin-bottom: 0;
}

@media ( max-width: 600px ) {
	.zainabcraft-contact-form__row {
		grid-template-columns: 1fr;
	}
}

/* =====================================================================
   Custom Order form ([zainabcraft_custom_order_form], zainabcraft-core
   plugin) — deliberately mirrors .zainabcraft-contact-form above almost
   field-for-field, so it reads as the same form system rather than a
   one-off. Inputs/selects/textareas/checkboxes need no rules of their
   own here: they already inherit the sitewide `.woocommerce form`
   styling (border, radius, focus ring) defined earlier in this file.
   ===================================================================== */

.zainabcraft-custom-order-form {
	width: 100%;
}

.zainabcraft-custom-order-form__section {
	font-family: var( --zc-font-heading );
	font-size: var( --wp--preset--font-size--heading-4 );
	margin: 2rem 0 1rem;
}

.zainabcraft-custom-order-form__section:first-of-type {
	margin-top: 0.5rem;
}

.zainabcraft-custom-order-form__honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.zainabcraft-custom-order-form__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1.25rem;
}

.zainabcraft-custom-order-form__field {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin-bottom: 1.25rem;
}

/* The "Other Color" field is toggled via the plain `hidden` attribute
   (both from PHP on first render and from custom-order-form.js after),
   which normally sets display:none via the browser's own stylesheet —
   but that's user-agent-origin, so the `display: flex` above (an author
   rule, always outranks user-agent origin regardless of specificity)
   was winning and keeping it visible even while hidden. Restating
   display:none for `[hidden]` here, in this same author stylesheet,
   fixes it. */
.zainabcraft-custom-order-form__field[hidden] {
	display: none;
}

.zainabcraft-custom-order-form__field label {
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--label );
	color: var( --zc-color-text );
	font-weight: 500;
}

.zainabcraft-custom-order-form__required {
	color: var( --zc-color-error );
}

.zainabcraft-custom-order-form__field textarea {
	resize: vertical;
	min-height: 7rem;
}

.zainabcraft-custom-order-form__field--quantity input {
	max-width: 120px;
}

.zainabcraft-custom-order-form__hint {
	font-size: var( --wp--preset--font-size--small );
	color: var( --zc-color-text-muted );
}

.zainabcraft-custom-order-form__preview {
	margin-top: 0.5rem;
	max-width: 160px;
	max-height: 160px;
	border-radius: var( --zc-radius-sm );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	object-fit: cover;
}

/* Preferred Color: a native <input type="color"> (no plugin, no palette)
   plus a readout that mirrors its value as text — the control itself has
   no unstyled state to fall back on across browsers, so it gets its own
   scoped sizing/border here rather than inheriting the sitewide
   `.input-text` rules, which target text-like inputs only. */
.zainabcraft-custom-order-form__color-control {
	display: flex;
	align-items: center;
	gap: 0.9rem;
	flex-wrap: wrap;
}

.zainabcraft-custom-order-form input[type="color"] {
	width: 3.25rem;
	height: 3.25rem;
	padding: 0.2rem;
	border: var( --zc-border-width ) solid var( --zc-color-border );
	border-radius: var( --zc-radius-sm );
	background-color: var( --zc-color-surface );
	cursor: pointer;
}

.zainabcraft-custom-order-form input[type="color"]:focus {
	border-color: var( --zc-color-focus );
	outline: none;
	box-shadow: 0 0 0 1px var( --zc-color-focus );
}

.zainabcraft-custom-order-form input[type="color"]::-webkit-color-swatch-wrapper {
	padding: 0;
}

.zainabcraft-custom-order-form input[type="color"]::-webkit-color-swatch {
	border: none;
	border-radius: calc( var( --zc-radius-sm ) - 2px );
}

.zainabcraft-custom-order-form input[type="color"]::-moz-color-swatch {
	border: none;
	border-radius: calc( var( --zc-radius-sm ) - 2px );
}

.zainabcraft-custom-order-form__color-readout {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	font-family: var( --zc-font-body );
	font-size: var( --wp--preset--font-size--medium );
	color: var( --zc-color-text );
}

.zainabcraft-custom-order-form__color-swatch {
	display: inline-block;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: var( --zc-radius-sm );
	border: var( --zc-border-width ) solid var( --zc-color-border );
	background-color: var( --zc-color-surface );
	flex-shrink: 0;
}

.zainabcraft-custom-order-form__color-swatch[data-empty="1"] {
	background-image: linear-gradient( 45deg, var( --zc-color-border ) 25%, transparent 25%, transparent 50%, var( --zc-color-border ) 50%, var( --zc-color-border ) 75%, transparent 75%, transparent );
	background-size: 8px 8px;
}

.zainabcraft-custom-order-form__color-note {
	margin-top: 0.6rem;
	margin-bottom: 0;
}

.zainabcraft-custom-order-form__field--consent label {
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	font-weight: 400;
}

.zainabcraft-custom-order-form__field--consent input[type="checkbox"] {
	margin-top: 0.2rem;
	flex-shrink: 0;
}

.zainabcraft-custom-order-form__actions {
	margin-top: 0.5rem;
}

.zainabcraft-custom-order-form__actions .wp-element-button {
	cursor: pointer;
	border: none;
}

.zainabcraft-custom-order-form__notice {
	margin-bottom: 1.5rem;
}

@media ( max-width: 600px ) {
	.zainabcraft-custom-order-form__row {
		grid-template-columns: 1fr;
	}
}

/* =====================================================================
   Size & Measurement Guide page (zainabcraft-core/includes/size-guide.php)
   ===================================================================== */

.zainabcraft-size-guide__section + .zainabcraft-size-guide__section {
	border-top: var( --zc-border-width ) solid var( --zc-color-border );
}

.zainabcraft-size-guide__diagram {
	display: block;
	width: 100%;
	max-width: 200px;
	height: auto;
	margin: 0 auto;
	color: var( --zc-color-primary );
}

.zainabcraft-size-guide__callout {
	margin: 1.5rem 0;
}

.zainabcraft-size-guide__note {
	font-size: var( --wp--preset--font-size--small );
	color: var( --zc-color-text-muted );
}

.zainabcraft-size-guide__table {
	max-width: 320px;
}

.zainabcraft-size-guide__table th,
.zainabcraft-size-guide__table td {
	border: var( --zc-border-width ) solid var( --zc-color-border );
	padding: 0.6rem 1rem;
	font-size: var( --wp--preset--font-size--medium );
	text-align: left;
}

.zainabcraft-size-guide__table th {
	background-color: var( --zc-color-background );
	font-weight: 600;
}

/* Product page: "Not sure about your size?" link (size-guide.php), placed
   right after the existing "Choose Size" selector. Reuses
   .zainabcraft-size-selector__note (product-size-selector.php) as-is, so
   no separate rule is needed here — this comment documents why that class
   appears in a file it isn't defined in. */

/* =====================================================================
   Smooth scrolling + scroll-reveal animation system
   (assets/js/scroll-reveal.js)

   Progressive enhancement throughout: `.zainabcraft-anim` /
   `.zainabcraft-anim-stagger` are the only classes ever written into
   template markup, and neither carries any visual style of its own — a
   page that never runs the JS (disabled, blocked, still loading) shows
   every marked element exactly as authored, fully visible, immediately.
   The JS is solely responsible for promoting a marked element to
   `.zainabcraft-reveal` (which *does* carry the hidden initial state)
   right before observing it, so "hidden" and "will eventually be shown
   again" only ever exist together.
   ===================================================================== */

html {
	scroll-behavior: smooth;
}

/* Anchor targets (e.g. the "Explore New Arrivals" hero button, the Size
   Guide's #bangles / #hair-catches sections) would otherwise land flush
   under the sticky header on desktop/tablet (measured: ~102px visible
   once the announcement bar has scrolled off — see the sticky header
   rule itself further up this file). A small unconditional offset also
   applies on mobile, where the header isn't sticky, purely for breathing
   room above the heading. */
[id] {
	scroll-margin-top: 24px;
}

@media ( min-width: 768px ) {
	[id] {
		scroll-margin-top: 110px;
	}
}

.zainabcraft-reveal {
	opacity: 0;
	transform: translateY( 24px );
	transition: opacity 0.7s cubic-bezier( 0.22, 1, 0.36, 1 ),
		transform 0.7s cubic-bezier( 0.22, 1, 0.36, 1 );
	will-change: opacity, transform;
}

.zainabcraft-reveal.is-visible {
	opacity: 1;
	transform: translateY( 0 );
}

/* Editorial/hero images: a slightly-scaled fade rather than an upward
   slide — subtler, and avoids competing with a large image's own visual
   weight. */
.zainabcraft-reveal--image {
	transform: scale( 0.98 );
}

.zainabcraft-reveal--image.is-visible {
	transform: scale( 1 );
}

/* Small, hand-placed delay steps for a handful of elements that need to
   lag slightly behind a sibling (e.g. the hero's buttons appearing just
   after its heading/text) — harmless on an element that never gets
   promoted to .zainabcraft-reveal, since transition-delay alone has no
   visible effect without an actual transition running. */
.zainabcraft-reveal-delay-1 {
	transition-delay: 120ms;
}

.zainabcraft-reveal-delay-2 {
	transition-delay: 240ms;
}

@media ( prefers-reduced-motion: reduce ) {
	html {
		scroll-behavior: auto;
	}

	.zainabcraft-reveal {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
		will-change: auto;
	}
}
