/* ==========================================================================
   Marble Consulting Group — section layer, part 2

   Split from sections.css after an editing mistake truncated that file and
   silently removed three whole sections' styles. Small files that are written
   whole, rather than appended to repeatedly, are much harder to damage.
   ========================================================================== */

/* ==========================================================================
   06 WHY BRANDS WORK WITH US - "the screen"   (.fold, index.html)

   A FOLDING SCREEN OF FOUR LEAVES, standing in a shallow concave arc with the
   reader at the focus of the curve. One leaf per claim, each with its own
   photograph, all four at the same size and the same reading distance.

   WHY AN ARC AND NOT A ROW OF CARDS. Cards sit in a plane and read as four
   separate objects; leaves are facets of one surface. They share creases,
   they take light unevenly because they face different ways, and the whole
   object answers the pointer as a single thing. Four statements, one
   standard - made structural instead of stated.

   THE ARC IS DECLARED HERE AND NOWHERE ELSE. Every leaf's geometry is
   interpolated in CSS between a CLOSED pose (steep, far back, pulled toward
   the centre) and its REST pose in the open arc, driven by one scalar per
   leaf: --fold-open. motion.js tweens that single number from 0 to 1 on arrival
   and touches nothing else about the fold. So the stylesheet owns the
   finished section, --fold-open rests at 1, and with no JavaScript, reduced
   motion, or a dead CDN what renders is the open screen rather than a stage
   waiting for its cue.

   LIGHT IS THE ANIMATION. Every other cinematic section on the homepage moves
   on an axis - the worlds push Z, the forge turns an object, the ascent
   climbs Y. This one holds its geometry and rakes LIGHT across the folded
   surface instead: --fold-lit runs 0..1 per leaf and drives both the shade that
   sits on its photograph and the sheen that comes off it. The rest values
   below are a plain frontal light on a concave arc - the two centre leaves
   face the reader and are bright, the two outer leaves are turned away and
   fall off - so even with no JavaScript the screen is lit like an object
   rather than flat like a page.

   --fold-lit NEVER TOUCHES TEXT. It is applied inside .fold__plate only.
   Running a 0.6-opacity shade over --ink body copy on the outer leaves would
   have taken them under AA; the photograph can lose luminance, the statement
   cannot.

   EVERY PROPERTY THIS SECTION OWNS IS PREFIXED --fold-, and that is not
   tidiness. The first draft called them --lit, --open, --rule and --pitch,
   and editorial-1b.css registers `@property --lit { inherits: false }` for
   the lane hairlines. A registered non-inheriting property does not reach a
   descendant, so --lit set on a leaf arrived at its own .fold__shade as the
   registered initial value of 0 and the light did not exist - silently, with
   no error anywhere. Names in this file are global; treat them as such.
   ========================================================================== */
.fold {
  position: relative;
  padding-block: clamp(2.25rem, 1.8rem + 2vw, 3.75rem);
}

/* The backdrop clips ITSELF rather than the section clipping everything.
   On a pointer lean the outer leaves project a dozen pixels past the
   container, and an overflow:hidden on .fold would shear that edge off. */
.fold__bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}
.fold__aura {
  position: absolute;
  left: 50%;
  top: 46%;
  width: min(120rem, 150%);
  aspect-ratio: 2 / 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    closest-side,
    rgba(184, 145, 88, 0.085),
    rgba(184, 145, 88, 0.03) 46%,
    transparent 72%
  );
}
.fold__ghost {
  position: absolute;
  right: -1.5%;
  bottom: 4%;
  font-size: clamp(3.5rem, 10vw, 9rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(156, 120, 72, 0.085);
  user-select: none;
}

.fold__head {
  position: relative;
  z-index: 1;
  max-width: 48rem;
}
.fold__h {
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.4rem);
  letter-spacing: -0.028em;
  text-wrap: balance;
}
.fold__h em { color: var(--gold-light); font-style: italic; }

/* the key. The swatch is the SAME 2px vertical rule that marks each statement
   on the leaves, at the same two colours, so the mapping is read rather than
   remembered. */
.fold__key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  margin-top: clamp(0.9rem, 0.75rem + 0.5vw, 1.2rem);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.fold__k {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.fold__k i {
  width: 2px;
  height: 0.9rem;
  border-radius: 2px;
  flex: none;
}
.fold__k--them { color: var(--vein); }
.fold__k--them i { background: rgba(168, 160, 150, 0.3); }
.fold__k--us { color: var(--gold-light); }
.fold__k--us i { background: linear-gradient(180deg, var(--gold-light), var(--gold-shadow)); }

.fold__stage {
  position: relative;
  z-index: 1;
  margin-top: clamp(1.4rem, 1.1rem + 1.4vw, 2.25rem);
}
.fold__screen {
  display: flex;
  align-items: stretch;
  list-style: none;
  margin: 0;
  padding: 0;
}
.fold__leaf { min-width: 0; }
.fold__face {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  /* the stone the leaf is cut from. The gold in the wash is tied to --fold-lit, so
     the surface itself warms and cools with the light crossing it. */
  background:
    linear-gradient(
      180deg,
      rgba(184, 145, 88, calc(0.05 * var(--fold-lit, 0.6))),
      transparent 42%
    ),
    linear-gradient(180deg, var(--surface-2), var(--obsidian-raised));
}

/* the photograph, and the only thing --fold-lit is allowed to touch */
.fold__plate {
  position: relative;
  display: block;
  flex: none;
  overflow: hidden;
  background: var(--obsidian);
}
.fold__lens {
  position: absolute;
  inset: 0;
  display: block;
  will-change: transform;
}
.fold__img {
  position: absolute;
  left: 0;
  top: -6%;
  width: 100%;
  height: 112%;
  object-fit: cover;
  object-position: 50% 42%;
  filter: saturate(0.94) contrast(1.05);
  will-change: transform;
}
/* raised on arrival and burnt off; invisible at rest so with no JS the
   photograph is already developed */
.fold__burn {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: rgb(var(--scrim-rgb) / 0.94);
}
.fold__shade,
.fold__sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* THE FLOOR ON THIS IS SET BY THE PHOTOGRAPHS, not by the lighting model. A
   turned-away facet wants to be dark, but these are already low-key images on
   a near-black ground: at the first values here the two outer photographs
   went to mud and the section stopped being half pictures. The shade tops out
   around 0.37 of black at its darkest edge, which still reads unmistakably as
   a facet turned out of the light. */
.fold__shade {
  background: linear-gradient(
    var(--fold-rake, 90deg),
    rgba(6, 6, 8, 0.72),
    rgba(6, 6, 8, 0.22) 58%,
    rgba(6, 6, 8, 0.44)
  );
  opacity: calc(0.72 - 0.6 * var(--fold-lit, 0.6));
}
.fold__sheen {
  background: linear-gradient(
    var(--fold-rake, 90deg),
    rgba(255, 240, 212, 0) 8%,
    rgba(255, 240, 212, 0.14) 46%,
    rgba(255, 240, 212, 0.02) 76%,
    transparent 100%
  );
  opacity: calc(0.16 + 0.6 * var(--fold-lit, 0.6));
}

.fold__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: clamp(0.95rem, 0.8rem + 0.5vw, 1.3rem) clamp(0.9rem, 0.75rem + 0.5vw, 1.2rem)
    clamp(1.1rem, 0.95rem + 0.5vw, 1.4rem);
}
.fold__topic {
  font-size: clamp(1rem, 0.94rem + 0.32vw, 1.18rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--white);
  margin-bottom: clamp(0.65rem, 0.55rem + 0.3vw, 0.9rem);
}
.fold__them,
.fold__us {
  position: relative;
  padding-left: 0.85rem;
  font-size: clamp(0.84rem, 0.81rem + 0.16vw, 0.94rem);
  line-height: 1.58;
  text-wrap: pretty;
}
/* --fold-rule rests at 1, so the no-JS screen is fully ruled */
.fold__them::before,
.fold__us::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.3em;
  bottom: 0.26em;
  width: 2px;
  border-radius: 2px;
  transform: scaleY(var(--fold-rule, 1));
  transform-origin: 50% 0;
}
/* THE TWO BANDS ARE HELD ON ONE LINE ACROSS ALL FOUR LEAVES, which is what
   makes the key under the heading readable across the whole screen rather
   than leaf by leaf. Each statement RESERVES ITS WORST CASE IN LINES, so a
   longer answer on one leaf lengthens nothing and moves nothing. The
   reservations are per breakpoint because the count changes with the column:
   see the arc block below. Bottom-aligning the two instead was tried first,
   and is what put one leaf's answer 23px above its neighbours'. */
.fold__them {
  color: var(--vein);
  min-height: calc(2 * 1.58em);
}
.fold__them::before { background: rgba(168, 160, 150, 0.3); }
/* border-box is on globally, so the padding has to be added back or the
   reservation is a line and a half rather than three lines */
.fold__us {
  padding-top: clamp(0.7rem, 0.6rem + 0.3vw, 0.95rem);
  color: var(--ink);
  min-height: calc(3 * 1.58em + clamp(0.7rem, 0.6rem + 0.3vw, 0.95rem));
}
.fold__us::before {
  top: calc(0.3em + clamp(0.7rem, 0.6rem + 0.3vw, 0.95rem));
  background: linear-gradient(180deg, var(--gold-light), var(--gold-shadow));
}

.fold__cta {
  position: relative;
  z-index: 1;
  margin-top: clamp(1.4rem, 1.1rem + 1vw, 2.1rem);
}

.fold__hint {
  display: none;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--vein);
}
.fold__hint svg { color: var(--gold); }

/* --------------------------------------------------------------------------
   PHONE AND SMALL TABLET: the fold flattens into a snapping rail.

   Four stacked blocks with photographs is 1300px of scrolling on a phone,
   which is the single thing this section exists to avoid. As a rail the
   section stays ONE screen tall: the next leaf is deliberately left peeking
   past the right edge, which is the affordance, and the hint under it says so
   in words for anyone who does not read the peek.
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {
  .fold__ghost { display: none; }
  .fold__stage { margin-inline: calc(var(--gutter) * -1); }
  .fold__screen {
    gap: 0.7rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    padding-inline: var(--gutter);
    scroll-padding-inline: var(--gutter);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .fold__screen::-webkit-scrollbar { display: none; }
  .fold__leaf {
    flex: 0 0 min(76vw, 19.5rem);
    scroll-snap-align: start;
  }
  /* separate objects on a rail, so here they DO carry an edge */
  .fold__face {
    border: 1px solid var(--border-neutral);
    border-radius: var(--radius-md);
  }
  .fold__plate { aspect-ratio: 16 / 10; }
  .fold__hint { display: inline-flex; margin-inline: var(--gutter); }
  /* on a flat rail every leaf faces the reader, so they are lit alike */
  .fold__leaf { --fold-lit: 0.72; }
}

/* --------------------------------------------------------------------------
   THE ARC. From 900px up the leaves stand in space.

   Each leaf's pose is interpolated between CLOSED and REST by --fold-open, and
   every magnitude below is written POSITIVE with a --fold-dir of 1 or -1 for the
   side it stands on. That is not decoration: it keeps the calc() free of
   "- -13" style double signs, which is where this kind of expression breaks.

   The four rest angles and depths are measured, not picked. At the section's
   own perspective, a 283px leaf turned 13 degrees and set back 54px projects
   about 8px narrower than its layout box - so the 12px crease between leaves
   OPENS to roughly 20px rather than closing, and no leaf can ever overlap its
   neighbour however the screen is leaned.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .fold__stage {
    perspective: clamp(1200px, 100vw, 1800px);
    perspective-origin: 50% 46%;
  }
  .fold__screen {
    /* the creases. Wider than it looks it needs to be, because perspective
       eats it: the two centre leaves are nearest the reader and project
       OUTWARD over their layout boxes, so the middle crease closes to about a
       third of this value at 920px. The floor is set from that measurement,
       not from the look of the number. */
    gap: clamp(0.6rem, 0.95vw, 1rem);
    transform-style: preserve-3d;
    transform: rotateY(var(--fold-yaw, 0deg)) rotateX(var(--fold-pitch, 0deg));
    will-change: transform;
  }

  .fold__leaf {
    flex: 1 1 0;
    --fold-open: 1;
    --fold-ry: calc(
      var(--fold-dir) * (var(--fold-a-rest) * var(--fold-open) + var(--fold-a-shut) * (1 - var(--fold-open))) * 1deg
    );
    --fold-tx: calc(-1px * var(--fold-dir) * var(--fold-x-shut) * (1 - var(--fold-open)));
    --fold-tz: calc(-1px * (var(--fold-z-rest) * var(--fold-open) + var(--fold-z-shut) * (1 - var(--fold-open))));
    transform: translate3d(var(--fold-tx), 0, var(--fold-tz)) rotateY(var(--fold-ry));
    will-change: transform;
  }
  /* outer pair: turned hardest, set deepest, lit least */
  .fold__leaf:nth-child(1),
  .fold__leaf:nth-child(4) {
    --fold-a-rest: 13;
    --fold-a-shut: 46;
    --fold-x-shut: 130;
    --fold-z-rest: 54;
    --fold-z-shut: 250;
    --fold-lit: 0.42;
  }
  /* inner pair: nearly square to the reader, so nearly fully lit */
  .fold__leaf:nth-child(2),
  .fold__leaf:nth-child(3) {
    --fold-a-rest: 4.4;
    --fold-a-shut: 30;
    --fold-x-shut: 44;
    --fold-z-rest: 6;
    --fold-z-shut: 190;
    --fold-lit: 0.86;
  }
  .fold__leaf:nth-child(1),
  .fold__leaf:nth-child(2) { --fold-dir: -1; }
  .fold__leaf:nth-child(3),
  .fold__leaf:nth-child(4) { --fold-dir: 1; }

  /* light comes from the middle of the arc, so the two halves rake opposite
     ways and the creases catch it from the inside */
  .fold__leaf:nth-child(1) .fold__plate,
  .fold__leaf:nth-child(2) .fold__plate { --fold-rake: 82deg; }
  .fold__leaf:nth-child(3) .fold__plate,
  .fold__leaf:nth-child(4) .fold__plate { --fold-rake: 278deg; }

  .fold__face {
    border-radius: 2px;
    /* the crease: the depth of the fold, dark on the edge that turns away and
       a hairline of caught light on the edge that turns toward the reader */
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.045),
      inset calc(var(--fold-dir) * 26px) 0 46px -30px rgba(0, 0, 0, 0.95);
  }
  .fold__leaf:nth-child(1) .fold__face,
  .fold__leaf:nth-child(2) .fold__face { border-right: 1px solid rgba(184, 145, 88, 0.14); }
  .fold__leaf:nth-child(3) .fold__face,
  .fold__leaf:nth-child(4) .fold__face { border-left: 1px solid rgba(184, 145, 88, 0.14); }

  /* THE PHOTOGRAPH IS MEASURED IN VIEWPORT HEIGHT, not in an aspect ratio.
     This section's whole promise is that all four claims are taken in at
     once, and the plate is the one part of the leaf that can give ground: at
     an aspect ratio it grew with the WIDTH of the screen, which is the axis
     that has room to spare, and pushed the section past the fold on every
     768px laptop. Tied to height it takes 23% of whatever screen it is on,
     between a floor that still reads as a photograph and a ceiling that stops
     it dominating the copy. */
  .fold__plate {
    height: clamp(9rem, 23vh, 15rem);
  }

  /* THREE LINES ARE RESERVED FOR THE USUAL ARRANGEMENT between 900 and
     1200px, because that is where the four statements DISAGREE about their
     line count. Measured across the range: at 1000px the column takes about
     25 characters and all four wrap to three lines; at 1280 it takes 38 and
     all four take two. Between them, around 1100, the two shorter statements
     fit on two lines and the two longer ones do not - so ours would start at
     two different heights on one screen. Reserving the worst case costs one
     empty line at the widths where it is not needed and costs the alignment
     nothing at the widths where it is. */
  .fold__them { min-height: calc(3 * 1.58em); }
}

/* past 1200px the column is wide enough that all four are two lines, every
   time, and the reserved third line is only air */
@media (min-width: 1200px) {
  .fold__them { min-height: calc(2 * 1.58em); }
}

/* Short screens - the 1366x768 and 1440x800 laptops, which is most of them.
   The section is trimmed rather than allowed to run past the fold: the
   photographs are already on a vh, so what is left to give back is the air
   around the type. */
@media (min-width: 900px) and (max-height: 840px) {
  .fold { padding-block: clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem); }
  .fold .eyebrow { margin-bottom: var(--space-2); }
  .fold__stage { margin-top: clamp(1.1rem, 0.9rem + 0.9vw, 1.6rem); }
  .fold__cta { margin-top: clamp(1rem, 0.85rem + 0.6vw, 1.4rem); }
}

/* ==========================================================================
   08 IN THEIR WORDS   (.voices, index.html)

   Three cards across, sitting after the team so a visitor meets the people
   before they read what anyone says about them.

   THE SAMPLE FLAG IS DELIBERATELY UGLY-ADJACENT. It is a small gold-bordered
   tag on every placeholder card, because a placeholder that looks finished is
   how a fake testimonial reaches production. Deleting the .quote__flag span
   and swapping .quote--sample for .quote turns a slot into a live quote, and
   the card is styled identically either way apart from the tag and a slight
   dimming.

   Cards lift, brighten and draw a gold rule across the attribution row on
   approach. The middle card sits a touch proud on desktop, because a row of
   three identical boxes reads as a table and a row with a centre of gravity
   reads as a composition.
   ========================================================================== */
.voices { padding-block: clamp(2.5rem, 2rem + 2.4vw, 4.5rem); }
.voices__head { max-width: 46rem; margin-bottom: clamp(1.75rem, 1.4rem + 1.8vw, 3rem); }
.voices__h {
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.4rem);
  letter-spacing: -0.028em;
  text-wrap: balance;
}
.voices__h em { color: var(--gold-light); font-style: italic; }
.voices__lead {
  margin-top: 0.9rem;
  color: var(--vein);
  font-size: var(--text-base);
  line-height: 1.7;
  text-wrap: pretty;
}

.voices__grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: clamp(1rem, 0.85rem + 0.8vw, 1.5rem);
  align-items: stretch;
}
/* a lone card should read as a statement, not a grid with holes */
.voices__grid:has(> :only-child) { grid-template-columns: minmax(0, 46rem); }

.quote {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 1.2rem + 1.2vw, 2.1rem);
  border: 1px solid var(--border-gold);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, rgba(156, 120, 72, 0.05), rgba(6, 6, 8, 0) 62%);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out);
}
/* the centre card carries the row */
@media (min-width: 900px) {
  .quote:nth-child(2) { transform: translateY(-0.85rem); }
  .quote:nth-child(2):hover,
  .quote:nth-child(2):focus-within { transform: translateY(-1.2rem); }
}
.quote:hover,
.quote:focus-within {
  border-color: var(--border-gold-strong);
  transform: translateY(-4px);
  background: linear-gradient(180deg, rgba(156, 120, 72, 0.09), rgba(6, 6, 8, 0) 62%);
}
/* a wash that only appears on approach */
.quote::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 90% at 18% 0%, rgba(156, 120, 72, 0.14), transparent 60%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}
.quote:hover::after,
.quote:focus-within::after { opacity: 1; }

/* the placeholder tag */
.quote--sample { opacity: 0.92; }
.quote__flag {
  position: relative;
  align-self: flex-start;
  margin-bottom: 0.9rem;
  padding: 0.28rem 0.6rem;
  border: 1px solid var(--border-gold-strong);
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-light);
  background: rgba(156, 120, 72, 0.08);
}

.quote__mark {
  position: relative;
  font-size: clamp(2.1rem, 1.7rem + 1.6vw, 3rem);
  line-height: 0.7;
  color: var(--gold);
  opacity: 0.45;
  margin-bottom: 0.65rem;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.quote:hover .quote__mark,
.quote:focus-within .quote__mark { opacity: 1; transform: translateY(-2px); }

.quote__body { position: relative; flex: 1; }
.quote__body p {
  color: var(--ink);
  font-size: clamp(0.95rem, 0.92rem + 0.25vw, 1.06rem);
  line-height: 1.62;
  text-wrap: pretty;
}

.quote__foot {
  position: relative;
  margin-top: clamp(1.15rem, 1rem + 0.7vw, 1.6rem);
  padding-top: clamp(0.85rem, 0.7rem + 0.5vw, 1.15rem);
}
/* the attribution rule fills in with the hover */
.quote__foot::before,
.quote__foot::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 1px;
}
.quote__foot::before { right: 0; background: var(--border-neutral); }
.quote__foot::after {
  width: 100%;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.7s var(--ease-out);
}
.quote:hover .quote__foot::after,
.quote:focus-within .quote__foot::after { transform: scaleX(1); }

.quote__who { display: flex; flex-direction: column; gap: 0.15rem; }
.quote__name {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--white);
  letter-spacing: -0.012em;
}
.quote__role {
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

.voices__foot { margin-top: clamp(1.5rem, 1.2rem + 1vw, 2.25rem); }
.quote__call {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.95rem;
  font-weight: 600;
  white-space: nowrap;
}
.quote__call svg { transition: transform var(--dur) var(--ease-out); }
.quote__call:hover svg { transform: translateX(3px); }

@media (max-width: 560px) {
  .quote__foot { padding-top: 0.9rem; }
}

/* ==========================================================================
   09 CAREERS - moved out of this file.

   This slot used to hold .roll, "the field runs": a photographic band that
   ran edge to edge for ever with six facts standing still underneath. It was
   replaced by THE REEL, a pinned three-beat stage that keeps the same
   argument and adds the open roles and what the job gives back. That section
   is large enough to own a sheet, and it is loaded by index.html alone:

       css/reel.css      (.reel, and js/motion.js -> initReel)

   Nothing on any page still references .roll. If you are here from a git
   blame looking for it, it is in the history at this line.
   ========================================================================== */

/* Two named people rather than three. Without this the pair sits in a
   3-column grid and leaves a visibly empty third cell. */
.crew__row--two {
  grid-template-columns: repeat(2, 1fr);
  max-width: 44rem;
}

/* Four named people: one row of four on desktop, a 2x2 below that. Four in
   the stock three-column grid orphans the last card on a row of its own.
   Same rule as sections-2.css, so the homepage row lays out exactly as
   team.html#people. */
.crew__row--four { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) {
  .crew__row--four { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   .offr - the six services, as a ledger (about.html)
   Deliberately NOT the homepage's .bill index. That component is the
   showcase and owns the interaction budget for the whole site; running it
   twice makes the second one read as the copy. Here the same six services
   are a scannable two-column ledger you read top to bottom in one pass,
   with services.html carrying the detail.

   The animation is the hairline: each rule draws left to right as its row
   arrives, so the list assembles itself rather than fading in as a slab.
   It rides the existing .reveal/.is-visible IO baseline - no new JS.
   ============================================================ */
.offr__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: clamp(2rem, 4vw, 4.5rem);
}
.offr__item {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: clamp(0.85rem, 1.5vw, 1.25rem);
  padding: clamp(1.1rem, 0.9rem + 0.6vw, 1.6rem) 0;
  border-top: 1px solid var(--border-neutral);
}
/* the drawn rule sits ON the border above, so it replaces it in gold */
.offr__item::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: -1px;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.75s var(--ease-out);
}
.offr__item.is-visible::after { transform: scaleX(1); }
.offr__n {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--gold);
  padding-top: 0.3rem;
  font-variant-numeric: tabular-nums;
  transition: color var(--dur) var(--ease-out);
}
.offr__name {
  font-size: clamp(1.02rem, 0.96rem + 0.32vw, 1.22rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  color: var(--white);
}
.offr__desc {
  margin-top: 0.4rem;
  color: var(--vein);
  font-size: var(--text-sm);
  line-height: 1.62;
  text-wrap: pretty;
}
.offr__item:hover .offr__n { color: var(--gold-light); }
.offr__act { margin-top: clamp(1.5rem, 1.2rem + 1vw, 2.25rem); }
@media (max-width: 760px) {
  .offr__grid { grid-template-columns: 1fr; }
}

/* .hrul - the house rules (team.html culture) - REMOVED.
   Replaced by `.post` in css/post.css. Nothing else on the site used it,
   and this stylesheet loads on nine pages. */

/* ============================================================
   .cf - the contact form, conventional
   Replaces the numbered "sheet": engraved serials 01-05, floating labels and
   bare underlines. It looked like a document and not like something you fill
   in - people could not tell where to type, which is the one thing a contact
   form has to make obvious.

   So: visible label above every field, a real bordered box with a background
   a shade lighter than the page, and a focus ring. Nothing here is clever.
   A form is the one component on a site where being boring IS the design -
   the user has a job to do and every ornament is in the way.
   ============================================================ */
.cf {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 0.85rem + 0.6vw, 1.5rem);
  max-width: 46rem;
}
.cf__row--full { grid-column: 1 / -1; }
.cf__label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}
.cf__req { color: var(--gold); margin-left: 0.15rem; }
.cf__opt {
  margin-left: 0.4rem;
  font-weight: 400;
  font-size: var(--text-xs);
  color: var(--vein);
}
.cf__in {
  display: block;
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--white);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border-neutral);
  border-radius: var(--radius-md);
  transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.cf__in::placeholder { color: var(--vein); opacity: 0.72; }
.cf__in:hover { border-color: var(--border-gold-strong); }
.cf__in:focus {
  outline: none;
  border-color: var(--gold);
  background: rgba(255, 255, 255, 0.055);
  box-shadow: 0 0 0 3px rgba(156, 120, 72, 0.16);
}
textarea.cf__in {
  min-height: 9.5rem;
  resize: vertical;
  line-height: 1.62;
}
.cf__hint {
  margin-top: 0.4rem;
  font-size: var(--text-xs);
  color: var(--vein);
  line-height: 1.5;
}

/* A GROUPING RULE, NOT A DECORATION. Five fields in a flat stack give the eye
   nothing to hold: which of these do I have to answer, and where does the
   admin end and the actual message begin? The hairline answers both without
   adding a word of copy — above it is who you are, below it is what you need,
   and the last one closes the sheet off before the send row.

   Its own row in the grid rather than a border on a field, so it does not
   move when a field grows or an error line appears under one. */
.cf__sep {
  grid-column: 1 / -1;
  height: 1px;
  /* NO MARGIN OF ITS OWN. The grid's row-gap already sits above and below it,
     so the rule lands centred in a break of exactly two gaps — 49px at 1440.
     Adding margin on top of that made the break 76px, which stopped reading
     as a division between two groups and started reading as two unrelated
     forms on one page. */
  margin-block: 0;
  background: linear-gradient(90deg,
    rgba(184, 145, 88, 0.22),
    rgba(184, 145, 88, 0.1) 55%,
    rgba(184, 145, 88, 0.03));
}

/* THE INVALID STATE BELONGS WITH `.cf`, NOT WITH ONE PAGE'S FORM. These two
   rules lived in css/roles.css, which only the three role pages load, so the
   contact form could set aria-invalid and show nothing for it. They are
   generic `.cf` states and they live here now; `.cf__err` stays in roles.css
   because only the application form has per-field error text. */
.cf__in[aria-invalid="true"] {
  border-color: #b4523c;
  background: rgba(180, 82, 60, 0.06);
}
.cf__in[aria-invalid="true"]:focus {
  border-color: #e0785f;
  box-shadow: 0 0 0 3px rgba(224, 120, 95, 0.18);
}
.cf__foot {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  margin-top: 0.35rem;
}
.cf__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
}
.cf__alt {
  color: var(--vein);
  font-size: var(--text-sm);
  line-height: 1.55;
}
.cf__alt a { color: var(--gold-light); text-decoration: underline; text-underline-offset: 3px; }
/* The status line is a polite live region, so it stays rendered even when
   empty - display:none on a live region costs the announcement. An empty <p>
   is already zero-height, so the spacing below is applied ONLY when it has
   something to say, and an untouched form shows no phantom gap. */
.cf__status {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--gold-light);
}
.cf__status:not(:empty) { margin-bottom: 0.9rem; }
.cf__status.is-error { color: #e0785f; }
@media (max-width: 620px) {
  .cf { grid-template-columns: 1fr; }
}

/* ============================================================
   .gmap - the office map, as a plain Google embed
   Was a MapLibre GL vector map repainted to the brand palette with every
   label switched off. It was the better-looking object and the worse map:
   with no street names, no search and no "open in Maps", a visitor could not
   do the one thing a contact-page map exists for.
   A real embed gives back labels, zoom, Street View and directions for free.
   ============================================================ */
.gmap__grid {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: clamp(1.25rem, 1rem + 1.5vw, 2.5rem);
  align-items: stretch;
}
.gmap__frame {
  position: relative;
  min-height: clamp(17rem, 14rem + 14vw, 25rem);
  overflow: hidden;
  border: 1px solid var(--border-gold);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.gmap__frame iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.gmap__side {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.35rem;
}
.gmap__label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.35rem;
}
.gmap__addr {
  font-size: clamp(1.05rem, 0.98rem + 0.4vw, 1.3rem);
  font-weight: 600;
  color: var(--white);
  line-height: 1.45;
  letter-spacing: -0.015em;
}
.gmap__meta { margin-top: 0.85rem; color: var(--vein); font-size: var(--text-sm); line-height: 1.6; }
.gmap__meta a { color: var(--ink); }
.gmap__meta a:hover { color: var(--gold-light); }
.gmap__act { margin-top: clamp(1.1rem, 0.9rem + 0.7vw, 1.6rem); }
@media (max-width: 820px) {
  .gmap__grid { grid-template-columns: 1fr; }
}

/* ============================================================
   about.html hero - the two plates
   Overrides the carved-block geometry in editorial-2.css:2813-3234. It lives
   HERE, not there, for two reasons: sections-2.css is the last stylesheet on
   every page, so these win on source order; and the originals are spread
   across five media-query blocks (3178-3234) that would each need patching
   separately. Selectors are prefixed .hero--block so they out-specify every
   one of those single-class rules regardless of which block they sit in.

   The old geometry and why it failed is documented at the markup in
   about.html. In short: a height that stopped growing at 30rem, a width that
   never stopped growing, images clamped to 100% while still offset -6%, and
   a --bleed measured from 100vw (scrollbar included) that pushed the right
   plate off the page.
   ============================================================ */
.hero--block .blk__stage {
  position: relative;
  width: 100%;
  max-width: none;
  margin: 0;
}
.hero--block .blk__block {
  position: static;
  height: auto;
  aspect-ratio: auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(0.6rem, 0.45rem + 0.5vw, 1rem);
  row-gap: clamp(0.5rem, 0.4rem + 0.3vw, 0.8rem);
}
/* one ratio for both plates: two photographs at the same size read as a
   pair, which is what the labels claim. Unequal slots read as a collage. */
.hero--block .bface {
  position: relative;
  inset: auto;
  width: auto;
  height: auto;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: var(--radius-md);
  box-shadow: inset 0 0 0 1px rgba(156, 120, 72, 0.3), 0 14px 38px -24px rgba(0, 0, 0, 0.9);
}
.hero--block .bface--a { grid-area: 1 / 1; }
.hero--block .bface--b { grid-area: 1 / 2; }
/* static + 100%/100%: the old -6%/112% headroom existed for a GSAP drift
   that no longer runs, and main.css:120 capped the width at 100% anyway */
.hero--block .bface img {
  position: static;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero--block .bface--a img { object-position: 42% 52%; }
.hero--block .bface--b img { object-position: 50% 46%; }
/* the labels leave the stone and sit under their own plate, so the rule that
   used to hang beside them now underlines the column */
.hero--block .blk__idx {
  position: static;
  padding-left: 0;
  white-space: normal;
}
.hero--block .blk__idx--a { grid-area: 2 / 1; }
.hero--block .blk__idx--b { grid-area: 2 / 2; }
.hero--block .blk__idx::before {
  position: static;
  display: block;
  width: 1.55rem;
  margin-bottom: 0.5rem;
}
.hero--block .blk__tell {
  padding-right: 0;
  max-width: none;
}
@media (max-width: 640px) {
  .hero--block .blk__block { grid-template-columns: 1fr; }
  .hero--block .bface--a { grid-area: 1 / 1; }
  .hero--block .blk__idx--a { grid-area: 2 / 1; }
  .hero--block .bface--b { grid-area: 3 / 1; }
  .hero--block .blk__idx--b { grid-area: 4 / 1; }
}

/* ============================================================
   Repeat visits: no curtain
   The preloader now runs only on the first page of a session (see the inline
   head script on every page). On every page after that <html> carries
   .no-preload, and the curtain must be gone before first paint - not faded
   out afterwards, which would still flash a full-screen panel over content
   that is already there.

   display:none rather than opacity/visibility because the element is fixed
   and inset:0: anything short of removing it from layout leaves a full-page
   node over the site until something takes it away.
   ============================================================ */
html.no-preload .preloader { display: none; }
/* .is-loading is never set on these loads, so nothing is scroll-locked or
   held at opacity 0 - this is belt and braces for a stale class surviving a
   bfcache restore. */
html.no-preload,
html.no-preload body { overflow: visible; }
html.no-preload main,
html.no-preload .nav { opacity: 1; }

/* ============================================================
   The record - CUT 2026-08-16

   This block turned the struck ledger into a four-up card: one bordered,
   tinted box holding four equal cells, each with a circular gold icon
   badge over a centred figure and an uppercase label. It was written to
   buy back the 728px the original vertical ledger cost, and it did -
   but measured at 1280 it rendered as four 297x226 centre-ranged cells,
   which is the most recognisable component shape on the web, on a page
   that ranges left everywhere else. Its own predecessor's comment
   promised "figures right-aligned on a shared digit column"; neither
   layout ever did that.

   Replaced by THE ACCOUNT (css/account.css, .acct): the same four
   figures read as three postings and a footing, because 100% closed in
   person is not a fourth statistic - it is the method that produced the
   other three. The figures finally do share one right-ranged digit
   column.

   The .ledger rules in css/editorial.css are now inert too: no element
   on any page carries a .ledger class. initLedger() in js/motion.js
   returns early for the same reason and is left in place.
   ============================================================ */

/* ============================================================
   Client strip - MOVED OUT 2026-08-16

   This block held the second strip: two centred lines with "Fortune 500"
   in a bordered gold pill. Both it and the original row in sections.css
   were replaced by "the register" (css/register.css), which now owns
   every .strip rule. The credential survives the move - it is still the
   strongest thing on the band - but it is stated in gold type at the end
   of the ruled line rather than worn as a badge.
   ============================================================ */

/* ==========================================================================
   MOBILE CORRECTIONS
   This site is opened on a phone far more than on a desktop, so these are
   corrections to the primary surface, not defensive tweaks for a minor one.

   They live here, at the end of the last stylesheet, because they override
   rules spread across main.css, editorial-1b/2/3.css, sections.css and
   roles.css. Collecting them in one block keeps the reasoning in one place;
   the alternative was fourteen edits in five files at specific line numbers.

   The 12-column .grid collapse is NOT here - that one is a correction to the
   rule itself and lives at main.css:338 where the grid is defined.
   ========================================================================== */

/* --- Breaking: the primary CTA was wider than the phone ------------------
   'Start a partnership conversation' inherits white-space:nowrap from .btn,
   giving it a 339px intrinsic width. Centred in the 320px content column of
   a 360px phone it landed 10px from both screen edges, punching through the
   gutter every other element respects - and .cta-band has overflow:hidden,
   so under ~340px the label was silently sliced. The hero button already had
   this treatment; the closing CTA never got it. */
@media (max-width: 760px) {
  .cta-band .hero__actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    max-width: 22rem;
    margin-inline: auto;
  }
  .cta-band .hero__actions .btn {
    white-space: normal;
    padding-inline: 1.25rem;
    font-size: 0.875rem;
  }
}

/* The .joinus__negs strike-through correction that used to live here went
   with the component: .joinus was replaced by .roll, and the struck lines it
   patched had already been cut from the markup before that. Rules that
   describe markup which no longer exists are how the wrong one gets edited. */

/* --- iOS zoom-on-focus ---------------------------------------------------
   Safari force-zooms the whole page when a focused control is under 16px,
   and does not zoom back out on blur. The footer email field was 14px. */
@media (max-width: 1020px) {
  .imp__field input { font-size: 1rem; padding-block: 0.6rem; }
}

/* --- Tap targets ---------------------------------------------------------
   44px is the floor. Measured before: footer phone and email 24px tall and
   6.4px apart (a low tap on the number opened the mail client instead), the
   nine footer links 20px in rows 36px apart, the newsletter submit a 32px
   icon with no label, 'Back to top' 20px on a page ~19 screens long. */
@media (max-width: 1020px) {
  .imp__reach { gap: 0; }
  .imp__reach a,
  .imp__run a,
  .imp__top-link,
  .lat__mail,
  .rle__back {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .imp__run { gap: 0.25rem 1.5rem; }
  .lat__num { min-height: 44px; padding-block: 0.4rem; }
  .imp__top-link { padding-block: 0.7rem; }
  /* keeps the 32px circle the design draws, widens only what the thumb hits */
  .imp__field button { position: relative; }
  .imp__field button::before { content: ""; position: absolute; inset: -6px; }
}

/* --- Type that had shrunk below legibility -------------------------------
   Two captions were clamped to 0.56rem = 8.96px on phones: the about hero
   plate labels, and the caption set on top of the team-walk photograph. */
@media (max-width: 620px) {
  .hero--block .blk__idx { font-size: 0.75rem; letter-spacing: 0.18em; }
  .frm__cap { font-size: 0.7rem; letter-spacing: 0.14em; }
}

/* --- Portraits on a narrow phone ------------------------------------------
   Two to a row down to 340px, one column under it (the reasoning is with the
   rule in home-sections.css: one full-width portrait per row made four people
   2.3 screens of scrolling at 375px). The variants declare their columns in
   THIS file, which loads after home-sections.css, and media queries add no
   specificity - so the narrow-phone column has to be restated here or the
   later rule wins. This block used to force one column under 460px. */
@media (max-width: 339px) {
  .crew__row--two,
  .crew__row--four { grid-template-columns: minmax(0, 1fr); max-width: 22rem; }
}

/* ============================================================
   Anchored sections clear the fixed header
   Buttons now point at sections rather than page tops (contact.html#write,
   careers.html#apply, services.html#services ...). The nav is fixed, so
   without this the browser scrolls the target to y=0 and the header sits on
   top of the heading you were sent to see.

   Same-page clicks already get an -80px offset from the Lenis handler in
   motion.js; this covers the case that handler cannot reach - arriving from
   another page, a bookmark, or a browser back/forward restore.
   ============================================================ */
[id] { scroll-margin-top: clamp(4.5rem, 4rem + 2vw, 6rem); }

/* ============================================================
   The pendant over "How we count"  (services.html, .rules)
   Copied from the darkroom bench further down the same page - .lat__lamp for
   the cord and shade, .lat__safelight::after for the cone - so the two
   sections are lit by the same object rather than by two different lamps.

   Scoped and self-contained: .rules gets position:relative and
   overflow:hidden, or the cone spills into the sections above and below it.
   Both nodes are aria-hidden and pointer-events:none.
   ============================================================ */
.rules {
  position: relative;
  overflow: hidden;
  --lamp-x: clamp(1.5rem, 9vw, 9rem);
  --lamp-w: 3.6rem;
  --lamp-h: clamp(4.5rem, 8vw, 7.5rem);
  --cone-w: clamp(13rem, 26vw, 26rem);
}
.rules > .container { position: relative; z-index: 2; }

/* the warm wash the shade throws across the top of the section */
.rules__glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(34% 30% at 82% 2%, rgba(206, 166, 104, 0.16), rgba(156, 120, 72, 0.05) 46%, transparent 72%),
    radial-gradient(88% 52% at 64% 30%, rgba(146, 108, 58, 0.08), transparent 72%);
}
/* the cone. clip-path makes the trapezoid, blur softens the edges. */
.rules__glow::after {
  content: "";
  position: absolute;
  top: calc(var(--lamp-h) - 0.5rem);
  right: calc(var(--lamp-x) + var(--lamp-w) / 2 - var(--cone-w) / 2);
  width: var(--cone-w);
  height: clamp(15rem, 30vw, 30rem);
  clip-path: polygon(44% 0%, 56% 0%, 100% 100%, 0% 100%);
  background: linear-gradient(180deg, rgba(214, 172, 108, 0.22), rgba(192, 156, 96, 0.055) 44%, transparent 78%);
  filter: blur(16px);
}

.rules__lamp {
  position: absolute;
  top: 0;
  right: var(--lamp-x);
  z-index: 1;
  width: var(--lamp-w);
  height: var(--lamp-h);
  pointer-events: none;
}
/* the cord */
.rules__lamp::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 1px;
  height: calc(100% - 1.15rem);
  background: linear-gradient(180deg, transparent, rgba(156, 120, 72, 0.55));
}
/* the shade, and the light it throws straight down out of its rim */
.rules__lamp::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: var(--lamp-w);
  height: 1.4rem;
  transform: translateX(-50%);
  border-radius: 100% 100% 4px 4px / 100% 100% 4px 4px;
  background: linear-gradient(178deg, #1d1912 0%, #0d0b09 100%);
  border: 1px solid rgba(156, 120, 72, 0.5);
  border-bottom: 0;
  box-shadow:
    0 2px 3px -1px rgba(238, 206, 150, 0.75),
    0 8px 22px -4px rgba(214, 172, 108, 0.5),
    0 28px 60px -8px rgba(192, 156, 96, 0.3),
    0 70px 130px -20px rgba(156, 120, 72, 0.26);
}
/* on a phone the lamp sits in from the edge and the cone narrows with it */
@media (max-width: 620px) {
  .rules { --lamp-x: 0.75rem; --lamp-w: 2.6rem; }
  .rules__lamp::after { width: 2.6rem; height: 1.05rem; }
}

/* ============================================================
   .ph - image placeholder
   Moved here from careers.css: it started as a careers component but is
   a generic utility, and team.html needs it too. Loaded on every page.
   ============================================================ */
.ph {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: var(--ph-ar, 4 / 5);
  overflow: hidden;
  border: 1px dashed var(--border-gold-strong);
  border-radius: var(--radius-md);
  background:
    repeating-linear-gradient(135deg, rgba(156, 120, 72, 0.05) 0 10px, transparent 10px 20px),
    var(--surface);
  color: var(--vein);
}
.ph__label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.5rem 1rem;
  line-height: 1.5;
  text-wrap: balance;
}
/* a real photograph drops in here and needs no other change */
.ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ph:has(img) { border-style: solid; }
.ph:has(img) .ph__label { display: none; }


/* ============================================================
   .fnc - how the team is built (team.html)
   Replaced .fld: four photographic panes tiling one field, their seams
   travelling on a scroll-linked --g. That was ~1,000px of page and four
   images to define four seats. This is the same four definitions as text,
   in one scannable row.
   ============================================================ */
.fnc { padding-block: clamp(2.25rem, 1.8rem + 2.4vw, 4rem); }
.fnc__head { max-width: 46rem; margin-bottom: clamp(1.5rem, 1.2rem + 1.4vw, 2.25rem); }
.fnc__h {
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.4rem);
  font-weight: 600;
  letter-spacing: -0.028em;
  color: var(--white);
  text-wrap: balance;
}
.fnc__h em { font-style: italic; color: var(--gold-light); }
.fnc__lead { margin-top: 0.85rem; color: var(--vein); line-height: 1.65; text-wrap: pretty; }

.fnc__grid {
  list-style: none;
  display: grid;
  gap: 0;
}
.fnc__item {
  padding: clamp(0.95rem, 0.85rem + 0.5vw, 1.3rem) 0;
  border-top: 1px solid var(--border-neutral);
}
.fnc__grid .fnc__item:last-child { border-bottom: 1px solid var(--border-neutral); }
.fnc__n {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.4rem;
}
.fnc__kicker {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--vein);
  margin-bottom: 0.25rem;
}
.fnc__name {
  font-size: clamp(0.98rem, 0.93rem + 0.3vw, 1.12rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.3;
  color: var(--white);
  text-wrap: balance;
}
.fnc__copy { margin-top: 0.35rem; font-size: var(--text-sm); line-height: 1.55; color: var(--vein); text-wrap: pretty; }

/* four across from 820px: the whole point of the rebuild is that all four
   seats are readable in one glance without scrolling */
@media (min-width: 820px) {
  .fnc__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(1.25rem, 1rem + 1.4vw, 2.5rem);
    border-top: 1px solid var(--border-gold);
    padding-top: clamp(1.1rem, 0.95rem + 0.6vw, 1.6rem);
  }
  .fnc__item { padding: 0; border-top: 0; }
  .fnc__grid .fnc__item:last-child { border-bottom: 0; }
}
@media (min-width: 560px) and (max-width: 819px) {
  .fnc__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.75rem; }
  .fnc__item:nth-child(2) { border-top: 1px solid var(--border-neutral); }
}

/* ============================================================
   .vhero - about hero, centred text over a video background

   THREE LAYERS, IN THIS ORDER, AND EVERY ONE OF THEM STANDS ALONE:
     .vhero__still   a local photograph, always painted. The hero's ground.
     .vhero__film    assets/video/about.mp4, over the still, fading in only
                     once it is actually playing.
     .vhero__scrim   the reading ground for the type, over both.

   The still is the fix, and the reasoning is at the markup in about.html:
   the embed used to be the ONLY thing behind the scrim, so reduced motion,
   a file:// open, a content blocker or a slow network each emptied the hero
   to flat black. A layer that cannot fail now sits under the one that can.

   Note the comment this replaces described a <video> with no <source> and a
   "video goes here" pill (.vhero__ph, removed by :has(source)). Both the
   element and the pill were gone from the markup - the sheet was describing
   a hero that no longer existed, and carrying dead rules for it.
   ============================================================ */
.vhero {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(30rem, 78vh, 46rem);
  padding-block: clamp(6.5rem, 5rem + 8vw, 9rem) clamp(3rem, 2.5rem + 3vw, 5rem);
  overflow: hidden;
  text-align: center;
}
.vhero__media { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

/* the layer that cannot fail. No filter stack beyond the site's own grade:
   the scrim above it already owns legibility, and dimming the still twice
   is what turns a dusk photograph into a black rectangle. */
.vhero__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* the tower's shoulders, not its feet: the type is centred over this and
     the upper third of the frame is the quietest part of the picture */
  object-position: 50% 38%;
  filter: saturate(0.88) contrast(1.03);
}

/* A LOCAL <video> COVERS ITS BOX WITH ONE DECLARATION, which is the whole
   reason the iframe was worth replacing. What used to be here was the cover
   built by hand - 177.78vh wide, 100vh tall, min-width 100%, min-height
   56.25vw, plus a container-query rewrite of the same maths - because an
   iframe cannot be object-fit. All of it is object-fit: cover now, and it
   is measured against the element's own box, so it cannot be wrong at a
   viewport the maths was never checked at. */
.vhero__film {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* the skyline sits low in this footage and the type sits over the middle,
     so the crop favours the sky the type is read against */
  object-position: 50% 44%;
  /* scenery, not a control: it can never take a click or the focus ring */
  pointer-events: none;
  /* opaque by default: with no JS, or if `playing` never fires, the film
     simply appears when it appears. Only JS arms the fade, and only because
     it is also what clears it. */
  opacity: 1;
  transition: opacity 0.9s var(--ease-out);
}
.vhero__media.is-armed .vhero__film { opacity: 0; }
.vhero__media.is-armed.is-live .vhero__film { opacity: 1; }
/* THE SCRIM IS TUNED TO THIS FILM, MEASURED, NOT ESTIMATED. It used to say
   it kept the copy readable over "any footage handed over" - which was a
   claim it could not keep once real footage arrived. The film is a night
   skyline: mostly dark, but with blown-out window lights and sky glow that
   reach 255 in places, and they move.

   So it was measured. Nine frames sampled across the ten-second loop, each
   composited through this scrim, sampling the 98th-percentile luminance
   inside the REAL ink box of every piece of type in the hero (not the band
   it sits in - the bright pixels are at the edges of the frame, the type is
   in the middle, and measuring the full width fails the whole hero for
   nothing). Then WCAG 2.1 contrast against each element's own colour.

   Two things came out of it and both are in the numbers below:

   1. THE LIGHT STOP MOVED DOWN AND SOFTENED, 0.6@42% to 0.62@46%. That band
      is where the headline sits and where the film is most visible - it is
      deliberately still the thinnest part of the scrim.
   2. THE LOWER RAMP DEEPENS SOONER, a new 0.86 stop at 78%. The standfirst,
      the note and the button all sit below 57%, they are small and quiet,
      and the bottom of this frame is foreground street rather than skyline -
      so there is nothing down there to protect and the type gets the margin
      instead.

   The eyebrow needed its own answer, at .vhero .eyebrow below. */
.vhero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      rgba(6, 6, 8, 0.86) 0%,
      rgba(6, 6, 8, 0.62) 46%,
      rgba(6, 6, 8, 0.86) 78%,
      rgba(6, 6, 8, 0.94) 100%),
    radial-gradient(70% 60% at 50% 45%, rgba(156, 120, 72, 0.1), transparent 72%);
}
.vhero__inner { position: relative; z-index: 1; }
.vhero .eyebrow { justify-content: center; }
.vhero .eyebrow::before { display: none; }
/* THE ONE PIECE OF TYPE THE SCRIM COULD NOT SAVE. --gold (#B89158) is a mid
   tone - relative luminance 0.31 - and at 12px it needs 4.5:1, which means
   the background under those four letters has to sit at 0.031 or darker.
   Over the brightest frame of this film it measured 0.112, for 2.25:1, and
   getting it to 0.031 needs 0.85 alpha of scrim: the film would be gone.

   So the eyebrow moves up the same ramp instead. This is the pale gold the
   nav beam and the footer lip already use, it is still unmistakably gold,
   and at luminance 0.71 it clears AA over the same frame with margin. It is
   scoped to .vhero because it is a fix for type over film - the gold eyebrow
   everywhere else on the site sits on stone and is fine. */
.vhero .eyebrow { color: #f4dca4; }
.vhero__h {
  font-size: clamp(1.85rem, 1.4rem + 2.4vw, 3.1rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--white);
  max-width: 20ch;
  margin-inline: auto;
  text-wrap: balance;
}
.vhero__h em { font-style: italic; color: var(--gold-light); }
.vhero__sub {
  margin: clamp(1rem, 0.85rem + 0.6vw, 1.4rem) auto 0;
  max-width: 40rem;
  color: var(--ink);
  font-size: var(--text-base);
  line-height: 1.65;
  text-wrap: pretty;
}
.vhero__note {
  margin: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem) auto 0;
  max-width: 34rem;
  color: var(--vein);
  font-size: var(--text-sm);
  line-height: 1.6;
}
.vhero__act { margin-top: clamp(1.5rem, 1.25rem + 1vw, 2.25rem); }

/* motion off: a looping background film is exactly what this setting is for */
@media (prefers-reduced-motion: reduce) {
  /* THIS RULE USED TO EMPTY THE HERO. The film was the whole background, so
     a reader with motion off - one toggle in Windows' Visual effects, not a
     developer setting - got the scrim over nothing. The still underneath is
     untouched here on purpose: the hero keeps its photograph and simply
     stops moving, which is what the setting asks for.

     `display: none` and not `pause`: a paused film still holds a decoder and
     a frame buffer for a picture nobody asked to see, and the still is the
     better image to be left looking at anyway. */
  .vhero__film { display: none; }
}

/* ==========================================================================
   MOBILE UI PASS  -  the findings in MOBILE-UI-REPORT.md
   Measured live at 390x844, not read off the stylesheet. Nothing here changes
   a layout; it is all type size and padding, which is what the report found.
   ========================================================================== */

/* --- Tap targets ---------------------------------------------------------
   44px is the floor for a thumb, and a miss on a phone usually means hitting
   the wrong thing. Measured before this rule: the email address rendered
   240x17 - the highest-intent tap on a sales site, at 17px tall - and every
   .link-line CTA came in at 30px.

   min-height on an inline-flex, NOT padding: padding on an inline <a> inside a
   paragraph overlaps the lines above and below it, which is how a "fix" for
   this turns into two overlapping hit areas. */
@media (max-width: 1020px) {
  .link-line,
  .imp__reach a,
  .cf__alt a,
  .prof__meta a,
  .gmap__meta a,
  main a[href^="mailto:"],
  main a[href^="tel:"] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* the email address is long enough to wrap on a phone; when it does, the
     44px floor must not stretch the whole wrapped block */
  main a[href^="mailto:"] { flex-wrap: wrap; }
}

/* --- Type below the legibility floor -------------------------------------
   Below ~11.5px, tracked uppercase type stops being readable at arm's length
   and starts being decoration. These were measured at 9-11.2px.

   .wordmark__sub is the important one: 9px, in the header, on every page.

   Only classes on the homepage, and only those whose own sheet loads before
   this one: a later sheet wins the tie and undoes the floor. The careers
   tags (.jr__tags, home-careers.css) set theirs beside their own rule there.
   .acx__lbl and .pq__role came out of this block: they belong to about.html,
   which does not load it. */
@media (max-width: 1020px) {
  .wordmark__sub { font-size: 0.75rem; letter-spacing: 0.14em; }
  /* the hero's "Face to face marketing | Cincinnati, Ohio" rule */
  .eyebrow--bare span,
  .skyhero__eyebrow span { font-size: 0.75rem; }
  .fbeat__tag { font-size: 0.72rem; }
}

/* --- iOS zoom-on-focus, absolute rule ------------------------------------
   Safari force-zooms the page when a focused control is under 16px and does
   not zoom back out. The real forms are already 16px; this catches the CSS-tab
   radios on the homepage so the rule has no exceptions. */
@media (max-width: 1020px) {
  input, select, textarea { font-size: max(1rem, 1em); }
}

/* `.clkp__cap` keeps its 8.8px at 640px and under. It is the only sub-11.5px
   type left on team.html and careers.html now that the careers stamp is gone,
   and it is exempt for the same reason the stamp was: it is a caption engraved
   on a photograph, it repeats nothing the page does not say in full elsewhere,
   and at that size the plate reads as a plate rather than as a card with a
   label. Lifting it would push the caption over the chronograph standing on
   the same corner. Deliberately not lifted. */

/* ============================================================
   .shot  -  a photograph inside a section
   The homepage carried ZERO photographs: twelve sections of type, rules and
   numbers. On a site whose whole argument is "we send people to doors", that
   is the one thing the page should show and did not.

   One component, used on alternating sections so the page breathes rather
   than turning into a gallery. Ratio-locked so nothing reflows as the image
   decodes, and captioned - a photograph with no caption on a claims-based
   page is decoration; with one it is evidence.
   ============================================================ */
.shot {
  position: relative;
  margin-top: clamp(1.75rem, 1.4rem + 1.6vw, 2.75rem);
  /* SPAN THE WHOLE ROW. Several of the sections these land in are two-column
     grids (.plain__grid is 485/643, and others like it). Without this the
     figure becomes a third grid item, takes column 1 on a new row, and sits
     at 485px with the other column empty beside it - which is exactly how it
     looked wrong. grid-column is inert on a non-grid parent, so the one rule
     is safe everywhere. */
  grid-column: 1 / -1;
}
.shot__frame {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid var(--border-gold);
  border-radius: var(--radius-md);
  background: var(--surface);
  aspect-ratio: var(--shot-ar, 21 / 9);
}
.shot__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--shot-pos, 50% 42%);
  filter: saturate(0.94) contrast(1.03);
  transform: scale(1.01);
  transition: transform 1.2s var(--ease-out), filter var(--dur) var(--ease-out);
}
.shot:hover .shot__frame img { transform: scale(1.05); filter: saturate(1) contrast(1.04); }
/* the scrim is what lets a caption sit ON the photograph and stay readable
   whatever the image is doing underneath it */
.shot__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 40%, rgb(var(--scrim-rgb) / 0.72) 100%);
}
.shot__cap {
  position: absolute;
  left: clamp(0.9rem, 0.8rem + 0.6vw, 1.5rem);
  bottom: clamp(0.75rem, 0.65rem + 0.5vw, 1.2rem);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}
.shot__cap::before {
  content: "";
  width: 1.4rem;
  height: 1px;
  background: var(--gold);
  flex: none;
}
/* a 21:9 letterbox is 170px tall on a phone - too thin to read as a picture */
@media (max-width: 720px) {
  .shot__frame { aspect-ratio: var(--shot-ar-m, 3 / 2); }
}

/* the two-channel columns each carry their own photograph: one business, one
   home. Side by side they ARE the argument the section is making. */
.duo2__shot {
  --shot-ar: 4 / 3;
  --shot-ar-m: 3 / 2;
  margin: 0 0 clamp(1rem, 0.85rem + 0.6vw, 1.5rem);
}

/* ============================================================
   .quote__logo  -  the client's mark on a testimonial card
   The card carries the brand it came from, so a reader can see WHO said it
   before reading WHAT they said. Reversed to white by the same
   brightness/invert used on .strip__mark - the source files are dark ink on
   transparency.
   ============================================================ */
.quote__logo {
  display: flex;
  align-items: center;
  height: clamp(1.35rem, 1.15rem + 0.8vw, 1.85rem);
  margin-bottom: clamp(1rem, 0.85rem + 0.6vw, 1.4rem);
  opacity: 0.72;
  filter: brightness(0) invert(1);
  transition: opacity var(--dur) var(--ease-out);
}
.quote:hover .quote__logo { opacity: 1; }
.quote__logo img {
  max-height: 100%;
  width: auto;
  max-width: clamp(5.5rem, 9vw, 7.5rem);
  object-fit: contain;
}

/* ============================================================
   .panes  -  who we represent, as three windows on one horizon

   THREE BRANDS IN THREE UNRELATED CATEGORIES, SOLD BY ONE TEAM. The three
   are windows; the one is a line. Each brand is a pane of glass onto its own
   world, and a single gold horizon is drawn straight through all three,
   unbroken across the gaps. Three views, one level.

   THE HORIZON IS THE LOAD-BEARING ELEMENT. It sits outside the panes as a
   sibling of the row, because the whole of its meaning is that it does not
   stop at their edges - a border, an inset shadow or a per-pane pseudo would
   each have broken it into three lines, which is the opposite claim. Its
   height is derived from --pane-h so it lands at the same point of every
   pane at every width, and the shutters part AT it.

   EACH PANE IS A VOLUME, NOT A PICTURE. Three planes stand at three
   distances inside a local perspective: the world at -150px, the mark at
   -40px, the grade and jamb at 0. Every plane is scaled by exactly the
   reciprocal of its own perspective divide, so at rest the stack projects
   to the size of the pane and nothing is cropped or floating - the depth is
   only visible when something rotates, which is exactly when it should be.

   THE MARK IS INSIDE THE WORLD. Not a logo at the top of a card: a mark
   suspended in the middle distance of the place we work. It parallaxes
   against its own photograph, which is the difference between a client list
   and a claim to be in the room.

   NO --lit, NO RAKING, NO FACETS. The section above this one is lit and
   holds still; this one moves and holds its light. Custom properties are
   prefixed --pane- for the reason written at the head of the .fold block.
   ============================================================ */
.panes {
  position: relative;
  padding-block: clamp(2.25rem, 1.8rem + 2vw, 3.75rem);
}
.panes__bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}
.panes__aura {
  position: absolute;
  left: 50%;
  top: 58%;
  width: min(110rem, 145%);
  aspect-ratio: 2.4 / 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    closest-side,
    rgba(184, 145, 88, 0.075),
    rgba(184, 145, 88, 0.026) 48%,
    transparent 74%
  );
}

.panes__head {
  position: relative;
  z-index: 1;
  max-width: 48rem;
}
.panes__h {
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.4rem);
  letter-spacing: -0.028em;
  text-wrap: balance;
}
.panes__h em { color: var(--gold-light); font-style: italic; }
.panes__lead {
  margin-top: clamp(0.7rem, 0.6rem + 0.4vw, 1rem);
  max-width: 42rem;
  color: var(--vein);
  line-height: 1.7;
  text-wrap: pretty;
}

/* --pane-h is declared once, here, and read by the glass AND by the horizon.
   Two places needing the same number is exactly how the line drifts off the
   window at some width nobody tested. */
.panes__frame {
  position: relative;
  z-index: 1;
  margin-top: clamp(1.4rem, 1.1rem + 1.4vw, 2.25rem);
  --pane-h: clamp(10rem, 26vh, 16rem);
  --pane-cut: 0.62;
}
.panes__row {
  position: relative;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.1vw, 1.25rem);
  margin: 0;
  padding: 0;
}
.pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.pane__glass {
  position: relative;
  height: var(--pane-h);
  overflow: hidden;
  border-radius: 2px;
  background: var(--obsidian);
  /* the reveal is projected locally: an element that clips its contents
     cannot also pass an outer scene's depth through to them */
  perspective: 780px;
  perspective-origin: 50% 46%;
  box-shadow:
    inset 0 0 0 1px rgba(184, 145, 88, 0.13),
    inset 0 24px 46px -28px rgba(0, 0, 0, 0.95),
    inset 0 -20px 42px -26px rgba(0, 0, 0, 0.8);
}
.pane__space {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(var(--pane-rx, 0deg)) rotateY(var(--pane-ry, 0deg));
  will-change: transform;
}
/* 780 / (780 + 150) = 0.839, so 1.192 puts this plane back at pane size;
   1.30 overfills it by 9% instead, which is the room the rotation needs */
.pane__far {
  position: absolute;
  inset: 0;
  display: block;
  transform: translateZ(-150px) scale(1.3);
}
.pane__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 44%;
  filter: saturate(0.9) contrast(1.06) brightness(0.86);
}
/* 780 / (780 + 40) = 0.951 -> 1.052 is exactly its own reciprocal, so the
   mark sits at true size and only MOVES with the depth, never resizes */
.pane__mid {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateZ(-40px) scale(1.052);
}
/* THE THREE MARKS ARE BOXED, NOT WIDTH-MATCHED. They are 480x195, 480x161
   and 480x106 - set to one width, AT&T renders 40px tall and Primo Water 22px,
   which reads as three brands of three different importances. Bounded by a
   max width AND a max height instead, each mark fills whichever edge it meets
   first and the three carry the same optical weight. Same box the client
   strip under the hero uses. */
.pane__logo {
  width: auto;
  height: auto;
  max-width: clamp(4.5rem, 7.5vw, 6.5rem);
  max-height: clamp(1.6rem, 2.6vw, 2.4rem);
  object-fit: contain;
  opacity: 0.95;
  filter: brightness(0) invert(1) drop-shadow(0 2px 16px rgba(0, 0, 0, 0.9));
}
.pane__near {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(118% 88% at 50% 44%, transparent 30%, rgba(6, 6, 8, 0.6) 100%),
    linear-gradient(180deg, rgba(6, 6, 8, 0.34), transparent 32%, rgba(6, 6, 8, 0.5));
}
/* lifted on arrival and burnt off; invisible at rest so with no JS the world
   behind the glass is already developed */
.pane__burn {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: rgb(var(--scrim-rgb) / 0.92);
}
/* THE SHUTTER RESTS OPEN. Both halves sit at scaleY(0), so a dead CDN or a
   missing IntersectionObserver leaves three lit windows rather than three
   black rectangles. motion.js animates 1 -> 0, never the other way. */
.pane__shut {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.pane__shut i {
  position: absolute;
  left: 0;
  right: 0;
  display: block;
  background: linear-gradient(180deg, var(--surface-2), var(--obsidian-raised));
  transform: scaleY(0);
}
.pane__shut i:first-child {
  top: 0;
  height: calc(var(--pane-cut) * 100%);
  transform-origin: 50% 0;
}
.pane__shut i:last-child {
  top: calc(var(--pane-cut) * 100%);
  bottom: 0;
  transform-origin: 50% 100%;
}

/* the line. --pane-draw rests at 1 so it is fully drawn without JavaScript */
.panes__horizon {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--pane-h) * var(--pane-cut));
  z-index: 3;
  pointer-events: none;
}
.panes__horizon i {
  display: block;
  height: 1px;
  transform: scaleX(var(--pane-draw, 1));
  transform-origin: 0 50%;
  background: linear-gradient(
    90deg,
    rgba(192, 156, 96, 0),
    var(--gold-light) 4%,
    var(--gold-light) 96%,
    rgba(192, 156, 96, 0)
  );
  box-shadow: 0 0 14px rgba(192, 156, 96, 0.42);
}

.pane__sill { padding-top: clamp(0.85rem, 0.75rem + 0.45vw, 1.15rem); }
.pane__cat {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}
.pane__what {
  margin-top: 0.55rem;
  color: var(--ink);
  font-size: clamp(0.84rem, 0.81rem + 0.16vw, 0.94rem);
  line-height: 1.6;
  text-wrap: pretty;
}
.pane__meta {
  margin-top: 0.55rem;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--vein);
}
.pane__meta b { color: var(--gold-light); font-weight: 600; }

/* the line's caption, set at the end of it rather than on it: a small light
   label over three arbitrary photographs is a contrast problem waiting to
   happen, and the dash carries the connection well enough */
.panes__stamp {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: clamp(0.85rem, 0.75rem + 0.4vw, 1.2rem);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--vein);
}
.panes__stamp::before {
  content: "";
  width: clamp(2rem, 6vw, 4.5rem);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold));
}

/* --------------------------------------------------------------------------
   PHONE AND SMALL TABLET: the windows lie down.

   Three full-width panes with copy beneath is about 1200px of scrolling,
   which is the thing this section exists to avoid. Each brand becomes one
   short row instead - a square window on the left, its sentence beside it -
   and the horizon turns ninety degrees with them: one vertical hairline down
   the gutter, through all three rows. Same claim, same single line, a third
   of the height.
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {
  .panes__frame {
    --pane-thumb: clamp(5.5rem, 25vw, 7.25rem);
    --pane-lane: clamp(0.85rem, 3vw, 1.15rem);
  }
  .panes__row {
    grid-template-columns: 1fr;
    gap: clamp(0.9rem, 3vw, 1.3rem);
  }
  /* the horizon, stood on end */
  .panes__row::before {
    content: "";
    position: absolute;
    top: 0.35rem;
    bottom: 0.35rem;
    left: calc(var(--pane-thumb) + var(--pane-lane) / 2);
    width: 1px;
    background: linear-gradient(
      180deg,
      rgba(192, 156, 96, 0),
      var(--gold-light) 10%,
      var(--gold-light) 90%,
      rgba(192, 156, 96, 0)
    );
    opacity: 0.55;
  }
  .pane {
    display: grid;
    grid-template-columns: var(--pane-thumb) minmax(0, 1fr);
    gap: var(--pane-lane);
    align-items: start;
  }
  .pane__glass {
    height: auto;
    aspect-ratio: 1 / 1;
    perspective: none;
  }
  .pane__far { transform: none; }
  .pane__mid { transform: none; }
  .pane__logo { max-width: 72%; max-height: 30%; }
  .pane__sill { padding-top: 0; }
  .panes__horizon { display: none; }
  .panes__stamp { justify-content: flex-start; }
}

/* Phones. Three rows plus a head plus a lead lands about 35px past a 812pt
   screen once the fixed nav is taken off it, and 35px is the difference
   between "the whole section" and "most of the section". It comes out of the
   air around the type, because the three windows are already as small as they
   can be and still be photographs. */
@media (max-width: 640px) {
  .panes { padding-block: clamp(1.6rem, 1.3rem + 1.4vw, 2.5rem); }
  .panes .eyebrow { margin-bottom: var(--space-2); }
  .panes__lead { margin-top: 0.6rem; }
  .panes__frame { margin-top: clamp(1.05rem, 0.9rem + 0.8vw, 1.6rem); }
}

@media (max-width: 420px) {
  .panes__stamp::before { width: 1.5rem; }
}

/* --------------------------------------------------------------------------
   THE COPY IS HELD TO A FIXED LINE COUNT so the three categories, the three
   sentences and the three notes each sit on one line across the row. Same
   reasoning as the .fold statements: below 1200px the column takes about 35
   characters and all three sentences wrap to three lines; above it they all
   take two. Reserving the worst case per breakpoint costs a line of air at
   the widths where it is not needed and costs nothing where it is.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .pane__what { min-height: calc(3 * 1.6em); }
}
@media (min-width: 1200px) {
  .pane__what { min-height: calc(2 * 1.6em); }
}

/* Short screens. The windows are already on a vh; what is left to give back
   is the air around the type. */
@media (min-width: 900px) and (max-height: 840px) {
  .panes { padding-block: clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem); }
  .panes .eyebrow { margin-bottom: var(--space-2); }
  .panes__frame { margin-top: clamp(1.1rem, 0.9rem + 0.9vw, 1.6rem); }
}

/* small orphans from the sections above */
.bill__more { flex: none; }
.crew__meta { min-width: 0; }
