:root {
  --shell-1: #d9d2c4;
  --shell-2: #b8ad95;
  --shell-3: #8e8472;
  --shell-dark: #6f6860;
  --shell-edge: #2b2318;
  --screen-frame-1: #2a2a2a;
  --screen-frame-2: #1a1a1a;
  --lcd-off: #8b956d;
  --lcd-bg: #9bbc0f;
  --text: #2b2318;
  --accent: #8b0000;
}
* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  color: #ddd;
  font-family: "Courier New", monospace;
}
html, body { overflow-x: hidden; }
body {
  min-height: 100vh;
  background: #000 url("skybg.webp") center center / cover no-repeat fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px 20px;
}

/* ============================================================
   Device shell
   ============================================================ */
.device {
  background: linear-gradient(180deg, var(--shell-1) 0%, var(--shell-2) 55%, var(--shell-3) 100%);
  border-radius: 14px 14px 64px 14px;
  padding: 28px 28px 40px 28px;
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,0.65),
    inset 0 -4px 0 rgba(0,0,0,0.35),
    inset 0 0 0 1px rgba(0,0,0,0.25),
    0 18px 40px rgba(0,0,0,0.35),
    0 0 120px rgba(139, 188, 15, 0.06);
  max-width: 400px;
  width: 100%;
  position: relative;
  overflow: hidden;
}
.device::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image:
    repeating-linear-gradient(135deg,
      rgba(0,0,0,0.025) 0, rgba(0,0,0,0.025) 1px,
      transparent 1px, transparent 3px);
  pointer-events: none;
  mix-blend-mode: multiply;
}

.brand {
  text-align: right;
  font-style: italic;
  font-weight: bold;
  color: var(--text);
  font-size: 13px;
  letter-spacing: 1px;
  margin-bottom: 12px;
  font-family: Georgia, serif;
  text-shadow: 0 1px 0 rgba(255,255,255,0.4);
  position: relative;
}
.brand span { color: var(--accent); }

/* ============================================================
   Volume dial — the only interactive hardware element
   ============================================================ */
.volume-dial {
  position: relative;
  width: 110px;
  user-select: none;
  flex-shrink: 0;
  padding: 14px 10px;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.10), rgba(0,0,0,0.02));
  border-radius: 6px;
  box-shadow:
    inset 0 2px 3px rgba(0,0,0,0.25),
    inset 0 -1px 0 rgba(255,255,255,0.45),
    inset 0 0 0 1px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.dial-knob {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  margin: 0 auto;
  cursor: pointer;
  background: radial-gradient(circle at 35% 30%, #777 0%, #3a3a3a 55%, #121212 100%);
  box-shadow:
    inset 0 2px 3px rgba(255,255,255,0.35),
    inset 0 -3px 6px rgba(0,0,0,0.75),
    0 2px 4px rgba(0,0,0,0.5),
    0 0 0 2px var(--shell-edge);
  position: relative;
  transform: rotate(-135deg);
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.dial-knob::before {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
      rgba(255,255,255,0.08) 0deg, rgba(255,255,255,0.08) 4deg,
      rgba(0,0,0,0.3) 4deg, rgba(0,0,0,0.3) 8deg);
  pointer-events: none;
}
.dial-knob::after {
  content: "";
  position: absolute;
  inset: 10px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #555, #1a1a1a 70%);
  box-shadow: inset 0 0 4px rgba(0,0,0,0.8);
}
.dial-indicator {
  position: absolute;
  top: 4px; left: 50%;
  width: 3px; height: 10px;
  margin-left: -1.5px;
  background: linear-gradient(180deg, #fff, #bbb);
  border-radius: 2px;
  box-shadow: 0 0 4px rgba(255,255,255,0.6);
  z-index: 2;
}
.dial-label {
  font-size: 9px;
  letter-spacing: 2px;
  font-weight: bold;
  color: var(--text);
  text-shadow: 0 1px 0 rgba(255,255,255,0.4);
}
.dial-ticks {
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 0 6px;
  pointer-events: none;
}
.dial-ticks .tick {
  font-size: 7px;
  letter-spacing: 1px;
  font-weight: bold;
  color: var(--text);
  opacity: 0.7;
  text-shadow: 0 1px 0 rgba(255,255,255,0.3);
}

/* ============================================================
   Screen frame + LCD
   ============================================================ */
.screen-frame {
  background: linear-gradient(180deg, var(--screen-frame-1), var(--screen-frame-2));
  border-radius: 10px 10px 40px 10px;
  padding: 32px 28px;
  position: relative;
  box-shadow:
    inset 0 2px 4px rgba(0,0,0,0.8),
    inset 0 0 30px rgba(0,0,0,0.6),
    0 2px 0 rgba(255,255,255,0.35);
}
.screen-label {
  position: absolute;
  top: 10px; left: 14px;
  color: var(--accent);
  font-size: 9px;
  letter-spacing: 3px;
  font-weight: bold;
  text-shadow: 0 0 4px rgba(139,0,0,0.5);
}
.screen-label.right { left: auto; right: 14px; color: #ddd; }
.power-led {
  position: absolute;
  top: 12px; right: 70px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #ff6666, #8b0000 60%, #3a0000);
  box-shadow: 0 0 8px rgba(255, 60, 60, 0.75), inset 0 0 2px rgba(255,255,255,0.4);
}
.lcd {
  /* Tamagotchi-style LCD: no inner green frame, canvas fills the pane */
  background: #a9b38a;   /* fallback when canvas isn't rendering yet */
  padding: 0;
  border-radius: 3px;
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,0.4),
    inset 0 2px 10px rgba(0,0,0,0.7),
    inset 0 0 40px rgba(0, 30, 0, 0.25);
  position: relative;
  overflow: hidden;
}
.lcd::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, transparent 75%, rgba(0,0,0,0.15) 100%),
    repeating-linear-gradient(to bottom,
      rgba(0,0,0,0.03) 0px, rgba(0,0,0,0.03) 1px,
      transparent 2px, transparent 4px);
  mix-blend-mode: multiply;
}
canvas {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: var(--lcd-bg);
}

/* ============================================================
   LCD "no cartridge" overlay
   ============================================================ */
.lcd-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  pointer-events: none;
  /* Tamagotchi olive-green LCD panel */
  background:
    radial-gradient(ellipse at 50% 40%, #b8c494 0%, #9fa979 70%, #8a9464 100%);
  color: #2e4a1a;    /* dark olive ink */
  font-family: "Courier New", monospace;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.25),
    0 -1px 0 rgba(0, 0, 0, 0.18);
  transition: opacity 0.4s ease;
  z-index: 2;
}
.lcd-overlay[hidden] { opacity: 0; pointer-events: none; display: flex; }
.lcd-msg-main, .lcd-msg-sub {
  animation: lcd-blink 1.4s ease-in-out infinite;
}
.lcd-msg-main {
  font-size: 18px;
  letter-spacing: 3px;
  font-weight: bold;
}
.lcd-msg-sub {
  font-size: 10px;
  letter-spacing: 2px;
}
@keyframes lcd-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* ============================================================
   Cartridge slot — bottom edge of device
   ============================================================ */
.cart-slot {
  position: relative;
  margin: 14px auto 0;
  width: 62%;
  height: 22px;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.6), rgba(0,0,0,0.25));
  border-radius: 4px;
  box-shadow:
    inset 0 2px 4px rgba(0,0,0,0.85),
    inset 0 -1px 0 rgba(255,255,255,0.3),
    0 1px 0 rgba(255,255,255,0.25);
  transition: box-shadow 0.2s ease;
}
.cart-slot-mouth {
  position: absolute;
  top: 4px; left: 8px; right: 8px; height: 6px;
  background: #0a0a0a;
  border-radius: 2px;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.95);
}
.cart-slot-label {
  position: absolute;
  left: 0; right: 0; bottom: -14px;
  text-align: center;
  font-size: 7px;
  letter-spacing: 3px;
  font-weight: bold;
  color: var(--text);
  opacity: 0.55;
  text-shadow: 0 1px 0 rgba(255,255,255,0.35);
}
.cart-slot.drop-active {
  box-shadow:
    inset 0 2px 4px rgba(0,0,0,0.85),
    inset 0 -1px 0 rgba(155,255,155,0.6),
    0 0 18px rgba(155, 255, 155, 0.75),
    0 0 32px rgba(100, 220, 100, 0.45);
}
/* Inserted-cart stub showing above slot (half of cart visible) */
.cart-slot.has-cart::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 40%;
  height: 12px;
  transform: translateX(-50%);
  background: linear-gradient(180deg, #7a7a7a, #4a4a4a 55%, #2a2a2a);
  border: 1px solid #1a1a1a;
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.3);
}

/* ============================================================
   Cartridge tray — slides up from the bottom of the viewport
   ============================================================ */
.cart-tray-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
  z-index: 900;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.cart-tray-backdrop[hidden] { display: none; }
.cart-tray-backdrop.show { opacity: 1; }

.cart-tray {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translate(-50%, 100%);
  width: 100%;
  max-width: 560px;
  padding: 14px 16px 28px;
  background:
    linear-gradient(180deg, rgba(40,40,40,0.97), rgba(20,20,20,0.97));
  border-top: 1px solid #1a1a1a;
  border-radius: 16px 16px 0 0;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.08),
    0 -10px 40px rgba(0,0,0,0.75);
  text-align: center;
  color: #ddd;
  font-family: "Courier New", monospace;
  z-index: 950;
  transition: transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.cart-tray[hidden] { display: block !important; }  /* keep in flow for transition */
.cart-tray.show { transform: translate(-50%, 0); }
/* While the user is dragging, make the backdrop click-through so the
   device slot above is reachable. We DO NOT move the tray itself, or the
   browser's HTML5 drag session (which started inside the tray) breaks. */
.cart-tray-backdrop.dragging-out {
  opacity: 0;
  pointer-events: none;
}
.cart-tray.dragging-out {
  /* fade a bit but stay in place, and pass clicks through the frame */
  opacity: 0.35;
  pointer-events: none;
}
.cart-tray.dragging-out .cart { pointer-events: auto; }

.cart-tray-handle {
  position: relative;
  height: 14px;
  margin-bottom: 8px;
}
.cart-tray-handle-bar {
  width: 48px;
  height: 4px;
  margin: 4px auto 0;
  background: rgba(255,255,255,0.35);
  border-radius: 2px;
}
.cart-tray-close {
  position: absolute;
  top: -2px; right: 0;
  width: 22px; height: 22px;
  background: none;
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 50%;
  color: #ddd;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
}
.cart-tray-close:hover { background: rgba(255,255,255,0.1); }
.cart-tray-title {
  font-size: 10px;
  letter-spacing: 4px;
  font-weight: bold;
  margin-bottom: 12px;
  opacity: 0.85;
}
.cart-tray-cards {
  display: flex;
  gap: 14px;
  justify-content: center;
  flex-wrap: wrap;
}
.cart-tray-hint {
  margin-top: 12px;
  font-size: 9px;
  letter-spacing: 2px;
  opacity: 0.6;
}

/* --- Individual cartridge --- */
.cart {
  width: 110px;
  height: 130px;
  background:
    linear-gradient(180deg, #8d8d8d 0%, #6a6a6a 40%, #4a4a4a 100%);
  border: 1px solid #1a1a1a;
  border-radius: 3px 3px 8px 8px / 3px 3px 4px 4px;
  position: relative;
  cursor: grab;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.4),
    inset 0 -3px 0 rgba(0,0,0,0.4),
    0 4px 8px rgba(0,0,0,0.5);
  user-select: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.2s ease;
}
.cart:active { cursor: grabbing; }
.cart:hover {
  transform: translateY(-4px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.5),
    inset 0 -3px 0 rgba(0,0,0,0.4),
    0 8px 14px rgba(0,0,0,0.6);
}
.cart.dragging {
  opacity: 0.45;
  cursor: grabbing;
}
.cart.inserted {
  pointer-events: none;
  opacity: 0.3;
  filter: grayscale(0.5);
}
/* little tab at the top (like real GB carts) */
.cart-top {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 16px;
  background: linear-gradient(180deg, #6a6a6a, #3a3a3a);
  border-bottom: 1px solid #1a1a1a;
  border-radius: 2px 2px 0 0;
}
.cart-top::before {
  /* notch */
  content: "";
  position: absolute;
  top: 4px; left: 50%;
  transform: translateX(-50%);
  width: 36%;
  height: 6px;
  background: #1a1a1a;
  border-radius: 2px;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.9);
}
.cart-label {
  position: absolute;
  top: 24px; left: 8px; right: 8px; bottom: 24px;
  background: linear-gradient(180deg, #f4ecd8, #d9cfae);
  border: 1px solid #6a5a3a;
  border-radius: 2px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.6);
  padding: 8px 6px;
  text-align: center;
  color: #2b2318;
}
.cart-label-title {
  font-size: 11px;
  font-weight: bold;
  letter-spacing: 1px;
  font-family: Georgia, serif;
}
.cart-label-sub {
  margin-top: 4px;
  font-size: 7px;
  letter-spacing: 2px;
  opacity: 0.7;
}
.cart-label-pip {
  position: absolute;
  bottom: 6px; left: 50%;
  transform: translateX(-50%);
  width: 10px; height: 10px;
  border-radius: 50%;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.4), 0 0 4px currentColor;
}
.pip-red { background: #c94a2a; color: rgba(255, 100, 50, 0.5); }
.pip-blue { background: #2a6ac9; color: rgba(80, 160, 255, 0.55); }
.cart-id {
  position: absolute;
  bottom: 4px; left: 0; right: 0;
  text-align: center;
  font-size: 6px;
  letter-spacing: 2px;
  color: rgba(255,255,255,0.55);
}

/* Drag ghost hint when over the slot */
.cart.flying-in {
  animation: cart-insert 0.45s cubic-bezier(0.55, 0.1, 0.4, 1.1) forwards;
}
@keyframes cart-insert {
  0%   { transform: translateY(-60px) scale(1); opacity: 1; }
  60%  { transform: translateY(-10px) scale(0.95); opacity: 1; }
  100% { transform: translateY(10px) scale(0.9); opacity: 0; }
}

/* ============================================================
   Status + upload
   ============================================================ */
.status {
  font-size: 11px;
  color: var(--text);
  text-align: center;
  margin-top: 14px;
  padding: 6px;
  background: rgba(0,0,0,0.08);
  border-radius: 3px;
  min-height: 18px;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.25);
}
.upload {
  margin-top: 12px;
  display: flex;
  justify-content: center;
  gap: 10px;
}
.file-btn { display: inline-block; position: relative; overflow: hidden; cursor: pointer; }
.file-btn input[type=file] { position: absolute; inset: 0; opacity: 0; cursor: pointer; font-size: 0; }
.file-btn span, .metal-btn {
  display: inline-block;
  font-family: "Courier New", monospace;
  font-size: 10px;
  letter-spacing: 2px;
  font-weight: bold;
  padding: 6px 14px;
  color: #1a1a1a;
  background: linear-gradient(180deg, #e8e8e8, #a8a8a8 55%, #707070);
  border: 1px solid #3a3a3a;
  border-radius: 3px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.7), inset 0 -1px 0 rgba(0,0,0,0.3), 0 2px 3px rgba(0,0,0,0.4);
  cursor: pointer;
  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
}
.metal-btn {
  background: linear-gradient(180deg, #c8b0b0, #8b2a2a 55%, #5a1515);
  color: #fff;
  text-shadow: 0 1px 0 rgba(0,0,0,0.5);
}
.chain-btn {
  display: inline-block;
  position: relative;
  font-family: "Courier New", monospace;
  font-size: 10px;
  letter-spacing: 2px;
  font-weight: bold;
  padding: 6px 12px;
  color: #fff;
  background: linear-gradient(180deg, #8fd79b, #3e8050 55%, #1f4a2c);
  border: 1px solid #1a2a1a;
  border-radius: 3px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), inset 0 -1px 0 rgba(0,0,0,0.35), 0 2px 3px rgba(0,0,0,0.4);
  cursor: pointer;
  text-shadow: 0 1px 0 rgba(0,0,0,0.4);
}
.cart-btn {
  background: linear-gradient(180deg, #9fb8e8, #3e5680 55%, #1f2e4a);
  border-color: #1a1a2a;
}
.dirty-badge {
  display: inline-block;
  margin-left: 6px;
  color: #ffd26b;
  font-size: 13px;
  line-height: 1;
  text-shadow: 0 0 8px rgba(255, 210, 107, 0.9), 0 0 14px rgba(255, 180, 40, 0.5);
  animation: dirty-blink 1.1s ease-in-out infinite;
}
.dirty-badge[hidden] { display: none; }
@keyframes dirty-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.file-btn:active span, .metal-btn:active, .chain-btn:active {
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.5);
  transform: translateY(1px);
}
/* ============================================================
   Onchain Save Center — retro modal
   ============================================================ */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
  backdrop-filter: blur(2px);
}
.modal-backdrop[hidden] { display: none; }

.modal-window {
  width: 100%;
  max-width: 480px;
  background: linear-gradient(180deg, #d9d2c4, #b8ad95);
  border: 2px solid #1a1a1a;
  border-radius: 4px;
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,0.7),
    inset 0 -3px 0 rgba(0,0,0,0.3),
    0 0 0 1px #3a3a3a,
    4px 4px 0 rgba(0,0,0,0.5),
    0 20px 60px rgba(0,0,0,0.8);
  font-family: "Courier New", monospace;
  color: #1a1a1a;
}
.modal-titlebar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 8px;
  background: linear-gradient(90deg, #000080, #1a4aa0 40%, #002060);
  color: #fff;
  border-bottom: 2px solid #1a1a1a;
}
.modal-title {
  font-size: 11px;
  font-weight: bold;
  letter-spacing: 2px;
  text-shadow: 1px 1px 0 #000;
}
.modal-close {
  width: 20px; height: 18px;
  font-family: inherit;
  font-size: 10px;
  font-weight: bold;
  color: #1a1a1a;
  background: linear-gradient(180deg, #f0f0f0, #a0a0a0);
  border: 1px solid #1a1a1a;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.7), inset 0 -1px 0 rgba(0,0,0,0.3);
}
.modal-close:active { box-shadow: inset 0 2px 2px rgba(0,0,0,0.4); }
.modal-body {
  padding: 14px;
}
.modal-view { display: flex; flex-direction: column; gap: 12px; }
.modal-view[hidden] { display: none; }

.connect-hero {
  padding: 20px 12px 16px;
  text-align: center;
  background: rgba(0,0,0,0.08);
  border-radius: 3px;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.25), inset 0 -1px 0 rgba(255,255,255,0.3);
}
.connect-icon {
  font-size: 38px;
  line-height: 1;
  margin-bottom: 10px;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.4));
}
.connect-title {
  font-size: 12px;
  letter-spacing: 3px;
  font-weight: bold;
  color: #1a1a1a;
  margin-bottom: 8px;
  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
}
.connect-desc {
  font-size: 10px;
  letter-spacing: 0.5px;
  line-height: 1.6;
  color: rgba(43, 35, 24, 0.8);
  padding: 0 6px;
}
.connect-btn {
  padding: 10px 16px !important;
  font-size: 12px !important;
  letter-spacing: 3px !important;
}
.connect-hint {
  text-align: center;
  font-size: 9px;
  letter-spacing: 1px;
  color: rgba(43, 35, 24, 0.6);
  text-shadow: 0 1px 0 rgba(255,255,255,0.4);
}

.dirty-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: linear-gradient(180deg, #fff3c4, #f4d46a 60%, #c9a22b);
  border: 1px solid #6a4a0a;
  border-radius: 3px;
  color: #3a2a00;
  font-size: 10px;
  letter-spacing: 1px;
  font-weight: bold;
  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.55), inset 0 -1px 0 rgba(0,0,0,0.25);
  animation: banner-glow 2s ease-in-out infinite;
}
.dirty-banner[hidden] { display: none; }
.dirty-banner .dirty-dot {
  color: #c94a2a;
  font-size: 14px;
  line-height: 1;
  text-shadow: 0 0 6px rgba(255, 100, 50, 0.8);
}
@keyframes banner-glow {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,0.55), inset 0 -1px 0 rgba(0,0,0,0.25), 0 0 0 rgba(255, 210, 107, 0); }
  50%      { box-shadow: inset 0 1px 0 rgba(255,255,255,0.55), inset 0 -1px 0 rgba(0,0,0,0.25), 0 0 12px rgba(255, 210, 107, 0.55); }
}
.modal-v.dirty-on {
  color: #8a5a00;
  font-weight: bold;
}
.modal-section {
  padding: 10px;
  background: rgba(0,0,0,0.08);
  border-radius: 3px;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.25), inset 0 -1px 0 rgba(255,255,255,0.3);
}
.modal-row, .progress-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 10px;
  letter-spacing: 1px;
  padding: 3px 0;
}
.modal-k {
  color: rgba(43, 35, 24, 0.7);
  font-weight: bold;
}
.modal-v {
  color: #1a1a1a;
  font-family: "Courier New", monospace;
  font-weight: bold;
  max-width: 65%;
  text-align: right;
  word-break: break-all;
}
.modal-actions {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  background: none;
  box-shadow: none;
  padding: 0;
}
.modal-actions .chain-btn { flex: 1; }
.modal-actions .chain-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: grayscale(0.5);
}

.progress-bar {
  margin-top: 8px;
  height: 14px;
  background: #1a1a1a;
  border-radius: 2px;
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.8);
  overflow: hidden;
  position: relative;
}
.progress-fill {
  height: 100%;
  width: 0%;
  background:
    repeating-linear-gradient(90deg,
      #9bff9b 0px, #9bff9b 4px,
      #6bdf6b 4px, #6bdf6b 8px);
  box-shadow: 0 0 8px rgba(155, 255, 155, 0.7), inset 0 1px 0 rgba(255,255,255,0.3);
  transition: width 0.2s ease;
}

.modal-log {
  max-height: 140px;
  overflow-y: auto;
  padding: 8px 10px;
  background: #0a0a0a;
  color: #9bff9b;
  font-family: "Courier New", monospace;
  font-size: 10px;
  line-height: 1.5;
  border-radius: 3px;
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.9);
  border: 1px solid #000;
  white-space: pre-wrap;
}
.modal-log .log-line { padding: 1px 0; }
.modal-log .log-err { color: #ff6b6b; }
.modal-log .log-ok  { color: #9bff9b; }
.modal-log .log-info { color: #c8c8c8; }

/* ============================================================
   Engraved control legend — keyboard only, no buttons
   Effect: text looks debossed into the plastic shell
   ============================================================ */
/* Panel row: legend (left) + volume dial (right) */
.panel {
  margin-top: 22px;
  display: flex;
  align-items: stretch;
  gap: 16px;
}
.legend {
  flex: 1;
  padding: 14px 18px;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.10), rgba(0,0,0,0.02));
  border-radius: 6px;
  box-shadow:
    inset 0 2px 3px rgba(0,0,0,0.25),
    inset 0 -1px 0 rgba(255,255,255,0.45),
    inset 0 0 0 1px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  justify-content: center;
}
.legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
}
.legend-label {
  font-size: 10px;
  letter-spacing: 2px;
  font-weight: bold;
  color: rgba(43, 35, 24, 0.85);
  /* debossed text: dark color + light bottom highlight */
  text-shadow:
    0 1px 0 rgba(255,255,255,0.5),
    0 -1px 0 rgba(0,0,0,0.15);
}
.legend-sep {
  color: rgba(43, 35, 24, 0.35);
  font-size: 12px;
  padding: 0 2px;
  text-shadow: 0 1px 0 rgba(255,255,255,0.4);
}
/* A key-cap with its label stacked vertically below (for START/SELECT) */
.key-pair {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 0 10px;
}
.key-pair .legend-label {
  font-size: 9px;
  letter-spacing: 2px;
}

/* key caps: raised plastic, tiny */
.key-cap {
  display: inline-block;
  min-width: 20px;
  padding: 2px 7px;
  font-family: "Courier New", monospace;
  font-size: 10px;
  font-weight: bold;
  letter-spacing: 0.5px;
  text-align: center;
  color: #2b2318;
  background: linear-gradient(180deg, #f5efe0, #cfc6af 55%, #9f977f);
  border: 1px solid rgba(0,0,0,0.3);
  border-radius: 3px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.8),
    inset 0 -1px 0 rgba(0,0,0,0.25),
    0 1px 2px rgba(0,0,0,0.25);
  text-shadow: 0 1px 0 rgba(255,255,255,0.55);
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 500px) {
  .device { padding: 18px 18px 28px 18px; }
  .panel { flex-direction: column; }
  .volume-dial { width: 100%; padding: 12px; }
  .dial-knob { width: 48px; height: 48px; }
  .legend { padding: 10px 12px; }
  .legend-row { gap: 6px; }
  .legend-label, .key-cap { font-size: 9px; }
}

/* ============================================================
   TV banner — "on-chain source" CRT link above the device
   ============================================================ */
.tv-banner {
  display: block;
  width: 260px;
  margin: 0 auto 24px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.15s ease;
}
.tv-banner:hover { transform: translateY(-2px); }
.tv-banner:active { transform: translateY(0); }

/* outer plastic casing — matches the Game Boy shell palette */
.tv-body {
  position: relative;
  padding: 10px 12px 14px;
  background: linear-gradient(180deg, var(--shell-1) 0%, var(--shell-2) 55%, var(--shell-3) 100%);
  border-radius: 10px 10px 14px 14px;
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,0.55),
    inset 0 -3px 0 rgba(0,0,0,0.32),
    inset 0 0 0 1px rgba(0,0,0,0.25),
    0 8px 18px rgba(0,0,0,0.55);
}
/* two stubby feet underneath */
.tv-body::after {
  content: "";
  position: absolute;
  bottom: -4px; left: 15%; right: 15%;
  height: 4px;
  background: linear-gradient(180deg, var(--shell-3), #5a5245);
  border-radius: 0 0 6px 6px;
}

/* CRT screen — deep inset black with green phosphor text */
.tv-screen {
  position: relative;
  height: 58px;
  background: radial-gradient(ellipse at center, #0d1a0d 0%, #050a05 85%);
  border-radius: 4px;
  box-shadow:
    inset 0 2px 5px rgba(0,0,0,0.95),
    inset 0 0 20px rgba(0,0,0,0.8),
    inset 0 0 0 1px rgba(0,0,0,0.6),
    0 1px 0 rgba(255,255,255,0.35);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-family: "Courier New", monospace;
  color: #9bff9b;
  text-shadow: 0 0 6px rgba(155,255,155,0.9), 0 0 2px rgba(255,255,255,0.35);
  letter-spacing: 2px;
}
/* scanlines + subtle vignette */
.tv-screen::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom,
      rgba(0,0,0,0.35) 0px, rgba(0,0,0,0.35) 1px,
      transparent 2px, transparent 3px),
    radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,0.55) 100%);
  mix-blend-mode: multiply;
  animation: tv-flicker 6s linear infinite;
}
@keyframes tv-flicker {
  0%, 96%, 100% { opacity: 1; }
  97% { opacity: 0.85; }
  98% { opacity: 1; }
}

.tv-line-1 {
  font-size: 11px;
  font-weight: bold;
}
.tv-line-2 {
  font-size: 9px;
  opacity: 0.85;
}

/* REC dot top-left */
.tv-rec {
  position: absolute;
  top: 5px; left: 8px;
  font-size: 10px;
  color: #ff4545;
  text-shadow: 0 0 6px rgba(255,70,70,0.95), 0 0 2px rgba(255,255,255,0.3);
  animation: tv-rec-blink 1.5s ease-in-out infinite;
}
@keyframes tv-rec-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@media (max-width: 500px) {
  .tv-banner { width: 220px; margin-bottom: 18px; }
  .tv-screen { height: 50px; }
  .tv-line-1 { font-size: 10px; }
  .tv-line-2 { font-size: 8px; }
}

/* Page stack: TV banner sits centered above the device */
.page-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* LCD overlay + TV banner use the monospace stack — avoids shipping a
   heavy webfont; Courier New / system monospace is already retro enough */
.lcd-msg-main, .lcd-msg-sub,
.tv-line-1, .tv-line-2 {
  font-family: "Courier New", monospace;
}

/* ============================================================
   Touch gamepad — mobile only
   ============================================================ */
.touchpad {
  display: none;                 /* hidden on desktop */
  flex: 1;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 8px 6px;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* cross-shaped D-pad using CSS only */
.tp-dpad {
  position: relative;
  width: 150px;
  height: 150px;
}
.tp-dpad-btn {
  position: absolute;
  background: linear-gradient(180deg, #2a2a2a, #0a0a0a);
  box-shadow:
    inset 0 2px 2px rgba(255,255,255,0.12),
    inset 0 -2px 2px rgba(0,0,0,0.65),
    0 3px 4px rgba(0,0,0,0.55);
  cursor: pointer;
}
.tp-dpad-btn.pressed {
  background: linear-gradient(180deg, #4a4a4a, #1f1f1f);
  box-shadow: inset 0 3px 5px rgba(0,0,0,0.75), 0 0 14px rgba(155, 255, 155, 0.7);
}
.tp-up    { top: 0;        left: 34%; width: 32%; height: 36%; border-radius: 10px 10px 0 0; }
.tp-down  { bottom: 0;     left: 34%; width: 32%; height: 36%; border-radius: 0 0 10px 10px; }
.tp-left  { left: 0;       top: 34%;  width: 36%; height: 32%; border-radius: 10px 0 0 10px; }
.tp-right { right: 0;      top: 34%;  width: 36%; height: 32%; border-radius: 0 10px 10px 0; }
.tp-dpad-center {
  position: absolute;
  left: 34%; top: 34%;
  width: 32%; height: 32%;
  background: linear-gradient(180deg, #2a2a2a, #0a0a0a);
  box-shadow: inset 0 0 4px rgba(0,0,0,0.9);
  pointer-events: none;
}

/* A / B big red circles */
.tp-ab {
  display: flex;
  gap: 22px;
  align-items: center;
  transform: rotate(-20deg);
}
.tp-btn {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #d55a5a 0%, #9b2a2a 55%, #5a1515 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-family: Georgia, serif;
  font-size: 28px;
  font-weight: bold;
  text-shadow: 0 2px 3px rgba(0,0,0,0.6);
  box-shadow:
    inset 0 2px 2px rgba(255,255,255,0.3),
    inset 0 -3px 4px rgba(0,0,0,0.6),
    0 4px 6px rgba(0,0,0,0.5),
    0 0 0 4px rgba(0,0,0,0.18);
  cursor: pointer;
}
.tp-btn span { transform: rotate(20deg); }
.tp-btn.pressed {
  transform: translateY(3px);
  box-shadow: inset 0 3px 6px rgba(0,0,0,0.7), 0 0 18px rgba(155, 255, 155, 0.7);
}

/* Start / Select pill buttons */
.tp-startsel {
  display: flex;
  gap: 22px;
  transform: rotate(-20deg);
}
.tp-pill {
  min-width: 78px;
  padding: 8px 14px;
  border-radius: 14px;
  background: linear-gradient(180deg, #888, #3a3a3a 55%, #1a1a1a);
  color: #eaeaea;
  font-family: "Courier New", monospace;
  font-size: 11px;
  font-weight: bold;
  letter-spacing: 2px;
  text-align: center;
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.3),
    inset 0 -1px 1px rgba(0,0,0,0.6),
    0 3px 4px rgba(0,0,0,0.5);
  cursor: pointer;
}
.tp-pill span { display: inline-block; transform: rotate(20deg); }
.tp-pill.pressed {
  transform: translateY(2px);
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.75), 0 0 12px rgba(155,255,155,0.7);
}

/* ============================================================
   Mobile layout (≤ 640px)
   ============================================================ */
@media (max-width: 640px) {
  body { padding: 10px; }

  /* Bigger device on phones — take nearly full viewport width */
  .device {
    max-width: 100%;
    padding: 18px 18px 24px;
    border-radius: 12px 12px 40px 12px;
  }

  .tv-banner { width: 72%; max-width: 320px; margin-bottom: 16px; }
  .tv-screen { height: 64px; }
  .tv-line-1 { font-size: 13px; }
  .tv-line-2 { font-size: 11px; }

  .lcd-msg-main { font-size: 22px; }
  .lcd-msg-sub  { font-size: 12px; }

  .screen-frame { padding: 30px 22px 26px; }

  /* Swap key-legend for actual touch pad */
  .panel { flex-direction: column; gap: 20px; align-items: stretch; }
  .legend { display: none; }
  .touchpad { display: flex; }
  .volume-dial { align-self: center; width: 140px; }
  .dial-knob { width: 64px; height: 64px; }

  /* Bigger chain buttons */
  .upload { flex-wrap: wrap; gap: 8px; }
  .chain-btn, .metal-btn, .file-btn span {
    font-size: 12px;
    padding: 10px 14px;
  }

  /* Bigger cart tray + cards when it slides up */
  .cart-tray { padding: 18px 16px 34px; }
  .cart-tray-title { font-size: 13px; letter-spacing: 3px; margin-bottom: 16px; }
  .cart-tray-cards { gap: 18px; }
  .cart { width: 132px; height: 156px; }
  .cart-label-title { font-size: 13px; }
  .cart-label-sub { font-size: 8px; }
  .cart-tray-hint { font-size: 11px; }

  /* Modal sizing */
  .modal-window { max-width: 95vw; }
  .modal-title { font-size: 12px; }
  .modal-row, .progress-row { font-size: 11px; }
  .connect-title { font-size: 14px; }
  .connect-desc { font-size: 12px; }
}

/* ============================================================
   Mobile overrides v2 — make the device fill the viewport and
   stop vertical centering so the page flows naturally top→bottom
   ============================================================ */
@media (max-width: 760px) {
  body {
    /* Top-aligned flow rather than vertical-centered, so the banner
       + device fill the upper screen without a huge gap above */
    align-items: flex-start;
    padding: 12px 8px 40px;
  }
  .page-stack { width: 100%; }

  .device {
    max-width: 100%;
    width: 100%;
    padding: 22px 18px 30px;
    border-radius: 14px 14px 48px 14px;
  }

  .tv-banner {
    width: 80%;
    max-width: 360px;
    margin: 0 auto 20px;
  }
  .tv-screen { height: 70px; }
  .tv-line-1 { font-size: 15px; }
  .tv-line-2 { font-size: 12px; }

  .screen-frame { padding: 34px 22px 28px; }
  canvas { width: 100%; }

  .lcd-msg-main { font-size: 24px; letter-spacing: 3px; }
  .lcd-msg-sub  { font-size: 13px; letter-spacing: 1.5px; }

  /* Control panel: stack vertically, hide key legend, show touchpad */
  .panel {
    flex-direction: column;
    gap: 22px;
    align-items: stretch;
    margin-top: 28px;
  }
  .legend { display: none; }
  .touchpad { display: flex; width: 100%; }

  /* Make touch targets larger than the default on phones */
  .tp-dpad { width: 180px; height: 180px; }
  .tp-btn  { width: 84px;  height: 84px; font-size: 30px; }
  .tp-pill { min-width: 96px; padding: 10px 16px; font-size: 13px; }

  .volume-dial {
    align-self: center;
    width: 150px;
    padding: 16px 12px;
  }
  .dial-knob { width: 70px; height: 70px; }
  .dial-label { font-size: 11px; }

  /* Action buttons bigger & more tappable */
  .upload {
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
  }
  .chain-btn, .metal-btn, .file-btn span {
    font-size: 12px;
    padding: 12px 16px;
    letter-spacing: 1.5px;
  }

  /* Cart tray sized for touch */
  .cart-tray {
    max-width: 100%;
    padding: 18px 14px 32px;
    border-radius: 18px 18px 0 0;
  }
  .cart-tray-title { font-size: 13px; letter-spacing: 3px; margin-bottom: 16px; }
  .cart-tray-cards { gap: 22px; }
  .cart { width: 140px; height: 166px; }
  .cart-label-title { font-size: 14px; }
  .cart-label-sub { font-size: 9px; }
  .cart-tray-hint { font-size: 11px; }

  /* Save Center modal */
  .modal-window { max-width: 94vw; }
  .modal-title { font-size: 12px; }
  .modal-row, .progress-row { font-size: 11px; }
  .connect-title { font-size: 14px; }
  .connect-desc { font-size: 12px; line-height: 1.5; }
  .modal-log { font-size: 11px; max-height: 120px; }
}

/* ============================================================
   Mobile overrides v3 — tighter spacing, smaller touchpad so the
   whole device fits the viewport; banner stays visible.
   ============================================================ */
@media (max-width: 760px) {
  body {
    align-items: flex-start;
    padding: 8px;
    min-height: auto;   /* stop forcing 100vh floor */
  }
  .page-stack { gap: 0; }

  .tv-banner { width: 70%; max-width: 300px; margin: 0 auto 12px; }
  .tv-screen { height: 54px; }
  .tv-line-1 { font-size: 13px; }
  .tv-line-2 { font-size: 10px; }

  .device { padding: 14px 14px 20px; border-radius: 12px 12px 40px 12px; }

  /* Keep the LCD compact — the screen frame was eating the top half
     of the page. Cap canvas height so the device proportions match
     a real DMG. */
  .screen-frame { padding: 26px 18px 20px; }
  .lcd { padding: 4px; }
  canvas {
    width: 100%;
    max-height: 45vh;      /* never dominate the layout */
    object-fit: contain;
  }
  .lcd-msg-main { font-size: 20px; }
  .lcd-msg-sub  { font-size: 11px; }

  .cart-slot { margin-top: 8px; }
  .status { font-size: 10px; margin-top: 8px; padding: 4px; }

  .upload { flex-wrap: wrap; gap: 8px; margin-top: 10px; justify-content: center; }
  .chain-btn, .metal-btn, .file-btn span {
    font-size: 11px;
    padding: 8px 12px;
    letter-spacing: 1px;
  }

  .panel { flex-direction: column; gap: 14px; margin-top: 14px; align-items: center; }
  .legend { display: none; }
  .touchpad { display: flex; gap: 10px; }

  /* Scale down the touchpad so A/B + D-pad actually fit on the screen
     together with the LCD + buttons above */
  .tp-dpad { width: 130px; height: 130px; }
  .tp-btn  { width: 62px; height: 62px; font-size: 24px; }
  .tp-pill { min-width: 72px; padding: 7px 12px; font-size: 11px; }

  .volume-dial { width: 120px; padding: 10px 8px; }
  .dial-knob { width: 56px; height: 56px; }
  .dial-label { font-size: 9px; }

  .cart-tray { max-width: 100%; padding: 14px 12px 28px; border-radius: 16px 16px 0 0; }
  .cart { width: 118px; height: 140px; }
  .cart-label-title { font-size: 12px; }
  .cart-label-sub { font-size: 8px; }

  .modal-window { max-width: 94vw; }
}

/* Extra-small phones (≤ 400px): shrink one notch more */
@media (max-width: 400px) {
  .tp-dpad { width: 110px; height: 110px; }
  .tp-btn  { width: 54px; height: 54px; font-size: 20px; }
  .tp-pill { min-width: 64px; padding: 6px 10px; font-size: 10px; }
  canvas { max-height: 40vh; }
  .upload { gap: 6px; }
  .chain-btn, .metal-btn { font-size: 10px; padding: 7px 10px; }
}

/* ============================================================
   Mobile overrides v4 — real DMG proportions
   Layout on phone:
     [ TV banner ]
     [ LCD ]
     [ cart slot ]
     [ status ]
     [ CART | SAVE | RESET ]  (single row, compact)
     [ D-PAD  ----  A B ]    (side by side, like a real GB)
     [    SELECT    START   ]
     [       VOLUME         ]
   ============================================================ */
@media (max-width: 760px) {
  /* Top action buttons: single compact row */
  .upload {
    flex-wrap: nowrap;
    gap: 6px;
    margin-top: 10px;
    justify-content: center;
  }
  .upload > * {
    flex: 0 1 auto;
    font-size: 10px;
    padding: 8px 10px;
    letter-spacing: 1px;
    white-space: nowrap;
  }
  /* Trim the main save-center button text to fit */
  #open-save-center { font-size: 10px; }

  /* Control panel = pad (dpad+AB) + startsel + volume, stacked */
  .panel {
    flex-direction: column;
    gap: 18px;
    margin-top: 18px;
    align-items: stretch;
  }
  .legend { display: none; }

  /* Touchpad: DPAD on the left, A/B on the right — like a real GB */
  .touchpad {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    column-gap: 8px;
    row-gap: 18px;
    align-items: center;
    width: 100%;
  }
  .tp-dpad {
    grid-column: 1;
    grid-row: 1;
    justify-self: center;
    width: 130px; height: 130px;
  }
  .tp-ab {
    grid-column: 2;
    grid-row: 1;
    justify-self: center;
  }
  .tp-startsel {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: center;
  }

  /* Volume dial centered below */
  .volume-dial {
    align-self: center;
    width: 130px;
    padding: 10px 8px;
  }
}

/* Extra small phones (≤ 400px): shrink a notch more */
@media (max-width: 400px) {
  #open-save-center { font-size: 9px; padding: 7px 8px; }
  #open-cart-tray  { font-size: 9px; padding: 7px 8px; }
  #reset           { font-size: 9px; padding: 7px 8px; }

  .tp-dpad { width: 116px; height: 116px; }
  .tp-btn  { width: 54px; height: 54px; font-size: 20px; }
  .tp-pill { min-width: 62px; padding: 6px 10px; font-size: 10px; }
  .touchpad { column-gap: 4px; }
}

/* ============================================================
   Mobile overrides v5 — keep the desktop layout proportions,
   just scale the whole device to fit the viewport. This avoids
   the "tall skinny stretched" look that comes from stretching
   each element to full width on a narrow screen.
   ============================================================ */
@media (max-width: 760px) {
  body {
    align-items: flex-start;
    padding: 8px 0;
    min-height: auto;
  }

  .page-stack {
    /* Render at a natural 400px width, then scale-to-fit */
    width: 400px;
    transform-origin: top center;
    transform: scale(min(1, calc(100vw / 420px)));
  }

  /* Undo the full-width stretching from v3/v4 — use desktop sizes */
  .device {
    max-width: 400px;
    width: 400px;
    padding: 28px 28px 40px;
    border-radius: 14px 14px 64px 14px;
  }

  .tv-banner { width: 260px; margin: 0 auto 24px; }
  .tv-screen { height: 58px; }
  .tv-line-1 { font-size: 11px; }
  .tv-line-2 { font-size: 9px; }

  .screen-frame { padding: 32px 28px; }
  canvas { max-height: none; width: 100%; }

  .lcd-msg-main { font-size: 18px; }
  .lcd-msg-sub  { font-size: 10px; }

  .upload { flex-wrap: nowrap; gap: 8px; margin-top: 12px; justify-content: center; }
  .upload > * { font-size: 10px; padding: 6px 12px; white-space: nowrap; }

  .panel {
    flex-direction: row;
    gap: 16px;
    align-items: stretch;
    margin-top: 22px;
  }
  .legend { display: flex; flex: 1; }
  .touchpad { display: none; }   /* hide touchpad when scaled — dpad/AB not useful on scaled device */
  .volume-dial {
    width: 110px;
    align-self: stretch;
    padding: 14px 10px;
  }
  .dial-knob { width: 56px; height: 56px; }
  .dial-label { font-size: 9px; }

  .cart-tray { max-width: 100%; padding: 18px 16px 32px; border-radius: 16px 16px 0 0; }
}

/* Touchpad shown only on phones that aren't scaled (truly small) — but
   since we scale, we never show it. Instead the legend renders with keycaps
   as a visual reminder. If you want a real touch pad, we need to NOT scale
   the device and redesign — keeping scale for now. */

/* Very small phones: allow smaller scale floor */
@media (max-width: 400px) {
  .page-stack {
    transform: scale(min(1, calc((100vw - 16px) / 420px)));
  }
}

/* ============================================================
   Mobile overrides v6 — keep elements full-width (no transform
   scale tricks), just rearrange + hide what doesn't work on phone.
   Desktop is untouched.
   ============================================================ */
@media (max-width: 760px) {
  /* Undo scale() from previous attempt */
  .page-stack { width: 100%; transform: none; }

  body {
    align-items: flex-start;
    padding: 8px;
    min-height: auto;
  }

  .device {
    width: 100%;
    max-width: 100%;
    padding: 14px 14px 20px;
    border-radius: 12px 12px 40px 12px;
  }

  .tv-banner { width: 72%; max-width: 300px; margin: 0 auto 12px; }
  .tv-screen { height: 56px; }
  .tv-line-1 { font-size: 12px; }
  .tv-line-2 { font-size: 10px; }

  .screen-frame { padding: 26px 18px 20px; }
  canvas { width: 100%; max-height: 40vh; object-fit: contain; }
  .lcd-msg-main { font-size: 20px; }
  .lcd-msg-sub  { font-size: 11px; }

  /* Hide cart slot + its label on phone — drag target makes no sense
     when cart picking is done by tap */
  .cart-slot { display: none; }

  .status { font-size: 10px; margin-top: 8px; padding: 4px; }

  .upload {
    flex-wrap: nowrap;
    gap: 6px;
    margin-top: 10px;
    justify-content: center;
  }
  .upload > * {
    font-size: 10px;
    padding: 8px 10px;
    letter-spacing: 1px;
    white-space: nowrap;
  }

  /* Control panel: dpad+AB on one row, startsel + volume below */
  .panel {
    flex-direction: column;
    gap: 14px;
    margin-top: 16px;
    align-items: center;
  }
  .legend { display: none; }
  .touchpad {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    column-gap: 8px;
    row-gap: 14px;
    align-items: center;
    width: 100%;
  }
  .tp-dpad { grid-column: 1; grid-row: 1; justify-self: center;
             width: 120px; height: 120px; }
  .tp-ab   { grid-column: 2; grid-row: 1; justify-self: center; gap: 14px; }
  .tp-btn  { width: 58px; height: 58px; font-size: 22px; }
  .tp-startsel { grid-column: 1 / -1; grid-row: 2; justify-self: center; gap: 16px; }
  .tp-pill { min-width: 68px; padding: 6px 12px; font-size: 11px; }

  .volume-dial { width: 120px; padding: 10px 8px; }
  .dial-knob { width: 56px; height: 56px; }
  .dial-label { font-size: 9px; }

  /* Cart tray: tap-to-select feel, hint text change handled in JS later */
  .cart-tray { max-width: 100%; padding: 14px 12px 24px; border-radius: 16px 16px 0 0; }
  .cart-tray-title { font-size: 12px; margin-bottom: 12px; }
  .cart-tray-cards { gap: 14px; }
  .cart {
    width: 120px;
    height: 142px;
    cursor: pointer;   /* tap target */
  }
  .cart:active { transform: translateY(2px); filter: brightness(0.95); }
  .cart-label-title { font-size: 12px; }
  .cart-label-sub { font-size: 8px; }
  .cart-tray-hint { font-size: 10px; }

  .modal-window { max-width: 94vw; }
}

@media (max-width: 400px) {
  .tp-dpad { width: 104px; height: 104px; }
  .tp-btn  { width: 50px; height: 50px; font-size: 18px; }
  .tp-pill { min-width: 60px; padding: 5px 10px; font-size: 10px; }
  .touchpad { column-gap: 4px; }
  .upload > * { font-size: 9px; padding: 7px 8px; }
}

/* Cart-tray hint: show the correct copy per input type */
.hint-mobile { display: none; }
@media (max-width: 760px) {
  .hint-desktop { display: none; }
  .hint-mobile  { display: inline; }
}

/* Hide the volume dial on mobile — default is 50% and users on phone
   can mute via the system volume if it's too loud. */
@media (max-width: 760px) {
  .volume-dial { display: none; }
}

/* ============================================================
   Touchpad v2 — more DMG-authentic: matte rubber A/B buttons
   recessed into the shell, proper 45° tilt, debossed Start/Select
   ============================================================ */

/* A/B cluster — tilted like the real DMG (A top-right, B bottom-left) */
@media (max-width: 760px) {
  .tp-ab {
    transform: rotate(-30deg);
    gap: 14px;
    position: relative;
    padding: 10px;
  }
  /* Well / recess around the buttons — painted into the shell */
  .tp-ab::before {
    content: "";
    position: absolute;
    inset: -6px;
    border-radius: 60px;
    background:
      radial-gradient(ellipse at center,
        rgba(0,0,0,0.14) 0%,
        rgba(0,0,0,0.05) 45%,
        transparent 70%);
    pointer-events: none;
    z-index: 0;
  }
  .tp-btn {
    position: relative;
    z-index: 1;
    background:
      /* subtle grain */
      radial-gradient(circle at 30% 25%, rgba(255,255,255,0.08), transparent 30%),
      /* main rubber body, matte dark red */
      radial-gradient(circle at 50% 55%, #8a2020 0%, #5a1010 55%, #3a0808 100%);
    box-shadow:
      /* top highlight — soft, not glossy */
      inset 0 2px 1px rgba(255,255,255,0.12),
      /* deep shadow under the dome */
      inset 0 -4px 6px rgba(0,0,0,0.55),
      /* edge ring */
      inset 0 0 0 1px rgba(0,0,0,0.45),
      /* cast shadow into the well */
      0 3px 0 rgba(0,0,0,0.3),
      0 5px 8px rgba(0,0,0,0.45);
    text-shadow: 0 -1px 0 rgba(0,0,0,0.6);
    color: rgba(255, 200, 200, 0.9);
    font-family: Georgia, serif;
    letter-spacing: 0;
  }
  .tp-btn span {
    transform: rotate(30deg);   /* cancel parent rotation on label */
    font-size: 22px;
  }
  .tp-btn.pressed {
    transform: translateY(2px);
    box-shadow:
      inset 0 3px 6px rgba(0,0,0,0.7),
      inset 0 0 0 1px rgba(0,0,0,0.5),
      0 0 0 rgba(0,0,0,0),
      0 0 12px rgba(155,255,155,0.5);
  }
}

/* Start/Select — slim plastic ovals, debossed labels below */
@media (max-width: 760px) {
  .tp-startsel {
    transform: rotate(-20deg);
    gap: 22px;
    padding: 8px 14px;
    position: relative;
  }
  .tp-startsel::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 60px;
    background:
      radial-gradient(ellipse at center,
        rgba(0,0,0,0.10),
        transparent 70%);
    pointer-events: none;
  }
  .tp-pill {
    min-width: 72px;
    padding: 5px 12px;
    border-radius: 12px;
    background:
      linear-gradient(180deg,
        #9a9a9a 0%,
        #6a6a6a 35%,
        #3a3a3a 65%,
        #202020 100%);
    color: transparent;    /* label rendered via text-shadow trick below */
    font-family: "Courier New", monospace;
    font-size: 0;          /* hide actual glyph — we use pseudo label below */
    box-shadow:
      inset 0 1px 1px rgba(255,255,255,0.35),
      inset 0 -1px 1px rgba(0,0,0,0.55),
      inset 0 0 0 1px rgba(0,0,0,0.35),
      0 2px 0 rgba(0,0,0,0.25),
      0 3px 4px rgba(0,0,0,0.4);
    position: relative;
  }
  /* Debossed label underneath the pill (rotated back to horizontal) */
  .tp-pill::after {
    content: attr(data-key);
    position: absolute;
    left: 50%;
    bottom: -14px;
    transform: translateX(-50%) rotate(20deg);
    font-family: "Courier New", monospace;
    font-size: 9px;
    letter-spacing: 2px;
    font-weight: bold;
    color: rgba(43, 35, 24, 0.85);
    text-transform: uppercase;
    text-shadow: 0 1px 0 rgba(255,255,255,0.55);
    white-space: nowrap;
  }
  .tp-pill.pressed {
    transform: translateY(2px);
    box-shadow:
      inset 0 2px 4px rgba(0,0,0,0.75),
      inset 0 0 0 1px rgba(0,0,0,0.45),
      0 0 12px rgba(155,255,155,0.55);
  }
}

/* D-pad also deserves a well */
@media (max-width: 760px) {
  .tp-dpad {
    position: relative;
    padding: 6px;
  }
  .tp-dpad::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background:
      radial-gradient(ellipse at center,
        rgba(0,0,0,0.14),
        rgba(0,0,0,0.04) 55%,
        transparent 75%);
    pointer-events: none;
    z-index: 0;
  }
  .tp-dpad-btn, .tp-dpad-center {
    z-index: 1;
  }
  /* Softer, more plasticky black */
  .tp-dpad-btn {
    background:
      linear-gradient(180deg, #2e2e2e 0%, #151515 50%, #090909 100%);
    box-shadow:
      inset 0 1px 1px rgba(255,255,255,0.1),
      inset 0 -2px 3px rgba(0,0,0,0.7),
      inset 0 0 0 1px rgba(0,0,0,0.5),
      0 2px 3px rgba(0,0,0,0.5);
  }
  .tp-dpad-btn.pressed {
    background:
      linear-gradient(180deg, #1a1a1a 0%, #050505 100%);
    box-shadow:
      inset 0 3px 5px rgba(0,0,0,0.8),
      0 0 14px rgba(155, 255, 155, 0.65);
  }
  .tp-dpad-center {
    background: linear-gradient(180deg, #1a1a1a, #050505);
    box-shadow:
      inset 0 0 5px rgba(0,0,0,0.9),
      inset 0 0 0 1px rgba(0,0,0,0.5);
  }
}

/* ============================================================
   Mobile v7 — fixed 400px device, same as desktop.
   No stretching. If the viewport is narrower, the body gets a
   horizontal scroll bar (rare at 400px on modern phones).
   ============================================================ */
@media (max-width: 760px) {
  body { align-items: flex-start; padding: 8px 0; min-height: auto; }
  .page-stack { width: 400px; }

  .device {
    width: 400px;
    max-width: 400px;
    padding: 28px 28px 40px 28px;
    border-radius: 14px 14px 64px 14px;
  }

  /* Keep desktop TV banner sizing */
  .tv-banner { width: 260px; margin: 0 auto 24px; }
  .tv-screen { height: 58px; }
  .tv-line-1 { font-size: 11px; }
  .tv-line-2 { font-size: 9px; }

  .screen-frame { padding: 32px 28px; }
  canvas { max-height: none; width: 100%; }
  .lcd-msg-main { font-size: 18px; }
  .lcd-msg-sub  { font-size: 10px; }

  .upload { flex-wrap: nowrap; gap: 8px; justify-content: center; }
  .upload > * { font-size: 10px; padding: 6px 10px; white-space: nowrap; }

  /* Panel: dpad + AB side-by-side, Start/Select below, no volume */
  .panel {
    flex-direction: column;
    gap: 16px;
    align-items: center;
    margin-top: 22px;
  }
  .legend { display: none; }
  .touchpad {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    column-gap: 10px;
    row-gap: 14px;
    align-items: center;
    width: 100%;
  }
  .tp-dpad {
    grid-column: 1; grid-row: 1; justify-self: center;
    width: 130px; height: 130px;
  }
  .tp-ab   { grid-column: 2; grid-row: 1; justify-self: center; gap: 14px; }
  .tp-btn  { width: 62px; height: 62px; font-size: 22px; }
  .tp-startsel { grid-column: 1 / -1; grid-row: 2; justify-self: center; gap: 20px; }
  .tp-pill { min-width: 72px; }

  .cart-slot { display: none; }
  .volume-dial { display: none; }

  .cart-tray { max-width: 100%; }
}

/* ============================================================
   Mobile v8 — 500px 이하에선 디바이스 300px로 축소
   ============================================================ */
@media (max-width: 500px) {
  .page-stack { width: 300px; }
  .device {
    width: 300px;
    max-width: 300px;
    padding: 22px 20px 32px;
    border-radius: 12px 12px 48px 12px;
  }
  .tv-banner { width: 220px; margin: 0 auto 18px; }
  .tv-screen { height: 50px; }
  .tv-line-1 { font-size: 10px; }
  .tv-line-2 { font-size: 8px; }

  .screen-frame { padding: 24px 20px 22px; }
  .lcd-msg-main { font-size: 16px; letter-spacing: 2px; }
  .lcd-msg-sub  { font-size: 9px; }

  .upload { gap: 5px; }
  .upload > * { font-size: 9px; padding: 6px 8px; letter-spacing: 0.5px; }

  .panel { gap: 12px; margin-top: 18px; }
  .touchpad { column-gap: 6px; row-gap: 12px; }
  .tp-dpad { width: 110px; height: 110px; padding: 4px; }
  .tp-btn  { width: 54px; height: 54px; font-size: 20px; }
  .tp-pill { min-width: 62px; padding: 5px 10px; font-size: 10px; }
  .tp-pill::after { font-size: 8px; bottom: -12px; }
  .tp-startsel { gap: 16px; }

  .cart-tray { max-width: 100%; }
  .cart { width: 110px; height: 130px; }
  .cart-label-title { font-size: 11px; }
  .cart-label-sub { font-size: 7px; }
}

/* ============================================================
   A/B button polish — deeply engraved serif, not pixel font
   Applies to all widths. Carved-into-rubber look.
   ============================================================ */
.tp-btn {
  font-family: "Didot", "Bodoni 72", "Playfair Display",
               "Hoefler Text", "Times New Roman", Georgia, serif;
  font-weight: 700;
  font-style: italic;
}
.tp-btn span {
  /* Deep deboss: dark inner color + top-dark rim + bottom-light rim */
  color: rgba(40, 8, 8, 0.85);
  text-shadow:
    0 -1px 0 rgba(0, 0, 0, 0.75),
    0 1px 0 rgba(255, 180, 180, 0.25),
    0 0 2px rgba(0, 0, 0, 0.4);
  letter-spacing: 0;
}

/* ============================================================
   Polish v2
   - DOT MATRIX label + red battery LED with space-between
   - upload buttons (CARTRIDGES / SAVE CENTER / RESET) get
     engraved-serif labels to match A/B look
   - ≤500px: smaller brand + smaller action buttons
   ============================================================ */

/* Make the "DOT MATRIX WITH STEREO SOUND" row stretch across the
   screen frame so the ▶ sits at the left edge and the battery LED
   sits at the right edge. */
.screen-label {
  /* override previous left-only positioning */
  left: 14px;
  right: auto;
}
.screen-label.right {
  /* unused for battery now — but keep for compat if needed */
}
.screen-frame > .screen-label:first-of-type {
  /* anchor as a flex row instead */
  top: 10px;
  left: 14px;
  right: 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.screen-frame > .screen-label:first-of-type::after {
  content: "●";
  color: #ff6666;
  font-size: 8px;
  text-shadow: 0 0 6px rgba(255, 90, 90, 0.85);
  animation: tv-rec-blink 2.2s ease-in-out infinite;
}

/* Engraved serif labels on the 3 action buttons (all sizes). */
.chain-btn, .metal-btn, .file-btn > span {
  font-family: "Didot", "Bodoni 72", "Playfair Display",
               "Hoefler Text", "Times New Roman", Georgia, serif;
  font-style: italic;
  font-weight: 700;
  letter-spacing: 1px;
}
/* Deep carved-into-plastic text shadow */
.chain-btn {
  text-shadow:
    0 -1px 0 rgba(0, 0, 0, 0.5),
    0 1px 0 rgba(255, 255, 255, 0.2);
}
.metal-btn {
  text-shadow:
    0 -1px 0 rgba(0, 0, 0, 0.55),
    0 1px 0 rgba(255, 255, 255, 0.28);
}

/* Mobile ≤500px: shrink brand + action buttons further so the
   device height stays compact. */
@media (max-width: 500px) {
  .brand {
    font-size: 11px;
    margin-bottom: 10px;
    white-space: nowrap;           /* stop PoiQemon wrapping */
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .brand em { font-size: 10px; }

  .upload { gap: 4px; }
  .chain-btn, .metal-btn, .file-btn > span {
    font-size: 8px !important;
    padding: 5px 7px !important;
    letter-spacing: 0.5px;
  }
  /* Emoji/diamonds glyphs look awkward at tiny sizes — trim a bit */
  .dirty-badge { font-size: 10px; margin-left: 3px; }
}

/* ============================================================
   Upload / action strip — recessed well like the volume panel
   so the three buttons sit in a carved channel
   ============================================================ */
.upload {
  /* shrink down; the legend/volume have the same treatment */
  margin-top: 14px;
  padding: 10px 12px;
  background: linear-gradient(180deg, rgba(0,0,0,0.10), rgba(0,0,0,0.02));
  border-radius: 6px;
  box-shadow:
    inset 0 2px 3px rgba(0,0,0,0.25),
    inset 0 -1px 0 rgba(255,255,255,0.45),
    inset 0 0 0 1px rgba(0,0,0,0.1);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
}

/* Desktop button sizing: smaller text so nothing wraps at 400px */
.chain-btn, .metal-btn {
  font-size: 9px;
  padding: 6px 10px;
  letter-spacing: 1px;
  white-space: nowrap;
}

/* Mobile mirrors the wider desktop buttons inside the well */
@media (max-width: 760px) {
  .upload { padding: 10px 10px; gap: 6px; }
  .chain-btn, .metal-btn, .file-btn > span {
    font-size: 9px;
    padding: 6px 8px;
  }
}
@media (max-width: 500px) {
  .upload { padding: 8px 8px; gap: 4px; }
  .chain-btn, .metal-btn, .file-btn > span {
    font-size: 8px !important;
    padding: 5px 7px !important;
  }
}

/* ============================================================
   LCD overlay polish
   - "Drag a cart" subtext glows like the main text
   - Scanlines + vignette overlay on top (only while overlay is
     visible = only while no cart is inserted)
   ============================================================ */

/* Subtext matches the Tamagotchi ink style of the main message */
.lcd-msg-sub {
  color: #2e4a1a;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.25),
    0 -1px 0 rgba(0, 0, 0, 0.18);
  opacity: 1;
}

/* CRT scanlines — pseudo-element on the overlay so it only shows
   while the overlay is visible (i.e. no cart inserted). Sits above
   the flat-black background, under the text (text has own glow). */
.lcd-overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    /* faint horizontal scanlines */
    repeating-linear-gradient(to bottom,
      rgba(0,0,0,0.08) 0px,
      rgba(0,0,0,0.08) 1px,
      transparent 2px,
      transparent 4px),
    /* very soft vignette */
    radial-gradient(ellipse at center, transparent 72%, rgba(0,0,0,0.18) 100%);
  mix-blend-mode: multiply;
  animation: tv-flicker 6s linear infinite;
  z-index: 1;
}
.lcd-overlay > * { position: relative; z-index: 2; }

/* ============================================================
   Engraved labels on action buttons — match the legend-label
   "debossed into plastic" look: dark top edge + light bottom edge.
   ============================================================ */

/* All action buttons: deep black engraved text for max contrast */
.chain-btn, .cart-btn, .metal-btn {
  color: #000;
  text-shadow:
    0 -1px 0 rgba(0, 0, 0, 0.6),
    0 1px 0 rgba(255, 255, 255, 0.55);
}

/* ============================================================
   Stop the LCD overlay from blinking — tamagotchi panel is static
   ============================================================ */
.lcd-msg-main, .lcd-msg-sub { animation: none; }

/* Deep inset bezel on the LCD pane — looks carved into the shell */
.lcd {
  box-shadow:
    /* sharp dark groove just inside the edge */
    inset 0 2px 3px rgba(0, 0, 0, 0.65),
    inset 0 -1px 0 rgba(255, 255, 255, 0.08),
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),
    /* subtle interior darkening */
    inset 0 0 20px rgba(0, 20, 0, 0.25),
    /* raised highlight on the outside top, plastic lip */
    0 1px 0 rgba(255, 255, 255, 0.35),
    0 -1px 0 rgba(0, 0, 0, 0.35);
}

/* Stop the pseudo-scanline on the overlay from flickering too */
.lcd-overlay::before { animation: none; }

/* ============================================================
   IQ logo inside the LCD overlay, masked so it inherits text color
   ============================================================ */
.lcd-logo {
  width: 104px;
  height: 78px;
  margin-bottom: 10px;
  background-color: currentColor;   /* inherits from .lcd-overlay */
  color: #2e4a1a;                    /* same dark olive as text */
  -webkit-mask: url("iq_logo.svg") center / contain no-repeat;
          mask: url("iq_logo.svg") center / contain no-repeat;
  opacity: 0.9;
}

@media (max-width: 500px) {
  .lcd-logo { width: 84px; height: 62px; margin-bottom: 6px; }
}

/* LCD outer "inner screen inside a dark frame" effect */
.lcd {
  border: 2px solid #0a0a0a;         /* thin black bezel edge */
  box-shadow:
    /* existing carved-inside look */
    inset 0 2px 3px rgba(0, 0, 0, 0.65),
    inset 0 -1px 0 rgba(255, 255, 255, 0.08),
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),
    inset 0 0 20px rgba(0, 20, 0, 0.25),
    /* dark halo spreading outward — the "screen inside a shadow" */
    0 0 0 1px rgba(0, 0, 0, 0.55),
    0 2px 8px rgba(0, 0, 0, 0.55),
    0 0 18px rgba(0, 0, 0, 0.35);
}

/* Micro-rounded LCD corners — real plastic never has perfectly sharp edges */
.lcd { border-radius: 2px; }

/* Screen-frame inner lip: a soft highlight ring where the plastic rises
   up toward the LCD, so it reads as a molded bezel (like a real device) */
.screen-frame {
  box-shadow:
    /* existing big dark frame */
    inset 0 2px 4px rgba(0,0,0,0.8),
    inset 0 0 30px rgba(0,0,0,0.6),
    /* soft bright ring just inside the frame, reflecting light off
       the molded plastic edge that surrounds the LCD */
    inset 0 0 0 1px rgba(255, 255, 255, 0.04),
    inset 0 0 8px rgba(255, 255, 255, 0.05),
    0 2px 0 rgba(255,255,255,0.35);
}

.lcd { border-radius: 6px; }

/* ============================================================
   Mobile: pull the cart tray fully above Safari's bottom URL bar
   + safe-area, and shrink its contents so the whole tray fits on
   small iPhone viewports without clipping.
   ============================================================ */
@media (max-width: 760px) {
  .cart-tray {
    padding: 12px 14px calc(20px + env(safe-area-inset-bottom));
    max-height: 88dvh;
    overflow-y: auto;
  }
  .cart-tray-handle { margin-bottom: 6px; }
  .cart-tray-title { font-size: 12px; margin-bottom: 12px; letter-spacing: 2px; }
  .cart-tray-cards { gap: 14px; }
  .cart { width: 92px; height: 108px; }
  .cart-label-title { font-size: 11px; }
  .cart-label-sub { font-size: 8px; }
  .cart-id { font-size: 8px; }
  .cart-tray-hint { margin-top: 10px; font-size: 9px; }
}
@media (max-width: 400px) {
  .cart-tray { padding: 10px 12px calc(16px + env(safe-area-inset-bottom)); }
  .cart { width: 84px; height: 100px; }
  .cart-tray-cards { gap: 10px; }
  .cart-tray-title { font-size: 11px; margin-bottom: 10px; }
}

/* Make the action strip noticeably smaller on mobile — the screenshot
   showed CARTRIDGES / ONCHAIN SAVE CENTER / RESET eating too much vertical
   space on a real iPhone viewport. */
@media (max-width: 500px) {
  .upload { padding: 6px 6px; gap: 4px; margin-top: 10px; }
  .chain-btn, .metal-btn, .file-btn > span {
    font-size: 7px !important;
    padding: 4px 6px !important;
    letter-spacing: 0.3px !important;
  }
}
@media (max-width: 400px) {
  .upload { padding: 5px 5px; gap: 3px; }
  .chain-btn, .metal-btn, .file-btn > span {
    font-size: 6.5px !important;
    padding: 4px 5px !important;
  }
}
