/* First-flight tutorial overlay. All tutorial chrome is DOM, floating over the game canvas —
   renderer-agnostic by construction. Visual language follows the matchmaking chrome: Electrolize,
   steel-blue accent + glow, corner-tick reticles, radial scrims instead of boxed panels, and
   composited-only animations (opacity / transform / filter — never layout properties on text). */

#tut-root {
  --acc: #7fb0ff;
  /* Where the callout block (progress dots, copy, feedback line) sits. A beat whose spotlight
     lands on top of it moves the whole block down together — see `calloutBelowSpotlight` in
     tutorial.js, which the menu beat uses to sit its copy under the highlighted panel. */
  --callout-y: 13%;
  --glow: rgba(127, 176, 255, 0.45);
  /* Objective markers (beacon ring + its off-screen edge arrow) are white — a clean, neutral
     "go here" that reads on any map. Green (.tut-ring.good) means earned: the dwell state while
     the ship holds station, and where a beacon settles as it's dismissed (.tut-ring.resolving).
     Red (.foe) is the other half of the vocabulary: a mark tracking something hostile rather than
     a place to fly to. The chrome accent stays steel-blue. */
  --mark: #ffffff;
  --mark-glow: rgba(255, 255, 255, 0.5);
  --foe: #ff6060;
  --foe-glow: rgba(255, 96, 96, 0.6);
  position: fixed;
  inset: 0;
  z-index: 150; /* over the game + chips (10), under toasts (300) and the cursor */
  pointer-events: none;
  font-family: 'Electrolize', 'Segoe UI', system-ui, -apple-system, sans-serif;
}
#tut-root.tut-out { animation: tut-fade-out 0.45s ease-in forwards; }
@keyframes tut-fade-out { to { opacity: 0; } }

/* index.html still carries a GLOBAL `* { overflow: hidden }`; neutralize it inside the overlay
   (same trick as #mm-toast). :where() keeps the reset at zero specificity: it beats the global
   purely by loading later, and every component class below still wins over it.
   The companion `:where(#tut-root) span` reset that sat here is gone — index.html's `span {}` rule
   is scoped to #game-settings now, so the reset was restating the browser defaults. */
:where(#tut-root, #tut-root *) { overflow: visible; }

/* While the tutorial runs, the page chrome (login/matchmaking chips) stays out of the way. */
body.tutorial-active #login-toggle,
body.tutorial-active #mm-toggle { display: none !important; }

/* ---- Spotlight ------------------------------------------------------------------------ */
/* A modal highlight of one HUD element (tutorial.js: the world is paused for its whole life).
   Two pieces: #tut-scrim obscures everything *except* the element — a black wash over a blurred
   backdrop, with a rounded-rect hole punched by the evenodd clip-path JS writes (Chrome clips
   backdrop-filter to it, so only the hole stays sharp) — and #tut-spot draws the lit frame of
   the hole itself. The pair is only up while #tut-root has .tut-modal. */
#tut-scrim {
  position: fixed;
  inset: 0;
  display: none;
  background: rgba(0, 0, 0, 0.66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  /* The scrim swallows clicks aimed at the game — only the acknowledge button gets through. */
  pointer-events: auto;
}
#tut-root.tut-modal #tut-scrim { display: block; animation: tut-spot-in 0.28s ease-out; }

#tut-spot {
  position: fixed;
  display: none;
  border-radius: 14px;
  outline: 1px solid var(--acc);
  outline-offset: 2px;
  box-shadow: 0 0 22px var(--glow);
  transition: left 0.5s cubic-bezier(0.2, 0.8, 0.25, 1), top 0.5s cubic-bezier(0.2, 0.8, 0.25, 1),
              width 0.5s cubic-bezier(0.2, 0.8, 0.25, 1), height 0.5s cubic-bezier(0.2, 0.8, 0.25, 1);
}
#tut-spot.tut-on { display: block; animation: tut-spot-in 0.4s ease-out; }
@keyframes tut-spot-in { from { opacity: 0; } }

/* The acknowledge button — JS parks it just outside the hole, over the obscured area, so the
   dismissal sits with the thing it's about. It is the product's gold call-to-action (the same
   ramp, ink and 3D edge as the splash PLAY button and the auth-card submits in index.html),
   deliberately NOT the steel-blue of the tutorial's own chrome: everything blue on screen is
   something to read, and the one gold thing is the thing to press. */
#tut-ack {
  position: fixed;
  display: none;
  pointer-events: auto;
  padding: 11px 26px;
  background: linear-gradient(180deg, #ffe89e 0%, #f4c64e 100%);
  border: 0;
  border-radius: 9px;
  color: #2a1d02;
  font-family: inherit;
  font-size: 15px;
  font-weight: bold;
  /* Electrolize ships one weight, so faux-bold tops out early; thicken the glyphs with a
     text-stroke in the label colour (same trick as the auth-card CTA). */
  -webkit-text-stroke: 0.5px #2a1d02;
  letter-spacing: 0.1em;
  white-space: nowrap;
  cursor: pointer;
  text-shadow: 0 1px 0 rgba(255, 246, 214, 0.6); /* embossed label */
  /* Inset top bevel + bottom shade, a hard bottom edge for depth, a drop shadow to lift it off
     the scrim, and a warm bloom so it separates from the blurred dark backdrop. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.65),
    inset 0 -3px 6px rgba(150, 100, 0, 0.28),
    0 4px 0 #c2901d,
    0 9px 18px rgba(0, 0, 0, 0.45),
    0 0 30px rgba(244, 198, 78, 0.25);
  transition: filter 0.12s ease, box-shadow 0.1s ease, transform 0.06s ease;
}
#tut-root.tut-modal #tut-ack { display: block; animation: tut-ack-in 0.32s cubic-bezier(0.2, 0.9, 0.2, 1) 0.12s backwards; }
#tut-ack:hover { filter: brightness(1.06); }
/* Press it "into" the surface: drop the bottom edge, sink the bevel inward. */
#tut-ack:active {
  transform: translateY(3px);
  box-shadow:
    inset 0 2px 5px rgba(120, 80, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    0 1px 0 #c2901d,
    0 2px 6px rgba(0, 0, 0, 0.4);
}
/* A slow halo ping — the world is frozen and this is the only way out of it, so the button
   says so without pulsing the button itself (transform + opacity only). */
#tut-ack::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 12px;
  border: 1px solid rgba(255, 224, 122, 0.6);
  opacity: 0;
  pointer-events: none;
  animation: tut-ack-ping 2.6s ease-out 0.7s infinite;
}
@keyframes tut-ack-in { from { opacity: 0; transform: translateY(-4px); } }
@keyframes tut-ack-ping {
  0%        { opacity: 0.5; transform: scale(0.98); }
  60%, 100% { opacity: 0; transform: scale(1.15); }
}

/* While the highlight is up it is the only thing to act on, and the only thing on screen: the
   instruction line steps aside (its keys do nothing until the world restarts, and the acknowledge
   button is parked wherever the highlighted element happens to be), as do the world-anchored marks
   — they track a frozen world and point away from the thing being taught. The callout stays: it's
   the copy explaining what is lit up. */
#tut-root.tut-modal #tut-keys,
#tut-root.tut-modal #tut-rings,
#tut-root.tut-modal #tut-arrow { visibility: hidden; }

/* Dismissal: the scrim, the lit frame and the button fade out together instead of being cut away.
   tutorial.js swaps `.tut-modal` for `.tut-modal-out` and drops that once the animation is done, so
   these rules only have to keep the three displayed while it runs (`forwards` holds them
   transparent at the end). The world resumes immediately, so the marks and the action line come
   back *through* the fading scrim rather than popping in after it. Pointer events go straight
   away — a click landing mid-fade must not hit a button that has already done its job. */
#tut-root.tut-modal-out #tut-scrim,
#tut-root.tut-modal-out #tut-spot.tut-on,
#tut-root.tut-modal-out #tut-ack {
  display: block;
  pointer-events: none;
  animation: tut-modal-out 0.3s ease-in forwards;
}
@keyframes tut-modal-out { to { opacity: 0; } }

/* ---- Slow-motion vignette ------------------------------------------------------------- */
#tut-vignette {
  position: fixed;
  inset: 0;
  opacity: 0;
  background: radial-gradient(70% 70% at 50% 50%, transparent 55%, rgba(10, 20, 45, 0.55) 100%);
  transition: opacity 0.35s ease;
}
#tut-vignette.tut-on { opacity: 1; }

/* ---- Callout -------------------------------------------------------------------------- */
#tut-callout {
  position: fixed;
  top: var(--callout-y);
  left: 50%;
  transform: translateX(-50%);
  width: fit-content;
  max-width: min(620px, 86vw);
  padding: 12px 30px 14px;
  text-align: center;
}
#tut-callout::before {
  content: "";
  position: absolute;
  inset: -8px 0;
  z-index: -1;
  background: radial-gradient(58% 130% at 50% 50%, rgba(0, 0, 0, 0.72), transparent 74%);
}
.tut-title {
  font-size: 13px;
  letter-spacing: 0.32em;
  color: var(--acc);
  text-shadow: 0 0 12px var(--glow);
  margin-bottom: 6px;
  animation: tut-text-in 0.35s cubic-bezier(0.2, 0.9, 0.2, 1) backwards;
}
.tut-text {
  font-size: 17px;
  line-height: 1.4;
  color: #f4f8fc;
  text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000, 0 0 16px var(--glow);
  animation: tut-text-in 0.35s cubic-bezier(0.2, 0.9, 0.2, 1) 0.06s backwards;
}
@keyframes tut-text-in {
  from { opacity: 0; filter: blur(3px); transform: translateY(-2px); }
  to   { opacity: 1; filter: blur(0); transform: none; }
}
.tut-tick {
  position: absolute;
  width: 11px;
  height: 11px;
  border: 1px solid var(--acc);
  opacity: 0.8;
  animation: tut-tick-in 0.22s cubic-bezier(0.2, 0.9, 0.2, 1) backwards;
}
.tut-tick.tl { top: 0; left: 0; border-right: 0; border-bottom: 0; --tx: -7px; --ty: -7px; }
.tut-tick.tr { top: 0; right: 0; border-left: 0; border-bottom: 0; --tx: 7px; --ty: -7px; animation-delay: 0.03s; }
.tut-tick.bl { bottom: 0; left: 0; border-right: 0; border-top: 0; --tx: -7px; --ty: 7px; animation-delay: 0.06s; }
.tut-tick.br { bottom: 0; right: 0; border-left: 0; border-top: 0; --tx: 7px; --ty: 7px; animation-delay: 0.09s; }
@keyframes tut-tick-in { from { opacity: 0; transform: translate(var(--tx), var(--ty)); } }

/* ---- Feedback flash (armor deflects, duel hits) ---------------------------------------- */
#tut-flash {
  position: fixed;
  top: calc(var(--callout-y) + 106px);
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
}
.tut-flash-text {
  display: inline-block;
  font-size: 14px;
  letter-spacing: 0.2em;
  animation: tut-flash-in 1.6s ease-out forwards;
  text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000;
}
.tut-flash-text.warn { color: #ff9a5c; text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000, 0 0 14px rgba(255, 122, 74, 0.5); }
.tut-flash-text.good { color: #7dffb0; text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000, 0 0 14px rgba(90, 255, 160, 0.45); }
@keyframes tut-flash-in {
  0%   { opacity: 0; transform: translateY(-3px) scale(1.06); filter: blur(2px); }
  12%  { opacity: 1; transform: none; filter: blur(0); }
  75%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ---- Drift readout (brake beat) -------------------------------------------------------- */
#tut-meter {
  position: fixed;
  top: calc(var(--callout-y) + 106px);
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
}
.tut-meter-text {
  font-size: 15px;
  letter-spacing: 0.24em;
  color: #cfd7e4; /* neutral — the readout never changes colour */
  text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000;
  font-variant-numeric: tabular-nums;
}

/* ---- Progress dots -------------------------------------------------------------------- */
#tut-progress {
  position: fixed;
  top: calc(var(--callout-y) - 26px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 9px;
}
.tut-dot {
  width: 6px;
  height: 6px;
  transform: rotate(45deg); /* diamonds, echoing the reticle language */
  background: rgba(127, 176, 255, 0.22);
  transition: background 0.3s, box-shadow 0.3s;
}
.tut-dot.on { background: var(--acc); box-shadow: 0 0 8px var(--glow); }
.tut-dot.past { background: rgba(127, 176, 255, 0.55); }

/* ---- Keycaps -------------------------------------------------------------------------- */
/* The bottom action block: the control line (keycaps + prose) with the smaller objective
   caption stacked beneath it. */
#tut-keys {
  position: fixed;
  bottom: 11%;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  max-width: min(720px, 90vw);
  text-align: center;
}
.tut-action {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 7px 10px;
}
.tut-instr {
  font-size: 18px;
  color: #f4f8fc;
  letter-spacing: 0.01em;
  text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000, 0 0 12px var(--glow);
}
.tut-objective {
  font-size: 14px;
  letter-spacing: 0.04em;
  color: #b3bccb;
  text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000;
}
.tut-objective .tut-obj-label {
  color: var(--acc);
  text-shadow: 0 0 8px var(--glow);
  margin-right: 0.35em;
}
.tut-keygroup { display: flex; align-items: center; gap: 4px; }
.tut-plus { color: #d7dbe2; font-size: 22px; font-weight: 600; margin: 0 3px; }
/* A dished keycap seen straight-on (no tilt): the outer div is the dark skirt, its padding
   framing the raised .tut-face on every side — thicker at the front so the cap reads as
   rising toward you. Legends stay flat and crisp. Pressing sinks the face and brightens it. */
.tut-key {
  position: relative;
  height: 56px;
  padding: 5px 5px 9px 5px;
  box-sizing: border-box;
  /* Shrink-wrap deterministically. (A flex key + flex:1 face poisoned the intrinsic width —
     every cap computed ~290px regardless of content.) */
  display: inline-block;
  border-radius: 11px;
  /* Dark steel skirt, like an actual keyboard — no blue cast, no tilt. */
  background: linear-gradient(180deg, #26282e 0%, #15161a 100%);
  box-shadow: 0 3px 7px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09);
}
.tut-face {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-width: 48px;
  padding: 0 11px;
  box-sizing: border-box;
  border-radius: 8px;
  /* Cylindrical dish across the width — an old keycap curved to the finger. Brightest through
     the middle, rolling off to darker left/right edges, biased a touch left for upper-left
     light. The inset highlight/shadow below carries the top-to-bottom bevel. */
  background: linear-gradient(90deg, #303237 0%, #494b52 24%, #55575e 46%, #44464c 76%, #2e3035 100%);
  box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, 0.28), inset 0 -1px 2px rgba(0, 0, 0, 0.4);
  color: #e8eaed;
  font-size: 14px;
  letter-spacing: 0.05em;
  transition: filter 0.06s ease, transform 0.06s ease;
}
.tut-key.pressed { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); }
.tut-key.pressed .tut-face { transform: translateY(2px); filter: brightness(1.35); }

/* Directional cap faces: a real arrow (stem + head) via clip-path — immune to symbol-glyph
   font metrics, one shape rotated per direction. Slim stem/head, closer to a consumer
   keyboard's arrow legend. */
.tut-arr {
  width: 19px;
  height: 19px;
  background: #e8eaed;
  clip-path: polygon(50% 7%, 81% 47%, 60% 47%, 60% 93%, 40% 93%, 40% 47%, 19% 47%);
}
.tut-arr.down  { transform: rotate(180deg); }
.tut-arr.left  { transform: rotate(-90deg); }
.tut-arr.right { transform: rotate(90deg); }

/* ---- Objective marker + edge arrow ---------------------------------------------------- */
/* Four independent arcs (real SVG <path>s, injected by tutorial.js) that slowly rotate and emit a
   glow. The stroke is currentColor and the layered drop-shadows bloom in --ring-glow, so the dwell
   state (.good) swaps both together. .tut-ring is the positioned box JS moves; it spins as a whole. */
.tut-ring {
  --ring-glow: var(--mark-glow);
  position: fixed;
  display: none;
  width: 74px;
  height: 74px;
  margin: -37px 0 0 -37px; /* centered on (left, top) */
  color: var(--mark); /* arc stroke, via currentColor */
  filter: drop-shadow(0 0 4px var(--ring-glow)) drop-shadow(0 0 12px var(--ring-glow));
  animation: tut-ring-spin 7s linear infinite;
  /* White→green is a settle, not a cut — the stroke and its bloom cross together. */
  transition: color 200ms linear, filter 200ms linear;
}
.tut-ring .tut-ring-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  /* Scale about the ring's true centre (the resolve animation), not the SVG origin. */
  transform-box: view-box;
  transform-origin: 50% 50%;
}
.tut-ring .tut-ring-svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
}
.tut-ring.tut-on { display: block; }
/* A ring on something hostile — a practice target, the drone — rather than on a place to fly to.
   Fixed for the life of the ring (the director's `f` flag), and never earned, so .good below
   still wins if the two ever meet. */
.tut-ring.foe {
  color: var(--foe);
  --ring-glow: var(--foe-glow);
}
/* Dwell beacon lit green while the ship is inside it (the reverse-thrusters beat), and the
   colour an earned beacon settles on as it's dismissed. */
.tut-ring.good {
  color: #7dffb0;
  --ring-glow: rgba(90, 255, 160, 0.65);
}
@keyframes tut-ring-spin { to { transform: rotate(360deg); } }

/* The dismissal (beacon.resolve() in tutorial.js — the director keeps projecting the mark
   throughout, so this plays glued to the world point the player just took). It rides the inner
   SVG so the ring keeps spinning underneath it: hold while the colour settles green, blink out
   and back twice — hard cuts, from paired keyframes — then swell and fade away. */
.tut-ring.resolving .tut-ring-svg { animation: tut-ring-resolve 920ms linear forwards; }
@keyframes tut-ring-resolve {
  0%,      22%    { opacity: 1; transform: scale(1); }
  22.01%,  34%    { opacity: 0; }
  34.01%,  46%    { opacity: 1; }
  46.01%,  58%    { opacity: 0; }
  58.01%,  70%    { opacity: 1; transform: scale(1); }
  100%            { opacity: 0; transform: scale(1.35); }
}
#tut-arrow {
  position: fixed;
  display: none;
  width: 0;
  height: 0;
  /* A chevron built from borders; rotated toward the target, positioned at the screen edge. */
  border-left: 11px solid transparent;
  border-right: 11px solid transparent;
  border-bottom: 20px solid var(--mark);
  filter: drop-shadow(0 0 10px var(--mark-glow));
  animation: tut-arrow-pulse 1.1s ease-in-out infinite;
}
/* The chevron takes the colour of whatever it's pointing at, so an off-screen hostile still
   reads as one. */
#tut-arrow.foe {
  border-bottom-color: var(--foe);
  filter: drop-shadow(0 0 10px var(--foe-glow));
}
#tut-arrow.tut-on { display: block; }
@keyframes tut-arrow-pulse {
  0%, 100% { opacity: 0.95; }
  50%      { opacity: 0.5; }
}

/* ---- Skip link ------------------------------------------------------------------------ */
/* Plain text link (no button chrome); the arrow slides right on hover. */
#tut-skip {
  position: fixed;
  right: 22px;
  bottom: 18px;
  pointer-events: auto;
  padding: 6px 4px;
  background: none;
  border: 0;
  color: rgba(200, 220, 250, 0.7);
  font-family: inherit;
  font-size: 12.5px;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: color 0.15s ease;
}
#tut-skip:hover { color: #eaf2ff; }
.tut-skip-arrow {
  display: inline-block;
  margin-left: 0.15em;
  transition: transform 0.18s ease;
}
#tut-skip:hover .tut-skip-arrow { transform: translateX(5px); }

/* ---- Reduced motion ------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  #tut-root *, #tut-root { animation: none !important; transition: none !important; }
  /* With the fade-out animation gone, the dismissed modal would otherwise sit there at full
     opacity for the length of the (now invisible) animation before being torn down. Cut it. */
  #tut-root.tut-modal-out #tut-scrim,
  #tut-root.tut-modal-out #tut-spot.tut-on,
  #tut-root.tut-modal-out #tut-ack { display: none !important; }
}
