/* ============================================================
   GoJoy - fresh fruit export
   Design tokens are declared once here. Nothing below invents
   a colour, radius or easing that is not in this block.
   ============================================================ */

:root{
  /* colour: sampled from the GoJoy wordmark */
  --green:        #2F8B22;
  --green-deep:   #1C5E15;   /* primary button fill, passes AA on white text */
  --green-900:    #0E3A0B;   /* footer */
  --green-tint:   #F1F6EF;   /* section band */
  --orange:       #EE7A08;   /* accent, decoration on light only */
  --orange-lt:    #F9A03C;   /* accent, text on dark only */

  /* hover steps, one shade off their base */
  --green-hover:  #174F11;
  --orange-hover: #FF8B17;
  --tint-deep:    #E4EDE1;   /* plate, when the section is already tinted */

  --ink:          #16231A;
  --ink-2:        #4A5A50;
  --ink-on-orange:#3A1C00;   /* 5.2:1 on --orange, the only text allowed there */
  --paper:        #FFFFFF;
  --muted:        #6B7971;   /* input placeholders: 4.6:1, AA at body size */
  --line:         rgba(22,35,26,.12);
  --line-soft:    rgba(22,35,26,.07);

  /* semantic, used by the enquiry form and the map legend */
  --danger:       #B3261E;
  --ok-bg:        #E8F2E4;
  --key-blue:     #1F6FD0;   /* matches the sourcing-map graphic's markers */

  /* type */
  --display: "Outfit", system-ui, sans-serif;
  --body:    "Manrope", system-ui, sans-serif;

  /* radius: cards 24, small 12, buttons pill. No other values. */
  --r-lg: 24px;
  --r-sm: 12px;
  --r-pill: 999px;

  /* elevation: tinted to the brand green-black, never pure black */
  --e1: 0 2px 8px -2px rgba(14,58,11,.10);
  --e2: 0 18px 40px -18px rgba(14,58,11,.22);
  --e3: 0 36px 80px -32px rgba(14,58,11,.34);

  /* motion */
  --ease: cubic-bezier(.32,.72,0,1);
  --t-fast: .28s;
  --t-mid:  .6s;
  --t-slow: .9s;

  --wrap: 1240px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section: clamp(4.5rem, 9vw, 8.5rem);
}

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

html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--body);
  font-size:clamp(1rem,.96rem + .2vw,1.075rem);
  line-height:1.68;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

img{ display:block; max-width:100%; height:auto; }
h1,h2,h3{ font-family:var(--display); font-weight:600; line-height:1.1; margin:0; text-wrap:balance; }
p{ margin:0; text-wrap:pretty; }
a{ color:inherit; }

.wrap{ width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:var(--gutter); }

.h2{
  font-size:clamp(1.75rem,1.3rem + 2vw,2.9rem);
  letter-spacing:-.02em;
  max-width:20ch;
}

.skip-link{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--green-deep); color:#fff; padding:.75rem 1.25rem;
  border-radius:0 0 var(--r-sm) 0; font-weight:600; text-decoration:none;
}
.skip-link:focus{ left:0; }

:where(a,button,[tabindex]):focus-visible{
  outline:2px solid var(--green-deep);
  outline-offset:3px;
  border-radius:var(--r-sm);
}

/* the nav turns solid once this much of the page has scrolled past */
#top-sentinel{ position:absolute; top:0; left:0; height:96px; width:1px; pointer-events:none; }

/* ============================================================
   Buttons
   Pill radius is reserved for interactive elements only.
   The trailing arrow always sits in its own nested circle.
   ============================================================ */

.btn{
  display:inline-flex; align-items:center; gap:.6rem;
  padding:.72rem .72rem .72rem 1.4rem;
  border:0; border-radius:var(--r-pill);
  font-family:var(--body); font-weight:600; font-size:.98rem;
  line-height:1; white-space:nowrap; text-decoration:none; cursor:pointer;
  transition:background var(--t-fast) var(--ease),
             color var(--t-fast) var(--ease),
             transform var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease);
}
.btn:active{ transform:scale(.975); }

.btn__icon{
  display:grid; place-items:center;
  width:2rem; height:2rem; flex:none;
  border-radius:var(--r-pill);
  font-size:.95rem;
  transition:transform var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.btn:hover .btn__icon{ transform:translate(2px,-2px); }

.btn--primary{ background:var(--green-deep); color:#fff; box-shadow:var(--e1); }
.btn--primary .btn__icon{ background:rgba(255,255,255,.16); }
.btn--primary:hover{ background:var(--green-hover); box-shadow:var(--e2); }

.btn--accent{ background:var(--orange); color:var(--ink-on-orange); }
.btn--accent .btn__icon{ background:rgba(58,28,0,.14); }
.btn--accent:hover{ background:var(--orange-hover); }

.btn--outline{
  background:transparent; color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--line);
}
.btn--outline .btn__icon{ background:var(--green-tint); }
.btn--outline:hover{ box-shadow:inset 0 0 0 1.5px var(--green-deep); color:var(--green-deep); }

/* on photography: hairline glass, white label, no plate */
.btn--glass{
  padding:.72rem 1.4rem;
  background:rgba(255,255,255,.10);
  color:#fff;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.55);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
}
.btn--glass:hover{ background:rgba(255,255,255,.2); box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.9); }

.btn--sm{ font-size:.9rem; padding:.5rem .5rem .5rem 1.1rem; }
.btn--sm .btn__icon{ width:1.7rem; height:1.7rem; font-size:.82rem; }

.link-arrow{
  display:inline-flex; align-items:center; gap:.5rem;
  font-weight:600; color:var(--green-deep); text-decoration:none;
  padding-bottom:2px;
  box-shadow:inset 0 -1.5px 0 rgba(28,94,21,.28);
  transition:box-shadow var(--t-fast) var(--ease), gap var(--t-fast) var(--ease);
}
.link-arrow:hover{ gap:.8rem; box-shadow:inset 0 -1.5px 0 var(--orange); }

/* ============================================================
   Nested-enclosure panel (outer shell + inner core)
   ============================================================ */

.panel{
  padding:.5rem;
  border-radius:calc(var(--r-lg) + .5rem);
  background:rgba(255,255,255,.55);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.6), var(--e3);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
}
.panel__in{
  border-radius:var(--r-lg);
  background:var(--paper);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
  padding:clamp(1.6rem,3.4vw,2.9rem);
}
@media (prefers-reduced-transparency: reduce){
  .panel{ background:rgba(255,255,255,.95); backdrop-filter:none; -webkit-backdrop-filter:none; }
}

/* ============================================================
   Navigation
   ============================================================ */

.nav{
  position:fixed; inset:0 0 auto 0; z-index:40;
  height:72px; display:flex; align-items:center;
  transition:background var(--t-mid) var(--ease), box-shadow var(--t-mid) var(--ease);
}
.nav__inner{ display:flex; align-items:center; gap:clamp(1rem,3vw,2.5rem); }

.nav__brand{ flex:none; line-height:0; }
.nav__brand img{ width:auto; height:34px; }

.nav__links{ display:flex; align-items:center; gap:clamp(.9rem,2vw,1.9rem); margin-inline:auto; }
.nav__links a{
  font-size:.95rem; font-weight:600; text-decoration:none; color:#fff;
  text-shadow:0 1px 12px rgba(14,58,11,.55);
  padding:.35rem 0;
  box-shadow:inset 0 -2px 0 rgba(255,255,255,0);
  transition:box-shadow var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.nav__links a:hover,
.nav__links a[aria-current]{ box-shadow:inset 0 -2px 0 var(--orange-lt); }

.nav__end{ display:flex; align-items:center; gap:.75rem; flex:none; }

/* scrolled state: solid bar, dark links */
.nav.is-stuck{ background:rgba(255,255,255,.92); box-shadow:0 1px 0 var(--line-soft), var(--e1); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); }
.nav.is-stuck .nav__links a{ color:var(--ink); text-shadow:none; }
.nav.is-stuck .nav__links a:hover,
.nav.is-stuck .nav__links a[aria-current]{ color:var(--green-deep); box-shadow:inset 0 -2px 0 var(--orange); }
.nav.is-stuck .burger span{ background:var(--ink); }

.burger{
  display:none; position:relative;
  width:44px; height:44px; padding:0;
  background:transparent; border:0; cursor:pointer;
}
.burger span{
  position:absolute; left:11px; width:22px; height:2px; border-radius:2px;
  background:#fff;
  transition:transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease), top var(--t-fast) var(--ease);
}
.burger span:nth-child(1){ top:18px; }
.burger span:nth-child(2){ top:25px; }
.burger[aria-expanded="true"] span{ background:var(--ink); top:21px; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ transform:rotate(-45deg); }

.menu{
  position:fixed; inset:0; z-index:35;
  display:flex; flex-direction:column; justify-content:center; gap:2.5rem;
  padding:6rem var(--gutter) 3rem;
  background:rgba(255,255,255,.94);
  backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px);
}
.menu[hidden]{ display:none; }
.menu__links{ display:flex; flex-direction:column; gap:.4rem; }
.menu__links a,
.menu__cta{
  opacity:0; transform:translateY(28px);
  animation:menu-in .55s var(--ease) forwards;
  animation-delay:calc(var(--i) * 55ms + 60ms);
}
.menu__links a{
  font-family:var(--display); font-size:clamp(2rem,9vw,3rem); font-weight:600;
  text-decoration:none; color:var(--ink); line-height:1.25;
}
.menu__cta{ align-self:flex-start; }
@keyframes menu-in{ to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion: reduce){
  .menu__links a,.menu__cta{ animation:none; opacity:1; transform:none; }
}

/* ============================================================
   Hero
   ============================================================ */

.hero{
  position:relative; isolation:isolate; overflow:hidden;
  min-height:min(700px, 90dvh);
  display:flex; align-items:flex-end;
  padding-block:7rem clamp(3.5rem,7vw,5.5rem);
}
.hero__stage{ position:absolute; inset:0; z-index:-2; background:var(--green-900); }
.hero__slide{
  position:absolute; inset:0; margin:0;
  opacity:0; transition:opacity 1.1s var(--ease);
}
.hero__slide.is-active{ opacity:1; }
.hero__slide img{ width:100%; height:100%; object-fit:cover; }

/* slow drift gives the stills some life while a slide is on screen */
.hero__slide.is-active img{ animation:drift 9s var(--ease) forwards; }
@keyframes drift{ from{ transform:scale(1); } to{ transform:scale(1.045); } }

/* Two stacked scrims rather than one: the horizontal pass carries the copy,
   the vertical pass keeps the nav legible up top and anchors the base.
   Together they hold white text above 7:1 across the whole text block while
   the right two thirds of the photograph stay open. */
.hero::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(100deg,
      rgba(4,20,6,.62) 0%,
      rgba(4,20,6,.34) 45%,
      rgba(4,20,6,0)   78%),
    linear-gradient(180deg,
      rgba(4,20,6,.50) 0%,
      rgba(4,20,6,.16) 24%,
      rgba(4,20,6,.42) 56%,
      rgba(4,20,6,.78) 88%,
      rgba(4,20,6,.86) 100%);
}

.hero__inner{ position:relative; }
.hero__title{
  color:#fff;
  font-size:clamp(2rem,1rem + 3.1vw,3.35rem);
  letter-spacing:-.03em;
  line-height:1.06;
  /* held inside the dark half of the scrim so white stays above 4.5:1 */
  max-width:27ch;
  margin-bottom:1.15rem;
  text-shadow:0 2px 30px rgba(4,18,6,.45);
}
.hero__sub{
  color:rgba(255,255,255,.9);
  font-size:clamp(1rem,.95rem + .35vw,1.2rem);
  max-width:46ch;
  margin-bottom:2rem;
  text-shadow:0 1px 20px rgba(4,18,6,.5);
}
.hero__actions{ display:flex; flex-wrap:wrap; gap:.75rem; }

.hero__dots{
  position:absolute; z-index:2;
  right:var(--gutter); bottom:clamp(3.5rem,7vw,5.5rem);
  display:flex; gap:.55rem;
}
.hero__dots button{
  width:34px; height:4px; padding:0; border:0; cursor:pointer;
  border-radius:var(--r-pill);
  background:rgba(255,255,255,.42);
  transition:background var(--t-fast) var(--ease), width var(--t-fast) var(--ease);
}
.hero__dots button:hover{ background:rgba(255,255,255,.7); }
.hero__dots button[aria-current="true"]{ background:var(--orange-lt); width:52px; }

/* ============================================================
   Company introduction
   ============================================================ */

.intro{ padding-block:var(--section); }
.intro__grid{
  display:grid; gap:clamp(2.5rem,6vw,5rem);
  grid-template-columns:minmax(0,1fr);
  align-items:center;
}
@media (min-width:960px){
  .intro__grid{ grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr); }
}
.intro__copy p{ color:var(--ink-2); margin-top:1.15rem; max-width:56ch; }
.intro__copy .h2{ letter-spacing:-.025em; }
.intro__copy .link-arrow{ margin-top:1.9rem; }

.intro__media{ position:relative; }
.intro__plate{
  position:absolute; inset:auto auto -1.5rem -1.5rem;
  width:62%; aspect-ratio:1/1;
  border-radius:var(--r-lg);
  background:var(--green-tint);
}
.intro__img{
  position:relative;
  width:100%; aspect-ratio:4/3; object-fit:cover;
  border-radius:var(--r-lg);
  box-shadow:var(--e2);
}
.intro__inset{
  position:absolute; right:-1rem; bottom:-2.5rem;
  width:44%; max-width:15rem; aspect-ratio:4/3; object-fit:cover;
  border-radius:var(--r-lg);
  border:6px solid var(--paper);
  box-shadow:var(--e2);
}
@media (max-width:767px){
  .intro__inset,.intro__plate{ display:none; }
}

/* ============================================================
   Product rail
   ============================================================ */

.products{ padding-block:var(--section); background:var(--green-tint); }
.products__head{ margin-bottom:clamp(2rem,4vw,3rem); }

/* six products on a four-up track: 4 then 2, no horizontal scrolling */
.product-grid{
  display:grid; gap:1.25rem;
  grid-template-columns:repeat(4,minmax(0,1fr));
}
@media (max-width:1080px){ .product-grid{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (max-width:820px){  .product-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:520px){  .product-grid{ grid-template-columns:minmax(0,1fr); } }

.card{
  display:flex; flex-direction:column;
  border-radius:calc(var(--r-lg) + .375rem);
  background:rgba(255,255,255,.6);
  padding:.375rem;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.8), var(--e1);
  transition:transform var(--t-mid) var(--ease), box-shadow var(--t-mid) var(--ease);
}
.card:hover{ transform:translateY(-6px); box-shadow:inset 0 0 0 1px rgba(255,255,255,.8), var(--e2); }
.card__media{ border-radius:var(--r-lg) var(--r-lg) 0 0; overflow:hidden; }
.card__media img{ width:100%; aspect-ratio:4/3; object-fit:cover; transition:transform var(--t-slow) var(--ease); }
.card:hover .card__media img{ transform:scale(1.05); }
.card__body{
  flex:1; display:flex; flex-direction:column;
  background:var(--paper);
  border-radius:0 0 var(--r-lg) var(--r-lg);
  padding:1.4rem 1.4rem 1.5rem;
}
.card__body h3{ font-size:1.3rem; letter-spacing:-.015em; }
.card__body p{ color:var(--ink-2); font-size:.95rem; margin-top:.6rem; }
.card__body p.card__season{
  margin-top:auto;
  font-size:.82rem; font-weight:600;
  color:var(--green-deep);
  padding-top:1.4rem;
  border-top:1px solid var(--line-soft);
}
.products__foot{ margin-top:clamp(1rem,3vw,2rem); }

/* ============================================================
   Availability band
   ============================================================ */

.season{ padding-block:var(--section); }
.season__note{ color:var(--ink-2); max-width:52ch; margin-top:1rem; }
.season__scroll{ margin-top:clamp(2rem,4vw,3rem); overflow-x:auto; scrollbar-width:thin; }
.season__grid{ min-width:44rem; }

.season__months,
.season__row{
  display:grid;
  grid-template-columns:9.5rem repeat(12,1fr);
  align-items:center;
  column-gap:.25rem;
}
.season__months span{
  font-size:.72rem; font-weight:600; letter-spacing:.04em;
  color:var(--ink-2); text-align:center; padding-bottom:.7rem;
}
.season__row{ border-top:1px solid var(--line-soft); }
.season__row:last-child{ border-bottom:1px solid var(--line-soft); }
.season__name{ grid-column:1; font-weight:600; font-size:.98rem; padding:1rem .75rem 1rem 0; }

/* one segment per continuous run of months; seasons that cross the new
   year simply carry two segments rather than one wrapping bar */
.season__bar{
  grid-row:1;
  grid-column:var(--a) / var(--b);
  height:34px; display:grid; place-items:center;
  border-radius:var(--r-pill);
  background:var(--green);
  color:#fff; font-size:.76rem; font-weight:600;
  white-space:nowrap; overflow:hidden;
}

/* ============================================================
   Why choose us
   ============================================================ */

.why{ position:relative; isolation:isolate; padding-block:var(--section); }
.why__media{ position:absolute; inset:0 0 42% 0; z-index:0; background:var(--green-900); }
.why__media img{ width:100%; height:100%; object-fit:cover; }
.why__media::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg,
    rgba(8,32,8,.5) 0%,
    rgba(8,32,8,.10) 52%,
    rgba(255,255,255,0) 76%,
    #fff 100%);
}
.why > .wrap{ position:relative; z-index:1; }
.why__panel{ margin-top:clamp(6rem,16vw,13rem); }
.why__lead{ color:var(--ink-2); margin-top:1.15rem; max-width:62ch; }

.strengths{
  list-style:none; margin:clamp(1.8rem,3.5vw,2.6rem) 0 0; padding:0;
  display:grid; gap:1.15rem 2rem;
  grid-template-columns:repeat(auto-fit,minmax(min(15rem,100%),1fr));
}
.strengths li{ display:flex; align-items:center; gap:.85rem; font-weight:600; font-size:.98rem; }
.strengths i{
  display:grid; place-items:center; flex:none;
  width:2.6rem; height:2.6rem; border-radius:var(--r-pill);
  background:var(--green-tint); color:var(--green-deep);
  font-size:1.2rem;
}

/* ============================================================
   Sourcing and supply
   ============================================================ */

.reach{ padding-block:var(--section); background:var(--green-tint); }
.reach .h2{ margin-inline:auto; text-align:center; max-width:22ch; }

/* the map sits straight on the section, no plate, no frame */
.reach__map{ margin:clamp(1.5rem,3vw,2.5rem) auto 0; max-width:76rem; }
.reach__map img{ width:100%; height:auto; }

.reach__legend{
  display:grid; gap:clamp(1.5rem,4vw,3rem);
  grid-template-columns:repeat(auto-fit,minmax(min(19rem,100%),1fr));
  max-width:60rem; margin:clamp(2.5rem,5vw,3.5rem) auto 0;
}
.reach__block h3{ font-size:1.15rem; margin-top:.75rem; }
.reach__block p{ color:var(--ink-2); font-size:.98rem; margin-top:.6rem; }
.reach__key{ display:block; width:.7rem; height:.7rem; border-radius:var(--r-pill); }
.reach__key--source{ background:var(--key-blue); }
.reach__key--market{ background:var(--green); }

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

.foot{ background:var(--green-900); color:rgba(255,255,255,.78); padding-top:var(--section); }
.foot__grid{
  display:grid; gap:clamp(2.5rem,5vw,3.5rem);
  grid-template-columns:repeat(auto-fit,minmax(min(13rem,100%),1fr));
  padding-bottom:clamp(3rem,6vw,4.5rem);
}
@media (min-width:900px){
  .foot__grid{ grid-template-columns:1.6fr .9fr .9fr 1.3fr; }
}
.foot__brand img{ width:auto; height:38px; }
.foot__tag{ color:var(--orange-lt); font-weight:600; margin-top:1.1rem; }
.foot__line{ margin-top:.6rem; font-size:.95rem; }

.foot h3{
  font-family:var(--body); font-size:.85rem; font-weight:700;
  letter-spacing:.09em; text-transform:uppercase;
  color:#fff; margin-bottom:1.1rem;
}
.foot__col{ display:flex; flex-direction:column; gap:.6rem; align-items:flex-start; }
.foot__col a{
  font-size:.98rem; text-decoration:none;
  transition:color var(--t-fast) var(--ease);
}
.foot__col a:hover{ color:var(--orange-lt); }
.foot__contact{ gap:.75rem; }
.foot__contact .btn{ margin-top:.75rem; }

/* honest placeholder: real details still needed from the client.
   Base is the light-background form; the footer overrides for dark. */
.tbd{
  font-size:.95rem; font-style:italic;
  color:var(--ink-2);
  padding-left:.9rem;
  border-left:2px dashed rgba(238,122,8,.55);
}
.foot .tbd{
  color:rgba(255,255,255,.5);
  border-left-color:rgba(249,160,60,.5);
}

.foot__base{
  display:flex; flex-wrap:wrap; justify-content:space-between; gap:.5rem 1.5rem;
  padding-block:1.6rem;
  border-top:1px solid rgba(255,255,255,.12);
  font-size:.88rem; color:rgba(255,255,255,.55);
}
.foot__base p{ margin:0; }

/* ============================================================
   Inner pages
   Everything below is shared by /about/, /products/,
   /quality-control/ and /contact/.
   ============================================================ */

/* ── page hero: same scrim principle as the homepage, half the height ── */
.page-hero{
  position:relative; isolation:isolate; overflow:hidden;
  min-height:min(460px, 62dvh);
  display:flex; align-items:flex-end;
  padding-block:8rem clamp(2.75rem,5vw,4rem);
  background:var(--green-900);
}
.page-hero__bg{
  position:absolute; inset:0; z-index:-2;
  width:100%; height:100%; object-fit:cover;
}
.page-hero::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(100deg, rgba(4,20,6,.66) 0%, rgba(4,20,6,.38) 48%, rgba(4,20,6,.02) 82%),
    linear-gradient(180deg, rgba(4,20,6,.52) 0%, rgba(4,20,6,.18) 34%, rgba(4,20,6,.42) 72%, rgba(4,20,6,.80) 100%);
}
.page-hero__inner{ position:relative; }
.page-hero__title{
  color:#fff;
  font-size:clamp(1.9rem,1.1rem + 2.6vw,3rem);
  letter-spacing:-.03em; line-height:1.08;
  max-width:24ch;
  text-shadow:0 2px 30px rgba(4,18,6,.45);
}
.page-hero__sub{
  color:rgba(255,255,255,.9);
  max-width:52ch; margin-top:1rem;
  text-shadow:0 1px 20px rgba(4,18,6,.5);
}

/* ── generic section shells ─────────────────────────────────────────── */
.sec{ padding-block:var(--section); }
.sec--tint{ background:var(--green-tint); }
.sec__head{ max-width:62ch; margin-bottom:clamp(2rem,4vw,3.25rem); }
.sec__head p{ color:var(--ink-2); margin-top:1rem; }
.sec__head--center{ margin-inline:auto; text-align:center; }
.sec__head--center .h2{ margin-inline:auto; }

.label{
  display:block;
  font-size:.78rem; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--green-deep);
  margin-bottom:.85rem;
}

.prose p{ color:var(--ink-2); max-width:62ch; }
.prose p + p{ margin-top:1.15rem; }

/* A quieter heading step for narrative sections. Marketing sections want the
   title to dominate; a story wants the prose and the photography to carry
   equal weight, so this drops the title-to-body ratio from 2.7x to about 1.9x. */
.h2--quiet{
  font-size:clamp(1.45rem,1.15rem + 1.05vw,1.95rem);
  line-height:1.24;
  letter-spacing:-.015em;
  max-width:26ch;
}
.prose--narrative p{ max-width:64ch; line-height:1.75; }
.prose--narrative p + p{ margin-top:1.05rem; }

/* Story: text first, photography beneath it, the way an editorial page reads.
   Side by side made the heading compete with the image; stacking lets the
   narrative breathe and gives the pictures a band of their own. */
.story__intro{
  display:grid; gap:clamp(1.25rem,3vw,3rem);
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:900px){
  /* the heading sits against the optical centre of the prose rather than its
     first line, so the empty half of the left column stops reading as a gap */
  .story__intro{ grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr); align-items:center; }
}

.sec--tight-bottom{ padding-bottom:clamp(2.5rem,5vw,4rem); }

/* ── parallax divider ────────────────────────────────────────────────
   A full-bleed photograph acting as a rule between sections. The picture
   is taller than its frame and drifts inside it as the band travels
   through the viewport, so it lags behind the page instead of moving
   with it.

   Driven from main.js, not CSS. `animation-timeline: view()` looks like the
   right tool but resolves the subject against its nearest scrollport
   ancestor, and this frame is `overflow:hidden`, which makes it exactly
   that: a scrollport that never scrolls. The timeline sits frozen at a
   constant value. A named `view-timeline` on the frame would work around it,
   but a rAF loop gated to visibility is one code path that behaves the same
   everywhere, so that is what runs. */
.parallax{
  position:relative;
  overflow:hidden;
  height:clamp(19rem,40vw,30rem);
  background:var(--green-900);
}
/* Overhang and drift are coupled, and the drift lives in main.js. Keep them
   in step or the frame edge shows:

     overhang px = 0.65 x frame height          (the inset below)
     drift px    = 0.25 x image height          (the translate in main.js)
                 = 0.25 x 2.30 x frame height
                 = 0.575 x frame height
     margin      = 0.65 - 0.575 = ~36px at a 480px frame

   Travel is 552px, up from 294px. Raising it further is tempting and wrong:
   260% against a 30% drift leaves 10px of margin, which is close enough to
   rounding error to expose the frame edge.

   The source had to be recropped for this. At 2000x900 there was simply not
   enough picture above and below the visible window to reveal; it is 2000x1400
   now, which is near the photograph's own aspect, so the fruit in the branches
   and the people underneath both come into view as the band crosses. */
.parallax img{
  position:absolute;
  inset:-65% 0;
  width:100%; height:230%;
  object-fit:cover;
  will-change:transform;
}
/* no script, or reduced motion: the still sits centred and still covers the
   frame, because the overhang is symmetrical */
@media (prefers-reduced-motion: reduce){
  .parallax img{ transform:none !important; }
}

/* ── two-tone statement band ─────────────────────────────────────────
   Paired statements set as facing panels, edge to edge, no container.
   One dark, one light, so the split itself carries the contrast and the
   text needs no plate behind it. */
.duo{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
}
.duo__panel{
  display:grid; place-items:center;
  min-height:clamp(16rem,26vw,21rem);
  padding:clamp(2.75rem,6vw,4.5rem) clamp(1.5rem,5vw,4rem);
}
.duo__panel--dark{ background:var(--green-900); }
.duo__panel--light{ background:var(--green-tint); }
.duo__inner{ max-width:34ch; text-align:center; }
.duo__label{
  display:block;
  font-family:var(--display); font-weight:600;
  font-size:.82rem; letter-spacing:.16em; text-transform:uppercase;
  margin-bottom:1.1rem;
}
.duo__panel--dark .duo__label{ color:var(--orange-lt); }
.duo__panel--light .duo__label{ color:var(--green-deep); }
.duo__text{
  font-family:var(--display); font-weight:500;
  font-size:clamp(1.05rem,.95rem + .55vw,1.4rem);
  line-height:1.5; letter-spacing:-.01em;
}
.duo__panel--dark .duo__text{ color:#fff; }
.duo__panel--light .duo__text{ color:var(--green-900); }

@media (max-width:720px){
  .duo{ grid-template-columns:minmax(0,1fr); }
  .duo__panel{ min-height:0; }
}

/* ── split: media beside copy, mirrored with --flip ─────────────────── */
.split{
  display:grid; gap:clamp(2.25rem,5vw,4.5rem);
  grid-template-columns:minmax(0,1fr);
  align-items:center;
}
@media (min-width:900px){
  .split{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .split--wide-media{ grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr); }
  .split--flip .split__media{ order:-1; }
}
.split__media img{
  width:100%; aspect-ratio:4/3; object-fit:cover;
  border-radius:var(--r-lg); box-shadow:var(--e2);
}

/* offset pair, as used on the homepage introduction */
.media-pair{ position:relative; }
.media-pair__plate{
  position:absolute; inset:auto auto -1.5rem -1.5rem;
  width:60%; aspect-ratio:1/1;
  border-radius:var(--r-lg); background:var(--green-tint);
}
.sec--tint .media-pair__plate{ background:var(--tint-deep); }
.media-pair img:first-of-type{
  position:relative;
  width:100%; aspect-ratio:4/3; object-fit:cover;
  border-radius:var(--r-lg); box-shadow:var(--e2);
}
.media-pair__inset{
  position:absolute; right:-1rem; bottom:-2.5rem;
  width:42%; max-width:14rem; aspect-ratio:3/4; object-fit:cover;
  border-radius:var(--r-lg); border:6px solid var(--paper); box-shadow:var(--e2);
}
@media (max-width:899px){
  .media-pair__inset,.media-pair__plate{ display:none; }
}

/* ── value cards: mission / vision, packaging details ───────────────── */
.value-grid{
  display:grid; gap:1.25rem;
  grid-template-columns:repeat(auto-fit,minmax(min(17rem,100%),1fr));
}
.value{
  background:var(--paper);
  border-radius:var(--r-lg);
  padding:clamp(1.6rem,3vw,2.4rem);
  box-shadow:var(--e1);
  display:flex; flex-direction:column; gap:.85rem;
}
.value i{
  display:grid; place-items:center;
  width:3rem; height:3rem; border-radius:var(--r-pill);
  background:var(--green-tint); color:var(--green-deep);
  font-size:1.4rem;
}
.value h3{ font-size:1.3rem; letter-spacing:-.015em; }
.value p{ color:var(--ink-2); font-size:.98rem; }

/* ── numbered process: quality control inspection steps ──────────────
   Four alternating splits, which the zigzag cap in brand-spec 8 otherwise
   forbids. An ordered process is the second exception to it: mirroring is
   what makes the sequence legible as a sequence, and a reader walking down
   the page follows the alternation rather than re-reading a repeated shape.

   The mirroring is :nth-child, not a --flip modifier. With four rows a
   hand-placed class is one careless reorder away from putting two pictures
   on the same side, and nothing would catch it. */
.steps{
  display:grid; gap:clamp(2.75rem,6vw,5rem);
  counter-reset:step; list-style:none;
}
.step{
  display:grid; gap:clamp(1.5rem,4vw,3.5rem);
  grid-template-columns:minmax(0,1fr);
  align-items:center;
  counter-increment:step;
}
@media (min-width:900px){
  .step{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  /* odd rows read picture-left; even rows mirror. Below 900px the single
     column falls back to DOM order, picture first, for every row. */
  .step:nth-child(even) .step__media{ order:2; }
}
.step__media img{
  width:100%; aspect-ratio:4/3; object-fit:cover; display:block;
  border-radius:var(--r-lg); box-shadow:var(--e2);
}
/* Rule plus numeral. The rule is where the orange goes: as an accent line it
   is on-system, whereas orange numerals on white measure 2.85:1 and miss even
   the 3:1 large-text floor. The numeral itself is --green-deep at 7.9:1. */
.step__num{
  display:flex; align-items:center; gap:.8rem;
  font-family:var(--display); font-weight:700;
  font-size:.95rem; letter-spacing:.14em;
  color:var(--green-deep);
  margin-bottom:.9rem;
}
.step__num::before{
  content:''; flex:none;
  width:clamp(1.5rem,4vw,2.5rem); height:2px;
  background:var(--orange);
}
.step__num::after{ content:'Step ' counter(step,decimal-leading-zero); }
.step__body h3{
  font-size:clamp(1.35rem,1.1rem + .9vw,1.9rem);
  letter-spacing:-.02em;
  margin-bottom:.65rem;
}
.step__body p{ color:var(--ink-2); max-width:46ch; }

/* ── product record: catalogue row on the products page ─────────────── */
.record{
  padding-block:clamp(3rem,6vw,5rem);
  border-top:1px solid var(--line-soft);
  scroll-margin-top:92px;   /* clears the fixed nav when jumped to */
}
.record:first-of-type{ border-top:0; }
.record__name{
  font-size:clamp(1.6rem,1.2rem + 1.6vw,2.35rem);
  letter-spacing:-.025em;
}
.record__season{
  display:inline-flex; align-items:center; gap:.5rem;
  margin-top:.9rem; padding:.4rem 1rem;
  border-radius:var(--r-pill);
  background:var(--green-tint); color:var(--green-deep);
  font-size:.85rem; font-weight:600;
}
.record .prose{ margin-top:1.5rem; }

/* specification strip: every unsupplied field renders as a visible gap */
.spec{
  margin-top:1.9rem;
  border-top:1px solid var(--line-soft);
}
.spec__row{
  display:grid; gap:.35rem 1.5rem;
  grid-template-columns:minmax(0,1fr);
  padding-block:.85rem;
  border-bottom:1px solid var(--line-soft);
}
@media (min-width:560px){
  .spec__row{ grid-template-columns:11rem minmax(0,1fr); align-items:baseline; }
}
.spec__key{
  font-size:.82rem; font-weight:700; letter-spacing:.05em;
  text-transform:uppercase; color:var(--ink);
}
.spec__val{ font-size:.96rem; color:var(--ink-2); }

/* "Not applicable", the editor's third state. A certification GoJoy does not
   hold is not a gap waiting to be filled, so it should not sit on the page
   reading "to be supplied" for ever. Hiding the value alone would leave an
   orphaned label, so the whole row goes. The rule on the value itself is the
   fallback for engines without :has(); worst case a label shows with nothing
   beside it rather than the row vanishing. */
.spec__val.is-off{ display:none; }
.spec__row:has(> .spec__val.is-off){ display:none; }
.spec__val.tbd{ font-size:.92rem; }

/* ── anchor chips: jump between product records ─────────────────────── */
.chips{ display:flex; flex-wrap:wrap; gap:.6rem; }
.chip{
  display:inline-flex; align-items:center;
  padding:.5rem 1.05rem;
  border-radius:var(--r-pill);
  background:var(--paper); color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--line);
  font-size:.9rem; font-weight:600; text-decoration:none;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease);
}
.chip:hover{ background:var(--green-deep); color:#fff; box-shadow:none; }

/* strengths as a ruled list, so the About page does not simply repeat
   the homepage's chip row */
.strengths--list{
  grid-template-columns:repeat(auto-fit,minmax(min(24rem,100%),1fr));
  gap:0 clamp(2rem,5vw,4rem);
  margin-top:clamp(2rem,4vw,3rem);
}
.strengths--list li{
  padding-block:1.15rem;
  border-bottom:1px solid var(--line-soft);
  font-size:1.02rem;
}

/* ── callout: certifications and other flagged gaps ─────────────────── */
.callout{
  border-radius:var(--r-lg);
  background:var(--green-tint);
  padding:clamp(1.6rem,3vw,2.4rem);
  box-shadow:inset 0 0 0 1px var(--line-soft);
}
.sec--tint .callout{ background:var(--paper); }
.callout h3{ font-size:1.2rem; margin-bottom:.75rem; }
.callout p{ color:var(--ink-2); max-width:62ch; }
.callout .tbd{ margin-top:1.1rem; }

/* ── contact ─────────────────────────────────────────────────────────── */
.contact-grid{
  display:grid; gap:clamp(2.5rem,5vw,4rem);
  grid-template-columns:minmax(0,1fr);
  align-items:start;
}
@media (min-width:900px){
  .contact-grid{ grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); }
}
.contact-list{ display:flex; flex-direction:column; gap:1.5rem; }
.contact-item{ display:flex; gap:1rem; align-items:flex-start; }
.contact-item i{
  display:grid; place-items:center; flex:none;
  width:2.75rem; height:2.75rem; border-radius:var(--r-pill);
  background:var(--green-tint); color:var(--green-deep);
  font-size:1.25rem;
}
.contact-item h3{ font-size:1rem; margin-bottom:.35rem; }
.contact-item .tbd{ border-left:0; padding-left:0; }

/* Two related values stacked under one heading: phone with WhatsApp, Facebook
   with LinkedIn. Each is its own editable slot, so they cannot share a line. */
/* Two ways for a row to vanish, and they are not interchangeable.
   `is-off` is a statement: somebody ticked "not applicable", so the row is gone
   on purpose and stays gone.
   `hide-when-empty` is the absence of a statement: an optional link they simply
   do not have yet. It rides on `tbd`, so filling the field brings the row back
   with no second action and clearing it takes the row away again.
   Only for things a buyer would not miss. Never for an address or a phone
   number, where a visible "to be supplied" is the honest thing to show. */
.hide-when-empty.tbd{ display:none; }

.contact-lines > span{ display:block; }
.contact-lines > span + span{ margin-top:.3rem; }

/* Generated contact links. The visible text is a label like "Facebook", never
   the URL, so these need to read as links without shouting. */
.contact-item a,
.foot__contact a:not(.btn){
  text-decoration:none;
  box-shadow:inset 0 -1px 0 currentColor;
  transition:color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.contact-item a{ color:var(--green-deep); box-shadow:inset 0 -1px 0 rgba(28,94,21,.35); }
.contact-item a:hover{ box-shadow:inset 0 -1px 0 var(--orange); }
.foot__contact a:not(.btn){ color:#fff; box-shadow:inset 0 -1px 0 rgba(255,255,255,.32); }
.foot__contact a:not(.btn):hover{ color:var(--orange-lt); box-shadow:inset 0 -1px 0 var(--orange-lt); }

/* ── form ────────────────────────────────────────────────────────────── */
.form{
  background:var(--paper);
  border-radius:var(--r-lg);
  padding:clamp(1.6rem,3.4vw,2.6rem);
  box-shadow:var(--e2);
}
.field + .field{ margin-top:1.15rem; }
.field label{
  display:block; font-size:.88rem; font-weight:600;
  color:var(--ink); margin-bottom:.45rem;
}
.field .req{ color:var(--orange); }
.field input,
.field textarea{
  width:100%;
  font-family:var(--body); font-size:1rem; color:var(--ink);
  background:var(--paper);
  padding:.8rem 1rem;
  border:1.5px solid var(--line);
  border-radius:var(--r-sm);
  transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.field textarea{ min-height:9rem; resize:vertical; }
/* What used to be the textarea's placeholder. A placeholder disappears the
   moment someone starts typing, which is exactly when a list of the things to
   include is worth reading, and it never passed contrast either. */
.field__hint{
  margin:-.15rem 0 .55rem; font-size:.85rem; color:var(--ink-2);
}
.field input::placeholder,
.field textarea::placeholder{ color:var(--muted); }
.field input:hover,
.field textarea:hover{ border-color:rgba(22,35,26,.24); }
.field input:focus,
.field textarea:focus{
  outline:none;
  border-color:var(--green-deep);
  box-shadow:0 0 0 3px rgba(28,94,21,.14);
}
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"]{ border-color:var(--danger); }
.field__error{
  display:none;
  margin-top:.4rem; font-size:.85rem; color:var(--danger);
}
.field input[aria-invalid="true"] ~ .field__error,
.field textarea[aria-invalid="true"] ~ .field__error{ display:block; }

.form__foot{ margin-top:1.6rem; display:flex; flex-wrap:wrap; align-items:center; gap:1rem; }
/* Honeypot. Off-screen rather than display:none, because some bots skip
   anything a browser would not render. */
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* The live region is never hidden and never removed, only emptied.
   `role="status"` on an element that is display:none at the moment the message
   arrives is a region the screen reader was not watching, and the announcement
   is simply lost: the one user who cannot see the form turn green is the one
   who gets no confirmation that their enquiry went anywhere. Empty, it has no
   line box and no box of its own, so it occupies nothing. */
.form__note{ margin:0; font-size:.9rem; color:var(--ink-2); }
.form__note:not(:empty){
  margin-top:1.25rem; padding:.9rem 1.1rem;
  border-radius:var(--r-sm);
  background:var(--green-tint);
}
.form__note--ok:not(:empty){ background:var(--ok-bg); color:var(--green-deep); }

/* ── closing call to action ─────────────────────────────────────────── */
.cta{
  background:var(--green-900); color:#fff;
  padding-block:clamp(3.5rem,7vw,6rem);
}
.cta__inner{
  display:flex; flex-wrap:wrap; align-items:center;
  justify-content:space-between; gap:2rem;
}
.cta h2{
  color:#fff;
  font-size:clamp(1.6rem,1.2rem + 1.8vw,2.5rem);
  letter-spacing:-.02em; max-width:20ch;
}
.cta p{ color:rgba(255,255,255,.78); max-width:46ch; margin-top:.9rem; }

/* ============================================================
   Scroll reveal
   ============================================================ */

.reveal{ opacity:0; transform:translateY(26px); }
.reveal.is-in{
  opacity:1; transform:none;
  transition:opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.reveal--delay.is-in{ transition-delay:.12s; }
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity:1; transform:none; }
  .hero__slide.is-active img{ animation:none; }
  .hero__slide{ transition:none; }
  .btn,.card{ transition:none; }
}

/* ============================================================
   Breakpoints
   ============================================================ */

@media (max-width:900px){
  .nav__links{ display:none; }
  .nav__end .btn{ display:none; }
  .burger{ display:block; }
  .hero__dots{ left:var(--gutter); right:auto; bottom:1.5rem; }
  .hero{ padding-bottom:5rem; }
}

/* below tablet the 12-month track stops being readable, so each program
   collapses to "name .... range" and the empty wrap segments drop out */
@media (max-width:767px){
  .season__scroll{ overflow:visible; }
  .season__grid{ min-width:0; }
  .season__months{ display:none; }
  .season__row{
    display:flex; align-items:center; justify-content:space-between;
    gap:1rem; padding-block:.55rem;
  }
  .season__name{ padding:0; }
  .season__bar{ flex:none; height:30px; padding-inline:1.05rem; }
  .season__bar:empty{ display:none; }
}



/* ── long-form legal copy ────────────────────────────────────────────
   One column, generous leading, headings that separate rather than shout.
   Nobody reads a privacy policy for pleasure; the job is to let someone
   scanning for one specific answer find it without reading the rest. */
.legal{ max-width:64ch; }
/* `.prose p` also sets a colour and matches this, so the tag has to be in the
   selector to outrank it. */
.legal p.legal__meta{ font-size:.85rem; color:var(--muted); margin-bottom:2.25rem; }
.legal .h2{ font-size:1.32rem; margin-top:2.75rem; margin-bottom:.75rem; }
.legal .h2:first-of-type{ margin-top:0; }
.legal ul{ margin:.9rem 0 0; padding-left:1.15rem; }
.legal li{ margin-top:.5rem; line-height:1.7; }
.legal li::marker{ color:var(--green); }
.legal strong{ color:var(--ink); font-weight:600; }

/* ── consent banner ──────────────────────────────────────────────────
   Anchored to the bottom, never over the content. A B2B buyer who has to
   dismiss a wall before reading the first sentence is a buyer who leaves, and
   nothing in the law requires the page to be held hostage: it requires the
   choice to be free, informed and as easy to refuse as to accept, which is why
   Decline and Accept are the same size and sit side by side.

   Hidden with the `hidden` attribute rather than a class, so that with the
   stylesheet missing it is absent rather than stuck across the page. */
.consent[hidden]{ display:none; }
.consent{
  position:fixed; z-index:60; inset:auto 0 0 0;
  padding:0 var(--gutter) max(var(--gutter), env(safe-area-inset-bottom));
}
.consent__inner{
  max-width:var(--wrap); margin-inline:auto;
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:1rem 2rem;
  padding:1.15rem 1.4rem;
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--e3);
  /* it rises into place; with reduced motion the transform never runs */
  transform:translateY(1.5rem); opacity:0;
  transition:transform var(--t-mid) var(--ease), opacity var(--t-mid) var(--ease);
}
.consent.is-in .consent__inner{ transform:none; opacity:1; }
.consent__copy{ flex:1 1 26rem; min-width:0; }
.consent__title{
  font-family:var(--display); font-size:1.02rem; font-weight:600;
  letter-spacing:-.01em; margin:0 0 .3rem;
}
.consent__copy p{ margin:0; font-size:.9rem; color:var(--ink-2); }
.consent__actions{ display:flex; gap:.6rem; flex:none; }
.consent__actions .btn{ padding-inline:1.15rem; }

@media (prefers-reduced-motion: reduce){
  .consent__inner{ transform:none; transition:none; }
}

/* Stacked on a phone, and the buttons go full width so neither is the easier
   one to hit by accident. */
@media (max-width:640px){
  .consent__actions{ width:100%; }
  .consent__actions .btn{ flex:1 1 0; justify-content:center; }
}

/* A button that reads as a link: it opens the chooser, it does not navigate,
   so it must not be an anchor. */
.linkish{
  background:none; border:0; padding:0; cursor:pointer;
  font:inherit; color:inherit; text-decoration:underline;
  text-underline-offset:.18em;
}
.linkish:hover{ color:var(--paper); }

.foot__legal{ display:flex; flex-wrap:wrap; gap:.4rem 1.1rem; }

@media (max-width:640px){
  .why__media{ inset:0 0 58% 0; }
  .foot__base{ flex-direction:column; }
}
