/* face.css - piece P13 (the Storyteller particle face). Owner: P13.
   The mount .stage__center[data-center="face"] is placed and sized by
   stage.css (P2); nothing here moves or resizes it. This sheet dresses what
   face.js puts INSIDE it: one transparent canvas, so the page's dot lattice
   shows through between the ink points. Nothing here paints a colour.

   The bleed. The canvas is the mount plus --face-bleed on every side (10% of
   the box: 58px on the 576px mount at 1440x900, 35px on the phone's 348).

   IT CAME DOWN FROM 12.5% WITH THE SUBJECT, and the reason is worth stating,
   because a bleed that is merely "generous" is how a fringe gets clipped. On
   the retired portraits the fit box was the head's DENSE silhouette (the data's
   2..98 percentile) and everything loose - antenna tips, beard wisps - lived
   outside it, so the bleed had to hold a real part of the picture. The bear
   ships with a matte, and with a matte there are no loose ends: the sampler
   frames the drawing's own bounding box, so NOTHING is outside the fit box at
   rest and the bleed only has to hold the yaw's overhang.
   That overhang is arithmetic rather than taste. The model spans x -0.549..0.519
   of the unit box about its origin and z -0.182..0.443 about the pivot, so at
   yaw 15 the widest point lands at 0.519*cos15 + 0.443*sin15 = 0.616 and the
   far edge at -0.577, against a canvas half-width of (288 + 58) / 493 = 0.701.
   Pitch 10 is the same sum vertically (0.633 against 0.765). Both clear, with
   room, and `beefydanFace.clipped` reports any point whose kernel crosses the
   edge so the claim is checked rather than asserted.

   THE MOUNT IS A SQUARE AND SO IS THIS SOURCE (1254x1254 against the retired
   1792x2400), which changes which bound binds. face.js fits the box as
   min(mountH / fitH, mountW / (fitW + YAW_ROOM)); a portrait-shaped head filled
   the mount's HEIGHT, and a square one is bound by the WIDTH, because the 0.10
   of yaw room has to come from somewhere. So the bear renders 526 x 493 in a
   576 mount - 25 px of air each side, 41 px top and bottom - and that air is
   not a shortfall, it is the room the head turns into.
   The frame is the mount; the mount's own box is untouched (overflow: visible
   is stage.css's).

   Fallback box: while no stylesheet positions the mount (face.js finds it
   position: static / unsized and adds `face--self-placed`), the mount takes
   the geometry P2 was briefed with - a clamp(280px, 42vh, 520px) square,
   centred horizontally, centred in the field above the band's resting line
   (100% - --band-h - 1px hairline). The class is never added once stage.css
   positions the mount, so this block cannot fight P2's rule. */

/* THE EMANATION'S LENGTH, and the only place it is stated.
   Dan, 2026-09-04: "the pixelated behavior when it appears is too fast. Slow it
   down by 50% so it's more dramatic when it materializes." So the piece takes
   TWO of the site's materialisation beats instead of one: 2 x --dur-condense =
   1800ms. It is a count, not a duration, on purpose - the site's beat stays the
   one clock (P6's showcase condense and this head still start from the same
   number), and this piece says how many of it the bear is worth. A count is
   also the only form face.js can read back: an unregistered custom property
   holding `calc(900ms * 2)` computes to that literal string, and parseFloat of
   it is NaN.
   Nothing else about the entrance moves with it. The stagger, the ease, the
   arrival order and the wavefront are functions of one progress scalar q; this
   number only says how long q takes to cross 0..1, so the motion Dan approved
   is the same motion, twice as long. */
.stage__center[data-center="face"] {
  --face-emanate-beats: 2;
  --face-bleed: 10%;
  /* stage.css's contract: how far past the mount this centrepiece paints, for
     the FIRST FRAME only - from the moment there is paint, stage.js measures the
     canvas's own alpha and that wins. The bear's whole silhouette is INSIDE the
     mount at rest (it is bound by the width, so it stops 25 px short on each
     side and 41 px top and bottom); only a turned head reaches into the bleed,
     and only by about 21 px. The honest first-frame answer is therefore ZERO -
     declaring the whole bleed would have stood the statement 58 px lower than
     the drawing's real floor for exactly one frame, and then jumped it. */
  --center-bleed: 0px;
  pointer-events: none;
  user-select: none;
}

.stage__center.face--self-placed {
  position: absolute;
  left: 50%;
  top: calc((100% - var(--band-h, 30svh) - 1px) / 2);
  width: clamp(280px, 42vh, 520px);
  height: clamp(280px, 42vh, 520px);
  transform: translate(-50%, -50%);
  z-index: 1;
}

/* the canvas: the mount's box grown by the bleed on all four sides. A canvas
   is a replaced element - four insets alone leave it at its intrinsic 300x150
   (measured) - so the box is stated outright: offset by the bleed, sized to
   the mount plus twice the bleed (percentages of the mount's own box). */
.face__canvas {
  position: absolute;
  top: calc(-1 * var(--face-bleed, 0px));
  left: calc(-1 * var(--face-bleed, 0px));
  width: calc(100% + 2 * var(--face-bleed, 0px));
  height: calc(100% + 2 * var(--face-bleed, 0px));
  display: block;
  max-width: none;
  pointer-events: none;
  background: transparent;
}

/* the box exists before the data does; nothing flashes in the meantime */
.stage__center[data-center="face"][data-face="loading"] .face__canvas,
.stage__center[data-center="face"][data-face="failed"] .face__canvas {
  visibility: hidden;
}
