/* ============================================================
   Event Weather Service — "the quiet instrument"
   ============================================================ */

:root {
  --paper: #ffffff;
  --ink: #000000;
  --ink-soft: #222222;
  --muted: #777777;
  --hairline: #cccccc;
  --faint: #efefef;
  --signal-red: #d30b1a;
  --range-blue: #0d17d1;

  --font-display: "Archivo", "Helvetica Neue", sans-serif;
  --font-body: "Source Serif 4", Georgia, serif;
  --font-label: "Archivo", "Helvetica Neue", sans-serif;

  --measure: 34em;
  --gutter: clamp(1.5rem, 6vw, 6rem);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  /* anchored content clears the fixed header */
  scroll-padding-top: 7rem;
}

body {
  background: var(--paper);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--faint); color: var(--ink); }

a { color: inherit; }

a:focus-visible,
.wordmark:focus-visible {
  outline: 2px solid var(--range-blue);
  outline-offset: 4px;
}

strong, b { font-weight: 600; }

/* keyboard-only escape past the header; invisible until focused */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
}

.skip-link:focus {
  left: var(--gutter);
  top: 0.75rem;
  font-family: var(--font-label);
  font-size: 0.74rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  background: var(--ink);
  padding: 0.9em 1.8em;
}

main:focus { outline: none; }

.c-red  { color: var(--signal-red); }
.c-blue { color: var(--range-blue); }

/* ---------------- header ---------------- */

/* header stays fixed; becomes a full-width white bar once scrolling */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 1.5rem var(--gutter);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 260ms ease, border-color 260ms ease, padding 260ms ease;
}

.site-header.scrolled {
  background: var(--paper);
  border-bottom-color: var(--faint);
  padding-top: 0.8rem;
  padding-bottom: 0.8rem;
}

.wordmark { display: block; }

.wordmark img {
  display: block;
  height: clamp(2.5rem, 3.6vw, 3.4rem);
  width: auto;
  transition: height 260ms ease;
}

.site-header.scrolled .wordmark img { height: 2.2rem; }

.wordmark-c {
  font-size: 0.5em;
  letter-spacing: 0;
  vertical-align: super;
  margin-left: 0.4em;
}

.header-inquire {
  font-family: var(--font-label);
  font-weight: 300;
  font-size: 0.74rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  padding: 0.9em 1.8em;
  white-space: nowrap;
  /* hidden at the top of the page; fades in with the header bar.
     visibility keeps it out of the tab order while invisible —
     delayed on the way out so the fade can finish first */
  opacity: 0;
  visibility: hidden;
  transition: background 180ms ease, border-color 180ms ease,
              opacity 320ms ease, visibility 0s linear 320ms;
}

.site-header.scrolled .header-inquire {
  opacity: 1;
  visibility: visible;
  transition: background 180ms ease, border-color 180ms ease,
              opacity 320ms ease, visibility 0s;
}

.header-inquire:hover { background: var(--signal-red); border-color: var(--signal-red); }

/* ---------------- mobile nav ---------------- */

/* the toggle only exists below the breakpoint; on desktop every section is a
   short scroll away and the header stays a wordmark and one action */
.nav-toggle {
  display: none;
  appearance: none;
  background: none;
  border: 0;
  padding: 0.6rem;
  margin-right: -0.6rem;
  cursor: pointer;
  color: var(--ink);
}

.nav-bars {
  display: block;
  width: 1.4rem;
}

.nav-bars i {
  display: block;
  height: 2px;
  background: currentColor;
  transition: transform 260ms ease, opacity 180ms ease;
}

.nav-bars i + i { margin-top: 5px; }

/* the bars fold into a cross while the panel is open */
.nav-toggle[aria-expanded="true"] .nav-bars i:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-bars i:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-bars i:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.site-nav {
  position: fixed;
  inset: 0;
  z-index: 55;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2.5rem;
  padding: 6rem var(--gutter) 3rem;
  background: var(--paper);
}

.site-nav[hidden] { display: none; }

.nav-list { list-style: none; }

.nav-list a {
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.35rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--faint);
}

.nav-list li:first-child a { border-top: 1px solid var(--faint); }

.nav-mail {
  font-family: var(--font-label);
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  overflow-wrap: break-word;
}

/* ---------------- hero ---------------- */

.hero {
  position: relative;
  min-height: min(100svh, 62rem);
  display: flex;
  align-items: center;
  padding: 6rem var(--gutter) 5rem;
  overflow: hidden;
}

/* the ring field sits fully inside the viewport. Running it off the edge read
   as a clipped or half-loaded image rather than a deliberate crop. */
.hero-instrument {
  position: absolute;
  top: 50%;
  right: clamp(1.5rem, 4vw, 5rem);
  transform: translateY(-50%);
  width: min(72svh, 44vw);
  aspect-ratio: 1;
  pointer-events: none;
}

#instrument { width: 100%; height: 100%; display: block; }

.ring { stroke-width: 1.25; }
.ring-gray { stroke: var(--hairline); }
.ring-red  { stroke: var(--signal-red); stroke-width: 2.5; }
.ring-blue { stroke: var(--range-blue); stroke-width: 1.5; }

.ring-label {
  font-family: var(--font-label);
  font-weight: 400;
  font-size: 24px;
  letter-spacing: 2px;
  fill: var(--muted);
  text-anchor: middle;
  dominant-baseline: central;
}

/* the copy column is capped against the viewport so the headline always stops
   short of the ring field rather than running across it */
.hero-copy {
  position: relative;
  z-index: 2;
  max-width: min(46rem, 40vw);
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 100;
  font-size: clamp(2.1rem, 5.2vw, 4.15rem);
  line-height: 1.14;
  letter-spacing: 0.115em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 2.25rem;
}

.hero-sub {
  max-width: var(--measure);
  color: var(--ink-soft);
  font-size: 1.125rem;
}

/* strike readout plotted inside the ring field */
.readout {
  opacity: 0;
  transition: opacity 900ms ease;
}

.readout.visible { opacity: 1; }

/* the paper stroke sits behind the fill, so the bolt keeps its edges crisp
   while still clearing the range rings it lands on */
.readout-bolt {
  fill: var(--signal-red);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 4;
  stroke-linejoin: round;
}

.readout-text {
  font-family: var(--font-label);
  font-weight: 300;
  font-size: 19.5px;
  letter-spacing: 2px;
  fill: var(--signal-red);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 7px;
  stroke-linejoin: round;
}

/* ------------- instrument motion ------------- */

#vane { transform-box: fill-box; transform-origin: 54% 93%; }

#vane.wobbling {
  animation: vane-wobble 1.9s ease-in-out 1;
}

@keyframes vane-wobble {
  0%   { transform: rotate(0deg); }
  28%  { transform: rotate(-3deg); }
  62%  { transform: rotate(1.6deg); }
  100% { transform: rotate(0deg); }
}

/* gust speed printed on the fin while the cups spin */
.gust-text {
  font-family: var(--font-label);
  font-weight: 300;
  font-size: 33px;
  letter-spacing: 4px;
  fill: #ffffff;
  opacity: 0;
  transition: opacity 600ms ease;
}

.gust-text.visible { opacity: 1; }

/* WBGT flag rise and sink */
.wbgt-group {
  transform: translateY(100px);
  transition: transform 950ms cubic-bezier(0.22, 0.9, 0.3, 1);
}

.wbgt-group.up { transform: translateY(0); }

.wbgt-flag {
  stroke: var(--ink);
  stroke-width: 1.5;
}

.wbgt-text {
  font-family: var(--font-label);
  font-weight: 300;
  font-size: 27px;
  letter-spacing: 3px;
}

.ring { transform-box: fill-box; transform-origin: 50% 50%; }

.ring.pulsing { animation: ring-pulse 2.4s ease-out 1; }

@keyframes ring-pulse {
  0%   { stroke-opacity: 1;    }
  18%  { stroke-opacity: 0.15; }
  36%  { stroke-opacity: 1;    }
  54%  { stroke-opacity: 0.3;  }
  78%  { stroke-opacity: 1;    }
  100% { stroke-opacity: 1;    }
}

/* ---------------- sections ---------------- */

.section {
  padding: clamp(5rem, 12vh, 8.5rem) var(--gutter);
  max-width: 72rem;
  margin: 0 auto;
}

/* section headers carry a rule across the full column: at weight 200 and
   0.78rem they read as captions rather than headings, and get lost */
.eyebrow {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink);
  border-top: 2px solid var(--ink);
  padding-top: 1.15rem;
  margin-bottom: 3rem;
  /* the rule runs to the section edge, lining up with the service bands;
     the padding puts the text back where it would otherwise sit */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
}

.deg {
  color: var(--signal-red);
  font-weight: 400;
  margin-right: 0.1em;
}

.statement {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  line-height: 1.3;
  color: var(--ink);
  max-width: 22em;
  margin-bottom: 2rem;
}

.statement-center { margin-left: auto; margin-right: auto; text-align: center; }

.section-body {
  max-width: var(--measure);
  color: var(--ink-soft);
}

.body-center { margin-left: auto; margin-right: auto; text-align: center; }

/* ---------------- mandate frame ---------------- */

/* Two open corner brackets rather than a closed box: the section reads as a
   plotted area, not a card. Red marks the near corner and blue the far one —
   the same near/far language the range rings carry on the instrument, where
   8 miles is red and 25 is blue. */
/* The mandate is the thesis block, so it takes the full instrument treatment:
   the anemometer body carries both a red and a blue band on one plate stack,
   and this plate does the same — red at its head, blue at its foot. The
   protocol plates each carry a single band; this one carries the pair.
   max-width is sized so the text inside still sits at the reading measure. */
.mandate-frame {
  /* generous padding rather than a longer line: the plate gains presence while
     the text stays at the reading measure (~72 characters) */
  --plate-pad: clamp(1.75rem, 5.5vw, 6.5rem);
  position: relative;
  max-width: calc(var(--measure) + 2 * var(--plate-pad) + 2px);
  padding: var(--plate-pad);
  border: 1px solid var(--faint);
}

.mandate-frame::before,
.mandate-frame::after {
  content: "";
  position: absolute;
  left: -1px;
  right: -1px;
  height: 3px;
  pointer-events: none;
}

.mandate-frame::before {
  top: -1px;
  background: var(--signal-red);
}

.mandate-frame::after {
  bottom: -1px;
  background: var(--range-blue);
}

/* ---------------- services ---------------- */

.service-list {
  list-style: none;
  /* pull the rows out to the section gutter so the alternating fill reads as a
     full band while the text stays aligned with the rest of the page */
  margin-inline: calc(var(--gutter) * -1);
}

.service {
  display: grid;
  grid-template-columns: minmax(14rem, 22rem) 1fr;
  gap: 1.5rem 4rem;
  padding: 2.5rem var(--gutter);
  border-top: 1px solid var(--faint);
}

.service:nth-child(even) { background: var(--faint); }

.service:last-child { border-bottom: 1px solid var(--faint); }

.service-name {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: 1.02rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.5;
}

.service-desc { max-width: var(--measure); }

.service-note {
  grid-column: 2;
  font-family: var(--font-label);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  color: var(--muted);
  margin-top: 0.75rem;
}

/* ---------------- protocol ---------------- */

.protocol-list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 1.6vw, 1.5rem);
}

/* each step is an instrument plate, the way the anemometer body is a stack of
   plates divided by thin brand bands. The band reads as distance out from the
   event, following the range rings: blue at 25 miles, grey through the middle
   rings, red at 8 — so the colour walks from planning to live watch. */
.protocol-step {
  --step-accent: var(--muted);
  position: relative;
  border: 1px solid var(--faint);
  padding: clamp(1.75rem, 2.6vw, 2.5rem);
}

/* pulled out over the border so the band runs flush across the head of the
   plate, as it does on the instrument body */
.protocol-step::before {
  content: "";
  position: absolute;
  top: -1px;
  left: -1px;
  right: -1px;
  height: 3px;
  background: var(--step-accent);
}

.protocol-step:first-child { --step-accent: var(--range-blue); }
.protocol-step:last-child  { --step-accent: var(--signal-red); }

.step-num {
  font-family: var(--font-label);
  font-weight: 300;
  font-size: 0.78rem;
  letter-spacing: 0.2em;
  color: var(--step-accent);
  margin-bottom: 1.5rem;
}

.step-name {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: 1.02rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 1.25rem;
}

.step-desc { font-size: 1rem; }

/* ---------------- contact ---------------- */

#contact { text-align: center; padding-bottom: clamp(6rem, 14vh, 10rem); }

#contact .eyebrow { margin-bottom: 4rem; }

.contact-lead {
  font-family: var(--font-body);
  font-size: clamp(1.4rem, 2.6vw, 2rem);
  color: var(--ink);
  margin-bottom: 2.75rem;
}

.contact-mail {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 100;
  /* the upper half of the range keeps the reduced desktop size; the floor is
     lifted so the address stays legible and tappable on a phone, while still
     fitting on one line at 375px */
  font-size: clamp(0.875rem, 1.8vw, 1.35rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 0.3em;
  transition: color 200ms ease, border-color 200ms ease;
  /* break-word, not anywhere: it honours the <wbr> after the @ first, so a
     very narrow screen splits the address at the @ instead of mid-domain */
  overflow-wrap: break-word;
}

.contact-mail:hover { color: var(--range-blue); border-color: var(--range-blue); }

.contact-note {
  margin-top: 2.5rem;
  font-size: 0.95rem;
  color: var(--muted);
  font-style: italic;
}

/* ---------------- footer ---------------- */

.site-footer {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 2rem;
  padding: 3rem var(--gutter) 3.5rem;
  border-top: 1px solid var(--faint);
}

.footer-mark {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: 1.1rem;
  letter-spacing: 0.4em;
  color: var(--ink);
}

.footer-meta {
  font-family: var(--font-label);
  font-weight: 300;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  color: var(--muted);
  text-transform: uppercase;
}

/* ---------------- reveal on scroll ---------------- */

/* hidden state only applies once JS confirms it will reveal */
.js .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 800ms ease, transform 800ms ease;
}

.js .reveal.revealed { opacity: 1; transform: none; }

/* ---------------- responsive ---------------- */

@media (max-width: 900px) {
  /* stacked, not layered: the instrument takes its own space above the copy,
     so the headline can never sit on top of the ring field */
  .hero {
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    min-height: auto;
    padding-top: 7rem;
    padding-bottom: 4rem;
    gap: 2.5rem;
  }

  .hero-instrument {
    position: relative;
    top: auto;
    right: auto;
    transform: none;
    width: min(74vw, 19rem);
    margin: 0 auto;
  }

  /* the labels stay, but the instrument is ~304px here, so a 24px label would
     render at about 7px. Scaling the type to 40 units puts it back around 12px,
     and each gap widens to match the larger glyphs. */
  .ring-label { font-size: 40px; }

  #ring-8  { stroke-dasharray: 93.85 6.15; stroke-dashoffset: 59.42; }
  #ring-10 { stroke-dasharray: 94.28 5.72; stroke-dashoffset: 59.64; }
  #ring-15 { stroke-dasharray: 96.05 3.95; stroke-dashoffset: 60.52; }
  #ring-25 { stroke-dasharray: 97.11 2.89; stroke-dashoffset: 61.06; }

  .hero-copy { max-width: 100%; }

  .hero-title {
    font-size: 1.72rem;
    letter-spacing: 0.1em;
  }

  .hero-sub { font-size: 1.04rem; }

  .readout { left: var(--gutter); right: auto; }

  .service { grid-template-columns: 1fr; gap: 1rem; }
  .service-note { grid-column: 1; }

  .protocol-list { grid-template-columns: 1fr; gap: 1rem; }

  .site-header { padding-top: 1rem; padding-bottom: 1rem; }
  .wordmark img { height: 1.7rem; }
  .site-header.scrolled .wordmark img { height: 1.4rem; }

  /* the menu replaces the Inquire button here — the panel carries the address,
     and three items crowd a phone-width header */
  .header-inquire { display: none; }
  .nav-toggle { display: block; }

  .site-footer { flex-direction: column; gap: 1rem; }
}

/* ---------------- reduced motion ---------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .js .reveal { opacity: 1; transform: none; transition: none; }

  #vane.wobbling, .ring.pulsing { animation: none; }

  .readout, .gust-text, .wbgt-group { transition: none; }

  .header-inquire,
  .site-header.scrolled .header-inquire { transition: none; }
}
