/* ───────────────────────────────────────────────────────────────────────────
   The shell: tokens, the floating nav, the dodo band, the footer and the
   light/dark switch. Every page loads this, so the chrome is defined once and
   a page cannot drift from the others by being edited on its own.

   Load order matters: site.css first for the page components, this LAST, so the
   shell wins wherever the two name the same thing.

   Originally v3. The layout of the dark alternative (page 2/3 of Whisper_Home_Alternatives),
   on Grey 03 rather than white or black.

   Sunil asked for the dark design's LAYOUT with the off-white background: the
   film at the top rather than below a headline, genres visible on landing, the
   gradient panel for Who We Are, and everything on rounded cards. That is page
   3 of the PDF, which is the same structure as page 2 with the ground flipped.

   White is kept for the cards. Grey 03 behind them is what stops the page
   reading as clinical, which was the note; making the cards grey too would just
   move the problem.
   ─────────────────────────────────────────────────────────────────────────── */
:root{
  --red:#ff000e;
  --pink:#ff0097;
  /* Horizontal, five stops, measured off Whisper_Logo_RGB_Gradient.svg. Red to
     pink, left to right, which the CEO asked us to check everywhere. */
  --grad:linear-gradient(90deg,
          #ff000e 0%, #ff000e .24%, #ff0038 25.64%,
          #ff006b 59.82%, #ff008b 85.68%, #ff0097 100%);
  --black:#000;
  --white:#fff;
  --grey-01:#575752;
  --grey-02:#b9b9b4;
  /* Everything that changes between light and dark is a token, and every token
     gets its light value here FIRST. A colour defined only inside the dark
     block is the classic bug where one theme renders unreadable. */
  --bg:#f5f5f1;                      /* Grey 03 */
  --fg:#000;
  --card:#fff;                       /* the panels that sit on --bg */
  --muted:#000;                      /* was #575752. Secondary text is the
                                        foreground now: the palette has no grey,
                                        so size and weight carry the hierarchy. */
  --line:#e2e2dc;                    /* a hairline that reads on Grey 03 */
  --display:"Pilat Extended",Arial,Helvetica,sans-serif;
  --body:"Pilat",Arial,Helvetica,sans-serif;
  --gutter:clamp(16px,3vw,40px);
  --maxw:1440px;
  --r:14px;                          /* card radius. "More like buttons." */
  color-scheme:light;
}

/* Dark: the PDF's page 2. Not an inversion - the cards lift off pure black by a
   notch rather than going grey, which is what keeps it reading as a streamer
   rather than a dimmed document. */
:root[data-theme="dark"]{
  --bg:#000; --fg:#fff; --card:#101010; --muted:#fff; --line:#242424;
  color-scheme:dark;
}
/* Kept as a backstop for a browser with JavaScript off, where the pre-paint
   script never runs and no data-theme attribute is set. With JS on, dark is the
   default for everyone and only the switch moves the site to light, so this
   block is not what decides the theme any more. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#000; --fg:#fff; --card:#101010; --muted:#fff; --line:#242424;
    color-scheme:dark;
  }
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0; background:var(--bg); color:var(--fg);
  font-family:var(--body); font-size:16px; line-height:1.5;
  -webkit-font-smoothing:antialiased}
img,video{max-width:100%; display:block}
a{color:inherit}
.wrap{max-width:var(--maxw); margin:0 auto; padding-inline:var(--gutter)}
.skip{position:absolute; left:-9999px}
.skip:focus{left:8px; top:8px; z-index:99; background:var(--black); color:var(--white); padding:10px 14px}

/* ── nav: one floating bar, not a band across the top ───────────────────── */
/* site.css still carries the v1 gradient bar, and three of its rules reached
   through into this shell because they are scoped to `.topbar` and `.topbar
   nav` - which outrank, or simply are not named by, the rules below:
     1. `.topbar{color:#fff}` made Work/About/News white on the white pill.
        They were invisible, not missing.
     2. `.topbar .wrap{display:flex; max-width:none}` turned .bar into a
        shrink-to-fit flex ITEM, so it sized to its content and left the rest
        of the row empty. At 2560 that was a 77px gap left and 1180px right.
     3. `.topbar nav a{padding-block:4px}` (0,1,2) beat `.navmain a` (0,1,1)
        and flattened the Home pill.
   Deleting the v1 bar from site.css is the real fix; it stays until the
   remaining pages are off it, so these override it explicitly. Everything
   below is scoped under .topbar for that reason. */
.topbar{position:sticky; top:0; z-index:40; padding-block:14px; background:var(--bg);
  color:var(--fg)}
/* Back to the centred content column, so the bar's edges line up with the hero
   card and every section under it at any width. */
.topbar .wrap{display:block; max-width:var(--maxw); min-height:0; gap:normal;
  padding-inline:var(--gutter)}
.topbar .bar{display:flex; align-items:center; gap:18px;
  background:var(--card); border:1px solid var(--line); border-radius:999px;
  padding:10px 10px 10px 22px; box-shadow:0 1px 2px rgba(0,0,0,.04)}
/* 19px -> 23px (+20%, requested 5 Oct). site.css sets 22px with margin-right:auto
   at the same specificity; this wins only because shell.css loads last. */
/* The logotype is 1920x193 - 9.95:1 - so at 23px tall it wants 229px of the
   bar. `.topbar .bar` is a flex row and this anchor had the default
   flex-shrink:1, so the moment the nav and the pill ran out of room the
   anchor shrank, `img,video{max-width:100%}` above clamped the img to the
   anchor, and because the height is pinned at 23px the logotype SQUASHED
   rather than scaled. That is the "logo changes size with the window" -
   it is horizontal distortion, not responsive sizing, and it got worse the
   narrower the window. flex:0 0 auto stops the anchor giving ground; the nav
   yields instead, and it already has breakpoints to do that with. */
.topbar .logolink{flex:0 0 auto; display:flex; align-items:center}
.topbar .logo{height:23px; width:auto; max-width:none; margin-right:8px}
.topbar .navmain{display:flex; gap:4px; align-items:center}
.topbar .navmain a{font-weight:700; font-size:13px; letter-spacing:.08em;
  text-transform:uppercase; text-decoration:none; padding:9px 16px; border-radius:999px}
.topbar .navmain a[aria-current]{background:var(--fg); color:var(--bg)}
.navrule{width:1px; height:22px; background:var(--line)}
/* The genres were lighter than the main nav - a second level rather than four
   more top-level pages, which is what the artboard shows. Overruled 5 Oct:
   they now carry the same weight and colour as the main nav. Hover drops to
   70% so there is still feedback without reintroducing a second grey. */
.topbar .navgenre{display:flex; gap:20px}
.topbar .navgenre a{font-weight:700; font-size:12px; letter-spacing:.08em;
  text-transform:uppercase; text-decoration:none; color:var(--fg)}
.topbar .navgenre a:hover{opacity:.7}
/* 10px, not the nav link's 9px: the nav links carry a 2px bottom border for
   the current-page marker and this does not, so equal padding left it 2px
   short. Matched on the RENDERED height, 40px either way, rather than on the
   declaration. A little more side padding, which
   is what makes it read as the one button in the bar without making it a
   different size.

   nowrap is not cosmetic. "Siaradwch a ni" is four characters longer than
   "Let's talk" and was breaking onto two lines, which pushed the pill to 65px
   and stretched the whole bar with it. The width also moved with the viewport,
   so it broke in a different place at every width. */
.topbar .talk{background:var(--fg); color:var(--bg);
  font-family:var(--body); font-weight:700; font-size:13px; letter-spacing:.08em;
  text-transform:uppercase; text-decoration:none; padding:10px 18px; border-radius:999px;
  border:0; cursor:pointer; white-space:nowrap;
  transition:background .16s, color .16s}
/* The one place a gradient PILL stays. Everywhere else in the nav the gradient
   went onto the word, but this is a button rather than a link, and .pill and
   the carousel button already read white on the gradient. */
.topbar .talk:hover,.topbar .talk:focus-visible{background:var(--grad); color:var(--white)}

/* ── the Happen Device ─────────────────────────────────────────────────── */
/* One file, any colour. An <img> cannot inherit currentColor - it renders the
   SVG's own fill - so a white device would have come out black on the dark
   panels. Masking instead paints `background` through the shape, which means
   `color` controls it and the device is black or white automatically from
   whatever it sits in. Size it with font-size or an explicit width. */
/* The Happen Device is retired as a standalone mark, so the bullet is the dodo
   silhouette instead. Whisper_Dodo_RGB_Black.svg is a single path on a
   transparent ground, which is all a mask needs - the fill colour in the file is
   ignored, only its alpha is read, so one asset serves black and white.
   Sized by HEIGHT, not width: the device was .72em wide at 161.334/178.671,
   so .7973em tall. The dodo matches that height at .7973 x (1050/1080) =
   .775em wide. Matching width instead would have left it 12% short beside
   uppercase text. */
.dodobullet{display:inline-block; vertical-align:-.2em;
  width:.845em; aspect-ratio:1050/1080; background:currentColor;
  -webkit-mask:url(/assets/brand/Whisper_Dodo_RGB_Black.svg) no-repeat center/contain;
          mask:url(/assets/brand/Whisper_Dodo_RGB_Black.svg) no-repeat center/contain}

/* ── the dodo band, then the footer ────────────────────────────────────── */
/* Black in BOTH themes. The band is a full-bleed shot of the film, not a panel
   that follows the page - on Grey 03 it reads as a deliberate cut to black,
   which is what the artboard does. */
/* position:relative anchors the caption; the band stays full-bleed. */
.dodoband{position:relative; background:#000; overflow:hidden; line-height:0}
/* "Defy Impossible" over the crawl: top half, hard left, white, and sized at
   ~30% of the band's height. The band is clamp(140px,22vw,320px), so the type
   is the same clamp scaled by .3 - it then holds that proportion at every
   width instead of drifting. Left edge tracks the content column on a wide
   screen and falls back to the gutter once the viewport is narrower than it. */
/* Centred over the band (12 Oct). It was hard left, tracking the left edge of
   the content column. Pinning both sides to the gutter and centring inside
   that keeps it clear of either edge at every width, and drops the max() the
   left-only version needed to stop the line running off a narrow screen. The
   font-size cap below still governs the type. */
/* 42.8%, not 14% (20 Oct). The flying film arrived with DEFY IMPOSSIBLE burnt
   in; the clean master Richard sent has no type, so we set it ourselves and it
   has to land where his did. Measured off the burnt-in frame: caps run rows
   271-348 of 564, so 48.0% to 61.7% of the band, centred on 54.85%. Our caps
   sit 0.1875em below the box top ((.9 - (1.080+.205))/2 + (1.080-.700), from
   Pilat Extended Regular's hhea 1080/-205 and cap height 700) and are .700em
   tall, so their centre is .5375em below it. Type to band is 6.6vw/29.44vw =
   .2242 and holds within 1% across the whole clamp, so .5375 x .2242 = 12.05%
   of the band: top = 54.85 - 12.05 = 42.8%. Our caps are taller than the
   burnt-in ones (15.7% of the band against 13.7%), so we match the centre
   rather than the cap line.

   69.9%, not 42.8% (20 Oct, second pass). The 16-second master is cropped
   at y=160 rather than y=464, so every row of the band moved and the type
   had to move with it to stay in the same place ON THE BIRD. The burnt-in
   caps ran frame rows 1006-1160 of 2160; in a band cropped at y=160 that
   is 75.0% to 88.7%, centre 81.9%. Our cap centre sits 12.05% of the band
   below the box top, as derived above, so top = 81.9 - 12.05 = 69.9%.
   Checked against rendered frames at 1, 7 and 12 seconds: the eyes stay
   clear above the line, which was the point of raising the crop. */
.dodoline{position:absolute; z-index:1; top:69.9%;
  left:var(--gutter); right:var(--gutter); text-align:center;
  margin:0; font-family:var(--display); font-weight:400; text-transform:uppercase;
  color:var(--white);
  /* 400, not 900: extended but not bold - Richard, 16 Oct.
     The 42px floor was set from the band's height, not from the words in it.
     The second term caps the type at what the viewport can actually hold:
     gutters of 16 either side, so font <= (vw - 32) / (width per px of type).
     That ratio is a property of the FACE, so dropping from Heavy to Regular
     moved it. Measured in the browser with the real files loaded, not taken
     from the old comment: "IMPOSSIBLE" runs 9.332px per 1px of type in Pilat
     Extended Heavy and 5.958px in Regular, 36% narrower. The cap therefore
     goes 9.5vw to 15vw. At 15vw a 320px screen allows 48px, which is above
     the 42px floor, so this term no longer bites at any size we support -
     it stays as the guard it was meant to be rather than a live constraint. */
  font-size:min(clamp(42px,6.6vw,96px), 15vw); line-height:.9;
  letter-spacing:-.01em; text-wrap:balance; pointer-events:none}
.dodoband video,.dodoband img{width:100%; height:clamp(140px,22vw,320px);
  object-fit:cover; object-position:50% 78%; display:block}
.footcols{display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:28px;
  padding-block:clamp(30px,3.4vw,48px)}
/* --fg, not --muted. The palette is Red, Pink, Black and White; --muted is
   #575752 in light and #9a9499 in dark, and neither is a brand colour. These
   are the five column headings, so they were the largest piece of grey on the
   page. --fg rather than a literal #fff because the footer sits on --bg, which
   is white in light mode - a hardcoded white would have erased them there. */
.footcols h2{font-size:10px; font-weight:700; letter-spacing:.18em;
  text-transform:uppercase; color:var(--fg); margin:0 0 14px}
.footcols ul{list-style:none; margin:0; padding:0; display:grid; gap:9px}
.footcols a{font-size:13px; text-decoration:none}
.footcols a:hover{text-decoration:underline}
.bottombar{border-top:1px solid var(--line); border-image:var(--grad) 1}
.bottombar .wrap{display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  padding-block:20px; font-weight:700; font-size:10px; letter-spacing:.15em;
  text-transform:uppercase; color:var(--muted)}
.bottombar a{text-decoration:none}
/* The language switch left the footer for the More menu (12 Oct). These two
   rules stay harmless; .mmlang below is the live one. */
.bottombar .lang{margin-left:auto; display:flex; gap:10px}
.bottombar .lang a[aria-current]{color:var(--fg)}
/* One link, offering the language you are not reading. It sits under the
   second rule in the menu, below About / News / Careers, because it is a
   setting rather than a destination. lang= on the anchor so a screen reader
   says "Cymraeg" in Welsh rather than reading it as English. */
/* Off by default: above 1190 the button is on the bar and this would be the
   same link twice in one header. */
.topbar .moremenu .mmtalk,
.topbar .moremenu .mmtalkrule{display:none}
.topbar .moremenu .mmlang{display:block; font-weight:700; font-size:13px;
  letter-spacing:.08em; text-transform:uppercase; text-decoration:none}
/* .signoff is gone from the markup (12 Oct). "Defy Impossible" is on the page
   already, big, over the walking dodo directly above this bar - having it
   twice in the same footer read as a stutter rather than as a sign-off. The
   rule stays because the class is still in the Welsh pages until build-cy
   regenerates them, and it costs nothing if it comes back. */
.bottombar .signoff{font-family:var(--display); font-weight:400; font-size:12px;
  letter-spacing:.24em; color:var(--fg)}


@media (max-width:1100px){
  .footcols{grid-template-columns:repeat(3,minmax(0,1fr))}
}
/* The divisions come down in two stages, not one: first the bar gives up its
   spacing, and only when that is spent does the burger take them.

   Measured on staging 9 Oct with Pilat loaded, by cloning .bar into the topbar
   at width:max-content so nothing grows or shrinks. The bar's own minimum is
   the sum of its five children plus four gaps, its padding and the wrap gutter:

                      English   Welsh
     at desk spacing   1241px   1395px
     tightened         1163px   1317px

   So at the old breakpoints English had 59px of slack and Welsh had 5. The
   1201/1313 figures in the note this replaces were measured before "Let's
   talk" became a pill and before the rule came out, and had gone stale.

   What gives way, and why those three: the bar gap 18->12, the gap between
   division links 4->2, and the links' own side padding 16->10. Together they
   are 78px, which is 1.5 division words. Nothing here touches the type size or
   the letter-spacing, so the words themselves are untouched - they simply sit
   closer. The links keep 10px either side, which is enough for the filled pill
   the current page wears to still read as a pill.

   Scoped to .topbar to match the base rules above. Unscoped, the display:none
   lost to site.css's `.topbar nav{display:flex}` (0,1,1) and the divisions
   stayed on at every width - which is what pushed the page 1215px wide at 768.
   Below the burger breakpoint the home page carousel is the route to each
   division. */
@media (max-width:1300px){
  .topbar .bar{gap:12px}
  .topbar .navdiv{column-gap:2px}
  .topbar .navdiv a{padding-left:10px; padding-right:10px}
}
/* The divisions used to come off the bar at 1190. Richard, 14 Oct: keep them,
   lose Let's talk first, and narrow them if they still do not fit. So three
   stages rather than one, each measured by forcing the links on and stepping
   the window down until they overflow .navdiv:
     1190  the button goes, the divisions stay      - they fit to ~1000
     1010  the divisions go to 13px / 6px padding   - they fit to ~905
      930  only then do they fold into the burger
   930 rather than 905 for the same reason 1190 sat above 1163: a media query
   counts the scrollbar gutter and the measurement does not. That is 260px
   more of the range with all four on the bar. The button is in
   the More menu from 1190 down (.mmtalk), so the route to it never goes. */
/* Banded, not open-ended. Below 880 the divisions are in the burger anyway,
   so the button has the room again - and the phone rules further down were
   written to fit it at 390px, which an open-ended hide would have quietly
   thrown away. */
@media (max-width:1190px) and (min-width:931px){
  .topbar .talk{display:none}
  .topbar .moremenu .mmtalk,
  .topbar .moremenu .mmtalkrule{display:block}
}
@media (max-width:930px){
  .topbar .navdiv{display:none}
}
/* Welsh needs both stages earlier. "Siaradwch a ni" is 163px against "Let's
   talk" at 117, and the Welsh division names are longer again: "Rhaglenni
   dogfen" is 207px where "Documentaries" is 180. Keyed off the lang attribute
   rather than the /cy/ path, because the attribute is what is actually true
   about the document. Same 23px headroom over the measured 1317. */
@media (max-width:1400px){
  html[lang="cy"] .topbar .bar{gap:12px}
  html[lang="cy"] .topbar .navdiv{column-gap:2px}
  html[lang="cy"] .topbar .navdiv a{padding-left:10px; padding-right:10px}
}
/* Welsh carries the same three stages, each shifted up by the 150px that its
   single hide already sat above the English one. Not measured - the Welsh
   pages are stale and need a build-cy.py run before the widths mean
   anything - so treat these as the English pattern applied, not as
   thresholds taken off a render. */
@media (max-width:1340px) and (min-width:1081px){
  html[lang="cy"] .topbar .talk{display:none}
  html[lang="cy"] .topbar .moremenu .mmtalk,
  html[lang="cy"] .topbar .moremenu .mmtalkrule{display:block}
}
@media (max-width:1080px){
  html[lang="cy"] .topbar .navdiv{display:none}
}
/* Phones. The logotype is 229px wide at its desk size and the bar only has
   358px at 390px wide, so it genuinely does have to come down here - but by
   height, which keeps the 9.95:1 ratio, not by letting flex squash the width.
   17px clears the 16px minimum in the brand guide (p12). Measured at 390px:
   logo 169 + gap 12 + "Siaradwch a ni" 163 = 344 inside 358. */
/* Phones. Measured at 390px: the bar is a 358px pill with 32px of its own
   padding, leaving 326px, and the Welsh set - logotype 229 + 8 margin + 18 gap
   + 14 margin + "SIARADWCH A NI" 163 - wants 432. English wants 386. Both
   overflowed; the logo used to absorb it by squashing, which is the bug this
   block replaces. Nothing here is shaved to nothing: the logotype comes down
   by height so the 9.95:1 ratio holds and 16px clears the brand-guide minimum
   (p12), the pill keeps its shape, and the two dead margins go because `gap`
   already does that job. */
@media (max-width:520px){
  .topbar .bar{gap:10px; padding:10px 8px 10px 14px}
  .topbar .logo{height:16px; margin-right:0}
  .topbar .talk{padding:9px 14px; font-size:12px}
  .talk{margin-left:0}
}
/* Small phones. Welsh is the binding case: "SIARADWCH A NI" is 145px against
   "LET'S TALK" at 103, and at 375px the Welsh pill was landing flush against
   the bar's right edge with no padding left to show. Measured after this:
   English clears 320px, Welsh clears 345px. Below that the logotype would have
   to go under the 16px brand minimum, so it is left to overflow rather than
   quietly broken - if a 320px phone matters, the fix is a brand decision
   (the device on its own instead of the full lockup), not a CSS one. */
@media (max-width:400px){
  .topbar .bar{padding-left:10px}
  .topbar .talk{padding:8px 11px}
}
@media (max-width:760px){
  .footcols{grid-template-columns:repeat(2,minmax(0,1fr))}
  .topbar .navmain{display:none}
  /* The rule divides the divisions from About/News. With both navs gone it
     divides nothing - and a zero-width flex item still spends a gap on each
     side, 24px the Welsh bar did not have. display:none, not visibility. */
  .topbar .navrule{display:none}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}
/* ── theme switch ──────────────────────────────────────────────────────── */
/* Partner logos stay on WHITE tiles in both themes. They are supplied as
   full-colour marks with no knocked-out versions, and inverting a coloured
   logo looks far worse than a white tile on a dark page. */
.themesw{margin-left:auto; display:flex; align-items:center;
  background:var(--bg); border:1px solid var(--line); border-radius:999px; padding:3px}
.themesw button{width:37px; height:33px; border:0; border-radius:999px; cursor:pointer;
  background:none; color:var(--muted); font-size:13px; line-height:1;
  display:grid; place-items:center}
.themesw button[aria-pressed="true"]{background:var(--card); color:var(--fg);
  box-shadow:0 1px 2px rgba(0,0,0,.18)}
.talk{margin-left:14px}
/* Full-colour logo on light, white on dark. Brand rule, not a preference. */
/* The logo is a link to the home page from every page but the home page
   itself, where it points at where you already are. So it gets a hover state
   everywhere else and none there, which is what aria-current on the link
   marks - semantics the screen reader wants anyway, not a class invented for
   the CSS.

   The hover swaps to Whisper_Logo_RGB_Gradient.svg. That is the approved
   gradient master logo as supplied, not the white or black one tinted: the
   guide is explicit that the mark is never recoloured, and a filter or a
   background-clip over it would be exactly that.

   The link carries aria-label="Whisper" and all three logotypes are alt="",
   so swapping which one is displayed cannot take the link's accessible name
   away mid-hover.

   Specificity: :root[data-theme="dark"] .logo-dark is (0,2,1), so the hover
   rules have to out-rank it rather than merely come later. .topbar .logolink
   :not([aria-current]):hover .logo-dark is (0,5,0) and does. */
.topbar .logo-grad{display:none}
.topbar .logolink:not([aria-current]):hover .logo-light,
.topbar .logolink:not([aria-current]):hover .logo-dark,
.topbar .logolink:not([aria-current]):focus-visible .logo-light,
.topbar .logolink:not([aria-current]):focus-visible .logo-dark{display:none}
.topbar .logolink:not([aria-current]):hover .logo-grad,
.topbar .logolink:not([aria-current]):focus-visible .logo-grad{display:block}
.topbar .logolink:not([aria-current]){cursor:pointer}
.topbar .logolink[aria-current]{cursor:default}

.logo-dark{display:none}
:root[data-theme="dark"] .logo-light{display:none}
:root[data-theme="dark"] .logo-dark{display:block}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .logo-light{display:none}
  :root:not([data-theme="light"]) .logo-dark{display:block}
}
@media (max-width:620px){ .themesw{display:none} }
/* ── statutory pages: privacy, terms, cookies, reports ──────────────────── */
/* These pages are long-form reading, not marketing. One column, a measure that
   stops at about 72 characters, and headings that step down clearly, because
   people arrive here to find one clause and leave. */
/* THE LOGOTYPE AT THE HEAD OF A LEGAL DOCUMENT - Richard, 20 Oct. The legal
   PDFs carry a black Whisper logotype at the top of page one; the HTML
   versions of the same notices carried nothing in the body and relied on the
   site header above them, so a page and its PDF did not read as the same
   document.

   It uses the header's own .logo-light / .logo-dark pair, so it is the BLACK
   logotype on the light theme, exactly as on the PDF, and the white one on
   dark - where a black mark would be invisible. Same artwork either way: the
   logotype in the PDFs and the SVGs here were compared pixel for pixel and
   differ by 0.883 of 255, which is antialiasing.

   140px is the logotype at roughly the width of the H1 beneath it at the
   narrow end, and it is 9.95:1 so it never gets tall. */
.legal .doclogo{display:block; width:140px; height:auto;
  margin:0 0 clamp(20px,2.4vw,30px)}
/* The light/dark switch has to be restated at THIS specificity. The generic
   .logo-dark{display:none} is (0,1,0) and the rule above is (0,2,0), so on
   the light theme the display:block beat it and BOTH marks drew, one under
   the other. Measured in a browser: on light, .logo-light 140x14 shown and
   .logo-dark 140x14 shown. Dark happened to be right only because
   :root[data-theme="dark"] .logo-light is (0,2,1) and still won. */
.legal .doclogo.logo-dark{display:none}
:root[data-theme="dark"] .legal .doclogo.logo-light{display:none}
:root[data-theme="dark"] .legal .doclogo.logo-dark{display:block}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .legal .doclogo.logo-light{display:none}
  :root:not([data-theme="light"]) .legal .doclogo.logo-dark{display:block}
}
.legal{padding-block:clamp(34px,5vw,72px)}
.legal .wrap > *{max-width:72ch}
/* Welsh compounds run long: "Gaethwasiaeth" alone is 402px of Pilat Extended
   Heavy on a 390px phone, against 358px of content column, and "Datganiad ar
   Gaethwasiaeth a Masnachu mewn Pobl" took the anti-slavery page 28px past the
   viewport. anywhere, not break-word: these headings sit in grid and flex
   tracks, and only anywhere lowers the min-content width so the track can
   actually give. It breaks without inserting a hyphen, which is what the brand
   guide asks for. Same treatment as .depthero h1. */
.legal h1,.legal h2,.legal h3{overflow-wrap:anywhere}
.legal h1{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(30px,4.6vw,58px); line-height:1; letter-spacing:-.01em;
  margin:0 0 14px; text-wrap:balance}
.legal .legalmeta{margin:0 0 clamp(28px,3.4vw,44px); color:var(--muted); font-size:14px}
.legal h2{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:clamp(17px,1.7vw,22px); letter-spacing:.01em;
  margin:clamp(34px,3.6vw,52px) 0 12px; scroll-margin-top:92px}
.legal h3{font-size:15px; font-weight:700; letter-spacing:.01em;
  margin:26px 0 8px}
.legal p{margin:0 0 14px; font-size:15px; line-height:1.65}
.legal ul,.legal ol{margin:0 0 18px; padding-left:22px}
.legal li{font-size:15px; line-height:1.65; margin-bottom:9px}
.legal a{color:inherit; text-underline-offset:3px}
.legal a:hover{opacity:.7}
.legal code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px}
.legal .legalnote{font-size:13px; color:var(--muted)}

/* contents list. An <ol> so the numbers match the clause numbers, which is how
   people cite these pages to each other. */
.legaltoc{border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  border-image:var(--grad) 1;
  padding-block:18px; margin-bottom:clamp(28px,3.4vw,44px)}
.legaltoc h2{margin:0 0 10px; font-size:12px; letter-spacing:.16em}
.legaltoc ol{margin:0; padding-left:20px}
.legaltoc li{margin-bottom:5px; font-size:14px}

/* Tables. min-width:0 on the scroller or the grid parent sizes to the table and
   the whole page scrolls sideways instead of just the table. */
.cookietable,.lawtable{width:100%; border-collapse:collapse; margin:0 0 20px;
  font-size:14px; text-align:left}
.cookietable th,.lawtable th{font-family:var(--body); font-weight:700;
  font-size:11px; letter-spacing:.13em; text-transform:uppercase;
  padding:0 14px 9px 0; border-bottom:1px solid var(--fg)}
.cookietable td,.lawtable td{padding:12px 14px 12px 0; vertical-align:top;
  border-bottom:1px solid var(--line); line-height:1.55}
.cookietable td:last-child,.lawtable td:last-child,
.cookietable th:last-child,.lawtable th:last-child{padding-right:0}
.lawtable td:first-child{width:34%; font-weight:700}

.doclink{margin-top:clamp(24px,3vw,36px)}
.legal .pill{font-size:12px}

/* ── cookie banner ──────────────────────────────────────────────────────── */
/* Bottom-left, above the Welsh notice's corner. Not a full-width bar and not a
   modal: it must not block the page, because a banner that traps you is the
   thing everyone hates, and consent given to escape a wall is not consent. */
.cookiebar{position:fixed; z-index:120; left:12px; bottom:12px;
  max-width:min(94vw,420px);
  background:var(--card); color:var(--fg);
  border:1px solid var(--line); border-radius:var(--r);
  padding:16px 18px; box-shadow:0 10px 34px rgba(0,0,0,.34)}
.cookiebar p{margin:0 0 14px; font-size:13px; line-height:1.55}
.cookiebar a{color:inherit; text-underline-offset:3px}
.cookiebtns{display:flex; flex-wrap:wrap; gap:9px}
.cookiebar button{font-family:var(--body); font-weight:700; font-size:11px;
  letter-spacing:.11em; text-transform:uppercase; cursor:pointer;
  padding:11px 18px; border-radius:999px;
  border:1px solid currentColor; background:transparent; color:inherit}
.cookiebar button:hover{opacity:.72}
/* The accept button carries the gradient, which is the only place on these
   pages it appears - it is the one thing we are asking people to decide. */
.cookiebar button.primary{border-color:transparent; background:var(--grad);
  color:var(--white)}
.cookiebar button:focus-visible{outline:2px solid currentColor; outline-offset:3px}

@media (max-width:620px){
  .cookiebar{left:12px; right:12px; max-width:none; bottom:12px}
  .cookietable,.lawtable{font-size:13px}
  .lawtable td:first-child{width:auto}
}
/* Narrow phones cannot hold a two-column table of clause text, so it becomes
   stacked blocks with the header as a label on each cell. */
@media (max-width:480px){
  .lawtable thead{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0)}
  .lawtable tr{display:block; border-bottom:1px solid var(--line); padding-block:14px}
  .lawtable td{display:block; border:0; padding:0 0 8px}
  .lawtable td:first-child{width:auto}
}

/* ── Welsh draft notice on the statutory pages ──────────────────────────── */
/* A corner banner is not enough on a page someone might rely on. The draft
   state has to be unmissable and it has to survive a print, because that is
   exactly how a policy ends up in a file as if it were the real thing. So:
   a solid block at the top that names the English version as authoritative,
   and a repeating diagonal watermark behind the whole page.

   The watermark is a background-image on the MAIN element, not on an overlay
   over the text, so it never sits between the reader and a word. */
.legal.isdraft{position:relative}
.legal.isdraft::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  opacity:.055;
  background-image:url('data:image/svg+xml;utf8,\
<svg xmlns="http://www.w3.org/2000/svg" width="420" height="300" viewBox="0 0 420 300">\
<text x="0" y="150" transform="rotate(-24 210 150)" fill="%23FF000E" \
font-family="Arial,Helvetica,sans-serif" font-weight="700" font-size="46" \
letter-spacing="6">DRAFFT / DRAFT</text></svg>');
  background-repeat:repeat}
.legal.isdraft > .wrap{position:relative; z-index:1}

/* The block at the top. Gradient edge, black panel, white type: on-brand, and
   it reads as a stamp rather than as part of the policy. */
/* The gradient runs left to right, per the brand guide, so it goes across the
   TOP of the block. As a 5px left border it sampled only the leftmost stop and
   came out solid red, which is not the gradient. */
.draftnote{max-width:72ch; margin:0 0 clamp(26px,3.2vw,40px);
  background:var(--black); color:var(--white);
  border-radius:var(--r); overflow:hidden; border:1px solid var(--line)}
.draftnote::before{content:""; display:block; height:5px; background:var(--grad)}
.draftnote > div{padding:16px 20px}
.draftnote h2{font-family:var(--display); font-weight:900; text-transform:uppercase;
  font-size:13px; letter-spacing:.14em; margin:0 0 8px; color:var(--white)}
.draftnote p{margin:0 0 8px; font-size:13px; line-height:1.6; color:var(--white)}
.draftnote p:last-child{margin-bottom:0}
.draftnote a{color:var(--white); text-underline-offset:3px}
.draftnote .en{opacity:.8}

/* Print: screens can carry a 5% tint, paper cannot, so the watermark comes up
   and the block prints as a hard border. */
@media print{
  .legal.isdraft::before{opacity:.12}
  .draftnote{border:2px solid #000; color:#000; background:#fff}
  .draftnote h2,.draftnote p,.draftnote a{color:#000}
}

/* ---- The bar: hover highlight, and the More menu -------------------------
   The four divisions take the room between the logotype and the controls and
   spread across it rather than bunching beside the logo.

   Hover was a gradient pill behind white text. Dropped 9 Oct for the gradient
   on the word itself, which also settles the contrast question that pill
   carried: white on the gradient measured 3.68:1 at the pink end and 3.99 at
   the red, against the 4.5 that 13px bold wants.
------------------------------------------------------------------------- */
.topbar .navdiv{flex:1 1 auto; justify-content:space-evenly; min-width:0}
/* 15px, not the main nav's 13. These four are the top level of the site now
   and the row has the width between the logotype and the controls to itself.
   Scoped to .navdiv so the same links keep 13px inside the More menu, where
   they sit in a narrow panel. Equal specificity to `.topbar .navmain a`, so
   this wins on source order - it has to stay below it in this file. */
.topbar .navdiv a{font-size:15px; transition:color .16s}
/* The narrowing stage, and it has to live BELOW the 15px above rather than up
   with the other topbar media queries. Both are (0,1,2), so source order
   decides, and from up there the 13px lost silently - the links still
   measured 15px at 950 and still overflowed. */
@media (max-width:1010px){
  .topbar .navdiv a{font-size:13px; padding-left:6px; padding-right:6px}
}
@media (max-width:1160px){
  html[lang="cy"] .topbar .navdiv a{font-size:13px; padding-left:6px; padding-right:6px}
}
/* The current division was a solid white pill. It marked the page, but at a
   glance it read as a button that does nothing, so it goes. aria-current stays
   on the link, so the page is still announced; the gradient on the word
   carries it visually, the same ramp the hover uses. Same source-order note as
   above: this has to stay below `.topbar .navmain a[aria-current]`. */
/* border-bottom:0 is the other half of removing the pill. site.css carries
   `.topbar nav a[aria-current]{border-bottom:2px solid var(--white)}`, and the
   nav link is border-radius:999px, so that 2px renders as an arc under the
   word. It was invisible for as long as there was a white pill behind it -
   white on white - and the moment the pill came off it showed as a stray
   curve. (0,3,1) here against (0,2,2) there, so this wins on specificity
   rather than on file order. */
.topbar .navdiv a[aria-current]{background:var(--grad);
  background-origin:content-box; background-repeat:no-repeat;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  border-bottom:0}
/* background-origin is doing the work here. The link keeps the nav's 9px/16px
   padding, and background-clip:text paints the ramp across the background
   POSITIONING area - the padding box by default. A short word like SPORT sits
   16px in from either end of that box, so it samples the middle of the ramp
   and comes out a flat magenta. Moving the origin to the content box makes the
   ramp exactly as wide as the word, so all four run red to pink whatever their
   length. Same fault, same fix, as .workcard .h3 in site.css, which got there
   with width:fit-content because it had no padding to work around. */
/* ROLLOVER: the gradient pill with white type, which is what it was before
   12 Oct. The word-only gradient read as the word changing colour rather than
   as a target you had hit, and the four division names are the one row in the
   bar you aim at. The pill is the same shape the link already carries
   (border-radius:999px from .topbar .navmain a), so nothing moves on hover.

   The three resets are not decoration. background-clip and background-origin
   have to be put BACK to their initial values here, because the
   a[aria-current] rule above sets them to text/content-box, and a hover on the
   CURRENT division would otherwise keep clipping the ramp to the glyphs - a
   gradient pill with an invisible word inside it. border-box and padding-box
   make the ramp fill the whole pill, edge to edge, and colour:white puts the
   word back on top of it. White on the gradient is the same reading the
   Let's talk button and the carousel button already use. */
.topbar .navdiv a:hover,
.topbar .navdiv a:focus-visible,
.topbar .navdiv a[aria-current]:hover{background:var(--grad);
  background-origin:padding-box; background-repeat:no-repeat;
  -webkit-background-clip:border-box; background-clip:border-box;
  color:var(--white); -webkit-text-fill-color:var(--white)}
/* Forced colours drops background images, so the clip has nothing to paint and
   the word would go to the transparent colour and vanish. */
@media (forced-colors:active){
  .topbar .navdiv a:hover,
  .topbar .navdiv a:focus-visible,
  .topbar .navdiv a[aria-current],
  .topbar .navdiv a[aria-current]:hover{color:LinkText; background:none;
    -webkit-text-fill-color:currentColor}
}

/* margin-left:auto keeps the button with the theme switch and Let's talk.
   At full width .navdiv has flex:1 and has already eaten the slack, so the
   auto margin finds nothing to take and nothing moves; below 1300 the
   divisions are display:none and without this the button fell back against
   the logotype with a void between it and the rest of the controls. */
.navmore{position:relative; flex:0 0 auto; margin-left:auto}
/* ONE auto margin in the row, not two. .themesw already carried
   margin-left:auto to push the controls right, so with .navmore claiming it as
   well the slack was split evenly and the button landed mid-bar with a void on
   either side. Measured at 1200: both computed 278.906px, burger at 593-631
   against a theme switch at 928. The claim moves to .navmore, which is now the
   first of the right-hand group, and the three travel together. */
.topbar .themesw{margin-left:0}

.burger{width:38px; height:38px; padding:0; border:1px solid var(--line); border-radius:999px;
  background:none; cursor:pointer; display:grid; place-content:center; gap:4px}
.burger span{display:block; width:16px; height:2px; background:var(--fg);
  transition:transform .18s ease, opacity .18s ease, background-color .18s ease}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}
/* Rolled over, the pill fills red to pink and the bars go white against it:
   the same move .topbar .talk makes, so the two controls either side of the
   bar behave alike. The border goes transparent rather than staying a grey
   ring with a gradient inside it. Keyboard focus gets the fill as well as
   its outline, so the affordance is not mouse-only.

   Only the border and the bars tween. A gradient is a background-IMAGE, and
   those do not interpolate, so the fill itself arrives at once however long
   a transition it is given - no point pretending otherwise here. */
.burger{transition:border-color .18s ease}
.burger:hover,
.burger:focus-visible{border-color:transparent; background:var(--grad)}
.burger:hover span,
.burger:focus-visible span{background:var(--white)}
.burger:focus-visible{outline:2px solid var(--pink); outline-offset:2px}

/* 14px at the foot against 8px elsewhere. The last item's own 10px of padding
   used to run almost into the 16px corner radius, so the list looked like it
   had been cut off rather than ended. */
/* .topbar scoping is load-bearing: site.css's `.topbar nav{align-items:center}`
   is (0,1,1) and plain `.moremenu` is (0,1,0), so it won and the shrink-wrapped
   items sat centred in a ragged stack. (0,2,0) here. Only showed up once the
   items stopped being full width - before that, alignment had nothing to do. */
/* Opens to the RIGHT of the burger, not the left. At right:0 the panel's right
   edge met the burger's and the other 210px ran leftwards, so it sat under
   BRANDED and read as that word's menu. Centring on the button was not enough
   either: measured, its left edge still landed 12px behind BRANDED at 1366 and
   23px at 1310, and cleared by only 2px at 1440. left:0 starts it at the
   burger's own left edge, which clears the last division by 89px at 1440 and
   holds down to 620, where the rule below takes over. */
.topbar .moremenu{position:absolute; top:calc(100% + 12px);
  left:0; right:auto; min-width:210px; z-index:60;
  background:var(--card); border:1px solid var(--line); border-radius:16px;
  padding:8px 8px 14px;
  display:flex; flex-direction:column; align-items:flex-start; gap:2px;
  box-shadow:0 14px 36px rgba(0,0,0,.28)}
.moremenu[hidden]{display:none}
/* width:fit-content is what lets the gradient land on the word. These are
   flex children in a column, so they stretch to the panel's full width by
   default, and background-clip:text paints across the whole positioning area -
   a short word like NEWS would sit in the middle of the ramp and come out flat
   magenta, the same fault the bar links had. Shrink-wrapping each item makes
   the ramp as wide as the word. It costs hit area: a row is now its word plus
   14px either side rather than the full 210px panel: measured, ABOUT is now
   79.2 x 27.5 against the panel's 210. The height is unchanged, only the
   width. */
.moremenu a{font-weight:700; font-size:13px; letter-spacing:.08em; text-transform:uppercase;
  text-decoration:none; color:var(--fg); padding:10px 14px; border-radius:999px;
  width:fit-content}
/* No pill in here either, in the bar or the menu. Gradient on the word for
   hover, focus and the current page alike. */
/* Scoped through .topbar on purpose. site.css's `.topbar nav a[aria-current]`
   is (0,2,2) and `.moremenu a[aria-current]` is only (0,2,1), so the 2px white
   border-bottom survived in here and drew the same arc under the current item
   that it drew in the bar - visible in a screenshot, invisible in the computed
   styles I checked first, because I was reading the bar's link. (0,3,1) now. */
.topbar .moremenu a:hover,.topbar .moremenu a:focus-visible,
.topbar .moremenu a[aria-current],
.topbar .moremenu a[aria-current]:hover{background:var(--grad);
  background-origin:content-box; background-repeat:no-repeat;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  border-bottom:0}
@media (forced-colors:active){
  .topbar .moremenu a:hover,.topbar .moremenu a:focus-visible,
  .topbar .moremenu a[aria-current],
  .topbar .moremenu a[aria-current]:hover{color:LinkText; background:none}
}
/* Back to the right edge where there is no room to open rightwards: at 420 a
   left-anchored panel runs 20px past the viewport. */
@media (max-width:620px){
  .topbar .moremenu{left:auto; right:0}
}
/* 931 to 1190 the panel ran off the right of the SCREEN and the whole page
   scrolled sideways - 31px at 1190, 34 at 1100, 39 at 931. Measured 20 Oct on
   the home page, and it predates the Cymru link: deleting that link in the
   live DOM and re-measuring gave the identical numbers at every width.

   The band is exactly where the divisions are still IN the bar while Let's
   talk has come off it. Losing the button lets the row spread, the burger
   moves right, and the 210px panel no longer has 210px of screen beside it:
   from the burger's left edge to the wrap's right edge is only 171 to 179px
   anywhere in the band.

   right:0 against the BURGER is not the fix. At 1100 that lands the panel at
   752-962 while BRANDED sits at 791-895, which is precisely the "reads as
   that word's menu" fault the note further up describes. Anchoring to the BAR
   instead pins the panel to the wrap's right edge - 890-1100 at that width -
   so it clears BRANDED and cannot leave the screen, because the bar cannot.

   The two position declarations are what move the containing block from the
   burger to the bar; right:0 on its own would still resolve against .navmore.
   Below 931 the divisions leave the bar, the burger jumps left, and the
   original left:0 has room again. */
@media (min-width:931px) and (max-width:1190px){
  .topbar .bar{position:relative}
  .topbar .navmore{position:static}
  /* width, not just min-width. An absolutely positioned box shrink-wraps
     against its CONTAINING BLOCK, so moving that from the 38px burger to the
     full-width bar let the panel grow to its content - 258px, wide enough to
     swallow BRANDED whole at 931. Pinning it to the same 210 it uses at every
     other width keeps one panel rather than two. */
  .topbar .moremenu{left:auto; right:0; width:210px}
}
.mmrule{height:1px; background:var(--line); margin:6px 10px}
/* The divisions live in the bar at this width, so the menu holds About and
   News only. */
.moremenu a[href^="/work/"]{display:none}
/* These two must track the breakpoints where .navdiv is hidden, not the ones
   where it starts tightening - otherwise the divisions sit in the bar AND in
   the menu at the same time through the whole tightening band. */
@media (max-width:1190px){ .moremenu a[href^="/work/"]{display:block} }
@media (max-width:1340px){ html[lang="cy"] .moremenu a[href^="/work/"]{display:block} }
