/*
 * Our colour, in the template's own tokens.
 *
 * Linked after main.css rather than imported with the overrides, because the
 * bundled stylesheet lands in <head> before the linked ones and would lose
 * every one of these to the template's defaults.
 *
 * The template's accent is #002bba, a deep blue, and it sets white on top of
 * it. Ours is #C1FF72 — a pale volt green that white is illegible on. So this
 * is not a one-line swap: the accent changes and the ink that sits on it
 * changes with it, which is the pairing the product has used all along
 * (`bg-[#C1FF72] text-zinc-950`).
 */

:root,
:root[color-scheme="light"],
:root[color-scheme="dark"] {
  /* The brand green, in both schemes. It is light enough to work on either. */
  --accent--light: #c1ff72;
  --accent--dark: #c1ff72;

  /*
   * What is written on the accent.
   *
   * White on volt is roughly 1.3:1 — invisible. Near-black is about 15:1 and
   * is what every accent surface in the product already uses.
   */
  --pt-t-accent-bright: #09090b;
  --pt-t-accent-medium: #27272a;
  --pt-t-accent-muted: #3f3f46;
}

/*
 * The hero's sentence is a paragraph here, not a five-word statement.
 *
 * The template pairs a short name ("Solei") with one large line under it, so
 * neither has a width: the title block grows to whatever it holds and ran to
 * 2547px against a 1440 viewport. A five-word line never noticed. Our copy is
 * the sentence each medium page opens with, which simply ran off the screen.
 *
 * So the sentence gets a measure and a size of its own. The headline above it
 * keeps the template's scale, because that is the part of the design doing the
 * shouting.
 */
.mxd-hero-04__descr {
  max-width: min(86vw, 46ch);
  /*
   * Room under the headline.
   *
   * Measured, the sentence sat 8px below it on a wide screen — close enough
   * that the two read as one block and the headline lost its own weight. The
   * template never needed the gap because its hero name is one short word on
   * one line; ours is two lines of something very large.
   *
   * Padding rather than margin. The headline carries a `margin-bottom` of its
   * own — 23px on a phone — and adjacent vertical margins collapse to the
   * larger of the two, so a `margin-top` of 18px changed the gap by nothing
   * at all there. Padding is additive at every width.
   */
  padding-top: 1.6rem;
}

.mxd-hero-04__descr p {
  font-size: clamp(15px, 1.45vw, 20px);
  line-height: 1.45;
}

/*
 * The headline stops where the rectangle starts.
 *
 * Only on the first slide, which is the only one with a rectangle, and only
 * at the width where that rectangle exists. Below 1200px there is none, and
 * holding the headline to 76% there cost it a line for nothing: at 390px
 * "Imagine it." broke after "Imagine".
 */
@media only screen and (min-width: 1200px) {
  .mxd-hero-04__slide:first-child .mxd-hero-04__title {
    max-width: 76%;
  }
}

/*
 * The headline sits on two lines, the way every medium page sets it.
 *
 * "Imagine it. / Make it." — /make/videos, /make/stories and /make/games all
 * break between the two halves, and the break is doing work: the accent half
 * is the payoff and wants its own line. The template's name is one short word
 * ("Solei"), so it never needed one.
 *
 * It also has to fit. On the first slide the rectangle takes the right fifth,
 * and a single line of this length ran underneath it — the words disappearing
 * behind the colour rather than stopping at it.
 */
.mxd-hero-04__name p span,
.mxd-hero-04__name h1 span {
  /* `h1` as well as `p`: the first slide's headline is the page's one h1 and
     the other two are paragraphs, so a rule written for the template's markup
     alone missed the only slide that has a headline long enough to need the
     break. "Imagine it. Make it." ran on one line and the last two words went
     under the rectangle. */
  display: block;
}

/*
 * The headline sits on a photograph, so it is set in white.
 *
 * The template's hero name takes the page ink, which is near-black, because
 * in the template this block carries a project title over art chosen to suit
 * it. Ours is a full-bleed picture that changes every few seconds, and
 * near-black on any of them was unreadable — measured on the plate this
 * replaced, the dark half of the headline sat on a pale sky and the volt half
 * sat on sunlit green.
 *
 * White with a soft shadow reads on all three, and the shadow is what makes
 * it survive a picture that turns out lighter than planned.
 */
.mxd-hero-04__name h1,
.mxd-hero-04__name p {
  color: var(--nl-white, #ffffff);
  text-shadow: 0 2px 30px rgba(15, 15, 15, 0.45);
}

.mxd-hero-04__descr p,
.mxd-hero-04__caption p {
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 18px rgba(15, 15, 15, 0.5);
}

/*
 * The scrim the block ships does almost nothing.
 *
 * `rgba(black, .4)` at `mix-blend-mode: soft-light` deepens the midtones a
 * little and leaves the highlights where they were, which is fine over the
 * template's own art and not enough under type. This puts a real gradient
 * under the words — heaviest at the bottom left, where the headline is, and
 * clear at the top right, where the picture is doing its work.
 */
.mxd-hero-04__cover {
  background-color: transparent;
  background-image:
    linear-gradient(to top, rgba(12, 12, 14, 0.82) 0%, rgba(12, 12, 14, 0.34) 38%, rgba(12, 12, 14, 0) 68%),
    linear-gradient(to right, rgba(12, 12, 14, 0.62) 0%, rgba(12, 12, 14, 0.12) 45%, rgba(12, 12, 14, 0) 72%);
  mix-blend-mode: normal;
}



/*
 * The plate: the picture and the rectangle as one moving thing.
 *
 * It fills the media box and carries GSAP's transform, so the rectangle scales
 * and drifts exactly as it would if it had been painted into the file — which
 * is what the template actually does. Bolted on outside, it stays pinned to
 * the slide while the picture parallaxes underneath, and the two come apart.
 */
/*
 * The slider track is as wide as it has slides.
 *
 * The block hardcodes `width: 300%` on the track and `flex: 1` on each slide,
 * because the template ships exactly three. Add a fourth and the four share
 * the same 300%: measured at a 1600px viewport, each slide came out 1200px
 * wide, so slide one showed with a quarter of slide two beside it and the
 * volt band landed in the middle of the screen.
 *
 * The count comes from the component, which is the only place that knows it.
 */
.mxd-hero-04__slides {
  width: calc(100% * var(--zc-hero-slides, 3));
}

.zc-hero-plate {
  position: absolute;
  inset: 0;
  will-change: transform;
}

.zc-hero-plate > video,
.zc-hero-plate > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * Wider than it looks. The plate stands at scale 1.25 and slides ±25% of the
 * viewport as you scroll, so a band cut to the width you want on screen walks
 * off the edge halfway through the transition. This one is cut to survive the
 * travel; the media box clips the rest.
 */
.zc-hero-band {
  position: absolute;
  top: -10%;
  right: -6%;
  bottom: -10%;
  /*
   * Cut so its edge lands under the start of "Get started" in the header.
   *
   * Not a flat percentage: the header's controls sit a fixed distance in from
   * the right, so that word moves 40px further out between a 1440 and a 1920
   * window while a percentage band moves 120px. At 38% it overshot the word by
   * 61px on a wide screen and fell 31px short on a narrow one.
   *
   * The plate stands at scale 1.25 about its centre, and the algebra falls out
   * neatly: the band's left edge lands at `viewport - 1.25 x (the fixed part)`,
   * whatever the viewport. So 336px puts it 420px in from the right at every
   * width, and the middle of the rectangle is always 210px in.
   */
  width: calc(16% + 336px);
  background-color: var(--accent);
}

/*
 * The picture slides left inside its own plate, so the subject clears the band.
 *
 * object-position could not do this. The source is 1920x1200 against a box of
 * roughly 1440x950, so `cover` only has about 80px of horizontal slack to pan
 * within — and the character needed about twice that to get out from under the
 * band's edge, where she was being cut down the middle.
 *
 * Widening the picture and pulling it left moves the content properly. It
 * leaves the right of the plate bare, which costs nothing: that is exactly the
 * strip the band is sitting on.
 */
.mxd-hero-04__slide:first-child .zc-hero-plate > video,
.mxd-hero-04__slide:first-child .zc-hero-plate > img {
  /*
   * A transform, because width will not do it.
   *
   * `width: 118%` was ignored, and so were left/right offsets: a video is a
   * replaced element, and for an absolutely positioned one the spec resolves
   * `width: auto` from the intrinsic size and drops `right` as
   * over-constrained. It stayed 1440 either way. A transform has no such
   * argument with the layout.
   *
   * Scaled up so the crop has something to take from, then pushed left so the
   * character clears the band's edge instead of being cut down the middle. The
   * bare strip it leaves on the right is exactly where the band sits.
   */
  transform: scale(1.12) translateX(-14%);
  /* Anchored right so the zoom grows leftward. Scaling from the centre pushed
     everything right of it further right — the character moved *towards* the
     band as the picture got bigger, which is the opposite of the intent. */
  transform-origin: right center;
}

/*
 * Everything on the right sits in the middle of the rectangle.
 *
 * The header's buttons, the scroll prompt and the arrow were each positioned
 * against the edge of the screen, which is where the template put them because
 * the template has nothing there to line up with. With a rectangle behind them
 * they need to line up with it, or they read as three things that happen to be
 * near each other.
 *
 * Fixed offsets rather than percentages, because all four of these are pinned a
 * constant distance from the right edge — the rectangle by the algebra above,
 * the rest by their own padding — so the gaps do not change with the viewport.
 *
 * Only where there is a rectangle. Written unbounded these reached the phone,
 * where the burger ended up 27px from the right edge against the logo's 30px
 * on the left: three pixels of disagreement in aid of a band that is not on
 * screen. Below 1200 the template's own insets are right and are left alone.
 */
@media (min-width: 1200px) {
  .mxd-header__controls {
    transform: translateX(73px);
  }

  .mxd-menu__contain {
    /* The burger is fixed and is not in the header's flow, so it moves by the
       same amount separately or the cluster comes apart. */
    right: 27px;
  }
}

.mxd-hero-04__right {
  transform: translateX(-8px);
}

.mxd-hero-04__arrow {
  transform: translateX(-3px);
}

/*
 * Bounded at both ends, not just the top.
 *
 * Everything in here exists to line the header up with the volt band, and
 * the band stops below 1200px. Left open at the bottom it reached the phone
 * too, which is how the burger came to sit 20px from the right edge there
 * while the logo sat 30px from the left — the two ends of the header not
 * agreeing, for the sake of a rectangle that is not on screen.
 */
@media (min-width: 1200px) and (max-width: 1599px) {
  /*
   * The same centring, corrected for a narrower window.
   *
   * The rectangle holds its 420px at every width — that is the algebra above —
   * but the template's own paddings do not: the hero controls and the header
   * both tuck in closer to the edge below 1600px, so the three groups drifted
   * 20 to 53px right of the middle. Measured at 1440 and taken back out.
   */
  .mxd-header__controls {
    transform: translateX(53px);
  }
  .mxd-menu__contain {
    /*
     * 20px, not 47.
     *
     * The controls' shift and the burger's inset were tuned separately and
     * together they met: measured at every width from 1200 to 1599 the gap
     * between the end of "Get started" and the start of the burger was
     * exactly -5px, with the top bar crossing the D. Moving the icon out
     * rather than pulling the caption in, because the caption is the thing
     * being centred on the band and the icon is not. The gap is 22px now,
     * against 35px above 1600.
     */
    right: 20px;
  }
  .mxd-hero-04__right {
    transform: translateX(-48px);
  }
  .mxd-hero-04__arrow {
    transform: translateX(-56px);
  }
}

@media (max-width: 1199px) {
  /*
   * No rectangle below 1200px, and nothing shifted towards one.
   *
   * The band's width has a fixed 336px term, which the algebra above needs so
   * its edge lands under "Get started" at any width. What that does not
   * survive is a narrow window: the effective width is 420px at every size,
   * so the band is 26% of a 1600px screen, 41% of a 1024px one and most of a
   * phone. Measured at 1024 it ran from 604 to the right edge and left the
   * scroll cue floating in the middle of an empty green field.
   *
   * The shifts go with it. They exist to centre the header controls and the
   * cue on the band; with no band they only pushed "Get started" into the
   * burger, which is what it was doing at 1024.
   */
  .zc-hero-band {
    display: none;
  }
  .mxd-header__controls,
  .mxd-hero-04__right,
  .mxd-hero-04__arrow {
    transform: none;
  }
  .mxd-hero-04__slide:first-child .zc-hero-plate > video,
  .mxd-hero-04__slide:first-child .zc-hero-plate > img {
    transform: none;
  }
}

/*
 * The burger goes back to the corner on a phone.
 *
 * It was pinned 100px in from the right edge, which put it in the middle of
 * the header with a hand's width of empty space beyond it — measured at 390,
 * 430 and 360, always 100px from the edge while the logo sat 30px from the
 * other one. The two ends of the header did not agree.
 *
 * That value came from an older layout and was never right here. The
 * template's own base is `right: 3rem`, which mirrors the logo's inset
 * exactly, so the override is simply gone rather than replaced.
 */

/*
 * The parallax divider shows one of ours.
 *
 * Its picture comes from a background on `.divider-image-4`, not from the
 * component — which is why it kept 404ing after every other asset had been
 * swapped: there was nothing in the JSX to change. The theme does ship the
 * file; it is just somebody else's photograph of somebody else's work.
 */
.mxd-divider__image.divider-image-4 {
  background-image: url("/marketing/home/closing.jpg");
}

/*
 * The audience card's colour and its cut-out.
 *
 * The template's niche card is a flat page-tint panel with a photograph in
 * it. Ours is the audience's own wash — the three stops the live site paints
 * that card with — and the picture is the cut-out its page leads with, which
 * is drawn to its own edges and cannot be cropped to fill a box.
 */
#audiences .zc-niche {
  background-image: linear-gradient(
    to bottom right,
    var(--zc-tint-from, #f4f4f5),
    var(--zc-tint-via, #fafafa),
    var(--zc-tint-to, #f4f4f5)
  );
  /* The whole card is an anchor now, and an anchor brings its own ink. */
  color: inherit;
  text-decoration: none;
}

@media only screen and (min-width: 1200px) {
  /*
   * `absolute-desktop-full` covers the panel, which crops whatever it is
   * given. That is right for a photograph of an office and wrong for a person
   * cut out of one: it took the top off their head. Contained and set to the
   * corner, the figure stands in the right of the card with the words clear
   * on the left.
   */
  #audiences .zc-niche__image.absolute-desktop-full img {
    object-fit: contain;
    object-position: right bottom;
  }
}

@media only screen and (min-width: 1200px) {
  /*
   * The thumbnail at the template's size, kept inside the panel.
   *
   * It hangs it off the right edge at `right: -8rem` and lets the panel clip
   * what overflows, which reads as an illustration carrying on past the
   * frame. Ours is a person, and the frame was taking their arm off — so the
   * width the template gives it stands, and only the offset changes.
   */
  #audiences .zc-niche__image.absolute-desktop-aside {
    right: 1.5rem;
    bottom: 0;
    /*
     * The figure, not the box around it. The template keeps 3rem of padding
     * each side of this slot, so a 200px slot drew a 140px person; with the
     * padding gone the width declared here is the width that shows.
     */
    padding: 0;
    width: 200px;
  }

  /*
   * The template's height as a floor, not a ceiling.
   *
   * `fixed-height-desktop` is an exact 420px, and at the narrow end of the
   * desktop range the measure left beside the thumbnail is about 170px, which
   * is enough lines to run off the bottom of that. Everything above 1400px
   * still comes out at exactly the height the template sets.
   */
  #audiences .zc-niche--aside.fixed-height-desktop {
    /* 100%, not auto: the two of these sit side by side and a panel that
       stops at its own content no longer matches the one next to it. */
    height: 100%;
    min-height: 420px;
  }

  /*
   * And the sentence keeps out of its way.
   *
   * The template gives this card's description 300px, which works when most
   * of the thumbnail is outside the panel. Held inside, it stands where those
   * last two lines were, so the measure narrows to what is left beside it.
   */
  #audiences .zc-niche--aside .mxd-niche-cards__descr.short {
    max-width: 125px;
  }
}

@media only screen and (min-width: 1600px) {
  #audiences .zc-niche__image.absolute-desktop-aside {
    width: 260px;
  }

  #audiences .zc-niche--aside.fixed-height-desktop {
    min-height: 500px;
  }

  #audiences .zc-niche--aside .mxd-niche-cards__descr.short {
    max-width: 150px;
  }
}

@media only screen and (min-width: 1200px) {
  /*
   * The teacher, a little further in.
   *
   * Her cut-out carries the water cycle she has just made off to her right,
   * so the figure herself sits left of centre in the file and reads as
   * further from the words than the others do. The sentence gives up the
   * width the picture takes.
   */
  #audiences .zc-niche--teachers .zc-niche__image.absolute-desktop-aside {
    right: 3.5rem;
  }

  #audiences .zc-niche--teachers .mxd-niche-cards__descr.short {
    max-width: 105px;
  }
}

@media only screen and (min-width: 1600px) {
  #audiences .zc-niche--teachers .mxd-niche-cards__descr.short {
    max-width: 130px;
  }
}

/*
 * The clip fills the tile the template sized.
 *
 * `.marquee__item.item-imageblock` is 200px wide and 300px from 768 up, and
 * `.marquee__image img` is `width: 100%; height: auto`. A <video> has to be
 * told the same, and so does the wrapper the clip component puts around it,
 * or the box lays out at the file's own size and the row stops being a row.
 */
#shelf-marquee .marquee__image {
  /* The tile states its height; the clip fills it and is cropped to fit. */
  width: 100%;
}

#shelf-marquee .zc-reel__media {
  display: block;
  width: 100%;
  height: 100%;
}

#shelf-marquee .zc-reel__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}



/*
 * A section that scrolls over a pinned one needs its own ground.
 *
 * `PinnedSection` pins with `pinSpacing: false`, so the pinned section is
 * taken out of the flow, fixed to the viewport, and faded and shrunk while
 * whatever follows rides up over it. That is the effect, and it only reads as
 * one if the thing riding over is opaque: every section on this page is
 * transparent by default, so the block underneath stayed legible through it
 * and two sets of words scrolled across each other.
 *
 * Applied to the three sections that follow a pinned one rather than to all
 * of them, because the two that paint their own ground — the cast panel and
 * the process band — must keep it.
 */
.zc-over-pin {
  position: relative;
  z-index: 1;
  background-color: var(--base);
}

/*
 * The figures on a dark ground.
 *
 * This block sits directly under the pinned grid, and the two of them ran as
 * one long pale stretch. Dark, it reads as the pause it is: the grid stops,
 * the numbers state what comes out of it, and the page goes back to light for
 * "who it is for".
 *
 * The block has no dark variant of its own — it is drawn for the page ground
 * — so its parts are given the opposite ink the template already carries.
 * `bg-color-opposite` cannot do the work here: it and `.zc-over-pin` are both
 * single classes, and brand.css is the later sheet, so the light ground would
 * win. The id settles it.
 */
#what-you-get {
  background-color: var(--base-opp);
}

#what-you-get .title-number,
#what-you-get .manifest,
#what-you-get .mxd-stats-lines__number p {
  color: var(--t-opp-bright);
}

#what-you-get .manifest span,
#what-you-get .mxd-stats-lines__caption p {
  color: var(--t-opp-medium);
}

/* The hairline each figure rises from behind. */
#what-you-get .mxd-stats-lines__divider {
  background-color: var(--t-opp-muted);
}

/*
 * No missing backdrop behind the loop.
 *
 * `.mxd-hero-09` names `img/hero/1920x1200_h02.webp`, which the package does
 * not ship — h01 and h02 are both absent from the files it came with, so the
 * block 404s on sight. Ours runs a video across that whole area anyway, so
 * there is nothing for a backdrop to do but fail to load.
 *
 * Every use of the block, not just the first: /make/games opens on hero-09 and
 * hit the same 404 on sight.
 */
.mxd-hero-09 {
  background-image: none;
}

/*
 * A light scrim on the games hero, because the picture does the work now.
 *
 * It was heavy — half black plus a strong angled gradient — back when the
 * background was a lit night street and the headline band measured luma 80
 * against the theme's 28. The three plates that play there now are composed
 * dark on the left and lit on the right, so the legibility is in the picture
 * and the cover only has to settle it.
 *
 * Which matters, because these were generated to be vivid: at the old weight
 * the coral and the fish went to mud, and a page arguing that a game made here
 * looks good should not open on a muddy one. The angle stays — weight where
 * the type is, nothing where the reef is.
 */
#games-hero .mxd-hero-09__cover {
  background-color: rgba(0, 0, 0, 0.3);
  background-image: linear-gradient(
    105deg,
    rgba(0, 0, 0, 0.42) 0%,
    rgba(0, 0, 0, 0.18) 45%,
    rgba(0, 0, 0, 0) 78%
  );
}

/*
 * The headline, which is an h2 here.
 *
 * Every rule the block writes for this slot names `h1` — the size, the face,
 * the white it needs to sit on a video. This page already has its h1 in the
 * hero, and a second one for a mid-page section is the wrong outline, so the
 * h2 is given the same treatment rather than the heading being promoted to
 * suit a stylesheet.
 */
#cast .mxd-hero-09__headline h2 {
  /*
   * 9cqw, not the block's 13. That size is cut for "Alex Walker" — eleven
   * characters — and the rule sets `white-space: nowrap`, so "Your character."
   * at fifteen ran off the right edge at the size it inherited.
   */
  font-size: clamp(1.6rem, 9cqw, 27rem);
  line-height: 0.746;
  font-style: normal;
  font-weight: 500;
  font-family: var(--_font-accent);
  text-transform: uppercase;
  letter-spacing: -0.2cqw;
  color: var(--nl-white);
  white-space: nowrap;
}

@media only screen and (min-width: 1200px) {
  #cast .mxd-hero-09__headline h2 {
    font-size: clamp(1.6rem, 9.7cqw, 27rem);
  }
}

/*
 * A clip in the card's picture slot.
 *
 * The block styles `img` there: fill the width, height from the file, and sit
 * at scale(1.08) so the panel's clip-path crops it until the pointer arrives
 * and it settles back to 1. A <video> gets none of that by selector, and
 * neither does the wrapper the clip component puts around it, so the card
 * laid out at the file's own size and never moved on hover.
 */
#cast .zc-shot {
  display: block;
  width: 100%;
}

/*
 * The shape of the box a clip is cropped to.
 *
 * `wide` is the ratio it was filmed in and crops nothing. The other two exist
 * to give the row the uneven edge the block is drawn for, since every frame
 * of a character this product makes is 16:9.
 */
#cast .zc-shot--square .zc-shot,
#cast .zc-shot--tall .zc-shot {
  height: 100%;
}

#cast .zc-shot--square {
  aspect-ratio: 1;
}

#cast .zc-shot--tall {
  /* The shot in this slot is made at 9:16, so the box is 9:16 and the frame
     is shown whole rather than cropped to fit a shape it was not filmed in. */
  aspect-ratio: 9 / 16;
}

#cast .zc-shot--square .zc-shot__video,
#cast .zc-shot--tall .zc-shot__video {
  height: 100%;
  object-fit: cover;
}

#cast .zc-shot__video {
  display: block;
  width: 100%;
  height: auto;
  transform: scale(1.08);
  transform-origin: top center;
  will-change: transform;
  transition: transform var(--_animspeed-medium);
}

.no-touch #cast .mxd-blog-item:hover .zc-shot__video {
  transform: scale(1);
}

/*
 * The word sits under the row, not a screen below it.
 *
 * `about-mission-text` carries a 15.5rem top margin — 12.3 on a phone, more
 * again past 1600 — because on the page it comes from it closes a section
 * that has nothing else in it. Here it follows four cards and that margin
 * left a blank screen between them and it.
 */
/*
 * Up into the white the stagger leaves, box and all.
 *
 * The word's ink runs from x39 to x517, under the first card and the left of
 * the second. Those two end well above the tall third, so there is a band of
 * empty page beside it for the word to sit in.
 *
 * The pull goes on `.about-mission`, not on the text inside it. That element
 * is `overflow: hidden` — the block's own reveal depends on it — so moving
 * only the text lifted the glyphs out of the box that clips them and cut them
 * in half. Moving the block moves the clip with it.
 *
 * The margin comes back on the bottom because a negative top margin shortens
 * the parent as well, and the word ended up hanging past the section's edge,
 * where the next section paints its own ground straight over it.
 */
#cast .about-mission {
  margin-top: -9rem;
  margin-bottom: 8rem;
  /* `bottom-text` nudges the wrap down 0.4rem, which put the baseline that
     far past the clip box; the box gets it back. */
  padding-bottom: 1rem;
}

#cast .about-mission-text {
  margin-top: 0;
}

/*
 * The photograph, laid over the scene it ends up in.
 *
 * Top left, small, labelled — so the card reads as the two halves of one
 * claim rather than a picture with a caption. Above the card's cover, which
 * the stack fades across the media, or it would disappear with it.
 */
.zc-card-inset {
  position: absolute;
  left: 1.6rem;
  top: 1.6rem;
  z-index: 3;
  width: 34%;
  max-width: 190px;
  margin: 0;
  overflow: hidden;
  border-radius: 0.6rem;
  box-shadow: 0 1.2rem 3rem -1.4rem rgba(9, 9, 11, 0.8);
}

.zc-card-inset img {
  display: block;
  width: 100%;
  height: auto;
}

.zc-card-inset figcaption {
  padding: 0.6rem 0.8rem;
  background: rgba(9, 9, 11, 0.82);
  font: normal 500 1rem/1.2 var(--_font-accent);
  letter-spacing: 0.06rem;
  text-transform: uppercase;
  color: #ffffff;
}

@media only screen and (min-width: 1200px) {
  .zc-card-inset {
    left: 2.4rem;
    top: 2.4rem;
  }
}

/*
 * Black behind the face and voice cards.
 *
 * `zc-over-pin` gives every section that rides over a pinned one the page
 * ground, #eeeae8, so it can cover what is fading underneath. This one wants
 * plain white instead — the cards on it are near-black, and the extra step
 * between them and the page makes them read as objects on a sheet rather than
 * panels on a wall. It still needs the covering ground, so this overrides the
 * colour and leaves the stacking alone.
 */
#face-voice,
#face-voice .mxd-stack-cards.opposite {
  background-color: #000000;
}

/*
 * The marquee behind the cards is a watermark, not text to read.
 *
 * The block sets it a few percent off its own ground — #191a1d on #0f0f0f.
 * Against true black it needs the same small step, or the words that were a
 * texture either vanish entirely or become the loudest thing in the section.
 */
#face-voice .card__marquees .marquee__text {
  color: #121316;
}


/*
 * The cursor's disc goes behind its picture, not over it.
 *
 * `.mxd-cursor__dot` is z-index 3 and `.mxd-cursor__image` is 1, so on
 * anything carrying both — every row of the projects archive — the disc
 * punched a circle out of the middle of the thumbnail. The disc is meant as a
 * backdrop: an element asking for `active-cursor-image` rather than
 * `-image-tr` is saying it wants one. Behind the picture it does that job and
 * still sits under the caption, which is z-index 4.
 */
.mxd-cursor:has(.mxd-cursor__image.show) .mxd-cursor__dot {
  z-index: 0;
}

/*
 * The capabilities list keeps the ground the block is drawn for.
 *
 * It was on the brand volt, which meant overriding the number, the tags, the
 * hairlines and the muted half of every sentence — each of them a grey cut
 * for off-white that turns to mud on green. On the page's own ground none of
 * that is needed and the block looks like itself.
 */

/*
 * A clip in the capabilities row's picture column.
 *
 * The block styles an `img` there — fill the width, height from the file. A
 * <video> gets none of that by selector, and neither does the wrapper the
 * clip component puts around it, so the row laid out at the file's own size.
 */
#process .zc-medium-clip {
  display: block;
  width: 100%;
}

#process .zc-medium-clip__video {
  display: block;
  width: 100%;
  height: auto;
}

/*
 * The footer wordmark, sized by its own length.
 *
 * The theme sets `.fw-mark__content` to 28cqw with `white-space: nowrap` on
 * the span. 28cqw is the size at which "Azurio" — six characters — fills the
 * container exactly, so the number is really a measurement of that one word.
 * "Zing Canvas" is eleven, ran off the right edge, and read "ZING CA".
 *
 * So the constant is restated as what it always was: a per-character width,
 * divided by however many characters the mark actually has. The component
 * passes the count. Rename the product and the mark still fits.
 */
.mxd-footer .fw-mark__content {
  font-size: calc(166cqw / var(--zc-mark-chars, 6));
}

@media only screen and (min-width: 992px) {
  .mxd-footer .fw-mark__content {
    font-size: calc(166cqw / var(--zc-mark-chars, 6));
  }
}

/*
 * The right-hand half of the footer's nav block.
 *
 * The theme fills it with a numbered list of social profiles, which have their
 * own dividers and spacing. Ours holds a form and an address, so the
 * spacing is stated here rather than inherited from a list that is not there.
 */
/*
 * The form at the top, the address at the bottom.
 *
 * The link columns opposite are two groups tall; this half is a form and one
 * line, so packed to the top it left the lower two thirds of the column empty
 * and the footer looked like it had been laid out in a hurry. Pushing the
 * address down puts a baseline under both halves.
 */
.zc-footer-aside {
  display: flex;
  flex-direction: column;
  gap: 4rem;
  width: 100%;
  min-height: 100%;
}

.zc-subscribe__label {
  display: block;
  margin-bottom: 1.2rem;
  max-width: 44rem;
  color: var(--t-medium);
  font: normal 400 1.6rem/1.5 var(--_font-accent);
}

/* The field and its button share a baseline: the theme's input is underlined,
   so a button sitting below it would leave the rule hanging in mid-air. */
.zc-subscribe__row {
  display: flex;
  align-items: flex-end;
  gap: 1.6rem;
}

.zc-subscribe__row input {
  flex: 1 1 auto;
  min-width: 0;
}

.zc-subscribe__row .btn {
  flex: 0 0 auto;
}

/* The honeypot field: present in the DOM, absent from the page. */
.zc-subscribe__hp {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.zc-subscribe__error {
  margin: 1rem 0 0;
  color: var(--t-bright);
  font: normal 400 1.4rem/1.4 var(--_font-accent);
}

.zc-subscribe__reply {
  min-height: 5.8rem;
  display: flex;
  align-items: center;
}

.zc-footer-aside__contact {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: auto;
}

/* On a phone the button under the field is the only thing that fits. */
@media only screen and (max-width: 767px) {
  .zc-subscribe__row {
    flex-direction: column;
    align-items: stretch;
  }
  .zc-subscribe__row .btn {
    justify-content: center;
  }
}

/*
 * The logo, and the band at the top of the footer it now occupies.
 *
 * The theme opens its v2 footer with 17.4rem of empty ground above the link
 * columns — room the design wants, but room that was holding nothing. The mark
 * goes there, and nav02 and the half opposite give back the space it takes, so
 * the footer starts where it always did rather than growing by the height of a
 * logo.
 */
.zc-footer-logo {
  padding-top: 8rem;
  padding-bottom: 3.4rem;
}

.zc-footer-logo__link {
  display: inline-flex;
  line-height: 0;
}

/* Height, and the width follows the file's own 460:120 — so the lockup can
   never be squashed by a number typed here going stale. */
.zc-footer-logo__image {
  display: block;
  width: auto;
  height: 5.2rem;
}

@media only screen and (max-width: 767px) {
  .zc-footer-logo__image {
    height: 4.4rem;
  }
}

.mxd-footer .mxd-footer__nav02,
.mxd-footer .mxd-footer__socials-list {
  padding-top: 0;
}

@media only screen and (max-width: 1199px) {
  .zc-footer-logo {
    padding-top: 6rem;
  }
  /* Below xl the two halves stack, so the lower one needs its own space back. */
  .mxd-footer .mxd-footer__socials-list {
    padding-top: 4.6rem;
  }
}

/* The column the aside sits in is a flex item of the row; without this the
   aside has no height to distribute and `margin-top: auto` does nothing. */
.mxd-footer .mxd-footer__socials-list {
  display: flex;
  height: 100%;
}

/*
 * The full-bleed band on /make/videos, holding a clip.
 *
 * The theme's divider is a fixed-height box with a background image on a
 * child. A <video> is not a background, so it is laid over the box and told to
 * cover it — the box keeps its own height at every breakpoint, which is what
 * makes the band the same shape here as everywhere else in the template.
 */
.zc-divider-clip {
  position: relative;
}

.zc-divider-clip__host,
.zc-divider-clip .zc-divider-clip__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/*
 * The button and the jump link in the headline's last column.
 *
 * The theme puts one control there and lets it sit on its own baseline. Two
 * need a gap and an edge to line up on, and on desktop that edge is the right
 * one, matching `align-end-desktop` on the same element.
 */
.zc-headline-actions {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  align-items: flex-start;
}

@media only screen and (min-width: 1200px) {
  .zc-headline-actions {
    align-items: flex-end;
  }
}

/*
 * A sentence in the slot the theme keeps for a word.
 *
 * `h1.large` is `white-space: nowrap` from 768px up, at 9rem rising to 15rem.
 * That is a size chosen for "Azurio" — one short word — and the heading here is
 * a whole sentence, which ran off the column and was cut mid-word by the line
 * mask the split-text animation puts around it. Wrapping is allowed and the
 * scale is stepped down to what two lines of this heading actually need.
 */
.zc-inner-title h1.large {
  white-space: normal;
  text-wrap: balance;
}

@media only screen and (min-width: 768px) {
  .zc-inner-title h1.large {
    font-size: 6rem;
  }
}
@media only screen and (min-width: 1200px) {
  .zc-inner-title h1.large {
    font-size: 8.5rem;
  }
}
@media only screen and (min-width: 1400px) {
  .zc-inner-title h1.large {
    font-size: 10rem;
    letter-spacing: -0.4rem;
  }
}
@media only screen and (min-width: 1600px) {
  .zc-inner-title h1.large {
    font-size: 12rem;
  }
}

/*
 * Label over value in the details list.
 *
 * The theme's split-info span is inline, which suits "Client: IB Themes" and
 * runs straight into the label the moment the value is a sentence — it read
 * "Shapes:16:9 for YouTube". These values are sentences, so the value takes
 * its own line under the label.
 */
.zc-details .split-info__details span {
  display: block;
  margin-top: 0.6rem;
}

/*
 * Room for tags that are phrases.
 *
 * The theme caps this pair of columns at 385px, which fits "Branding" and
 * "Marketing". These say what shape, what look and what comes back, so at 385
 * they broke to three and four lines each; widened, each one sits on its own.
 */
@media only screen and (min-width: 768px) {
  .zc-headline-tags {
    max-width: 640px;
  }
}

/*
 * The mark where the theme puts the customer's face.
 *
 * That block is a testimonial block, and its author slot is a round portrait.
 * The words in it are the product's own claim rather than something a customer
 * said, so the slot carries the brand glyph — square, not round, because a
 * logo cropped to a circle is a logo with its corners cut off.
 */
.zc-promise-mark {
  display: inline-flex;
  flex: 0 0 auto;
  width: 6.4rem;
  height: 6.4rem;
  line-height: 0;
}

.zc-promise-mark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/*
 * The door at the foot of /make/videos.
 *
 * `.mxd-next-prj__media` is `height: 100vh` from 1200px up, so this block's
 * shape is the viewport's and no picture can be cut to fit it everywhere.
 * `cover` is therefore right — it fills at any window — and the picture carries
 * a wide margin of bare table so the crop never reaches the book.
 *
 * The two rules below are the fix for the real bug. UkiyoParallax sizes its
 * wrapper to the picture's own aspect and multiplies it by the 1.2 it zooms by,
 * and the theme leaves this box's overflow visible — so a 1200x920 picture gave
 * a 1472px wrapper inside a 1000px box, and the bottom 470px, the page the
 * story is printed on, was drawn underneath the footer. Pinning the wrapper to
 * the box and clipping it keeps the parallax and keeps it inside, which is what
 * the image grid's own parallaxes already do.
 */
.mxd-next-prj__image {
  overflow: hidden;
}

.mxd-next-prj__image .parallax-img-small {
  height: 100%;
}

/*
 * And the picture shows whole.
 *
 * The theme's rule here is `cover`, which is right for a photograph whose
 * subject is its middle and wrong for a photograph of an object — a book with
 * its covers sliced off is not a book, and a laptop with its edges cut is not a
 * laptop. Both pages end on an object, so both want `contain`.
 *
 * This was lost once already: it went in with an earlier version of the block
 * above and was dropped when that block was rewritten to keep the parallax.
 */
.mxd-next-prj__image img {
  object-fit: contain;
}

/*
 * And the same for a film in that slot.
 *
 * The teaser plays a loop where there is one. Every rule the theme wrote for
 * this box names `img` — the block, the full width and height, the cover — so
 * a <video> matched none of them and drew at its own intrinsic size in the top
 * left of a 100vh box. It gets the theme's sizing and our `contain` both.
 */
.mxd-next-prj__image video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/*
 * The younger stack on /make/stories sits on black.
 *
 * `mxd-stack-cards opposite` is the theme's dark variant — its titles, tags
 * and marquee are all cut for a dark ground — so this is the ground the block
 * is drawn for, and the bright cards have something to sit against.
 *
 * Both selectors, because `.mxd-stack-cards.opposite` paints `--base-opp` on
 * itself: setting the section alone leaves the band running on its own ground
 * and the change only shows at the edges.
 */
#younger,
#younger .mxd-stack-cards.opposite {
  background-color: #000000;
}

/*
 * The sliding band behind the cards, in color.
 *
 * The theme runs it as a watermark — #191a1d on #0f0f0f, a texture rather than
 * words. These are the picture-book palette instead, and pale rather than deep:
 * a hue chosen to read on white goes muddy the moment it is laid on black.
 *
 * The opacity is the part that matters. Set solid, three saturated hues at that
 * size stop being a texture and become the loudest thing in the section, which
 * is the one job the band does not have. Held back, the color is still legible
 * as color and the cards are in front of it.
 */
#younger .card__marquees .marquee__text {
  color: #ffd166;
  opacity: 0.45;
}

#younger .card__marquees .marquee__item:nth-child(3n + 2) .marquee__text {
  color: #8ecae6;
}

#younger .card__marquees .marquee__item:nth-child(3n) .marquee__text {
  color: #ffb4a2;
}

/*
 * The age label, which has to be read.
 *
 * `.mxd-section-title__caption` is #575960, a grey cut for the page's own
 * off-white ground. On black it measures 3.0:1, and it is the one line in the
 * section that says who the half is for. At #a8aab3 it is 9.1:1.
 */
#younger .mxd-section-title__caption {
  color: #a8aab3;
}

/*
 * A small step above a stack section's heading — no more than that.
 *
 * The theme's lightest step for a section opening on a heading is
 * `padding-top-title`, 12.3rem rising to 14.9rem, which came to 180px on a
 * wide screen. Nothing smaller exists in that scale, and two passes at a value
 * of our own were still too generous: what this needs is enough that the age
 * label is not welded to the top edge of the black, and nothing beyond that.
 */
.zc-stack-section {
  padding-top: 2.4rem;
}

@media only screen and (min-width: 768px) {
  .zc-stack-section {
    padding-top: 3rem;
  }
}

/*
 * A sentence under a stack card's title.
 *
 * The theme's card carries a title and two columns of tags and nothing else,
 * which is right for an agency listing services — the title is the service.
 * Here the title is a claim, and a claim that cannot be expanded on is a
 * slogan.
 *
 * The colour is set here rather than left to the theme's `permanent` class,
 * which the card title uses: on a bare <p> that class resolved to the page's
 * dark ink and the sentence came out near-black over a dark picture. Slightly
 * off white, so it reads as the note under the claim and not as a second
 * claim.
 */
/*
 * The title and its sentence, in one centred column.
 *
 * `.card__title` is absolutely positioned by the theme — left and top 50%,
 * translated back by half, 70% wide — so it floats in the middle of the card
 * no matter what else is in `.card__content`. Wrapping it in a plain flex
 * column did nothing: the title kept floating and the wrapper shrank to the
 * sentence, which then sat out at the right-hand edge of the card.
 *
 * So the wrapper takes that positioning and the title goes back to static
 * inside it.
 */
.zc-card-say {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 70%;
  padding: 4rem 3rem;
  text-align: center;

  /*
   * A scrim, because the type is white and the picture underneath is not
   * always dark.
   *
   * The first card has to be two things at once: its middle is what the
   * opening clip-path reveals as a square, so the character sits there — and
   * that character is lit warm and pale. White type on it is unreadable, and
   * making the middle dark instead would give the reveal a hole to open on.
   *
   * A soft ellipse rather than a panel: at the centre it is enough to carry
   * the type, by the edges it is nothing, so it reads as the picture darkening
   * under the words rather than as a box laid over it.
   */
  background: radial-gradient(
    ellipse 70% 60% at 50% 50%,
    rgba(0, 0, 0, 0.62) 0%,
    rgba(0, 0, 0, 0.44) 52%,
    rgba(0, 0, 0, 0) 78%
  );
}

.zc-card-say .card__title {
  position: static;
  width: 100%;
  transform: none;
}

.zc-card-body {
  max-width: 46rem;
  margin: 1.6rem 0 0;
  color: rgba(255, 255, 255, 0.82);
  font: normal 400 1.7rem/1.5 var(--_font-default);
  text-wrap: pretty;
}

@media only screen and (min-width: 768px) {
  .zc-card-body {
    font-size: 1.9rem;
  }
}

/*
 * Opaque over a pinned section, on the page's real ground.
 *
 * `PinnedSection` pins with `pinSpacing: false`, so the pinned block leaves the
 * flow and whatever follows rides up over it. That only reads as the effect it
 * is if the thing riding over is opaque, and every section here is transparent
 * by default.
 *
 * White rather than `--base`, which `zc-over-pin` uses. `--base` is #eeeae8 and
 * suits the homepage's own sections; the ground these pages actually sit on is
 * the root layout's `min-h-screen bg-white`, so #eeeae8 shows up as a warm-grey
 * band rather than as nothing.
 */
/* The template's ground, not white: these pages show `--base` now, and an
   opaque block painted #ffffff over it is a pale rectangle on a warm page. */
.zc-opaque-over-pin {
  position: relative;
  z-index: 1;
  background-color: var(--base, #eeeae8);
}

/*
 * Films taking turns in one slot.
 *
 * The box carries the theme's own slot class, so it is sized and placed by the
 * block's rules. Its aspect comes from the files (an inline style, because it
 * is data about the films rather than a design decision) and the films are laid
 * on top of one another inside it, so the box does not resize between shots.
 *
 * 0.9s is roughly twice the length of the load fade. A handover wants to be
 * slower than an entrance — the entrance is the page arriving, and a handover
 * should read as one shot becoming another rather than as a cut.
 */
.zc-crossfade {
  position: relative;
  overflow: hidden;
}

/*
 * The full-bleed variant, for a background rather than a panel.
 *
 * `.mxd-hero-09__background` is already absolutely placed over the whole hero,
 * so this fills it rather than holding an aspect of its own — a box with an
 * aspect-ratio inside a full-height parent leaves a band of nothing under it.
 */
.zc-crossfade--fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/*
 * A still in the slot gets what the block gives a video there.
 *
 * `.mxd-hero-09__background video` sets the cover; an `<img>` in the same place
 * matches no selector the theme wrote and drew at its intrinsic size, so a
 * 1920-wide plate sat in the top left of the hero with the rest bare.
 */
.mxd-hero-09__background .zc-crossfade__clip {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.zc-crossfade__clip {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.9s ease;
}

.zc-crossfade__clip.is-active {
  opacity: 1;
}

/*
 * The handover still happens, it just stops being a dissolve. Holding the
 * shot instead would leave the first film on screen for good, which is not the
 * reduced-motion version of three films, it is one film.
 */
@media (prefers-reduced-motion: reduce) {
  .zc-crossfade__clip {
    transition: opacity 0.01s linear;
  }
}

/*
 * The slot needs a width of its own now that what fills it is a div.
 *
 * `.mxd-hero-09__media` is a flex column with a max-width and no width, so it
 * is shrink-to-fit: it took its size from the picture's intrinsic width. A
 * `<div>` has no intrinsic width, and `.mxd-hero-09__image` sets `width: 100%`,
 * which against a shrink-to-fit parent resolves to nothing — `aspect-ratio`
 * then gave it a height to match. Measured, the whole slot came out 60x0, the
 * width of the button that was holding it open.
 *
 * Filling the track lets the block's own max-width — 280, 320, then 380 — go
 * back to being what decides the size.
 */
#games-hero .mxd-hero-09__media {
  width: 100%;
}

/*
 * Two filter rows that combine, above one grid.
 *
 * The legend matters: with two rows and no labels, "Any" and "Anyone" sitting
 * one above the other read as one long list of unrelated words rather than two
 * questions with an answer each.
 */
.zc-filters {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 2.4rem 0 0.8rem;
}

@media only screen and (min-width: 1200px) {
  .zc-filters {
    position: relative;
  }
  .zc-filters .zc-filter__count {
    position: absolute;
    top: 2.4rem;
    right: 0;
  }
}

.zc-filter__legend {
  min-width: 3.4rem;
  font-family: var(--_font-accent);
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-muted, #8a8a90);
}

/* Nothing matched both filters at once — which is a real answer, not an error,
   and says how to get back rather than apologising. */
.zc-empty {
  padding: 4rem 0;
  font-family: var(--_font-default);
  font-size: 1.8rem;
  color: var(--t-medium, #55555a);
}

/* ------------------------------------------------*/
/* TEMPLATES GRID                                   */
/* ------------------------------------------------*/

/*
 * The counted figures, as one row.
 *
 * These were a pinned section of their own, and it cost a whole screen at 8%
 * ink to say four numbers — the block held for 1130px while nothing changed.
 * Four short columns say the same thing in the space they are worth.
 */
.zc-facts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem 2.4rem;
  padding: 1rem 0 3.2rem;
  border-bottom: 1px solid var(--t-muted-extra, rgba(18, 18, 18, 0.12));
}

@media only screen and (min-width: 768px) {
  .zc-facts {
    grid-template-columns: repeat(4, 1fr);
  }
}

.zc-facts__number {
  font-family: var(--_font-accent);
  font-size: 3.2rem;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--t-bright, #121212);
}

.zc-facts__caption {
  margin-top: 0.6rem;
  max-width: 22ch;
  font-size: 1.4rem;
  line-height: 1.35;
  color: var(--t-medium, #55555a);
}

/*
 * A tile is a button, so it has to be told not to look like one.
 *
 * One aspect for every tile, because the catalogue holds 16:9, 9:16 and 1:1 and
 * `.mxd-project-item__media img` is `height: auto` — fed the real files the
 * rows came apart, a vertical poster standing three times the height of a
 * landscape one beside it. The shape each film is actually cut to is on the tag
 * under it, where it can be read rather than guessed from the crop.
 */
.zc-tile {
  display: block;
  width: 100%;
  overflow: hidden;
  padding: 0;
  border: none;
  border-radius: var(--_radius-m, 1.2rem);
  background-color: var(--base-opp, #121212);
  cursor: pointer;
}

/* The tile carries the aspect, set per card from what it shows, and the media
   fills it. `aspect-ratio: 3 / 2` lived here and flattened all thirty-three to
   the same shape, which is the one thing the block's grid does not do. */
.zc-tile__media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  transition: transform 0.5s cubic-bezier(0.25, 1, 0.5, 1);
}

.zc-tile__media--clip {
  position: absolute;
  inset: 0;
  height: 100%;
}

.zc-tile:hover .zc-tile__media {
  transform: scale(1.04);
}

/* The one thing that has to sit on the picture, because it is a condition of
   starting rather than a description of the result. */
.zc-tile__needs {
  position: absolute;
  top: 1rem;
  right: 1rem;
  background-color: var(--accent, #c1ff72);
  color: var(--nl-black, #121212);
}

.zc-tile:focus-visible {
  outline: 2px solid var(--accent, #c1ff72);
  outline-offset: 3px;
}

/* The name is a button too — same action as the tile, for anyone who tabs to
   it or reads the caption first. */
.zc-tile__name {
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.zc-tile__blurb {
  margin-top: 0.4rem;
  max-width: 40ch;
  font-size: 1.4rem;
  line-height: 1.4;
  color: var(--t-medium, #55555a);
}

/*
 * A shorter headline, because what follows it is a catalogue.
 *
 * The block is cut for a page that opens on a statement and gives it room:
 * 555px for a word and a sentence, then `margin-bottom-subtitle` adds 130px
 * more. On an editorial page that is the point. Here it pushed the first tile
 * to y1015 on a 1000px screen — a shop whose window shows only the sign, and
 * measured, the opening screen came out 9% ink.
 *
 * Tightened, the first row of tiles is above the fold, which is the whole job
 * of this page.
 */
.zc-head .inner-headline {
  margin-bottom: 2.4rem;
}

.zc-head .inner-headline__content {
  padding-top: 0;
}

/*
 * The sentence under the typed line reads as a lede, not a second headline.
 *
 * The block sets it at 44px, which is right when it is the only thing the page
 * has to say. Here it wrapped to five lines across 625px of a 1095px column and
 * left the right half of the opening screen empty, while pushing the catalogue
 * down. Smaller and wider it is two lines, and the first row of tiles comes up
 * above the fold.
 */
.zc-head .inner-headline__subtitle {
  margin-top: 1.2rem;
}

.zc-head .inner-headline__subtitle p {
  max-width: 76ch;
  font-size: 2.4rem;
  line-height: 1.4;
}

@media only screen and (min-width: 1200px) {
  .zc-head .inner-headline__title {
    padding-top: 0;
  }
}

/*
 * The filter chips themselves.
 *
 * Not the theme's `.tag`, which is a label rather than a control: it has no
 * pressed state and nothing to say it can be clicked. This borrows its size and
 * letterspacing and adds the two things a filter needs — a border you can see
 * before you touch it, and a filled state for the one that is on.
 */
.zc-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.zc-filter__tag {
  padding: 0.6rem 1.4rem;
  border: 1px solid var(--t-muted-extra, rgba(18, 18, 18, 0.2));
  border-radius: 10rem;
  background-color: transparent;
  color: var(--t-medium, #55555a);
  font-family: var(--_font-accent);
  font-size: 1.2rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition:
    border-color 0.2s ease,
    background-color 0.2s ease,
    color 0.2s ease;
}

.zc-filter__tag:hover {
  border-color: var(--t-bright, #121212);
  color: var(--t-bright, #121212);
}

.zc-filter__tag.is-on {
  border-color: var(--nl-black, #121212);
  background-color: var(--nl-black, #121212);
  color: var(--nl-white, #fff);
}

.zc-filter__tag:focus-visible {
  outline: 2px solid var(--accent, #c1ff72);
  outline-offset: 2px;
}

/*
 * The caption under a tile.
 *
 * The block's 6rem gap is cut for a project name beside four category tags on
 * a full-width row. At three-to-a-row these captions are 425px wide, and 60px
 * of it spent on a gap pushed the tags off on their own.
 */
.mxd-project-item__caption {
  gap: 1.6rem;
}

.mxd-project-item__caption .mxd-project-item__tags {
  flex-shrink: 0;
}

/*
 * A poster in the hero collage.
 *
 * The block's items are links; ours are buttons, because pressing one starts a
 * film rather than opening a page about it. A button brings its own border,
 * padding and background, and `.marquee__item` sets none of those back.
 *
 * No aspect is forced here, unlike the tiles in the grid. The collage is built
 * out of pictures of different shapes passing at the same vertical centre —
 * that is what makes it read as scattered rather than as a filmstrip — and the
 * catalogue is 16:9, 9:16 and 1:1 already.
 */
.zc-hero-item {
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

/*
 * A ceiling on how tall a poster in the collage gets.
 *
 * `.marquee__item.item-hero` fixes the width and lets the height fall out of
 * the aspect, and the band is as tall as its tallest member. The theme's
 * tallest is 737x1200; ours is a 9:16 poster, which is taller still, and the
 * band came out 676px against the theme's 618 — enough to push the links and
 * the scroll cue under the fold on a 1000px screen.
 *
 * In vh rather than pixels because the hero is `mxd-hero-fullheight-desktop`,
 * so what matters is the share of the screen the band takes, not its size.
 */
.zc-hero-item .marquee__image {
  overflow: hidden;
  border-radius: var(--_radius-m, 1.2rem);
  max-height: 62vh;
}

.zc-hero-item .marquee__image {
  position: relative;
}

/*
 * The picture sets the item's height, which is the whole point of the band.
 *
 * `height: 100%` against a wrapper with no height of its own resolves to
 * nothing, so every item measured 380x0 and the collage collapsed. `auto` lets
 * each poster stand at its own aspect — tall, square or wide — which is what
 * makes a row of them read as a collage rather than a filmstrip.
 */
.zc-hero-item .marquee__image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.zc-hero-item__clip {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The clip sits on its own poster, which is its first frame, so a shot
   arriving or leaving the band does not flash. */
.zc-hero-item__clip {
  position: absolute;
  inset: 0;
}

.zc-hero-item:focus-visible {
  outline: 2px solid var(--accent, #c1ff72);
  outline-offset: 4px;
}

/*
 * Air above the grid's heading.
 *
 * The divider ends and the section title starts — measured, a gap of exactly
 * zero — so the type sat on the picture's bottom edge with nothing between
 * them. Every other block on the page arrives after a padding step; this one
 * follows a full-bleed image, which has none of its own.
 */
.mxd-section-title.pre-grid {
  padding-top: 7.2rem;
}

@media only screen and (min-width: 1200px) {
  .mxd-section-title.pre-grid {
    padding-top: 11rem;
  }
}

/*
 * The catalogue flows into columns instead of rows.
 *
 * The block lays its cards out as a wrapping flex row, which is right when
 * there are six of them and their heights are close. With thirty-three at a
 * range of 2.3 to 1, a row is as tall as its tallest card and everything
 * shorter leaves a hole underneath it until the next row starts — measured,
 * 336 to 355px of empty ground in every row, which over eleven rows is most of
 * a screen of nothing.
 *
 * Columns close that. Each card sits directly under the one above it whatever
 * height either of them is, so the varied shapes stay and the gaps go. The
 * reading order becomes column by column rather than row by row, which for a
 * wall you browse rather than read is the usual arrangement and no loss.
 *
 * Scoped to this page's gallery: the block's own grid elsewhere is untouched.
 */
#works .mxd-projects-grid__gallery {
  display: block;
  column-count: 1;
  column-gap: 2.4rem;
}

@media only screen and (min-width: 768px) {
  #works .mxd-projects-grid__gallery {
    column-count: 2;
  }
}

@media only screen and (min-width: 1200px) {
  #works .mxd-projects-grid__gallery {
    column-count: 3;
  }
}

/*
 * A card must not be split across a column break, and `inline-block` is what
 * makes browsers honour that reliably inside a column layout.
 */
#works .mxd-projects-grid__gallery .mxd-project-item {
  display: inline-block;
  width: 100%;
  max-width: 100%;
  margin-bottom: 4.8rem;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}

/*
 * Dark ink on the accent band, because our accent is light.
 *
 * The block sets everything in here to white — `h2.permanent`, the button's
 * caption and its border — and that is right for the template: measured on the
 * published demo its accent is rgb(0, 43, 186), a deep blue that white sits on
 * comfortably. Ours is #C1FF72. White on it measures about 1.2:1, which is not
 * a contrast problem so much as an invisible call to action.
 *
 * This existed once and went out with a block deletion that took too wide a
 * range; it is here with the rest of the templates rules now rather than off on
 * its own next to something unrelated.
 *
 * Scoped to the accent variant, so the same block on a dark ground — which is
 * what `.mxd-gravity-section` is without it — keeps the white it needs.
 */
.mxd-gravity-section.accent .mxd-promo__caption h2,
.mxd-gravity-section.accent .mxd-promo__caption h2 .char,
.mxd-gravity-section.accent .mxd-promo__caption h2 .word,
.mxd-gravity-section.accent .mxd-promo__caption h2 .line {
  color: var(--nl-black, #121212);
}

/* The button: its caption, and the rule around it. Dark grey rather than the
   full black of the heading, so the two do not compete. */
.mxd-gravity-section.accent .mxd-promo__btngroup .btn,
.mxd-gravity-section.accent .mxd-promo__btngroup .btn-caption {
  color: #2a2a2e;
}

.mxd-gravity-section.accent .mxd-promo__btngroup .btn-line-permanent,
.mxd-gravity-section.accent .mxd-promo__btngroup .btn {
  border-color: rgba(18, 18, 18, 0.35);
}

.mxd-gravity-section.accent .mxd-promo__btngroup .btn:hover {
  border-color: var(--nl-black, #121212);
  color: var(--nl-black, #121212);
}

/* ------------------------------------------------*/
/* AUDIENCE PAGES                                   */
/* ------------------------------------------------*/

/*
 * No missing backdrop behind hero-01.
 *
 * It names `img/hero/1920x1200_h01.webp`, which the package does not ship —
 * h01 and h02 are both absent — so the block 404s on sight. The same was true
 * of hero-09. These pages lay their own picture over the whole area anyway.
 */
.mxd-hero-01 {
  background-image: none;
}

/*
 * The audience picture, in two pieces.
 *
 * The plate is landscape with nobody in it and the character is a cut-out laid
 * over it. They were drawn that way for a reason worth keeping: one flat
 * picture matched the band's width exactly, so `object-position` could only
 * move it up and down, and moving the child sideways meant generating the
 * picture again and hoping.
 */
.zc-audience-hero__art {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.zc-audience-hero__plate {
  object-fit: cover;
  object-position: center;
}

/*
 * The character sits at the right, clear of the words and clear of the
 * wordmark along the bottom.
 */
.zc-audience-hero__character {
  position: absolute;
  right: 2%;
  bottom: 14%;
  width: auto;
  height: 62%;
  max-width: 46%;
  object-fit: contain;
}

@media only screen and (max-width: 991px) {
  .zc-audience-hero__character {
    right: -6%;
    bottom: 22%;
    height: 42%;
    max-width: 68%;
  }
}

/* The sentence under the tags, and the eyebrow over it. */
/*
 * The sentence and the button, which the block has no slot for.
 *
 * Its own contact area is a phone number and an email — two short lines. A
 * sentence and a button need more room than that: measured, the column took
 * its width from the tag list above it and the lede wrapped inside 365px while
 * three quarters of the hero sat empty beside it.
 */
.zc-audience-hero__say {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2rem;
  margin-top: 1.2rem;
}

.zc-audience-hero__lede {
  width: max-content;
  max-width: min(46ch, 42vw);
  font-size: 2.2rem;
  line-height: 1.35;
  color: var(--nl-white, #fff);
}

@media only screen and (max-width: 991px) {
  .zc-audience-hero__lede {
    max-width: 100%;
    font-size: 1.8rem;
  }
}

/*
 * The wordmark, sized to the word rather than to "Azurio".
 *
 * `.fullwidth-text__content` is `28cqw` with no wrapping, which is cut for six
 * characters. These pages set anything from "amazing" at seven to "stories to
 * life" at fifteen, and at the block's own size the longer ones run off both
 * edges. 168cqw is that same size expressed as a total — six times 28 — so a
 * six-character word is unchanged and everything else is scaled to fit.
 */
.zc-audience-hero .fullwidth-text__content {
  font-size: calc(168cqw / var(--zc-mark-chars, 6));
  text-transform: uppercase;
}

/*
 * The block's own cover, kept.
 *
 * An earlier pass replaced the flat 40% black with an angled gradient, so the
 * picture stayed bright and the weight sat only where the type was. It read
 * well on its own and it did not read like the template: measured against the
 * published demo, its cover is a flat rgba(0, 0, 0, 0.4) across the whole
 * frame and that even darkness is most of what the hero looks like.
 *
 * A little heavier here, because the plates are brighter than the portrait the
 * block was drawn around — measured, they run luma 161 to 225 where its own is
 * far darker — and 40% over a sunlit field is not the same 40%.
 */
.zc-audience-hero .mxd-hero-01__cover {
  background-color: rgba(0, 0, 0, 0.46);
}

/*
 * The tags read as type, not as labels on a form.
 *
 * `.tag` takes the page's ink, which on a light page is near-black — and these
 * sit on a picture. White, and a shade lighter than the sentence under them so
 * the two are not the same voice.
 */
.zc-audience-hero .mxd-hero-01__data-tags .tag,
.zc-audience-hero .mxd-hero-01__data-contact .tag {
  color: var(--nl-white, #fff);
  white-space: nowrap;
}

.zc-audience-hero .mxd-hero-01__data-tags .tag:hover {
  color: var(--nl-white, #fff);
}

/*
 * The wordmark is a watermark, not a headline.
 *
 * At 336px it is the largest thing on the page, and at full white it fights
 * the child for the eye. The block sets it `permanent` white over a dark
 * picture; here it sits over grass and sky, so it is white at a third and
 * lifts when the pointer is on it.
 */
/*
 * The word itself, not just the link around it.
 *
 * `.fullwidth-text__content span` carries its own colour in the block, and the
 * character splitter wraps every letter in another span inside that — so
 * colouring the anchor left the link white and every letter still near-black.
 * Measured: the anchor read rgba(255, 255, 255, 0.92) while its span read
 * rgb(18, 18, 18), which is what was on screen.
 */
.zc-audience-hero .fullwidth-text__content,
.zc-audience-hero .fullwidth-text__content span,
.zc-audience-hero .fullwidth-text__content .char,
.zc-audience-hero .fullwidth-text__content .word {
  color: rgba(255, 255, 255, 0.92);
  transition: color 0.3s ease;
}

.zc-audience-hero .fullwidth-text__content:hover,
.zc-audience-hero .fullwidth-text__content:hover span,
.zc-audience-hero .fullwidth-text__content:hover .char {
  color: var(--nl-white, #fff);
}

/*
 * The character clears the panel.
 *
 * The block puts its small playing panel in the top right, and at 62% height
 * the child's head reached into it — the panel landed across her face. Lower
 * and a little smaller, she stands under it.
 */
.zc-audience-hero__character {
  right: 3%;
  bottom: 3%;
  height: 54%;
}

/*
 * The showcase rows.
 *
 * The air between them used to be set here, with
 * `.zc-showcase__row + .zc-showcase__row { margin-top: 9.6rem }`. Each row now
 * sits in its own `.mxd-block`, as the template has it, so the rows are no
 * longer adjacent siblings and that rule matched nothing — the 83px between
 * them is `.mxd-split-descr.pre-manifest-l`, which is the spacing the template
 * uses for exactly this pairing.
 *
 * The picture still needs a lid: these are product screens and film frames
 * rather than the block's own illustration, which arrives with its corners
 * already drawn.
 */
.zc-showcase__image {
  overflow: hidden;
  border-radius: var(--_radius-m, 1.2rem);
}

.zc-showcase__image img,
.zc-showcase__image video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* The small line over each claim, in the accent face so it reads as a label
   rather than as the first line of the sentence under it. */
.zc-showcase__kicker {
  margin-bottom: 1.6rem;
  font-family: var(--_font-accent);
  font-size: 1.2rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-muted, #8a8a90);
}

/* The words are laid out by the block itself, with one thing set back.

   `.mxd-split-descr__wrap` is already a flex column that goes `height: 100%;
   justify-content: space-between` at 992px. This file had replaced that with
   `justify-content: center`, which floated the whole group in the middle of a
   column it no longer lined up with, and added `padding-left: 4rem` for a
   gutter that `.mxd-grid-item` already provides — so the text sat 40px inside
   its column on one row and, through the `:first-child` flip, 40px inside the
   other edge on the next. Both are gone: measured against the template's own
   demo, the claim is level with the top of the picture and the text is flush
   to its column.

   What does not carry over is `space-between`. The template's paragraph fills
   its column; ours is three lines against a 447px picture, so the tags were
   pushed to the foot and left 238px of nothing under the sentence. They sit
   under the paragraph instead, at the block's own 3.2rem. */
@media only screen and (min-width: 992px) {
  .zc-showcase__row .mxd-split-descr__wrap {
    justify-content: flex-start;
  }

  .zc-showcase__row .mxd-split-descr__tags {
    margin-top: 3.2rem;
  }
}

/* Two columns of tags, stacked, as the block itself does it.

   This rule used to make the column a wrapping row. That was right while every
   tag sat in one full-width column, and wrong the moment there were two of
   them at 210px: three two-word tags wrapped onto two lines each and the two
   columns interleaved, so "Your lines / Your colors / It moves / Still yours"
   read as one broken sentence across both. */
.zc-showcase .mxd-split-descr__tags .row > div {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
}

/* The films fill the art layer the plate used to, and sit under the block's
   cover like the plate did. */
.zc-audience-hero__art .zc-crossfade--fill .zc-crossfade__clip {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The header lockup.
   `.mxd-logo__image` in the template is a square app icon and is sized as
   one; this is the full 460x120 lockup, so it needs its own width and has to
   keep its ratio rather than be squeezed into the icon's box. */
.zc-logo-lockup {
  width: auto;
  height: 4rem;
  max-width: none;
  object-fit: contain;
}

/*
 * The animated mark in the menu overlay.
 *
 * Eight seconds, and it is a mark being painted rather than three shapes
 * sliding in: the canvas rules itself on, each stroke wipes in the direction a
 * hand would pull it, a sheen passes over the finished mark once, a few motes
 * come off it, and it holds before starting again.
 *
 * Transform and opacity only, so nothing lays out twice. The wipes are rects
 * inside clipPaths — scaling one of those is the only way to draw an SVG shape
 * on with CSS alone.
 */
.zc-menu-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 12%;
  background:
    radial-gradient(
      60% 50% at 50% 45%,
      rgba(193, 255, 114, 0.16) 0%,
      rgba(193, 255, 114, 0) 70%
    ),
    #0c0d10;
}

.zc-menu-mark__svg {
  /* A mark, not a mural. At 100% of a 640px panel the Z was three quarters of
     the width of the overlay and read as a background rather than as a logo. */
  width: 38%;
  min-width: 16rem;
  height: auto;
  max-height: 60%;
  overflow: visible;
  filter: drop-shadow(0 0 3.2rem rgba(193, 255, 114, 0.28));
  animation: zc-mark-settle 8s ease-in-out infinite;
}

.zc-menu-mark__svg * {
  transform-box: view-box;
  transform-origin: 0 0;
}

/* The canvas, ruled on first and held faint behind everything. */
.zc-menu-mark__grid {
  opacity: 0;
  animation: zc-mark-grid 8s ease-out infinite;
}

/* Each stroke is revealed by its own rect growing across the clip. */
.zc-mark-wipe {
  animation: zc-mark-wipe-x 8s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

.zc-mark-wipe--bar {
  animation-delay: 0.55s;
}

/* The diagonal runs top-right to bottom-left, so it is pulled downward. */
.zc-mark-wipe--stroke {
  animation-name: zc-mark-wipe-y;
  animation-delay: 0.95s;
}

.zc-mark-wipe--foot {
  animation-delay: 1.5s;
}

@keyframes zc-mark-wipe-x {
  0%,
  6% {
    transform: scaleX(0);
  }
  22%,
  88% {
    transform: scaleX(1);
  }
  100% {
    transform: scaleX(0);
  }
}

@keyframes zc-mark-wipe-y {
  0%,
  6% {
    transform: scaleY(0);
  }
  22%,
  88% {
    transform: scaleY(1);
  }
  100% {
    transform: scaleY(0);
  }
}

@keyframes zc-mark-grid {
  0% {
    opacity: 0;
  }
  8%,
  86% {
    opacity: 0.1;
  }
  100% {
    opacity: 0;
  }
}

/* One pass of light across the finished mark, then gone. */
.zc-menu-mark__sheen {
  opacity: 0;
  animation: zc-mark-sheen 8s ease-in-out infinite;
}

@keyframes zc-mark-sheen {
  0%,
  30% {
    opacity: 0;
    transform: translateX(0) skewX(-12deg);
  }
  34%,
  52% {
    opacity: 0.9;
  }
  58%,
  100% {
    opacity: 0;
    transform: translateX(2100px) skewX(-12deg);
  }
}

/* A few motes lifting off as it lands. */
.zc-mark-mote {
  opacity: 0;
  animation: zc-mark-mote 8s ease-out infinite;
}

.zc-mark-mote--1 {
  animation-delay: 1.7s;
}
.zc-mark-mote--2 {
  animation-delay: 2s;
}
.zc-mark-mote--3 {
  animation-delay: 1.85s;
}
.zc-mark-mote--4 {
  animation-delay: 2.2s;
}
.zc-mark-mote--5 {
  animation-delay: 2.35s;
}

@keyframes zc-mark-mote {
  0% {
    opacity: 0;
    transform: translate(0, 0) scale(0.4);
  }
  6% {
    opacity: 0.85;
  }
  28%,
  100% {
    opacity: 0;
    transform: translate(40px, -150px) scale(1);
  }
}

/* The whole thing lifts a little as the last stroke lands, then rests. */
@keyframes zc-mark-settle {
  0%,
  14% {
    transform: scale(0.965);
  }
  26% {
    transform: scale(1.015);
  }
  40%,
  88% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.965);
  }
}

/* Finished, and still. */
@media (prefers-reduced-motion: reduce) {
  .zc-menu-mark__svg,
  .zc-menu-mark__svg * {
    animation: none;
  }
  .zc-menu-mark__grid {
    opacity: 0.1;
  }
  .zc-mark-wipe {
    transform: none;
  }
  .zc-menu-mark__sheen,
  .zc-mark-mote {
    opacity: 0;
  }
}

/* Get started, in the menu's right column.
   `.menu-contact__list` sets its links to the column's muted grey, which won
   over the accent button and left rgb(142,147,161) on the green — a contrast
   of about 1.9:1. The button keeps the block's ink. */
.zc-menu-cta,
.zc-menu-cta .btn-caption,
.zc-menu-cta span {
  color: #121212;
}

/* The two account links sit together above the address rather than in the
   same rhythm as it, and centred on the column — the button is the one thing
   in the menu that is a thing to press rather than a place to go, so it reads
   as a block rather than as another line in a list. */
.zc-menu-cta {
  /* It comes last, under the address and Sign in, and wants air above it so
     it reads as the thing to press rather than the third line of a list.
     On top of the list's own 0.8rem, which makes 2.4rem in all — three times
     the space between the two links above it. */
  margin-top: 1.6rem;
  justify-content: center;
  text-align: center;
}

.zc-menu-cta .btn-caption {
  width: 100%;
  text-align: center;
}

/* The whole column, not just the button — a centred button over a
   left-ranged address reads as a mistake. */
.mxd-menu__right .menu-contact__item .menu-contact__list {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* The template's list has no gap of its own: making it a flex column left
     the address and Sign in 2px apart, reading as one wrapped line. */
  gap: 0.8rem;
}

/*
 * Sign in, on the template's contact form.
 *
 * The block's own inputs and button carry almost all of it; what is left is
 * the row the card had and the template has no equivalent for — remember me
 * beside the forgotten-password link — and the line under the form.
 */
.zc-auth-form .mxd-form-container {
  max-width: none;
}

.zc-auth-form__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  margin-bottom: 2.4rem;
}

.zc-auth-form__remember {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font: normal 400 1.4rem/1.6 var(--_font-default);
  color: var(--t-medium);
  cursor: pointer;
}

.zc-auth-form__remember input {
  width: 1.6rem;
  height: 1.6rem;
  margin: 0;
  accent-color: var(--accent, #c1ff72);
  cursor: pointer;
}

.zc-auth-form__forgot,
.zc-auth-form__alt {
  font: normal 400 1.4rem/1.6 var(--_font-default);
  color: var(--t-medium);
}

/* Centred, because everything it sits under is: the divider, the provider
   buttons and the preview note are all centred, and the line was ranging left
   from 800px while the fields themselves start at 830. */
.zc-auth-form__alt {
  margin-top: 2.4rem;
  text-align: center;
}

/* The address set across the full width, on the sign-in page.
   `.fullwidth-text__content.small` is 10.46cqw, which fits the template's own
   hello@azurio.com — sixteen characters. Ours is twenty, and the .com ran off
   the right edge. 10.46 x 16 is 167, so the same width divided by however many
   characters it actually has. */
.zc-auth-email .fullwidth-text__content.small {
  font-size: calc(167cqw / var(--zc-email-chars, 16));
}

/*
 * The sign-in page is one short form, not a case study.
 *
 * The inner-headline block is cut for a page with a lot under it: 169px
 * between the breadcrumb and the title, 190px above the address, and the
 * section's own 200px underneath. That put the address 1067px down and the
 * footer 1357px down — two screens to see a form and an email address.
 *
 * Tightened here only, so /contact and anything else built on the block keep
 * the spacing they were drawn with. No padding under the section either: the
 * address is meant to run straight into the footer.
 */
.zc-auth-section {
  padding-bottom: 0;
}

.zc-auth-section .inner-headline__content {
  padding-top: 6.4rem;
}

.zc-auth-section .zc-auth-email {
  margin-top: 6.4rem;
}

/* Sign-ups closed: one button and a way back, where the form would be. */
.zc-auth-closed {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2.4rem;
  margin-top: 4rem;
}

.zc-auth-closed .zc-auth-form__alt {
  margin-top: 0;
  text-align: left;
}

/* Password, with the eye sitting in the right-hand end of the field. */
.zc-auth-pw {
  position: relative;
}

.zc-auth-pw input {
  padding-right: 4.8rem;
}

.zc-auth-pw__eye {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.4rem;
  height: 5.2rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--t-medium);
  cursor: pointer;
  transition: color 0.2s ease;
}

.zc-auth-pw__eye:hover,
.zc-auth-pw__eye:focus-visible {
  color: var(--t-bright, #121212);
}

/* The step rail, level with the fields.
   `.mxd-grid-item` carries 30px of side padding, which is what puts the
   inputs and the lede above them on 830 — the rail and the buttons were
   outside it and ranged from 800. They take the class rather than a copy of
   the number, so they follow it at every breakpoint. */
.zc-auth-form__steps {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 3.2rem;
}

/* The wizard's buttons: room above them, and Back beside Continue. */
.zc-auth-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.6rem;
  margin-top: 3.2rem;
}

/* Ranged left with everything else on the page, not centred under the
   buttons — it was the only thing on the step that was not on 830. */
.zc-auth-form__skip {
  display: block;
  width: 100%;
  margin-top: 1.6rem;
  border: 0;
  background: none;
  font: normal 400 1.4rem/1.6 var(--_font-default);
  color: var(--t-medium);
  text-align: left;
  cursor: pointer;
}

/*
 * The sign-up questions, on the template's tags.
 *
 * They were the card's pills — 13px text in a thin grey capsule, four of them
 * in a row under a small grey legend. Against the template's inputs above
 * them they read as a different form pasted in.
 */
.zc-auth-pills {
  margin: 0 0 3.2rem;
  /* Vertical only. `padding: 0` here also cleared the 30px that
     `.mxd-grid-item` puts on the sides, so the questions and their answers
     ranged from 800 while the fields, the step rail and the buttons were all
     on 830. A fieldset's own default padding is the thing being reset. */
  padding-top: 0;
  padding-bottom: 0;
  border: 0;
}

.zc-auth-pills__label {
  display: block;
  margin-bottom: 1.6rem;
  padding: 0;
  font: normal 600 1.2rem/1.6 var(--_font-accent);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-medium);
}

.zc-auth-pills__set {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

/* `.tag` in the template is a plain text label with no edge at all, so as a
   chooser it read as five words in a row with nothing to press. These get the
   chip the template draws on its buttons: a hairline, a small radius, and the
   accent when chosen. */
.zc-auth-pills__tag {
  display: inline-flex;
  align-items: center;
  padding: 0.9rem 1.8rem;
  border: 1px solid rgba(18, 18, 18, 0.18);
  border-radius: 0.8rem;
  color: var(--t-medium);
  cursor: pointer;
  user-select: none;
  transition:
    border-color 0.2s ease,
    background-color 0.2s ease,
    color 0.2s ease;
}

.zc-auth-pills__tag:hover {
  border-color: rgba(18, 18, 18, 0.5);
  color: #121212;
}

.zc-auth-pills__tag:has(:checked) {
  border-color: var(--t-bright, #121212);
  background-color: #c1ff72;
  color: #121212;
}

.zc-auth-pills__tag:has(:focus-visible) {
  outline: 2px solid #121212;
  outline-offset: 2px;
}

/* The terms line on the last step. */
.zc-auth-terms {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 0.8rem;
  font: normal 400 1.4rem/1.6 var(--_font-default);
  color: var(--t-medium);
  cursor: pointer;
}

/* Not a `.form` field: the template styles those full width with an
   underline, and this is a 16px box. */
.zc-auth-terms__box {
  flex: 0 0 auto;
  width: 1.6rem !important;
  height: 1.6rem !important;
  margin: 0.3rem 0 0 !important;
  padding: 0 !important;
  border: 0 !important;
  accent-color: #c1ff72;
  cursor: pointer;
}

.zc-auth-terms a {
  color: var(--t-bright, #121212);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/*
 * Sign-ups closed: everything ranged from the sentence above it.
 *
 * `.zc-auth-closed` sat outside the grid item, so the button and the sign-in
 * line started at 800 while "We have paused new accounts" started at 830.
 */
.zc-auth-closed {
  padding-left: 3rem;
  padding-right: 3rem;
}

/* Room under the last line before the address runs across the foot. */
.zc-auth-form__alt {
  margin-bottom: 4.8rem;
}

/*
 * Errors, in the template's voice.
 *
 * They were a 12px red chip with a rounded border, sitting flush against
 * whatever came next. A message like "Sign-ups are closed at the moment" is
 * the most important thing on the page when it appears, and it was the
 * smallest.
 */
.zc-auth-note {
  margin: 2.4rem 0;
  padding: 1.6rem 2rem;
  border-left: 2px solid #c0392b;
  background: rgba(192, 57, 43, 0.06);
  font: normal 400 1.5rem/1.6 var(--_font-default);
  color: #8e2a20;
}

.zc-auth-note--warn {
  border-left-color: #b8860b;
  background: rgba(184, 134, 11, 0.08);
  color: #7a5a08;
}

.zc-auth-note a {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/*
 * The terms and the privacy policy.
 *
 * A long document is read, not scanned, so the clause heading sits in a
 * narrow left column and the text runs in a wide right one, with a hairline
 * between rows. Both pages were a single 2xl column where a six-word heading
 * and a sixty-word clause had the same measure.
 */
.zc-legal__intro {
  margin-top: 3.2rem;
  font: normal 400 1.5rem/1.7 var(--_font-default);
  color: var(--t-medium);
}

.zc-legal__intro a,
.zc-legal__text a {
  color: var(--t-bright, #121212);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.zc-legal {
  padding-bottom: 0;
}

.zc-legal__row {
  padding: 4rem 0;
  border-top: 1px solid rgba(18, 18, 18, 0.12);
}

.zc-legal__row--end {
  padding-bottom: 4rem;
}

/* `bottom-text-small` puts 190px above the address, which is right under a
   headline and far too much under the last clause — it left 265px of nothing
   between "See also our Privacy Policy" and the address. */
.zc-legal__email .zc-auth-email {
  margin-top: 0;
}

.zc-legal__heading {
  margin: 0;
  font: normal 600 1.4rem/1.5 var(--_font-accent);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--t-bright, #121212);
}

.zc-legal__text {
  margin: 0;
  /* Around 70 characters at this size, which is where long prose reads. */
  max-width: 62rem;
  font: normal 400 1.7rem/1.75 var(--_font-default);
  color: var(--t-medium);
}

@media only screen and (max-width: 991px) {
  .zc-legal__row {
    padding: 3.2rem 0;
  }

  .zc-legal__heading {
    margin-bottom: 1.6rem;
  }
}

/* The 404's secondary ways out, on the block's dataline.
   `.mxd-error__dataline` is `position: absolute; bottom: 0; width: 100%`,
   pinned to the bottom of `.mxd-error__content`. That works in the template,
   where the content box is tall enough to clear it — four floating
   illustrations around the digits. Ours is the digits, a caption and one
   button, so the pinned row came down across the button: transparent, full
   width, and on top, so `elementFromPoint` over "Back to the home page"
   returned the dataline and the button could not be clicked at all.
   Put it back in the flow, below the button, centred with it. */
.zc-notfound__links {
  position: static;
  margin-top: 3.2rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2.4rem;
}

.zc-notfound__links a {
  color: var(--t-medium);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.2s ease;
}

.zc-notfound__links a:hover {
  color: var(--t-bright, #121212);
}


/* ─────────────────────────────────────────────────────────────────────────
   /pricing
   The template's pricing block covers the cards. These are the four things
   it has no class for: the term switch, the shared-feature list, the
   comparison table, and the three composition cards.
   ───────────────────────────────────────────────────────────────────────── */

/* Monthly / Yearly, under the lede in the headline block. */
.zc-term {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.2rem;
  margin-top: 3.2rem;
}

/* `btn-default-icon` reserves 0.4rem on the right for the 4rem icon box.
   These have no icon, so the padding is evened up by hand. */
.zc-term__btn {
  padding: 1rem 2rem !important;
  font-size: 1.6rem !important;
}

.zc-term__note {
  color: var(--t-muted);
}

/* "Let's talk" set at the amount's 7.4rem runs off the card. It is a phrase,
   not a figure, so it is sized like one. */
.zc-plan__words {
  font-size: 3.6rem !important;
  letter-spacing: -0.1rem !important;
  line-height: 1.1 !important;
}

.zc-plan__saving,
.zc-plan__films {
  font: normal 400 1.4rem/1.5 var(--_font-accent);
  color: var(--t-medium);
}

.zc-plan__saving {
  margin-top: 0.8rem;
}

.zc-plan__saving s {
  color: var(--t-muted);
}

.zc-plan__films {
  margin-top: 1.6rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--st-muted);
}

/* The band of what never differs. Two columns so six short lines read as a
   list rather than a column six deep. */
.zc-shared__list {
  column-gap: 4rem;
}

@media only screen and (min-width: 768px) {
  .zc-shared__list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media only screen and (min-width: 1200px) {
  .zc-shared__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ── The comparison table ──
   The template has no table anywhere in it, so this is built out of its
   tokens rather than borrowed from a block: the tint for the head, the muted
   stroke for the rules, and the accent face for the figures, which are what a
   reader is comparing down a column. */
.zc-plans {
  overflow-x: auto;
  border-top: 1px solid var(--st-bright);
}

.zc-plans table {
  width: 100%;
  min-width: 60rem;
  border-collapse: collapse;
  text-align: left;
}

.zc-plans th,
.zc-plans td {
  padding: 1.8rem 2rem 1.8rem 0;
  border-bottom: 1px solid var(--st-muted);
  vertical-align: baseline;
}

.zc-plans thead th {
  font: normal 700 1.8rem/1.4 var(--_font-default);
  color: var(--t-bright);
  border-bottom-color: var(--st-bright);
}

.zc-plans tbody th {
  font: normal 400 1.5rem/1.5 var(--_font-default);
  color: var(--t-medium);
  width: 28%;
}

.zc-plans td {
  font: normal 500 1.5rem/1.5 var(--_font-accent);
  color: var(--t-bright);
  font-variant-numeric: tabular-nums;
}

.zc-plans tbody tr:last-child th,
.zc-plans tbody tr:last-child td {
  border-bottom: 0;
}

/* ── The three compositions ── */
.zc-comp {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: var(--base-tint);
}

.zc-comp__art {
  position: relative;
  aspect-ratio: 16 / 7;
  overflow: hidden;
}

.zc-comp__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.08);
}

.zc-comp__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 3rem;
}

.zc-comp__meta {
  font: normal 400 1.3rem/1.4 var(--_font-accent);
  text-transform: uppercase;
  letter-spacing: 0.05rem;
  color: var(--t-muted);
}

.zc-comp__total {
  margin-top: 1.2rem;
  font: normal 700 4.4rem/0.95 var(--_font-default);
  letter-spacing: -0.2rem;
  color: var(--t-bright);
  font-variant-numeric: tabular-nums;
}

.zc-comp__name {
  margin-top: 1.2rem;
  font: normal 700 1.8rem/1.4 var(--_font-default);
  color: var(--t-bright);
}

.zc-comp__note {
  margin-top: 0.4rem;
  font-size: 1.5rem;
  line-height: 1.5;
  color: var(--t-medium);
}

/* One bar rather than a chart. The only thing worth seeing is that the shots
   are nearly all of it, and that is what decides the price. */
.zc-comp__bar {
  display: flex;
  height: 0.8rem;
  margin-top: 2.4rem;
  overflow: hidden;
  background-color: var(--t-muted-extra);
}

.zc-comp__seg {
  display: block;
  height: 100%;
}

.zc-comp__dot {
  flex: none;
  width: 0.8rem;
  height: 0.8rem;
  margin-top: 0.7rem;
  border-radius: 50%;
}

.zc-comp__seg.is-accent,
.zc-comp__dot.is-accent {
  background-color: var(--accent);
}

.zc-comp__seg.is-ink,
.zc-comp__dot.is-ink {
  background-color: var(--base-opp);
}

.zc-comp__seg.is-leaf,
.zc-comp__dot.is-leaf {
  background-color: #7ed957;
}

.zc-comp__seg.is-stone,
.zc-comp__dot.is-stone {
  background-color: var(--st-medium);
}

.zc-comp__lines {
  margin-top: 2rem;
  flex: 1;
  border-top: 1px solid var(--st-muted);
}

.zc-comp__line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.6rem;
  padding: 1.2rem 0;
  border-bottom: 1px solid var(--st-muted);
}

.zc-comp__line:last-child {
  border-bottom: 0;
}

.zc-comp__line dt {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.zc-comp__line dt b {
  display: block;
  font: normal 700 1.4rem/1.4 var(--_font-default);
  color: var(--t-bright);
}

.zc-comp__line dt em {
  display: block;
  margin-top: 0.2rem;
  font: normal 400 1.2rem/1.4 var(--_font-default);
  color: var(--t-muted);
}

.zc-comp__line dd {
  flex: none;
  font: normal 500 1.4rem/1.4 var(--_font-accent);
  color: var(--t-bright);
  font-variant-numeric: tabular-nums;
}

/* The two ways out at the foot of the page. */
.zc-pricing-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.6rem;
}


/* ── The receipt ──
   Five line items and the sum. The template's stats block set each of these
   at headline size down three screens, which stopped the total reading as a
   total — it was just the sixth cell. Along one line they add up in front of
   the reader, and the answer stands apart from the working. */
.zc-receipt {
  display: flex;
  flex-direction: column;
  gap: 3.2rem;
  border-top: 1px solid var(--st-bright);
  padding-top: 2.4rem;
}

@media only screen and (min-width: 992px) {
  .zc-receipt {
    flex-direction: row;
    align-items: flex-end;
    gap: 6rem;
  }
}

.zc-receipt__lines {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2.4rem 3.2rem;
  flex: 1;
}

@media only screen and (min-width: 768px) {
  .zc-receipt__lines {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* Each amount pushed to the bottom of its own cell, so all five sit on one
   line however many lines the label above it takes. A guessed minimum height
   gets this wrong the moment somebody rewrites one of the words. */
.zc-receipt__line {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.zc-receipt__line + .zc-receipt__line {
  padding-left: 2.4rem;
  border-left: 1px solid var(--st-muted);
}

.zc-receipt__line dt {
  font-size: 1.4rem;
  line-height: 1.4;
  color: var(--t-medium);
}

.zc-receipt__line dd {
  margin-top: auto;
  padding-top: 1.2rem;
  font: normal 700 2.4rem/1 var(--_font-default);
  letter-spacing: -0.05rem;
  color: var(--t-bright);
  font-variant-numeric: tabular-nums;
}

.zc-receipt__total {
  flex: none;
  padding-top: 2rem;
  border-top: 1px solid var(--st-bright);
}

@media only screen and (min-width: 992px) {
  .zc-receipt__total {
    padding: 0 0 0 4.8rem;
    border-top: 0;
    border-left: 1px solid var(--st-bright);
  }
}

.zc-receipt__total-label {
  font: normal 400 1.3rem/1.4 var(--_font-accent);
  text-transform: uppercase;
  letter-spacing: 0.05rem;
  color: var(--t-medium);
}

.zc-receipt__total-num {
  margin-top: 0.6rem;
  font: normal 800 5.6rem/0.9 var(--_font-default);
  letter-spacing: -0.3rem;
  color: var(--t-bright);
  font-variant-numeric: tabular-nums;
}

/* The line under the three cards, and the two ways out under that. */
.zc-comp__footnote {
  margin-top: 4.8rem;
}

.zc-pricing-cta {
  margin-top: 3.2rem;
}


/* ── The four plan cards, aligned ──
   The block sets `justify-content: space-between` on the card body, which
   pushes the price and the button to the bottom of it — and the bottom of it
   is wherever the check list below happens to start. Measured across the four
   tiers that put the four prices at 230, 339, 403 and 518 from the top of
   their cards: a row of four cards with nothing lining up.

   Under the header with a fixed gap instead, the price sits at the same place
   in every card, because the headers are the same height — which they are
   because no title wraps and every positioning line runs to three lines, not
   because a minimum height is holding them open. Rewrite one of those lines
   longer and the row rags again, so the copy is the thing to keep in check. */
.zc-plans-row .mxd-pricing-table__data {
  justify-content: flex-start;
  gap: 3.2rem;
}

/* `.small` is 4.4rem, at which "Pay as you go" takes two lines and the other
   three take one. */
.zc-plans-row .pricing-header__title {
  font-size: 3.4rem;
  letter-spacing: -0.07rem;
}

.zc-plans-row .pricing-header__descr {
  font-size: 1.6rem;
  line-height: 1.5;
}


/* On the yearly term the amount is a division, so "$99" becomes "$274.08" —
   six glyphs at 7.4rem, which ran "/MONTH" off the right edge of the card.
   A long figure is set smaller, and the row may wrap rather than overflow if
   a tier's price ever grows another digit still. */
.zc-plans-row .pricing-data__num {
  flex-wrap: wrap;
}

.zc-plans-row .pricing-data__amount {
  font-size: 6.2rem;
  letter-spacing: -0.3rem;
}

.zc-plans-row .pricing-data__amount.zc-plan__long {
  font-size: 4.6rem;
  letter-spacing: -0.2rem;
}

/* ─────────────────────────────────────────────────────────────────────────
   A white page
   The template paints everything `--base`, a warm off-white, and every tone
   in it is picked against that. Painting only the page white leaves the body
   showing warm at the ends of the scroll and leaves every block that reads
   the token disagreeing with the surface under it, so the token is rebound
   here as well as the paint changed.
   ───────────────────────────────────────────────────────────────────────── */
body:has(.zc-page-white) {
  background-color: #ffffff;
}

.zc-page-white {
  --base: #ffffff;
  --base-rgb: 255, 255, 255;
  /* The tint is what every panel on these pages is filled with — the sidebar
     widgets, the contents list inside a post, the note at the foot of one.
     At its own #f9f7f7 it is six units off white and none of them read as
     panels at all, so it moves with the ground rather than staying put. */
  --base-tint: #f4f2f0;
  background-color: #ffffff;
}

/* `--base-tint` is #f9f7f7: six units off the warm ground and invisible
   against white. Anything that used the tint as its surface needs an edge
   instead. */
.zc-page-white .zc-comp {
  background-color: #fbfbfa;
  border: 1px solid rgba(18, 18, 18, 0.08);
}

/* ─────────────────────────────────────────────────────────────────────────
   The plan cards, as glass
   Two layers: a soft bloom of brand light sitting in the card's own footprint
   but outside the panel, and the panel itself, translucent and blurred so it
   picks the bloom up. On a white page there is nothing else behind the card
   to sample, so the light has to be put there — glass over nothing looks like
   a flat white box.
   ───────────────────────────────────────────────────────────────────────── */
.zc-plans-row .mxd-pricing-table__item {
  position: relative;
}

.zc-plan__aura {
  position: absolute;
  inset: 5rem 2rem;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  /* Three separated blooms rather than one wash. Overlapped, they add up to
     a flat green tint over the whole card, which reads as a highlight and
     not as light coming through glass — what makes it glass is the colour
     changing from one corner to the other. */
  background:
    radial-gradient(38% 26% at 16% 6%, rgba(193, 255, 114, 0.95), transparent 70%),
    radial-gradient(42% 30% at 88% 42%, rgba(129, 159, 254, 0.85), transparent 72%),
    radial-gradient(40% 28% at 30% 92%, rgba(126, 217, 87, 0.8), transparent 72%);
  filter: blur(44px);
  transform: scale(0.9);
  transition:
    opacity 0.5s var(--_animbezier),
    transform 0.6s var(--_animbezier);
}

.zc-plans-row .mxd-pricing-table__inner {
  position: relative;
  z-index: 1;
  background-color: rgba(255, 255, 255, 0.62);
  border: 1px solid rgba(18, 18, 18, 0.08);
  -webkit-backdrop-filter: blur(22px) saturate(1.5);
  backdrop-filter: blur(22px) saturate(1.5);
  transition:
    background-color 0.4s var(--_animbezier),
    border-color 0.4s var(--_animbezier),
    box-shadow 0.4s var(--_animbezier),
    transform 0.4s var(--_animbezier);
}

/* A thin sheen along the top edge, which is what makes a translucent panel
   read as a pane rather than as a tint. */
.zc-plans-row .mxd-pricing-table__inner::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.9) 30%,
    rgba(255, 255, 255, 0.9) 70%,
    transparent
  );
  opacity: 0;
  transition: opacity 0.4s var(--_animbezier);
  pointer-events: none;
}

/* `.no-touch` is the template's own guard — it keeps hover states off touch
   screens, where :hover sticks after a tap. */
.no-touch .zc-plans-row .mxd-pricing-table__item:hover .zc-plan__aura {
  opacity: 1;
  transform: scale(1.06);
}

.no-touch .zc-plans-row .mxd-pricing-table__inner:hover {
  /* The block's own hover sets this to `--base`, which on a white page is
     white — opaque, and the bloom disappears under it. */
  background-color: rgba(255, 255, 255, 0.46);
  border-color: rgba(18, 18, 18, 0.14);
  box-shadow: 0 24px 60px -30px rgba(18, 18, 18, 0.35);
  transform: translateY(-4px);
}

.no-touch .zc-plans-row .mxd-pricing-table__inner:hover::before {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .zc-plan__aura,
  .zc-plans-row .mxd-pricing-table__inner {
    transition: none;
  }
  .no-touch .zc-plans-row .mxd-pricing-table__inner:hover {
    transform: none;
  }
}


/* "Choose Studio" and "Choose Team" wrapped to two lines in the full-width
   button while "Buy credit" and "Talk to us" did not, so two of the four
   buttons were a line taller than the others. */
.zc-plans-row .pricing-data__btnholder .btn {
  font-size: 1.6rem;
}

/* The footer keeps the template's warm ground. The white is the argument's
   ground — the cards, the table, the receipt — and the footer is the site's
   furniture, the same on every page; carried white it read as another
   section of the page rather than the end of it. The token goes back with
   the paint, so the rules and muted type inside it are picked against what
   they actually sit on. */
.zc-page-white .mxd-footer {
  --base: #eeeae8;
  --base-rgb: 238, 234, 232;
  background-color: #eeeae8;
}


/* ─────────────────────────────────────────────────────────────────────────
   /blog
   ───────────────────────────────────────────────────────────────────────── */

/* Two things wrong in the block itself.
   `.recent-post__thumb` is a 120px square painted `background-color: yellow`
   — a debug fill the template author left in, invisible there only because
   their thumbnails happen to cover it. And the anchor inside is `display:
   block` with no height, so the image resolves to its own 3:2 ratio, stands
   90px tall in a 120px box, and the last 30px of every thumbnail is that
   yellow. Fill the square and drop the paint. */
.widget__recent-posts .recent-post__thumb {
  background-color: var(--base-tint);
}

.widget__recent-posts .recent-post__thumb a {
  display: block;
  width: 100%;
  height: 100%;
}

.widget__recent-posts .recent-post__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The featured post sets its words in white over the picture. The template's
   images are photographs and dark enough to carry that; ours are line
   drawings on near-white, and the block's scrim is not built for them. */
.post-featured__cover {
  background: linear-gradient(
    180deg,
    rgba(15, 15, 15, 0.25) 0%,
    rgba(15, 15, 15, 0.62) 55%,
    rgba(15, 15, 15, 0.82) 100%
  );
}

/* The one line in a post that is a figure or a rule rather than an argument. */
.zc-article-note {
  margin-top: 2.4rem;
  padding: 1.6rem 2rem;
  border-left: 2px solid var(--accent);
  background-color: var(--base-tint);
  font: normal 400 1.5rem/1.6 var(--_font-accent);
  color: var(--t-medium);
}

.zc-sidebar-cta {
  margin-top: 2rem;
}


/* The section headings inside a post.
   The template's article sets them as `h3`, because its title is an `h2`.
   Ours is an `h1` — it is the page's only title and it should say so to a
   screen reader — which makes the sections `h2`, and the global `h2` is the
   size a section title on a landing page wants, not the size of a heading in
   running text. So the tag is chosen for the document and the size here. */
.mxd-article__block h2 {
  font: normal 700 3rem/1.25 var(--_font-default);
  letter-spacing: -0.1rem;
  color: var(--t-bright);
}

@media only screen and (min-width: 768px) {
  .mxd-article__block h2 {
    font-size: 3.6rem;
  }
}

/* `.article-ul` is in the template's article markup and has no rule anywhere
   in its CSS, so the lists came out on browser defaults: no gap, no hanging
   indent, and every wrapped line running back to the margin under its own
   bullet. */
.mxd-article__content .article-ul {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  margin: 0;
  padding-left: 2.6rem;
  list-style: disc outside;
}

.mxd-article__content .article-ul li {
  padding-left: 0.6rem;
  font: normal 500 1.8rem/1.6 var(--_font-default);
  color: var(--t-medium);
}

.mxd-article__content .article-ul li::marker {
  color: var(--st-medium);
}

.mxd-article__content .article-ul li strong {
  font-weight: 700;
  color: var(--t-bright);
}


/* Previous and next, at the foot of a post.
   The template's titles are four or five words; ours run to eight, and the
   two buttons sit in `col-6` columns with nothing stopping their captions
   growing past them — measured, "Seven stages, and you approve every one"
   and "The cheapest place to disagree is the treatment" overlapped in the
   middle of the row, printing one title over the other. Let the caption wrap
   inside its own column, and keep the two apart. */
.mxd-article-navigation__navitem {
  min-width: 0;
  padding-right: 1.6rem;
}

.mxd-article-navigation__navitem.right {
  padding-right: 0;
  padding-left: 1.6rem;
}

.mxd-article-navigation__link {
  max-width: 100%;
}

.mxd-article-navigation__link .btn-caption {
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: left;
}

.mxd-article-navigation__navitem.right .mxd-article-navigation__link .btn-caption {
  text-align: right;
}


/* The article ends on a ruled row of previous/next links, and this block
   opens on a heading set very large. Without a gap the two touch and the
   heading reads as a label on the rule. */
.zc-more {
  padding-top: 9rem;
}


/* `bg-base-tint` and `radius-m` are in the template's sidebar markup and
   neither has a rule anywhere in its CSS — measured, the About and Try-it
   widgets come out fully transparent with no padding and no radius. They are
   meant to be panels, so here they are panels. */
.mxd-sidebar__widget.bg-base-tint {
  padding: 2.8rem;
  background-color: var(--base-tint);
}

.mxd-sidebar__widget.radius-m {
  border-radius: var(--_radius-m, 1.2rem);
}

/* ─────────────────────────────────────────────────────────────────────────
   Inside a post
   The template's article block styles its own paragraph, excerpt and quote
   and nothing else. Everything below is a shape it has no rule for.
   ───────────────────────────────────────────────────────────────────────── */

/* Links inside running text. Underlined, because a colour change alone is
   not enough to identify a link to a reader who cannot see the colour. */
.mxd-article__content a.zc-article-link {
  color: var(--t-bright);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--st-medium);
  transition: text-decoration-color 0.2s ease;
}

.mxd-article__content a.zc-article-link:hover {
  text-decoration-color: var(--t-bright);
}

.zc-article-h3 {
  font: normal 700 2.2rem/1.35 var(--_font-default);
  letter-spacing: -0.04rem;
  color: var(--t-bright);
}

/* Ordered lists, where the number is the content. */
.mxd-article__content .article-ol {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  margin: 0;
  padding-left: 2.6rem;
  list-style: decimal outside;
}

.mxd-article__content .article-ol li {
  padding-left: 0.6rem;
  font: normal 500 1.8rem/1.6 var(--_font-default);
  color: var(--t-medium);
}

.mxd-article__content .article-ol li::marker {
  font-family: var(--_font-accent);
  font-size: 1.5rem;
  color: var(--t-muted);
}

.mxd-article__content .article-ol li strong,
.mxd-article__content .article-ul li strong {
  font-weight: 700;
  color: var(--t-bright);
}

/* Tables in running text. Scrolls on its own rather than the page. */
.zc-article-table {
  overflow-x: auto;
  border-top: 1px solid var(--st-bright);
}

.zc-article-table table {
  width: 100%;
  min-width: 46rem;
  border-collapse: collapse;
  text-align: left;
}

.zc-article-table th,
.zc-article-table td {
  padding: 1.6rem 2.4rem 1.6rem 0;
  border-bottom: 1px solid var(--st-muted);
  vertical-align: top;
  font: normal 500 1.5rem/1.5 var(--_font-default);
  color: var(--t-medium);
}

/* Every cell but the first in its row gets a left gutter. Without it the
   columns butt straight against each other and a long value in one reads as
   though it runs into the next. */
.zc-article-table th + th,
.zc-article-table th + td,
.zc-article-table td + td {
  padding-left: 2.4rem;
}

.zc-article-table tr > *:last-child {
  padding-right: 0;
}

/* Proportions rather than whatever the content negotiates. Left to itself the
   row label came out at 123px and the last column at 569px, which is a label
   squeezed to two lines beside a column with room to spare. */
.zc-article-table tbody th {
  width: 22%;
  font-weight: 700;
  color: var(--t-bright);
}

.zc-article-table tbody td:first-of-type {
  width: 28%;
  /* The column people scan down. Mono lines the figures and units up. */
  font-family: var(--_font-accent);
  font-size: 1.4rem;
  color: var(--t-bright);
  font-variant-numeric: tabular-nums;
}

.zc-article-table thead th {
  font: normal 400 1.2rem/1.4 var(--_font-accent);
  text-transform: uppercase;
  letter-spacing: 0.08rem;
  color: var(--t-muted);
  border-bottom-color: var(--st-bright);
}

/* A three-column table of prose is unreadable much below this, and the
   article column on a phone is far below it. Scroll it rather than crush it. */
@media only screen and (max-width: 767px) {
  .zc-article-table table {
    min-width: 52rem;
  }
}

/* The short version, at the top. The one block on the page written for
   somebody who is not going to read the rest. */
.zc-takeaways {
  padding: 3rem;
  border-left: 3px solid var(--accent);
  background-color: var(--base-tint);
}

@media only screen and (min-width: 768px) {
  .zc-takeaways {
    padding: 3.4rem 4rem;
  }
}

.zc-takeaways .mxd-check-list li {
  align-items: flex-start;
}

/* Questions, answered visibly. This is the block `FAQPage` describes, and
   it exists for the reader first — the markup is only allowed because the
   answers are here to be read. */
.zc-faq__item {
  padding-top: 2.4rem;
  border-top: 1px solid var(--st-muted);
}

.zc-faq__item:first-of-type {
  border-top: 0;
  padding-top: 0;
}

.zc-faq__q {
  margin-bottom: 1rem;
  font: normal 700 2rem/1.35 var(--_font-default);
  letter-spacing: -0.03rem;
  color: var(--t-bright);
}

.zc-faq__a {
  font: normal 500 1.7rem/1.6 var(--_font-default);
  color: var(--t-medium);
}

/* Who wrote it. No portrait and no invented biography — what is here is
   what can be checked. */
.zc-byline {
  padding: 3rem;
  background-color: var(--base-tint);
}

.zc-byline__name {
  margin-top: 1.2rem;
  font: normal 700 2rem/1.4 var(--_font-default);
  color: var(--t-bright);
}

.zc-byline__bio {
  margin-top: 0.8rem;
  font: normal 500 1.6rem/1.6 var(--_font-default);
  color: var(--t-medium);
}

/* ── Share ──
   Four controls on one row, each a bordered pill with its glyph. They were
   unstyled and ran together as one word: "XLinkedInEmailCopy link". */
.zc-share__label {
  font: normal 400 1.4rem/1.4 var(--_font-accent);
  text-transform: uppercase;
  letter-spacing: 0.08rem;
  color: var(--t-muted);
}

.zc-share__row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1.8rem;
}

.zc-share__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.8rem;
  border: 1px solid var(--st-muted);
  border-radius: 0.4rem;
  background: transparent;
  font: normal 500 1.4rem/1 var(--_font-accent);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--t-bright);
  cursor: pointer;
  transition:
    border-color 0.25s ease,
    background-color 0.25s ease,
    color 0.25s ease;
}

.zc-share__btn svg {
  display: block;
  fill: currentColor;
  flex: none;
}

.no-touch .zc-share__btn:hover {
  border-color: var(--t-bright);
  background-color: var(--t-bright);
  color: var(--base);
}

.zc-share__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.zc-share__btn--copy {
  /* The label swaps to "Link copied" on success, which is two characters
     wider than "Copy link". Without a floor the row twitches. */
  min-width: 15rem;
  justify-content: center;
}

.zc-share__url {
  margin-top: 1.6rem;
  font: normal 400 1.3rem/1.4 var(--_font-accent);
  color: var(--t-muted);
  word-break: break-all;
}

/* The template's article column is 870px on a wide screen; the share row
   and the byline sit inside it like everything else. */
@media only screen and (max-width: 575px) {
  .zc-share__btn {
    flex: 1 1 auto;
    justify-content: center;
  }
}

/* The check list is the template's feature list: uppercase mono, sized for
   two or three words. Set in it, a full sentence is a wall of capitals — the
   takeaways are the one block on the page meant to be read fastest, and
   uppercase is the slowest thing to read. */
.zc-takeaways .mxd-check-list {
  gap: 1.4rem;
}

.zc-takeaways .mxd-check-list li span {
  font: normal 500 1.6rem/1.55 var(--_font-default);
  text-transform: none;
  letter-spacing: 0;
  color: var(--t-bright);
}

.zc-takeaways .mxd-check-list li svg {
  margin-top: 0.4rem;
}

.zc-takeaways .table-of-contents__title {
  margin-bottom: 2rem;
}

/* The four posts on the homepage.
   The block's stagger comes from its pictures disagreeing about their shape —
   its own four are 1.47, 1.00, 0.67 and 1.78. The blog's drawings are all
   landscape, at 1.34 or 1.79, so alternating them gives a much shallower
   rhythm than the block was built for. The third card is cropped to portrait
   to put the depth back. */
@media only screen and (min-width: 992px) {
  .zc-home-posts__item:nth-child(3) .mxd-blog-item__media img {
    aspect-ratio: 3 / 4;
    height: auto;
    object-fit: cover;
  }

  .zc-home-posts__item:nth-child(2) .mxd-blog-item__media img {
    aspect-ratio: 1 / 1;
    height: auto;
    object-fit: cover;
  }
}

/* The "every plan makes the same film" line under the plan cards. The cards
   end and the sentence began 12px later, which read as a footnote to the last
   card rather than a statement about all four. */
.zc-plans-note {
  margin-top: 4rem;
}

@media only screen and (max-width: 767px) {
  .zc-plans-note {
    margin-top: 3.5rem;
  }

  /* On a phone the caption stacks over the cards and ran straight into the
     first one. The root is 10px, so this is 40px of air. */
  .zc-plans-caption {
    margin-bottom: 4rem;
  }
}

/* The heading sat tight on the caption under it on a phone and on the cards
   beside it on a desktop. Three classes deep because the template's
   `.mxd-section-title__title.pre-caption` sets this margin at every width and
   a single class loses to it. */
.mxd-section-title__title.pre-caption.zc-plans-heading {
  margin-bottom: 4rem;
}
@media only screen and (min-width: 1200px) {
  .mxd-section-title__title.pre-caption.zc-plans-heading {
    margin-bottom: 5rem;
  }
}

/*
 * The scroll blur is a desktop effect.
 *
 * `.blur-container` is a fixed 240px strip of progressive backdrop-blur along
 * the bottom of the viewport, switched on whenever a section is in view. On a
 * 1000px-tall desktop it is the soft edge of the page. On a 664px phone it is
 * over a third of the screen, and on the audience cards — whose pictures sit
 * at the bottom of a tall card — it sat over the picture the whole time the
 * card was being read. `!important` because the effect sets `display: block`
 * inline as sections come and go.
 */
@media only screen and (max-width: 767px) {
  .blur-container {
    display: none !important;
  }
}

/* "Your face. Your voice. Your choice." sat at 0px from the top of its
   section: the block has no top padding of its own, and on a phone nothing
   above it lends any. 60px, the root being 10px. */
@media only screen and (max-width: 767px) {
  #face-voice .mxd-section-title {
    padding-top: 6rem;
  }
}

/* The tint veil on the full-bleed audience cards (Families, Authors) is
   solid card colour at the top of the picture fading to clear at the bottom.
   On a desktop it blends a picture that sits *behind* the words into the
   card. On a phone the picture sits *below* the words, so the veil only
   fogged the top half of the family and the writer. */
@media only screen and (max-width: 767px) {
  #audiences .mxd-niche-cards__gradient {
    display: none;
  }
}

/* The section labels were the template's "A/01" and "C/02" — an index for a
   portfolio, meaning nothing here. They are words now, and words at the
   number's 60px do not fit their column, so the size steps down and the
   tracking loosens from a numeral's to a word's. */
.title-number.zc-title-word {
  font-size: 2.6rem;
  letter-spacing: -0.06rem;
  line-height: 1.05;
}
@media only screen and (min-width: 768px) {
  .title-number.zc-title-word { font-size: 3.2rem; letter-spacing: -0.08rem; }
}
@media only screen and (min-width: 1200px) {
  /* 3.4, not 3.8: the column is 427px and "Three things to make" in the
     mono runs 456px at 38px. */
  .title-number.zc-title-word { font-size: 3.4rem; letter-spacing: -0.1rem; }
}

/* A hero headline whose accent will not fit a phone at 60px. See `compact` in
   Hero.tsx: only "you can hold." is marked, and only phones are affected. */
@media only screen and (max-width: 767px) {
  .zc-hero-name--compact h1,
  .zc-hero-name--compact p {
    font-size: 44px;
    line-height: 1.1;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   The homepage's closing sections
   ───────────────────────────────────────────────────────────────────────── */

/* The band under "What will you make?". The template carried its picture on
   `divider-image-4`, so changing the picture meant leaving the class behind. */
.zc-divider-make {
  background-image: url(/marketing/home/divider-make.jpg);
}

/* The fanned triple under "What will you make?".
   The block drops its two outer pictures to 30% opacity, which works on the
   flat GIF it shipped and turns a photograph into a grey smear. They are
   three finished things here and all three should be legible; the outer two
   sit back through scale and a light veil instead. */
.mxd-divider-gif__back img {
  opacity: 0.78;
}

.mxd-divider-gif__back {
  transform: scale(0.94);
}

.mxd-divider-gif__front,
.mxd-divider-gif__back {
  border-radius: 0.6rem;
  overflow: hidden;
}

.mxd-divider-gif__front {
  box-shadow: 0 22px 50px -26px rgba(18, 18, 18, 0.45);
}

/*
 * The Templates button stops colliding with the headline.
 *
 * The block centres its controls row (`top: 50%`) and anchors the headline to
 * the floor (`bottom: 90px`). In the template that never meets, because the
 * hero name there is one short word on one line. Ours is two lines and 455px
 * tall, so the headline's top is at `100vh - 545px` and the button's bottom
 * at `50vh + 14px` — which collide on any viewport shorter than about 1118px,
 * i.e. most laptops. Measured at 1000px tall the overlap was 59px, and at
 * 760px it was 179px: "[ TEMPLATES ]" printed straight through "Imagine it."
 *
 * Anchoring the row to the top instead of the middle fixes it for good rather
 * than for one window size: the button is measured down from the header and
 * the headline up from the floor, so they move apart as the viewport grows
 * instead of towards each other.
 */
@media only screen and (min-width: 992px) {
  .mxd-hero-04__controls {
    /* Clamped rather than fixed: at 16rem flat the button still ran into the
       headline on a 700px-tall window, which is a real laptop with a lot of
       browser chrome. The clamp pulls it up on short viewports and lets it
       breathe on tall ones. */
    top: clamp(9rem, 12vh, 16rem);
    /*
     * The row spans the hero instead of sitting on one line of it.
     *
     * The two controls in it want opposite ends: "Templates" is a link into
     * the site and belongs up by the header, and "Scroll to explore" is an
     * instruction about the bottom of the screen and belongs at the bottom of
     * the screen. Centred together they were both in the middle; moved up
     * together to clear the headline they were both under the header, which
     * is where the scroll cue made least sense of all.
     *
     * At this width the row is horizontal, so the two are distributed along
     * it and the cross axis is what puts one at the top and the other at the
     * bottom. Stretching the row and using `justify-content` was the wrong
     * axis entirely: measured, both children grew to 700px tall and the cue
     * stayed exactly where it was.
     *
     * The offset comes off the arrow rather than being picked. The pixel
     * arrow on the band is 21.4rem tall and sits 10rem clear of the floor —
     * measured, `top` resolves to `100vh - 314px` at every height — so the
     * line above it with a gap is 10 + 21.4 + 2.4. Dropped to the floor
     * instead, the cue printed across the arrow's bottom two rows.
     */
    bottom: 33.8rem;
    align-items: flex-start;
    transform: none;
  }

  .mxd-hero-04__right {
    align-self: flex-end;
  }
}


/*
 * The scroll cue takes its ink from whatever is behind it.
 *
 * The controls row is not in the slider — it stays put while the slides
 * travel under it — and the volt band is part of the first slide's plate, so
 * it travels. The cue is therefore over the band on slide one and over a
 * picture on the other three, and those want opposite ink.
 *
 * White is the default, because three of the four slides are dark pictures
 * and that is what the template sets. On slide one it takes the ink that goes
 * on our accent everywhere else: the template's white works on its own deep
 * pink, and on volt it was the hardest thing to read on the page it is meant
 * to be instructing.
 *
 * `data-slide` comes from the slider, which is the only thing that knows.
 */
.mxd-hero-04__right .btn-caption,
.mxd-hero-04__right .btn,
.mxd-hero-04__right svg {
  color: var(--nl-white, #ffffff);
  fill: var(--nl-white, #ffffff);
  transition:
    color 0.25s ease,
    fill 0.25s ease;
}

@media only screen and (min-width: 1200px) {
  /* Only where there is a band to sit on. Below 1200px it is hidden and the
     cue is over the picture, where white is right. */
  [data-slide="0"] .mxd-hero-04__right .btn-caption,
  [data-slide="0"] .mxd-hero-04__right .btn,
  [data-slide="0"] .mxd-hero-04__right svg {
    color: var(--pt-t-accent-bright, #09090b);
    fill: var(--pt-t-accent-bright, #09090b);
  }
}

/*
 * The header's right-hand cluster, where it sits on the volt band.
 *
 * `mxd-header-permanent` paints everything in the header white, which is
 * right over the dark plates on /for/ and right over the left of the
 * homepage's opener — the wordmark is on the picture. It is wrong for the two
 * things that land inside the accent rectangle: measured, "Get started" spans
 * 1370–1483 and the burger 1518–1573, inside a band starting at 1180, and
 * both were white on volt.
 *
 * They take the ink that goes on our accent everywhere else. See the effect
 * in Header1 for why the flag is on the document rather than on the header.
 */
[data-hero-band] .mxd-header-permanent .mxd-header__link,
[data-hero-band] .mxd-header-permanent .mxd-header__link .btn-caption {
  color: var(--pt-t-accent-bright, #09090b);
}

/*
 * The burger is left alone, and that took a measurement to establish.
 *
 * `.mxd-menu__contain` carries `mix-blend-mode: difference`, so its bars are
 * composited against whatever is behind rather than painted over it. On volt
 * the template's white lands at rgb(62, 0, 141) — the dark purple you can
 * see — and darkening them to rgb(9, 9, 11) lands at rgb(184, 246, 103),
 * which is volt with the faintest tint. Made "correct" they disappeared.
 */

/* Below 1200px there is no band, so "Get started" is back over the picture
   and back to white. This boundary has to be the same one the band uses or
   the ink goes dark on a dark photograph. */
@media only screen and (max-width: 1199px) {
  [data-hero-band] .mxd-header-permanent .mxd-header__link,
  [data-hero-band] .mxd-header-permanent .mxd-header__link .btn-caption {
    color: var(--nl-white, #ffffff);
  }
}

/*
 * No scroll cue on a phone.
 *
 * Above 768px the controls are a row and the cue sits opposite "Templates"
 * with the width of the screen between them. Below it the row becomes a
 * column, so the two stack — and they stack in the middle of the picture,
 * directly over the headline's air, which is the one place in the hero
 * nothing should be.
 *
 * Of the two, the cue is the one to drop. "Templates" is a way into the site
 * and cannot be reached otherwise from here; "Scroll to explore" is an
 * instruction to do the thing a phone does by default.
 */
@media only screen and (max-width: 767px) {
  .mxd-hero-04__right {
    display: none;
  }
}

/*
 * Pointer-trail heroes on a device with no pointer.
 *
 * The trail images sit at opacity 0 until the pointer moves over them, so on
 * a touch screen they never appear — and on /make/stories they are the only
 * picture in the hero, which left a page about picture books with no picture
 * on it.
 *
 * They also cost a horizontal scrollbar. Each is scaled 1.2 with no clipping
 * ancestor, so at 390px the document measured 393 and the page could be
 * dragged sideways. `display: none` takes them out of layout rather than just
 * hiding them, which is what removes the 3px.
 *
 * `(hover: none)` rather than a width, because the condition is not how wide
 * the screen is — it is whether anything can hover. A narrow desktop window
 * still gets the trail; a large tablet never could.
 */
@media (hover: none) {
  .mxd-trail-transparent-wrapper {
    display: none;
  }
}

/* The fan that replaces it. Only where the trail cannot run. */
.zc-hero-still {
  display: none;
}

@media (hover: none) {
  .zc-hero-still {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 1.2rem;
    margin-bottom: 3rem;
    pointer-events: none;
  }

  .zc-hero-still img {
    width: 30%;
    height: auto;
    border-radius: 0.6rem;
    box-shadow: 0 18px 40px -22px rgba(18, 18, 18, 0.5);
  }

  /* A fan, not a row: the middle one stands up and the outer two lean away,
     which is how the trail reads when it is moving. */
  .zc-hero-still img:first-child {
    transform: rotate(-7deg) translateY(1.2rem);
  }

  .zc-hero-still img:last-child {
    transform: rotate(7deg) translateY(1.2rem);
  }
}

/*
 * Wide pictures in a full-height card, on a phone.
 *
 * The stacking cards are 100vh tall, and `.card__image img/video` covers
 * them. On a laptop that box is roughly 16:9 and the cover crop takes almost
 * nothing. On a phone it is 390x844 — a ratio of 0.46 against the art's 1.78
 * — so 26% of each picture is shown and the rest is thrown away. Measured
 * across /for/kids and /for/teachers: every idea clip and every panel.
 *
 * Some survive it. A character standing upright in the middle of the frame
 * reads fine as a tall slice. A wide one does not: the water cycle on
 * /for/teachers lost its sea and its vapour ring, which is most of the
 * diagram the card is captioned after.
 *
 * So on a phone the picture sits whole inside the card instead of filling it.
 * The card keeps its own ground behind, which is what stops the letterbox
 * reading as a loading state.
 */
@media only screen and (max-width: 767px) {
  .mxd-stack-cards__card .card__image,
  .mxd-dv-sticky-img__images {
    background-color: #0f0f0f;
  }

  .mxd-stack-cards__card .card__image img,
  .mxd-stack-cards__card .card__image video,
  /* The numbered panels are a different block with the same fault: the
     pictures fill a 100vh sticky frame and 26% of each one shows. */
  .mxd-dv-sticky-img__images img,
  .mxd-dv-sticky-img__images video {
    object-fit: contain;
    /*
     * Held near the top rather than centred.
     *
     * Centred, the picture is a strip floating in the middle of a black
     * screen with the card's title printed across it and empty ground above
     * and below. Pushed up it becomes a card: picture at the top at its own
     * ratio, the title underneath it in the dark, the caption at the foot.
     */
    object-position: 50% 18%;
  }
}

/*
 * The numbered panels get a ground of their own.
 *
 * `.mxd-dv-sticky-img` and everything down to its sticky frame are fully
 * transparent — measured, `rgba(0, 0, 0, 0)` at every level. Both it and the
 * statement above it are pinned, so while one hands over to the other they
 * are both on screen and the statement's "[ START CREATING ]" prints straight
 * through the panel's picture.
 *
 * Black rather than the page ground, because these panels are dark
 * photographs and their letterbox on a phone is already black.
 */
.mxd-dv-sticky-img {
  position: relative;
  z-index: 1;
  background-color: #0f0f0f;
}

/*
 * The statement reads over the pictures passing behind it.
 *
 * The block scrolls its image rows behind a centred statement. On a wide
 * screen the pictures are small against the words and it works. On a phone
 * they are nearly the full width: measured, the caption runs 296 to 598 and
 * the first picture starts at 444, so half the sentence sits on a photograph
 * with nothing between them.
 *
 * The pictures stay — they are the effect — but they sit back far enough for
 * the words to win.
 */
@media only screen and (max-width: 767px) {
  .mxd-dv-sticky-cap__scroll {
    opacity: 0.28;
  }

  /*
   * `isolation` matters here. The image rows come after the words in the
   * markup, so without a z-index they paint on top of them — but a bare
   * z-index on the words escaped the section and put the button above the
   * panels below, which is the bleed-through this was meant to stop. The
   * isolate keeps the whole contest inside this block.
   */
  .mxd-dv-sticky-cap {
    isolation: isolate;
  }

  .mxd-dv-sticky-cap__content {
    position: relative;
    z-index: 2;
  }
}

/*
 * The panel title needs room for the title it has.
 *
 * `.mxd-dv-sticky-img__titlelist` is a fixed window with its titles absolutely
 * positioned inside it, so it cannot grow to its contents. The template sets
 * 68px, 71px and 124px, which fits the one-line titles it ships with. Ours are
 * sentences: measured, the tallest is 172px at 390, 140px at 768 and 195px at
 * 1440 — so at every width the last line or two fell out of the window and
 * printed over the "Start creating" button underneath it.
 *
 * Sized to the real measurements with a little room, rather than to the
 * template's assumption about how long a title is.
 */
.mxd-dv-sticky-img__titlelist {
  height: 18rem;
}

@media only screen and (min-width: 768px) {
  .mxd-dv-sticky-img__titlelist {
    height: 15rem;
  }
}

@media only screen and (min-width: 1200px) {
  .mxd-dv-sticky-img__titlelist {
    height: 21rem;
  }
}
