/* ============================================================
   DAK HABITATS — storefront styles
   Plain CSS, no preprocessor.
   ============================================================ */

/* ------------------------------------------------------------------
   BRAND FACES — self-hosted, latin subset only.
   Self-hosted on purpose: privacy.html §5 states this site makes no
   third-party requests, and a Google Fonts <link> hands every visitor's
   IP to a third party. Re-subset from fonts.google.com if a locale
   outside latin is ever added.
   ------------------------------------------------------------------ */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/space-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/space-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ------------------------------------------------------------------
     DAK HABITATS THEME — "bioactive".

     Sampled straight out of the hero photograph (assets/hero-terrarium.*):
     a lit acrylic vivarium standing in deep jungle shade. Three families:

       grounds  the loam under the canopy. Near-black with an OLIVE cast
                (#191e0c and #151706 read out of the photo's shadows),
                never neutral grey — the warm ground is what makes the
                cool mark on top of it read as glass.
       accent   the blue of the mark etched on the enclosure (#266797 in
                the photo, opened up here so it clears AA as text). The
                only cool hue on the page, which is the point: it is the
                brand, and everything interactive wears it.
       growth   --moss, the lit canopy chartreuse (#90a521), and --ember,
                the bromeliad flare (#d55a06). Decorative and data-ink
                only — never the sole carrier of an interactive state.

     Every alpha tint in this file resolves through the *-rgb triplets,
     so keep each triplet in sync with its hex counterpart.

     --accent is used in BOTH directions. As text on a dark ground it
     clears AA comfortably (7.0:1). As a button GROUND it does NOT clear
     AA with --ink on top (2.4:1) — so anything sitting on an accent
     ground uses --on-accent (6.9:1) instead. --ember carries the same
     split via --on-ember. --moss has no ground use yet and so ships no
     on- colour; give it one before you put type on top of it.
     ------------------------------------------------------------------ */
  --bg: #090c07;
  --bg-rgb: 9, 12, 7;
  --bg-elev: #0f1409;
  --bg-card: #151b0f;

  /* Inks carry the faintest green in them so they sit in the photograph
     rather than on it. Pure #fff on this ground reads as a UI overlay. */
  --ink: #eaf0e4;
  --ink-rgb: 234, 240, 228;
  --ink-dim: #aab59f;
  --ink-mute: #7d8a71;

  --accent: #3fa3dd;
  --accent-rgb: 63, 163, 221;
  --accent-hot: #6bc0f0;
  --accent-hot-rgb: 107, 192, 240;
  --accent-deep: #1d6a9c;
  --accent-deep-rgb: 29, 106, 156;
  --on-accent: #041014;

  /* Canopy chartreuse — the lit moss at the top of the enclosure.
     10:1 as text on --bg, so it is safe for small type. */
  --moss: #a8c53f;
  --moss-rgb: 168, 197, 63;

  /* Bromeliad flare. The hottest thing in the photo and the hottest
     thing on the page — spend it sparingly, on one element per view. */
  --ember: #e2701f;
  --ember-rgb: 226, 112, 31;
  --on-ember: #1a0c02;

  /* Markdown red. The one hue on this page that is not sampled from the hero
     photograph, and that is the point: a price cut has to read as an
     interruption of the palette, not as another leaf in it. Two values, the
     same on-ground split as --accent/--on-accent above — the ground is dark
     enough for white on it (5.7:1) and too dark to be legible AS text on
     --bg (3.4:1), so red type uses --sale-red-ink (7.0:1) instead.
     Spent only on the deals strip; the Sale flag elsewhere stays --ember. */
  --sale-red: #c5251a;
  --sale-red-rgb: 197, 37, 26;
  --on-sale-red: #ffffff;
  --sale-red-ink: #ff6b5e;

  /* Announcement yellow. Sits between --moss and --ember in hue and is
     brighter than either, which is how the bar still cuts out of a page
     that now has warm accents of its own. Ink on it is near-black, not
     --ink: #17120a on #f2c14e is 11:1, while the light --ink on the same
     ground would be about 1.5:1 and unreadable. Same on-ground rule as
     --accent/--on-accent above. */
  --warn: #f2c14e;
  --warn-rgb: 242, 193, 78;
  --on-warn: #17120a;

  /* Wet lava rock, out of the right-hand side of the enclosure. */
  --stone: #232a1c;
  --rule: rgba(var(--ink-rgb), 0.16);
  --rule-soft: rgba(var(--ink-rgb), 0.07);

  --font-display: "Space Grotesk", "Segoe UI", system-ui, -apple-system, Helvetica, Arial, sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --container: 1200px;
  --section-y: clamp(80px, 10vw, 148px);
  --radius-sm: 10px;
  --radius-md: 18px;

  /* Elevation. --lift is the shadow, --ring the accent hairline that
     comes with it on hover; they are meant to be used together. */
  --lift: 0 30px 70px -34px rgba(0, 0, 0, 0.9);
  --ring: 0 0 0 1px rgba(var(--accent-rgb), 0.28);
  --glow: 0 14px 40px -18px rgba(var(--accent-rgb), 0.55);
}

/* ---------- reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.62;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img {
  display: block;
  max-width: 100%;
  height: auto;
}
a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.04;
  margin: 0;
}
p {
  margin: 0;
}

/* Visually hidden, still read aloud. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- skip link ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  border-radius: var(--radius-sm);
  padding: 12px 18px;
  z-index: 999;
}
.skip-link:focus {
  left: 12px;
  top: 12px;
}

/* ---------- container ---------- */
.container {
  width: min(100% - 40px, var(--container));
  margin-inline: auto;
}

/* ---------- focus ---------- */
:focus-visible {
  outline: 3px solid var(--accent-hot);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ============================================================
   HEADER
   ============================================================ */
/* A solid black bar, not a translucent one. It is the only chrome above the
   photograph, and glass over a photograph would put a slice of jungle behind
   the wordmark; flat black is what lets the picture start cleanly at its
   bottom edge. Pure #000 rather than --bg for the same reason: --bg is a
   dark olive and would read as a third colour against the photo. */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 80;
  padding: 11px 0;
  background: #000;
  border-bottom: 1px solid rgba(var(--ink-rgb), 0.14);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 13px;
  min-width: 0;
}

/* The lockup: flat PNG mark + two-tone wordmark, at the size the bar used to
   settle to — one size, held the whole way down the page. There is no larger
   arrival state; the bar you land on is the bar you keep. A flat height rather
   than a clamp, because at this size the lockup and the nav already share one
   line at every width the nav is visible at. */
.brand-logo {
  height: 38px;
  width: auto;
  flex: none;
  filter: drop-shadow(0 2px 14px rgba(var(--accent-rgb), 0.5));
  transition: transform 380ms cubic-bezier(0.2, 0.8, 0.2, 1), filter 380ms ease;
}
.brand:hover .brand-logo,
.brand:focus-visible .brand-logo {
  transform: translateY(-2px) rotate(-4deg);
  filter: drop-shadow(0 6px 18px rgba(var(--accent-rgb), 0.75));
}
.brand-mark {
  font-family: var(--font-display);
  font-size: clamp(19px, 2.4vw, 24px);
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  line-height: 1.05;
  color: var(--ink);
  white-space: nowrap;
  display: block;
}
/* Second word steps back so the lockup reads as one shape, not two. */
.brand-mark span {
  font-weight: 500;
  color: var(--ink-dim);
}

.primary-nav {
  display: flex;
  align-items: center;
  gap: 28px;
}
.primary-nav a {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  position: relative;
  padding: 6px 0;
  transition: color 200ms ease, font-size 320ms ease;
}
.primary-nav a:hover {
  color: var(--ink);
}
.primary-nav a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 0;
  background: var(--accent);
  transition: width 280ms ease;
}
.primary-nav a:not(.btn):hover::after {
  width: 100%;
}

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  position: relative;
}
.nav-toggle span {
  position: absolute;
  left: 10px;
  right: 10px;
  height: 2px;
  background: var(--ink);
  transition: transform 280ms ease, opacity 200ms ease, top 280ms ease;
}
.nav-toggle span:nth-child(1) {
  top: 14px;
}
.nav-toggle span:nth-child(2) {
  top: 21px;
}
.nav-toggle span:nth-child(3) {
  top: 28px;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  top: 21px;
  transform: rotate(45deg);
}
.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  top: 21px;
  transform: rotate(-45deg);
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 22px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 200ms ease, background-color 200ms ease, border-color 200ms ease,
    color 200ms ease, box-shadow 280ms ease;
  white-space: nowrap;
}
.btn-sm {
  padding: 10px 16px;
  font-size: 12px;
}
/* Dark label on the blue, not light — see the --on-accent note at :root. */
.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  font-weight: 700;
  box-shadow: var(--glow);
}
.btn-primary:hover {
  background: var(--accent-hot);
  border-color: var(--accent-hot);
  transform: translateY(-2px);
  box-shadow: 0 18px 44px -16px rgba(var(--accent-hot-rgb), 0.75);
}
.btn-ghost {
  border-color: var(--rule);
  color: var(--ink);
  background: rgba(var(--ink-rgb), 0.02);
}
.btn-ghost:hover {
  border-color: rgba(var(--accent-rgb), 0.55);
  color: var(--ink);
  background: rgba(var(--accent-rgb), 0.1);
  transform: translateY(-2px);
}
.btn-link {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 0;
  border: 0;
}
.btn-link:hover {
  color: var(--accent-hot);
}
.btn-icon svg {
  width: 16px;
  height: 16px;
}

/* ============================================================
   HERO
   The photograph, edge to edge, sized to whatever the fixed black bar
   leaves of the first screen. There is deliberately no copy over it:
   the wordmark in the bar is the only thing competing for attention,
   and the pitch picks up in the section below the fold.
   ============================================================ */
.hero {
  position: relative;
  /* Both bars are position:fixed, so the hero has to reserve their height
     itself. box-sizing is border-box, so the picture gets exactly the
     leftover. --promo-h is 0px when there is no announcement bar, which is
     why this one rule covers both cases. */
  padding-top: calc(var(--promo-h) + var(--header-h));
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: var(--bg);
}
.hero-picture,
.hero-photo {
  display: block;
  width: 100%;
  height: 100%;
}
/* 44% rather than centre: the enclosure sits slightly high in the frame, and
   on a wide viewport the crop is vertical, so biasing up keeps the lid and
   loses undergrowth instead of the other way round. */
.hero-photo {
  object-fit: cover;
  object-position: center 44%;
}
/* The photograph's own bottom edge is a hard horizontal line against the
   section under it. This dissolves it over the last few percent so the page
   reads as one surface rather than a banner stuck on top of a site. */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 16%;
  background: linear-gradient(180deg, transparent, var(--bg));
  pointer-events: none;
}

/* Portrait takes the square crop (see the <picture> in index.html) and drops
   the full-screen height with it: the hero becomes exactly as tall as that
   crop is, so the whole build is on screen and the first scroll still reaches
   real content instead of more photograph. Matches the preload and the
   <source> above it — all three switch on (orientation). */
@media (orientation: portrait) {
  .hero {
    height: auto;
  }
  .hero-picture,
  .hero-photo {
    height: auto;
  }
  .hero-photo {
    aspect-ratio: 1160 / 1024;
  }
}

.eyebrow {
  font-family: var(--font-body);
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 22px;
}
/* Still used by every page hero (shop, contact, cart, terms, privacy) even
   though the landing page no longer has a headline of its own. No italic
   here: Space Grotesk ships no italic cut, and a synthesised oblique on a
   geometric face reads as a mistake. The emphasis is the colour plus the
   underglow. */
.accent-word {
  color: var(--accent);
  font-weight: 700;
  position: relative;
}
.accent-word::after {
  content: "";
  position: absolute;
  left: 0;
  right: 8%;
  bottom: 0.06em;
  height: 0.1em;
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.5), rgba(var(--accent-rgb), 0));
  z-index: -1;
}

/* ============================================================
   SECTIONS
   ============================================================ */
.section {
  padding: var(--section-y) 0;
  position: relative;
}
/* The recessed bands. A flat fill reads as a grey stripe once the page has a
   photograph in it, so the band carries the same light the hero does: a cool
   wash off the top edge, a warm one off the bottom, both at a few percent. */
.section-alt {
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(var(--accent-deep-rgb), 0.14) 0%, transparent 70%),
    radial-gradient(90% 55% at 50% 100%, rgba(var(--moss-rgb), 0.055) 0%, transparent 72%),
    var(--bg-elev);
  border-block: 1px solid var(--rule-soft);
}

.section-head {
  max-width: 720px;
  margin: 0 auto 64px;
  text-align: center;
}
.section-head h2 {
  font-size: clamp(2rem, 4vw, 3.2rem);
  margin-bottom: 18px;
}
.section-head .section-lede {
  color: var(--ink-dim);
  font-size: 1.05rem;
}
.section-head-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 32px;
  text-align: left;
  max-width: none;
}

/* ============================================================
   FEATURE GRID + SIZE GUIDE  (homepage)
   Both are markup the DAK fork added to index.html; neither had any
   styling in the template, so they rendered as a bare list and a bare
   table. Defined here rather than inline so shop/contact can reuse them.
   ============================================================ */
.feature-grid {
  /* 320px floor lands on three columns at container width, so the six cards
     fall 3 + 3 instead of a lopsided 4 + 2. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 20px;
  counter-reset: feature;
}
.feature-card {
  position: relative;
  padding: 34px 28px 30px;
  background:
    linear-gradient(180deg, rgba(var(--ink-rgb), 0.035), rgba(var(--ink-rgb), 0) 58%),
    var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform 320ms ease, border-color 320ms ease, box-shadow 320ms ease;
}
/* Counter rather than hand-numbered markup, so reordering the list in
   index.html cannot desync the numbers. */
.feature-card::before {
  counter-increment: feature;
  content: counter(feature, decimal-leading-zero);
  position: absolute;
  top: 20px;
  right: 24px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--ink-mute);
  transition: color 320ms ease;
}
.feature-card::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0), transparent);
  transition: background 320ms ease;
}
.feature-card:hover {
  transform: translateY(-4px);
  border-color: rgba(var(--accent-rgb), 0.32);
  box-shadow: var(--lift), var(--ring);
}
.feature-card:hover::before {
  color: var(--accent);
}
.feature-card:hover::after {
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.75), transparent);
}
.feature-card h3 {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 14px;
  padding-right: 34px;
}
.feature-card p {
  color: var(--ink-dim);
  font-size: 15px;
  line-height: 1.62;
}

/* ============================================================
   SPECIES PLACEHOLDER ART
   Decorative SVG-pattern tiles standing in for real photos.
   ============================================================ */
.species-art {
  width: 100%;
  aspect-ratio: 1 / 1;
  position: relative;
  overflow: hidden;
  background: radial-gradient(ellipse at 30% 30%, #26301b 0%, #080c05 70%);
}
.species-art::before,
.species-art::after {
  content: "";
  position: absolute;
  inset: 0;
}
/* legs / web pattern */
.species-art::before {
  background:
    radial-gradient(circle at 50% 60%, rgba(var(--accent-rgb), 0.22) 0%, transparent 35%),
    repeating-conic-gradient(
      from 0deg at 50% 60%,
      rgba(var(--ink-rgb), 0.05) 0deg 6deg,
      transparent 6deg 30deg
    );
  mix-blend-mode: screen;
}
/* body silhouette */
.species-art::after {
  background:
    radial-gradient(ellipse 38% 28% at 50% 62%, #16190f 60%, transparent 62%),
    radial-gradient(ellipse 18% 14% at 50% 46%, #10130b 60%, transparent 62%);
}
/* variation by data-species */
.species-art[data-species="2"]::before {
  filter: hue-rotate(-25deg);
}
.species-art[data-species="3"]::before {
  filter: hue-rotate(15deg) brightness(1.1);
}
.species-art[data-species="4"]::before {
  filter: brightness(0.8);
}
.species-art[data-species="5"]::before {
  filter: hue-rotate(-15deg) brightness(1.05);
}
.species-art[data-species="6"]::before {
  filter: hue-rotate(8deg);
}
.species-art[data-species="7"]::before {
  filter: hue-rotate(-30deg) brightness(0.9);
}
.species-art[data-species="8"]::before {
  filter: hue-rotate(20deg) brightness(1.1);
}

/* ============================================================
   FEATURED SPECIES GRID
   ============================================================ */
.species-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 28px;
}
.species-card {
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform 320ms ease, border-color 320ms ease, box-shadow 320ms ease;
}
.species-card:hover {
  transform: translateY(-6px);
  border-color: rgba(var(--accent-rgb), 0.32);
  box-shadow: var(--lift), var(--ring);
}
.species-media {
  position: relative;
}
.species-body {
  padding: 24px 24px 26px;
}
.species-body h3 {
  font-size: 1.4rem;
  margin-bottom: 4px;
}
.species-sci {
  font-style: italic;
  color: var(--ink-mute);
  font-size: 14px;
  margin-bottom: 18px;
}
.species-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 18px;
  margin-bottom: 22px;
  padding-block: 16px;
  border-top: 1px solid var(--rule-soft);
  border-bottom: 1px solid var(--rule-soft);
}
.species-meta li {
  font-size: 14px;
  color: var(--ink);
}
.species-meta span {
  display: block;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 4px;
}

.tag {
  position: absolute;
  top: 14px;
  left: 14px;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 6px 10px;
  background: rgba(var(--bg-rgb), 0.7);
  backdrop-filter: blur(6px);
  border: 1px solid var(--rule-soft);
  color: var(--ink);
}
.tag-status::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--moss);
  margin-right: 7px;
  vertical-align: middle;
  box-shadow: 0 0 8px rgba(var(--moss-rgb), 0.9);
}
.tag-limited::before {
  background: var(--accent-hot);
  box-shadow: 0 0 8px var(--accent-hot);
}
.tag-sold::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-mute);
  margin-right: 7px;
  vertical-align: middle;
}
.tag-sold {
  color: var(--ink-dim);
}

/* ============================================================
   PILLARS (WHY US)
   ============================================================ */
.pillar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px;
}
.pillar {
  text-align: center;
  padding: 38px 24px;
  background:
    linear-gradient(180deg, rgba(var(--ink-rgb), 0.035), rgba(var(--ink-rgb), 0) 58%),
    var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  transition: border-color 320ms ease, transform 320ms ease, box-shadow 320ms ease;
}
.pillar:hover {
  border-color: rgba(var(--accent-rgb), 0.32);
  transform: translateY(-4px);
  box-shadow: var(--lift), var(--ring);
}
.pillar-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  color: var(--accent);
  margin-bottom: 20px;
  background: rgba(var(--accent-rgb), 0.08);
  box-shadow: inset 0 0 24px -8px rgba(var(--accent-rgb), 0.5);
}
.pillar-icon svg {
  width: 28px;
  height: 28px;
}
.pillar h3 {
  font-size: 1.05rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.pillar p {
  color: var(--ink-dim);
  font-size: 15px;
  line-height: 1.55;
}

/* ============================================================
   BEGINNERS
   ============================================================ */
.beginners-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.beginners-copy h2 {
  font-size: clamp(2rem, 4vw, 3.2rem);
  margin: 12px 0 22px;
}
.beginners-copy p {
  color: var(--ink-dim);
  margin-bottom: 32px;
  max-width: 460px;
}
.beginners-list li {
  display: flex;
  gap: 16px;
  padding: 18px 0;
  border-bottom: 1px solid var(--rule-soft);
}
.beginners-list li:last-child {
  border-bottom: 0;
}
.beginners-list .check {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--accent);
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
}
.beginners-list strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.04em;
  font-size: 1.05rem;
  margin-bottom: 2px;
}
.beginners-list span {
  color: var(--ink-dim);
  font-size: 14px;
}

/* ============================================================
   MINI GRID (Availability)
   ============================================================ */
.mini-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 20px;
}
.mini-card {
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform 280ms ease, border-color 280ms ease;
}
.mini-card:hover {
  transform: translateY(-4px);
  border-color: var(--rule);
}
.mini-card h4 {
  font-size: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 14px 14px 2px;
}
.mini-card p {
  font-style: italic;
  font-size: 12px;
  color: var(--ink-mute);
  margin: 0 14px 8px;
}
.mini-price {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-dim);
  font-style: normal;
  margin: 0 14px 16px;
}
.species-price {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-dim);
  margin: 8px 0 0;
}
.species-quantity {
  font-size: 13px;
  color: var(--ink-mute);
  margin: 4px 0 0;
  letter-spacing: 0.02em;
}

/* ---- Merch & Supplies cards ---- */
.merch-category {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}
.merch-desc {
  font-size: 14px;
  color: var(--ink-mute);
  line-height: 1.5;
  margin-bottom: 18px;
}
/* Exterior measurement of the selected size. Tabular figures keep the numbers
   aligned down a column of cards instead of jittering per glyph width. */
.merch-dims {
  font-size: 13px;
  color: var(--ink-dim);
  margin: .6rem 0 0;
  font-variant-numeric: tabular-nums;
}
.merch-dims-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-right: .45rem;
}
.btn-link.is-disabled {
  color: var(--ink-dim);
  cursor: default;
  pointer-events: none;
}
.mini-quantity {
  font-size: 12px;
  color: var(--ink-mute);
  margin: 0 14px 14px;
  letter-spacing: 0.02em;
}
.section-foot {
  text-align: center;
  margin-top: 36px;
}
.species-no-photo {
  background: radial-gradient(ellipse at 40% 35%, var(--bg-card) 0%, var(--bg) 75%);
}
.inventory-empty {
  color: var(--ink-mute);
  font-size: 14px;
  text-align: center;
  padding: 40px 0;
  grid-column: 1 / -1;
}

/* ============================================================
   INQUIRY FORM
   ============================================================ */
.inquiry-form {
  max-width: 820px;
  margin: 0 auto;
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  padding: clamp(28px, 4vw, 48px);
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.8);
}
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}
.form-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.form-field-wide {
  grid-column: 1 / -1;
}
.form-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.form-label .req {
  color: var(--accent);
  margin-left: 2px;
}
.form-label .opt {
  letter-spacing: 0.06em;
  text-transform: none;
  font-weight: 400;
  color: var(--ink-mute);
  margin-left: 4px;
}
.inquiry-form input,
.inquiry-form select,
.inquiry-form textarea {
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  background: rgba(var(--bg-rgb), 0.55);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  width: 100%;
  transition: border-color 200ms ease, background-color 200ms ease, box-shadow 200ms ease;
}
.inquiry-form input::placeholder,
.inquiry-form textarea::placeholder {
  color: var(--ink-mute);
}
.inquiry-form select {
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-position: calc(100% - 22px) 52%, calc(100% - 16px) 52%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 44px;
}
.inquiry-form select option {
  background: var(--bg-elev);
  color: var(--ink);
}
.inquiry-form input:hover,
.inquiry-form select:hover,
.inquiry-form textarea:hover {
  border-color: rgba(var(--accent-rgb), 0.35);
}
.inquiry-form input:focus,
.inquiry-form select:focus,
.inquiry-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(var(--bg-rgb), 0.85);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18);
}
.inquiry-form input:invalid:not(:placeholder-shown) {
  border-color: rgba(var(--accent-hot-rgb), 0.55);
}
.inquiry-form textarea {
  resize: vertical;
  min-height: 120px;
  font-family: var(--font-body);
  line-height: 1.55;
}
.form-honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 28px;
  margin-top: 28px;
  padding-top: 24px;
  border-top: 1px solid var(--rule-soft);
}
.form-note {
  color: var(--ink-mute);
  font-size: 13px;
  flex: 1 1 220px;
  line-height: 1.5;
}
.form-error {
  color: var(--accent-hot);
  font-size: 14px;
  margin-bottom: 16px;
  padding: 12px 16px;
  border: 1px solid rgba(var(--accent-hot-rgb), 0.35);
  border-radius: var(--radius-sm);
  background: rgba(var(--accent-hot-rgb), 0.08);
}
.inquiry-form button[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}
.form-success {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(32px, 6vw, 72px) 24px;
  gap: 18px;
}
.form-success-icon {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 1px solid var(--accent);
  background: rgba(var(--accent-rgb), 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  font-size: 28px;
}
.form-success h3 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  margin: 0;
}
.form-success p {
  color: var(--ink-dim);
  max-width: 420px;
  font-size: 1rem;
  line-height: 1.6;
}
@media (max-width: 640px) {
  .form-grid {
    grid-template-columns: 1fr;
    gap: 18px;
  }
  .form-actions .btn {
    width: 100%;
  }
  .form-note {
    text-align: center;
  }
}

/* ============================================================
   CTA
   ============================================================ */
.cta {
  position: relative;
  padding: clamp(80px, 12vw, 160px) 0;
  text-align: center;
  isolation: isolate;
  overflow: hidden;
  border-block: 1px solid var(--rule);
}
.cta-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(var(--accent-rgb), 0.26) 0%, transparent 55%),
    radial-gradient(ellipse at 18% 100%, rgba(var(--accent-deep-rgb), 0.34) 0%, transparent 60%),
    radial-gradient(ellipse at 84% 96%, rgba(var(--moss-rgb), 0.16) 0%, transparent 58%),
    linear-gradient(180deg, var(--bg-elev) 0%, var(--bg) 100%);
}
.cta-inner {
  max-width: 760px;
}
.cta h2 {
  font-size: clamp(2.2rem, 4.5vw, 3.6rem);
  margin: 8px 0 18px;
}
.cta-sub {
  color: var(--ink-dim);
  font-size: 1.1rem;
  margin-bottom: 40px;
}
.cta-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
}

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer {
  padding: 56px 0 40px;
  background: var(--bg);
  border-top: 1px solid var(--rule-soft);
}
.footer-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 32px;
}
.footer-brand {
  display: flex;
  align-items: center;
  gap: 16px;
}
.footer-brand .brand-logo {
  height: 50px;
}
.footer-brand .brand-mark {
  font-size: 20px;
}
.footer-tag {
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}
.footer-nav a {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 200ms ease;
}
.footer-nav a:hover {
  color: var(--accent);
}
/* Bottom bar: copyright · legal links · studio credit */
.footer-bottom {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 28px;
  padding-top: 28px;
  border-top: 1px solid var(--rule-soft);
}
.footer-copy {
  margin: 0;
  font-size: 12px;
  color: var(--ink-mute);
  letter-spacing: 0.06em;
}
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.footer-legal a {
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  text-decoration: underline;
  text-decoration-color: rgba(var(--ink-rgb), 0.25);
  text-underline-offset: 3px;
  transition: color 200ms ease;
}
.footer-legal a:hover {
  color: var(--ink);
}

/* King Sago credit backlink — styling only. The link itself must stay
   followed (no rel="nofollow"/"sponsored"/"noreferrer"); see
   backlink-badge/README.md. */
.ks-credit {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  margin-left: auto;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  transition: color 200ms ease;
}
.ks-credit:hover,
.ks-credit:focus-visible {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.ks-credit__arrow {
  font-size: 1.05em;
  transition: transform 200ms ease;
}
.ks-credit:hover .ks-credit__arrow {
  transform: translateX(2px);
}

/* ============================================================
   LEGAL / LONG-FORM PAGES  (terms.html)
   ============================================================ */
.legal {
  max-width: 760px;
  margin-inline: auto;
}

/* --- prose. Declared first; the meta strip and the table of contents below
   re-qualify with .legal so they outrank these on equal-specificity ties. --- */
.legal h2 {
  margin: 56px 0 18px;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  scroll-margin-top: 100px;
}
.legal h2:first-of-type {
  margin-top: 0;
}
.legal p,
.legal li {
  color: var(--ink-dim);
  font-size: 1rem;
  line-height: 1.75;
}
.legal p {
  margin: 0 0 18px;
}
/* the global reset strips ul markers — put them back for prose */
.legal ul {
  list-style: disc;
  margin: 0 0 18px;
  padding-left: 1.3em;
}
.legal li {
  margin-bottom: 12px;
}
.legal li::marker {
  color: var(--ink-mute);
}
.legal strong {
  color: var(--ink);
  font-weight: 600;
}
.legal a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: rgba(var(--ink-rgb), 0.35);
  text-underline-offset: 3px;
  transition: text-decoration-color 200ms ease;
}
.legal a:hover {
  text-decoration-color: var(--accent-hot);
}

/* --- effective date / business line --- */
.legal .legal-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin: 0 0 40px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 12px;
  line-height: 1.6;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* --- table of contents --- */
.legal .legal-toc {
  margin-bottom: 56px;
  padding: 28px 32px;
  background: var(--bg-elev);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
}
.legal .legal-toc-title {
  margin: 0 0 18px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent);
}
.legal .legal-toc ol {
  margin: 0;
  padding-left: 1.4em;
  columns: 2;
  column-gap: 36px;
}
.legal .legal-toc li {
  margin-bottom: 8px;
  break-inside: avoid;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-mute);
}
.legal .legal-toc a {
  color: var(--ink-dim);
  text-decoration: none;
  transition: color 200ms ease;
}
.legal .legal-toc a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============================================================
   REVEAL ANIMATION
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 700ms ease, transform 700ms ease;
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 960px) {
  .nav-toggle {
    display: block;
  }
  .primary-nav {
    position: fixed;
    /* Was a hardcoded 76px, which drifted the moment the brand lockup or the
       announcement bar changed height. Both terms are measured now. */
    inset: calc(var(--promo-h) + var(--header-h)) 0 0 0;
    background: rgba(var(--bg-rgb), 0.97);
    backdrop-filter: blur(16px);
    flex-direction: column;
    align-items: flex-start;
    padding: 32px 28px;
    gap: 4px;
    transform: translateX(100%);
    transition: transform 320ms ease;
    border-top: 1px solid var(--rule-soft);
  }
  .primary-nav.is-open {
    transform: translateX(0);
  }
  .primary-nav a {
    width: 100%;
    padding: 18px 0;
    border-bottom: 1px solid var(--rule-soft);
    font-size: 16px;
    letter-spacing: 0.14em;
  }
  .primary-nav a.btn {
    margin-top: 22px;
    border-bottom: 0;
    width: 100%;
  }
  .beginners-grid {
    grid-template-columns: 1fr;
    gap: 36px;
  }
  .mini-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .gallery {
    grid-template-columns: repeat(3, 1fr);
  }
  .footer-inner {
    grid-template-columns: 1fr;
    text-align: left;
  }
  .section-head-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 640px) {
  body {
    font-size: 16px;
  }
  .mini-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }
  .section-head {
    margin-bottom: 48px;
  }
  .cta-buttons {
    flex-direction: column;
  }
  .cta-buttons .btn {
    width: 100%;
  }
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
  }
  .ks-credit {
    margin-left: 0;
  }
  .legal-toc {
    padding: 24px 22px;
  }
  .legal-toc ol {
    columns: 1;
  }
}

/* ============================================================
   REAL PHOTOS
   ============================================================ */
.species-img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* ---- In-card photo carousel ---- */
.gallery-track {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.gallery-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  transition: opacity 320ms ease;
}
.gallery-slide.is-active {
  opacity: 1;
}
.gallery-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 220ms ease, background 220ms ease;
}
.gallery-nav:hover {
  background: rgba(0, 0, 0, 0.72);
}
.gallery-prev { left: 10px; }
.gallery-next { right: 10px; }
.species-media:hover .gallery-nav,
.gallery-nav:focus-visible {
  opacity: 1;
}
.gallery-dots {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 10px;
  display: flex;
  justify-content: center;
  gap: 7px;
}
.gallery-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  transition: background 220ms ease, transform 220ms ease;
}
.gallery-dot.is-active {
  background: var(--accent);
  transform: scale(1.25);
}
/* Touch devices can't hover — keep controls visible */
@media (hover: none) {
  .gallery-nav { opacity: 1; }
}

.species-body-minimal {
  padding: 18px 22px;
}


/* ============================================================
   STORE PAGE
   ============================================================ */
.page-hero {
  /* Reserves both fixed bars the way .hero does, then adds the gap itself —
     a flat top pad cleared the header by luck, and this tracks it whatever
     height it settles at. --promo-h is 0px with no announcement bar. */
  padding: calc(var(--promo-h) + var(--header-h) + clamp(36px, 5vw, 64px)) 0
    clamp(56px, 8vw, 100px);
  text-align: center;
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
/* Same canopy as .hero, at a fraction of the strength: enough that shop,
   contact and cart open under the same light as the landing page, not so
   much that it competes with the product grid underneath. It is the same
   464-byte thumbnail the home page already has cached. */
.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: url("assets/hero-ambient.webp") no-repeat center 20% / cover;
  filter: blur(56px) saturate(130%);
  opacity: 0.34;
  transform: scale(1.1);
}
.page-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(var(--accent-rgb), 0.2) 0%, transparent 55%),
    linear-gradient(180deg, rgba(var(--bg-rgb), 0.72) 0%, rgba(var(--bg-rgb), 0.86) 55%, var(--bg) 100%);
}
.page-hero h1 {
  font-size: clamp(2.4rem, 6vw, 5rem);
  margin-bottom: 16px;
}
.page-hero p {
  color: var(--ink-dim);
  font-size: 1.05rem;
  max-width: 560px;
  margin: 0 auto;
}

.store-filters {
  padding: 0 0 clamp(36px, 5vw, 60px);
}

.filter-toolbar {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 18px;
}
.filter-search-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
}
.filter-search-wrap svg {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--ink-mute);
  pointer-events: none;
}
.filter-search {
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
  padding: 10px 14px 10px 38px;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
.filter-search::placeholder {
  color: var(--ink-mute);
}
.filter-search:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.15);
}
.filter-sort {
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-dim);
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
  padding: 10px 36px 10px 13px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-position: calc(100% - 16px) 52%, calc(100% - 10px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  transition: border-color 200ms ease;
  white-space: nowrap;
  flex-shrink: 0;
}
.filter-sort:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.15);
}
.filter-sort option {
  background: var(--bg-elev);
  color: var(--ink);
}

.filter-pills-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
}
.filter-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.filter-divider {
  width: 1px;
  height: 20px;
  background: var(--rule-soft);
  flex-shrink: 0;
}
.filter-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.filter-pill {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 13px;
  border-radius: 999px;
  border: 1px solid var(--rule-soft);
  color: var(--ink-dim);
  background: transparent;
  cursor: pointer;
  transition: border-color 200ms ease, color 200ms ease, background-color 200ms ease;
}
.filter-pill:hover {
  border-color: var(--rule);
  color: var(--ink);
}
.filter-pill.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

@media (max-width: 640px) {
  .filter-toolbar {
    flex-direction: column;
    align-items: stretch;
  }
  .filter-divider {
    display: none;
  }
  .filter-pills-row {
    gap: 10px 0;
    flex-direction: column;
    align-items: flex-start;
  }
}

.store-grid-section {
  padding-bottom: clamp(72px, 10vw, 140px);
}
.store-count {
  margin-top: 36px;
  font-size: 13px;
  color: var(--ink-mute);
  letter-spacing: 0.08em;
  text-align: center;
}
.store-empty {
  color: var(--ink-mute);
  font-size: 14px;
  text-align: center;
  padding: 60px 0;
  grid-column: 1 / -1;
}

.nav-active {
  color: var(--ink) !important;
}
.nav-active::after {
  width: 100% !important;
}

/* ============================================================
   CART BADGE (header)
   ============================================================ */
.cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.cart-link svg {
  width: 20px;
  height: 20px;
}
.cart-badge {
  position: absolute;
  top: -8px;
  right: -11px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
.cart-badge.is-empty {
  display: none;
}

/* ============================================================
   ADD TO CART BUTTON
   ============================================================ */
.add-to-cart-btn {
  font-family: var(--font-body);
}
.add-to-cart-btn[disabled] {
  opacity: 0.6;
  cursor: default;
}

/* ============================================================
   CART PAGE
   ============================================================ */
.cart-section {
  padding-bottom: clamp(72px, 10vw, 140px);
}
.cart-layout {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 40px;
  align-items: start;
}
.cart-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.cart-row {
  display: grid;
  grid-template-columns: 72px 1fr auto auto;
  gap: 16px;
  align-items: center;
  padding: 16px;
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
}
.cart-row-unavailable {
  border-color: rgba(var(--accent-hot-rgb), 0.4);
}
.cart-row-media img,
.cart-row-no-photo {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--bg-elev);
}
.cart-row-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
}
.cart-row-sci {
  font-style: italic;
  color: var(--ink-mute);
  font-size: 13px;
  margin-top: 2px;
}
.cart-row-qty {
  color: var(--ink-dim);
  font-size: 13px;
  margin-top: 4px;
}
.cart-row-flag {
  color: var(--accent-hot);
  font-size: 13px;
  margin-top: 4px;
}
.cart-row-price {
  font-weight: 600;
  color: var(--ink-dim);
  white-space: nowrap;
}
.cart-empty {
  text-align: center;
  padding: 60px 20px;
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}
.cart-empty[hidden] {
  display: none;
}
.cart-empty p {
  color: var(--ink-dim);
}
.cart-summary {
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  position: sticky;
  top: 100px;
}
.cart-summary h2 {
  font-size: 1.2rem;
}
.cart-summary input {
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  background: rgba(var(--bg-rgb), 0.55);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  width: 100%;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
.cart-summary input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18);
}
.cart-totals {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding-top: 18px;
  border-top: 1px solid var(--rule-soft);
}
.cart-totals > div {
  display: flex;
  justify-content: space-between;
  font-size: 14px;
  color: var(--ink-dim);
}
.cart-totals dt,
.cart-totals dd {
  margin: 0;
  font-weight: 500;
}
.cart-total-row {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  padding-top: 10px;
  border-top: 1px solid var(--rule-soft);
}
.cart-checkout-btn {
  width: 100%;
}
.cart-disclaimer {
  font-size: 12px;
  color: var(--ink-mute);
  line-height: 1.5;
}

@media (max-width: 860px) {
  .cart-layout {
    grid-template-columns: 1fr;
  }
  .cart-summary {
    position: static;
  }
  .cart-row {
    grid-template-columns: 56px 1fr auto;
  }
  .cart-row-price {
    grid-column: 2;
  }
}

/* ============================================================
   CHECKOUT ISSUE MODAL
   ============================================================ */
.modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
}
.modal[hidden] {
  display: none;
}
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: blur(2px);
}
.modal-box {
  position: relative;
  z-index: 1;
  background: var(--bg-card);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.6);
  width: 100%;
}
.modal-box-sm {
  max-width: 420px;
  padding: 32px 28px;
}
.modal-box-sm h3 {
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--ink);
  margin-bottom: 12px;
}
.checkout-modal-message {
  color: var(--ink-dim);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 24px;
  white-space: pre-line;
}
.checkout-modal-actions {
  display: flex;
  justify-content: flex-end;
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
   SIZE SELECTOR — grouped product cards
   A product line's sizes are separate Firestore docs clustered into one card;
   these are the controls that switch between them.
   ============================================================ */
.size-row {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin: .75rem 0 .5rem;
}

.size-opt {
  padding: .35rem .7rem;
  font: inherit;
  font-size: .85rem;
  color: var(--ink-dim);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
.size-opt:hover { color: var(--ink); border-color: rgba(var(--ink-rgb), .4); }
.size-opt.is-active {
  color: var(--ink);
  border-color: var(--accent-hot);
  background: rgba(var(--accent-rgb), .18);
}
.size-opt.is-sold {
  color: var(--ink-mute);
  cursor: not-allowed;
  text-decoration: line-through;
  opacity: .55;
}
.size-opt:focus-visible { outline: 2px solid var(--accent-hot); outline-offset: 2px; }

.size-single {
  margin: .6rem 0 .35rem;
  font-size: .85rem;
  color: var(--ink-dim);
}

/* ---- Sale pricing ---- */
.species-price.is-sale {
  display: flex;
  align-items: baseline;
  gap: .5rem;
}
.price-was {
  font-size: .85em;
  color: var(--ink-mute);
  text-decoration: line-through;
}
.price-now { color: var(--ember); }

/* The stock tag already owns the top-left corner, so the sale flag takes the
   opposite one rather than stacking on top of it. */
.tag-sale {
  left: auto;
  right: 14px;
  background: var(--ember);
  border-color: var(--ember);
  color: var(--on-ember);
  font-weight: 700;
  box-shadow: 0 6px 22px -8px rgba(var(--ember-rgb), 0.85);
}

/* ============================================================
   DEALS STRIP  (homepage, between the hero and the featured grid)
   The section carries `hidden` in the markup; deals.js drops it once it has
   cards to put in. Everything below therefore only ever paints on a strip
   that has at least one real deal in it.
   ============================================================ */

/* Tighter than a full .section top and bottom: this has to read as the tail of
   the hero rather than as the next chapter of the page. */
.deals {
  padding: clamp(52px, 6.5vw, 88px) 0 clamp(60px, 7.5vw, 100px);
  /* The nav tab exists to jump here, and both bars above are position:fixed —
     without this the heading lands underneath them. */
  scroll-margin-top: calc(var(--promo-h) + var(--header-h) + 12px);
  /* Transparent at both edges on purpose. The hero's ::after already fades the
     photograph into --bg, and any solid band here would put a hard seam back
     under it — so the tint swells in the middle and dies at both ends. */
  background: linear-gradient(
    180deg,
    transparent 0%,
    rgba(var(--sale-red-rgb), 0.075) 46%,
    transparent 100%
  );
}
.deals .section-head {
  margin-bottom: 44px;
}
/* The eyebrow and the live price carry the section's red rather than the site
   accent, so the badge is not the only red thing in the band. Both use the
   text-safe value, never the badge ground. */
.deals .eyebrow,
.deals .price-now {
  color: var(--sale-red-ink);
}

/* The badge. A circle rather than the flag .tag-sale uses elsewhere, because
   the number is the message here and a circle gives it a shape the eye finds
   before it reads anything. Top-right: .tag keeps the top-left corner for
   stock status. */
.deal-badge {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: clamp(64px, 16vw, 76px);
  aspect-ratio: 1;
  padding-inline: 6px;
  border-radius: 50%;
  background: var(--sale-red);
  color: var(--on-sale-red);
  text-align: center;
  line-height: 1;
  /* The ring is the page ground, not a lighter red: the circle lands on
     photographs it does not control, and a dark separator holds its edge over
     a pale one where a tinted outline would disappear into it. */
  box-shadow:
    0 0 0 2px rgba(var(--bg-rgb), 0.55),
    0 10px 26px -12px rgba(var(--sale-red-rgb), 0.95);
}
.deal-badge-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 3.2vw, 1.2rem);
  letter-spacing: -0.02em;
}
.deal-badge-off {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin-top: 5px;
  opacity: 0.92;
}
/* The card lifts on hover; the badge rides with it rather than being animated
   separately, so nothing detaches from the photo underneath. */
.species-card:hover .deal-badge {
  box-shadow:
    0 0 0 2px rgba(var(--bg-rgb), 0.55),
    0 14px 32px -12px rgba(var(--sale-red-rgb), 1);
}

/* ============================================================
   PROMO BANNER — daily deals bar
   The site header is position:fixed at the top of the viewport, so the bar
   takes the top slot and the header is pushed down by its measured height.
   --promo-h is set by promo-banner.js after the bar renders; the fallback of 0
   means nothing shifts on a page with no active promo.
   ============================================================ */
:root {
  --promo-h: 0px;
  /* Fallback only. script.js measures the real header and overwrites this on
     load, resize and webfont-ready. The bar is one fixed size now, so this is
     close to the real number rather than a guess between two states. */
  --header-h: 60px;
}

.promo-banner {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 90;               /* above .site-header's 80 */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .75rem;
  padding: 10px 44px 10px 16px;   /* right padding clears the close button */
  font-size: .875rem;
  line-height: 1.4;
  text-align: center;
  background: var(--accent-deep);
  color: var(--ink);
  border-bottom: 1px solid var(--rule-soft);
}

.promo-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: .5rem .75rem;
}

.promo-msg { font-weight: 500; }

.promo-code {
  padding: .15rem .45rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .95em;
  letter-spacing: .08em;
  background: rgba(var(--ink-rgb), .14);
  border: 1px dashed rgba(var(--ink-rgb), .35);
  border-radius: 3px;
  cursor: pointer;
}
.promo-code:hover { background: rgba(var(--ink-rgb), .22); }

.promo-link {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}

.promo-close {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  font-size: 20px;
  line-height: 1;
  color: inherit;
  background: transparent;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  opacity: .65;
}
.promo-close:hover { opacity: 1; background: rgba(var(--ink-rgb), .12); }
.promo-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }

/* Tone variants. `sale` is the loud one; `info` is the quiet default. */
.promo-sale   { background: var(--accent-hot); color: var(--bg); }
.promo-sale .promo-code  { background: rgba(0,0,0,.14); border-color: rgba(0,0,0,.3); }
.promo-sale .promo-close:hover { background: rgba(0,0,0,.12); }
.promo-urgent { background: #7e2f14; color: #f6ece6; }

/* `yellow` is the launch/announcement tone and the loudest thing on the page.
   Like .promo-sale it is a LIGHT ground, so every tint that resolves through
   --ink-rgb has to be re-stated against black — the default rules assume the
   dark ground and would come out invisible here. */
.promo-yellow {
  background: var(--warn);
  color: var(--on-warn);
  border-bottom-color: rgba(0, 0, 0, .22);
}
.promo-yellow .promo-msg   { font-weight: 600; }
.promo-yellow .promo-code  { background: rgba(0, 0, 0, .12); border-color: rgba(0, 0, 0, .34); }
.promo-yellow .promo-code:hover  { background: rgba(0, 0, 0, .2); }
.promo-yellow .promo-close:hover { background: rgba(0, 0, 0, .12); }
.promo-yellow .promo-close:focus-visible { outline-color: var(--on-warn); }
.promo-yellow .promo-link  { text-decoration-thickness: 2px; }

/* Push everything down by the bar's height once it exists. */
body.has-promo .site-header { top: var(--promo-h); }

@media (max-width: 640px) {
  .promo-banner { font-size: .8rem; padding-right: 40px; }
  .promo-link { white-space: normal; }
}

/* ============================================================
   PWA — install button and update toast
   Both are injected by pwa.js and only ever exist when the browser has
   actually offered the capability, so neither is styled for a static page.
   ============================================================ */

/* Sits in .primary-nav ahead of the cart. It is a <button>, not an <a>, so it
   inherits none of the nav's link styling and restates it here. */
.install-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 999px;
  cursor: pointer;
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease;
}
.install-btn svg { width: 15px; height: 15px; flex: none; }
.install-btn:hover {
  color: var(--ink);
  border-color: rgba(var(--accent-rgb), 0.55);
  background: rgba(var(--accent-rgb), 0.08);
}
.install-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Bottom-left, so it never lands on the cart button or a mobile nav drawer.
   Below the promo bar's z-index but above page content. */
.pwa-toast {
  position: fixed;
  left: max(16px, env(safe-area-inset-left));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 85;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(420px, calc(100vw - 32px));
  padding: 12px 14px;
  font-size: 14px;
  color: var(--ink);
  background: var(--bg-card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  box-shadow: var(--lift);
  animation: pwa-toast-in 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes pwa-toast-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pwa-toast { animation: none; }
}

.pwa-toast-action {
  flex: none;
  padding: 6px 12px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* --on-accent, not --ink: see the palette note at the top of this file. */
  color: var(--on-accent);
  background: var(--accent);
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.pwa-toast-action:hover { background: var(--accent-hot); }
.pwa-toast-action:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.pwa-toast-close {
  flex: none;
  width: 26px;
  height: 26px;
  font-size: 18px;
  line-height: 1;
  color: var(--ink-mute);
  background: transparent;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}
.pwa-toast-close:hover { color: var(--ink); background: rgba(var(--ink-rgb), 0.08); }

/* Installed / standalone. There is no browser chrome to pad against the notch,
   so the header has to do it itself — without this the lockup sits under the
   iOS status bar. `display-mode: standalone` also matches minimal-ui on Android. */
@media (display-mode: standalone) {
  .site-header { padding-top: calc(12px + env(safe-area-inset-top)); }
  .promo-banner { padding-top: calc(10px + env(safe-area-inset-top)); }
  /* An installed app has no back button on iOS, so the credit link is the only
     way out of a dead end — keep it clear of the home indicator. */
  .site-footer { padding-bottom: calc(env(safe-area-inset-bottom) + 24px); }
}
