/* The MADgicians — dark theme.
   Loads after styles.css and overrides it for this page only. */

.mg{
  color-scheme:dark;    /* this page is built dark on purpose */
  --vd:      #07070A;   /* void */
  --vd2:     #0E0E13;   /* raised */
  --vd3:     #17171F;   /* hover */
  --inv:     #F3F2EF;   /* type */
  --dim:     #9A98A6;   /* secondary type */
  --faint:   rgba(243,242,239,.12);
  --glow:    #4FD9F0;   /* neon, taken from the logo */
  --glow-dk: #1C7FA8;

  background:var(--vd);
  color:var(--inv);
}
.mg ::selection{background:var(--glow);color:#04161C}

/* ---------- opening logo ---------- */
.intro{
  position:fixed;inset:0;z-index:200;
  background:#05060A;
  display:grid;place-items:center;overflow:hidden;
  transition:opacity .7s ease,visibility .7s ease;
}
.intro.is-done{opacity:0;visibility:hidden;pointer-events:none}
.intro__stage{position:relative;width:100%;height:100%;display:grid;place-items:center}
/* sized so the whole wordmark always fits across: fills the screen on desktop,
   and on tall screens shrinks to the width, fading out at the top and bottom.
   hidden until it is actually playing, so the screen is just dark while it loads */
.intro__video{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(max(100vw, 100vh * 2.8), 167vw);height:auto;aspect-ratio:2.8;
  object-fit:cover;opacity:0;transition:opacity .35s ease;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 86%,transparent);
          mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 86%,transparent);
}
@media (orientation:portrait){.intro__video{width:140vw}}
.intro.is-video .intro__video,.intro.is-still .intro__video{opacity:1}
.intro__fallback{position:relative;z-index:2;width:min(760px,84vw)}
/* the typeset wordmark only runs if the video cannot play */
.intro:not(.is-fallback) .intro__fallback{display:none}

.intro__fallback{display:grid;justify-items:center;gap:.9rem}
.intro__the{
  font-size:clamp(.6rem,1.1vw,.75rem);font-weight:700;
  letter-spacing:.62em;color:var(--dim);text-indent:.62em;
  opacity:0;animation:introFade .9s ease .25s forwards;
}
.intro__word{display:flex;font-weight:800;letter-spacing:-.04em;line-height:1}
.intro__word span{
  font-size:clamp(2.3rem,8vw,5.5rem);
  opacity:0;transform:translateY(.36em);
  animation:introUp .72s cubic-bezier(.16,1,.3,1) forwards;
}
.intro__word span:nth-child(1){animation-delay:.34s}
.intro__word span:nth-child(2){animation-delay:.40s}
.intro__word span:nth-child(3){animation-delay:.46s}
.intro__word span:nth-child(4){animation-delay:.60s;color:var(--glow)}
.intro__word span:nth-child(5){animation-delay:.66s;color:var(--glow)}
.intro__word span:nth-child(6){animation-delay:.72s;color:var(--glow)}
.intro__word span:nth-child(7){animation-delay:.78s;color:var(--glow)}
.intro__word span:nth-child(8){animation-delay:.84s;color:var(--glow)}
.intro__word span:nth-child(9){animation-delay:.90s;color:var(--glow)}
.intro__word span:nth-child(10){animation-delay:.96s;color:var(--glow)}
.intro__rule{
  height:1px;width:0;background:linear-gradient(90deg,transparent,var(--glow),transparent);
  animation:introRule 1s cubic-bezier(.16,1,.3,1) 1.1s forwards;
}
@keyframes introFade{to{opacity:1}}
@keyframes introUp{to{opacity:1;transform:none}}
@keyframes introRule{to{width:100%}}

.intro__skip{
  position:absolute;z-index:3;right:clamp(1rem,3vw,2.5rem);bottom:clamp(1rem,3vw,2.5rem);
  background:none;border:0;cursor:pointer;color:var(--dim);
  font:inherit;font-size:.75rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  padding:.6rem;transition:color .2s ease;
}
.intro__skip:hover{color:var(--inv)}

/* ---------- shared dark overrides ---------- */
.mg .masthead--dark{
  background:rgba(7,7,10,.72);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--faint);
}
.mg .masthead--dark .nav a{color:var(--dim)}
.mg .masthead--dark .nav a:hover,
.mg .masthead--dark .nav a.is-current,
.mg .masthead--dark .nav a[aria-current="page"]{color:var(--inv)}
.mg .masthead--dark .nav a:not(.btn)::after{background:var(--glow)}
.mg .masthead--dark .wordmark img{filter:invert(1) brightness(1.6)}
.mg .masthead--dark .burger{color:var(--inv)}
.mg .masthead--dark .nav .btn{color:var(--inv);border-color:rgba(243,242,239,.45);background:transparent}
.mg .masthead--dark .nav .btn:hover{background:var(--inv);color:var(--vd)}
@media (max-width:767px){
  .mg .masthead--dark .nav{background:var(--vd);border-bottom-color:var(--faint)}
  .mg .masthead--dark .nav a{border-bottom-color:var(--faint)}
}

.mg .media{background:var(--vd2)}
.mg .media__slug{color:rgba(243,242,239,.3)}
.mg .head p,.mg .head--center p{color:var(--dim)}
/* the gap between two sections, the same on both pages of the site. every section
   gives half of it above and below, so any two meeting leave exactly that much, and
   --close is the half gap the few deliberately tight boundaries use. phones set
   --sect smaller near the end of this file */
.mg{--sect:clamp(3rem,5.5vw,5rem);--close:calc(var(--sect) / 4)}
.mg .section{padding-block:calc(var(--sect) / 2)}

.eyebrow{
  font-size:.75rem;font-weight:700;letter-spacing:.34em;text-transform:uppercase;
  color:var(--glow);margin:0 0 1.5rem;
}

/* ---------- the name every section wears ---------- */
/* one label for all of them: a short neon dash and the caption beside it. it used to be
   a hairline across the page, but with four of them, two ruled lists and the footer the
   page had turned into a stack of lines. the rules that are left now mean something:
   they separate the items in a list. the headline itself is still the section's h2,
   only set small, so a section is named the same way wherever you are on the page */
.seclabel{
  display:flex;align-items:flex-start;gap:clamp(.6rem,1.2vw,.85rem);
  margin-bottom:clamp(1.75rem,4vw,3rem);
}
/* the dash runs the full height of the caption, so a label that wraps on a phone has the
   mark beside both of its lines. it is inset top and bottom by the same amount on every
   line: its ends sit half a dash either side of the middle of the capitals (10.5px down
   each 19.5px line of the 15px type), so on a one-line label it is exactly --dash tall,
   and on two lines it reaches from the first line's capitals to the second's. the dash
   grows on wider screens, and the insets shrink by half of whatever it grew */
.seclabel::before{
  --dash:clamp(15px,1.8vw,20px);
  content:"";flex:0 0 auto;width:2px;align-self:stretch;
  margin-top:calc(10.5px - var(--dash) / 2);margin-bottom:calc(9px - var(--dash) / 2);
  border-radius:2px;
  background:var(--glow);box-shadow:0 0 14px rgba(79,217,240,.55);
}
/* the Media label shares its row with the pill, which is taller than the caption, so its
   dash keeps the one-line size rather than stretching to the pill */
.seclabel--tag::before{align-self:auto;height:var(--dash);margin-bottom:0}
/* a quarter bigger than the eyebrows inside a section, since this is the section's name */
.seclabel .eyebrow{margin:0;font-size:.9375rem;line-height:1.3}

/* ---------- buttons ---------- */
.mg .btn{border-radius:999px;font-weight:600}
.btn--glow{
  background:var(--inv);color:var(--vd);border-color:var(--inv);
  box-shadow:0 0 0 0 rgba(79,217,240,.5);
  transition:background .2s ease,color .2s ease,box-shadow .35s ease,transform .2s ease;
}
.btn--glow:hover{
  background:var(--glow);border-color:var(--glow);color:#04161C;
  box-shadow:0 0 34px 0 rgba(79,217,240,.40);
}
.btn--wire{
  background:transparent;color:var(--inv);border-color:rgba(243,242,239,.32);
}
.btn--wire:hover{border-color:var(--inv);background:rgba(243,242,239,.06);color:var(--inv)}
.btn--lg{padding:1.15rem 2.6rem;font-size:1rem}

/* ---------- hero ---------- */
/* the screen under the menu bar exactly, so the scroll line at its foot shows on load */
.mghero{
  position:relative;min-height:calc(100svh - var(--head-h,69px));display:flex;align-items:center;
  padding-block:clamp(7rem,14vh,10rem) clamp(5rem,10vh,7rem);
  overflow:hidden;
}
.mghero::before{
  content:"";position:absolute;z-index:1;inset:-20% -10% auto -10%;height:120%;
  background:
    radial-gradient(ellipse 46% 40% at 22% 34%, rgba(28,127,168,.34) 0%, rgba(7,7,10,0) 70%),
    radial-gradient(ellipse 40% 36% at 82% 68%, rgba(79,217,240,.14) 0%, rgba(7,7,10,0) 70%);
  animation:drift 18s ease-in-out infinite alternate;
}
@keyframes drift{to{transform:translate3d(2.5%,-2%,0) scale(1.06)}}
/* background showreel, muted and looping, fades in once the video is playing.
   sits under the neon glow and grain; the scrim keeps the copy readable
   and fades the bottom into the page */
.mghero__video{position:absolute;inset:0;z-index:0;overflow:hidden;opacity:0;transition:opacity 1.2s ease}
.mghero__video.is-ready{opacity:1}
.mghero__video iframe{
  position:absolute;top:50%;left:50%;
  width:100vw;height:56.25vw;              /* 16:9 by width  */
  min-width:177.78vh;min-height:100%;      /* 16:9 by height */
  transform:translate(-50%,-50%);
  border:0;pointer-events:none;
}
/* where supported, cover the hero box exactly rather than the whole screen */
@supports (width:1cqw){
  .mghero__video{container-type:size}
  .mghero__video iframe{width:max(100cqw,177.78cqh);height:max(100cqh,56.25cqw);min-width:0;min-height:0}
}
/* no scrim over the reel. only the bottom edge fades, starting low and
   closing fast so it reaches solid page black before the section ends */
.mghero__video::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(7,7,10,0) 62%, rgba(7,7,10,.35) 78%, rgba(7,7,10,.82) 90%, var(--vd) 97%);
}
/* once the reel is up, the neon glow and grain step aside so it shows clean */
.mghero::before,.mghero__grain{transition:opacity 1.2s ease}
.mghero.has-video::before,.mghero.has-video .mghero__grain{opacity:0}
.mghero__grain{
  position:absolute;inset:0;z-index:1;opacity:.5;pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.055'/></svg>");
}
/* hero type, buttons and the gaps between them all scale off --hs.
   desktop runs at full size, phones 30% smaller */
.mghero{--hs:1}
/* phones: same height as the homepage hero rather than a full screen */
@media (max-width:767px){
  .mghero{--hs:.7;min-height:clamp(440px,76svh,780px);padding-block:3.5rem 5.5rem}
}
/* copy centred like the homepage hero and sat low: the buttons stop 10px above
   the scroll line. both read --scroll-b, so the gap holds at every screen size,
   and the hero's height (min-height) is unchanged */
/* the scroll line sits 20px off the hero's bottom edge, so the copy, the buttons and
   the line all sit low and the black under them stays short */
.mghero{--scroll-b:20px;align-items:flex-end;padding-bottom:calc(var(--scroll-b) + 52px + 10px)}
.mghero__inner{position:relative;z-index:2;text-align:center}
.mghero .eyebrow{font-size:calc(.75rem * var(--hs));margin-bottom:calc(1.5rem * var(--hs))}
.mghero__title{
  font-size:calc(clamp(2.4rem,6.4vw,5.6rem) * var(--hs));font-weight:800;
  letter-spacing:-.04em;line-height:1.02;margin:0;
}
/* sits straight on the reel, so white with a tight shadow to hold up over bright footage */
.mghero__lead{
  margin:0 auto;max-width:56ch;
  text-shadow:0 1px 2px rgba(7,7,10,.75),0 2px 16px rgba(7,7,10,.55);
  font-size:calc(clamp(1rem,1.35vw,1.2rem) * var(--hs));line-height:1.65;color:var(--inv);
}
.mghero .btn--wire{background:rgba(7,7,10,.4);border-color:rgba(243,242,239,.55);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.mghero .btn--wire:hover{background:rgba(7,7,10,.6);border-color:var(--inv)}
.mghero__actions{margin-top:calc(clamp(2rem,3.5vw,3rem) * var(--hs));display:flex;justify-content:center;gap:calc(.75rem * var(--hs));flex-wrap:wrap}
.mghero__actions .btn{font-size:calc(.9375rem * var(--hs));padding:calc(.95rem * var(--hs)) calc(1.9rem * var(--hs))}
/* phones: buttons use the shared phone button size from styles.css instead */
@media (max-width:767px){
  .mghero__actions .btn,.btn--lg{font-size:var(--mbtn-fs);padding:var(--mbtn-pad)}
}
.mghero__scroll{
  position:absolute;left:50%;bottom:var(--scroll-b);transform:translateX(-50%);
  width:1px;height:52px;background:var(--faint);overflow:hidden;z-index:2;
}
.mghero__scroll span{
  display:block;width:100%;height:40%;background:var(--glow);
  animation:scrolldot 2.2s cubic-bezier(.65,0,.35,1) infinite;
}
@keyframes scrolldot{0%{transform:translateY(-100%)}60%,100%{transform:translateY(250%)}}

/* ---------- showreel pop up ---------- */
/* shared styles live in styles.css; here the close button glows neon */
.mg .reelbox__close:hover{background:var(--glow);border-color:var(--glow);color:#04161C}

/* ---------- media pop up ---------- */
/* fills the screen: the photo as large as fits in the middle, arrows at the sides,
   close top right, the count (and a link, for a photo with a feature) underneath.
   phones move the arrows down beside the count, out of the photo's way */
.mediabox{
  --side:clamp(4.5rem,7vw,6.5rem);--top:4.75rem;--bot:5rem;
  position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;
  margin:0;padding:0;border:0;overflow:hidden;
  background:transparent;color:var(--inv);
}
.mediabox::backdrop{background:rgba(7,7,10,.94);backdrop-filter:blur(8px)}
.mediabox[open]{animation:reelfade .3s ease}
.mediabox[open]::backdrop{animation:reelfade .3s ease}
.mediabox__stage{
  position:absolute;inset:var(--top) var(--side) var(--bot);
  display:grid;place-items:center;
}
/* sized off the screen itself: a percentage of the stage does not hold inside a grid cell */
.mediabox__img{
  max-width:calc(100vw - 2 * var(--side));max-height:calc(100svh - var(--top) - var(--bot));
  width:auto;height:auto;display:block;
  box-shadow:0 30px 80px rgba(0,0,0,.6);
  transition:opacity .25s ease,transform .35s cubic-bezier(.16,1,.3,1);
}
.mediabox__img.is-swapping{opacity:0;transform:scale(.985)}
.mediabox__close{right:clamp(1rem,2.5vw,2rem);top:1rem;bottom:auto}
.mediabox__arrow{
  position:absolute;z-index:2;top:50%;transform:translateY(-50%);
  width:52px;height:52px;display:grid;place-items:center;padding:0;cursor:pointer;
  border-radius:50%;border:1px solid rgba(243,242,239,.32);
  background:rgba(7,7,10,.4);color:var(--inv);
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
.mediabox__arrow svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
@media (hover:hover){.mediabox__arrow:hover{background:var(--glow);border-color:var(--glow);color:#04161C}}
.mediabox__arrow[hidden]{display:none}
.mediabox__arrow--prev{left:clamp(1rem,2.5vw,2rem)}
.mediabox__arrow--next{right:clamp(1rem,2.5vw,2rem)}
/* the foot spans the full width under the photo; only its count and link take taps,
   so on phones the arrows beside them (layered above) get theirs */
.mediabox__foot{
  position:absolute;left:0;right:0;bottom:0;height:var(--bot);
  display:flex;align-items:center;justify-content:center;gap:1.5rem;
  pointer-events:none;
}
.mediabox__foot > *{pointer-events:auto}
.mediabox__count{margin:0;font-size:.8125rem;font-weight:600;letter-spacing:.14em;color:var(--dim);font-variant-numeric:tabular-nums}
.mediabox__link{font-size:.875rem;font-weight:600;color:var(--glow);text-decoration:none;border-bottom:1px solid rgba(79,217,240,.4)}
.mediabox__link:hover{border-bottom-color:var(--glow)}
.mediabox__link[hidden]{display:none}
@media (max-width:767px){
  .mediabox{--side:.75rem;--top:4.25rem;--bot:6rem}
  .mediabox__arrow{top:auto;bottom:calc((var(--bot) - 48px) / 2);transform:none;width:48px;height:48px}
  .mediabox__foot{flex-direction:column;gap:.5rem}
}
@media (prefers-reduced-motion:reduce){
  .mediabox[open],.mediabox[open]::backdrop{animation:none}
  .mediabox__img{transition:none}
}

.stats{
  margin-top:clamp(2.5rem,5vw,4rem);
  display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:1px;background:var(--faint);border:1px solid var(--faint);
}
.stat{background:var(--vd);padding:clamp(1.5rem,3vw,2.25rem)}
.stat b{
  display:block;font-size:clamp(2rem,4vw,3.25rem);font-weight:800;
  letter-spacing:-.04em;line-height:1;font-variant-numeric:tabular-nums;
}
.stat span{display:block;margin-top:.6rem;font-size:.8125rem;color:var(--dim)}

/* ---------- big statement lines ---------- */
.bigline{
  font-size:clamp(2.2rem,6vw,5rem);font-weight:800;
  letter-spacing:-.04em;line-height:1.04;margin:0;
}

/* ---------- process ---------- */
.process{margin-top:clamp(1rem,2vw,2rem)}
.process__tabs{
  display:flex;gap:0;flex-wrap:wrap;
  border-top:1px solid var(--faint);border-bottom:1px solid var(--faint);
}
.process__tab{
  flex:1 1 160px;background:none;border:0;cursor:pointer;
  font:inherit;font-size:1rem;font-weight:600;color:var(--dim);
  padding:1.35rem 1rem;text-align:left;position:relative;
  display:flex;align-items:baseline;gap:.7rem;
  transition:color .22s ease,background .22s ease;
}
.process__tab i{font-style:normal;font-size:.75rem;font-weight:700;letter-spacing:.1em;opacity:.55}
.process__tab::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:var(--glow);transform:scaleX(0);transform-origin:left;
  transition:transform .4s cubic-bezier(.16,1,.3,1);
}
.process__tab:hover{color:var(--inv);background:rgba(243,242,239,.03)}
.process__tab.is-on{color:var(--inv)}
.process__tab.is-on i{color:var(--glow);opacity:1}
.process__tab.is-on::after{transform:scaleX(1)}

.process__panels{position:relative;margin-top:clamp(2rem,4vw,3.5rem)}
.process__panel{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.process__panel[hidden]{display:none}
.process__panel.is-on{animation:panelIn .6s cubic-bezier(.16,1,.3,1)}
@keyframes panelIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.process__copy h3{font-size:clamp(1.35rem,2.6vw,2.1rem);letter-spacing:-.03em;line-height:1.15}
.process__copy p{margin-top:1.25rem;color:var(--dim);font-size:1rem;line-height:1.7;max-width:46ch}
@media (max-width:900px){
  .process__panel{grid-template-columns:1fr}
  .process__tab{flex:1 1 120px;padding:1rem .75rem;font-size:.9375rem}
}
/* phones: all four steps stay on one row, number beside the label, type sized to fit */
@media (max-width:767px){
  .process__tabs{flex-wrap:nowrap}
  .process__tab{
    flex:1 1 0;min-width:0;padding:.9rem .3rem;white-space:nowrap;
    gap:.3rem;font-size:clamp(.75rem,3.5vw,.9375rem);
  }
  .process__tab i{font-size:clamp(.625rem,2.6vw,.75rem);letter-spacing:.04em}
}

/* ---------- media features ---------- */
/* photos of any shape in rows of equal height. each tile is as wide as its --ar (width
   over height, read from the photo by madgicians.js) allows, and every row stretches to
   the full width, so nothing is cropped. madgicians.js cuts the grid a little way into
   the third row and fades it until "See more" opens the rest */
.press{
  --row:clamp(150px,17vw,240px);--gap:clamp(6px,.8vw,12px);
  --lift:14px; /* room around the grid for a hovered photo to grow into */
  position:relative;
}
/* the padding gives a hovered photo room to grow past the grid's edge without being cut
   off; the negative margin keeps the photos lined up with the heading. madgicians.js
   takes the padding off when it measures the width */
.press__grid{
  position:relative;display:flex;flex-wrap:wrap;align-items:flex-start;gap:var(--gap);
  padding:var(--lift);margin:calc(var(--lift) * -1) calc(var(--lift) * -1) 0;
  overflow:hidden;transition:max-height .7s cubic-bezier(.16,1,.3,1);
}
/* soaks up the spare room on the last row so its photos stay at their natural height */
.press__grid::after{content:"";flex:999 1 0}
.press__item{
  --ar:1.5;
  position:relative;flex:var(--ar) 1 calc(var(--ar) * var(--row));min-width:0;
  aspect-ratio:var(--ar);overflow:hidden;
  display:grid;place-items:center;background:var(--vd2);color:var(--dim);
}
.press__item img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top;
}
/* a photo grows a little and lifts over its neighbours on hover; a click opens it large */
.press__item.is-loaded{
  cursor:zoom-in;
  transition:transform .45s cubic-bezier(.16,1,.3,1),box-shadow .45s ease;
}
@media (hover:hover){
  .press__item.is-loaded:hover{
    z-index:2;transform:scale(1.04);
    box-shadow:0 18px 44px rgba(0,0,0,.7),0 0 0 1px rgba(79,217,240,.45);
  }
}
.press__item:focus-visible{outline:2px solid var(--glow);outline-offset:3px;z-index:2}
.press__item .media__slug{font-size:.6875rem;text-align:center;overflow-wrap:anywhere}
.press__item.is-loaded .media__slug,
.press__item.is-empty img{display:none}
.press::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:var(--fade,0px);pointer-events:none;
  background:linear-gradient(to bottom,rgba(7,7,10,0),rgba(7,7,10,.75) 55%,var(--vd));
  opacity:0;transition:opacity .4s ease;
}
.press.is-clipped::after{opacity:1}
.press__more{display:flex;justify-content:center;margin-top:clamp(1rem,2vw,1.5rem)}
.press__more[hidden]{display:none}
@media (max-width:767px){
  .press{--row:120px}
  .press__item .media__slug{font-size:.5625rem;padding:.25rem}
}
@media (prefers-reduced-motion:reduce){.press__grid,.press::after,.press__item.is-loaded{transition:none}}

/* ---------- projects ---------- */
/* --pg is the gutter, used between the tiles and at the screen edges alike */
.projects{
  --pg:clamp(1rem,1.6vw,1.5rem);
  margin-top:clamp(2rem,4vw,3rem);
  display:grid;grid-template-columns:repeat(3,1fr);gap:var(--pg);padding-inline:var(--pg);
}
.project{
  position:relative;background:var(--vd);text-decoration:none;color:var(--inv);
  display:block;overflow:hidden;border:1px solid var(--faint);
}
.project__media{position:relative;aspect-ratio:4/5;overflow:hidden;background:var(--vd2);display:grid;place-items:center}
.project__media img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .8s cubic-bezier(.16,1,.3,1);
}
.project:hover .project__media img{transform:scale(1.06)}
/* posters show whole inside the frame, with a blurred, slightly dimmed copy of
   themselves filling the edges they leave, so the poster itself stands out */
.project__media--poster img{object-fit:contain}
.project__media--poster .project__fill,
.project:hover .project__media--poster .project__fill{
  object-fit:cover;transform:scale(1.2);filter:blur(20px) brightness(.6);
}
.project::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(79,217,240,0);
  transition:box-shadow .35s ease;
}
.project:hover::after{box-shadow:inset 0 0 0 1px rgba(79,217,240,.6)}
.project__bar{
  position:relative;z-index:2;padding:1.35rem clamp(1rem,2vw,1.75rem) 1.6rem;
  display:flex;flex-direction:column;gap:.3rem;
}
.project__name{font-weight:700;font-size:1.05rem;letter-spacing:-.02em}
.project__meta{font-size:.8125rem;color:var(--dim)}
.project:hover .project__meta{color:var(--glow)}
/* tablets: two across once there are more than three projects; three stay in one row */
@media (min-width:768px) and (max-width:900px){
  .projects:has(> .project:nth-child(4)){grid-template-columns:repeat(2,1fr)}
}
/* phones: three across, so the projects sit in short rows of three */
@media (max-width:767px){
  .projects{--pg:.5rem;grid-template-columns:repeat(3,minmax(0,1fr))}
  .project__bar{padding:.6rem .55rem .75rem;gap:.15rem}
  .project__name{font-size:.75rem;line-height:1.25}
  .project__meta{font-size:.625rem}
}

/* ---------- roster ---------- */
.roster{border-top:1px solid var(--faint);margin-top:clamp(1rem,2vw,2rem)}
.roster__row{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:baseline;gap:clamp(1rem,3vw,2.5rem);
  padding:clamp(1.4rem,2.6vw,2.1rem) 0;
  border-bottom:1px solid var(--faint);
  text-decoration:none;color:var(--inv);
  transition:padding .35s cubic-bezier(.16,1,.3,1),color .25s ease;
}
.roster__row:hover{padding-left:clamp(.75rem,2vw,1.75rem)}
.roster__n{font-size:.75rem;font-weight:700;letter-spacing:.1em;color:var(--dim);transition:color .25s ease}
.roster__row:hover .roster__n{color:var(--glow)}
.roster__name{
  font-size:clamp(1.5rem,3.6vw,2.6rem);font-weight:800;letter-spacing:-.035em;line-height:1.05;
  transition:opacity .25s ease;
}
.roster__role{font-size:.875rem;color:var(--dim);text-align:right}
.roster:hover .roster__row:not(:hover) .roster__name{opacity:.4}

.roster__peek{
  position:fixed;z-index:5;top:0;left:0;width:230px;height:290px;
  margin:-145px 0 0 -115px;pointer-events:none;overflow:hidden;
  opacity:0;transform:scale(.94);
  transition:opacity .3s ease,transform .4s cubic-bezier(.16,1,.3,1);
  border:1px solid rgba(79,217,240,.4);
}
.roster__peek.is-on{opacity:1;transform:scale(1)}
.roster__peek img{width:100%;height:100%;object-fit:cover;display:block;background:var(--vd2)}
@media (hover:none),(pointer:coarse),(max-width:900px){.roster__peek{display:none}}
@media (max-width:700px){
  .roster__row{grid-template-columns:auto minmax(0,1fr);gap:.75rem 1rem}
  .roster__role{grid-column:2;text-align:left}
}

/* ---------- closing cta ---------- */
.mgcta{
  position:relative;text-align:center;overflow:hidden;
  padding-block:calc(var(--sect) / 2);
  border-top:1px solid var(--faint);
}
.mgcta::before{
  content:"";position:absolute;inset:auto 0 -60% 0;height:140%;z-index:0;
  background:radial-gradient(ellipse 52% 60% at 50% 100%, rgba(79,217,240,.20) 0%, rgba(7,7,10,0) 70%);
}
.mgcta .shell{position:relative;z-index:2}
.mgcta p{margin:clamp(1.5rem,2.5vw,2rem) auto clamp(2rem,3.5vw,2.75rem);max-width:48ch;color:var(--dim)}

/* the enquiry form under the closing line: the homepage form, in the dark palette */
.mgcta .form{margin:0 auto;text-align:left}
.mg .field label{color:var(--dim)}
.mg .field input,.mg .field textarea{background:var(--vd2);border-color:var(--faint);color:var(--inv)}
.mg .field input::placeholder,.mg .field textarea::placeholder{color:rgba(243,242,239,.35)}
.mg .field input:focus,.mg .field textarea:focus{border-color:var(--glow)}
/* the entertainment dropdown, in the same dark fields with the neon for focus and ticks */
.mg .select__toggle{background:var(--vd2);border-color:var(--faint);color:rgba(243,242,239,.35)}
.mg .select__toggle:hover{border-color:rgba(243,242,239,.3)}
.mg .select[open] .select__toggle{border-color:var(--glow);color:var(--inv)}
.mg .select__toggle.is-filled{color:var(--inv)}
.mg .select__toggle:focus-visible,.mg .opt input:focus-visible{outline-color:var(--glow)}
.mg .select__panel{background:var(--vd2);border-color:var(--glow);box-shadow:0 14px 30px rgba(0,0,0,.5)}
.mg .opt{color:var(--dim)}
.mg .opt:hover{background:rgba(243,242,239,.06);color:var(--inv)}
/* .mg .field input above reaches these boxes too and resets their background, so the
   tick (in near black here) is set up again */
.mg .opt input{
  border-color:rgba(243,242,239,.3);
  background:var(--vd2) no-repeat center / 0 0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.17 7.8 5.97 11.5 13.77 3.1' fill='none' stroke='%2307070A' stroke-width='2.2'/%3E%3C/svg%3E");
}
.mg .opt input:checked{background-color:var(--glow);border-color:var(--glow);background-size:100% 100%}
.mg .opt:has(input:checked){color:var(--inv)}
.mg .form button{
  background:var(--inv);color:var(--vd);
  transition:background .2s ease,color .2s ease,box-shadow .35s ease;
}
.mg .form button:hover{background:var(--glow);color:#04161C;box-shadow:0 0 34px rgba(79,217,240,.4)}
.mg .form{--ok:#3DDC84;--bad:#FF6B6B}
.mg .form__bar{background:var(--faint)}
.mg .form__msg,.mgcta .form__msg{margin:0;max-width:none;text-align:left;color:var(--dim)}

/* ---------- footer ---------- */
.foot--dark{background:var(--vd);border-top:1px solid var(--faint)}
.foot--dark .wordmark img{filter:invert(1) brightness(1.6)}
.foot--dark h4{color:var(--inv)}
.foot--dark a{color:var(--dim)}
.foot--dark a:hover{color:var(--inv)}
.foot--dark .muted{color:var(--dim)}
.foot--dark .foot__base{border-top-color:var(--faint);color:var(--dim)}
.foot--dark .map{background:var(--vd2)}
.foot--dark .social a{border-color:rgba(243,242,239,.24);color:var(--inv)}
.foot--dark .social a:hover{background:var(--glow);border-color:var(--glow);color:#04161C}

@media (prefers-reduced-motion:reduce){
  .intro__the,.intro__word span,.intro__rule{animation:none;opacity:1;transform:none;width:100%}
  .mghero::before,.mghero__scroll span,.process__panel.is-on{animation:none}
}

/* ================= countries: its own scroller ================= */
/* The list scrolls inside its own box. The page scroll is untouched, so
   anyone can skim straight past this section. */
/* --win is the list window, --row one country; the list padding centres the lit row */
.cty-sec{position:relative;overflow:hidden;--win:min(70vh,560px);--row:54px}
/* half the standard gap above and below the countries, on every screen. the gallery
   before it and whichever section comes next give up the same amount on the side
   facing it */
.mg{--cty-gap:var(--close)}
.mg .cty-sec{padding-block:var(--cty-gap)}
.mg .cty-sec + .mgsection,
.mg .cty-sec + [hidden] + .mgsection{padding-top:var(--cty-gap)}
.cty-sec::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:radial-gradient(ellipse 46% 50% at 80% 50%, rgba(28,127,168,.20) 0%, rgba(7,7,10,0) 70%);
}
.cty-sec .shell{position:relative;z-index:2}

/* the photos are landscape (3:2), so they take everything the list does not need: the
   list column sizes itself to its longest name, and the photo gets the rest. that keeps
   the photo under the height of the list window beside it, so the section stays exactly
   as tall as it was and nothing above or below it moves */
.pin__grid{
  display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(1.5rem,3.5vw,3rem);align-items:center;
}

.cty__window{
  position:relative;height:var(--win);
  /* room for the lit row to step right without touching the photo */
  padding-right:clamp(.5rem,1.4vw,1.1rem);
  overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:none;-ms-overflow-style:none;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 15%,#000 85%,transparent 100%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 15%,#000 85%,transparent 100%);
}
.cty__window::-webkit-scrollbar{display:none}
.cty{
  list-style:none;margin:0;padding:0;
  padding-block:calc(var(--win) / 2 - var(--row) / 2);
}
.cty__row{
  display:flex;align-items:center;gap:clamp(.9rem,2vw,1.6rem);
  height:var(--row);
  opacity:.3;
  transition:opacity .35s ease,transform .45s cubic-bezier(.16,1,.3,1);
  cursor:default;
}
.cty__row.is-on{opacity:1;transform:translateX(clamp(.5rem,1.4vw,1.1rem))}
.cty__dot{
  flex:0 0 auto;width:7px;height:7px;border-radius:50%;
  background:var(--dim);opacity:.35;
  transition:background .35s ease,opacity .35s ease,box-shadow .35s ease,transform .35s ease;
}
.cty__row.is-on .cty__dot{
  background:var(--glow);opacity:1;transform:scale(1.15);
  box-shadow:0 0 14px rgba(79,217,240,.75);
}
.cty__name{
  font-size:clamp(1.4rem,2.8vw,2.25rem);font-weight:800;
  letter-spacing:-.038em;line-height:1.05;
}

.ctyimg{position:relative;aspect-ratio:3/2;background:var(--vd2);border:1px solid var(--faint);overflow:hidden}
.ctyfig{
  position:absolute;inset:0;margin:0;display:grid;place-items:center;
  opacity:0;transform:scale(1.06);
  transition:opacity .55s ease,transform 1s cubic-bezier(.16,1,.3,1);
}
.ctyfig.is-on{opacity:1;transform:scale(1)}
.ctyfig img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

.pin__bar{margin-top:clamp(1.25rem,3vw,2rem);height:1px;background:var(--faint);position:relative}
.pin__bar i{
  position:absolute;left:0;top:0;height:100%;width:0;background:var(--glow);
  display:block;  /* no transition: the width is set every frame already */
}

/* narrower screens keep the list beside the photo, just scaled down */
@media (max-width:900px){
  .cty-sec{--win:clamp(240px,68vw,380px);--row:clamp(30px,8vw,44px)}
  .pin__grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(1rem,4vw,2rem)}
  .cty__row{gap:clamp(.55rem,2vw,1rem)}
  .cty__name{font-size:clamp(.8125rem,3.2vw,1.4rem);line-height:1.05}
}
/* phones: the photo runs the full width of the screen and the list sits over its left
   side, on a scrim dark enough to read the names against any of the photos */
@media (max-width:767px){
  /* the list window is as tall as the photo, which is the screen's width at 3:2, so the
     lit row in the middle of the list lands in the middle of the photo */
  .cty-sec{--win:calc(100vw / 1.5)}
  /* one cell, both in it: the photo underneath, the list on top */
  .pin__grid{grid-template-columns:minmax(0,1fr);gap:0}
  .pin__grid > *{grid-area:1/1}
  .ctyimg{margin-inline:calc(var(--gut) * -1);border-inline:0}
  /* solid black at the left, so the photo has no visible edge there, and off the shade
     quickly: only the strip the names sit on is dark, the rest of the photo is clear */
  /* the shade only has to carry the names, so it is gone a little past where they end:
     "Malaysia" finishes at 29% of the width and the gradient is clear by 34%, which
     leaves the photo itself almost entirely in view */
  .ctyimg::after{
    content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(to right,
      rgba(7,7,10,1) 0%, rgba(7,7,10,1) 12%, rgba(7,7,10,.82) 22%,
      rgba(7,7,10,.45) 28%, rgba(7,7,10,0) 34%);
  }
  /* only as wide as the longest country, plus room for the lit row's nudge right */
  .cty__window{
    position:relative;z-index:2;
    width:max-content;max-width:78%;padding-right:clamp(.5rem,1.4vw,1.1rem);
  }
  /* the shadow carries the names over the brighter parts of a photo */
  .cty__name{
    font-size:clamp(1rem,4.4vw,1.5rem);white-space:nowrap;
    text-shadow:0 1px 3px rgba(7,7,10,.95), 0 2px 16px rgba(7,7,10,.85);
  }
}

/* ================= instagram reels ================= */
/* three reels in the cards Instagram serves, side by side on desktop. on phones they
   become one strip you swipe, the next reel showing past the edge of the screen under
   a fade, with three lines underneath that follow where you are. the card's height is
   set by script, since an iframe cannot work it out for itself */
.reelsec__wrap{position:relative}
.reelstrip{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(1rem,2vw,1.75rem);
}
.reelstrip__item{position:relative;min-width:0}
.reelstrip__frame{
  display:block;width:100%;border:0;background:#fff;border-radius:4px;
  aspect-ratio:350/646;  /* only until the script sets the real height */
}
.reelsec__fade,.reelstrip__lines{display:none}

/* while a reel loads, a stand in drawn like an Instagram reel card sits over it: a header
   with a round picture, two lines for the name and a button, the tall video with the
   reel mark outlined in the middle, then the row of icons and the caption lines. its
   grey shapes pulse gently. madgicians.js adds it and fades it away once Instagram says
   the reel has drawn itself (or a few seconds after it has loaded, whichever is first) */
.reelskel{
  position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;
  background:#fff;border-radius:4px;overflow:hidden;pointer-events:none;
  transition:opacity .45s ease;
}
.reelskel.is-gone{opacity:0}
.reelskel i{display:block;background:#E9E9EB;border-radius:4px;animation:reelpulse 1.4s ease-in-out infinite}
.reelskel__head{display:flex;align-items:center;gap:10px;height:60px;padding:0 12px;flex:0 0 auto}
.reelskel__head .av{width:32px;height:32px;border-radius:50%;flex:0 0 auto}
.reelskel__who{flex:1;display:grid;gap:6px}
.reelskel__who i:nth-child(1){width:46%;height:10px}
.reelskel__who i:nth-child(2){width:30%;height:8px;animation-delay:.1s}
.reelskel__head .pill{width:76px;height:28px;border-radius:6px;flex:0 0 auto;animation-delay:.2s}
.reelskel__media{
  position:relative;flex:1 1 auto;min-height:0;display:grid;place-items:center;
  background:#F2F2F4;animation:reelpulse 1.4s ease-in-out infinite;animation-delay:.15s;
}
.reelskel__media svg{width:clamp(34px,16%,56px);height:auto;color:#C9C9CE}
.reelskel__foot{flex:0 0 auto;padding:12px 12px 16px;display:grid;gap:9px}
.reelskel__icons{display:flex;gap:14px}
.reelskel__icons i{width:22px;height:22px;border-radius:6px;animation-delay:.25s}
.reelskel__icons i:last-child{margin-left:auto}
.reelskel__foot > i:nth-of-type(1){width:36%;height:9px;animation-delay:.3s}
.reelskel__foot > i:nth-of-type(2){width:86%;height:8px;animation-delay:.35s}
.reelskel__foot > i:nth-of-type(3){width:62%;height:8px;animation-delay:.4s}
@keyframes reelpulse{0%,100%{opacity:1}50%{opacity:.45}}
@media (prefers-reduced-motion:reduce){.reelskel i,.reelskel__media{animation:none}}

@media (max-width:767px){
  /* the strip carries on past the right edge of the screen, so the next reel shows */
  .reelsec__wrap .shell{padding-right:0}
  .reelstrip{
    display:flex;gap:clamp(.75rem,3vw,1.25rem);
    overflow-x:auto;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;
    scrollbar-width:none;-ms-overflow-style:none;
    padding-right:var(--gut);
  }
  .reelstrip::-webkit-scrollbar{display:none}
  /* just under two thirds of the screen, which leaves the next reel about half shown */
  .reelstrip__item{flex:0 0 62vw;scroll-snap-align:start}
  .reelsec__fade{
    display:block;position:absolute;top:0;bottom:0;right:0;width:26vw;
    pointer-events:none;opacity:1;transition:opacity .35s ease;
    background:linear-gradient(to right, rgba(7,7,10,0) 0%, rgba(7,7,10,.7) 55%, var(--vd) 100%);
  }
  /* at the end of the strip there is nothing more to hint at, so the fade steps aside
     and the last reel is seen whole */
  .reelsec__wrap.is-end .reelsec__fade{opacity:0}
  /* the same dashes as under the rotating gallery: 32px by 4px, the lit one 50px long,
     glowing */
  /* 40px under the reels, edge to edge: the same room as between the rotating gallery
     and its dashes on phones */
  .reelstrip__lines{display:flex;justify-content:center;align-items:center;gap:.5rem;margin-top:40px}
  .reelstrip__line{
    width:32px;height:4px;border-radius:2px;background:var(--dim);opacity:.35;
    transition:width .35s cubic-bezier(.16,1,.3,1),opacity .3s ease,background .3s ease,box-shadow .3s ease;
  }
  .reelstrip__line.is-on{width:50px;background:var(--glow);opacity:1;box-shadow:0 0 12px rgba(79,217,240,.7)}
}

/* ================= in the press ================= */
/* laid out like the front page of a news site, so it reads as articles at a glance: a
   grid of cards ruled off from one another by hairlines, each with a snapshot of the
   article's page (its own masthead names the publication), the headline and a short
   summary.
   neighbouring cards share one line (each pulls back over the last by a pixel), and a row
   that is not full simply stops, the way a newspaper column does */
.artsec .seclabel{margin-bottom:clamp(1rem,2vw,1.5rem)}
.arts{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  padding:1px 0 0 1px;   /* room for the first row and column to pull back into */
}
.art{
  display:flex;flex-direction:column;
  margin:-1px 0 0 -1px;
  padding:clamp(1.1rem,1.8vw,1.6rem);
  /* --faint laid over the page's black, as a solid colour. --faint is see-through, so
     where two cards overlap their line it would draw twice and come out brighter than
     the outside edge; a solid colour looks the same however many times it is drawn */
  border:1px solid #232326;
  color:inherit;text-decoration:none;
  transition:background .3s ease;
}
/* a snapshot of the top of the article's page, so the publication's own masthead shows.
   the snapshots are taken a little taller than a screen (1280x883) so the window shows
   more of the page under the masthead, and none of it is cropped */
.art__shot{display:block;overflow:hidden;background:#0d0d12;border:1px solid #232326}
.art__shot img{
  display:block;width:100%;height:auto;aspect-ratio:1100/759;object-fit:cover;object-position:50% 0;
  transition:transform .8s cubic-bezier(.16,1,.3,1);
}
.art__title{
  margin:1rem 0 0;
  font-size:clamp(1.0625rem,1.35vw,1.25rem);font-weight:700;letter-spacing:-.01em;line-height:1.3;
  transition:color .3s ease;
}
.art__dek{display:block;margin-top:.6rem;font-size:.875rem;line-height:1.6;color:var(--dim)}
/* pushed to the foot of the card, so every card in a row ends on the same line */
.art__go{
  margin-top:auto;padding-top:1.1rem;
  font-size:.75rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--glow);
}
@media (hover:hover){
  .art:hover{background:rgba(243,242,239,.03)}
  .art:hover .art__title{color:var(--glow)}
  .art:hover .art__shot img{transform:scale(1.04)}
}
.art:focus-visible{outline:2px solid var(--glow);outline-offset:-2px}
/* the first rows show, then the start of the next one fading into the page, the same
   way Media does, and "See more" glides the rest open. a screen and a tablet show three
   rows, a phone two. madgicians.js sets the height and the fade; until it runs, and with
   no script at all, every card shows */
.arts__box{position:relative}
.arts{overflow:hidden;transition:max-height .7s cubic-bezier(.16,1,.3,1)}
.arts__box::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:var(--fade,0px);pointer-events:none;
  background:linear-gradient(to bottom,rgba(7,7,10,0),rgba(7,7,10,.75) 55%,var(--vd));
  opacity:0;transition:opacity .4s ease;
}
.arts__box.is-clipped::after{opacity:1}
.arts__more{display:flex;justify-content:center;margin-top:clamp(1.5rem,2.5vw,2rem)}
.arts__more[hidden]{display:none}
@media (max-width:1023px){
  .arts{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* phones keep two to a row, two rows before "See more". the cards are narrow here, so
   the type steps down and the summary is left out: the snapshot, the headline and
   "Read article" say enough */
@media (max-width:640px){
  .art{padding:.85rem}
  .art__title{margin-top:.75rem;font-size:.9375rem;line-height:1.3}
  .art__dek{display:none}
  .art__go{padding-top:.85rem;font-size:.625rem;letter-spacing:.12em}
}
@media (prefers-reduced-motion:reduce){
  .art,.art__title,.art__shot img,.arts,.arts__box::after{transition:none}
  .art:hover .art__shot img{transform:none}
}

/* ================= team, over a full bleed group photo ================= */
/* the panorama runs edge to edge at its own shape, so every act in it shows,
   then fades into the page with the heading and copy underneath */
/* the band gives its half of the gap above as padding: the colour behind it is the
   page's own, so the space is invisible. below it, Meet The MADgicians follows close */
.teamband{position:relative;background:var(--vd);padding-top:calc(var(--sect) / 2)}
.teamband__strip{position:relative;aspect-ratio:2400/540;overflow:hidden;background:var(--vd2)}
.teamband__strip img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.teamband__strip::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to bottom, var(--vd) 0%, rgba(7,7,10,0) 14%, rgba(7,7,10,0) 62%, var(--vd) 100%);
}
/* wide screens: the whole panorama at once, still (it fits, so there is nothing to slide).
   narrow screens (phones), where only a taller crop of it fits: the whole stage slides
   past, right to left, without end, and can be dragged or swiped either way, like the
   client logos on the homepage. madgicians.js moves the copies of the looping picture;
   the browser never scrolls the strip itself */
.teamband__loop{display:none}
@media (max-width:767px){
  .teamband__strip{aspect-ratio:16/9}
  .teamband__strip img{visibility:hidden}   /* still there for Google and screen readers */
  .teamband__loop{
    display:block;position:absolute;inset:0;overflow:hidden;
    touch-action:pan-y;      /* a sideways swipe moves the strip, up and down still scrolls the page */
    -webkit-user-select:none;user-select:none;
  }
  .teamband__track{display:flex;height:100%;width:max-content;will-change:transform}
  .teamband__track > span{
    flex:0 0 auto;height:100%;aspect-ratio:2240/540;
    background:url(../images/madgicians-premium-loop.jpg) 0 0/100% 100% no-repeat;
  }
}
/* a statement rather than a column of copy, so it is centred under the photo */
.teamband__inner{padding-block:clamp(1.25rem,3vw,2.5rem) calc(var(--sect) / 2);width:100%;text-align:center}
.teamband__inner .bigline{margin-inline:auto}
.teamband__lead{
  margin:clamp(1.5rem,2.5vw,2.25rem) auto 0;max-width:60ch;
  font-size:clamp(1rem,1.3vw,1.15rem);line-height:1.7;color:rgba(243,242,239,.86);
}
.teamband__note{
  margin:1.25rem auto 0;max-width:52ch;font-size:.9375rem;line-height:1.7;color:var(--dim);
}

/* ================= meet the madgicians ================= */
/* the homepage's Meet the Team cards, in the dark theme. it follows straight on from
   the team band above, so it starts closer than a new section would */
.mg .magicians{padding-top:calc(var(--sect) / 2)}   /* the standard gap after the team band */
.mg .card__role{color:var(--dim)}

@media (prefers-reduced-motion:reduce){
  .cty__window{scroll-behavior:auto}
  .ctyfig{transition:none}
}

/* ================= 3d gallery ================= */
.wheelsec{overflow:hidden}
/* half a section gap above the heading (40px on a screen, 30px on a phone), from the
   hero's bottom edge. the standard gap below, from the dashes to the countries (whose
   own top padding is --cty-gap, so this gives the rest) */
.mg .wheelsec{padding-top:calc(var(--sect) / 2);padding-bottom:calc(var(--sect) - var(--cty-gap))}
/* phones: the countries come 30px closer to the gallery's dashes (40px, edge to edge) */
@media (max-width:767px){.mg .wheelsec{padding-bottom:calc(var(--sect) - var(--cty-gap) - 30px)}}
/* the gap under the heading lives on this wrapper because a centred heading that ends
   a block has its own margin zeroed */
.wheelsec__head{margin-bottom:clamp(1rem,2.5vw,2.25rem)}
/* the stage photo under the heading. a full screen tall on desktop (never taller
   than the photo's own 3:2 shape), a 4:5 crop from the middle on phones so both
   performers stay in. both edges fade into the page */
.wheelsec__banner{
  position:relative;isolation:isolate;
  min-height:min(100svh, 100vw * 2 / 3);
  background:var(--vd2);
}
.wheelsec__bg{position:absolute;inset:0;z-index:-2}
.wheelsec__bg img{width:100%;height:100%;object-fit:cover;object-position:50% 60%}
.wheelsec__banner::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(to bottom,
    var(--vd) 0%, rgba(7,7,10,0) 14%, rgba(7,7,10,0) 80%, var(--vd) 100%);
}
@media (max-width:767px){
  .wheelsec__banner{min-height:0;aspect-ratio:4/5}
  /* the performers stand left of the photo's middle, so the phone crop sits a little
     left of centre to bring them to the middle of the screen */
  .wheelsec__bg img{object-position:35% 60%}
}
/* heading always sits on two lines: the box runs the full content width and the
   type scales with it. its longer half is about 21 times the font size wide */
.wheelsec .head--center{max-width:none}
.wheelsec .head--center h2{
  max-width:none;text-wrap:balance;
  font-size:min(2.75rem, (100vw - 2 * var(--gut)) / 21.5);
}
/* phones run it bigger, over three lines: a third of the sentence is about 14.5 times
   the font size wide, so 15 keeps it to three with a little room to spare */
@media (max-width:767px){
  .wheelsec .head--center h2{font-size:calc((100vw - 2 * var(--gut)) / 15)}
}
/* the panel is sized off the screen width so the side panels reach both edges,
   capped by height so the wheel still fits on screen. a tight radius keeps the
   gaps between panels narrow; the flat perspective carries them out to the edges */
.wheel{
  --panel: clamp(210px, min(44vw, 72vh), 900px);
  --tall: .86;         /* a card's height for its width: the 4:3 photo plus a strip at the foot for its title */
  --radius: calc(var(--panel) * 1.36);
  position:relative;
  /* the panels sit close under the photo: 4px on phones up to 24px on desktop. the
     stage leaves 9% of a panel of room above them, so that comes off */
  margin-top:calc(clamp(.25rem,1.2vw,1.5rem) - var(--panel) * .09);
}
.wheel__stage{
  /* trimmed to just around the panels, so the heading above and the arrows below sit
     close to them */
  perspective:calc(var(--panel) * 12);perspective-origin:50% 41%;
  height:calc(var(--panel) * var(--tall) * 1.24);
  display:grid;place-items:center;
}
.wheel__spin{
  position:relative;width:var(--panel);height:calc(var(--panel) * var(--tall));
  transform-style:preserve-3d;
  transform:translateZ(calc(var(--radius) * -1)) rotateY(0deg);
  will-change:transform;
}
.wheel__face{
  position:absolute;inset:0;
  transform-style:preserve-3d;
  backface-visibility:hidden;
}
.wheel__card{
  position:relative;width:100%;height:100%;overflow:hidden;
  background:var(--vd2);border:1px solid var(--faint);
  display:grid;place-items:center;
  box-shadow:0 30px 60px rgba(0,0,0,.55);
}
/* the photo keeps its 4:3 at the top of the card; under it the card runs on a little
   in near black, and a gradient carries the photo down into it, so the title at the foot
   reads clearly while sitting in the picture */
.wheel__card{background:#07070A}
.wheel__card img{position:absolute;top:0;left:0;width:100%;height:calc(.75 / var(--tall) * 100%);object-fit:cover}
/* the title and its gradient are one element laid over the foot of the card, so the
   card needs no layers of its own (a stacking layer inside a 3D panel makes Safari draw
   the panels in the wrong order) */
.wheel__title{
  position:absolute;left:0;right:0;bottom:0;height:44%;
  display:flex;align-items:flex-end;justify-content:center;
  padding:0 1rem calc(var(--panel) * .04);text-align:center;color:var(--inv);
  font-size:clamp(.95rem,calc(var(--panel) * .05),2.25rem);font-weight:700;letter-spacing:-.02em;line-height:1.1;
  text-shadow:0 2px 14px rgba(0,0,0,.5);
  background:linear-gradient(to top,#07070A 0%,rgba(7,7,10,.92) 32%,rgba(7,7,10,.45) 62%,rgba(7,7,10,0) 100%);
}
.wheel__face::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:rgba(7,7,10,var(--shade,.55));
}
.wheel__card{box-shadow:0 30px 70px rgba(0,0,0,.6)}


/* the dashes under the wheel: one per card, the front one lit. there are no arrows */
.wheel__dots{
  display:flex;justify-content:center;align-items:center;gap:.5rem;
  /* the dashes sit 60px under the front card, at every screen size. the 3D stage keeps a
     band of empty room below the cards (12% of a card's height), so they are pulled up by
     that and put back down 60px (48 to the top of the button, whose dash is 12 down) */
  margin-top:calc(var(--panel) * var(--tall) * -.12 + 48px);
}
/* phones: 40px under the front card, edge to edge, the same as the reels' dashes */
@media (max-width:767px){
  .wheel__dots{margin-top:calc(var(--panel) * var(--tall) * -.12 + 30px)}
}
/* each is a dash, the lit one longer and glowing. the button itself is taller than the
   dash, so it is easy to tap */
.wheel__dot{
  position:relative;width:32px;height:24px;padding:0;border:0;background:none;cursor:pointer;
  transition:width .35s cubic-bezier(.16,1,.3,1);
}
.wheel__dot::before{
  content:"";position:absolute;left:0;right:0;top:50%;height:4px;margin-top:-2px;border-radius:2px;
  background:var(--dim);opacity:.35;
  transition:opacity .3s ease,background .3s ease,box-shadow .3s ease;
}
.wheel__dot.is-on{width:50px}
.wheel__dot.is-on::before{background:var(--glow);opacity:1;box-shadow:0 0 12px rgba(79,217,240,.7)}
.wheel.is-dragging{cursor:grabbing}
.wheel{cursor:grab;touch-action:pan-y}   /* a sideways swipe spins it, up and down still scrolls the page */

@media (max-width:640px){
  .wheel{--panel:clamp(180px,56vw,260px);--radius:calc(var(--panel) * 1.34)}
  .wheel__stage{perspective:1200px}
}

@media (prefers-reduced-motion:reduce){
  .wheel__spin{transition:none}
}

/* ================= phones: spacing ================= */
/* a phone shows one section at a time, so the gaps do not have to be a screen's worth,
   but they do have to be legible as gaps: about 60px between any two sections, the
   enquiry form and the footer included. the few tight boundaries keep a bigger share of
   that here than they do on a screen, since at this width they were reading as crowding
   rather than as two things belonging together */
@media (max-width:767px){
  .mg{--sect:clamp(3.75rem,15vw,5.5rem);--close:calc(var(--sect) / 2.4)}
  .foot--dark .foot__grid{gap:1.75rem}
  .foot--dark .map{margin-top:.5rem}
}
