/* Clear Cut — the stage, shared by the phone (play.html) and the big screen (display.html).
   Lifted out of play.html unchanged. It lives on its own because BOTH screens draw the same falling
   log, and the one thing this game cannot afford is two copies of that drifting apart: the client's
   scoring bands already drifted from the server's once, and a cut that reads GREAT in your hand and
   GOOD on the stream is the same bug wearing a costume. One file, one fall. */
    /* ===== Clear Cut ===== */
.cc-head{ display:flex; align-items:center; justify-content:space-between; width:min(100%,420px); margin:0 auto 6px; }
.cc-kicker{ font-family:"Russo One",sans-serif; font-size:12px; letter-spacing:2px; text-transform:uppercase; color:#c9a24a; }
.cc-tier{ font-family:"Russo One",sans-serif; font-size:11px; letter-spacing:1.5px; text-transform:uppercase; color:#8c93a8; }
/* SQUARE, because the plate is square. At 4:5 the plate had to be `cover`-cropped to fill the box,
   which threw away 10% of its width off each side — the dojo's own door frames — and left the
   scene looking cut out rather than photographed. Cutting the discarded strips back in as separate
   layers is what produced the jagged doubled wall; the honest fix is to stop discarding them.
   Matching the plate means plate fractions ARE stage fractions, horizontally as well as vertically,
   so nothing has to be mapped through a crop any more.
   Fixed, not viewport-driven: a timing contest has to show every phone the same picture, and an
   aspect that varied would give a tall phone a longer visible drop. The svh cap changes only the
   overall size — svh not vh, because vh ignores the mobile browser chrome that was eating SLASH.
   420px, the same cap .cc-head and .cc-go carry: the square stage is shorter than the old 4:5 one
   and there was room to let it grow, but a wider stage than button leaves it standing proud of the
   column on any screen past 420px. Three numbers that have to agree, so they are the same number. */
.cc-stage{ position:relative; width:min(100%, 420px, 62svh); aspect-ratio:1/1; margin:0 auto; border-radius:16px;
  container-type:inline-size;   /* so the score can be sized to the stage (cqw) on any screen */
  overflow:hidden; background:#141a26 url('scyther/stage.webp') center/cover no-repeat;
  box-shadow:0 12px 30px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.07); touch-action:manipulation; }
/* Drifting clouds, in the sky window measured off the plate (13.2%-86.8% wide). The band's aspect
   band's height is set so the tile's aspect matches the strip's exactly — the clouds are never
   squashed. The band spans the WHOLE stage and the posts are drawn over it, so clouds leave the
   frame behind timber rather than stopping at a line in mid-sky. The inner is three band-widths
   and one tile is 49.04% of it, so translating by that is exactly one tile and the loop has no
   jump — and three still covers band plus tile. Slow on purpose: this screen is a timing test. */
/* Stage and plate are both square, so a plate fraction and a stage fraction are the same number.
   The sky window, measured off the plate: 13.17%-86.75%, used as-is now that the stage is square
   and shows the whole plate. It was the mis-mapping of exactly this that put a second, offset copy
   of the wall down each side with a hard step where it ended. */
.cc-sky{ position:absolute; left:13.17%; width:73.58%; top:7%; height:13.4%; z-index:1;
  overflow:hidden; pointer-events:none; }
/* No side posts. They existed to hide the clouds' ends behind timber, which a sky window cut to the
   actual opening does by itself — and they were the jagged edge, being an opaque rectangle of plate
   laid over a differently-scaled copy of the same plate. */
.cc-sky i{ position:absolute; top:0; bottom:0; left:0; width:300%;
  background:url('scyther/clouds.webp') repeat-x; background-size:53.32% 100%;
  animation:ccDrift 120s linear infinite; }
/* One tile exactly, so the loop has no jump. The tile is 2064x235; at the band's height (13.4%)
   that is 117.7% of the stage's width and 159.95% of the band, a third of that across the
   300%-wide runner. Unchanged by the square stage: band width and height scaled together. */
@keyframes ccDrift{ from{ transform:translateX(0) } to{ transform:translateX(-53.32%) } }
@media (prefers-reduced-motion:reduce){ .cc-sky i{ animation:none } }
/* Plain full width: the kerb is cut across the plate's whole width, and the whole width is now on
   screen. It needed a -12.5%/125% overhang only to survive the crop. */
.cc-lip{ position:absolute; left:0; width:100%; bottom:0; height:7.6%; z-index:8; pointer-events:none;
  background:url('scyther/stage-lip.webp') center/100% 100% no-repeat; }
/* The rig hangs BEHIND the dojo frame: the beam (z7) and the pit kerb (z8) both sit in front of
   the log (z6), so it is hidden across the beam's depth and shows again in the sky above it, and
   the cut halves drop away behind the kerb. The log still passes in FRONT of Scyther (z3). */
.cc-beam{ position:absolute; left:0; right:0; top:0; height:17.5%; z-index:7; pointer-events:none;
  background:url('scyther/stage-beam.webp') center/100% 100% no-repeat; }
.cc-scy{ position:absolute; left:50%; z-index:3; transform:translateX(-50%); transform-origin:50% 100%; pointer-events:none; }
.cc-scy.bob{ animation:ccBob 2.6s ease-in-out infinite; }
@keyframes ccBob{ 0%,100%{ transform:translateX(-50%) translateY(0) } 50%{ transform:translateX(-50%) translateY(-1.1%) } }
/* Contact shadow. Without it he reads as pasted onto the plate rather than standing on it — the
   plate has its own baked lighting and he arrived with none. An ellipse, not a round blob: the
   camera looks slightly DOWN on the slab (its top face is visible, 63.5%-68.8%), so a circle on
   the ground foreshortens. Sized and offset per pose from the sprite's own footprint — see CC_POSE.
   The wrapper carries the position and the size; the inner <i> carries the paint and the bob, so
   the two transforms never fight over the same property. */
/* -58%, not -50%: the camera looks down, so the ground recedes UPWARD on screen and a contact
   shadow falls mostly behind the feet. Centring it on the sole spread half the ellipse over the
   slab's front lip — he now stands on that lip, so that half had nothing to land on. */
.cc-shadow{ position:absolute; left:50%; z-index:3; transform:translate(-50%,-58%); pointer-events:none; }
.cc-shadow i{ display:block; width:100%; height:100%; border-radius:50%;
  background:radial-gradient(ellipse at 50% 50%, rgba(28,18,8,.5) 0%, rgba(28,18,8,.34) 45%, rgba(28,18,8,0) 72%); }
/* counter-phase with ccBob on the SAME clock: he rises, the shadow tightens and lifts off */
.cc-shadow.bob i{ animation:ccBobShadow 2.6s ease-in-out infinite; }
@keyframes ccBobShadow{ 0%,100%{ transform:scale(1); opacity:1 } 50%{ transform:scale(.93); opacity:.8 } }
.cc-winch{ position:absolute; left:50%; top:17%; z-index:6; transform:translateX(-50%); pointer-events:none; }
.cc-rope{ position:absolute; left:50%; z-index:6; width:0.88%; transform:translateX(-50%);
  background:url('scyther/rope.webp') center/100% auto repeat-y; pointer-events:none; }
.cc-log{ position:absolute; left:50%; z-index:6; overflow:hidden; aspect-ratio:204/1212; transform:translateX(-50%); pointer-events:none; }
.cc-log img{ display:block; width:100%; height:100%; }
/* The two halves are the SAME log image twice, each clipped to its side of the cut. Clipping the
   real sprite means the cut can land anywhere — no set of pre-cut log art could cover a continuous
   cut position — and the two faces always line up because they came from one picture. */
.cc-half{ position:absolute; left:50%; z-index:6; aspect-ratio:204/1212; transform:translateX(-50%);
  pointer-events:none; will-change:transform; }
.cc-half img{ display:block; width:100%; height:100%; }
/* Paint on the log, so exactly the log's width — nothing overhangs the silhouette. The sprite is
   drawn with the ring's plane at its vertical centre, so translateY(50%) puts that plane on the
   target height rather than the sprite's bottom edge.
   The ratio is the sprite's OWN: `100% 100%` stretches whatever it is given, so a box of the wrong
   shape silently squashes the arc. 204/136 was right here and always had been — it is the ribbon at
   the log's true camera angle. What drifted was the SPRITE, which quietly shrank to 204/106 when the
   generator lost its grip on the cap size, and the reveal's copy of this rule was then "corrected"
   to match the broken art. Both are back on the sprite's real shape. */
.cc-band{ position:absolute; inset:0; z-index:7; pointer-events:none;
  -webkit-mask:url('scyther/log.webp') center/100% 100% no-repeat;
          mask:url('scyther/log.webp') center/100% 100% no-repeat; }
.cc-line{ position:absolute; left:0; width:100%; aspect-ratio:204/136;
  transform:translateY(50%);
  background:url('scyther/ribbon.webp') center/100% 100% no-repeat; }
.cc-fx{ position:absolute; left:50%; z-index:9; transform:translate(-50%,-50%); pointer-events:none; opacity:0; }
.cc-fx.go{ animation:ccFx .5s ease-out forwards; }
@keyframes ccFx{ 0%{ opacity:0; transform:translate(-50%,-50%) scale(.4) } 25%{ opacity:1; transform:translate(-50%,-50%) scale(1.05) } 100%{ opacity:0; transform:translate(-50%,-50%) scale(1.25) } }
/* The halves keep falling after they part — they drop past the block and vanish behind the pit
   kerb, which sits above them in z-order. They used to stop dead in mid-air a moment after the cut. */
@keyframes ccTopOff{ 12%{ transform:translateX(-50%) translate(-7%, 6%) rotate(-11deg) }
                    100%{ transform:translateX(-50%) translate(-13%, 105%) rotate(-31deg) } }
@keyframes ccBotOff{ 12%{ transform:translateX(-50%) translate(3%, 8%) rotate(5deg) }
                    100%{ transform:translateX(-50%) translate(7%, 118%) rotate(14deg) } }
/* cc-up / cc-dn, NOT top / bot: `.top` is already the page header's class, and a half carrying it
   picked up display:flex and the header's layout, which is what turned the upper half into a box. */
.cc-half.cc-up{ animation:ccTopOff 1.15s cubic-bezier(.4,0,.85,1) forwards; }
.cc-half.cc-dn{ animation:ccBotOff 1.15s cubic-bezier(.45,0,.9,1) forwards; }
/* SCORE REVEAL: the two cut pieces rise back out of the pit they fell into, parted at the cut, so
   the swing can be read against the line. Nothing carries them — no rope, no riser. Both were tried
   and both raised the question of what the mechanism was, when the only thing worth looking at is
   where the cut landed against the paint.
   Sized by HEIGHT (LOGH) plus the sprite's aspect, exactly as the hanging log is, so the piece that
   rises is the same log that fell and neither can drift from the other. */
.cc-reveal{ position:absolute; left:50%; bottom:33%; height:55%; aspect-ratio:204/1212; z-index:7;
  pointer-events:none; transform:translateX(-50%) translateY(185%);
  animation:ccRise 4s cubic-bezier(.3,.45,.35,1) forwards; }
/* 4s, MUST equal RISE_MS in games/clearcut.js (which spaces the logs around it). Slow on purpose: the
   pieces come up under the "Clear Cut End" jingle, and at 1.05s they had arrived before the music had
   got going. The ease is gentle so they are still visibly climbing late into it. The how-to card has no
   music and stays quick (see .ccd below). */
/* 185% of its own height clears the stage floor below it, so it enters from off-screen rather than
   fading in mid-air: the box's foot sits 36% up, which is 80% of its own height above the stage's
   bottom edge, and another 100% takes the whole piece below that. */
@keyframes ccRise{ to{ transform:translateX(-50%) translateY(0) } }
/* Each piece is a FULL-log box, so both share one coordinate space and the cut lines up by
   construction; only the upper one is moved, to open the gap. */
.cc-rev-piece{ position:absolute; inset:0; }
/* The gap has to beat the cut ellipse's own height or the pieces do not part at all: the upper
   piece's face and the lower piece's dome are the SAME ellipse, so until the lift exceeds it one is
   simply drawn over the other. 110/1212 of the log is 9.1% of it, and 15.5% leaves about a
   finger of daylight between them. */
.cc-rev-piece.up{ transform:translateY(-15.5%); }
.cc-rev-piece > img.barrel{ display:block; width:100%; height:100%; }
/* The two ends, each cut from the log's own sprite. We are BELOW the cut, so the lower piece shows
   no sawn face at all — just barrel bending away, which is the log's repainted top end — while the
   upper piece shows its face, which is the log's bottom end. One exposed end per piece, and the
   curves are the sprite's own, not an approximation of them. */
/* translateY(50%) centres the end ON the cut, the same way the paint line is centred on its own
   value — so "how far is the cut from the line" is a comparison of two like things on screen. */
.cc-rev-end{ position:absolute; left:0; width:100%; transform:translateY(50%); }
/* No z-order fight between the paint and the face, because with the ring drawn at the log's true cap
   size the two can no longer disagree: the ring's arc and the face's near rim are congruent curves,
   so wherever the line sits above the cut the paint sits above the rim by exactly that much, and
   never lands on end-grain at all. Layering the face on top was a patch for the era when the ring was
   drawn a fifth too flat — and it cost more than it fixed, swallowing the ring whole on a dead-on cut
   when that is the one cut whose paint you most want to see. */
/* Full-size, for two reasons. The piece's own cut clip applies to the paint in the piece's
   coordinates — and, being the log's box exactly, it can be MASKED BY THE LOG. The bark is inset from
   that box by a few px, and by a different few at each height, so the ring's ends were landing on
   bare sky and drawing their dark end-caps there as two little ticks floating off the silhouette.
   Masking with log.webp's own alpha ends the paint precisely where the wood does, at every height,
   because it is the same picture asking the same question. */
.cc-rev-band{ position:absolute; inset:0; z-index:3;
  -webkit-mask:url('scyther/log.webp') center/100% 100% no-repeat;
          mask:url('scyther/log.webp') center/100% 100% no-repeat; }
.cc-rev-line{ position:absolute; left:0; width:100%; aspect-ratio:204/136; z-index:3;
  transform:translateY(50%); background:url('scyther/ribbon.webp') center/100% 100% no-repeat; }
.cc-hint{ text-align:center; font-size:13px; font-weight:700; color:#8c93a8; margin:10px auto 0; min-height:18px; }
.cc-go{ display:block; width:min(100%,420px); margin:12px auto 0; font:inherit; font-family:"Russo One",sans-serif;
  font-size:22px; letter-spacing:2px; padding:20px 0; border:0; border-radius:16px; color:#1a1204;
  background:linear-gradient(180deg,#ffe07a,#e5a820); box-shadow:0 8px 24px rgba(245,197,66,.35); cursor:pointer; }
.cc-go:disabled{ filter:grayscale(.7) brightness(.6); box-shadow:none; }
.cc-verdict{ text-align:center; font-family:"Russo One",sans-serif; font-size:26px; letter-spacing:2px; margin:12px 0 2px; }
.cc-verdict.PERFECT{ color:#ffe07a } .cc-verdict.GREAT{ color:#37d18a } .cc-verdict.GOOD{ color:#7fd0ff }
.cc-verdict.CLOSE{ color:#d3ad3f } .cc-verdict.OFF,.cc-verdict.MISS,.cc-verdict.LATE{ color:#ff8f8f }


/* ===== How-to mini (the playable card on the phone's how-to screen) =====
   The round's own stage, filling the card's square. Sized in cqw because the card is a size container. */
.ccd{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2.5cqh; padding:3cqh 0; cursor:pointer; -webkit-user-select:none; user-select:none; }
/* The stage stays square (it is the plate's shape) and gives up height to the SLASH button below it. */
.ccd .cc-reveal{ animation-duration:1.05s; animation-timing-function:cubic-bezier(.2,.75,.3,1); }
.ccd-view{ position:relative; height:76%; aspect-ratio:1/1; flex:none; }
.ccd-stage{ width:100%; height:100%; border-radius:3cqw; box-shadow:none; }
/* The round's own gold SLASH, scaled to the card: the how-to should show the thing you will press. */
.ccd-go.cc-go{ width:76%; margin:0; padding:0; height:14%; font-size:6.5cqw; letter-spacing:.5cqw; border-radius:3cqw;
  box-shadow:0 1cqw 3cqw rgba(245,197,66,.35); flex:none; }
.ccd-read{ position:absolute; left:0; right:0; bottom:2%; z-index:10; display:flex; flex-direction:column;
  align-items:center; gap:.6cqw; pointer-events:none; text-shadow:0 1px 3px rgba(0,0,0,.85); }
.ccd-verdict{ font-family:"Russo One",sans-serif; font-size:9cqw; letter-spacing:.5cqw; margin:0; line-height:1; white-space:nowrap; }
.ccd-verdict:empty{ display:none; }
.ccd-cap{ font-size:4.4cqw; white-space:nowrap; font-weight:800; color:#fff; padding:.8cqw 3cqw; border-radius:99px; background:rgba(0,0,0,.45); }

/* THE SCORE, big on the stage as the cut pieces rise. Over the floor and pit, the one band of the stage
   the rising pieces never reach (they stop a third of the way up), so it never sits across the log. */
.cc-pts{ position:absolute; left:0; right:0; bottom:3%; z-index:11; display:flex; flex-direction:column;
  align-items:center; gap:1cqw; pointer-events:none; opacity:0; }
.cc-pts.on{ animation:ccPtsIn .5s cubic-bezier(.2,1.5,.4,1) forwards; }
@keyframes ccPtsIn{ from{ opacity:0; transform:scale(.55) translateY(4cqw) } to{ opacity:1; transform:none } }
.cc-pts b{ font-family:"Russo One",sans-serif; font-size:17cqw; line-height:1; letter-spacing:.3cqw; color:#ffe07a;
  text-shadow:0 .6cqw 0 rgba(0,0,0,.45), 0 0 4cqw rgba(0,0,0,.55); }
.cc-pts b small{ font-size:6cqw; margin-left:1cqw; letter-spacing:.2cqw; opacity:.9; }
.cc-pts.GREAT b{ color:#37d18a } .cc-pts.GOOD b{ color:#7fd0ff } .cc-pts.CLOSE b{ color:#d3ad3f }
.cc-pts.OFF b, .cc-pts.MISS b, .cc-pts.LATE b{ color:#ff8f8f }
.cc-pts span{ font-size:4cqw; font-weight:800; color:#fff; padding:.8cqw 3cqw; border-radius:99px; background:rgba(0,0,0,.5); }
@media (prefers-reduced-motion:reduce){ .cc-pts.on{ animation:none; opacity:1 } }
/* how-to: the points sit in the verdict line instead */
.ccd-pts{ font-size:.8em; margin-left:.4em; }
