/* ==========================================================
   GENERATED FILE — do not edit.
   Built from src/css/: tokens.css base.css components.css
   Regenerate with: ./tools/build-assets.sh
   ========================================================== */

/* ---------- tokens.css ---------- */
/* ==========================================================================
   Design tokens. Values only — no selectors beyond :root.
   Documented in DESIGN_NOODLESITE.md §3–§5.
   ========================================================================== */

:root {
  /* ---- Brand color -------------------------------------------------- */
  --brown:        #936546;   /* primary: nav, buttons, section headings   */
  --brown-dark:   #7A5138;   /* headings, hover, emphasis                 */
  --blush:        #FDF4EF;   /* warm off-white section background         */
  --surface:      #FFFFFF;
  --text:         #333333;
  --line:         #E8DDD5;

  /* Muted text. Was #999 on the old site, which fails WCAG AA on both
     white (2.85:1) and blush (2.63:1). #6B5A50 passes on both
     (6.56:1 / 6.04:1) and keeps the warm cast. See DESIGN_NOODLESITE.md §3. */
  --muted:        #6B5A50;

  /* ---- Hero-only accents -------------------------------------------- */
  --hero-kick:    #E8C89F;
  --hero-accent:  #F0B65E;
  --hero-bg:      #2B1D16;

  /* Stat figures, sampled from the original site's About page. 3.54:1 on
     blush — fine for the 46px numeral (AA large text is 3:1) but not for the
     unit beside it, so that gets a darker shade at 5.06:1. */
  --stat-blue:     #1E84E4;
  --stat-blue-ink: #166BB8;
  /* Diagonal scrim: text sits in the dark left third. Slightly stronger than
     the original site's, which left the sub-copy weak over pale food photos. */
  /* Diagonal scrim: the copy sits in the dark left portion. Held stronger and
     further right than the original site's, because the hero photographs have
     bright packaging on the right and the sub-copy overruns it at ~1050px. */
  --hero-scrim: linear-gradient(100deg,
                  rgba(30,18,12,.88)   0%,
                  rgba(30,18,12,.78)  42%,
                  rgba(30,18,12,.58)  72%,
                  rgba(30,18,12,.22) 100%);

  --hero-scrim-narrow: linear-gradient(180deg,
                  rgba(30,18,12,.55)   0%,
                  rgba(30,18,12,.74)  50%,
                  rgba(30,18,12,.86) 100%);

  /* ---- Type --------------------------------------------------------- */
  /* Latin: DM Sans replaces Century Gothic / Questrial. Those had no bold
     weight, read weakly at body sizes, and Century Gothic is absent from
     most non-Windows machines. See DESIGN_NOODLESITE.md §4. */
  --font-latin: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
                Roboto, Helvetica, Arial, sans-serif;

  /* CJK: system stack only. A full CJK webfont is 4–10 MB and must never
     be a blocking load. See ARCHITECTURE_DESIGN.md §7. */
  --font-cjk:   "PingFang SC", "Microsoft YaHei", "微软雅黑",
                "Hiragino Sans GB", "Source Han Sans SC",
                "Noto Sans CJK SC", "Heiti SC", sans-serif;

  --font-body:  var(--font-cjk);

  /* Scale. Body is 16px, up from the old site's 14px — that is a Chinese-web
     convention and reads small to a US audience, especially B2B buyers. */
  --fs-xs:   0.8125rem;  /* 13px — legal, ICP line          */
  --fs-sm:   0.875rem;   /* 14px — captions, timestamps     */
  --fs-base: 1rem;       /* 16px — body                     */
  --fs-md:   1.125rem;   /* 18px — lead paragraphs          */
  --fs-lg:   1.25rem;    /* 20px — stat labels              */
  --fs-xl:   1.5rem;     /* 24px — quiet section headings   */
  --fs-2xl:  2rem;       /* 32px — section headings         */
  --fs-3xl:  2.5rem;     /* 40px — key section headings     */

  --lh-tight: 1.25;
  --lh-body:  1.75;
  --lh-cjk:   1.9;   /* CJK needs more leading at the same size */

  /* ---- Layout ------------------------------------------------------- */
  --container: 1200px;
  --gutter:    20px;
  --header-h:  70px;

  --space-section:       84px;
  --space-section-quiet: 56px;

  --radius: 2px;

  /* ---- Motion ------------------------------------------------------- */
  --t-fast:  .2s;
  --t-mid:   .25s;

  /* Hero swipe. The curve is the one iOS uses for a page transition —
     quick off the mark, long soft landing — so the gesture reads as native
     rather than as a web carousel. */
  --t-swipe:    .55s;
  --ease-swipe: cubic-bezier(.32, .72, 0, 1);

  --shadow-header: 0 1px 6px rgba(0,0,0,.06);
  --shadow-card:   0 6px 26px rgba(0,0,0,.05);
  --shadow-menu:   0 8px 24px rgba(120,80,55,.13);
}

/* Latin-language pages lead with the Latin face. */
:root:lang(en) { --font-body: var(--font-latin); }

/* ---------- base.css ---------- */
/* ==========================================================================
   Reset, element defaults, typography, and accessibility primitives.
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* Chinese needs more leading than Latin at the same size. */
:lang(zh) body,
body:lang(zh) { line-height: var(--lh-cjk); }

img, picture, svg, video {
  max-width: 100%;
  display: block;
  border: 0;
}

/* Every <img> carries width/height attributes to reserve space and stop
   layout shift. Without this, any rule setting `width: 100%` leaves the
   attribute height in force, so the image renders at its natural height and
   object-fit silently crops it — which is what was happening to the About
   page photographs. Components that want a fixed height set one explicitly
   in components.css, which loads after this and wins. */
img { height: auto; }

a { color: inherit; text-decoration: none; }

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

h1, h2, h3, h4 {
  margin: 0;
  line-height: var(--lh-tight);
  font-weight: 700;
  color: var(--brown-dark);
  text-wrap: balance;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

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

/* --------------------------------------------------------------------------
   Accessibility
   -------------------------------------------------------------------------- */

/* Visible focus ring. Never remove without a replacement. */
:focus-visible {
  outline: 3px solid var(--brown);
  outline-offset: 2px;
  border-radius: var(--radius);
}

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

/* First focusable element on every page. */
.skip-link {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -110%);
  z-index: 200;
  background: var(--brown-dark);
  color: #fff;
  padding: 12px 22px;
  border-radius: 0 0 var(--radius) var(--radius);
  transition: transform var(--t-fast);
}
.skip-link:focus { transform: translate(-50%, 0); }

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */

.wrap {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.sec { padding: var(--space-section) 0; }

.sec--quiet { padding: var(--space-section-quiet) 0; }
.sec--quiet .sec__hd { margin-bottom: 26px; }
.sec--quiet .sec__hd h2 { font-size: var(--fs-xl); opacity: .85; }

.sec--key { background: var(--blush); }
.sec--key .sec__hd h2 { font-size: var(--fs-3xl); color: var(--brown-dark); }

.sec__hd {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 44px;
}
.sec__hd h2 {
  font-size: var(--fs-2xl);
  margin: 0;
  max-width: 22em;
}
.sec__hd .sub {
  margin: 10px 0 0;
  font-size: var(--fs-base);
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   Per-language typographic conventions
   These do not transfer between scripts — keep them separated.
   -------------------------------------------------------------------------- */

/* 2em first-line indent is correct Chinese paragraph style and reads as a
   mistake in English. Wide tracking reads elegant in CJK display type and
   broken in Latin. */
html[lang="zh-CN"] .intro p { text-indent: 2em; }
html[lang="zh-CN"] .intro h2 { letter-spacing: .28em; }
html[lang="zh-CN"] .sec__hd h2 { letter-spacing: .02em; }

html[lang="en"] .intro p { text-indent: 0; }
html[lang="en"] .intro h2 { letter-spacing: .06em; }
html[lang="en"] .sec__hd h2,
html[lang="en"] .photoband h2 { font-family: var(--font-latin); }

/* --------------------------------------------------------------------------
   Motion preference
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- components.css ---------- */
/* ==========================================================================
   Components. Documented in DESIGN_NOODLESITE.md §6.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Buttons
   One primary style site-wide. --brown is the only call-to-action color.
   -------------------------------------------------------------------------- */

/* Every button on the site shares one interaction language:
     rest    a shadow, so it already looks raised rather than printed on
     hover   a 2px lift and a deeper shadow — the thing that reads as "pressable"
     active  pressed back flush, so the click is acknowledged
   A flat rectangle that only swaps colour on hover reads as a label. The lift
   is what makes it read as a control. base.css collapses all of it to ~0ms
   under prefers-reduced-motion, so nothing here moves for anyone who asked
   it not to. */

.btn-primary {
  display: inline-block;
  background: var(--brown);
  color: #fff;
  border: 1px solid var(--brown);
  font-size: var(--fs-base);
  padding: 13px 30px;
  border-radius: var(--radius);
  line-height: 1.4;
  box-shadow: 0 3px 10px rgba(60,40,28,.18);
  transition: background var(--t-fast), border-color var(--t-fast),
              transform var(--t-fast), box-shadow var(--t-fast);
}
.btn-primary:hover {
  background: var(--brown-dark); border-color: var(--brown-dark); color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 9px 22px rgba(60,40,28,.30);
}
.btn-primary:active {
  transform: translateY(0);
  box-shadow: 0 2px 5px rgba(60,40,28,.22);
}

.btn-primary--sm { font-size: var(--fs-sm); padding: 9px 18px; }

/* Sits on the hero photograph, so the shadow is neutral black rather than
   brown — a warm shadow over a photo reads as a smudge. */
.btn-line {
  display: inline-block;
  border: 1px solid rgba(255,255,255,.75);
  color: #fff;
  font-size: var(--fs-base);
  padding: 13px 28px;
  border-radius: var(--radius);
  box-shadow: 0 3px 12px rgba(0,0,0,.20);
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast), transform var(--t-fast),
              box-shadow var(--t-fast);
}
.btn-line:hover {
  background: #fff; color: var(--brown-dark); border-color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 9px 24px rgba(0,0,0,.32);
}
.btn-line:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(0,0,0,.26);
}

.btn-more {
  flex: none;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--brown);
  font-size: var(--fs-sm);
  padding: 9px 22px;
  margin-top: 8px;
  border-radius: var(--radius);
  box-shadow: 0 2px 6px rgba(60,40,28,.10);
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast), transform var(--t-fast),
              box-shadow var(--t-fast);
}
.btn-more:hover {
  background: var(--brown); color: #fff; border-color: var(--brown);
  transform: translateY(-2px);
  box-shadow: 0 8px 18px rgba(60,40,28,.24);
}
.btn-more:active {
  transform: translateY(0);
  box-shadow: 0 2px 5px rgba(60,40,28,.18);
}

/* Text link with a rule underneath. */
.more {
  display: inline-block;
  margin-top: 22px;
  font-size: var(--fs-base);
  color: var(--brown);
  letter-spacing: .04em;
}
/* Not a button, so it gets the text-link equivalent: the rule draws itself
   out to the full width of the label on hover. */
.more { transition: color var(--t-fast); }
.more::after {
  content: "";
  display: block;
  width: 54px; height: 1px;
  background: currentColor;
  margin-top: 12px;
  transition: width var(--t-mid);
}
.more:hover { color: var(--brown-dark); }
.more:hover::after { width: 100%; }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.hd {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 99;
  background: var(--surface);
  height: var(--header-h);
  box-shadow: var(--shadow-header);
}
.hd .wrap { height: var(--header-h); display: flex; align-items: center; gap: 14px; }

.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.brand img {
  height: clamp(34px, 4.2vw, 46px);
  width: auto;
  max-width: min(46vw, 340px);
  object-fit: contain;
}

.nav { margin-left: auto; display: flex; align-items: center; gap: clamp(12px, 1.8vw, 30px); }
.nav > a {
  position: relative;
  font-size: 15px;
  color: var(--brown);
  padding: 24px 0;
  white-space: nowrap;
  transition: color var(--t-fast);
}
.nav > a::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 0; height: 2px;
  background: var(--brown);
  transition: width var(--t-mid);
}
.nav > a:hover::before,
.nav > a[aria-current="page"]::before { width: 72px; }
.nav > a:hover { color: var(--brown-dark); }

/* The quote CTA is an <a> inside .nav, so `.nav > a` (specificity 0,1,1) beats
   `.btn-primary--sm` (0,1,0) and was flattening the button's padding to
   `24px 0` and drawing the nav underline through it. Match specificity. */
.nav > a.btn-primary {
  padding: 9px 18px;
  color: #fff;
}
.nav > a.btn-primary::before { display: none; }

.hdtools { display: flex; align-items: center; gap: 10px; flex: none; }

/* ---- Language switcher ---- */
.lang { position: relative; }
.lang__btn {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--fs-sm);
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 6px 11px;
  border-radius: var(--radius);
  line-height: 1.4;
  transition: color var(--t-fast), border-color var(--t-fast),
              background var(--t-fast);
}
.lang__btn:hover { color: var(--brown); border-color: var(--brown); background: var(--blush); }
.lang__btn[aria-expanded="true"] { color: var(--brown); border-color: var(--brown); background: var(--blush); }
.lang__btn svg { width: 13px; height: 13px; opacity: .65; }
.lang__btn .caret { transition: transform var(--t-fast); }
.lang__btn[aria-expanded="true"] .caret { transform: rotate(180deg); }

.lang__menu {
  position: absolute;
  right: 0; top: calc(100% + 8px);
  min-width: 186px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-menu);
  padding: 5px;
  display: none;
  z-index: 120;
}
.lang__menu.open { display: block; }
.lang__opt {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  background: none; border: 0;
  text-align: left;
  padding: 9px 12px;
  font-size: var(--fs-base);
  color: var(--text);
}
.lang__opt:hover { background: var(--blush); }
.lang__opt small { margin-left: auto; font-size: var(--fs-xs); color: var(--muted); }
.lang__opt[aria-current="true"] { background: var(--blush); }
.lang__opt[aria-current="true"] small { color: var(--brown); }

/* ---- Hamburger ----
   The three bars are empty <span>s, so they have no intrinsic width. Sizing
   them explicitly rather than letting them stretch to the flex container is
   what keeps them from collapsing to nothing and leaving a blank bordered
   box — the failure this icon was reported with. Same reason the colour is
   currentColor: an undefined --brown would paint them transparent. */
.hamb {
  display: none;
  position: relative;
  width: 44px; height: 38px;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0;
  color: var(--brown);
  transition: border-color var(--t-fast), color var(--t-fast),
              background var(--t-fast);
}
.hamb:hover { border-color: var(--brown); color: var(--brown-dark); background: var(--blush); }

/* Each bar is placed against the button rather than stacked by the flex box,
   so no markup wrapper is needed and nothing depends on stretch. The three
   tops are 7px apart; the outer two translate 7px onto the middle one, which
   fades, giving all three a shared origin to rotate into an X. */
.hamb span {
  position: absolute;
  left: 50%; margin-left: -11px;
  width: 22px; height: 2px;
  border-radius: 1px;
  background: currentColor;
  transition: transform var(--t-mid), opacity var(--t-fast);
}
.hamb span:nth-child(1) { top: 10px; }
.hamb span:nth-child(2) { top: 17px; }
.hamb span:nth-child(3) { top: 24px; }

.hamb[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamb[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamb[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.navmask { display: none; }

/* --------------------------------------------------------------------------
   Hero
   Slides are <img> rather than background-image so they can carry srcset,
   intrinsic dimensions (no layout shift), and lazy-loading on slides 2–3.

   Each slide sits in one of three positions, one class each: parked right
   (no class), centre (.on), parked left (.left). `overflow: hidden` above
   clips the two that are parked. A looping carousel always has one slide
   that must cross the whole strip to get back in front of the queue —
   .no-anim lets carousel.js teleport it there without animating.

   `.slide.on` alone must render exactly as it did under the old crossfade:
   pagekit.banner() stamps a single static one into every interior page
   banner, and those pages never load carousel.js.
   -------------------------------------------------------------------------- */

.banner {
  position: relative;
  margin-top: var(--header-h);
  height: calc(100vh - var(--header-h));
  min-height: 420px;
  max-height: 760px;
  overflow: hidden;
  background: var(--hero-bg);
  /* Horizontal gesture is the carousel's, vertical scroll stays the page's. */
  touch-action: pan-y;
  -webkit-user-select: none; user-select: none;
}
.slide {
  position: absolute; inset: 0;
  transform: translateX(100%);
  transition: transform var(--t-swipe) var(--ease-swipe);
}
.slide.on      { transform: translateX(0); }
.slide.left    { transform: translateX(-100%); }
.slide.no-anim { transition: none; }
.slide img {
  width: 100%; height: 100%; object-fit: cover;
  /* The browser's native image drag would otherwise swallow the gesture. */
  pointer-events: none;
  -webkit-user-drag: none;
}

.banner__mask { position: absolute; inset: 0; background: var(--hero-scrim); }

.banner__txt {
  position: absolute; inset: 0;
  display: flex; align-items: center;
  z-index: 3;
  pointer-events: none;
}
.banner__txt .wrap { pointer-events: auto; }
.banner__txt .kick {
  font-size: var(--fs-sm);
  letter-spacing: .22em;
  color: var(--hero-kick);
  margin: 0 0 18px;
}
.banner__txt h1 {
  font-size: clamp(38px, 5.4vw, 68px);
  color: #fff;
  margin: 0 0 20px;
  letter-spacing: .04em;
}
.banner__txt h1 b { color: var(--hero-accent); }
.banner__txt .sub {
  font-size: var(--fs-md);
  color: rgba(255,255,255,.9);
  margin: 0 0 34px;
  max-width: 32em;
}
html[lang="en"] .banner__txt h1 { letter-spacing: 0; font-family: var(--font-latin); }
html[lang="en"] .banner__txt .kick { letter-spacing: .16em; }

.hb__cta { display: flex; flex-wrap: wrap; gap: 14px; }

.arrow {
  position: absolute; top: 50%;
  transform: translateY(-50%);
  width: 44px; height: 44px;
  background: none; border: 0;
  color: #fff; opacity: .7;
  display: flex; align-items: center; justify-content: center;
  font-size: 34px; line-height: 1;
  user-select: none;
  z-index: 4;
}
.arrow:hover { opacity: 1; }
.arrow.prev { left: 26px; }
.arrow.next { right: 26px; }

.dots {
  position: absolute; bottom: 24px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 10px;
  z-index: 4;
}
.dots button {
  width: 9px; height: 9px;
  padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.5);
}
.dots button[aria-current="true"] { background: #fff; }

/* --------------------------------------------------------------------------
   Intro card — overlaps the hero
   -------------------------------------------------------------------------- */

.intro { position: relative; z-index: 5; margin-top: -92px; }
.intro__box {
  background: var(--surface);
  padding: 52px 56px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: center;
  box-shadow: var(--shadow-card);
}
.intro .kicker { font-size: var(--fs-sm); color: var(--muted); margin: 0 0 14px; }
.intro h2 { font-size: var(--fs-3xl); margin: 0 0 26px; }
.intro p { margin: 0 0 12px; color: var(--text); }

.intro__pic { position: relative; }
.intro__pic img { width: 100%; height: 330px; object-fit: cover; }
/* The badge over the plant photo. It was a decorative <div> in blush that
   looked like a caption and did nothing; it is now the second route into the
   About page, alongside the "See more" text link in the column beside it.
   Brown fill and white text put it on the same footing as .btn-primary, which
   is the site's only call-to-action colour — a pale badge on a pale ground is
   exactly what nobody clicked. 5.01:1 on white, so it clears AA for the label. */
.explore {
  position: absolute; left: -52px; top: 50%;
  transform: translateY(-50%);
  width: 104px; height: 104px;
  border-radius: 50%;
  background: var(--brown);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-base);
  letter-spacing: .1em;
  line-height: 1.2;
  text-align: center;
  box-shadow: 0 10px 24px rgba(60,40,28,.24);
  transition: background var(--t-fast), transform var(--t-mid), box-shadow var(--t-mid);
}
/* The hover transform has to restate translateY(-50%) — it is doing the
   vertical centring, not just decoration. */
.explore:hover,
.explore:focus-visible {
  background: var(--brown-dark);
  color: #fff;
  transform: translateY(-50%) scale(1.06);
  box-shadow: 0 14px 30px rgba(60,40,28,.32);
}
/* A slow ring leaving the badge, to catch the eye without nagging. It stops
   once the pointer arrives — by then it has done its job. The global
   prefers-reduced-motion block in base.css kills it outright. */
.explore::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid var(--brown);
  opacity: 0;
  pointer-events: none;
  animation: explore-ring 2.8s ease-out infinite;
}
.explore:hover::after,
.explore:focus-visible::after { animation: none; opacity: 0; }

@keyframes explore-ring {
  0%   { transform: scale(1);    opacity: .5; }
  70%  { transform: scale(1.34); opacity: 0; }
  100% { transform: scale(1.34); opacity: 0; }
}

html[lang="en"] .explore { letter-spacing: .04em; font-size: var(--fs-sm); }

/* --------------------------------------------------------------------------
   Stats
   -------------------------------------------------------------------------- */

.nums {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 70px 0 76px;
  text-align: center;
}
.nums > div { border-left: 1px solid var(--line); }
.nums > div:first-child { border-left: 0; }
/* Blue, like the original site's animated figures — see .factbar, which uses
   the same pair. 3.84:1 on white clears AA for the 60px numeral (large text is
   3:1); the 20px unit beside it does not qualify as large, so it takes the
   darker ink at 5.48:1. The two read as the same blue at a glance. */
.nums .n {
  font-family: var(--font-latin);
  font-size: 60px;
  line-height: 1;
  color: var(--stat-blue);
  font-weight: 400;
  /* The figures count up. Tabular digits keep 0 → 2005 from breathing in and
     out as it gains digits, and hold the label beneath still. */
  font-variant-numeric: tabular-nums;
}
.nums .n small {
  font-size: var(--fs-lg);
  margin-left: 4px;
  color: var(--stat-blue-ink);
}
.nums h3 { font-size: var(--fs-md); color: var(--brown-dark); font-weight: 400; margin: 14px 0 10px; }
.nums p { margin: 0; color: var(--muted); font-size: var(--fs-sm); }

/* --------------------------------------------------------------------------
   Brand band — asymmetric, text bleeds to the viewport edge
   -------------------------------------------------------------------------- */

.brandband {
  display: grid;
  grid-template-columns: 38% 62%;
  background: var(--blush);
  align-items: center;
}
.brandband__txt {
  padding: 0 0 0 max(var(--gutter), calc((100vw - var(--container)) / 2 + var(--gutter)));
}
.brandband h2 { font-size: var(--fs-2xl); margin: 0 0 22px; font-weight: 400; letter-spacing: .06em; }
.brandband p { font-size: var(--fs-xl); color: var(--muted); margin: 0; line-height: 1.6; }
.brandband .tag { margin-top: 38px; font-size: var(--fs-sm); color: var(--muted); }
.brandband img { width: 100%; height: 440px; object-fit: cover; }

/* --------------------------------------------------------------------------
   Product grid
   -------------------------------------------------------------------------- */

/* One .cats grid per branch, four tiles each, with a .catgroup__h label above.
   Four rather than three so each branch gets a full row of its own — the
   domestic/export split is the point of the section. */
.catgroup__h {
  margin: 0;
  padding: 36px 0 14px;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--brown);
}

.cats { display: grid; grid-template-columns: repeat(4, 1fr); background: var(--blush); }
.cats a {
  padding: 34px 20px 30px;
  text-align: center;
  border-left: 1px solid #F3E6DD;
  border-top: 1px solid #F3E6DD;
  transition: background var(--t-mid);
}
.cats a:nth-child(-n+4) { border-top: 0; }
.cats a:nth-child(4n+1) { border-left: 0; }
.cats a:hover { background: var(--surface); }
.cats img { height: 150px; width: 100%; margin: 0 auto 26px; object-fit: contain; }
.cats span { font-size: var(--fs-base); color: var(--brown-dark); }

/* --------------------------------------------------------------------------
   Full-bleed photo band
   -------------------------------------------------------------------------- */

.photoband {
  position: relative;
  height: 430px;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
}
.photoband::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(30,18,12,.6), rgba(30,18,12,.15));
}
.photoband .wrap { width: 100%; position: relative; z-index: 2; }
.photoband h2 { font-size: var(--fs-3xl); color: #fff; margin: 0; font-weight: 400; }
.photoband p { color: rgba(255,255,255,.9); font-size: var(--fs-md); margin: 8px 0 0; }
.photoband .more { color: #fff; }

.photoband--quiet { height: 300px; }
.photoband--quiet h2 { font-size: var(--fs-2xl); }

/* --------------------------------------------------------------------------
   News
   -------------------------------------------------------------------------- */

.news { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 56px; }
.news a { display: block; padding: 22px 0; border-bottom: 1px solid var(--line); }
.news a:hover h4 { color: var(--brown); }
.news h4 { margin: 0 0 6px; font-size: var(--fs-md); font-weight: 400; color: var(--text); transition: color var(--t-fast); }
.news time { font-family: var(--font-latin); font-size: var(--fs-sm); color: var(--muted); }
.news p {
  margin: 8px 0 0;
  font-size: var(--fs-sm);
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Certifications
   The strongest asset for the US wholesale audience — see
   DESIGN_NOODLESITE.md §1.
   -------------------------------------------------------------------------- */

.certlist { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 46px; }
.certlist li {
  display: flex; gap: 20px; align-items: baseline;
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
}
.certlist b {
  font-family: var(--font-latin);
  font-size: var(--fs-lg);
  color: var(--brown-dark);
  min-width: 104px;
  font-weight: 500;
}
/* The store page's route labels are words ("Private label"), not short
   codes like IFS, so they need a wider column to sit on one line. Scoped
   so the certifications list keeps its tighter measure. */
.certlist--wide b { min-width: 160px; }
.certlist span { font-size: var(--fs-sm); color: var(--muted); line-height: 1.75; }

.certnote { margin: 30px 0 16px; font-size: var(--fs-sm); color: var(--muted); }

/* Three columns, not four: the certificate count went from four to nine when
   the 2026 decks turned up, and nine over four columns leaves a 4+4+1 tail.
   Three also buys each scan ~390px of tile, which is the difference between a
   thumbnail you can identify and one you have to click to recognise. */
.certthumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.certthumbs a { text-align: center; }
.certthumbs img {
  height: 250px; width: 100%;
  object-fit: contain;
  background: var(--surface);
  padding: 7px;
  border: 1px solid var(--line);
  transition: border-color var(--t-fast);
}
.certthumbs a:hover img { border-color: var(--brown); }
.certthumbs span { display: block; margin-top: 9px; font-size: var(--fs-sm); color: var(--muted); }

.certcta { margin-top: 38px; }

/* --------------------------------------------------------------------------
   Interior page banner
   Same treatment as the homepage hero — full-bleed photo, scrim, overlaid
   copy — but shorter and without the carousel.
   -------------------------------------------------------------------------- */

.banner--page {
  height: clamp(300px, 34vw, 430px);
  min-height: 0;
  max-height: none;
}
.banner--page .banner__txt h1 { font-size: clamp(30px, 4.4vw, 54px); }
.banner--page .banner__txt .sub { margin-bottom: 26px; }
.banner--page .banner__txt .sub:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Interior page header
   Sits below the fixed header on pages with no hero carousel.
   -------------------------------------------------------------------------- */

.pagehead {
  margin-top: var(--header-h);
  background: var(--blush);
  padding: 64px 0 56px;
}
.pagehead .kick {
  font-size: var(--fs-sm);
  letter-spacing: .18em;
  color: var(--brown);
  margin: 0 0 14px;
}
.pagehead h1 {
  font-size: var(--fs-3xl);
  color: var(--brown-dark);
  margin: 0 0 16px;
}
.pagehead .lead {
  font-size: var(--fs-md);
  color: var(--muted);
  margin: 0;
  max-width: 46em;
}

/* --------------------------------------------------------------------------
   Catalog — the original site's layout: a vertical family menu on the left,
   product grid on the right, the whole block on the blush ground.
   -------------------------------------------------------------------------- */

.catalog { background: var(--blush); padding: 52px 0 64px; }

.catalog__inner {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: 26px;
  /* Top-aligned. This was `center` back when there were seven families that
     all rendered two rows of cards. At fifteen families the rail is ~850px
     while a panel ranges from one card to eight, so centring moved BOTH
     columns every time you switched family — the one-item families floated
     down to the middle of the rail. Start-alignment pins the grid to the same
     y position for every family, which is the whole point of a tab. */
  align-items: start;
}

/* Filled category blocks; the active family inverts to the page ground. */
.catside {
  /* Was `align-self: center` + a 50px nudge to line the menu up with the card
     grid rather than the family header. Both are gone: with a fifteen-item
     rail the nudge overflowed the section, and centring is what made the grid
     jump. Rail and panel now share one top edge. */
  align-self: start;
}
.catside a {
  display: block;
  padding: 17px 18px;
  background: var(--brown);
  color: #fff;
  font-size: var(--fs-sm);
  line-height: 1.4;
  text-align: center;
  border-bottom: 1px solid rgba(255,255,255,.22);
  transition: background var(--t-fast), color var(--t-fast);
}
.catside a:last-child { border-bottom: 0; }
.catside a:hover { background: var(--brown-dark); }
.catside a[aria-current="true"] {
  background: var(--surface);
  color: var(--brown-dark);
  font-weight: 700;
  box-shadow: inset 3px 0 0 var(--brown);
}
.catside a[aria-current="true"]:hover { background: var(--surface); }
.catside .n { font-size: var(--fs-xs); opacity: .75; margin-left: 5px; }

.catmain { min-width: 0; }

.famsec { scroll-margin-top: calc(var(--header-h) + 20px); }
.famsec + .famsec { margin-top: 26px; }
/* Tab behaviour only switches on once products.js flags the container, so with
   JS off every family stays visible and indexable. */
.catalog[data-tabs="on"] .famsec { display: none; margin-top: 0; }
.catalog[data-tabs="on"] .famsec.is-active { display: block; }

.famsec__hd {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  padding-bottom: 16px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
.famsec__hd h2 { font-size: var(--fs-xl); color: var(--brown-dark); margin: 0; }
.famsec__hd .alt { display: block; margin-top: 5px; font-size: var(--fs-sm); color: var(--muted); }
.famsec__hd .sub { margin: 0; max-width: 40ch; font-size: var(--fs-sm); color: var(--muted); }

.prodgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.prodgrid figure {
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 18px 20px;
  display: flex;
  flex-direction: column;
  text-align: center;
  transition: border-color var(--t-fast), transform var(--t-fast);
}
.prodgrid figure:hover { border-color: var(--brown); transform: translateY(-2px); }
.prodgrid img {
  width: 100%;
  height: 180px;
  object-fit: contain;
  margin-bottom: 14px;
}
.prodgrid figcaption {
  font-size: var(--fs-sm);
  color: var(--brown-dark);
  line-height: 1.5;
  margin-top: auto;
}
.prodgrid .alt { display: block; margin-top: 4px; font-size: var(--fs-xs); color: var(--muted); }

/* --------------------------------------------------------------------------
   About — inline fact bar and numbered value cards
   -------------------------------------------------------------------------- */

.factbar {
  display: flex;
  gap: clamp(28px, 5vw, 64px);
  margin-top: 36px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.factbar div { position: relative; }
.factbar div + div { padding-left: clamp(28px, 5vw, 64px); }
.factbar div + div::before {
  content: "";
  position: absolute; left: 0; top: 4px; bottom: 4px;
  border-left: 1px solid var(--line);
}
.factbar b {
  display: block;
  font-family: var(--font-latin);
  font-size: 46px;
  font-weight: 500;
  line-height: 1;
  color: var(--stat-blue);
  /* The figure counts up, so reserve the width of the final number — otherwise
     the label beneath shifts as 0 → 21 gains a digit. */
  font-variant-numeric: tabular-nums;
}
.factbar b small {
  font-size: var(--fs-base);
  margin-left: 3px;
  color: var(--stat-blue-ink);
  vertical-align: super;
  line-height: 1;
}
/* Direct child only. The figure is now wrapped in its own <span> for the
   counter, and a bare `.factbar span` also matched it — turning the number
   grey and pushing the unit onto its own line. */
.factbar div > span { display: block; margin-top: 8px; font-size: var(--fs-sm); color: var(--muted); }

.values { display: flex; flex-direction: column; gap: 30px; }
.value { display: flex; gap: 22px; align-items: flex-start; }

/* Rotated square marker, number counter-rotated back to level. */
.value__n {
  flex: none;
  width: 54px; height: 54px;
  display: grid; place-items: center;
  transform: rotate(45deg);
  background: var(--brown);
  border-radius: 3px;
}
.value__n span {
  transform: rotate(-45deg);
  font-family: var(--font-latin);
  font-size: var(--fs-base);
  font-weight: 700;
  color: #fff;
}
/* Second marker uses the hero accent; ink text on it is 9.94:1, white is not. */
.value:nth-child(2) .value__n { background: var(--hero-accent); }
.value:nth-child(2) .value__n span { color: var(--hero-bg); }

.value h3 { font-size: var(--fs-md); color: var(--brown-dark); margin: 6px 0 8px; }
.value p { margin: 0 0 4px; font-size: var(--fs-sm); color: var(--muted); line-height: 1.8; }
.value p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Inquiry form
   -------------------------------------------------------------------------- */

.form {
  background: var(--blush);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(22px, 3vw, 34px);
}
.field { display: block; margin-bottom: 16px; }
.field > span {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.field input, .field select, .field textarea {
  width: 100%;
  font-family: inherit;
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--brown);
  outline-offset: 1px;
}
.field textarea { min-height: 118px; resize: vertical; }
.field .req { color: #C0392B; font-style: normal; }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-note { margin: 14px 0 0; font-size: var(--fs-sm); color: var(--muted); }

.form__status {
  display: none;
  margin: 16px 0 0;
  padding: 14px 16px;
  border-radius: var(--radius);
  font-size: var(--fs-sm);
}
.form__status.is-ok  { display: block; background: #EFF5EF; border: 1px solid #7FA085; }
.form__status.is-err { display: block; background: #FBEFEE; border: 1px solid #C0392B; color: #96291D; }

/* --------------------------------------------------------------------------
   Two-column content (About)
   -------------------------------------------------------------------------- */

.twocol {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 56px;
  align-items: start;
}
.twocol h2 { font-size: var(--fs-2xl); margin: 0 0 20px; }
.twocol p { color: var(--text); }
.twocol img { width: 100%; object-fit: cover; }

/* --------------------------------------------------------------------------
   Online store cards
   -------------------------------------------------------------------------- */

.storegrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px;
}
.storecard {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.storecard h2 { font-size: var(--fs-lg); margin: 0; }
.storecard p { margin: 0; color: var(--muted); font-size: var(--fs-sm); }
.storecard .storeregion {
  font-size: var(--fs-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--brown);
}
.storecard .btn-primary,
.storecard .more { margin-top: auto; align-self: flex-start; }
.storecard .btn-primary { margin-top: 18px; }

/* A storefront with no URL yet: shown, but never as a dead link. */
.storecard--soon { background: var(--blush); border-style: dashed; }
.storesoon {
  margin-top: 14px;
  font-size: var(--fs-sm);
  color: var(--muted);
  font-style: italic;
}
.storecard--soon .more { margin-top: 4px; }

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

.contactgrid {
  display: grid;
  /* The address column carries the map, so it gets more room. */
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 44px 40px;
  align-items: start;
}

/* Embedded map. OpenStreetMap needs no API key and is reachable from both
   mainland China and the US, which Google Maps is not. Lazy so it never
   blocks the page — an iframe pulls a whole map application. */
.mapembed {
  margin-top: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--blush);
  aspect-ratio: 4 / 3;
}
.mapembed iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.contactcol h2 {
  font-size: var(--fs-md);
  color: var(--brown-dark);
  margin: 0 0 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.contactcol p { margin: 0 0 8px; }
.contactcol a:hover { color: var(--brown); }
.contactcol .contactnote { font-size: var(--fs-sm); color: var(--muted); }
.contactcol .more { margin-top: 12px; }

/* Icon + value rows. baseline alignment would ride the icon up on the
   two-line address, so align to the top and nudge the icon onto the text
   baseline instead. */
.cinfo {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.cicon {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  color: var(--brown);
}

/* --------------------------------------------------------------------------
   Products page closing CTA
   -------------------------------------------------------------------------- */

.prodcta { max-width: 42em; }
.prodcta h2 { font-size: var(--fs-2xl); margin: 0 0 12px; }
.prodcta p { color: var(--muted); margin: 0 0 24px; }
.prodcta .prodnote {
  margin: 22px 0 0;
  font-size: var(--fs-xs);
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.ft { background: var(--blush); color: var(--muted); font-size: var(--fs-sm); }

.ft__top {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 40px;
  padding: 52px var(--gutter) 40px;
}

.ft__h {
  font-size: var(--fs-md);
  color: var(--brown-dark);
  font-weight: 700;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
/* Chinese heading with a Latin caption, the convention on the original site. */
.ft__h span {
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: .12em;
  color: var(--brown);
  margin-left: 8px;
}

.ft__col p { margin: 0 0 14px; line-height: 1.7; }
.ft__col p:last-child { margin-bottom: 0; }
.ft__col a:hover { color: var(--brown); }
.ft__muted { color: var(--muted); opacity: .8; }

/* Contact rows reuse .cinfo from the contact page. */
.ft .cinfo { align-items: flex-start; }
.ft .cinfo b { font-weight: 400; color: var(--brown-dark); }
.ft .cicon { color: var(--brown); }

.ft__links { display: flex; flex-direction: column; gap: 10px; }
.ft__links a { line-height: 1.5; }

.ft__bar {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 16px var(--gutter);
  border-top: 1px solid #F0E2D8;
  font-size: var(--fs-xs);
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1020px) {
  .intro { margin-top: -50px; }
  .intro__box { grid-template-columns: 1fr; padding: 34px 26px; gap: 30px; }
  .explore { display: none; }

  .nums { grid-template-columns: repeat(2, 1fr); }
  .nums > div:nth-child(3) { border-left: 0; }
  .nums > div:nth-child(-n+2) { border-bottom: 1px solid var(--line); padding-bottom: 34px; margin-bottom: 34px; }

  .brandband { grid-template-columns: 1fr; }
  .brandband__txt { padding: 36px var(--gutter); }
  .brandband img { height: 280px; }

  .cats { grid-template-columns: repeat(2, 1fr); }
  .cats a { border-left: 1px solid #F3E6DD; border-top: 1px solid #F3E6DD; }
  .cats a:nth-child(odd) { border-left: 0; }
  .cats a:nth-child(-n+2) { border-top: 0; }

  .certlist { grid-template-columns: 1fr; gap: 0; }
  .contactgrid { grid-template-columns: 1fr 1fr; }
  .contactcol--wide { grid-column: 1 / -1; }
  .mapembed { aspect-ratio: 16 / 9; }

  .catalog__inner { grid-template-columns: 1fr; gap: 18px; }
  .catside { display: flex; overflow-x: auto; scrollbar-width: none; }
  /* The branch headings become inline chips in the scrolling rail rather than
     full-width bars, so domestic and export stay legible as separators. */
  .catside__h { flex: none; align-self: stretch; display: flex; align-items: center;
                margin: 0; white-space: nowrap; }
  .catside__h:not(:first-child) { margin-top: 0; }
  .catside::-webkit-scrollbar { display: none; }
  .catside a { flex: none; padding: 13px 18px; border-bottom: 0;
               border-right: 1px solid rgba(255,255,255,.22); white-space: nowrap; }
  .catside a[aria-current="true"] { box-shadow: inset 0 -3px 0 var(--brown); }
  .two { grid-template-columns: 1fr; }
  .twocol { grid-template-columns: 1fr; gap: 32px; }
  .factbar { gap: 28px; }
  .certthumbs { grid-template-columns: repeat(2, 1fr); }

  .news { grid-template-columns: 1fr; gap: 0; }
  .ft__top { grid-template-columns: 1fr 1fr; }
  .ft__col--contact { grid-column: 1 / -1; }

  .sec__hd h2, .photoband h2 { font-size: var(--fs-2xl); }
  .sec--key .sec__hd h2 { font-size: var(--fs-2xl); }
}

/* Nav-only breakpoint, deliberately separate from the 1020px layout one above.
   Raised 940 -> 1020 -> 1150 as links were added; it now carries SIX links
   plus the quote button. Measured at 1030px with the sixth (Private label)
   in place, "About" overlapped the logo wordmark, so the collision point sits
   around 1100px in English — 1150 leaves margin for the wider zh button. */
@media (max-width: 1150px) {
  .hamb { display: flex; }
  .nav {
    position: fixed;
    top: var(--header-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    gap: 0;
    background: var(--surface);
    padding: 6px var(--gutter) 22px;
    border-top: 1px solid var(--line);
    box-shadow: 0 14px 28px rgba(60,40,28,.14);
    opacity: 0; visibility: hidden;
    transform: translateY(-10px);
    transition: opacity .22s ease, transform .22s ease, visibility .22s;
    z-index: 98;
  }
  .nav.open { opacity: 1; visibility: visible; transform: none; }
  .nav > a { padding: 15px 2px; border-bottom: 1px solid var(--line); font-size: var(--fs-md); }
  .nav > a::before { display: none; }
  .nav > a[aria-current="page"] { color: var(--brown-dark); font-weight: 700; }
  .nav .btn-primary--sm { display: block; margin: 20px 0 0; padding: 13px; font-size: var(--fs-base); text-align: center; }

  .navmask {
    display: block;
    position: fixed; inset: var(--header-h) 0 0;
    background: rgba(30,18,12,.32);
    opacity: 0; visibility: hidden;
    transition: opacity .22s, visibility .22s;
    z-index: 97;
  }
  .navmask.on { opacity: 1; visibility: visible; }
}

@media (max-width: 660px) {
  .nums { grid-template-columns: 1fr; }
  .nums > div { border-left: 0; }
  .nums > div:nth-child(3) { border-bottom: 1px solid var(--line); padding-bottom: 34px; margin-bottom: 34px; }

  .cats { grid-template-columns: 1fr; }
  .cats a { border-left: 0 !important; border-top: 1px solid #F3E6DD !important; }
  .cats a:first-child { border-top: 0 !important; }

  .certthumbs { grid-template-columns: repeat(2, 1fr); }
  .ft__top { grid-template-columns: 1fr; gap: 22px; }
  .ft__bar { flex-direction: column; gap: 6px; }

  .banner__txt .sub { font-size: var(--fs-base); }
  .banner__mask { background: var(--hero-scrim-narrow); }
  .arrow { display: none; }

  .pagehead { padding: 40px 0 34px; }
  .pagehead h1 { font-size: var(--fs-2xl); }
  .pagehead .lead { font-size: var(--fs-base); }
  .prodgrid { grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .prodgrid img { height: 120px; }
  .prodgrid figure { padding: 12px 10px 12px; }
  .sec { padding: 56px 0; }
}


/* ============================================================ catalog v2 ===
   Branch headings in the category rail. The catalog splits into domestic
   retail and export OEM (data/products.json "branches"); a visiting importer
   only ever wants the second half, so the split is a heading in the rail
   rather than a filter that hides half the range behind a click. */

.catside__h {
  margin: 0;
  padding: 13px 18px 11px;
  background: var(--brown-dark);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  text-align: center;
}
.catside__h + a { border-top: 0; }
.catside__h:not(:first-child) { margin-top: 10px; }

.famsec__branch {
  margin: 0 0 4px;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--brown);
}

/* Deck-sourced family shots are group photographs of a whole range, not the
   square product-on-white tiles the old CMS produced, so the grid cell has to
   accept any aspect ratio. contain, never cover: cropping a lineup of eight
   packs to a square silently deletes six of them. */
.prodgrid figure img { object-fit: contain; }

/* ================================================================ shared ===  */

.sech {
  margin: 0 0 8px;
  font-size: var(--fs-2xl);
  color: var(--brown-dark);
}
.secsub {
  margin: 0 0 34px;
  max-width: 58ch;
  font-size: var(--fs-md);
  color: var(--muted);
}

/* ============================================================== partners ===
   The OEM page. Its job is to make a buyer believe the plant can supply them,
   and the fastest way to do that is to show the retailers who already decided
   it could. */

.oemlede { max-width: 62ch; margin-bottom: 38px; }
.oemlede h2 { margin: 0 0 12px; font-size: var(--fs-2xl); color: var(--brown-dark); }
.oemlede p { margin: 0; font-size: var(--fs-md); line-height: var(--lh-body); }

.oemcaps {
  display: grid;
  /* 320px, not 260: six capabilities across four columns leaves a ragged
     4+2 row. At 320 the container fits three, so it reads 3+3. */
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 26px 34px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.oemcaps li { border-top: 2px solid var(--brown); padding-top: 14px; }
.oemcaps b {
  display: block;
  margin-bottom: 6px;
  font-size: var(--fs-base);
  color: var(--brown-dark);
}
.oemcaps span { display: block; font-size: var(--fs-sm); color: var(--muted); line-height: 1.6; }

.brandgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 20px;
}
.brandcard {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 0;
  padding: 24px 22px 22px;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
/* Fixed-height mark area so seven logos of wildly different proportions —
   Walmart is 6.5:1, ALDI is square — sit on one optical baseline instead of
   each card setting its own. */
.brandcard__marks {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  height: 58px;
}
.brandcard__marks img {
  max-height: 100%;
  max-width: 100%;
  width: auto;
  object-fit: contain;
}
.brandcard figcaption { display: block; }
.brandcard figcaption b {
  display: block;
  font-size: var(--fs-base);
  color: var(--brown-dark);
}
.brandcard__where {
  display: block;
  margin-top: 3px;
  font-size: var(--fs-xs);
  color: var(--brown);
  letter-spacing: .04em;
  text-transform: uppercase;
}
.brandcard figcaption p {
  margin: 9px 0 0;
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.6;
}

.brandnote {
  margin: 30px 0 0;
  max-width: 74ch;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.65;
}

.facgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
}
.facgrid figure { margin: 0; }
.facgrid img {
  width: 100%;
  height: 240px;
  object-fit: cover;
  border-radius: var(--radius);
  display: block;
}
.facgrid figcaption {
  margin-top: 10px;
  font-size: var(--fs-sm);
  color: var(--muted);
}

@media (max-width: 560px) {
  .facgrid img { height: 200px; }
  .brandcard__marks { height: 50px; }
}

