@font-face {
  font-family: "Fusion Pixel";
  src: url("assets/fonts/fusion-pixel-12px-zh_hans.woff2") format("woff2");
  font-display: swap;
}
:root {
  /* Shell: matte cobalt plastic, lit from above */
  --shell-hi: #3d7cf2;
  --shell: #2059d2;
  --shell-mid: #1747b3;
  --shell-lo: #0f3794;
  --shell-deep: #0a2a76;
  /* Recesses the controls sit in */
  --well-top: #061b50;
  --well-mid: #0d3088;
  --well-bottom: #2058c8;
  /* Satin charcoal keys */
  --key-hi: #4d5058;
  --key-mid: #2b2d33;
  --key-lo: #15161a;
  --key-side: #050608;
  --ink: #e7eaf0;
  /* Pad-printed labels on the shell */
  --print: rgba(232, 240, 255, 0.86);
  --print-dim: rgba(214, 228, 255, 0.55);
  --accent: #ffec27;
  --S: 384px; /* screen edge, set by main.js to a whole number of device pixels per PICO-8 pixel */
  --sans: "Avenir Next", "SF Pro Display", "Helvetica Neue", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
  --pixel: "Fusion Pixel", monospace;
  --shoulder-h: min(7.8vh, 44px);
}
* {
  box-sizing: border-box;
}
/* hidden wins over a class's display (the volume bar is display: flex) */
[hidden] {
  display: none !important;
}
html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--shell-lo);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  touch-action: none;
}

/* Device shell: top light, a soft falloff to the edges, fine grain, and the
   seam of the front plate a little inside the edge */
.device {
  position: fixed;
  inset: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background:
    radial-gradient(110% 62% at 50% -14%, rgba(255, 255, 255, 0.24), rgba(255, 255, 255, 0) 64%),
    radial-gradient(150% 125% at 50% 38%, rgba(0, 0, 0, 0) 52%, rgba(2, 12, 50, 0.55) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E"),
    linear-gradient(180deg, var(--shell-hi) 0%, var(--shell) 28%, var(--shell-mid) 64%, var(--shell-lo) 100%);
  background-blend-mode: normal, normal, soft-light, normal;
  font-family: var(--sans);
  color: var(--ink);
}
.device::before {
  content: "";
  position: absolute;
  inset: max(6px, 1.1vh);
  border-radius: max(18px, 4.5vh);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -1px 0 rgba(0, 10, 40, 0.35),
    0 1px 0 rgba(0, 10, 40, 0.3),
    0 -1px 0 rgba(255, 255, 255, 0.08);
  pointer-events: none;
}
/* The two sides mirror each other. Each is one column of four, all centred on
   the same line and as wide as each other: the shoulder key at the top edge,
   the AGENT key / the touchpad, the d-pad / the face buttons, and the small
   keys, whose bottom is level with the screen's (--bezel-bottom, set by
   main.js). The gaps between them are equal. */
.side {
  /* The AGENT key's text size; --pw × --ph is the box of the AGENT key and the
     touchpad, and the width of the shoulder key and the small keys */
  --size: min(10.4vh, 6vw, 64px);
  --pw: calc(var(--size) * 3);
  --ph: min(15vh, 9vw, 100px);
  /* The face buttons' size; the d-pad is centred in a row this tall too */
  --face: min(40vh, 19vw, 280px);
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto minmax(0, 1fr) var(--face) minmax(0, 1fr) auto;
  justify-items: center;
  min-width: 0;
  padding-top: calc(env(safe-area-inset-top) + 1.1vh);
  padding-bottom: var(--bezel-bottom, 3vh);
}
.side > :nth-child(2) {
  grid-row: 3;
}
.side > :nth-child(3) {
  grid-row: 5;
  align-self: center;
}
.side > :nth-child(4) {
  grid-row: 7;
}
/* Small keys: VOL on the left, MENU and SETTING sharing the same width on the right */
.small-row {
  display: flex;
  gap: min(2.4vh, 16px);
  width: var(--pw);
}
.small-row > .pill-well {
  flex: 1;
}
.small-row .pill {
  width: 100%;
  min-width: 0;
  padding: 0;
  font-size: min(2.2vh, 13px);
  letter-spacing: 0.1em;
}
.print {
  color: var(--print);
  text-shadow: 0 1px 0 rgba(0, 10, 40, 0.35);
}

/* Keys: one satin surface for all of them. --lift is the key's height above
   its recess; pressed, it sinks most of the way in. */
.key {
  --lift: 4px;
  position: relative;
  color: var(--ink);
  background:
    radial-gradient(70% 55% at 34% 22%, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0) 72%),
    radial-gradient(120% 80% at 50% 118%, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0) 62%),
    linear-gradient(180deg, var(--key-hi), var(--key-mid) 52%, var(--key-lo));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -1px 0 rgba(0, 0, 0, 0.55),
    0 var(--lift) 0 var(--key-side),
    0 calc(var(--lift) + 3px) 7px rgba(0, 6, 30, 0.5);
  font-family: var(--sans);
  font-weight: 700;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.75), 0 1px 0 rgba(255, 255, 255, 0.07);
  transition: transform 45ms ease-out, box-shadow 45ms ease-out, filter 45ms;
}
.key.down {
  transform: translateY(calc(var(--lift) - 1px));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    inset 0 2px 6px rgba(0, 0, 0, 0.6),
    0 1px 0 var(--key-side),
    0 2px 3px rgba(0, 6, 30, 0.45);
  filter: brightness(0.88);
}
/* A key the highlight is pressing (feed.js onDemoKeys) glows without sinking;
   the glow fades slowly so a two-frame tap still shows */
.key::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  box-shadow: 0 0 0 3px var(--accent), 0 0 20px 5px rgba(255, 236, 39, 0.6);
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease-out;
}
.key.ghost {
  color: var(--accent);
}
.key.ghost::after {
  opacity: 1;
  transition: none;
}
/* Recesses molded into the shell: shadowed at the top, catching light at the lower lip */
.key-well,
.pill-well,
.agent-well,
.dpad-well,
.shoulder,
.touchpad {
  background: linear-gradient(180deg, var(--well-top), var(--well-mid) 55%, var(--well-bottom));
  box-shadow:
    inset 0 3px 6px rgba(0, 6, 30, 0.7),
    inset 0 -1px 0 rgba(255, 255, 255, 0.22),
    0 1px 0 rgba(255, 255, 255, 0.16),
    0 -1px 0 rgba(0, 10, 40, 0.25);
}

/* Shoulders: set into the top edge */
.shoulder {
  z-index: 2;
  padding: 3px 3px 5px;
  border-radius: 16px 16px 28px 28px;
}
.shoulder.left {
  border-radius: 16px 16px 30px 18px;
}
.shoulder.right {
  border-radius: 16px 16px 18px 30px;
}
.shoulder .key {
  --lift: 4px;
  display: block;
  width: calc(var(--pw) - 6px);
  height: var(--shoulder-h);
  border-radius: inherit;
  font-size: min(4.4vh, 22px);
  letter-spacing: 0.1em;
}

@keyframes blink {
  50% {
    opacity: 0.35;
  }
}

/* D-pad: one cross (SVG) with a bevel, a dished centre and embossed arrows,
   in a round recess; it rocks toward the pressed direction */
.dpad-well {
  --pad: min(33vh, 15.5vw, 236px);
  display: grid;
  place-items: center;
  width: calc(var(--pad) * 1.18);
  height: calc(var(--pad) * 1.18);
  border-radius: 50%;
}
.dpad {
  width: var(--pad);
  height: var(--pad);
  touch-action: none;
  transition: transform 60ms ease-out;
  filter: drop-shadow(0 5px 6px rgba(0, 6, 30, 0.5));
}
.dpad svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.dpad .arrow {
  fill: #c3c8d2;
  stroke: transparent;
  stroke-width: 3;
  stroke-linejoin: round;
  opacity: 0.6;
  transition: fill 280ms ease-out, stroke 280ms ease-out, opacity 280ms ease-out;
}
/* The highlight's presses light the arrow up, larger, without rocking the pad */
.dpad.ghost-up .arrow.up,
.dpad.ghost-down .arrow.down,
.dpad.ghost-left .arrow.left,
.dpad.ghost-right .arrow.right {
  fill: var(--accent);
  stroke: var(--accent);
  opacity: 1;
  transition: none;
}
.dpad.up {
  transform: perspective(520px) rotateX(11deg);
}
.dpad.down {
  transform: perspective(520px) rotateX(-11deg);
}
.dpad.left {
  transform: perspective(520px) rotateY(-11deg);
}
.dpad.right {
  transform: perspective(520px) rotateY(11deg);
}
.dpad.up .arrow.up,
.dpad.down .arrow.down,
.dpad.left .arrow.left,
.dpad.right .arrow.right {
  fill: var(--accent);
  opacity: 1;
}

/* Screen */
.center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.bezel {
  position: relative;
  padding: 5px calc(var(--S) * 0.04) calc(var(--S) * 0.022);
  border-radius: calc(var(--S) * 0.055) calc(var(--S) * 0.055) calc(var(--S) * 0.085) calc(var(--S) * 0.085);
  background:
    linear-gradient(152deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.035) 24%, rgba(255, 255, 255, 0) 42%),
    linear-gradient(180deg, #1d1f24, #111215 55%, #0a0b0d);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.6),
    0 0 0 calc(var(--S) * 0.014) var(--shell-deep),
    0 0 0 calc(var(--S) * 0.014 + 1px) rgba(255, 255, 255, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 -1px 0 rgba(0, 0, 0, 0.8),
    0 1.6vh 3.2vh rgba(0, 8, 40, 0.5);
}
.viewport {
  position: relative;
  width: var(--S);
  height: var(--S);
  overflow: hidden;
  background: #000;
  box-shadow:
    0 0 0 1px #000,
    0 0 0 2px rgba(255, 255, 255, 0.07);
  touch-action: none;
  cursor: grab;
}
/* The display sits a little below the glass */
.viewport::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 9;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.65),
    inset 0 2px 6px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}
.track {
  position: absolute;
  inset: 0;
  will-change: transform;
}
.track.animate {
  transition: transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.track canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--S);
  height: var(--S);
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: #000;
}

/* On-screen info (pixel font, multiples of 12px) */
.overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 1.25;
  color: #fff;
  text-shadow: 1px 1px 0 #000, -1px 0 0 #000, 0 -1px 0 #000, 1px 0 0 #000;
  transition: opacity 200ms;
}
.overlay[data-mode="play"],
.overlay.dragging {
  opacity: 0;
}
.hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  padding: 2px 0 3px;
  background: rgba(0, 0, 0, 0.55);
  text-align: center;
  text-shadow: none;
  transition: opacity 300ms;
}
.overlay[data-hint="hide"] .hint {
  opacity: 0;
}
.hint::after {
  content: " ▶";
  animation: blink 1.1s steps(2, jump-none) infinite;
}
.overlay[data-mode="loading"] .hint::after,
.overlay[data-mode="seeking"] .hint::after {
  content: "";
}
.overlay[data-mode="error"] .hint {
  top: 0;
  bottom: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: rgba(29, 43, 83, 0.9);
  white-space: pre-line;
}

/* Pixel-font strips and panels at 2x on a large screen (--ui, set by main.js) */
.tabs,
.label,
.howto,
.page,
.like-pop,
.asker,
.overlay,
.menu,
.osd,
.agent-screen,
.ask {
  zoom: var(--ui, 1);
}
.label {
  width: calc(var(--S) / var(--ui, 1));
  height: calc(var(--S) * 0.06 / var(--ui, 1));
}
.howto {
  width: calc(var(--S) / var(--ui, 1));
}

/* Strip on the glass over the screen: the views L/R switch between */
.tabs {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 2px;
  height: 20px;
  margin-bottom: 4px;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 1;
  color: #6f7480;
  white-space: nowrap;
}
.tabs span {
  padding: 3px 6px;
  border-radius: 3px;
}
.tabs span.on {
  background: linear-gradient(180deg, #ff2d62, #dc0040);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 8px rgba(255, 0, 77, 0.4);
  color: #fff;
}
.tabs b {
  margin: 0 6px;
  padding: 2px 5px;
  border-radius: 4px;
  background: linear-gradient(180deg, #2c2e34, #16171a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 0 #000;
  color: #a2a7b2;
  font-weight: normal;
}

/* Code, sprite sheet, map and SFX views over the screen */
.view {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #000;
}
.view canvas {
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.view .code {
  position: absolute;
  inset: 0;
  padding: 2px 0;
  overflow: hidden;
  background: #1d2b53;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #fff1e8;
  white-space: pre;
}
.view .code div.cur {
  background: rgba(255, 255, 255, 0.12);
}
.view .code i {
  font-style: normal;
  color: #5f574f;
  margin-right: 6px;
}
.view .code .c {
  color: #83769c;
}
.view .code .k {
  color: #ff77a8;
}
.view .code .s {
  color: #29adff;
}
.view .code .n {
  color: #ffa300;
}
.menu {
  z-index: 2;
}
.info {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bezel[data-view="game"] .info,
.bezel:not([data-view="game"]) .badge,
.bezel:not([data-view="game"]) .byline,
.bezel:not([data-view="game"]) .position {
  display: none;
}

/* Strip on the glass under the screen: what's playing */
.label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 18px;
  padding-top: 5px;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 1;
  color: #9ea3ae;
  white-space: nowrap;
}
.badge {
  padding: 2px 4px;
  border-radius: 2px;
  background: linear-gradient(180deg, #ff2d62, #dc0040);
  color: #fff;
}
.badge:empty {
  display: none;
}
.title {
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #f2f4f8;
}
.byline {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.position {
  display: none; /* the card count is not worth a permanent place */
}
.like {
  color: #6f7480;
}
.like.on {
  color: #ff004d;
}
/* The game's 怎么玩 line, written by the Agent from its code: what to do,
   then each key and what it does; the keys stay whole, the text gives way */
.howto {
  display: flex;
  align-items: center;
  overflow: hidden;
  padding-top: 3px;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #d4d8e0;
  white-space: nowrap;
}
.howto-line {
  display: none; /* the strip shows the keys; what to do is on the game's page */
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.howto-keys {
  display: flex;
  flex: none;
  gap: 6px;
  margin-left: 6px;
}
.howto-line:empty + .howto-keys {
  margin-left: 0;
}
.key-chip {
  display: flex;
  align-items: center;
  gap: 2px;
  color: #aeb3be;
  transition: color 280ms ease-out;
}
.key-chip kbd {
  padding: 0 2px;
  border-radius: 2px;
  background: #2b2e36;
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.5);
  color: #e6e9ef;
  font: inherit;
  transition: background 280ms ease-out, color 280ms ease-out;
}
/* ... lit while the highlight presses that key */
.key-chip.lit {
  color: var(--accent);
  transition: none;
}
.key-chip.lit kbd {
  background: var(--accent);
  color: #1d2b53;
  transition: none;
}
.howto b {
  flex: none;
  margin-right: 6px;
  padding: 0 3px;
  border-radius: 2px;
  background: #2b2e36;
  color: var(--accent);
  font-weight: normal;
}
.bezel:not([data-view="game"]) .howto {
  display: none;
}
.progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: rgba(255, 255, 255, 0.2);
}
.progress span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
}

/* Pause menu, styled like PICO-8's */
.menu {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  min-width: 55%;
  padding: 10px 14px;
  background: #000;
  border: 2px solid #fff;
  font-family: var(--pixel);
  font-size: 24px;
  line-height: 1.3;
  color: #fff;
}
.menu div {
  position: relative;
  padding-left: 20px;
  white-space: nowrap;
}
.menu div.selected::before {
  content: "▶";
  position: absolute;
  left: 0;
  color: var(--accent);
}
/* In an editor the menu (undo, redo, …) sits low and small so the edit stays in view */
.bezel:not([data-view="game"]) .menu {
  top: auto;
  bottom: 4px;
  transform: translateX(-50%);
  min-width: 40%;
  padding: 4px 8px;
  border-width: 1px;
  font-size: 12px;
  line-height: 15px;
}
.bezel:not([data-view="game"]) .menu div {
  padding-left: 14px;
}

/* MENU, a pill key in a pill recess */
.pill-well {
  padding: 3px;
  border-radius: 99px;
}
.pill {
  --lift: 3px;
  display: block;
  min-width: min(12vh, 78px);
  height: min(5.4vh, 34px);
  padding: 0 1.8vh;
  border-radius: 99px;
  font-size: min(2.6vh, 15px);
  letter-spacing: 0.14em;
}

/* Face buttons, Picotron numbering: O=4 X=5 A=12 B=13, each in its own recess */
.face {
  position: relative;
  width: var(--face);
  height: var(--face);
  touch-action: none;
}
.key-well {
  position: absolute;
  width: 39%;
  height: 39%;
  border-radius: 50%;
}
.key-well.top {
  left: 30.5%;
  top: 0;
}
.key-well.bottom {
  left: 30.5%;
  bottom: 0;
}
.key-well.left {
  left: 0;
  top: 30.5%;
}
.key-well.right {
  right: 0;
  top: 30.5%;
}
.face-btn {
  --lift: max(3px, calc(var(--face) * 0.02));
  position: absolute;
  inset: 8% 8% calc(8% + var(--lift));
  border-radius: 50%;
  font-size: calc(var(--face) * 0.13);
}

.rotate {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 20;
  align-items: center;
  justify-content: center;
  background: var(--shell-lo);
  color: #fff;
  font-family: var(--pixel);
  font-size: 24px;
}
@media (orientation: portrait) and (max-width: 760px) {
  .rotate {
    display: flex;
  }
}
@media (prefers-reduced-motion: reduce) {
  .track.animate {
    transition: none;
  }
  .hint,
  .agent-well::after,
  .touchpad *,
  .page,
  .like-pop,
  .agent-screen * {
    animation: none !important;
  }
}

.volume {
  --lift: 3px;
  display: flex;
  align-items: center;
  height: min(5.4vh, 34px);
  border-radius: 99px;
  overflow: hidden;
}
.vol-key {
  width: min(6.4vh, 40px);
  height: 100%;
  font-size: min(4.4vh, 26px);
  font-weight: 500;
  line-height: 1;
  transition: background 50ms, box-shadow 50ms;
}
.vol-key.down {
  background: rgba(0, 0, 0, 0.35);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.6);
}
.vol-mark {
  font-size: min(2.2vh, 13px);
  letter-spacing: 0.16em;
  opacity: 0.5;
}

/* Volume level, shown on the screen for a moment */
.osd {
  position: absolute;
  left: 50%;
  top: 10%;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  background: rgba(0, 0, 0, 0.85);
  border: 2px solid #fff1e8;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 1;
  color: #fff1e8;
  pointer-events: none;
}
.osd .speaker-icon {
  width: 12px;
  height: 12px;
  background: #fff1e8;
  clip-path: polygon(0 32%, 32% 32%, 70% 0, 70% 100%, 32% 68%, 0 68%);
}
.osd .speaker-icon.mute {
  background: #ff004d;
}
.osd .bars {
  display: flex;
  gap: 2px;
}
.osd .bars i {
  width: 5px;
  height: 12px;
  background: #5f574f;
}
.osd .bars i.on {
  background: #00e436;
}
.osd .level {
  width: 14px;
  text-align: right;
}

/* Touchpad beside the screen, after the DualSense's: up/down switch games,
   left/right the author page, a double tap likes. It sits in a recess between
   two light strips; the surface lights up under the finger. */
.touchpad {
  display: flex;
  gap: 3px;
  width: var(--pw);
  height: var(--ph);
  padding: 3px;
  border-radius: 14px 14px 22px 22px;
  touch-action: none;
  cursor: grab;
}
.pad-surface {
  position: relative;
  flex: 1;
  overflow: hidden;
  border-radius: 11px 11px 19px 19px;
  background:
    radial-gradient(120% 90% at 30% 0%, rgba(255, 255, 255, 0.17), rgba(255, 255, 255, 0) 55%),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.02) 0 1px, transparent 1px 3px),
    linear-gradient(180deg, #2b2e34, #17181c 70%, #0e0f12);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -2px 3px rgba(0, 0, 0, 0.6),
    0 2px 3px rgba(0, 6, 30, 0.5);
}
.pad-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at var(--tx, 50%) var(--ty, 50%), rgba(150, 196, 255, 0.38), rgba(150, 196, 255, 0) 40%);
  opacity: 0;
  transition: opacity 120ms;
}
.touchpad.touching .pad-glow {
  opacity: 1;
}
.pad-light {
  width: 3px;
  margin: 8% 0;
  border-radius: 3px;
  background: #2f5fc4;
  box-shadow: 0 0 6px rgba(80, 140, 255, 0.45);
  opacity: 0.6;
  transition: opacity 120ms, background 120ms, box-shadow 120ms;
}
.touchpad.touching .pad-light {
  opacity: 1;
  background: #a8caff;
  box-shadow: 0 0 10px #6aa8ff;
}
.touchpad.liked .pad-light {
  animation: pad-like 650ms ease-out;
}
.touchpad.unliked .pad-light {
  animation: pad-unlike 650ms ease-out;
}
@keyframes pad-like {
  0%, 60% { opacity: 1; background: #ff6aa9; box-shadow: 0 0 14px #ff4f97; }
}
@keyframes pad-unlike {
  0%, 60% { opacity: 1; background: #c2c3c7; box-shadow: 0 0 8px #c2c3c7; }
}

/* The AGENT key and the touchpad are the same size. The AGENT key's status
   line, when lit, shows in the gap under it and moves nothing. */
.agent-wrap {
  position: relative;
  display: grid;
  justify-items: center;
}

/* AGENT key (was POWER): a pill key with a microphone; its recess carries the LED ring */
.agent-well {
  --ring: #39e05a;
  position: relative;
  width: var(--pw);
  height: var(--ph);
  padding: calc(var(--size) * 0.09);
  border-radius: 99px;
}
.agent-well::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 99px;
  box-shadow:
    0 0 0 1.5px color-mix(in srgb, var(--ring) 85%, transparent),
    0 0 12px color-mix(in srgb, var(--ring) 55%, transparent),
    inset 0 0 8px color-mix(in srgb, var(--ring) 45%, transparent);
  opacity: 0.7;
  pointer-events: none;
}
.agent {
  --lift: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--size) * 0.16);
  width: 100%;
  height: 100%;
  padding: 0 calc(var(--size) * 0.44) 0 calc(var(--size) * 0.32);
  border-radius: 99px;
  font-size: calc(var(--size) * 0.34);
  letter-spacing: 0.1em;
}
.agent .mic {
  width: calc(var(--size) * 0.48);
  height: calc(var(--size) * 0.48);
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  filter: drop-shadow(0 -1px 0 rgba(0, 0, 0, 0.7));
}
.agent .mic rect {
  fill: var(--ring);
  stroke: none;
}
.agent-well:has([data-state="listening"]) {
  --ring: #ff3b4d;
}
.agent-well:has([data-state="cancel"]) {
  --ring: #8a8f99;
}
.agent-well:has([data-state="working"]) {
  --ring: #ffb020;
}
.agent-well:has([data-state="error"]) {
  --ring: #ff3b4d;
}
.agent-well:has([data-state="done"]) {
  --ring: #5cff7a;
}
.agent-well:has([data-state="listening"])::after,
.agent-well:has([data-state="done"])::after {
  opacity: 1;
  animation: glow 0.9s ease-in-out infinite;
}
.agent-well:has([data-state="working"])::after {
  animation: breathe 1.6s ease-in-out infinite;
}
@keyframes glow {
  50% { opacity: 0.45; }
}
@keyframes breathe {
  50% { opacity: 0.25; }
}
/* The key's status line: a tiny inset display */
.agent-status {
  position: absolute;
  top: calc(100% + 1vh);
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 10px;
  border-radius: 6px;
  background: linear-gradient(180deg, #071640, #0b2058);
  box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.55), 0 1px 0 rgba(255, 255, 255, 0.16);
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #a9b8dc;
  white-space: nowrap;
}
.agent-status:not([data-state]),
.agent-status[data-state="idle"] {
  visibility: hidden; /* lit only while the Agent has something to say */
}
.agent-status[data-state="listening"],
.agent-status[data-state="error"] {
  color: #ff8a95;
}
.agent-status[data-state="working"] {
  color: #ffd27a;
}
.agent-status[data-state="done"] {
  color: #8dff9f;
}

/* The Agent's screens, on the handheld's display (pixel font, PICO-8 colours) */
.agent-screen {
  position: absolute;
  inset: 0;
  z-index: 5;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #fff1e8;
  pointer-events: none;
}
.agent-screen[data-mode="banner"] {
  inset: 6px 6px auto;
}
.agent-screen[data-mode="listen"],
.agent-screen[data-mode="panel"],
.agent-screen[data-mode="form"] {
  pointer-events: auto;
  background: rgba(0, 0, 0, 0.74);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.banner {
  --c: #c2c3c7;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: rgba(17, 29, 53, 0.95);
  border: 2px solid var(--c);
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.45);
  pointer-events: auto;
  cursor: pointer;
  animation: drop-in 160ms ease-out;
}
.banner.sent { --c: #29adff; }
.banner.done { --c: #00e436; }
.banner.error { --c: #ff004d; }
.banner.reply { --c: #ffec27; }
.banner .dot {
  flex: none;
  width: 8px;
  height: 8px;
  background: var(--c);
}
.banner .thumb {
  flex: none;
  width: 48px;
  height: 48px;
  image-rendering: pixelated;
  background: #000;
  outline: 1px solid #fff1e8;
}
.banner .body {
  min-width: 0;
}
.banner .headline {
  color: var(--c);
}
.banner .text {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@keyframes drop-in {
  from { transform: translateY(-8px); opacity: 0; }
}

.listen {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: auto 1fr auto auto;
  gap: 6px;
  padding: 8px;
}
.listen.cancel {
  background: rgba(126, 37, 83, 0.6);
}
.listen .top {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #ff004d;
}
.listen.cancel .top {
  color: #fff1e8;
}
.listen .rec {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  animation: blink 1s steps(2, jump-none) infinite;
}
.listen .ctx {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #c2c3c7;
}
.mic-big {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.mic-big i {
  width: 6px;
  height: 30px;
  background: #ff004d;
  animation: wave 1.1s ease-in-out infinite;
}
.mic-big i:nth-child(2) { animation-delay: -0.9s; }
.mic-big i:nth-child(3) { animation-delay: -0.6s; }
.mic-big i:nth-child(4) { animation-delay: -0.3s; }
.mic-big i:nth-child(5) { animation-delay: -0.75s; }
.mic-big.hearing i {
  background: #ffec27;
  animation-duration: 0.55s;
}
.listen.cancel .mic-big i {
  background: #5f574f;
  animation-play-state: paused;
}
@keyframes wave {
  0%, 100% { transform: scaleY(0.25); }
  50% { transform: scaleY(1); }
}
.listen .words {
  max-height: 84px;
  overflow: hidden;
  padding: 0 4px;
  font-size: 24px;
  line-height: 28px;
  text-align: center;
  word-break: break-all;
}
.listen .words.long {
  font-size: 12px;
  line-height: 15px;
}
.listen .words .prompt {
  font-size: 12px;
  color: #c2c3c7;
}
.listen .words .live {
  color: #29adff;
}
.listen .foot {
  text-align: center;
  color: #83769c;
}

.panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
}
.panel .head {
  display: flex;
  align-items: center;
  gap: 6px;
}
.panel .name {
  padding: 0 4px;
  background: #ff004d;
}
.panel .model {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #83769c;
}
.task {
  --c: #29adff;
  padding: 4px 6px;
  background: rgba(29, 43, 83, 0.92);
  border: 2px solid var(--c);
}
.task.error { --c: #ff004d; }
.task.idle { --c: #5f574f; }
.task-head {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--c);
}
.task-head .time {
  margin-left: auto;
  color: #fff1e8;
}
.spin {
  width: 8px;
  height: 8px;
  border: 2px solid var(--c);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
.request {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.request .tag {
  margin-left: 6px;
  color: #ffec27;
}
.task .tip {
  color: #c2c3c7;
}
.row .new {
  flex: none;
  padding: 0 3px;
  background: #00e436;
  color: #000;
}
.steps {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  color: #83769c;
}
.steps li {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.steps li::before {
  content: "✓ ";
  color: #00e436;
}
.steps li.now {
  color: #fff1e8;
}
.steps li.now::before {
  content: "▶ ";
  color: #ffec27;
}
.meter {
  color: #ffa300;
}
.rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
}
.rows::-webkit-scrollbar {
  display: none;
}
.section {
  margin-top: 4px;
  color: #83769c;
}
.row {
  position: relative;
  display: flex;
  gap: 6px;
  padding-left: 14px;
  cursor: pointer;
}
.row .what {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row .note {
  flex: none;
  margin-left: auto;
  color: #83769c;
}
.row.selected::before {
  content: "▶";
  position: absolute;
  left: 0;
  color: #ffec27;
}
.row.selected .what {
  color: #ffec27;
}
.row.danger .what {
  color: #ff77a8;
}
.panel .foot {
  text-align: center;
  color: #5f574f;
}

/* Typing instead of talking, on the display too */
.ask {
  position: absolute;
  inset: 6px 6px auto;
  z-index: 6;
  padding: 8px;
  background: #1d2b53;
  border: 2px solid #fff1e8;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.45);
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #fff1e8;
  user-select: text;
  -webkit-user-select: text;
}
.ask-title {
  color: #ffec27;
}
.ask textarea {
  display: block;
  width: 100%;
  margin: 6px 0;
  padding: 4px 6px;
  resize: none;
  background: #000;
  border: 1px solid #5f574f;
  border-radius: 0;
  color: #fff1e8;
  font-family: var(--pixel);
  font-size: 24px;
  line-height: 28px;
  outline: none;
}
.ask textarea:focus {
  border-color: #29adff;
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.chips button {
  padding: 1px 6px;
  border: 1px solid #29adff;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #29adff;
}
.ask-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 6px;
}
.ask-actions button {
  padding: 2px 10px;
  background: #fff1e8;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #000;
}
.ask-actions button[type="submit"] {
  background: #ffec27;
}

/* A like: a heart pops where the screen was double-tapped (or in the middle) */
.like-pop {
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  z-index: 6;
  font-family: var(--pixel);
  font-size: 48px;
  line-height: 1;
  color: #ff004d;
  text-shadow: 0 3px 0 #7e2553;
  pointer-events: none;
  animation: like-pop 700ms ease-out forwards;
}
.like-pop.off {
  color: #c2c3c7;
  text-shadow: 0 3px 0 #5f574f;
}
@keyframes like-pop {
  0% { transform: translate(-50%, -50%) scale(0.3); opacity: 0; }
  20% { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
  40% { transform: translate(-50%, -50%) scale(1); }
  100% { transform: translate(-50%, -90%) scale(1); opacity: 0; }
}

/* Pages on the screen: the author page and 我的, sliding in from the right */
.page {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  background: #0b0f1e;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #fff1e8;
  animation: page-in 180ms ease-out;
}
.page.out {
  animation: page-out 160ms ease-in forwards;
}
@keyframes page-in {
  from { transform: translateX(100%); }
}
@keyframes page-out {
  to { transform: translateX(100%); }
}
.page-inner {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}
.page-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px;
  background: #111d35;
  color: #c2c3c7;
}
.page-head .where {
  margin-left: auto;
  color: #fff1e8;
}
.page-head .close-hint {
  margin-left: auto;
  color: #5f574f;
}
.page-head .back {
  color: #29adff;
  cursor: pointer;
}
.profile {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
}
.avatar {
  flex: none;
  width: 40px;
  height: 40px;
  image-rendering: pixelated;
  outline: 2px solid #fff1e8;
}
.about {
  min-width: 0;
}
.about .name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.about .stats {
  color: #ffec27;
}
.about .bio {
  color: #83769c;
}
.page-tabs {
  display: flex;
  box-shadow: inset 0 -1px 0 #1d2b53;
}
.page-tabs span {
  flex: 1;
  padding: 2px 0 4px;
  text-align: center;
  color: #83769c;
}
.page-tabs span.on {
  color: #fff1e8;
  box-shadow: inset 0 -2px 0 #ff004d;
}
.page .grid {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-content: start;
  gap: 6px 4px;
  padding: 6px;
  scrollbar-width: none;
}
.page .grid::-webkit-scrollbar {
  display: none;
}
.tile {
  position: relative;
  min-width: 0;
  cursor: pointer;
}
.tile .thumb {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  image-rendering: pixelated;
  background: #000;
  outline: 1px solid #1d2b53;
}
.tile.selected .thumb {
  outline: 2px solid #ffec27;
}
.tile-title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #c2c3c7;
}
.tile.selected .tile-title {
  color: #ffec27;
}
.tile-like {
  position: absolute;
  top: 2px;
  right: 3px;
  color: #ff004d;
  text-shadow: 1px 1px 0 #000;
}
.tile-now {
  position: absolute;
  top: 2px;
  left: 2px;
  padding: 0 2px;
  background: #ff004d;
}
.page .empty {
  grid-column: 1 / -1;
  padding: 18px 6px;
  text-align: center;
  color: #83769c;
}
.page .rows {
  flex: 1;
  padding: 6px;
}
.page .row {
  position: relative;
  display: flex;
  gap: 8px;
  padding: 2px 0 2px 14px;
  cursor: pointer;
}
.page .row .what {
  flex: none;
  color: #c2c3c7;
}
.page .row .value {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.page .row.fixed .value {
  color: #83769c;
}
.page .row.selected::before {
  content: "▶";
  position: absolute;
  left: 0;
  color: #ffec27;
}
.page .row.selected .what {
  color: #ffec27;
}
.page-foot {
  padding: 3px 6px;
  text-align: center;
  color: #5f574f;
}

/* The Agent asking about the last play: a card at the bottom of the screen */
.asker {
  position: absolute;
  inset: auto 6px 6px;
  z-index: 5;
  font-family: var(--pixel);
  font-size: 12px;
  line-height: 15px;
  color: #fff1e8;
}
.ask-card {
  padding: 6px 8px;
  background: rgba(17, 29, 53, 0.96);
  border: 2px solid #ffec27;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.45);
  animation: drop-in 160ms ease-out;
}
.ask-card .who {
  margin-right: 6px;
  padding: 0 3px;
  background: #ff004d;
}
.ask-answers {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 6px 0 4px;
}
.ask-answers span {
  padding: 1px 6px;
  border: 1px solid #29adff;
  color: #29adff;
  cursor: pointer;
}
.ask-answers span.on {
  background: #ffec27;
  border-color: #ffec27;
  color: #000;
}
.ask-foot {
  color: #83769c;
}
.ask-foot .dismiss {
  cursor: pointer;
}
