/* ============================================================================
   Steeplejack Robotics — the hero
   ----------------------------------------------------------------------------
   This is a reproduction of docs/mission.png, the approved brand design. It is
   not an interpretation: the geometry below was measured off that file pixel by
   pixel and every number is expressed as a percentage of the composition's own
   width, so the whole thing scales as one unit.

   HOW THE FIT IS GUARANTEED
   -------------------------
   .hero__frame is an inline-size container, and *every* length inside it is in
   cqw — container query width units. That makes the rendered height a fixed
   multiple of the frame width: height = width x --frame-ratio, where the ratio
   is the composition's own aspect. Because the ratio is known, the frame can
   simply refuse to be wider than the viewport height allows:

       width = min(available width, available height / ratio)

   so the hero always fits 100dvh exactly, at any viewport, with no overflow and
   no media-query jumps. Introducing a px or rem length inside the frame would
   break that proportionality — if you need a floor, change the ratio instead.

   Each layout has its own measured ratio. After changing the composition, run
   `node scripts/measure-hero.js` and set --frame-ratio to what it reports —
   a ratio smaller than the truth is what makes the hero overflow.

   TYPE IS SIZED BY CAP HEIGHT, NOT BY EM
   --------------------------------------
   Montserrat and Source Sans have taller capitals than the faces used in the
   source, so each font-size here is the source's cap height converted through
   the *rendered* cap height, and each margin is a cap-line-to-cap-line gap less
   the leading the font puts above its capitals. Both are solved by
   `node scripts/calibrate-hero.js` — re-run it after touching a font, a size or
   a line height, and paste back what it prints.

   REFERENCE GEOMETRY (docs/mission.png, 1536x1024)
   ------------------------------------------------
   The frame runs from the mark's left ink to the wordmark's right ink and from
   the mark's top ink to the last line of pillar text.

   Frame            x  42..1456 (1414px)   y  39..992 (953px)
   Logo mark        x  42..427   (27.23%)  y  39..501
   Lockup           x 459..1456  (67.54%)  gap between them 5.23%
     wordmark       cap  87px    y 228..314   sets to the full column width
     submark        cap  44px    y 349..392   rules 122px wide, 4px thick
     tagline        cap  27px    y 427..453
   Mission rule     y 562, 3px navy, 94.34% wide, interrupted 39px either side
   Mission label    cap  29px
   Mission text     cap  29px    y 608..757, three lines, pitch 56.5px
   Pillars          y 785..992   dividers at the quarter points, #ECEEF0
     icon           88px         y 785..873
     title          cap  15px    y 891..905
     text           19px/1.37    y 922..992

   TWO DELIBERATE DEPARTURES FROM THE SOURCE
   -----------------------------------------
   - The tagline is centred under the wordmark. In mission.png it sits 0.85% of
     the frame width left of centre, which reads as a drafting artefact.
   - The pillar columns are equal. In mission.png they are 351/338/334px, again
     a drafting artefact rather than a decision.
   ============================================================================ */

.hero {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100dvh;
  /* Fallback for browsers without dvh; dvh wins where supported. */
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: var(--hero-pad) var(--gutter);
  background: var(--bg);

  /* Vertical budget the frame may not exceed: the block padding plus the row
     reserved for the scroll indicator. Kept as a variable so the width
     calculation below and the actual box always agree. */
  --hero-pad: clamp(1rem, 2.2vh, 2.25rem);
  --hero-scroll-h: 2.75rem;
  --hero-reserve: calc(2 * var(--hero-pad) + var(--hero-scroll-h));
}

.hero__frame {
  /* Composition aspect (content height / content width), measured. */
  --frame-ratio: 0.6850;
  --frame-max: 1760px;

  width: min(
    100%,
    var(--frame-max),
    (100dvh - var(--hero-reserve)) / var(--frame-ratio)
  );
  margin-inline: auto;
  align-self: center;
  container-type: inline-size;
}

/* --- Upper band: identity ------------------------------------------------ */

.hero__identity {
  display: grid;
  grid-template-columns: 27.23cqw 67.54cqw;
  gap: 5.23cqw;
  align-items: start;
}

.hero__mark {
  width: 100%;
  height: auto;
}

.lockup {
  /* The lockup is its own container so the wordmark, submark and tagline can be
     sized against the column they share rather than against the whole frame. */
  container-type: inline-size;
  margin: 0;
  /* Every margin below places a *cap line*, not a box edge: the values are the
     gaps measured off mission.png, less the leading each font puts above its
     capitals. Solved by scripts/calibrate-hero.js — re-run it after any change
     to a font, a font size or a line height. */
  margin-top: 12.59cqw;
  font-weight: 400;
  letter-spacing: normal;
  text-wrap: wrap;
}

.lockup__wordmark {
  display: block;
  color: var(--navy);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 12.45cqw;
  line-height: 1;
  /* Tracking that makes STEEPLEJACK set to exactly the width of its column, so
     it aligns with the rules under it. Solved by scripts/calibrate-hero.js. */
  letter-spacing: 0.0608em;
  text-transform: uppercase;
  /* The trailing letter-space would otherwise push the right edge past the
     column and break alignment with the submark rule below. */
  margin-right: -0.0608em;
  white-space: nowrap;
}

.lockup__submark {
  display: flex;
  align-items: center;
  gap: 1.78cqw;
  margin-top: 1.28cqw;
}

.lockup__rule {
  flex: 0 0 12.77cqw;
  height: 0.42cqw;
  min-height: 1px;
  background: var(--orange);
}

.lockup__submark-text {
  flex: 1;
  color: var(--orange);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 6.34cqw;
  line-height: 1;
  letter-spacing: 0.42em;
  text-align: center;
  text-transform: uppercase;
  /* Centre the letters optically: without this the trailing letter-space makes
     the word sit left of the gap between the two rules. */
  text-indent: 0.42em;
  white-space: nowrap;
}

.lockup__tagline {
  display: block;
  margin-top: 2.19cqw;
  color: var(--navy);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 3.88cqw;
  line-height: 1;
  letter-spacing: normal;
  text-align: center;
  text-transform: none;
}

/* --- Middle band: mission ------------------------------------------------ */

.hero__mission {
  margin-top: 3.38cqw;
  text-align: center;
}

.mission-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2.76cqw;
  width: 94.34cqw;
  margin-inline: auto;
}

/* The navy rule runs the full width and is interrupted by the label: two
   flexing segments either side reproduce that without faking a background. */
.mission-label::before,
.mission-label::after {
  content: '';
  flex: 1;
  height: 0.212cqw;
  min-height: 1px;
  background: var(--navy);
}

.mission-label span {
  /* --orange-display is the brand orange darkened just enough to clear the 3:1
     large-text threshold; see tokens.css. Graphics keep the pure brand orange. */
  color: var(--orange-display);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 3.06cqw;
  line-height: 1;
  letter-spacing: 0.055em;
  text-indent: 0.055em;
  text-transform: uppercase;
  white-space: nowrap;
}

.mission-text {
  margin-top: 0.86cqw;
  color: var(--navy);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 2.84cqw;
  line-height: 1.41;
  letter-spacing: -0.004em;
  text-wrap: nowrap;
}

/* --- Lower band: the four pillars ---------------------------------------- */

.pillars {
  margin: 1.07cqw 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  list-style: none;
}

.pillar {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-inline: 2.2cqw;
  text-align: center;
}

.pillar + .pillar {
  border-left: 1px solid var(--rule-soft);
}

.pillar__icon {
  width: 7.60cqw;
  height: 7.60cqw;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pillar__icon .ic-navy {
  stroke: var(--navy);
  stroke-width: 5;
}

.pillar__icon .ic-navy-fill {
  fill: var(--navy);
  stroke: none;
}

.pillar__icon .ic-orange {
  stroke: var(--orange);
  stroke-width: 5;
}

.pillar__icon .ic-orange-fill {
  fill: var(--orange);
  stroke: none;
}

.pillar__title {
  /* Gaps in this band are cap-line to cap-line, like the lockup's; see
     scripts/calibrate-hero.js. */
  margin-top: 0.27cqw;
  color: var(--navy);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.55cqw;
  line-height: 1.1;
  letter-spacing: 0.045em;
  text-indent: 0.045em;
  text-transform: uppercase;
  text-wrap: balance;
}

.pillar__text {
  margin-top: 0.34cqw;
  color: var(--navy);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 1.34cqw;
  line-height: 1.37;
  text-wrap: balance;
}

/* --- Scroll indicator ---------------------------------------------------- */

.hero__scroll {
  align-self: end;
  justify-self: center;
  height: var(--hero-scroll-h);
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink-soft);
  font-family: var(--font-display);
  font-size: clamp(0.6rem, 0.55rem + 0.2vw, 0.7rem);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-decoration: none;
  text-transform: uppercase;
  transition: color var(--dur-fast) var(--ease);
}

.hero__scroll:hover {
  color: var(--navy);
}

.hero__scroll b {
  font-weight: 400;
  animation: hero-nudge 2.4s var(--ease) infinite;
}

@keyframes hero-nudge {
  0%,
  70%,
  100% {
    transform: translateY(0);
  }
  35% {
    transform: translateY(0.25rem);
  }
}

/* ============================================================================
   Stacked layout — below the desktop breakpoint
   The mark moves above the lockup and both centre; the pillars fold to 2x2.
   Same cqw technique, a different measured ratio.
   ============================================================================ */

@media (max-width: 1023px) {
  .hero__frame {
    --frame-ratio: 1.3502;
    --frame-max: 720px;
  }

  .hero__identity {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 2cqw;
  }

  .hero__mark {
    width: 26cqw;
  }

  .lockup {
    width: 100%;
    margin-top: 0;
  }

  .lockup__wordmark {
    font-size: 8.85cqw;
    text-align: center;
  }

  .lockup__submark {
    gap: 1.2cqw;
    margin-top: 1.3cqw;
  }

  .lockup__rule {
    flex: 0 0 8.7cqw;
    height: 0.3cqw;
  }

  .lockup__submark-text {
    font-size: 4.48cqw;
  }

  .lockup__tagline {
    margin-top: 2.2cqw;
    font-size: 3.4cqw;
  }

  .hero__mission {
    margin-top: 5cqw;
  }

  .mission-label {
    width: 100cqw;
    gap: 3cqw;
  }

  .mission-label span {
    font-size: 3.1cqw;
  }

  .mission-text {
    margin-top: 2.6cqw;
    font-size: 3.5cqw;
    line-height: 1.3;
    text-wrap: balance;
  }

  /* Below the desktop breakpoint the mission statement reflows naturally. */
  .mission-text br {
    display: none;
  }

  .pillars {
    margin-top: 5cqw;
    grid-template-columns: repeat(2, 1fr);
    row-gap: 4.5cqw;
  }

  .pillar {
    padding-inline: 3cqw;
  }

  .pillar + .pillar {
    border-left: 0;
  }

  /* With a 2x2 grid only the right-hand column carries a divider, and a single
     horizontal rule separates the rows. */
  .pillar:nth-child(2n) {
    border-left: 1px solid var(--rule-soft);
  }

  .pillar:nth-child(n + 3) {
    padding-top: 4.5cqw;
    border-top: 1px solid var(--rule-soft);
  }

  .pillar__icon {
    width: 9cqw;
    height: 9cqw;
  }

  .pillar__title {
    margin-top: 2cqw;
    font-size: 2.5cqw;
  }

  .pillar__text {
    margin-top: 1.6cqw;
    font-size: 2.25cqw;
  }
}

/* Phones are proportionally far taller than tablets, so the same 2x2 layout is
   set larger relative to the frame — otherwise the composition fits inside
   100dvh with a third of the viewport left empty beneath it. */
@media (max-width: 560px) {
  .hero__frame {
    --frame-ratio: 1.7460;
  }

  .hero__mark {
    width: 34cqw;
  }

  .lockup__wordmark {
    font-size: 11.4cqw;
  }

  .lockup__submark {
    margin-top: 0.85cqw;
  }

  .lockup__rule {
    flex: 0 0 11.2cqw;
  }

  .lockup__submark-text {
    font-size: 5.77cqw;
  }

  .lockup__tagline {
    margin-top: 2.6cqw;
    font-size: 4.2cqw;
  }

  .hero__mission {
    margin-top: 6cqw;
  }

  .mission-label span {
    font-size: 3.9cqw;
  }

  .mission-text {
    margin-top: 3cqw;
    font-size: 4.4cqw;
  }

  .pillars {
    margin-top: 6cqw;
    row-gap: 5.5cqw;
  }

  .pillar__icon {
    width: 11.5cqw;
    height: 11.5cqw;
  }

  .pillar__title {
    margin-top: 2.4cqw;
    font-size: 3.15cqw;
  }

  .pillar__text {
    margin-top: 1.8cqw;
    font-size: 2.85cqw;
  }

  .pillar:nth-child(n + 3) {
    padding-top: 5.5cqw;
  }
}

/* Tall phones have room for a single column, which reads better than 2x2. On
   short ones the grid stands, because fitting the viewport is the harder
   constraint. */
@media (max-width: 560px) and (min-height: 740px) {
  .hero__frame {
    --frame-ratio: 2.2520;
  }

  .pillars {
    grid-template-columns: 1fr;
    row-gap: 3cqw;
  }

  .pillar:nth-child(2n) {
    border-left: 0;
  }

  .pillar:nth-child(n + 2) {
    padding-top: 3cqw;
    border-top: 1px solid var(--rule-soft);
  }

  .pillar:nth-child(n + 3) {
    padding-top: 3cqw;
  }

  .pillar__icon {
    width: 12cqw;
    height: 12cqw;
  }

  .pillar__title {
    margin-top: 2.4cqw;
    font-size: 3.4cqw;
  }

  .pillar__text {
    margin-top: 1.8cqw;
    font-size: 3.1cqw;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__scroll b {
    animation: none;
  }
}
