/* Device frames (ported from the mockup renderer). All sizes derive from --w on each device root. */

/* ── MacBook Pro (space black) ─────────────────────────────── */
.mbp { --w: 1600px; width: var(--w); position: relative; }
.mbp__lid {
  position: relative;
  width: 100%;
  aspect-ratio: 1512 / 982;
  padding: calc(var(--w) * 0.0145);
  padding-bottom: calc(var(--w) * 0.0175);
  border-radius: calc(var(--w) * 0.024) calc(var(--w) * 0.024) calc(var(--w) * 0.006) calc(var(--w) * 0.006);
  background: #050506;
  box-shadow:
    inset 0 0 0 calc(var(--w) * 0.0016) #3a3b3f,
    inset 0 0 0 calc(var(--w) * 0.0028) #121214;
  box-sizing: content-box;
  width: calc(100% - var(--w) * 0.029);
}
.mbp__screen {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: calc(var(--w) * 0.0085) calc(var(--w) * 0.0085) 0 0;
  background: #000;
}
.mbp__menubar { position: absolute; inset: 0 0 auto 0; height: 3.77%; background: #000; z-index: 2; }
.mbp__notch {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  width: 12.6%; height: 3.4%; background: #050506; z-index: 3;
  border-radius: 0 0 calc(var(--w) * 0.006) calc(var(--w) * 0.006);
}
.mbp__notch::after {
  content: ''; position: absolute; left: 50%; top: 32%; transform: translateX(-50%);
  width: calc(var(--w) * 0.0042); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #2b3550, #0b0d14 60%);
}
.mbp__shot { position: absolute; left: 0; right: 0; top: 3.77%; bottom: 0; background-size: cover; background-position: top center; }
.mbp__hinge {
  width: calc(100% - var(--w) * 0.03); height: calc(var(--w) * 0.006);
  margin: 0 auto;
  background: linear-gradient(#2a2b2e, #0c0c0d);
}
.mbp__base {
  position: relative;
  width: 110%; margin-left: -5%;
  height: calc(var(--w) * 0.019);
  border-radius: 0 0 calc(var(--w) * 0.05) calc(var(--w) * 0.05) / 0 0 calc(var(--w) * 0.016) calc(var(--w) * 0.016);
  background: linear-gradient(180deg, #5d5f64 0%, #2c2d30 18%, #1d1e20 55%, #0d0d0e 100%);
  box-shadow: inset 0 calc(var(--w) * 0.0012) 0 #8a8c91;
}
.mbp__base::before {
  content: ''; position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  width: 13%; height: 42%;
  border-radius: 0 0 calc(var(--w) * 0.012) calc(var(--w) * 0.012);
  background: linear-gradient(180deg, #121214, #2a2b2e);
}

/* ── iPhone 17 Pro (deep blue aluminium) ───────────────────── */
.iph { --w: 420px; --frame: #2c3a52; --frame-hi: #6f7f9c; width: var(--w); position: relative; }
.iph--silver { --frame: #b9bcc1; --frame-hi: #f4f5f7; }
.iph--orange { --frame: #c4612a; --frame-hi: #f0a06c; }
.iph__body {
  position: relative;
  width: 100%;
  aspect-ratio: 438 / 910;
  border-radius: calc(var(--w) * 0.165);
  padding: calc(var(--w) * 0.012);
  background:
    linear-gradient(135deg, var(--frame-hi) 0%, var(--frame) 18%, var(--frame) 82%, var(--frame-hi) 100%);
  box-shadow:
    inset 0 0 calc(var(--w) * 0.006) rgba(255,255,255,.45),
    inset 0 0 0 calc(var(--w) * 0.002) rgba(0,0,0,.35);
}
.iph__bezel {
  width: 100%; height: 100%;
  border-radius: calc(var(--w) * 0.153);
  background: #000;
  padding: calc(var(--w) * 0.032);
}
.iph__screen {
  position: relative; width: 100%; height: 100%;
  border-radius: calc(var(--w) * 0.125);
  overflow: hidden; background: #000;
}
.iph__shot { position: absolute; left: 0; right: 0; top: 6.6%; bottom: 0; background-size: cover; background-position: top center; }
.iph__status {
  position: absolute; inset: 0 0 auto 0; height: 6.6%; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.4% 9% 0 11%;
  font: 600 calc(var(--w) * 0.04) / 1 -apple-system, "SF Pro Text", "Helvetica Neue", sans-serif;
  letter-spacing: -0.01em;
}
.iph__status svg { height: calc(var(--w) * 0.03); width: auto; display: block; }
.iph__status-r { display: flex; gap: calc(var(--w) * 0.013); align-items: center; }
.iph__island {
  position: absolute; left: 50%; top: 1.25%; transform: translateX(-50%);
  width: 31.5%; height: 4.25%; border-radius: 999px; background: #000; z-index: 3;
}
.iph__home {
  position: absolute; left: 50%; bottom: 0.9%; transform: translateX(-50%);
  width: 36%; height: 0.6%; border-radius: 999px; z-index: 3;
}
.iph__btn { position: absolute; width: calc(var(--w) * 0.008); background: linear-gradient(90deg, var(--frame-hi), var(--frame)); border-radius: 2px; }
.iph__btn--a { left: calc(var(--w) * -0.006); top: 18%; height: 4%; }
.iph__btn--b { left: calc(var(--w) * -0.006); top: 25%; height: 7.5%; }
.iph__btn--c { left: calc(var(--w) * -0.006); top: 34%; height: 7.5%; }
.iph__btn--d { right: calc(var(--w) * -0.006); top: 28%; height: 11%; }
.iph__btn--e { right: calc(var(--w) * -0.005); top: 58%; height: 6%; }

/* ── Desktop display (aluminium, 16:10) ────────────────────── */
.disp { --w: 1800px; width: var(--w); position: relative; }
.disp__panel {
  width: 100%;
  padding: calc(var(--w) * 0.011);
  border-radius: calc(var(--w) * 0.012);
  background: linear-gradient(180deg, #d9dadd, #b7b9bd);
  box-shadow: inset 0 0 0 calc(var(--w) * 0.0012) #eceef0;
}
.disp__glass {
  padding: calc(var(--w) * 0.016);
  background: #070708;
  border-radius: calc(var(--w) * 0.006);
}
.disp__screen { position: relative; width: 100%; aspect-ratio: 1512 / 945; overflow: hidden; background: #000; }
.disp__shot { position: absolute; inset: 0; background-size: cover; background-position: top center; }
.disp__neck {
  width: 15%; height: calc(var(--w) * 0.15); margin: 0 auto;
  background: linear-gradient(90deg, #9fa1a5, #e3e4e6 30%, #cfd0d3 60%, #8f9195);
  clip-path: polygon(8% 0, 92% 0, 100% 100%, 0 100%);
}
.disp__foot {
  width: 26%; height: calc(var(--w) * 0.012); margin: 0 auto;
  border-radius: 0 0 calc(var(--w) * 0.006) calc(var(--w) * 0.006);
  background: linear-gradient(180deg, #e9eaec, #a9abaf);
}

/* glare on all glass */
.glare::after {
  content: ''; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background: linear-gradient(115deg, rgba(255,255,255,.07) 0%, rgba(255,255,255,.02) 32%, rgba(255,255,255,0) 33%);
}

/* ── Live device scenes: devices on the project's brand colour (--brand), lit from the top
      left with a dark floor, tilted in 3D. Pose is driven by assets/devices.js. ── */
.dscene{position:relative;overflow:hidden;border-radius:4px;background:var(--brand,#1a1a1a);container-type:size;aspect-ratio:16/9;isolation:isolate}
.dscene--tall{aspect-ratio:4/5}
.dscene::before{content:'';position:absolute;inset:0;z-index:0;
  background:
    radial-gradient(ellipse 70% 60% at 30% 18%, rgba(255,255,255,.26), transparent 70%),
    radial-gradient(ellipse 90% 40% at 50% 108%, rgba(0,0,0,.55), transparent 70%)}
.dscene::after{content:'';position:absolute;inset:0;z-index:3;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E")}
.dscene__cam{position:absolute;inset:0;z-index:1;perspective:160cqw;perspective-origin:50% 40%}
.dev{position:absolute;left:var(--x);top:var(--y);transform-origin:50% 50%;will-change:transform}
/* Shadows are box-shadows on the device shells, not filter:drop-shadow on the moving layer:
   a filter re-blurs on every transform update, a box-shadow is rasterized once */
.dscene{--sh:0 3cqw 4cqw rgba(0,0,0,.5),0 .6cqw .8cqw rgba(0,0,0,.3);--shk:1}
.dscene--clear{--sh:0 4cqw 5cqw rgba(0,0,0,.26),0 .6cqw .8cqw rgba(0,0,0,.16)}
/* small boxes (phones, grid tiles): the same shadow reads far heavier at a quarter of the size, so it is lighter there */
@container (max-width:560px){
  .dscene{--sh:0 2.4cqw 3.2cqw rgba(0,0,0,.28),0 .5cqw .7cqw rgba(0,0,0,.16);--shk:.6}
  .dscene--clear{--sh:0 3cqw 4cqw rgba(0,0,0,.16),0 .5cqw .7cqw rgba(0,0,0,.1)}
}
.dscene .iph__body{box-shadow:inset 0 0 calc(var(--w) * 0.006) rgba(255,255,255,.45),inset 0 0 0 calc(var(--w) * 0.002) rgba(0,0,0,.35),var(--sh)}
.dscene .mbp__lid{box-shadow:inset 0 0 0 calc(var(--w) * 0.0016) #3a3b3f,inset 0 0 0 calc(var(--w) * 0.0028) #121214,var(--sh)}
.dscene .scr{box-shadow:inset 0 0 0 1px rgba(255,255,255,.12),var(--sh)}
.dscene .iph__status{background:var(--brand,#000);color:var(--brand-ink,#fff)}
.dscene .iph__home{background:rgba(255,255,255,.85)}
/* Apple Studio Display: hairline aluminium edge, uniform black bezel, 16:9 panel, flat L stand */
.dscene .disp__panel{padding:calc(var(--w) * 0.004);border-radius:calc(var(--w) * 0.012);background:linear-gradient(180deg,#dcdde0,#b9bbbf);
  box-shadow:inset 0 0 0 calc(var(--w) * 0.0008) #f2f3f5,0 calc(var(--w) * 0.002) calc(var(--w) * 0.004) rgba(0,0,0,.25),var(--sh)}
.dscene .disp__glass{padding:calc(var(--w) * 0.016);background:#050506;border-radius:calc(var(--w) * 0.009)}
.dscene .disp__screen{aspect-ratio:16/9;border-radius:calc(var(--w) * 0.002)}
.dscene .disp__neck{width:17%;height:calc(var(--w) * 0.095);clip-path:none;border-radius:0;
  background:linear-gradient(90deg,#9ea0a4,#d9dadd 18%,#cfd0d3 70%,#96989c);box-shadow:inset 0 calc(var(--w) * 0.006) calc(var(--w) * 0.006) rgba(0,0,0,.35)}
.dscene .disp__foot{width:30%;height:calc(var(--w) * 0.03);border-radius:calc(var(--w) * 0.004);
  background:linear-gradient(180deg,#f0f1f3 0%,#d4d5d8 45%,#a9abaf 100%);box-shadow:inset 0 1px 0 #fff,0 calc(var(--w) * 0.006) calc(var(--w) * 0.012) rgba(0,0,0,.3)}
/* Bare screenshot card: the page itself, no device chrome
   (restored: it was dropped when the Studio Display block was rewritten) */
.scr{width:var(--w);aspect-ratio:16/10;border-radius:calc(var(--w) * 0.012);overflow:hidden;background:#000;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.12)}
.scr__shot{position:absolute;inset:0;background-size:cover;background-position:top center}
/* studio collage: floating devices run 20% larger */
.collage__item .dscene{--zoom:1.2}
/* the renderer's font stack is unavailable here; keep the status bar on the system face */
.dscene .iph__status{font-family:-apple-system,BlinkMacSystemFont,"Helvetica Neue",sans-serif}

/* Clear scenes: no backdrop, devices float on the page and may overhang the box */
.dscene--clear{background:transparent;overflow:visible}
.dscene--clear::before,.dscene--clear::after{display:none}


/* Inside a .media box the scene fills it; the box keeps its own aspect ratio */
.media > .dscene{aspect-ratio:auto;position:absolute;inset:0;transform:none;border-radius:0}
.fcase__media .dscene{border-radius:4px}
/* --zoom scales the devices up where the box is narrow (phones) */
.dscene{--zoom:1}
@media (max-width:820px){
  .proj-cover .dscene{--zoom:1.4}
  .b-image .dscene{--zoom:1.25}
  .b-pair .dscene{--zoom:1.1}
  .fcase--big .dscene{--zoom:1.3}
}

/* ── PNG device frames (assets/devices/*.png via scripts/build-devices.mjs) ──
   .pdev is the render at --w wide; the screen hole and the shadow box are placed by the
   percentages the build script measured. The shot sits under the PNG, so the bezel's own
   edge clips it. Overlays (status bar, island, menubar) keep the CSS-frame rules. */
.pdev{width:var(--w);aspect-ratio:var(--ar)}  /* position comes from .dev (absolute in the scene) */
.pdev__frame{position:absolute;inset:0;z-index:2;width:100%;height:100%;display:block;pointer-events:none;user-select:none;-webkit-user-drag:none}
.pdev__screen{position:absolute;z-index:1;overflow:hidden;background:#000}
.pdev__plane{position:absolute;inset:0;transform-origin:0 0;overflow:hidden}
/* angled render: the plane is mapped onto the screen corners (devices.js fitPlanes), the box itself stays clear */
.pdev__screen--quad{background:transparent;overflow:visible}
.pdev__screen--quad .pdev__plane{background:#000;backface-visibility:hidden}
/* An angled plane is a rectangle mapped onto the screen's four corners: its sharp corners poke past the
   device's rounded ones where the PNG is transparent. Clip the plane in its own space (clip-path applies
   before the transform) with the screen's corner radius and a hair of inset. */
.pdev--angled .iph__screen .pdev__plane{clip-path:inset(0.5% 0.9% round 13% / 6%)}
.pdev--angled .mbp__screen .pdev__plane{clip-path:inset(0.4% 0.3% round 1.6% / 2.6%)}
.pdev--angled .disp__screen .pdev__plane{clip-path:inset(0.4% 0.3% round 1.2% / 2%)}
.pdev--angled .tab__screen .pdev__plane{clip-path:inset(0.5% 0.5% round 5% / 3.8%)}
.pdev__shadow{position:absolute;z-index:0;border-radius:calc(var(--w) * 0.04);box-shadow:var(--sh)}
.pdev--iph .pdev__shadow{border-radius:calc(var(--w) * 0.16)}
.pdev--disp .pdev__shadow{border-radius:calc(var(--w) * 0.012)}
.pdev--mbp .pdev__shadow{border-radius:calc(var(--w) * 0.02)}
/* angled render: a box edge never matches the silhouette, so the shadow is a soft contact ellipse
   under the footprint (painted inside its box, nothing to read as a card) */
.pdev--angled .pdev__shadow{box-shadow:none;border-radius:50%;opacity:var(--shk,1);
  background:radial-gradient(ellipse 50% 50% at 50% 50%,rgba(0,0,0,.42),rgba(0,0,0,.18) 45%,transparent 72%);
  transform:translateY(12%) scale(1.25,1.1)}
.dscene--clear .pdev--angled .pdev__shadow{opacity:calc(.55 * var(--shk,1))}
/* the hole's own corners are rounded by the PNG; the shot stays square underneath */
.pdev .iph__shot,.pdev .mbp__shot{border-radius:0}
.pdev .disp__shot{position:absolute;inset:0}
.pdev .iph__status{padding-top:2.2%}
/* a PNG phone often draws its own island in the bezel layer: keep ours but let it sit tighter */
.pdev .iph__island{display:none}  /* the render draws its own island */
.pdev--tab .pdev__shadow,.pdev--crt .pdev__shadow{border-radius:calc(var(--w) * 0.03)}

/* Finished mockups (MOCKUPS in devices.js): one image per scene, contained, on its own sampled background */
.dscene--baked .dev.bake{left:50%;top:50%;width:100%;height:100%}
.dscene--baked::before{display:none}   /* the image carries its own light; the backdrop glow would show a seam */
.bake__img{position:absolute;inset:0;background:center / contain no-repeat}
