/* ==========================================================================
   Supreme Beings — Coming Soon prototype
   Design tokens
   ========================================================================== */

:root {
  --color-yellow: #FFFF30;
  --color-sky: #6BCAE8;
  --color-navy: #14152D;
  --color-white: #FFFFFF;

  --color-sky-tint: #EAF8FD;
  --color-sky-pale: #EAF6FC;
  --color-sky-deep: #7AACC1;
  --color-navy-soft: #1F2140;
  --ink-muted-on-light: rgba(20, 21, 45, 0.68);
  --ink-muted-on-navy: rgba(255, 255, 255, 0.72);

  --font-body: "degular-text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --container-width: 1180px;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;

  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 28px;
  --radius-pill: 999px;

  --shadow-card: 0 12px 32px rgba(20, 21, 45, 0.08);
  --shadow-lift: 0 20px 48px rgba(20, 21, 45, 0.16);
}

/* ==========================================================================
   Reset
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-navy);
  background: var(--color-white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--color-yellow);
  color: var(--color-navy);
}

img { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

h1, h2, h3, p, figure { margin: 0; }

ul { margin: 0; padding: 0; list-style: none; }

button, input { font-family: inherit; font-size: inherit; }

.container {
  width: 100%;
  max-width: var(--container-width);
  margin-inline: auto;
  padding-inline: var(--space-3);
}

@media (min-width: 768px) {
  .container { padding-inline: var(--space-4); }
}

/* ==========================================================================
   Intro splash
   ========================================================================== */

body.intro-active {
  overflow: hidden;
}

.no-intro .intro-splash {
  display: none;
}

.intro-splash {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-navy);
  overflow: hidden;
  opacity: 1;
  transition: opacity 0.8s ease;
}

.intro-splash[data-hide="true"] {
  opacity: 0;
  pointer-events: none;
}

.intro-splash__content {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.8s ease;
}

.intro-splash__content[data-show="true"] {
  opacity: 1;
}

.intro-splash__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  max-width: none;
}

.intro-splash__content::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(20, 21, 45, 0.28);
  z-index: 1;
}

.intro-splash__logo {
  position: relative;
  z-index: 2;
  width: min(242px, 46.2vw);
  height: auto;
}

/* Faux loading bar — not tied to real load progress, just fills over the
   splash's hold duration so the wait reads as "loading" rather than a
   plain timed hold. Reuses the same [data-show] trigger main.js already
   sets on .intro-splash__content, so no extra JS is needed: the fill
   transition's own duration (3s) is hand-matched to holdMs in main.js. */
.intro-splash__progress {
  position: relative;
  z-index: 2;
  width: 96px;
  height: 2px;
  background: rgba(255, 255, 255, 0.25);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.intro-splash__progress-bar {
  width: 100%;
  height: 100%;
  background: var(--color-white);
  border-radius: var(--radius-pill);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 3s cubic-bezier(0.4, 0, 0.2, 1);
}

.intro-splash__content[data-show="true"] .intro-splash__progress-bar {
  transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
  .intro-splash,
  .intro-splash__content {
    transition: none;
  }

  .intro-splash__progress-bar {
    transition: none;
    transform: scaleX(1);
  }
}

/* Visually-hidden but screen-reader accessible */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-2);
  top: -3rem;
  background: var(--color-yellow);
  color: var(--color-navy);
  padding: 0.6rem 1rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  z-index: 100;
  transition: top 0.15s ease;
}

.skip-link:focus {
  top: var(--space-2);
}

:focus-visible {
  outline: 3px solid var(--color-yellow);
  outline-offset: 2px;
}

/* ==========================================================================
   Ticker band
   ========================================================================== */

.ticker {
  background: var(--color-yellow);
  color: var(--color-navy);
  overflow: hidden;
  white-space: nowrap;
}

.ticker__track {
  display: inline-flex;
  width: max-content;
  animation: ticker-scroll 30s linear infinite;
  padding-block: 0.55rem;
  will-change: transform;
}

.ticker__group {
  display: inline-flex;
  flex-shrink: 0;
}

.ticker__item {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-inline: 1.5rem;
  white-space: nowrap;
  position: relative;
}

.ticker__item::after {
  content: "•";
  position: absolute;
  right: -0.15rem;
}

@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; }
}

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

.site-header {
  position: relative;
  z-index: 60;
  background: var(--color-white);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 1.1rem;
}

@media (min-width: 768px) {
  /* Matches .hero-banner's own edge padding exactly (see below) so the
     logo and nav icon align with the rounded card's left/right edges,
     rather than the site-wide 1180px .container's own (different)
     max-width and padding. */
  .site-header .container {
    max-width: none;
    padding-inline: 30px;
  }
}

.site-header__logo img {
  height: 28.6px;
  width: auto;
}

.site-header__nav {
  position: relative;
  /* Without this, the nav-icon's inline-flex box sits in an inline
     formatting context whose line height (inherited font-size/line-height)
     is taller than the icon itself, adding ~4px of invisible height this
     element doesn't visually need — throwing off exact gap measurements
     around it (e.g. matching the space above/below the header). */
  display: flex;
}

.nav-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 49.3px;
  height: 49.3px;
  border: 2.55px solid var(--color-navy);
  border-radius: 8.5px;
  background: var(--color-white);
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.nav-icon:hover {
  background: var(--color-sky-tint);
}

.nav-icon__bar {
  position: absolute;
  left: 0;
  top: 0;
  height: 2.55px;
  background: var(--color-navy);
  border-radius: 1.7px;
  transition: transform 0.15s ease;
}

/* Geometry below comes from the actual "Hamburger-Icon" component set in
   Figma's design-system library (get_context_for_code_connect was gated
   behind Code Connect on this plan, so pulled via get_design_context on
   the component set's node, 21:917 — three real variants: Hambuger3
   (resting), Hover, Open). The set's master is built at 52px; our own
   58px icon has a real 3px CSS border (border-box), so its padding box is
   exactly 52px too — meaning the component's own percentages/pixels map
   straight onto our padding box with no extra scaling. (An earlier pass
   scaled the 58px *instance*'s own percentages directly, double-counting
   that scale-up — this replaces those numbers with the correct ones.)

   Plain mark (Hambuger3): two equal-length bars, offset diagonally.
   All geometry here is the original Figma-derived numbers scaled
   uniformly by 0.85 (15% smaller icon, per direct request) — same
   relationships, e.g. the close state's rotation origin still lands
   on the padding box's exact center. */
.nav-icon__bar:nth-child(1) {
  width: 11.9px;
  transform: translate(20.4px, 17px);
}

.nav-icon__bar:nth-child(2) {
  width: 11.9px;
  transform: translate(11.9px, 24.65px);
}

/* Hover (plain mark only — Figma has no Hover+Open combination): bars
   shift to sit centered/symmetric rather than diagonally offset. */
.nav-icon:not([data-mode="close"]):hover .nav-icon__bar:nth-child(1) {
  transform: translate(16.15px, 15.3px);
}

.nav-icon:not([data-mode="close"]):hover .nav-icon__bar:nth-child(2) {
  transform: translate(16.15px, 26.35px);
}

/* Close (science.html's link back to "/") — Figma's "Open" variant: the
   same two 14px bars, rotated in place around dead-center (26px, half of
   the 52px padding box) rather than growing into a wider X. Morphs in as
   the page arrives and reverses on click (main.js adds/removes
   .nav-icon--arriving and .nav-icon--reversing). Neither is a static
   "animation: ... both" on the base rule any more — deliberate: this page
   can be speculatively prerendered in the background (see the other
   page's <script type="speculationrules">), and a plain CSS animation
   with no gating plays and finishes silently during that hidden
   prerender, same bug the page-mask's own reveal had. Main.js defers
   adding --arriving to document.prerendering/prerenderingchange,
   identical to the page-mask's fix, so the morph only ever plays once the
   page is genuinely the one being shown. The base rule below is simply
   the resting X shape with no animation — end state whether or not JS
   ever ran (e.g. reduced motion), start state for --arriving. */
.nav-icon[data-mode="close"] .nav-icon__bar:nth-child(1) {
  width: 11.9px;
  transform: translate(16.15px, 20.825px) rotate(45deg);
}

.nav-icon[data-mode="close"] .nav-icon__bar:nth-child(2) {
  width: 11.9px;
  transform: translate(16.15px, 20.825px) rotate(-45deg);
}

.nav-icon[data-mode="close"].nav-icon--arriving .nav-icon__bar:nth-child(1) {
  animation: nav-icon-close-a 0.4s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.nav-icon[data-mode="close"].nav-icon--arriving .nav-icon__bar:nth-child(2) {
  animation: nav-icon-close-b 0.4s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.nav-icon[data-mode="close"].nav-icon--reversing .nav-icon__bar:nth-child(1) {
  animation: nav-icon-open-a 0.4s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.nav-icon[data-mode="close"].nav-icon--reversing .nav-icon__bar:nth-child(2) {
  animation: nav-icon-open-b 0.4s cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes nav-icon-close-a {
  from {
    width: 11.9px;
    transform: translate(20.4px, 17px) rotate(0deg);
  }
}

@keyframes nav-icon-close-b {
  from {
    width: 11.9px;
    transform: translate(11.9px, 24.65px) rotate(0deg);
  }
}

@keyframes nav-icon-open-a {
  from {
    width: 11.9px;
    transform: translate(16.15px, 20.825px) rotate(45deg);
  }
  to {
    width: 11.9px;
    transform: translate(20.4px, 17px) rotate(0deg);
  }
}

@keyframes nav-icon-open-b {
  from {
    width: 11.9px;
    transform: translate(16.15px, 20.825px) rotate(-45deg);
  }
  to {
    width: 11.9px;
    transform: translate(11.9px, 24.65px) rotate(0deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav-icon[data-mode="close"] .nav-icon__bar {
    animation: none !important;
  }
}

/* ==========================================================================
   Page transition mask — the header's own white extends downward to cover
   the screen, rather than a separate curtain sliding in. Starts covering
   by default (see the inline data-cover="true" in the markup) and main.js
   shrinks it back on load; clicking a nav-icon grows it again before the
   real navigation happens. Sits below the header at all times (top:
   var(--chrome-height)) — the header itself never needs its own z-index
   raised, since the mask never overlaps it.

   #main gets its own top-down clip reveal, purely reactive to the mask's
   data-cover attribute via the ~ sibling combinator (same DOM order on
   every page, #main always follows .page-mask) — no JS needed beyond the
   existing data-cover toggle. It shares the mask's own transition
   duration so the two run in step: content clips in from the top exactly
   as the box shrinks away, and reverses — clipping back off, bottom
   first — as the box grows to cover again on click.
   ========================================================================== */

.page-mask {
  position: fixed;
  z-index: 250;
  left: 0;
  right: 0;
  top: var(--chrome-height, 0px);
  height: 0;
  background: var(--color-white);
  overflow: hidden;
  transition: height 0.18s cubic-bezier(0.65, 0, 0.35, 1);
  pointer-events: none;
}

.page-mask[data-cover="true"] {
  height: calc(100vh - var(--chrome-height, 0px));
}

#main {
  clip-path: inset(0 0 0% 0);
  opacity: 1;
  transition: clip-path 0.18s cubic-bezier(0.65, 0, 0.35, 1), opacity 0.18s cubic-bezier(0.65, 0, 0.35, 1);
}

.page-mask[data-cover="true"] ~ #main {
  clip-path: inset(0 0 100% 0);
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .page-mask,
  #main {
    transition: none;
  }
}

/* ==========================================================================
   Buttons & form controls
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: none;
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: 1rem;
  padding: 0.9rem 1.6rem;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.btn:hover { transform: translateY(-1px); }

.btn--navy {
  background: var(--color-navy);
  color: var(--color-white);
}

.btn--navy:hover { box-shadow: var(--shadow-lift); }

.btn--yellow {
  background: var(--color-yellow);
  color: var(--color-navy);
}

.btn--outline {
  background: transparent;
  color: var(--color-navy);
  border: 2px solid var(--color-navy);
}

.btn--outline:hover {
  background: var(--color-sky-tint);
}

.btn[disabled] {
  opacity: 0.65;
  cursor: progress;
  transform: none;
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 0.15s ease;
}

.link-arrow:hover,
.link-arrow:focus-visible {
  border-color: currentColor;
}

/* ==========================================================================
   Hero banner — rounded card (image + copy) + supporting paragraph
   Pulled from Figma (get_design_context on node 14:329, desktop frame).
   Mobile has no structured Figma layers, only a flat reference image, so
   its layout below is a reasonable proportional approximation, not
   pixel-extracted.
   ========================================================================== */

.hero-banner {
  /* No top padding — without it, the gap between the header and the
     card was the header's own bottom padding (17.6px) PLUS this, making
     it bigger than the gap between the ticker and the header's top
     (just the header's own top padding). Zeroing this here matches the
     900px+ override below, so it now holds at every width instead of
     just desktop. */
  padding: 0 var(--space-3) var(--space-3);
}

@media (min-width: 768px) {
  .hero-banner {
    /* Figma's frame pads 30px from the edge with no centering container —
       a deliberate, scoped departure from the site's 1180px .container,
       just for this banner. */
    padding: 0 30px var(--space-3);
  }
}

.hero-banner__card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-sky-tint);
  /* Mobile/tablet only (<900px) — the stacked layout had no inset of its
     own, so the image and copy sat flush against the card's rounded
     edges. Zeroed again at 900px+ below, where the image is
     deliberately absolute-positioned to bleed off the card's edges by
     design (padding here would also shift its bottom-anchored offset). */
  padding: var(--space-3);
}

.hero-banner__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-banner__copy {
  position: relative;
  z-index: 1;
  order: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  /* Inline padding removed — .hero-banner__card's own edge already lines
     up with the header/image (both use .hero-banner's 30px), and this
     block's own left/right padding on top of that was insetting the
     paragraph 24px further than either, reported alongside the max-width
     issue above. Vertical padding kept for breathing room above/below
     the text between the image and the card's bottom edge. */
  padding-block: var(--space-3);
}

.hero-banner__image {
  position: relative;
  z-index: 1;
  order: 1;
}

@media (max-width: 899px) {
  /* Pulls the image back out to the card's edges, undoing .hero-banner__
     card's own padding for this child only — the headline/copy below it
     keeps the padding, just the image bleeds, per direct request. Zero
     bottom margin keeps the existing gap to the copy below intact. */
  .hero-banner__image {
    margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0;
    transform: translateX(20px);
  }
}

.hero-banner__image img {
  display: block;
  width: 100%;
  height: auto;
}

.hero-banner__title {
  font-size: clamp(1.75rem, 7vw, 4rem);
  font-weight: 700;
  font-style: italic;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--color-navy);
}

.hero-banner__subtitle {
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--color-navy);
  /* No max-width here (unlike .hero-banner__title, which already has
     none): a fixed 34ch doesn't bind at true phone widths, where the
     container itself is already narrower, but becomes the limiting
     factor in the wider stacked range just below the 900px desktop
     breakpoint — reported directly, with a screenshot showing the
     paragraph noticeably narrower than the image/header above it. */
}

.hero-banner__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  width: 100%;
}

@media (max-width: 639px) {
  .hero-banner__buttons .btn {
    flex: 1 1 auto;
  }
}

@media (min-width: 900px) {
  /* Desktop deviates from the Figma frame here on purpose, matching a
     reference site the user pointed to (moremud.co): a shorter, less
     exaggerated corner radius, copy overlaid directly on the image rather
     than sitting beside it in its own column, and the product shot
     anchored to the top-right corner, oversized so it bleeds off the
     card's top and right edges instead of sitting fully inset. */
  .hero-banner__card {
    display: block;
    /* Card itself (not the paragraph below it) reaches down to 12px above
       the bottom of the viewport, matching the reference site's image —
       --chrome-height (ticker+header) is measured synchronously in
       index.html's inline script. .hero-banner's own top padding is
       zeroed out below so there's nothing else above the card to account
       for here. */
    height: calc(100vh - var(--chrome-height, 0px) - 12px);
    border-radius: 24px;
    padding: 0;
  }

  .hero-banner__copy {
    position: absolute;
    z-index: 2;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    /* An explicit width (not just max-width) — title/subtitle below need
       a stable, definite box to resolve their own percentages against.
       With only max-width set here, this element's own width stays
       "auto" (shrink-to-fit), and a child's percentage width resolving
       against an auto-sized ancestor is circular/unreliable — that's
       what was collapsing the title to ~230px before this fix.
       Percentage resolves against .hero-banner__card's own width (the
       nearest positioned ancestor) — .hero-banner__image sits at a fixed
       ~42% of that same width regardless of card size (it's built from
       percentages throughout), so capping copy at 42% too means its right
       edge tracks the image's left edge at any card width instead of
       overlapping more as the window narrows. min() keeps wide screens
       pixel-identical to before (42% only wins below ~1524px card
       width — narrower than any of the desktop testing so far). */
    width: min(640px, 42%);
    padding: 0 0 0 var(--space-5);
  }

  .hero-banner__title {
    max-width: 100%;
  }

  .hero-banner__subtitle {
    /* Tuned to break "One scoop. ... matter most." across exactly three
       lines at this column width, rather than the site-wide default —
       narrower than .hero-banner__copy's own full width on purpose (100%
       gave it too much room and collapsed it to two lines). 67.5% of
       copy's width matches 27rem exactly at copy's 640px cap, then
       shrinks alongside copy below that. */
    max-width: min(27rem, 75%);
  }

  .hero-banner__image {
    position: absolute;
    z-index: 1;
    /* Anchored from the card's BOTTOM, not top — .hero-banner__card's
       height is viewport-height-driven (100vh - chrome - 12px), so a
       top-based offset that mixed a percentage of that variable height
       with a fixed pixel amount only balanced at the screen height it was
       tuned on; on a taller monitor the percentage term dragged the image
       up, leaving a growing empty gap below it (reported directly).
       Sizing by width alone (height auto, natural aspect ratio) and
       anchoring the bottom means the image's own size never depends on
       card height at all — a taller card on a bigger screen just adds
       more empty space above the image, which reads as normal framing
       rather than a bug. */
    bottom: 40px;
    right: -3%;
    width: 61%;
    max-width: none;
    padding-block: 0;
    /* Grows the right/top/bottom bleed without shifting the image's left
       edge, per direct feedback that the source photo's cropped arm
       corner was still peeking through at the top-right. */
    transform: scale(1.1);
    transform-origin: left center;
  }

  .hero-banner__image img {
    display: block;
    width: 100%;
    height: auto;
  }
}

.hero-banner__paragraph {
  padding: var(--space-3);
  max-width: 60ch;
  margin-inline: auto;
  text-align: center;
  font-size: 1.125rem;
  /* Medium (500) has no real face in the degular-text kit (only 400/700
     are actually loaded — checked via document.fonts), so the browser
     was silently falling back to Regular despite this saying 500. Bold
     is the only other weight that's real, so it's the only value that
     visibly changes anything until Medium is added to the kit. */
  font-weight: 700;
  line-height: 1.4;
  color: var(--color-navy);
}

@media (min-width: 768px) {
  .hero-banner__paragraph {
    padding-block: var(--space-4);
    font-size: 1.75rem;
  }
}

.hero__form-wrap {
  margin-top: var(--space-3);
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.email-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  max-width: 480px;
}

@media (min-width: 640px) {
  /* Joined single-pill row (input + button sharing one border) — the
     stacked separate-pill look below 640px is just the plain base
     styles further down (.email-form, .email-form__input, .btn), no
     override needed there. Swapped which breakpoint gets which look
     per direct request — this was mobile's styling, now desktop's. */
  .email-form {
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    background: var(--color-white);
    /* The input's own border is "none" below (it butts up against the
       button inside this same pill), so without this the whole form had
       no visible edge at all once the drop shadow was removed — the
       shadow had been doing double duty as the pill's boundary. */
    border: 2px solid rgba(20, 21, 45, 0.15);
    border-radius: 10px;
    overflow: hidden;
  }

  .email-form .btn {
    border-radius: 0;
    padding-inline: 1.25rem;
    font-size: 0.88rem;
  }
}

.email-form__field {
  flex: 1;
  position: relative;
}

.email-form__input {
  width: 100%;
  height: 100%;
  border: 2px solid rgba(20, 21, 45, 0.15);
  border-radius: var(--radius-pill);
  padding: 0.9rem 1.25rem;
  font-size: 0.9rem;
  color: var(--color-navy);
  background: var(--color-white);
}

.email-form__input:focus {
  outline: none;
}

@media (min-width: 640px) {
  .email-form__input { border: none; border-radius: 10px 0 0 10px; padding: 0.85rem 1rem; }
}

.email-form__input:invalid[data-touched="true"] {
  box-shadow: inset 0 0 0 2px #E4572E;
}

.email-form .btn {
  white-space: nowrap;
}

.email-form__message {
  min-height: 1.4em;
  font-size: 0.85rem;
  font-weight: 700;
}

.email-form__message:empty { margin: 0; }

.email-form__message[data-state] {
  margin-top: 0.6rem;
  display: inline-block;
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius-pill);
  background: var(--color-sky-tint);
}

.email-form__message[data-state="error"] { color: #B33A0F; }
.email-form__message[data-state="success"] { color: #1F7A4D; }

/* honeypot field, hidden from everyone but bots */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   Description band
   ========================================================================== */

.about {
  padding-block: var(--space-4);
  background: var(--color-white);
}

@media (max-width: 767px) {
  /* Mobile only, per direct request — halves the gap between the hero
     paragraph and this section's content (was .hero-banner's own 24px
     bottom padding + this 40px top padding = 64px combined; this brings
     the section's own contribution down to 8px, for 32px combined). */
  .about {
    padding-top: var(--space-1);
  }
}

.about__grid {
  display: grid;
  gap: var(--space-4);
  width: 100%;
  max-width: var(--container-width);
  margin-inline: auto;
  padding-inline: var(--space-3);
}

@media (min-width: 768px) {
  /* Matches .hero-banner's and .site-header .container's own edge
     padding exactly, so the about section's left/right edges line up
     with the logo and hamburger icon rather than the site-wide 1180px
     .container's own (different) max-width and padding. */
  .about__grid {
    max-width: none;
    padding-inline: 30px;
  }
}

.about__media {
  position: relative;
}

.about__media-photo {
  max-width: 480px;
  width: 100%;
  margin-inline: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

.about__media-logo {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 50%;
  max-width: 230px;
  height: auto;
  pointer-events: none;
}

@media (min-width: 640px) {
  /* 6-column grid so the image can take a 4:2 split instead of the old
     even 1:1 — per direct request, to size the image up substantially. */
  .about__grid {
    grid-template-columns: repeat(6, 1fr);
    align-items: center;
    gap: var(--space-3);
  }

  .about__media {
    order: 2;
    grid-column: span 4;
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    /* Matches the reference screenshot's proportions — the image fills
       this box edge-to-edge (object-fit: cover below) rather than
       sitting at its own intrinsic aspect ratio. */
    aspect-ratio: 1416 / 751;
  }

  .about__media-photo {
    max-width: none;
    width: 100%;
    height: 100%;
    margin-inline: 0;
    object-fit: cover;
    border-radius: 0;
    box-shadow: none;
  }

  .about__copy {
    order: 1;
    grid-column: span 2;
  }
}

@media (min-width: 900px) {
  /* The 6-column 4:2 split (set at 640px+) already defines the ratio
     consistently — no separate wider-screen override needed. */
  .about__grid { gap: var(--space-4); }
}

.about__eyebrow {
  color: var(--color-sky);
  background: var(--color-navy);
  display: inline-block;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-pill);
  margin-bottom: var(--space-2);
}

.about__title {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 800;
  line-height: 1.15;
  max-width: 16ch;
}

.about__copy .hero__form-wrap {
  align-items: flex-start;
  max-width: 420px;
}

.about__copy .email-form {
  width: 100%;
}

.about__body p {
  font-size: 1.05rem;
  line-height: 1.65;
  color: var(--ink-muted-on-light);
  max-width: 56ch;
}

.about__body p + p { margin-top: var(--space-2); }

.benefit-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: var(--space-3);
}

.benefit-tags li {
  background: var(--color-sky-tint);
  color: var(--color-navy);
  font-weight: 700;
  font-size: 0.9rem;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-pill);
}

.about__quote {
  text-align: center;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  font-weight: 700;
  color: var(--color-navy);
  max-width: 36ch;
  margin: 0 auto var(--space-4);
  line-height: 1.2;
}

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

.site-footer {
  background: var(--color-navy);
  color: var(--color-white);
  padding-block: var(--space-5) var(--space-4);
}

.site-footer__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
}

.site-footer__logo img {
  width: 40px;
  height: auto;
}

.site-footer__social {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
}

.site-footer__social a {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.8px solid rgba(255, 255, 255, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: var(--color-white);
}

.site-footer__social a svg {
  width: 18px;
  height: 18px;
}

.site-footer__social a:hover { background: rgba(255, 255, 255, 0.12); }

.site-footer__legal {
  font-size: 0.82rem;
  color: var(--ink-muted-on-navy);
  text-align: center;
}

/* ==========================================================================
   Science page — intro
   ========================================================================== */

.page-hero {
  background: var(--color-white);
  color: var(--color-navy);
  padding-block: var(--space-5) var(--space-4);
}

.page-hero__eyebrow {
  color: var(--color-navy);
  background: transparent;
  border: 1.5px solid var(--color-navy);
  display: inline-block;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-pill);
  margin-bottom: var(--space-2);
}

.page-hero__title {
  font-size: clamp(2rem, 4.5vw, 3rem);
  font-weight: 800;
  line-height: 1.1;
  max-width: 20ch;
}

.page-hero__subtitle {
  margin-top: var(--space-2);
  color: var(--ink-muted-on-light);
  max-width: 60ch;
  font-size: 1.05rem;
  line-height: 1.6;
}

/* ==========================================================================
   Ingredient / benefit groups + cards (reusable pattern)
   ========================================================================== */

.ingredient-groups {
  padding-block: var(--space-4) var(--space-6);
}

@media (max-width: 767px) {
  .page-hero {
    padding-block: var(--space-5) var(--space-3);
  }

  .ingredient-groups {
    padding-block: var(--space-2) var(--space-6);
  }
}

.ingredient-cards {
  display: block;
  border-top: 1px solid rgba(20, 21, 45, 0.12);
}

.ingredient-card {
  border-bottom: 1px solid rgba(20, 21, 45, 0.12);
}

.ingredient-card__summary {
  padding-block: 1.25rem;
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}

.ingredient-card__summary::-webkit-details-marker { display: none; }

.ingredient-card__name {
  font-size: 1.1rem;
  font-weight: 600;
}

.ingredient-card__toggle {
  position: relative;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid rgba(20, 21, 45, 0.3);
}

.ingredient-card__toggle::before,
.ingredient-card__toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--color-navy);
  transform: translate(-50%, -50%);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.ingredient-card__toggle::before {
  width: 12px;
  height: 1.5px;
}

.ingredient-card__toggle::after {
  width: 1.5px;
  height: 12px;
}

.ingredient-card[open] .ingredient-card__toggle::after {
  opacity: 0;
  transform: translate(-50%, -50%) rotate(90deg);
}

.ingredient-card__body {
  padding: 0 0 1.5rem;
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 700px) {
  .ingredient-card__body { grid-template-columns: repeat(2, 1fr); }
  .ingredient-card__body .field--full { grid-column: 1 / -1; }
}

.field__label {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-sky);
  margin-bottom: 0.3rem;
  display: block;
}

.field__value {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--color-navy);
}

.field__value ul { margin-top: 0.3rem; }
.field__value li { position: relative; padding-left: 1.1rem; margin-bottom: 0.3rem; }
.field__value li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.55em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--color-sky);
}

.study-ref {
  font-size: 0.88rem;
  line-height: 1.5;
}

.study-ref + .study-ref { margin-top: 0.6rem; }

.placeholder-flag {
  display: inline-block;
  margin-top: 0.4rem;
  background: var(--color-yellow);
  color: var(--color-navy);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-sm);
}

/* ==========================================================================
   Utility sections
   ========================================================================== */

.section-title-group {
  margin-bottom: var(--space-3);
}

.eyebrow-light {
  color: var(--color-sky);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
