/* ==================================================================
   The city — one continuous world behind the whole About page.

   Reference is val.town, studied properly this time. What it actually
   does, top to bottom:

     - a warm, slightly-off-white ground, never pure white
     - PALE DIAGONAL BANDS crossing the page at a shallow angle and
       repeating down it — the streets
     - simple illustrated pieces standing along those bands, cropped
       by the page edges: buildings, trees, lamps, a van, and little
       figures walking about
     - density that BREATHES: sparse behind the reading, and a full
       street scene as the footer approaches

   The last one is the part that is easy to miss and is most of why it
   works. A background at constant density is wallpaper; one that opens
   out and closes in is a place you are travelling through.

   Everything here is either CSS or a transparent cut-out, so it costs
   almost nothing and rescales to any page length.

   LAYERING — easy to break, so it is written down:
     z 0  .city        ground, streets, pieces
     z 1  .wd--hero    opaque; the city begins where it ends
     z 2  .tk sections transparent, so the city shows through
     z 3  .tk__in      the copy
   ================================================================== */

main.ab{ position: relative; }

/* ==================================================================
   The opening band.

   The previous hero was a wide cut-out strip pinned to the bottom of
   the band with the copy floating in white above it. This artwork is a
   different animal: a full 21:9 composition that carries its OWN sky,
   with the city massed to the right and bottom and open sky deliberately
   left in the upper left. So it fills the whole band and the copy sits
   in the sky the illustration already provides, rather than in white
   space the layout has to reserve.
   ================================================================== */

.hero2{
  position: relative;
  overflow: hidden;
  /* A GRID, not arithmetic. The copy takes the height it needs and the
     artwork row takes exactly what is left, so the opening is always
     precisely one screen and the city always lands on the bottom edge of
     the viewport — at any window size, with any length of headline.
     Computing a --band by hand meant the sum was 2% out on some screens
     and the art stopped short of the fold. */
  min-height: 100svh;
  display: grid;
  /* ONE explicit column. Without it, the moment the artwork spans both
     rows (short screens, below) it can no longer share a cell with the
     copy, and auto-placement quietly invents a second column — the art
     got 378px of a 1280px hero and the right half of the screen went
     white. A single named column keeps both children stacked. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(14rem, 1fr);
  background: #fff;
  z-index: 1;
}
.hero2__in{
  /* Both children are pinned to column 1 so they OVERLAP rather than sit
     side by side. Without the explicit column, an item spanning every row
     fills column 1 and grid politely invents a column 2 for the other. */
  grid-row: 1; grid-column: 1;
  /* STRETCH, not shrink-to-fit. As a grid item this was sizing to its
     own longest line and then centring that box, so the left edge of
     the headline landed wherever the text happened to end — 498px in,
     while every section label below starts at 200px. Nothing lined up
     with anything, which is exactly what read as "random". Stretched,
     .wrap's own max-width and auto margins put the opening on the same
     column as the rest of the page. */
  justify-self: stretch; width: 100%;
  /* Clears the floating nav pill with room to spare. At 11vh a 900px
     window put the eyebrow at 77px and the pill's own bottom edge at
     81px — the opening line and the navigation were on the same line. */
  padding-top: clamp(7.5rem, 15vh, 10rem);
  padding-bottom: clamp(1.25rem, 3vh, 2.25rem);
  position: relative; z-index: 3;
}
.hero2__art{
  /* Spans the whole hero and sits on its bottom edge. The BOX carries the
     artwork's own aspect ratio, so the image is drawn complete: there is
     no box for it to be cropped into. Everything above it is the sky the
     illustration already contains, which is where the copy goes. */
  grid-row: 1 / -1; grid-column: 1;
  align-self: end;
  position: relative;
  width: 100%; height: auto;
  aspect-ratio: 1200 / 923;          /* the phone crop; desktop overrides */
  min-height: 0; min-width: 0;
  z-index: 0; pointer-events: none;
}
.hero2__art img{
  position: absolute; inset: 0;
  display: block;
  width: 100%; height: 100%;
  /* CONTAIN, not cover. The box already matches the file's ratio, so this
     draws it edge to edge — but if the two ever drift apart it letterboxes
     by a pixel instead of silently slicing the top off the city. */
  object-fit: contain;
  object-position: center bottom;
}
.hero2__art::before{
  content: "";
  /* Only deep enough to soften where the copy actually lands, and it
     runs out well above the skyline. It used to be a 62% curtain at 97%
     white, which greyed the towers and the gantry — the artwork was
     being dimmed to solve a legibility problem the composition does not
     have, because the copy sits over the illustration's own empty sky. */
  position: absolute; inset: 0 0 auto 0; height: 26%;
  background: linear-gradient(180deg,
    rgba(255,255,255,.78) 0%, rgba(255,255,255,.34) 58%, rgba(255,255,255,0) 100%);
  z-index: 2;
}

.hero2__eyebrow{
  font-family: var(--display); font-weight: 700;
  font-size: .76rem; letter-spacing: .24em; text-transform: uppercase;
  color: var(--coral); margin: 0 0 clamp(.7rem, 1.4vw, .95rem);
}
.hero2__h{
  font-family: var(--display); font-weight: 600;
  font-size: clamp(2rem, 3.4vw, 3rem);
  line-height: .98; letter-spacing: -.04em;
  color: var(--ink); margin: 0; max-width: 13ch; text-wrap: balance;
}
.hero2__p{
  margin: clamp(.85rem, 1.6vw, 1.1rem) 0 0; max-width: 40ch;
  /* The opening sub-line reads as one block with the headline above it, so it
     takes the headline's ink rather than the muted body blue-grey. --ink-2 is
     right for running copy further down the page; up here it made the second
     line look faded next to the first. */
  color: var(--ink);
  font-size: clamp(.95rem, 1vw, 1.02rem); line-height: 1.6;
  text-wrap: balance;
}
.hero2__cta{ display: flex; flex-wrap: wrap; gap: .65rem; margin-top: clamp(1.25rem, 2.2vw, 1.65rem); }
.hero2__cta .btn{ font-weight: 700; font-size: .92rem; padding: .82rem 1.4rem;
  box-shadow: 0 10px 24px rgba(226,96,74,.28); }
.hero2__ghost{
  display: inline-block; text-decoration: none;
  font-family: var(--display); font-weight: 700; font-size: .92rem;
  padding: calc(.82rem - 1.5px) calc(1.4rem - 1.5px);
  border: 1.5px solid var(--line); border-radius: 999px;
  color: var(--ink); background: #fff;
  transition: border-color .25s ease, background .25s ease;
}
.hero2__ghost:hover{ border-color: var(--ink); background: var(--paper-2); }

/* A SHORT window cannot hold the full-size opening type and an uncropped
   band at the same time. The band's height is locked to the artwork's
   ratio, so it cannot give — which means the type is what steps down,
   rather than the artwork being sliced. Same move about.css makes for the
   old hero. */
/* --------------------------------------------------------------
   DESKTOP — the wide crop, drawn whole.

   Earlier versions fitted the city to a leftover band with `cover`,
   which meant every screen sliced something off the top: at 1280x720
   it took 21% and beheaded the rocket. No crop of the FILE fixes that,
   because trimming the file's top and cover-trimming are the same
   operation. So the band stopped being a fixed height at all — it is
   the artwork's own ratio, pinned to the bottom of the screen, and the
   copy overlaps its upper LEFT, where the illustration is clouds and
   open sky. The tall work — gantry, rocket, spire, balloon — all lives
   in the right 40%, so nothing has to be dimmed or cut for the type.
   -------------------------------------------------------------- */
@media (min-width: 761px){
  .hero2__art{ aspect-ratio: 2600 / 1081; }

  /* The opening line runs ON ONE LINE. Sized in vw with nowrap, so it
     cannot break: both the type and the column scale with the window, and
     at the clamp ceiling (84px in an 1120px column) the line is ~830px —
     it still has room. Breaking "We're Hello / Rocket." across two lines
     was what made the opening look small and cramped. */
  .hero2__h{
    /* Two lines, broken after "We're" by a <br> in the markup. The
       longest line is now 13 characters instead of 19, which buys a much
       larger size in the same column. nowrap stays so neither line can
       pick up a break of its own. */
    /* Capped by HEIGHT as well as width. On a short window 7.6vw alone
       pushed the lead down onto the cloud line; the headline has to know
       how much screen it is standing in, not just how wide it is. */
    font-size: min(clamp(3rem, 7.6vw, 8.5rem), 11.5vh);
    line-height: .95; letter-spacing: -.045em;
    max-width: none; white-space: nowrap;
  }
  .hero2__p{
    font-size: clamp(1.08rem, 1.4vw, 1.42rem);
    line-height: 1.55; max-width: 42ch;
    margin-top: clamp(1rem, 1.5vw, 1.35rem);
  }
  .hero2__eyebrow{ font-size: .82rem; margin-bottom: clamp(.9rem, 1.6vw, 1.2rem); }
  .hero2__cta{ margin-top: clamp(1.5rem, 2.4vw, 2rem); }
  .hero2__cta .btn, .hero2__ghost{ font-size: 1.02rem; padding: 1rem 1.7rem; }
  .hero2__ghost{ padding: calc(1rem - 1.5px) calc(1.7rem - 1.5px); }
}

/* Ultra-wide, short windows are the one case where a full-width city is
   taller than the screen. Fit it by height there, still uncropped. */
@media (min-width: 761px) and (min-aspect-ratio: 12/5){
  .hero2__art{ width: auto; height: 100%; margin-inline: auto; }
}

/* A portrait tablet is served the phone crop by <picture>, so the BOX has
   to carry the phone crop's ratio too. Mismatched, `contain` did the safe
   thing and letterboxed — no slicing, but white bars above the city. This
   must stay after the desktop rule: same specificity, source order wins. */
@media (orientation: portrait) and (max-width: 1180px){
  .hero2__art{ aspect-ratio: 1200 / 923; width: 100%; height: auto; }
}

/* Height the copy does not spend is height the artwork gets, so the
   type steps down before the picture does. */
@media (min-width: 761px) and (max-height: 900px){
  .hero2__in{
    padding-top: clamp(6rem, 11.5vh, 8rem);
    padding-bottom: clamp(.75rem, 1.6vh, 1.25rem);
  }
  .hero2__p{ margin-top: .75rem; }
  .hero2__cta{ margin-top: 1rem; }
  .hero2__eyebrow{ margin-bottom: .55rem; }
}

/* Phones get the 4:3 crop around the gantry — the wide band at 390px
   renders the city too small to read as anything. */
@media (max-width: 760px){
  .hero2{
    /* Row 2 is EXACTLY the artwork's height — 100vw at the crop's ratio —
       so row 1 is precisely the space left over, and the copy is centred
       in it. Before this, the copy was pinned to the top by a fixed
       padding and every pixel the artwork gave back piled up as one dead
       band between the buttons and the city. Centring splits that slack
       above and below the copy instead of dumping it in the middle. */
    grid-template-rows: 1fr calc(100vw / 1.30);
  }
  .hero2__art{ grid-row: 2; align-self: end; }
  .hero2__in{
    grid-row: 1; align-self: center;
    /* The nav is a floating pill overlaying the top of this row, so
       centring in the raw row put the copy 65px low — exactly the pill's
       height. Padding the top by that amount hands the centring the space
       the reader can actually see. */
    /* 4.1rem is the pill's own height, which balances the block exactly:
       87px of clear space above the eyebrow and 87px below the buttons.
       The extra 2rem drops the opening line further clear of the nav —
       the block is centred, so padding moves it by half, about 16px. */
    padding-top: 6.1rem; padding-bottom: 0;
  }
  .hero2__h{
    max-width: none;
    font-size: clamp(2.5rem, 11vw, 3.4rem);
    line-height: .98;
  }
  .hero2__p{ max-width: 46ch; }
  /* One column, one width. Two auto-width pills stacked left gave the
     block a ragged right edge that read as unfinished. */
  .hero2__cta{ flex-direction: column; align-items: stretch; gap: .6rem; }
  .hero2__cta .btn, .hero2__ghost{ text-align: center; }
}

/* Short phones — an SE, or any handset once the browser chrome is counted.
   The copy exactly fills the row there, so the centring has no slack left
   and the eyebrow ends up under the nav pill. The type gives way. */
@media (max-width: 760px) and (max-height: 700px){
  /* A short phone has no height to give away. The extra 2rem that drops
     the opening line clear of the nav on a normal handset left an SE with
     6px under the buttons, so here the padding goes back to the pill's
     own height and the balance is restored. */
  .hero2__in{ padding-top: 4.1rem; }
  .hero2__h{ font-size: clamp(1.9rem, 9vw, 2.6rem); }
  .hero2__p{ font-size: .95rem; margin-top: .7rem; }
  .hero2__eyebrow{ margin-bottom: .55rem; }
  .hero2__cta{ margin-top: 1rem; gap: .5rem; }
  .hero2__cta .btn, .hero2__ghost{ font-size: .88rem; padding: .72rem 1.1rem; }
  .hero2__ghost{ padding: calc(.72rem - 1.5px) calc(1.1rem - 1.5px); }
}

/* ==================================================================
   The city behind the page — rebuilt from scratch beneath the new hero
   ================================================================== */

.city{
  position: absolute; inset: 0;
  z-index: 0; overflow: hidden; pointer-events: none;
  background: linear-gradient(180deg,
    #FFFFFF 0%, #FBFDFF 20%, #F6FAFE 52%, #FAFCFF 82%, #FFFFFF 100%);
}
.city__bands{
  position: absolute; inset: -20% -10%;
  background-image: repeating-linear-gradient(
    108deg,
    rgba(255,255,255,0)   0 clamp(320px, 36vw, 640px),
    rgba(255,255,255,.9) clamp(320px, 36vw, 640px) clamp(780px, 84vw, 1440px));
  opacity: .45;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
}
.vig{
  position: absolute; left: var(--x); top: var(--y); width: var(--w);
  transform: translate3d(0,0,0); will-change: transform;
}
.vig img{
  display: block; width: 100%; height: auto;
  filter: drop-shadow(0 16px 22px rgba(40,70,110,.10));
}
.vig--flip img{ transform: scaleX(-1); }
.vig--soft img{ opacity: .55; }

@media (prefers-reduced-motion: reduce){ .vig{ transform: none !important; } }

/* ==================================================================
   Sections go transparent

   `main > section` is required: styles.css paints every section white
   at (0,1,2) and tech.css repeats that weight for its own grounds, so
   a bare `.tk` loses to both.
   ================================================================== */

main > section.tk,
main > section.tk--wash{
  background: transparent;
  border-block-color: transparent;
}

/* Copy legibility, handled per section rather than by dimming the whole
   city: each block lays a soft plume of the ground under its own text
   column only — strongest where the words are, gone before it reaches
   the buildings. */
main > section.tk .tk__in::before{
  content: "";
  position: absolute;
  inset: -8% -16% -8% -42%;
  z-index: -1;
  /* A LINEAR wash, not a radial. The radial version was centred on the
     left where most copy sits, which left the right-hand column of any
     two-column head unprotected — the tower landed straight on it. This
     covers the whole reading width and only lets go past 72%, which is
     where the buildings start. */
  background: linear-gradient(100deg,
    rgba(252,252,252,.97) 0%,
    rgba(252,252,252,.93) 48%,
    rgba(252,252,252,.6)  70%,
    rgba(252,252,252,0)   90%);
  pointer-events: none;
}
/* the closing band sits over the densest street, so it gets a rounder,
   stronger plume centred on itself */
/* The close stands IN the street scene — that is the whole point of the
   scene being there — so its wash only has to lift the type off the
   ground, not erase what is behind it. The first version was strong
   enough to white out the entire city. */
main > section.tk-close .tk__in::before{
  inset: -6% -4%;
  background: radial-gradient(56% 58% at 50% 48%,
    rgba(252,252,252,.92) 0%, rgba(252,252,252,.6) 52%, rgba(252,252,252,0) 80%);
}

/* A section whose scene sits on the LEFT pushes its copy across, so the
   two never share the same column. This is the "change the layout of the
   words to present the background better" move — without it the scene
   has nowhere to live except under the text. */
main > section.tk--flip .tk__in{ padding-left: 44%; }

/* ==================================================================
   Smaller screens

   The copy takes the full width, so there is no clear column for a
   building to stand in. The set thins to what can sit at the very edge
   and be cropped, the streets widen so fewer bands cross the reading,
   and everything scales down.
   ================================================================== */

@media (max-width: 900px){
  main > section.tk--flip .tk__in{ padding-left: 0; }
  /* the copy runs full width on a phone, so the scenes shrink, move to the
     edges to be cropped, and fade well back */
  .vig{ width: var(--w-m, calc(var(--w) * .52)); opacity: .5; }
  .city__bands{ opacity: .3; }
}
@media (max-width: 560px){
  main > section.tk .tk__in::before{
    inset: -6% -22%;
    background: radial-gradient(82% 62% at 50% 50%,
      rgba(252,252,252,.95) 0%, rgba(252,252,252,.78) 52%, rgba(252,252,252,0) 84%);
  }
}

@media (prefers-reduced-motion: reduce){
  .pc--walk img{ animation: none; }
  .pc{ transform: none !important; }   /* the scroll handler stands down too */
}
