/* Intro — design node 464:84118 (x -0.5, y 897, w 1601, h 726).

   The wrapper is TRANSPARENT and only the panel inside is painted. It used to
   be green to fill the panel's two rounded top corners, but that wrapper is
   full-section-height and opaque, so it covered the sticky hero as the intro
   rode up — green showing over DONK and the flocked shapes (client,
   2026-08-25). Transparent lets the corner notches reveal the hero instead,
   which is what the cover-reveal is for. */

.rdk-intro {
  position: relative;
  z-index: 1;
}

.rdk-intro__panel {
  display: flex;
  flex-direction: column;
  gap: calc(144 * var(--u));
  overflow: clip;
  padding: calc(96 * var(--u)) calc(88 * var(--u));
  background: var(--rdk-black-green);
  border-radius: calc(96 * var(--u)) calc(96 * var(--u)) 0 0;
}

/* ---------- headline ---------- */

.rdk-intro__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: calc(48 * var(--u));
}

.rdk-intro__headline {
  display: flex;
  flex-direction: column;
  gap: calc(2 * var(--u));
  /* --du, not --u: the four designed rows are `white-space: nowrap`, so the
     measure has to floor WITH the type or they run straight out of it —
     measured 45px of overflow at 820 before this. Type and the measure it
     was drawn against are one object. */
  width: calc(892 * var(--du));
  /* Redonk Avant Garde Bold, confirmed against nodes 464:84123 et al —
     NOT Satoshi. 55/46 is Figma's rendered line box over the type size. */
  font-family: var(--rdk-font-brand);
  font-weight: 700;
  font-size: calc(46 * var(--du));
  line-height: calc(55 * var(--u));
  letter-spacing: calc(-1.15 * var(--du));
  color: var(--rdk-white);
}

/* Each designed line is its own flex row so the inline chips sit on the
   baseline grid without being torn apart by a line-splitter. */
.rdk-intro__line {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
  white-space: nowrap;
}

/* The last row closes to 8 (node 1:579). Its chip ENDS the sentence rather
   than sitting between two runs of words, so the designed 12 reads as a gap
   after a full stop. */
.rdk-intro__line--tight {
  gap: calc(8 * var(--u));
}

/* ALL FOUR CHIPS ARE THE SAME OBJECT NOW (node 1:553, 2026-09-15): a 52 box
   on rgba(0,191,0,0.15) at radius 8, holding a flocked green thing. The
   outlined and pill-round variants are gone with them, and so are
   `icon-random.svg` and `icon-color-palette.svg` — the design has one chip
   now, not three. */
.rdk-intro__chip {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  overflow: clip;
  width: calc(52 * var(--u));
  height: calc(52 * var(--u));
  background: rgba(0, 191, 0, 0.15);
  border-radius: calc(8 * var(--u));
}

/* `--icon` is the object's size PER CHIP, because two of the four are drawn
   LARGER than the box (61 and 63 in a 52) and are clipped by it — that crop
   is the design, not an accident. `--icon-y` nudges those two down off dead
   centre, the only way the node's -2.5 top differs from a centred 61 or 63.

   SIZED AS A SHARE OF THE CHIP, NOT IN DESIGN UNITS, so the crop is identical
   at every width including the phone, where the box is 8vw rather than 52u.
   Written as `--icon * --u` instead, the phone needed its own icon size — and
   any number picked there is a second crop to keep in step with this one.
   One rule, one proportion, both breakpoints.

   The 2x on the nudge is because a CENTRED flex item shares its margin with
   the free space on the other side, so a margin of n shifts it by n/2.
   Measured: 2 and 3 design units, exactly as the node has them.

   margin-top, not `translate`: js/intro.js's word sequence transforms the
   CHIP, and GSAP clears the standalone properties on anything it takes a
   transform over. The img is a different element, but keeping the nudge off
   transforms entirely means the two can never meet. */
.rdk-intro__chip img {
  width: calc(var(--icon, 41) / 52 * 100%);
  height: calc(var(--icon, 41) / 52 * 100%);
  margin-top: calc(var(--icon-y, 0) / 52 * 200%);
  max-width: none;
}

/* Figma sets these in "Avantt TRIAL" SemiBold/Regular — a trial face we do
   not have and which is not one of the project's two fonts. Satoshi carries
   the weight contrast (600 vs 400) that the design actually relies on;
   Redonk Avant Garde could not, since Bold is the only weight we have. */
/* Restyled in the 2026-08 file (node 1:589): Satoshi Variable BOLD at 15/1.5,
   in green/500 — it used to be Avantt SemiBold at 12/1.2 in Redonk Lime, and
   the separators used to drop to Regular. They are now the same weight, just
   a point smaller. `frac` is enabled on every one of these label runs in the
   design; it is inert for this copy (Satoshi's frac only fires on digit /
   digit) but it is what the design specifies. */
.rdk-intro__tags {
  display: flex;
  flex: none;
  align-items: center;
  gap: calc(16 * var(--u));
  font-family: var(--rdk-font-body);
  font-weight: 700;
  font-size: calc(15 * var(--u));
  letter-spacing: calc(1.5 * var(--u));
  font-feature-settings: "frac" 1;
  text-transform: uppercase;
  color: var(--rdk-green);
}

.rdk-intro__tags span:nth-child(even) {
  font-size: calc(14 * var(--u));
  letter-spacing: calc(1.4 * var(--u));
}

/* ---------- body + video ---------- */

.rdk-intro__bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: calc(48 * var(--u));
}

.rdk-intro__body {
  width: calc(683 * var(--u));
  font-family: var(--rdk-font-body);
  font-weight: var(--rdk-body-weight);
  font-size: var(--rdk-body-xl);
  line-height: var(--rdk-body-lh-xl);
  letter-spacing: var(--rdk-body-track);
  /* Two STYLISTIC SETS, both enabled on this node in Figma (1:596):
     ss02 swaps in the single-storey `g`, ss03 the alternate `t` and `4`.
     Every `t` and `g` in this paragraph changes shape — it is not subtle. */
  font-feature-settings: "ss03" 1, "ss02" 1;
  /* Balance, not the body's inherited `pretty` (client, 2026-09-24: "weird
     rag"). `pretty` only rescues a short LAST line; this paragraph's trouble
     was the whole shape — two long lines then two short ones. Five lines is
     inside Chrome's balance limit, and an unsupported browser simply wraps as
     before. */
  text-wrap: balance;
  /* Full white is the NO-JS resting state on purpose. js/intro.js dims the
     words and then fills them back in on scroll, so if GSAP never loads the
     copy is still readable rather than 15%-opacity ghost text. */
  color: var(--rdk-white);
}

/* ---------- "Meet Donk!" (node 1:597) ----------
   Standing in the showreel's slot until there is a film. It keeps the video
   button's exact 328 x 164 green box, which is the point: the bottom row is
   `space-between` with a 683 paragraph in a 1409 measure, so an empty slot
   leaves 726 of dark — half the row — and the intro becomes the only band on
   the page with no object in it at all.
   `.rdk-intro__video` and the whole `.rdk-video` overlay below are LEFT IN
   PLACE and inert: `initVideo()` already returns early when there is no
   thumbnail, so putting the button back is a markup change and nothing
   else. */
.rdk-intro__meet {
  position: relative;
  flex: none;
  width: calc(328 * var(--u));
  height: calc(164 * var(--u));
  overflow: clip;
  background: var(--rdk-green);
  border-radius: calc(40 * var(--u));
}

/* The words are `aria-hidden` and the img's alt carries "Meet Donk" instead —
   two absolutely placed runs that Donk paints over would otherwise be read
   out as fragments either side of him. */
.rdk-intro__meet-word {
  position: absolute;
  top: calc((82 - 23.32) * var(--u));
  font-family: var(--rdk-font-brand);
  font-weight: 700;
  font-size: calc(36.712 * var(--du));
  line-height: 1.2;
  letter-spacing: calc(-1.1014 * var(--du));
  white-space: nowrap;
  color: var(--rdk-white);
  translate: -50%;
}

.rdk-intro__meet-word--l { left: calc((164 - 100.5) * var(--u)); }
.rdk-intro__meet-word--r { left: calc((164 + 105) * var(--u)); }

/* HE IS TALLER THAN THE BOX AND CLIPPED BY IT — 269 in a 164, his centre 15.5
   below the box's, so the frame cuts 37 off his heads and 68 off his feet.
   That crop is the design.
   Placed with MARGINS off a 50%/50% anchor rather than a percentage
   `translate`, so `transform` stays entirely GSAP's — the DONK-rig split the
   hero and the services cursor both use. -119 is 15.5 - 134.5, and -97.75 is
   -0.11 - 97.64. */
.rdk-intro__donk-rig {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(195.281 * var(--u));
  height: calc(269 * var(--u));
  margin: calc(-119 * var(--u)) 0 0 calc(-97.75 * var(--u));
}

/* Pivoting at his FEET, which sit 68 below the box's bottom edge — so the
   sway reads as a pendulum hanging from off-screen and his heads travel
   furthest, the same arrangement as the pricing hero's Donk. */
.rdk-intro__donk {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  transform-origin: 50% 100%;
}

.rdk-intro__video {
  position: relative;
  flex: none;
  width: calc(328 * var(--u));
  height: calc(164 * var(--u));
  padding: 0;
  overflow: clip;
  background: var(--rdk-green);
  border-radius: calc(40 * var(--u));
  cursor: pointer;
}

.rdk-intro__video-donk {
  position: absolute;
  left: 50%;
  top: calc(50% + 15 * var(--u));
  width: calc(208 * var(--u));
  height: calc(286 * var(--u));
  max-width: none;
  /* Standalone properties, not the `transform` shorthand — js/intro.js drives
     this element's transform for the open/close flip. */
  translate: -50% -50%;
}

.rdk-intro__video-play {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(64 * var(--u));
  height: calc(64 * var(--u));
  max-width: none;
  translate: -50% -50%;
}

@media (max-width: 767px) {
  /* GREEN behind the panel, so the rounded top corners are visible at rest.

     They always were rounded; there was just nothing behind them to see.
     `.rdk-intro` is transparent by design (see the note at the top of this
     file) so the corner notches reveal the sticky hero — which works on
     desktop, where the hero is 100svh and therefore always behind them. The
     mobile hero is capped at its frame's 435, so at scroll 0 the intro's top
     edge sits exactly where the hero ENDS: behind the notches is the body
     ground, which is the same `--rdk-black-green` as the panel. Invisible.
     Scroll, and the notches ride up into the pinned hero and appear — which
     is exactly how it was reported.

     Node 1:1872 paints its outer frame `#00bf00`, so this is the design's own
     answer. The trade is that the notches now show flat green rather than
     whatever of the hero is behind them; on a 390 frame they are 32u of
     corner, so there was never much of DONK to see through them. */
  .rdk-intro {
    background: var(--rdk-green);
  }

  .rdk-intro__panel {
    gap: 14vw;
    padding: 12vw 6vw;
    border-radius: 8vw 8vw 0 0;
  }

  .rdk-intro__top,
  .rdk-intro__bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 8vw;
  }

  /* Node 1:1874 puts the label row ABOVE the headline on mobile, where the
     desktop frame has it below. Done with `order` rather than by moving the
     markup, so the DOM stays one shape for both and js/intro.js's word/chip
     sequence is untouched. 24 is the frame's own gap. */
  .rdk-intro__top {
    gap: 24px;
  }

  .rdk-intro__tags {
    order: -1;
  }

  /* The designed line breaks assume an 892u measure, which cannot survive a
     375px screen — fitting them would mean ~17px type. So the four rows stop
     being rows and the headline becomes one continuously flowing paragraph,
     which wraps evenly instead of breaking into four separately-wrapping
     blocks with mismatched leading. The entrance animation is unaffected:
     it targets individual words (inline-block) and chips (inline-flex), both
     of which transform fine in either layout. */
  /* BALANCE, not the body's inherited `pretty` (client, 2026-09-15). The
     desktop's four designed rows become one wrapping paragraph down here, and
     it kept ending on "grow." plus its chip alone — a 95px last line in a 330
     measure. `pretty` does not catch it: it only pulls a word down to rescue a
     single short one, and the chip after the full stop is enough for it to
     call the line long enough.

     Measured at every phone width from 320 to 767, `balance` removes the
     orphan everywhere and NEVER costs a line except at exactly 600, where it
     goes 3 -> 4. That is one 20px band against a 95px orphan at 700-767 and
     at 360-412, so it is worth it.

     Safe to degrade: where `balance` is unsupported, or past the browser's
     line cap (Chrome stops at ~6), it falls back to ordinary wrapping, which
     is what shipped before. Desktop is unaffected either way — its lines are
     explicit rows at `white-space: nowrap` and never wrap at all. */
  .rdk-intro__headline {
    display: block;
    width: 100%;
    font-size: 6.4vw;
    line-height: 1.25;
    letter-spacing: -0.03em;
    text-wrap: balance;
  }

  .rdk-intro__line {
    display: inline;
    white-space: normal;
  }

  .rdk-intro__chip {
    display: inline-flex;
    width: 8vw;
    height: 8vw;
    margin: 0 0.1em;
    border-radius: 1.6vw;
    vertical-align: middle;
  }

  /* Node 1:1875, and straight px because these are small absolute sizes in a
     390 frame — a vw would drift with the screen. Note the phone differs from
     the desktop in COLOUR as well as scale: Redonk Lime here, `--rdk-green`
     there. */
  .rdk-intro__tags {
    gap: 16px;
    font-size: 11px;
    letter-spacing: 1.32px;
    color: var(--rdk-lime);
  }

  /* The desktop drops the separators a step; the phone frame sets every run
     at 11. */
  .rdk-intro__tags span:nth-child(even) {
    font-size: 11px;
    letter-spacing: 1.32px;
  }

  .rdk-intro__body {
    width: 100%;
  }

  /* Full-bleed on the phone, exactly as the video thumbnail was. The box
     grows but Donk does NOT: he is sized off the box's own height so the
     crop stays the design's — 269 of him in a 164 box is the same fraction
     at 48vw as it is at 164u. The words scale with him. */
  .rdk-intro__meet {
    width: 100%;
    height: 48vw;
    border-radius: 6vw;
  }

  /* Every one of these is the design's own fraction of the BOX, which here is
     88vw wide (100% less the panel's 6vw either side) and 48vw tall:
       top   58.68 / 164 = 35.78% of the height
       left  100.5 / 328 and 105 / 328 of the width
       size  36.712 / 328 of the width
     Guessed vw values had the words 27 too high and 9 too far out at 375. */
  .rdk-intro__meet-word {
    top: 17.17vw;
    font-size: 9.85vw;
    letter-spacing: -0.03em;
  }

  .rdk-intro__meet-word--l { left: calc(50% - 26.96vw); }
  .rdk-intro__meet-word--r { left: calc(50% + 28.17vw); }

  .rdk-intro__donk-rig {
    width: 57.2vw;
    height: 78.8vw;
    margin: -34.8vw 0 0 -28.6vw;
  }

  .rdk-intro__video {
    width: 100%;
    height: 48vw;
    border-radius: 6vw;
  }

  .rdk-intro__video-donk {
    width: 38vw;
    height: 52vw;
  }

  .rdk-intro__video-play {
    width: 14vw;
    height: 14vw;
  }
}

/* ---------- video overlay ----------
   Opened by .rdk-intro__video. The box is deliberately the SAME green as the
   thumbnail so the open animation reads as the thumbnail itself growing,
   rather than a new panel appearing over it. */

.rdk-video[hidden] {
  display: none;
}

.rdk-video {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(16px, calc(48 * var(--u)));
  /* Stop a flung scroll inside the overlay from chaining to the page. */
  overscroll-behavior: contain;
}

.rdk-video__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 20, 7, 0.88);
  backdrop-filter: blur(calc(8 * var(--u)));
  cursor: pointer;
}

.rdk-video__box {
  position: relative;
  width: min(calc(1180 * var(--u)), 100%);
  aspect-ratio: 16 / 9;
  overflow: clip;
  background: var(--rdk-green);
  border-radius: calc(40 * var(--u));
  /* The flip measures this box, so it must not have a transform of its own. */
  will-change: transform;
}

.rdk-video__frame,
.rdk-video__frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.rdk-video__close {
  position: absolute;
  z-index: 2;
  top: calc(20 * var(--u));
  right: calc(20 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  width: max(40px, calc(52 * var(--u)));
  height: max(40px, calc(52 * var(--u)));
  padding: 0;
  font-family: var(--rdk-font-brand);
  /* The BOX has a px floor and the glyph needs the same one, or the button is
     a correctly-sized 40px tap target with a 5.9px x in the middle of it —
     --u is 100vw/1600, so 24u is 5.6px at 375 and 6.5 at 430. 18 holds the
     design's own 24/52 proportion at the 40px floor. */
  font-size: max(18px, calc(24 * var(--u)));
  line-height: 1;
  color: var(--rdk-green);
  background: var(--rdk-white);
  border-radius: 50%;
}

@media (max-width: 767px) {
  .rdk-video__box {
    border-radius: 4vw;
  }
}

/* The overlay's own mobile block, and it has to live AFTER the rules it
   overrides: a media query adds no specificity, so at equal weight the later
   declaration wins. Put these in the section's mobile block further up and
   `.rdk-video__box`'s desktop width silently beats them. */
@media (max-width: 767px) {
  /* `.rdk-video__box` is `min(1180u, 100%)`, and 1180u on a 390 screen is
     288px — SMALLER than the 343px thumbnail it is supposed to be growing out
     of, so the player shrank on open instead of expanding (client,
     2026-08-27). The unit cap is a desktop idea, stopping the player getting
     absurd on a huge monitor; on a phone there is no such risk, so the box
     takes the width it is given. */
  .rdk-video {
    padding: 12px;
  }

  .rdk-video__box {
    width: 100%;
    /* The thumbnail's own 6vw, so the morph reads as that box growing rather
       than as a different one appearing. */
    border-radius: 6vw;
  }

  .rdk-video__close {
    top: 10px;
    right: 10px;
  }
}

/* ---------- tablet portrait (2026-09-16) ----------
   THE SAME NOTCH PROBLEM THE PHONE HAS, AND FOR THE SAME REASON — caused by
   capping the hero (client: "missing the rounded corners on the dark section
   under the hero on tablet portrait").

   The corners were never gone: measured at 820 the panel still draws its
   49.2px arc. What vanished is the CONTRAST behind it. This section is
   transparent so its notches reveal whatever is behind, and the reveal only
   works while the sticky hero IS behind — on a full-height hero the intro
   starts below the fold and has ridden up over green by the time anyone sees
   its corners. The portrait hero is `897 * --u`, i.e. 460 here, and the
   intro starts at exactly 460: the notch shows the page GROUND, which is
   `--rdk-black-green`, which is what the panel is painted. Dark on dark.

   So it takes the phone's own answer, and the phone's own trade: the notches
   read flat green rather than whatever of the hero is behind them. At this
   size they are ~49px of corner, so there was never much of DONK in them.
   Landscape keeps the full-height hero and needs none of this. */
@media (min-width: 768px) and (orientation: portrait) {
  .rdk-intro {
    background: var(--rdk-green);
  }

  /* THE BODY'S MEASURE IS IN THE TYPE'S OWN UNITS HERE (client, 2026-09-16:
     "make this body copy take up more of the width of the section").

     NOTHING WAS PROPORTIONALLY WRONG, which is why it is worth writing down —
     the same finding the case-study description already records. The row
     splits 328 / 183 / 157 at 768, which IS the design's 683 / 398 / 328 at
     its own scale, and `683 * --u` resolves to exactly the design's share of
     the row. What broke it is the body-scale floor: the copy is 18px here
     where the design's is 24px, so the measure went from 28.5em a line to
     18.2em and four designed lines became eight.

     A measure and its type have to scale together, and `--u` stopped being
     what the type scales with. So the body FILLS the row instead, capped at
     the node's measure over the node's font size — 683/24 = 28.5em, which is
     the design exactly. At 768 the cap is not what binds (the row is), so it
     lands 463 / 25.7em / five lines.

     BOTH LINES ARE A NO-OP WHERE THE TYPE IS STILL `--u`-SCALED, and that is
     exact rather than approximate: with `font-size: 24 * --u`, `calc(683em /
     24)` IS `683 * --u`, so the cap lands on the width the rule replaced. The
     48 gap is not binding there either, `space-between` having slack to
     distribute. Verified at 1200 x 1500 (512 either way) and 1600 x 900 (683,
     gap 398, the design exactly).

     SO THE BAND THIS ACTUALLY CHANGES IS 768-1024 WIDE IN PORTRAIT, AND THAT
     IS THE FLOOR'S OWN BAND, NOT ONE CHOSEN HERE. The floor at tokens.css:291
     is `(min-width: 768px) and (max-width: 1024px)` OR `(hover: none)` — a
     WIDTH clause, not only a pointer one — so a 900-wide desktop window in
     portrait is already being given the tablet's 18px type. Widening the
     measure to match is the same correction, not a second decision: wherever
     the type is floored the measure is floored with it. Measured at 900 x
     1400: 384 -> 512, gap 89.

     The gap is the design's own 48 UNSCALED, for the reason the type is:
     a design unit is too small at this width to be the thing it was drawn
     as. At `48 * --u` (23px) the paragraph all but touches the box. */
  .rdk-intro__bottom {
    gap: 48px;
  }

  .rdk-intro__body {
    flex: 1 1 auto;
    width: auto;
    max-width: calc(683em / 24);
  }
}
