/* ============================================================================
   HYDRO2050 - COMPONENTS
   ----------------------------------------------------------------------------
   The shared vocabulary: buttons and links, the pattern, the navy closing
   band, and the two cross-cutting rules that keep the design's fixed-pixel
   grids inside the viewport and every target at 44px.
   ========================================================================== */

/* ===== BUTTONS =========================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding-inline: 28px;
  border-radius: 12px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: var(--wt-semi);
  line-height: 1;
  text-decoration: none;
  transition: background-color var(--dur-hover) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn--primary { background: var(--brand-blue-cta); color: var(--on-navy); }   /* 6.16:1 */
.btn--primary:hover { background: var(--brand-blue-cta-h); }                  /* 8.38:1 */
.btn--turq { background: var(--brand-turq); color: var(--brand-navy); }       /* 5.89:1 */
.btn--turq:hover { background: #1ACFCA; }                                     /* navy on it = 4.95:1 */
.btn--block { width: 100%; }
.btn:active { transform: translateY(1px); }

/* The one oversized button on the site, on Home. 82 / 24 is the 1440 figure
   and home.css drops it to 56 / 17 below the breakpoint, so held flat it
   stepped by 26px in the middle of a drag. The ramp starts from that same
   56 / 17 at 900, so the two meet instead of stepping. */
.btn--big {
  min-height: clamp(56px, calc(4.8148vw + 12.667px), 82px);   /* 56 -> 82 */
  font-size:  clamp(17px, calc(1.2963vw +  5.333px), 24px);   /* 17 -> 24 */
}

/* A text link that carries a turquoise underline. The underline is 1.5px and
   sits below the descender, so it never crosses a letterform. */
.link-rule {
  display: inline-block;
  padding-bottom: 2px;
  border-bottom: 1.5px solid var(--brand-turq);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: var(--wt-semi);
  line-height: 22px;
  color: var(--azure-ink);        /* 4.94:1 on page */
  text-decoration: none;
  transition: color var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out);
}
.link-rule:hover { color: var(--azure-hover); border-color: var(--azure-hover); }

/* ===== PATTERN =========================================================== */

/* The dot-ring the design uses behind the contact plinth and inside the hero
   card. Drawn rather than imaged, so it takes the brand colour from a token
   and stays crisp at any size.

   .pattern--mirror carries the scaleX(-1) that Page 08 is missing in Paper:
   without it Page 08's opening reads identically to Page 01's. The modifier
   exists here so the fix is already in the system when Page 08 is built. */
.pattern { position: absolute; pointer-events: none; z-index: var(--z-art); }
.pattern--mirror { transform: scaleX(-1); }
.pattern--dim { opacity: 0.16; }
.pattern > * { position: relative; z-index: var(--z-content); }

/* 640 x 640 at left -324, bottom -398 inside the 400-wide plinth, so it is
   three quarters off the panel on both axes. Expressed against the plinth
   rather than in artboard pixels: -324/400 and -398/640 of its own height. */
.plinth__ring {
  position: absolute;
  left: -81%;
  bottom: -62%;
  z-index: var(--z-art);
  width: 160%;
  height: auto;
  aspect-ratio: 1;
  opacity: 0.16;
  pointer-events: none;
}

/* ===== NAVY CLOSING BAND ================================================= */

/* Navy, full bleed, with a 560px photograph running off the right edge under
   a 90deg scrim that is opaque where it meets the text column and near clear
   at the page edge. Right padding is 600px so no line of type can ever reach
   the photograph. At mobile the photograph moves below the copy and the scrim
   rotates to 180deg, which is what the 375 artboard shows. */
.band {
  position: relative;
  isolation: isolate;
  overflow: clip;
  background: var(--surface-navy);
  padding-block: var(--rhythm-section);
  /* Left edge on the content column, so the band's headline lines up with the
     section above it at every width rather than only at 1440.

     The right figure has to clear the photograph, and the old 41.7vw did not.
     The photograph is `min(560px, 42%)` of a full-bleed band, so below 1334 it
     is 42vw wide while the padding reserved 41.7. Three tenths of a per cent,
     but the sign is wrong: the type box crossed INTO the photograph, measured
     at 3px at 900 and 4px at 1200 on the nine pages that carry a band. Nothing
     showed it, because `overflow: clip` swallows the evidence and today's copy
     does not fill its last line. It was a collision waiting on a longer
     sentence.

     42vw reaches the photograph's edge, plus the 40px of clearance the
     artboard draws at 1440, which is 2.78vw of it. Above 1334 the clamp caps
     at the artboard's own 600 and the photograph caps at 560, so the clearance
     stays exactly 40 from there up. */
  padding-inline: var(--pad-column) clamp(var(--gutter), 44.78vw, 600px);
  color: var(--on-navy);
}
/* Two levels, as the artboard has them: the eyebrow, headline and body sit at
   22 inside their own block, and 40 separates that block from the button. A
   single uniform gap runs the band 36px taller and reads looser. */
.band__inner { position: relative; z-index: var(--z-content); display: flex; flex-direction: column; gap: var(--rhythm-block); align-items: flex-start; }
.band__copy { display: flex; flex-direction: column; gap: 22px; width: min(760px, 100%); }
.band__headline { max-width: 760px; }
/* 18 / 30 was a literal here, held flat at every width, so the one paragraph
   in the closing band read a size larger than the running copy above it on a
   375 screen. This is the first user of --text-copy, the token minted for
   exactly this role: 17 / 26 up to the breakpoint, 18 / 30 at 1440. */
.band__body {
  max-width: 680px;
  font-size: var(--text-copy);
  line-height: var(--lh-copy);
  color: var(--on-navy-mute);   /* 6.69:1 on navy */
}

.band__photo {
  position: absolute;
  inset: 0 0 0 auto;
  z-index: var(--z-media);
  width: min(560px, 42%);
  height: 100%;
  object-fit: cover;
}
.band__scrim {
  position: absolute;
  inset: 0 0 0 auto;
  z-index: var(--z-media);
  width: min(560px, 42%);
  background: linear-gradient(90deg,
    #00477B 0%, rgba(0,71,123,0.94) 14%, rgba(0,71,123,0.62) 40%,
    rgba(0,71,123,0.28) 70%, rgba(0,71,123,0.16) 100%);
}

@media (max-width: 899px) {
  /* At mobile the photograph moves from the right edge to below the copy, and
     the scrim rotates from 90deg to 180deg. The band becomes a flex column and
     the copy is given order:1 so it paints first: the photograph and scrim are
     written before it in the markup, because on desktop they have to sit
     behind it, and without the ordering they land above it here. */
  .band {
    display: flex;
    flex-direction: column;
    padding: var(--rhythm-row) var(--gutter-mob) var(--rhythm-block);
  }
  .band__inner { order: 1; gap: 32px; }
  .band__copy { gap: 14px; }
  /* Full width and square, as the 375 artboard draws it. */
  .band__inner .btn--turq {
    width: 100%;
    height: 56px;
    justify-content: center;
    border-radius: 0;
    font-size: 17px;
    line-height: 22px;
  }
  .band__photo { order: 2; }
  .band__scrim { order: 3; }
  /* max-width:100% from the base reset caps an <img> at its content box, so
     the 100vw band was rendering 335 wide with a 40px navy strip beside it
     while the scrim, a <span>, ran the full 375 and overhung it. The photo
     needs the cap lifted explicitly. */
  .band__photo, .band__scrim {
    position: static;
    width: 100vw;
    max-width: 100vw;
    height: 200px;
    margin: 40px calc(50% - 50vw) 0;
    object-fit: cover;
  }
  .band__scrim {
    margin-top: -200px;
    margin-bottom: -40px;
    background: linear-gradient(180deg,
      #00477B 0%, rgba(0,71,123,0.62) 34%,
      rgba(0,71,123,0.28) 68%, rgba(0,71,123,0.16) 100%);
  }
}

.link-rule { display: inline-flex; align-items: center; min-height: 44px; }

/* ===== STATES ============================================================
   The spec asks for a defined rest, hover, focus, active and disabled state on
   every interactive element. Hover and focus-visible are defined per component
   above; rest is the default. This block covers the two that were only defined
   on the buttons: the pressed state, and disabled.

   :active is set on everything a person can press rather than only on the
   pills and buttons, because a tap that produces no visible change inside
   ~100ms reads as a dropped tap and gets repeated. The transition is
   --dur-fast, 140ms, so the acknowledgement lands inside that window. */

a[href], button, [role="button"], summary {
  -webkit-tap-highlight-color: transparent;
  transition: opacity var(--dur-fast) var(--ease-out),
              color var(--dur-hover) var(--ease-out),
              background-color var(--dur-hover) var(--ease-out);
}
a[href]:active, button:active, [role="button"]:active { opacity: 0.72; }

/* Components that already move on press keep their own treatment and opt out
   of the opacity dip, so a button does not both sink and fade. */
.btn:active, .pill:active, .pill-cta:active,
.nav__toggle:active, .drawer__link:active, .drawer__sub-link:active { opacity: 1; }

/* Disabled. Nothing in this phase ships disabled, but the state is defined so
   the first control that needs one does not invent its own. */
[disabled], [aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}
