@font-face { font-family: "FranklinCn";
  src: url("../assets/fonts/FranklinGothicLTPro-DmCn.otf") format("opentype"); font-display: swap; }

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; background: #04050a; overflow: hidden;
  font-family: "FranklinCn", "Arial Narrow", sans-serif; color: #eafcff;
  -webkit-tap-highlight-color: transparent;
  /* prefixed pair + callout: Safari honours neither of the last two on the unprefixed
     property alone, which is why holding the knob selected it instead of charging */
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
img, video, canvas, iframe { -webkit-user-drag: none; -webkit-touch-callout: none; }
.jp { font-family: "Yu Mincho", "Hiragino Mincho ProN", "MS PMincho", serif; }

/* ---------- the feed: one machine per full screen, snap scrolling ---------- */
#feed { position: fixed; inset: 0; overflow-y: scroll; overflow-x: hidden;
  scroll-snap-type: y mandatory; scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; }
#feed::-webkit-scrollbar { display: none; }

.slide { position: relative; width: 100%; height: 100%; scroll-snap-align: start;
  scroll-snap-stop: always; overflow: hidden; background: #04050a;
  display: flex; align-items: center; justify-content: center; }

.slide .poster { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; opacity: .55; filter: blur(1px) saturate(.9);
  transition: opacity .45s; }
.slide.live .poster { opacity: 0; }

.slide iframe { position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; opacity: 0; transition: opacity .5s; }
.slide.live iframe { opacity: 1; }

/* card shown before a machine is mounted, and for machines still in production */
.slide .card { position: relative; z-index: 2; text-align: center; padding: 0 8vw;
  transition: opacity .35s; }
.slide.live .card { opacity: 0; pointer-events: none; }
.slide .card .client { font-size: clamp(11px, 1.7vh, 16px); letter-spacing: .38em; color: #8fa4b6; }
.slide .card .title  { font-size: clamp(26px, 6vh, 62px); letter-spacing: .12em; margin: .35em 0 .5em;
  text-shadow: 0 0 30px rgba(120,200,255,.35); }
.slide .card .credits{ font-size: clamp(10px, 1.5vh, 14px); letter-spacing: .2em; color: #6d8296; }
.slide .card .soon { display: inline-block; margin-top: 1.4em; padding: .5em 1.3em;
  border: 1px solid rgba(255,255,255,.28); border-radius: 99px;
  font-size: clamp(10px, 1.5vh, 14px); letter-spacing: .3em; color: #cfe0ee; }

/* ---------- chrome ---------- */
#brand { position: fixed; top: 2.2vh; left: 4vw; z-index: 20; pointer-events: none;
  font-size: clamp(13px, 2vh, 20px); letter-spacing: .2em; opacity: .9;
  text-shadow: 0 2px 12px #000; }
#brand span { opacity: .65; }

#scrollHint { position: fixed; bottom: 2.4vh; left: 50%; transform: translateX(-50%); z-index: 20;
  pointer-events: none; font-size: clamp(9px, 1.4vh, 13px); letter-spacing: .32em;
  color: rgba(230,244,255,.72); text-shadow: 0 2px 10px #000;
  display: flex; align-items: center; gap: .7em; transition: opacity .5s; }
#scrollHint.gone { opacity: 0; }
#scrollHint i { display: block; width: 1px; height: 2.4vh;
  background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.85));
  animation: hintdrop 1.6s ease-in-out infinite; }
@keyframes hintdrop { 0%,100% { transform: translateY(-25%); opacity: .35 } 50% { transform: translateY(25%); opacity: 1 } }

#soundChip { position: fixed; top: 2.2vh; right: 4vw; z-index: 20; cursor: pointer;
  padding: .45em 1em; border-radius: 99px; font-size: clamp(9px, 1.4vh, 13px);
  letter-spacing: .26em; color: #ffe9b8;
  background: rgba(8,10,16,.72); border: 1px solid rgba(255,200,90,.4);
  box-shadow: 0 2px 14px rgba(0,0,0,.6); backdrop-filter: blur(6px); }
#soundChip.hidden { display: none; }
#soundChip .jp { margin-right: .5em; }

/* ---------- machines live in a fixed overlay, never inside the scroller ----------
   The scroller can therefore teleport by a whole block to loop forever without ever
   re-parenting (and thus reloading) an iframe. */
#stage { position: fixed; inset: 0; z-index: 10; pointer-events: none; }
#stage iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
  opacity: 0; transition: opacity .28s ease; pointer-events: none; }
/* The live machine must NOT take pointer events: a full-screen iframe would swallow
   every swipe and trap the viewer on one machine. The feed keeps the gestures; the
   machine's own controls are re-created above as transparent hit targets. */
#stage iframe.live { opacity: 1; pointer-events: none; }
#stage iframe.grab { pointer-events: auto; }      /* except while a dialog is open */
/* visibility, not just opacity: an opacity-0 layer is still painted and composited every
   frame. Hidden, the fixed stage stops taking part in the scroll at all. */
#stage.settling iframe.live { opacity: 0; visibility: hidden; }

#hits { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
#stage.settling #hits { display: none; }
#hits .hit { position: absolute; margin: 0; padding: 0; border: 0; background: transparent;
  border-radius: 50%; cursor: pointer; pointer-events: auto; touch-action: none;
  -webkit-tap-highlight-color: transparent; appearance: none;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
#hits .hit-close { border-radius: 10px; }
#hits .hit:focus-visible { outline: 2px solid rgba(255,220,150,.7); outline-offset: 3px; }

/* ---------- no accidental zoom ----------
   `user-scalable=no` is in the viewport meta and iOS has ignored it since iOS 10, so a
   double tap near the launch knob was zooming the whole page mid-game. touch-action is the
   control Safari actually honours: `manipulation` keeps panning and pinch working but
   removes the double-tap-to-zoom gesture, which is the one nobody wants here. */
/* touch-action is NOT an inherited property. Setting it on html/body did nothing for the
   elements that actually receive the touch — the scroller, the stage, the slides, the posters,
   the iframe and the board image inside it were all still `auto`, so double tap still zoomed
   everywhere except the body itself. It has to be declared on the elements, hence the
   universal selector. `#hits .hit` keeps its stricter `none` on specificity. */
*, html, body { touch-action: manipulation; }
