@import url("tokens.css");

/* ==========================================================================
   1. Base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--ge-header-h) + 16px); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
body {
  margin: 0; background: var(--ge-paper); color: var(--ge-ink-2);
  font: 400 17px/1.62 var(--ge-body);
  -webkit-font-smoothing: antialiased; overflow-x: clip;
}
img, svg, video, iframe { display: block; max-width: 100%; }
img { height: auto; }
a { color: var(--ge-link); text-underline-offset: .18em; }
a:hover { color: var(--ge-green-800); }
:focus-visible { outline: 3px solid var(--ge-lime); outline-offset: 2px; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

/* ==========================================================================
   2. Headings — condensed, heavy, set in caps.
   The first draft set sentence-case Barlow at weight 600 and read as a default.
   ========================================================================== */
h1, h2, h3, h4 {
  margin: 0 0 .42em; color: var(--ge-ink);
  font-family: var(--ge-head); font-weight: 600; line-height: 1.02;
  letter-spacing: .005em; text-transform: uppercase; text-wrap: balance;
}
.ge-h1 { font-size: clamp(2.7rem, 5.4vw, 4.6rem); line-height: .96; }
.ge-h2 { font-size: clamp(2.1rem, 3.5vw, 3.15rem); }
.ge-h3 { font-size: clamp(1.28rem, 1.5vw, 1.55rem); letter-spacing: .012em; }
.ge-h4 { font-size: 1.12rem; letter-spacing: .02em; }
/* Body copy must never inherit the caps. */
.ge-lead, p, li, dd, figcaption { text-transform: none; }
.ge-lead { font-size: clamp(1.02rem, .38vw + .95rem, 1.16rem); color: var(--ge-ink-2); line-height: 1.6; }

.ge-sr {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.ge-skip {
  position: absolute; left: 12px; top: -60px; z-index: 300;
  background: var(--ge-green-600); color: #fff; padding: 12px 20px; border-radius: var(--ge-r);
  font-weight: 700; transition: top .18s var(--ge-ease);
}
.ge-skip:focus { top: 12px; color: #fff; }

/* ==========================================================================
   3. Layout + bands
   ========================================================================== */
.ge-wrap { width: 100%; max-width: var(--ge-wrap); margin-inline: auto; padding-inline: var(--ge-gut); }
.ge-band { padding-block: var(--ge-band); position: relative; }
.ge-band--paper { background: var(--ge-paper); }
.ge-band--white { background: var(--ge-white); }
.ge-band--mist  { background: var(--ge-paper-2); }
.ge-band--green { background: var(--ge-green-800); color: #dcecd6; }
.ge-band--deep  { background: var(--ge-green-950); color: #cfe3c8; }
.ge-band--tight { padding-block: clamp(30px, 3.2vw, 48px); }
.ge-band--flush { padding-block: 0; }
.ge-band--green h1, .ge-band--green h2, .ge-band--green h3, .ge-band--green h4,
.ge-band--deep h1, .ge-band--deep h2, .ge-band--deep h3, .ge-band--deep h4 { color: #fff; }
.ge-band--green .ge-lead, .ge-band--deep .ge-lead { color: #bdd6b4; }
.ge-band--green a, .ge-band--deep a { color: var(--ge-green-300); }
.ge-band > .ge-wrap { position: relative; z-index: 2; }

/* ==========================================================================
   4. Section headings.

   THERE IS NO SECTION LABEL. Round 2 opened every band with a small uppercase
   eyebrow in a solid block ("Start here", "Common questions", "Industries we
   serve"). The operator removed all nine on 2026-09-30: an eyebrow over every
   heading is one of the loudest generated-page tells, and reading them in a
   column made the page sound like a template. Headings carry their own weight.
   ge_head() still takes a $label argument and deliberately ignores it, so the
   pattern cannot creep back in through the page templates.
   ========================================================================== */

/* Section heading: title left, lead right. Fills the width instead of leaving
   half the band empty under a centred paragraph. */
.ge-head { margin-bottom: clamp(26px, 3vw, 44px); }
.ge-head--split {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 56px); align-items: end;
}
.ge-head--split > :first-child { min-width: 0; }
.ge-head--split .ge-lead { padding-bottom: .4em; }
@media (max-width: 860px) { .ge-head--split { grid-template-columns: 1fr; align-items: start; } }
.ge-head h2, .ge-head h3 { margin-bottom: 0; }

/* ==========================================================================
   5. The diagonal — Greer's own device, taken from their hero
   ========================================================================== */
.ge-cut { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 1; }
/* Translucent, like Greer's own: you can see the yard through the green. The
   first pass was 93% opaque and simply hid the film behind it. */
.ge-cut::before {
  content: ""; position: absolute; inset: -10% -2%;
  background: linear-gradient(115deg, rgba(20,56,15,.94) 0%, rgba(27,74,20,.88) 55%, rgba(39,96,29,.74) 100%);
  clip-path: polygon(0 0, 58% 0, 42% 100%, 0 100%);
}
.ge-cut::after {
  content: ""; position: absolute; inset: -10% -2%;
  background: var(--ge-lime);
  clip-path: polygon(58% 0, 59.2% 0, 43.2% 100%, 42% 100%);
}
/* The homepage hero keeps the old narrow-width sweep: its content is one
   left-aligned column over a video, so a band across the lower half has
   nothing to collide with. */
@media (max-width: 900px) {
  .ge-hero .ge-cut::before { clip-path: polygon(0 0, 100% 0, 100% 64%, 0 88%); opacity: .95; }
  .ge-hero .ge-cut::after  { clip-path: polygon(0 88%, 100% 64%, 100% 65.6%, 0 89.6%); }
}

/* THE FAMILY HEROES CANNOT KEEP THE STEEP DIAGONAL BELOW ~1240px.
   Those heroes are a text column plus an aside, and the diagonal was designed
   to pass through the gap between them. The gap closes as the viewport
   narrows: at 1100 it is about four per cent of the width, far less than a
   slanted band needs, so the lime stripe was crossing the lead copy, the codes
   card and — worst — the city locator, where it ran straight over the dashed
   line between the city and its dispatch office. At 960 it cut through the
   paragraph itself.
   Below 1240 it therefore moves out of the columns entirely and becomes a band
   across the foot of the hero, in padding added for it, so it is under the
   content rather than over it. */
@media (max-width: 1240px) {
  /* The pseudo-element is inset -10%, so its box is 120% of the hero and a
     clip-path percentage here is (hero% + 10) / 1.2. The band has to clear the
     locator map, whose foot sits near 86% of the hero, AND the reach caption
     under it — the first attempt put the lime stripe straight through both. */
  .ge-phero { padding-bottom: calc(clamp(44px, 6vw, 84px) + 104px); }
  .ge-phero .ge-cut::before { clip-path: polygon(0 100%, 100% 100%, 100% 85%, 0 93%); }
  .ge-phero .ge-cut::after  { clip-path: polygon(0 93%, 100% 85%, 100% 86.3%, 0 94.3%); }
}
/* A standalone diagonal rule, for band seams. */
.ge-seam { height: 6px; background: linear-gradient(100deg, var(--ge-lime) 0 38%, var(--ge-gold-500) 38% 100%); }

/* ==========================================================================
   6. Buttons
   ========================================================================== */
.ge-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--ge-head); font-weight: 500; font-size: 1.02rem;
  letter-spacing: .06em; text-transform: uppercase; text-decoration: none; cursor: pointer;
  padding: 13px 24px; border-radius: var(--ge-r); border: 2px solid transparent; line-height: 1.2;
  transition: background .18s var(--ge-ease), border-color .18s var(--ge-ease), color .18s var(--ge-ease), transform .18s var(--ge-ease), box-shadow .18s var(--ge-ease);
}
.ge-btn:hover { transform: translateY(-2px); }
.ge-btn:active { transform: none; }
.ge-btn .ge-icon { width: 19px; height: 19px; }
.ge-btn--go { background: var(--ge-green-600); color: #fff; box-shadow: var(--ge-shadow); }
.ge-btn--go:hover { background: var(--ge-green-700); color: #fff; box-shadow: var(--ge-shadow-lg); }
.ge-btn--gold { background: var(--ge-gold-500); color: var(--ge-green-950); }
.ge-btn--gold:hover { background: var(--ge-gold-400); color: var(--ge-green-950); }
.ge-btn--light { background: #fff; color: var(--ge-green-800); }
.ge-btn--light:hover { background: var(--ge-green-100); color: var(--ge-green-800); }
.ge-btn--ghost { border-color: currentColor; color: inherit; background: transparent; }
.ge-band--green .ge-btn--ghost, .ge-band--deep .ge-btn--ghost { color: #fff; }
.ge-btn--ghost:hover { background: rgba(255,255,255,.14); }
.ge-band--paper .ge-btn--ghost:hover, .ge-band--white .ge-btn--ghost:hover { background: rgba(23,32,15,.06); }
.ge-btn--sm { font-size: .92rem; padding: 10px 17px; }
.ge-btn--block { width: 100%; }
.ge-btns { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

.ge-more {
  display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
  font-family: var(--ge-head); font-weight: 500; font-size: .95rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ge-link);
}
.ge-more .ge-icon { width: 17px; height: 17px; transition: transform .18s var(--ge-ease); }
.ge-more:hover .ge-icon { transform: translateX(4px); }
.ge-band--green .ge-more, .ge-band--deep .ge-more { color: var(--ge-green-300); }

/* ==========================================================================
   7. Icons
   ========================================================================== */
.ge-icon { width: 24px; height: 24px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* A filled circular icon badge, the way the reference build marks a section. */
.ge-badge {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: var(--ge-green-600); color: #fff; flex: none;
}
.ge-badge .ge-icon { width: 23px; height: 23px; stroke-width: 1.8; }
.ge-badge--gold { background: var(--ge-gold-500); color: var(--ge-green-950); }
.ge-badge--light { background: #fff; color: var(--ge-green-700); }

/* ==========================================================================
   8. The motif
   ========================================================================== */
.ge-mark { display: block; flex: none; }
.ge-mark .ge-mark__oval { fill: var(--ge-gold-500); }
.ge-mark .ge-mark__leaf { fill: var(--ge-green-500); }
.ge-mark--mono .ge-mark__oval { fill: currentColor; opacity: .3; }
.ge-mark--mono .ge-mark__leaf { fill: currentColor; }
.ge-watermark {
  position: absolute; top: 50%; right: -4%; translate: 0 -50%;
  width: min(40vw, 520px); opacity: .06; pointer-events: none; z-index: 0;
}

/* ==========================================================================
   9. Reveal on scroll — the same mechanism as the BioMed build.

   Three rules this has to obey, and the reason each one exists:

   1. NOTHING IS HIDDEN UNLESS JAVASCRIPT RUNS. The hiding is scoped to
      .ge-js, a class site.js puts on <html> itself. Ship it the other way
      round and a JS error, a blocked bundle or a crawler leaves the whole
      page invisible.
   2. NOTHING ABOVE THE FOLD ANIMATES. The hero and the four promise cards
      that straddle it are on screen at load; fading them in delays the LCP
      for no gain. site.js skips them.
   3. prefers-reduced-motion TURNS IT ALL OFF, not just down.

   --d is a per-item stagger the script sets from the sibling index, capped so
   a 21-item grid does not end with a two-second wait.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .ge-js .ge-rv {
    opacity: 0; transform: translateY(24px);
    transition: opacity .62s var(--ge-ease), transform .62s cubic-bezier(.2, .7, .2, 1);
    transition-delay: var(--d, 0s);
  }
  .ge-js .ge-rv.is-in { opacity: 1; transform: none; }

  /* Bands that lead with a photograph get a slower, longer travel from the
     side the photo sits on, so a full-bleed split assembles instead of
     blinking. */
  .ge-js .ge-rv--left  { transform: translateX(-30px); }
  .ge-js .ge-rv--right { transform: translateX(30px); }
  .ge-js .ge-rv--left.is-in, .ge-js .ge-rv--right.is-in { transform: none; }

  /* The stats bar counts up from a flat line instead of sliding. */
  .ge-js .ge-rv--wipe { opacity: 0; transform: scaleY(.6); transform-origin: 50% 100%; }
  .ge-js .ge-rv--wipe.is-in { opacity: 1; transform: none; }
}
