/* ---- shell --------------------------------------------------------------
   The hub (a shelf of cartridges), the boot overlay (handheld power-on),
   and the stage (where a game mounts). Game-specific chrome lives with the
   game, not here.

   No web fonts and no inline styles: _headers sets `style-src 'self'` with
   no 'unsafe-inline', and default-src 'self' blocks a font CDN. The display
   face is therefore a stack of faces that ship with the OS, with a real
   fallback at the end. */

:root {
  --desk: #2a241c;
  --desk-2: #1f1a14;
  --shelf: #3d3428;
  --shelf-edge: #1a1510;
  --wood-lit: #5a4a36;
  --plastic: #aaa59a;
  --plastic-deep: #8e897e;
  --plastic-lit: #c3beb2;
  --emboss: #7d786d;
  --label-paper: #e8e0c8;
  --label-ink: #1a1810;
  --text: #f0ebe0;
  --dim: #b0a894;
  --dim-2: #8a8070;
  --accent: #c4a35a;
  --lcd: #9bbc0f;
  --lcd-deep: #0f380f;
  --lcd-ink: #0f380f;

  --display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--desk-2);
  color: var(--text);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* --- decorative shelf backdrop --- */

/* Fixed rather than scrolling with the list, and pointer-events:none so it
   never eats a click meant for a cart underneath it. */
.hub-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(90% 60% at 50% 0%, #3a3228 0%, transparent 55%),
    linear-gradient(180deg, var(--desk) 0%, var(--desk-2) 100%);
}

/* A fine film grain over the whole backdrop. Generated by the browser from
   an SVG data URI (allowed: img-src is 'self' data:) rather than shipping a
   PNG, so it costs nothing to load and tiles at any size. */
.hub-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Soft shelf board under the carts — a quiet wood plane, not a glow blob. */
.hub-bg-shelf {
  position: absolute;
  left: 5%;
  right: 5%;
  top: 42%;
  height: 38%;
  border-radius: 4px 4px 0 0;
  background:
    linear-gradient(180deg, var(--wood-lit) 0%, var(--shelf) 28%, var(--shelf-edge) 100%);
  box-shadow:
    0 1px 0 #6a5a44 inset,
    0 24px 48px -20px #000000aa;
  opacity: .55;
}

/* --- layout --- */

.hub {
  position: relative;
  min-height: 100vh;
}

.hub-inner {
  position: relative;
  z-index: 1;
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(2.5rem, 8vh, 5rem) 1.5rem 3rem;
}

.hub-head {
  margin-bottom: clamp(1.75rem, 4vh, 2.75rem);
}

.hub-kicker {
  margin: 0 0 .75rem;
  font: 500 11px/1 var(--mono);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--dim-2);
}

/* Sized against the viewport so the wordmark stays the largest thing on the
   page on a phone as well as a desktop. */
.hub-title {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2.75rem, 9vw, 4.25rem);
  font-weight: 400;
  line-height: .95;
  letter-spacing: -.015em;
  color: var(--text);
}

.hub-sub {
  margin: 1rem 0 0;
  max-width: 42ch;
  color: var(--dim);
  font-size: 1rem;
  line-height: 1.55;
}

.hub-error {
  margin: 1.25rem 0 0;
  padding: .7rem .9rem;
  border: 1px solid #6d3242;
  border-left-width: 3px;
  border-radius: 4px;
  background: #2a181c;
  color: #ffb3b3;
  font-size: .9rem;
}
.hub-error[hidden] { display: none; }

.hub-empty {
  color: var(--dim-2);
  font-family: var(--mono);
  font-size: .9rem;
}
.hub-empty[hidden] { display: none; }

/* --- cartridge shelf --- */

.hub-list {
  list-style: none;
  margin: 0;
  padding: 1.5rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 2rem 1.75rem;
  justify-content: flex-start;
  align-items: flex-end;
}

.shelf-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .85rem;
  width: min(100%, 188px);
}

.cart {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  filter: drop-shadow(0 10px 14px #00000066);
  transition: transform .18s ease, filter .18s ease;
}

.cart:hover,
.cart:focus-visible {
  transform: translateY(-6px);
  filter: drop-shadow(0 16px 18px #00000077);
}
.cart:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 6px;
}
.cart:active { transform: translateY(-2px); }

.cart-shell {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  position: relative;
  width: 100%;
  padding: 0 9% 0;
  border-radius: 4px 4px 7px 7px;
  background:
    linear-gradient(180deg, var(--plastic-lit) 0%, var(--plastic) 38%, var(--plastic-deep) 100%);
  box-shadow:
    0 1px 0 #ffffff55 inset,
    0 -3px 0 #00000026 inset,
    2px 0 0 #ffffff22 inset,
    -2px 0 0 #00000018 inset;
  /* The cut top corner is what makes it read as a cart, not an app tile.
     The drop-shadow on .cart follows the clipped outline. */
  clip-path: polygon(0 0, 86% 0, 100% 8%, 100% 100%, 0 100%);
}

/* Top lip: a molded groove, with the shelf's mark pressed into it. */
.cart-mark {
  display: block;
  margin: 0 -9% 7%;
  padding: 7% 0 5%;
  border-bottom: 1px solid #00000022;
  box-shadow: 0 1px 0 #ffffff44;
  font: 700 7.5px/1 var(--mono);
  letter-spacing: .2em;
  text-align: center;
  text-transform: uppercase;
  color: var(--emboss);
  text-shadow: 0 1px 0 #ffffff55;
}

/* The label sits in a shallow recess molded into the shell. */
.cart-label {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 5px 5px 2px 2px;
  background: var(--label-paper);
  box-shadow:
    0 0 0 3px var(--plastic-deep),
    0 0 0 4px #00000030,
    0 1px 0 4px #ffffff40;
}

.cart-art {
  display: block;
  aspect-ratio: 1;
  background: #e8e0c8;
}
.cart-art svg,
.cart-art img {
  display: block;
  width: 100%;
  height: 100%;
}

.cart-label-text {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  padding: .4rem .5rem .45rem;
  background: var(--label-paper);
}

.cart-title {
  font-family: var(--mono);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.15;
  color: var(--label-ink);
}

.cart-tag {
  font: 600 8.5px/1.2 var(--mono);
  letter-spacing: .14em;
  text-align: center;
  text-transform: uppercase;
  color: #5e5848;
}

/* Grip ridges at the connector end, with the insert arrow pressed in the
   middle. Both are pure decoration drawn from gradients. */
.cart-grip {
  position: relative;
  display: block;
  height: 30px;
  margin: 10% -9% 0;
  background:
    repeating-linear-gradient(180deg,
      transparent 0 3px, #00000022 3px 4px, #ffffff2a 4px 5px)
      bottom / 100% 15px no-repeat;
}
.cart-grip::after {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 12px;
  height: 7px;
  transform: translateX(-50%);
  background: var(--emboss);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  filter: drop-shadow(0 1px 0 #ffffff55);
}

.cart-blurb {
  margin: 0;
  max-width: 22ch;
  color: var(--dim);
  font-size: .78rem;
  line-height: 1.45;
  text-align: center;
}

/* --- footer --- */

.hub-foot {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: clamp(2.5rem, 8vh, 4rem);
  padding-top: 1.25rem;
  border-top: 1px solid #4a4034;
  color: var(--dim-2);
  font: 400 12px/1.6 var(--mono);
}
.hub-foot-dot { color: #6a5a48; }

/* --- boot overlay --- */

.boot {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  pointer-events: none;
}
.boot[hidden] { display: none; }

.boot-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  width: min(92vw, 420px);
  aspect-ratio: 10 / 9;
  max-height: 70vh;
  padding: 2rem;
  border-radius: 8px;
  background: var(--lcd-deep);
  color: var(--lcd);
  box-shadow:
    0 0 0 3px #1a2a10,
    0 0 0 6px #0a1008,
    inset 0 0 40px #00000055;
  opacity: 0;
  transform: scale(.98);
}

.boot-mark {
  margin: 0;
  font: 700 clamp(1rem, 4vw, 1.35rem)/1.2 var(--mono);
  letter-spacing: .08em;
  text-align: center;
  color: var(--lcd);
  text-shadow: 0 0 12px #9bbc0f44;
}

.boot-power {
  margin: 0;
  font: 500 11px/1 var(--mono);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--lcd);
  opacity: .75;
}

.boot--run .boot-screen {
  animation: boot-lcd 1.2s ease-out forwards;
}

@keyframes boot-lcd {
  0% {
    opacity: 0;
    transform: scale(.98);
    background: #000;
    color: #000;
  }
  18% {
    opacity: 1;
    background: #000;
    color: #000;
  }
  28% {
    background: var(--lcd-deep);
    color: var(--lcd);
    transform: scale(1);
  }
  85% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1.02);
  }
}

/* Everything decorative here is motion for its own sake, so it all goes. */
@media (prefers-reduced-motion: reduce) {
  .cart { transition: none; }
  .cart:hover,
  .cart:focus-visible,
  .cart:active { transform: none; }
  .boot--run .boot-screen {
    animation: none;
    opacity: 1;
    transform: none;
    background: var(--lcd-deep);
    color: var(--lcd);
  }
}

/* --- stage --- */

.stage {
  position: fixed;
  inset: 0;
  /* Center whatever canvas a game mounts, instead of pinning top-left. */
  display: flex;
  align-items: center;
  justify-content: center;
  background: #14141e;
  overflow: hidden;
  /* Notch / home-indicator: stage fills the screen; games can add their
     own safe-area reserves on top. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
    env(safe-area-inset-bottom) env(safe-area-inset-left);
  box-sizing: border-box;
}
.stage[hidden] { display: none; }

/* Pixel canvases: keep crisp when a game upscales its paint buffer. */
.stage canvas {
  display: block;
  flex-shrink: 0;
  touch-action: none;
  image-rendering: -webkit-optimize-contrast !important;
  image-rendering: crisp-edges !important;
  image-rendering: pixelated !important;
}
