/* =========================================================
   Oxinex — project overrides
   Loaded after main.css. Keep template edits here so main.css
   stays close to the vendor original.
   1. header layout + action icons
   2. search popup
   3. footer quick links
   4. footer copyright bar
   5. checkout payment methods
   6. checkout place-order button
   7. policy modal
   8. product not-found state
   ========================================================= */

/* Fallbacks for the light theme. dark.css / herbal.css / ocean.css each
   redefine these, so components below follow whichever theme is active
   without needing a rule per theme. */
:root {
  --ox-page: #ffffff;
  --ox-surface: #ffffff;
  --ox-surface-2: #f5f5f5;
  --ox-border: #ebebeb;
  --ox-shadow: rgba(25, 25, 25, 0.18);
  /* solid header bar for viewports where the hero is hidden */
  --ox-header-solid: #8e2f13;
}

/* ---------- 1. header layout + action icons ---------- */
/* The menu must stay in normal flow: the links carry the header's
   vertical padding, so taking them out of flow collapses the header
   height. Centring is done with auto margins inside the growing
   wrapper instead, which leaves the header geometry untouched. */
@media (min-width: 1200px) {
  .tgmenu__navbar-wrap.tgmenu__main-menu {
    flex-grow: 1;
  }
  /* direct child only, so the Shop dropdown's .sub-menu is untouched */
  .tgmenu__navbar-wrap.tgmenu__main-menu > ul {
    margin: 0 auto;
    justify-content: center;
    flex-wrap: nowrap;
    white-space: nowrap;
  }
  /* actions stay pinned right so the menu reads as centred */
  .tgmenu__nav > .tgmenu__action {
    margin-left: auto;
    flex: 0 0 auto;
  }
}

/* --- header height ---
   The nav links carry the header's vertical size (main.css ships
   43px top and bottom), so trimming their padding is what shortens
   the bar. */
@media (min-width: 1200px) {
  .tgmenu__navbar-wrap ul li a {
    padding-top: 28px;
    padding-bottom: 28px;
  }
}

/* --- header side gutters ---
   .custom-container is capped at 1650px and centres, so on wide screens
   the logo and the offcanvas button sit hard against that edge. Extra
   inline padding pulls them inwards. */
.tg-header__area > .custom-container {
  padding-left: 70px;
  padding-right: 70px;
}
@media (max-width: 1199.98px) {
  .tg-header__area > .custom-container {
    padding-left: 20px;
    padding-right: 20px;
  }
}

/* --- mobile header row ---
   .tgmenu__nav allows wrapping, so at mobile widths the 60px toggler
   circle dropped onto a second line below the logo. Keep the row on one
   line and scale the toggler to match the smaller action icons. */
@media (max-width: 1199.98px) {
  .tgmenu__nav {
    flex-wrap: nowrap;
    gap: 12px;
  }
  .tgmenu__nav > .tgmenu__action {
    margin-left: auto;
  }
  .tgmenu__action > ul li {
    margin-left: 18px;
  }
  /* theme toggle, cart and search all come down from 21px */
  .tgmenu__action > ul li svg,
  .header-theme .theme-toggle,
  .header-theme .theme-toggle svg {
    width: 18px;
    height: 18px;
  }
  .tgmenu__action > ul li .cart-count span {
    transform: scale(0.72);
  }
  .tg-header__area .mobile-nav-toggler {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    margin: 0;
  }
  .tg-header__area .mobile-nav-toggler svg {
    width: 20px;
    height: 20px;
  }
}
@media (max-width: 575.98px) {
  .tgmenu__action > ul li {
    margin-left: 13px;
  }
  .tgmenu__action > ul li svg,
  .header-theme .theme-toggle,
  .header-theme .theme-toggle svg {
    width: 17px;
    height: 17px;
  }
  .tg-header__area .mobile-nav-toggler {
    width: 36px;
    height: 36px;
  }
  .tgmenu__nav .logo img {
    max-width: 130px;
  }
}

/* --- hero slider ---
   main.css ships 950px tall with 200px of top padding to clear the
   taller original header; with the header trimmed both come down.
   The title drops from 80px to 70px — only the title, the sub-title
   and body copy keep their template sizes. */
.slider__bg {
  /* Hero height = padding-top + content row + padding-bottom, floored by
     min-height: 130 + 476 + 80 = 686px. Briefly trimmed to 596px, which also
     shrank the photo (see .slider__thumb below — the two are tied), so it is
     back at the original figure. */
  min-height: 600px;
  padding: 130px 0 80px;
}
@media (max-width: 1500px) {
  .slider__bg {
    min-height: 540px;
  }
}
@media (max-width: 991.98px) {
  .slider__bg {
    min-height: 480px;
    padding: 110px 0 70px;
  }
}
.slider__content .title {
  font-size: 70px;
  margin-bottom: 35px;
}

/* --- hero product image ---
   Fills the empty right-hand column of each slide: a single theme-matched
   photo (Storefront::sharedTokens' hero_img_1/2) lifted off a soft radial
   glow. Used to be a 3-image group (one large centre + two smaller side
   images) — simplified to one image, so .slider__thumb-main is sized to
   carry the column on its own rather than share it with .slider__thumb-side
   (removed; no longer referenced by any template markup). */
.slider__thumb {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 1;
}
.slider__thumb::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: 92%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle,
              rgba(255, 214, 170, 0.30) 0%,
              rgba(255, 170, 100, 0.12) 42%,
              rgba(255, 170, 100, 0) 68%);
  z-index: -1;
  pointer-events: none;
}
.slider__thumb img {
  display: block;
  height: auto;
  object-fit: contain;
}
.slider__thumb-main {
  width: 78%;
  z-index: 2;
  filter: drop-shadow(0 24px 34px rgba(40, 12, 3, 0.45));
}

@media (min-width: 992px) {
  /* The photo is lifted out of the grid so it can spill past the container
     edge and fill the whole empty right-hand side of the slide, instead of
     being boxed into the 5-column track. It positions against .slider__bg —
     the slide's own full-width, relatively-positioned backdrop — so every
     slide keeps its own photo and the fade between slides still works.

     .col-lg-5 holds on to the height the photo used to contribute: taking it
     out of flow would otherwise shorten the hero and drag the text block up
     with it. Nothing about the text column changes — same type, same
     spacing, same position. */
  .slider__area .col-lg-5 {
    /* This is what actually sets the hero's content height — the photo is
       absolutely positioned, so without it the row would collapse to the
       text block (~318px) and the hero would shrink with it. */
    min-height: 476px;
  }
  /* Narrows the text block inside col-lg-7 (the column class itself is
     untouched) so the photo can start closer to it. This is free space, not
     a squeeze: the headline's glyphs are a constant 646px wide at every
     desktop size — the font-size doesn't scale — and they were sitting in a
     block 71-94px wider than that. 660px keeps ~14px of slack past the
     longest line, so nothing re-wraps and no text moves. */
  .slider__area .slider__content {
    max-width: 660px;
  }
  .slider__thumb {
    position: absolute;
    top: 0;
    right: 0;
    /* Bounds how far `cover` can zoom. The box is as tall as the hero (686px)
       but grows with the viewport, and a square photo covering it scales to
       the box's WIDTH — so the wider the screen, the more is cropped off the
       top. Capping the width near the hero's own height keeps the box roughly
       square, which keeps the crop small (~30px at 1540, ~74px at 1920)
       instead of unbounded. Below this width nothing changes. */
    max-width: 760px;
    /* An absolutely positioned box with both left and right set is
       over-constrained once max-width bites: the browser keeps `left` and
       drops `right`, which pinned the photo to the LEFT of the span and left
       dead space against the viewport edge. Auto margin resolves it the other
       way, so the photo stays flush right once capped. */
    margin-left: auto;
    /* Anchored just past the headline column rather than given a fixed
       width. The container is centred with a capped max-width, so the text
       track's right edge sits at roughly `50% + 110px` at every desktop
       size, and the text block above is capped at 660px of that. +55px sits
       ~20-40px past the text block's new right edge (35-54px past the last
       actual glyph) at every width from 992px up. Pulling it in this far
       is what shrinks the gap beside the headline — and, because the box
       gets correspondingly wider, it also cuts how much of the photo's
       sides `cover` has to crop away. */
    left: calc(50% + 55px);
    width: auto;
    height: 100%;
    margin-bottom: 0;
    align-items: center;
    /* No inset. The photo is meant to reach all four edges of this box, so
       any padding here would reintroduce the gap it exists to fill. */
    padding: 0;
  }
  /* Two classes, so this beats `.slider__thumb img`'s height:auto (one
     class + one type) on specificity.

     `cover`, not `contain`: contain scales the photo until it fits *inside*
     the box, which leaves bars on whichever pair of sides the photo's
     aspect ratio doesn't match — that was the gap above and to the left of
     the photo. cover scales until the box is fully covered instead, so the
     photo reaches all four edges whatever its proportions. The trade is
     that the overflowing dimension is cropped rather than shrunk.

     object-position decides which part survives that crop, and the two axes
     want different answers. Vertically, `bottom` keeps the photo standing on
     the hero's bottom edge and takes the crop off the top, where these
     photos have the most headroom to give. Horizontally, `center` — pinning
     it `left` looked right on a wide screen (where nothing is cropped
     horizontally anyway) but on a ~992px screen the box is much taller than
     it is wide, so the crop swings to the horizontal axis and a left pin
     threw away the whole right side of the photo, cutting the subject's
     face off. Centring keeps the subject in frame at every width, and costs
     nothing where the horizontal fit is exact. */
  .slider__thumb .slider__thumb-main {
    width: 100%;
    height: 100%;
    /* cover, so the photo fills its box and sits flush to the right edge
       with only a small crop off the top — the intended look.

       contain was tried instead and rejected: with nothing cropped, a square
       graphic in a box wider than it is tall gets letterboxed, which pushed
       the photo away from the headline and left dead space either side.

       cover's own failure mode is the opposite — the box widens with the
       viewport, so the crop grows with it (219px off the top at a 1920px
       viewport). That is what max-width on the box below is for. */
    object-fit: cover;
    object-position: center bottom;
  }
  /* glow is a % of the (now much wider) box, so it needs pulling back in */
  .slider__thumb::before {
    width: 76%;
  }
}

@media (max-width: 991.98px) {
  /* columns stack here, so keep the group short */
  .slider__thumb {
    max-width: 420px;
    margin: 40px auto 0;
  }
}
@media (max-width: 575.98px) {
  .slider__thumb { max-width: 300px; }
}

/* --- hero video panel ---
   main.css sizes this generously for the taller original hero; scaled
   down to sit comfortably in the shorter one. */
.slider__video-wrap {
  padding: 18px 20px;
  gap: 24px;
  border-radius: 12px;
  /* the product group carries its own z-index, so the panel needs a
     higher one to float in front of the jars */
  z-index: 5;
  /* main.css sits it at 15% from the bottom */
  bottom: 9%;
}
@media (max-width: 1500px) {
  .slider__video-wrap {
    bottom: 7%;
  }
}
.slider__video-wrap .thumb {
  width: 74px;
}
.slider__video-wrap .content {
  gap: 14px;
}
.slider__video-wrap .content a span {
  width: 32px;
  height: 32px;
}
.slider__video-wrap .content a span svg {
  width: 11px;
}
.slider__video-wrap .content a,
.slider__video-wrap .content p {
  font-size: 14px;
}
@media (max-width: 1199.98px) {
  .slider__video-wrap {
    padding: 14px 16px;
    gap: 16px;
  }
  .slider__video-wrap .thumb {
    width: 62px;
  }
}

/* --- breadcrumb banner ---
   main.css ships 230px top / 150px bottom to clear the taller original
   header; trimmed to match the shorter one. */
.breadcrumb__bg {
  padding: 130px 0 70px;
}
@media (max-width: 1500px) {
  .breadcrumb__bg {
    padding: 120px 0 60px;
  }
}
@media (max-width: 767.98px) {
  .breadcrumb__bg {
    padding: 100px 0 55px;
  }
}
.breadcrumb__content .title {
  font-size: 46px;
  margin-bottom: 10px;
}
@media (max-width: 767.98px) {
  .breadcrumb__content .title { font-size: 34px; }
}

/* --- mini cart ---
   Rows are rebuilt by cart.js; these cover the states the template
   never had markup for. */
.mini__cart-empty {
  margin: 30px 0;
  text-align: center;
  font-size: 15px;
  color: var(--tg-body-color);
}
#cartCheckout.is-disabled {
  opacity: 0.45;
  pointer-events: none;
}
.mini__cart-delete { cursor: pointer; }

/* --- hero on mobile ---
   The slide is a wide two-column composition that does not earn its
   height on a phone, so the product section leads instead. */
@media (max-width: 767.98px) {
  .slider__area { display: none; }

  /* .transparent-header is position:absolute and relies on the hero
     sitting behind it. With no hero it floated over the white product
     section and the white nav icons vanished, so put it back in flow
     over a solid bar. */
  .transparent-header {
    position: relative;
  }
  /* only while it sits at the top of the page: once main.js adds
     .sticky-menu the template repaints the bar and flips the logo and
     icons to their dark variants, which need the light sticky
     background to stay legible */
  .tg-header__area:not(.sticky-menu) {
    background-color: var(--ox-header-solid);
  }
  /* main.js swaps in this spacer when the bar goes sticky; the template
     sizes it for the original 100px header */
  #header-fixed-height.active-height {
    height: 80px;
  }
}

/* --- section rhythm ---
   main.css ships 150px; the smaller breakpoints below it (100px at
   992px, 60px at 768px) still take over on narrow screens. */
.section-py-150 {
  padding: 65px 0;
}
.section-pt-150 {
  padding-top: 70px;
}

/* --- action icons ---
   The SVGs carry width/height attributes (30px for cart and search),
   which CSS overrides. */
.tgmenu__action > ul li svg {
  width: 21px;
  height: 21px;
}
/* theme toggle button — a shared component, so it lives here rather
   than in one of the theme files (those load later and would win) */
.header-theme .theme-toggle {
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--tg-color-white-default);
  cursor: pointer;
  transition: color 0.3s ease-in-out;
}
/* size only — a `display` here (0,2,1) would outrank the
   `.theme-toggle .icon-moon` hide rules (0,2,0) and show every icon */
.header-theme .theme-toggle svg {
  width: 20px;
  height: 20px;
}
.header-theme .theme-toggle:hover { color: var(--tg-color-yellow-light); }
.sticky-menu .header-theme .theme-toggle { color: var(--tg-heading-color); }
.sticky-menu .header-theme .theme-toggle:hover { color: var(--tg-color-yellow-light); }
.tgmenu__action > ul li.header__offCanvas a {
  width: 40px;
  height: 40px;
}
.tgmenu__action > ul li.header__offCanvas a svg {
  width: 16px;
  height: 16px;
}
.tgmenu__action > ul li .cart-count span {
  transform: scale(0.82);
}
@media (min-width: 1200px) {
  /* the template spaces these 45px apart, which reads loose once the
     glyphs are smaller */
  .tgmenu__action > ul li {
    margin-left: 26px;
  }
}

/* ---------- 2. search popup ---------- */
/* main.css ships 70px / 100px; tightened here */
.search__popup {
  padding-top: 45px;
  padding-bottom: 50px;
}

.search__head {
  text-align: center;
  margin-bottom: 30px;
}
.search__head .sub-title {
  display: block;
  font-family: var(--tg-heading-font-family);
  font-size: 14px;
  font-weight: var(--tg-fw-semi-bold);
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--tg-theme-primary);
  margin-bottom: 8px;
}
.search__head .title {
  font-size: 40px;
  margin: 0;
  color: var(--tg-heading-color);
}
@media (max-width: 767.98px) {
  .search__head .title { font-size: 28px; }
}

.search__suggest {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 22px;
}
.search__suggest > span {
  font-size: 14px;
  color: var(--tg-body-color);
  text-transform: uppercase;
  letter-spacing: 1px;
}
.search__suggest .list-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.search__suggest .list-wrap a {
  display: inline-block;
  padding: 6px 16px;
  border: 1px solid var(--tg-border-1);
  border-radius: 50px;
  font-size: 14px;
  font-weight: var(--tg-fw-medium);
  color: var(--tg-heading-color);
  transition: 0.3s ease-in-out;
}
.search__suggest .list-wrap a:hover {
  background: var(--tg-theme-primary);
  border-color: var(--tg-theme-primary);
  color: var(--tg-color-white-default);
}

/* live suggestions */
.search__results {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
  max-height: 46vh;
  overflow-y: auto;
  border: 1px solid var(--ox-border);
  border-radius: 10px;
  background: var(--ox-surface);
}
.search__results li + li { border-top: 1px solid var(--ox-border); }
.search__results a {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  transition: 0.3s ease-in-out;
}
.search__results a:hover { background: var(--tg-color-gray-1); }
.search__result-thumb {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  background: var(--tg-color-gray-1);
  border-radius: 8px;
}
.search__result-thumb img {
  max-width: 42px;
  max-height: 46px;
  object-fit: contain;
}
.search__result-text { display: grid; gap: 2px; margin-right: auto; }
.search__result-text strong {
  font-family: var(--tg-heading-font-family);
  font-size: 17px;
  font-weight: var(--tg-fw-semi-bold);
  color: var(--tg-heading-color);
  line-height: 1.3;
}
.search__result-text span {
  font-size: 14px;
  color: var(--tg-body-color);
  text-transform: capitalize;
}
.search__result-price {
  flex: 0 0 auto;
  font-family: var(--tg-heading-font-family);
  font-size: 18px;
  font-weight: var(--tg-fw-bold);
  color: var(--tg-theme-primary);
}

.search__empty {
  margin: 26px 0 0;
  text-align: center;
  font-size: 15px;
  color: var(--tg-body-color);
}

/* ---------- 3. footer quick links ---------- */
/* The column spans 5 of 12 so the footer row still totals 12 after two
   link columns became one. Centring its contents closes the gap that
   would otherwise open between the links and the newsletter block. */
/* A one-column grid sized to its widest child: justify-content centres
   that column in the footer, justify-items keeps the title and the
   links flush left inside it, so their left edges line up. Centring
   each child individually instead would stagger them. */
@media (min-width: 992px) {
  .footer__widget-center {
    display: grid;
    justify-content: center;
    justify-items: start;
  }
  .footer__widget-center .footer__widget-link {
    text-align: left;
  }
}

/* --- footer height ---
   main.css ships 120px of top padding on the widget row and 32px on
   the copyright bar. */
.footer__top {
  padding: 60px 0 20px;
}
@media (max-width: 767.98px) {
  .footer__top {
    padding: 50px 0 20px;
  }
}
.footer__bottom {
  padding: 20px 0;
}

/* ---------- 4. footer copyright bar ---------- */
.copyright__content-center {
  text-align: center;
}
.copyright__content-center p {
  margin: 0;
}
.copyright__content-center strong {
  color: var(--tg-color-white-default);
  font-weight: var(--tg-fw-semi-bold);
}

/* ---------- 5. checkout payment methods ---------- */
.payment__methods {
  display: grid;
  gap: 12px;
  margin-bottom: 30px;
}
.payment__option {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--ox-border);
  border-radius: 10px;
  background: var(--ox-surface);
  cursor: pointer;
  transition: 0.3s ease-in-out;
}
.payment__option:hover { border-color: var(--tg-theme-primary); }
.payment__option input {
  width: 18px;
  height: 18px;
  margin: 3px 0 0;
  flex: 0 0 auto;
  accent-color: var(--tg-theme-primary);
  cursor: pointer;
}
/* :has lets the whole card react to its own radio */
.payment__option:has(input:checked) {
  border-color: var(--tg-theme-primary);
  box-shadow: inset 0 0 0 1px var(--tg-theme-primary);
}
.payment__option-body { display: grid; gap: 4px; }
.payment__option-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.payment__option-name {
  font-family: var(--tg-heading-font-family);
  font-size: 17px;
  font-weight: var(--tg-fw-semi-bold);
  color: var(--tg-heading-color);
}
.payment__option-note {
  font-size: 14px;
  line-height: 1.6;
  color: var(--tg-body-color);
}
.payment__badge {
  display: inline-block;
  padding: 3px 12px;
  border-radius: 50px;
  background: var(--tg-theme-primary);
  color: var(--tg-color-white-default);
  font-size: 12px;
  font-weight: var(--tg-fw-bold);
  letter-spacing: 1px;
  text-transform: uppercase;
  line-height: 1.6;
}

/* discount row + nudge in the order summary */
.order__info-wrap .list-wrap li.order__discount span {
  color: var(--tg-theme-primary);
}
.order__save-note {
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: 8px;
  border: 1px dashed var(--tg-theme-primary);
  background: color-mix(in srgb, var(--tg-theme-primary) 8%, transparent);
  color: var(--tg-heading-color);
  font-size: 14px;
}

/* ---------- 6. checkout place-order button ---------- */
/* .order__info-wrap .tg-btn only sets width/alignment, so the button
   inherited the plain pill. Give it the brand fill and a little more
   presence as the page's primary action. */
.order__place-btn {
  margin-top: 18px;
  /* .tg-btn's 40px icon bubble sets the height, so it comes down too */
  padding: 5px 5px 5px 24px;
  border: none;
  font-size: 16px;
  font-weight: var(--tg-fw-semi-bold);
  cursor: pointer;
}
.order__place-btn span {
  width: 34px;
  height: 34px;
  margin-left: auto;
}

/* ---------- 7. policy modal ---------- */
/* Colours come from the --ox-* and --tg-* variables, so the modal
   follows whichever theme is active with no per-theme rules. */
body.policy-modal-open { overflow: hidden; }

.policy-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(12, 10, 9, 0.62);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}
.policy-modal[hidden] { display: none; }
.policy-modal.is-open { opacity: 1; }

.policy-modal__dialog {
  position: relative;
  width: 100%;
  max-width: 760px;
  max-height: min(86vh, 800px);
  display: flex;
  flex-direction: column;
  background: var(--ox-surface);
  border-radius: 20px;
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.32);
  transform: translateY(24px) scale(0.97);
  transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
  overflow: hidden;
}
.policy-modal.is-open .policy-modal__dialog { transform: none; }
/* brand rule across the top, the same accent the section titles use */
.policy-modal__dialog::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 4px;
  background: linear-gradient(90deg, var(--tg-theme-primary), var(--tg-color-yellow-light));
}

.policy-modal__head {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 18px;
  padding: 32px 34px 24px;
  border-bottom: 1px solid var(--ox-border);
}
.policy-modal__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--tg-theme-primary) 12%, transparent);
  color: var(--tg-theme-primary);
}
.policy-modal__headings { margin-right: auto; }
.policy-modal__eyebrow {
  display: block;
  font-family: var(--tg-heading-font-family);
  font-size: 12px;
  font-weight: var(--tg-fw-semi-bold);
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--tg-theme-primary);
  margin-bottom: 6px;
}
.policy-modal__title {
  margin: 0;
  font-size: 30px;
  line-height: 1.15;
  color: var(--tg-heading-color);
}
.policy-modal__updated {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--tg-body-color);
}
.policy-modal__close {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: var(--ox-surface-2);
  border: none;
  border-radius: 50%;
  color: var(--tg-heading-color);
  cursor: pointer;
  transition: 0.3s ease-in-out;
}
.policy-modal__close:hover {
  background: var(--tg-theme-primary);
  color: var(--tg-color-white-default);
  transform: rotate(90deg);
}

.policy-modal__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 28px 34px 32px;
  color: var(--tg-body-color);
  font-size: 15px;
  line-height: 1.8;
  scrollbar-width: thin;
  scrollbar-color: var(--ox-border) transparent;
}
.policy-modal__body::-webkit-scrollbar { width: 6px; }
.policy-modal__body::-webkit-scrollbar-track { background: transparent; }
.policy-modal__body::-webkit-scrollbar-thumb {
  background: var(--ox-border);
  border-radius: 3px;
}
.policy-modal__body::-webkit-scrollbar-thumb:hover { background: var(--tg-theme-primary); }

/* first paragraph reads as a standfirst */
.policy-modal__body > p:first-child {
  font-size: 16px;
  color: var(--tg-heading-color);
  padding: 16px 18px;
  border-left: 3px solid var(--tg-theme-primary);
  border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--tg-theme-primary) 7%, transparent);
  margin-bottom: 26px;
}
.policy-modal__body h4 {
  position: relative;
  margin: 30px 0 10px;
  padding-left: 16px;
  font-size: 17px;
  letter-spacing: 0.4px;
  color: var(--tg-heading-color);
}
.policy-modal__body h4::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--tg-theme-primary);
}
.policy-modal__body p { margin: 0 0 14px; }
.policy-modal__body ul {
  margin: 0 0 18px;
  padding: 0;
  list-style: none;
}
.policy-modal__body li {
  position: relative;
  margin-bottom: 8px;
  padding-left: 26px;
}
.policy-modal__body li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 11px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 2px solid var(--tg-theme-primary);
}
.policy-modal__body strong { color: var(--tg-heading-color); }
.policy-modal__body a {
  color: var(--tg-theme-primary);
  font-weight: var(--tg-fw-medium);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.policy-modal__body a:hover { color: var(--tg-color-orange-light); }

.policy-modal__foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding: 20px 34px 24px;
  border-top: 1px solid var(--ox-border);
  background: var(--ox-surface-2);
}
.policy-modal__foot p {
  margin: 0;
  font-size: 14px;
  color: var(--tg-body-color);
}
.policy-modal__foot a { color: var(--tg-theme-primary); }
.policy-modal__ok { border: none; cursor: pointer; }

@media (max-width: 767.98px) {
  .policy-modal { padding: 0; }
  .policy-modal__dialog {
    max-width: none;
    height: 100%;
    max-height: 100%;
    border-radius: 0;
  }
  .policy-modal__head { padding: 24px 20px 18px; gap: 14px; }
  .policy-modal__icon { width: 44px; height: 44px; }
  .policy-modal__icon svg { width: 22px; height: 22px; }
  .policy-modal__title { font-size: 23px; }
  .policy-modal__body { padding: 22px 20px 26px; }
  .policy-modal__foot { padding: 16px 20px 20px; justify-content: center; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .policy-modal,
  .policy-modal__dialog,
  .policy-modal__close { transition: none; }
}

/* ---------- 8. product not-found state ---------- */
.product__notfound {
  display: grid;
  place-items: center;
  min-height: 320px;
}
.product__notfound-inner {
  text-align: center;
  max-width: 620px;
}
.product__notfound-inner > svg {
  color: var(--tg-theme-primary);
  margin-bottom: 22px;
}
.product__notfound-inner .title {
  font-size: 38px;
  margin-bottom: 14px;
  color: var(--tg-heading-color);
}
@media (max-width: 767.98px) {
  .product__notfound-inner .title { font-size: 28px; }
}
.product__notfound-inner > p { margin-bottom: 30px; }
.product__notfound-inner strong { color: var(--tg-theme-primary); }

.product__notfound-list {
  list-style: none;
  margin: 0 0 35px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  text-align: left;
}
.product__notfound-list a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--ox-border);
  border-radius: 10px;
  background: var(--ox-surface);
  transition: 0.3s ease-in-out;
}
.product__notfound-list a:hover {
  border-color: var(--tg-theme-primary);
  transform: translateY(-3px);
}
.product__notfound-list img {
  width: 40px;
  height: 46px;
  object-fit: contain;
  flex: 0 0 auto;
}
.product__notfound-list span { display: grid; gap: 2px; }
.product__notfound-list strong {
  font-family: var(--tg-heading-font-family);
  font-size: 15px;
  font-weight: var(--tg-fw-semi-bold);
  color: var(--tg-heading-color);
  line-height: 1.3;
}
.product__notfound-list span span {
  font-size: 14px;
  color: var(--tg-theme-primary);
}

/* --- product detail: main photo must stay inside its box ------------------
   main.css gives .product__details-img a FIXED 530px box (400px on mobile)
   and centres the photo in it, but constrains the <img> itself only inside
   two mobile media queries. At desktop the image had `max-height: none` and
   `object-fit: fill`, so it rendered at whatever size it wanted.

   That was invisible with the designer's own demo photography, which is
   252x362 or so and fits the box with room to spare. Real listings are not:
   a supplier's 1223x1600 upload rendered 540x706, spilling 176px past the
   box and landing 73px ON TOP of the thumbnail strip below it, which sits in
   normal flow with only a 15px margin.

   Capping the image to the box is what keeps the layout the designer drew --
   fixed frame, photo centred inside it, thumbnails cleanly underneath --
   whatever the reseller's supplier happens to upload.

   `contain`, not `cover`: this is the product being sold, and cover crops to
   fill, which on a tall bottle or a wide appliance cuts off the item itself.
   Contain letterboxes instead, and the box already carries the template's own
   grey surface so the spare space reads as intended rather than as a gap.

   --- 2026-09-04: the frame is now fixed for every upload ------------------
   Capping with max-* alone left the IMAGE ELEMENT sized by the photo, so the
   slot changed shape from product to product: a 1589x1600 upload rendered
   526x530 and a 1223x1600 one 405x530 — 121px narrower for the next product
   in the same grid — while a 16:9 photo would come out 540x304. A small
   upload was worse: with only a maximum set it rendered at its natural size
   and sat marooned in the middle of the box.

   Giving the element the box's own width and height fixes the slot at
   540x530 (400px tall on mobile) whatever is uploaded, and lets object-fit
   do the scaling — which now also scales small photos UP to the frame
   instead of leaving them tiny. Still `contain`: the brief was a fixed
   frame, not a cropped one, and cover would have taken about a quarter off
   the height of a tall product shot. */
.product__details-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* --- contact panel: hide a line the reseller left empty --------------------
   The three contact values are per-site columns now, seeded when the site is
   created and the reseller's to change. A cleared field resolves to '' by
   design, which without this leaves the panel showing an empty heading -- a
   blank line where a phone number was, which reads as broken rather than as
   "not provided".

   :empty matches an element with no children AND no text, which is exactly
   what a token that resolved to nothing produces. */
.offcanvas-contact .number:empty,
.offcanvas-contact .email:empty,
.offcanvas-contact p:empty {
  display: none;
}

/* Product detail: no rule under the quantity / Buy now row.
   main.css draws a 1px border-bottom on .product__details-info (dark.css only
   recolours it), a divider that used to separate the row from the Tag /
   Categories list below it. That list is switched off (see shop.js, #pdTags),
   so the divider was left under the button with nothing beneath it. The row's
   padding stays, so the spacing below the button is unchanged. */
.product__details-info {
  border-bottom: 0;
}
