/* ============================================================================
   The Assembly: Platypus Media homepage act.
   Ships as assets/pm-assembly.css, loaded after assets/styles.css.

   Mechanism. The pinned act publishes --sc-p (0..1) on itself; everything
   below is plain CSS custom-property math on that value, no engine device
   beyond pin, one whisper of parallax on the desk plate, and the engine's
   cues for the caption, the part labels and the title block.

     --e     per part: a smoothstep of (--p - --s0) / --sw. 0 = exploded,
             1 = seated. Drives the piece transform, the leader line, the
             parts-list tick, and (through the engine cue windows, which are
             authored to the same numbers) the label.
     --fill  0 -> 1 over p 0.66 -> 0.79. The silhouette masks wipe in from
             the bill to the tail in the mark's own colours. The peak.
     --ring  0 -> 1 over p 0.74 -> 0.90. A ring draws around the creature.

   Colours are the site's own light-palette values written literally, not
   the theme tokens: the act sits on a photograph of cream paper, so it stays
   light even if the tweaks panel flips the page to dark.
   ========================================================================== */

.pma-intro,
.pma {
  --pma-paper:     #F2EEE5;
  --pma-off:       #FAF8F4;
  --pma-ink:       #0E0E10;
  --pma-ink-soft:  #2a2a2e;
  --pma-muted:     #6b6b70;
  --pma-amber:     #C76B2C;
  --pma-navy:      #0A2E5C;
  --pma-navy-deep: #061f3f;
  --pma-grey:      #4B4B4F;
  --pma-line:      rgba(14, 14, 16, 0.16);
  --pma-display:   var(--font-display, "Space Grotesk", "Helvetica Neue", Arial, sans-serif);
  --pma-serif:     var(--font-serif, "Instrument Serif", Georgia, serif);
  --pma-body:      var(--font-body, "Manrope", "Helvetica Neue", Arial, sans-serif);
  --pma-mono:      "JetBrains Mono", "SF Mono", ui-monospace, monospace;
  color: var(--pma-ink);
}

/* ------------------------------------------------------------ intertitle
   A printed title on the page's own off-white. The hard cut into the paper
   plate below is the first "distinct scene". */
.pma-intro {
  background: var(--pma-off);
  padding-block: clamp(3rem, 7vw, 6rem) clamp(2.5rem, 6vw, 5rem);
}
.pma-intro__wrap {
  width: 100%;
  max-width: 1360px;
  margin-inline: auto;
  padding-inline: var(--gutter, clamp(1.25rem, 3vw, 2rem));
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 2rem 4rem;
  align-items: end;
}
.pma-intro__h {
  margin: 0;
  font-family: var(--pma-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(2.4rem, 1.5rem + 4.2vw, 5.4rem);
  line-height: 0.98;
  letter-spacing: -0.01em;
  color: var(--pma-ink);
  max-width: 13ch;
  text-wrap: balance;
}
.pma-intro__p {
  margin: 0;
  font-family: var(--pma-body);
  font-size: var(--step-1, clamp(1.15rem, 1.05rem + 0.4vw, 1.35rem));
  line-height: 1.5;
  color: var(--pma-ink-soft);
  max-width: 40ch;
  text-wrap: pretty;
}

/* ------------------------------------------------------------- the act */
.pma {
  padding: 0;
  margin: 0;
  background: var(--pma-paper);
  --p: var(--sc-p, 0);
  --fill: clamp(0, calc((var(--p) - 0.66) / 0.13), 1);
  --ring: clamp(0, calc((var(--p) - 0.74) / 0.16), 1);
}
/* No `position` here: .sc-stage (also on this element) sets sticky, and a
   same-specificity rule later in the cascade would silently un-pin it.
   Only add what .sc-stage does not already set. */
.pma__stage {
  overflow: clip;
  background: var(--pma-paper);
  color: var(--pma-ink);
  font-family: var(--pma-body);
  --box-w: min(50vw, 720px);
  --box-h: calc(var(--box-w) / 2.925);
  --box-x: 27%;
  --box-y: 36%;
}

/* the desk plate: far plane, drifts a little slower than the paper on it.
   Wider than the stage on purpose: the sheet's edges and the tools sit at
   the plate's own edges, and `cover` only hides them when the viewport is
   at least 16:10. A short, wide window (a real 1440x900 browser window has
   ~150px of chrome) fits the plate by width and drags the sheet's left edge
   under the parts list. Overscanning 12% a side keeps the sheet edge-to-edge
   at every aspect the act can meet. */
.pma__desk {
  position: absolute;
  inset: -3% -12%;
  z-index: 0;
}
.pma__desk picture,
.pma__desk img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* ---------------------------------------------------------------- parts
   One set of numbers per part, read by the piece, its leader, its row. */
.pma [data-part] {
  --t: clamp(0, calc((var(--p) - var(--s0)) / var(--sw)), 1);
  --e: calc(var(--t) * var(--t) * (3 - 2 * var(--t)));
}
.pma [data-part="body"] { --s0: 0.22; --sw: 0.14; --dx: 3%;   --dy: -7%;  --rot: 0deg;  }
.pma [data-part="tail"] { --s0: 0.30; --sw: 0.14; --dx: 11%;  --dy: 42%;  --rot: 5deg;  }
.pma [data-part="feet"] { --s0: 0.38; --sw: 0.14; --dx: -5%;  --dy: 52%;  --rot: 0deg;  }
.pma [data-part="bill"] { --s0: 0.46; --sw: 0.14; --dx: -8%;  --dy: -60%; --rot: -7deg; }
.pma [data-part="eye"]  { --s0: 0.56; --sw: 0.10; --dx: 9%;   --dy: -78%; --rot: 0deg;  }

/* the drawing box: every piece is this box, clipped to its own part */
.pma__box {
  position: absolute;
  left: var(--box-x);
  top: var(--box-y);
  width: var(--box-w);
  height: var(--box-h);
  z-index: 3;
}
.pma__piece {
  position: absolute;
  inset: 0;
  z-index: 2;
  will-change: transform;
  transform:
    translate(calc(var(--dx) * (1 - var(--e))), calc(var(--dy) * (1 - var(--e))))
    rotate(calc(var(--rot) * (1 - var(--e))));
}
.pma__piece[data-part="body"] { clip-path: url(#pma-clip-body); }
.pma__piece[data-part="tail"] { clip-path: url(#pma-clip-tail); }
.pma__piece[data-part="feet"] { clip-path: url(#pma-clip-feet); }
.pma__piece[data-part="bill"] { clip-path: url(#pma-clip-bill); }
.pma__piece[data-part="eye"]  { clip-path: url(#pma-clip-eye); }

.pma__fill,
.pma__line {
  position: absolute;
  inset: 0;
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
.pma__fill {
  -webkit-mask-image: url(plat-sil.webp);
          mask-image: url(plat-sil.webp);
  background: var(--pma-navy);
  clip-path: inset(0 calc((1 - var(--fill)) * 100%) 0 0);
}
.pma__piece[data-part="bill"] .pma__fill { background: var(--pma-grey); }
.pma__piece[data-part="tail"] .pma__fill { background: var(--pma-ink); }
.pma__piece[data-part="feet"] .pma__fill { background: var(--pma-navy); }
.pma__line {
  -webkit-mask-image: url(plat-line.webp);
          mask-image: url(plat-line.webp);
  background: var(--pma-ink);
  opacity: calc(1 - 0.6 * var(--fill));
}
/* the mark's white eye: a dot that lands with the fill */
.pma__eye-dot {
  position: absolute;
  left: 20.3%;
  top: 23.4%;
  width: 2.1%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--pma-off);
  translate: -50% -50%;
  transform: scale(var(--fill));
}

/* the ring: behind the pieces, draws from the top, clockwise */
.pma__ring {
  position: absolute;
  z-index: 1;
  width: calc(var(--box-h) * 1.28);
  height: calc(var(--box-h) * 1.28);
  left: 47%;
  top: 50%;
  translate: -50% -50%;
  rotate: -90deg;
  overflow: visible;
}
/* No vector-effect here: non-scaling-stroke breaks pathLength-normalised
   dashes in Chrome, so the ring drew as fractional arcs at ring = 0.
   Stroke width is in the circle's own units (100 = the ring's diameter). */
.pma__ring circle {
  fill: none;
  stroke: var(--pma-ink);
  stroke-width: 0.5;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--ring));
}

/* leader lines: label to exploded part, dashed, fade as the part seats */
.pma__leaders {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  z-index: 4;
  pointer-events: none;
}
.pma__leader {
  opacity: calc(1 - var(--e));
}
.pma__leader line {
  stroke: var(--pma-amber);
  stroke-width: 0.18;
  stroke-dasharray: 1.4 1;
  stroke-linecap: round;
}
.pma__leader circle { fill: var(--pma-amber); }
.pma__leaders--mobile { display: none; }

/* part labels: real markup, one per part, positioned in box coordinates.
   The label <p> stays non-interactive by default (it fades in on a cue and
   an invisible link would still be a click target); pm-assembly.js flips
   pointer-events to auto once a label's own opacity says it is legible. */
.pma__label {
  position: absolute;
  z-index: 5;
  margin: 0;
  width: max-content;
  max-width: 15rem;
  font-family: var(--pma-body);
  font-size: 0.9rem;
  line-height: 1.35;
  color: var(--pma-ink);
  translate: 0 -50%;
  pointer-events: none;
}
.pma__label-link {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.1rem 0.6rem;
  color: inherit;
  text-decoration: none;
  border-radius: 4px;
}
.pma__label-link:hover b,
.pma__label-link:focus-visible b {
  color: var(--pma-amber);
  text-decoration: underline;
  text-underline-offset: 0.22em;
}
.pma__label-link:focus-visible {
  outline: 2px solid var(--pma-amber);
  outline-offset: 4px;
}
.pma__label svg {
  grid-row: 1 / span 2;
  width: 18px;
  height: 18px;
  stroke: var(--pma-amber);
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  margin-top: 2px;
}
.pma__label b {
  font-family: var(--pma-mono);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pma-ink);
}
.pma__label span { color: var(--pma-ink-soft); }

.pma__label[data-part="eye"]  { left: 44%; top: -55%; }
.pma__label[data-part="bill"] { left: 9%;  top: -26%; }
.pma__label[data-part="body"] { left: 62%; top: -30%; }
.pma__label[data-part="tail"] { left: 76%; top: 150%; }
.pma__label[data-part="feet"] { left: 6%;  top: 165%; }

/* ------------------------------------------------------------- caption */
.pma__caption {
  position: absolute;
  z-index: 6;
  right: 5%;
  top: 12%;
  margin: 0;
  max-width: 20rem;
  text-align: right;
}
.pma__caption-big {
  display: block;
  font-family: var(--pma-serif);
  font-style: italic;
  font-size: clamp(1.8rem, 1.2rem + 2vw, 3rem);
  line-height: 1;
  color: var(--pma-ink);
}
.pma__caption-small {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--pma-mono);
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pma-ink-soft);
}

/* ---------------------------------------------------------- parts list
   The chrome. A live ruled table: ticks as each part seats, rows jump. */
.pma__parts {
  position: absolute;
  z-index: 6;
  left: 4%;
  top: 50%;
  translate: 0 -50%;
  width: clamp(12.5rem, 16.5vw, 15.5rem);
  /* its own paper plate, same ruled-block language as the title block, so
     legibility never depends on what part of the photograph is under it */
  padding: 0.8rem 0.9rem 0.35rem;
  border: 1px solid var(--pma-ink);
  background: rgba(242, 238, 229, 0.94);
}
.pma__parts-h {
  margin: 0 0 0.35rem;
  padding-bottom: 0.45rem;
  border-bottom: 1px solid var(--pma-ink);
  font-family: var(--pma-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pma-ink-soft);
}
.pma__parts-ol { list-style: none; margin: 0; padding: 0; }
.pma__row button {
  all: unset;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: 1.7rem 1fr auto;
  align-items: center;
  column-gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0 0.45rem;
  border-bottom: 1px solid var(--pma-line);
  cursor: pointer;
  font-family: var(--pma-mono);
  font-size: 0.72rem;
  color: var(--pma-ink);
  transition: color 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.pma__row button:focus-visible { outline: 2px solid var(--pma-amber); outline-offset: 3px; border-radius: 4px; }
.pma__row button:active { transform: translateY(1px); }
.pma__no { color: var(--pma-ink-soft); font-variant-numeric: tabular-nums; }
.pma__part {
  font-family: var(--pma-display);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: -0.01em;
  color: color-mix(in oklab, var(--pma-ink-soft) calc((1 - var(--e)) * 100%), var(--pma-ink));
}
.pma__disc {
  grid-column: 2;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--pma-ink-soft);
}
.pma__tick {
  grid-column: 3;
  grid-row: 1 / span 2;
  width: 0.72rem;
  height: 0.72rem;
  border: 1px solid var(--pma-ink);
  position: relative;
}
.pma__tick::after {
  content: "";
  position: absolute;
  inset: 1px;
  background: var(--pma-amber);
  transform: scale(var(--e));
  transform-origin: center;
}
@media (hover: hover) and (pointer: fine) {
  .pma__row button:hover .pma__part { color: var(--pma-amber); }
}

/* ---------------------------------------------------------- title block
   The close. A small ruled block in the trailing corner; the CTA is a
   field of the block, not a button island. Holds. */
.pma__title {
  position: absolute;
  z-index: 7;
  right: 4%;
  bottom: 6%;
  width: min(22rem, 92vw);
  padding: 1rem 1.1rem 0.6rem;
  border: 1px solid var(--pma-ink);
  background: rgba(242, 238, 229, 0.86);
}
.pma__title-h {
  margin: 0;
  padding-right: 3rem;
  font-family: var(--pma-display);
  font-weight: 700;
  letter-spacing: -0.03em;
  font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.5rem);
  line-height: 1;
  color: var(--pma-ink);
}
.pma__title-p {
  margin: 0.7rem 0 0.9rem;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--pma-ink-soft);
  text-wrap: pretty;
}
.pma__fields {
  margin: 0;
  border-top: 1px solid var(--pma-ink);
}
.pma__fields > div {
  display: grid;
  grid-template-columns: 3.6rem 1fr;
  column-gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--pma-line);
  font-size: 0.8rem;
  line-height: 1.35;
}
.pma__fields > div:last-child { border-bottom: 0; }
.pma__fields dt {
  font-family: var(--pma-mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pma-ink-soft);
  padding-top: 0.2em;
}
.pma__fields dd { margin: 0; color: var(--pma-ink); }
.pma__cta {
  display: inline-block;
  font-family: var(--pma-display);
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--pma-ink);
  text-decoration: underline;
  text-decoration-color: var(--pma-amber);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.22em;
  transition: color 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.pma__cta:hover { color: var(--pma-amber); }
.pma__cta:active { transform: translateY(1px); }
.pma__mark {
  position: absolute;
  top: 0.85rem;
  right: 0.9rem;
  width: 36px;
  height: 36px;
}

/* ------------------------------------------------------- reduced motion
   The resolved state, still: everything seated and filled, the ring drawn,
   the title block open, the parts list fully ticked (it carries every
   discipline, so the exploded labels can go). No position changes. */
@media (prefers-reduced-motion: reduce) {
  .pma { --p: 1; }
  .pma .pma__caption,
  .pma .pma__label,
  .pma .pma__leaders { opacity: 0 !important; visibility: hidden; }
  .pma .pma__title { opacity: 1 !important; transform: none !important; pointer-events: auto !important; }
}

/* --------------------------------------------------------------- mobile
   Art-directed separately: the drawing spans the width, the parts explode
   vertically, the parts list becomes a strip along the bottom edge. */
@media (max-width: 860px) {
  .pma__stage { --box-w: 88vw; --box-x: 6%; --box-y: 45%; }

  .pma [data-part="body"] { --dx: 0%;   --dy: 0%;    --rot: 0deg;  }
  .pma [data-part="tail"] { --dx: 4%;   --dy: 100%;  --rot: 4deg;  }
  .pma [data-part="feet"] { --dx: -2%;  --dy: 175%;  --rot: 0deg;  }
  .pma [data-part="bill"] { --dx: 2%;   --dy: -108%; --rot: -6deg; }
  .pma [data-part="eye"]  { --dx: 12%;  --dy: -178%; --rot: 0deg;  }

  .pma__label { font-size: 0.78rem; max-width: 12.5rem; }
  .pma__label-link { gap: 0.05rem 0.45rem; }
  .pma__label svg { width: 15px; height: 15px; }
  .pma__label b { font-size: 0.62rem; }
  .pma__label[data-part="eye"]  { left: 42%;  top: -156%; }
  .pma__label[data-part="bill"] { left: 26%;  top: -78%; }
  .pma__label[data-part="body"] { left: 40%;  top: -32%; }
  .pma__label[data-part="tail"] { left: 2%;   top: 152%; }
  .pma__label[data-part="feet"] { left: 22%;  top: 306%; }
  .pma__leaders--desktop { display: none; }
  .pma__leaders--mobile { display: block; }

  .pma__ring { width: calc(var(--box-h) * 1.8); height: calc(var(--box-h) * 1.8); }

  .pma__caption {
    left: 5%;
    right: 5%;
    top: 5.2rem;
    max-width: none;
    text-align: left;
  }
  .pma__caption-big { font-size: clamp(1.6rem, 1rem + 3vw, 2.2rem); }

  .pma__parts {
    left: 4%;
    right: 4%;
    top: auto;
    bottom: 4.5%;
    translate: none;
    width: auto;
    padding: 0.35rem 0.6rem 0.5rem;
  }
  .pma__parts-h { display: none; }
  .pma__parts-ol { display: grid; grid-template-columns: repeat(5, 1fr); column-gap: 5px; }
  .pma__row button {
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    column-gap: 0.3rem;
    padding: 0.35rem 0 0;
    border-bottom: 0;
    border-top: 1px solid var(--pma-ink);
    font-size: 0.6rem;
  }
  .pma__part { font-size: 0.72rem; grid-column: 1 / -1; }
  .pma__disc { display: none; }
  .pma__tick { grid-column: 2; grid-row: 1; width: 0.5rem; height: 0.5rem; justify-self: end; }

  .pma__title {
    left: 4%;
    right: 4%;
    width: auto;
    bottom: 11%;
    padding: 0.8rem 0.9rem 0.4rem;
  }
  .pma__title-p { font-size: 0.82rem; margin: 0.5rem 0 0.7rem; }
  .pma__fields > div { padding: 0.4rem 0; font-size: 0.74rem; }
  .pma__mark { width: 30px; height: 30px; }
}

/* short desktop windows (a real 1440x900 browser window is ~750px of
   content): a slightly smaller, higher drawing so the title block clears
   the tail at the close. */
@media (min-width: 861px) and (max-height: 800px) {
  .pma__stage { --box-w: min(46vw, 660px); --box-y: 30%; }
}

/* compact phones (short viewports): the exploded column is compressed,
   leaders go (the pieces sit beside their labels), and the title block
   drops the lines the strip already carries so it clears the creature. */
@media (max-width: 860px) and (max-height: 700px) {
  .pma__stage { --box-y: 44%; }
  .pma [data-part="tail"] { --dy: 80%; }
  .pma [data-part="feet"] { --dy: 120%; }
  .pma [data-part="bill"] { --dy: -70%; }
  .pma [data-part="eye"]  { --dy: -120%; }
  .pma__leaders { display: none !important; }
  .pma__label { font-size: 0.72rem; max-width: 11.5rem; }
  .pma__label[data-part="eye"]  { left: 42%; top: -120%; }
  .pma__label[data-part="bill"] { left: 26%; top: -70%; }
  .pma__label[data-part="body"] { left: 46%; top: -24%; }
  .pma__label[data-part="tail"] { left: 2%;  top: 128%; }
  .pma__label[data-part="feet"] { left: 22%; top: 232%; }
  .pma__caption { top: 4.6rem; }
  .pma__caption-big { font-size: 1.45rem; }
  .pma__caption-small { margin-top: 0.3rem; font-size: 0.66rem; }
  .pma__ring { width: calc(var(--box-h) * 1.5); height: calc(var(--box-h) * 1.5); }
  .pma__title { bottom: 12%; padding: 0.7rem 0.8rem 0.3rem; }
  .pma__title-h { font-size: 1.5rem; }
  .pma__title-p,
  .pma__fields > div:first-child { display: none; }
  .pma__fields { margin-top: 0.6rem; }
}
