/* ============================================================
 * PNGI — Visuals: media frames, 3D motion, art-safe fallbacks
 * ------------------------------------------------------------
 * One small layer that every page can use so imagery behaves the same
 * everywhere: fixed aspect boxes (no layout shift while a photo decodes),
 * a scrim so captions stay readable on any picture, a hover tilt that reads as
 * a physical object, and a guaranteed non-broken state — if a file is missing or
 * blocked, the frame keeps its gradient and the caption, never a broken icon.
 *
 * Everything animated here is disabled under prefers-reduced-motion, and the
 * pointer-driven effects are dropped on touch devices where hover does not exist.
 * ============================================================ */

.p3d {
  position: relative;
  display: block;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--radius-lg, 20px);
  background:
    radial-gradient(120% 90% at 78% 12%, rgba(0, 212, 255, .16), transparent 60%),
    radial-gradient(110% 100% at 12% 96%, rgba(124, 58, 237, .20), transparent 62%),
    linear-gradient(145deg, #0f2044 0%, #120a35 55%, #050a1a 100%);
  border: 1px solid rgba(255, 255, 255, .10);
}
/* Skeleton: painted under the image, so a decoded photo hides it by itself. */
.p3d::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .07) 45%, transparent 70%);
  background-size: 220% 100%;
  animation: p3d-sweep 2.4s linear infinite;
}
@keyframes p3d-sweep { from { background-position: 120% 0 } to { background-position: -80% 0 } }

.p3d-img {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: 0;
  background: none;
}
/* Art that failed to load leaves the frame's gradient + caption, not a broken glyph. */
.p3d-img[data-failed] { opacity: 0 }
.p3d:has(.p3d-img[data-failed])::before { animation: none }

.p3d-scrim {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  height: 62%;
  background: linear-gradient(to top, rgba(3, 7, 20, .92) 0%, rgba(3, 7, 20, .55) 45%, transparent 100%);
  pointer-events: none;
}
.p3d-cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  padding: .8rem .95rem;
  font-size: .8rem;
  line-height: 1.45;
  color: #eaf2ff;
}
.p3d-cap b { display: block; font-size: .9rem; font-weight: 800; letter-spacing: -.01em; color: #fff }
.p3d-cap span { display: block; color: rgba(233, 240, 255, .72); font-size: .74rem }

/* Honesty pill: these pictures are renders of the product, not photographs of
   a building we are claiming. It says which. */
.p3d-tag {
  position: absolute;
  top: .6rem;
  right: .6rem;
  z-index: 4;
  padding: .2rem .5rem;
  border-radius: 999px;
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(226, 238, 255, .72);
  background: rgba(5, 10, 26, .62);
  border: 1px solid rgba(255, 255, 255, .14);
  backdrop-filter: blur(6px);
}
.p3d-chip {
  position: absolute;
  left: .6rem;
  bottom: .6rem;
  z-index: 4;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  font-size: 1.05rem;
  background: rgba(5, 10, 26, .74);
  border: 1px solid rgba(255, 255, 255, .16);
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
}
.p3d-over { position: relative; z-index: 3 }

/* ---- aspect boxes: the height is known before the bytes arrive ---------- */
.p3d-21x9 { aspect-ratio: 21 / 9 }
.p3d-16x9 { aspect-ratio: 16 / 9 }
.p3d-1x1  { aspect-ratio: 1 / 1 }

/* ---- motion: depth on hover, drift in the hero ------------------------- */
.p3d-tilt {
  transform: perspective(900px) translateZ(0);
  transform-style: preserve-3d;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1), box-shadow .35s ease, border-color .35s ease;
  will-change: transform;
}
.p3d-tilt:hover,
.p3d-tilt:focus-visible {
  transform: perspective(900px) rotateX(4deg) rotateY(-5deg) translateY(-4px) scale(1.012);
  box-shadow: 0 26px 58px rgba(0, 0, 0, .5), 0 0 0 1px rgba(0, 212, 255, .22) inset;
  border-color: rgba(0, 212, 255, .42);
  outline: none;
}
.p3d-tilt:hover .p3d-img { transform: scale(1.045) }
.p3d-img { transition: transform .6s cubic-bezier(.2, .7, .2, 1), opacity .35s ease }

.p3d-kb .p3d-img { animation: p3d-kenburns 26s ease-in-out infinite alternate }
@keyframes p3d-kenburns {
  from { transform: scale(1) translate3d(0, 0, 0) }
  to   { transform: scale(1.07) translate3d(-1.4%, -1%, 0) }
}

/* Emissive edge: makes a rectangular render read as a lit object on a dark page. */
.p3d-glow::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  box-shadow: 0 0 60px rgba(26, 108, 247, .22) inset, 0 0 1px rgba(0, 212, 255, .5) inset;
}

/* Blend a wide render into the page background instead of ending on a hard edge. */
.p3d-mask-soft  { -webkit-mask-image: radial-gradient(120% 100% at 50% 40%, #000 55%, transparent 100%); mask-image: radial-gradient(120% 100% at 50% 40%, #000 55%, transparent 100%) }

/* ---- page hooks used by the home grid cards ---------------------------- */
.p3d-cat { border-radius: 14px; margin: 0 0 .7rem }
.p3d-cat .p3d-chip { width: 26px; height: 26px; border-radius: 8px; font-size: .82rem; left: .45rem; bottom: .45rem }

/* ---- phones and stylus/touch: no hover, smaller frames ----------------- */
@media (pointer: coarse) {
  .p3d-tilt:hover { transform: none; box-shadow: none }
  .p3d-tilt:hover .p3d-img { transform: none }
}
@media (prefers-reduced-motion: reduce) {
  .p3d::before { animation: none }
  .p3d-kb .p3d-img { animation: none }
  .p3d-tilt, .p3d-tilt:hover { transform: none }
  .p3d-tilt:hover .p3d-img { transform: none }
  .p3d-img, .p3d-tilt { transition: none }
}
@media print {
  .p3d { border: 1px solid #cbd5e1; background: #fff }
  .p3d-scrim, .p3d-tag { display: none }
  .p3d-cap { position: static; color: #0f172a; padding: .35rem 0 0 }
  .p3d-cap b, .p3d-cap span { color: #0f172a }
}
