/* ==========================================================================
   Wholesome Labs — Components
   Reusable branded sections: hero, trust strip, cards, badges, documentation,
   accordions, disclaimers, empty states, research-use gate.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero — home page

   Three layers, and the first two are a pair: the translucent still, an ivory
   wash over the top of it, then the content grid. The wash is what buys the
   headline its contrast, so raising the still's opacity without deepening the
   wash is the thing that will break legibility here.
   -------------------------------------------------------------------------- */

.wl-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--wl-ivory);
  border-bottom: var(--wl-border);
}

.wl-hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.wl-hero__backdrop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 42%;
  opacity: 0.62;
}

.wl-hero__backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      96deg,
      rgba(247, 243, 234, 0.97) 0%,
      rgba(247, 243, 234, 0.93) 26%,
      rgba(247, 243, 234, 0.6) 50%,
      rgba(247, 243, 234, 0.24) 76%,
      rgba(247, 243, 234, 0.4) 100%
    ),
    linear-gradient(
      to bottom,
      rgba(247, 243, 234, 0.55) 0%,
      rgba(247, 243, 234, 0) 24%,
      rgba(247, 243, 234, 0) 70%,
      rgba(247, 243, 234, 0.72) 100%
    );
}

.wl-hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  /* Match an alignwide block exactly. The hero used to carry its own
     narrower gutter, which was invisible while wideSize was 1240 and every
     container hit its cap. Once wideSize grew, the hero text sat 16px left
     of everything below it. Adding the gutter to the cap means the content
     box lands on wideSize, exactly where alignwide sits, at any viewport. */
  max-width: calc(var(--wp--style--global--wide-size, 1600px) + 2 * var(--wl-gutter));
  margin-inline: auto;
  padding-block: clamp(2.75rem, 6.5vw, 5rem);
  padding-inline: var(--wl-gutter);
}

/* The lockup is the welcome. It carries the brand at a size the 58px header
   mark never can, and the headline sits underneath as support rather than
   competing with it for the same job. */
.wl-hero__logo {
  margin: 0 0 clamp(1.25rem, 2.6vw, 2rem);
}

.wl-hero__logo img {
  width: clamp(215px, 25vw, 335px);
  height: auto;
  max-width: 100%;
}

.wl-hero__title {
  margin: 0;
  font-size: clamp(2rem, 4.4vw, 3.25rem);
  line-height: 1.08;
  letter-spacing: -0.005em;
}

.wl-hero__sub {
  margin: 1.25rem 0 0;
  max-width: 46ch;
  font-size: clamp(1rem, 1.4vw, 1.0625rem);
  line-height: 1.75;
  color: var(--wl-warm-gray);
}

.wl-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: clamp(1.5rem, 3vw, 2.1rem);
}

/* Credibility rail. It spans both columns rather than sitting under the CTAs:
   in one column the longest chip wrapped onto three lines, and a rail under the
   whole hero ties the copy and the film together instead of leaving them as two
   unrelated halves. Stacked, it lands last, which is also where it belongs. */
.wl-hero__chips {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem 2.25rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.25rem, 2.4vw, 1.75rem);
  border-top: 1px solid rgba(214, 208, 197, 0.7);
}

.wl-hero__chips span {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--wl-warm-gray);
}

.wl-hero__chips svg { width: 15px; height: 15px; color: var(--wl-eucalyptus); flex: none; }

/* The film -------------------------------------------------------------- */

.wl-hero__media {
  position: relative;
  margin: 0;
}

/* A hairline panel offset behind the frame, so the film reads as placed on the
   page rather than pasted onto it. Gold is punctuation here and nothing more. */
.wl-hero__media::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: clamp(12px, 2vw, 22px);
  left: clamp(12px, 2vw, 22px);
  right: calc(-1 * clamp(12px, 2vw, 22px));
  bottom: calc(-1 * clamp(12px, 2vw, 22px));
  border: 1px solid rgba(212, 178, 114, 0.55);
  border-radius: 22px;
  pointer-events: none;
}

.wl-hero__frame {
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid rgba(214, 208, 197, 0.9);
  background: var(--wl-ivory-soft);
  box-shadow:
    0 30px 60px -32px rgba(31, 59, 46, 0.45),
    0 4px 14px -8px rgba(31, 59, 46, 0.14);
  /* The film is 16:9. Cropping it to 5:4 keeps the vial and the pedestal and
     trims empty wall off the edges, which is what lets the panel stand as tall
     as the copy column beside it. */
  aspect-ratio: 5 / 4;
}

.wl-hero__film {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--wl-ivory-soft);
}

@media (max-width: 980px) {
  .wl-hero__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2rem, 6vw, 2.75rem);
  }

  /* Stacked, the horizontal wash has nothing left to protect: the copy now
     sits over the top of the still rather than beside it. */
  .wl-hero__backdrop::after {
    background: linear-gradient(
      to bottom,
      rgba(247, 243, 234, 0.95) 0%,
      rgba(247, 243, 234, 0.88) 42%,
      rgba(247, 243, 234, 0.55) 72%,
      rgba(247, 243, 234, 0.8) 100%
    );
  }

  .wl-hero__backdrop img { object-position: 58% 28%; }

  .wl-hero__frame { aspect-ratio: 16 / 10; }

  .wl-hero__media::before { display: none; }
}

@media (max-width: 560px) {
  .wl-hero__logo img { width: min(230px, 72vw); }
  .wl-hero__chips { gap: 0.65rem 1.25rem; }
}

/* Card actions: the quiet "view details" link sits under the add-to-cart. */
.wl-card-viewwrap { margin: 0; }
/* --------------------------------------------------------------------------
   Trust strip — reusable across home, product, cart, checkout
   -------------------------------------------------------------------------- */

/* The default ("band") used to run edge to edge with a rule top and bottom.
   It now sits on the content width as a rounded panel, so it lines up with the
   cards and column rows around it instead of cutting the page in half.
   --panel is the same shape in mist, used on checkout. */
.wl-trust {
  background: var(--wl-white);
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
}

.wl-trust--plain { background: transparent; border: 0; }
.wl-trust--panel {
  background: var(--wl-mist);
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
}

.wl-trust__inner {
  max-width: var(--wp--style--global--wide-size, 1240px);
  margin-inline: auto;
  padding: 1.5rem;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1.25rem 1.5rem;
}

.wl-trust--panel .wl-trust__inner { padding-inline: 1.5rem; }

.wl-trust__item {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--wl-ink);
}

.wl-trust__item svg {
  flex: none;
  width: 19px;
  height: 19px;
  color: var(--wl-eucalyptus);
  margin-top: 1px;
}

.wl-trust__item strong {
  display: block;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.wl-trust__item span {
  display: block;
  color: var(--wl-warm-gray);
  font-size: 0.75rem;
  margin-top: 2px;
}

/* Stacked variant for narrow columns (cart / checkout sidebar). */
.wl-trust--stack .wl-trust__inner { grid-template-columns: 1fr; gap: 1rem; }

@media (max-width: 1024px) {
  .wl-trust__inner { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .wl-trust__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
  .wl-trust__item span { display: none; }
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.wl-card {
  background: var(--wl-white);
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  box-shadow: var(--wl-shadow-soft);
  height: 100%;
}

.wl-card h3 { margin: 0 0 0.6rem; font-size: 1.25rem; }
.wl-card p  { margin: 0; color: var(--wl-warm-gray); line-height: 1.7; font-size: 0.9375rem; }

.wl-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--wl-radius);
  background: var(--wl-sage-pale);
  color: var(--wl-forest);
  margin-bottom: 1.15rem;
}

.wl-card__icon svg { width: 21px; height: 21px; }

/* Grid wrappers */
.wl-grid { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
.wl-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wl-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wl-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 900px) {
  .wl-grid--3, .wl-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
  .wl-grid--2, .wl-grid--3, .wl-grid--4 { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Badges
   -------------------------------------------------------------------------- */

.wl-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--wl-radius-pill);
  font-family: var(--wl-sans);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.3;
  white-space: nowrap;
}

.wl-badge svg { width: 12px; height: 12px; flex: none; }

/* Research use only — present but calm, never alarming. */
.wl-badge--ruo {
  background: var(--wl-sage-pale);
  color: var(--wl-forest-deep);
  border: 1px solid rgba(110, 143, 130, 0.32);
}

/* Documentation available */
.wl-badge--doc {
  background: rgba(212, 178, 114, 0.16);
  color: #7A5E24;
  border: 1px solid rgba(212, 178, 114, 0.45);
}

/* Neutral / category */
/* The COA badge is a link. Without these it inherits the global link colour and
   underline and stops reading as a badge at all. */
a.wl-badge {
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

a.wl-badge--doc:hover,
a.wl-badge--doc:focus-visible {
  background: rgba(212, 178, 114, 0.3);
  border-color: rgba(212, 178, 114, 0.8);
  color: #5F4718;
}
.wl-badge--neutral {
  background: var(--wl-mist);
  color: var(--wl-warm-gray);
  border: 1px solid var(--wl-stone);
}

.wl-badgerow { display: flex; flex-wrap: wrap; gap: 0.45rem; }

/* --------------------------------------------------------------------------
   Process steps
   -------------------------------------------------------------------------- */

.wl-steps { counter-reset: wl-step; }

.wl-step { position: relative; padding-top: 2.5rem; }

.wl-step::before {
  counter-increment: wl-step;
  content: counter(wl-step, decimal-leading-zero);
  position: absolute;
  top: 0;
  left: 0;
  font-family: var(--wl-serif);
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--wl-gold);
  line-height: 1;
}

.wl-step::after {
  content: "";
  position: absolute;
  top: 10px;
  left: 2.6rem;
  right: 0;
  height: 1px;
  background: var(--wl-stone);
}

.wl-step:last-child::after { display: none; }

.wl-step h3 { margin: 0 0 0.5rem; font-size: 1.125rem; }
.wl-step p  { margin: 0; font-size: 0.9375rem; color: var(--wl-warm-gray); line-height: 1.7; }

@media (max-width: 900px) {
  .wl-step::after { display: none; }
}

/* --------------------------------------------------------------------------
   Documentation / COA
   -------------------------------------------------------------------------- */

/* Mist is a cool grey (red minus blue is -2) and the page is warm cream (+13),
   so the panel read as a dirty grey patch rather than a raised surface.
   ivory-soft sits in the same warm family as the page, and the border is what
   defines the edge. Shared with the COA panel on product pages. */
.wl-doc {
  background: var(--wl-ivory-soft);
  border: 1px solid rgba(110, 143, 130, 0.32);
  border-radius: var(--wl-radius-lg);
  padding: clamp(1.25rem, 3vw, 1.75rem);
}

.wl-doc__head {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-bottom: 1rem;
}

.wl-doc__head svg { width: 20px; height: 20px; color: var(--wl-eucalyptus); flex: none; }

.wl-doc__head h3 {
  margin: 0;
  font-family: var(--wl-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--wl-forest);
}

.wl-doc__meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 0.9rem 1.5rem;
  margin-bottom: 1.25rem;
}

.wl-doc__meta dt {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--wl-warm-gray);
  margin-bottom: 0.3rem;
}

.wl-doc__meta dd {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.8125rem;
  color: var(--wl-ink);
}

.wl-doc__meta dd.is-empty { color: var(--wl-taupe); font-style: italic; font-family: var(--wl-sans); }

/* Documentation library rows */
.wl-doclist { display: grid; gap: 0.75rem; }

/* One track definition for the header row and the data rows, or the column
   labels drift out of line with the values under them.

   The last track is a fixed width rather than auto. The header has no action
   button in that cell, so an auto track collapses to nothing there and hands
   its width back to the fr tracks, making every header track slightly wider
   than the matching one in the rows. The drift accumulates left to right and
   is obvious by the last column. */
.wl-doclist,
.wl-doclist__head {
  --wl-doclist-cols:
    minmax(0, 2.4fr) minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr) 4.75rem;
}

.wl-docrow {
  display: grid;
  grid-template-columns: var(--wl-doclist-cols);
  align-items: center;
  gap: 1rem;
  background: var(--wl-white);
  border: var(--wl-border);
  border-radius: var(--wl-radius);
  padding: 1rem 1.25rem;
  transition: border-color 0.2s var(--wl-ease), box-shadow 0.2s var(--wl-ease);
}

.wl-docrow:hover { border-color: var(--wl-sage); box-shadow: var(--wl-shadow-soft); }

/* Every track must be allowed to shrink or the nowrap document badge spills
   over the neighbouring column. */
.wl-docrow > * { min-width: 0; }

.wl-docrow .wl-badge {
  white-space: normal;
  text-align: center;
  line-height: 1.35;
}

.wl-docrow__name { font-weight: 600; font-size: 0.9375rem; color: var(--wl-ink); }
.wl-docrow__name small { display: block; font-weight: 400; color: var(--wl-warm-gray); font-size: 0.75rem; margin-top: 2px; }

.wl-docrow__label {
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--wl-warm-gray);
  display: none;
}

.wl-doclist__head {
  display: grid;
  grid-template-columns: var(--wl-doclist-cols);
  gap: 1rem;
  padding: 0 1.25rem 0.5rem;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wl-warm-gray);
}

@media (max-width: 860px) {
  .wl-doclist__head { display: none; }
  .wl-docrow { grid-template-columns: 1fr; gap: 0.6rem; }
  .wl-docrow__label { display: block; }
  .wl-docrow > a { justify-self: start; }
}

/* --------------------------------------------------------------------------
   Specification table (product details)
   -------------------------------------------------------------------------- */

.wl-spec {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.wl-spec th,
.wl-spec td {
  text-align: left;
  padding: 0.85rem 0;
  border-bottom: var(--wl-border-soft);
  vertical-align: top;
}

.wl-spec th {
  width: 38%;
  font-weight: 500;
  color: var(--wl-warm-gray);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

.wl-spec td { color: var(--wl-ink); }
.wl-spec tr:last-child th,
.wl-spec tr:last-child td { border-bottom: 0; }
.wl-spec .is-empty { color: var(--wl-taupe); font-style: italic; }

/* --------------------------------------------------------------------------
   Accordion (native details/summary — keyboard accessible for free)
   -------------------------------------------------------------------------- */

.wl-acc { border-top: var(--wl-border); }

.wl-acc details {
  border-bottom: var(--wl-border);
}

.wl-acc summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.35rem 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--wl-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--wl-ink);
  transition: color 0.2s var(--wl-ease);
}

.wl-acc summary::-webkit-details-marker { display: none; }
.wl-acc summary:hover { color: var(--wl-forest); }

.wl-acc summary::after {
  content: "";
  flex: none;
  width: 11px;
  height: 11px;
  border-right: 1.5px solid var(--wl-warm-gray);
  border-bottom: 1.5px solid var(--wl-warm-gray);
  rotate: 45deg;
  translate: 0 -3px;
  transition: rotate 0.3s var(--wl-ease), border-color 0.2s var(--wl-ease);
}

.wl-acc details[open] > summary::after { rotate: -135deg; translate: 0 2px; }
.wl-acc details[open] > summary { color: var(--wl-forest); }
.wl-acc summary:hover::after { border-color: var(--wl-forest); }

.wl-acc__body {
  padding: 0 0 1.5rem;
  max-width: 68ch;
  color: var(--wl-warm-gray);
  line-height: 1.75;
  font-size: 0.9375rem;
}

.wl-acc__body > *:first-child { margin-top: 0; }
.wl-acc__body > *:last-child  { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Research-use disclaimer block
   -------------------------------------------------------------------------- */

/* Sage fill, to give the disclaimer presence without spending gold on a large
   area -- the brand keeps gold as punctuation. Sage sits at almost exactly the
   same lightness as gold, so the box separates from the ivory page just as
   strongly; sage-pale was the other candidate but is light enough to fade back
   into the page. Everything inside is forest-toned: body text measures 5.8:1 on
   sage, the secondary line 4.6:1. */
.wl-disclaimer {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  background: var(--wl-sage);
  border: 1px solid rgba(31, 59, 46, 0.24);
  border-left: 3px solid var(--wl-forest-deep);
  border-radius: var(--wl-radius);
  padding: 1.15rem 1.35rem;
}

.wl-disclaimer svg {
  flex: none;
  width: 18px;
  height: 18px;
  color: var(--wl-forest-deep);
  margin-top: 2px;
}

.wl-disclaimer p {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--wl-forest-deep);
}

.wl-disclaimer a {
  color: var(--wl-forest-deep);
  text-decoration-color: rgba(31, 59, 46, 0.55);
}

.wl-disclaimer a:hover { text-decoration-color: var(--wl-forest-deep); }

.wl-disclaimer strong { font-weight: 600; }

.wl-disclaimer em {
  display: block;
  margin-top: 0.45rem;
  color: var(--wl-forest);
  font-size: 0.75rem;
}

.wl-disclaimer--compact { padding: 0.85rem 1rem; }
.wl-disclaimer--compact p { font-size: 0.75rem; }

/* --------------------------------------------------------------------------
   Volume pricing

   Deliberately a table rather than the row of cards the reference sites use:
   there are six rows counting the base price, and six cards across a product
   column would set each one about 90px wide. A table also lets the per-vial
   figures sit in a column the eye can run down, which is the number a buyer is
   actually comparing.
   -------------------------------------------------------------------------- */

.wl-volume {
  margin-top: 1.25rem;
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
  background: var(--wl-white);
  overflow: hidden;
}

.wl-volume__head {
  padding: 1.1rem 1.25rem 0.9rem;
  border-bottom: var(--wl-border);
  background: var(--wl-ivory-soft);
}

.wl-volume__head h3 {
  margin: 0;
  font-family: var(--wl-sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wl-forest);
}

.wl-volume__head p {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--wl-warm-gray);
}

.wl-volume__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.wl-volume__table th,
.wl-volume__table td {
  padding: 0.65rem 1.25rem;
  text-align: left;
  vertical-align: middle;
}

.wl-volume__table thead th {
  font-family: var(--wl-sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--wl-warm-gray);
  padding-block: 0.6rem;
  border-bottom: 1px solid var(--wl-stone);
}

.wl-volume__table tbody tr + tr { border-top: 1px solid rgba(214, 208, 197, 0.6); }

.wl-volume__table tbody th {
  font-family: var(--wl-sans);
  font-weight: 600;
  color: var(--wl-ink);
  white-space: nowrap;
}

.wl-volume__table td { color: var(--wl-ink); }
.wl-volume__table td .woocommerce-Price-amount { font-variant-numeric: tabular-nums; }

/* The unit column.

   Tinted and set in the brand green rather than left as another grey number:
   on a compound sold in three strengths it is the only figure in the table
   that stays comparable as both the size and the tier change, so it should be
   the one the eye lands on. */
/* Filled, not tinted. At 9% opacity this column was technically highlighted
   and practically invisible; the figure it carries is the one worth looking at,
   so it gets a real block of colour and a dark cap to head it. */
.wl-volume__table .wl-volume__unitcol { background: var(--wl-sage-pale); }

.wl-volume__table td.wl-volume__unitcol {
  font-weight: 600;
  color: var(--wl-forest-deep);
}

.wl-volume__table thead th.wl-volume__unitcol {
  background: var(--wl-forest);
  color: var(--wl-ivory);
}

/* The discount pills sit in the next column and are also sage-pale. Against a
   solid sage-pale neighbour they lost their edge, so on this table they take
   the deeper sage instead. */
.wl-volume__table .wl-volume__save {
  background: var(--wl-sage);
  color: var(--wl-forest-deep);
}

.wl-volume__base {
  font-size: 0.75rem;
  color: var(--wl-warm-gray);
}

.wl-volume__save {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--wl-sage-pale);
  color: var(--wl-forest-deep);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* Four columns on a phone. The table is worth keeping whole rather than
   collapsing to stacked rows — comparing down a column is the whole point of
   it — so the padding gives way instead. */
@media (max-width: 560px) {
  .wl-volume__head { padding-inline: 1rem; }

  .wl-volume__table th,
  .wl-volume__table td { padding-inline: 0.55rem; }

  .wl-volume__table { font-size: 0.75rem; }
  .wl-volume__table thead th { font-size: 0.625rem; letter-spacing: 0.06em; }

  .wl-volume__save {
    padding-inline: 0.4rem;
    font-size: 0.625rem;
    letter-spacing: 0;
  }
}
/* --------------------------------------------------------------------------
   FAQ section chips

   The same pill as .wl-badge--ruo, but at heading scale: these are still
   section headings, so they keep the serif face and their size in the type
   scale rather than being demoted to badge-sized uppercase sans.

   inline-block so the pill hugs its own text instead of running the width of
   the column, and the margins are set explicitly because the block gap the
   layout would otherwise supply does not leave enough air around a filled
   shape.
   -------------------------------------------------------------------------- */

.wl-faq-section {
  display: inline-block;
  margin-block: clamp(2.25rem, 4.5vw, 3.25rem) 1.1rem;
  padding: 0.5rem 1.4rem;
  border-radius: var(--wl-radius-pill);
  background: var(--wl-sage-pale);
  color: var(--wl-forest-deep);
  border: 1px solid rgba(110, 143, 130, 0.32);
  font-size: clamp(1.2rem, 2.3vw, 1.5rem);
  /* 700 is real here, not synthesised: the Cormorant face is declared 400-700
     in theme.json (see DESIGN-NOTES 14). The axis is gentle, so the step from
     500 reads as firm rather than heavy. */
  font-weight: 700;
  line-height: 1.35;
}

/* The first one follows the page intro, which already carries its own space. */
.wl-faq-section:first-child { margin-block-start: 0; }
/* The support panel was justified for a while. Reverted — don't put it back.

   The column is about 30 characters wide, which is too narrow for justified
   text: the browser has almost no words to distribute the slack across, so it
   opens visible gaps between them and rivers run down the paragraph. Even with
   automatic hyphenation on it read as gappy. Ragged right is the correct
   setting at this measure, and it is the default, so there is no rule here. */
/* --------------------------------------------------------------------------
   Notices

   The contact form used to borrow WooCommerce's .wc-block-components-notice-
   banner class. That styling only ships with the cart and checkout bundles, so
   on the contact page the banner arrived unstyled and its icon blew up to the
   full width of the panel. A form the theme owns gets a notice the theme owns.
   -------------------------------------------------------------------------- */

.wl-notice {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  margin: 0 0 1.5rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--wl-stone);
  border-left: 3px solid var(--wl-eucalyptus);
  border-radius: var(--wl-radius);
  background: var(--wl-white);
  box-shadow: var(--wl-shadow-soft);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--wl-ink);
}

/* Always give an inline SVG an explicit size inside a flex row. Without one it
   has no intrinsic size to lay out against, and flex:none stops it shrinking. */
.wl-notice > svg {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  color: var(--wl-eucalyptus);
}

.wl-notice p { margin: 0; }

.wl-notice--success { background: var(--wl-mist); border-left-color: var(--wl-forest); }
.wl-notice--success > svg { color: var(--wl-forest); }

.wl-notice--error { background: #FBF3F1; border-left-color: #A8503F; }
.wl-notice--error > svg { color: #A8503F; }

/* Not an error — a lot that did not match is usually a typo, not a fault. Gold
   rather than red keeps it as information. */
.wl-notice--warn { background: rgba(212, 178, 114, 0.12); border-left-color: var(--wl-gold); }
.wl-notice--warn > svg { color: #A8813C; }
.wl-notice--warn p + p { margin-top: 0.5rem; }

/* --------------------------------------------------------------------------
   Credibility tabs
   --------------------------------------------------------------------------

   Every panel is in the markup and visible by default. site.js adds
   `is-enhanced`, and only then does the group behave as tabs. Without
   JavaScript the five claims read as a stacked list rather than vanishing --
   they are the page's proof, so they degrade to plain text, not to nothing.
   -------------------------------------------------------------------------- */

.wl-trusttabs__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.wl-trusttabs__tab {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--wl-stone);
  border-radius: var(--wl-radius-pill);
  background: var(--wl-ivory-soft);
  font-family: var(--wl-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--wl-ink);
  cursor: pointer;
  transition: background-color 0.2s var(--wl-ease), border-color 0.2s var(--wl-ease),
    color 0.2s var(--wl-ease);
}

.wl-trusttabs__tab svg { width: 15px; height: 15px; flex: none; color: var(--wl-eucalyptus); }

.wl-trusttabs__tab:hover { border-color: var(--wl-sage); background: var(--wl-sage-pale); }

.wl-trusttabs__tab.is-active {
  background: var(--wl-forest);
  border-color: var(--wl-forest);
  color: var(--wl-ivory);
}

.wl-trusttabs__tab.is-active svg { color: var(--wl-gold); }

.wl-trusttabs__panel {
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
  background: var(--wl-white);
  padding: clamp(1.25rem, 3vw, 1.85rem);
}

/* Stacked, until the script says otherwise. */
.wl-trusttabs__panel + .wl-trusttabs__panel { margin-top: 0.75rem; }

.wl-trusttabs.is-enhanced .wl-trusttabs__panel { display: none; margin-top: 0; }
.wl-trusttabs.is-enhanced .wl-trusttabs__panel.is-active { display: block; }

.wl-trusttabs__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.85rem;
  margin-bottom: 0.7rem;
}

.wl-trusttabs__head h3 {
  margin: 0;
  font-size: 1.25rem;
  color: var(--wl-forest-deep);
}

.wl-trusttabs__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.65rem;
  border-radius: var(--wl-radius-pill);
  background: var(--wl-sage-pale);
  color: var(--wl-forest-deep);
  font-family: var(--wl-sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.wl-trusttabs__badge svg { width: 12px; height: 12px; color: var(--wl-eucalyptus); }

.wl-trusttabs__body {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--wl-warm-gray);
}

.wl-trusttabs__cards { margin-top: 1rem; }

/* The payoff line. Gold rule rather than sage: it is the one sentence in the
   panel written for the reader rather than about the process. */
.wl-trusttabs__why {
  margin: 1.1rem 0 0;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--wl-gold);
  border-radius: 0 var(--wl-radius) var(--wl-radius) 0;
  background: var(--wl-ivory-soft);
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--wl-ink);
}

.wl-trusttabs__why strong { color: var(--wl-forest-deep); }

/* On a phone the five pills used to be one horizontally scrolling row. The
   theory was that a label cut off mid-pill advertises the scroll; in practice
   the last two headlines sat off-screen and went unread, which is the whole
   point of the rail lost. Reported from a real phone, so the affordance was
   not one.

   Stacked full-width rows instead. Every label is visible at once, there is
   nothing to swipe sideways, and the open panel sits directly beneath a list
   only five rows tall. The tablist markup is untouched -- this is entirely a
   layout change, so roles, arrow keys and the roving tabindex all still work
   exactly as they do on desktop. */
@media (max-width: 700px) {
  .wl-trusttabs__tabs {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0.45rem;
    margin-bottom: 0.9rem;
  }

  .wl-trusttabs__tab {
    width: 100%;
    /* Left-aligned rather than centred: five centred labels of different
       lengths have no common edge for the eye to run down. */
    justify-content: flex-start;
    padding: 0.75rem 1rem;
    border-radius: var(--wl-radius);
    font-size: 0.8125rem;
  }

  .wl-trusttabs__tab svg { width: 15px; height: 15px; }
}

/* --------------------------------------------------------------------------
   Lot lookup
   --------------------------------------------------------------------------

   A plain GET form. The lot ends up in the URL, so a result is shareable,
   linkable from the QR code on a label, and cacheable — none of which is true
   of a form that posts. No JavaScript either: the person using this is often
   standing at a bench holding a vial.
   -------------------------------------------------------------------------- */

.wl-lotfind {
  margin: 0 0 1.75rem;
  padding: 1.2rem 1.35rem 1.1rem;
  background: var(--wl-ivory-soft);
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
}

.wl-lotfind__label {
  display: block;
  margin-bottom: 0.6rem;
  font-family: var(--wl-sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wl-forest);
}

.wl-lotfind__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.wl-lotfind input[type="search"] {
  flex: 1 1 18rem;
  min-width: 0;
  /* Set like the label on the vial, so what is typed can be compared to what
     is being read character by character. */
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.wl-lotfind input[type="search"]::placeholder { text-transform: none; letter-spacing: 0; }

/* Once the button has wrapped below the field it may as well match its width;
   a short button stranded on its own line reads as a leftover. */
@media (max-width: 480px) {
  .wl-lotfind__row .wl-btn { flex: 1 1 100%; }
}

.wl-lotfind__hint {
  margin: 0.7rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--wl-warm-gray);
}

.wl-lotfind__result {
  margin: 0 0 1.1rem;
  font-size: 0.9375rem;
  color: var(--wl-ink);
}

.wl-lotfind__result .wl-mono { font-weight: 600; }

/* --------------------------------------------------------------------------
   Earlier lots, on a product page
   -------------------------------------------------------------------------- */

.wl-doc__earlier {
  margin-top: 1.35rem;
  padding-top: 1.1rem;
  border-top: var(--wl-border);
}

.wl-doc__earlier h4 {
  margin: 0 0 0.7rem;
  font-family: var(--wl-sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wl-warm-gray);
}

.wl-doc__earlier ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.45rem;
}

.wl-doc__earlier li {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  font-size: 0.8125rem;
}

.wl-doc__earlier li .wl-mono { flex: 1 1 auto; }

.wl-doc__earlier-date { color: var(--wl-warm-gray); font-size: 0.75rem; }
/* --------------------------------------------------------------------------
   Empty states
   -------------------------------------------------------------------------- */

.wl-empty {
  text-align: center;
  max-width: 480px;
  margin-inline: auto;
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
}

.wl-empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 1px solid var(--wl-stone);
  background: var(--wl-white);
  color: var(--wl-sage);
  margin-bottom: 1.5rem;
}

.wl-empty__icon svg { width: 26px; height: 26px; }

.wl-empty h2 { margin: 0 0 0.65rem; font-size: 1.5rem; }
.wl-empty p  { margin: 0 0 1.75rem; color: var(--wl-warm-gray); line-height: 1.7; }

.wl-empty__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; }

/* --------------------------------------------------------------------------
   Research-use gate
   -------------------------------------------------------------------------- */

/* A full-screen scene, not a modal over the page. The gate is the first thing
   a visitor sees, so it does the brand's introduction as well as taking the
   acknowledgment.

   The old translucent scrim and backdrop-filter are gone. The field is opaque
   ivory now, which is cheaper to paint and steers clear of backdrop-filter,
   which has already caused one compositing problem in this theme (the fixed
   mobile nav overlay, DESIGN-NOTES 6). */
.wl-gate {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  overflow: hidden;
  background:
    radial-gradient(90% 70% at 50% 6%, rgba(168, 183, 154, 0.24) 0%, rgba(168, 183, 154, 0) 60%),
    radial-gradient(70% 60% at 10% 92%, rgba(110, 143, 130, 0.18) 0%, rgba(110, 143, 130, 0) 62%),
    var(--wl-ivory);
  opacity: 0;
  animation: wl-gate-in 0.45s var(--wl-ease) forwards;
}

@keyframes wl-gate-in { to { opacity: 1; } }

.wl-gate[hidden] { display: none; }

/* The film behind the card.

   One ambient product shot, held deliberately soft. The blur is not a
   compromise, it is the point: it keeps the vial reading as atmosphere rather
   than as a legible label, it stops a background competing with a dialog that
   is asking for two decisions, and as a side effect it means the small file
   the gate downloads never looks under-resolved.

   The poster is on the element from the start; the video is attached by
   site.js only once the gate is open, and only on a screen wide enough for the
   film to be worth the bytes. See inc/research-gate.php. */
.wl-gate__scene {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.wl-gate__film {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The blur has to grow with the viewport, not sit at a fixed pixel count.
     The film is cropped to fill the height, so a taller window magnifies the
     source further and a fixed blur stops hiding the label -- which is the one
     thing it is not allowed to stop doing. See COMPLIANCE.md. */
  filter: blur(clamp(5px, 0.75vh, 16px)) saturate(0.92);
  /* Blur samples past the element's own edges and leaves a soft transparent
     border. Scaling up pushes that outside the box. */
  transform: scale(1.16);
  opacity: 0;
  animation: wl-gate-film-in 1.1s var(--wl-ease) 0.1s forwards;
}

@keyframes wl-gate-film-in { to { opacity: 1; } }

/* The ivory veil. Narrow screens hold the card over the middle of the frame,
   so the veil has to be heavy enough that body text stays comfortable on the
   busiest part of the shot. */
.wl-gate__wash {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      180deg,
      rgba(247, 243, 234, 0.66) 0%,
      rgba(247, 243, 234, 0.48) 40%,
      rgba(247, 243, 234, 0.88) 100%
    ),
    radial-gradient(
      115% 85% at 50% 46%,
      rgba(247, 243, 234, 0.44) 0%,
      rgba(247, 243, 234, 0.9) 100%
    );
}

/* Wide screens: card on the left, film on the right.

   The shot is a centred close-up, so centring the card on top of it would bury
   the only thing worth looking at. Moving the two apart is also what lets the
   veil come down -- nothing is being read through the film any more, so the
   product can actually be seen. This is the same left-copy / right-film
   composition as the home page hero, on purpose. */
@media (min-width: 1040px) {
  .wl-gate {
    justify-items: start;
    padding-inline: clamp(2.5rem, 7vw, 7rem);
  }

  .wl-gate__scene {
    left: 44%;
    /* Feathered rather than cut, so there is no vertical seam down the middle
       of the screen where the photograph stops and the field starts. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 30%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 30%);
  }

  .wl-gate__wash {
    background:
      linear-gradient(90deg, rgba(247, 243, 234, 0.8) 0%, rgba(247, 243, 234, 0) 48%),
      linear-gradient(
        180deg,
        rgba(247, 243, 234, 0.45) 0%,
        rgba(247, 243, 234, 0.08) 34%,
        rgba(247, 243, 234, 0.58) 100%
      );
  }
}

@media (prefers-reduced-motion: reduce) {
  .wl-gate { animation: none; opacity: 1; }

  /* site.js never attaches the video in this case, so this is the poster
     holding still -- the same composition, without the movement. */
  .wl-gate__film { animation: none; opacity: 1; }
}

.wl-gate__panel {
  position: relative;
  z-index: 1;
  width: min(520px, 100%);
  max-height: calc(100dvh - 2.5rem);
  overflow-y: auto;
  background: var(--wl-white);
  border: 1px solid rgba(214, 208, 197, 0.85);
  border-radius: var(--wl-radius-xl);
  /* Two layers, because the card now sits on a photograph rather than on a
     flat field: the tight one draws the edge, the wide one lifts it off. */
  box-shadow:
    0 1px 3px rgba(31, 59, 46, 0.07),
    0 34px 76px -30px rgba(31, 59, 46, 0.45);
  padding: clamp(1.75rem, 5vw, 2.75rem);
  text-align: center;
}

.wl-gate__mark { margin: 0 auto 1.25rem; width: 60px; height: 60px; }
.wl-gate__mark img { width: 100%; height: auto; }

.wl-gate__panel h2 {
  margin: 0 0 0.75rem;
  font-size: 1.625rem;
}

.wl-gate__lede {
  margin: 0 0 1.5rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--wl-warm-gray);
}

/* The two attestations. Each one is its own tile rather than a row in a shared
   box, so a checked statement can be shown as checked — which is the point of
   asking separately instead of running one "I agree" button. */
.wl-gate__checks {
  display: grid;
  gap: 0.6rem;
  margin: 0 0 1.5rem;
  text-align: left;
}

.wl-gate__check {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.85rem 1rem;
  background: var(--wl-ivory-soft);
  border: var(--wl-border);
  border-radius: var(--wl-radius);
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--wl-ink);
  cursor: pointer;
  transition: border-color 0.2s var(--wl-ease), background 0.2s var(--wl-ease);
}

.wl-gate__check:hover { border-color: var(--wl-sage); }
.wl-gate__check:has(input:checked) {
  border-color: var(--wl-eucalyptus);
  background: var(--wl-sage-pale);
}

.wl-gate__check input {
  flex: none;
  width: 17px;
  height: 17px;
  margin: 1px 0 0;
  accent-color: var(--wl-forest);
  cursor: pointer;
}

.wl-gate__check strong { font-weight: 600; color: var(--wl-forest-deep); }

.wl-gate__actions { display: grid; gap: 0.7rem; }

/* Until both boxes are ticked the button is inert. Kept visible rather than
   hidden so it is obvious what ticking them is for. */
.wl-gate__actions .wl-btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.wl-gate__exit {
  margin: 1.1rem 0 0;
  font-size: 0.8125rem;
  color: var(--wl-warm-gray);
}

.wl-gate__exit button,
.wl-gate__leave button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.wl-gate__exit button:hover,
.wl-gate__leave button:hover { color: var(--wl-ink); }

.wl-gate__leave {
  display: flex;
  gap: 1.25rem;
  justify-content: center;
  margin: 1.25rem 0 0;
  font-size: 0.8125rem;
  color: var(--wl-warm-gray);
}

.wl-gate__fine {
  margin: 1.25rem 0 0;
  font-size: 0.6875rem;
  line-height: 1.6;
  color: var(--wl-taupe);
}

.wl-gate__fine a { color: var(--wl-eucalyptus); }

/* Declined view */
.wl-gate__panel[data-view="declined"] .wl-gate__checks,
.wl-gate__panel[data-view="declined"] .wl-gate__actions { display: none; }

body.wl-gate-open { overflow: hidden; }

/* --------------------------------------------------------------------------
   Philosophy / statement band
   -------------------------------------------------------------------------- */

.wl-statement {
  /* Both gaps around the supporting line read off this, so they stay equal.
     60px on desktop, easing down on narrow screens. */
  --wl-statement-gap: clamp(2.5rem, 4.7vw, 3.75rem);

  padding-bottom: var(--wl-statement-gap);
  background: var(--wl-forest-deep);
  color: var(--wl-ivory);
  position: relative;
  overflow: hidden;
}

.wl-statement::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -30%;
  translate: -50% 0;
  width: min(900px, 120vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(168, 183, 154, 0.14) 0%, rgba(168, 183, 154, 0) 62%);
  pointer-events: none;
}

.wl-statement__inner { position: relative; z-index: 1; text-align: center; }

.wl-statement h2 {
  color: var(--wl-ivory);
  font-size: clamp(2rem, 4.5vw, 3.25rem);
  margin: 0;
  line-height: 1.15;
}

.wl-statement p {
  margin: 1.5rem auto 0;
  max-width: 58ch;
  color: rgba(247, 243, 234, 0.72);
  line-height: 1.8;
  font-size: 1.0625rem;
}

/* Sit the supporting line midway between the headline and the foot of the
   panel. It previously carried a 1.5rem top margin against ~90px of bottom
   padding, so it read as tucked under the heading with a dead band beneath.
   Matching --wl-section means the two gaps stay equal at every width,
   because the panel's padding is the same clamp. */
.wl-statement__inner p:not(.wl-eyebrow) {
  margin-top: var(--wl-statement-gap);
}

/* `.wl-statement p` is 0,1,1 and was beating `.wl-eyebrow` on both size and
   line-height, so the eyebrow in this band rendered at the body size with a
   30px line box — larger than the same label everywhere else on the site, by
   accident rather than by design. Restated here so the label is a label. */
.wl-statement .wl-eyebrow {
  color: var(--wl-gold);
  font-size: 0.8125rem;
  line-height: 1.4;
}
.wl-statement .wl-eyebrow::before,
.wl-statement .wl-eyebrow::after { background: rgba(212, 178, 114, 0.6); }

/* Gate: declined state */
.wl-gate__declined { display: none; }
.wl-gate__panel[data-view="declined"] .wl-gate__declined { display: block; }
.wl-gate__panel[data-view="declined"] .wl-gate__intro { display: none; }
.wl-gate__declined p { font-size: 0.9375rem; line-height: 1.7; color: var(--wl-warm-gray); margin: 0 0 1rem; }

/* --------------------------------------------------------------------------
   Contact form
   -------------------------------------------------------------------------- */

.wl-contactform {
  background: var(--wl-white);
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
  padding: clamp(1.5rem, 4vw, 2.25rem);
  box-shadow: var(--wl-shadow-soft);
}

.wl-formgrid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 1.25rem;
}

.wl-field { margin: 0 0 1.15rem; }

.wl-honeypot {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

@media (max-width: 600px) {
  .wl-formgrid { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   core/details rendered inside a .wl-acc wrapper
   -------------------------------------------------------------------------- */

.wl-acc .wp-block-details {
  border-bottom: var(--wl-border);
  padding: 0;
}

.wl-acc .wp-block-details summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.35rem 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--wl-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--wl-ink);
}

.wl-acc .wp-block-details > *:not(summary) {
  max-width: 68ch;
  color: var(--wl-warm-gray);
  line-height: 1.75;
  font-size: 0.9375rem;
  margin-block: 0 1.35rem;
}

.wl-acc .wp-block-details > *:not(summary):last-child { margin-bottom: 1.5rem; }

/* --------------------------------------------------------------------------
   Editorial helpers used by page content
   -------------------------------------------------------------------------- */

.wl-center { text-align: center; }
.wl-center .wl-lede { margin-inline: auto; }

.wl-panel {
  background: var(--wl-white);
  border: var(--wl-border);
  border-radius: var(--wl-radius-lg);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  box-shadow: var(--wl-shadow-soft);
}

.wl-panel--quiet { background: var(--wl-ivory-soft); box-shadow: none; }

/* Newsletter block dropped into the footer */
.wl-footer .wp-block-hostinger-reach-subscription input[type="email"],
.wl-footer .wp-block-hostinger-reach-subscription input[type="text"] {
  background: rgba(247, 243, 234, 0.08);
  border-color: rgba(247, 243, 234, 0.25);
  color: var(--wl-ivory);
}

.wl-footer .wp-block-hostinger-reach-subscription input::placeholder { color: rgba(247, 243, 234, 0.45); }
/* --------------------------------------------------------------------------
   Hostinger Reach subscription block, restyled for the dark footer
   -------------------------------------------------------------------------- */

.wl-footer .hostinger-reach-block-subscription-form-wrapper {
  margin-top: 1.75rem;
  max-width: 320px;
}

.wl-footer .hostinger-reach-block-form-fields {
  display: grid;
  gap: 0.6rem;
}

.wl-footer .hostinger-reach-block-form-field label {
  display: block;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wl-gold);
  margin-bottom: 0.45rem;
}

.wl-footer .hostinger-reach-block-form-field label .required { color: var(--wl-sage); }

.wl-footer .hostinger-reach-block-form-field input[type="email"],
.wl-footer .hostinger-reach-block-form-field input[type="text"] {
  width: 100%;
  background: rgba(247, 243, 234, 0.07);
  border: 1px solid rgba(247, 243, 234, 0.24);
  border-radius: var(--wl-radius-pill);
  color: var(--wl-ivory);
  padding: 0.7rem 1.1rem;
  font-size: 0.875rem;
}

.wl-footer .hostinger-reach-block-form-field input::placeholder { color: rgba(247, 243, 234, 0.42); }

.wl-footer .hostinger-reach-block-form-field input:focus {
  border-color: var(--wl-sage);
  box-shadow: 0 0 0 3px rgba(168, 183, 154, 0.18);
  outline: none;
}

.wl-footer .hostinger-reach-block-submit {
  justify-self: start;
  background: var(--wl-sage) !important;
  color: var(--wl-forest-deep) !important;
  border: 1px solid var(--wl-sage) !important;
  border-radius: var(--wl-radius-pill) !important;
  font-family: var(--wl-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.65rem 1.5rem;
  cursor: pointer;
  transition: background-color 0.2s var(--wl-ease);
}

.wl-footer .hostinger-reach-block-submit:hover {
  background: var(--wl-ivory) !important;
  border-color: var(--wl-ivory) !important;
}

.wl-footer .reach-subscription-message {
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: rgba(247, 243, 234, 0.8);
}

.wl-footer .reach-subscription-message svg path { fill: var(--wl-sage); }

/* --------------------------------------------------------------------------
   Fluent Forms subscription form in the dark footer — successor to the
   Reach block above (Reach rules kept for reference/rollback)
   -------------------------------------------------------------------------- */

.wl-footer .fluentform {
  margin-top: 1.75rem;
  max-width: 320px;
}

.wl-footer .fluentform .ff-t-container {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.wl-footer .fluentform .ff-t-cell { width: 100% !important; }

.wl-footer .fluentform .ff-el-group { margin-bottom: 0; }

.wl-footer .fluentform .ff-el-form-control {
  width: 100%;
  background: rgba(247, 243, 234, 0.07);
  border: 1px solid rgba(247, 243, 234, 0.24);
  border-radius: var(--wl-radius-pill);
  color: var(--wl-ivory);
  padding: 0.7rem 1.1rem;
  font-size: 0.875rem;
}

.wl-footer .fluentform .ff-el-form-control::placeholder { color: rgba(247, 243, 234, 0.42); }

.wl-footer .fluentform .ff-el-form-control:focus {
  border-color: var(--wl-sage);
  box-shadow: 0 0 0 3px rgba(168, 183, 154, 0.18);
  outline: none;
}

.wl-footer .fluentform .ff-btn-submit {
  background: var(--wl-sage) !important;
  color: var(--wl-forest-deep) !important;
  border: 1px solid var(--wl-sage) !important;
  border-radius: var(--wl-radius-pill) !important;
  font-family: var(--wl-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.65rem 1.5rem;
  min-width: 0 !important;
  cursor: pointer;
  transition: background-color 0.2s var(--wl-ease);
}

.wl-footer .fluentform .ff-btn-submit:hover {
  background: var(--wl-ivory) !important;
  border-color: var(--wl-ivory) !important;
  color: var(--wl-forest-deep) !important;
}

.wl-footer .fluentform .ff-message-success {
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: rgba(247, 243, 234, 0.8);
}

.wl-footer .fluentform .ff-el-is-error .text-danger,
.wl-footer .fluentform .error {
  color: var(--wl-gold);
  font-size: 0.75rem;
}

/* --------------------------------------------------------------------------
   Email signup popup (wl-popup) - armed by site.js for settled-in visitors
   -------------------------------------------------------------------------- */

.wl-popup { position: fixed; inset: 0; z-index: 400; display: flex; align-items: center; justify-content: center; padding: 1.25rem; }
.wl-popup[hidden] { display: none; }
.wl-popup__veil { position: absolute; inset: 0; background: rgba(36, 42, 38, 0.55); }
.wl-popup__card { position: relative; background: var(--wl-ivory, #F7F3EA); border-radius: 1rem; box-shadow: var(--wl-shadow-soft, 0 18px 50px rgba(31, 59, 46, 0.18)); max-width: 420px; width: 100%; padding: 2rem 2rem 1.75rem; }
.wl-popup__close { position: absolute; top: 0.75rem; right: 0.9rem; background: none; border: 0; font-size: 1.5rem; line-height: 1; color: var(--wl-warm-gray, #6F726B); cursor: pointer; padding: 0.25rem; }
.wl-popup__close:hover { color: var(--wl-ink, #242A26); }
.wl-popup__eyebrow { font-family: var(--wl-sans); font-size: 0.625rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--wl-gold, #D4B272); margin: 0 0 0.5rem; }
.wl-popup__title { font-size: 1.5rem; margin: 0 0 0.5rem; color: var(--wl-ink, #242A26); }
.wl-popup__lede { font-size: 0.875rem; color: var(--wl-warm-gray, #6F726B); margin: 0 0 1.1rem; }
.wl-popup .fluentform .ff-t-container { display: flex; flex-direction: column; gap: 0.6rem; }
.wl-popup .fluentform .ff-t-cell { width: 100% !important; }
.wl-popup .ff-el-group { margin-bottom: 0; }
.wl-popup .ff-el-form-control { width: 100%; background: #fff; border: 1px solid var(--wl-stone, #D6D0C5); border-radius: var(--wl-radius-pill, 999px); padding: 0.7rem 1.1rem; font-size: 0.875rem; color: var(--wl-ink, #242A26); }
.wl-popup .ff-el-form-control:focus { border-color: var(--wl-sage, #A8B79A); box-shadow: 0 0 0 3px rgba(168, 183, 154, 0.18); outline: none; }
.wl-popup .ff-btn-submit { background: var(--wl-forest, #2E4A3B) !important; color: var(--wl-ivory, #F7F3EA) !important; border: 1px solid var(--wl-forest, #2E4A3B) !important; border-radius: var(--wl-radius-pill, 999px) !important; font-family: var(--wl-sans); font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.02em; padding: 0.65rem 1.5rem; min-width: 0 !important; cursor: pointer; transition: background-color 0.2s var(--wl-ease, ease); }
.wl-popup .ff-btn-submit:hover { background: var(--wl-forest-deep, #1F3B2E) !important; border-color: var(--wl-forest-deep, #1F3B2E) !important; }
.wl-popup .ff-message-success { margin-top: 0.75rem; font-size: 0.8125rem; color: var(--wl-eucalyptus, #6E8F82); }
.wl-popup .ff-el-is-error .text-danger, .wl-popup .fluentform .error { color: #8a5a2b; font-size: 0.75rem; }

@media (max-width: 640px) {
  .wl-popup { align-items: flex-end; padding: 0; }
  .wl-popup__card { border-radius: 1rem 1rem 0 0; max-width: none; }
}