/* ════════════════════════════════════════════════════════════════════
   3D phones (2026-09-27, made lighter the same day)
   ════════════════════════════════════════════════════════════════════

   SWITCH: the class "phones-3d" on <html> (index.html). Remove it and the
   page shows the flat phones exactly as before: every extra layer below
   hides itself and the wrappers are plain boxes.

   The phone is real CSS 3D, not a picture, so the live screen (the rating
   demo, the step animations) keeps running on it:

     .p3d-stage     perspective, the ground shadow and the glow (not rotated)
       .p3d         the pose (+ the mouse tilt on computers, js/phones-3d.mjs)
         .p3d-float the idle float (keyframes)
           .p3d-rim    the metal band: 7 hollow rounded rings stacked in
                       depth. Hollow, so they cost almost no GPU memory, and
                       a 6px ring still closes the band up to steep angles.
                       The side buttons are small bumps on the middle rings.
           .phone      the existing phone = the front face (untouched)

   Kept cheap for phones scrolling the page: 8 flat, parallel layers per
   phone (nothing crosses another plane, so the browser never has to split
   and sort them), no blur filters, no glass reflection, nothing driven by
   scrolling, and phones far off screen drop their band and stop floating
   (the "p3d-idle" class from js/phones-3d.mjs).

   --f on each ring (inline) is its brightness: a sheen that peaks in the
   middle of the band, like light on a rounded metal edge.
   ════════════════════════════════════════════════════════════════════ */

/* Off by default: flat phones, no extra layers. */
.p3d-rim,
.p3d-shadow {
  display: none;
}

.phones-3d .p3d-stage {
  position: relative;
  perspective: 1400px;
  perspective-origin: 50% 40%;
}

.phones-3d .p3d {
  --d: 28px;              /* body thickness, about 1/10 of the width like a real phone */
  --r: 38px;              /* corner radius, same as .phone */
  --rx: -7deg;            /* pose: top leans toward us a little */
  --ry: -24deg;           /* screen turned to the left */
  --rz: 2deg;
  position: relative;
  transform-style: preserve-3d;
  /* js/phones-3d.mjs replaces this inline on computers to add the tilt. */
  transform: rotateX(var(--rx)) rotateY(var(--ry)) rotateZ(var(--rz));
}
/* Phones on the left of their text turn their screen to the right. */
.phones-3d .p3d[data-face='right'] {
  --ry: 24deg;
  --rz: -2deg;
}
.phones-3d .p3d-sm { --d: 22px; }

.phones-3d .p3d-float {
  position: relative;
  transform-style: preserve-3d;
  animation: p3d-float 6s ease-in-out infinite;
}
.phones-3d .p3d-sm .p3d-float { animation-duration: 5s; }
@keyframes p3d-float {
  0%, 100% { transform: translate3d(0, 0, 0) rotateY(-2.5deg); }
  50%      { transform: translate3d(0, -12px, 0) rotateY(2.5deg); }
}

/* The existing phone becomes the front face. Its own float and flat drop
   shadow step aside: the whole body floats now, and the shadow sits on the
   ground below it. */
.phones-3d .p3d .phone {
  animation: none;
  transform: translateZ(calc(var(--d) / 2));
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.07),
    inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}

.phones-3d .p3d-rim {
  display: block;
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  pointer-events: none;
}
.phones-3d .p3d-rim i {
  position: absolute;
  inset: 0;
  border-radius: var(--r);
  border: 6px solid;
  /* Warm titanium, lit from above: top brightest, bottom darkest. */
  border-color:
    hsl(15 7% calc(var(--f) * 46%))
    hsl(15 6% calc(var(--f) * 34%))
    hsl(15 6% calc(var(--f) * 22%))
    hsl(15 6% calc(var(--f) * 34%));
  transform: translateZ(calc(var(--d) * (var(--k) / 7 - 0.5)));
}
/* Side buttons: bumps just outside the band on the middle rings, in the
   ring's own plane (iPhone layout: power right, two volume keys left). */
.phones-3d .p3d-rim i.b::before,
.phones-3d .p3d-rim i.b::after {
  content: '';
  position: absolute;
  width: 3px;
  border-radius: 2px;
  background: hsl(15 5% calc(var(--f) * 44%));
}
.phones-3d .p3d-rim i.b::before {
  right: -9px;
  top: 25%;
  height: 13%;
}
.phones-3d .p3d-rim i.b::after {
  left: -9px;
  top: 22%;
  height: 7%;
  /* The second volume key, one key-length plus a gap lower. */
  box-shadow: 0 calc(var(--d) * 2.1) 0 hsl(15 5% calc(var(--f) * 44%));
}

/* Ground shadow: flat, below the phone, breathing with the float. A soft
   gradient on its own (a blur filter here cost a GPU pass every frame). */
.phones-3d .p3d-shadow {
  display: block;
  position: absolute;
  left: 10%;
  right: 10%;
  bottom: -50px;
  height: 54px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.25) 55%, rgba(0, 0, 0, 0));
  pointer-events: none;
  animation: p3d-shadow 6s ease-in-out infinite;
}
.phones-3d .p3d-sm + .p3d-shadow { animation-duration: 5s; }
@keyframes p3d-shadow {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(0.86); opacity: 0.7; }
}

/* Coral glow the flat phone had, now behind the body (no blur filter:
   the gradient already fades to nothing). */
.phones-3d .p3d-stage::before {
  content: '';
  position: absolute;
  inset: -4% -18%;
  background: radial-gradient(closest-side, rgba(226, 121, 102, 0.16), rgba(226, 121, 102, 0.05) 60%, rgba(226, 121, 102, 0));
  pointer-events: none;
}

/* Far off screen: no band layers, no float (js/phones-3d.mjs). */
.phones-3d .p3d-idle .p3d-rim { display: none; }
.phones-3d .p3d-idle .p3d-float,
.phones-3d .p3d-idle .p3d-shadow {
  animation-play-state: paused;
}

@media (min-width: 960px) {
  .phones-3d .p3d { --d: 32px; }
  .phones-3d .p3d-sm { --d: 26px; }
}
@media (min-width: 1200px) {
  .phones-3d .p3d { --d: 34px; }
  .phones-3d .p3d-sm { --d: 27px; }
}
/* Phones stack under the text on narrow screens: a gentler turn. */
@media (max-width: 959px) {
  .phones-3d .p3d { --ry: -18deg; }
  .phones-3d .p3d[data-face='right'] { --ry: 18deg; }
}

@media (prefers-reduced-motion: reduce) {
  .phones-3d .p3d-float,
  .phones-3d .p3d-shadow {
    animation: none !important;
  }
}
