/* Stratum — depth.
   Loaded for the 3D and 5D formats only.

   3D  Planes get real Z offsets inside a perspective container, the masthead
       responds to hover, and cards lift. Nothing moves on its own.

   5D  Adds two axes that only exist while someone is reading:
       time     — --stx-scroll (0 to 1) drives plane separation and drift.
       presence — --stx-px/--stx-py (pointer position, as percentages) and
                  --stx-pxn/--stx-pyn (the same, normalised to -1…1) drive the
                  light source, parallax and tilt.

   Every offset is multiplied by --stx-k, the intensity setting, so one slider
   scales the whole system. All four pointer properties have sensible defaults
   in :root, so the layout is correct before any event arrives and stays correct
   if the script never loads. */

.stx-depth-3d .stx-stage,
.stx-depth-5d .stx-stage {
  perspective: var(--stx-perspective);
  transform-style: preserve-3d;
}

/* ------------------------------------------------------------- plane depths */

.stx-depth-3d [data-plane],
.stx-depth-5d [data-plane] {
  transform-style: preserve-3d;
  transition: transform .4s cubic-bezier(.2, .7, .3, 1);
}

.stx-depth-3d .stx-stage [data-plane="1"],
.stx-depth-5d .stx-stage [data-plane="1"] { transform: translateZ(calc(52px * var(--stx-k))); }
.stx-depth-3d .stx-stage [data-plane="2"],
.stx-depth-5d .stx-stage [data-plane="2"] { transform: translateZ(calc(26px * var(--stx-k))); }
.stx-depth-3d .stx-stage [data-plane="3"],
.stx-depth-5d .stx-stage [data-plane="3"] { transform: translateZ(0); }
.stx-depth-3d .stx-stage [data-plane="4"],
.stx-depth-5d .stx-stage [data-plane="4"] { transform: translateZ(calc(-40px * var(--stx-k))); }
.stx-depth-3d .stx-stage [data-plane="5"],
.stx-depth-5d .stx-stage [data-plane="5"] { transform: translateZ(calc(-72px * var(--stx-k))); }

/* --------------------------------------------------------------- 5D: presence */
/* The whole stage leans toward the pointer. Three degrees is the ceiling: past
   that the wordmark starts to look like it is falling over rather than sitting
   on a surface. */

.stx-depth-5d .stx-stage {
  transform:
    rotateX(calc(var(--stx-pyn) * -2.2deg * var(--stx-k)))
    rotateY(calc(var(--stx-pxn) * 3deg * var(--stx-k)));
  transition: transform .5s cubic-bezier(.2, .7, .3, 1);
}

.stx-depth-5d .stx-plane-bg__sweep,
.stx-depth-5d .stx-holo__sweep { transition: none; }

/* Parallax on the back planes: they slide against the pointer, which is what
   makes the separation read as distance rather than as a drop shadow. */
.stx-depth-5d .stx-stage [data-plane="4"] {
  transform:
    translateZ(calc(-40px * var(--stx-k)))
    translate3d(calc(var(--stx-pxn) * -14px * var(--stx-k)), calc(var(--stx-pyn) * -8px * var(--stx-k)), 0);
}

.stx-depth-5d .stx-stage [data-plane="5"] {
  transform:
    translateZ(calc(-72px * var(--stx-k)))
    translate3d(calc(var(--stx-pxn) * -22px * var(--stx-k)), calc(var(--stx-pyn) * -12px * var(--stx-k)), 0);
}

/* ------------------------------------------------------------------ 5D: time */
/* Strata bands separate as the page scrolls instead of the masthead shrinking.
   --stx-scroll is written by depth.js on a rAF loop and clamped to 0…1. */

.stx-depth-5d .stx-bands__band[data-plane="5"] { transform: translateY(calc(var(--stx-scroll) * -26px * var(--stx-k))); }
.stx-depth-5d .stx-bands__band[data-plane="4"] { transform: translateY(calc(var(--stx-scroll) * -14px * var(--stx-k))); }
.stx-depth-5d .stx-bands__band[data-plane="3"] { transform: translateY(calc(var(--stx-scroll) * 12px * var(--stx-k))); }

.stx-depth-5d .stx-plane-bg__grid {
  transform: translate3d(calc(var(--stx-pxn) * -10px), calc(var(--stx-scroll) * -30px), 0);
}

/* --------------------------------------------------------------- magnetic nav */
/* Links lean toward the pointer. The offset is written per link by depth.js and
   defaults to zero, so this rule is inert until it is. */

.stx-depth-5d .stx-nav__list > li > a {
  transform: translate3d(var(--stx-mx, 0px), var(--stx-my, 0px), 0);
}

/* ----------------------------------------------------------------- wordmark */
/* In 5D the extrusion direction follows the light, so the side face appears on
   the far side of the letterform from the pointer. */

.stx-depth-5d .stx-brand--extrude .stx-brand__word {
  transform: translate3d(calc(var(--stx-pxn) * 4px * var(--stx-k)), calc(var(--stx-pyn) * 3px * var(--stx-k)), 0);
  transition: transform .35s cubic-bezier(.2, .7, .3, 1);
}

/* --------------------------------------------------------------------- cards */

.stx-cards-depth .stx-card,
.stx-cards-depth .stx-index__tile,
.stx-cards-depth .stx-lead__main,
.stx-cards-depth .stx-spot {
  transition: transform .28s cubic-bezier(.2, .7, .3, 1), box-shadow .28s ease, border-color .28s ease;
}

.stx-cards-depth .stx-card:hover,
.stx-cards-depth .stx-index__tile:hover,
.stx-cards-depth .stx-lead__main:hover {
  transform: translateY(calc(-4px * var(--stx-k)));
  box-shadow: var(--stx-elev-3);
  border-color: var(--stx-rim);
}

/* The pointer highlight travels across a photograph. On a card with no image it
   lands on flat colour and reads as a coloured smear, so those keep the lift
   and lose the highlight. */
.stx-depth-5d .stx-card:not(.stx-card--nomedia) { position: relative; }

.stx-depth-5d .stx-card:not(.stx-card--nomedia)::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s ease;
  background: radial-gradient(16rem 16rem at var(--stx-cx, 50%) var(--stx-cy, 50%),
    color-mix(in srgb, var(--stx-z1) 22%, transparent), transparent 62%);
}

.stx-depth-5d .stx-card:not(.stx-card--nomedia):hover::after { opacity: 1; }

/* Tilt on hovered cards, driven per card by depth.js. */
.stx-depth-5d [data-stx-tilt]:hover {
  transform:
    translateY(calc(-4px * var(--stx-k)))
    rotateX(calc(var(--stx-cyn, 0) * -2.5deg * var(--stx-k)))
    rotateY(calc(var(--stx-cxn, 0) * 2.5deg * var(--stx-k)));
}

.stx-depth-5d .stx-cards,
.stx-depth-5d .stx-mosaic,
.stx-depth-5d .stx-index { perspective: 1400px; }

/* ---------------------------------------------------------------- rim light */
/* A soft inset border rather than a blended gradient. An overlay gradient
   darkens a light card instead of lightening it, and a hard stop draws a seam
   across the surface — this does the same job in both schemes with neither
   problem. */

.stx-depth-3d .stx-card::before,
.stx-depth-5d .stx-card::before,
.stx-depth-3d .stx-plane--pad::before,
.stx-depth-5d .stx-plane--pad::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--stx-rim) 60%, transparent),
    inset 0 0 0 1px color-mix(in srgb, var(--stx-hairline) 70%, transparent);
}

.stx-plane--pad { position: relative; }

/* --------------------------------------------------------------- 404 stack */

.stx-depth-5d .stx-404__stack span[data-plane="3"] { transform: translate3d(calc(-14px + var(--stx-pxn) * -10px), 10px, 0); }
.stx-depth-5d .stx-404__stack span[data-plane="2"] { transform: translate3d(calc(-7px + var(--stx-pxn) * -5px), 5px, 0); }

/* ------------------------------------------------------------ reduced motion */
/* The clamp is repeated at the CSS level so a reader who asks for reduced
   motion gets a still masthead even when the setting says otherwise. */

@media (prefers-reduced-motion: reduce) {
  .stx-depth-5d .stx-stage,
  .stx-depth-5d .stx-stage [data-plane="4"],
  .stx-depth-5d .stx-stage [data-plane="5"],
  .stx-depth-5d .stx-brand--extrude .stx-brand__word,
  .stx-depth-5d .stx-nav__list > li > a,
  .stx-depth-5d .stx-plane-bg__grid,
  .stx-depth-5d [data-stx-tilt]:hover { transform: none !important; }

  .stx-depth-5d .stx-bands__band { transform: none !important; }
  .stx-rail--differential { transform: none !important; }
}
