/* Services — a state of the hero stage, not a separate page. Requires
   base.css, hero.css and about.css.

   Clicking `services` puts `.is-services` on the section. hero.css owns the
   curtain: the mid chevron (carrying the `services` label) slides left onto
   the back chevron, the fourth chevron arrives from the right — plain this
   time, with nothing hanging off it — and the logo folds into the corner.
   The front chevron (`about`) does not move here; only `about` moves it. What
   services adds is a top-left title, a header and a four-panel grid filling
   the stage's open middle.

   Geometry is a percentage of the stage, measured off
   `references site/sections/services/services_full.png`. That mockup is a
   hand-cut paste-up of a Tailwind demo onto the about background, so it is
   evidence about *placement* only — its palette, its rounded corners and its
   nav labels are all inherited from somewhere else and none of them apply. */

.hero {
  /* The block runs wider than about's copy column, filling the stage's open
     middle between the (still-parked) front chevron and the fourth one.

     Its right edge is not a new number — it is exactly where about's copy
     column ends, so flipping between the two sections keeps one shared edge
     and the scroll rail (--rail-x: 72.42%) still clears both. Only the left
     edge is measured.

     --bento-left was pulled 5 percentage points right, from 28.1% to
     33.1%, on request (first asked at 10%, then corrected to "only just by
     5%" — the same treatment asked for on about.css's --copy-left/
     --copy-width, which stayed at the original 10%) — --bento-right is
     untouched, since it's still about's own copy-column right edge and only
     the left side was asked to narrow.

     --bento-left is now a live calc off --shift-mid, not a bare literal,
     matching the pattern products.css/events.css already use for their own
     left edge (--products-left off --shift-back, --events-left off
     --shift-quad) — about.css got the analogous treatment for its own copy
     column alongside this change, via a *new*, about-local
     --copy-left-live rather than touching --copy-left itself (see below).
     The mid chevron shifts left when `services` is entered (hero.css's
     `.hero.is-services { --shift-mid: -10cqw; }`), and without tying this
     block to that same shift, retuning --shift-mid in the future would
     silently desync the grid from the chevron it sits next to. Base is
     43.1%, not 33.1%, precisely so today's already-correct rendered
     position doesn't move: --shift-mid is always exactly -10cqw whenever
     `services` is showing, so 43.1% + (-10cqw) = 33.1%, the same value as
     before. --bento-left has no other file cross-referencing it (only
     --copy-left does, via --bento-right/--events-right just below), so it
     was safe to tie directly — no --bento-left-live needed. */
  --bento-left: calc(43.1% + var(--shift-mid));
  /* Reads about.css's --copy-left, which stays a bare literal specifically
     so this keeps working: custom properties resolve by cascade at the
     element that reads them, so if --copy-left were itself tied to
     --shift-front, this line (evaluated inside .is-services, where
     --shift-front is always the base 0cqw, not about's -9cqw) would land
     9 points too far right. See about.css's own --copy-left comment. */
  --bento-right: calc(var(--copy-left) + var(--copy-width));
  /* Aligned to about's copy column's own top (about.css's --copy-top, 18%),
     on request — was 22.4%. */
  --bento-top: 18%;
  /* Bottom edge (--grid-top + --grid-height) aligned to about's copy column
     bottom (--copy-left's --copy-top 18% + --copy-height 61% = 79%), on
     request — was 32.5% (bottom 71%). Then reduced 10% on request (40.5% ->
     36.45%), top edge held fixed, so only the bottom edge moved up. Then a
     top margin was requested (first 5%, corrected down to 2%) — since the
     grid is absolutely positioned (a literal margin-top here would resolve
     against the container's width, not height, per this file's own
     percentage-margin gotcha), it is added directly to --grid-top instead
     (38.5% -> 40.5%), pushing the whole grid down by that amount. */
  --grid-top: 40.5%;
  --grid-height: 36.45%;

  /* Gutter between panels, and the padding inside them.

     In vw, not in percentages. A percentage column-gap resolves against the
     grid's own width but a percentage row-gap resolves against its height, so
     one number would draw two different gutters; and a percentage padding
     resolves against width even for its top and bottom. The stage is
     full-bleed, so 1vw is 1% of it — the same reason --shift-front is in vw —
     and one value in vw draws a gutter that is genuinely square. */
  --bento-gutter: 0.8cqw;
  /* The two narrow panels are a quarter of the block wide, so they carry less
     padding than the lead panel or the figure inside them has nowhere to go. */
  --card-pad: 1.9cqw;
}

/* ---------- Laptop tier ----------

   Laptop-only geometry (aspect <= 1.85:1 — see hero.css's own "Sub-page
   content geometry" comment, once one exists, for the shared threshold;
   see about.css's own "Laptop tier" block for the fuller rationale, first
   introduced there this session). Outside this range the section falls
   back to --bento-left/--bento-right just above, i.e. today's
   pre-this-session geometry. */
@media (max-aspect-ratio: 1.85/1) {
  .hero {
    /* Both edges pushed right as a pure translate, on request ("move the
       whole column by 5% right", corrected to "only by 4%", then "only by
       3%") — width (right minus left) unchanged. */
    --bento-left: calc(43.1% + var(--shift-mid) + 3%);
    --bento-right: calc(var(--copy-left) + var(--copy-width) + 3%);
  }
}

/* Turns on services' own layer; the base `.section-layer` rule is in hero.css.
   Nothing here reaches right of the fourth chevron's apex, so unlike about's
   gallery no panel has to be cut against the chevron's diagonal. */
.is-services .services-layer {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--ease-fade) var(--delay-settle),
    visibility 0s linear var(--delay-settle);
}

/* `services` is the current section once it lands on the back chevron's
   point, so it stops being a link there. `products` stays visible underneath
   it. The transform + transition that carries it there live on the
   unconditional `.hero-nav__link--services` rule in hero.css (mirroring
   `.hero-nav__link--about` in about.css) — that rule now delays `opacity`
   for the *leaving* direction, so this rule restates the eased transition to
   keep entering's fade-out-while-travelling unchanged. */
.is-services .hero-nav__link--services {
  opacity: 0;
  pointer-events: none;
  transition: transform var(--ease-move), opacity var(--ease-move),
    color var(--ease-ui);
}

/* ---------- Header ---------- */

.services__head {
  position: absolute;
  left: var(--bento-left);
  top: var(--bento-top);
  width: calc(var(--bento-right) - var(--bento-left));
  text-align: left;
}

/* Top-left, same 11.2% top / face / size / tracking `.about__title` uses —
   a sibling of `.services__head`, not nested inside it, the same
   relationship `.about__title` has to `.about__copy`. Anchored at
   `--bento-left`/`--bento-right`, the same span the grid below uses, so the
   title's left edge lines up with the grid's rather than sitting further
   right at `--copy-left`. This used to sit at `--copy-left` instead, to
   clear the still-parked front chevron's upper edge, which grazed the last
   letter at `--bento-left` — moot now that `.arrow--front` fades to opacity 0
   for `services` (see hero.css) rather than just parking there. */
.services__title {
  position: absolute;
  left: var(--bento-left);
  top: 11%;
  width: calc(var(--bento-right) - var(--bento-left));
  margin: 0;
  font-family: var(--font-utility);
  font-size: var(--size-heading);
  font-weight: normal;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--paper);
}

/* Full width of `.services__head` (itself already the grid's own span), not
   the previous 74%-and-centered column — matching the grid's width exactly
   rather than floating narrower inside it. */
.services__lead {
  margin: 1.4cqh 0 0;
  max-width: 100%;
  font-family: var(--font-utility);
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--paper);
}

/* ---------- Grid ---------- */

/* Four panels on a four-column grid. The lead panel takes the left half and
   the full height; the two small ones sit on the top right; the call to action
   spans the bottom right. Rows are 1.39:1, which is where the mockup puts the
   join. */
.services__grid {
  position: absolute;
  left: var(--bento-left);
  top: var(--grid-top);
  width: calc(var(--bento-right) - var(--bento-left));
  height: var(--grid-height);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  /* minmax(0, ...) and not a bare fr: an fr track floors at its content's
     height, so a panel whose copy runs one line long silently pushes the whole
     grid past --grid-height and out of its band instead of showing that
     something needs shortening. */
  grid-template-rows: minmax(0, 1.39fr) minmax(0, 1fr);
  gap: var(--bento-gutter);
}

/* Square corners, like every other panel on the site — the gallery tile, the
   lightbox frame and its tabs are all hard-edged, and the chevron the whole
   page is built from has no curve in it anywhere.

   The shadow is deliberately tight and biased downward. Panels sit a gutter
   apart, and a shadow spreads in every direction: a wide one would wash the
   neighbouring panel off --panel-gallery, which is the failure the docs
   describe under "a panel is subtly the wrong shade of blue". */
.services-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--card-pad);
  background: var(--panel-gallery);
  box-shadow: 0 0.5cqh 0.9cqw rgba(var(--shadow-ink), 0.22);
}

/* Now a full-bleed photo rather than a headline + list, on request — padding
   drops to 0 so the image reaches every edge of the panel, the same
   edge-to-edge treatment .products-card__image uses. */
.services-card--lead {
  grid-column: span 2;
  grid-row: span 2;
  padding: 0;
  overflow: hidden;
}

.services-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.services-card--stat,
.services-card--note {
  justify-content: center;
  gap: 1.6cqh;
}

/* ---------- Panel type ---------- */

.services-card__name {
  margin: 0;
  font-family: var(--font-utility);
  font-size: var(--size-body);
  font-weight: normal;
  line-height: 1.15;
  color: var(--paper);
}

.services-card__meta {
  margin: 0;
  font-family: var(--font-utility);
  font-size: var(--size-caption);
  line-height: var(--lh-caption);
  color: var(--paper);
}

/* ---------- Call to action ---------- */

/* The only thing on this screen you can click, so it is the only panel that
   answers to a pointer. */
.services-card--cta {
  grid-column: span 2;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--card-pad);
  --card-pad: 1.5cqw;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--ease-ui);
}

/* `.services-card--cta:hover` background and the `.services-card__go`
   plate/chevron (including its hover/active nudge) moved to base.css's
   "Card CTA chevron" section 2026-09-16 — byte-identical to
   `.events-card--cta`/`.events-card__go`, so shared from one place
   instead of duplicated per file. This rule (the CTA card's own layout)
   stays here since its `gap` reads a locally-scoped `--card-pad`
   override that `.events-card--cta` doesn't share the name of. */

.services-card__copy {
  display: flex;
  flex-direction: column;
  gap: 1.6cqh;
}

/* ---------- Mobile flow ---------- */

@media (max-width: 1024px), (max-aspect-ratio: 1/1) {
  .services__head,
  .services__title,
  .services__grid {
    position: static;
    left: auto;
    top: auto;
    width: 100%;
  }

  /* Only the title (the section's first element) needs top clearance for
     the fixed mobile header — `.services__head` doesn't, matching
     products.css's own `.products__title`/`.products__head` split. Giving
     both their own 6vh top padding (the previous rule here) stacked the
     header's clearance on top of the title-to-lead gap a second time. */
  .services__head {
    padding: 0 5vw;
  }

  .services__title {
    padding: 6vh 5vw 0;
  }

  .services__grid {
    height: auto;
    padding: 3vh 5vw 5vh;
    grid-template-columns: 1fr;
    grid-template-rows: none;
    gap: 3vh;
  }

  /* A single column has no second row/column to span into — reset both so
     the lead/cta cards don't leave phantom empty grid cells. */
  .services-card--lead,
  .services-card--cta {
    grid-column: auto;
    grid-row: auto;
  }

  /* Relied on the grid cell's implicit height on desktop; needs its own
     ratio now that the card's height is just its content's. */
  .services-card--lead .services-card__image {
    aspect-ratio: 4 / 3;
  }

  .services-card--cta {
    flex-direction: row;
  }

  /* Plain, non-interactive box on mobile/tablet — no link, no red arrow
     chevron (removed on request; about.js also skips the goTo() navigation
     for this card whenever `!stageQuery.matches`). */
  .services-card--cta {
    cursor: default;
    pointer-events: none;
  }

  .services-card__go {
    display: none;
  }
}

/* Tablet tier: same single-column stack as phone, above, with content
   running near-full-width (a flat 32px side gutter, not a centered
   narrower column — a wide, centered `max-width` column was tried first
   and reverted on request: it read as too much dead margin on a
   768-1024px screen) and grid/card spacing scaled up for the larger
   screen. First pass, no tablet reference exists yet. */
@media (min-width: 768px) and (max-width: 1024px) {
  .services__head {
    padding: 0 32px;
  }

  .services__title {
    padding: 8vh 32px 0;
  }

  .services__grid {
    padding: 4vh 32px 6vh;
    gap: 3.5vh;
  }

  .services-card {
    padding: 2.4vw;
  }

  .services-card--lead .services-card__image {
    aspect-ratio: 16 / 10;
  }
}
