/* ==========================================================================
   SAATVIK HERBS — INTERIOR PAGES
   Product pages, contact, about and the policy routes. Shares every component
   with the home page via base.css; what's here is the layout those pages need
   and the home page doesn't.
   ========================================================================== */

/* ------------------------------------------------------------- BREADCRUMB */
.crumbs {
  padding-top: calc(var(--nav-h) + var(--s-md));
  padding-bottom: var(--s-md);
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  display: flex;
  gap: 0.6em;
  flex-wrap: wrap;
}
.crumbs a { color: var(--terracotta); }
.crumbs a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ══════════════════════════════════════════════════════ PRODUCT PAGE HEAD
   Phone: art first, then everything needed to decide — price, stock, one
   button — before any scrolling. Desktop: two columns, art sticky so the
   purchase control stays with you while the specs scroll past. */
.pdp-head { display: grid; gap: var(--s-lg); padding-bottom: var(--section); }

.pdp-art { aspect-ratio: 4 / 5; box-shadow: var(--shadow-lg); }

.pdp-name { margin: var(--s-sm) 0 var(--s-md); }

.pdp-price {
  margin: var(--s-lg) 0 var(--s-sm);
  padding-top: var(--s-md);
  border-top: 1px solid var(--rule);
}
.pdp-price-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  margin: 0;
}
.pdp-price-value {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.35em;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 7vw, 3.25rem);
  line-height: 1;
  color: var(--terracotta);
}
.pdp-price-unit { font-size: var(--fs-small); color: var(--text-muted); }
.pdp-price-note {
  margin: 0.55rem 0 0;
  font-size: var(--fs-micro);
  color: var(--text-muted);
}
.pdp-price-note a { color: var(--terracotta); text-decoration: underline; text-underline-offset: 2px; }

/* Stock state, shown as a dot plus words — never colour alone (§9 has to be
   legible to someone who can't distinguish green from red). */
.pdp-stock {
  display: flex;
  align-items: center;
  gap: 0.55em;
  font-size: var(--fs-small);
  color: var(--text-muted);
  margin-bottom: var(--s-md);
}
.dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; flex: none; }
.dot--in  { background: var(--olive); box-shadow: 0 0 0 3px rgba(74,94,77,0.18); }
.dot--out { background: var(--terracotta); box-shadow: 0 0 0 3px rgba(152,93,68,0.18); }

.pdp-fineprint {
  margin-top: var(--s-sm);
  font-size: var(--fs-micro);
  color: var(--text-muted);
  line-height: 1.7;
}
.pdp-fineprint a { color: var(--terracotta); text-decoration: underline; text-underline-offset: 2px; }

.pdp-spec {
  margin-top: var(--s-lg);
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  overflow: hidden;
}
.pdp-spec > div {
  padding: var(--s-sm) var(--s-md);
  /* Rules drawn per cell and pulled back onto the container's own border, so
     a grid with an odd number of items has no empty coloured cell. */
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
  margin: -1px 0 0 -1px;
}
.pdp-spec dt {
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.2rem;
}
.pdp-spec dd { margin: 0; font-weight: 600; font-size: var(--fs-small); }

/* ------------------------------------------------------------- PDP BODY */
.pdp-cols { display: grid; gap: var(--s-xl); }
.pdp-desc { margin: var(--s-md) 0 var(--s-xl); font-size: var(--fs-lede); line-height: 1.55; max-width: 60ch; }
.pdp-cols .label-rule + .benefits { margin-top: var(--s-md); }

.pdp-aside { display: grid; gap: var(--s-sm); align-content: start; }
.panel {
  padding: var(--s-md);
  background: var(--oat);
  border-radius: var(--r-lg);
}
.panel .h3 { margin-bottom: var(--s-2xs); }
.panel p { font-size: var(--fs-small); }

/* --------------------------------------------------------- INFO / CONTACT */
.info-grid { display: grid; gap: var(--s-lg); margin-top: var(--s-lg); }
.info-grid p { font-size: var(--fs-small); margin-top: var(--s-2xs); }
.info-grid a { color: var(--terracotta); text-decoration: underline; text-underline-offset: 2px; }

/* ------------------------------------------------------------- CROSSLINK */
.crosslink {
  margin-top: var(--s-lg);
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-md);
  padding: var(--s-sm);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  transition: border-color var(--t-fast) var(--ease-soft), background-color var(--t-fast) var(--ease-soft);
}
.crosslink:hover { border-color: var(--olive); background: var(--oat); }
.crosslink-art { width: 5rem; aspect-ratio: 1; border-radius: var(--r-md); }
.crosslink-copy { display: grid; gap: 0.15rem; }
.crosslink-copy .muted { font-size: var(--fs-small); }
.crosslink .arw { color: var(--terracotta); transition: transform var(--t-fast) var(--ease); }
.crosslink:hover .arw { transform: translateX(4px); }

/* ═════════════════════════════════════════════════════════ CONTENT PAGES
   Contact, about and the policy routes: one readable column, generous
   leading, headings that stay in the family voice. */
.page-head {
  padding-top: calc(var(--nav-h) + var(--section));
  padding-bottom: var(--s-lg);
}
.page-head .lede { margin-top: var(--s-md); }

.prose { max-width: 68ch; }
.prose h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-display);
  word-spacing: var(--ws-display);
  color: var(--olive);
  margin: var(--s-xl) 0 var(--s-sm);
}
.prose h3 { font-size: var(--fs-h3); font-weight: 600; margin: var(--s-lg) 0 var(--s-2xs); }
.prose p { margin-bottom: var(--s-sm); }
.prose ul { display: grid; gap: 0.5rem; margin: var(--s-sm) 0 var(--s-md); }
.prose ul li { padding-left: 1.4rem; position: relative; }
.prose ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.72em;
  width: 0.6rem; height: 2px;
  background: var(--ochre);
  border-radius: 2px;
}
.prose a { color: var(--terracotta); text-decoration: underline; text-underline-offset: 3px; }

/* ---- Contact cards ---- */
.contact-grid { display: grid; gap: var(--s-sm); margin-top: var(--s-lg); }
.contact-card {
  padding: var(--s-md);
  background: var(--oat);
  border-radius: var(--r-lg);
  display: grid;
  gap: var(--s-2xs);
}
.contact-card .label { color: var(--olive); }
.contact-card strong { font-size: 1.0625rem; }
.contact-card a { color: var(--terracotta); text-decoration: underline; text-underline-offset: 3px; }
.contact-card .muted { font-size: var(--fs-small); }

.hours { display: grid; gap: 0.4rem; font-size: var(--fs-small); }
.hours div { display: flex; justify-content: space-between; gap: var(--s-sm); border-bottom: 1px solid var(--rule); padding-bottom: 0.4rem; }
.hours div:last-child { border-bottom: 0; }

/* ══════════════════════════════════════════════════════════ REVIEWS PAGE */
.reviews-page-head {
  padding-top: var(--s-md);
  padding-bottom: var(--section);
}
.reviews-page-head .lede { margin-top: var(--s-md); }
.reviews-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2xs);
  margin-top: var(--s-lg);
}

.reviews-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-sm);
  padding-bottom: var(--s-lg);
}
.reviews-count {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  color: var(--text-muted);
}
.reviews-count strong {
  font-family: var(--font-display);
  font-size: 2.25rem;
  font-weight: 400;
  line-height: 1;
  color: var(--accent);
}
.reviews-count span {
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
}

/* Masonry-ish columns rather than a grid: reviews are wildly uneven in length
   — two words to five sentences — and a row grid would leave craters. */
.review-grid { display: grid; gap: var(--s-sm); }
.review-grid .review { flex: none; width: auto; scroll-snap-align: none; }

.reviews-cta { margin-top: var(--s-lg); }

@media (min-width: 46rem) {
  .review-grid { grid-template-columns: repeat(2, 1fr); align-items: start; }
}
@media (min-width: 72rem) {
  .review-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ══════════════════════════════════════════════════ DESKTOP (≥1024px) */
@media (min-width: 640px) {
  .info-grid { grid-template-columns: repeat(3, 1fr); }
  .contact-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .pdp-head {
    grid-template-columns: 0.9fr 1fr;
    gap: var(--s-2xl);
    align-items: start;
  }
  /* The art rides along while the specification column scrolls, so the price
     and the button never leave the screen on a long page. */
  .pdp-art { position: sticky; top: calc(var(--nav-h) + var(--s-md)); }
  .pdp-buy .btn--block { width: auto; display: inline-flex; }

  .pdp-cols { grid-template-columns: 1.35fr 1fr; gap: var(--s-2xl); }
  .pdp-spec { grid-template-columns: repeat(3, 1fr); }

  .crosslink-art { width: 7rem; }
  .page-head .lede { font-size: 1.5rem; max-width: 32ch; }
}


/* ═══════════════════════════════════════════════════════════════════ FAQ
   Two columns of question-and-answer on the paper layer, everything open.
   The rule sits above each question rather than between pairs, so a column
   that breaks unevenly still reads as a list of questions rather than as a
   grid that lost a cell. */
.faq-head { margin: var(--s-md) 0 var(--s-xl); max-width: 14ch; }

.faq {
  display: grid;
  gap: var(--s-lg) var(--s-2xl);
  margin: 0;
}
.faq-item { border-top: 1px solid var(--rule); padding-top: var(--s-sm); }

.faq-q {
  font-family: var(--font-display);
  font-size: 1.3rem;
  line-height: 1.24;
  /* Display type at this line-height clips its own descenders inside the
     grid row; the allowance is cancelled by the margin so spacing is unchanged. */
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
  color: var(--text);
}
.faq-a {
  margin: var(--s-2xs) 0 0;
  font-size: var(--fs-small);
  line-height: 1.62;
  color: var(--text-muted);
  max-width: 46ch;
  text-wrap: pretty;
}

.faq-foot {
  margin-top: var(--s-xl);
  padding-top: var(--s-md);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-small);
}

@media (min-width: 46rem) {
  .faq { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .faq-q { font-size: 1.5rem; }
}

/* The prepaid line sits directly under the price, before the stock line, so
   the two numbers a customer is weighing up are next to each other. */
.pdp-prepaid {
  margin: calc(var(--s-2xs) * -1) 0 var(--s-sm);
}

/* ── Policy pages ────────────────────────────────────────────────────────
   The four routes compliance §13–§16 requires, plus the story page, all run
   through partials/policy-page.php. `.prose` already sets the measure and the
   heading scale; these rules only do the one thing prose cannot, which is
   separate a long page into sections a reader can scan and stop at.

   A policy page is read by someone looking for one specific answer — what it
   costs, how many days, who to call. Long unbroken prose fails that reader
   even when every sentence in it is correct, so the section rule is doing
   real work rather than decoration. */
.policy .policy-section {
  padding-top: var(--s-lg);
  border-top: 1px solid var(--rule, rgba(28, 38, 31, 0.14));
  margin-top: var(--s-lg);
}
.policy .policy-section:first-child {
  padding-top: 0;
  border-top: 0;
  margin-top: 0;
}
.policy .policy-section h2 {
  margin-top: 0;
}
/* A policy that opens with a bold sentence is one someone can act on without
   reading the rest — the answer first, the qualifications after. */
.policy .policy-section p strong:first-child {
  color: var(--charcoal, #1C261F);
}

/* ── Product gallery ─────────────────────────────────────────────────────
   A strip of photographs on the product pages. Two layouts from one markup,
   the same way the rest of the site works: a scroll-snapping row on a phone,
   a grid on a wide screen, diverging at the 1024px line everything else uses.

   Nothing here hides anything. Every frame is painted from first load; the
   only thing CSS decides is whether they sit side by side or in a row you
   push with your thumb. That is deliberate — a gallery that needs script to
   show its second photograph is a gallery with one photograph for anyone
   whose script did not load (§4). */
.pdp-gallery .gallery-strip {
  /* Belt and braces: whatever else this element picks up, it must never be
     promoted to its own compositor layer. `will-change` on a scroll container
     full of large images is what stopped the browser lazy-loading the frames
     it could not see. */
  will-change: auto !important;
  transform: none !important;
  list-style: none;
  margin: var(--s-lg) 0 0;
  padding: 0 0 var(--s-xs);
  display: flex;
  gap: var(--s-sm);
  overflow-x: auto;
  /* `proximity`, not `mandatory`. A mandatory snap container has to land on a
     snap point after every gesture, and when it cannot resolve one it keeps
     trying — which is a documented way to leave a page's input handling out of
     step with its scroll position, looking fine and answering no clicks until
     a reload. `proximity` snaps when a frame is already close and otherwise
     lets the scroll rest wherever the thumb left it. The feel is nearly
     identical; the failure mode is gone. */
  scroll-snap-type: x proximity;
  /* Bleed the strip to the screen edge on a phone so a half-visible next
     frame tells the reader there is more, then pad it back to the text
     margin. Without this the row stops dead at the column edge and reads as
     a finished set of two. */
  margin-inline: calc(var(--gutter, 1.25rem) * -1);
  padding-inline: var(--gutter, 1.25rem);
  scroll-padding-inline: var(--gutter, 1.25rem);
  /* No `-webkit-overflow-scrolling: touch`. It has done nothing on iOS since
     13 — momentum scrolling is the default now — and the old implementation
     put the scroller on its own compositor layer, which is the other well-worn
     way a nested horizontal scroller leaves the page underneath unresponsive. */
  scrollbar-width: thin;
}
.pdp-gallery .gallery-item {
  flex: 0 0 min(78%, 20rem);
  scroll-snap-align: start;
  margin: 0;
  /* Nothing here may be transformed. The reveal now runs on the strip as a
     whole (see the markup), not on each frame, for two reasons.

     The bug: transformed children inside a scroll-snap container give the
     browser snap positions that move under it while it is trying to snap to
     them — the same family as the clip-path that made a figure invisible to
     its own IntersectionObserver (§7.7). A state that animates must not sit on
     the element another mechanism is measuring.

     The design: per-frame reveals were also just wrong for a scroller. A frame
     off to the right stayed at opacity 0 until it was scrolled to, so the
     reader swiped towards something invisible and then watched it fade in.
     The strip arrives as one thing; the frames are simply there. */
}
.pdp-gallery figure { margin: 0; }

.pdp-gallery .gallery-frame {
  /* One ratio for frames shot at three — 2:3, 3:4 and 4:5 — so the row has a
     steady baseline instead of a ragged one. `object-fit: cover` crops rather
     than squashes, and the subject is centred in every frame. */
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 14px;
  background: var(--oat, #EAE3D2);
}
.pdp-gallery .gallery-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.pdp-gallery figcaption {
  margin-top: var(--s-2xs);
  font-size: 0.94rem;
  line-height: 1.55;
  color: var(--muted, #676D66);
  max-width: 34ch;
}
.pdp-gallery .gallery-note {
  margin-top: var(--s-md);
  font-size: 0.9rem;
}

@media (min-width: 1024px) {
  .pdp-gallery .gallery-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--s-md);
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
  .pdp-gallery .gallery-item { flex: none; }
}

/* Someone who has asked for less motion still gets the photographs; they just
   arrive already in place. The strip stays scrollable either way. */
@media (prefers-reduced-motion: reduce) {
  .pdp-gallery .gallery-strip { scroll-behavior: auto; }
}
.pdp-gallery .gallery-head { margin-bottom: var(--s-xs); }
