/* devices.css — the hero device rig.

   Each device is a flat <img> of a Blender render (tools/render_devices.py).
   The perspective, the metal, the glass and the light are all baked into the
   pixels, so this file does exactly two things: place them, and float them.

   HARD RULE: no rotate, no scale, no 3D transform on anything containing a
   device image. A rotated or scaled compositor layer is re-rasterised with
   bilinear filtering on one mip level, and the screenshot inside turns to mush
   — that is precisely what sank the hand-drawn SVG version. Translation alone
   does not resample a layer, so the float below is translate3d only.

   This replaced a three-device triangle (laptop / tablet / phone, each with its
   own caption). That composition needed a --u container unit, absolute
   positions for all three, per-device shadows and three labels that had to be
   re-tracked at every breakpoint to stop them colliding. The dark hero only
   needs one dominant object, so all of that is gone. */

/* The wrapper takes whatever vertical space the hero copy leaves and the rig
   scales into it, so the render is never cut off by the fold. min-height:0 is
   required — a flex item defaults to min-height:auto and would refuse to shrink
   below the image's intrinsic height, which is the whole problem. */
/* centre, not flex-end: pinned to the bottom, all the leftover height collected
   into one dead gap between the buttons and the render. Centred, the slack
   splits above and below and the render sits in the space rather than under it. */
.hd-rig-wrap{min-width:0;flex:1 1 auto;min-height:0;display:flex;
  align-items:center;justify-content:center;
  padding-top:clamp(16px,2.4vw,30px)}
/* The laptop stays IN FLOW — it defines the rig's box, and the phone is
   positioned in percentages off that box, so the two can never drift apart.
   The rig is therefore sized by WIDTH, and the third term is what keeps it
   inside the fold: --hd-chrome is everything above it (nav, hero padding,
   headline, lede, buttons and their margins), so the leftover height converted
   through the asset's own 1700:1326 ratio gives the widest the laptop may be.
   Measured, not guessed — see the probe in the commit message. */
.hd-rig{position:relative;margin:0 auto;
  --hd-chrome:552px;
  width:min(94%, 980px, calc((100svh - var(--hd-chrome)) * 1700 / 1326))}
/* Short-viewport tier. dark-sections.css tightens the hero copy at the same
   breakpoint; this is the matching chrome budget, and it has to live HERE
   because devices.css loads last and would otherwise override it. */
@media (max-height:820px) and (min-width:700px){
  .hd-rig{--hd-chrome:372px}
}
.hd{margin:0;will-change:transform}
.hd img{display:block;width:100%;height:auto}

.hd-laptop img{filter:drop-shadow(0 26px 54px rgba(0,0,0,.55))}

/* Sean, 6 Aug: at real-device proportion (17%) the phone reads as
   microscopic next to the laptop — true anatomy, wrong on screen. Enlarged to
   34% (2x) and pulled further out past the laptop's corner so the bigger
   render has room and doesn't bury the laptop's own bottom-right content. */
.hd-phone{position:absolute;right:-3%;bottom:-6%;width:34%}
.hd-phone img{filter:drop-shadow(0 18px 34px rgba(0,0,0,.6))}

/* Below 700px the phone renders about 55px wide — its screen content is not
   readable at that size, so it stops being a second product and becomes a
   speck. The hero's whole brief was less small information, so it goes. */
@media(max-width:700px){.hd-phone{display:none}}

/* the float: two different durations with a negative delay, so the devices are
   permanently out of phase and never read as one locked group */
@keyframes hdFloat{
  0%,100%{transform:translate3d(0,0,0)}
  50%    {transform:translate3d(0,-11px,0)}
}
html.motion-on .hd{animation:hdFloat var(--fd,8s) var(--fdel,0s) ease-in-out infinite}
@media (prefers-reduced-motion:reduce){.hd{animation:none}}
