/* Bifröst — night, a black void, one lit road across it.
 *
 * The whole chrome is deliberately colourless. Seven saturated lanes are the
 * entire visual idea of this game, and they only read as seven if nothing else
 * on the screen is competing with them. */

:root {
  --ground: #0a0912;
  --panel: #12101d;
  --panel-2: #1b1829;
  --ink: #f0ecf7;
  --ink-dim: #948da8;
  --rule: #2c2740;
  --rule-soft: #201c30;
  --accent: #f5c518;
  --accent-ink: #0a0912;
  --good: #3faa4e;
  --warn: #f07f18;

  --display: 'Futura', 'Avenir Next', ui-sans-serif, system-ui, sans-serif;
  --ui: ui-sans-serif, -apple-system, 'Segoe UI', system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  --radius: 14px;
  --rule-w: 1px;
  --shadow-hard: 0 10px 30px rgba(0,0,0,.45);
  color-scheme: dark;
}
:root[data-theme="light"] {
  /* There is no light Bifröst. The game is a night sky with one lit road over
     it, and a pale chrome around that reads as a bug rather than a preference.
     The panel lifts a little and that is all. */
  --panel: #17142a;
  --panel-2: #221e3a;
  --rule: #3b3358;
  color-scheme: dark;
}


/* ---------------------------------------------------------------------------
   THE GAME
   --------------------------------------------------------------------------- */

/* The canvas fills the stage edge to edge. The stage's own padding is for
   screens made of words; a road has no margin. */
.bf, .bf-splash { position: absolute; inset: 0; }
.bf { overflow: hidden; border-radius: var(--radius); }
.bf canvas, canvas.bf-splash {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  touch-action: none;                 /* an up-swipe must not pull to refresh */
  user-select: none; -webkit-user-select: none;
}

/* --- the head-up display --- */
.bf-hud {
  position: absolute; inset: 0;
  pointer-events: none;
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 8px;
  font-family: var(--ui);
}
.bf-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bf-pips { display: flex; gap: 6px; }
.bf-pips i {
  width: 15px; height: 15px; border-radius: 50%;
  background: rgba(255,255,255,.16);
  border: 2px solid rgba(0,0,0,.5);
  transition: background .18s;
}
.bf-pips i.on { background: #e8402a; }
.bf-dist {
  font-family: var(--display); font-size: 26px; letter-spacing: .03em;
  color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.6);
}

/* The rainbow bar: how many colours are on the road, then how much of the
   fifteen seconds you have banked. One bar doing two jobs, because they are
   the same job — how far through tonight's song you are. */
.bf-bow {
  height: 10px; border-radius: 6px;
  background: rgba(0,0,0,.5);
  border: 1px solid rgba(255,255,255,.14);
  overflow: hidden;
}
.bf-bow i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg,#e8402a,#f07f18,#f5c518,#3faa4e,#2b8fd6,#5b5fd0,#8a3fbf);
  transition: width .2s linear;
}
.bf-bow.full { box-shadow: 0 0 0 2px rgba(245,197,24,.55); }
.bf-bow.bump { animation: bfbump .42s ease; }
@keyframes bfbump { 0%,100% { transform: scaleY(1) } 40% { transform: scaleY(2.1) } }
.bf-bowlab {
  font-size: 12px; letter-spacing: .10em; text-transform: uppercase;
  color: rgba(255,255,255,.72); text-shadow: 0 1px 0 rgba(0,0,0,.7);
}
.bf-mute {
  position: absolute; right: 12px; bottom: 12px;
  pointer-events: auto;
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.18); background: rgba(0,0,0,.45);
  color: #fff; font-size: 18px; cursor: pointer;
}

/* --- the card that opens and closes a run --- */
.bf-card {
  position: absolute; inset: 0; z-index: 5;
  background: rgba(10,9,18,.93);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 24px 22px; text-align: center;
}
.bf-kicker {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-dim);
}
/* A title shrinks, it never breaks mid-word and it is never clipped. */
.bf-song {
  font-family: var(--display);
  font-size: clamp(22px, 8cqw, 38px);
  line-height: 1.1; letter-spacing: .02em; text-transform: uppercase;
  color: var(--ink); text-wrap: balance;
}
.bf-song.small { font-size: clamp(18px, 6cqw, 26px); }
.bf-have { font-size: 14px; color: var(--ink-dim); }
.bf-have.new { color: var(--accent); font-weight: 600; }
.bf-have.on { color: var(--good); }
.bf-order { display: flex; gap: 7px; }
.bf-order i { width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid rgba(0,0,0,.55); }
.bf-grid {
  display: grid; grid-template-columns: repeat(12, 1fr); gap: 5px;
  width: 100%; max-width: 260px;
}
.bf-grid i {
  aspect-ratio: 1; border-radius: 3px;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.08);
}
.bf-grid i.on { background: var(--accent); border-color: var(--accent); }
.bf-coach {
  font-size: 14px; line-height: 1.45; color: var(--ink);
  background: rgba(245,197,24,.10);
  border: 1px solid rgba(245,197,24,.30);
  border-radius: 10px; padding: 12px 14px;
}
.bf-bars { display: flex; width: 100%; height: 18px; border-radius: 5px; overflow: hidden; gap: 1px; }
.bf-bars i { display: block; min-width: 2px; }
.bf-card .btn { margin-top: 4px; min-width: 190px; }

/* A disabled primary button must not arrive full-green and full-contrast: a
   button that looks live and does nothing reads as broken. */
.btn:disabled, .btn[disabled] { opacity: .45; cursor: default; filter: saturate(.4); }

/* --- the first-sighting card ---------------------------------------------
   One thing, one picture, one sentence, one button. It stops the run, so it
   has to be readable in the time it takes to look up, and gone in one tap. */
.bf-tip {
  background: rgba(10,9,18,.96);
  border-top: 3px solid var(--tint);
  animation: bftip .18s ease-out;
}
@keyframes bftip { from { opacity: 0; transform: scale(.97) } to { opacity: 1; transform: none } }
.bf-tipart {
  width: 100%; max-width: 210px; height: 34cqw; max-height: 190px;
  display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 10px 22px rgba(0,0,0,.6));
}
.bf-tipart img { max-width: 100%; max-height: 100%; object-fit: contain }
.bf-tipart i { width: 76px; height: 76px; border-radius: 16px; display: block }
.bf-tipline {
  margin: 0; font-size: 15.5px; line-height: 1.5; color: var(--ink);
  max-width: 30ch;
}
.bf-tip .bf-song { color: var(--tint) }

/* --- the field guide, in the help sheet ---------------------------------- */
.bf-guide { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 14px }
.bf-grow {
  display: flex; align-items: center; gap: 13px;
  padding: 9px 11px; border-radius: 11px;
  background: var(--panel-2);
  border-left: 3px solid var(--tint);
}
.bf-gpic {
  flex: 0 0 54px; height: 54px;
  display: flex; align-items: center; justify-content: center;
}
.bf-gpic img { max-width: 100%; max-height: 100%; object-fit: contain }
.bf-gpic i { width: 28px; height: 28px; border-radius: 8px; display: block }
.bf-gtext { display: flex; flex-direction: column; gap: 2px; min-width: 0 }
.bf-gtext b { font-size: 14.5px; color: var(--ink); font-weight: 600 }
.bf-gtext span { font-size: 13px; line-height: 1.45; color: var(--ink-dim) }

/* --- the count-in ---------------------------------------------------------
   Thrown up over the live road and dropped, so the three seconds are also a
   look at what you are about to run into. */
.bf-count {
  position: absolute; inset: 0; z-index: 6;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
  font-family: var(--display);
  font-size: 34cqw; line-height: 1;
  color: #fff;
  text-shadow: 0 0 26px rgba(0,0,0,.85), 0 6px 0 rgba(0,0,0,.5);
  animation: bfcount .62s cubic-bezier(.2,.8,.3,1) forwards;
}
.bf-count.go { font-size: 22cqw; letter-spacing: .06em; color: var(--accent) }
@keyframes bfcount {
  0%   { opacity: 0; transform: scale(1.7) }
  22%  { opacity: 1; transform: scale(1) }
  70%  { opacity: 1; transform: scale(1) }
  100% { opacity: 0; transform: scale(.82) }
}

/* The off switch is not a second big button under the primary one: it turns off
   every explanation the game has, forever, and a thumb aiming for "Got it"
   should not be able to hit it. */
.bf-tipoff {
  margin-top: 2px;
  background: none; border: 0; padding: 8px 12px;
  color: var(--ink-dim); font: inherit; font-size: 13px;
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
.bf-tipoff:active { color: var(--ink) }

/* --- the title screen -----------------------------------------------------
   A still plate with a canvas motion layer over it, never a video: about a
   hundredth of the weight, and every piece stays re-composable. */
.bf-title { position: absolute; inset: 0; overflow: hidden; border-radius: var(--radius); }
.bf-plate {
  position: absolute; inset: -3%;
  background: #0a0912 url("/art/title.jpg") center / cover no-repeat;
  animation: bfdrift 26s ease-in-out infinite alternate;
}
@keyframes bfdrift {
  from { transform: scale(1.03) translateY(0) }
  to   { transform: scale(1.10) translateY(-1.6%) }
}
.bf-titlefx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.bf-logo {
  position: absolute; left: 50%; top: 4.5%;
  width: min(78%, 320px); height: auto;
  transform: translateX(-50%);
  filter: drop-shadow(0 8px 20px rgba(0,0,0,.85));
  animation: bfland .7s cubic-bezier(.2,1.4,.4,1) both, bfidle 5.5s ease-in-out 1s infinite;
  pointer-events: none;
}
@keyframes bfland {
  0%   { opacity: 0; transform: translateX(-50%) translateY(-26%) scale(1.25) }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1) }
}
@keyframes bfidle {
  0%, 100% { rotate: -1.1deg }
  50%      { rotate: 1.1deg }
}

/* The plate carries the name, so the host's text title would be a second one.
   Only the bare title is hidden — a challenge headline lives in a .stack and
   is exactly what a player who tapped somebody's result came to read. */
.screen.on-splash > .big { display: none }
.screen.on-splash {
  margin-top: auto; margin-bottom: 14px;
  background: linear-gradient(to top, rgba(10,9,18,.94) 62%, rgba(10,9,18,0));
  padding: 30px 16px 6px; border-radius: var(--radius);
}
.screen.on-splash .muted { text-shadow: 0 1px 6px rgba(0,0,0,.9) }
