/* hero.css - the bar, and the split fold under it.

   Structure taken from the reference: a bar with the mark at the left, the links
   as one centred group, and a single action at the right; then a fold that is a
   panel of media beside a panel of type rather than type floating on a
   full-bleed film.

   THE PALETTE IS NOT TAKEN FROM THE REFERENCE. Those screenshots are a warm
   light grey with a coral accent, and this site is navy on near-black. Adopting
   the layout is one change; repainting every page to match someone else's brand
   is a different and much larger one, and it is not what was asked for. */

/* ------------------------------------------------------------------ the bar */
/* Solid, because it now sits ABOVE the fold rather than floating over a film.
   A transparent bar over a split panel puts white type over whatever the media
   happens to be doing at its top edge. */
.osnav--bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: 0 clamp(16px, 3vw, 34px);
  height: 70px;
  background: #0b0f14;
  mix-blend-mode: normal;
}
.osnav--bar .osnav__brand { justify-self: start; }

/* One group, one ground, one border: the links read as a single control rather
   than as four separate words spaced across the bar. */
.navpill {
  justify-self: center;
  display: flex;
  align-items: stretch;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 0;
  padding: 3px;
}
.navpill a {
  display: inline-flex; align-items: center;
  padding: 0 16px; height: 30px;
  font-size: .84rem; letter-spacing: -.01em;
  color: #fff;
  text-decoration: none;
  border-radius: 0;
  transition: background .18s ease;
}
.navpill a:hover { background: rgba(255, 255, 255, .12); }
/* The divider is drawn between items, not around them, so the group keeps one
   outline however many links it holds. */
.navpill a + a { box-shadow: inset 1px 0 0 rgba(255, 255, 255, .12); }

.navcta {
  justify-self: end;
  display: inline-flex; align-items: center;
  height: 34px; padding: 0 18px;
  border-radius: 0;
  background: #fff; color: #0b0f14;
  font-size: .84rem; font-weight: 500; letter-spacing: -.01em;
  text-decoration: none;
  transition: opacity .18s ease;
}
.navcta:hover { opacity: .86; }

/* Under 900 the pill and the action give way to the burger, which already opens
   a full menu carrying the same destinations. */
@media (max-width: 900px) {
  .osnav--bar { grid-template-columns: 1fr auto; }
  .navpill, .navcta { display: none; }
}
@media (min-width: 901px) {
  .osnav--bar .osburger { display: none; }
}

/* ----------------------------------------------------------------- the fold */
/* COMPRESSED. The old fold was a full-bleed film pulled up under the bar and
   held at 100vh + 70px, so the first screen was almost entirely water with a
   line of type in it. This one is sized by its own contents with a bounded
   height, and it starts directly under the bar with no lead-in space at all. */
.hero--split {
  /* The bar is position:fixed and therefore takes no flow space, so the fold has
     to reserve its height itself. Without this the panel starts at y=0 and the
     video runs up behind the bar, which is what the first pass did. */
  padding: calc(70px + clamp(10px, 1.4vh, 20px)) clamp(16px, 3vw, 34px) clamp(20px, 3vh, 40px);
  background: #0b0f14;
  min-height: 0;
  margin-top: 0;
}
.hsplit {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  gap: clamp(18px, 2.4vw, 40px);
  align-items: stretch;
  /* Bounded rather than 100vh: tall enough to be the fold, short enough that the
     section under it shows a sliver and the page reads as having more in it. */
  min-height: min(66vh, 620px);
}
@media (max-width: 900px) { .hsplit { grid-template-columns: minmax(0, 1fr); } }

.hsplit__media {
  position: relative;
  overflow: hidden;
  background: #070a0e;
  min-height: clamp(260px, 42vh, 520px);
}
/* The video was absolutely positioned against the old full-bleed hero. In a
   panel it fills the panel. */
.hsplit__media .hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

.hsplit__copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(16px, 3vw, 52px) clamp(4px, 2vw, 30px);
  min-width: 0;
}
.hero__banner {
  margin: 0;
  color: #fff;
  max-width: 15ch;
  font-size: clamp(2.1rem, 4.1vw, 3.6rem);
  line-height: 1.04;
  letter-spacing: -.032em;
  text-wrap: balance;
}
/* The body sits well below the headline and above the action, the way the
   reference holds them: the headline is the statement, the paragraph qualifies
   it, and the button is the only thing to do. */
.hsplit__lede {
  margin: auto 0 clamp(18px, 2.4vh, 30px);
  padding-top: clamp(18px, 3vh, 34px);
  max-width: 46ch;
  font-size: .95rem;
  line-height: 1.6;
  color: #fff;
}
.hsplit__cta {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 10px;
  height: 42px; padding: 0 20px;
  background: #fff; color: #0b0f14;
  font-size: .9rem; font-weight: 500;
  text-decoration: none;
  transition: opacity .18s ease;
}
.hsplit__cta:hover { opacity: .86; }


/* -------------------------------------------------------------- no grey type
   A hard rule, applied last so it wins.

   site.css and os.css set body copy in rgba(255,255,255,.42), .72 and .78 on a
   near-black ground. Those are greys however they are spelled: dropping a white
   to 42% opacity over #0b0f14 lands on roughly #6b6f74, which is exactly the
   washed-out look this was meant to lose. Everything that reads as text goes to
   white, and the ONE step below it is 90%, which is still the same hue and
   still reads as the same voice.

   Backgrounds and hairlines are untouched. Low-alpha white is correct for a
   rule or a hover ground; it is only wrong for a word. */
.osnav__brand, .osnav__brand b,
.navpill a, .navcta,
p, li, dd, dt, figcaption, blockquote, small,
.os p, .os li, .oscell p, .osgo, .osrow p, .osprov p,
/* The footer set its links and the copyright line at 72% white, which is the
   same grey by another route. A legal link is still a word someone reads. */
footer a, footer p, footer span, footer small,
.foot__legal, .foot__legal a, .foot__legal span, .foot__made, .foot__copy,
[class^="foot__"], [class^="foot__"] a, [class^="foot__"] span {
  color: #fff;
}
/* The single permitted step down, for a caption or a note that qualifies the
   line above it rather than being read on its own. */
.osnote, .oscap, .os__meta, figcaption small { color: rgba(255, 255, 255, .9); }


/* The two controls that sit ON white have to keep their dark ink. The blanket
   no-grey rule above set every link to #fff, which turned the action in the bar
   and the one in the fold into white text on a white ground. A rule that broad
   has to name its own exceptions. */
.navcta, .navcta:hover,
.hsplit__cta, .hsplit__cta:hover { color: #0b0f14; }


/* ============================================================ MACH BAR
   Three slots and nothing else: the wordmark set on two lines at the left, the
   brand mark centred, the three lines at the right. The pill of links and the
   Request access button are gone from the bar because the reference has neither
   and because both of their destinations are already in the panel. */
.osnav--bar{background:#000;height:clamp(58px,5vw,72px);gap:12px}
.osnav__word{display:flex;flex-direction:column;justify-self:start;color:#fff;
  line-height:1.05;letter-spacing:.02em;text-transform:uppercase;
  font-size:clamp(.7rem,.9vw,.84rem);font-weight:500}
.osnav__mark{justify-self:center;display:block}
.osnav__mark img{height:clamp(19px,2.1vw,27px);width:auto;display:block}
.osnav--bar .osburger{justify-self:end;margin-right:0}
.navpill,.navcta,.osnav__brand{display:none}

/* ============================================================ INSET HERO
   The film is a plate laid on the page, not the page's ground. It clears the
   bar and holds an equal margin on the other three sides, so it never runs off
   an edge. */
.oshero{background:#000;
  --gap:clamp(12px,1.5vw,24px);
  padding:calc(clamp(58px,5vw,72px) + var(--gap)) var(--gap) var(--gap)}
.oshero__frame{position:relative;width:100%;overflow:hidden;background:#050505;
  height:calc(100vh - clamp(58px,5vw,72px) - (var(--gap) * 2));
  height:calc(100svh - clamp(58px,5vw,72px) - (var(--gap) * 2))}
.oshero__frame video{width:100%;height:100%;object-fit:cover;display:block}
@media (max-width:640px){
  .oshero__frame{height:min(62vh,500px)}
  .osnav__word{font-size:.66rem}
}

/* The burger is the only control in the bar now, at every width. The rule above
   hid it above 900px because the pill of links carried the routes there; with
   the pill gone that left a desktop bar with no way into the menu at all. */
@media (min-width:901px){
  .osnav--bar .osburger{display:grid}
}


/* A longer, softer character fade to match the slower stagger: at .5s each
   letter still snapped, and slowing only the stagger made the run feel stepped
   rather than smooth. */
[data-os] .os__c{transition:opacity .95s linear,transform .95s cubic-bezier(.165,.84,.44,1)}

/* The panel hangs off the bar, and the bar is sized in hero.css now, so the
   panel takes its offset from the same number instead of from a stale token. */
.osmenu{top:clamp(58px,5vw,72px)}


/* ============================================================ PANELS
   One screen each, built like a plate on the reference board: the picture takes
   two thirds, the copy takes the other third as a black cell. The division is a
   change of ground rather than a drawn rule, which keeps the page free of the
   repeated hairlines it had before.

   Sides alternate, so the eye crosses the page rather than running down one
   gutter. */
.ospanel{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);
  min-height:100vh;min-height:100svh;background:#000}
.ospanel--flip .ospanel__media{order:-1}
.ospanel__copy{display:flex;flex-direction:column;justify-content:center;
  padding:clamp(28px,4vw,72px);background:#000}
.ospanel__n{font-size:.78rem;font-weight:500;letter-spacing:.12em;
  font-variant-numeric:tabular-nums;color:#fff;margin-bottom:clamp(10px,1.2vw,16px)}
.ospanel__k{font-size:.78rem;font-weight:500;letter-spacing:.16em;text-transform:uppercase;
  color:#fff;margin-bottom:clamp(22px,2.8vw,44px)}
.ospanel h2{font-size:clamp(1.5rem,2.3vw,2.3rem);font-weight:450;line-height:1.14;
  letter-spacing:-.024em;color:#fff;max-width:16ch}
.ospanel p{margin-top:clamp(16px,1.8vw,26px);font-size:clamp(.95rem,1.02vw,1.02rem);
  line-height:1.55;color:#fff;max-width:34ch}
.ospanel__media{overflow:hidden;background:#050505}
.ospanel__media img,.ospanel__media video{width:100%;height:100%;object-fit:cover;display:block}

@media (max-width:900px){
  .ospanel{grid-template-columns:1fr;min-height:0}
  .ospanel--flip .ospanel__media{order:0}
  .ospanel__media{height:52vh}
  .ospanel__copy{padding-block:clamp(34px,7vw,64px)}
}

/* The flip has to swap the ratios as well as the order. order:-1 alone moved the
   picture into the first column, which is the narrow one, so the flipped panels
   gave the image a third and left the copy sitting in two thirds of empty
   black. The picture keeps two thirds whichever side it is on. */
.ospanel--flip{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}


/* ============================================================ PANEL COPY
   A tag line and a sentence. The tag is a drawn mark, the index and the label
   on one baseline; the sentence under it is the only large type in the cell.
   The headline that used to sit between them was the same claim as the sentence
   at a bigger size, which is why every panel read the same. */
.ospanel__tag{display:flex;align-items:center;gap:clamp(10px,1vw,15px);
  margin-bottom:clamp(22px,2.6vw,40px)}
.ospanel__glyph{width:clamp(22px,1.9vw,28px);height:auto;flex:none;
  fill:none;stroke:#fff;stroke-width:1;vector-effect:non-scaling-stroke;opacity:.9}
.ospanel__n{font-size:.8rem;font-weight:500;letter-spacing:.1em;
  font-variant-numeric:tabular-nums;color:#fff;margin:0}
.ospanel__k{font-size:.8rem;font-weight:500;letter-spacing:.18em;text-transform:uppercase;
  color:#fff;margin:0}
/* the index and the label read as one run, divided by a rule rather than a gap */
.ospanel__n::after{content:"";display:inline-block;width:clamp(14px,1.4vw,22px);
  height:1px;background:#fff;vertical-align:middle;margin:0 0 3px clamp(10px,1vw,15px)}

.ospanel__line{margin:0;font-size:clamp(1.7rem,2.9vw,3rem);font-weight:450;
  line-height:1.1;letter-spacing:-.028em;color:#fff;max-width:15ch}

@media (max-width:900px){
  .ospanel__line{font-size:clamp(1.5rem,5.4vw,2.2rem)}
}

/* .ospanel p is one class and one element, so it outranks the single class on
   .ospanel__line and the sentence was rendering at body size. Qualified, it
   wins back. */
.ospanel p.ospanel__line{font-size:clamp(1.7rem,2.9vw,3rem);line-height:1.1;
  letter-spacing:-.028em;margin-top:0;max-width:15ch}

/* ============================================================ CASCADE
   The picture arrives rather than being there. It starts inset from the side
   the copy is on and slightly over scale, then unclips and settles: the frame
   opens out of the black cell next to it, which is what makes consecutive
   panels read as coming out of one another rather than as a stack.

   1.6s on a long ease, and the image's own drift runs a beat behind the clip so
   the two do not finish together. */
.ospanel__media{clip-path:inset(0 0 0 100%);}
.ospanel--flip .ospanel__media{clip-path:inset(0 100% 0 0);}
.ospanel__media img,.ospanel__media video{transform:scale(1.08);transform-origin:50% 50%}
[data-os] .ospanel__media{
  transition:clip-path 1.6s cubic-bezier(.16,.84,.3,1)}
[data-os] .ospanel__media img,[data-os] .ospanel__media video{
  transition:transform 2.1s cubic-bezier(.16,.84,.3,1) .12s}
[data-os] .ospanel.is-on .ospanel__media{clip-path:inset(0 0 0 0)}
[data-os] .ospanel.is-on .ospanel__media img,
[data-os] .ospanel.is-on .ospanel__media video{transform:scale(1)}

/* The copy rises under it, a beat later again. */
[data-os] .ospanel__tag,[data-os] .ospanel__line{
  transition:opacity 1.2s cubic-bezier(.16,.84,.3,1) .3s,
             transform 1.2s cubic-bezier(.16,.84,.3,1) .3s}
[data-os] .ospanel__tag{opacity:0;transform:translateY(18px)}
[data-os] .ospanel.is-on .ospanel__tag{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  .ospanel__media{clip-path:none}
  .ospanel__media img,.ospanel__media video{transform:none}
  [data-os] .ospanel__tag{opacity:1;transform:none}
  [data-os] .ospanel__media,[data-os] .ospanel__media img,[data-os] .ospanel__media video,
  [data-os] .ospanel__tag{transition:none}
}


/* A longer character fade to match the longer stagger. */
[data-os] .os__c{transition:opacity 1.25s linear,transform 1.25s cubic-bezier(.165,.84,.44,1)}

/* Fewer words, more size. The cell holds one line of tag and one sentence, so
   the sentence can carry the weight the panel needs without crowding it. */
.ospanel p.ospanel__line{font-size:clamp(2rem,3.7vw,3.9rem);line-height:1.06;
  letter-spacing:-.032em;max-width:13ch}
.ospanel__n,.ospanel__k{font-size:clamp(.86rem,1.02vw,1.02rem);letter-spacing:.14em}
.ospanel__glyph{width:clamp(26px,2.4vw,36px)}
.ospanel__tag{margin-bottom:clamp(26px,3.2vw,50px)}




/* ---------- panel copy, stripped ----------
   A title and one small paragraph, and the whole hierarchy is the gap between
   their sizes. The index, the drawn mark and the rule between them were three
   devices competing with the photograph beside them. */
.ospanel__title{font-size:clamp(2.2rem,4.2vw,4.4rem);font-weight:450;line-height:1;
  letter-spacing:-.032em;color:#fff;margin:0 0 clamp(18px,2vw,30px)}
.ospanel p.ospanel__sub{font-size:clamp(.98rem,1.08vw,1.08rem);line-height:1.55;
  letter-spacing:0;color:#fff;max-width:34ch;margin:0}
.ospanel__tag,.ospanel__glyph,.ospanel__n,.ospanel__k,.ospanel__line{display:none}
/* space between the plates, so they read as separate pictures */
.ospanel{border-bottom:0;margin-bottom:clamp(10px,1.2vw,20px)}


/* Faster than the last pass and easier: a long linear fade read as sluggish,
   and the ease is what carries the smoothness rather than the duration. */
[data-os] .os__c{transition:opacity .6s cubic-bezier(.22,.61,.36,1),
                            transform .6s cubic-bezier(.22,.61,.36,1)}
[data-os] .ospanel__media{transition:clip-path 1.15s cubic-bezier(.22,.61,.36,1)}
[data-os] .ospanel__media img,[data-os] .ospanel__media video{
  transition:transform 1.5s cubic-bezier(.22,.61,.36,1) .06s}


/* ============================================================ THE STACK
   The reference unit, measured off it: a two digit index at about 13px, the
   name at display size on the same side, the description on a short measure
   beside it starting near 28 percent, and the film below at the full width but
   inset from the page edges so it never touches them. Sides alternate. */
.macv{background:#000;color:#fff;padding:clamp(46px,5.4vw,92px) 0 clamp(34px,4vw,68px)}
.macv__head{display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr);
  gap:clamp(20px,4vw,90px);align-items:start;
  padding-inline:clamp(20px,4vw,72px);margin-bottom:clamp(28px,3.4vw,58px)}
.macv__n{grid-column:1;font-size:.78rem;font-weight:500;letter-spacing:.08em;
  font-variant-numeric:tabular-nums;color:#fff;display:block;margin-bottom:clamp(4px,.6vw,10px)}
.macv__name{grid-column:1;grid-row:2;font-size:clamp(2.6rem,6vw,6rem);font-weight:600;
  line-height:.9;letter-spacing:-.03em;text-transform:uppercase;margin:0;white-space:nowrap}
.macv__desc{grid-column:2;grid-row:2;font-size:clamp(.98rem,1.1vw,1.12rem);line-height:1.5;
  max-width:36ch;margin:0;padding-top:.35em;color:#fff}
/* the film: full measure, inset, never touching an edge */
.macv__film{margin-inline:clamp(20px,4vw,72px);aspect-ratio:16/9;overflow:hidden;background:#050505}
.macv__film video{width:100%;height:100%;object-fit:cover;display:block}
/* mirrored: index and name to the right, description to the left of them */
.macv--flip .macv__head{grid-template-columns:minmax(0,1fr) minmax(0,auto)}
.macv--flip .macv__n{grid-column:2;justify-self:end;text-align:right}
.macv--flip .macv__name{grid-column:2;grid-row:2;justify-self:end}
.macv--flip .macv__desc{grid-column:1;grid-row:2;justify-self:end;text-align:left}

/* the film arrives the way the panels do */
[data-os] .macv__film{clip-path:inset(0 0 100% 0);
  transition:clip-path 1.15s cubic-bezier(.22,.61,.36,1)}
[data-os] .macv__film video{transform:scale(1.06);
  transition:transform 1.5s cubic-bezier(.22,.61,.36,1) .06s}
[data-os] .macv.is-on .macv__film{clip-path:inset(0 0 0 0)}
[data-os] .macv.is-on .macv__film video{transform:scale(1)}

@media (max-width:820px){
  .macv__head{grid-template-columns:1fr;gap:14px}
  .macv--flip .macv__head{grid-template-columns:1fr}
  .macv__name,.macv--flip .macv__name{grid-column:1;grid-row:auto;white-space:normal;justify-self:start}
  .macv__n,.macv--flip .macv__n{grid-column:1;grid-row:auto;justify-self:start;text-align:left}
  .macv__desc,.macv--flip .macv__desc{grid-column:1;grid-row:auto;justify-self:start;padding-top:0}
}
@media (prefers-reduced-motion:reduce){
  [data-os] .macv__film{clip-path:none;transition:none}
  [data-os] .macv__film video{transform:none;transition:none}
}


/* ============================================================ TYPE
   Two faces now, and the split is by job rather than by taste.

   Chakra Petch carries every name, index and label: it is the angular,
   squared-terminal face the defense references are set in, and it is what makes
   a word like COLLECTION read as a designation rather than as a heading. SIL
   Open Font Licence, self hosted, latin subset only, about 10KB a weight.

   Inter keeps the running prose, because an angular display face at paragraph
   size and thin weight is a legibility problem, not a style. */
@font-face{font-family:Chakra;font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/chakra-400.woff2) format("woff2")}
@font-face{font-family:Chakra;font-style:normal;font-weight:500;font-display:swap;
  src:url(../fonts/chakra-500.woff2) format("woff2")}
@font-face{font-family:Chakra;font-style:normal;font-weight:600;font-display:swap;
  src:url(../fonts/chakra-600.woff2) format("woff2")}

:root{--angular:Chakra,"DIN Condensed",InterVar,system-ui,sans-serif}

/* Names, indices and labels take the angular face. */
.macv__name,.ospanel__title,.osnav__word,.macv__n,.ospanel__k,.ospanel__n,
.os__kicker,.os__num,.osgrid__k,.osgrid__n,.osgo,.oscell h3{
  font-family:var(--angular);font-weight:600;letter-spacing:.005em}
.macv__name{font-weight:600;letter-spacing:.01em}
.ospanel__title{font-weight:600;letter-spacing:0}
.osnav__word{font-weight:500;letter-spacing:.06em}

/* Running prose: thin, and a touch off pure white so it sits back from the
   names without becoming grey. */
.macv__desc,.ospanel p.ospanel__sub,.os__lede,.os__quote p,.osgrid__col p{
  font-family:var(--sans);font-weight:200;color:rgba(255,255,255,.88);
  letter-spacing:.004em}
/* the left hand runs are thin, but not as thin as the paragraphs */
.ospanel p.ospanel__sub{font-weight:300;color:rgba(255,255,255,.92)}
.os__statement{font-weight:300}

/* A ladder of heights, so no two runs on a screen share a size. */
.macv__name{font-size:clamp(2.6rem,6.2vw,6.2rem);line-height:.88}
.macv__desc{font-size:clamp(1rem,1.15vw,1.18rem);line-height:1.46}
.macv__n{font-size:.82rem;letter-spacing:.14em}
.ospanel__title{font-size:clamp(2.1rem,4vw,4.2rem);line-height:.96}
.ospanel p.ospanel__sub{font-size:clamp(.98rem,1.06vw,1.06rem);line-height:1.62}

/* The technology page's opening plate. */
.plate--tech{background:#000;color:#fff;
  padding:calc(clamp(58px,5vw,72px) + clamp(46px,6vw,110px)) clamp(20px,4vw,72px) clamp(30px,4vw,64px)}
.plate--tech .ospanel__title{max-width:none;margin-bottom:clamp(20px,2.4vw,34px)}
.plate__lede{font-family:var(--sans);font-weight:200;font-size:clamp(1rem,1.18vw,1.2rem);
  line-height:1.5;max-width:56ch;color:rgba(255,255,255,.88);margin:0}


/* ============================================================ CONTACT
   Brutalist: pure black, one rule down the middle, labels above their fields
   and a field that is a line rather than a box. Nothing is rounded, nothing is
   filled, and the only inversion on the page is the send control.

   The back link exists because the bar's only control is the menu, and a form
   is the one page a reader lands on with no obvious way out of it. */
.ct{background:#000;color:#fff;min-height:100vh;min-height:100svh;
  padding:calc(clamp(58px,5vw,72px) + clamp(40px,5vw,86px)) clamp(20px,4vw,72px) clamp(48px,6vw,110px)}
.ct__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(30px,5vw,110px);align-items:start}
.ct__back{font-family:var(--angular);font-weight:500;font-size:.78rem;letter-spacing:.14em;
  text-transform:uppercase;color:#fff;display:inline-block;margin-bottom:clamp(26px,3.4vw,56px)}
.ct__back:hover{text-decoration:underline;text-underline-offset:4px}
.ct__title{font-family:var(--angular);font-weight:600;
  font-size:clamp(2.4rem,5.4vw,5.4rem);line-height:.94;letter-spacing:0;margin:0}
.ct__lede{margin-top:clamp(18px,2vw,30px);font-family:var(--sans);font-weight:200;
  font-size:clamp(1rem,1.15vw,1.16rem);line-height:1.5;max-width:34ch;
  color:rgba(255,255,255,.88)}

.ct__form{display:flex;flex-direction:column;gap:clamp(20px,2.4vw,34px)}
.ct__row{display:flex;flex-direction:column;gap:9px}
.ct__row label{font-family:var(--angular);font-weight:500;font-size:.72rem;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.72)}
.ct__row input,.ct__row select,.ct__row textarea{
  font-family:var(--sans);font-weight:300;font-size:1.02rem;color:#fff;
  background:transparent;border:0;border-bottom:1px solid rgba(255,255,255,.34);
  border-radius:0;padding:11px 0;width:100%;
  transition:border-color .3s cubic-bezier(.22,.61,.36,1)}
.ct__row textarea{resize:vertical;min-height:104px}
.ct__row input:focus,.ct__row select:focus,.ct__row textarea:focus{
  outline:0;border-bottom-color:#fff}
/* the native menu paints its list in the page's colours, and white on white is
   unreadable, so the options get the ground explicitly */
.ct__row select option{background:#000;color:#fff}
.ct__note{font-family:var(--sans);font-weight:300;font-size:.9rem;min-height:1.3em;margin:0}
.ct__send{align-self:flex-start;font-family:var(--angular);font-weight:600;
  font-size:.76rem;letter-spacing:.16em;text-transform:uppercase;
  padding:15px 30px;border:1px solid #fff;background:transparent;color:#fff;
  transition:background .3s cubic-bezier(.22,.61,.36,1),color .3s cubic-bezier(.22,.61,.36,1)}
.ct__send:hover{background:#fff;color:#000}

@media (max-width:820px){
  .ct__grid{grid-template-columns:1fr;gap:38px}
}

/* Seven cells: four routes, and a picture after each of the first three. */
.osmenu{grid-template-columns:repeat(7,minmax(0,1fr))}
@media (max-width:900px){.osmenu{grid-template-columns:1fr}}

/* The multiple selection. Square boxes, no rounding, no fill until checked,
   which is the same control language as the send button. */
.ct__label{font-family:var(--angular);font-weight:500;font-size:.72rem;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.72)}
.ct__multi{display:flex;flex-wrap:wrap;gap:10px 12px;margin-top:4px}
.ct__multi label{display:inline-flex;align-items:center;gap:9px;cursor:pointer;
  border:1px solid rgba(255,255,255,.34);padding:10px 14px;
  transition:border-color .25s cubic-bezier(.22,.61,.36,1),background .25s cubic-bezier(.22,.61,.36,1)}
.ct__multi label:hover{border-color:#fff}
.ct__multi input{appearance:none;-webkit-appearance:none;margin:0;flex:none;
  width:12px;height:12px;border:1px solid rgba(255,255,255,.6);background:transparent;
  transition:background .2s linear,border-color .2s linear}
.ct__multi input:checked{background:#fff;border-color:#fff}
.ct__multi label:has(input:checked){border-color:#fff;background:rgba(255,255,255,.08)}
.ct__multi input:focus-visible{outline:2px solid #fff;outline-offset:3px}
.ct__multi span{font-family:var(--sans);font-weight:300;font-size:.93rem;color:#fff}

/* The tape fills its frame the way the films do, and tiles horizontally so a
   wide screen gets columns of it rather than one column and a lot of black. */
.macv__film--tape{background:#050505;position:relative}
.macv__film--tape canvas{position:absolute;inset:0;width:100%;height:100%;display:block}


/* ---------- the panel loses its rule ----------
   The line under the bar was separating two surfaces that are the same colour,
   so it read as a seam across the middle of the screen rather than as an edge. */
.osmenu{border-top:0}



/* ---------- the line on the film ---------- */
.oshero__frame{position:relative}
.oshero__line{position:absolute;left:0;right:0;bottom:clamp(24px,4vw,64px);
  margin:0;padding-inline:clamp(20px,3.4vw,56px);z-index:2;
  font-family:var(--angular);font-weight:600;
  font-size:clamp(1.5rem,4.4vw,4.4rem);line-height:1;letter-spacing:.01em;
  text-transform:uppercase;color:#fff}
/* the grade sits under the type only, not over the whole frame */
.oshero__frame::after{content:"";position:absolute;left:0;right:0;bottom:0;
  height:min(46%,320px);z-index:1;pointer-events:none;
  background:linear-gradient(0deg,rgba(0,0,0,.68),rgba(0,0,0,.28) 46%,rgba(0,0,0,0))}


/* ============================================================ BOOT
   The first screen assembles. The frame opens from the centre, the film comes
   off its over scale behind it, and the line writes on last. Each step waits on
   the one before it rather than all three firing together, which is what makes
   it read as a sequence instead of a fade.

   Everything is keyed on [data-booted], which os.js sets only once the first
   frame has decoded, so this never plays against an empty box. */
[data-os] .oshero__frame{clip-path:inset(0 50% 0 50%);
  transition:clip-path 1.25s cubic-bezier(.16,.84,.3,1) .12s}
[data-os] .oshero__frame video{transform:scale(1.12);
  transition:transform 2.4s cubic-bezier(.16,.84,.3,1) .12s}
[data-os] .oshero__frame::after{opacity:0;transition:opacity .9s linear .9s}
[data-os][data-booted] .oshero__frame{clip-path:inset(0 0 0 0)}
[data-os][data-booted] .oshero__frame video{transform:scale(1)}
[data-os][data-booted] .oshero__frame::after{opacity:1}

/* the bar drops in over it */
[data-os] .osnav{transform:translateY(-100%);
  transition:transform .8s cubic-bezier(.16,.84,.3,1)}
[data-os][data-booted] .osnav{transform:none}

/* The line is written on by the boot, not by the observer. The stagger comes
   from the inline delay splitWrite sets on each character, so nothing here may
   set transition-delay: an earlier version did, with !important, and the whole
   run wiped in at once. */
[data-os] .oshero__line{opacity:1}

@media (prefers-reduced-motion:reduce){
  [data-os] .oshero__frame,[data-os] .oshero__frame video,
  [data-os] .oshero__frame::after,[data-os] .osnav,[data-os] .oshero__line{
    transition:none;clip-path:none;transform:none;opacity:1}
}

/* The line writes on once the frame has opened. Its characters carry the same
   stagger as every other run, offset past the clip so the two do not overlap. */
[data-os] .oshero__line .os__c{transition-delay:inherit}
[data-os] .oshero__line{opacity:1;transition:none}
[data-os] .oshero__line .os__c{opacity:0}
[data-os][data-booted] .oshero.is-on .oshero__line .os__c{opacity:1}

/* ---------- provenance: lower, centred, larger ---------- */
.osprov{padding-top:clamp(90px,11vw,180px);padding-bottom:clamp(80px,10vw,160px)}
.osprov__row{margin-top:clamp(48px,6vw,92px);gap:clamp(30px,4.2vw,74px)}
.osprov__row img{height:clamp(34px,3.1vw,46px)}
.osprov__row img.osprov--seal{height:clamp(74px,7.6vw,116px)}


/* ---------- the line: low, and centred across the frame ---------- */
.oshero__line{top:auto;bottom:clamp(30px,5vw,80px);transform:none;
  text-align:center;letter-spacing:.02em}
/* the grade is a floor wash again, because the type is back on the floor */
.oshero__frame::after{top:auto;bottom:0;transform:none;height:min(50%,340px);
  background:linear-gradient(0deg,rgba(0,0,0,.72),rgba(0,0,0,.3) 44%,rgba(0,0,0,0))}

/* ---------- the page leaves over it ----------
   The hero is pinned and everything below scrolls up across it, so the first
   screen is uncovered rather than pushed. Every section below already paints a
   solid ground, which is what makes the pass opaque; the stacking order is the
   only thing that had to be stated. */
.oshero{position:sticky;top:0;z-index:0}
.oshero + *,
.macv,.ospanel,.os,.osrow,.foot{position:relative;z-index:1}

/* ---------- a page that is black all the way down ----------
   The commercial page inherits its section markup from site.css, where most
   blocks paint nothing and let the paper ground show through, and one paints
   its own near black. On a black page that is a set of bands nobody chose. */
body.pg-black,
body.pg-black section,
body.pg-black main,
body.pg-black .centerhead,
body.pg-black .conn,
body.pg-black .cta,
body.pg-black .band,
body.pg-black .foot{background:#000;color:#fff}
body.pg-black .cta__in,
body.pg-black .conn__panel{background:#000}


/* ---------- a slower entry ----------
   The frame opened in 1.25s and the film settled in 2.4s, which is quick enough
   to read as a transition rather than as an arrival. Everything is stretched
   and the ease is softened so the first screen assembles rather than snapping
   into place. */
[data-os] .oshero__frame{transition:clip-path 2.1s cubic-bezier(.16,.9,.24,1) .25s}
[data-os] .oshero__frame video{transition:transform 3.6s cubic-bezier(.16,.9,.24,1) .25s}
[data-os] .oshero__frame::after{transition:opacity 1.4s linear 1.5s}
[data-os] .osnav{transition:transform 1.2s cubic-bezier(.16,.9,.24,1) .1s}

/* The line writes on after the frame has finished opening, not during it. The
   observer was firing it on load because the hero is on screen from the first
   frame, so it played against a half open picture. */
[data-os] .oshero__line .os__c{opacity:0}
[data-os][data-booted] .oshero.is-lit .oshero__line .os__c{opacity:1}

/* ---------- the commercial page: brighter, bigger, shorter ----------
   site.css sets its body copy in --body, a mid grey chosen for a paper ground.
   On black that is the dimmest thing on the page and it carried most of the
   argument. Everything comes up near white, the headings go up a step, and the
   measures come in so the shorter runs do not stretch across the full column. */
body.pg-black,body.pg-black p,body.pg-black li,body.pg-black .cap p,
body.pg-black .conn p,body.pg-black .centerhead p,body.pg-black .kv b,
body.pg-black .fl__body p,body.pg-black td,body.pg-black th{color:rgba(255,255,255,.92)}
body.pg-black .centerhead h2,body.pg-black .conn h2,body.pg-black h2{
  font-family:var(--angular);font-weight:600;letter-spacing:0}
body.pg-black .centerhead h2{font-size:clamp(2rem,4.4vw,4.4rem);line-height:.98}
body.pg-black .cap h3,body.pg-black .fl__body h3{
  font-family:var(--angular);font-weight:600;
  font-size:clamp(1.25rem,1.9vw,1.9rem);line-height:1.06;letter-spacing:0}
body.pg-black .fl__body p,body.pg-black .cap p{
  font-family:var(--sans);font-weight:300;font-size:clamp(.98rem,1.06vw,1.06rem);
  line-height:1.5;max-width:40ch}
/* the small mono labels inside the console mockups stay legible on black */
body.pg-black .kv span,body.pg-black .ui__chip,body.pg-black .sub{
  color:rgba(255,255,255,.78)}
/* the last dim run: a label inside the console mockup */
body.pg-black .search .box{color:rgba(255,255,255,.86)}


/* ---------- the line unveils, it does not appear ----------
   Each character is wiped in from its own top edge rather than faded up, so the
   run reads as being drawn down onto the film. clip-path does it without any
   extra markup: the split already gives one span per character, and the stagger
   on those spans is what sweeps the wipe left to right.

   The inset is negative top and bottom so the mask clears ascenders and
   descenders; at 0 it shaves the tops off the caps. */
[data-os] .oshero__line .os__c{
  opacity:1;
  clip-path:inset(-18% 0 100% 0);
  transform:translateY(-.18em);
  transition:clip-path .72s cubic-bezier(.16,.9,.24,1),
             transform .72s cubic-bezier(.16,.9,.24,1)}
[data-os][data-booted] .oshero.is-lit .oshero__line .os__c{
  clip-path:inset(-18% 0 -18% 0);
  transform:none}

@media (prefers-reduced-motion:reduce){
  [data-os] .oshero__line .os__c{clip-path:none;transform:none;transition:none}
}

/* ---------- the entry arrives sooner ----------
   Two seconds before the first word is a hold, not a reveal. The frame still
   opens smoothly, it just starts on the click rather than after it, and the
   line follows the opening instead of waiting for it to finish. */
[data-os] .oshero__frame{transition:clip-path 1.25s cubic-bezier(.16,.9,.24,1) 0s}
[data-os] .oshero__frame video{transition:transform 2.6s cubic-bezier(.16,.9,.24,1) 0s}
[data-os] .oshero__frame::after{transition:opacity .8s linear .35s}
[data-os] .osnav{transition:transform .7s cubic-bezier(.16,.9,.24,1) 0s}
[data-os] .oshero__line .os__c{
  transition:clip-path .5s cubic-bezier(.16,.9,.24,1),
             transform .5s cubic-bezier(.16,.9,.24,1)}

/* ---------- provenance in two rows ----------
   The four seals on top and the four company marks under them. They are two
   different kinds of relationship and two different kinds of artwork, and
   running all eight on one line made the seals dominate a row of wordmarks.
   Each row centres on its own, so neither is dragged off axis by the other. */
.osprov__rows{display:flex;flex-direction:column;
  gap:clamp(28px,3.6vw,58px);margin-top:clamp(44px,5.4vw,84px)}
.osprov__row{margin-top:0;justify-content:center;align-items:center;
  gap:clamp(26px,3.8vw,66px)}
.osprov__row--gov img{height:clamp(56px,5.8vw,88px)}
.osprov__row--corp img{height:clamp(24px,2.3vw,34px)}
/* the Waterloo mark is square rather than a wide wordmark, so at a shared
   height it reads about half the weight of the others */
.osprov__row--corp img.osprov--tall{height:clamp(38px,3.6vw,54px)}


/* ============================================================ PHONE
   Measured at 390px rather than guessed. Two classes of problem came out of it
   and both are the same mistake: sizes that were tuned on a desktop and then
   allowed to keep shrinking with the viewport.

   Type first. The wordmark was landing at 10.6px and the controls at 10.9px,
   which is under the floor where a caps run set in an angular face stays
   readable on a handset. Nothing on the page is under 12px now.

   Then the targets. The mark, the wordmark, the back link and the form fields
   were all between 19 and 24px tall against a 44px guideline, so they were
   accurate to hit only with a fingertip and a steady hand. They are padded to
   44 without moving anything, because the padding is inside the hit area
   rather than added to the layout. */
@media (max-width:640px){
  .osnav__word{font-size:.76rem;line-height:1.22}
  .osgo,.oscell .osgo,.btn,.ct__send{font-size:.75rem;padding:14px 20px}
  .ct__row label,.ct__label,.ct__back,.osrow__k,.macv__n,.os__kicker,.os__num,
  .osgrid__k,.ospanel__k,.ospanel__n{font-size:.76rem}
  .ct__multi span{font-size:.9rem}
  .osfoot__flag,.foot__made,.foot__legal{font-size:.82rem}

  /* hit areas, without moving the marks they sit on */
  .osnav__word,.osnav__mark{min-height:44px;display:flex;align-items:center}
  .osnav__word{flex-direction:column;justify-content:center;align-items:flex-start}
  .ct__back{min-height:44px;display:inline-flex;align-items:center}
  .ct__row input,.ct__row select,.ct__row textarea{min-height:46px;font-size:16px}
  .ct__multi label{min-height:46px}
  .foot__legal a,.osfoot__col a{min-height:44px;display:inline-flex;align-items:center}

  /* 16px on the fields is not a style choice: below it, iOS zooms the page in
     on focus and leaves the reader on a viewport they did not ask for. */

  /* the panel: one column, and the pictures earn their space */
  .osmenu{grid-template-columns:1fr;height:auto;
    max-height:calc(100vh - clamp(58px,5vw,72px));
    grid-auto-rows:min-content;align-content:start;overflow-y:auto}
  .oscell{min-height:0;padding:20px}
  .oscell--img{height:20vh}

  /* the film stack: names wrap rather than run off, description under them */
  .macv__name{font-size:clamp(2rem,11vw,3rem);white-space:normal}
  .macv__desc{font-size:1rem;max-width:none}
  .macv__film{margin-inline:16px}
  .macv{padding-block:clamp(38px,9vw,64px)}

  /* the panels stack, picture first */
  .ospanel__title{font-size:clamp(1.9rem,9vw,2.6rem)}
  .ospanel p.ospanel__sub{font-size:1rem;max-width:none}

  /* the tape needs height to read as a tape at all */
  .macv__film--tape{aspect-ratio:3/4}

  /* provenance: two rows of two, so nothing is scaled into illegibility */
  .osprov__row{flex-wrap:wrap;gap:26px 30px}
  .osprov__row--gov img{height:58px}
  .osprov__row--corp img{height:26px}
  .osprov__row--corp img.osprov--tall{height:40px}

  /* the hero line has to fit the frame it sits on */
  .oshero__line{font-size:clamp(1.15rem,6.4vw,1.9rem);
    padding-inline:16px;bottom:22px;letter-spacing:.01em}
  .oshero__frame{height:min(66vh,520px)}
}
/* the last one: the inline Learn more inside the commercial feature list */
@media (max-width:640px){
  .learn{min-height:44px;display:inline-flex;align-items:center}
}

/* The bar keeps its three slots on a phone. An earlier rule dropped it to
   `1fr auto` under 900px, which was right when the bar held a brand and a
   burger; with the mark in the middle that is three children in two columns, so
   the burger wrapped onto a second row and the bar grew a phantom line. */
@media (max-width:900px){
  .osnav--bar{grid-template-columns:1fr auto 1fr}
}

/* ---------- the marks: larger, and centred in their own band ----------
   They sat high in the section with a long fall of empty black under them, so
   the block read as the top of something rather than as the middle of it. The
   space above and below the rows is now equal, and every mark goes up a step. */
.osprov{padding-top:clamp(76px,9vw,140px);padding-bottom:clamp(76px,9vw,140px)}
.osprov__rows{margin-top:clamp(52px,6.4vw,96px);gap:clamp(34px,4.4vw,68px)}
.osprov__row--gov img{height:clamp(72px,7.4vw,116px)}
.osprov__row--corp img{height:clamp(32px,3.1vw,46px)}
.osprov__row--corp img.osprov--tall{height:clamp(50px,4.8vw,72px)}
.osprov__row--gov{gap:clamp(30px,4.4vw,78px)}
.osprov__row--corp{gap:clamp(30px,4.6vw,82px)}

@media (max-width:640px){
  .osprov{padding-top:64px;padding-bottom:64px}
  .osprov__rows{margin-top:42px;gap:32px}
  .osprov__row--gov img{height:66px}
  .osprov__row--corp img{height:30px}
  .osprov__row--corp img.osprov--tall{height:46px}
}


/* ============================================================ HANDHELD, ALL OF IT
   The first pass at this covered 640px and the four pages I had audited, which
   left the 768px tablet band and the legal pages untouched: 'Get in touch' and
   'Contact' were still rendering at 10.9px there, the console mockup's status
   chips at 10px, and a run of links at 20 to 24px tall against a 44px target.

   This block is deliberately not scoped to a page. Anything small enough to be
   a problem on a handset is a problem on every page that has it. */
@media (max-width:900px){
  /* nothing on a handheld screen is set below 12px */
  .osgo,.btn,.ct__send,.learn,.ui__chip,.kv span,.sub,.act,
  .foot__legal,.foot__legal a,.foot__legal span,.foot__made,
  .legal__meta,.legal small,.cap span,.overline_text{font-size:.76rem!important}
  .ct__multi span,.dial__name{font-size:.9rem}

  /* every interactive thing clears 44px, with the padding inside the hit area
     so the layout around it does not move */
  a,button{min-height:0}
  .foot__legal a,.osfoot__col a,.legal a,.learn,.osgo,.ct__back,
  .nav__links a,.foot a{min-height:44px;display:inline-flex;align-items:center}
  .btn,.ct__send{min-height:46px}
  input,select,textarea{min-height:46px;font-size:16px}

  /* the legal pages were never given a handheld measure */
  .legal{padding-inline:20px}
  .legal h1{font-size:clamp(1.8rem,7vw,2.6rem);line-height:1.06}
  .legal h2{font-size:clamp(1.1rem,4.6vw,1.4rem)}
  .legal p,.legal li{font-size:1rem;line-height:1.62}

  /* the console mockups on the commercial page carry the smallest type on the
     site; they are scaled as a unit rather than rule by rule */
  .ui{font-size:.86rem}
  .ui__bar b{font-size:.9rem}
  table,td,th{font-size:.86rem}
}
/* The wordmark and the mark in the bar: the 640px block sized these, so between
   641 and 900 they were still on the desktop clamp and landing under 12px. */
@media (max-width:900px){
  .osnav__word{font-size:.78rem;line-height:1.22;min-height:44px;
    display:flex;flex-direction:column;justify-content:center;align-items:flex-start}
  .osnav__mark{min-height:44px;display:flex;align-items:center}
}


/* ---------- the figure in the quote's left column ----------
   That column held nothing but the quote mark, so a third of the block was
   empty while the number it belongs to sat two sections away. The figure takes
   the top of the column, its caption sits under it, and the mark drops to the
   foot where it still reads as the opening of the passage beside it. */
.os__figcol{display:flex;flex-direction:column;align-items:flex-start}
.os__fig{font-family:var(--angular);font-weight:600;
  font-size:clamp(2.6rem,5vw,5rem);line-height:.92;letter-spacing:-.01em;
  color:#fff;font-variant-numeric:tabular-nums;display:block}
.os__figcap{margin-top:clamp(10px,1.2vw,16px);font-family:var(--sans);font-weight:200;
  font-size:clamp(.9rem,1.02vw,1.02rem);line-height:1.4;
  color:rgba(255,255,255,.88);max-width:22ch;display:block}
.os__figcol .os__mark{margin-top:clamp(26px,3.4vw,52px)}

@media (max-width:900px){
  .os__fig{font-size:clamp(2.2rem,11vw,3rem)}
  .os__figcol .os__mark{margin-top:22px}
}
/* The figure sits a little above the paragraph's first line rather than on the
   same baseline, so the two columns read as one composition instead of two runs
   starting together. */
.os__figcol{margin-top:clamp(-18px,-1.2vw,-8px)}

/* ---------- the figure sits under the mark ----------
   Mark, then figure, then caption: the mark opens the column the way it opens
   the passage beside it, and the number reads as what the quote is about rather
   than as a separate item above it. Sized up, and the three parts are spaced on
   their own rhythm instead of inheriting the column's. */
.os__figcol{margin-top:0}
.os__figcol .os__mark{margin-top:0;margin-bottom:clamp(14px,1.6vw,24px);
  font-size:clamp(2.2rem,3.4vw,3.2rem);line-height:.7;opacity:.9}
.os__fig{font-size:clamp(3rem,6.4vw,6.4rem);line-height:.88;letter-spacing:-.02em}
.os__figcap{margin-top:clamp(12px,1.4vw,20px);font-size:clamp(.92rem,1.06vw,1.06rem);
  max-width:24ch}

@media (max-width:900px){
  .os__figcol .os__mark{font-size:2rem;margin-bottom:12px}
  .os__fig{font-size:clamp(2.6rem,13vw,3.6rem)}
}

/* ---------- the figure, larger and in red ----------
   The one coloured run on the page, and it is the number the whole section is
   about. Red on the lifted grey rather than on black, so it stays a signal
   instead of a warning. The caption moves onto the angular face and takes a
   short measure so it stacks under the figure in two or three lines rather than
   running the width of the column. */
.os__fig{font-size:clamp(3.6rem,7.6vw,7.6rem);line-height:.86;letter-spacing:-.028em;
  color:#E0362E}
.os__figcap{font-family:var(--angular);font-weight:500;
  font-size:clamp(.86rem,1vw,1rem);line-height:1.34;letter-spacing:.06em;
  text-transform:uppercase;max-width:14ch;color:rgba(255,255,255,.9)}
.os__figcol .os__mark{color:rgba(255,255,255,.55)}

@media (max-width:900px){
  .os__fig{font-size:clamp(3rem,15vw,4.4rem)}
  .os__figcap{font-size:.84rem;max-width:16ch}
}


/* ---------- the figure, sized to its column ----------
   It was set at 109px and filling 61% of a 484px column, so it read as a number
   sitting in a space rather than as the point of the block. Measured: this face
   runs about 2.7px of width per 1px of size for a six character run, so filling
   a column that is a third of the measure needs roughly 12vw. It is set just
   under that, which fills the column and leaves the descender room.

   Red because it is money leaving. The figure is the loss, the rule under it
   draws the eye down the way a falling number does, and the caption states what
   it is without editorialising. */
.os__fig{font-size:clamp(3.4rem,11.6vw,11.6rem);line-height:.82;
  letter-spacing:-.035em;color:#E0362E;display:block;white-space:nowrap}
.os__figcol .os__mark{font-size:clamp(1.8rem,2.4vw,2.4rem);margin-bottom:clamp(8px,1vw,14px)}
/* a rule the width of the figure, so the number and its caption read as one
   object rather than two runs that happen to be stacked */
.os__figcap{position:relative;margin-top:clamp(16px,1.8vw,26px);
  padding-top:clamp(14px,1.6vw,22px);max-width:none;
  font-size:clamp(.82rem,.94vw,.94rem);letter-spacing:.1em;line-height:1.4}
.os__figcap::before{content:"";position:absolute;top:0;left:0;
  width:100%;max-width:var(--figw,100%);height:1px;background:rgba(224,54,46,.55)}

@media (max-width:900px){
  .os__fig{font-size:clamp(3rem,17vw,5.4rem)}
  .os__figcol .os__mark{font-size:1.7rem}
  .os__figcap{font-size:.8rem}
}


/* ============================================================ TECHNOLOGY HEAD
   Three changes to the two grey blocks on the Technology page, and they are
   the same change: the head was a decoration with a label in it, and it is a
   structure with a number in it now.

   The hatched band goes. It was nine pixels of fine diagonals drawn across the
   top of each block, which at a glance is a texture rather than a rule, and it
   was the only thing on either block that carried no information at all.

   The index goes up from 0.78rem to display size. At twelve pixels a figure
   that rerolls through digits and settles is a flicker nobody can see; at forty
   the scramble is the point of it. The label moves alongside it on the same
   baseline instead of being pushed to the far edge, so the head reads as one
   block in the corner rather than as two marks holding the ends of a line. */
.os__rule{display:none}

.os__head{display:flex;align-items:baseline;justify-content:flex-start;
  gap:clamp(14px,1.8vw,26px);margin-top:0;margin-bottom:clamp(30px,4vw,56px)}
.os__num{font-family:var(--angular);font-weight:600;
  font-size:clamp(2rem,3.6vw,3.6rem);line-height:.9;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;order:-1}
.os__kicker{font-family:var(--angular);font-weight:600;
  font-size:clamp(.92rem,1.15vw,1.15rem);letter-spacing:.12em;gap:clamp(8px,.9vw,12px)}
.os__kicker i{width:clamp(7px,.7vw,9px);height:clamp(7px,.7vw,9px)}

/* the figures in the mandate grid come up with them */
.osgrid__n{font-family:var(--angular);font-weight:600;
  font-size:clamp(2.6rem,4.6vw,4.6rem);line-height:.9;letter-spacing:-.028em}
.osgrid__k{font-family:var(--angular);font-weight:600;
  font-size:clamp(.92rem,1.15vw,1.15rem);letter-spacing:.12em}

/* solid, meaning the columns share a baseline and the space between the parts
   is the same in every one of them rather than falling out of the copy */
.osgrid{gap:clamp(30px,4vw,72px);align-items:start}
.osgrid__col{gap:clamp(14px,1.6vw,22px)}
.osgrid__k,.osgrid__n{margin-bottom:0}

@media (max-width:900px){
  .os__num{font-size:clamp(1.8rem,7vw,2.6rem)}
  .osgrid__n{font-size:clamp(2.2rem,9vw,3rem)}
  .os__kicker,.osgrid__k{font-size:.86rem}
}


/* The Plex Condensed experiment is reverted. The site has one display face and
   it is the one the home page sets, Chakra, so Defense and Technology take it
   with every other page rather than each holding its own. The head's label
   position and the sizes that came down with the experiment both stay: they
   were the right calls independently of which face was carrying them. */

/* ---------- the head's label sits at the far edge ----------
   The index leads at the left and the label is pushed to the right margin, so
   the head spans the block rather than clustering in one corner of it. */
.os__head{justify-content:space-between}
