/* CropNow home: the landing screen.
 *
 * One continuous chalk-white surface. The name scrolls across the full width
 * over the line-drawn village, with the CropNow mark rolling between repeats;
 * the slogan and identity lines run along the bottom. hero.js makes the name
 * respond to the pointer.
 */

.hero {
  --ticker-h: clamp(4.75rem, 13vh, 9rem);
  --scene-h: min(62vh, 40vw);
  --title-size: min(21vw, 46vh);
  --title-stretch: 1.36;

  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 61fr) minmax(0, 39fr);
  grid-template-rows: minmax(0, 1fr) var(--ticker-h);
  grid-template-areas:
    "title title"
    "slogan identity";
  min-height: 100vh;
  min-height: 100svh;
  padding-top: var(--header-h);
  overflow: hidden;
  /* The sky is the same chalk white as the village's land. */
  background: var(--chalk);
}

/* -- Village --------------------------------------------------------------- */

.hero__scene {
  position: absolute;
  right: 0;
  bottom: calc(var(--ticker-h) * .62);
  left: 0;
  z-index: -1;
  height: var(--scene-h);
  pointer-events: none;
  /* Fades softly at both sides and into the slogan below. hero.js shifts it
   * a little with the pointer, for depth. */
  -webkit-mask-image:
    linear-gradient(90deg, transparent, #000 6% 94%, transparent),
    linear-gradient(180deg, #000 0 84%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent, #000 6% 94%, transparent),
    linear-gradient(180deg, #000 0 84%, transparent 100%);
  mask-composite: intersect;
  translate: var(--scene-x, 0) var(--scene-y, 0);
}

/* -- Marquees -------------------------------------------------------------
 * The server renders one group; home.js fills it to the window's width,
 * adds a copy and starts the loop, so without JavaScript the text is still.
 */

.marquee {
  display: block;
  overflow: hidden;
  white-space: nowrap;
}

.marquee__track {
  display: flex;
  width: max-content;
  margin-left: var(--marquee-start, 0px);
}

.marquee__group,
.marquee__item {
  display: flex;
  flex: none;
  align-items: baseline;
}

.marquee[data-ready] .marquee__track {
  animation: marquee-left var(--marquee-duration, 40s) linear infinite;
}

@keyframes marquee-left {
  to { transform: translate3d(-50%, 0, 0); }
}

/* -- Title --------------------------------------------------------------- */

.hero__title {
  grid-area: title;
  align-self: center;
  min-width: 0;
  margin: 0;
  margin-top: calc(var(--title-size) * -.06);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--title-size);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -.004em;
}

.marquee--title {
  --marquee-start: var(--gutter);
  padding-block: .06em .2em;
  /* Tall: the condensed face, stretched a little further upright. */
  transform: scaleY(var(--title-stretch));
  transform-origin: 50% 70%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4vw, #000 calc(100% - 4vw), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4vw, #000 calc(100% - 4vw), transparent);
}

/* The CropNow mark between repeats, kept round despite the stretch. */
.title-mark {
  display: inline-block;
  width: .62em;
  height: .62em;
  margin: 0 .2em 0 .16em;
  align-self: center;
  transform: scaleY(calc(1 / var(--title-stretch)));
}

.title-mark img {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Live (hero.js): the track moves by script, and each letter is a stalk. */
.marquee--title.is-live {
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.marquee--title.is-grabbing {
  cursor: grabbing;
}

.marquee--title .ch {
  display: inline-block;
  transform-origin: 50% 92%;
  will-change: transform;
}

.marquee--title .title-mark.ch {
  transform-origin: 50% 50%;
}

.hero__hint {
  position: absolute;
  right: var(--gutter);
  bottom: calc(var(--ticker-h) + .6rem);
  color: rgb(13 59 9 / .55);
  font: 600 .75rem/1 var(--font-text);
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity .6s var(--ease);
}

.hero:hover .hero__hint {
  opacity: 1;
}

@media (hover: none) {
  .hero__hint {
    display: none;
  }
}

/* -- Slogan and identity lines ------------------------------------------- */

.hero__slogan {
  grid-area: slogan;
  align-self: center;
  min-width: 0;
  margin: 0 clamp(1.5rem, 4vw, 4.5rem) 0 0;
  font-size: clamp(1.3rem, .85rem + 1.3vw, 2.5rem);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -.015em;
}

.marquee--slogan {
  --marquee-start: var(--gutter);
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 9vw), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 9vw), transparent);
}

/* Each repeat ends with the green full stop. */
.marquee--slogan .marquee__item::after {
  content: "";
  align-self: center;
  width: .3em;
  height: .3em;
  margin-inline: 1.15em;
  border-radius: 50%;
  background: var(--green);
}

.hero__identity {
  grid-area: identity;
  align-self: center;
  display: flex;
  align-items: center;
  gap: .75rem;
  min-width: 0;
  padding-left: clamp(.5rem, 1.5vw, 1.5rem);
  padding-right: calc(var(--gutter) - .5rem);
}

.marquee--identity {
  flex: 1;
  min-width: 0;
  color: var(--forest);
  font-size: clamp(.82rem, .62rem + .4vw, 1.04rem);
  font-weight: 500;
  letter-spacing: .01em;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 3.5rem, #000 calc(100% - 3.5rem), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 3.5rem, #000 calc(100% - 3.5rem), transparent);
}

.identity-sep {
  margin-inline: .95em;
  color: var(--green);
}

/* Pause and play for everything that moves (WCAG 2.2.2). */
.motion-toggle {
  position: relative;
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--forest);
  cursor: pointer;
  opacity: .5;
  transition: opacity .2s, background-color .2s;
}

.motion-toggle:hover,
.motion-toggle:focus-visible {
  opacity: 1;
  background: rgb(197 209 181 / .45);
}

.motion-toggle::before,
.motion-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  width: .19rem;
  height: .72rem;
  border-radius: 1px;
  background: currentColor;
  translate: 0 -50%;
}

.motion-toggle::before {
  left: calc(50% - .3rem);
}

.motion-toggle::after {
  left: calc(50% + .11rem);
}

.motion-toggle[aria-pressed="true"]::before {
  left: calc(50% - .2rem);
  width: 0;
  height: 0;
  border-style: solid;
  border-width: .4rem 0 .4rem .64rem;
  border-color: transparent transparent transparent currentColor;
  border-radius: 0;
  background: none;
}

.motion-toggle[aria-pressed="true"]::after {
  display: none;
}

/* -- Paused motion --------------------------------------------------------
 * Set by the toggle, or by default when the visitor prefers reduced motion.
 */

[data-motion="paused"] .marquee__track {
  animation-play-state: paused !important;
}

/* -- Portrait screens -----------------------------------------------------
 * Phones and portrait tablets: the name over the landscape, then the slogan
 * and the identity line, in one screen.
 */

@media (max-aspect-ratio: 1/1) {
  .hero {
    --ticker-h: auto;
    --scene-h: min(120vw, 52vh);
    --title-size: min(32vw, 20vh);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "title"
      "slogan"
      "identity";
    height: max(100svh, 34rem);
    min-height: 0;
    padding-top: var(--header-h);
    padding-bottom: .75rem;
  }

  .hero__scene {
    bottom: 6.5rem;
  }

  .hero__title {
    align-self: start;
    margin-top: 12vh;
  }

  .hero__slogan {
    margin: 0;
    padding: 0 0 .6rem;
    font-size: clamp(1.25rem, 5.4vw, 2rem);
  }

  .marquee--slogan {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 12vw), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 12vw), transparent);
  }

  .hero__identity {
    padding-left: var(--gutter);
  }
}

/* -- Introduction -----------------------------------------------------------
 * Read top to bottom by default: without JavaScript, on narrow or portrait
 * screens, and for visitors who prefer reduced motion. On wide screens
 * intro.js adds .is-horizontal: the stage pins to the window and the six
 * paragraphs travel from right to left as the visitor scrolls, one per stage.
 */

.intro {
  --read: min(50rem, 100vw - 2 * var(--gutter));
  position: relative;
  padding-block: clamp(3rem, 10vh, 7rem);
}

.intro__head {
  width: var(--read);
  margin: 0 auto clamp(2rem, 5vh, 3.5rem);
}

.intro__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 1.2rem + 3.4vw, 4.6rem);
  font-weight: 900;
  line-height: .98;
  letter-spacing: -.004em;
  text-wrap: balance;
}

/* The same green full stop as the title above. */
.intro__stop {
  color: var(--green);
}

.intro__count,
.intro__scenery {
  display: none;
}

.intro__track {
  display: grid;
  gap: clamp(2.25rem, 6vh, 4rem);
  width: var(--read);
  margin: 0 auto;
}

.intro__panel p {
  margin: 0;
  font-size: clamp(1.08rem, .82rem + .72vw, 1.62rem);
  line-height: 1.62;
  letter-spacing: -.003em;
  text-wrap: pretty;
}

/* CropNow photographs for each paragraph: one under the other below it here,
 * one to the left and one to the right, and either side of it in the
 * horizontal journey. Each keeps its own proportions (--ar, set from the
 * file) so nothing is cropped, with a distorted, torn edge (.photo-edge in
 * site.css), never framed. */
.intro__photos {
  display: grid;
  gap: clamp(1rem, 4vw, 1.75rem);
  margin-top: clamp(1.5rem, 5vw, 2.5rem);
}

.intro__photo {
  width: min(100%, 34rem, 26rem * var(--ar));
  height: auto;
  aspect-ratio: var(--ar);
}

.intro__photo--right {
  justify-self: end;
}

.intro__num {
  display: block;
  margin-bottom: .55rem;
  color: var(--green);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .14em;
  font-variant-numeric: tabular-nums;
}

.band--top {
  margin-bottom: clamp(1.5rem, 5vh, 3rem);
}

.band--bottom {
  margin-top: clamp(2rem, 6vh, 3.5rem);
}

/* Horizontal journey. The section is as tall as the scrolling it takes to
 * travel through the stages; the chalk-white background covers the page-edge
 * scenery, because the stage frames its reading area with its own. */
.intro.is-horizontal {
  --floor: 28vh;
  /* The reading column narrows to leave room for the photographs. */
  --side: clamp(12rem, 27vw, 30rem);
  --read: min(40rem, 100vw - 2 * var(--side));
  height: calc(100vh + (var(--stages) - 1) * 88vh);
  padding: 0;
  background: var(--chalk);
}

.intro.is-horizontal .band {
  display: none;
}

.intro.is-horizontal .intro__stage {
  position: sticky;
  top: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  height: 100vh;
  padding: clamp(3.5rem, 11vh, 7.5rem) 0 var(--floor);
  overflow: hidden;
}

.intro.is-horizontal .intro__head {
  margin-bottom: 0;
}

.intro.is-horizontal .intro__count {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: clamp(.9rem, 2.4vh, 1.6rem) 0 0;
  color: rgb(13 59 9 / .55);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .14em;
  font-variant-numeric: tabular-nums;
}

.intro__now {
  color: var(--green);
}

.intro__bar {
  position: relative;
  width: 5.5rem;
  height: 2px;
  border-radius: 2px;
  background: rgb(197 209 181 / .75);
  overflow: hidden;
}

.intro__fill {
  position: absolute;
  inset: 0;
  background: var(--green);
  transform: scaleX(0);
  transform-origin: left center;
}

.intro.is-horizontal .intro__track {
  display: flex;
  gap: 0;
  width: calc(var(--stages) * 100%);
  margin: 0;
  will-change: transform;
}

.intro.is-horizontal .intro__panel {
  position: relative;
  display: grid;
  flex: 0 0 calc(100% / var(--stages));
  grid-template-columns: minmax(0, 1fr) var(--read) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "left text right";
  align-items: center;
}

/* intro.js sets --intro-size on short windows so the longest paragraph fits
 * under the heading; whatever still overflows runs down over the scenery,
 * never up over the counter. */
.intro.is-horizontal .intro__panel p {
  grid-area: text;
  align-self: safe center;
  font-size: var(--intro-size, clamp(1.08rem, .82rem + .72vw, 1.62rem));
}

.intro.is-horizontal .intro__photos {
  display: contents;
}

/* Centred in the columns either side of the text, as large as the column
 * allows, and free to reach up beside the heading (that space is empty) and
 * down over the scenery. Staggered a little, one higher and one lower. */
.intro.is-horizontal .intro__photo {
  --col: (100% - var(--read)) / 2;
  position: absolute;
  top: 50%;
  width: min(var(--col) - 4.5rem, 60vh * var(--ar));
}

.intro.is-horizontal .intro__photo--left {
  left: calc(var(--col) / 2);
  translate: -50% calc(-50% - 3vh);
}

.intro.is-horizontal .intro__photo--right {
  right: calc(var(--col) / 2);
  translate: 50% calc(-50% + 3vh);
}

.intro.is-horizontal .intro__num {
  display: none;
}

/* Scenery framing the reading area: a floor across the bottom of the stage
 * and taller scenes in the columns either side of the text, never behind
 * it. intro.js moves it with the reader. */
.intro.is-horizontal .intro__scenery {
  display: block;
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  height: 52vh;
  opacity: .9;
  pointer-events: none;
  -webkit-mask-image:
    linear-gradient(180deg, transparent 40%, #000 60%),
    linear-gradient(90deg,
      #000 calc(50% - var(--read) / 2 - 8rem),
      transparent calc(50% - var(--read) / 2 - 1.5rem),
      transparent calc(50% + var(--read) / 2 + 1.5rem),
      #000 calc(50% + var(--read) / 2 + 8rem));
  mask-image:
    linear-gradient(180deg, transparent 40%, #000 60%),
    linear-gradient(90deg,
      #000 calc(50% - var(--read) / 2 - 8rem),
      transparent calc(50% - var(--read) / 2 - 1.5rem),
      transparent calc(50% + var(--read) / 2 + 1.5rem),
      #000 calc(50% + var(--read) / 2 + 8rem));
}

/* -- Five goals ---------------------------------------------------------------
 * A vertical sequence on the shared background. On wide screens the page-edge
 * village shows in the columns either side, so the text keeps to the plain
 * centre; narrow screens get a strip below instead. goals.js adds .is-armed:
 * each goal then waits to fade up into view, and stays once it has; the
 * number of the goal in focus turns from sage to CropNow green.
 */

.goals {
  --goals-w: min(52rem, 100vw - 2 * var(--gutter));
  position: relative;
  padding-block: clamp(5rem, 16vh, 10rem) clamp(4rem, 14vh, 9rem);
}

/* The same conditions that show the page-edge village (site.css). */
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .goals {
    --goals-w: min(52rem, 100vw - 26rem);
    padding-bottom: clamp(8rem, 30vh, 16rem);
  }
}

.goals__head {
  width: var(--goals-w);
  margin: 0 auto clamp(3.5rem, 11vh, 7rem);
}

.goals__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 1.2rem + 3.4vw, 4.6rem);
  font-weight: 900;
  line-height: .98;
  letter-spacing: -.004em;
  text-wrap: balance;
}

.goals__lede {
  max-width: 36rem;
  margin: clamp(1rem, 2.4vh, 1.5rem) 0 0;
  color: var(--forest);
  font-size: clamp(1.05rem, .9rem + .45vw, 1.35rem);
  line-height: 1.55;
  text-wrap: pretty;
}

.goals__list {
  container-type: inline-size;
  display: grid;
  gap: clamp(3.5rem, 12vh, 7.5rem);
  width: var(--goals-w);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.goal {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

/* Number and illustration: side by side above the text on narrow screens,
 * one above the other beside it once there is room. */
.goal__aside {
  display: flex;
  align-items: flex-end;
  gap: 1.25rem;
  margin-bottom: 1rem;
}

.goal__num {
  color: var(--sage);
  font-family: var(--font-display);
  font-size: clamp(4.5rem, 3rem + 6vw, 8rem);
  font-weight: 900;
  line-height: .8;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  transition: color .9s var(--ease);
}

.goal.is-focus .goal__num {
  color: var(--green);
}

.goal__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 1.15rem + 2vw, 3.1rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -.002em;
  text-wrap: balance;
}

.goal__text {
  max-width: 40rem;
  margin: clamp(.8rem, 2vh, 1.15rem) 0 0;
  font-size: clamp(1.02rem, .86rem + .45vw, 1.3rem);
  line-height: 1.65;
  letter-spacing: -.003em;
  text-wrap: pretty;
}

/* Number beside the text once there is room for both. */
@container (min-width: 34rem) {
  .goal {
    grid-template-columns: 9.5rem minmax(0, 1fr);
  }

  .goal__aside {
    display: block;
    margin: 0;
  }

  .goal .goal__visual {
    width: 7.5rem;
    margin-top: 1.25rem;
  }

  .goal__body {
    padding-top: .35rem;
  }
}

/* Revealed together, number, heading and paragraph. */
.goals.is-armed .goal {
  opacity: 0;
  transform: translate3d(0, 1.75rem, 0);
  transition: opacity 1.1s var(--ease), transform 1.2s var(--ease);
}

.goals.is-armed .goal.is-revealed {
  opacity: 1;
  transform: none;
}

/* Paused motion, or reduced motion by default: fade only, no rise. */
[data-motion="paused"] .goals.is-armed .goal {
  transform: none;
}

/* -- Goal illustrations -------------------------------------------------------
 * Pen lines in forest and CropNow green with sage, sun and clay fills, like
 * the village. When a goal is revealed its lines draw themselves in and its
 * fills fade up; while it is in focus its small loops run (the sun rises, the
 * water moves, warnings pulse, guidance arrives, the links flow). Out of focus
 * they hold still where they are. Paused motion shows them drawn and still.
 */

.goal__visual {
  display: block;
  flex: none;
  width: 5.25rem;
  aspect-ratio: 1;
  color: var(--forest);
}

.goal__visual svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.goal__visual .ln {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.goal__visual .ln--green { stroke: var(--green); }
.goal__visual .ln--soft { stroke: rgb(13 59 9 / .4); }
.goal__visual .ln--thin { stroke: rgb(13 59 9 / .5); stroke-width: 1.3; }
.goal__visual .fl-sun { fill: var(--sun); }
.goal__visual .fl-leaf { fill: rgb(66 146 62 / .55); }
.goal__visual .fl-water { fill: rgb(66 146 62 / .3); }
.goal__visual .fl-sage { fill: rgb(197 209 181 / .9); }
.goal__visual .fl-green { fill: var(--green); }
.goal__visual .fl-clay { fill: var(--clay); }
.goal__visual .fl-ink { fill: var(--forest); }

/* Drawn in on reveal (only when goals.js is running). */
.goals.is-armed .goal__visual .draw {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.8s var(--ease) .25s;
}

.goals.is-armed .goal.is-revealed .goal__visual .draw {
  stroke-dashoffset: 0;
}

.goals.is-armed .goal__visual .fade {
  transition: opacity 1s var(--ease) .9s;
}

.goals.is-armed .goal:not(.is-revealed) .goal__visual .fade {
  opacity: 0;
}

/* The water rises into the drop. */
.goal__visual .g-level {
  transition: transform 2.2s var(--ease) .5s;
}

.goals.is-armed .goal:not(.is-revealed) .goal__visual .g-level {
  transform: translateY(30px);
}

/* Guidance arrives one message at a time. */
.goal__visual .g-msg {
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}

.goal__visual .g-msg--1 { transition-delay: .9s; }
.goal__visual .g-msg--2 { transition-delay: 1.4s; }
.goal__visual .g-msg--3 { transition-delay: 1.9s; }

.goals.is-armed .goal:not(.is-revealed) .goal__visual .g-msg {
  opacity: 0;
  transform: translateY(5px);
}

/* Loops: running only while their goal is in focus. */
.goal__visual .g-sun { animation: goal-bob 5s ease-in-out infinite alternate; }

.goal__visual .g-sway {
  transform-origin: 66px 89px;
  animation: goal-sway 4.5s ease-in-out infinite alternate;
}

.goal__visual .g-wave { animation: goal-wave 3.2s linear infinite; }
.goal__visual .g-drip { animation: goal-drip 2.4s ease-in infinite; }

.goal__visual .g-pulse {
  transform-box: fill-box;
  transform-origin: center;
  vector-effect: non-scaling-stroke;
  animation: goal-pulse 3s ease-out infinite;
}

.goal__visual .g-pulse--2 { animation-delay: -1s; }
.goal__visual .g-pulse--3 { animation-delay: -2s; }
.goal__visual .g-alert { animation: goal-blink 1.6s ease-in-out infinite alternate; }
.goal__visual .g-msg--2 { animation: goal-bob 2.4s ease-in-out infinite alternate; }

.goal__visual .g-link {
  stroke-dasharray: 2 4;
  animation: goal-flow 1.6s linear infinite;
}

.goal:not(.is-focus) .goal__visual * {
  animation-play-state: paused;
}

[data-motion="paused"] .goal__visual * {
  animation: none !important;
}

[data-motion="paused"] .goals.is-armed .goal__visual .draw {
  stroke-dashoffset: 0;
  transition: none;
}

@keyframes goal-bob {
  to { transform: translateY(-3px); }
}

@keyframes goal-sway {
  from { transform: rotate(-4deg); }
  to { transform: rotate(4deg); }
}

@keyframes goal-wave {
  to { transform: translateX(60px); }
}

@keyframes goal-drip {
  from { transform: translateY(0); opacity: 1; }
  to { transform: translateY(14px); opacity: 0; }
}

@keyframes goal-pulse {
  from { transform: scale(1); opacity: .75; }
  to { transform: scale(3.2); opacity: 0; }
}

@keyframes goal-blink {
  from { opacity: .35; }
  to { opacity: 1; }
}

@keyframes goal-flow {
  to { stroke-dashoffset: -12; }
}

/* =============================================================================
 * The sections after the goals: How CropNow works, Our products, Impact and
 * initiatives, Get involved. Each has its own layout and its own movement;
 * they share the section heading, the call to action, the reveal and the
 * code-drawn illustrations (.art). Like the goals, their content keeps to the
 * plain centre while the page-edge village shows either side.
 * ========================================================================== */

.works,
.products,
.impact,
.involve {
  --sec-w: min(60rem, 100vw - 2 * var(--gutter));
  position: relative;
  padding-block: clamp(5rem, 15vh, 10rem);
}

@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .works,
  .products,
  .impact,
  .involve {
    --sec-w: min(60rem, 100vw - 26rem);
  }
}

.works__inner,
.products__inner,
.impact__inner,
.involve__inner {
  width: var(--sec-w);
  margin-inline: auto;
  container-type: inline-size;
}

/* -- Section heading: a small green label, then the line in the display face. */

.sec-eyebrow {
  display: flex;
  align-items: center;
  gap: .85rem;
  margin: 0;
  color: var(--green);
  font: 600 .8rem/1.2 var(--font-text);
  letter-spacing: .16em;
  text-transform: uppercase;
}

.sec-lead {
  margin: .9rem 0 0;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 1.2rem + 3.4vw, 4.6rem);
  font-weight: 900;
  line-height: .98;
  letter-spacing: -.004em;
  text-wrap: balance;
}

.sec-lead--big {
  font-size: clamp(2.8rem, 1.2rem + 4.6vw, 5.8rem);
}

.sec-intro {
  max-width: 40rem;
  margin: 1.25rem 0 0;
  color: var(--forest);
  font-size: clamp(1.05rem, .9rem + .45vw, 1.3rem);
  line-height: 1.6;
  text-wrap: pretty;
}

.sec-head--centre {
  text-align: center;
}

.sec-head--centre .sec-eyebrow {
  justify-content: center;
}

.works__text p,
.product__text p,
.impact__p,
.involve__text p {
  font-size: clamp(1.02rem, .88rem + .4vw, 1.22rem);
  line-height: 1.68;
  text-wrap: pretty;
}

/* -- Call to action: the words, and an arrow in a green circle that leads on. */

.cta {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  margin-top: 2.25rem;
  color: var(--forest);
  font: 600 1.05rem/1.2 var(--font-text);
  text-decoration: none;
  transition: color .3s var(--ease);
}

.cta__arrow {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--green);
  color: var(--chalk);
  font-size: 1.1rem;
  transition: transform .4s var(--ease);
}

.cta:hover {
  color: var(--green);
}

.cta:hover .cta__arrow,
.cta:focus-visible .cta__arrow {
  transform: translateX(.4rem);
}

.cta--solid {
  margin: 0;
  padding: .7rem .7rem .7rem 1.7rem;
  border-radius: 999px;
  background: var(--forest);
  color: var(--chalk);
  font-size: clamp(1.05rem, .95rem + .3vw, 1.25rem);
  transition: background-color .3s var(--ease);
}

.cta--solid:hover {
  background: #0a2e07;
  color: var(--chalk);
}

/* -- Reveal: parts ease up into view once (home-sections.js arms them). ----- */

[data-reveal].is-armed {
  transition: opacity 1s var(--ease), transform 1.1s var(--ease);
}

[data-reveal].is-armed:not(.is-in) {
  opacity: 0;
  transform: translateY(1.75rem);
}

[data-motion="paused"] [data-reveal].is-armed:not(.is-in) {
  transform: none;
}

/* -- Code-drawn illustrations (templates/website/home/) ------------------------
 * Isometric scenes in the site's palette: sage ground, forest lines, CropNow
 * green for what is alive or active, clay and sun for warmth.
 */

.art svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.art .ln { fill: none; stroke: var(--forest); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.art .ln--green { stroke: var(--green); }
.art .ln--thin { stroke: rgb(13 59 9 / .5); stroke-width: 1; }
.art .ln--thick { stroke-width: 2.8; }
.art .ln--soft { stroke: rgb(13 59 9 / .3); }
.art .ln--chalk { stroke: var(--chalk); stroke-width: 2; }
.art .ln--forest { stroke: var(--forest); stroke-width: 1.4; }
.art .ln--crop { stroke: var(--green); stroke-width: 2.6; stroke-dasharray: 2 7; }
.art .ln--data { stroke: var(--green); stroke-width: 2; }
.art .ln--track { stroke: rgb(13 59 9 / .22); stroke-dasharray: 6 6; }
.art .ln--orbit { stroke: rgb(13 59 9 / .28); stroke-dasharray: 3 6; }
.art .ln--earth { stroke: rgb(13 59 9 / .3); stroke-width: 1.2; }
.art .ln--link { stroke: var(--green); stroke-width: 2; stroke-dasharray: 5 6; animation: art-flow 1.2s linear infinite; }

.art .fc-top { fill: #e1e9d6; }
.art .fc-top-pale { fill: #eef2e8; }
.art .fc-left { fill: #c5d1b5; }
.art .fc-right { fill: #adbf9b; }
.art .fc-field { fill: #dce6cf; }
.art .fc-panel { fill: #23412b; }
.art .fc-box { fill: var(--chalk); stroke: var(--forest); stroke-width: 1.4; }
.art .fc-box-side { fill: #dde5d3; stroke: var(--forest); stroke-width: 1.4; stroke-linejoin: round; }
.art .fc-box-top { fill: #eef2e8; stroke: var(--forest); stroke-width: 1.4; stroke-linejoin: round; }
.art .fc-wall-left { fill: #ead9c4; }
.art .fc-wall-right { fill: #f6eee3; }
.art .fc-wall-top { fill: #f6eee3; }
.art .fc-roof-left { fill: #9b583b; }
.art .fc-roof-right { fill: var(--clay); }
.art .fc-shirt { fill: var(--green); }
.art .fc-disk-top { fill: #eef2e8; stroke: var(--forest); stroke-width: 1.4; }
.art .fc-disk-side { fill: #c5d1b5; stroke: var(--forest); stroke-width: 1.4; }
.art .fc-bubble-green { fill: var(--green); }
.art .fc-bubble-clay { fill: var(--clay); }
.art .fc-wheel { fill: #23412b; }
.art .fc-hub-ring { fill: #3b5a43; }
.art .ln--spoke { stroke: #c5d1b5; stroke-width: 1.6; }
.art .fc-screen-frame { fill: #23412b; }
.art .fc-screen { fill: #f3f6ef; }
.art .fc-node-green { fill: var(--green); }
.art .fc-node-sage { fill: #8fa67a; }
.art .fc-sky { fill: #f3e3b8; }
.art .fc-earth { fill: #c98e6e; }
.art .fc-dot { fill: #b3322a; }
.art .fc-hub { fill: #e1e9d6; }
.art .fl-green { fill: var(--green); }
.art .fl-leaf { fill: rgb(66 146 62 / .6); }
.art .fl-sage { fill: #dce6cf; }
.art .fl-sun { fill: var(--sun); }
.art .fl-ink { fill: var(--forest); }
.art .fl-chalk { fill: var(--chalk); }

.art .art-num { fill: rgb(13 59 9 / .5); font: 600 12px var(--font-text); letter-spacing: .14em; }
.art .art-label { fill: var(--chalk); font: 700 8.5px var(--font-text); letter-spacing: .06em; text-anchor: middle; }

/* Small loops that bring the scenes to life. */
.art .g-spin { animation: art-spin 1.3s linear infinite; }
.art .g-led { animation: art-blink 1.8s ease-in-out infinite alternate; }
.art .arc { opacity: 0; animation: art-signal 2.4s ease-out infinite; }
.art .arc--2 { animation-delay: .3s; }
.art .arc--3 { animation-delay: .6s; }
.art .g-drive { animation: art-drive 6s ease-in-out infinite alternate; }
.art .g-spokes { animation: art-roll 1.1s linear infinite; }
.art .g-tile { animation: art-bob 3s ease-in-out infinite alternate; }
.art .g-tile--2 { animation-delay: -1.5s; }
.art .g-bubble { animation: art-bob 2.6s ease-in-out infinite alternate; }
.art .g-bubble--2 { animation-delay: -1.3s; }
.art .g-sway { animation: goal-sway 4.5s ease-in-out infinite alternate; }
.art .g-rise { animation: art-rise 7s ease-in-out infinite alternate; }

[data-motion="paused"] .art *,
[data-motion="paused"] .products__stage {
  animation: none !important;
}

@keyframes art-flow { to { stroke-dashoffset: -22; } }
@keyframes art-spin { 50% { transform: scaleX(-1); } }
@keyframes art-blink { from { opacity: .35; } to { opacity: 1; } }
@keyframes art-signal { 30% { opacity: 1; } 100% { opacity: 0; } }
@keyframes art-drive { from { transform: translate(-18px, 10.4px); } to { transform: translate(18px, -10.4px); } }
@keyframes art-roll { to { transform: rotate(360deg); } }
@keyframes art-bob { to { transform: translateY(-4px); } }
@keyframes art-rise { from { transform: translateY(14px); } to { transform: translateY(-2px); } }
@keyframes art-ripple { from { transform: scale(1); opacity: .6; } to { transform: scale(1.9); opacity: 0; } }

/* -- How CropNow works ------------------------------------------------------- */

.works__grid {
  display: grid;
  gap: 2.5rem;
  margin-top: clamp(2.5rem, 6vh, 4rem);
}

@container (min-width: 46rem) {
  .works__grid {
    grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
    align-items: center;
    gap: clamp(2.5rem, 5cqi, 4rem);
  }
}

.works__text p {
  margin: 0 0 1.1rem;
}

/* The text comes in from the left and the diagram rises. */
.works__text.is-armed:not(.is-in) {
  transform: translateX(-1.75rem);
}

/* Sentences light up with their step, like a highlighter. */
.works__sentence[data-step] {
  background: linear-gradient(transparent 60%, rgb(66 146 62 / .24) 0) no-repeat 0 0 / 0% 100%;
  transition: background-size .9s var(--ease);
}

.works:not(.is-stepped) .works__sentence[data-step],
.works[data-active="observe"] .works__sentence[data-step="observe"],
.works[data-active="repository"] .works__sentence[data-step="repository"],
.works[data-active="act"] .works__sentence[data-step="act"] {
  background-size: 100% 100%;
}

/* In the diagram the parts not in focus step back; the one in focus lifts. */
.works [data-part] {
  transition: opacity .6s var(--ease), transform .7s var(--ease);
}

.works.is-stepped [data-part] {
  opacity: .4;
}

.works[data-active="observe"] [data-part="observe"],
.works[data-active="repository"] [data-part="repository"],
.works[data-active="act"] [data-part="act"] {
  opacity: 1;
  transform: translateY(-7px);
}

.works__steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(.75rem, 2cqi, 1.5rem);
  margin-top: 1.5rem;
}

.works__step {
  position: relative;
  display: block;
  padding: 1rem 0 .25rem;
  border: 0;
  background: none;
  color: rgb(13 59 9 / .55);
  text-align: left;
  cursor: pointer;
  transition: color .4s var(--ease);
}

.works__step:hover,
.works__step[aria-pressed="true"] {
  color: var(--forest);
}

.works__step-num {
  display: block;
  font: 600 .75rem/1 var(--font-text);
  letter-spacing: .16em;
}

.works__step[aria-pressed="true"] .works__step-num {
  color: var(--green);
}

.works__step-label {
  display: block;
  margin-top: .4rem;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, .9rem + .7vw, 1.5rem);
  font-weight: 900;
  line-height: 1;
}

/* A line above each step that fills while it is on; it fills over the
 * time a step stays when the steps take turns by themselves. */
.works__step-bar {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 3px;
  border-radius: 3px;
  background: rgb(197 209 181 / .8);
  overflow: hidden;
}

.works__step-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--green);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s var(--ease);
}

.works__step[aria-pressed="true"] .works__step-bar::after {
  transform: scaleX(1);
}

.works.is-auto .works__step[aria-pressed="true"] .works__step-bar::after {
  transition: transform 4.5s linear;
}

/* -- Our products --------------------------------------------------------------- */

.products__show {
  display: grid;
  gap: 3rem;
  margin-top: clamp(2.5rem, 6vh, 4rem);
}

.products__stage {
  display: none;
}

.product__art {
  max-width: 26rem;
  margin: 0 auto 1rem;
}

.product__name {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .2rem .9rem;
}

.product__pick {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1.6rem + 3vw, 4.4rem);
  font-weight: 900;
  line-height: .95;
  cursor: pointer;
  transition: color .4s var(--ease);
}

/* The tagline on its own line under the name (no dash between them). */
.product__tagline {
  display: block;
  margin-top: .3rem;
  color: var(--forest);
  font: 600 clamp(.95rem, .85rem + .3vw, 1.1rem)/1.3 var(--font-text);
  transition: color .4s var(--ease);
}

.product__text p {
  margin: .75rem 0 0;
}

.product.is-active .product__pick,
.product.is-active .product__tagline {
  color: var(--green);
}

/* Items slide in from the right; keep that inside the page. */
.products {
  overflow-x: clip;
}

.product__text.is-armed:not(.is-in) {
  transform: translateX(1.75rem);
}

/* Wide: one stage on the left for the product in focus, the three products
 * on the right. The stage is a slowly changing organic platform. */
@container (min-width: 46rem) {
  .products__show {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    grid-template-rows: repeat(3, auto);
    column-gap: clamp(2.5rem, 5cqi, 4.5rem);
    row-gap: 2.75rem;
    align-items: center;
  }

  .product {
    display: contents;
  }

  .products__stage,
  .product__art {
    position: sticky;
    top: max(5rem, 50vh - 14rem);
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: start;
  }

  .products__stage {
    display: block;
    justify-self: center;
    width: 94%;
    aspect-ratio: 1.12;
    border-radius: 46% 54% 58% 42% / 52% 46% 54% 48%;
    background: radial-gradient(closest-side, rgb(197 209 181 / .75), rgb(197 209 181 / .3) 75%, rgb(197 209 181 / 0));
    animation: stage-morph 16s ease-in-out infinite alternate;
  }

  .product__art {
    width: 100%;
    max-width: none;
    margin: 0;
    transition: opacity .7s var(--ease), transform .9s var(--ease);
  }

  .product:not(.is-active) .product__art {
    opacity: 0;
    transform: translateY(1.75rem) scale(.96);
    pointer-events: none;
  }

  .product__text {
    grid-column: 2;
    grid-row: var(--row);
  }

  .product:not(.is-active) .product__pick {
    color: rgb(13 59 9 / .45);
  }

  .product__pick:hover {
    color: var(--forest);
  }
}

@keyframes stage-morph {
  to { border-radius: 58% 42% 44% 56% / 44% 58% 42% 56%; transform: rotate(6deg); }
}

/* -- Impact and initiatives -------------------------------------------------- */

/* The rings draw outwards as --p (set while scrolling) goes from 0 to 1. */
.impact__rings {
  --p: 1;
  max-width: 50rem;
  margin: clamp(2rem, 5vh, 3.5rem) auto 0;
}

.art .ring {
  fill: none;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 1 1;
}

.art .ring--1 { stroke: var(--green); stroke-dashoffset: calc(1 - clamp(0, var(--p) * 3, 1)); }
.art .ring--2 { stroke: rgb(13 59 9 / .65); stroke-dashoffset: calc(1 - clamp(0, var(--p) * 3 - 1, 1)); }
.art .ring--3 { stroke: #8fa67a; stroke-dashoffset: calc(1 - clamp(0, var(--p) * 3 - 2, 1)); }
.art .ring-dot--1 { fill: var(--green); opacity: clamp(0, var(--p) * 3, 1); }
.art .ring-dot--2 { fill: var(--forest); opacity: clamp(0, var(--p) * 3 - 1, 1); }
.art .ring-dot--3 { fill: #8fa67a; opacity: clamp(0, var(--p) * 3 - 2, 1); }

.art .ring-label {
  fill: var(--forest);
  font: 600 15px var(--font-text);
  letter-spacing: .01em;
  text-anchor: middle;
}

.art .ring-label--1 { opacity: clamp(0, (var(--p) * 3 - .5) * 2, 1); }
.art .ring-label--2 { opacity: clamp(0, (var(--p) * 3 - 1.5) * 2, 1); }
.art .ring-label--3 { opacity: clamp(0, (var(--p) * 3 - 2.5) * 2, 1); }

/* A ripple keeps leaving the field. */
.art .ring-pulse {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  transform-origin: 320px 312px;
  animation: ring-pulse 4.5s ease-out infinite;
}

@keyframes ring-pulse {
  from { transform: scale(1); opacity: .55; }
  to { transform: scale(4.2); opacity: 0; }
}

.impact__grid {
  display: grid;
  gap: 1.5rem 3.5rem;
  margin-top: clamp(2rem, 5vh, 3rem);
}

.impact__p {
  margin: 0;
}

@container (min-width: 46rem) {
  .impact__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "first initiatives"
      "last initiatives";
    align-items: start;
  }

  .impact__p--first { grid-area: first; }
  .impact__p--last { grid-area: last; }
  .impact__initiatives { grid-area: initiatives; }
}

.impact__inner > .cta {
  display: flex;
  width: max-content;
  margin-inline: auto;
}

.initiatives {
  display: flex;
  gap: clamp(1.5rem, 4cqi, 3rem);
  margin-bottom: 1.25rem;
}

.initiative {
  width: clamp(6.5rem, 14cqi, 8.5rem);
  margin: 0;
  text-align: center;
}

.initiative figcaption {
  margin-top: .6rem;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 900;
  line-height: 1;
}

.art .dot-ripple {
  fill: none;
  stroke: #b3322a;
  stroke-width: 1.5;
  transform-box: fill-box;
  transform-origin: center;
  animation: art-ripple 3s ease-out infinite;
}

.art .dot-ripple--2 {
  animation-delay: -1.5s;
}

/* -- Get involved ------------------------------------------------------------------ */

.involve__network {
  max-width: 48rem;
  margin: clamp(1.5rem, 4vh, 3rem) auto 0;
}

.art .person__link {
  stroke: rgb(13 59 9 / .28);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-dasharray: 1 1;
  transition: stroke .3s var(--ease), stroke-width .3s var(--ease);
}

.art .person__dot {
  fill: var(--green);
  transition: transform .3s var(--ease);
  transform-box: fill-box;
  transform-origin: center;
}

.art .person__name {
  fill: var(--forest);
  font: 600 16px var(--font-text);
  animation: art-float 5s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -.8s);
  transition: fill .3s var(--ease);
}

.art .person {
  cursor: default;
}

.art .person:hover .person__link {
  stroke: var(--green);
  stroke-width: 2.4;
}

.art .person:hover .person__name {
  fill: var(--green);
}

.art .person:hover .person__dot {
  transform: scale(1.6);
}

@keyframes art-float {
  from { transform: translateY(-3px); }
  to { transform: translateY(3px); }
}

/* The links draw out to each person in turn, and the names follow. */
.involve__network.is-armed .person__link {
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1s var(--ease), stroke .3s var(--ease), stroke-width .3s var(--ease);
  transition-delay: calc(var(--i) * .12s + .3s), 0s, 0s;
}

.involve__network.is-armed .person__name,
.involve__network.is-armed .person__dot {
  opacity: 0;
  transition: opacity .7s var(--ease) calc(var(--i) * .12s + .8s), fill .3s var(--ease), transform .3s var(--ease);
}

.involve__network.is-in .person__link {
  stroke-dashoffset: 0;
}

.involve__network.is-in .person__name,
.involve__network.is-in .person__dot {
  opacity: 1;
}

.involve__network.is-armed:not(.is-in) {
  transform: none;
}

.involve__text {
  display: grid;
  gap: 1rem 2.5rem;
  max-width: 40rem;
  margin: clamp(1.5rem, 4vh, 2.5rem) auto 0;
}

.involve__text p {
  margin: 0;
}

@container (min-width: 52rem) {
  .involve__text {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    max-width: none;
  }
}

.involve__action {
  display: flex;
  justify-content: center;
  margin-top: clamp(2.5rem, 6vh, 4rem);
}

.involve .band--bottom {
  margin-top: clamp(3rem, 8vh, 5rem);
}

/* On narrow screens the drawings shrink, so their words grow to stay readable. */
@container (max-width: 34rem) {
  .art .ring-label {
    font-size: 24px;
  }

  .art .person__name {
    font-size: 22px;
  }
}


/* A way to the Gallery, after the introduction. */
.gallery-link {
  display: flex;
  justify-content: center;
  margin: clamp(1.5rem, 5vh, 3rem) auto 0;
  padding-inline: var(--gutter);
}

.gallery-link .cta {
  margin-top: 0;
}
