/* =========================================================
   Section redesign — SUSTAINABILITY. See REDESIGN-BRIEF.md.

   Loads after pages.css so it can override the .tile/.g3 rules
   it replaces. Scoped to this page only; nothing here ships to
   the other six.

   The page carries `page--green` on <body>, which sets
   --page-accent / --page-accent-ink. Green is used here as a
   LINE and MARK colour — the loop stroke, the rail fills, the
   index numerals — never as a surface. Navy still carries every
   band. Tokens only; --rad stays 3px and is barely used, because
   almost nothing on this page is a rectangle any more.
   ========================================================= */

/* ---------------------------------------------------------
   0 · Two bands enter from the RIGHT — the loop's readable half
   and the value bento — because everything else on this page
   rises or comes from the left, and a page where all motion
   shares one vector is still a dead page.

   A rightward `from` offset on a full-width block widens the
   document until the tween lands, which at 375px is a visible
   horizontal scrollbar before the visitor has scrolled at all.
   The band absorbs it. `clip` where it exists (it does not turn
   the section into a scroll container); `hidden` as the fallback,
   safe here because neither band holds a sticky child.

   The four sections the client's content added in round 2 are
   deliberately NOT in this list: every one of their entrances is
   a vertical rise, so none of them can widen the document, and
   clipping a band costs more than it is worth when nothing needs
   clipping.
   --------------------------------------------------------- */

#loop, #value { overflow: hidden; }
@supports (overflow: clip) { #loop, #value { overflow: clip; } }

/* =========================================================
   0 · HERO — "daylight"

   `.phero` lives in the shared pages.css, which this page may
   not edit, so everything here overrides it from outside and is
   scoped to `.shero`.

   The composition: the photograph is a WALL OF LIGHT standing on
   the right edge — full height, no frame, its left side masked
   away so daylight bleeds into the navy instead of stopping at a
   border. The one drawn element is a green hairline that runs the
   full width of the viewport, through the type and on across the
   photograph, tying the two halves into one object.

   Green stays a LINE and a tint, never a surface and never a
   button, which is the rule the rest of this page already keeps.
   ========================================================= */

.shero {
  min-height: clamp(460px, 66vh, 640px);
  display: grid; align-content: center;
  /* Tighter than the shared hero at both ends. `.phero`'s padding was cut
     for a hero with nothing in it but type; this one has a wall of light
     doing half the work and does not need the air. */
  padding: calc(var(--nav-h) + clamp(2.2rem, 5.5vh, 3.8rem)) 0 clamp(2.4rem, 6vh, 4rem);
  isolation: isolate;
}

.shero__media {
  position: absolute; top: 0; bottom: 0; right: 0; width: 54%; margin: 0;
  overflow: hidden;
}

/* THE DISSOLVE IS A MASK, AND IT IS ON THE THREE PAINTED LAYERS RATHER
   THAN ON THE FIGURE.

   Painting navy over the left of the photo instead — which is what this
   did first — leaves a hard vertical seam at the figure's edge, because
   the hero's own `.phero__bg` carries a green bloom that the navy sheet
   covers on one side of the line and not the other. A mask does not
   paint anything: the background shows through unaltered and there is
   no edge to see.

   It is not on the <figure> because a mask on the figure would take the
   figcaption with it and leave the label sitting at whatever opacity the
   ramp happened to reach at that x.

   The ramp opens slowly on purpose. The h1 runs to roughly 43% of the
   viewport and the mask is under 6% there, which is what keeps green
   type on navy rather than green type on daylight. Verified at glyph
   pixels by _qc/herocontrast3.js. */
.shero__img, .shero__veil, .shero__wash {
  -webkit-mask-image: linear-gradient(90deg,
      transparent 0%, rgba(0,0,0,.06) 18%, rgba(0,0,0,.46) 40%, #000 62%);
          mask-image: linear-gradient(90deg,
      transparent 0%, rgba(0,0,0,.06) 18%, rgba(0,0,0,.46) 40%, #000 62%);
}

.shero__img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 46% 54%;
  /* A stop under `.ph--live`: this is the brightest photograph on the
     site and it is standing next to type. */
  filter: saturate(.94) brightness(.88) contrast(1.04);
}

.shero__veil {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(6,21,41,.55) 0%, rgba(6,21,41,0) 26%, rgba(6,21,41,.18) 66%, rgba(6,21,41,.88) 100%),
    linear-gradient(90deg,
      rgba(6,21,41,.55) 0%, rgba(6,21,41,.14) 46%, rgba(6,21,41,.10) 100%),
    radial-gradient(70% 62% at 64% 40%, rgba(30,122,76,.16) 0%, rgba(30,122,76,0) 66%);
}

/* The reveal, and the only thing on this hero that animates on load.
   It starts as a solid navy sheet and fades to nothing — the PHOTOGRAPH
   never moves and is never faded, because it is this page's LCP element
   and it is painted at full size on the first frame. Occlusion costs
   nothing; opacity on the largest paint costs seconds. */
.shero__wash {
  position: absolute; inset: 0; pointer-events: none;
  background: var(--navy-900); opacity: 0;
}

.shero__cap {
  position: absolute; z-index: 2;
  right: clamp(1rem, 2.4vw, 2rem); bottom: clamp(1.1rem, 3.2vh, 2rem);
  max-width: 26ch;
  padding: .45rem .75rem;
  font: 500 var(--fs-label)/1.5 var(--f-mono);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--steel);
  background: rgba(6,21,41,.9);
  border: 1px solid var(--rule-d);
  border-left: 1px solid var(--green-lt);
}

/* ---- the type, and the line through it ------------------ */

.shero__inner { display: grid; justify-items: start; }
.shero__top, .shero__body { max-width: min(100%, 46ch); }
.shero__body { max-width: min(100%, 48ch); }

/* The h1 is held clear of the daylight. pages.css caps it at 15ch, which
   at the top of the clamp is wide enough to reach the mask; 11ch keeps
   "Sustainability in Practice" over navy at every width. */
.shero__inner h1 { max-width: 11ch; }
.shero__inner .phero__sub { max-width: 24ch; }
.shero__inner .phero__lede { max-width: 46ch; margin-top: 0; }

/* Full bleed from inside a .wrap. `100vw` is wider than the wrap and
   would normally widen the document — .phero carries overflow:hidden, so
   the overhang is clipped and never reaches the scrollbar. Checked at
   375 → 1920 by _qc/responsive.js. */
.shero__rule {
  display: block; height: 1px; width: 100vw;
  margin: clamp(1.5rem, 3.6vh, 2.4rem) 0 clamp(1.4rem, 3.4vh, 2.2rem) calc(50% - 50vw);
  background: linear-gradient(90deg,
    rgba(78,201,138,0) 0%, rgba(78,201,138,.55) 4%, rgba(78,201,138,.55) 54%,
    rgba(78,201,138,.34) 78%, rgba(78,201,138,0) 99%);
  transform-origin: 0 50%;
}

@media (max-width: 1024px) {
  .shero__media { width: 62%; }
  .shero__inner h1 { max-width: 9ch; }
}

/* Below 820px the wall of light becomes a header band: the copy needs
   the full width, and a 62%-wide photo behind a 100%-wide paragraph is
   the one arrangement that would fail contrast. */
@media (max-width: 820px) {
  .shero { min-height: 0; }
  .shero__media {
    top: 0; bottom: auto; left: 0; right: 0; width: auto;
    height: clamp(170px, 30vh, 260px);
  }
  .shero__img { object-position: 50% 44%; }
  /* The same dissolve, turned through 90°: the band fades out at its foot
     so the copy below it starts on clean ground. */
  .shero__img, .shero__veil, .shero__wash {
    -webkit-mask-image: linear-gradient(180deg,
        #000 0%, rgba(0,0,0,.62) 58%, rgba(0,0,0,.16) 86%, transparent 100%);
            mask-image: linear-gradient(180deg,
        #000 0%, rgba(0,0,0,.62) 58%, rgba(0,0,0,.16) 86%, transparent 100%);
  }
  .shero__veil {
    background:
      linear-gradient(180deg,
        rgba(6,21,41,.44) 0%, rgba(6,21,41,.16) 30%, rgba(6,21,41,.46) 70%, rgba(6,21,41,.70) 100%),
      radial-gradient(80% 70% at 62% 34%, rgba(30,122,76,.16) 0%, rgba(30,122,76,0) 70%);
  }
  /* Top of the band, not the bottom: the bottom of the band is where the
     veil closes to solid navy and the label would disappear into it. */
  .shero__cap {
    top: calc(var(--nav-h) + .45rem); bottom: auto;
    left: var(--gutter); right: var(--gutter);
    max-width: none; text-align: right;
  }
  .shero__inner { padding-top: clamp(4.5rem, 15vh, 7rem); }
  .shero__inner h1, .shero__inner .phero__sub { max-width: none; }
}
@media (max-width: 560px) {
  .shero__cap { font-size: .66rem; letter-spacing: .08em; }
}

/* ---------------------------------------------------------
   1 · THE LOOP — archetype 8, the page's one moment.
   --------------------------------------------------------- */

.loop {
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.loop__viz { display: flex; justify-content: center; }

/* Square stage. Overflow stays visible so the ring's outboard
   stage names are not clipped; they are hidden below 1180px,
   where there is no longer room for them. */
.loop__stage {
  position: relative;
  width: 100%;
  max-width: 470px;
  aspect-ratio: 1;
}

.loop__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.loop__guide {
  fill: none; stroke: var(--rule-d);
  stroke-width: 1; stroke-dasharray: 2 9;
}
.loop__track { fill: none; stroke: var(--rule-d2); stroke-width: 1.5; }

/* The drawn arc. dasharray/dashoffset are written by
   js/sec-sustainability.js; the values here are 2πr for r=150,
   so the ring is empty before JS touches it and a no-JS visitor
   still sees a complete, sensible diagram (JS sets offset 0). */
.loop__arc {
  fill: none;
  stroke: url(#loopGrad);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 942.48;
  stroke-dashoffset: 942.48;
  transform: rotate(-90deg);
  transform-origin: 200px 200px;
}

/* The travelling glint — a short bright dash chasing the ring, so
   the loop reads as running rather than merely drawn. It is the
   only perpetual motion on the page and it is 4px of stroke. */
.loop__glint {
  fill: none;
  stroke: var(--green-lt);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 26 916.48;
  stroke-dashoffset: 0;
  transform: rotate(-90deg);
  transform-origin: 200px 200px;
  opacity: 0;
  animation: loopglint 11s linear infinite;
}
@keyframes loopglint {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -942.48; }
}
.loop.is-drawn .loop__glint { opacity: .9; }

.loop__ticks path { stroke: var(--rule-d2); stroke-width: 1; }

/* Centre: the loop's own subject at the centre of the loop. */
.loop__core {
  position: absolute; left: 50%; top: 50%;
  width: 44%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  padding: 6px;
  background: var(--navy-800);
  box-shadow: 0 0 0 1px var(--rule-d2);
}
.loop__photo {
  width: 100%; height: 100%;
  border-radius: 50%;
  /* The slot is a 175px circle and the photo is 16:9, so `cover` keeps only
     the middle ~56% of the frame. The hand doing the sorting sits at 67-95%
     across and would be cropped away by a centred crop -- and the hand is the
     reason the client sent this photograph. Pulled right to keep it. */
  background-position: 74% 50%;
}

/* Stage markers, positioned on the ring at 60° intervals. */
.loop__node {
  position: absolute; left: var(--x); top: var(--y);
  width: 34px; height: 34px;
  transform: translate(-50%, -50%) scale(.82);
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--navy-800);
  box-shadow: inset 0 0 0 1px var(--rule-d2);
  transition: box-shadow var(--d-s) var(--e-out), transform var(--d-s) var(--e-out),
              background-color var(--d-s) var(--e-out);
}
.loop__node i {
  font-style: normal;
  font-family: var(--f-mono); font-size: .62rem; letter-spacing: .06em;
  color: var(--steel-dim);
  transition: color var(--d-s) var(--e-out);
}
.loop__node em {
  position: absolute; left: 50%; top: 50%;
  font-style: normal; white-space: nowrap;
  font-family: var(--f-mono); font-size: var(--fs-label);
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--steel-dim);
  transform: var(--lt);
  transition: color var(--d-s) var(--e-out);
}

.loop__node.is-on {
  transform: translate(-50%, -50%) scale(1);
  background: var(--navy-700);
  box-shadow: inset 0 0 0 1px var(--green-lt), 0 0 0 4px rgba(78,201,138,.12);
}
.loop__node.is-on i  { color: var(--green-lt); }
.loop__node.is-on em { color: var(--chrome); }

/* Hover parity with the legend beside it — pointing at a stage in
   the list should light it on the ring, and vice versa. */
.loop__node.is-hot {
  transform: translate(-50%, -50%) scale(1.14);
  box-shadow: inset 0 0 0 1px var(--green-lt), 0 0 0 7px rgba(78,201,138,.18);
}

.loop__node--n0 { --x: 50%;     --y: 12.5%;  --lt: translate(-50%, calc(-50% - 30px)); }
.loop__node--n1 { --x: 82.48%;  --y: 31.25%; --lt: translate(26px, -50%); }
.loop__node--n2 { --x: 82.48%;  --y: 68.75%; --lt: translate(26px, -50%); }
.loop__node--n3 { --x: 50%;     --y: 87.5%;  --lt: translate(-50%, calc(-50% + 30px)); }
.loop__node--n4 { --x: 17.52%;  --y: 68.75%; --lt: translate(calc(-100% - 26px), -50%); }
.loop__node--n5 { --x: 17.52%;  --y: 31.25%; --lt: translate(calc(-100% - 26px), -50%); }

/* ---- the readable half ---- */

.loop__lede {
  font-family: var(--f-display); font-weight: 300;
  font-size: clamp(1.02rem, .92rem + .5vw, 1.32rem);
  line-height: 1.36; letter-spacing: -.01em;
  color: var(--white); max-width: 38ch; margin: 0 0 clamp(1.4rem, 3vh, 2rem);
}

.loop__legend { list-style: none; margin: 0; padding: 0; }
.loop__stagerow {
  position: relative;
  padding: .78rem 0 .78rem 3.1rem;
  border-top: 1px solid var(--rule-d);
}
.loop__stagerow:last-child { border-bottom: 1px solid var(--rule-d); }
.loop__ln {
  position: absolute; left: 0; top: .95rem;
  font-family: var(--f-mono); font-size: var(--fs-label); letter-spacing: .14em;
  color: var(--steel-dim);
  transition: color var(--d-s) var(--e-out);
}
.loop__stagerow h3 {
  font-family: var(--f-display); font-weight: 600; font-size: 1rem;
  letter-spacing: -.012em; color: var(--white); margin: 0 0 .12rem;
}
.loop__stagerow p { margin: 0; font-size: var(--fs-small); color: var(--steel); }

/* A hairline that fills from the left as the stage lights — the
   list's own version of the arc being drawn. */
.loop__stagerow::after {
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px;
  background: var(--green-lt);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform var(--d-m) var(--e-out);
}
.loop__stagerow.is-on::after { transform: scaleX(1); }
.loop__stagerow.is-on .loop__ln { color: var(--green-lt); }
.loop__stagerow.is-hot { background: rgba(78,201,138,.06); }

.loop__links {
  display: flex; flex-wrap: wrap; gap: 1.1rem 1.8rem;
  margin-top: clamp(1.3rem, 3vh, 1.9rem);
}
.loop__links .arrowlink { color: var(--green-lt); }

@media (max-width: 1180px) {
  .loop__node em { display: none; }
}
@media (max-width: 940px) {
  .loop { grid-template-columns: 1fr; gap: clamp(2rem, 5vh, 3rem); }
  .loop__stage { max-width: 360px; }
}
@media (max-width: 460px) {
  .loop__stage { max-width: 280px; }
  .loop__node { width: 28px; height: 28px; }
}

/* ---------------------------------------------------------
   2 · SHE COMMITMENT — the statement and the four undertakings.

   Round 2, item 5. Replaces nothing: this block did not exist
   before the client supplied it. Two halves — a statement on
   the left, a 2x2 field of ruled cells on the right — because
   the four undertakings answer the statement, and a stack would
   have read as five equal paragraphs.

   Green appears exactly twice here: the hairline over the
   statement and the four drawn marks. Everything else is navy
   and chrome, which is the page's standing rule.
   --------------------------------------------------------- */

.she__grid {
  display: grid;
  grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}

.she__lead .label { margin-bottom: clamp(1rem, 2.4vh, 1.5rem); }

.she__t {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.7rem, 1.15rem + 2.1vw, 3rem);
  line-height: 1.14;
  letter-spacing: -.024em;
  color: var(--chrome);
  text-wrap: balance;
}
/* The green line lives ABOVE the statement — a line, not a
   surface, and the only one in the band besides the four marks. */
.she__t::before {
  content: '';
  display: block;
  width: clamp(48px, 9vw, 116px);
  height: 2px;
  background: var(--green-lt);
  margin-bottom: clamp(1rem, 2.4vh, 1.6rem);
}
.she__lede {
  margin: clamp(1.2rem, 3vh, 1.9rem) 0 0;
  max-width: 44ch;
  color: var(--steel);
  font-size: var(--fs-body);
  line-height: 1.62;
}

.she__field {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(1.4rem, 3vw, 2.6rem);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Ruled, not boxed. Every cell draws its own top rule and the two
   in the right column draw a left one, so the field reads as a
   divided plane rather than as four cards. */
.she__cell {
  border-top: 1px solid var(--rule-d);
  padding: clamp(1.2rem, 2.8vh, 1.8rem) 0 clamp(1.4rem, 3vh, 2.1rem);
}
.she__cell:nth-child(2n) {
  padding-left: clamp(1.4rem, 3vw, 2.6rem);
  border-left: 1px solid var(--rule-d);
  margin-left: calc(-1 * clamp(1.4rem, 3vw, 2.6rem));
}

.she__mark {
  display: block;
  width: 30px; height: 30px;
  margin-bottom: clamp(.8rem, 1.8vh, 1.1rem);
  color: var(--green-lt);
}
.she__mark svg {
  width: 100%; height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.she__cell h3 {
  margin: 0 0 .5rem;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1rem, .95rem + .22vw, 1.14rem);
  letter-spacing: -.014em;
  line-height: 1.3;
  color: var(--white);
}
.she__cell p {
  margin: 0;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--steel);
  max-width: 40ch;
}

@media (max-width: 1000px) {
  .she__grid { grid-template-columns: 1fr; gap: clamp(1.8rem, 5vh, 2.8rem); }
  .she__lede { max-width: 60ch; }
}
@media (max-width: 600px) {
  .she__field { grid-template-columns: 1fr; }
  /* One column: the vertical rule has nothing to divide, and the
     negative margin that pulled the right column onto it would
     drag the cell out of the gutter. */
  .she__cell:nth-child(2n) { padding-left: 0; border-left: 0; margin-left: 0; }
}

/* ---------------------------------------------------------
   3 · SUSTAINABLE MANUFACTURING — the four-step ledger.

   Round 2, item 5. Replaces "Our Four Pillars". A horizontal
   green rail across the top with four marks on it, the fill
   scrubbed by js/sec-sustainability.js. The client's numbering
   is a sequence through the process, so it is set as an index
   and never reordered.

   Below 1080px the rail goes and each mark keeps its own ring —
   a rail across a two-row grid would only touch the first row.
   The same progress value still lights the marks, so there is no
   second code path to keep in step.
   --------------------------------------------------------- */

.smanu__head { max-width: 42ch; margin-bottom: clamp(2rem, 5vh, 3.4rem); }
.smanu__head .label { margin-bottom: clamp(.8rem, 2vh, 1.2rem); }
.smanu__t {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.5rem);
  line-height: 1.16;
  letter-spacing: -.022em;
  color: var(--ink);
  text-wrap: balance;
}

.smanu__ledger { position: relative; }

.smanu__rail {
  position: absolute;
  left: 0; right: 0; top: 5px;
  height: 2px;
  background: var(--rule-l2);
  overflow: hidden;
}
.smanu__fill {
  display: block;
  position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--green), var(--green-lt));
  transform: scaleX(var(--sp, 0));
  transform-origin: 0 50%;
}

.smanu__track {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.4rem, 3vw, 2.8rem);
  list-style: none;
  margin: 0;
  padding: 0;
}
.smanu__step { position: relative; padding-top: 2.4rem; }

/* The mark sits ON the rail: a ring that fills as the front
   reaches it — the same language the loop's ring markers and the
   Manufacturing schematic's stations both use. */
.smanu__dot {
  position: absolute;
  left: 0; top: 0;
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 2px solid var(--rule-l2);
  background: var(--paper);
  transition: border-color var(--d-s) var(--e-out), background-color var(--d-s) var(--e-out);
}
.smanu__step.is-on .smanu__dot { border-color: var(--green); background: var(--green); }

.smanu__no {
  display: block;
  font-family: var(--f-mono);
  font-size: var(--fs-label);
  letter-spacing: .16em;
  color: var(--slate);
  transition: color var(--d-s) var(--e-out);
}
.smanu__step.is-on .smanu__no { color: var(--green); }

.smanu__step h3 {
  margin: .6rem 0 .55rem;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.02rem, .95rem + .3vw, 1.2rem);
  line-height: 1.26;
  letter-spacing: -.016em;
  color: var(--ink);
}
.smanu__step p {
  margin: 0;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--slate);
}

@media (max-width: 1080px) {
  .smanu__track { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: clamp(2rem, 4vh, 2.8rem); }
  .smanu__rail { display: none; }
}
@media (max-width: 620px) {
  .smanu__track { grid-template-columns: 1fr; }
  .smanu__step { padding-top: 0; padding-left: 2.2rem; }
  .smanu__dot { top: .3rem; }
  .smanu__step h3 { margin-top: .35rem; }
}

/* ---------------------------------------------------------
   4 · POLICIES — two plates, set as documents.

   Round 2, item 5. There is no "read the full policy" link
   because there is no policy document — see the CLIENT: marker
   in build/pages/sustainability.html. A green rule along the top
   edge and a drawn seal do the work a link would have done: this
   is a stated position, formally set.
   --------------------------------------------------------- */

.spol__head { max-width: 52ch; margin-bottom: clamp(1.8rem, 4.5vh, 3rem); }
.spol__head .label { margin-bottom: clamp(.8rem, 2vh, 1.2rem); }
.spol__t {
  margin: 0 0 clamp(1rem, 2.4vh, 1.5rem);
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.4rem);
  line-height: 1.16;
  letter-spacing: -.022em;
  color: var(--chrome);
  text-wrap: balance;
}
.spol__lede {
  margin: 0;
  max-width: 62ch;
  color: var(--steel);
  font-size: var(--fs-small);
  line-height: 1.66;
}

.spol__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.2rem, 2.6vw, 2.2rem);
}
.spol__doc {
  position: relative;
  padding: clamp(1.8rem, 4vh, 2.6rem) clamp(1.4rem, 3vw, 2.2rem) clamp(1.8rem, 4vh, 2.4rem);
  border: 1px solid var(--rule-d);
  border-top: 2px solid var(--green-lt);
  background: rgba(255, 255, 255, .02);
}
.spol__seal {
  display: block;
  width: 44px; height: 44px;
  margin-bottom: clamp(1rem, 2.4vh, 1.5rem);
  color: var(--green-lt);
  opacity: .85;
}
.spol__seal svg {
  width: 100%; height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.spol__doc h3 {
  margin: 0 0 .7rem;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.15rem, 1rem + .55vw, 1.5rem);
  letter-spacing: -.02em;
  line-height: 1.22;
  color: var(--white);
}
.spol__doc p {
  margin: 0;
  max-width: 44ch;
  font-size: var(--fs-small);
  line-height: 1.65;
  color: var(--steel);
}

@media (max-width: 760px) {
  .spol__grid { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------
   5 · ESG PRINCIPLES — three lettered registers.

   Round 2, item 5. Replaces "ESG Commitments". The letter is the
   index, set at display scale and aria-hidden because the word
   beside it already says it. Four priorities per letter, ruled
   off — the third distinct shape on the page after the ring and
   the ledger.
   --------------------------------------------------------- */

.esgp__head { max-width: 40ch; margin-bottom: clamp(2rem, 5vh, 3.4rem); }
.esgp__head .label { margin-bottom: clamp(.8rem, 2vh, 1.2rem); }
.esgp__t {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 1.15rem + 1.9vw, 2.7rem);
  line-height: 1.14;
  letter-spacing: -.024em;
  color: var(--chrome);
  text-wrap: balance;
}

.esgp__cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.6rem, 3.6vw, 3.4rem);
}
.esgp__col {
  position: relative;
  padding-top: clamp(1rem, 2.4vh, 1.6rem);
  border-top: 1px solid var(--rule-d2);
}

.esgp__letter {
  display: block;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(2.6rem, 1.6rem + 3.4vw, 4.6rem);
  line-height: .9;
  letter-spacing: -.04em;
  color: var(--green-lt);
  opacity: .9;
}
.esgp__col h3 {
  margin: clamp(.7rem, 1.8vh, 1.1rem) 0 clamp(.9rem, 2.2vh, 1.3rem);
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.05rem, .96rem + .34vw, 1.24rem);
  letter-spacing: -.016em;
  color: var(--white);
}
.esgp__list { list-style: none; margin: 0; padding: 0; }
.esgp__list li {
  position: relative;
  padding: .68rem 0 .68rem 1.15rem;
  border-top: 1px solid var(--rule-d);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--steel);
}
.esgp__list li::before {
  content: '';
  position: absolute;
  /* Optical centre of the FIRST line: .68rem of padding plus half a
     1.5 line-height. 1.28em sat visibly above it on two-line rows. */
  left: 0; top: 1.55em;
  width: 6px; height: 1px;
  background: var(--green-lt);
}

@media (max-width: 900px) {
  .esgp__cols { grid-template-columns: 1fr; gap: clamp(1.6rem, 4vh, 2.4rem); }
  /* Stacked, the letter moves beside the register rather than
     above it — four rows under a 4.6rem letter is a lot of empty
     column on a phone. */
  .esgp__col {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: clamp(1.2rem, 4vw, 2rem);
    align-items: start;
  }
  /* A FIXED track, not `auto`. Sized to the glyph, the auto column is as
     wide as whichever letter that column holds — E, S and G are three
     different widths, so the three registers indented by three different
     amounts down the page. */
  .esgp__letter {
    grid-row: 1 / span 2;
    width: 2.1rem;
    font-size: clamp(2.4rem, 1.6rem + 4vw, 3.4rem);
  }
  .esgp__col h3 { margin-top: 0; }
}
/* ---------------------------------------------------------
   6 · VALUE — archetype 2, editorial bento. Unequal on purpose:
   the lead claim owns a tall column, the other two stack.
   --------------------------------------------------------- */

.vgrid {
  display: grid;
  grid-template-columns: 1.32fr 1fr;
  grid-template-rows: auto auto;
  border-top: 1px solid var(--rule-d);
}
.vcell { padding: clamp(1.4rem, 3vw, 2.3rem) clamp(1.2rem, 2.6vw, 2.2rem) clamp(1.4rem, 3vw, 2.3rem) 0; }
/* Two rows tall, so the index sits at the top of the column and the claim
   drops to the foot of it. Centring left the cell floating and top-aligning
   left a hole under it; anchoring both ends makes the height deliberate. */
.vcell--lead {
  grid-row: 1 / 3;
  border-right: 1px solid var(--rule-d);
  display: flex; flex-direction: column;
}
.vgrid > .vcell:not(.vcell--lead) { padding-left: clamp(1.2rem, 2.6vw, 2.2rem); }
.vgrid > .vcell:nth-child(3) { border-top: 1px solid var(--rule-d); }

/* THE PHOTOGRAPHS, 2026-08-08 — Daniel: "for the section Sustainability that
   Creates Value, we need to put photos too."

   The lead column was anchored at both ends with air in the middle, which
   was defensible as a poster margin and indefensible once you notice the
   whole band is the only one on the page without a picture. The air is now
   the photograph: it takes the slack the `margin-bottom: auto` used to hold,
   so the cell is still anchored top and bottom and nothing else moved.

   These are .ph slots, not <img>. assets/photos.js probes each file and adds
   .ph--live only on a real decode, so all three fall back to the aluminium
   gradient plus billet texture until the files are generated — the section
   reads as finished either way. See PHOTOS-TO-GENERATE.md Part 2. */
.vcell__ph {
  border-radius: var(--rad);
  margin: clamp(1rem, 2.4vh, 1.5rem) 0 clamp(1.1rem, 2.6vh, 1.6rem);
}
/* Sized, not greedy. `flex: 1 1 auto` let it absorb every pixel of slack the
   taller right-hand column created — measured 489px, which pushed "Long-term
   Value" clean off a 900px screen. The claim is the point of the cell; the
   photograph supports it. Fixed band, and the leftover slack goes back to the
   auto margin below so the cell stays anchored top and bottom as designed. */
.vcell__ph--lead { flex: 0 0 auto; height: clamp(200px, 30vh, 360px); }
.vcell--lead h3 { margin-top: auto; }
/* The stacked pair are compact, so theirs is a band rather than a panel. */
.vgrid > .vcell:not(.vcell--lead) .vcell__ph { height: clamp(130px, 17vh, 190px); }

.vcell__ph.ph--live { filter: saturate(.94) brightness(.92) contrast(1.04); }

.vcell__no {
  display: block; margin-bottom: .8rem;
  font-family: var(--f-mono); font-size: var(--fs-label); letter-spacing: .16em;
  color: var(--green-lt);
}
.vcell h3 {
  font-family: var(--f-display); font-weight: 600; font-size: var(--fs-h3);
  letter-spacing: -.015em; color: var(--white); margin: 0 0 .45rem;
}
/* The lead cell is two rows tall, so it has to carry the weight to match —
   at the standard h3 size it read as a normal cell with a hole under it. */
.vcell--lead h3 { font-size: clamp(1.55rem, 1.1rem + 1.75vw, 2.75rem); line-height: 1.08; margin-bottom: .7rem; }
.vcell p { margin: 0; font-size: var(--fs-small); color: var(--steel); max-width: 40ch; }
.vcell--lead p {
  font-family: var(--f-display); font-weight: 300;
  font-size: clamp(1rem, .92rem + .45vw, 1.28rem); line-height: 1.36;
  letter-spacing: -.008em; color: var(--chrome); max-width: 26ch;
}

@media (max-width: 820px) {
  .vgrid { grid-template-columns: 1fr; }
  .vcell--lead { grid-row: auto; border-right: 0; border-bottom: 1px solid var(--rule-d); display: block; }
  .vcell--lead .vcell__no { margin-bottom: .8rem; }
  .vgrid > .vcell:not(.vcell--lead) { padding-left: 0; }
  .vgrid > .vcell:nth-child(3) { border-top: 1px solid var(--rule-d); }
}

/* ---------------------------------------------------------
   REDUCED MOTION — land every device in its finished state.
   JS sets the progress-driven ones (arc, rail fills, node and
   row lighting); these are the CSS-owned ones.
   --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .loop__glint { display: none; }
  .loop__node { transform: translate(-50%, -50%) scale(1); }
  .loop__stagerow::after { transform: scaleX(1); }
  /* The ledger rail and its marks are progress-driven, and
     js/sec-sustainability.js writes them to the finished state
     rather than scrubbing them in this mode. Stated here as well
     so the band is correct even if the script never runs at all. */
  .smanu__fill { transform: scaleX(1); }
  .smanu__dot { border-color: var(--green); background: var(--green); }
  .smanu__no { color: var(--green); }
}

/* 2026-08-21 — heading weight brought back to the site standard.
   These four section headings were the only H2s on the whole site not using
   `.sechead__title`, and they carried font-weight 300 where every other H2 —
   including `The Aluminium Loop` on this same page — is 600. Side by side the
   page read as two different typefaces. Family, size and tracking are
   unchanged; only the weight moved. Poppins 300 is still loaded and still
   used by .sechead__sub / .phero__sub / .loop__lede, so no font file changed. */
