/* ============================================================================
   HYDRO2050 - PAGES 11 AND 12, THE LEGAL PAGES
   ----------------------------------------------------------------------------
   Measured from Paper artboards 8H8-0 "Page 11, Privacy policy 1440" and
   8KY-0 "Page 12, Terms and conditions 1440". The two are the same layout with
   different section names, so they are one stylesheet.

   Neither page has a 375 artboard. The mobile layout below is derived from the
   conventions the built pages already use, recorded in DESIGN-NOTES.md.

   Both pages call Hydro.footer({ lifted: false }): they have no navy closing
   band for the enquiry card to straddle, so it sits in normal flow.
   ========================================================================== */

.legal-open { padding-top: var(--rhythm-open); }
.legal-open__eyebrow { margin-bottom: 28px; }
.legal-open__title { max-width: 820px; margin-bottom: 28px; }
.legal-open__deck {
  max-width: 680px;
  font-size: 16px;
  line-height: 24px;
  color: var(--ink-muted);       /* 5.51:1 on page */
}

/* The body carries the brand's own artwork as a full-section background, at
   the measured cover fit. Every run of type over it is measured from real
   pixels by tools/over-image-contrast.mjs rather than assumed safe. */
.legal-body {
  /* 88 at 1440 and 40 at 375, both measured, and the scale has no 88 step:
     --rhythm-sm tops out at 72 and --rhythm-open at 104. Rather than move
     the design 16px either way this is the same clamp construction the
     rhythm tokens use, built from this rule's own two measured ends.
     slope = (88 - 40) / 1065 = 4.5070vw, base = 40 - 4.5070 * 3.75. */
  padding: clamp(40px, calc(23.099px + 4.5070vw), 88px) 0 var(--rhythm-section);
  background-image: url(../assets/img/pattern-bluewhite.jpg);
  background-size: cover;
  background-position: 50%;
}
.legal-body__grid {
  display: grid;
  /* 320 + 96 + 680 = 1096 inside 1312. The artboard leaves the remaining 216
     empty rather than widening the prose column.

     Both figures are fractions of the column: 320 / 1312 = 24.390% and
     96 / 1312 = 7.317%, which resolve to the measured 320 and 96 at 1440.
     As literals they took 512 of the 772 the page has at 900, leaving the
     policy itself 260 and setting eight-word section headings across two
     lines beside a contents list that had room to spare. A contents list is
     a subordinate element and gives way first. */
  grid-template-columns: minmax(220px, 24.390%) minmax(0, 680px) minmax(0, 1fr);
  column-gap: 7.317%;
  align-items: start;
}

/* ===== CONTENTS ========================================================== */

.legal-toc {
  border-top: 1px solid var(--rule);
  padding-top: 28px;
}
.legal-toc__label { display: block; margin-bottom: 14px; }
.legal-toc__list { display: flex; flex-direction: column; }
/* The artboard draws these rows at 28px with a 14px gap. The project floor for
   a target is 44, so the line box keeps its measured 16 / 28 and the hit area
   grows around it with 8px above and below. Adjacent rows then sit 16 apart
   rather than the measured 14; that 2px is the cost of a real target. */
.legal-toc__list a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-block: 8px;
  font-size: 16px;
  line-height: 28px;
  color: var(--brand-blue-cta);   /* 6.16:1 on page */
  text-decoration: none;
}
.legal-toc__list a:hover { color: var(--brand-blue-cta-h); text-decoration: underline; }

/* ===== SECTIONS ========================================================== */

.legal-section {
  border-top: 1px solid var(--rule);
  padding-top: 28px;
  padding-bottom: 32px;
  /* No scroll-margin-top here. Every one of these sections carries an id and
     sits inside #main, so layout.css's `#main [id]` rule already lands them
     clear of the header, and it derives the distance from --header-h rather
     than restating it. The literal that used to sit here was 120px against a
     correct 108, and its mobile pair was 84 against a correct 88, which put
     the heading under the bar at exactly the width where the bar is tallest
     relative to the page. */
}
.legal-sections > .legal-section:last-child { border-bottom: 1px solid var(--rule); }

.legal-section__title {
  font-family: var(--font-display);
  font-size: 21px;
  line-height: 28px;
  font-weight: var(--wt-medium);
  color: var(--brand-navy);
  margin-bottom: 14px;
}
.legal-section__body {
  font-size: 18px;
  line-height: 30px;
  color: var(--ink);
}

/* ===== MOBILE ============================================================
   Derived, not measured: these two pages have no 375 artboard. One column,
   the 20px gutter, and the mobile type scale the built pages already use. */

@media (max-width: 899px) {
  .legal-open { padding-top: 32px; }
  .legal-open__eyebrow { margin-bottom: 14px; }
  .legal-open__title { margin-bottom: 14px; }
  .legal-open__deck { font-size: 15px; line-height: 23px; }

  .legal-body { padding: 40px 0 48px; }
  .legal-body__grid { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }

  .legal-toc__list a { font-size: 15px; line-height: 22px; }

  .legal-section { padding-top: 20px; padding-bottom: 24px; }
  .legal-section__title { font-size: 22px; line-height: 28px; letter-spacing: -0.02em; margin-bottom: 10px; }
  .legal-section__body { font-size: 17px; line-height: 26px; }
}

/* ===== RUNNING POLICY TEXT ===============================================
   base.css zeroes every margin and takes the markers off every list, which is
   right for a site built out of components and wrong for the one place on it
   that carries a document. A policy has consecutive paragraphs, and four
   passages of the terms are bulleted lists on Hydro2050's own site: read as
   running text they are unreadable ("You must not: Republish material Sell,
   rent or sub-license material..."). These give the client's own text back its
   paragraph breaks and its bullets, and change nothing else.

   Spacing follows the two figures this stylesheet already uses: 14px, the
   measured gap under a section title, and the 18/30 body. */

.legal-open__deck + .legal-open__deck { margin-top: 14px; }

.legal-section__body + .legal-section__body,
.legal-section__body + .legal-section__list,
.legal-section__list + .legal-section__body { margin-top: 14px; }

.legal-section__list {
  list-style: disc;
  padding-left: 22px;
  font-size: 18px;
  line-height: 30px;
  color: var(--ink);
}
.legal-section__list li + li { margin-top: 6px; }

/* The mobile block above this one sets .legal-section__body to 17/26. It sits
   earlier in the file, so it cannot reach a selector declared here: the list
   carries its own pair rather than inheriting a size the media query already
   moved. */
@media (max-width: 899px) {
  .legal-section__list { font-size: 17px; line-height: 26px; }
}

/* The only link in either document is the policy's own mailto. It takes the
   same blue as the contents list, which is 6.16:1 on this page's ground. */
.legal-section__body a { color: var(--brand-blue-cta); }
.legal-section__body a:hover { color: var(--brand-blue-cta-h); }

/* ===== ANCHOR TARGETS ====================================================
   THIS OVERRIDES layout.css's `#main [id]`, and the comment that used to sit
   in .legal-section saying no scroll-margin was needed here was wrong. Both
   the note and the global rule are correct about the header's COVERING height,
   which is the 84px bar. Neither accounts for the header's FLOW height, which
   is 116: .site-header carries `padding: 32px 32px 0` at rest and
   `.is-stuck` drops it to 0.

   A sticky element still occupies its normal flow box, so when that padding
   collapses the box shrinks from 116 to 84 and every element below it moves up
   32px. On any anchor jump that starts at the top of the page the destination
   is computed BEFORE the collapse and the page lands after it, so the target
   finishes 32px higher than asked. Measured on 2026-08-23, headless Chrome at
   1440: all eight anchors on both pages landed at sectionClear -8, that is
   the intended 24px gap minus the 32px that left the flow, with the h2 cap
   clipped by the bar. The defect vanishes under prefers-reduced-motion only
   because Lenis never initialises there and nothing scrolls far enough.

   So the target has to clear the header's flow height, not its covering
   height: --header-h + 24 + the 32 that is about to leave the flow. The 32 is
   .site-header's own padding-top in css/chrome.css and is written here as its
   own term rather than folded into the 24, so the two numbers stay traceable
   to the two different things they came from.

   This is the CSS half. It covers a cold load with a #hash already in the URL
   and the non-Lenis scrollIntoView path. Lenis does not read scroll-margin, so
   a click on a contents link is not fixed here: that half is headerOffset() in
   js/motion.js.

   SPECIFICITY IS LOAD-BEARING HERE. layout.css's rule is `#main [id]`, which
   is (1,1,0); motion.css wraps its own copy in :where() and carries none. A
   bare `.legal-section` is (0,1,0) and loses to layout.css silently, which is
   exactly what happened on the first attempt: the declaration was in the
   sheet, the cascade dropped it, and the cold-load numbers did not move. The
   `#main` and the `[id]` are here to outrank it, not for their own sake. */

#main .legal-section[id] {
  scroll-margin-top: calc(var(--header-h) + 24px + 32px);
}

/* AND THE 32 COMES BACK OFF UNDER REDUCED MOTION, because there the shift does
   not survive. Lenis never initialises, so goTo() falls to scrollIntoView and
   the browser owns the scroll; when the header then collapses and pulls the
   page up 32px, Chrome's scroll anchoring adjusts the offset to keep what is
   on screen where it was, and the target does not move. Lenis defeats that by
   writing scrollTop itself every frame, which is why the normal path needs the
   compensation and this one does not.

   Measured, and this rule exists because the measurement caught a regression
   rather than because the behaviour was predicted: under
   --force-prefers-reduced-motion at 1440 the anchors were already landing on
   the intended 24 before any of this work, and adding the 32 unguarded pushed
   all sixteen of them to 56 on both pages, in all three cases, warm click,
   stuck click and cold load. */
@media (prefers-reduced-motion: reduce) {
  #main .legal-section[id] {
    scroll-margin-top: calc(var(--header-h) + 24px);
  }
}
