/* Optimized Peptide Solutions storefront.
   Light metallic theme: metallic white surfaces, ultra-realistic metallic gold accents, Rubik type. */

:root {
  --ink: #16181c;
  --ink-soft: #3d4149;
  --muted: #6b7078;
  --white: #ffffff;

  /* Page ground. The site was built on a white ground; the partner asked for beige, so the
     ground colour is a token rather than a literal. Every surface that used to be white
     BECAUSE it was the page ground reads this token: the body fill, the fixed art backdrop,
     the veil over that art, the hero's full-strength copy of it, and the halo behind the hero
     copy. --white is left alone: it still means "white the colour" (text on the black panels,
     the form fields, the disclaimer card inside the black footer), not "the page ground".
     Held as an RGB triple so the veil and the halo can take an alpha off the same value and a
     single override changes all five layers together. */
  --ground-rgb: 240, 231, 216;
  --ground: rgb(var(--ground-rgb));
  --ground-veil: rgba(var(--ground-rgb), 0.72);

  /* Metallic gold ramp: antique gold, sampled from the hero logo's letter pixels
     (ops-letters-2.png luminance percentiles), so gold text/buttons match the artwork */
  --gold-1: #fbf1bd;
  --gold-2: #dab878;
  --gold-3: #b98f50;
  --gold-4: #966e39;
  --gold-5: #5b4226;
  --gold-mid: #a67d43;

  /* Metallic white / silver ramp */
  --silver-1: #ffffff;
  --silver-2: #f4f6f9;
  --silver-3: #e6e9ee;
  --silver-4: #d7dbe2;

  --line: #d9dde4;
  --gold-line: rgba(150, 110, 57, 0.45);

  /* Ring version of the antique gold ramp, for borders. A conic sweep is used instead of the
     linear --metal-gold because a linear ramp puts its darkest stop (#5b4226) on one whole
     edge of a wide box, and that edge then disappears against a black panel. The sweep keeps
     every side inside the readable part of the ramp while still travelling light-to-dark. */
  --metal-gold-ring: conic-gradient(from 215deg, #8f6a37 0%, #c9a15c 9%, #f0dfa6 18%, #a67d43 30%, #dab878 42%, #8a6532 54%, #e6cd90 66%, #b98f50 78%, #7d5a2e 88%, #8f6a37 100%);

  /* Vertical version of the antique gold ramp, for the side rails. --metal-gold runs at 105deg,
     which on a 10px-wide full-height box compresses every stop into the first few pixels; this
     one travels top to bottom so the rail reads as one long brushed strip. Same stops, same
     ramp: no palette value is changed here. */
  --metal-gold-rail: linear-gradient(180deg, #5b4226 0%, #b98f50 8%, #dab878 16%, #966e39 28%, #fbf1bd 42%, #a67d43 56%, #dab878 68%, #835f2f 80%, #c69c5c 90%, #5b4226 100%);

  --metal-gold: linear-gradient(105deg, #5b4226 0%, #b98f50 12%, #dab878 22%, #966e39 34%, #fbf1bd 46%, #a67d43 58%, #dab878 70%, #835f2f 82%, #c69c5c 92%, #5b4226 100%);
  --metal-gold-btn: linear-gradient(180deg, var(--gold-1) 0%, var(--gold-2) 22%, var(--gold-3) 55%, var(--gold-4) 100%);
  --metal-white: linear-gradient(168deg, var(--silver-1) 0%, var(--silver-2) 28%, var(--silver-3) 52%, var(--silver-1) 74%, var(--silver-3) 100%);
  --metal-white-flat: linear-gradient(180deg, var(--silver-1) 0%, var(--silver-2) 60%, var(--silver-3) 100%);

  /* Text colours for the black panel surfaces. Body copy is held just off pure white so large
     blocks do not halate against the near-black fill. */
  --panel-ink: #f2f3f5;
  --panel-ink-soft: #c7cad0;

  /* Metallic black ramp (nav bar) */
  --metal-black: linear-gradient(180deg, #3a3d42 0%, #22252a 16%, #101216 44%, #05070a 62%, #16191e 82%, #2b2e34 100%);
  --metal-black-panel: linear-gradient(180deg, #24272c 0%, #131519 40%, #0a0c0f 100%);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  background-color: var(--ground);
  color: var(--ink);
  font-family: 'Rubik', -apple-system, 'Segoe UI', Arial, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  min-height: 100vh;
  /* Column flex so <main> can absorb the slack and hold the footer at the bottom of short
     pages (cart, 404, order confirmation). Without this the black footer ends mid-viewport
     and the white page backdrop shows beneath it. The .bg-fixed / .bg-overlay layers are
     position: fixed, so they stay out of this flow. */
  display: flex;
  flex-direction: column;
}
main { flex: 1 0 auto; }

/* Fixed background layer: stationary while the page scrolls. Vitruvian line art on a white backdrop.
   The element is itself position:fixed at viewport size, so it stays put on its own. Do NOT add
   background-attachment: fixed here: it is redundant, and mobile Safari either ignores it (the
   artwork then scrolls away) or fails to paint the image at all. */
.bg-fixed {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-color: var(--ground);
  background-image: url('/img/ops-body.png');
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}
.bg-overlay {
  position: fixed;
  inset: 0;
  z-index: -1;
  /* The veil is the GROUND colour at 0.72, not white: over the artwork it knocks the line art
     back, and everywhere else it lands on the identical --ground fill below it, so the page
     reads as one flat beige. Phase 4's transparent hero depends on this rule staying a single
     flat fill at z-index -1 that .hero::before can overpaint; only the colour moved. */
  background: var(--ground-veil);
}

/* Side frame: a metallic gold rail down each edge of the viewport, so the page reads as a
   framed sheet rather than as copy running off into the browser chrome.
   Built on body::before / body::after and position: fixed on purpose. Fixed boxes are out of
   flow, so they add nothing to the document width and cannot produce a horizontal scrollbar at
   any viewport; a bordered wrapper or a 100vw box would do both. body is display: flex, which
   is also why these have to stay out of flow: in flow they would become flex items and push the
   header down. The rail is narrower than the .container side padding (20px) at every width, so
   it never covers content, and pointer-events: none keeps it out of the way of links.
   z-index sits above the sticky header (50) so the frame runs the whole height of the window,
   including across the black bar; the header's own dropdowns open inside the container padding,
   clear of the rail. */
body::before,
body::after {
  content: '';
  position: fixed;
  top: 0;
  bottom: 0;
  width: var(--frame-w, 10px);
  z-index: 70;
  pointer-events: none;
  background: var(--metal-gold-rail);
}
body::before { left: 0; box-shadow: 1px 0 0 rgba(0, 0, 0, 0.35); }
body::after { right: 0; box-shadow: -1px 0 0 rgba(0, 0, 0, 0.35); }
/* Narrow the rail on phones so it stays well inside the container padding on a 320px screen. */
@media (max-width: 860px) {
  body::before, body::after { --frame-w: 6px; }
}

h1, h2, h3, .display {
  font-family: 'Rubik', -apple-system, 'Segoe UI', Arial, sans-serif;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.25;
}

/* Gold headings: uniform antique gold (solid, not gradient-clipped. The metallic
   gradient's light stops made letter parts illegible on white surfaces) */
.gold-metal-text,
.hero h1,
.brand-name,
.section-title,
.panel h2,
.panel h3 {
  color: var(--gold-4);
}

a { color: var(--gold-4); text-decoration: none; }
a:hover { color: var(--gold-5); }

.container { max-width: 1140px; margin: 0 auto; padding: 0 20px; }

/* Announcement bar (only rendered when the console sets one) */
.announcement {
  background: var(--metal-gold);
  color: var(--ink);
  text-align: center;
  padding: 8px 16px;
  font-size: 0.9rem;
  font-weight: 500;
  border-bottom: 1px solid var(--gold-line);
}

/* Header: metallic black bar */
.site-header {
  background: var(--metal-black);
  border-bottom: 1px solid #000;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.14) inset, 0 -1px 0 rgba(0, 0, 0, 0.9) inset, 0 3px 16px rgba(0, 0, 0, 0.35);
  position: sticky;
  top: 0;
  z-index: 50;
}
.site-header .container {
  display: flex;
  align-items: center;
  gap: 18px;
  height: 90px;
  padding-top: 0;
  padding-bottom: 0;
}
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.brand img {
  height: 102px;
  width: auto;
  max-width: min(620px, 62vw);
  object-fit: contain;
  display: block;
  position: relative;
  z-index: 61;
}

/* Nav: hamburger menu at every viewport size */
.main-nav { margin-left: auto; display: flex; align-items: center; gap: 16px; }
/* Search and cart: one shared spec, so the pair cannot drift apart again.
   Bare glyphs with no frame, gold at the hamburger's weight, white on hover. */
.search-btn,
.cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  color: var(--gold-2);
  cursor: pointer;
}
.search-btn:hover,
.cart-link:hover { color: var(--white); }
.search-toggle:checked ~ .search-btn { color: var(--white); }
.cart-badge {
  position: absolute;
  top: -3px;
  right: -6px;
  min-width: 17px;
  padding: 1px 4px;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  color: #1a1206;
  background: var(--gold-2);
  border-radius: 999px;
}

.nav-toggle { display: none; }
.hamburger {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 42px;
  height: 40px;
  padding: 8px 9px;
  cursor: pointer;
  border: 1px solid var(--gold-line);
  background: var(--metal-black-panel);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset, 0 2px 6px rgba(0, 0, 0, 0.4);
  border-radius: 6px;
}
.hamburger span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--gold-2);
  border-radius: 2px;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.nav-toggle:checked ~ .hamburger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle:checked ~ .hamburger span:nth-child(2) { opacity: 0; }
.nav-toggle:checked ~ .hamburger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-menu {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  min-width: 230px;
  background: var(--metal-black-panel);
  border: 1px solid var(--gold-line);
  border-top: 2px solid var(--gold-3);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
  padding: 10px 0;
  z-index: 60;
}
.nav-toggle:checked ~ .nav-menu { display: block; }
.main-nav { position: relative; }
.nav-menu a {
  display: block;
  padding: 11px 22px;
  color: var(--white);
  font-size: 0.98rem;
  font-weight: 500;
}
.nav-menu a:hover, .nav-menu a.active {
  background: linear-gradient(90deg, rgba(217, 181, 68, 0.24), rgba(217, 181, 68, 0.05));
  color: var(--gold-2);
}

/* Header search: magnifying glass next to the cart, opening a panel under the
   header. CSS-only toggle so it works with JavaScript off, styled to match the
   hamburger and the nav dropdown. */
.search-toggle { display: none; }

.search-panel {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 61;
  min-width: 320px;
  gap: 8px;
  padding: 12px;
  background: var(--metal-black-panel);
  border: 1px solid var(--gold-line);
  border-top: 2px solid var(--gold-3);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
}
.search-toggle:checked ~ .search-panel { display: flex; }
.search-panel .search-input {
  flex: 1;
  min-width: 0;
  padding: 9px 12px;
  font: inherit;
  font-size: 0.95rem;
  color: var(--white);
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid var(--gold-line);
  border-radius: 4px;
}
.search-panel .search-input::placeholder { color: rgba(255, 255, 255, 0.55); }
.search-panel .search-input:focus { outline: none; border-color: var(--gold-2); }
.search-panel .search-go {
  padding: 9px 16px;
  font: inherit;
  font-size: 0.92rem;
  font-weight: 700;
  color: #1a1206;
  cursor: pointer;
  background: var(--metal-gold-btn);
  border: 1px solid var(--gold-line);
  border-radius: 4px;
}
.search-panel .search-go:hover { filter: brightness(1.08); }

@media (max-width: 520px) {
  .search-panel { min-width: 0; width: calc(100vw - 32px); right: -8px; }
  /* Narrow phones: the wordmark carries z-index 61, so at 62vw it painted straight
     over the search and cart glyphs instead of being pushed off by them. Give the
     nav its space back by capping the mark to what is actually left after the three
     controls and their gaps, and drop the height to match so it does not letterbox. */
  .brand img { height: 64px; max-width: calc(100vw - 168px); }
  .main-nav { gap: 12px; }
  .site-header .container { gap: 10px; height: 68px; }
}

/* Hero */
.hero { padding: 44px 0 56px; text-align: center; position: relative; }
/* Transparent hero: overpaint the page-wide white veil inside the hero box with the artwork at
   full strength, so the hero reads as see-through while the rest of the page stays veiled.
   This is the ONE place background-attachment: fixed is load-bearing: it is what keeps this
   copy in register with .bg-fixed at every scroll position. Mobile Safari does not honour it,
   so the effect is gated to wider viewports below; on mobile the hero is simply veiled like
   the rest of the page, which degrades cleanly.
   Paint order note: this and .bg-overlay are both z-index -1 in the root stacking context, so
   this wins on DOM order alone. Anything later at that layer, or a stacking context on .hero,
   silently reverts the effect. */
@media (min-width: 861px) {
  .hero::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background-color: var(--ground);
    background-image: url('/img/ops-body.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed;
    pointer-events: none;
    /* Fade the cutout out at the bottom edge so it blends into the veiled artwork below. */
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 80px), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 80px), transparent 100%);
  }
}
.hero-logo { height: 170px; width: 170px; object-fit: contain; margin-bottom: 20px; filter: drop-shadow(0 6px 16px rgba(22, 24, 28, 0.18)); }
/* OPS mark: the band between the nav bar and the top of the figure's head, never on the face.
   The figure is painted by the viewport-registered background layers (.bg-fixed, and the hero's
   own copy in .hero::before) at background-size: contain, so on a landscape viewport the head
   starts at 17.7vh from the top (measured: first head ink is row 364 of the 2048px ops-body.png
   canvas). The mark's height is therefore driven off vh on desktop so it always lands above the
   head instead of over it. The 5:1 box aspect is load-bearing for the cover-crop below, so the
   width is derived from the height rather than set on its own. */
.hero-mark {
  display: block;
  margin: 0 auto 14px;
  /* source canvas is 1536x1024 with the letters in a thin middle band (rows 374-658);
     cover-crop the transparent bands at render time so they don't read as margin;
     the file itself stays untouched because favicon and og_image share it */
  --mark-h: calc(min(460px, 78vw) * 0.2);
  height: var(--mark-h);
  width: calc(var(--mark-h) * 5);
  max-width: 100%;
  object-fit: cover;
  filter: drop-shadow(0 8px 20px rgba(22, 24, 28, 0.22));
}
/* Hero stack: the motto leads and is the largest thing on the page, the company name follows it
   as a smaller line, and each element is given more room so the middle of the page stops reading
   as one block of jumbled words over the drawing. */
.hero .tagline {
  font-size: clamp(2rem, 4.2vw, 3.4rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: 880px;
  margin: 6px auto 0;
}
.hero h1 { font-size: 1.6rem; font-weight: 600; letter-spacing: 0.02em; margin-top: 16px; }
.hero .subtitle { color: var(--ink); margin: 18px auto 0; font-size: 1.1rem; max-width: 620px; }
.hero-cta { margin-top: 34px; }
/* Legibility over the line art. A white halo lifts the hero copy off the drawing behind it.
   It is deliberately a text-shadow on the copy and NOT a background on .hero: the hero reads as
   see-through because .hero::before cuts a hole in the page-wide .bg-overlay veil, and giving
   .hero a background of its own would fill that hole back in. text-shadow creates no stacking
   context, so the z-index: -1 paint order is untouched. */
.hero .tagline,
.hero h1,
.hero .subtitle {
  text-shadow:
    0 0 8px rgba(var(--ground-rgb), 0.98),
    0 0 20px rgba(var(--ground-rgb), 0.92),
    0 0 38px rgba(var(--ground-rgb), 0.78);
}
/* Desktop only: tighten the gap under the fixed nav and size the mark to the band above the head.
   Padding and a custom property only. No background, no transform/filter/opacity/isolation and no
   position + z-index on .hero itself, so .hero::before still wins over .bg-overlay on DOM order. */
@media (min-width: 861px) {
  .hero { padding-top: 8px; }
  .hero-mark { --mark-h: clamp(20px, calc(17.7vh - 115px), 92px); }
}

/* Status chip (order confirmation etc.) */
.badge {
  display: inline-block;
  border: 1px solid var(--gold-3);
  background: var(--metal-white-flat);
  color: var(--gold-4);
  padding: 6px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 4px;
}

/* Panels: metallic black surfaces over the fixed background, ringed in antique metallic gold.
   The border is the gold ramp painted into the border-box layer (dual-background technique:
   panel fill clipped to padding-box, gold gradient clipped to border-box, border kept
   transparent), so the ring reads as brushed antique gold rather than one flat line.
   Do NOT collapse this into `background: <fill>` plus `border: 1px solid <colour>`: that
   throws away the metallic ramp and the panels go back to reading as plain outlines. */
.panel {
  background: var(--metal-black-panel) padding-box, var(--metal-gold-ring) border-box;
  border: 2px solid transparent;
  border-radius: 10px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset, 0 10px 26px rgba(0, 0, 0, 0.45);
  padding: 34px;
  margin: 26px 0;
  color: var(--panel-ink);
}
/* Gold on black needs the lighter end of the ramp: gold-4 (the heading gold on white surfaces)
   drops to roughly 3:1 against the panel fill and stops being comfortably readable. */
.panel h1, .panel h2, .panel h3, .panel h4 { color: var(--gold-2); }
.panel .blog-body h1,
.panel .blog-body h2,
.panel .blog-body h3 { color: var(--gold-2); }
.panel .p-price { color: var(--gold-2); }
.panel h2 { margin-bottom: 14px; font-size: 1.6rem; }
.panel h3 { margin: 18px 0 8px; font-size: 1.15rem; }
.panel p, .panel li { color: var(--panel-ink); margin-bottom: 10px; }
.panel ul, .panel ol { padding-left: 22px; }

/* Centre the copy in the black bar on the home page. Scoped structurally rather than with a new
   class so no markup changes: home.ejs is the only view with a .hero, and the black bar is the
   first child of the .container that directly follows it. Every other .panel on the site (FAQ,
   product, cart, checkout, blog) keeps its left-aligned copy. */
.hero + .container > .panel { text-align: center; }

/* Panel interiors: anything that carried a dark-on-light colour has to be re-pointed for the
   black surface. Selectors are kept at or above the specificity of the light-theme rule they
   override (e.g. .product-detail .meta is 0-2-0, so .panel .meta alone would lose). */
.panel .meta,
.panel .p-strength,
.panel .blog-date,
.panel .form-grid label,
.panel .blog-body blockquote { color: var(--panel-ink-soft); }
.panel strong, .panel b { color: var(--white); }
.panel a { color: var(--gold-2); }
.panel a:hover { color: var(--gold-1); }
.panel .faq-item { border-bottom: 1px solid var(--gold-line); }
.panel .product-detail .img-wrap,
.panel.product-detail .img-wrap { border-color: var(--gold-line); }
/* Research-use note and code blocks: dark surfaces so they sit inside the panel, not on top of it */
.panel .ruo-note {
  background: rgba(255, 255, 255, 0.05);
  color: var(--panel-ink-soft);
}
.panel .blog-body pre {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--gold-line);
  color: var(--panel-ink);
}

.section-title {
  text-align: center;
  font-size: 2rem;
  font-weight: 700;
  margin: 40px 0 6px;
}
.section-sub { text-align: center; color: var(--ink-soft); margin-bottom: 24px; }

/* Buttons: metallic gold */
.btn {
  display: inline-block;
  border: 1px solid var(--gold-4);
  background: var(--metal-gold-btn);
  color: #241a02;
  font-family: 'Rubik', -apple-system, 'Segoe UI', Arial, sans-serif;
  font-weight: 600;
  padding: 11px 26px;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  cursor: pointer;
  text-transform: uppercase;
  border-radius: 6px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.65) inset, 0 -2px 6px rgba(138, 106, 20, 0.35) inset, 0 4px 12px rgba(184, 134, 11, 0.28);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35);
}
.btn:hover { filter: brightness(1.06); color: #241a02; }
.btn-outline {
  background: var(--metal-white);
  color: var(--gold-4);
  border: 1px solid var(--gold-3);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 3px 10px rgba(22, 24, 28, 0.1);
  text-shadow: none;
}
.btn-outline:hover { background: var(--metal-gold-btn); color: #241a02; }
/* Disabled buttons only ever appear inside cards and panels, both of which are black, so the
   spent state is a dim gold outline rather than the old silver pill. */
.btn[disabled], .btn:disabled {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(150, 110, 57, 0.55);
  color: #8d9096;
  cursor: not-allowed;
  box-shadow: none;
  text-shadow: none;
}

/* Shop controls */
.shop-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: center;
  margin: 10px 0 24px;
}
.shop-controls input[type="text"], .shop-controls select {
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 10px 14px;
  font-family: 'Rubik', -apple-system, 'Segoe UI', Arial, sans-serif;
  font-size: 0.95rem;
  min-width: 220px;
  border-radius: 6px;
}
.shop-controls .btn { padding: 10px 20px; }
/* The link between the two shop views. It sits where the stock tally used to,
   so the eye lands on the way through to the rest of the catalog instead of on
   a figure the partner asked to drop. */
.shop-crosslink { text-align: center; margin-bottom: 22px; }
.shop-crosslink a {
  color: var(--gold-4);
  font-size: 0.92rem;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--gold-line);
  padding-bottom: 2px;
}
.shop-crosslink a:hover { color: var(--gold-3); border-bottom-color: var(--gold-3); }

/* Product grid */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
  margin-bottom: 40px;
}
/* Cards carry the same black fill and antique gold ring as the panels. overflow: hidden is
   what clips the product image to the rounded corners, and it also clips the border-box gold
   layer, so the ring is drawn on an inner wrapper-free element by keeping the border
   transparent and letting the gradient show through it, exactly as on .panel. */
.product-card {
  background: var(--metal-black-panel) padding-box, var(--metal-gold-ring) border-box;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset, 0 8px 20px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  position: relative;
  color: var(--panel-ink);
}
.product-card .img-wrap { position: relative; }
/* The bottle shots are portrait (900x1080) inside a square card. object-fit: contain shows
   the whole vial instead of cropping the cap and base off, and the padding pulls it in to
   80% of the card so it sits in the frame rather than filling it. */
.product-card img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  padding: 10%;
  box-sizing: border-box;
  display: block;
}
.stock-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  background: var(--metal-white-flat);
  border: 1px solid var(--gold-3);
  color: var(--gold-4);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  padding: 4px 10px;
  text-transform: uppercase;
  border-radius: 4px;
}
.product-card .card-body { padding: 16px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.product-card .p-name { color: var(--panel-ink); font-size: 1rem; font-weight: 500; }
.product-card .p-name a { color: var(--panel-ink); }
.product-card .p-name a:hover { color: var(--gold-2); }
.product-card .p-strength { color: var(--panel-ink-soft); font-size: 0.85rem; }
.product-card .p-price { color: var(--gold-2); font-weight: 700; font-size: 1.05rem; margin-top: auto; }
.product-card .btn { width: 100%; margin-top: 10px; text-align: center; }

/* Product detail */
.product-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 34px; align-items: start; }
.product-detail .img-wrap { position: relative; border: 1px solid var(--silver-4); border-radius: 10px; overflow: hidden; }
.product-detail img { width: 100%; display: block; }
.product-detail .p-price { font-size: 1.6rem; color: var(--gold-4); font-weight: 700; margin: 12px 0; }
.product-detail .meta { color: var(--muted); font-size: 0.9rem; margin-bottom: 12px; }
.ruo-note { border-left: 3px solid var(--gold-3); padding: 10px 14px; background: var(--silver-2); color: var(--muted); font-size: 0.85rem; margin-top: 18px; border-radius: 0 6px 6px 0; }

/* Forms */
.form-grid { display: grid; gap: 14px; max-width: 560px; }
.form-grid label { color: var(--ink-soft); font-size: 0.88rem; font-weight: 500; }
.form-grid input, .form-grid textarea {
  width: 100%;
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 11px 14px;
  font-family: 'Rubik', -apple-system, 'Segoe UI', Arial, sans-serif;
  font-size: 0.95rem;
  border-radius: 6px;
}
.form-grid textarea { min-height: 140px; resize: vertical; }
.form-success {
  border: 1px solid var(--gold-3);
  background: linear-gradient(180deg, rgba(253, 243, 198, 0.7), rgba(243, 216, 121, 0.35));
  color: var(--gold-5);
  padding: 14px 18px;
  margin-bottom: 18px;
  border-radius: 6px;
}

/* FAQ */
.faq-item { border-bottom: 1px solid var(--line); padding: 16px 0; }
.faq-item h3 { margin: 0 0 6px; }

/* Footer: metallic black band, matching the panels. The gold ring is applied as a top edge
   only: the footer is full-bleed, so a ring on all four sides would run off the viewport
   left and right and read as a broken box rather than a border. */
.site-footer {
  background: var(--metal-black-panel);
  border-top: 2px solid transparent;
  border-image: var(--metal-gold-ring) 1;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset;
  margin-top: 60px;
  padding: 44px 0 26px;
  font-size: 0.9rem;
  color: var(--panel-ink);
}
.footer-cols {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 30px;
  margin-bottom: 28px;
}
.footer-cols h3 {
  font-size: 1rem;
  margin-bottom: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gold-2);
}
.footer-cols ul { list-style: none; }
.footer-cols li { margin-bottom: 7px; }
.footer-cols a { color: var(--panel-ink); }
.footer-cols a:hover { color: var(--gold-2); }
.footer-cols p { color: var(--panel-ink); }
/* Research-use disclaimer: kept on the light metallic surface deliberately. It is the one
   block in the black footer that stays a white card, so the legal copy reads as a notice
   rather than as more footer chrome. Do not fold it into the black treatment. */
.ruo-disclaimer {
  border: 1px solid var(--silver-4);
  background: var(--white);
  padding: 18px 22px;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.7;
  border-radius: 8px;
}
.ruo-disclaimer strong { color: var(--gold-4); }
.copyright { text-align: center; color: var(--panel-ink-soft); margin-top: 22px; font-size: 0.8rem; }

@media (max-width: 860px) {
  /* minmax(0, 1fr) rather than a bare 1fr, plus a break opportunity inside the footer links.
     A bare 1fr floors at min-content, and the support address is one unbreakable 38-character
     token, so the first footer column measured 275px inside a 350px container and pushed the
     document 16px wider than a 390px viewport. That horizontal scroll is what would carry the
     page out from under the fixed side rails on a phone, so it is fixed here rather than left
     for the rails to fail against. */
  .footer-cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .footer-cols a { overflow-wrap: anywhere; }
  .product-detail { grid-template-columns: 1fr; }
  .hero h1 { font-size: 1.35rem; }
}

/* Blog */
.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 22px; }
.blog-card { display: flex; flex-direction: column; gap: 8px; color: var(--ink); }
.blog-card:hover h2 { color: var(--gold-5); }
.blog-card-cover { width: 100%; height: 170px; object-fit: cover; border-radius: 8px; border: 1px solid var(--gold-line); }
.blog-date { color: var(--muted); font-size: 0.85rem; }
.blog-readmore { color: var(--gold-4); font-weight: 600; margin-top: auto; }
.blog-backlink { margin-bottom: 14px; }
.blog-post-cover { width: 100%; max-height: 380px; object-fit: cover; border-radius: 8px; border: 1px solid var(--gold-line); margin: 6px 0 16px; }
.blog-body { line-height: 1.65; }
.blog-body h1, .blog-body h2, .blog-body h3 { color: var(--gold-4); margin: 20px 0 8px; }
.blog-body p, .blog-body ul, .blog-body ol { margin-bottom: 12px; }
.blog-body ul, .blog-body ol { padding-left: 22px; }
.blog-body img { max-width: 100%; border-radius: 8px; }
.blog-body a { text-decoration: underline; }
.blog-body blockquote { border-left: 3px solid var(--gold-3); padding: 6px 14px; color: var(--muted); margin: 12px 0; }
.blog-body pre { background: var(--silver-2); border: 1px solid var(--line); border-radius: 8px; padding: 12px; overflow-x: auto; margin-bottom: 12px; }

/* Full product list A-Z. A reading list, not a shelf: one row per product, name
   first because the list is sorted on it, then the detail a customer needs to
   decide whether to open the product page. Rules between rows rather than cards,
   so fifty-odd rows stay scannable. */
.az-list {
  margin: 0 auto 44px;
  padding: 0;
  max-width: 820px;
  list-style: none;
  border-top: 1px solid var(--gold-line);
}
.az-row {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: baseline;
  gap: 6px 18px;
  padding: 11px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 0.94rem;
}
.az-name { color: var(--ink); font-weight: 500; }
.az-name:hover { color: var(--gold-4); }
.az-strength { color: var(--muted); font-size: 0.86rem; }
.az-price { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.az-stock {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  min-width: 92px;
  text-align: right;
}
.az-stock-in { color: var(--gold-4); }
.az-stock-out { color: var(--muted); }
/* Narrow screens: the name takes its own line, the detail wraps under it. */
@media (max-width: 620px) {
  .az-row { grid-template-columns: 1fr auto; }
  .az-name { grid-column: 1 / -1; }
  .az-strength { grid-column: 1; }
  .az-price { grid-column: 2; text-align: right; }
  .az-stock { grid-column: 1 / -1; text-align: left; min-width: 0; }
}
.stock-section-empty {
  margin: 30px 0;
  text-align: center;
  color: var(--ink-soft);
}

/* ============================================================
   Login wall (site gate)
   Modelled on the design Jay supplied, rendered in the OPS
   black/gold/beige palette rather than the reference's blue.
   Tabs are CSS-only: two hidden radios above the panel drive
   which form shows, so this works with JavaScript off.
   ============================================================ */

.gate-wrap {
  min-height: 70vh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 48px 20px 72px;
}

.gate {
  width: 100%;
  max-width: 520px;
  background: linear-gradient(180deg, #14161a 0%, #0b0d10 100%);
  border: 1px solid var(--gold-line, rgba(150, 110, 57, 0.5));
  border-radius: 10px;
  padding: 34px 30px 28px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.35);
  text-align: center;
  color: #e9e4da;
}

.gate-mark { height: 62px; width: auto; max-width: 70%; object-fit: contain; margin: 0 auto 10px; display: block; }

.gate-title {
  font-family: 'IM Fell English', Georgia, serif;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 30px;
  margin: 0 0 16px;
  color: var(--gold-2, #c9a35f);
}

.gate-lead { margin: 0 0 14px; line-height: 1.55; color: #e9e4da; }
.gate-lead strong { color: var(--gold-2, #c9a35f); }

/* The age and RUO statement. Deliberately loud: it is the legal notice. */
.gate-notice {
  text-transform: uppercase;
  font-size: 13px;
  line-height: 1.6;
  letter-spacing: 0.03em;
  color: #b9c2cf;
  margin: 0 0 20px;
}

.gate-error,
.gate-notice-msg {
  text-align: left;
  border-radius: 6px;
  padding: 10px 12px;
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.45;
}
.gate-error       { border: 1px solid #a03a3a; color: #f0a9a9; background: rgba(160, 58, 58, 0.14); }
.gate-notice-msg  { border: 1px solid #3f7a4a; color: #a9e0b6; background: rgba(63, 122, 74, 0.14); }

/* Tabs */
.gate-tab-input { position: absolute; opacity: 0; pointer-events: none; }
.gate-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid rgba(233, 228, 218, 0.18);
  margin-bottom: 22px;
}
.gate-tab {
  padding: 12px 6px;
  cursor: pointer;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #9aa3af;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  transition: color 120ms ease, border-color 120ms ease;
}
.gate-tab:hover { color: #e9e4da; }
#tab-login:checked  ~ .gate-tabs label[for="tab-login"],
#tab-create:checked ~ .gate-tabs label[for="tab-create"] {
  color: var(--gold-2, #c9a35f);
  border-bottom-color: var(--gold-2, #c9a35f);
}

/* Only the selected tab's form is shown. */
.gate-form { display: none; text-align: left; }
#tab-login:checked  ~ .gate-form-login  { display: block; }
#tab-create:checked ~ .gate-form-create { display: block; }

.gate-form label {
  display: block;
  font-weight: 700;
  font-size: 14px;
  margin: 0 0 6px;
  color: #e9e4da;
}
.gate-optional { font-weight: 400; color: #8d94a0; }

.gate-form input[type="text"],
.gate-form input[type="email"],
.gate-form input[type="date"],
.gate-form input[type="password"] {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(233, 228, 218, 0.28);
  border-radius: 0;
  color: #f4f1ea;
  font-size: 16px;           /* 16px stops iOS zooming the page on focus */
  padding: 10px 2px;
  margin-bottom: 20px;
}
.gate-form input:focus {
  outline: none;
  border-bottom-color: var(--gold-2, #c9a35f);
}
/* The native date picker indicator is near-invisible on a dark field. */
.gate-form input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.8); cursor: pointer; }

/* Password field plus its eye toggle */
.gate-pw { position: relative; }
.gate-pw input { padding-right: 40px; }
.gate-eye {
  position: absolute;
  right: 0;
  top: 4px;
  background: none;
  border: 0;
  padding: 4px;
  cursor: pointer;
  color: #8d94a0;
  line-height: 0;
}
.gate-eye:hover,
.gate-eye.is-on { color: var(--gold-2, #c9a35f); }

.gate-check {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 400 !important;
  margin: 0 0 22px !important;
  cursor: pointer;
}
.gate-check input { width: 18px; height: 18px; accent-color: var(--gold-3, #a8823f); margin: 0; }

.gate-hint { font-size: 13px; color: #8d94a0; margin: -14px 0 20px; }

/* Live password rules */
.gate-rules { list-style: none; margin: -8px 0 22px; padding: 0; font-size: 13px; color: #8d94a0; }
.gate-rules li { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.gate-rule-dot {
  width: 8px; height: 8px; border-radius: 50%;
  border: 1px solid #6b727d; background: transparent;
  flex: 0 0 auto;
  transition: background 120ms ease, border-color 120ms ease;
}
.gate-rules li.met { color: #a9e0b6; }
.gate-rules li.met .gate-rule-dot { background: #6fbf7f; border-color: #6fbf7f; }

.gate-submit { width: 100%; margin-bottom: 16px; }
.gate-alt { text-align: center; margin: 0; }
.gate-alt a { color: var(--gold-2, #c9a35f); }
.gate-foot {
  margin: 22px 0 0;
  font-size: 12px;
  color: #79808b;
  border-top: 1px solid rgba(233, 228, 218, 0.12);
  padding-top: 16px;
}

@media (max-width: 520px) {
  .gate { padding: 26px 20px 22px; }
  .gate-title { font-size: 25px; }
  .gate-wrap { padding: 26px 14px 52px; }
}

/* Log Out sits in the nav menu next to Account, so it has to look like the
   other nav links rather than a button. */
.nav-logout { margin: 0; padding: 0; display: block; }
.nav-logout button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
  width: 100%;
}
