/* ==========================================================================
   THE WORKSHOP — the piece under the cursor.

   The monumental D'HiPPO stands unglazed, front on, on the studio's red. Move
   across it and it is painted where your hand is: the commission shows
   through a clean round window and the rest of the body stays bare. Nothing
   turns, nothing nods, nothing is staged — the reveal IS the idea, and it is
   the one interaction that reads instantly without a single instruction.

   THE WINDOW IS A CIRCLE. It was turbulence-displaced smoke; on a photograph
   that reads as a broken JPEG rather than as atmosphere, and it fought the
   object instead of showing it. A hard-edged circle with three per cent of
   feather is the whole effect.

   IT MOVES ON A GAP, NOT ON POSITION. Mapping twenty-three commissions across
   the width of a body gives each of them thirty pixels, so the smallest
   movement flickers through six of them and none of them is ever seen. The
   piece changes once per ninety pixels of TRAVEL, and never twice inside two
   hundred milliseconds — so a slow sweep walks the range one commission at a
   time and stopping holds one still.

   Every layer is the studio's own photograph of a commission that was really
   painted, registered offline onto the blank's frame: same head top, same
   foot line, same axis, same plinth. That registration is why the window can
   sit anywhere on the body and the design lines up underneath it.

   The red was sampled out of the renders: #D40011 where the light lands,
   falling to #94000A in the far corners.
   ========================================================================== */

.wk-section {
  --wk-lit:    #D40011;
  --wk-red:    #C10010;
  --wk-deep:   #94000A;
  --wk-cream:  #EFEAE0;
  --wk-gap:    clamp(18px, 2.4vw, 34px);   /* the only vertical measure here */

  position: relative;
  isolation: isolate;
  color: var(--wk-cream);
  background: radial-gradient(126% 88% at 50% 104%,
              var(--wk-lit) 0%, var(--wk-red) 46%, var(--wk-deep) 100%);
  border-top-color: transparent;
  padding-top:    calc(var(--wk-gap) * 2);
  padding-bottom: calc(var(--wk-gap) * 2);
  overflow: hidden;
}
.wk-section + .section--hair { border-top-color: transparent; }

.wk-section .eyebrow { color: rgba(239, 234, 224, .55); }
.wk-section .display-l { color: var(--wk-cream); }
.wk-section :focus-visible { outline-color: var(--wk-cream); }

/* The sweep the render was shot on, put back under the cut-out. */
.wk-section::before {
  content: ""; position: absolute; inset: auto 0 0; height: 44%;
  background: linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,255,255,.05) 60%, rgba(255,255,255,.08));
  pointer-events: none; z-index: 0;
}
.wk-section > * { position: relative; z-index: 1; }

[data-workshop] { width: 100%; align-self: stretch; }

.wk-head {
  display: flex; flex-direction: column; align-items: center;
  gap: calc(var(--wk-gap) * .35); text-align: center;
  margin-bottom: calc(var(--wk-gap) * 1.6);
}

/* ==========================================================================
   One centred column, spaced by one number.
   ========================================================================== */

.wk {
  --wk-h: clamp(300px, 62vh, 620px);
  display: flex; flex-direction: column; align-items: center;
  gap: calc(var(--wk-gap) * 1.2);
  text-align: center;
}

/* ---- the piece ---------------------------------------------------------- */

.wk__stage {
  /* A LENGTH, not a percentage. `radial-gradient(circle 27% at ...)` is not
     valid CSS — a percentage radius is only allowed on an ellipse — and an
     invalid mask silently paints nothing at all. */
  --wk-r: calc(var(--wk-h) * .215);
  position: relative;
  height: var(--wk-h);
  aspect-ratio: 720 / 1120;
  cursor: none;
  touch-action: pan-y;
}
.wk__stage img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block; user-select: none; -webkit-user-drag: none;
}

/* Everything painted lives inside one masked box, so the window is defined
   once and switching commission is only an opacity change. */
.wk__reveal {
  /* clip-path, not a mask.
   *
   * A radial-gradient mask is the textbook way to do this and in Chrome it
   * hid the layer outright — opacity 1, src loaded, geometry correct, nothing
   * painted, and no rule in any stylesheet that said it should be hidden.
   * `-webkit-mask-image` and `mask-image` disagreeing about whether a
   * gradient is alpha or luminance is a fight not worth having for a shape
   * that is a circle. clip-path IS a circle, is one line, and cannot be read
   * two ways. The edge is hard on purpose: the smoke this replaced read as a
   * broken JPEG on a photograph. */
  position: absolute; inset: 0;
  clip-path: circle(var(--wk-r) at var(--wk-x, 50%) var(--wk-y, 42%));
}
/* Pinned from the rail: the whole piece wears it, no window. */
.wk--worn .wk__reveal { clip-path: none; }
/* ONE image, whose src changes — not twenty-three stacked and cross-faded.
 * The stack looked right on paper and was unreadable in practice: with a
 * transition on each layer the browser held the incoming one at zero opacity
 * indefinitely, and no rule in any sheet said it should. One element cannot
 * have that argument with itself. The next commission is decoded off-screen
 * before it is swapped in, so the change is instant and never flashes. */
.wk__coat { opacity: 1; }

/* The cursor. A ring, and nothing else — no smoke, no wobble, no filter. */
.wk__lens {
  /* left/top, not translate: a percentage in translate() is a percentage of
     the LENS, and a percentage in left/top is a percentage of the stage — and
     the stage is what the pointer was measured against. */
  position: absolute; pointer-events: none;
  left: var(--wk-x, 50%); top: var(--wk-y, 42%);
  width: calc(var(--wk-r) * 2); aspect-ratio: 1;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(239, 234, 224, .5);
  transform: translate(-50%, -50%);
  opacity: 0; transition: opacity .3s var(--ease);
  will-change: left, top;
}
.wk__stage:hover .wk__lens { opacity: 1; }
.wk--worn .wk__lens { opacity: 0 !important; }

/* its reflection in the floor */
.wk__floor {
  position: absolute; left: 0; right: 0; top: 99%; height: 28%;
  overflow: hidden; pointer-events: none;
  opacity: .26; filter: blur(1.5px);
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,.8), rgba(0,0,0,0) 94%);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,.8), rgba(0,0,0,0) 94%);
}
.wk__floor img {
  position: absolute; left: 0; top: 0; width: 100%; height: auto;
  transform: scaleY(-1); display: block;
}

/* ==========================================================================
   The rail.
   ========================================================================== */

.wk__rail { display: flex; flex-direction: column; align-items: center; gap: var(--wk-gap); width: 100%; }

.wk__name {
  font-family: var(--display); font-weight: 300; font-synthesis: none;
  text-transform: uppercase; font-size: clamp(19px, 1.8vw, 26px);
  line-height: 1.1; letter-spacing: 0; margin: 0; color: var(--wk-cream);
  min-height: 1.1em;
}

.wk__ask {
  font-family: var(--body); font-size: 11px; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; margin: 0;
  color: rgba(239, 234, 224, .62);
}
.wk__ask b { color: var(--wk-cream); }

.wk__list {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  /* twelve to a row, twice — an even block reads as a palette */
  margin: 0; padding: 0; list-style: none; max-width: 728px;
}
.wk__sw {
  appearance: none; -webkit-appearance: none;
  width: 52px; height: 52px; padding: 0; border: 0; border-radius: 0;
  cursor: pointer; background-color: rgba(0,0,0,.16);
  background-size: 168%; background-position: 50% 34%; background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px rgba(239, 234, 224, .26);
  transition: box-shadow .3s var(--ease-ui), transform .3s var(--ease-ui);
}
.wk__sw:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px rgba(239,234,224,.7); }
.wk__sw.is-on {
  box-shadow: inset 0 0 0 2px var(--wk-cream), 0 8px 18px -8px rgba(0,0,0,.7);
  transform: translateY(-3px);
}
.wk__sw--blank { background: var(--wk-cream); }

/* ==========================================================================
   Narrower rooms. The column is centred, so only the scale changes.
   ========================================================================== */

@media (max-width: 1079.98px) { .wk { --wk-h: clamp(280px, 52vh, 460px); } }
@media (max-width: 639.98px) {
  .wk { --wk-h: clamp(260px, 44vh, 380px); }
  .wk__sw { width: 42px; height: 42px; }
  .wk__stage { cursor: default; }
}

/* Reduced motion: it drifts on its own and the window is still a window. */
@media (prefers-reduced-motion: reduce) {
  .wk__lens { transition: none; }
}
