/* Playground subpage (wave → a drawer of compartments). Same paper as the
   Work and About pages, thin #d4d4d4 lines like the Work dieline, very light
   fills, ghost title bottom-left, and the Photography project hover. */

/* Fade the collage layers, not the stage (see work.css for why). */
body.is-playground .stage {
  pointer-events: none;
}
body.is-playground .stage .bg,
body.is-playground .stage .layer,
body.is-playground .stage .camera-clean {
  opacity: 0;
}
body.is-playground .beam-canvas {
  visibility: hidden;
}

/* Ghost "Playground" title: bottom-left, as on the Photography page, and a
   link home (hover reads "Home" — script.js). */
body.is-playground .beam-label {
  pointer-events: auto;
  cursor: pointer;
}
body.is-playground .beam-label {
  left: 3vw;
  top: 88vh;
  transform: translate(0, -50%);
  font-size: clamp(3rem, 8vw, 7rem);
  z-index: 7;
  transition: none; /* the move to the corner is a FLIP on transform (script.js) */
}

.playground {
  position: fixed;
  inset: 0;
  z-index: 6;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  opacity: 0;
  transition: opacity 0.35s ease 0.05s;
}
.playground::-webkit-scrollbar {
  display: none;
}
.playground[hidden] {
  display: none;
}
.playground.is-on {
  opacity: 1;
}
/* Back to the homepage: the whole page fades out at once, in step with the
   collage fading in (same 0.5s, no delay) — one crossfade. */
.playground:not(.is-on) {
  transition: opacity 0.5s ease;
}
.pg-end {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
}

/* ---- The scene: a 2D stage (scaled to fit) > perspective box > 3D world ---- */
.pg-stage {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
}
.pg-drawer {
  position: relative;
  perspective-origin: 50% -10%; /* the eye: centred, above the drawer */
}
.pg-world,
.pg-tray {
  position: absolute;
  transform-style: preserve-3d;
}
.pg-world > *,
.pg-tray > * {
  position: absolute;
  box-sizing: border-box;
}
/* Closed: pushed into the cabinet (only the front panel shows). */
.pg-tray {
  transform: translateY(var(--pull));
  transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.45s;
}
.pg-drawer.is-open .pg-tray,
.pg-drawer.is-measure .pg-tray {
  transform: none;
}
/* Going home: pushed back in quickly (ease-in, no delay); the rows fade as
   they go back into the cabinet, the front panel stays. */
.pg-drawer.is-closing .pg-tray {
  /* the opening slide, rewound: same length, reversed curve */
  transition: transform 0.8s cubic-bezier(0.64, 0, 0.78, 0);
}
/* Each row stays until it passes into the cabinet (--cd, playground.js),
   then goes quickly. */
.pg-drawer.is-closing .pg-part,
.pg-drawer.is-closing .pg-card,
.pg-drawer.is-closing .pg-shadow {
  transition: opacity 0.12s linear var(--cd, 0ms);
}
.pg-drawer.is-closing .pg-ground {
  transition: opacity 0.6s ease 0.2s;
}

/* ---- Material: frosted acrylic, an almost neutral warm white (base
   rgb(246, 243, 238), barely warmer than the page), ~65% on walls and
   dividers, ~80% on the floor. Edges catch the light: a warm near-white line just
   inside a thin warm-grey outline. The grain (--grain) makes it frosted. */
.pg-drawer {
  --acrylic: 246, 243, 238;
  --acrylic-lit: 250, 248, 245;
  --acrylic-shade: 239, 236, 231;
  --edge: #d6d4d0;
  --glint: rgba(255, 254, 252, 0.95);
}
.pg-cab {
  border: 1px solid var(--edge);
  background: rgba(var(--acrylic), 0.12);
}
.pg-floor,
.pg-face,
.pg-rim,
.pg-front-face {
  background-image: var(--grain);
  background-size: 45px 45px;
  border: 1px solid var(--edge);
}
.pg-floor {
  background-color: rgba(var(--acrylic), 0.8);
  border: 0;
}
.pg-face {
  backface-visibility: hidden;
}
/* Dividers */
.pg-face.is-facing {
  background-color: rgba(var(--acrylic), 0.65);
  box-shadow: inset 0 1px 0 var(--glint);
}
.pg-face.is-lit {
  background-color: rgba(var(--acrylic-lit), 0.65);
  box-shadow: inset 1px 0 0 var(--glint);
}
.pg-face.is-shaded {
  background-color: rgba(var(--acrylic-shade), 0.65);
  box-shadow: inset -1px 0 0 var(--glint);
}
.pg-rim {
  background-color: rgba(var(--acrylic-lit), 0.78);
  box-shadow: inset 0 0 0 1px var(--glint);
}
/* The drawer's own walls: a touch denser. */
.pg-shell.is-facing {
  background-color: rgba(var(--acrylic), 0.72);
}
.pg-shell.is-lit {
  background-color: rgba(var(--acrylic-lit), 0.72);
}
.pg-shell.is-shaded {
  background-color: rgba(var(--acrylic-shade), 0.72);
}
.pg-shell.pg-rim {
  background-color: rgba(var(--acrylic-lit), 0.85);
}
/* Wall segments meet row to row without a seam line. */
.pg-shell.pg-face:not(.is-first),
.pg-shell.is-side:not(.is-first) {
  border-top-width: 0;
}
.pg-shell.pg-face:not(.is-last),
.pg-shell.is-side:not(.is-last) {
  border-bottom-width: 0;
}
/* Front panel: frosted too; the front-row cards' bottoms show through. */
.pg-front-face {
  background-color: rgba(var(--acrylic), 0.7);
  border-color: #d1cfcb;
  box-shadow: inset 0 0 0 1px var(--glint);
}
.pg-front-top {
  background-color: rgba(var(--acrylic-lit), 0.85);
}
/* Optional frosted blur behind the walls (M.blur). Off by default: inside
   a 3D scene browsers don't render it reliably. */
.pg-drawer.has-blur .pg-face,
.pg-drawer.has-blur .pg-front-face {
  -webkit-backdrop-filter: blur(6px) saturate(1.1);
  backdrop-filter: blur(6px) saturate(1.1);
}
/* Handle: light grey metal with a small highlight. */
.pg-handle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 18%;
  height: 9%;
  transform: translate(-50%, -50%);
  border: 1px solid #b9b7b4;
  border-radius: 999px;
  background: linear-gradient(to bottom, #f6f6f6, #d6d5d3 55%, #c4c3c1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95);
}
/* The drawer's soft shadow on the page (light from the top-left). */
.pg-ground {
  pointer-events: none;
  box-shadow: 20px 30px 90px 14px rgba(40, 30, 20, var(--shadow));
}
.pg-part,
.pg-front,
.pg-cab,
.pg-ground,
.pg-shadow {
  pointer-events: none; /* hover/click go to the invisible .pg-hit planes */
}

/* Cards: stand on the floor, turned to face the viewer (the floor's tilt,
   undone), like slides in a white mount. --z lifts them straight up. */
.pg-card {
  transform-origin: 50% 100%;
  transform: translateZ(var(--z, 0px)) rotateX(calc(-1 * var(--tilt)))
    translate(var(--fx, 0px), var(--fy, 0px)) rotate(var(--fr, 0deg)) scale(var(--sc, 1));
  border: 6px solid #ffffff; /* the slide mount (M.mount; a % padding would follow the tray width) */
  overflow: hidden;
  background: #ffffff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
}
.pg-card img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
}
/* Objects: cutouts standing as they are — no mount, whole image shown. */
.pg-obj {
  border: 0;
  background: none;
  box-shadow: none;
  overflow: visible;
}
.pg-obj img {
  object-fit: contain;
  object-position: 50% 100%;
}
/* The upcoming project's label: only on hover, above its object (2D). */
.pg-ph-label {
  position: absolute;
  transform: translate(-50%, -100%);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 10px;
  line-height: 1.35;
  letter-spacing: 0;
  color: #8f8f8f;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease 0.1s;
}
.pg-ph-label.is-on {
  opacity: 1;
}

/* Seen through the acrylic: soft and washed out. */
.pg-img-soft {
  filter: blur(3px) saturate(0.55) contrast(0.75) brightness(1.18);
}
/* The sharp image ends where the wall in front starts hiding the card
   (--cut, from the bottom); when the card rises it slides down in step. */
.pg-img-sharp {
  clip-path: inset(0 0 var(--cut, 0px) 0); /* static */
}
/* When the card rises, the full sharp image fades in over the clipped one. */
.pg-img-full {
  opacity: 0;
  transition: opacity var(--rise-ms, 350ms) cubic-bezier(0.22, 1, 0.36, 1);
}
.pg-card.is-on .pg-img-full {
  opacity: 1;
}
/* Pointer only when projects are links (linkProjects in the config). */
a.pg-run,
.pg-hit[href] {
  cursor: pointer;
}
.pg-run {
  outline: none;
}
.pg-loose {
  pointer-events: none; /* hover comes from the compartment's .pg-hit planes */
}
.pg-paper {
  background: linear-gradient(to bottom, #f5f3f0, #fdfcfb 40%);
  box-shadow: 0 0 0 1px #d9d9d9;
}
.pg-card-label {
  position: absolute;
  left: 9%;
  right: 7%;
  top: 10%;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 9px;
  line-height: 1.35;
  letter-spacing: 0;
  color: #a3a3a3;
}
.pg-shadow {
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.09), rgba(0, 0, 0, 0));
}

/* Hover: the item rises straight up out of its compartment; a project's
   stack rises into one centred column (front item at the bottom). Loose
   items rise too. */
.pg-card.is-on {
  --z: var(--rise);
  --fx: var(--dx, 0px);
  --sc: var(--cs, 1); /* < 1 only when a column must shrink to fit */
}

/* ---- Entry: rows appear as they come out of the cabinet; cards after. ---- */
.pg-part,
.pg-card,
.pg-shadow,
.pg-ground {
  opacity: 0;
  transition: opacity 0.3s ease calc(0.45s + var(--rd, 0ms)),
    transform var(--rise-ms, 350ms) cubic-bezier(0.22, 1, 0.36, 1);
}
.pg-drawer.is-open .pg-part,
.pg-drawer.is-open .pg-card,
.pg-drawer.is-open .pg-shadow,
.pg-drawer.is-open .pg-ground {
  opacity: 1;
}
.pg-drawer.is-settled .pg-part,
.pg-drawer.is-settled .pg-card,
.pg-drawer.is-settled .pg-shadow,
.pg-drawer.is-settled .pg-ground,
.pg-front,
.pg-cab {
  transition: opacity 0.4s ease, transform var(--rise-ms, 350ms) cubic-bezier(0.22, 1, 0.36, 1);
}
.pg-drawer.is-instant *,
.pg-drawer.is-measure * {
  transition: none !important;
}

/* ---- Project hover: the Photography treatment. ---- */
.pg-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.pg-bg.is-on {
  opacity: 1;
}
/* Hovering a project: its background image fills the page behind the
   drawer (which stays, frosted over it); every other item fades out; the
   hovered one floats up. */
.playground.has-active .pg-item:not(.is-on) {
  opacity: 0;
}
.playground.has-active .pg-ground {
  opacity: 0;
}
/* The ghost title turns white over the image. */
body.is-playground .beam-label {
  transition: color 0.5s ease; /* the move itself: FLIP on transform (script.js) */
}
body.is-pg-hover .beam-label,
body.is-pg-hover .beam-label::after {
  color: #ffffff;
}
body.is-pg-hover .beam-label.show-home {
  color: transparent;
}
.pg-names {
  position: absolute;
  left: 0;
  top: 0;
}
.pg-name {
  position: absolute;
  transform: translate(-100%, -50%);
  text-align: right;
  font-family: "Inter", system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.04em;
  font-size: clamp(0.85rem, 1.35vw, 1.4rem);
  line-height: 1.2;
  color: #ffffff;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.pg-name.is-on {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  body.is-playground .stage .bg,
  body.is-playground .stage .layer,
  body.is-playground .stage .camera-clean,
  body.is-playground .beam-label,
  .playground,
  .pg-drawer *,
  .pg-bg,
  .pg-name {
    transition: none !important;
  }
}
