/* ============================================================
   About — "We're serious about our work."   (node 975:112516)
   ============================================================
   REBUILT 2026-09-20. This was a scroll-driven photo WALL: eighteen (later
   five) tiles rising through a pinned card on a scrub, with two springs each,
   a scroll-velocity lean, an idle float and headline-avoidance orbiting. The
   client's new node is a hand-placed COLLAGE — six photographs scattered
   round a centred copy block, bleeding off all four edges — and asked for it
   to behave "exactly like the photo section at the top of the About page".
   So the wall's machinery is gone and this is the About page's collage model
   instead: one custom property for the whole entrance, per-tile placement in
   design units, and the tiles pickupable and throwable.

   THE NODE IS DRAWN 1:1, not the 0.937 most nodes in this file carry. Checked
   rather than assumed, on values the build already shares with it: its
   headline is 72 / 0.95 / -2.16 on a 634 measure and its CTA is a 4 border
   with 56 padding, a 23 label and an 80 box — the shipped numbers exactly. So
   every length here is the node's own, and `--cu` is simply `--u`.

   WHAT IS SHARED WITH THE ABOUT PAGE IS THE BEHAVIOUR, NOT THIS GEOMETRY.
   js/collage-throw.js owns the throw and its spring, because that is a
   mechanism with documented failure modes; where these six photographs sit is
   a design and belongs here. See that file's header for the split.

   The panel does NOT pin. The wall needed a pin because a scrub had to run
   somewhere; a burst that plays itself needs no scroll budget at all, and
   leaving the pin behind is what the About page's own 2026-09-10 pass calls
   out — "anything that pins on scroll has to earn it". `--about-scroll` is
   therefore gone, and the section is simply as tall as its panel. */

.rdk-about {
  /* The collage's unit. Separate from `--u` only so the cloud can be scaled
     as one thing without touching the panel — the About page's `--tile-k`
     lesson, where tying the two together meant adjusting the section height
     silently resized every photograph. */
  --cu: var(--u);
  /* The panel's height in DESIGN UNITS, not a share of the viewport. The
     About page's own 2026-09-16 lesson: how tall the section is and how big
     the cloud is are two decisions, so this and `--tile-k` stay separate. */
  --panel-u: 1211;
  --panel-h: calc(var(--panel-u) * var(--u));

  /* Spread knobs, all no-ops at 1. They exist because the About page's
     collage needed them within a day of shipping and this one will too: they
     rescale how far the cloud reaches without moving six pairs of numbers.
     `--spread-up` and `--spread-down` are separate for the reason recorded
     there — lifting the top row with one vertical dial drops the bottom row
     through the panel's foot. */
  --spread-x: 1;
  --spread-up: 1;
  --spread-down: 1;
  --tile-k: 0.82;

  /* THE CLIENT'S OWN PASS (2026-09-20), pasted from ?tune. Hand-placed by eye
     against this arrangement, so there is no rule to re-apply if the panel or
     the spreads move — they want re-doing in the panel. Every tile not named
     here sits exactly where node 975:112516 puts it.

     `--tile-k: 0.82` is the one global move: the photographs at full size
     crowded the copy once the cloud was on a real page rather than a frame. */
  --n2-x: 77;
  --n2-y: 6;
  --n2-k: 1.07;
  --n2-r: 4;
  --n6-k: 0.93;

  position: relative;
  z-index: 1;
  /* 96 is the design's gap above the panel. base.css is border-box, so with
     no stated height the panel and this padding simply add up.

     NO TAIL ON DESKTOP, DELIBERATELY (client, 2026-09-20: "I dont want the
     bottom padding on desktop, only mobile"). The reveal lifts `main` off the
     footer here, so the card's bottom edge is the edge that sweeps away —
     there is nothing for a gap to sit in. It is the PHONE that needs one, and
     the phone's block is where it is. */
  padding: calc(96 * var(--u)) calc(40 * var(--u)) 0;
  background: var(--rdk-black-green);
}

/* `overflow: clip` and not `hidden`: hidden would make this a scroll
   container. It is also what crops the photographs at the panel's edges,
   which is the whole composition — four of the six bleed off. */
.rdk-about__panel {
  position: relative;
  height: var(--panel-h);
  overflow: clip;
  background: var(--rdk-white);
  border-radius: calc(96 * var(--u));
}

/* Node 975:112517 — the copy block is 714 wide, centred in the panel, with a
   48 gap to the button and 32 inside the text. */
.rdk-about__intro {
  position: absolute;
  left: 50%;
  top: 50%;
  /* Above every tile. The wall used to put half the photographs in FRONT of
     the type, which is why it needed the orbiting; this node keeps a clear
     channel down the middle instead, so the type simply wins. */
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(48 * var(--u));
  /* --du: the measure below carries the headline's designed line break, so it
     floors with the type. On --u the type grew at the tablet floor and the
     measure did not. */
  width: calc(714 * var(--du));
  translate: -50% -50%;
}

.rdk-about__text {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(32 * var(--du));
}

/* The phone breaks after the first sentence; the desktop wraps naturally in
   its 634 measure. An explicit element rather than a width that happens to
   force it. NOTE the space before it in the markup — a `<br>` that is
   `display: none` contributes nothing at all, not even whitespace. */
.rdk-about__headline-break {
  display: none;
}

/* Display/M 72 (node 975:112519). THE TRACKING IS THE NODE'S -2.16, WHICH IS
   -3%, where the ladder's own rung for 72 is -3.43%. Kept the node's because
   it is what the designer set the 634 measure against; at the ladder's -2.47
   the type runs ~5 narrower and the wrap is a coin toss. It leaves 72 and 62
   tracked the same — a flat spot on the ladder rather than an inversion. */
.rdk-about__headline {
  width: calc(634 * var(--du));
  margin: 0;
  font-family: var(--rdk-font-brand);
  font-weight: 700;
  font-size: calc(72 * var(--du));
  line-height: 0.95;
  letter-spacing: calc(-2.16 * var(--du));
  text-align: center;
  color: var(--rdk-black-green);
}

/* Node 977:115574. The standfirst step, so it PICKS A STEP rather than
   declaring a size — `--rdk-body-l` is 20 here and floors with the scale on a
   touch tablet. It takes the token's 1.5 leading over the node's 1.4, the
   same call the footer blurb's own note records: holding one leading across
   the body scale is worth more than matching a frame by 2px on one line. */
.rdk-about__lede {
  max-width: calc(634 * var(--du));
  margin: 0;
  font-size: var(--rdk-body-l);
  line-height: 1.5;
  letter-spacing: 0.01em;
  text-align: center;
  color: var(--rdk-black-green);
  opacity: 0.9;
}

/* ---------- the button (nodes 179:7203 + 179:7213) ----------
   The case studies' "View project" treatment, driven by the shared
   integrator in js/btn-shove.js: the PILL grows on hover and that growth
   shoves the CHIP along by layout, because they are flex siblings; the chip
   then carries on past where the pill left it and hits the pill's edge.
   `--grow`, `--push` and `--squish` are written onto the group by the JS. */
.rdk-about__cta-group {
  display: inline-flex;
  align-items: stretch;
  --push: 0;
}

.rdk-about__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: calc(80 * var(--u));
  /* 56 designed, opening by --grow-travel per side as the spring fires.
     base.css is border-box, so the 4u border sits inside this and the label
     starts at the designed 60 from the pill's edge. */
  padding: 0 calc((56 + var(--grow-travel, 9.5) * var(--grow, 0)) * var(--u));
  font-family: var(--rdk-font-brand);
  font-weight: 700;
  font-size: calc(23 * var(--u));
  line-height: 1.2;
  letter-spacing: calc(-0.23 * var(--u));
  white-space: nowrap;
  color: var(--rdk-black-green);
  border: calc(4 * var(--u)) solid var(--rdk-green);
  border-radius: 999px;
}

/* Overlaps the pill by 4 so the two borders merge into one shape. It only
   ever MOVES and DEFORMS — the circle is never scaled uniformly, which the
   client ruled out on the case studies. */
.rdk-about__cta-chip {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: calc(80 * var(--u));
  margin-left: calc(-4 * var(--u));
  color: var(--rdk-black-green);
  border: calc(4 * var(--u)) solid var(--rdk-green);
  border-radius: 999px;
  translate: calc(var(--push, 0) * 1px) 0;
  scale: calc(1 - 0.16 * var(--squish, 0)) calc(1 + 0.11 * var(--squish, 0));
}

/* The caret's element size is the size the ASSET renders at, not the 6.769 x
   13.538 path box `get_design_context` reports — the stroke with square caps
   adds 2.12 on every side and Figma's own export carries that in its viewBox.
   Same geometry as the contact dialog's submit chip. */
.rdk-about__cta-chip svg {
  width: calc(11.01 * var(--u));
  height: calc(17.78 * var(--u));
}

/* ---------- the collage ----------
   ONE property. `--p` on the collage goes 0 -> 1.35: 0..1 is the burst, each
   tile from the copy block's centre out to its place once its own `--d` has
   passed, and the part beyond 1 is the slow outward drift that keeps going
   after they land. js/about.js plays it once; the stylesheet's default is 1,
   so with no JS the panel is simply the frame.

   NOT GIVEN A Z-INDEX, deliberately. A positioned element with `z-index:
   auto` opens no stacking context, so a tile could in principle be lifted
   over the copy later without restructuring anything. */
.rdk-about__collage {
  --p: 1;
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* A tile: positioned by its CENTRE (`--x`/`--y`, the node's own coordinates
   in its 1520 x 1211 panel, taken against the composition's centre at
   760, 605.5), sized in `--cu`, tilted by `--rot`, and waiting out `--d` of
   the burst before it moves.

     --pt   this tile's own 0..1, `--p` with its delay removed
     --ex   how far past 1 `--p` has gone: the drift outward after landing

   `--dx`/`--dy` are the THROW, written by js/collage-throw.js. They fold into
   `translate` here and nothing else touches that channel, which is why the
   throw can be a custom property at all — see that file. */
.rdk-about__tile {
  --pt: clamp(0, (var(--p) - var(--d, 0)) / (1 - var(--d, 0)), 1);
  --ex: max(0, var(--p) - 1);
  /* `--nx` / `--ny` / `--nk` / `--nr` ARE THE TUNER'S PER-TILE NUDGE, and
     they fold into the designed CENTRE here rather than into `translate` for
     the reason the About page's collage records: the throw already owns
     `--dx`/`--dy` on that channel and would overwrite anything put beside
     them. Folding them in here also means a nudge travels through the spread
     knobs exactly as `--x`/`--y` do.

     They are OFFSETS FROM the design, all defaulting to the identity, so a
     stored session always reads as a correction rather than a replacement and
     Reset is unambiguous. `--nr` arrives as a bare number and is given its
     unit here, because the panel writes plain numbers. */
  --px: calc(var(--x) + var(--nx, 0));
  --py: calc(var(--y) + var(--ny, 0));
  --rotn: calc(var(--rot, 0deg) + var(--nr, 0) * 1deg);
  --tw: calc(var(--w) * var(--cu) * var(--tile-k, 1) * var(--nk, 1));
  --th: calc(var(--h) * var(--cu) * var(--tile-k, 1) * var(--nk, 1));
  /* THE BOTTOM CLAMP USES THE ROTATED EXTENT, NOT THE BOX. Every tile is
     tilted, so what the panel's foot meets is `w * |sin| + h * |cos|`. `abs()`
     is newer than the trig functions, so the absolute value is taken as
     `max(x, -1 * x)` — the About page's own workaround. */
  --sinr: max(sin(var(--rotn)), -1 * sin(var(--rotn)));
  --cosr: max(cos(var(--rotn)), -1 * cos(var(--rotn)));
  --rh: calc(var(--tw) * var(--sinr) + var(--th) * var(--cosr));
  --offx: calc((var(--px) - 760) * var(--cu) * var(--spread-x, 1));
  --offy-raw: calc(
    min(0, var(--py) - 605.5) * var(--cu) * var(--spread-up, 1) +
    max(0, var(--py) - 605.5) * var(--cu) * var(--spread-down, 1));
  /* NO BOTTOM CLAMP, AND THAT IS A DELIBERATE DIFFERENCE FROM THE ABOUT
     PAGE'S COLLAGE. That one caps how far a tile may travel down, because a
     photograph cut by the panel's FOOT read as the next section eating it —
     the flamingo complaint. This composition bleeds off all four edges ON
     PURPOSE: node 975:112516 puts tile 6's bottom at 1270 in a 1211 panel, so
     the crop IS the design and the panel's `overflow: clip` is the frame.

     Imported unexamined, that clamp pulled tile 6 seventy-one pixels up —
     measured against the node, which is the only reason it was caught. The
     lesson generalises: a rule that exists to stop an accident on one
     composition is not automatically right on another that does the same
     thing on purpose.

     `--rh` above is kept although the placement no longer reads it, because
     it is what any future clamp or tuner readout must measure with: a tilted
     tile's real extent is `w * |sin| + h * |cos|`, never its box. */
  --offy: var(--offy-raw);
  position: absolute;
  left: calc(50% + var(--offx));
  top: calc(50% + var(--offy));
  width: var(--tw);
  height: var(--th);
  margin: calc(var(--th) / -2) 0 0 calc(var(--tw) / -2);
  translate:
    calc(var(--offx) * -1 * (1 - var(--pt)) + var(--offx) * 0.15 * var(--ex) + var(--dx, 0px))
    calc(var(--offy) * -1 * (1 - var(--pt)) + var(--offy) * 0.15 * var(--ex) + var(--dy, 0px));
  rotate: calc(var(--rotn) + (1 - var(--pt)) * 40deg);
  scale: var(--pt);
  border-radius: calc(24 * var(--cu));
  overflow: clip;
  pointer-events: auto;
  will-change: translate, scale, rotate;
}

/* Bound by `data-tile`, OUTSIDE the rule above — written inside it the
   parser salvages what it can, the nudges never arrive, and NOTHING appears
   in the console. A nested selector would need CSS Nesting, which this
   project does not use. The About page's collage carries the same warning
   for the same reason; it is the first thing to check when a tuner control
   does nothing. */
.rdk-about__tile[data-tile="1"] { --nx: var(--n1-x); --ny: var(--n1-y); --nk: var(--n1-k); --nr: var(--n1-r); }
.rdk-about__tile[data-tile="2"] { --nx: var(--n2-x); --ny: var(--n2-y); --nk: var(--n2-k); --nr: var(--n2-r); }
.rdk-about__tile[data-tile="3"] { --nx: var(--n3-x); --ny: var(--n3-y); --nk: var(--n3-k); --nr: var(--n3-r); }
.rdk-about__tile[data-tile="4"] { --nx: var(--n4-x); --ny: var(--n4-y); --nk: var(--n4-k); --nr: var(--n4-r); }
.rdk-about__tile[data-tile="5"] { --nx: var(--n5-x); --ny: var(--n5-y); --nk: var(--n5-k); --nr: var(--n5-r); }
.rdk-about__tile[data-tile="6"] { --nx: var(--n6-x); --ny: var(--n6-y); --nk: var(--n6-k); --nr: var(--n6-r); }

/* Only while a fine pointer is there to pick one up: `grab` on a touch device
   promises something that is deliberately not offered (js/collage-throw.js
   leaves touch to the browser so a thumb still scrolls). */
@media (hover: hover) and (pointer: fine) {
  .rdk-about__tile { cursor: grab; }
  .rdk-about__tile.is-held { cursor: grabbing; }
}

/* THE CROP IS BAKED IN, so there is nothing for `object-fit` to choose: each
   file is composited at its card's exact aspect from the node's own layer
   offsets. `object-fit: cover` is stated anyway as a floor, in case a
   replacement arrives cut to a different shape. */
.rdk-about__tile img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}


/* ---------- phone ----------
   INVENTED — node 975:112516 is desktop only, as the About page's collage
   node was. It follows the arrangement the wall's own phone layout settled
   on and the client approved: FOUR photographs, one bleeding off each corner,
   with the copy in the clear middle. Six at this size is a collage of
   thumbnails, and the two dropped are the ones the desktop already crops
   hardest.

   The unit comes off the VIEWPORT here, not off `--u`: `--u` is 100vw/1600,
   so a 475u tile would be 111px on a 375 screen — the collapsing-unit trap
   this project records in a dozen places. */
@media (max-width: 767px) {
  .rdk-about {
    --cu: calc(100vw / 390 * 0.40);
    /* SOLVED, NOT PICKED. Swept 480 combinations at 375 x 812 against two
       numbers: how much of the copy's INK the photographs cover, and how much
       of the least-visible one is still on the panel. Six photographs in a
       335-wide card is a real squeeze — pulled IN they land on the type,
       pushed OUT they leave the panel — so the answer is smaller tiles with a
       tight horizontal spread and a hard push upward.

       This is the largest `--tile-k` that reaches ZERO copy coverage while
       keeping every photograph at least half on the card: 0% covered, worst
       tile 59% on. The top row crops against the panel's top edge, which is
       the gesture the node already makes with three of the six. */
    --spread-x: 0.55;
    --spread-up: 1.48;
    --spread-down: 1.64;
    --tile-k: 0.78;

    /* THE CLIENT'S OWN PASS (2026-09-20), pasted from ?tune — hand-placed, so
       there is no rule to re-apply if the spreads or the card move. The sweep
       above found the SPREAD; every tile is then moved by eye on top of it,
       which is what a 335-wide card with six photographs in it needs. */

    /* EVERY VALUE IS STATED, IDENTITIES INCLUDED, and that is not tidiness in
       reverse. This block refines the SAME selector as the desktop one, so a
       property left out here does not fall back to the rule's own default —
       it inherits whatever the desktop block set. Trimming `--n2-k: 1` and
       `--n6-k: 1` as "no-ops" silently handed the phone the desktop's 1.07
       and 0.93, and two tiles came out 10px wrong. Paste the panel's Copy
       block whole. */
    --n1-x: 56;   --n1-y: -37;  --n1-k: 1.09;  --n1-r: 0;
    --n2-x: 190;  --n2-y: 0;    --n2-k: 1;     --n2-r: 4;
    --n3-x: 13;   --n3-y: 62;   --n3-k: 0.85;  --n3-r: 9;
    --n4-x: 127;  --n4-y: 21;   --n4-k: 1;     --n4-r: 0;
    --n5-x: -24;  --n5-y: 78;   --n5-k: 0.87;  --n5-r: 13;
    --n6-x: 0;    --n6-y: -45;  --n6-k: 1;     --n6-r: 0;
    /* The card is the viewport's here, not a number of design units, which is
       why the panel's height control is the one thing still hidden on this
       breakpoint. */
    /* THE CARD IS SIZED OFF WIDTH, NOT OFF `svh` (client, 2026-09-20, from a
       real iPhone: "section needs to be taller I think?").

       IT WAS `80svh`, AND THAT IS THE BUG RATHER THAN THE NUMBER. The cloud
       is sized in `--cu`, which is a share of the WIDTH, so it does not
       shrink when Safari's bars appear — but `svh` is the viewport with those
       bars SHOWING, so on a real 844-tall phone the card is ~560 where the
       pane's 812-tall emulation gives 650. The photographs sit at fixed
       distances from the card's centre, so 90px of missing card comes
       straight off the top and bottom edges: measured, tiles 2 and 6 fall
       from 96% and 100% on the card to 64% and 63%. That is the cropping in
       the screenshot, and it is invisible in the browser pane by
       construction.

       On width, the card and the cloud keep one relationship on every device.
       The `svh` cap is only a backstop for a LANDSCAPE phone, where 1.7 x a
       700 width would be 1190 in a 375-tall window. */
    --panel-h: min(calc(100vw * 1.7), 92svh);
    /* A GAP OF PAGE GROUND UNDER THE CARD (client, 2026-09-20: "missing the
       gap between the bottom of the section and the green footer on mobile.
       Should be a little black showing between").

       IT MATCHES THE GAP ABOVE, not the side inset (client, same day:
       "increase the bottom padding on mobile to match the padding that is
       between the section above and the top of the were serious section").
       Measured at 375, the case studies' bottom edge sits exactly 40 above
       this card — which is this section's own `padding-top`, nothing else
       contributing — so the two are one value and the card sits evenly in its
       own band of ground. `--gutter` stays the narrower side inset.

       ON THE SECTION, NOT ON THE FOOTER, which is where tablet portrait puts
       its equivalent. A footer margin is the right tool when the footer has
       to come away from what is above it; here the card simply has no tail,
       and it had one before the rebuild by accident — the old phone layout
       centred an 80svh card in a 100svh section, so ~10svh of ground fell out
       below it. Nothing replaced that when the section became as tall as its
       panel.

       DESKTOP HAS NO TAIL AND MUST NOT INHERIT ONE: the reveal lifts `main`
       off the footer there, so the card's bottom edge is the edge that sweeps
       away and there is nothing for a gap to sit in. */
    --gutter: 20px;
    --band: 40px;
    padding: var(--band) var(--gutter) var(--band);
  }

  .rdk-about__panel {
    border-radius: 32px;
  }

  .rdk-about__intro {
    width: calc(100% - 48px);
    gap: 28px;
  }

  .rdk-about__text { gap: 16px; }

  .rdk-about__headline {
    width: 100%;
    font-size: 34px;
    letter-spacing: -1.02px;
  }

  /* Shown here: at 34px the sentence wraps mid-clause without it. */
  .rdk-about__headline-break { display: inline; }

  .rdk-about__lede {
    max-width: 300px;
    font-size: var(--rdk-body-s);
  }

  /* The button was inheriting its desktop --u sizes, which on a 390 screen
     made it a 19.5px-tall pill with 13.6px of side padding. Node 230:20007
     gives the phone its own: a 3 border, 32/17 padding, 15px label — and a
     52 chip, which is deliberately SHORTER than the pill's 58, so it centres
     rather than stretching. */
  .rdk-about__cta-group {
    align-items: center;
  }

  /* Node 230:20007: 64 tall, 16/40 padding, a 3.692 border, fully round. The
     height is STATED — with `auto` the padding and the label decided it and it
     came out 15 short.

     THE LABEL IS 18, NOT THE NODE'S 22.15 (client, 2026-08-28): it has to
     match the footer's CTA, which node 267:41710 sets at 18. Everything else
     about the two already agreed — both 64 tall, 16/40 padding, fully round —
     so the type size was the only thing making them look like different
     buttons.

     `--grow-travel` stays in the padding: that is js/btn-shove.js's spring
     and it is in px already, so it rides on top of the design's 40. */
  .rdk-about__cta {
    height: 64px;
    padding: 16px calc(40px + var(--grow-travel, 9.5) * var(--grow, 0) * 1px);
    font-size: 18px;
    line-height: 1.2;
    letter-spacing: normal;
    /* 4, matching the footer's CTA — not this node's own 3.692 (client,
       2026-08-28). The two buttons are the same button. */
    border-width: 4px;
  }

  /* Node 230:20014 is 64 square — the SAME height as the pill, where the
     previous pass had it deliberately shorter (52 against 58). The design
     squares them up on a phone. */
  .rdk-about__cta-chip {
    width: 64px;
    height: 64px;
    /* The overlap is the border width, so the two rings merge into one line
       rather than doubling — it moves with it. */
    margin-left: -4px;
    border-width: 4px;
  }

  .rdk-about__cta-chip svg {
    width: 8.9px;
    height: 14.3px;
  }

  /* The four corners. Each tile is anchored to the edge it bleeds off, so the
     card's height can change without a photograph wandering into the copy —
     the same reason the wall's phone bands were anchored rather than centred.
     `--x`/`--y` are ignored here; these are placements, not a scaled cloud. */
  /* ALL SIX ON THE PHONE, ON THE SAME CLOUD MODEL AS THE OTHER TWO (client,
     2026-09-20: "Missing all 6 photos. Add back in the missing photos").

     THIS REPLACES A FOUR-CORNER ARRANGEMENT, and the four corners are why two
     photographs were missing: tiles 1 and 5 were `display: none` because that
     layout had nowhere to put them. It was also the reason twelve of the
     panel's controls were dead here — the corners are anchored to the panel's
     edges, so `--offx`/`--offy` and the three Spread knobs drove nothing.

     On the cloud model every control is live on every breakpoint, which is
     what "match the tuner for all 3 breakpoints" actually needs, and the
     arrangement is then tunable by eye rather than being four hand-written
     corner rules. The unit comes off the VIEWPORT, not off `--u`: `--u` is
     100vw/1600, so a 475u tile would be 111px on a 375 screen.

     The spreads pull the cloud IN horizontally (0.58) and push it out
     vertically (1.18): a phone card is tall and narrow, so the photographs
     have to clear a five-line copy block rather than a two-line one, and
     there is far less room either side of it than the node has. */
}

/* ---------- tablet portrait ----------
   The phone's four-corner arrangement, which is the right shape for a tall
   card, at the tablet's own scale. Landscape tablets take the desktop cloud:
   the panel is wide enough for it and the fault the phone block answers is a
   viewport that is tall for its width. */
@media (min-width: 768px) and (orientation: portrait) {
  .rdk-about {
    --cu: calc(100vw / 820 * 0.72);
    --panel-u: 1393;
    --tile-k: 0.92;

    /* THE CLIENT'S OWN PASS (2026-09-20), pasted from ?tune — hand-placed,
       with no rule behind it. A portrait tablet is a much taller card than
       the node's, so five of the six are moved rather than merely scaled. */
    /* Stated in full for the reason the phone block sets out at length: an
       omitted value here inherits the DESKTOP block's, not the identity. */
    --n1-x: 210;  --n1-y: 56;   --n1-k: 0.92;  --n1-r: 0;
    --n2-x: 239;  --n2-y: 112;  --n2-k: 0.85;  --n2-r: 5.5;
    --n3-x: 0;    --n3-y: 0;    --n3-k: 1;     --n3-r: 0;
    --n4-x: 190;  --n4-y: -101; --n4-k: 1;     --n4-r: 0;
    --n5-x: -206; --n5-y: -41;  --n5-k: 0.75;  --n5-r: 0;
    --n6-x: -1;   --n6-y: -88;  --n6-k: 0.78;  --n6-r: -2.5;
  }

  .rdk-about__intro { width: calc(100% - 120px); }
}

/* ---------- the touch target floor (2026-09-16) ----------
   THE PILL + CHIP IS PURE `N * --u` WITH NO FLOOR, so on a touch device it
   draws 41 with an 11.8px label at 820 — under the 44 every platform asks of
   a target a thumb has to hit (client: "the buttons also seem too small").
   The nav's CTA is the one button on the page that already floors itself,
   and it draws 44 there against a scaled 28.7; this is that, applied to the
   component the About, services, project and 404 pages share.

   GATED ON THE POINTER RATHER THAN ON WIDTH OR ORIENTATION — a touch target
   belongs to the device. See the matching note in css/cases.css for why that
   is the only gate that gets both tablet orientations right without reaching
   a desktop. Above 768 only: the phone has its own designed 64 from node
   230:20007 and must not be floored into.

   `max()` only raises, so it is inert from about 880 wide upward. */
@media (min-width: 768px) and (hover: none) {
  .rdk-about__cta-group {
    --cta-h: max(44px, calc(80 * var(--u)));
  }

  .rdk-about__cta {
    height: var(--cta-h);
    font-size: max(15px, calc(23 * var(--u)));
  }

  /* Width only — the chip's height comes from the row stretching to the
     pill's, so flooring one dimension without the other draws an oval. */
  .rdk-about__cta-chip {
    width: var(--cta-h);
  }

  .rdk-about__cta-chip svg {
    width: calc(var(--cta-h) * 11.01 / 80);
    height: calc(var(--cta-h) * 17.78 / 80);
  }
}

/* ---------- reduced motion ----------
   The burst is the only thing that moves on its own, so the collage simply
   renders at its resting state — which `--p: 1` already is. js/about.js
   returns before playing anything, and js/collage-throw.js still binds: a
   throw is something the reader asks for, and it returns the photograph
   without a spring under this setting. */
@media (prefers-reduced-motion: reduce) {
  .rdk-about__collage { --p: 1; }
  .rdk-about__tile { will-change: auto; }
}
