/* ============================================================================
 * Title screen. The canvas (title.js) owns the space; this owns the type and
 * the buttons that sit on top of it.
 * ========================================================================== */

/* the scene is edge-to-edge — no padding, no scroll, the canvas fills it */
.title-scene{padding:0;overflow:hidden;position:relative;justify-content:flex-start;
  align-items:stretch;text-align:center}
.tt-cv{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:0}
/* a tap that leaves the label highlighted is the loudest "this is a web
   page" tell there is */
.tt-ui{-webkit-user-select:none;user-select:none;position:relative;z-index:1;flex:1;display:flex;flex-direction:column;align-items:center;
  padding:0 12px calc(18px + var(--safe-b));text-align:center;min-height:0}
/* the top third belongs to Uranus and the ship — the UI starts under them.
 * CAPPED (Michael 2026-08-19: "move the QUEST FOR URANUS text up"). This spacer is
 * the only grower in the column, so uncapped it ate every pixel of slack and pinned
 * the whole lockup — logo, tagline, ticker, keys — to the bottom safe area, leaving
 * a dead band between the ship and the Q. With a ceiling on it the leftover slack
 * falls past the keys instead (the column is flex-start), so the lockup rides up and
 * the air lands under the buttons where it belongs. It is a MAX, so on a short phone
 * where the spacer never reaches the ceiling nothing about this changes. */
.tt-top{flex:1 1 auto;min-height:0;max-height:46vh;pointer-events:none}

/* ---------------------------------------------------------------- logo */
.tt-logo-wrap{position:relative;width:100%;max-width:min(75vw,344px);flex:0 0 auto}
/* the cool halo is what keeps SILVER alive against the nebula — a neutral mark on
   a blue-purple sky with no rim light reads as flat grey type. It is the one place
   the old ice-blue survives, and it is doing a job now instead of being the face. */
.tt-logo{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.85)) drop-shadow(0 0 32px rgba(150,205,255,.34))}
.tt-logo text{text-anchor:middle;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI Black",system-ui,sans-serif;
  font-weight:900;letter-spacing:-1px;paint-order:stroke fill}
/* the extrusion — opaque, tightly stacked. A soft/faded stack reads as a
   blurry ghost; the fill colour is set per-plate in JS so the lowest side
   walls catch a warm bounce off the nebula. */
.tt-ext{stroke-width:2;stroke-linejoin:round;paint-order:stroke fill}
/* the top lip — 1px of white along the crown gives the face real thickness. It
   pushes harder on silver than it did on blue: the crown of the alloy ramp is
   already near-white, so a .32 lip had nothing left to add. */
.tt-lip{fill:none;stroke:rgba(255,255,255,.55);stroke-width:1;stroke-linejoin:round}
/* the outline that keeps the letters legible against a bright ring — steel-dark
   now rather than navy, for the same reason the side walls are (see title.js) */
.tt-out{fill:none;stroke:#0b101c;stroke-width:6;stroke-linejoin:round}
.tt-face{}
/* the moving specular; screen-blended so it only ever adds light */
.tt-swp{mix-blend-mode:screen;pointer-events:none}
.tt-forT{text-anchor:middle;font-weight:900;letter-spacing:.5px;
  font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif}
/* the ribbon casts onto URANUS — that shadow is what makes the three
   lines read as one lockup instead of three stacked elements */
.tt-for{filter:drop-shadow(0 3px 0 rgba(6,8,26,.9)) drop-shadow(0 0 12px rgba(255,216,77,.45))}

/* entrance — each half of the logo slams in, then the shockwave rides out */
.tt-l1{animation:ttSlam .62s cubic-bezier(.16,1.3,.3,1) .05s both;transform-origin:200px 46px}
.tt-l2{animation:ttSlam .62s cubic-bezier(.16,1.3,.3,1) .20s both;transform-origin:200px 139px}
.tt-for{animation:ttPop .5s cubic-bezier(.2,1.7,.35,1) .40s both;transform-origin:200px 92px}
@keyframes ttSlam{0%{opacity:0;transform:scale(2.1) translateY(-14px);filter:blur(9px)}
  70%{opacity:1;filter:blur(0)}100%{opacity:1;transform:scale(1) translateY(0);filter:blur(0)}}
@keyframes ttPop{0%{opacity:0;transform:scale(0) rotate(-22deg)}100%{opacity:1;transform:scale(1) rotate(0)}}
.tt-shock{position:absolute;left:50%;top:52%;width:14px;height:14px;margin:-7px 0 0 -7px;
  border-radius:50%;border:2px solid #9fe8ff;pointer-events:none;
  animation:ttShock .7s ease-out .42s both}
@keyframes ttShock{0%{opacity:.85;transform:scale(1)}100%{opacity:0;transform:scale(26)}}

/* ---------------------------------------------------------------- copy */
/* the tagline is the quiet subtitle; the rotating chatter is the hook, so the
   emphasis is deliberately the other way round from where it started */
.tt-tag{margin:10px 0 0;font-size:12.5px;font-weight:700;letter-spacing:3px;text-transform:uppercase;
  color:#c3d6ee;text-shadow:0 2px 6px #000,0 0 18px #000;
  animation:ttUp .5s ease-out .50s both}
/* the chatter line — one joke, one threat, on rotation */
.tt-tick{margin:8px 0 0;height:40px;width:100%;max-width:min(88vw,380px);display:flex;align-items:center;justify-content:center;
  animation:ttUp .5s ease-out .58s both}
.tt-tick-t{font-size:14px;line-height:1.25;font-weight:500;font-style:italic;color:#c8bdf0;letter-spacing:.2px;
  text-shadow:0 0 12px rgba(160,120,255,.3),0 1px 5px #000,0 0 22px #000}
.tt-tick-t.in{animation:ttTick .55s cubic-bezier(.2,.9,.3,1) both}
@keyframes ttTick{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}100%{opacity:1;transform:none;filter:blur(0)}}
@keyframes ttUp{0%{opacity:0;transform:translateY(14px)}100%{opacity:1;transform:none}}

/* ---------------------------------------------------------------- buttons */
/* THE FRONT DOOR IS MILLED FROM THE DECK'S SHEET (Michael 2026-08-19).
 * All three controls were hand-rolled gel: PLAY carried its own five-stop gradient,
 * its own bevels, its own stem, its own gloss cap and a travelling sheen; the two
 * ghosts carried a frosted pane. None of it was the material every other button in
 * the game is made of, so the very first screen a player sees was the one screen
 * that did not look like the rest of the ship.
 *
 * They are .plate now. The face, the brushed grain, the 149deg axis, the gloss, the
 * specular, the lip, the rivets and the press all come from plate.css — the recipe
 * is NOT restated here. What is left below is geometry, type and the entrance only.
 * (This file loads after plate.css, so a stray `background`, `border-radius` or
 * `box-shadow` here would silently take the metal away again. --rad is how a plate
 * is told its corner; setting border-radius directly is what breaks the gloss.)
 *
 * WHICH BAR each key is cut from is decided in app.js (data-metal, one plateBtns
 * pass, then the pair re-cut off a single blue bar) — see SCREENS.title. */
.tt-btns{width:100%;max-width:min(88vw,400px);margin-top:26px;flex:0 0 auto;display:flex;flex-direction:column;gap:14px}

.tt-play{position:relative;width:100%;padding:21px 12px;--rad:22px;
  font-size:23px;font-weight:900;letter-spacing:3px;cursor:pointer;
  /* the halo BREATHES, the plate does not. The breath is a drop-shadow and never a
     box-shadow, because box-shadow is the whole metal shell (--plate) and an
     infinite animation on it would outrank the press and flatten it. */
  animation:ttUp .5s ease-out .66s both, ttBreathe 3.4s ease-in-out 1.2s infinite}
@keyframes ttBreathe{0%,100%{filter:drop-shadow(0 5px 13px rgba(57,255,120,.16))}
  50%{filter:drop-shadow(0 8px 22px rgba(57,255,120,.46))}}

.tt-row{display:flex;gap:10px;animation:ttUp .5s ease-out .74s both}
/* the pair is deliberately quieter than PLAY: smaller type, a tighter corner, and
   the darker half of its own bar. Same metal, lower voice. */
.tt-ghost{flex:1;padding:18px 6px;--rad:15px;cursor:pointer;
  font-size:14.5px;font-weight:800;letter-spacing:.4px}
/* SMALL KEYS WEAR SMALL HEADS (Michael 2026-08-19: "do the rivets on the bottom two
   as well"). The rule beside plateBtns in app.js said a key too short for the heads
   loses them rather than shrinking its label — but there was always a third answer,
   and .plt-riv already exposes it: --r is the head, --i its inset from the corner.
   At the stock 8px/9px the heads close in on the ink; one size down they sit where a
   fastener would and leave a clear channel for the label. The heads scale, the LABEL
   never does — so when the key grew (Michael 2026-08-19) the type went up with it and
   the heads went up only to 6px/7px, the same pair the launch pad's keys wear. */
.tt-ghost .plt-riv{--r:6px;--i:7px}
.tt-ghost:focus{outline:none}
.tt-ghost:focus-visible,.tt-play:focus-visible{outline:none;box-shadow:var(--plate),0 0 0 2px rgba(160,220,255,.6)}

/* soft gas clouds — the burst was 14 hard dots for a game whose entire
   premise is gas */
.tt-gas{position:absolute;width:24px;height:24px;margin:-12px 0 0 -12px;border-radius:50%;pointer-events:none;z-index:5;
  background:radial-gradient(circle,rgba(180,255,150,.55),rgba(90,220,120,.22) 45%,rgba(57,255,20,0) 72%);
  animation:ttGas .9s cubic-bezier(.15,.75,.3,1) both}
@keyframes ttGas{0%{opacity:.9;transform:translate(0,0) scale(.4)}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(2.6)}}
.tt-bean{position:absolute;pointer-events:none;z-index:5;margin:-9px 0 0 -9px;
  animation:ttSpark .8s cubic-bezier(.15,.8,.3,1) both}

/* the launch wipe — the burst carries into the route instead of cutting */
/* fixed + on <body>, so it OUTLIVES the route swap; fully opaque at the
   moment the screens change, then fading off the new one */
.tt-wipe{position:fixed;pointer-events:none;z-index:9999;border-radius:50%;
  background:radial-gradient(circle,rgba(214,255,180,.98) 0%,rgba(90,230,120,.95) 55%,rgba(60,200,110,.9) 80%,rgba(20,140,80,0) 98%);
  transform:translate(-50%,-50%) scale(0);animation:ttWipe .52s cubic-bezier(.3,.8,.4,1) both}
@keyframes ttWipe{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}
  30%{opacity:1;transform:translate(-50%,-50%) scale(2.2)}
  55%{opacity:1;transform:translate(-50%,-50%) scale(5.2)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(7)}}

/* the gas that puffs out of PLAY when you hit it */
.tt-spark{position:absolute;width:8px;height:8px;margin:-4px 0 0 -4px;border-radius:50%;pointer-events:none;z-index:5;
  background:radial-gradient(circle at 35% 32%,#e9ffcf,#39ff14 45%,rgba(57,255,20,0) 72%);
  animation:ttSpark .66s cubic-bezier(.15,.8,.3,1) both}
@keyframes ttSpark{0%{opacity:1;transform:translate(0,0) scale(var(--s))}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(calc(var(--s) * 2.4))}}

/* ---------------------------------------------------------------- a11y */
.reduced-motion .tt-l1,.reduced-motion .tt-l2,.reduced-motion .tt-for,
.reduced-motion .tt-tag,.reduced-motion .tt-tick,.reduced-motion .tt-row,
.reduced-motion .tt-play{animation:none}
.reduced-motion .tt-shock{display:none}
.reduced-motion .tt-tick-t.in{animation:none}

/* short phones: give the planet less room and tighten the type */
@media (max-height:680px){
  .tt-logo-wrap{max-width:min(70vw,288px)}
  .tt-tag{font-size:12.5px;letter-spacing:1.8px;margin-top:6px}
  .tt-play{padding:16px 12px;font-size:20px}
  .tt-ghost{padding:14px 6px}
}
