/*
Theme Name: Bella Beauty (Woodmart Child)
Theme URI: https://bellabeautybh.com/
Description: Child theme of Woodmart for Bella Beauty. All custom CSS/PHP lives here: the parent theme is never edited.
Author: Bella Beauty
Template: woodmart
Version: 1.0.0
Text domain: woodmart-child
License: GNU General Public License version 3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/

/* ---------------------------------------------------------------------------
   Typography: CAIRO for everything (owner, 2026-08-14).

   Previously the stack led with Montserrat and let Arabic fall back per character
   to Cairo. That is a real technique, but on this site it split every mixed line
   between two typefaces: «6.000 د.ب» drew the digits in Montserrat and the letters
   in Cairo, and prices, phone numbers and percentages appear on nearly every
   screen. The two faces have different proportions, so the result read as a
   mistake rather than a pairing.

   Cairo carries a full Latin set, so one family now covers both scripts and every
   line is internally consistent. Montserrat is no longer requested at all: one
   less font file on first paint.

   Both `--bb-font-latin` and `--bb-font-arabic` are kept and both point at Cairo:
   nothing in the stylesheet references them today, but leaving the names in place
   means a future per-script decision has somewhere to live.
   --------------------------------------------------------------------------- */
:root {
  --bb-font-latin: "Cairo";
  --bb-font-arabic: "Cairo";
  --bb-font-stack: "Cairo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* -------------------------------------------------------------------------
     DESIGN STANDARD: the single source for type and section rhythm.
     Every new section, block or page uses these; nothing hard-codes a px value
     that one of these already covers. Full rationale and the measured audit
     behind them: Docs/design-standard.md.

     Desktop values here; the two overrides below restate ONLY what changes at
     each breakpoint, so a token is never defined in a media query alone.
     ------------------------------------------------------------------------- */
  --bb-fs-hero-title: 44px;
  --bb-fs-hero-body: 17px;
  --bb-fs-hero-eyebrow: 14px;
  --bb-fs-section-title: 24px;   /* every «الأكثر مبيعاً»-class section heading */
  /* Item title = the heading that names ONE item in a row. The product card and
     the category tile already get theirs from theme options, so this token is for
     NEW sections that introduce their own item rows. */
  --bb-fs-item-title: 15px;
  --bb-fs-body: 15px;
  --bb-fs-small: 14px;           /* section links, nav, CTA labels */
  --bb-fs-micro: 11px;           /* card feature words */

  /* Section rhythm: gap between one section's last VISIBLE element and the next
     section. Measure it that way: a carousel container's box ends above its
     visible content, so box-to-box readings lie. */
  --bb-gap-section: 40px;

  /* Product media frame. Every product photo is shown in this ratio, cropped to
     fill. The catalogue's own images run 0.666 to 1.5 (56 measured), so without a
     fixed frame the gallery jumped between 240px and 1066px tall from slide to
     slide. 1:1 is the catalogue's median AND most common ratio (19 of 56) and is
     the shape the shop cards already use. Owner decision 2026-08-12:
     Docs/design-standard.md §5. */
  --bb-ratio-product-media: 1 / 1;

  /* Band grey: Docs/design-standard.md §4. One definition, used by the home
     page's categories strip and the product page's section bands. */
  --bb-color-band: #f4f4f4;
}

@media (max-width: 1024px) {
  :root {
    --bb-fs-hero-title: 32px;
    --bb-fs-hero-body: 16px;
    --bb-fs-hero-eyebrow: 13px;
    --bb-fs-section-title: 22px;
    --bb-fs-item-title: 14px;
    --bb-gap-section: 24px;
  }
}

@media (max-width: 768.98px) {
  :root {
    --bb-fs-hero-title: 26px;
    --bb-fs-hero-body: 15px;
    --bb-fs-hero-eyebrow: 12px;
    --bb-fs-section-title: 20px;
    --bb-fs-item-title: 13px;
    --bb-gap-section: 16px;
  }
}

/* ---------------------------------------------------------------------------
   Header language switcher
   TranslatePress renders its own markup, which sat 150x62 at y14 next to the
   theme's 40x40 tools at y25: bigger and misaligned. Short names are set in the
   plugin itself (short-names, which also renders no flag), so this only matches
   the theme's tool styling so it reads as one of the group. Logical properties
   throughout, so it mirrors on the English side.
   --------------------------------------------------------------------------- */
.bb-lang-switcher {
  display: flex;
  align-items: center;
}

/* Only the CURRENT item is sized to match the tools. The switcher container and
   the dropdown list must stay unconstrained: an earlier version set height:40px
   on the container and on every .trp-language-item, which clipped the open
   dropdown so the second language could never be seen or clicked. */
.bb-lang-switcher .trp-shortcode-switcher__wrapper,
.bb-lang-switcher .trp-language-switcher {
  width: auto;
  min-width: 0;
  padding: 0;
  margin: 0;
}

.bb-lang-switcher .trp-current-language-item__wrapper {
  height: 40px;
  display: flex;
  align-items: center;
}

.bb-lang-switcher .trp-language-item {
  padding-block: 6px;
  padding-inline: 8px;
  display: flex;
  align-items: center;
  gap: 5px;
  border: 0;
  background: none;
}

.bb-lang-switcher .trp-current-language-item__wrapper .trp-language-item {
  padding-block: 0;
  height: 40px;
}

/* Match the neighbouring tools: same size, same weight. */
.bb-lang-switcher .trp-language-item-name {
  font-size: var(--wd-header-el-font-size, 13px);
  font-weight: var(--wd-header-el-font-weight, 600);
  text-transform: uppercase;
  line-height: 1;
  color: inherit;
}

/* The theme's generated settings stylesheet emits every font variable as
   `"Montserrat", "Cairo", Arial, Helvetica, sans-serif`: Montserrat is its own
   default and the typography options are unset (§6i), so nothing we do in the
   dashboard changes it. Overriding the VARIABLES here catches every rule the
   theme writes against them, with no per-selector CSS.

   `:root:root` is (0,2,0) so it beats the theme's own `:root` block, which is
   printed inline AFTER this stylesheet.

   THE LIST MUST BE COMPLETE. Measured on staging 2026-08-14: `--wd-title-font`
   was missing from it, so every `h2` still resolved to
   `Montserrat, Cairo, Arial…`. With Montserrat no longer downloaded, Latin
   characters and digits inside headings fell through to ARIAL while the body ran
   in Cairo: a worse split than the one the Cairo switch was meant to fix. If the
   theme ever adds another `--wd-*-font`, it belongs here too. */
:root:root,
html:root .wd-popup,
html:root .mfp-wrap {
  --wd-text-font: var(--bb-font-stack);
  --wd-title-font: var(--bb-font-stack);
  --wd-primary-font: var(--bb-font-stack);
  --wd-secondary-font: var(--bb-font-stack);
  --wd-alternative-font: var(--bb-font-stack);
  --wd-widget-title-font: var(--bb-font-stack);
  --wd-entities-title-font: var(--bb-font-stack);
  --wd-header-el-font: var(--bb-font-stack);
  --wd-nav-font: var(--bb-font-stack);
}

/* ---------------------------------------------------------------------------
   Mobile menu submenu arrows in RTL
   The chevron is an icon-font glyph (mod-nav-opener.css: .wd-nav-opener::after,
   font-family: woodmart-font) that always points right. Its POSITION already
   mirrors correctly under RTL (opener x0, link x50), so only the glyph itself
   needs flipping. The expanded state rotates 90deg to point down, which reads
   the same in both directions, so it is left alone.
   --------------------------------------------------------------------------- */
[dir="rtl"] .mobile-nav .wd-nav-opener::after {
  transform: scaleX(-1);
}

[dir="rtl"] .mobile-nav .wd-nav-opener.wd-active::after {
  transform: rotate(90deg);
}

/* ---------------------------------------------------------------------------
   Front page: hero sits flush under the header.

   `.wd-content-layout { padding-block: 40px }` (style.css:5758) is the theme's
   global page gutter, applied to every page. The front page opens with a
   full-bleed stretched slider, so that 40px reads as a white band between the
   header and the hero.

   This mirrors the theme's OWN idiom for flush content:
   `.wd-header-overlap:where(:not(.single-product)) .wd-content-layout:first-child
   { padding-top: 0 }` (style.css:4176): but scoped to the front page instead of
   borrowing the overlap class, which would also pull the header on top of the
   hero. Bottom padding is untouched, and no other page is affected.
   --------------------------------------------------------------------------- */
.home .wd-content-layout:first-child {
  padding-top: 0;
}

/* ---------------------------------------------------------------------------
   Full-bleed hero: cancel the container gutter.

   `.wd-slider[class*="wd-section-stretch"]` sets
   `--wd-width: calc(100vw - var(--wd-scroll-w) - ...)` (style.css:9206), i.e. the
   full viewport width. The margin that pulls it back over the container's 15px
   side padding lives on `.wd-slider.wd-section-stretch-content`
   (style.css:9209): a class the theme only adds on the WPBakery path. On
   Gutenberg the width lands with no offset, so measured at 1440 the hero ran
   -15 -> 1410 inside a 1425 viewport: 15px of bare page down the right edge.

   Same declaration the theme uses, applied to the Gutenberg case only. Logical
   margins, so it holds in both RTL and LTR.
   --------------------------------------------------------------------------- */
.wd-slider.wd-section-stretch:not(.wd-section-stretch-content) {
  /* The theme sets width to the full viewport via --wd-width; `auto` margins
     centre that over the container whatever the container width is. A fixed
     -15px was tied to the old full-width container and left the hero 52px off
     centre once the container became 1320. */
  /* Centre the full-viewport width over whatever the container width is:
     (container - viewport) / 2 is the negative pull needed on each side.
     `auto` does not centre here, so it is stated explicitly. */
  margin-inline: calc((100% - var(--wd-width, 100vw)) / 2);
}

/* ---------------------------------------------------------------------------
   Hero slide typography and layout.

   The slide copy previously carried class names that matched no rule anywhere,
   so it rendered as raw body text at one size on every viewport. These are the
   sizes agreed for the responsive scale. Breakpoints follow the theme's own:
   1024px (tablet) and 768.98px (mobile).
   --------------------------------------------------------------------------- */
/* The copy must sit on the image's clean half: the INLINE START (right in RTL,
   left in LTR). `margin-inline-start: auto` would push the box to the inline END,
   i.e. over the product. The auto goes on the END side. */
.wd-slide-inner {
  max-width: 500px;
  margin-inline-start: 0;
  margin-inline-end: auto;
  text-align: start;
}

.wd-slide-label {
  margin-bottom: 12px;
  color: var(--wd-primary-color, #d4076e);
  font-size: var(--bb-fs-hero-eyebrow);
  font-weight: 600;
  letter-spacing: .08em;
}

.wd-slide-title {
  margin-bottom: 18px;
  color: #1d1d1d;
  font-size: var(--bb-fs-hero-title);
  font-weight: 700;
  line-height: 1.2;
}

.wd-slide-sub {
  margin-bottom: 28px;
  max-width: 42ch;
  color: #4a4a4a;
  font-size: var(--bb-fs-hero-body);
  line-height: 1.7;
}

.wd-slide-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 0;
}

.wd-slide-cta .btn {
  font-size: 15px;
}

/* Sizes are NOT restated here: they come from the tokens, which already carry
   their own breakpoints. Only the spacing and width that genuinely differ. */
@media (max-width: 1024px) {
  .wd-slide-inner { max-width: 420px; }
  .wd-slide-sub   { margin-bottom: 22px; }
  .wd-slide-cta .btn { font-size: var(--bb-fs-small); }
}

@media (max-width: 768.98px) {
  /* Was 100%, so a line ran the full 390 and the copy sat over the busiest part
     of the photo. A measured cap keeps the line length readable and leaves the
     product visible beside it. */
  .wd-slide-inner { max-width: 78%; }
  .wd-slide-title { margin-bottom: 12px; }
  .wd-slide-label { margin-bottom: 8px; }
  .wd-slide-sub   { margin-bottom: 18px; line-height: 1.6; }
}

/* D2 of the 2026-09-08 client edits: «هنحتاج نشيل الـ buttons دي اللي على اليمين
   وعلى الشمال، شكلها وحش» (V2 03:00, said over the hero at mobile width, frame
   w_0180s). Measured at 390: two 40px arrows over the photo, the «next» one
   hanging 10px off the left edge (x -10).

   The slider's own control cannot do this. `arrows_style = 0` removes the arrows
   at EVERY width (inc/shortcodes/slider.php:252, `hide_prev_next_buttons`), and
   the slider metabox has no per-device arrow field. So the option keeps the
   desktop arrows, and they are hidden only below the theme's own mobile
   breakpoint, the same 768.98px the slider's generated CSS uses. Swipe and the
   dots stay, so mobile keeps two ways to change slide. `.home .wd-slider` is the
   scope the file already uses for this hero; no term id, which differs per
   environment. */
@media (max-width: 768.98px) {
  .home .wd-slider .wd-slider-arrows { display: none; }
}

/* D3 of the 2026-09-08 client edits: «الأسود اللي هنا ده محتاجين نعمله background،
   محتاجين نغمق الصورة شوية … المهم محتاجين إن … الـ text المكتوب يكون ظاهر بشكل
   أحسن» (V2 03:00). Owner chose (2026-09-10): darken behind the text, copy white.

   Measured at 390 before: the title passed, but the pink eyebrow reached 4.5:1 on
   0 to 7% of its pixels and the grey paragraph on 0 to 71%. Slides have no overlay
   option (`bg_color` paints BEHIND the image, desktop only,
   inc/shortcodes/slider.php:691), so this layer is the panel.

   0.55 is not a chosen number: it is the lightest black that brings white copy to
   4.5:1 (3:1 for the title) on 95% of the pixels under every text box on all three
   slides, computed from the photos themselves. It sits behind the COPY, not over
   the whole photo, so the product outside the copy keeps its colour. Padding is the
   16px mobile rhythm (design standard §3); corners follow the theme's own rounding
   token, which is 0 on this site. The pink CTA keeps its own colours. */
@media (max-width: 768.98px) {
  .home .wd-slider .wd-slide-inner {
    padding: 16px;
    background-color: rgba(0, 0, 0, .55);
    border-radius: var(--wd-brd-radius, 0);
  }

  .home .wd-slider .wd-slide-label,
  .home .wd-slider .wd-slide-title,
  .home .wd-slider .wd-slide-sub {
    color: #fff;
  }
}

/* Slide copy sat flush against the container edge on desktop. Logical padding so
   it holds in both directions; only above the theme's 1024px breakpoint, since the
   mobile hero already uses the full width. */
@media (min-width: 1025px) {
  .wd-slide-inner {
    padding-inline: 40px;
    max-width: 580px;
  }
}

/* ---------------------------------------------------------------------------
   Footer on mobile: EVERYTHING centred (owner request 2026-08-09).

   This rule started life covering only the logo column, because columns 2-4 are
   collapsed into accordions by the theme's own `collapse_footer_widgets` option
   and their headings read acceptably at the inline start. The owner wants the
   whole footer centred on a phone, so the scope widens here rather than a second
   block being added beside it.

   The accordion heading needs `justify-content` as well as `text-align`: the
   theme lays it out as a flex row (title + chevron), so text-align alone leaves
   the title pinned to the start with the chevron pushed away from it.
   Scoped to the theme's own mobile breakpoint (768.98px).
   --------------------------------------------------------------------------- */
@media (max-width: 768.98px) {
  .wd-footer .footer-column,
  .wd-footer .footer-column .wd-widget {
    text-align: center;
  }

  .wd-footer .footer-column img {
    margin-inline: auto;
  }

  .wd-footer .footer-column p,
  .wd-footer .footer-column ul {
    margin-inline: auto;
  }

  /* Accordion header: centre the title without losing the chevron, which the
     theme absolutely positions at the inline end. */
  .wd-footer .footer-column .widget-title {
    justify-content: center;
    text-align: center;
  }

  .wd-footer .footer-column .wd-widget li {
    text-align: center;
  }
}

/* ---------------------------------------------------------------------------
   SCOPE: every `.wd-products-element` rule in this file describes the VERTICAL
   product card (loop layout «BB Product Card»).

   They were written unscoped, and `.wd-products-element` matches EVERY products
   element on the site: so when the compact «BB Mini Product Card» arrived for the
   product page's best-seller row, these rules hijacked it twice: the add-to-cart
   was dragged 52px above its own box by a `margin-top: -52px` meant to sit it on a
   photo, and then forced into a 40px circle. Both were debugged as if they were
   theme bugs.

   `:not(.wd-bbpdpbst)` excludes that one block by its own generated class rather
   than by layout id, because ids differ between local and staging.

   IF A SECOND non-standard card block is ever added, it must be added to these
   exclusions: or, better, these rules moved onto a positive class that only the
   vertical card carries.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Product card add-to-cart: white label on the brand fill.

   The theme drives button colours through --btn-* custom properties, so setting
   `color`/`background` directly loses to its own rules. Setting the variables is
   the layer the theme actually reads.

   No radius here: the 8px this rule used to set never rendered (measured 0px on
   the E4 button, 2026-09-12), because the site's buttons take the theme's
   `--wd-brd-radius`, which is 0. Square, like every other button on the site.
   --------------------------------------------------------------------------- */
.wd-product .wd-add-btn > a,
.wd-product .add_to_cart_button {
  --btn-color: #fff;
  --btn-color-hover: #fff;
  --btn-bgcolor: var(--wd-primary-color, #d4076e);
  --btn-bgcolor-hover: #bc0661;
  --btn-brd-color: var(--wd-primary-color, #d4076e);
  --btn-brd-color-hover: #bc0661;
  color: #fff;
}

/* ---------------------------------------------------------------------------
   Carousel scrollbar in the brand colour.
   Measured element names: `.wd-nav-scroll` is the track, `.wd-nav-scroll-drag`
   the thumb (its own background is transparent, so the colour goes on the drag
   element itself).
   --------------------------------------------------------------------------- */
.wd-carousel-container .wd-nav-scroll-drag,
.wd-nav-scroll .wd-nav-scroll-drag {
  background-color: var(--wd-primary-color, #d4076e);
  border-radius: 4px;
}

.wd-carousel-container .wd-nav-scroll {
  background-color: rgba(212, 7, 110, .12);
  border-radius: 4px;
}

/* Section header: title opposite an "all products" link, as the reference does. */
.bb-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}

/* The section heading was the ONE heading on the page that did not scale: 24px
   at 1440 and 24px at 390, while the hero, the card and the category tile all
   stepped down. The token carries the steps. */
.bb-section-head .bb-section-title {
  margin: 0;
  font-size: var(--bb-fs-section-title);
}

.bb-section-link {
  color: var(--wd-primary-color, #d4076e);
  font-size: 14px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Wishlist heart: SOLID fill, white by default, brand pink once in the wishlist.

   The theme draws the heart as an icon-font glyph (\f106 on
   .wd-action-icon::before, woodmart-font) which is an OUTLINE: a font glyph
   cannot be filled by colour alone. It also reveals a SECOND glyph beside it
   when added (.wd-check-icon, \f107), which appeared as the pink blob next to
   the card once the icons were coloured.

   Both glyphs are suppressed and the heart is painted with a mask instead, so
   the shape is genuinely filled and its colour is just background-color.
   --------------------------------------------------------------------------- */
:root {
  --bb-heart: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12 21s-7.5-4.7-7.5-10A4.5 4.5 0 0 1 12 8.2 4.5 4.5 0 0 1 19.5 11c0 5.3-7.5 10-7.5 10z'/%3E%3C/svg%3E");
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn .wd-check-icon {
  display: none !important;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn .wd-action-icon::before {
  content: none !important;
}

/* E5 of the 2026-09-08 client edits: «الـ wishlist جوه في الـ product كبيرة جدا»
   (V3 02:30, said while scrolling the shop grid). It was 30px on a 196px photo.
   20px is not a chosen number: it is what the add-to-cart glyph on the SAME photo
   measures (20px, inside its 38px circle), so the two overlays are now the same
   size instead of the heart being half again as big as the action beside it.

   THIS RULE IS THE ONLY CONTROL. The block's `iconSize` attribute cannot touch
   the card heart: the theme's glyph is suppressed two rules above
   (`content: none`) and the shape is a mask on this box, so the size is this
   width/height and nothing else. A second rule further down used to set 30px
   here, which is the duplication §6e forbids; it is gone and this is the single
   place the heart is sized. The PDP heart is a different element and is sized by
   its own block attribute in build/build-product-layout.php. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn .wd-action-icon {
  display: block;
  width: 20px;
  height: 20px;
  background-color: #fff;
  transition: background-color .2s ease;
  -webkit-mask: var(--bb-heart) center / contain no-repeat;
          mask: var(--bb-heart) center / contain no-repeat;
}

/* The heart's SHADOW lives on the link, not on the heart.

   It used to be `filter: drop-shadow(...)` on `.wd-action-icon`, the same box
   that carries the heart `mask`. CSS applies filter BEFORE mask on one element,
   so the mask cut away every pixel of the shadow outside the heart: it never
   rendered at all. Measured on «البكج السحري» (white packaging) at 1440: the 1px
   band around the heart reached a median 1.15:1 against the white fill, the same
   as the bare photo, which is why the heart disappeared into pale shots.

   On the parent the filter follows the heart's rendered alpha. A 1px edge in the
   design standard's muted token #6a6a6a (four 0-blur offsets make a crisp
   outline) brings that band to a median 4.00:1, over the 3:1 WCAG 1.4.11 asks of
   a control's boundary; the original soft shadow is kept underneath for depth.
   The fill stays white, as the standard says. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn > a {
  filter:
    drop-shadow(1px 0 0 #6a6a6a)
    drop-shadow(-1px 0 0 #6a6a6a)
    drop-shadow(0 1px 0 #6a6a6a)
    drop-shadow(0 -1px 0 #6a6a6a)
    drop-shadow(0 1px 3px rgba(0, 0, 0, .35));
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn a.added .wd-action-icon,
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn a:hover .wd-action-icon {
  background-color: var(--wd-primary-color, #d4076e);
}

/* ---------------------------------------------------------------------------
   Product card to the owner's sketch.

   image  : heart top-start, label pills top-end
   below  : 3-cell feature row, then title, stars with the review count (E1), price,
            and a full-width add-to-cart button (E4, since 2026-09-12; it was a
            round cart icon on the photo's corner, shown on hover on desktop)
   --------------------------------------------------------------------------- */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-product-wrapper {
  position: relative;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .08);
  border-radius: 12px;
  overflow: hidden;
}

/* Overlays on the photo */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn,
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-labels {
  position: absolute;
  z-index: 3;
  margin: 0;
}

/* The heart shrank to 20px for E5, and the button box IS the mark, so the tap
   target would have shrunk with it, from 30px to 20px. The padding gives it a
   40x40 target and the smaller offset keeps the MARK exactly where it was, 12px
   from the photo's top and reading edge (10 padding + 2 offset). Nothing moves
   on screen; only the area a thumb can hit grows. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-wishlist-btn {
  top: 2px;
  inset-inline-start: 2px;
  padding: 10px;
}
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-labels { top: 12px; inset-inline-end: 12px; }

/* Feature icons: one row of equal cells, directly under the photo. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs {
  display: flex;
  margin: 0;
  border-top: 1px solid rgba(0, 0, 0, .08);
  border-bottom: 1px solid rgba(0, 0, 0, .08);
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs table,
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs tbody,
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs tr {
  display: flex;
  width: 100%;
  margin: 0;
  border: 0;
}

/* Cell geometry lives in the single feature-strip block further down; this file
   must not set it twice. */

/* Every text part sits 14px in from the card edge; the stars keep the title's 6px
   step, and the button takes the price's 14px inset and bottom gap, so the card's
   rhythm is the one it already had (E1 + E4, 2026-09-12). */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-title  { margin: 12px 14px 6px; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-rating { margin: 0 14px 6px; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .price               { display: block; margin: 0 14px 14px; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-add-btn-wrapp    { margin: 0 14px 14px; }

/* ---------------------------------------------------------------------------
   Equal-height cards.

   Products carry different numbers of features (some none at all) and titles
   wrap to one or two lines, so the cards ended up different heights in the same
   row. Stretch every card to the tallest in the row and let the content column
   distribute, with the title area reserving two lines so the price always sits
   on the same baseline across the row.
   --------------------------------------------------------------------------- */
.wd-products-element:not(.wd-bbpdpbst) .wd-carousel-item,
.wd-products-element:not(.wd-bbpdpbst) .wd-product {
  display: flex;
  height: 100%;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-product-wrapper {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.6em;
}

/* Price pinned to the bottom so every card ends on the same line; the button
   follows it (order 7), so price and button share one baseline across a row and
   the stars stay directly under the name. */
/* On the block's WRAPPER, the element that is actually a flex item of the card.
   It was on the inner `.price`, where `margin-top: auto` pushes nothing: measured
   2026-09-12 at 390, a sale price on two lines put its button 21px below the next
   card's, and the shorter card kept 21px of empty space under its button. The
   wrapper's own 8px bottom margin goes too, so price to button is the card's 14px
   step (the price's own bottom margin), the same as button to card edge. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-price {
  margin-top: auto;
  margin-bottom: 0;
}

/* The carousel track sizes each item to its own content, so a card with no
   feature row came out ~56px shorter. Stretch the track and reserve the row
   even when the block renders nothing for that product. */
.wd-products-element:not(.wd-bbpdpbst) .wd-carousel-wrap {
  align-items: stretch;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-carousel-item {
  height: auto;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-product-wrapper::after {
  content: "";
  display: block;
  flex: 0 0 0;
}

/* A card with no features still has to reserve the strip, or its price lands on
   a different line from the rest of the row. 33px = the measured height of a
   filled strip (6px padding each side + one 21px line). */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs:empty,
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-product-wrapper > .wd-loop-prod-title:first-of-type {
  min-height: 33px;
}

/* The separator is a real element (`.wd-term-sep`), so it is hidden directly in
   the feature-strip block below. The old font-size:0 / letter-spacing:-1em
   workaround was written before the markup was dumped; it is gone because it
   fought the size the terms actually need. */

/* The photo is a positioning context for anything the theme overlays on it. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-thumb { position: relative; }


/* Product labels are NOT styled here. Woodmart owns them end to end through
   Theme Settings > Product labels: shape, percentage-vs-word, and a background
   and text colour per label type (inc/admin/settings/shop.php:667-916). The
   values are written by build/set-product-labels.php. Colouring them from this
   file would out-specify the options and make the dashboard controls dead. */

/* ---------------------------------------------------------------------------
   Categories strip: grey band across the full width, white circles.
   --------------------------------------------------------------------------- */
.wd-cats-element {
  position: relative;
  padding-block: 36px;
}

.wd-cats-element::before {
  /* --wd-width is not defined on this element, so the band was stuck at the
     container width. Bleed from the element's own centre to the viewport edges
     instead; 100vw includes the scrollbar, so it is trimmed off. */
  content: "";
  position: absolute;
  inset-block: 0;
  left: 50%;
  width: calc(100vw - var(--wd-scroll-w, 0px));
  transform: translateX(-50%);
  background: var(--bb-color-band);
  z-index: 0;
}

.wd-cats-element > * { position: relative; z-index: 1; }

.wd-cats-element .wd-cat-thumb {
  background: #fff;
  border-radius: 50%;
  overflow: hidden;
}

/* Item titles are NOT sized here. The category tile title is owned by Theme
   Settings > Advanced typography (`product_category_title`, which emits
   `html .product.wd-cat .wd-entities-title`: specificity 0,3,1, so a child rule
   would have to out-specify a live dashboard control to win). The product card
   title takes the theme's own loop size. build/set-typography.php holds the
   values. */

/* Gap between the hero and the first section below it.
   This rule used to zero the margin, from when the grey CATEGORIES band followed
   the hero and its own padding supplied the gap. Best-sellers sits there now:
   a white section with no padding of its own: so the slider carries the gap.
   Same 40/24/16 rhythm the section blocks use in build-home.php. */
.home .wd-slider { margin-bottom: 40px !important; }

@media (max-width: 1024px) {
  .home .wd-slider { margin-bottom: 24px !important; }
}

@media (max-width: 768.98px) {
  .home .wd-slider { margin-bottom: 16px !important; }
}

/* Photo bleeds to the card edges: no white gutter above or beside it. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-thumb {
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 0;
  overflow: hidden;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-thumb img {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-product-wrapper > *:first-child {
  margin-top: 0;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-product-wrapper { position: relative; }

/* Card content order. The loop layout emits the blocks in its own sequence and the
   theme gives the parts fixed flex orders (§6j), so this file owns the order:
   photo, features, title, stars (E1), price, add-to-cart button (E4). A part left
   out of this list renders at order 0, ABOVE the photo: measured 2026-09-12, which
   is how the new stars and button first landed on top of the card. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-thumb  { order: 1; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs  { order: 3; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-title  { order: 4; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-rating { order: 5; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-price,
.wd-products-element:not(.wd-bbpdpbst) .wd-product .price               { order: 6; }
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-add-btn-wrapp    { order: 7; }


/* ---------------------------------------------------------------------------
   FEATURE STRIP: the single place this row is styled.

   Real markup, dumped from the rendered card:
     <td><span class="wd-term"><span class="wd-term-name">X</span>
         <span class="wd-term-sep">, </span></span> … </td>

   All three terms sit in ONE <td>, so the equal cells come from a grid on the
   cell and the divider goes on the term, not on a cell border. `justify-items`
   must stay `stretch`: with `center` the term shrinks to its text and the
   dividers land at uneven gaps.
   --------------------------------------------------------------------------- */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-loop-prod-attrs td {
  display: grid !important;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: center;
  justify-items: stretch;
  width: 100%;
  padding: 6px 0 !important;
}

/* Names only. The card's feature icons (E2) were removed by the owner on
   2026-09-10 («keep the names of the existing features and don't add the
   icons»); this is the rule as it stood before E2. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-term {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: 6px;
  text-align: center;
}

.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-term + .wd-term {
  border-inline-start: 1px solid rgba(0, 0, 0, .1);
}

/* The client's keywords (2026-09-30) are longer than the old one-word features
   («للمنطقة الحساسة», «لجميع أنواع البشرة»): at 390 a third of a card is about 55px,
   so a word WRAPS inside its own cell instead of being cut off. `align-items: center`
   on the cell keeps a one-line neighbour centred against a two-line one. */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-term-name {
  font-size: 11px;
  line-height: 1.3;
  color: #6a6a6a;
  white-space: normal;
}

/* The separator is a real element, so it is hidden as one: no font-size:0
   trickery competing with the size the terms need. */
/* The PDP feature row uses the same taxonomy through `wd/sp-additional-info-table`,
   whose separator is the same real element: one rule governs the property in
   both places rather than two rules setting it (CLAUDE.md §6e). */
.wd-products-element:not(.wd-bbpdpbst) .wd-product .wd-term-sep,
.wd-single-attrs .wd-term-sep {
  display: none;
}

/* ---------------------------------------------------------------------------
   SCOPE NOTE for the card rules below and the hover rule above.

   These describe the VERTICAL product card (loop layout «BB Product Card»).

   `.wd-products-element` alone matched every products element on the site,
   including the product page's best-seller row, which uses the compact
   horizontal card «BB Mini Product Card» with its own icon button. A card rule
   that leaked into it once dragged that button 52px ABOVE the card (measured at
   390, button top 343 against a card top of 395).

   `:not(.wd-bbpdpbst)` excludes that one block by its own generated class rather
   than by layout id, so it holds on staging and live where post ids differ.
   --------------------------------------------------------------------------- */


/* ---------------------------------------------------------------------------
   TABBED PRODUCTS SECTION (بكجات / وصل حديثاً)

   The element itself is the theme's own `[products_tabs]`; only three things
   are not expressible through its attributes.

   Sizes and gaps come from the tokens at the top of this file: see
   Docs/design-standard.md.
   --------------------------------------------------------------------------- */

/* 1. Section rhythm is NOT set here.

   The gap above this section is carried by the categories block's own
   `marginBottom` attribute in build/build-home.php: a theme control, per
   Docs/design-standard.md §1.

   Measured why: the theme's generated settings stylesheet is printed inline in
   wp_head, i.e. AFTER this file, and already sets a margin on content children.
   A child rule at the same specificity loses on order, and beating it would mean
   out-specifying a live dashboard control: exactly what the standard forbids. */

/* 2. SIX products at every width since F2 (Samir, 2026-09-11). The shortcode now
   asks for exactly six (build/build-home.php), so the phone-only rule that hid
   products 7 to 10 is gone: it would have matched nothing. */

/* 3. One button under the grid, pointing at the ACTIVE tab's collection.

   Both links are in the markup and CSS reveals the one whose tab the THEME has
   marked `.wd-active` (inc/shortcodes/products-tabs.php:135). `:has()` reads
   that state directly, so there is no JavaScript re-implementing tab state and
   nothing to fall out of step when the theme updates. */
.bb-tabs-cta {
  display: flex;
  justify-content: center;
  margin-top: 28px;
}

/* Carries the section gap down to the About band. Set on this element rather
   than as a margin-top on `.bb-about`, because the theme's generated settings
   stylesheet is printed AFTER this file and already puts a 20px bottom margin on
   content children. That rule is the same specificity as a two-class selector
   here, so it wins on order alone: three classes is what actually takes. */
.home .entry-content .bb-tabs-cta {
  margin-bottom: var(--bb-gap-section);
}

.bb-tabs-cta a {
  display: none;
}

/* One line per tab, by POSITION: build/build-home.php numbers the buttons in the
   same order as the tabs (F3 added a third, «عروض خاصة», on 2026-09-10). */
.entry-content:has(.products-tabs-title li:nth-child(1).wd-active) .bb-tabs-cta a[data-bb-tab="1"],
.entry-content:has(.products-tabs-title li:nth-child(2).wd-active) .bb-tabs-cta a[data-bb-tab="2"],
.entry-content:has(.products-tabs-title li:nth-child(3).wd-active) .bb-tabs-cta a[data-bb-tab="3"] {
  display: inline-flex;
}

/* ---------------------------------------------------------------------------
   ABOUT SECTION: قصّة بيلا بيوتي

   Layout only. Every piece of content is a theme element (woodmart_title,
   woodmart_button) or a core image block; nothing here restyles their internals.
   Sizes and gaps come from the tokens: see Docs/design-standard.md.
   --------------------------------------------------------------------------- */
.bb-about {
  gap: 40px;
}

/* The reference centres the copy against the image. `align-items` on the row is
   NOT the way to get it here: probed at (0,1,0), (0,2,0) and (0,2,1) it still
   computes `normal`, so only !important would win: and that would be a wall
   against a rule I could not identify. Centring the text inside its own column
   reaches the same result on a class nothing else touches. */
.bb-about-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The picture is a 630x944 PORTRAIT at the `large` size, so left alone it grew
   the column to 945px and dwarfed the copy. Cap it and crop, rather than ship a
   differently-cropped file. */
.bb-about .bb-about-media img {
  display: block;
  width: 100%;
  height: 420px;
  object-fit: cover;
  border-radius: 8px;
}

.bb-about .bb-about-media figure {
  margin: 0;
}

/* The two buttons sit side by side, as the reference has them. The theme wraps
   each one in its own `.wd-button-wrapper`, which computes `display: block`
   here even with the element's own `inline-element` class: and the text column
   is a column-flex box, so each wrapper would take a full row. Both are inside
   one `.bb-about-cta` in the markup, and that wrapper is the flex row. */
.bb-about-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Alignment is LOGICAL, so it mirrors with the document direction instead of
   being pinned to a physical side. The theme's own `align` attribute emits
   `text-left`/`text-right`, which put the Arabic copy on the wrong edge and
   would do the same to the English side of the TranslatePress switcher: so the
   attribute is deliberately not passed and this is the single source. */
.bb-about-text,
.bb-about-text .title-wrapper,
.bb-about-text .title-subtitle,
.bb-about-text .title-after_title {
  text-align: start;
}

.bb-about-text .bb-about-cta {
  justify-content: flex-start;
}

/* The title element ships its own bottom spacing; this only separates the copy
   block from the buttons. */
.bb-about-text .title-wrapper {
  margin-bottom: 24px;
}

@media (max-width: 768.98px) {
  .bb-about {
    gap: 20px;
  }

  .bb-about .bb-about-media img {
    height: 260px;
  }

  /* Image first on a phone (owner request). The columns stack in source order,
     which puts the copy on top; `order` flips them without touching the markup,
     so the desktop two-column reading order stays as the reference has it. */
  .bb-about .bb-about-media {
    order: 1;
  }

  .bb-about .bb-about-text {
    order: 2;
  }
}

/* ---------------------------------------------------------------------------
   ANNOUNCEMENT BAR: one message at a time, flipping (owner, 2026-09-09).

   It was a `wd/marquee`: a continuous horizontal ticker with every line on
   screen at once. The owner asked for one message at a time, flipping. Nothing
   in the stack does that: the marquee only slides, `woodmart_slider` offers
   slide / fade / parallax / distortion and no flip (metaboxes/slider.php:2036),
   the nested carousel has no effect param, and no installed plugin ships a text
   rotator: so this is the one hand-built component in the bar, approved on that
   basis. The markup comes from build/build-announcement-bar.php.

   No JavaScript. Slides stack in a single grid cell and each one owns a slice of
   a shared cycle through `animation-delay`, so the browser drives it alone.

   The old ticker's rules are GONE with it, not left to conflict: the 180px equal
   item boxes, the hairline separators, the corrected keyframe, the speed
   variable and the RTL double-flip correction were all marquee-specific. With
   one message on screen there are no neighbours to be equal to or separated
   from, which is how «عايز كل حاجة تبقى متساوية» is answered now.

   SLIDE, NOT FLIP, since 2026-09-12 (client, Samir: «الانيميشن خليه slide بدل
   fade»). Each message now travels in from the start of the reading line and out
   past its end, the full width of the bar, like the theme's own carousels. The
   class names keep "flip" from the first version: renaming them would mean
   re-running build/build-announcement-bar.php, which rewrites the offer line (a
   static snapshot, §6p) for no reason. The direction follows the document, so the
   same rules slide the other way on a left-to-right page.
   --------------------------------------------------------------------------- */
/* The row wraps its columns in `.container`, which caps them at 1320px and adds
   gutters. The rotator centres a single message, so it never sits against an
   edge and the cap only costs it room: at 390 the container left 286px for a
   296px slide and the offer's CTA overflowed its column. */
.whb-top-bar > .container {
  max-width: 100%;
  padding-inline: 0;
}

/* The html-block element is content-sized, so the rotator inside it was 286px
   wide and sat at the row's reading edge instead of the middle of the bar.
   Both need the full row for the message to centre. */
.whb-top-bar .wd-header-html {
  width: 100%;
}

.whb-top-bar .bb-flipper {
  --bb-flip-dwell: 4s;                    /* time one message holds the bar */
  --bb-slide-from: -100%;                  /* rtl: in from the left ... */
  --bb-slide-to: 100%;                     /* ... out to the right */
  width: 100%;
  display: grid;
  align-items: center;
  min-height: 100%;
  overflow: hidden;                        /* a parked message is off the bar */
}

/* `:not([dir="rtl"])`, not `[dir="ltr"]`: English pages carry no `dir` attribute
   at all (measured on /en/, 2026-09-15), so a `[dir="ltr"]` test never matched. */
html:not([dir="rtl"]) .whb-top-bar .bb-flipper {
  --bb-slide-from: 100%;
  --bb-slide-to: -100%;
}

/* Each message spans the whole bar and centres its own content, so a 100% shift
   moves it the full width of the bar, not just its own width. */
.whb-top-bar .bb-flip-item {
  grid-area: 1 / 1;                        /* every slide in the same cell */
  display: flex;
  align-items: center;
  justify-content: center;
  justify-self: stretch;
  gap: 12px;
  color: #fff;
  font-size: var(--bb-fs-small);
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;                              /* hidden while waiting for its turn */
  animation-duration: calc(var(--bb-flip-dwell) * var(--bb-flip-count));
  animation-timing-function: ease;
  animation-iteration-count: infinite;
  animation-delay: calc(var(--bb-flip-dwell) * var(--bb-flip-i));
  will-change: transform, opacity;
}

/* The stagger is set by position, not by an inline style: `wp_insert_post` runs
   the content through kses when WP-CLI has no user, and `safecss_filter_attr`
   drops custom properties out of a `style` attribute, so `style="--bb-flip-i:2"`
   would have arrived stripped and every slide would have shared one delay. */
.whb-top-bar .bb-flip-item:nth-child(1) { --bb-flip-i: 0; }
.whb-top-bar .bb-flip-item:nth-child(2) { --bb-flip-i: 1; }
.whb-top-bar .bb-flip-item:nth-child(3) { --bb-flip-i: 2; }
.whb-top-bar .bb-flip-item:nth-child(4) { --bb-flip-i: 3; }
.whb-top-bar .bb-flip-item:nth-child(5) { --bb-flip-i: 4; }

/* Hover holds the bar still, the same courtesy the ticker's `pauseOnHover` gave:
   a message you are reading must not leave, and the CTA must not move under the
   cursor mid-click. */
.whb-top-bar .bb-flipper:hover .bb-flip-item {
  animation-play-state: paused;
}

/* The visible window is one slide's share of the cycle, so the keyframes differ
   with the slide count. Only two counts exist: five with the offer and its CTA,
   four when no package is on sale and the offer is left out. Each message slides
   in over ~10% of its own window, holds, slides out, then waits hidden, off the
   bar, for its next turn. */
.whb-top-bar .bb-flip-5 .bb-flip-item {
  --bb-flip-count: 5;
  animation-name: bb-slide-5;
}

.whb-top-bar .bb-flip-4 .bb-flip-item {
  --bb-flip-count: 4;
  animation-name: bb-slide-4;
}

@keyframes bb-slide-5 {
  0%          { opacity: 1; transform: translateX(var(--bb-slide-from)); }
  2%          { opacity: 1; transform: translateX(0); }
  18%         { opacity: 1; transform: translateX(0); }
  20%         { opacity: 1; transform: translateX(var(--bb-slide-to)); }
  20.1%, 100% { opacity: 0; transform: translateX(var(--bb-slide-to)); }
}

@keyframes bb-slide-4 {
  0%          { opacity: 1; transform: translateX(var(--bb-slide-from)); }
  2.5%        { opacity: 1; transform: translateX(0); }
  22.5%       { opacity: 1; transform: translateX(0); }
  25%         { opacity: 1; transform: translateX(var(--bb-slide-to)); }
  25.1%, 100% { opacity: 0; transform: translateX(var(--bb-slide-to)); }
}

/* A message sliding across the top of every page forever is exactly the movement
   this setting exists for, so it becomes a cross-fade: same timing, same
   one-at-a-time reading, nothing moving sideways. */
@media (prefers-reduced-motion: reduce) {
  .whb-top-bar .bb-flip-5 .bb-flip-item { animation-name: bb-fade-5; }
  .whb-top-bar .bb-flip-4 .bb-flip-item { animation-name: bb-fade-4; }

  @keyframes bb-fade-5 {
    0%   { opacity: 0; }
    2%   { opacity: 1; }
    18%  { opacity: 1; }
    20%  { opacity: 0; }
    100% { opacity: 0; }
  }

  @keyframes bb-fade-4 {
    0%   { opacity: 0; }
    2.5% { opacity: 1; }
    22.5%{ opacity: 1; }
    25%  { opacity: 0; }
    100% { opacity: 0; }
  }
}

/* ONE campaign line (client, 2026-09-30: the bar carries the month's campaign):
   nothing to rotate, so the single message simply stays on the bar. */
.whb-top-bar .bb-flip-1 .bb-flip-item {
  opacity: 1;
  animation: none;
}

/* The offer keeps the ticker's own type; its CTA is the theme's button element,
   so only the pill's own spacing needs saying here. */
.whb-top-bar .bb-flip-item .btn {
  flex: 0 0 auto;
}
/* ---------------------------------------------------------------------------
   MEGA MENUS: anchored to the header, not to their own menu item.

   Reported 2026-09-09: the offers dropdown opened off-centre and "broke" when the
   desktop window was resized.

   Cause, measured: a full-width dropdown's `offsetParent` is its own `<li>`, which
   is `position: relative` and 112px wide. Everything between that and
   `.whb-main-header` is `static`. So the theme cannot place it in CSS at all and
   patches the position in JavaScript instead: `menuOffsets.js` computes an inline
   `right: -446px` on hover, and re-clears it on resize behind a 2s-delayed handler.
   Anything that misses that timing leaves the dropdown wherever static positioning
   put it, which is off-screen by several hundred pixels.

   Making the item `static` moves the containing block up to `.whb-main-header`,
   which is exactly the viewport width, so `inset-inline: 0` spans and centres it
   with no JavaScript and nothing to go stale on resize. The theme's own handler
   still runs and now computes an offset of 0, so it agrees rather than fights.
   --------------------------------------------------------------------------- */
.whb-general-header .wd-nav-main > li.menu-mega-dropdown {
  position: static;
}

.whb-general-header .wd-nav-main > li.menu-mega-dropdown > .wd-dropdown-menu.wd-design-full-width {
  /* The theme's own width variable, not a competing `width` declaration: its
     default is `100vw`, which counts the scrollbar and overhung the 1425px header
     by 10px. `100%` is the containing block, which is now the full-width header. */
  --wd-dropdown-width: 100%;
  /* FLUSH WITH THE NAVBAR (owner, 2026-09-09). The theme leaves a 15px `margin-top`
     under the header, which on a full-width panel reads as a white band across the
     whole page between the nav and the menu. Measured: the panel's `top` is already
     130px, exactly the header's bottom, so removing the margin lands it on the line.
     The closed-state `translateY(15px)` stays: it animates to 0 as the panel opens,
     which is the theme's own drop motion, not a gap. */
  margin-top: 0;
  /* PHYSICAL `left`, deliberately, not `inset-inline`. With both logical edges at 0
     and an explicit width the box is over-constrained, and RTL resolves that by
     dropping the start edge: measured as a 10px offset that pushed the panel past
     the viewport. One physical edge plus a width is unambiguous in either
     direction, and this element is full-width so there is nothing to mirror. */
  left: 0;
  right: auto;
}

/* MOBILE TOOLBAR: the offers button's icon.

   The theme's custom toolbar buttons (`link_1` … `link_5`) take their icon from an
   `upload` field expecting an attachment (sticky-toolbar.php:446-460). With none
   set the icon slot renders EMPTY beside four glyph icons. Rather than introduce an
   image asset for one 24px icon, the glyph comes from the theme's own font, exactly
   as the other four do: measured: home U+f144, shop U+f146, wishlist U+f106, cart
   U+f105. U+f11e is the theme's gift/label glyph (`.wd-fg-label`), the closest
   match it ships for عروض/بكجات. */
.wd-toolbar .wd-toolbar-link-1 .wd-custom-icon::before {
  font-family: "woodmart-font";
  font-weight: normal;
  content: "\f11e";
}

/* DRAWERS OPEN FROM THE READING EDGES (owner, 2026-09-15): the cart from the LEFT
   in Arabic and the RIGHT in English; the main menu, and with it the shop's filter
   panel, from the RIGHT in Arabic and the LEFT in English.

   The CART needs nothing: the theme already puts it at the reading end,
   `$position = is_rtl() ? 'left' : 'right'`
   (integrations/woocommerce/template-tags.php:2952). A rule here used to swap it to
   the right (2026-09-09, on the client's «أي منيو تفتح من على اليمين»); it is gone.

   The MENU's side is a physical header-builder option (burger `position: right`,
   template-tags.php:2137-2159) and the FILTER panel's is `wd-right` in its layout
   markup (build/build-shop.php). The theme's side rules are physical in both
   directions (`.wd-side-hidden.wd-right` sets `right: 0` in base.css AND in
   base-rtl.css), so on a left-to-right page both are moved to the left here.
   English pages carry no `dir` attribute at all (measured on /en/), so the test is
   `:not([dir="rtl"])`, never `[dir="ltr"]`. The open state needs nothing:
   `.wd-side-hidden.wd-opened { transform: none }` is side-agnostic, and the
   `:not(.wd-opened)` guard keeps this 0,5,1 transform from beating it. */
html:not([dir="rtl"]) .mobile-nav.wd-side-hidden.wd-right,
html:not([dir="rtl"]) .wd-bbshopside.wd-side-hidden.wd-right {
  right: auto;
  left: 0;
}

html:not([dir="rtl"]) .mobile-nav.wd-side-hidden.wd-right:not(.wd-opened),
html:not([dir="rtl"]) .wd-bbshopside.wd-side-hidden.wd-right:not(.wd-opened) {
  transform: translate3d(-100%, 0, 0);
}

/* العروض والبكجات is a mega menu on DESKTOP ONLY (owner, 2026-09-09). On mobile it
   is a plain link that opens the packages collection: the markup already carries a
   real `<a href>`, so hiding the panel and its chevron leaves exactly that. Scoped
   by the item's own CSS-Classes field, set in build/build-mega-menu.php. */
.wd-nav-mobile > li.bb-desktop-mega > .wd-sub-menu,
.wd-nav-mobile > li.bb-desktop-mega > .wd-nav-opener {
  display: none;
}

/* ---------------------------------------------------------------------------
   BEFORE / AFTER: شاهدي الفرق بنفسك

   The slider itself is the theme's own `woodmart_compare_images`; its handle,
   drag behaviour and clipping all come from the theme. Only the framing is here.
   Sizes and gaps from the tokens: Docs/design-standard.md.
   --------------------------------------------------------------------------- */
.bb-ba {
  position: relative;
  max-width: 600px;
  margin-inline: auto;
  margin-top: 24px;
  border-radius: 10px;
  overflow: hidden;
}

/* Labels are real elements, not CSS `content`, so they stay translatable.
   Logical sides, so they mirror with the document direction. */
.bb-ba-label {
  position: absolute;
  top: 14px;
  z-index: 3;
  padding: 6px 16px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .92);
  color: #1d1d1d;
  font-size: var(--bb-fs-small);
  font-weight: 600;
  line-height: 1.4;
  pointer-events: none;
}

/* PHYSICAL left/right on purpose: the only place in this file that is.
   The compare element clips the second image with a physical inset, so the
   "before" photo is on the LEFT in both RTL and LTR. Logical properties put
   «قبل» over the after-half on the Arabic side, seen in the render. These
   labels track the images, not the reading direction. */
.bb-ba-label-before { left: 14px; }
.bb-ba-label-after  { right: 14px; }

.bb-ba .wd-compare-img-wrapp,
.bb-ba .wd-compare-img {
  margin: 0;
}

.bb-ba img {
  display: block;
  width: 100%;
  height: auto;
}

/* The owner's own disclaimer. Small and quiet, but it must stay while the
   photographs are placeholders. */
.bb-ba-note {
  margin-top: 12px;
  color: #6a6a6a;
  font-size: var(--bb-fs-small);
  text-align: center;
}

@media (max-width: 768.98px) {
  .bb-ba {
    max-width: 100%;
    margin-top: 16px;
  }
}

/* ---------------------------------------------------------------------------
   SHOPPABLE UGC: من عميلاتنا

   Layout only. The carousel, the play button and the lightbox playback are all
   the theme's own elements (nested carousel + video); nothing here re-implements
   them. References: havess.com.au, breatheeveryday.com.
   --------------------------------------------------------------------------- */
.bb-ugc {
  margin-top: 24px;
}

/* Section gap below the UGC row.

   Three classes, because the theme rule that governs margins on content children
   needs that to beat (see the tabs CTA note above).

   The +15px is the carousel offset documented in Docs/design-standard.md §3:
   `.wd-carousel-inner` carries `margin-bottom: -15px`, so a carousel container's
   box ends 15px ABOVE its visible content and a plain 40px lands as 25px. Measured
   both ways before adding it. */
.home .entry-content .bb-ugc {
  margin-bottom: calc(var(--bb-gap-section) + 15px);
}

/* 9:16 card, matching the vertical clips (480x848 / 720x1280). */
.bb-ugc-card {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: 12px;
  overflow: hidden;
  background: #f4f4f4;
}

/* The theme's video element and its poster fill the card.
   The overlay class is `.wd-el-video-overlay` (video.php:299): an earlier guess
   at `.wd-video-overlay` matched nothing, so the poster sat at its natural
   height and left a grey band across the bottom third of the card. */
.bb-ugc-card .wd-video,
.bb-ugc-card .wd-el-video,
.bb-ugc-card .wd-el-video-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  /* !important is needed and is safe here. The theme fixes `.wd-el-video` at
     400px, so in a 552px card the poster left a grey band across the bottom
     third. Probed the ladder: one class, two classes and an id-scoped rule all
     still computed 400px: only !important takes. This is a hardcoded stylesheet
     value with no Theme Settings control behind it, so overriding it breaks no
     dashboard option (cf. Docs/design-standard.md §1), and it is scoped to this
     one section. */
  height: 100% !important;
  margin: 0;
}

.bb-ugc-card .wd-el-video-overlay img {
  width: 100%;
  height: 100%;
  margin: 0;
  object-fit: cover;
}

/* Caption sits above the product card, over a gradient so it stays legible on
   any frame. */
.bb-ugc-caption {
  position: absolute;
  inset-inline: 12px;
  bottom: 78px;
  z-index: 3;
  color: #fff;
  font-size: var(--bb-fs-small);
  font-weight: 600;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
  pointer-events: none;
}

.bb-ugc-card::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  z-index: 2;
  height: 45%;
  background: linear-gradient(to top, rgba(0, 0, 0, .55), transparent);
  pointer-events: none;
}

/* Product card pinned to the bottom of the clip, as both references have it. */
.bb-ugc-product {
  position: absolute;
  inset-inline: 10px;
  bottom: 10px;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 10px;
  background: rgba(255, 255, 255, .95);
  text-decoration: none;
}

.bb-ugc-product-thumb img {
  display: block;
  width: 40px;
  height: 40px;
  border-radius: 6px;
  object-fit: cover;
}

.bb-ugc-product-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}

.bb-ugc-product-title {
  color: #1d1d1d;
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bb-ugc-product-price {
  color: var(--wd-primary-color, #d4076e);
  font-size: 12px;
  font-weight: 600;
}

/* The theme prints both the old and the current price; the strike-through one is
   noise at this size. */
.bb-ugc-product-price del {
  display: none;
}

.bb-ugc-product-price ins {
  text-decoration: none;
}

/* ---------------------------------------------------------------------------
   UGC lightbox: fit the clip to the viewport.

   The clips are vertical (480x848 and 720x1280). The theme's video popup sizes
   to the video's own dimensions, so a 1280-tall clip opened on a 900-tall
   window ran off the top and bottom: head and hands cropped out of frame.
   Constrain to the viewport and let the aspect ratio do the rest.
   --------------------------------------------------------------------------- */
.wd-video-popup video,
.mfp-content .wd-video-popup video {
  max-width: min(92vw, 520px);
  max-height: 88vh;
  width: auto;
  height: auto;
  margin-inline: auto;
  display: block;
  border-radius: 8px;
}

.wd-video-popup {
  display: flex;
  align-items: center;
  justify-content: center;
  max-height: 92vh;
  background: transparent;
}

/* ---------------------------------------------------------------------------
   Product page: "اشتري الآن" gets its own full-width row.

   The button is the theme's own (quick-buy/class-main.php:26 injects it on
   `woocommerce_after_add_to_cart_button`), so it lands INSIDE `form.cart`, which
   is a wrapping flex row. With the block's Stretch control on, the theme gives
   both buttons `flex: 1 1 auto` (style.css:24195), so add-to-cart and buy-now
   share one line and each ends up half width.

   The owner wants buy-now at the END of the section, full width. `flex-basis:
   100%` on the wrapping row does exactly that with no `!important` and no other
   property touched.

   Specificity: the theme's rule is `.wd-btn-design-full form.cart :where(…)` =
   0,2,1: `:where()` contributes nothing. This selector is 0,3,1, so it wins on
   its own. No theme option governs this placement, so child CSS is the correct
   layer (Docs/design-standard.md §1).
   --------------------------------------------------------------------------- */
.wd-single-add-cart form.cart .wd-buy-now-btn {
  flex: 1 1 100%;
}

/* ---------------------------------------------------------------------------
   Product page: the best-seller card fills its slide.

   The row uses one card per view with the compact loop layout «BB Mini Product
   Card». Its `.wd-carousel-item` computes to `display: flex`, so the card inside
   it is a flex item at the browser default `flex: 0 1 auto` and shrinks to its
   own content: measured at 390, a 218px card sitting in a 370px slide, with the
   whole row floating in the left half.

   The reference does not need this because its slide computes to `display:
   block`, where a block-level card fills by itself.

   NOT the theme's `wd_stretch_product*` metas: those look like the right switch
   but `css/parts/woo-opt-stretch-cont.css` only ever sets `height`, being the
   equal-height control for multi-column rows. Verified: the card stayed 218px
   with them on.

   Scoped to this one block by its own generated class, so no other product
   carousel on the site is affected.
   --------------------------------------------------------------------------- */
.wd-bbpdpbst .wd-carousel-item > .wd-product {
  flex: 1 1 auto;
}

/* ---------------------------------------------------------------------------
   Best-seller card: the add-to-cart icon.

   The card uses the theme's `icon` style (owner, 2026-08-12: icon only, no label
   beside it). The vertical card's circular-button rules a few hundred lines above
   are deliberately scoped away from this block, so the icon would otherwise
   render as a bare glyph on the text baseline.

   Same visual language as the vertical card: a filled brand-pink disc: but
   solid rather than white-on-photo, because here it sits on the card background
   and not over an image. Colours come from the theme's own action-icon variables
   (see the note on the vertical card), so no glyph colour is set directly.
   --------------------------------------------------------------------------- */
.wd-bbpdpbst .wd-product .wd-add-btn > a {
  --wd-action-icon-color: #fff;
  --wd-action-icon-color-hover: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background-color: var(--wd-primary-color, #d4076e);
  transition: background-color .25s ease;
}

.wd-bbpdpbst .wd-product .wd-add-btn > a:hover {
  background-color: #bc0661; /* brand pink dark: Docs/design-standard.md §4 */
}

/* ---------------------------------------------------------------------------
   Product gallery: one fixed frame for every photo.

   WooCommerce does not crop the `woocommerce_single` size: only catalog
   thumbnails have a cropping setting: so each slide took the height of its own
   image. Measured on «البكج الملكي» at 390: slides rendered 240, 1066, 240, 541,
   541, 541, 541 and 360px tall, so the whole page below the gallery jumped as the
   carousel moved. The theme's `product_slider_auto_height` option is already off;
   it governs the carousel, not the images.

   Nothing in the theme sets height, aspect-ratio or object-fit on these images
   (verified against every loaded stylesheet), so there is no rule to out-specify:
   this is the first thing to own the property, at the child-CSS layer the standard
   assigns to values no theme option covers.

   `.zoomImg` is excluded: it is the magnifier's absolutely-positioned clone, which
   the zoom script sizes itself (measured 1066px against a 360px frame). It does not
   affect layout, but constraining it would distort the magnification.

   Ratio comes from the token, not a number here.
   --------------------------------------------------------------------------- */
.woocommerce-product-gallery__image img:not(.zoomImg),
.wd-gallery-thumb .wd-carousel-item img {
  aspect-ratio: var(--bb-ratio-product-media);
  object-fit: cover;
  width: 100%;
  height: auto;
}

/* ---------------------------------------------------------------------------
   Product page trust badges: stack the icon above the label on mobile.

   The three badges are one `wd/container` row of `wd/paragraph` blocks, each an
   inline 16px icon followed by its label. At 390 the three labels do not fit on
   one line, so the row wrapped 2 + 1 and read as a broken grid.

   Below the theme's own 768.98px breakpoint each badge becomes its own column:
   icon over label, centred: and the three share the width equally, so they stay
   on one line. `flex: 1 1 0` on the paragraphs is what makes the columns equal;
   the anonymous text node after the `<img>` becomes the second flex item on its
   own, which is why no extra markup is needed.

   Label size uses the existing micro token rather than a new number
   (Docs/design-standard.md §2).
   --------------------------------------------------------------------------- */
/* Equal columns across the full width at every size, so the row reads as centred
   and nothing is left hugging one edge (owner, 2026-08-12). `flex: 1 1 0` gives
   the three badges an identical share regardless of label length. */
.wd-bbpdptru {
  flex-wrap: nowrap;
}

.wd-bbpdptru .wp-block-wd-paragraph {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  margin: 0;
}

/* Icon size lives here, not inline on the <img>, so it can differ per breakpoint. */
.wd-bbpdptru img {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
}

@media (max-width: 768.98px) {
  /* Icon above its label: the three labels do not fit on one line at 390, so the
     row wrapped 2 + 1 and read as a broken grid. The anonymous text node after the
     <img> becomes the second flex item on its own, so no extra markup is needed. */
  .wd-bbpdptru .wp-block-wd-paragraph {
    flex-direction: column;
    justify-content: flex-start;
    gap: 6px;
    font-size: var(--bb-fs-micro);
    line-height: 1.35;
  }

  .wd-bbpdptru img {
    width: 30px;
    height: 30px;
  }
}

/* ---------------------------------------------------------------------------
   Product page feature row: equal columns across the full width.

   The block renders one table cell holding all the terms as inline `.wd-term`
   spans, so they bunched at the reading edge with the rest of the row empty:
   measured at 390, three terms filled 248px of a 360px column, and at 1440 they
   used 400 of 625.

   The cell and the terms become flex here so each term takes an equal share and
   centres its own icon + label. This is presentation of one block instance, which
   no theme option covers, so child CSS is the right layer
   (Docs/design-standard.md §1): the icon SIZE stays on the block's own
   `termImageWidth` control and is deliberately not set here.

   Scoped to this block's generated class, so the shop and card attribute rows are
   untouched.
   --------------------------------------------------------------------------- */
.wd-bbpdpfea tr {
  width: 100%;
}

.wd-bbpdpfea td {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex: 1 1 auto;
  width: 100%;
}

.wd-bbpdpfea .wd-term {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
}

/* Since 2026-10-02 the row shows the client's three words per product (pa_keywords, the
   card's own words) with no icons, so it reads like the card's strip: equal cells, a hairline
   between them, the small step of the type scale. */
.wd-bbpdpfea .wd-term-name {
  font-size: var(--bb-fs-small);
  line-height: 1.35;
}

.wd-bbpdpfea .wd-term + .wd-term {
  border-inline-start: 1px solid rgba(0, 0, 0, .1);
}

/* ---------------------------------------------------------------------------
   Reviews pagination: centred.

   The list is paginated at 2 per page (WordPress `page_comments` +
   `comments_per_page`, which Woodmart styles as `.woocommerce-pagination`). The
   numbers already run right-to-left correctly: «1» rightmost, the next chevron at
   the far left pointing left: because the section inherits `dir="rtl"`; measured
   at 390: 1 at x341 down to the chevron at x193.

   What it lacked was balance: `text-align: start` pinned the row to the reading
   edge under a full-width list. Centring is a presentation choice no theme option
   covers, so it belongs here (Docs/design-standard.md §1).
   --------------------------------------------------------------------------- */
.wd-bbpdprev .woocommerce-pagination {
  display: flex;
  justify-content: center;
  text-align: center;
}

/* ---------------------------------------------------------------------------
   Product page: alternating section bands.

   Owner, 2026-08-12: "كل السكاشن سايحة على بعض"، every section was transparent on
   white, so nothing read as a boundary. Measured before changing anything: seven
   sections, all `rgba(0,0,0,0)`, separated by 16px: the same distance as the gaps
   INSIDE a section, and two of those collapsed to 5px.

   The two long, text-heavy blocks take the band; the product rows stay white. Only
   those two, deliberately: strict odd/even alternation breaks on this page because
   the up-sells row hides itself on the 29 products with no up-sells set, which
   would put two grey bands side by side on some products and not others.

   Technique is the one already proven on the home page's categories strip: a
   full-bleed `::before` from the element's own centre, since `--wd-width` is not
   defined here and the section is inside the 1320px container. Reused rather than
   reinvented (CLAUDE.md §6c), and the colour comes from the shared token.
   --------------------------------------------------------------------------- */
.wd-bbpdptab,
.wd-bbpdprev {
  position: relative;
  padding-block: 32px;
}

.wd-bbpdptab::before,
.wd-bbpdprev::before {
  content: "";
  position: absolute;
  inset-block: 0;
  left: 50%;
  width: calc(100vw - var(--wd-scroll-w, 0px));
  transform: translateX(-50%);
  background: var(--bb-color-band);
  z-index: 0;
}

.wd-bbpdptab > *,
.wd-bbpdprev > * {
  position: relative;
  z-index: 1;
}

/* H3 (2026-09-11) put the phone's description tabs on two centred rows. REVERSED 2026-10-02
   (owner: «يكونوا التابس دي على الموبايل كأنهم سلايدر ... كلهم يكونوا في صف واحد»): the
   theme's own phone behaviour is exactly that, one row that swipes sideways
   (`.wd-nav-wrapper.wd-mb-action-swipe`, base.css), so the override is simply gone. */

/* ---------------------------------------------------------------------------
   Product page: one heading scale for every section.

   Measured before: the four product rows rendered their heading at 22px while the
   reviews heading: WooCommerce's own `#reviews h2`, never styled as a section
   title: came out at 15px, smaller than the body text beside it, on a section
   1576px tall.

   All of them now take `--bb-fs-section-title` (24 / 22 / 20 by breakpoint), which
   is the documented scale in Docs/design-standard.md §2, so the mobile size is the
   20px the standard specifies rather than the 22px they happened to inherit.
   --------------------------------------------------------------------------- */
.single-product-page .wd-products-element .wd-el-title,
.single-product-page .wd-products-element > .title,
/* Two classes on the element itself, so this is 0,3,0 and beats the theme's own
   `.woocommerce-Reviews .woocommerce-Reviews-title { font-size: unset }` (0,2,0),
   which otherwise wins on load order: its stylesheet part is printed after this
   file: and drops the heading to the inherited 15px body size. No !important. */
.wd-single-reviews.wd-bbpdprev .woocommerce-Reviews-title {
  font-size: var(--bb-fs-section-title);
  font-weight: 600;
  line-height: 1.3;
}

/* ---------------------------------------------------------------------------
   Trust badge row in the prefooter: every page.

   Rendered by build/build-prefooter-badges.php into Woodmart's own `.wd-prefooter`
   (footer.php:41). Four equal cells with a hairline between them, which is the
   feature-strip convention already documented in Docs/design-standard.md §5, so the
   row matches the product card's feature strip rather than inventing a second look.

   Mobile-first: 2×2 at 390: four across is unreadable at that width, one per row
   makes the footer enormous. The hairlines follow the grid at each breakpoint.
   --------------------------------------------------------------------------- */
.bb-trust-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px 0;
  padding-block: 8px;
}

.bb-trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-inline: 12px;
  text-align: center;
}

/* Hairline between cells, never on the row's outer edges. At 2 columns that means
   no line on every 2nd item; at 4 it means no line on every 4th. */
.bb-trust-item:not(:nth-child(2n)) {
  border-inline-end: 1px solid rgba(0, 0, 0, 0.08);
}

.bb-trust-icon {
  width: 40px;
  height: 40px;
}

.bb-trust-label {
  color: #1d1d1d;
  font-size: var(--bb-fs-small);
  font-weight: 600;
  line-height: 1.3;
}

.bb-trust-sub {
  color: #6a6a6a;
  font-size: var(--bb-fs-micro);
  line-height: 1.4;
}

@media (min-width: 769px) {
  .bb-trust-row {
    grid-template-columns: repeat(4, 1fr);
  }

  .bb-trust-item:not(:nth-child(2n)) {
    border-inline-end: 0;
  }

  .bb-trust-item:not(:nth-child(4n)) {
    border-inline-end: 1px solid rgba(0, 0, 0, 0.08);
  }

  .bb-trust-icon {
    width: 44px;
    height: 44px;
  }
}

/* ---------------------------------------------------------------------------
   «من نحن» and «تواصلي معنا» pages.

   Only spacing and the band. Every value is a documented token: the section gap
   from Docs/design-standard.md §3, the band colour from §4: so nothing here picks
   a number of its own.

   The band's cells are core columns, which already stack to one per row below
   782px, so there is no breakpoint work: the mobile layout is what core gives us.
   --------------------------------------------------------------------------- */
.bb-about-page {
  align-items: center;
  margin-block-end: var(--bb-gap-section);
}

/* Square, cropped to fill: owner decision 2026-08-14, and consistent with the 1:1
   frame the rest of the site already uses for product media
   (Docs/design-standard.md §5). The source photo is portrait 390×584, so at 390 it
   rendered 540px tall and at 1440 it ran 566px against ~300px of text, leaving the
   text column half empty. A square fixes both viewports with one rule.

   Not `--bb-ratio-product-media`: that token is documented as the PRODUCT media
   frame, and this is a brand photograph. Same value today, different meaning: the
   two should be free to diverge. */
.bb-about-page-media figure {
  margin: 0;
}

.bb-about-page-media img {
  aspect-ratio: 1 / 1;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: 8px;
}

/* Full-bleed band, the same technique the home page's categories strip and the
   product page's sections use: reused rather than reinvented (§6c). */
.bb-band {
  position: relative;
  margin-block: var(--bb-gap-section);
  padding-block: 32px;
}

.bb-band::before {
  content: "";
  position: absolute;
  inset-block: 0;
  left: 50%;
  width: calc(100vw - var(--wd-scroll-w, 0px));
  transform: translateX(-50%);
  background: var(--bb-color-band);
  z-index: 0;
}

.bb-band > * {
  position: relative;
  z-index: 1;
}

.bb-band h2 {
  font-size: var(--bb-fs-section-title);
  font-weight: 600;
  margin-block-end: 16px;
}

.bb-band h3 {
  font-size: var(--bb-fs-item-title);
  font-weight: 600;
  margin-block-end: 4px;
}

.bb-band p {
  color: #6a6a6a;
}

.bb-about-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-block-start: 16px;
}

/* ---------------------------------------------------------------------------
   Product page: the mobile sticky add-to-cart bar's quantity stepper.

   Measured at 390: the whole 390px strip was one solid `#d4076e` slab. At <=768
   the theme makes `.wd-sticky-btn` itself transparent (woo-opt-sticky-add-to-cart.css),
   so the only painted surfaces are the full-width button and the quantity block
   absolutely positioned on top of it: and woo-mod-quantity-overlap.css paints that
   block from the SAME accent variables as the button:

     .wd-quantity-overlap div.quantity { filter: brightness(0.95) }
     .wd-quantity-overlap div.quantity :is(input[type],.btn) {
       background-color: var(--btn-accented-bgcolor);
       color: var(--btn-accented-color) }

   The theme's only separation is that `brightness(0.95)`: 5% on this pink is
   invisible, which is why the control read as part of the button. The xtemos demo
   renders no sticky bar on mobile, so there was no reference layout to match.

   Owner decision 2026-08-13: white block, `#4b4b4b` text, hairline divider: the
   same neutral treatment the in-page stepper on this page already has (measured
   transparent background, `rgb(75,75,75)` text), so pink stays reserved for the
   action itself. Docs/design-standard.md §4 for both colours.

   Specificity: the theme's base rule is 0,3,2 and its hover rule 0,5,2, so the
   selectors below carry `.wd-sticky-btn` as an extra class to reach 0,4,2 and
   0,6,2. Beating them on specificity rather than `!important` (CLAUDE.md §6b.4)
   keeps the theme's own active/pressed states working. Scoped to `.wd-sticky-btn`
   so the loop cards' overlap steppers, which use the same module, are untouched.
   --------------------------------------------------------------------------- */
.wd-sticky-btn.wd-quantity-overlap div.quantity {
  /* The theme dims the whole block to differentiate it; the block now has its own
     background, so the filter would only muddy the white. */
  filter: none;
  background-color: #fff;
  border-inline-end: 1px solid rgba(0, 0, 0, 0.08);
}

.wd-sticky-btn.wd-quantity-overlap div.quantity :is(input[type], .btn),
.wd-sticky-btn.wd-quantity-overlap :is(div, .cart):hover > div.quantity :is(input[type], .btn) {
  background-color: transparent;
  color: #4b4b4b;
}

/* ---------------------------------------------------------------------------
   FAQ accordion (2026-09-05)

   The block ships the theme's own `wd-style-shadow` accordion, which already
   gives every question a rounded card with a soft shadow. What the theme cannot
   know is Bella's type scale and the fact that a 1200px-wide question line is
   unreadable, so the child sets the measure, the spacing and the accent.

   The opener is the theme's `woodmart-font` chevron (`wd-opener-style-arrow`);
   it is given a filled circle rather than being replaced, so the theme's own
   rotate-on-open transform keeps working.
   --------------------------------------------------------------------------- */
.bb-faq {
  --wd-accordion-spacing: 18px;
  --wd-row-gap: 10px;
  max-width: 860px;
  margin-inline: auto;
}

/* The shadow style paints `--bgcolor-gray-200` under a light colour scheme; on
   the white product page and the white home section that reads as a grey slab.
   White card on a hairline is the card convention in Docs/design-standard.md. */
.bb-faq > .wd-accordion-item {
  background-color: #fff;
  border: 1px solid rgba(0, 0, 0, .08);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
  transition: box-shadow .25s ease, border-color .25s ease;
}

.bb-faq > .wd-accordion-item:hover,
.bb-faq > .wd-accordion-item:has(.wd-accordion-title.wd-active) {
  border-color: rgba(212, 7, 110, .28);
  box-shadow: 0 4px 16px rgba(212, 7, 110, .10);
}

.bb-faq .wd-accordion-title {
  gap: 14px;
  align-items: flex-start;
}

.bb-faq .wd-accordion-title-text {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.55;
  color: #1d1d1d;
}

/* The chevron sits in a pink disc so the control is findable at a glance. It
   keeps the theme's glyph and the theme's rotation. */
.bb-faq .wd-accordion-opener {
  flex: 0 0 auto;
  margin-block-start: 2px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: rgba(212, 7, 110, .08);
  color: #d4076e;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bb-faq .wd-accordion-title.wd-active .wd-accordion-opener {
  background-color: #d4076e;
  color: #fff;
}

/* A rule under the open question separates it from its answer without adding a
   second border to the card. */
.bb-faq .wd-accordion-content {
  border-top: 1px solid rgba(0, 0, 0, .06);
  padding-block-start: 14px;
  color: #4b4b4b;
  font-size: var(--bb-fs-body);
  line-height: 1.85;
}

.bb-faq .wd-accordion-content a {
  color: #d4076e;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The product page's FAQ heading is an h4 so it nests correctly under the page
   title, but it is a section heading and takes the section type size. */
.bb-pdp-faq-title {
  margin-block: 0 16px;
  font-size: var(--bb-fs-section-title);
  line-height: 1.35;
  text-align: center;
}

/* «أكملي روتينك» (2026-09-15): the routine section's heading, the block's own inner
   content (build/build-product-layout.php). A section heading, so the section type
   size; aligned to the reading start like the product rows' headings, not centred
   like the FAQ, because the routine is a row of products. */
.bb-pdp-routine-title,
.bb-pdp-ugc-title,
.bb-pdp-why-title {
  margin-block: 0 16px;
  font-size: var(--bb-fs-section-title);
  line-height: 1.35;
}

/* The placeholder note over the product page's customer videos (2026-09-16). Body size,
   the muted grey the standard uses for secondary lines; the «(يُراجع)» inside it is bold
   like every other review marker on the site. */
.bb-pdp-ugc-note {
  margin-block: -8px 16px;
  color: #6a6a6a;
}

/* «لماذا بيلا بيوتي؟» (2026-09-15, reference havess.com.au «Why buy from us»): five
   short lines, each after a tick in the brand pink, as on the reference. The tick is
   drawn with borders, not a character: Cairo has no ✓ glyph, so a character would
   fall back to whatever font the phone has. Body size and colour from the standard. */
/* Footer contacts on phones (owner, 2026-09-16). The theme folds the titled footer
   columns at 575px and below by adding `wd-widget-collapse` to every footer widget
   (js/scripts/global/widgetCollapse.js). The untitled widget under «تواصلي معنا»
   carries a copy of the contact lines: hidden while the columns are open, shown exactly
   when the theme has folded them, so the numbers are never behind a tap. */
.bb-footer-contact-phone {
  display: none;
}

.footer-widget.wd-widget-collapse .bb-footer-contact-phone {
  display: block;
  /* owner 2026-10-02: «تزودلي المسافة تحتها شوية» before the social icons; was 0. */
  margin-bottom: 24px;
}

/* The folded footer centres its text; the icons row is a flex line that starts at the
   reading edge, so it is centred with the lines above it (measured 2026-09-16 at 390). */
.footer-widget.wd-widget-collapse .bb-footer-social {
  justify-content: center;
}

.bb-why-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.bb-why-list li {
  position: relative;
  margin: 0 0 12px;
  padding-inline-start: 26px;
  color: #4b4b4b;
}

.bb-why-list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 4px;
  top: 0.35em;
  width: 6px;
  height: 11px;
  border: solid var(--wd-primary-color, #d4076e);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

@media (max-width: 768.98px) {
  .bb-faq {
    --wd-accordion-spacing: 15px;
  }

  .bb-faq .wd-accordion-title-text {
    font-size: 15px;
  }
}

/* Latin runs isolated with <bdi dir="ltr"> (phone numbers, e-mails, handles, the CR number)
   must never break in the middle. Measured 2026-09-17 on staging at 390: «+973 3624 4438»
   split over two lines in the stores page and in every product's ingredients tab, «+973»
   at the end of one line and «3624 4438» on the next. The isolation (§6k) fixes the order;
   this keeps the number whole. */
bdi[dir="ltr"] {
  white-space: nowrap;
}

/* Phone menu categories (owner, 2026-09-17: «decrease the icon size and one per row»).
   Inside the phone menu only, each category of «منتجاتنا» is one row: its 40px circle
   beside the name. The column count and the circle size are the block's own Mobile
   attributes (build/build-mega-menu.php); this only turns the theme's stacked tile
   (thumb above title) into a row. Title size stays with the theme typography option. */
.mobile-nav .wd-bbmegaca .wd-cat-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  /* the phone menu's own link inset (measured: `.wd-nav-mobile > li > a` 5px 20px) */
  padding-inline: 20px;
}

/* The theme centres the circle with automatic side margins (measured 64.8px each at
   300px). In a row those margins swallow the free space and pushed the names past the
   drawer's edge, so they are zeroed here and the circle keeps its size. */
.mobile-nav .wd-bbmegaca .wd-cat-thumb {
  flex: none;
  margin-inline: 0;
}

.mobile-nav .wd-bbmegaca .wd-cat-content {
  padding: 0;
  text-align: start;
}

/* ---------------------------------------------------------------------------
   Shop icon row (client reply of 2026-09-30): «الغاء هذا القسم، لتجنب تشتيت المستخدم»
   on the SHOP page only. The row now lists the subcategories of the category being
   viewed (`data_source: wc_query`, build/build-shop.php), which on the packages page
   are his six package groups and on the shop page would be the whole top level.
   ------------------------------------------------------------------------- */
.post-type-archive-product .wd-bbshopca {
  display: none;
}

/* Hero points and price (client reply of 2026-09-30). The points are his «✓» lines;
   the price line reads the hair set's own regular and sale price. */
.wd-slide-points {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin-bottom: 22px;
  color: #1d1d1d;
  font-size: var(--bb-fs-hero-body);
  font-weight: 600;
}

/* The tick is drawn with borders like .bb-why-list: Cairo has no ✓ glyph. */
.wd-slide-points span {
  position: relative;
  padding-inline-start: 20px;
}

.wd-slide-points span::before {
  content: "";
  position: absolute;
  inset-inline-start: 3px;
  top: 0.3em;
  width: 6px;
  height: 11px;
  border: solid var(--wd-primary-color, #d4076e);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.wd-slide-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin-bottom: 22px;
  font-size: var(--bb-fs-hero-body);
}

.wd-slide-price del {
  color: #6b6b6b;
}

.wd-slide-price strong {
  color: var(--wd-primary-color, #d4076e);
  font-size: 1.15em;
}

@media (max-width: 768.98px) {
  .wd-slide-points,
  .wd-slide-price { margin-bottom: 16px; }
}

/* Footer contact icons (client reply of 2026-09-30): a WhatsApp mark before the number
   and a mail mark before the address, drawn inline in currentColor. */
.bb-footer-contact a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.bb-footer-contact .bb-fc-icon {
  flex: none;
}

/* ---------------------------------------------------------------------------
   Stores page as cards (client reply of 2026-09-30: «طريقة عرض افضل واوضح»).
   White cards on the band, the standard's hairline border, square like every
   other surface on the site (--wd-brd-radius is 0). Buttons sit at the foot of
   each card so the three cards end on one line.
   ------------------------------------------------------------------------- */
.bb-store-cards {
  align-items: stretch !important; /* core ships align-items:normal!important (§6k) */
  gap: 20px;
}

.bb-store-card {
  display: flex;
  flex-direction: column;
  padding: 24px;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .08);
}

/* The store's NAME leads the card: the band's h3 token (13px on a phone) read
   smaller than the bold address under it (measured on staging at 390). It takes the
   hero body step (17 / 16 / 15), the address the small step, so name > address > text. */
.bb-band .bb-store-card h3 {
  margin-block-end: 8px;
  font-size: var(--bb-fs-hero-body);
  font-weight: 700;
}

.bb-band .bb-store-where {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-block-end: 8px;
  color: #1d1d1d;
  font-size: var(--bb-fs-small);
  font-weight: 600;
}

.bb-store-pin {
  flex: none;
  margin-block-start: 3px;
  color: var(--wd-primary-color, #d4076e);
}

.bb-store-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-block-start: auto;
  padding-block-start: 12px;
}

@media (max-width: 768.98px) {
  .bb-store-card {
    padding: 18px;
  }
}

/* Footer text on the brand pink (client reply of 2026-09-30: «تغيير اللون الى الوردي»).
   The theme's light scheme prints footer text at 80% white and links at 70% white
   (--wd-text-color, --color-gray-500 on .color-scheme-light). Those were written for a
   dark footer: on #d4076e they measure about 3.5:1 and 2.9:1. Full white is 5.18:1.
   The lost colour change on hover is replaced by an underline. */
.wd-footer.color-scheme-light {
  --wd-text-color: #fff;
  --wd-link-color: #fff;
  --color-gray-500: #fff;
  --color-gray-400: #fff;
}

.wd-footer.color-scheme-light a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------------------------------------------------------------------------
   «لماذا بيلا بيوتي؟» on the product page (owner, 2026-10-02): centred, on the shared light
   grey band (`.bb-band`, --bb-color-band). Each line shrinks to its text and centres, so the
   tick stays next to its words.
   ------------------------------------------------------------------------- */
.bb-pdp-why {
  text-align: center;
}

.bb-pdp-why .bb-why-list li {
  display: table;
  margin-inline: auto;
  text-align: start;
}

/* ---------------------------------------------------------------------------
   «أكملي روتينك» on phones (owner, 2026-10-02): the carousel goes, the form's rows become
   full-width cards stacked with a + between them: photo · name and price · checkbox. The
   whole card ticks its checkbox (the label is stretched over the row). The thumbnail is
   added by bb_child_fbt_row_thumbnails() and shown on phones only.
   ------------------------------------------------------------------------- */
.bb-fbt-thumb-wrap {
  display: none;
}

@media (max-width: 768.98px) {
  .wd-bbpdprtn .wd-fbt .wd-carousel-container {
    display: none;
  }

  .wd-bbpdprtn .wd-fbt-form {
    width: 100%;
    max-width: none;
  }

  .wd-bbpdprtn .wd-fbt-product {
    border: 1px solid rgba(0, 0, 0, .08);
    background: #fff;
  }

  .wd-bbpdprtn .wd-fbt-product + .wd-fbt-product {
    position: relative;
    margin-top: 28px;
  }

  .wd-bbpdprtn .wd-fbt-product + .wd-fbt-product::before {
    content: "+";
    position: absolute;
    inset-inline: 0;
    top: -24px;
    text-align: center;
    color: var(--wd-primary-color, #d4076e);
    font-size: var(--bb-fs-section-title);
    font-weight: 600;
    line-height: 20px;
  }

  .wd-bbpdprtn .wd-fbt-product-heading {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 12px;
    row-gap: 2px;
    padding: 10px 12px;
  }

  .wd-bbpdprtn .bb-fbt-thumb-wrap {
    display: block;
    order: 1;
    flex: 0 0 64px;
  }

  .wd-bbpdprtn .bb-fbt-thumb {
    display: block;
    width: 64px;
    height: 64px;
    object-fit: cover;
  }

  .wd-bbpdprtn .wd-fbt-product-heading label {
    order: 2;
    flex: 1 1 0;
    min-width: 0;
  }

  /* The whole card is the label's hit area. */
  .wd-bbpdprtn .wd-fbt-product-heading label::after {
    content: "";
    position: absolute;
    inset: 0;
  }

  /* Old price over new price: side by side they took 128px and squeezed the name to 42px,
     which split it mid-word. */
  .wd-bbpdprtn .wd-fbt-product-heading .price {
    order: 3;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    white-space: nowrap;
  }

  .wd-bbpdprtn .wd-fbt-product-heading input[type="checkbox"] {
    order: 4;
    position: relative;
    z-index: 1;
    flex: none;
    margin: 0;
  }
}
