/* ===========================================================================
   Whisper — shared stylesheet
   Built to Whisper_Guide_021026.pdf (the 2 Oct refresh), NOT the previous
   brand system. Differences that matter:
     - body copy is Pilat Regular/Bold, NOT Pilat Extended Book (superseded)
     - three greys are now brand colours with defined roles (p20)
     - gradient is "big hits of colour", not a 10% accent (p20)
     - partnership lockups put the PARTNER first with a lowercase x (p14)
     - red and pink type are never used together (p23)
   =========================================================================== */

/* --- type ---------------------------------------------------------------
   .otf is what brand supplied. These want converting to .woff2 (roughly a
   third of the size) once the web licence with General Type is settled —
   all four files are DEVELOPMENT builds, see the handover. */
@font-face { font-family:"Pilat Extended"; src:url("../fonts/PilatExtended-Heavy.otf") format("opentype");
             font-weight:900; font-style:normal; font-display:swap }
@font-face { font-family:"Pilat Extended"; src:url("../fonts/PilatExtended-Regular.otf") format("opentype");
             font-weight:400; font-style:normal; font-display:swap }
@font-face { font-family:"Pilat"; src:url("../fonts/Pilat-Bold.otf") format("opentype");
             font-weight:700; font-style:normal; font-display:swap }
@font-face { font-family:"Pilat"; src:url("../fonts/Pilat-Regular.otf") format("opentype");
             font-weight:400; font-style:normal; font-display:swap }

:root{
  --red:#ff000e;
  --pink:#ff0097;
  /* Taken from the brand artwork itself (Whisper_Logo_RGB_Gradient.svg), not
     from the guide, which gives the two end colours and no angle or stops.
     Horizontal, and five stops — it holds red far longer than a plain two-stop
     ramp, so a simple #ff000e -> #ff0097 does not match the logo sitting on it.
     NOTE: Maddie's build uses 142deg, which disagrees with the artwork. */
  --grad:linear-gradient(90deg,
          #ff000e 0%, #ff000e .24%, #ff0038 25.64%,
          #ff006b 59.82%, #ff008b 85.68%, #ff0097 100%);
  --black:#000000;
  --white:#ffffff;
  --grey-01:#575752;   /* type / backgrounds */
  --grey-02:#b9b9b4;   /* type / backgrounds */
  --grey-03:#f5f5f1;   /* backgrounds */

  --display:"Pilat Extended",Arial,Helvetica,sans-serif;
  --body:"Pilat",Arial,Helvetica,sans-serif;

  --gutter:clamp(20px,4vw,64px);
  --maxw:1440px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--white); color:var(--black);
  font-family:var(--body); font-weight:400; font-size:17px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%; display:block}
a{color:inherit}

.wrap{max-width:var(--maxw); margin:0 auto; padding-inline:var(--gutter)}

/* headlines: ALL CAPS, Pilat Extended Heavy (p22/p23) */
h1,h2,h3,.h{
  font-family:var(--display); font-weight:900; text-transform:uppercase;
  margin:0; line-height:.98; letter-spacing:-.005em; text-wrap:balance;
}
h1{font-size:clamp(40px,7.4vw,104px); line-height:.92; letter-spacing:-.02em}
h2{font-size:clamp(28px,4.4vw,56px)}
/* subheads: Pilat Extended Regular, sentence case (p22) */
/* --fg, not --black. shell.css flips --fg to #fff in dark mode; a literal
   black stays black, and on the Careers page these four paragraphs were black
   on a black background - present, selectable, and invisible. Any text on a
   surface that follows the theme takes a theme token. */
/* Section intro paragraph. Pilat, not Pilat Extended: it set in the display
   face until 14 Oct, which left every intro in a different typeface from the
   body copy right under it. Still bigger than body at 22px. */
.sub{font-family:var(--body); font-weight:400; text-transform:none;
     font-size:clamp(17px,1.5vw,22px); line-height:1.35; color:var(--fg,var(--black));
     max-width:46ch}
.eyebrow{font-family:var(--body); font-weight:700; text-transform:uppercase;
         font-size:12px; letter-spacing:.16em; color:var(--muted,var(--grey-01))}
/* The dodo mark sits inline in some eyebrows. v3.css sizes it, but v3.css is
   only linked on the home page - on the News page the same markup rendered the
   bird at its intrinsic size, about 500px tall, above the headline. Sized here
   so it holds wherever the eyebrow is used, and the flex row is what keeps the
   mark and the word on one baseline. */
.eyebrow:has(img){display:flex; align-items:center; gap:10px}
.eyebrow img{height:13px; width:auto}

/* --- top bar: gradient, full bleed ------------------------------------- */
/* TODO v1-REMOVAL: this whole block is the v1 bar. v3 pages use the floating
   pill in shell.css, which has to override four of these rules by force
   (.topbar colour, .topbar .wrap flex/max-width, .topbar nav a padding, and
   the specificity that kept .navgenre visible at every width). Delete this
   block once About and Sport are on the shell - and delete the overrides in
   shell.css at the same time, or the nav silently loses its responsive hides. */
.topbar{background:var(--grad); color:var(--white)}
.topbar .wrap{display:flex; align-items:center; gap:24px; min-height:84px;
  /* The gradient bar runs edge to edge. Inside the 1440px content column it
     left roughly 300px of empty gradient each side on a wide screen, which is
     Lily's note: the logo belongs hard left, the nav hard right. The gutter is
     fluid, so this holds from a 390px phone to an ultrawide without a
     breakpoint. Everything BELOW the bar still uses --maxw. */
  max-width:none; padding-inline:clamp(20px,3vw,80px)}
.topbar .logo{height:22px; width:auto; margin-right:auto}  /* min 16px on screen, p12 */
.topbar nav{display:flex; gap:22px; align-items:center}
.topbar nav a{font-family:var(--body); font-weight:700; font-size:13px;
  text-transform:uppercase; letter-spacing:.08em; text-decoration:none; padding-block:4px}
.topbar nav a[aria-current]{border-bottom:2px solid var(--white)}
.kickoff{background:var(--white); color:var(--black); border-radius:999px;
  padding:9px 22px; font-family:var(--body); font-weight:700; font-size:13px;
  text-transform:uppercase; letter-spacing:.08em; text-decoration:none; white-space:nowrap}

/* --- section nav -------------------------------------------------------- */
/* Full-width rules run the gradient, red to pink, left to right (9 Oct).
   border-image is how a gradient gets onto a border: slice 1 stretches the ramp
   along the edge, and the sides with width 0 paint nothing. The solid colour
   stays in the shorthand as the fallback, so a browser that drops border-image
   still draws the hairline rather than nothing.

   Only rules that span the full content column change. A rule that spans one
   column of a grid keeps its neutral hairline, because a gradient restarted in
   every column reads as five short ramps rather than one. */
.sectionnav{border-bottom:1px solid var(--grey-03); border-image:var(--grad) 1}
.sectionnav .wrap{display:flex; gap:30px; flex-wrap:wrap; padding-block:18px 12px}
/* Measured off the artboard. The separation between selected and the rest is
   carried by WEIGHT as much as colour - 400 against 700 - which is why having
   them all bold made the active tab barely stand out. */
.sectionnav button{font-family:var(--body); font-weight:400; font-size:15px;
  letter-spacing:.06em; text-transform:uppercase; color:rgba(0,0,0,.62);
  background:none; border:0; padding:0 0 6px; cursor:pointer; position:relative}
.sectionnav button:hover{color:rgba(0,0,0,.82)}
.sectionnav button.here{color:var(--black); font-weight:700}
/* Centred under the tab, not pinned left: under a long label like HOW WE WORK
   a left-aligned arrow points at nothing. Lily's note, 4 Oct. */
.sectionnav button.here::after{content:"\2193"; position:absolute;
  left:50%; transform:translateX(-50%); top:100%;
  font-size:13px; line-height:1}
.sectionnav button:focus-visible{outline:2px solid var(--pink); outline-offset:3px}

/* All five panes share ONE grid cell, so the section is always as tall as the
   tallest and switching tabs never shifts the film hero below it. Hidden panes
   use visibility (still occupy space, still removed from the a11y tree) rather
   than display:none, which would collapse the box and reintroduce the jump. */
.intro{padding-block:clamp(40px,5vw,66px) clamp(30px,4vw,54px); display:grid}
.intro > [role=tabpanel]{grid-area:1/1}
.intro > [role=tabpanel][hidden]{display:block; visibility:hidden; pointer-events:none}
.intro .sub{margin-top:20px}
/* matched to Maddie's rendered metrics: 92px, -0.02em tracking, 0.92 leading */
.lede{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(34px,6.4vw,92px); line-height:.92; letter-spacing:-.02em;
  margin:0; text-wrap:balance; max-width:17ch}
.values{list-style:none; margin:0; padding:0; display:grid; gap:26px;
  grid-template-columns:repeat(3,1fr)}
.values h3{font-size:clamp(17px,1.7vw,22px); margin-bottom:8px}
.values p{margin:0; font-size:15px; color:var(--muted,var(--grey-01)); max-width:34ch}
/* The posters, on Join us. They carry their own headline in the artwork, so
   the li holds a picture and the line under it and no heading at all. The
   ratio is the artwork's own, 543x768, give or take a pixel across the three
   - stated here rather than left to the file, so a replacement at a different
   size cannot quietly change the row. */
/* Framed - Richard, 19 Oct: "some go to back before others so they don't
   look level". The posters themselves were always level (measured 19 Oct:
   all three images 614px tall, same top, same bottom at 1440). What was
   ragged is the caption: "Talent gets us in the room, teamwork keeps us
   there." runs to two lines where the other two run to one, so the third
   column finished 29px lower than its neighbours and the row read crooked.
   Two things fix it together. The li stretches to the tallest in the row and
   carries a frame, so the three boxes start and finish on the same lines
   whatever the copy does. And the caption gets the height of two lines
   whether it uses them or not, so the text block is the same size in all
   three and the poster tops stay level with it.

   The frame was 1px of --line (#242424 on the dark band) and Richard asked
   for it a hair wider and more defined. 2px, and the colour comes off
   currentColor rather than --line so it follows the theme: 34% of white over
   black lands on about #575757, which is Grey 01, and 34% of black over the
   light theme's ground gives the same weight of line the other way up. */
/* THE FRAME STOPS AT THE PICTURE - Richard, 20 Oct. It was on the li, so it
   went round the caption as well and the three boxes were really three
   cards. On its own span it holds the poster and nothing else, and the line
   under it sits outside, which is what he asked for.

   The levelling still works, and it was never the frame doing it. The li
   stretches to the tallest in the row, and the caption is given the height
   of two lines whether it uses them or not, so all three posters start and
   finish on the same lines whatever the copy does. Measured 19 Oct: the
   images were always 614px and level; it was the two-line caption on
   "Talent gets us in the room" that made the row read crooked. */
.values.posters li{display:grid; gap:14px; align-content:start}
.values.posters .frame{display:block;
  border:2px solid color-mix(in srgb, currentColor 34%, transparent);
  border-radius:14px; padding:14px}
/* clip-path, and it is doing a job the crop could not. The exported artwork
   carried a bright rim, and trimming two pixels off every file cleared it in
   the FILES - measured, every edge now within one level of its interior - but
   a hairline was still drawn around each poster on screen. Nothing in the
   cascade draws it: no border, outline or box-shadow on the img, the li, the
   section or the body, all checked in the rendered page. So it is the edge
   row itself at the rendered scale. inset(1px) drops that row on all four
   sides before it is painted, and `round 8px` keeps the corner the radius
   was giving us.

   The box ratio always follows the artwork, so the full height of each
   poster is shown and cover trims at most a pixel off a side rather than
   cutting the bottom back. That matters more here than on an ordinary
   photograph: each poster carries its own headline near its foot, and a box
   even slightly short of the file takes the words off.

   16 Oct: the finished artwork landed and the placeholders went. All three
   are 1080x1521, so the box is 1080/1521. It was 539/754 for the set before
   it, which had ten pixels taken off the bottom on 14 Oct to kill a hairline
   that the inset above now handles properly. */
.values.posters img{width:100%; aspect-ratio:1080/1521; object-fit:cover;
  display:block; border-radius:8px; background:var(--black);
  clip-path:inset(1px round 8px)}
/* The caption matches the copy above the posters rather than sitting at the
   15px body size, and it is centred under its own poster - Richard, 14 Oct. */
/* var(--body), not var(--display). These match the .sub paragraphs above them
   by Richard's own instruction, and .sub moved to Pilat on 14 Oct - this was
   the last prose on the page still set in the display face. */
.values.posters p{max-width:none; text-align:center;
  font-family:var(--body); font-weight:400;
  font-size:clamp(17px,1.5vw,22px); line-height:1.35;
  color:var(--fg,var(--black));
  min-height:calc(2 * 1.35em)}
@media (max-width:820px){ .values{grid-template-columns:1fr} }

/* --- film hero ---------------------------------------------------------- */
.filmhero{position:relative; background:var(--black); color:var(--white); overflow:hidden}
/* Standing in for the brand film with the DodoWalk footage: clean, no burned-in
   headline, and 3:1 rather than the 5.21:1 letterbox the cropped still forced.
   Maddie's hero is nearer 2.25:1 — when the real film lands, this one value
   and the <source> change together. */
/* No image until the film exists. Sized to the slot so the composition can
   still be judged; a video or image dropped in here inherits this box. */
.filmhero{min-height:clamp(300px,34vw,460px)}
.filmhero video,.filmhero img{width:100%; height:100%; object-fit:cover; opacity:.85}
.filmhero{display:grid}
.filmhero video,.filmhero img{grid-area:1/1}
.filmhero .inner{grid-area:1/1; align-self:end; padding:var(--gutter);
  max-width:var(--maxw); width:100%; margin:0 auto;
  /* The video carries opacity:.85, which gives it a stacking context and so
     paints it ABOVE a plain in-flow sibling. Without this the overlay is
     under the video and the play button cannot be clicked at all. */
  position:relative; z-index:1}
.filmhero .eyebrow{color:var(--white); display:flex; align-items:center; gap:9px}
/* The floor was 40px, and IMPOSSIBLE in Pilat Extended Heavy is wider than
   a 390px screen at that size - it ran off the edge AND stretched the grid
   track, which is what pushed the video 19px wider than the viewport. */
.filmhero h1,.filmhero h2{font-size:clamp(28px,7.4vw,104px); margin-block:14px 22px}
/* Pressing play: the overlay gets out of the way, the video comes up to full
   opacity and the box takes the film's own shape instead of the cropped slot. */
/* At rest: the silent loop fills the slot, the full film is not in the layout
   at all. On play they swap and the box takes the film's own shape. */
#brandfilm{display:none}
.filmhero.playing #heroloop{display:none}
.filmhero.playing #brandfilm{display:block}
.filmhero.playing .inner{display:none}
.filmhero.playing{min-height:0}
.filmhero.playing video{height:auto; aspect-ratio:16/9; object-fit:contain; opacity:1}
.pill{display:inline-flex; align-items:center; gap:11px; background:var(--grad);
  color:var(--white); border-radius:999px; padding:13px 26px; text-decoration:none;
  font-family:var(--body); font-weight:700; font-size:13px; letter-spacing:.09em;
  text-transform:uppercase; border:0; cursor:pointer}

/* --- trusted by --------------------------------------------------------- */
.trusted{border-block:1px solid var(--grey-03); padding-block:24px}
.trusted .eyebrow{margin-bottom:16px}
/* TODO v1-REMOVAL: the v1 logo band. `.logos img{max-height:30px}` below
   survived v3's override (different property) and squashed every partner logo
   out of ratio until v3.css added max-height:none. Delete with the block above. */
.logos{display:grid; grid-template-columns:repeat(auto-fit,minmax(118px,1fr));
  gap:10px; margin:0; padding:0}
.logos li{list-style:none; border:1px solid var(--grey-03); border-radius:3px;
  display:grid; place-items:center; padding:16px 10px; min-height:74px;
  background:var(--white)}
.logos img{max-height:30px; width:auto; object-fit:contain}

/* --- what we do --------------------------------------------------------- */
.whatwedo{padding-block:clamp(40px,5vw,72px)}
.whatwedo h2{margin-block:10px 28px}
.depts{display:grid; grid-template-columns:repeat(4,1fr); gap:22px; list-style:none; padding:0; margin:0}
.dept{display:flex; flex-direction:column}
.dept .shot{position:relative; color:var(--white)}
.dept .shot img{aspect-ratio:4/3; object-fit:cover; width:100%}
.dept .shot .on{position:absolute; inset:auto 0 0 0; padding:16px 18px 18px;
  background:linear-gradient(to top,rgba(0,0,0,.82),rgba(0,0,0,0))}
.dept .shot h3{font-size:19px; letter-spacing:.02em}
/* Reserve two lines on every card. The overlay is bottom-anchored, so a card
   whose copy wraps to two lines pushes its title up and the row stops
   aligning — "Branded" against the other three. */
.dept .shot p{margin:6px 0 10px; font-size:14px; line-height:1.35; min-height:2.7em}
.dept .shot a{font-family:var(--body); font-weight:700; font-size:12px;
  letter-spacing:.1em; text-transform:uppercase; text-decoration:none}
.dept .who{display:flex; gap:11px; align-items:center; border:1px solid var(--grey-03);
  border-top:0; padding:12px 14px}
.dept .who img,.dept .who .blank{width:34px; height:34px; border-radius:50%; object-fit:cover;
  background:var(--grey-03); flex:0 0 auto}
.dept .who b{display:block; font-size:13px}
.dept .who span{display:block; font-size:12px; color:var(--muted,var(--grey-01)); line-height:1.3}

/* --- footer ------------------------------------------------------------- */
/* The <footer> now wraps the columns, the dodo band and the bottom bar, so
   everything down there sits inside one landmark. The padding moves to an
   inner block or it would inset the full-bleed dodo band. */
/* No rule on top of the columns, Richard 20 Oct. This is the gradient
   hairline that sits immediately under the dodo band, and against a black
   band it read as a stray line rather than a divider. The band is its own
   separation. (The one I took off .bottombar first was the wrong one: that
   sits further down, above the copyright row.) */
.footcols{padding-block:clamp(34px,4vw,54px)}
.cols{display:grid; grid-template-columns:repeat(5,1fr); gap:26px}
.cols .colhead{font-family:var(--body); font-weight:700; font-size:10px; letter-spacing:.19em;
  text-transform:uppercase; color:rgba(0,0,0,.62); margin:0 0 12px}
.cols ul{list-style:none; margin:0; padding:0; display:grid; gap:7px}
.cols a{font-size:14px; text-decoration:none; color:rgba(0,0,0,.8)}
.cols a:hover{text-decoration:underline}

/* The dodo band. THE DODO FLIES NOW - Richard picked the 3.4:1 crop on 20 Oct
   from four mockups. DODO_NOSUN_16X9_WEBSITE is 16:9 and the bird fills
   almost its whole height, where the old walking dodo was shot for a 3:1
   band; at the band's old 4.5:1 only 40% of the frame fitted and it cut his
   head off. 3.4:1 shows 52% and keeps the head, the wings and the type.
   Cropped in the FILE at 1920x564 rather than by object-position, so nothing
   is downloaded that is never drawn.
   The guide (p17) is explicit that the Dodo is never locked up with the logo,
   so it lives here on its own, below the footer. */
.dodoband{background:var(--black); overflow:hidden; line-height:0}
/* 1440x424, which is the 3.4:1 the file is cut to. Still capped rather than
   left as a pure aspect-ratio: past 1440 that kept growing and took the bird
   with it, so on a wide screen he was bigger than the design. 29.44vw is
   424/1440, and the floor moves with it - 140 was the floor at 320, so 186
   is the same proportion at 424.
   object-position is 50% 50% now and does nothing: the file is already the
   band's exact ratio, so cover has nothing to choose between. */
.dodoband video,.dodoband img{width:100%; height:clamp(186px,29.44vw,424px);
   object-fit:cover; object-position:50% 50%; display:block}

/* White, not black. The dodo band above is the dark note; the bar returns to
   the page. Measured off the artboard: everything here is 10px/700 at .15em
   in 62% black, except the active language, which is full black. */
/* TODO v1-REMOVAL: forcing white here is what put white signoff text on a
   white footer in dark mode. */
.bottombar{background:var(--bg,var(--white)); color:var(--muted,rgba(0,0,0,.62))}
.bottombar .wrap{display:flex; flex-wrap:wrap; gap:14px 30px; align-items:center;
  padding-block:26px; font-family:var(--body); font-weight:700; font-size:10px;
  letter-spacing:.15em; text-transform:uppercase}
.bottombar a{text-decoration:none; color:var(--muted,rgba(0,0,0,.62))}
.bottombar a:hover{color:var(--black)}
.bottombar .right{margin-left:auto; display:flex; gap:14px; align-items:center}
/* The language toggle is deliberately legible: Sunil has to sign off on
   whether Welsh ships, and he cannot do that if he cannot see the switch. */
.bottombar .lang{display:flex; gap:10px; align-items:center}
.bottombar .lang a[aria-current]{color:var(--black)}
.bottombar .lang .sep{color:rgba(0,0,0,.38)}
/* Pilat Extended REGULAR at 12px and .24em, not the Heavy cut. */
.bottombar .signoff{font-family:var(--display); font-weight:400; font-size:12px;
  letter-spacing:.24em; color:var(--black); margin-left:16px}

/* --- Welsh draft notice: generated pages only, delete with the banner ---- */
.cybanner{position:fixed; left:12px; bottom:12px; z-index:99;
  background:var(--white); color:var(--black); border:1px solid var(--grey-02);
  border-left:4px solid transparent; border-image:var(--grad) 1;
  border-radius:4px; padding:9px 13px; font-family:var(--body); font-size:11px;
  letter-spacing:.06em; max-width:min(92vw,340px); line-height:1.5}
.cybanner b{color:var(--black)}

/* --- review build banner: delete this block and the <aside> to ship ------ */
.reviewbar{position:fixed; right:12px; bottom:12px; z-index:99;
  background:var(--black); color:var(--white); border:1px solid var(--grey-01);
  border-radius:4px; padding:9px 13px; font-family:var(--body); font-size:11px;
  letter-spacing:.09em; text-transform:uppercase; max-width:min(92vw,330px); line-height:1.5}
.reviewbar b{color:var(--pink)}

@media (max-width:1080px){
  .depts{grid-template-columns:repeat(2,1fr)}
  .cols{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:620px){
  .topbar nav{display:none}
  .depts{grid-template-columns:1fr}
  .cols{grid-template-columns:repeat(2,1fr)}
  .sectionnav .wrap{gap:18px}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important; transition:none!important}
}

/* ===========================================================================
   Department page (Sport is the template; Entertainment, Documentaries and
   Branded inherit it unchanged)
   =========================================================================== */
.depttabs{border-bottom:1px solid var(--line,var(--grey-03)); border-image:var(--grad) 1}
.depttabs .wrap{display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding-block:13px}
.crumb{font-family:var(--body); font-weight:700; font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted,var(--grey-01)); margin-right:auto}
.crumb a{text-decoration:none}
.depttabs .tab{font-family:var(--body); font-weight:700; font-size:11px; letter-spacing:.11em;
  text-transform:uppercase; text-decoration:none; padding:8px 17px; border-radius:999px;
  border:1px solid var(--line,var(--grey-03)); color:var(--fg,var(--black))}
.depttabs .tab[aria-current]{background:var(--fg,var(--black)); color:var(--bg,var(--white)); border-color:var(--fg,var(--black))}
/* Roll over a tab and it fills. Richard asked for the pill on hover, 14 Oct:
   the shape was already a pill, it just did not answer the pointer. The fill
   is the brand gradient, the same one .pill carries, so a hovered tab and a
   button read as the same object. The border goes transparent rather than
   away, so nothing moves by a pixel as it fills. The current tab fills too -
   it is still the solid one at rest, which is where the "you are here" lives. */
.depttabs .tab{transition:background .16s ease, color .16s ease, border-color .16s ease}
.depttabs .tab:hover,.depttabs .tab:focus-visible{background:var(--grad);
  color:var(--white); border-color:transparent}

/* minmax(0,1fr): the image is a grid item whose aspect-ratio x min-height gives
   it an intrinsic width of 896px, and an auto track grows to fit that - so
   max-width:100% resolved against 896, not the viewport, and the page scrolled
   sideways on a phone. The track has to be allowed to shrink. */
.depthero{position:relative; background:var(--black); color:var(--white);
  display:grid; grid-template-columns:minmax(0,1fr)}
/* 2.1:1, not 3.2:1 (15 Oct). The band carries a 16:9 clip now, and at 3.2:1
   it showed the middle 55.6% of the frame - which took the tops off heads in
   both cuts. 2.1:1 shows 84.7%, and stands 720px tall on a 1512 screen.

   The cap is against the WINDOW, not the width. As a pure ratio the height
   follows the width, so a 1920 monitor got a 914px band that filled it and a
   2560 one 1219px.

   100vh minus 140 is the header (91) plus 49px of the section below it: when
   the cap bites, there is always that sliver of the next band showing, so the
   hero never reads as the whole page. On a 1512 x 860 window the ratio and the
   cap agree at 720 and nothing is given up; above that the cap takes over and
   the crop creeps back towards 72%, which is still a long way better than the
   55.6% a 3.2:1 band was showing. min-height beats max-height in the cascade,
   which is what stops the band collapsing in a short window. */
.depthero > img{grid-area:1/1; width:100%; max-width:100%; aspect-ratio:2.1/1;
  min-height:280px; max-height:calc(100vh - 140px); object-fit:cover}
/* The banner clip, laid OVER the still rather than in place of it. The still
   is what shows with no JavaScript, under prefers-reduced-motion, before the
   first frame arrives, and if the file ever 404s - so the band is never a
   black box. banner.js adds .on at the first painted frame. */
.depthero > video.clip{grid-area:1/1; width:100%; max-width:100%; aspect-ratio:2.1/1;
  min-height:280px; max-height:calc(100vh - 140px); object-fit:cover;
  opacity:0; transition:opacity .45s ease}
.depthero > video.clip.on{opacity:1}
/* A scrim, not a dimmer. The image stays bright where there is no type and
   darkens under it — white Pilat on a lit F1 garage is otherwise unreadable. */
.depthero::after{content:""; grid-area:1/1; pointer-events:none;
  background:linear-gradient(to top,rgba(0,0,0,.88) 0%,rgba(0,0,0,.55) 34%,rgba(0,0,0,.08) 66%,rgba(0,0,0,0) 100%)}
/* A column, not a row (12 Oct). The head of department used to sit to the
   RIGHT of the title, bottom-aligned with it, which put a 50px pill level with
   a 76px word and left a gap across the middle of the hero. It reads as a
   caption to the division now: SPORT, then the person who runs it, directly
   underneath.

   align-items:flex-start, so the pill is as wide as its contents and sits on
   the same left edge as the eyebrow and the title. Without it a stretch would
   run the white pill the full width of the hero. */
.depthero .inner{grid-area:1/1; align-self:end; width:100%; max-width:var(--maxw); margin:0 auto;
  padding:var(--gutter); display:flex; flex-direction:column; align-items:flex-start;
  gap:0; position:relative; z-index:1}
/* margin-right:auto was what pushed the card to the far edge of the row. In a
   column it does nothing, and the h1's own 20px bottom margin now sets the gap
   to the card. */
.depthero .lhs{margin-right:0}
.depthero .eyebrow{color:var(--white); display:flex; align-items:center; gap:9px}
/* Sized to DOCUMENTARIES and ENTERTAINMENT, not to SPORT.
   At 8vw/112px the thirteen-letter names ran 1443px wide inside a 1440 window
   and pushed the whole page sideways, while Sport looked perfect - the kind of
   fault that only shows on three of four pages. Left to wrap instead, a single
   word cannot break, so the size has to come down. */
.depthero h1{font-size:clamp(34px,5.4vw,76px); margin-block:10px 20px;
  overflow-wrap:anywhere}
/* the department head sits ON the hero, as a light card. It is an <a> on the
   division pages now (12 Oct) and goes to the enquiry form at the foot of the
   same page - clicking the person who runs a division should start a
   conversation with them, which was previously only possible by scrolling past
   every case study to find the form. */
.leadcard{background:var(--white); color:var(--black); border-radius:999px;
  display:flex; align-items:center; gap:14px; padding:9px 34px 9px 9px;
  flex:0 0 auto; max-width:100%; text-decoration:none;
  transition:transform .16s ease}
a.leadcard:hover,a.leadcard:focus-visible{transform:translateY(-2px)}
/* Two lines, not three (16 Oct). The name used to sit on its own at the top
   with "Talk to Pete" as a third line underneath; the name now rides in that
   line and the pill is the action rather than the introduction.

   .leadtalk is gone with it - the span it styled no longer exists on any of
   the four division pages, which are the only places it was ever used.

   The envelope is inline-block rather than a flex item on purpose. Making
   the <b> a flex container would break the ellipsis below, which needs a
   block box to truncate against; inline-block keeps both. It is drawn rather
   than set as a character because U+2709 carries an emoji presentation on
   several platforms and would land in the pill in colour, against a brand
   that is black and white. Sized in em so it tracks the line it sits on,
   which is now the 14px name rather than the 12px role. */
/* To the RIGHT of the name - Richard, 16 Oct - so the gap goes with it. */
.leadcard b .mico{width:1.2em; height:.9em; display:inline-block;
  vertical-align:-.08em; margin-left:6px}
.leadcard > div{min-width:0}
.leadcard b,.leadcard span{white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.leadcard img{width:42px; height:42px; border-radius:50%; object-fit:cover}
.leadcard b{display:block; font-size:14px}
/* The pill is white in BOTH themes, so this stays pinned to the light-mode
   grey. Through --muted it became #9a9499 on white: 2.97:1. */
.leadcard span{display:block; font-size:12px; color:var(--black); line-height:1.35}
/* The role and the email used to be one span with a <br> between them. The
   inner span was already display:block from the rule above, so it ended the
   line on its own and the <br> broke a second time - the blank line in the
   middle of the pill. Two siblings now, with the gap set deliberately here
   instead of by an accident of markup.
   And that gap is now nothing. 5px bought a visible step between the role and
   the email that the name and the role did not have, so the three lines read
   as two groups rather than one block, and the pill carried the height for
   it. They are one address: same leading throughout. */
.leadcard .mail{margin-top:0}
/* No underline on the address. In the pill it is one of three stacked lines in
   the same colour and size, so the rule under it read as a box edge rather than
   a link, and it is the only underlined thing on the page: every other link here
   sets text-decoration:none and relies on position and weight. It is still a
   mailto, and still shows the underline on keyboard focus. */
.leadcard .mail a{text-decoration:none}
.leadcard .mail a:focus-visible{text-decoration:underline}

.band{padding-block:clamp(34px,4vw,56px)}
.band.tint{background:var(--grey-03)}
/* The department partner band, treated exactly like the home page's "Proud to
   partner with" band. It is NOT sharing .logos from v3.css: v3.css is only
   linked on the home page, and pulling it onto four department pages to reuse
   ten lines would drag the whole home-page cascade with it. The numbers below
   are the same ones, and if one band changes the other has to change with it.

   The tile is 3:2 with no padding of its own. The normalised files are 600x400
   - the tile's own ratio, with the margin baked in by normalise-logos.py - so
   they fill it and every logo lands at the same optical weight. Padding here
   would squeeze the content box out of 3:2 and drop every PNG below centre. */
/* 80%, left aligned: six tiles across the full 1360px column put each logo at
   218px, which outweighed everything around it. This brings the tile to 173px,
   a shade over the 20% reduction asked for, and keeps the row's left edge on
   the same line as the eyebrow above it and the services below. The cap is
   lifted at the 3-column breakpoint, where the tiles are already wider than
   the desktop ones and have no room to give. */
.partners6{display:grid; grid-template-columns:repeat(6,1fr); gap:10px;
  list-style:none; margin:14px 0 0; padding:0; max-width:80%}
.partners6 li{background:#fff; border:1px solid var(--grey-03); border-radius:10px;
  padding:0; aspect-ratio:3/2; display:grid; place-items:center; overflow:hidden}
/* max-height:none is load-bearing: the v1 band's `.logos img{max-height:30px}`
   sits above this in the same file and would otherwise clamp every PNG to 30px
   inside a 92px tile. Overriding width and height does not clear it - it is a
   different property. */
.partners6 img{width:100%; height:auto; max-height:none; display:block}
.partners6 .vector{width:auto; max-width:74%; max-height:62%; margin-inline:auto}
/* Measured by rendering each at 600px and comparing ink centroid to bbox
   centre: EA sits 5.7% low, Red Bull 9.4% - its wordmark is heavier than the
   bulls above it. The nudge is a percentage of each image's OWN height, so it
   holds at every tile size. */
.partners6 img[src$="ea.svg"]{transform:translateY(-5.7%)}
.partners6 img[src$="red-bull.svg"]{transform:translateY(-9.4%)}

/* services: lead on the left, numbered list on the right */
.services{display:grid; grid-template-columns:minmax(220px,1fr) 2.1fr; gap:clamp(24px,4vw,64px); align-items:start}
.services .lead p{margin-top:14px; color:var(--muted,var(--grey-01)); font-size:15px; max-width:30ch}
/* .lede is sized for a full-width intro. In this column it must size off the
   column, not the viewport — 6.4vw in a 409px column gave 92px type. */
.services .lede{font-size:clamp(28px,3.1vw,46px); max-width:12ch; line-height:.95;
  overflow-wrap:anywhere}
.svclist{list-style:none; margin:0; padding:0}
/* The rules between services run red to pink. border-image is how a gradient
   gets onto a one-sided border: a slice of 1 stretches the ramp along the top
   edge, and the other three widths are 0 so nothing else paints. Six hairlines
   is well inside the gradient's share of a page. */
/* > li, not li. The Partners row holds a nested <ul> of logo tiles, and a
   descendant selector put a gradient hairline on top of all three of them.
   Richard spotted it on 14 Oct. */
.svclist > li{display:grid; grid-template-columns:104px 1fr; gap:18px; align-items:center;
  padding-block:16px; border-top:1px solid; border-image:var(--grad) 1}
.svclist > li:first-child{border-top:0}
/* Perks on Join us runs two columns - Richard, 19 Oct, when the placeholder
   still came out and the block went full width.

   NO HAIRLINES. .svclist gives every row a red-to-pink border-top, which
   works down a single full-width column and does not work here: in two
   columns each rule only spans its own column, so they read as four short
   dashes at different heights rather than as one divider. Richard asked for
   them off on 19 Oct. The row gap does the separating instead - 16px of the
   li's own padding each side, plus the gap below.

   Below 820 it falls back to one column. The rules stay off there too: the
   page is the same page at any width and should not grow a divider on a
   phone that it does not have on a desktop. */
.svclist.perks2{display:grid; grid-template-columns:1fr 1fr;
  column-gap:clamp(30px,4.4vw,64px); row-gap:clamp(6px,1vw,16px)}
.svclist.perks2 > li{align-items:start; border-top:0}
@media (max-width:820px){
  .svclist.perks2{grid-template-columns:1fr}
}
/* The marker column is gone. It held 01-06, then a dodo silhouette; six of them
   stacked down the page read as decoration rather than as a marker, and the
   <ol> carries the ordering without either. The span stays in the markup so the
   column can come back without touching six pages of HTML. */
.svclist .n{display:none}
/* Perks on Join us, and How to apply and Partners on the Academy, use the same
   column with no stills, so the text column runs the full width and the 52ch
   measure still holds it to sport's line. */
.svclist.noimg > li{grid-template-columns:1fr; gap:0}
/* A row can hold more than one paragraph: the first sits under the heading,
   the rest space off it. */
.svclist p + p{margin-top:11px}
/* The rows sit inside a .careers column. When the list follows copy it needs
   air above it; when it IS the column, as Perks is, it starts flush. */
.careers .svclist{margin-top:26px}
.careers .svclist > li:first-child{padding-top:0}
.careers > div > .svclist:first-child{margin-top:0}
/* .ruled puts the hairline back on a first row - a one-row list, like Partners
   under the Academy picture, otherwise has no rule at all. */
.svclist.ruled > li:first-child{border-top:1px solid; border-image:var(--grad) 1;
  padding-top:16px}

/* The genre pages lose the rules between services (16 Oct). The gradient
   hairline stays everywhere else it is used - careers still has it under
   Partners - so this is a modifier on the three lists that asked for it
   rather than the rule coming out of .svclist itself. Sport had a second
   shape of its own until 16 Oct and needed a second selector; now that its
   services are a plain list like everywhere else, one rule covers it. */
.svclist.noline > li{border-top:0}

/* Branded runs its two services side by side - Richard, 19 Oct, when the
   list came down from five to two. A two item stack left most of the band
   empty.

   THE SECTION HAS TO GO SINGLE COLUMN FOR THIS TO FIT, and that is the part
   worth writing down. .services is a two-up - minmax(220px,1fr) and 2.1fr -
   so the list lives in the right-hand column, 521px wide at 1440. Each li
   needs 377px of its own: a rigid 234px thumb, an 18px gap and 125px of
   text min-content - the thumbs grew four times on 19 Oct, Richard, 104 to
   125 to 150 to 195 to 234. Two across plus the gap is 806. It overflowed the PAGE
   by 2px at 1440 and 66px at 1100, and min-width:0 does nothing about it,
   because 247 is the content's own floor rather than a flex basis.

   So the intro goes full width and the services run underneath it.
   Measured at 1440: the section grows from 325px to 462px, because what
   used to sit beside the intro now sits below it. That is what a true row
   costs here.

   Scoped with :has to the .svcrow list, so Entertainment and the Welsh
   Sport page keep their two-up and their stacked lists.

   minmax(0,1fr), not 1fr: a bare 1fr is floored at min-content, which with
   a fixed thumb in each cell came out uneven, 247 and 278 rather than
   matching.

   Back to one column at 820, the same breakpoint the Join us perks use. */
.services:has(> .svclist.svcrow){grid-template-columns:1fr;
  row-gap:clamp(22px,3vw,40px)}
/* row-gap added 19 Oct: this was a single row of two until Entertainment's
   four categories went into a 2x2 and gave it a second. */
.svclist.svcrow{display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:clamp(24px,3.4vw,52px); row-gap:clamp(22px,2.6vw,38px);
  align-items:start}
/* 900, not 820, from 19 Oct. At a 234px thumb each item needs 234 + 18 +
   its text, and two of those plus the column gap asked for 2px more than an
   860px screen had. Two across genuinely does not fit between 820 and 900 at
   this size, so the stack starts higher. */
@media (max-width:900px){
  .svclist.svcrow{grid-template-columns:1fr; row-gap:4px}
}

/* ---------------------------------------------------------------------------
   Each service is its own heading with its words under it, 16 Oct. Mark's
   15 Oct shape put the explanation and the area in the same grid ROW, which
   tied both columns to one rhythm set by the still. Splitting them into two
   independent lists freed the left but left two columns that no longer
   related to one another. This is the third shape and the one Richard chose
   off the mock: the still and the title ARE the heading, the words sit under
   them, and nothing paces anything else.

   NO RULE under the heading. The mock carried a gradient hairline there and
   Richard took it off - seven of them down one page is well past the accent
   the gradient is meant to be.
--------------------------------------------------------------------------- */
.svcheads{list-style:none; margin:clamp(20px,2.4vw,34px) 0 0; padding:0;
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(26px,3vw,44px) clamp(32px,4vw,64px)}
/* The line sits under the TITLE, not under the picture - Richard, 17 Oct.
   It used to run the full width of the cell, starting back at the image's
   left edge, so every item was a picture-and-title row with a paragraph
   slung underneath it. Tucking the line into the second column puts the
   whole thing on one block and takes a row of height out of each of the
   seven.

   The li becomes the grid and .svch goes display:contents, so the img and
   the h3 inside it become items of the li's grid alongside the p, without
   changing the markup. The img spans both rows and holds the left column;
   the h3 and the p stack in the right one. */
/* THE THIRD ROW IS THERE TO SWALLOW THE SLACK, 19 Oct. The picture is 65px
   tall and spans the text rows, so where the paragraph ran to one or two
   lines the pair of auto rows had to grow to meet it - and a grid shares
   that surplus between the tracks, which pushed the paragraph away from its
   heading. Insight, on one line, sat furthest from its title; Live, on
   three, sat tight against it. Richard saw the gap wandering down the
   column. Rows one and two now stay at their content height, the image
   spans all three, and the empty 1fr row at the bottom takes whatever is
   left over. The 6px is moved onto the h3 so the row gap is zero and the
   spare row costs nothing. */
.svcheads > li{min-width:0; display:grid; grid-template-columns:234px 1fr;
  grid-template-rows:auto auto 1fr;
  column-gap:16px; row-gap:0; align-items:start}
.svcheads .svch{display:contents}
.svcheads .svch img{grid-column:1; grid-row:1 / -1; align-self:start}
.svcheads h3{grid-column:2; grid-row:1}
.svcheads > li > p{grid-column:2; grid-row:2; margin:0}
.svcheads .svch img{width:234px; aspect-ratio:16/10; object-fit:cover;
  border-radius:2px; display:block}
/* Sport's seventh area has no photograph yet and wears the stripes, exactly
   as it did while it lived in a .svclist. */
.svcheads img[data-placeholder]{background:repeating-linear-gradient(45deg,
  #2a2a28 0 12px,#1b1b1a 12px 24px)}
.svcheads h3{margin:0 0 6px; font-family:var(--display); font-weight:900;
  text-transform:uppercase; font-size:15px; line-height:1.14;
  letter-spacing:.01em; text-wrap:balance}
.svcheads p{font-size:14px; line-height:1.5;
  color:var(--muted,var(--grey-01)); max-width:46ch}
@media (max-width:860px){ .svcheads{grid-template-columns:1fr} }
/* And the ROW inside each item collapses on a phone, 19 Oct. The thumb went
   to 195px and a rigid 195 + 18 + the longest word in the copy came to more
   than a 360px screen has, so Sport scrolled sideways by 45px. The picture
   sits above its heading instead of beside it. .svclist does the same thing
   at this width; it hides its pictures, Sport keeps its eight. */
@media (max-width:620px){
  /* row-gap:0 and the space on the picture instead. A row-gap would sit
     between the heading and its copy too, and that gap is held at 6px by
     Richard's own instruction earlier today. */
  .svcheads > li{grid-template-columns:1fr; row-gap:0}
  .svcheads .svch img{margin-bottom:10px}
  .svcheads .svch img{grid-column:1; grid-row:auto}
  .svcheads h3{grid-column:1; grid-row:auto}
  .svcheads > li > p{grid-column:1; grid-row:auto}
}

/* The section's own headline, full width above the pairs rather than a lede
   in a left-hand column. 22ch because this one is a sentence where
   "Six services. One creative partner." was four words. */
.serviceslede{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(28px,3.1vw,46px); line-height:.98; max-width:22ch;
  letter-spacing:-.01em; margin:0 auto clamp(20px,2.4vw,34px);
  /* CENTRED, 19 Oct, with the other three division intros. The measure stays
     at 22ch; auto side margins are what move it, text-align is what sets the
     ragged edges either side of centre. */
  text-align:center}
/* A label over a stack, at the row headings' size rather than the 44px the
   column's own heading takes. */
.careers .stackhead{font-size:16px; letter-spacing:.02em; margin:26px 0 0}
.careers .stackhead + .svclist{margin-top:10px}
.svclist img{width:104px; aspect-ratio:16/10; object-fit:cover; border-radius:2px}
/* THE BIGGER THUMB IS FOR THE DIVISION PAGES ONLY - Richard, 19 Oct. The
   services lists on Sport, Branded and Entertainment carry .noline and
   nothing else on the site does; Join us uses .svclist.noimg for its perks
   and its academy logos, and About and News do not use the component at
   all. Scoped rather than left on the base rule so a list added elsewhere
   later does not quietly inherit a 150px picture. */
/* Top aligned, not centred - Richard, 20 Oct, on Entertainment. The base
   .svclist centres its text against the picture, which with a 234px thumb
   left each heading floating in the middle of its own row. Sport's .svcheads
   has aligned this way all along, so the three division lists now match it.
   Branded's pair is the same component and moves with Entertainment's quad. */
.svclist.noline > li{grid-template-columns:234px 1fr; align-items:start}
.svclist.noline img{width:234px}
.svclist h3{font-size:16px; letter-spacing:.02em}
.svclist p{margin:5px 0 0; font-size:14px; color:var(--muted,var(--grey-01)); max-width:52ch}
/* The five Perks blocks on Join Us went from prose to bullets - Richard,
   19 Oct. Same type and colour the paragraphs had, so the only change on the
   page is the shape. The marker sits in grey 02 so it reads as punctuation
   rather than a second column of text, and the indent is deliberately small:
   these lists sit inside a two-up, not a full measure. */
.svclist .perklist{margin:7px 0 0; padding-left:17px; max-width:52ch;
  list-style:disc; display:grid; gap:5px}
.svclist .perklist > li{font-size:14px; line-height:1.5;
  color:var(--muted,var(--grey-01)); padding-left:2px}
.svclist .perklist > li::marker{color:var(--grey-02); font-size:11px}

/* work: horizontal scroller */
.workhead{display:flex; align-items:center; gap:14px; margin-bottom:18px}
.workhead h2{margin-right:auto}
/* Keeps its white face in both themes, so the chevron is pinned black -
   inheriting --fg put a white glyph on a white button in dark mode. */
/* The same control as the News rail's, so the two carousels do not arrive at
   the same job wearing different clothes. It was a white disc with a pinned
   black chevron; the chevron takes the theme's foreground now, which is the
   fix that stopped the News arrows rendering as empty circles on black. */
.scrollbtn{width:38px; height:38px; border-radius:999px; cursor:pointer;
  border:1px solid var(--line,rgba(0,0,0,.18)); background:transparent;
  font:inherit; font-size:18px; line-height:1; color:var(--fg,var(--black))}
.scrollbtn:hover:not(:disabled){background:var(--fg,var(--black));
  color:var(--bg,var(--white)); border-color:var(--fg,var(--black))}
.scrollbtn:disabled{opacity:.3; cursor:default}
.scrollbtn:focus-visible{outline:2px solid var(--pink); outline-offset:3px}
/* No scroll snapping, and that is a reversal worth recording.
   It broke two features in a row. With `x mandatory`, setting scrollLeft to 50
   read back as 0. Relaxed to proximity it STILL cancelled the drift - a rAF
   loop accumulated 21.23px over 90 frames and scrollLeft read 0, because 21px
   is close enough to the snap point at 0 for proximity to pull it home. The
   same thing would eat the hover nudge, which moves by a part of a card.
   This is a free-scrolling strip of 330px cards in a 1360px rail, not a pager,
   so snapping was buying very little for the trouble it caused. Put it back
   only together with a drift and a nudge that work around it. */
.workrail{display:flex; gap:18px; overflow-x:auto; scroll-snap-type:none;
  scrollbar-width:none; padding-block:26px;
  /* 18px of room at each end for the end cards to grow into, pulled straight
     back off with an equal negative margin so the first card's left edge stays
     exactly where it was against the wrap. Without it the end cards had to
     grow inward from their own edge, which put all 33px of the scale on one
     side and 15px of it on top of the next card - Richard, 19 Oct. */
  padding-inline:18px;
  /* never wider than the gutter it is pulling back into, or the page itself
     gains 2px of horizontal scroll at 420px and below - measured 19 Oct */
  margin-inline:max(-18px, calc(var(--gutter) * -1))}
.workrail::-webkit-scrollbar{display:none}
/* The hover grow is NOT here. It has been further down since 9 Oct, with the
   transform-origin the end cards need, and a second copy added up here on 14
   Oct was dead weight that also hid the fact it already existed. */
.workcard{flex:0 0 clamp(250px,23vw,330px)}
.workcard .shot{position:relative}
/* .shot img, not any img in the card. This rule was also catching the partner
   marks in the lockup underneath: the ITV mark came out 39x22, which is 16:9,
   and the Whisper logotype was squashed to 20px wide. Same fault as
   .leaders img had with the LinkedIn mark - a photo rule written before
   there were any other images in the card. */
.workcard .shot img{width:100%; aspect-ratio:16/9; object-fit:cover}
.tag{position:absolute; top:10px; left:10px; background:var(--white); color:var(--black);
  font-family:var(--body); font-weight:700; font-size:10px; letter-spacing:.12em;
  text-transform:uppercase; padding:4px 9px; border-radius:2px}
.workcard h3{font-size:14px; margin-top:12px; letter-spacing:.02em}
.workcard p{margin:5px 0 0; font-size:12px; color:var(--muted,var(--grey-01)); line-height:1.45}
/* co-branding: partner FIRST, lowercase x in the gradient (guide p14) */
.lockup{margin-top:9px; font-size:11px; font-weight:700; letter-spacing:.11em; text-transform:uppercase}
/* Marks rather than words on the case study cards, and NO box around them -
   the tiles are reversed artwork on transparency, so they sit straight on the
   black. A partner we hold no mark for keeps its name in type rather than
   leaving a hole; those are listed in the commit. */
.lockup.marks{display:flex; align-items:center; gap:6.5px; flex-wrap:wrap;
  margin-top:11px; line-height:1;
  /* A partner we hold no mark for keeps its name in type, and that type has
     to MEASURE the same as the Whisper logotype beside it, not share its
     px value. 13.01px of font-size is 13.01px of em box; the logotype is
     13.01px of actual letter. Pilat at 700 has a cap height of 0.7344 of the
     em - measured off the rendered font at 1000px so the ratio is not rounded
     to a device pixel - so NEOM was printing at 9.55px against a 13.01px
     logo, a quarter short, which is what Richard saw on Branded, 14 Oct.
     13.01 / 0.7344 = 17.71px puts the caps on the logotype's own line.

     The gap is pinned in px for the same reason: at .5em it was riding on the
     font-size and would have grown with it, pushing every mark apart. */
  font-size:17.71px}
/* The separator is NOT a name and does not grow with them. Left at the size
   it has always been, which is where it reads correctly against both. */
.lockup.marks .x{font-size:13.01px}
.lockup.marks .lmark{height:22px; width:auto; flex:0 0 auto; display:block}
/* The logotype is 9.95:1 and the partner tiles are 3:2, so matching their
   BOXES would leave Whisper twice the optical weight. Height alone, set
   against the marks beside it. */
.lockup.marks .lmark.wmk{height:13.01px}

/* WHY EVERY MARK HAS ITS OWN HEIGHT AND ITS OWN CLIP.
 * Each tile in assets/partners/white is a 600x400 canvas with the artwork
 * padded inside it by a different amount, so one height sizes the CANVAS, not
 * the logo. mclaren.png inks 516x119 of its 400 rows, so height:22px drew the
 * wordmark at 6.5px against Whisper's 11px.
 *
 * Each mark carries a height measured from its own ink box, so the artwork
 * lands at 13.01px: the Whisper logotype's own height on these lockups. A mark
 * squarer than 3:1 carries a second line or is a symbol rather than a wordmark,
 * so it rises to 17.15px.
 *
 * THE NEGATIVE MARGINS CROP THE BOX. THE CLIP CROPS THE PAINT. The margins
 * alone pulled the box in to the artwork but the image still PAINTED its whole
 * canvas, and that canvas is opaque black - so artists-equity, which inks only
 * rows 151-257 of 400, reached 18.5px above its box and painted a black
 * rectangle straight over the word TURBULENCE above it. Invisible on an empty
 * black band, not invisible over a title. clip-path takes the same crop out of
 * what is drawn, so the two agree and nothing is painted outside the artwork.
 *
 * Generated by measuring the files. Rerun if a tile is replaced. */
.lockup.marks .lmark[src$="/amazon-prime.png"]{height:27.3px; margin:-5.99px -6.62px -4.94px -6.51px;
  clip-path:inset(21.75% 16.17% 18% 16%)}  /* ink 407x241, 1.69:1 */
.lockup.marks .lmark[src$="/artists-equity.png"]{height:63.7px; margin:-24.05px -6.63px -22.75px -6.63px;
  clip-path:inset(37.75% 7% 35.75% 7%)}  /* ink 516x106, 4.87:1 */
.lockup.marks .lmark[src$="/bbc.png"]{height:39.56px; margin:-14.28px -10.06px -14.1px -9.98px;
  clip-path:inset(36% 17% 35.75% 16.83%)}  /* ink 397x113, 3.51:1 */
.lockup.marks .lmark[src$="/canal-plus.png"]{height:55.5px; margin:-21.1px -5.8px -21.4px -5.8px;
  clip-path:inset(38% 7% 38.5% 7%)}  /* ink 516x94, 5.49:1 */
.lockup.marks .lmark[src$="/channel4.png"]{height:22.5px; margin:-1.6px -10.6px -3.8px -10.5px;
  clip-path:inset(7.25% 31.33% 16.75% 31.17%)}  /* ink 225x304, 0.74:1 */
/* Added 16 Oct. Unlike the marks around them these two arrived already
   white on a dark ground and were trimmed to their ink, so there is no
   canvas padding to claw back with negative margins - the height is the
   ink. 17px is the tallest trimmed mark in use, so they sit level with
   their neighbours and inside the 18px row the cards reserve. */
.lockup.marks .lmark[src$="/dazn.png"]{height:20.58px; margin:-2.47px -7.61px -2.47px -7.56px;
  clip-path:inset(12.00% 24.67% 12.00% 24.50%)}
/* SCEE, on Rage on the Red Sea. Supplied black on white, so the ink is the
   dark pixels and the mark is the inverted luminance.

   SET ON THE 17.1px SYMBOL BAND, not by optical mass. Mass compares the white
   two marks draw, which is the right ruler when they are the same KIND of
   thing. This is a swirl behind a serif wordmark filling 11 per cent of its
   box, and to reach the median mass of 193 it had to grow to 65px of ink on
   the card, two and a half times its neighbours. The swirl took over and the
   SKILL CHALLENGE ENTERTAINMENT line went illegible. Set like the other
   symbol-plus-wordmark marks instead, discovery+ and Artists Equity among
   them, which is 27.7 x 17.1 of ink. */
.lockup.marks .lmark[src$="/scee.png"]{height:22.50px; margin:-2.70px -3.09px -2.70px -2.98px;
  clip-path:inset(12.00% 9.17% 12.00% 8.83%)}  /* ink 492x304 */  /* ink 305x304 */
/* Black Orange Live and XDubai, the two partners on Dubai Games - Richard,
   20 Oct. Both arrived white-and-colour on an opaque black ground, the
   scribble orange and the X yellow; both are keyed to pure white so they
   read as one ink beside each other, and both sit on transparency so
   nothing is painted outside the artwork.

   SET ON THE 17.1px SYMBOL BAND, like SCEE and Kings League above. Each is a
   symbol beside a stacked wordmark, so mass is the wrong ruler - the scribble
   would have taken the row the way the SCEE swirl did. Rendered against
   discovery+, Artists Equity, SCEE and Kings League at their own sizes, both
   land at the same weight. "LIVE" is small at this size, as "SKILL CHALLENGE
   ENTERTAINMENT" already is on SCEE. */
/* adidas, on Al Qadsiah - Richard, 20 Oct. He had ruled it out earlier the
   same evening as an event sponsor rather than a client, then sent the mark;
   the film opens on adidas and the club crest together, so it is in the
   lockup as a partner.

   Supplied white on black like Black Orange and XDubai, keyed the same way.
   Three bars over a wordmark at 1.47:1, so it sits on the 17.1px symbol band
   with SCEE, Kings League and the other symbol-plus-wordmark marks rather
   than being sized by mass. */
.lockup.marks .lmark[src$="/adidas.png"]{height:22.50px; margin:-2.70px -4.33px -2.70px -4.28px;
  clip-path:inset(12.00% 12.83% 12.00% 12.67%)}  /* ink 447x304, 1.47:1 */
.lockup.marks .lmark[src$="/black-orange.png"]{height:30.67px; margin:-6.75px -3.22px -6.82px -3.22px;
  clip-path:inset(22.00% 7.00% 22.25% 7.00%)}  /* ink 516x223, 2.31:1 */
.lockup.marks .lmark[src$="/xdubai.png"]{height:37.38px; margin:-10.09px -3.92px -10.19px -3.92px;
  clip-path:inset(27.00% 7.00% 27.25% 7.00%)}  /* ink 516x183, 2.82:1 */
.lockup.marks .lmark[src$="/youtube.png"]{height:57.40px; margin:-21.96px -12.92px -21.96px -12.92px;
  clip-path:inset(38.25% 15.00% 38.25% 15.00%)}  /* ink 420x94 */
.lockup.marks .lmark[src$="/pfl.png"]{height:26.25px; margin:-3.15px -9.65px -3.15px -9.58px;
  clip-path:inset(12.00% 24.50% 12.00% 24.33%)}  /* ink 307x304 */
/* Disney is the one mark sized by eye rather than by its ink box. Measured,
   its artwork draws at 15.40px against ITV's 14.82px - it is already the
   TALLER of the two. It reads smaller because Disney+ is a light script
   whose height is mostly the loop of the D and the raised +, so the body of
   the word is a fraction of that, where itv is a solid block filling its.
   18% on the drawn height, 22 -> 25.96, and the crop margins scale with it
   so the clip still lands on the ink - Richard, 16 Oct. */
.lockup.marks .lmark[src$="/disney.png"]{height:25.96px; margin:-2.71px -2.71px -5.07px -2.71px;
  clip-path:inset(10.25% 7% 19.75% 7%)}  /* ink 516x280, 1.84:1 */
.lockup.marks .lmark[src$="/ea.png"]{height:31.5px; margin:-7.2px -15px -7.2px -15px;
  clip-path:inset(22.75% 31.83% 22.75% 31.83%)}  /* ink 218x218, 1.0:1 */
.lockup.marks .lmark[src$="/ecb.png"]{height:22.5px; margin:-2.7px -13.4px -2.7px -13.4px;
  clip-path:inset(12% 39.67% 12% 39.67%)}  /* ink 124x304, 0.41:1 */
.lockup.marks .lmark[src$="/fifa.png"]{height:39.5px; margin:-13.6px -9.6px -12.8px -9.6px;
  clip-path:inset(34.5% 16.17% 32.5% 16.17%)}  /* ink 406x132, 3.08:1 */
.lockup.marks .lmark[src$="/formula-1.png"]{height:46.5px; margin:-17.1px -9px -16.4px -8.8px;
  clip-path:inset(36.75% 12.83% 35.25% 12.67%)}  /* ink 447x112, 3.99:1 */
.lockup.marks .lmark[src$="/formula-e.png"]{height:47.5px; margin:-17.9px -5px -16.5px -5px;
  clip-path:inset(37.75% 7% 34.75% 7%)}  /* ink 516x110, 4.69:1 */
.lockup.marks .lmark[src$="/hbo.png"]{height:43.5px; margin:-14.7px -15.4px -14.6px -15.3px;
  clip-path:inset(33.75% 23.67% 33.5% 23.5%)}  /* ink 317x131, 2.42:1 */
.lockup.marks .lmark[src$="/itv.png"]{height:32.16px; margin:-7.39px -9.79px -10.27px -9.79px;
  clip-path:inset(23% 20.33% 32% 20.33%)}  /* ink 356x180, 1.98:1 */
.lockup.marks .lmark[src$="/kennedy-marshall.png"]{height:21px; margin:-4.1px -2.2px -1.3px -2.2px;
  clip-path:inset(19.5% 7% 6.25% 7%)}  /* ink 516x297, 1.74:1 */
.lockup.marks .lmark[src$="/kings-league.png"]{height:32.45px; margin:-8.47px -7.48px -7.26px -7.48px;
  clip-path:inset(26.25% 15.33% 22.5% 15.33%)}  /* ink 416x205, 2.03:1 */
.lockup.marks .lmark[src$="/lions.png"]{height:22.5px; margin:-2.7px -10.5px -2.7px -10.5px;
  clip-path:inset(12% 31.17% 12% 31%)}  /* ink 227x304, 0.75:1 */
.lockup.marks .lmark[src$="/mclaren.png"]{height:53.07px; margin:-21.11px -5.61px -16.23px -5.61px;
  clip-path:inset(39.75% 7% 30.5% 7%)}  /* ink 516x119, 4.34:1 */
.lockup.marks .lmark[src$="/netflix.png"]{height:34.2px; margin:-11.7px -4.05px -10.8px -3.96px;
  clip-path:inset(34.25% 7.83% 31.5% 7.67%)}  /* ink 507x137, 3.7:1 */
.lockup.marks .lmark[src$="/nfl.png"]{height:26.5px; margin:-4.7px -8.9px -5.3px -8.9px;
  clip-path:inset(17.75% 22.5% 20% 22.33%)}  /* ink 331x249, 1.33:1 */
.lockup.marks .lmark[src$="/paramount.png"]{height:26.5px; margin:-5.5px -9.3px -4.5px -9.3px;
  clip-path:inset(20.75% 23.5% 17% 23.5%)}  /* ink 318x249, 1.28:1 */
.lockup.marks .lmark[src$="/prem-rugby.png"]{height:36.52px; margin:-12.85px -9.15px -12.23px -9.15px;
  clip-path:inset(35.25% 16.67% 33.5% 16.67%)}  /* ink 400x125, 3.2:1 */
.lockup.marks .lmark[src$="/red-bull.png"]{height:27.5px; margin:-4.5px -7.4px -7.3px -7.3px;
  clip-path:inset(16.25% 17.83% 26.5% 17.67%)}  /* ink 387x229, 1.69:1 */
.lockup.marks .lmark[src$="/religion-of-sports.png"]{height:36.5px; margin:-11.3px -10.1px -10.9px -10px;
  clip-path:inset(31% 18.5% 30% 18.33%)}  /* ink 379x156, 2.43:1 */
.lockup.marks .lmark[src$="/roland-garros.png"]{height:25.2px; margin:-3.02px -9.3px -3.02px -9.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}  /* ink 304x304, 1.0:1 */
.lockup.marks .lmark[src$="/uefa.png"]{height:22.5px; margin:-2.7px -8.3px -2.7px -8.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}  /* ink 304x304, 1.0:1 */
.lockup.marks .lmark[src$="/unanimous.png"]{height:22.5px; margin:-2.7px -8.3px -2.7px -8.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}  /* ink 304x304, 1.0:1 */
.lockup.marks .lmark[src$="/us-open.png"]{height:25px; margin:-4.4px -6.1px -4.8px -6.1px;
  clip-path:inset(17.5% 16.17% 19% 16.17%)}  /* ink 406x254, 1.6:1 */
.lockup.marks .lmark[src$="/warner-bros.png"]{height:23.5px; margin:-4.1px -10.9px -2.1px -10.8px;
  clip-path:inset(17.5% 30.83% 8.75% 30.67%)}  /* ink 231x295, 0.78:1 */
/* Four marks for the Branded page - Richard supplied the artwork 19 Oct.
   Ford and UBS arrived already white on black; NEOM arrived dark on a near
   white ground and was inverted; Expo 2030 arrived white on transparent with
   a rule across it and a "World Expo 2030 Candidate" endorsement below, and
   Richard asked for the rule and everything under it to come off, so the
   crop keeps only the Riyadh lockup above row 107. On 19 Oct the
   "KINGDOM OF SAUDI ARABIA" line came out too: at this size it set as an
   unreadable smudge. It is the middle of three lines, so it could not be
   cropped off - the two remaining lines are re-set with the designer's own
   6px inter-line gap and the block re-centred against the symbol. The ink
   box lands at the same 516x160, so the rule below is unchanged.

   All four are normalised the same way as the rest of the set: the ink is
   cropped out of the supplied file, scaled to fit 516x304 and centred on the
   600x400 canvas the row assumes. The height, margins and clip-path below
   are then computed from the measured ink rather than guessed, exactly as
   the entries above were.

   INK HEIGHT IS 15.8px FOR ALL FOUR, which is McLaren's. McLaren is the only
   existing mark on the Branded page, so it is the one they sit beside and
   the one to match. That is a starting point rather than the optical pass
   the sixteen on the partners row got: these are all wide lockups and the
   set runs 11.18 to 19.95, so they want eyeballing in the row.

   UBS IS CLIPPED IN THE SOURCE. Measured on the file supplied: 22 pure white
   pixels sit in the last column and 37 in the one before, so the right side
   of the S runs out of the frame. The left key only grazes the edge (3
   pixels, peak 155, so anti-aliasing rather than a cut). It is usable and
   the cut is slight, but a file with clear space around it would be better.
   Expo 2030 touches both side edges too, for the same reason. */
.lockup.marks .lmark[src$="/ford.png"]{height:35.51px; margin:-9.85px -3.73px -9.85px -3.73px;
  clip-path:inset(27.75% 7.00% 27.75% 7.00%)}  /* ink 516x178 */
.lockup.marks .lmark[src$="/neom.png"]{height:44.82px; margin:-14.46px -4.71px -14.57px -4.71px;
  clip-path:inset(32.25% 7.00% 32.50% 7.00%)}  /* ink 516x141 */
.lockup.marks .lmark[src$="/ubs.png"]{height:31.76px; margin:-7.94px -3.33px -8.02px -3.33px;
  clip-path:inset(25.00% 7.00% 25.25% 7.00%)}  /* ink 516x199 */
.lockup.marks .lmark[src$="/expo-2030.png"]{height:39.50px; margin:-11.85px -4.15px -11.85px -4.15px;
  clip-path:inset(30.00% 7.00% 30.00% 7.00%)}  /* ink 516x160 */
/* W34 is the Saudi 2034 World Cup launch film. The artwork is the host
   nation lockup: the Saudi 2034 mark and the SAFF crest inside a drawn
   rectangle with a vertical divider, over a rule and "HOST NATION / SAUDI
   ARABIA". At the size this row works to, that line sets at about 2px, so
   only what sits above the rule is kept. Richard also asked for the frame
   and the divider off, so the two crests are trimmed apart and re-set side
   by side with a gap of 12% of their height. No other mark on the site
   carries a box, which is the reason; it is a change to a client's official
   lockup, which is the cost.
   17.1px, not the 15.8 the four wordmarks above take: this is two detailed
   symbols rather than type, and 17.1 is where the other symbol marks sit -
   uefa, wimbledon, lions, channel4. */
.lockup.marks .lmark[src$="/w34.png"]{height:27.36px; margin:-5.13px -2.87px -5.13px -2.87px;
  clip-path:inset(18.75% 7.00% 18.75% 7.00%)}  /* ink 516x250 */
/* Al Qadsiah. Supplied white on transparent at 368x368, the crest alone.
   17.1px like the other symbol marks, which leaves it 7.7px wide - the
   narrowest on the site after ecb at 6.97. That is the crest's own shape
   rather than a sizing choice: it is 159x353 in the file, so matching the
   others on height is what makes it narrow. */
.lockup.marks .lmark[src$="/al-qadsiah.png"]{height:22.50px; margin:-2.70px -13.05px -2.70px -12.99px;
  clip-path:inset(12.00% 38.67% 12.00% 38.50%)}  /* ink 137x304 */
/* Channel 5 and Whitworths, supplied 19 Oct. Both arrived as the shape in
   the ALPHA channel rather than as colour - Channel 5 as black ink on
   transparent, Whitworths already white - so "inverting" the 5 meant taking
   the alpha as the mark and painting it white, not inverting RGB. An RGB
   invert of either would have produced a black rectangle.

   Channel 5 takes 17.1px, the symbol band, like the other numerals and
   crests. Whitworths takes 15.8px, the wordmark band, like Ford and UBS.

   NEITHER IS ON A CARD YET. Richard sent them for Entertainment but did not
   say which cards, so the files and these rules are here and nothing
   references them. */
.lockup.marks .lmark[src$="/channel5.png"]{height:22.50px; margin:-2.70px -11.03px -2.70px -10.97px;
  clip-path:inset(12.00% 32.67% 12.00% 32.50%)}  /* ink 209x304 */
.lockup.marks .lmark[src$="/whitworths.png"]{height:36.74px; margin:-10.47px -3.86px -10.47px -3.86px;
  clip-path:inset(28.50% 7.00% 28.50% 7.00%)}  /* ink 516x172 */
/* SURJ, supplied 19 Oct for Sport and the Kings League card. White on
   transparent, so the shape is the alpha, same as Channel 5 and Whitworths.
   THE "SPORTS INVESTMENT" LINE IS CROPPED OFF: the file is two bands, the
   wordmark at 98px and the strapline at 20px, and at the 15.8px this row
   works to that line would set at about 1.6px. Same call Richard made on
   easyGroup minutes earlier. Say the word and it goes back. */
.lockup.marks .lmark[src$="/surj.png"]{height:27.76px; margin:-7.84px -2.92px -7.91px -2.92px;
  clip-path:inset(28.25% 7.00% 28.50% 7.00%)}  /* ink 516x173 */
/* PAIRS ARE BALANCED BY OPTICAL MASS, not by ink height - the white a mark
   actually draws, measured as its drawn box times its own fill. Ink height
   misleads whenever two marks differ in kind: a lowercase wordmark spends most
   of its height on an ascender while a numeral or a solid fills its box, which
   is how Channel 9 came to carry nearly twice ITV's weight at the same 26px.
   Three pairs were out and are brought into line here, mass going as the
   square of the scale:
     Max       845 -> 323  (x0.618)  level with Red Bull on Born Racers
     SURJ      743 -> 429  (x0.760)  level with Kings League
     Sela     1022 -> 429  (x0.648)  level with SURJ on Fury
   SURJ sets the Fury target because it appears on both cards and the rule is
   keyed on the file, so it carries one size everywhere. The partners rows size
   their own tiles and are untouched by any of this.

/* Sela. The supplied file carries a faint band at luminance 64 across the top
   - a watermark, not the mark - so the ink is thresholded above it and lifted
   by luminance. A symbol plus a wordmark, so the 15.8px band: 86.1 wide by
   24.0 tall, which sits comfortably beside SURJ at 71.6 on the Fury card, so
   no width capping needed. */
/* Rebalanced 20 Oct. Sela was set against SURJ when the Fury card read
   SURJ x Sela; the card is Sela x Netflix now, so it is Netflix's 235 it has
   to sit level with rather than SURJ's 194. Netflix is left alone because it
   carries other cards; Sela appears on this one alone, so it is the one that
   moves. */
.lockup.marks .lmark[src$="/sela.png"]{height:31.42px; margin:-10.06px -3.30px -10.06px -3.30px;
  clip-path:inset(32.00% 7.00% 32.00% 7.00%)}  /* ink 516x144 */

/* Peloton. White on near-black, lifted by luminance the way Max was. A symbol
   plus a wordmark, so the 15.8px band. */
.lockup.marks .lmark[src$="/peloton.png"]{height:41.58px; margin:-12.89px -4.37px -12.89px -4.37px;
  clip-path:inset(31.00% 7.00% 31.00% 7.00%)}  /* ink 516x152 */

/* Bose. Set by WIDTH, like easyGroup and Max. The mark is 8.3:1, the widest
   aspect on the site, so at the 15.8px band it drew about 200px of ink - half
   again wider than easyGroup, the widest thing here. Capped at 125px to match
   it, which puts it at 15.0px tall, just under the set's current floor of 16.4
   (Prem Rugby). That is the honest cost of the aspect: let it run wider and it
   dwarfs its row, hold it taller and it runs off the card. */
.lockup.marks .lmark[src$="/bose.png"]{height:63.74px; margin:-26.93px -6.69px -26.93px -6.69px;
  clip-path:inset(42.25% 7.00% 42.25% 7.00%)}  /* ink 516x62 */

/* S4C. Supplied as a white block with the letters knocked out, which is the
   logo's actual form rather than a mistake, so the alpha is painted white and
   the counters stay transparent - on black the letters read as black on a
   white slab. A symbol, so the 17.1px band. It will sit heavier than its
   neighbours because it is solid where they are letterforms; say the word and
   it comes down the way easyGroup and Max did. */
.lockup.marks .lmark[src$="/s4c.png"]{height:22.50px; margin:-2.70px -6.81px -2.70px -6.81px;
  clip-path:inset(12.00% 20.17% 12.00% 20.17%)}  /* ink 358x304 */

/* Max. Supplied as the metallic treatment on near-black: the ink runs 111 to
   254 against a 23-27 ground. Everything above 100 is saturated so the
   shading flattens to solid white, and the 40-100 ramp is kept as the
   antialiased edge.
   Set by WIDTH, like easyGroup. At the 15.8px band it drew 24.2px tall and
   87.9px wide, which is not an outlier on its own - NEOM is the same width -
   but it sits in a PAIR beside Red Bull at 40.4px, and no existing pair has a
   mark past about 72px: Disney 50.9 next to Red Bull, Channel 9 54.1 next to
   ITV, SURJ 71.6 next to Kings League. Taken to 70px of ink, level with SURJ,
   which puts it at 19.3px tall. */
.lockup.marks .lmark[src$="/max.png"]{height:22.07px; margin:-7.12px -2.32px -7.17px -2.32px;
  clip-path:inset(32.25% 7.00% 32.50% 7.00%)}  /* ink 516x141 */

/* discovery+. Supplied as the mark on a black plate inside a white frame, so
   the black square is found first and the ink lifted from inside it. A
   wordmark with a lead symbol, so the 15.8px band rather than 17.1. */
.lockup.marks .lmark[src$="/discovery-plus.png"]{height:57.98px; margin:-21.02px -6.09px -21.16px -6.09px;
  clip-path:inset(36.25% 7.00% 36.50% 7.00%)}  /* ink 516x109 */

/* Dogwoof, on Monster Maker. Supplied white on black, so the ink lifts
   straight off the luminance. Set by OPTICAL MASS rather than by either ink
   band: the white it draws comes to 193, which is the median of the 52 marks
   in use. A 7.5:1 wordmark sized to a cap-height band would have carried far
   more weight than the marks beside it, the way easyGroup did. */
.lockup.marks .lmark[src$="/dogwoof.png"]{height:69.26px; margin:-28.57px -7.27px -28.74px -7.27px;
  clip-path:inset(41.25% 7.00% 41.50% 7.00%)}  /* ink 516x69 */

/* Sony. Supplied as white ink on transparent, so nothing to invert. A
   wordmark, so the 15.8px band. */
.lockup.marks .lmark[src$="/sony.png"]{height:68.70px; margin:-26.45px -7.21px -26.45px -7.21px;
  clip-path:inset(38.50% 7.00% 38.50% 7.00%)}  /* ink 516x92 */

/* easyGroup. Supplied as white on orange with "Part of the easy family of
   brands" set underneath. Richard asked for the strapline dropped, so the cut
   is at the 355px blank band the artwork puts between the two lines, and the
   ink is lifted off the orange by its own luminance so the curves stay smooth.
   Set by WIDTH, not by the 15.8px band. At that band it measured 24.0px tall
   and 154.9px wide on the card - dead on the median height of the 34 marks,
   and half again wider than the next widest, Artists Equity at 124.9. A long
   wordmark set to the same cap height as a compact one carries far more
   optical mass, which is why it read oversized. Taken to 125px of ink, level
   with Artists Equity, which puts it at 19.4px tall. */
.lockup.marks .lmark[src$="/easygroup.png"]{height:63.74px; margin:-25.50px -6.69px -25.50px -6.69px;
  clip-path:inset(40.00% 7.00% 40.00% 7.00%)}  /* ink 516x80 */

/* Network 10 and Channel 9, both supplied with the shape in the alpha channel
   and a coloured fill (#0047F4 and black). An RGB invert would have produced a
   flat rectangle, so the mark is the alpha painted white, as with Channel 5,
   Whitworths and SURJ.

   SET BY OPTICAL MASS, not by the ink band. Both sit beside ITV, and at the
   17.1px symbol band they measured 26.0px tall against ITV's 26.4 - level on
   paper and plainly bigger on the page, which is what Richard saw. Ink height
   is the wrong ruler for a pair like this: "itv" is lowercase, so most of its
   measured height is a dot above an x-height, while a numeral fills the box.
   Measuring the WHITE each mark actually draws: ITV 496px, Network 10 670,
   Channel 9 965 - so the 9 was carrying nearly twice ITV's weight.
   Mass goes as the square of the scale, so Network 10 takes x0.860 and
   Channel 9 x0.717, which lands both on ITV's 496. */
.lockup.marks .lmark[src$="/network-10.png"]{height:19.36px; margin:-2.32px -3.92px -2.32px -3.92px;
  clip-path:inset(12.00% 13.50% 12.00% 13.50%)}  /* ink 438x304 */
.lockup.marks .lmark[src$="/channel9.png"]{height:19.77px; margin:-3.76px -2.08px -3.76px -2.08px;
  clip-path:inset(19.00% 7.00% 19.00% 7.00%)}  /* ink 516x248 */
.lockup.marks .lmark[src$="/wimbledon.png"]{height:22.5px; margin:-2.7px -8.3px -2.7px -8.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}  /* ink 304x304, 1.0:1 */
/* Ryder Cup, supplied black on white, so the ink is the DARK pixels and the
   mark is the inverted luminance. A square shield the same 304x304 ink as
   Wimbledon, but a far finer drawing - stars, a trophy, lettering - so it
   fills only 32 per cent of its box against Wimbledon's solid. Sized by
   optical mass at 193, the median of the set, which is why it stands taller
   than Wimbledon despite the identical ink. */
/* Set on HEIGHT, not mass, 19 Oct. The row is top aligned, so what the eye
   reads across a rail is how far down each mark comes, and mass equalises
   area instead. At mass 193 this shield drew 37.4px against a modal 24 and
   hung well below its neighbours - Richard saw it on Branded. 24.0 x 24.0
   now, the same depth as Ford, McLaren, NEOM, UBS, Expo and Peloton. */
.lockup.marks .lmark[src$="/ryder-cup.png"]{height:20.78px; margin:-2.49px -7.69px -2.49px -7.69px;
  clip-path:inset(12.00% 24.67% 12.00% 24.67%)}  /* ink 304x304 */
.lockup.marks .lmark[src$="/world-rugby.png"]{height:22.5px; margin:-2.9px -11.9px -2.5px -11.8px;
  clip-path:inset(12.75% 35.17% 11.25% 35%)}  /* ink 179x304, 0.59:1 */

/* The home page lockup runs the same artwork against a 15px Whisper.
 * Same clip as the table above, and for the same reason: the canvas is
 * opaque, so without it the overflow paints over whatever sits beside it. */
.logolock .chip img[src$="/amazon-prime.png"]{height:35.5px; margin:-7.7px -8.6px -6.4px -8.5px;
  clip-path:inset(21.75% 16.17% 18% 16%)}
.logolock .chip img[src$="/artists-equity.png"]{height:67px; margin:-25.3px -7px -24px -7px;
  clip-path:inset(37.75% 7% 35.75% 7%)}
.logolock .chip img[src$="/bbc.png"]{height:62.5px; margin:-22.5px -15.9px -22.3px -15.8px;
  clip-path:inset(36% 17% 35.75% 16.83%)}
.logolock .chip img[src$="/canal-plus.png"]{height:75.5px; margin:-28.7px -7.9px -29.1px -7.9px;
  clip-path:inset(38% 7% 38.5% 7%)}
.logolock .chip img[src$="/channel4.png"]{height:30.5px; margin:-2.2px -14.3px -5.1px -14.3px;
  clip-path:inset(7.25% 31.33% 16.75% 31.17%)}
.logolock .chip img[src$="/disney.png"]{height:30px; margin:-3.1px -3.1px -5.9px -3.1px;
  clip-path:inset(10.25% 7% 19.75% 7%)}
.logolock .chip img[src$="/ea.png"]{height:43px; margin:-9.8px -20.5px -9.8px -20.5px;
  clip-path:inset(22.75% 31.83% 22.75% 31.83%)}
.logolock .chip img[src$="/ecb.png"]{height:30.5px; margin:-3.7px -18.1px -3.7px -18.1px;
  clip-path:inset(12% 39.67% 12% 39.67%)}
.logolock .chip img[src$="/fifa.png"]{height:54px; margin:-18.6px -13.1px -17.6px -13.1px;
  clip-path:inset(34.5% 16.17% 32.5% 16.17%)}
.logolock .chip img[src$="/formula-1.png"]{height:63.5px; margin:-23.3px -12.2px -22.4px -12.1px;
  clip-path:inset(36.75% 12.83% 35.25% 12.67%)}
.logolock .chip img[src$="/formula-e.png"]{height:65px; margin:-24.5px -6.8px -22.6px -6.8px;
  clip-path:inset(37.75% 7% 34.75% 7%)}
.logolock .chip img[src$="/hbo.png"]{height:59.5px; margin:-20.1px -21.1px -19.9px -21px;
  clip-path:inset(33.75% 23.67% 33.5% 23.5%)}
.logolock .chip img[src$="/itv.png"]{height:45.5px; margin:-10.5px -13.9px -14.6px -13.9px;
  clip-path:inset(23% 20.33% 32% 20.33%)}
.logolock .chip img[src$="/kennedy-marshall.png"]{height:28.5px; margin:-5.6px -3px -1.8px -3px;
  clip-path:inset(19.5% 7% 6.25% 7%)}
.logolock .chip img[src$="/kings-league.png"]{height:40px; margin:-10.5px -9.2px -9px -9.2px;
  clip-path:inset(26.25% 15.33% 22.5% 15.33%)}
.logolock .chip img[src$="/lions.png"]{height:30.5px; margin:-3.7px -14.3px -3.7px -14.2px;
  clip-path:inset(12% 31.17% 12% 31%)}
.logolock .chip img[src$="/mclaren.png"]{height:59.5px; margin:-23.7px -6.2px -18.1px -6.2px;
  clip-path:inset(39.75% 7% 30.5% 7%)}
.logolock .chip img[src$="/netflix.png"]{height:52px; margin:-17.8px -6.1px -16.4px -6px;
  clip-path:inset(34.25% 7.83% 31.5% 7.67%)}
.logolock .chip img[src$="/nfl.png"]{height:36px; margin:-6.4px -12.2px -7.2px -12.1px;
  clip-path:inset(17.75% 22.5% 20% 22.33%)}
.logolock .chip img[src$="/paramount.png"]{height:36px; margin:-7.5px -12.7px -6.1px -12.7px;
  clip-path:inset(20.75% 23.5% 17% 23.5%)}
.logolock .chip img[src$="/prem-rugby.png"]{height:56.5px; margin:-19.9px -14.1px -18.9px -14.1px;
  clip-path:inset(35.25% 16.67% 33.5% 16.67%)}
.logolock .chip img[src$="/red-bull.png"]{height:37.5px; margin:-6.1px -10px -9.9px -9.9px;
  clip-path:inset(16.25% 17.83% 26.5% 17.67%)}
.logolock .chip img[src$="/religion-of-sports.png"]{height:50px; margin:-15.5px -13.9px -15px -13.8px;
  clip-path:inset(31% 18.5% 30% 18.33%)}
.logolock .chip img[src$="/roland-garros.png"]{height:30.5px; margin:-3.7px -11.3px -3.7px -11.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}
.logolock .chip img[src$="/uefa.png"]{height:30.5px; margin:-3.7px -11.3px -3.7px -11.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}
.logolock .chip img[src$="/unanimous.png"]{height:30.5px; margin:-3.7px -11.3px -3.7px -11.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}
.logolock .chip img[src$="/us-open.png"]{height:34px; margin:-6px -8.2px -6.5px -8.2px;
  clip-path:inset(17.5% 16.17% 19% 16.17%)}
.logolock .chip img[src$="/warner-bros.png"]{height:32px; margin:-5.6px -14.8px -2.8px -14.7px;
  clip-path:inset(17.5% 30.83% 8.75% 30.67%)}
.logolock .chip img[src$="/wimbledon.png"]{height:30.5px; margin:-3.7px -11.3px -3.7px -11.3px;
  clip-path:inset(12% 24.67% 12% 24.67%)}
.logolock .chip img[src$="/world-rugby.png"]{height:30.5px; margin:-3.9px -16.1px -3.4px -16px;
  clip-path:inset(12.75% 35.17% 11.25% 35%)}
.lockup.marks .x{padding-inline:0}
/* .workcard .csopen .lockup{display:block} is (0,3,0) and beats .lockup.marks
   at (0,2,0), so the row was laying out as a block and the three marks stacked
   on three lines. Same specificity, so the marks rule wins where it applies. */
/* margin-top:auto pins the row to the foot of the card, and the card already
   stretches to the tallest in the rail, so every lockup lands on one line.
   min-height is what makes it exact rather than nearly: a square mark is
   17.15px tall and a wordmark 13.01px, so bottom-aligned boxes alone still
   left their tops 4px apart. An 18px slot holds the tallest of them, and
   align-content keeps the marks at the top of it - which is also where the
   first line of a lockup long enough to wrap sits. */
/* padding-top, not margin-top: margin-top is already auto here, pushing the
   lockup to the foot of the card, and a second margin would be swallowed by
   it. The padding sits inside that and always shows. 9px rather than a bigger
   number because each mark carries its own negative top margin to crop its
   canvas, so the gap you see is larger than the gap you set - Richard asked
   for more air between the title and the partners on every genre, 14 Oct. */
/* A quarter larger, 16 Oct. zoom for the same reason the panel's lockup uses
   it: every mark carries its own px height and its own px trim margins cut to
   that height, so raising .lmark alone would strand all of them. min-height
   goes up with it or the row it pins to the foot of the card no longer
   reserves the right depth. */
/* .shotplay, NOT .csopen. Every lockup in every genre page sits inside the
   .shotplay button, after the still - checked across all four pages, 16 Oct -
   so the .csopen version of this rule matched nothing and the marks had never
   actually grown. That is why they still looked base size after the 16 Oct
   quarter. 1.2 is the twenty per cent Richard asked for, measured from what is
   on screen now. */
/* height, not min-height, and 18 rather than 28. Every mark carries negative
   margins that crop its canvas down to the ink, so a mark declared 46px tall
   like the BBC one occupies 13px of layout. 28 was reserving a row nothing
   could fill - measured 16 Oct, the tallest ink in use anywhere is 17.3px
   (Warner Bros) and most sit near 15. Raising the zoom was therefore growing
   the GAP faster than the logos, which is what Richard could see.
   A fixed height rather than a floor because the reserve has to be identical
   on every card or the titles below them stop lining up; min-height was being
   satisfied by the short marks and left a 4px spread across the Sport rail. */
.workcard .shotplay .lockup.marks{display:flex; box-sizing:content-box;
  /* 11 + 6 above was 27.2px at the old zoom. Halved to 5.5 + 3. margin-top is
     overridden here rather than on .lockup.marks, which the panel shares. */
  margin-top:5.5px; padding-top:3px;
  /* The box stays 18px: the tallest mark in use inks 17.33px, so there is only
     0.67px of slack in it and shrinking it clips Roland-Garros. The gap under
     a shorter mark is that slack, and -2px takes about half of it off every
     card at once without moving the marks themselves. */
  /* CENTRED, not top aligned, 19 Oct. Marks do not all ink to the same
     depth - a flat wordmark like Bose draws 15px where a squarer mark draws
     24 - and hanging them from a common top line left the short ones riding
     high and the tall ones low. A shared centreline is what reads as level. */
  height:18px; margin-bottom:-2px; align-content:center; zoom:1.52}
/* Same division as the panel, for the same reason. */
.workcard .shotplay .lockup.marks .x{font-size:calc(13.01px / 1.52)}
/* A card with no mark reserves the row anyway, so its title sits on the same
   line as every other title in the rail. Monster Maker rode up because it has
   no partner artwork; so did Easy Bake Battle and five of the branded cards.

   19 Oct: this was 25.64px and it was wrong. The reserve above really costs
   (5.5 + 3 + 18 - 2) * 1.52 = 37.24px, and the note that set 25.64 subtracted
   the 18.76px the row had lost from 44.4 rather than from the row's own new
   height. Measured on Branded at 1440 before the fix: titles on the six cards
   with no mark sat at 1154.8 and Adele Visits McLaren, the only one carrying a
   mark, sat at 1166.4. 11.6px out, which is exactly 37.24 - 25.64.

   Written as the same arithmetic as the reserve rather than as a number, so
   the two cannot drift apart again. Anything that changes the height, the
   padding, the margins or the zoom above has to be changed here too. */
.workcard:not(:has(.shotplay .lockup.marks)) .csopen{
  margin-top:calc((5.5px + 3px + 18px - 2px) * 1.52)}
.lockup .x{background:var(--grad); -webkit-background-clip:text; background-clip:text;
  color:transparent; font-weight:400; text-transform:lowercase; padding-inline:2px}
/* The same connector inside a HEADLINE. Every headline on the site is
   text-transform:uppercase, which turned the lowercase x the brand guide asks
   for into the uppercase X it forbids - "MCLAREN X ADELE" on the home page
   and twice on Branded. text-transform:lowercase is the only thing that
   exempts one word from it, so the word has to be wrapped; build-work.py does
   that for any title carrying " x " and the three hand-written cards on
   Branded carry it in the markup.

   em, not px, for the padding: this rides headlines from 17px to 92px. */
/* LIGHT, not the headline's weight - Richard, 19 Oct. font-weight:inherit took
   the headline's 900 and the connector read as another letter of the name
   rather than the join between two of them. 400 is Pilat Regular, the lightest
   face the site carries. */
h1 .x, h2 .x, h3 .x, .h3 .x, .ftitle .x, .lede .x{
  text-transform:lowercase; font-weight:400; padding-inline:.06em;
  background:var(--grad); -webkit-background-clip:text; background-clip:text;
  color:transparent}
/* The featured lockup as marks rather than words (12 Oct).
   The partner logos are DARK artwork - red-bull.svg is fill:#000000 and the
   normalised Disney is a white tile with black artwork baked into it - and
   this band is black, so neither can sit on it bare. We hold no knockout
   versions. So each partner mark gets the same small white chip the partner
   strip uses, which is the one treatment on the site that already carries a
   dark logo on a dark page.
   Whisper needs no chip: Whisper_Logo_RGB_White.svg IS the knockout. */
/* A tenth larger, 16 Oct. zoom rather than touching the heights: every mark
   below carries its own px height AND its own px trim margins, cut to that
   height's canvas padding, so raising the heights alone would leave thirty
   sets of margins sized for the old ones. zoom takes the box, the trim and
   the gap together and the lockup stays assembled. */
.logolock{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:12px;
  zoom:1.1}
/* No box. These are the partners' reversed marks on transparency, so they sit
   straight on the black like the ones on the case study cards. The chip was
   white with colour logos until 13 Oct, then black with a white border, and
   both were a frame around something that does not need one. */
.logolock .chip{display:grid; place-items:center; background:none;
  border:0; height:30px; padding:0}
/* The tiles are 600x400 with the mark normalised INSIDE them - ink capped at
   86% of the width and 76% of the height - so the file carries its own
   margin. Capping the image at 17px the way the tight-cropped SVGs were
   capped left the mark itself around 13px and visibly smaller than it used
   to be. 26px of tile puts about 20px of ink on the chip, which matches what
   the colour logos looked like. */
.logolock .chip img{height:26px; width:auto; max-width:none; display:block}
/* No per-mark nudge here any more. The white set is normalised to equal ink
   area and placed on its own centroid, so Red Bull needs no special case. */
/* The logotype is 9.95:1, so height alone sets it. 15px against a 30px chip
   keeps the two marks optically level rather than matching their boxes. */
.logolock .wmark{height:15px; width:auto; display:block}
.logolock .x{font-size:13px; padding-inline:0}

/* enquiry form */
/* The eyebrow follows the theme everywhere else, so on this fixed light panel
   it has to be pinned back or it arrives as dark-mode grey on near-white. */
.enquire .eyebrow{color:var(--black)}
/* Grey 03 panel in BOTH themes - it is a deliberate light block, not a
   surface that follows the page. So everything in it stays black; without
   this the heading inherited --fg and went white on near-white. */
.enquire{background:var(--grey-03); color:var(--black); padding:clamp(26px,3.4vw,44px)}
.enquire .grid{display:grid; grid-template-columns:1fr 1fr; gap:clamp(24px,4vw,56px); align-items:start}
/* The 10px top margin is what lines the heading up with NAME across the panel,
   and it is not arbitrary. h2 is line-height .98, so the glyphs overflow their
   line box and the caps sit ~9px ABOVE the box top at 56px; the 11px label sits
   1px below its own. 10px down, 9px back up, and the two cap lines meet.
   MEASURED at 1600/1440/1280: 0px apart. It was the eyebrow above the heading
   that pushed it 32px low, not the margin. */
.enquire h2{margin-block:10px 20px}
.field{display:block; margin-bottom:16px}
/* The label sits INSIDE the box, Richard's call on 14 Oct. The field was a
   caption over an empty white well, twice the height of the words above it;
   now the words are in the box and the box is never blank.

   The <span> stays in the DOM, clipped rather than display:none, because a
   placeholder is not a label: remove the real one and a screen reader
   announces three unnamed boxes. Clipped, it is still the accessible name,
   and the placeholder is only what the eye reads.

   The placeholder carries the label's own type - 11px, 700, uppercase, the
   same tracking - so it IS the text that was above the box, moved. Colour is
   the one place it differs, and deliberately: grey rather than black, because
   a placeholder in solid black reads as a value somebody has already typed.
   See the note on .field input::placeholder below. */
.field span{position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap}
.field input::placeholder,.field textarea::placeholder{font-family:var(--body);
  font-weight:700; font-size:11px; letter-spacing:.13em; text-transform:uppercase}
/* color-scheme:light on the panel, because the panel IS light in both themes.
   A form control does not inherit colour from an ancestor the way text does -
   the browser gives it its own - and under a dark colour-scheme that default
   is white. The panel is grey-03 and the input is white, so in dark mode you
   typed white on white: the text was there, and invisible. The caret went with
   it, so there was not even a cursor to say the field had focus.

   color-scheme fixes the caret, the placeholder, the textarea's scrollbar and
   the autofill colours in one go; the explicit colour below does not depend on
   the browser honouring it. */
.enquire{color-scheme:light}
.field input,.field textarea{width:100%; border:1px solid var(--grey-02); background:var(--white);
  color:var(--black); caret-color:var(--black);
  padding:12px 13px; font:inherit; font-size:15px; border-radius:2px}
/* The two greys left on the site, and both are deliberate. A placeholder in
   solid black reads as a value somebody has already typed, which is the one
   thing a placeholder must not do; and the dashed "logo needed" tile is a note
   to us rather than content, so it should sit back from the real marks beside
   it. Everything that is content is now black or white. */
.field input::placeholder,.field textarea::placeholder{color:var(--grey-01); opacity:1}
/* Same reasoning: --muted is a pale grey in dark mode and this note sits on
   the near-white panel, where it came out at about 2.6:1. */
.enquire .formnote{color:var(--black)}
.field textarea{min-height:104px; resize:vertical}
.field input:focus,.field textarea:focus{outline:2px solid var(--pink); outline-offset:-1px; border-color:transparent}
.submit{width:100%; border:0; border-radius:999px; background:var(--grad); color:var(--white);
  padding:14px 20px; font-family:var(--body); font-weight:700; font-size:12px;
  letter-spacing:.12em; text-transform:uppercase; cursor:pointer}
.formnote{margin-top:12px; font-size:12px; color:var(--muted,var(--grey-01))}
.formnote[hidden]{display:none}
/* An error is the one place on this form that earns the brand red. Not the
   gradient: the gradient is an accent for identity, and a failed send is not a
   moment to be decorative. role="status" carries it to a screen reader either
   way, so the colour is reinforcement, never the message. */
.formnote.isbad{color:var(--red)}
/* Where the AWS WAF puzzle renders. Hidden until a 405 comes back, so this is
   empty and out of flow on every normal submission. The explicit display rule
   beats the UA's [hidden]{display:none}, so hidden must be the attribute AND
   the selector here - the same trap the featured-project band fell into. */
.captchabox{margin-top:14px}
.captchabox[hidden]{display:none}

.more{display:grid; grid-template-columns:repeat(3,1fr); gap:18px; list-style:none; margin:18px 0 0; padding:0}
/* Rounded to --r, the same 14px the home carousel panels carry. overflow on
   the anchor rather than the image, so the caption scrim at the foot is
   clipped by the same corner as the photograph under it. */
/* THE CLIPS ARE BACK, 16 Oct, and the note that used to sit here explains
   why they work now. On 15 Oct a clip over a .more still left a band of the
   photograph along the top edge. That note had already spotted the
   difference without naming it as the cause: on the home carousel the video
   is a child of the TRANSFORMED panel itself, here it was a child of a
   wrapper inside the transformed element. A transform makes a containing
   block, so the <a> was being laid out and rounded against a box the
   browser had already scaled, and the two edges did not land on the same
   subpixel.
   So the <a> now does the whole job - position, overflow, radius AND the
   transform - exactly as .wpanel does, and banner.js drops the video in
   beside the still as a direct child of it. The li carries nothing. */
.more a{position:relative; display:block; color:var(--white); text-decoration:none;
  border-radius:var(--r); overflow:hidden;
  transition:transform .24s cubic-bezier(.22,.61,.36,1); transform-origin:center center}
.more li:first-child a{transform-origin:left center}
.more li:last-child a{transform-origin:right center}
.more a:hover,.more a:focus-visible{transform:scale(1.07)}
.more img{width:100%; aspect-ratio:16/9; object-fit:cover; display:block}
.more a > video.clip{position:absolute; inset:0; z-index:0; width:100%; height:100%;
  object-fit:cover; opacity:0; transition:opacity .3s ease}
.more a > video.clip.on{opacity:.92}
/* span.on, not .on. banner.js puts .on on the VIDEO once it has painted, so
   a bare .more .on would have caught the clip and absolutely positioned it
   at the foot of the tile as though it were the scrim. */
.more span.on{position:absolute; z-index:2; inset:auto 0 0 0; padding:14px 16px;
  display:flex; align-items:center; gap:10px;
  background:linear-gradient(to top,rgba(0,0,0,.84),rgba(0,0,0,0))}
.more h3{font-size:17px; margin-right:auto; transition:opacity .18s ease}
/* The name clears and the pill arrives, the same exchange the home carousel
   makes: by then the clip is running and the pill names the genre anyway. */
.more a:hover h3,.more a:focus-visible h3{opacity:0}
.more span.pill{position:absolute; left:16px; bottom:14px;
  opacity:0; transform:translateY(4px); pointer-events:none;
  transition:opacity .18s ease, transform .18s ease}
.more a:hover span.pill,.more a:focus-visible span.pill{opacity:1; transform:none}
/* The same 10% lift as the home carousel and the work cards, so the gesture
   means one thing across the site. The li is what scales, not the anchor:
   overflow:hidden on the li would otherwise crop the grown image, and the
   caption scrim is positioned against the anchor. End cards grow inward -
   at centre origin the first pushes past the wrap's left gutter and the last
   past its right, and there is no overflow here to absorb it. */
.more li{min-width:0}
/* Same 7% as the home carousel, and the same reason: at 10% a 441.3px card
   grew 22px a side against an 18px gap. 1 + 2*18/441.3 = 1.0816 is the
   ceiling. */
.more li:hover,.more li:focus-within{position:relative; z-index:2}
@media (prefers-reduced-motion:reduce){
  .more a{transition:none}
  .more a:hover,.more a:focus-visible{transform:none}
}
.more span{font-family:var(--body); font-weight:700; font-size:11px; letter-spacing:.11em; text-transform:uppercase}

@media (max-width:980px){
  .services{grid-template-columns:1fr}
  .partners6{grid-template-columns:repeat(3,1fr); max-width:none}
  .enquire .grid{grid-template-columns:1fr}
  .more{grid-template-columns:1fr}
  .more a:hover,.more a:focus-visible{transform:none}
}
@media (max-width:620px){
  .svclist > li{grid-template-columns:1fr}
  /* .noline is two classes and beats the line above on its own, so the
     division lists kept a 150px column here with nothing in it - 20px of
     sideways scroll on Entertainment at 360. It collapses with the rest. */
  .svclist.noline > li{grid-template-columns:1fr}
  .svclist img{display:none}
}

/* ===========================================================================
   About page
   Geometry measured off Maddie's "About (click-through)" artboard at 1440,
   not eyeballed. Where a number looks arbitrary it is hers.
   =========================================================================== */

/* Hero. 1440x640 plate, content pinned 80px off the bottom. */
.abouthero{position:relative; background:var(--black); color:var(--white); display:grid; grid-template-columns:minmax(0,1fr)}
.abouthero > img{grid-area:1/1; width:100%; max-width:100%; aspect-ratio:2.25/1; min-height:360px;
  object-fit:cover; object-position:62% 42%}
.abouthero::after{content:""; grid-area:1/1; pointer-events:none;
  background:linear-gradient(90deg,rgba(0,0,0,.95) 0%,rgba(0,0,0,.8) 34%,rgba(0,0,0,.1) 72%),
             linear-gradient(0deg,rgba(0,0,0,.85) 0%,rgba(0,0,0,0) 46%)}
.abouthero .inner{grid-area:1/1; align-self:end; width:100%; max-width:var(--maxw);
  margin:0 auto; padding:0 var(--gutter) clamp(34px,5.5vw,80px);
  /* ::after is the last grid item, so without this the scrim paints over the
     type instead of under it. */
  position:relative; z-index:1}
/* AN ILLUSTRATION, NOT A PHOTOGRAPH - 20 Oct. Everything the treatment above
   does to a picture is wrong for this one, so this variant undoes all three:
   the grid becomes flow so the type sits under the image rather than on it,
   the 2.25/1 cover-crop becomes the drawing's own ratio, and ::after - the
   scrim - is removed outright, because it runs 95% black down exactly the
   side the two charts are drawn on.

   object-fit:contain rather than cover: a drawing has no spare edges to give
   away. The paper the artwork sits on is near-white, so the section keeps a
   black background only for the band under it. */
.abouthero.graphic{display:block}
/* 64% of the width, centred. Richard asked for 25% off on 20 Oct, which took
   it to 75%, then for another 15% off the same evening: 75 x 0.85 = 63.75,
   set as 64%. The drawing is a chart, not a photograph, and at full bleed the
   wheel and the year labels read larger than the H1 underneath them. */
.abouthero.graphic > img{width:64%; margin-inline:auto;
  aspect-ratio:auto; min-height:0; height:auto;
  object-fit:contain; object-position:center; display:block}
.abouthero.graphic::after{content:none}
.abouthero.graphic .inner{padding-top:clamp(28px,4vw,56px)}
.abouthero .eyebrow{color:var(--white); display:flex; align-items:center; gap:10px;
  font-size:11px; font-weight:800; letter-spacing:.24em}
.abouthero h1{max-width:760px; margin-block:18px 24px;
  /* The department heroes carry one word ("SPORT"). This one carries 48
     characters, so it is capped here rather than globally. */
  font-size:clamp(34px,5vw,72px); line-height:.95; letter-spacing:-.02em}
.abouthero .pill{height:54px; padding:0 30px 0 24px; font-size:14px; letter-spacing:.06em}

/* Section label: a Pilat word with a red-to-pink hairline under it, running
   the full width. A thick white segment used to sit on the left of that
   hairline for the first ~170px; it came off on 14 Oct, so the gradient is
   the only line. --rulew set its length and went with it.
   The type was 22px Bold at .04em until 19 Oct, when Richard asked for Our
   Values and the rest of these titles to be set like OUR PARTNERS: 18px,
   weight 400, .02em. The hairline and the colour behaviour are unchanged -
   colour stays `inherit` so the dark bands (.people) still override it. */
.eyebrow.rule{display:block; font-size:18px; font-weight:400; letter-spacing:.02em;
  line-height:1.45; color:inherit; padding-bottom:16px;
  margin-bottom:clamp(18px,2vw,26px);
  border-bottom:1px solid currentColor; border-image:var(--grad) 1; position:relative}

/* Locations. H2 first, then the label, then five columns under hairlines. */
#locations h2{margin-bottom:40px}
#locations .eyebrow.rule{margin-bottom:40px}
/* Five rows, shared across every card: name, sub-brand, address, email, clock.
   Each card is a subgrid of those rows, so a long address in Riyadh pushes
   Riyadh's email down and every other card's email with it, and all five lines
   of every kind start level. Reserving a fixed height per row would need a
   magic number that is wrong at the next breakpoint; this needs none.

   London and Los Angeles have no sub-brand and carry an empty .org, which
   costs nothing here and keeps the addresses level in the fallback below too.

   The explicit grid-row on each child is what makes the empty .org work: with
   auto-placement an empty row still consumes a slot, but naming the row says
   so rather than relying on source order to be right forever. */
.places{display:grid; grid-template-columns:repeat(5,1fr);
  column-gap:24px; row-gap:8px;
  grid-template-rows:auto auto 1fr auto auto;
  list-style:none; margin:0; padding:0}
.places li{border-top:1px solid var(--line,rgba(0,0,0,.18)); padding-top:18px;
  display:grid; grid-row:span 5; grid-template-rows:subgrid}
.places li > h3{grid-row:1}
.places li > .org{grid-row:2; min-height:1.1em}
.places li > .addr{grid-row:3}
/* Local time ABOVE Contact, asked for 15 Oct. The rows are explicit, so the
   markup was swapped to match rather than left reading in a different order
   from the page. */
.places li > .clock{grid-row:4}
.places li > .mail{grid-row:5}
/* Full foreground, not the muted address grey it sits under: this is the one
   thing on the card you can act on, and underlined muted text on black reads
   as a footnote. */
.places .mail a{color:var(--fg,var(--black)); text-decoration:none;
  border-bottom:1px solid currentColor; padding-bottom:1px}
.places .mail{color:var(--muted,rgba(0,0,0,.55))}
.places .mail a:hover,.places .mail a:focus-visible{background:var(--grad);
  background-origin:content-box; background-repeat:no-repeat;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  border-bottom-color:var(--pink)}
/* Subgrid is in every browser this site supports, but a card that silently
   stacks into one column is a worse failure than a card that is merely not
   aligned. The empty .org above is what keeps the addresses level here. */
@supports not (grid-template-rows:subgrid){
  .places li{display:flex; flex-direction:column; gap:8px}
}
.places h3{font-size:18px; margin:0; letter-spacing:0}
.places p{margin:0; font-size:13px; color:var(--muted,rgba(0,0,0,.76)); line-height:1.45}
/* The sub-brand sits above its address, not appended to it: Whisper Cymru and
   Whisper North are names, and they were reading as part of the postcode. */
.places .org{font-size:12px; font-weight:700; letter-spacing:.02em;
  color:var(--fg,var(--black))}
.places .clock{font-size:10px; letter-spacing:.15em; text-transform:uppercase;
  font-weight:700; color:var(--muted,rgba(0,0,0,.62))}
.places .clock b{color:var(--fg,var(--black)); font-weight:900; font-variant-numeric:tabular-nums}

/* People. Black section; the four portraits butt together with no gutter. */
.people{background:var(--black); color:var(--white); padding-block:80px}
.people .eyebrow.rule{color:var(--white);
  border-bottom-color:rgba(255,255,255,.22); margin-bottom:40px}
.people h2{margin:0 0 32px; font-size:clamp(28px,3.1vw,44px)}

.peoplebar{display:flex; flex-wrap:wrap; align-items:flex-end; gap:16px; margin-bottom:36px}
.pick{display:flex; flex-direction:column; gap:8px}
.pick span{font-family:var(--body); font-weight:700; font-size:10px;
  letter-spacing:.19em; text-transform:uppercase; color:var(--fg)}
/* The artboard draws its own chevron, so the native one is suppressed and a
   glyph is drawn in the right-hand padding. */
.pick .sel{position:relative; display:block}
.pick .sel::after{content:"\25BC"; position:absolute; right:20px; top:50%;
  transform:translateY(-50%); font-size:11px; pointer-events:none; color:var(--white)}
.pick select{appearance:none; -webkit-appearance:none; width:240px; height:46px;
  border:1px solid rgba(255,255,255,.4); border-radius:999px; background:var(--black);
  color:var(--white); padding:0 44px 0 20px; font-family:var(--body); font-weight:400;
  font-size:12px; letter-spacing:.08em}
/* No text-transform here: the options carry their own capitalisation now, and
   uppercasing them made "Central Teams" and "All Departments" shout. The small
   DEPARTMENT / LOCATION labels above them stay uppercase - they are labels. */
.chip{height:46px; padding:0 22px; border:1px solid rgba(255,255,255,.4);
  border-radius:999px; background:transparent; color:var(--white);
  font-family:var(--body); font-weight:400; font-size:12px; letter-spacing:.08em;
  text-transform:uppercase; cursor:pointer}
/* Inert in the review build. Kept near full strength so the section reads
   as designed; the review bar says they do not work yet. */
/* Leadership is a toggle, so it needs an on state. White face on the black
   People band, the same inversion the active nav pill uses. */
.chip[aria-pressed="true"]{background:var(--white); color:var(--black); border-color:var(--white)}
.pick select:disabled,.chip:disabled,.pager button:disabled{opacity:.9; cursor:not-allowed}

.pager{margin-left:auto; display:flex; align-items:center; gap:18px}
.pager .count{margin:0; font-family:var(--body); font-weight:700; font-size:11px;
  letter-spacing:.14em; text-transform:uppercase; color:var(--fg)}
.pager button{width:46px; height:46px; border-radius:999px; background:transparent;
  border:1px solid rgba(255,255,255,.4); color:var(--white); display:grid;
  place-items:center; cursor:pointer; font-size:15px; line-height:1}

/* Four across, one row, as the artboard has it. The cards sit at 45% of their
   cell: 45% read too small, so 30% bigger. The 41.5% they give back is the
   space between people. Photos are the originals with 10% off each
   side and nothing else, so each keeps its own shape - which is why the row
   top-aligns rather than pretending every face is the same rectangle. */
.peoplegrid{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:0;
  list-style:none; margin:0; padding:0; text-align:center; align-items:start}
.peoplegrid > li{width:58.5%; margin-inline:auto}
/* Leadership: five across on one row rather than 4 + 1 on a second page. */
.peoplegrid.lead{grid-template-columns:repeat(5,minmax(0,1fr))}
.peoplegrid.lead > li{width:70%}
.peoplegrid li{display:flex; flex-direction:column; gap:4px}
.peoplegrid li[hidden]{display:none}
.peoplebar button:disabled{opacity:.4; cursor:not-allowed}
/* No aspect-ratio and no object-fit: nothing is cropped at render, the photo is
   shown at whatever shape the trim left it. */
.peoplegrid img{width:100%; height:auto; background:#1a1a1a;
  border:1px solid rgba(255,255,255,.16)}
.peoplegrid b{display:block; font-family:var(--display); font-weight:900;
  text-transform:uppercase; font-size:15px; letter-spacing:.02em; padding-top:16px}
.peoplegrid span{display:block; font-size:13px; letter-spacing:.04em;
  text-transform:uppercase; color:var(--fg)}
.peoplegrid .tagline{font-weight:700; font-size:10px; letter-spacing:.16em;
  color:var(--fg); padding-top:4px}

/* Careers. */
#careers{padding-block:80px}
#careers .eyebrow.rule{margin-bottom:40px}
/* ── careers page ──────────────────────────────────────────────────────── */
/* The closing paragraphs of Our Culture, beside a shot of a crew at work. Same
   two-up as .careers below but top-aligned, because this column is three
   paragraphs rather than a heading and a line. */
/* With the text column gone the photograph is on its own, and a 1fr/1.15fr
   grid would leave it at 47% with a hole beside it. One child, one column -
   and a wider crop with it, because 4/3 was framed for a half-width column
   and at the full 1320 it stands 990px tall, which is a screen and a half of
   one picture. */
.culturecap:has(> :only-child){grid-template-columns:1fr}
.culturecap:has(> :only-child) img{aspect-ratio:21/9}
.culturecap{display:grid; grid-template-columns:1fr 1.15fr; gap:clamp(24px,4vw,56px);
  align-items:start; margin-top:clamp(30px,4vw,52px)}
.culturecap img{width:100%; aspect-ratio:4/3; object-fit:cover; border-radius:8px}
.culturecap p{margin:0 0 16px; font-size:15px; color:var(--muted,var(--grey-01)); max-width:58ch}
/* The one line that earns the display face on this page. .lede is uppercase
   Pilat Heavy and is sized for a full-width intro, so it is brought down here
   to sit in a text column without shouting over the paragraphs around it. */
.culturecap .lede{font-size:clamp(22px,2.3vw,34px); margin-block:4px 18px; color:var(--fg)}

/* Benefits. Four groups, each a hairline-ruled block, two up. The rules run red
   to pink the same way .svclist does: border-image with a slice of 1 stretches
   the ramp along the top edge and the other three widths are 0. Four more
   hairlines is still a long way inside the gradient's 10% share of a page. */
.benefits{display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(24px,3.4vw,48px); margin-top:clamp(26px,3.4vw,44px)}
.benefits > div{border-top:1px solid; border-image:var(--grad) 1; padding-top:18px}
.benefits h3{font-size:16px; letter-spacing:.02em; margin-bottom:14px}
.benefits ul{list-style:none; margin:0; padding:0; display:grid; gap:11px}
/* auto 1fr, not a list-style marker: the dodo is a masked span, and a grid row
   keeps the second and later lines of a long benefit aligned under the first
   rather than running back under the bullet. */
.benefits li{display:grid; grid-template-columns:auto 1fr; gap:10px; align-items:start;
  font-size:14px; line-height:1.5; color:var(--muted,var(--grey-01)); max-width:56ch}
.benefits li b{color:var(--fg); font-weight:700}
/* The marker was a dodo silhouette and is now a short rule (12 Oct), the same
   mark the About tabs use. Drawn with ::before rather than marked up, so there
   is one place to change it and no empty span in twenty-one list items. 7px
   wide against a 14px line, sitting on the x-height rather than the cap, which
   is where a dash reads level with the text beside it. */
.benefits li::before{content:""; width:7px; height:2px; margin-top:.62em;
  background:currentColor; opacity:.75}
.wellbeing{margin-top:clamp(30px,4vw,52px); max-width:72ch}
.wellbeing h3{font-size:16px; letter-spacing:.02em; margin-bottom:12px}
.wellbeing p{margin:0 0 14px; font-size:15px; color:var(--muted,var(--grey-01))}

/* Academy. .acnote is the one-paragraph bridge under the two-up; .acgrid is
   The Opportunity and The Work side by side. */
.acnote{margin:clamp(24px,3vw,40px) 0 0; font-size:15px;
  color:var(--muted,var(--grey-01)); max-width:72ch}
.acgrid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(24px,3.4vw,48px); margin-top:clamp(26px,3.4vw,44px)}
.acgrid > div{border-top:1px solid; border-image:var(--grad) 1; padding-top:18px}
.acgrid h3{font-size:16px; letter-spacing:.02em; margin-bottom:12px}
.acgrid p{margin:0 0 14px; font-size:14px; line-height:1.55;
  color:var(--muted,var(--grey-01)); max-width:54ch}
.apply{margin-top:clamp(28px,3.6vw,46px); max-width:72ch}
.apply h3{font-size:16px; letter-spacing:.02em; margin-bottom:12px}
.apply p{margin:0 0 14px; font-size:15px; color:var(--muted,var(--grey-01))}
.apply .partners{font-size:13px; padding-top:16px;
  border-top:1px solid var(--line,rgba(0,0,0,.18)); border-image:var(--grad) 1}

/* Whisper Women. Text left, the closing line right, so the page ends on the
   display face rather than trailing off in body copy. */
.women{display:grid; grid-template-columns:1.4fr 1fr; gap:clamp(24px,4vw,56px);
  align-items:center; margin-top:clamp(24px,3vw,40px)}
.women p{margin:0 0 15px; font-size:15px; color:var(--muted,var(--grey-01)); max-width:58ch}
.women .sub{color:var(--fg); margin-bottom:18px}
.women > .lede{font-size:clamp(24px,2.6vw,40px); margin:0; color:var(--fg)}

@media (max-width:900px){
  .culturecap,.benefits,.acgrid,.women{grid-template-columns:1fr}
}

/* --- open roles --------------------------------------------------------
   The list on /careers/, fed from content/jobs.json. A row is a link when
   Bamboo gives one and a plain block when it does not, so a posting with no
   URL still appears rather than being dropped or pointing at nothing. */
.roles{list-style:none; margin:18px 0 0; padding:0;
  border-top:1px solid var(--line)}
.roles li{border-bottom:1px solid var(--line)}
.roles li > a,.roles li > div{display:block; padding:18px 0; text-decoration:none;
  color:inherit}
/* Weight 400, not 900 - Richard, 19 Oct. The face and the size stay: these
   are a list of roles, not a stack of headlines, and at Heavy they were
   competing with OPEN ROLES above them. */
.roles h3{margin:0; font-family:var(--display); font-weight:400;
  text-transform:uppercase; font-size:clamp(16px,1.7vw,22px); letter-spacing:.02em;
  width:fit-content; max-width:100%}
.roles li > a:hover h3,.roles li > a:focus-visible h3{background:var(--grad);
  -webkit-background-clip:text; background-clip:text; color:transparent}
.roles .rolemeta{display:flex; flex-wrap:wrap; gap:0 18px; margin:6px 0 0;
  font-family:var(--body); font-size:12px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:var(--fg)}
/* A dot between the parts, never before the first one. */
.roles .rolemeta span + span::before{content:"·"; margin-right:18px}
.roles .norole{border-bottom:0}
.roles .norole .sub{max-width:52ch}
.roles .norole .ctas{margin:16px 0 0}

/* start, not center: How to apply and Partners moved into the right column on
   14 Oct, so that column is now much taller than the picture and centring left
   the picture floating halfway down the band. */
.careers{display:grid; grid-template-columns:1fr 1fr; gap:40px; align-items:start}
.careers img{width:100%; aspect-ratio:16/9; object-fit:cover; border-radius:8px}
/* h3, not h2: the section label above it is the h2 now, so this steps down a
   level. Same size it has always been. Direct child only - the svclist rows in
   the same column carry h3s too, and this rule would blow them up to 44px. */
.careers > div > h3{margin:0 0 18px; font-size:clamp(28px,3.1vw,44px)}
.careers .sub{margin:0; font-size:15px; color:var(--muted,rgba(0,0,0,.76)); max-width:52ch}
/* margin:0 above was written when this block held one paragraph. The Academy
   copy that moved back here on 14 Oct has three, and they ran together into
   one block with no gap. Spacing between siblings only, so a single paragraph
   still sits flush under its heading. */
.careers .sub + .sub{margin-top:11px}
/* Life at Whisper and Perks run the full width of the band. The 46ch on .sub
   is right where the paragraph sits beside something - the two-up .careers
   grid, a card - and wrong where it has the band to itself, which left a
   third of the page empty to its right. Richard, 14 Oct.

   Scoped to a .sub that is a DIRECT child of a full-width band, which today
   is exactly the five paragraphs in #culture and #benefits and nothing else
   on the site. Anything nested in a column keeps its measure. */
.band.wrap > .sub{max-width:none}
/* Life at Whisper is general comment rather than a standfirst, so it steps
   down a tier to body size. Richard, 14 Oct. Scoped to #culture: the Perks
   intro and the Academy paragraphs are still introducing what follows them
   and keep the 22px. */
#culture > .sub{font-size:17px; line-height:1.5}
/* Two lines of air between the last of that copy and Our Values: 52px at
   17px/1.5, which lands within a few pixels of the 56px between the posters
   and Perks below it, so the two joins read the same. */
#culture > .sub + .eyebrow.rule{margin-top:52px}
/* Perks starts closer. The posters end with a line of caption under each and
   the band's own 56px sat on top of #culture's, so the join read as a hole.
   A line and a half off the pair of them. */
#culture{padding-bottom:clamp(18px,2vw,28px)}
#benefits{padding-top:clamp(18px,2vw,28px)}
/* One line. The ink is 1030px against 1360 of band, so the only thing
   breaking it was .sub's 46ch measure - and .band.wrap > .sub{max-width:none}
   does not reach it, because this one is nested in the roles list rather
   than being a direct child of the band. */
#roles .norole .sub{max-width:none}
.careers .ctas{display:flex; flex-wrap:wrap; gap:14px; margin:18px 0 0}
/* .btn is gone (12 Oct). It existed for this one block and did two things
   badly on a black band: .solid was a BLACK pill, so it vanished into the
   background and read as plain text, and .line was a hairline outline that
   looked like a disabled control. Both are .pill now, which is the one button
   treatment the rest of the site uses. */

@media (max-width:1100px){
  .places{grid-template-columns:repeat(3,1fr)}
  /* Columns still butt together, as the artboard has them, but once the grid
     wraps the rows need a gutter or a two-line name runs into the portrait
     below it. */
  .peoplegrid > li{width:91%}
  .peoplegrid .tagline{padding-bottom:2px}
}
@media (max-width:760px){
  .abouthero > img{aspect-ratio:1.25/1; min-height:400px}
  /* .eyebrow.rule used to step 22 -> 18 here. It is 18 everywhere now. */
  .places{grid-template-columns:1fr}
  .peoplegrid,.peoplegrid.lead{grid-template-columns:repeat(2,minmax(0,1fr)); gap:26px 14px}
  .peoplegrid > li,.peoplegrid.lead > li{width:100%}
  .careers{grid-template-columns:1fr}
  .people{padding-block:52px}
  .pager{margin-left:0; width:100%}
  .pick,.pick select{width:100%}
}

/* --- accessibility ------------------------------------------------------- */
/* Off-screen until focused, so a keyboard user can jump the nav. */
.skip{position:absolute; left:-9999px; top:0; z-index:200; background:var(--black);
  color:var(--white); padding:12px 18px; font-family:var(--body); font-weight:700;
  font-size:12px; letter-spacing:.12em; text-transform:uppercase; text-decoration:none}
.skip:focus{left:8px; top:8px}
/* The work rail scrolls horizontally, so it has to be reachable by keyboard. */
.workrail:focus-visible{outline:2px solid var(--pink); outline-offset:3px}

/* --- film hero on a phone ------------------------------------------------ */
/* Overlaying a 16:9 loop with big type only works when the box is wide. At
   390 the hero crops to a narrow centre slice and the headline sits straight
   on top of the subject. Stack instead: film at its own shape, words beneath. */
@media (max-width:760px){
  .filmhero{display:block; min-height:0}
  .filmhero video,.filmhero img{height:auto; aspect-ratio:16/9; opacity:1}
  .filmhero .inner{padding-block:22px 28px}
  .filmhero.playing{min-height:0}
}

/* ── News ────────────────────────────────────────────────────────────────
   Built by build-news.py from news.json. Everything here is theme-token
   driven: the artboard is black, but the page has to survive the light
   switch like every other page, so nothing below is a literal colour. */
.newshero{padding-block:clamp(26px,3.6vw,52px) 0}
/* The hero's bottom padding and the band's top padding were stacking to about
   86px, which read as a hole rather than a gap. The hero now ends flush and
   the band alone sets the distance. */
.newshero + .band.social{padding-top:clamp(18px,2.2vw,30px)}
/* The break after FROM is in the markup, not left to the column width. At
 * 92px the headline needs about 1400px for one line and the column has about
 * 1040, so it happened to wrap in the right place - but "happened to" is a
 * layout that changes on a wider screen. build-news.py writes the <br>.
 *
 * max-width:14ch used to sit here and did nothing: ch is relative to the
 * element's OWN font size, so at 92px it computed to 1426px, wider than the
 * column can ever be, and because the size is a viewport clamp it shrank in
 * step and never bit at any width. Gone rather than left to mislead. */
/* The same clamp as .depthero h1 on the division pages, Richard's call on
   14 Oct: News was running at 92px against their 76px, so the one page
   without a division shouted louder than the four that have one. */
.newshero h1{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(34px,5.4vw,76px); line-height:.92; letter-spacing:-.015em;
  margin:6px 0 0; overflow-wrap:anywhere}

/* The featured story. 1.55fr/1fr puts the still on the left at roughly the
   artboard's proportion and leaves the panel a comfortable measure. */
.featnews{display:grid; grid-template-columns:1.55fr 1fr; background:var(--card);
  border:1px solid var(--line); border-radius:var(--r,10px); overflow:hidden}
.featnews > img{width:100%; height:100%; object-fit:cover; aspect-ratio:16/10;
  display:block}
.featnews .fbody{padding:clamp(22px,2.6vw,38px); display:flex; flex-direction:column;
  justify-content:center; gap:14px; min-width:0}
.featnews h2{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(22px,2.2vw,34px); line-height:1.02; margin:0; overflow-wrap:anywhere}
.featnews .standfirst{margin:0; color:var(--muted); font-size:15px; max-width:40ch}

/* The kind/date line. The kind was in the brand gradient until 20 Oct, when
   Richard asked for it to match the tag on the work cards instead - a white
   chip, not a pink one. Same values as .tag so the two are one component:
   white ground, black type, .12em, 4px 9px, 2px radius. A page of news cards
   was showing eight gradient pills at once, which is well past the 10% the
   guide allows for the accent. */
.newsmeta{display:flex; align-items:center; gap:12px; margin:0;
  font-size:10px; font-weight:700; letter-spacing:.15em; text-transform:uppercase}
.newsmeta .kind{background:var(--white); color:var(--black);
  letter-spacing:.12em; padding:4px 9px; border-radius:2px}
.newsmeta time{color:var(--muted)}
.readmore{font-size:12px; font-weight:700; letter-spacing:.12em;
  text-transform:uppercase; text-decoration:none; align-self:flex-start}
.readmore:hover{text-decoration:underline}

.newsgrid{display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,2vw,28px); list-style:none; margin:14px 0 0; padding:0}
.newsgrid a{text-decoration:none; color:inherit; display:grid; gap:12px}
.newsgrid img{width:100%; aspect-ratio:16/10; object-fit:cover; border-radius:var(--r,10px)}
.newsgrid h3{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:15px; line-height:1.15; margin:0; overflow-wrap:anywhere}
.newsgrid .summary{margin:0; color:var(--muted); font-size:13px}
.newsgrid a:hover h3{text-decoration:underline}
.loadwrap{display:flex; justify-content:center; margin:clamp(26px,3vw,40px) 0 0}
/* The ghost pill: outline only, so it reads as secondary against the gradient
   pills that carry the primary actions. */
.pill.ghost{background:none; color:var(--fg); border:1px solid var(--line)}
.pill.ghost:hover{border-color:var(--fg)}
/* These now fill on hover, which is what every other pill-shaped control on
   the site does - the nav tabs (14 Oct) and the burger both take the gradient
   when you roll over them. The pink border-and-type treatment from 15 Oct was
   this component's alone and read as something else. Border goes transparent
   rather than away, so the pill does not resize under the cursor. The marks
   are white already, so they sit on the gradient as they are. */
.pill.ghost{transition:background .18s ease, border-color .18s ease, color .18s ease}
.pill.ghost.plat:hover,.pill.ghost.plat:focus-visible{
  background:var(--grad); border-color:transparent; color:var(--white)}

.social h2{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(26px,3.4vw,46px); line-height:1; margin:0}
.social .sub{margin:8px 0 0; color:var(--muted); font-size:14px}
/* The On LinkedIn band has no heading, no strapline and no eyebrow rule: the
   Follow pill is the heading, exactly as it is on the Instagram band, and the
   wordmark in it IS the word. .ldhead, .ldline and .ldrule went with them on
   15 Oct - zero hits left in any built page, Welsh included. */
.igbar,.ldbar{display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-top:clamp(20px,2.4vw,32px)}
.igbar .live{color:var(--muted)}
/* The gap lives on the CONTAINER, not on the wall. The stills are .igwall and
   the live feed replaces them with .igmosaic, which carried no top margin at
   all - so the moment the real feed loaded, the 12px vanished and the first
   row of posts sat hard against the handle and the Follow pill. */
.igfeed{margin-top:clamp(18px,2.2vw,28px)}
.igwall{display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:8px;
  list-style:none; margin:0; padding:0}
.igwall img{width:100%; aspect-ratio:1; object-fit:cover; border-radius:4px}
/* The live tiles wrap their image in a link and may carry a badge. The
   fallback stills are a bare <img>, so both shapes have to sit in the
   same grid cell without the layout moving when the feed swaps in. */
.igwall li{position:relative}
.igwall a{display:block; line-height:0}
.igwall a:focus-visible{outline:2px solid var(--pink); outline-offset:3px}
/* ---- News page: On the record ---------------------------------------------
   A rail, not a grid: the artboard has a count and a pair of arrows, and a
   horizontal scroller is the honest implementation of that. Scroll-snap so a
   drag lands on a card edge, and the arrows move by exactly one card. */
.rechead{display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap}
.rechead > div:first-child{margin-right:auto}
/* BACK TO HEAVY, 15 Oct. It went to regular on Richard's note and then read
   as the wrong font - which it was, in the sense that mattered: the brand
   guide sets headlines in Pilat Extended Heavy, and these two were the only
   h2s on the site in Pilat Extended Regular. The face was loading correctly
   (measured: Extended Regular, not an Arial fallback); it was simply a
   weight the rest of the site never uses for a heading. */
.record h2{font-size:clamp(22px,3vw,40px); line-height:1.04; margin:4px 0 0}
/* --fg, not --grey-01. Grey is not a brand colour, and #575752 on the black
   this rail sits on in dark mode is 2.89:1 - under the 4.5:1 that small text
   needs and barely readable. */
.reccount{margin:0; font-family:var(--body); font-weight:700; font-size:11px;
  letter-spacing:.16em; text-transform:uppercase; color:var(--fg);
  font-variant-numeric:tabular-nums}
.recnav{display:flex; gap:8px}
/* The chevron takes the theme's foreground, not --black. On a transparent
   button over a black page a black glyph is nothing at all: both controls
   rendered as empty outlined circles in dark mode, which is why the rail
   looked as though it did not carousel when it always had. Hover fills with
   the foreground and knocks the glyph out in the background colour, so it
   works the same way round in both themes. */
.recnav button{width:38px; height:38px; border-radius:999px; cursor:pointer;
  border:1px solid var(--line,rgba(0,0,0,.18)); background:transparent;
  font:inherit; font-size:18px; line-height:1; color:var(--fg,var(--black))}
.recnav button:hover:not(:disabled){background:var(--fg,var(--black));
  color:var(--bg,var(--white)); border-color:var(--fg,var(--black))}
.recnav button:disabled{opacity:.3; cursor:default}
.recnav button:focus-visible{outline:2px solid var(--pink); outline-offset:3px}

/* scroll-snap-type:none, not x mandatory. Snapping cancels a drift exactly as
   it did on the work rails: a rAF loop writes a fraction of a pixel, snap
   pulls it back to the card edge, and scrollLeft never moves. Same reversal,
   same reason - see the note on .workrail. */
/* padding-block, so a card grown by a tenth has somewhere to grow into. A
   413px card gains 41px, 21 of it above the top edge, and an overflow-x rail
   clips anything that leaves the box. The margin loses the same amount so
   nothing below it moves. */
.recrail{display:flex; gap:18px; overflow-x:auto; scroll-snap-type:none;
  list-style:none; margin:-4px 0 -22px; padding:22px 0 26px;
  scrollbar-width:none; -ms-overflow-style:none}
.recrail::-webkit-scrollbar{display:none}
.recrail:focus-visible{outline:2px solid var(--pink); outline-offset:3px}
.reccard{flex:0 0 clamp(260px,30%,420px); min-width:0;
  transition:transform .18s ease}
/* A tenth bigger under the pointer, the same on both rails. transform-origin
   centre, so a card grows into the gaps either side rather than shoving the
   one after it. */
/* The end cards grow INWARD, the same fix .workcard has carried since 9 Oct.
   Scaling the first card from its centre pushes it past the rail's left edge,
   where overflow-x:auto clips it - on the work rail that read as 'EET THE
   OWENS'. The press rail had the grow without this, so it had the bug. */
.reccard{transform-origin:center center}
.reccard:first-child{transform-origin:left center}
.reccard:last-child{transform-origin:right center}
.reccard:hover,.reccard:focus-within{transform:scale(1.1); z-index:2;
  position:relative}
@media (prefers-reduced-motion:reduce){
  .reccard{transition:none}
  .reccard:hover,.reccard:focus-within{transform:none}
}
/* A button now, not a link - the release opens in the panel on this site.
   Stripped back to the card it was: no chrome, inherited type and colour,
   and the text left rather than centred the way a button would have it. */
.reccard .csopen{display:flex; flex-direction:column; width:100%; height:100%;
  color:inherit; text-decoration:none; text-align:left; cursor:pointer;
  background:none; border:0; padding:0; font:inherit}
.reccard .csopen:focus-visible{outline:2px solid var(--pink); outline-offset:3px;
  border-radius:8px}
.reccard img{width:100%; aspect-ratio:16/10; object-fit:cover; border-radius:8px;
  display:block}
/* .newsmeta carries margin:0 because everywhere else it sits in a grid that
   spaces it - .newsgrid gives its cards gap:12px. The release rail is a flex
   column with no gap, so here the pill landed about 6px under the artwork and
   read as stuck to it. Scoped to .reccard rather than fixed on .newsmeta, or
   the news grid gets the margin on top of its gap. 14px matches .cskind, the
   same pill in the opened panel, so the card and the write-up measure the
   same. 15 Oct. */
.reccard .newsmeta{margin-top:14px}
/* REGULAR, not heavy (15 Oct). These are press release headlines - somebody
   else's words, quoted - rather than Whisper's own headlines, and at Heavy
   seven of them stacked across a rail shouted over the page they sit on.
   h1,h2,h3 sets 900 globally, so this is an override rather than an absence.
   The section heading above them stays Heavy: that one IS Whisper's. */
/* 14px, down from 16 (15 Oct). These headlines are the whole of the card -
   the summary came off on 14 Oct - so at 16 they filled three lines of a
   420px card and sat heavier than the artwork above them. Leading opens
   slightly as the size drops: 1.18 of 16px is 19px, and the same ratio at
   14px reads tight rather than deliberate. The panel keeps its own size;
   this is the rail. */
.reccard h3{font-size:14px; line-height:1.24; margin:8px 0 0; font-weight:400;
  text-transform:none; letter-spacing:0}
/* And the same release opened in the panel, which shares #cstitle with the
   work cards. casestudy.js puts .release on the panel for a press card, so
   the two read the same whether you are looking at the rail or the write-up
   - rather than a headline in sentence case on the card becoming a shout one
   click later. */
.cspanel.release #cstitle{text-transform:none; font-weight:400; letter-spacing:0;
  line-height:1.12}
/* margin-top:auto is what puts every Read the release on one baseline. The
   rail stretches its cards to the tallest, so the gap a short headline leaves
   opens ABOVE this line rather than under it. The summary came off the card
   on 14 Oct; with it there, the headline and the standfirst both varied and
   nothing lined up. */
.reccard .readmore{display:inline-block; margin-top:auto; padding-top:14px;
  font-family:var(--body); font-weight:700; font-size:11px; letter-spacing:.16em;
  text-transform:uppercase}
.reccard .csopen:hover .readmore{background:var(--grad); -webkit-background-clip:text;
  background-clip:text; color:transparent}

/* ---- News page: hero, the live Instagram mosaic, leadership ---------------
   The mosaic only exists once the feed has loaded. Row height comes from the
   one-cell tiles' aspect-ratio, and the hero spans two of them plus the gap,
   so nothing here needs a fixed pixel height to line up. */
/* The standfirst sits DIRECTLY under the headline, not in a column beside it.
 * Beside it, the ragged right edge of a two-line headline left a hole between
 * the two that read as a fault, and the standfirst ended up marooned against
 * the right margin with nothing near it. */
.nhrow{display:grid; grid-template-columns:minmax(0,1fr)}
/* The caption under a headline is one thing across the site, so this is
   .wprompt from v3.css - the line under "MULTI-GENRE. ONE TEAM." on the home
   page - rather than a second idea of what a standfirst looks like. 11px,
   uppercase, tracked, and hard under the headline rather than 18px adrift.
   The copy stays sentence case in the HTML; the caps are the style's. */
.nhsub{margin:12px 0 0; font-family:var(--body); font-weight:700; font-size:11px;
  letter-spacing:.16em; text-transform:uppercase; line-height:1.5;
  color:var(--fg)}

/* The platform's own mark beside the word, so the two feeds on this page are
   told apart at a glance rather than by reading. Sized off the eyebrow's own
   type and set on the text baseline, so it tracks the label at every width. */
.pmark{display:inline-block; height:1.25em; width:auto; vertical-align:-.22em;
  margin-right:.5em}
/* A pill that goes to a platform carries that platform's mark, so it reads as
   "this opens Instagram" rather than as another ghost button. Sized off the
   pill's own type and laid out as a row, which keeps the mark, the label and
   the arrow on one baseline whatever the label is. */

/* A touch more room inside the platform pills than the plain ones carry,
   19 Oct. The base pill is padded for a word; these hold a word AND a
   wordmark that inks nearly the whole inner height, so 13/26 left the
   LinkedIn and Instagram marks tight to the ends. 16/32. The leaders pill
   sets its own padding and is unaffected. */
.pill.plat{display:inline-flex; align-items:center; gap:.5em; padding:16px 32px}
.pill.plat .pmark{height:1.45em; width:auto; max-width:none; flex:0 0 auto;
  object-fit:contain; margin-right:0; vertical-align:baseline}

.igmosaic{display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:8px}
/* The hero needs its OWN aspect-ratio, not just a row span. Without it the
   cell sizes to its content, and a 9:16 story two columns wide is about three
   and a half columns tall - so both rows stretched to fit it and every square
   tile beside it sat in a box half again as tall as itself, with the page
   showing through underneath. It spans two columns and two rows, and the
   tiles are square, so the hero is square too. */
.igmosaic .ighero{grid-column:span 2; grid-row:span 2; aspect-ratio:1}
.ighero,.igtile{position:relative; display:block; line-height:0;
  border-radius:4px; overflow:hidden; background:var(--black)}
.igtile{aspect-ratio:1}
.igtile img,.ighero img{width:100%; height:100%; object-fit:cover; display:block}
.ighero:focus-visible,.igtile:focus-visible{outline:2px solid var(--pink);
  outline-offset:3px}
.leaders{display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(12px,2vw,24px); list-style:none; margin:0; padding:0}
.leaders li{min-width:0}
/* Square, because the supplied portraits are 800x800 and a 3/4 crop took
   100px off each side - which clipped Fiona's hands. The artboard's boxes
   are portrait; the photographs win. */
/* 90%, not 100%. All four shrink by the same amount so their right edges
   still line up with each other, and the name and title underneath stay
   left-aligned to the photograph's edge. */
/* > li > img, not any img in here. The portrait rule was also catching the
   LinkedIn mark inside each card's pill: a 256x64 wordmark forced to a 19px
   SQUARE with object-fit:cover, so it rendered as a cropped blue fragment
   and looked like a broken icon rather than a logo. */
/* Same clip as the Join us posters, and for the same reason: Fiona's
   headshot carried a bright rim from its export - the bottom two rows read
   108 and 70 against an interior of 21, and the right two columns 185 and
   167 against 146. Three pixels came off every side of all three files, and
   the inset drops the rendered edge row on top of that, so a browser still
   holding the old JPEG does not show the line either. */
/* The picture is a link to the same account as the pill, so the 90% that used
   to sit on the image sits on the anchor and the image fills it. */
.leaders > li > .shotlink{display:block; width:90%; border-radius:8px}
.leaders > li > .shotlink > img{width:100%; aspect-ratio:1; object-fit:cover;
  border-radius:8px; background:var(--grey-03); display:block;
  clip-path:inset(1px round 8px)}
.leaders > li > .shotlink:focus-visible{outline:2px solid var(--pink); outline-offset:3px}
/* A quiet lift on hover, so it reads as something you can click without
   adding a second button under every portrait. */
.leaders > li > .shotlink > img,
.leaders .brandcard .shot{transition:opacity .16s ease}
.leaders > li > .shotlink:hover > img,
.leaders > li > .shotlink:hover .shot{opacity:.82}
/* The name and the LinkedIn link share a line now, the link hard right
   (16 Oct). The role drops underneath on its own, so the card reads
   name-and-where-to-find-them, then what they do. */
.leaders .ldrow{display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-top:14px; min-width:0}
.leaders .ldrow b{margin-top:0; min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}
.leaders b{display:block; margin-top:14px; font-family:var(--display);
  font-size:15px; letter-spacing:.01em}
.leaders .role{display:block; margin-top:2px; font-size:12px; color:var(--fg)}
/* 5% off the pill itself - type, padding and gap - while the mark holds its
   size: 1.45em of the FULL pill type is 1.526em of this one, so the logo is
   the same number of pixels inside a slightly smaller button. The -1px is
   the hair higher. */
.leaders .ldrow .pill{margin-top:0; flex:0 0 auto}
.leaders .pill.plat{font-size:12.35px; padding:12.35px 24.7px; gap:.475em}
.leaders .pill.plat .pmark{height:1.526em; transform:translateY(-1px)}
/* The company card is a mark on a black tile, not a photograph. Same
   cell and the same rhythm, so the row still reads as one set. The
   gradient is the accent here and nowhere else on the page. */
/* width:100%, not 90% - the 90% moved to the .shotlink anchor around it, and
   nesting the two gave the dodo tile 81% of the cell. */
.leaders .brandcard .shot{display:grid; place-items:center; width:100%;
  aspect-ratio:1; background:var(--black); border-radius:8px}
.leaders .brandcard .shot img{width:50%; height:auto; aspect-ratio:auto;
  border-radius:0; background:none}
/* The company card is gone: the feed above IS the company page, and its link
   survives as the Follow pill at the top of the band. The explicit rows went
   with it - they existed only to give that card a row of its own, and with
   nothing on row 1 they stranded the three portraits under an empty row.
   The grid stays at four columns so the three portraits line up with the
   feed's four cards above them rather than spreading to thirds. The
   .brandcard styling below is left alone so re-adding a company entry to
   news.json still renders, it just flows in line with the people now. */

@media (max-width:760px){
  .nhsub{margin:10px 0 0}
  /* Two up below 760, so the explicit rows above would push three cards into
     a two-column row. Hand them back to auto placement. */
  .leaders{grid-template-columns:1fr 1fr}
  .igmosaic{grid-template-columns:repeat(3,minmax(0,1fr))}
  .igmosaic .ighero{grid-column:span 3; grid-row:span 2}
}

/* The Instagram clip, over the thumbnail rather than instead of it. The
   still is what shows with no JavaScript, under prefers-reduced-motion, on a
   phone where there is no hover, and for every post Meta gave us no video
   for. The script adds .on at the first painted frame. .igtag is appended
   after the clip so the Video badge keeps painting above it. */
.ighero .igclip,.igtile .igclip{position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; opacity:0; transition:opacity .3s ease}
.ighero .igclip.on,.igtile .igclip.on{opacity:1}
.igtag{position:absolute; top:8px; right:8px; line-height:1;
  font-family:var(--body); font-weight:700; font-size:9px;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--black); background:var(--white); padding:4px 7px;
  border-radius:999px}

.pressband{display:flex; align-items:center; justify-content:space-between;
  gap:20px; flex-wrap:wrap; border-top:1px solid var(--line);
  border-bottom:1px solid var(--line); border-image:var(--grad) 1}
.pressband .pressline{margin:6px 0 0; font-size:16px}
/* The eyebrow and the line came out on 14 Oct, leaving the band with one
   child. space-between has nothing to push against with one item, so the
   pill sits left unless it is told otherwise. */
.pressband > :only-child{margin-left:0}

/* A tile holds a mark where we have one and the name in type where we do not,
   so the row is never an empty box and the two can sit side by side while the
   set is being filled.

   The marks are COLOUR, Richard's call on 14 Oct, not the white set the band
   was first built for. Colour artwork almost always arrives on white, and a
   white JPEG on this black band reads as a white rectangle with a border
   round it - so a tile that holds a mark goes white and owns that, rather
   than pretending. A mark that turns out to be reversed artwork on
   transparency wants its tile black instead; that is one line per mark, and
   which ones need it is a question for when the files are here. */
/* The awards row IS the partners band in all but name - a centred label over
   a centred strip of white marks on black tiles - so it is built the same way.
   Richard, 16 Oct, once the award marks were reversed to white. Flex rather
   than a six-column grid: the strip wraps on its own and the tiles stay the
   same size at every width, which is what makes the two bands read as a pair.
   The marks are trimmed to their own ink and come in every aspect from 3.2:1
   to square, so they are CONTAINED in the tile rather than stretched across
   it - .partners can use width:100% because that set is pre-padded to a
   common canvas and this one is not. */
.awards{display:flex; flex-wrap:wrap; justify-content:center; gap:8px;
  list-style:none; margin:14px 0 0; padding:0}
.awards li{flex:0 0 116px; width:116px; aspect-ratio:3/2;
  background:var(--black); border:1px solid var(--white);
  border-radius:10px; padding:6px; display:grid; place-items:center;
  overflow:hidden; text-align:center;
  font-family:var(--body); font-weight:700; font-size:9px; line-height:1.3;
  letter-spacing:.04em; text-transform:uppercase; overflow-wrap:anywhere}
.awards li img{max-width:84%; max-height:76%; width:auto; height:auto;
  min-width:0; min-height:0; object-fit:contain; display:block}

/* The Whisper Academy partners, under the line that names them on Join us.
   Same tile as the awards row - three up rather than six, and wider, because
   there are three of them and two are horizontal wordmarks. */
.acpartners{display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:12px; list-style:none; margin:18px 0 0; padding:0}
/* Black tile, white border - the partners and awards bands both. The marks
   went to white-on-black on 16 Oct and a white mark on a white tile is
   nothing at all, which is exactly what this row became for one deploy. */
.acpartners li{display:grid; place-items:center; aspect-ratio:2.1/1;
  grid-template-rows:minmax(0,1fr); overflow:hidden;
  background:var(--black); border:1px solid var(--white);
  border-radius:var(--r,10px); padding:12px}
.acpartners img{max-width:100%; max-height:100%; width:auto; height:auto;
  min-width:0; min-height:0; object-fit:contain; display:block}
@media (max-width:620px){ .acpartners{grid-template-columns:repeat(2,minmax(0,1fr))} }

@media (max-width:900px){
  .featnews{grid-template-columns:1fr}
  .newsgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:620px){
  .newsgrid{grid-template-columns:1fr}
  .igwall{grid-template-columns:repeat(3,minmax(0,1fr))}
  .pressband{display:grid; justify-items:start}
  /* On a phone it goes back to the left, where everything else on the page
     starts; margin-left:auto would strand it against the right edge. */
  .pressband > :only-child{margin-left:0}
}

/* ---- Case studies -------------------------------------------------------
   A card opens a panel over the page rather than navigating to its own URL.
   Richard asked for "about 60% of the screen, in the middle", so the panel is
   60vw on a desktop and near full width once that stops being sensible.

   The whole card is a <button>, which is why the title and blurb are spans
   carrying .h3 and .p rather than real h3 and p elements: a button's content
   model is phrasing content, so headings and paragraphs inside one are invalid
   and screen readers treat the result unpredictably. The styles below give the
   spans what the real elements had.

   The copy lives in the page inside .csfull, not in a script. It is crawlable,
   it is one copy rather than two to keep in step, and the panel clones it.
------------------------------------------------------------------------- */
/* THE LOCKUPS ALL LAND ON ONE LINE ACROSS A RAIL.
   They used not to: everything above the lockup is as tall as its own words,
   so a one-line summary put the marks 17px higher than a two-line one, and a
   title that wrapped put them 21px lower again. Measured on 14 Oct the tops
   ran 232, 249, 269 and 270px down the same rail.

   The cards already stretch to the tallest in the rail - .workrail is a flex
   row - so the fix is to make the button a column and let the lockup take the
   slack above it rather than reserving a fixed number of lines for the title
   and the summary, which would have opened a gap on every card whose words are
   short. .workcard is a column too so the button can fill the card. */
.workcard{display:flex; flex-direction:column}
/* --- click the frame to play (documentaries, 14 Oct) --------------------
   The frame is its own button now, so the image click and the title click do
   different things: the frame plays, the words open the case study.

   The film opens in the panel, not in the card. It played inline first, at
   the size hover takes the card to; Richard looked at it and asked for a
   player instead, which is also the better answer - a 16:9 film in a 294px
   card is not a thing anybody watches.

   There is no video yet. A card with no data-video opens the panel with the
   still in the player's place, labelled, so the shape is reviewable now. */
.workcard .shotplay{display:block; width:100%; margin:0; padding:0; border:0;
  background:none; color:inherit; font:inherit; text-align:left; cursor:pointer}
/* NO pink box on the cards. It was never asked for, and a 2px outline offset
   3px from a card inside a rail reads as an error state rather than focus -
   Richard, 14 Oct. The keyboard affordance moves inside the card instead: the
   frame answers with a white ring around the play circle, and the title
   answers with the gradient it already uses on hover, three rules down. */
.workcard .shotplay:focus-visible{outline:none}
.workcard[data-video] .shotplay:focus-visible .shot::before{
  box-shadow:0 0 0 3px rgba(255,255,255,.92), 0 2px 14px rgba(0,0,0,.45)}
.workcard .shot{position:relative}
/* The card no longer plays in place. Clicking the frame opens the panel with
   a player in it, which is what Richard settled on after seeing it inline -
   so there is no .playing state here any more, and the kind is shown in the
   panel rather than under the card. */
/* The play cue is the Happen Device, Richard's call on 14 Oct, in place of the
   circled triangle that was here first. It is the right shape for the job: it
   already points right, and it is the real artwork rather than a drawn
   triangle - masked from happen-device.svg, which is itself lifted verbatim
   from the master logotype, so the angles and the weight are correct at any
   size. (It is otherwise retired as a standalone mark, which is why it appears
   nowhere else on the site.)

   ONLY ON A CARD THAT HAS A TRAILER. The cue is a promise - press this and a
   film plays - so it is scoped to [data-video]. Spencer, Turbulence and
   Monster Maker have no trailer, so they carry no device; the frame still
   opens the case study, it just does not claim to play anything.

   IN A CIRCLE, Richard's call on 14 Oct: the circled triangle it replaced,
   with the device in place of the triangle. A RING, not a filled disc - a
   2px white outline with the device inside it, which is the shape of the
   original. The centre carries a light scrim rather than nothing: a hairline
   ring alone disappears over a busy frame, and the scrim is dark enough to
   hold the white without reading as a black button. The shadow does the same
   job on the outside. Both layers lift together on hover. */
/* z-index on BOTH, and it is load-bearing. ::before is the first child of
   .shot and the <img> is a later sibling in the same stacking context, so
   without it the disc paints UNDER the picture and nothing shows at all.
   ::after already painted last, which is why the bare device never needed
   this. */
.workcard[data-video] .shotplay .shot::before,
.workcard[data-video] .shotplay .shot::after{content:""; position:absolute;
  left:50%; top:50%; transform:translate(-50%,-50%); z-index:1;
  pointer-events:none; transition:opacity .16s ease}
/* the ring */
.workcard[data-video] .shotplay .shot::before{width:56px; height:56px;
  border-radius:50%; border:2px solid var(--white);
  background:rgba(0,0,0,.28);
  box-shadow:0 2px 14px rgba(0,0,0,.45)}
/* the device inside it, 161x179 in the artwork, so 28 wide is 31 tall. It sits
   a shade right of centre: the mark points right and its visual weight is to
   the left of its bounding box, so dead centre reads as off. */
.workcard[data-video] .shotplay .shot::after{width:22px; height:24px;
  margin-left:1px; z-index:2;
  filter:drop-shadow(0 1px 4px rgba(0,0,0,.5));
  background:var(--white);
  -webkit-mask:url(/assets/brand/happen-device.svg) no-repeat center/contain;
          mask:url(/assets/brand/happen-device.svg) no-repeat center/contain}
/* The play button is for the hover, not for the shelf. Key art is designed to
   be looked at whole, and a disc parked in the middle of every tile competes
   with the thing it is sitting on - Richard, 15 Oct, with the Owens and Brady
   artwork in front of him. So it arrives on hover and leaves again.

   Guarded by (hover: hover). A phone has no hover, and a play button that
   only appears on a gesture the device cannot make is a play button nobody
   can see: touch keeps it on permanently, which is also where it is most
   useful, because there is no other cue that the tile holds a film.

   Keyboard is covered too. :focus-visible on the button brings it up, so
   tabbing to a tile shows the same affordance the mouse gets, and the white
   ring three rules above still lands on something that is on screen. */
@media (hover: hover) and (pointer: fine) {
  .workcard[data-video] .shotplay .shot::before,
  .workcard[data-video] .shotplay .shot::after{opacity:0}
  .workcard[data-video] .shotplay:hover .shot::before,
  .workcard[data-video] .shotplay:hover .shot::after,
  .workcard[data-video] .shotplay:focus-visible .shot::before,
  .workcard[data-video] .shotplay:focus-visible .shot::after{opacity:1}
  /* The whole card is the hover target, not just the picture: the cursor is
     as likely to land on the title underneath, and having the disc flicker
     off when it does would read as a fault. */
  .workcard[data-video]:hover .shotplay .shot::before,
  .workcard[data-video]:hover .shotplay .shot::after{opacity:1}
}
/* No hover available: it stays visible, as it was. */
.workcard[data-video] .shotplay:hover .shot::before,
.workcard[data-video] .shotplay:hover .shot::after{opacity:1}

@media (prefers-reduced-motion: reduce) {
  /* The fade is motion. Reduced motion gets the state change without it. */
  .workcard[data-video] .shotplay .shot::before,
  .workcard[data-video] .shotplay .shot::after{transition:none}
}

.workcard .csopen{display:flex; flex-direction:column; flex:1;
  width:100%; margin:0; padding:0; border:0;
  background:none; color:inherit; font:inherit; text-align:left; cursor:pointer}
.workcard .csopen:focus-visible{outline:none}
/* The data-noring attribute this used to need is gone with it: casestudy.js
   no longer returns focus to the card after a MOUSE close at all, which is
   also what stops :focus-within holding the card at scale 1.1. */
.workcard .shot{display:block}
/* width:fit-content is the whole fix for the hover colour. background-clip:text
   paints the gradient across the ELEMENT box, and a display:block .h3 is the
   full card width - so a short title like SVEN sat in the leftmost fifth of
   the ramp, which is still #ff000e, and the hover read as plain red. The award
   badge below already had fit-content and already went red to pink, which is
   what gave the fault away. */
.workcard .h3{display:block; width:fit-content; max-width:100%;
  font-family:var(--display); font-weight:900;
  text-transform:uppercase; font-size:14px; margin-top:12px; letter-spacing:.02em}
.workcard .p{display:block; margin:5px 0 0; font-size:12px;
  color:var(--muted,var(--grey-01)); line-height:1.45}

.workcard .csopen .lockup{display:block}
/* The pointer should say the card does something. */
.workcard .csopen:hover .h3,
.workcard .csopen:focus-visible .h3{background:var(--grad);
  -webkit-background-clip:text; background-clip:text; color:transparent}

/* The card you are pointing at comes forward 10%. Two things make that safe
   in a horizontally scrolling rail:
     - the rail is overflow-x:auto, which makes overflow-y compute to auto as
       well, so a card growing past the flow box would be CLIPPED top and
       bottom. The padding-block below is the room it grows into.
     - a 330px card grows 33px, 16.5px each side, and the gap is 18px, so it
       expands into the gap rather than over its neighbour. z-index puts it on
       top anyway for the narrow sizes where that is not true. */
.workcard{transition:transform .22s ease; transform-origin:center center}
/* Every card scales from its centre, the end cards included. They used to grow
   inward instead, because scaling from the centre pushed the first card past
   the rail's left edge where overflow-x:auto clipped it - the title read 'EET
   THE OWENS'. The rail's padding-inline is the room that fixes that properly,
   so the inward growth is no longer needed and the overlap it caused is gone. */
.workcard:hover, .workcard:focus-within{transform:scale(1.1); position:relative; z-index:2}
@media (prefers-reduced-motion:reduce){
  .workcard{transition:none}
  .workcard:hover, .workcard:focus-within{transform:none}
}

/* .88 and a blur, not .72. At .72 the hero, the partner tiles and the section
   headings all read straight through, so the panel looked like a card lying on
   a live page rather than the only thing you were meant to be reading. The
   blur is the part that actually does it: dimming alone keeps every edge, and
   it is edges the eye follows. */
.csmask{position:fixed; inset:0; z-index:200; background:rgba(0,0,0,.88);
  -webkit-backdrop-filter:blur(7px); backdrop-filter:blur(7px);
  display:grid; place-items:center; padding:clamp(16px,4vw,40px)}
.csmask[hidden]{display:none}
/* The panel still scrolls, it just does not draw the bar. A scrollbar inside
   a modal over a page that also has one puts two of them on screen an inch
   apart. Both spellings: Firefox reads scrollbar-width, Chrome and Safari the
   pseudo-element, and neither falls back to the other. */
.cspanel{width:60vw; max-width:1100px; max-height:84vh; overflow:auto;
  scrollbar-width:none;
  background:var(--bg,var(--black)); color:var(--fg,var(--white));
  position:relative; -webkit-overflow-scrolling:touch}
.cspanel::-webkit-scrollbar{width:0; height:0}
/* 60% of the screen stops being a sensible measure well before a phone: at
   900px it is a 540px column of 15px type, and at 420px it is unreadable. */
@media (max-width:1100px){ .cspanel{width:86vw; max-width:none} }
@media (max-width:620px){ .cspanel{width:100%; max-height:92vh} }
/* The write-up is the point of the panel, so the picture is a lead-in and not
   the whole first screen. Uncapped, an 864px-wide hero filled 540px of an
   84vh panel and pushed every word below the fold. */
/* The whole picture, never a crop. It used to be object-fit:cover with a
   46vh cap, which was fine while every hero was a photograph: a few pixels
   off the top and bottom of a still cost nothing. It stopped being true when
   designed artwork arrived - the press release posters, the Fury bill, the
   Sony quote card, and now the Roland-Garros and McLaren tiles, which carry
   their co-brand lockup inside the image. A crop takes out the thing the
   picture exists to show. Richard, 15 Oct: same rule as the releases, for
   all of them.

   contain on a black ground, and a taller cap than the old one so a 16:9
   still is not shrunk to nothing to pay for it. The reason the cap exists at
   all is unchanged: the write-up is the point of the panel, and an uncapped
   864px hero filled 540px of an 84vh panel and pushed every word below the
   fold. */
.cspanel img.cshero{display:block; width:100%; height:auto;
  max-height:min(56vh,560px); object-fit:contain; background:var(--black)}
/* 16px inline, not the 40 it was. That is where Chrome insets the player's
   own progress bar from the video edge, measured on staging 16 Oct, and
   Richard wants the kind pill to start on the same line as the bar. The
   lockup and the stats come with it so the column stays one left edge.
   padding-top is 18 rather than 40: the whole block sits closer to the film
   now, which is the point. A press release restores the wider gutter below,
   because that panel carries prose and 16px off the edge is too tight to
   read against. */
.csbody{padding:18px 16px clamp(22px,2.6vw,40px)}
.cspanel.release .csbody{padding:clamp(22px,2.6vw,40px)}
/* THE PLAYER IN THE PANEL. It sits where the hero still sits and takes the
   same width, so opening a film and opening a write-up are the same shape.
   16:9 because that is what the films are; the hero still is 16:10 because a
   picture wanted the extra room, and the two do not have to agree. */
/* [hidden] is display:none from the UA sheet, and ANY explicit display rule
   beats it - .cshero sets display:block, so hiding it by attribute did
   nothing and the still painted under the player. Both carry the attribute,
   so both need this. */
.cspanel img.cshero[hidden],.cspanel .csplayer[hidden]{display:none}
.csplayer{position:relative; background:var(--black)}
.csplayer video,.csplayer > img{display:block; width:100%; aspect-ratio:16/9;
  object-fit:cover; background:var(--black)}
/* Only while there is no film to play. It is a placeholder and should read as
   one rather than passing for a still that failed to start. */
.csnote{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  margin:0; font-family:var(--body); font-weight:700; font-size:12px;
  letter-spacing:.11em; text-transform:uppercase; color:var(--white);
  background:rgba(0,0,0,.62); padding:10px 18px; border-radius:999px}
/* The kind, under the picture - where it went when it came out of the frame.
   Double the size it was, and on the same inset as .csbody so it lines up
   with the lockup and the title under it - Richard, 15 Oct. */
/* A white pill, 16 Oct. Same 14px it already was - Richard asked for the
   pill, not a resize. inline-block so the pill is the width of the word
   rather than the width of the panel, which means the gutter that used to be
   padding-inline has to become a left margin: padding now draws the pill. */
/* 30% smaller, 16 Oct: 14px to 10px with the padding taken down in step,
   7/15 to 5/11. Both, or the pill keeps its old bulk around smaller type.
   Not zoom here - the left margin is the panel gutter and zoom would drag
   the pill in off it. Letter-spacing is in em so it follows on its own. */
/* 8px under the film and 16px in, so it starts where the play bar starts. */
/* The kind row. A card can carry more than one kind ("Host broadcaster,
   Digital content") and each is its OWN pill, not one pill with a comma in
   it - Richard, 16 Oct. So .cskind is the row and the span is the pill; the
   16px left margin that lines the row up with the start of the play bar
   stays on the row. */
.cskind{margin:4px 0 0 16px; display:flex; flex-wrap:wrap; gap:6px}
.cskind[hidden]{display:none}
.cskind span{padding:5px 11px; border-radius:999px;
  font-family:var(--body); font-weight:700; font-size:10px; letter-spacing:.11em;
  text-transform:uppercase; background:var(--white); color:var(--black)}
.csbody .lockup{margin:0 0 6px}
/* Twice the size in the panel, 16 Oct. zoom rather than a height override:
   every mark in .lockup.marks carries its own px height AND its own px
   negative margins, trimmed to that height's canvas padding. Doubling the
   height alone would leave those margins sized for the old one and pull each
   logo off its line. zoom scales the box, the clip and the margins together,
   so each mark stays trimmed exactly as it was, just bigger. */
.csbody .lockup.marks{zoom:3.25}
/* The x is divided back out of the zoom. The rule that sets it says the
   separator is NOT a name and does not grow with them - zoom does not know
   that and was scaling it to 42px, where the gradient has only one glyph's
   width of ramp to run through and reads as a solid block rather than red to
   pink. calc(13.01/zoom) lands it back at the 13.01px it has always been. */
.csbody .lockup.marks .x{font-size:calc(13.01px / 3.25)}
.csbody h3{font-size:clamp(26px,3.2vw,44px); line-height:1.02; margin:0 0 18px}
.csbody h4{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:14px; letter-spacing:.03em; margin:26px 0 8px}
/* No measure cap. 62ch left a third of the panel empty on the right and
   pushed the write-up down far enough to need scrolling, which is the one
   thing this panel should not do - Richard, 14 Oct. The panel's own width is
   the measure: 60vw capped at 1100, and under 1100 it is 86vw. */
.csbody p{margin:0 0 14px; font-size:15px; line-height:1.62}
/* A press release leads with its own summary bullets. The marker is the short
   rule the Perks list and the About tabs use, not a disc. */
.cscopy .csbullets{list-style:none; margin:0 0 20px; padding:0; display:grid; gap:9px}
.cscopy .csbullets li{display:grid; grid-template-columns:auto 1fr; gap:10px;
  align-items:start; font-size:15px; line-height:1.5; font-weight:700}
.cscopy .csbullets li::before{content:""; width:7px; height:2px; margin-top:.66em;
  background:currentColor; opacity:.75}
/* The numbers on a case study, in the panel rather than on the card. They
   went on the card first and were wrong there: five lines of figures under a
   title is a paragraph, not a headline, and the rail is a shelf you scan.
   Opened up there is room to set them as figures.

   auto-fit rather than five fixed columns, so they go five across on a
   desktop panel and fold to two or one as it narrows, without a breakpoint
   per count - the next case study to carry stats may not carry five. */
.cscopy .csstats{list-style:none; margin:6px 0 22px; padding:0;
  display:grid; gap:18px 14px;
  grid-template-columns:repeat(auto-fit,minmax(132px,1fr))}
.cscopy .csstats li{display:grid; gap:3px; align-content:start}
.cscopy .csstats b{font-family:var(--display); font-weight:900;
  font-size:clamp(22px,2.2vw,30px); line-height:1; letter-spacing:-.01em;
  color:var(--fg,var(--black))}
.cscopy .csstats span{font-size:12px; line-height:1.35; letter-spacing:.01em;
  color:var(--muted,var(--grey-01))}
.csbody p.lede-sm{font-size:17px; line-height:1.55}
.csbody p:last-child{margin-bottom:0}
.csclose{position:absolute; top:12px; right:12px; z-index:2;
  width:40px; height:40px; border:0; cursor:pointer; border-radius:50%;
  background:var(--black); color:var(--white); font-size:20px; line-height:1;
  display:grid; place-items:center}
.csclose:focus-visible{outline:2px solid var(--pink); outline-offset:2px}
/* An image still to come should look unfinished on staging, not pass for art. */
.workcard img[data-placeholder]{background:repeating-linear-gradient(45deg,
  #2a2a28 0 12px,#1b1b1a 12px 24px); min-height:120px}
/* Same treatment on a services still. Sport has seven areas and six
   photographs; the seventh borrows one and wears the stripes until it has
   its own, so it cannot ship looking finished. */
.svclist img[data-placeholder]{background:repeating-linear-gradient(45deg,
  #2a2a28 0 12px,#1b1b1a 12px 24px)}

/* ---- Partners: one row at a time ----------------------------------------
   Every page uses the SAME tile, 116x78, which is what Sport's eleven-across
   measured at 1440. Fixed width rather than 1fr columns, because a shared
   grid would hand a six-logo page much bigger tiles than an eleven-logo one
   and the two would not look like the same strip.

   The list pages rather than stacking. Pages are balanced, not filled: 21
   logos become 11 and 10, and 12 become 6 and 6, so you never get a full row
   followed by a row of one. Each holds 20 seconds and cross-fades.

   Under prefers-reduced-motion the script does not run at all, and flex-wrap
   leaves every logo on screen in the same tiles. Nothing is hidden from
   anybody who has asked the animation to stop.
------------------------------------------------------------------------- */
/* The heading sits centred over the marks - Richard, 16 Oct. The container
   differs between the two shapes, so both are named: on the home page the
   list is a sibling of .shead inside a .wrap, on the genre pages it follows
   the eyebrow inside the band itself. .partners already centres its own row;
   this is about what sits above it. .shead and an eyebrow carrying the dodo
   mark are both flex, so they need justify-content rather than text-align. */
.band:has(> .partners),
.wrap:has(> .partners),
.band:has(> .awards),
.wrap:has(> .awards){text-align:center}
.wrap:has(> .partners) .shead,
.band:has(> .partners) > .eyebrow,
.band:has(> .awards) > .eyebrow{justify-content:center}
/* "Our partners" is set from "Featured work" - .feyebrow in v3.css - because
   they are the same thing, a label on a section, and Richard wants the pair to
   read at one size everywhere the partners band appears. Two selectors because
   the home page carries the label in a .shead h2 and the genre pages carry it
   in a plain .eyebrow; both are scoped to the band so no other eyebrow on the
   site moves. (0,3,1) and (0,3,0) clear `.shead h2` and `.eyebrow` on count,
   so stylesheet order does not come into it. */
/* Measured on staging, 16 Oct: 101.8px between the foot of the featured still
   and the top of OUR PARTNERS - 44px off the work section, 54px off this one,
   and the heading's own line box. Richard asked for it to come up and take the
   void with it, so this section's top padding drops to 14 and the gap lands at
   about 62. Everything below follows on its own, it is all in flow. Scoped to
   the home page's shape (section > .wrap > .partners) so the genre bands,
   which are .band and were not part of the note, do not move. */
section:has(> .wrap > .partners){padding-block-start:14px}
.wrap:has(> .partners) .shead h2,
.band:has(> .partners) > .eyebrow,
.wrap:has(> .partners) > .eyebrow,
.band:has(> .awards) > .eyebrow,
.wrap:has(> .awards) > .eyebrow,
.newshero > .eyebrow,
.record .rechead .eyebrow{
  /* 18px, down a couple of points from the 20 it was set at - Richard,
     16 Oct. Awards Podium comes with it: it was matched to this band on
     purpose and the two sit a screen apart on About. Featured work stays at
     20, so these no longer match it to the point. */
  font-family:var(--body); font-weight:400; font-size:18px;
  letter-spacing:.02em; text-transform:uppercase; color:var(--fg)}
/* News and Press releases join the list rather than getting their own copy
   of the values - Richard, 19 Oct, so the four stay in step. It has to be
   done here: both of those headings sit inside the block build-news.py
   generates, so a class on the markup would not survive the next build. */
/* The genre pages put the partners band directly under the case study rail,
   and both are .band, so the two were paying 56px of padding each into the
   same gap - 156px from the foot of the last card to the OUR PARTNERS label,
   measured on Sport 16 Oct. 26 of that is the rail's own padding, 18 the
   label's margin, and the remaining 112 was the two sections agreeing to
   leave room for each other. 56px now. The home page is handled separately
   above, because there the band is a plain section wrapping a .wrap. */
.band:has(+ .band > .partners){padding-block-end:10px}
.band:has(> .partners){padding-block-start:20px}
.band:has(> .partners) > .eyebrow{margin-top:0}
.partners{display:flex; flex-wrap:wrap; justify-content:center; gap:8px;
  list-style:none; margin:14px 0 0; padding:0; transition:opacity .9s ease}
.partners.pfade{opacity:0}
/* Black, because the marks are now the partners' REVERSED (white) logos.
   The tile was white with colour marks until 13 Oct. Flipping it is what the
   white set requires - a white wordmark on a white tile is nothing at all. */
.partners li{flex:0 0 116px; width:116px; aspect-ratio:3/2;
  /* A WHITE border, not white at 14%. At .14 it rendered as a soft grey box,
     which is neither a box nor nothing, and grey is not a brand colour. */
  background:var(--black); border:1px solid var(--white);
  border-radius:10px;
  padding:0; display:grid; place-items:center; overflow:hidden}
/* A display rule on the element beats the browser's own [hidden]{display:none},
   so the tiles on the other page kept their space and the strip stayed two
   rows tall: 163px for a 77px row. Every li sets display:grid above, so the
   attribute has to be answered explicitly. */
.partners li[hidden]{display:none}
.partners img{width:100%; height:auto; max-height:none; display:block}
.partners .vector{width:auto; max-width:74%; max-height:62%; margin-inline:auto}
/* The same measured optical nudges as before: EA sits 5.7% low in its own box,
   Red Bull 9.4%, because its wordmark outweighs the bulls. */
.partners img[src$="ea.svg"]{transform:translateY(-5.7%)}
.partners img[src$="red-bull.svg"]{transform:translateY(-9.4%)}
/* The same box as its neighbours, dashed to say it is waiting rather than
   finished. White, like the rest: a grey tile among white ones reads as a
   rendering fault instead of a gap. */
.partners li.await{background:var(--black); border:1px dashed var(--white);
  color:var(--white); font-family:var(--body); font-weight:700; font-size:9px;
  line-height:1.3; letter-spacing:.04em; text-transform:uppercase;
  text-align:center; padding:6px; overflow-wrap:anywhere}

/* ---- Case study extras -------------------------------------------------
   An Emmy nomination is a credential, not a tag: tags say what KIND of work
   it is and sit on the image, so a nomination riding in that slot would read
   as a category. It goes under the title in the gradient, which is the one
   place the brand's accent earns its keep on a card.
------------------------------------------------------------------------- */
/* The award sits UNDER the partners now, Richard's call on 14 Oct, so it is
   below the lockup in the markup and no longer between the title and the
   summary. Its own line is reserved at the foot of every card in a rail that
   carries one, and the award is pulled back into that reserved strip by the
   same amount - so a card with an award and a card without still put their
   marks on the same line. Only rails that have an award pay for it. */
.workrail:has(.award:not(:first-child)) .csopen{padding-bottom:24px}
.workcard .award{display:block; margin:9px 0 -24px; font-family:var(--body);
  font-weight:700; font-size:10px; letter-spacing:.11em; text-transform:uppercase;
  background:var(--grad); -webkit-background-clip:text; background-clip:text;
  color:transparent; width:fit-content}

/* A tag that comes FIRST in the markup rides in the partner strip - Richard,
   20 Oct. The 14 Oct placement below the title stands for a CREDENTIAL like an
   Emmy nomination; a "coming soon" is a state, and it belongs on the same line
   as the partner marks rather than on a line of its own. Markup order decides
   which of the two a card gets, so nothing is scoped to a page.

   NOTHING MOVES. A card with no partner artwork already reserves that strip
   above - the rule up at .workcard:not(:has(.shotplay .lockup.marks)) .csopen
   holds (5.5 + 3 + 18 - 2) * 1.52 of margin open so its title lands on the
   same line as a card that has marks. The tag goes INTO that reserve rather
   than adding a second one. My first attempt at this put a 21px strip of its
   own at the top of every card in the rail, which pushed all eight titles
   down - including the six that have nothing to do with it.

   The three numbers below are the mark box's own, so the tag's line box and a
   mark's content box occupy exactly the same span: 18px tall, pulled up by
   (18 - 2), closed off by -2, all at the lockup's 1.52. Anything that changes
   the height, the margins or the zoom on .lockup.marks changes these too. */
.workcard:not(:has(.shotplay .lockup.marks)) .award:first-child{
  margin:calc((18px - 2px) * -1.52) 0 calc(-2px * 1.52);
  line-height:calc(18px * 1.52)}
/* Not yet released. The card still carries a real title and partner, so the
   only thing marking it out is the tag and a quieter picture. */
.workcard.upcoming .shot img{opacity:.78}

/* A quote is the whole panel for a film that has not come out yet, so it is
   set as one rather than dressed up as a paragraph. */
.csbody blockquote.pull{margin:0 0 18px; padding:0 0 0 18px;
  border-left:2px solid transparent;
  border-image:var(--grad) 1; font-family:var(--display); font-weight:900;
  font-size:clamp(18px,2.1vw,27px); line-height:1.24; text-transform:none;
  letter-spacing:-.01em; max-width:26ch}
.csbody blockquote.pull cite{display:block; margin-top:14px; font-family:var(--body);
  font-weight:700; font-size:11px; letter-spacing:.11em; text-transform:uppercase;
  font-style:normal; color:var(--fg)}
.csbody .partnerline{font-family:var(--body); font-weight:700; font-size:11px;
  letter-spacing:.11em; text-transform:uppercase; color:var(--fg)}

/* The rail's own affordance: the edge softens only on the side there is more.
   It outlives the drift, which stops the moment anybody touches the rail, so
   "there is more over there" is still answered at rest. */
.workrail.more-right{-webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 72px),transparent 100%);
  mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 72px),transparent 100%)}
.workrail.more-left.more-right{-webkit-mask-image:linear-gradient(90deg,transparent 0,#000 72px,#000 calc(100% - 72px),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 72px,#000 calc(100% - 72px),transparent 100%)}
.workrail.more-left:not(.more-right){-webkit-mask-image:linear-gradient(90deg,transparent 0,#000 72px,#000 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 72px,#000 100%)}
/* An arrow that cannot go anywhere says so rather than sitting there live. */
.scrollbtn[disabled]{opacity:.32; cursor:default}

/* A division intro where there is no services list yet. The lede carries the
   line that lands; the body runs at a readable measure rather than being
   squeezed into the 30ch lead column the services layout uses. */
/* The intro is a stack now: eyebrow, lede, then the copy UNDER it, and the
   whole block takes 60% with the service titles in the 40% beside it. The
   copy used to sit to the RIGHT of the lede, which put a 15px paragraph level
   with a 44px headline and made the two compete rather than read in order. */
/* CENTRED, 19 Oct, Richard, across all four divisions. Every measure in the
   block keeps its ch limit and gets auto side margins, because text-align on
   its own centres the LINES inside a block that is still sitting hard left.
   The points list goes with it: those lines are display:block with no marker,
   so they centre as a stack rather than leaving bullets hanging. */
.divintro{min-width:0; text-align:center}
.divintro > *{margin-inline:auto}
/* 42 characters at 14ch came out as five lines of display type against seven
   of body, so the lede swamped the paragraph it was introducing. 18ch brings
   it to three and the two columns balance. */
.divintro .lede{font-size:clamp(26px,2.9vw,44px); line-height:1.0; max-width:18ch;
  margin-inline:auto; overflow-wrap:anywhere}
.divintro .body, .divintro .body p{margin:0 auto 14px; font-size:15px; line-height:1.65;
  max-width:62ch; color:var(--muted,var(--grey-01))}
.divintro .body{margin-top:clamp(16px,1.8vw,24px)}
.divintro .body p:last-child{margin-bottom:0}
/* The division intros carry a short list under the paragraph. Same marker as the
   careers benefits: a 7px rule sitting on the x-height, not a dodo (12 Oct), and
   a grid row rather than a list-style marker, so the second line of a long item
   aligns under the first rather than running back under the bullet. .7em because
   this list is 15px on 1.65 where benefits is 14px on 1.5, so the half-leading
   above the text is deeper. */
.divintro .body ul.points{list-style:none; margin:14px 0 0; padding:0; display:grid; gap:10px}
/* No dash. The bold lead-in on each line already marks where one point ends
   and the next begins, and a rule 7px long doing the same job twice read as
   a stray hyphen. One column now, so nothing is left indenting to an absent
   marker. */
.divintro .body ul.points li{display:block;
  align-items:start; max-width:62ch; margin-inline:auto; font-size:15px; line-height:1.65}
.divintro .body ul.points b{color:var(--fg); font-weight:700}
.divintro .body ul.points + p{margin-top:14px}
/* 60 / 40: the intro and its copy, then the service titles alongside. */
.services{grid-template-columns:3fr 2fr}
@media (max-width:980px){ .divintro + .svclist{margin-top:clamp(22px,3vw,36px)} }
.divintro .eyebrow{margin-bottom:12px}
/* No service list to sit beside: the block keeps a readable measure instead of
   a 40% column of nothing. */
/* Documentaries has no list beside it, so the block carries its own measure.
   The auto margins centre the BLOCK; without them text-align merely centred
   the lines inside a 68ch column still sitting hard left - 647px off centre
   at 1440. 19 Oct. */
.divintro.solo{max-width:68ch; margin-inline:auto}
@media (max-width:980px){ .divintro{grid-template-columns:1fr} }

/* The logotype standing in for the word in a heading. Sized off the heading's
   own em so it tracks the clamp() rather than needing a second set of
   breakpoints, and nudged up because the logotype's optical centre sits above
   the baseline of the cap height beside it. The light/dark pair is the same
   mechanism the top bar uses. */
/* nowrap because h1,h2,h3 carry text-wrap:balance, which treated the logotype
   as a word and broke the line between ABOUT and it. The two are one lockup
   and must not come apart. */
.shead h2{white-space:nowrap; text-wrap:nowrap}
/* Both classes named on purpose, which is what makes this (0,3,1). The theme
   switch for these logotypes is `:root[data-theme="dark"] .logo-dark{display:block}`
   at (0,3,0), and a plain `.shead h2 .headlogo` is only (0,2,1) - so it lost,
   the image stayed display:block, and a block image takes a line of its own.
   That is what put WHISPER under ABOUT. No !important needed, just the count. */
.shead h2 .headlogo.logo-light,
.shead h2 .headlogo.logo-dark{height:.74em; width:auto; display:inline-block;
  vertical-align:baseline; transform:translateY(.055em); margin-left:.1em}
:root[data-theme="dark"] .shead h2 .headlogo.logo-light,
:root:not([data-theme="dark"]) .shead h2 .headlogo.logo-dark{display:none}

/* Nothing moves. banner.js never starts a clip under reduced motion; this is
   for the one clip element that is in the markup rather than built by it. */
@media (prefers-reduced-motion:reduce){video.clip{display:none}}

/* --- the company LinkedIn feed (EmbedSocial) ------------------------------
   Sits between the Follow pill and the three portraits. Until consent.js
   fills it, the fallback paragraph is what is in here, so it carries the
   band's own type rather than anything the widget brings.

   The question of whether the widget could be restyled from here is settled:
   it cannot. See the measurement note on .ldfeed[data-embed-state] below.

   Top margin matches .igfeed under the Instagram pill. The bottom one
   separates the feed from the people. It used to take the gap from .ldhead,
   which no longer exists. */
.ldfeed{margin:clamp(18px,2.2vw,28px) 0 clamp(30px,3.6vw,56px)}
/* The second Follow pill sits over the people, so it takes the feed's bottom
   margin as its own top one and the spacing round it matches the first. */
.ldbar-team{margin-top:clamp(18px,2.2vw,28px)}

/* Instagram to LinkedIn - Richard, 19 Oct, twice. The first pass took 30%
   off the two band paddings, which carry .band's clamp(34px,4vw,56px) each.
   That is not the whole gap: .ldbar also brings clamp(20px,2.4vw,32px) of
   its own, so what you actually see between the foot of the Instagram
   pictures and the top of the Follow pill was 110.4px at 1440, not the 78
   the first note claimed.

   Second pass takes 40% off that measured 110.4. All three parts scale by
   0.6 rather than losing a flat number, so the junction closes by the same
   proportion at every width: 110.4 -> 66.2 at 1440, 81.9 -> 49.2 at 1024,
   67.6 -> 40.6 at 768.

   .ldbar's margin is shared with .igbar, which sits above the Instagram
   pictures and was not part of the ask, so the override is scoped away from
   it - and away from .ldbar-team, the second pill over the people, which
   sets its own. */
.band.social{padding-block-end:clamp(14.28px,1.68vw,23.52px)}
.band.leadership{padding-block-start:clamp(14.28px,1.68vw,23.52px)}
.band.leadership > .ldbar:not(.ldbar-team){margin-top:clamp(12px,1.44vw,19.2px)}
.ldfallback{margin:0; max-width:52ch; font-size:15px; line-height:1.5;
  color:var(--muted,var(--grey-02))}
.linkish{font:inherit; color:var(--fg); background:none; border:0; padding:0;
  text-decoration:underline; text-underline-offset:3px; cursor:pointer}
.linkish:hover,.linkish:focus-visible{color:var(--pink)}
.linkish:focus-visible{outline:2px solid var(--pink); outline-offset:3px}
/* Measured on staging, 15 Oct: ht.js does NOT render inline. It injects a
   cross-origin iframe on embedsocial.com and sets its height inline as the
   content grows - 2294px of a 5774px page, so the feed was 40% of News.
   Nothing inside it can be reached from here: not the LinkedIn blue, not
   their typeface, not the card styling, not the raw @[name](urn:li:person:)
   mention markup. contentDocument throws. So this is the whole of what our
   CSS can do to it.

   max-height is the one lever that still works against an inline height,
   because it is a different property and caps the used value whatever the
   element's own style says - no !important needed. It is a guard, not a
   design: once the post count is cut in EmbedSocial's own settings the
   content sits inside the cap and the scrollbar never appears. It exists so
   the section can never run away down the page again. */
.ldfeed iframe{max-width:100%; border:0; display:block}
.ldfeed[data-embed-state="on"]{max-height:640px; overflow-y:auto; overflow-x:hidden}
@media (max-width:760px){
  .ldfeed[data-embed-state="on"]{max-height:520px}
}
