/* Bots & Bones handheld shell — shared by BnB Games, BnB Invaders and Koloblox Run.
   One file, copied verbatim into each project: edit it in bnb-games, then copy (see bnb-games/AGENTS.md).
   The shell is the Bots & Bones mascot in line art. Every part sits where it sits on the mascot
   render: the body is 32em wide (1em = --w / 32) and 1.486 widths tall, arms 0.33 widths out,
   legs 0.29 widths down. */
@font-face { font-family: 'Geist Pixel Square'; src: url('../assets/fonts/geist-pixel-square.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('../assets/fonts/geist-mono.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }

/* Single deliberate dark look: the device lives on a dark olive table in every host theme. */
:root {
  color-scheme: dark;
  /* Page and contour sit in the LCD family so the line art stays calm. */
  --page: #161813;
  --page-hi: #252921;
  --page-lo: #0e0f0c;
  --dots: #aab4961a;
  --line: #c9ccb8;
  --line-soft: #c9ccb82e;
  --muted: #8d917f;
  --lcd: #aab496;
  --coral: #ff5c45;
  --coral-active: #e04a35;
  --glow: #ff5c4580;
  --alarm: var(--coral);
  --logo-filter: invert(1);
  --stroke: 1.5px;
  --font-display: 'Geist Pixel Square', 'Courier New', monospace;
  --font-mono: 'Geist Mono', ui-monospace, monospace;
  /* Fit: the figure is (1 + 2 * arm) widths wide and (body + legs) widths tall. Equal top/bottom
     reserve keeps it centred and clear of the fixed footnote. */
  --reserve: 44px;
  --arm-k: 0.33;
  --tall-k: 1.78;
  --w: min(480px, calc((100vw - 24px) / (1 + 2 * var(--arm-k))), calc((100dvh - 2 * var(--reserve)) / var(--tall-k)));
}
/* Phones: shorter arms and a screen glass as tall as the crystal, so the game stays big. */
@media (max-width: 560px) {
  :root { --arm-k: 0.15; --tall-k: 1.92; }
}

/* Yellow skin: a mustard crystal and a warm yellow shell, set by body[data-skin]. */
body[data-skin="yellow"] {
  --page: #17120a;
  --page-hi: #2b2210;
  --page-lo: #0e0b06;
  --dots: #e2bb4d1a;
  --line: #f1d27a;
  --line-soft: #f1d27a2e;
  --muted: #a8905a;
  --lcd: #e2bb4d;
  --coral: #ffc21a;
  --coral-active: #e6a800;
  --glow: #ffc21a80;
  --alarm: #ff6a3d;
  --logo-filter: invert(1) sepia(1) saturate(2.4) hue-rotate(-6deg);
}

/* Ember skin (Khorovats, BNB-03): an apricot crystal like coals seen through smoke, a warm shell. */
body[data-skin="ember"] {
  --page: #1a0f0b;
  --page-hi: #2e1a12;
  --page-lo: #0f0806;
  --dots: #dc9f721a;
  --line: #f2c4a2;
  --line-soft: #f2c4a22e;
  --muted: #a8765c;
  --lcd: #dc9f72;
  --coral: #ff5c45;
  --coral-active: #e04a35;
  --glow: #ff5c4580;
  --alarm: #ffc21a;
  --logo-filter: invert(1) sepia(1) saturate(1.5) hue-rotate(-22deg);
}

/* Steel skin (Cargo Flow, BNB-04): a cold blue-grey crystal like a port at dawn, a slate shell, signal-orange accents. */
body[data-skin="steel"] {
  --page: #0d141b;
  --page-hi: #182430;
  --page-lo: #070b0f;
  --dots: #9db4c41a;
  --line: #c5d8e6;
  --line-soft: #c5d8e62e;
  --muted: #6f8799;
  --lcd: #9db4c4;
  --coral: #ff7a1a;
  --coral-active: #e06210;
  --glow: #ff7a1a80;
  --alarm: #ffc21a;
  --logo-filter: invert(1) sepia(1) saturate(1.1) hue-rotate(170deg);
}

/* Film skin (Defect Hunt, BNB-05): a mint crystal like an X-ray film on a lightbox, a deep teal shell, magenta accents. */
body[data-skin="film"] {
  --page: #0a1716;
  --page-hi: #13282a;
  --page-lo: #050c0c;
  --dots: #8fc7b81a;
  --line: #b9e6da;
  --line-soft: #b9e6da2e;
  --muted: #6a978d;
  --lcd: #8fc7b8;
  --coral: #ff3d8b;
  --coral-active: #e0266f;
  --glow: #ff3d8b80;
  --alarm: #ffc21a;
  --logo-filter: invert(1) sepia(1) saturate(1.3) hue-rotate(115deg);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  display: grid;
  place-items: center;
  min-height: 100%;
  padding: var(--reserve) 12px;
  background:
    radial-gradient(circle, var(--dots) 1px, transparent 1.6px) 0 0 / 14px 14px,
    radial-gradient(120% 90% at 50% 28%, var(--page-hi) 0%, var(--page) 60%, var(--page-lo) 100%);
  background-attachment: fixed;
  color: var(--line);
  font-family: var(--font-mono);
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}

/* ---------- the body ---------- */

.device {
  /* Screen glass: 0.88 x 0.667 widths on the mascot. Everything below hangs off its bottom edge. */
  --screen-h: 21.34em;
  --below: calc(1.28em + var(--screen-h));
  --arm: calc(var(--arm-k) * 32em);
  --leg: 9.3em;
  position: relative;
  width: var(--w);
  height: calc(var(--below) + 24.97em);
  font-size: calc(var(--w) / 32);
  margin: 0 var(--arm) var(--leg);
  background: transparent;
  border: var(--stroke) solid var(--line);
  border-radius: 1.8em;
  outline: 1px solid var(--line-soft);
  outline-offset: -0.45em;
  user-select: none;
  -webkit-user-select: none;
}
@media (max-width: 560px) {
  .device { --screen-h: 25.5em; }
}
.device > * { position: absolute; }

.micro {
  font-family: var(--font-mono);
  font-size: 0.62em;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Screen: the mascot's face — a wide rounded glass with the crystal centred in it. */
.bezel {
  left: 1.92em; top: 1.28em;
  width: 28.16em; height: var(--screen-h);
  border: var(--stroke) solid var(--line);
  border-radius: 1.1em;
  display: grid;
  place-items: center;
}
.lcd {
  position: relative;
  height: calc(100% - 1.8em);
  aspect-ratio: 160 / 144;
  background: var(--lcd);
  border-radius: 0.4em;
  box-shadow: inset 0 0.25em 0.5em #0000004d;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.lcd canvas { display: block; }
/* Glass: faint diagonal reflection. */
.lcd::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(125deg, #ffffff26 0%, #ffffff00 38%, #ffffff00 70%, #ffffff12 100%);
  pointer-events: none;
}
/* Refresh line rolling down the crystal. */
.lcd::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 16%;
  background: linear-gradient(#ffffff00, #ffffff1c 55%, #ffffff00);
  transform: translateY(-100%);
  animation: sweep 7s linear infinite;
  pointer-events: none;
  z-index: 1;
}
@keyframes sweep { 0% { transform: translateY(-100%); } 60%, 100% { transform: translateY(640%); } }

/* Status LED: under the screen on the left, where the mascot's green light is. */
.led {
  left: 5.66em; top: calc(var(--below) + 1.5em);
  width: 0.62em; height: 0.62em;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 0.6em var(--coral);
  animation: led 2.4s steps(1) infinite;
}
@keyframes led { 0%, 92% { opacity: 1; } 93%, 100% { opacity: 0.35; } }

/* Screws in the corners of the lower panel. */
.screw {
  width: 0.9em; height: 0.9em;
  border-radius: 50%;
  border: 1px solid var(--muted);
  opacity: 0.8;
}
.screw::after { content: ''; position: absolute; left: 15%; right: 15%; top: 50%; height: 1px; background: var(--muted); transform: rotate(-35deg); }
.screw-tl { left: 2.08em; top: calc(var(--below) + 1.2em); }
.screw-tr { right: 2.08em; top: calc(var(--below) + 1.2em); }
.screw-bl { left: 2.25em; bottom: 2.45em; }
.screw-br { right: 2.25em; bottom: 2.45em; }

/* ---------- keys ---------- */

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  touch-action: none;
  -webkit-touch-callout: none;
}
button:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; }
.fire:focus-visible { outline-width: 3px; }

.control { display: flex; flex-direction: column; align-items: center; gap: 0.55em; }

.key {
  border-radius: 50%;
  background: transparent;
  color: var(--line);
  border: var(--stroke) solid var(--line);
  font-size: 1em;
  display: grid;
  place-items: center;
  padding: 0;
  transition: background 60ms, color 60ms;
}
.key.is-down, .key:active { background: var(--line); color: var(--page); }

/* ◀ ▶ under the LED, in the left column. */
.rocker { left: 2.9em; top: calc(var(--below) + 3.7em); display: flex; gap: 0.7em; }
.rocker .key { width: 3.8em; height: 3.8em; }

/* Right cluster, a 2x2 grid like the mascot's keycaps: sign | FIRE over SOUND | START. */
.badge { left: 17.1em; top: calc(var(--below) + 3.5em); width: 5.2em; height: 5.2em; display: grid; place-items: center; }
.badge .logo { height: 3.5em; width: auto; display: block; filter: var(--logo-filter); opacity: 0.95; }
.control-fire { left: 23.1em; top: calc(var(--below) + 3.1em); width: 5.4em; }
.control-sound { left: 17.1em; top: calc(var(--below) + 10.4em); width: 5.2em; }
.control-start { left: 23.2em; top: calc(var(--below) + 10.4em); width: 5.2em; }
.key-sys { width: 2.7em; height: 2.7em; }

/* The one filled object: brand coral, drawn with a contour ring. */
.fire {
  width: 4.4em; height: 4.4em;
  border-radius: 50%;
  background: var(--coral);
  border: 0;
  outline: var(--stroke) solid var(--coral);
  outline-offset: 0.3em;
  transition: transform 60ms, box-shadow 120ms;
}
.fire.is-down, .fire:active {
  transform: scale(0.94);
  background: var(--coral-active);
  box-shadow: 0 0 2.4em 0.4em var(--glow);
}

/* On games.bots-n-bones.com the sign in each game links back to the cartridge menu. */
.back { display: flex; align-items: center; gap: 0.35em; color: var(--line); text-decoration: none; }
.back-arrow { font-size: 0.8em; color: var(--muted); }
.back:hover .back-arrow { color: var(--coral); }
.back:focus-visible { outline: 2px solid var(--coral); outline-offset: 0.3em; border-radius: 0.2em; }

/* Speaker: a framed grille; background-repeat: space fits whole holes only, none cut at the edges. */
.speaker {
  left: 11.2em; top: calc(var(--below) + 15.8em);
  width: 16.8em; height: 5.4em;
  border: var(--stroke) solid var(--line);
  border-radius: 0.8em;
  padding: 0.75em 0.9em;
  background: radial-gradient(circle, var(--line) 0 0.17em, transparent 0.2em) content-box 0 0 / 0.8em 0.8em space;
  opacity: 0.8;
}
/* Charging port on the bottom edge. */
.port {
  left: 19.1em; bottom: 0.55em;
  width: 5.9em; height: 1.5em;
  border: 1px solid var(--line);
  border-radius: 0.5em;
  background: repeating-linear-gradient(90deg, var(--muted) 0 1px, transparent 1px 0.42em) content-box;
  padding: 0.45em 0.7em;
  opacity: 0.7;
}

/* ---------- limbs: line-art arms and legs of the mascot ---------- */

.limb { color: var(--line); pointer-events: none; }
.limb svg { display: block; width: 100%; height: auto; }
.limb svg * { fill: none; stroke: currentColor; stroke-width: var(--stroke); vector-effect: non-scaling-stroke; stroke-linejoin: round; }
/* Each arm grows out of the body's side: the tube is cut by the body contour (the box clips it). */
.arm { width: var(--arm); top: calc(var(--below) + 4em); overflow: hidden; }
.arm-left { right: calc(100% + var(--stroke)); }
.arm-right { left: calc(100% + var(--stroke)); transform: scaleX(-1); }
.leg {
  top: calc(100% + var(--stroke));
  width: 6.88em;
  height: var(--leg);
  border: var(--stroke) solid currentColor;
  border-top: 0;
  border-radius: 0 0 1.1em 1.1em;
}
.leg::after { content: ''; position: absolute; left: 0; right: 0; bottom: 2.2em; border-top: var(--stroke) solid currentColor; }
.leg-left { left: 17.5%; }
.leg-right { right: 17.5%; }

/* Footnote: pinned to the bottom edge, outside the layout, so the device stays centred. */
.star { color: var(--coral); text-decoration: none; font-family: var(--font-mono); }
.footnote {
  position: fixed;
  left: 50%;
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100vw - 32px);
  margin: 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.02em;
  text-align: center;
  text-wrap: balance;
}
.footnote a { color: var(--line); text-decoration: underline; text-decoration-color: var(--coral); text-underline-offset: 3px; }
.footnote a:hover { color: var(--coral); }
.footnote a:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }
.footnote .sep { margin: 0 0.4em; }

/* ---------- device reactions, driven by the game ---------- */

/* Player hit: the whole mascot jolts. */
.device.fx-shake { animation: jolt 420ms linear; }
@keyframes jolt {
  0% { transform: none; }
  15% { transform: translate(-6px, 3px) rotate(-0.8deg); }
  35% { transform: translate(5px, -4px) rotate(0.6deg); }
  55% { transform: translate(-4px, 2px) rotate(-0.4deg); }
  75% { transform: translate(2px, -1px) rotate(0.2deg); }
  100% { transform: none; }
}

/* Danger: contour, limbs and LED go to alarm. */
.device.danger { animation: alarm 600ms steps(1) infinite; }
.device.danger.fx-shake { animation: jolt 420ms linear, alarm 600ms steps(1) infinite; }
@keyframes alarm { 0% { border-color: var(--alarm); } 50% { border-color: var(--line); } }
.device.danger .limb { animation: alarm-limb 600ms steps(1) infinite; }
@keyframes alarm-limb { 0% { color: var(--alarm); } 50% { color: var(--line); } }
.device.danger .led { animation: led-alarm 300ms steps(1) infinite; }
@keyframes led-alarm { 0% { opacity: 1; box-shadow: 0 0 1.2em var(--alarm); } 50% { opacity: 0.25; } }

/* Every kill pings the LED white. */
.device.fx-hit .led { animation: led-hit 240ms steps(1); }
@keyframes led-hit { 0% { background: #fff; box-shadow: 0 0 1.4em #fff; } 50% { background: var(--coral); box-shadow: 0 0 1.4em var(--coral); } }

@media (prefers-reduced-motion: reduce) {
  .led, .lcd::before, .device.danger, .device.danger .led, .device.danger .limb { animation: none; }
  .device.danger { border-color: var(--alarm); }
  .device.danger .limb { color: var(--alarm); }
  .key, .fire { transition: none; }
}

/* ---------- cartridge select: the shell recolours when the yellow cartridge is picked ---------- */

@property --line { syntax: '<color>'; inherits: true; initial-value: #c9ccb8; }
@property --muted { syntax: '<color>'; inherits: true; initial-value: #8d917f; }
@property --coral { syntax: '<color>'; inherits: true; initial-value: #ff5c45; }
@property --page { syntax: '<color>'; inherits: true; initial-value: #161813; }
@property --page-hi { syntax: '<color>'; inherits: true; initial-value: #252921; }
@property --lcd { syntax: '<color>'; inherits: true; initial-value: #aab496; }
body { transition: --line 260ms, --muted 260ms, --coral 260ms, --page 260ms, --page-hi 260ms, --lcd 260ms; }
@media (prefers-reduced-motion: reduce) { body { transition: none; } }

/* Plain links to every game for screen readers and no-JS visitors. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.sr-only:focus-within { position: fixed; top: 12px; left: 12px; width: auto; height: auto; margin: 0; clip: auto; overflow: visible; display: flex; gap: 12px; z-index: 5; }
.sr-only a { color: var(--line); font-size: 12px; text-decoration-color: var(--coral); }
