/* Yusaware game-studio site.
   Default theme: "press start" dark (deep space indigo + champagne gold).
   data-theme="converser": the page morphs into Converser's Soft Watercolor
   palette (cream / dusty rose / muted gold) while hovering its product card.
   .page-light (legal pages): the light palette, statically. */

:root, body {
  --bg: #0f1226;
  --bg2: #171a33;
  --card: #1b1e3d;
  --border: #2b2f5c;
  --text: #e8e6f5;
  --muted: #a5a3c2;
  --accent: #e6c88a;   /* champagne gold */
  --accent-dim: #a8834a; /* the second gold in YusaDM's mosaic border */
  --accent2: #ff8fae;  /* neon dusty rose */
  --shadow: rgba(0, 0, 0, 0.55);
  /* Table banding. Kept as a var so the light palette can restate it rather than
     fight a hardcoded rgba. The hero column is typography only, so it needs none. */
  --stripe: rgba(255, 255, 255, 0.04);
}

body.page-light {
  --bg: #faf6f0;
  --bg2: #f3ece2;
  --card: #ffffff;
  --border: #e5d9c6;
  --text: #2b2d4e;
  --muted: #5a5c7a;
  --accent: #b08d4f;   /* muted gold */
  --accent-dim: #8a6a3a;
  --accent2: #c76b82;  /* dusty rose */
  --shadow: rgba(43, 45, 78, 0.14);
  --stripe: rgba(43, 45, 78, 0.05);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  background-color: var(--bg);
  color: var(--text);
  line-height: 1.7;
  transition: background-color 0.6s ease, color 0.6s ease;
}

/* Starfield.

   Two things live here. The gradient layers below are the STILL fallback: what
   a visitor with JavaScript off sees, a populated sky that does not move.
   `stars.js` then builds one <i> per star on top and adds `.lit`, which retires
   the fallback.

   Why per-element: the field used to be nine gradient layers, and every star
   inside a layer shared that layer's fade, so the sky pulsed as a handful of
   big groups. Converser's Dream theme (sky_decoration.dart) gives each star its
   own period AND phase and steps the brightness lit -> dim -> out instead of
   easing it; that is the rule reproduced here. Nothing is shared, so nothing
   can re-synchronise. Fades out entirely in the light palette. */
.stars {
  position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    radial-gradient(1px 1px at 20% 30%, rgba(230, 200, 138, 0.8) 50%, transparent 51%),
    radial-gradient(1px 1px at 70% 12%, rgba(255, 143, 174, 0.7) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 84% 60%, rgba(232, 230, 245, 0.6) 50%, transparent 51%),
    radial-gradient(1px 1px at 40% 78%, rgba(230, 200, 138, 0.55) 50%, transparent 51%),
    radial-gradient(1px 1px at 8% 85%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 55% 45%, rgba(232, 230, 245, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 12% 18%, rgba(232, 230, 245, 0.7) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 30% 55%, rgba(255, 143, 174, 0.55) 50%, transparent 51%),
    radial-gradient(1px 1px at 48% 8%, rgba(230, 200, 138, 0.65) 50%, transparent 51%),
    radial-gradient(2px 2px at 92% 25%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 64% 88%, rgba(232, 230, 245, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 78% 74%, rgba(255, 143, 174, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 25% 92%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 90% 90%, rgba(255, 143, 174, 0.55) 50%, transparent 51%),
    radial-gradient(2px 2px at 5% 50%, rgba(232, 230, 245, 0.4) 50%, transparent 51%),
    radial-gradient(1px 1px at 60% 22%, rgba(255, 143, 174, 0.6) 50%, transparent 51%),
    radial-gradient(1px 1px at 36% 38%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 15% 68%, rgba(230, 200, 138, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 2% 8%, rgba(232, 230, 245, 0.55) 50%, transparent 51%),
    radial-gradient(1px 1px at 45% 96%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 66% 6%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 72% 50%, rgba(232, 230, 245, 0.55) 50%, transparent 51%),
    radial-gradient(1px 1px at 4% 65%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 32% 82%, rgba(255, 143, 174, 0.45) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 58% 76%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 80% 62%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 94% 14%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 50% 40%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 18% 50%, rgba(230, 200, 138, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 63% 34%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 28% 40%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 76% 88%, rgba(230, 200, 138, 0.45) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 42% 60%, rgba(255, 143, 174, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 88% 44%, rgba(232, 230, 245, 0.5) 50%, transparent 51%);
  opacity: 1; transition: opacity 0.6s ease;
}
.stars::before, .stars::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
}
.stars::before {
  background-image:
    radial-gradient(1px 1px at 3% 22%, rgba(232, 230, 245, 0.6) 50%, transparent 51%),
    radial-gradient(1px 1px at 16% 42%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 26% 15%, rgba(255, 143, 174, 0.55) 50%, transparent 51%),
    radial-gradient(1px 1px at 33% 70%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 44% 34%, rgba(230, 200, 138, 0.55) 50%, transparent 51%),
    radial-gradient(2px 2px at 52% 62%, rgba(255, 143, 174, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 58% 14%, rgba(232, 230, 245, 0.6) 50%, transparent 51%),
    radial-gradient(1px 1px at 66% 40%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 73% 66%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 81% 36%, rgba(232, 230, 245, 0.55) 50%, transparent 51%),
    radial-gradient(1px 1px at 87% 72%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 94% 48%, rgba(255, 143, 174, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 10% 82%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 22% 95%, rgba(230, 200, 138, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 46% 88%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 70% 92%, rgba(232, 230, 245, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 84% 4%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 38% 50%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 6% 55%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 20% 8%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 36% 26%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 48% 74%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 60% 52%, rgba(255, 143, 174, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 69% 8%, rgba(232, 230, 245, 0.55) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 78% 46%, rgba(230, 200, 138, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 90% 60%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 97% 30%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 12% 72%, rgba(230, 200, 138, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 30% 60%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 54% 20%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 64% 84%, rgba(230, 200, 138, 0.45) 50%, transparent 51%),
    radial-gradient(1px 1px at 40% 6%, rgba(255, 143, 174, 0.5) 50%, transparent 51%),
    radial-gradient(1px 1px at 83% 88%, rgba(232, 230, 245, 0.5) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 8% 38%, rgba(230, 200, 138, 0.45) 50%, transparent 51%);
}
.stars::after {
  background-image:
    radial-gradient(1.5px 1.5px at 7% 35%, rgba(232, 230, 245, 0.85) 50%, transparent 51%),
    radial-gradient(2px 2px at 19% 68%, rgba(230, 200, 138, 0.7) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 29% 40%, rgba(255, 143, 174, 0.7) 50%, transparent 51%),
    radial-gradient(1px 1px at 41% 18%, rgba(232, 230, 245, 0.8) 50%, transparent 51%),
    radial-gradient(2px 2px at 50% 30%, rgba(230, 200, 138, 0.65) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 62% 72%, rgba(255, 143, 174, 0.7) 50%, transparent 51%),
    radial-gradient(1px 1px at 71% 20%, rgba(232, 230, 245, 0.8) 50%, transparent 51%),
    radial-gradient(2px 2px at 79% 54%, rgba(230, 200, 138, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 89% 30%, rgba(255, 143, 174, 0.7) 50%, transparent 51%),
    radial-gradient(1px 1px at 97% 62%, rgba(232, 230, 245, 0.75) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 14% 12%, rgba(230, 200, 138, 0.65) 50%, transparent 51%),
    radial-gradient(2px 2px at 34% 82%, rgba(255, 143, 174, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 56% 90%, rgba(232, 230, 245, 0.7) 50%, transparent 51%),
    radial-gradient(1px 1px at 76% 84%, rgba(230, 200, 138, 0.65) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 92% 88%, rgba(255, 143, 174, 0.6) 50%, transparent 51%),
    radial-gradient(2px 2px at 48% 52%, rgba(232, 230, 245, 0.7) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 11% 52%, rgba(232, 230, 245, 0.75) 50%, transparent 51%),
    radial-gradient(2px 2px at 24% 26%, rgba(230, 200, 138, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 38% 62%, rgba(255, 143, 174, 0.65) 50%, transparent 51%),
    radial-gradient(1px 1px at 46% 10%, rgba(232, 230, 245, 0.8) 50%, transparent 51%),
    radial-gradient(2px 2px at 58% 44%, rgba(230, 200, 138, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 67% 60%, rgba(255, 143, 174, 0.65) 50%, transparent 51%),
    radial-gradient(1px 1px at 74% 34%, rgba(232, 230, 245, 0.8) 50%, transparent 51%),
    radial-gradient(2px 2px at 85% 66%, rgba(230, 200, 138, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 95% 44%, rgba(255, 143, 174, 0.65) 50%, transparent 51%),
    radial-gradient(1px 1px at 4% 20%, rgba(232, 230, 245, 0.8) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 22% 88%, rgba(230, 200, 138, 0.6) 50%, transparent 51%),
    radial-gradient(2px 2px at 44% 78%, rgba(255, 143, 174, 0.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 64% 92%, rgba(232, 230, 245, 0.7) 50%, transparent 51%),
    radial-gradient(1px 1px at 82% 14%, rgba(230, 200, 138, 0.65) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 30% 6%, rgba(255, 143, 174, 0.6) 50%, transparent 51%),
    radial-gradient(2px 2px at 52% 24%, rgba(232, 230, 245, 0.7) 50%, transparent 51%);
}
/* stars.js has taken over: drop the still field so the two do not stack. */
.stars.lit { background-image: none; }
.stars.lit::before, .stars.lit::after { content: none; }

/* One star. Everything that could tie it to its neighbours is set per element
   by stars.js: --sz size, --c tint, --b lit brightness, plus its own animation
   name, duration and negative delay. */
.stars i {
  position: absolute;
  width: var(--sz); height: var(--sz);
  background: var(--c);
  opacity: var(--b);
  animation-timing-function: step-end;
  animation-iteration-count: infinite;
}
/* The few plus-shaped ones, four arms one cell out. Same twinkle as the body,
   since box-shadow rides the element's opacity. */
.stars i.sparkle {
  box-shadow:
    calc(var(--sz) * -1) 0 0 var(--c),
    var(--sz) 0 0 var(--c),
    0 calc(var(--sz) * -1) 0 var(--c),
    0 var(--sz) 0 var(--c);
}
/* Stepped, never eased: lit, then dim, then out, then straight back to lit.
   The three variants only differ in how long each state holds, so stars that
   happen to land on a similar period still do not march together. */
@keyframes wink-a {
  0%  { opacity: var(--b); }
  50% { opacity: calc(var(--b) * 0.45); }
  68% { opacity: 0; }
}
@keyframes wink-b {
  0%  { opacity: var(--b); }
  55% { opacity: calc(var(--b) * 0.45); }
  72% { opacity: 0; }
}
@keyframes wink-c {
  0%  { opacity: var(--b); }
  60% { opacity: calc(var(--b) * 0.45); }
  76% { opacity: 0; }
}
body.page-light .stars { opacity: 0; }
body.page-light .stars i { animation: none; }

/* Retro pixel clouds drifting across the sky */
.clouds { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.cloud {
  position: absolute; width: 96px; height: 24px;
  background: rgba(165, 163, 194, 0.18);
  box-shadow:
    24px -12px 0 0 rgba(165, 163, 194, 0.18),
    48px -8px 0 0 rgba(165, 163, 194, 0.14),
    -12px 8px 0 0 rgba(165, 163, 194, 0.12),
    72px 4px 0 0 rgba(165, 163, 194, 0.12);
  image-rendering: pixelated;
  animation: drift linear infinite;
}
.cloud.c1 { top: 12%; animation-duration: 70s; animation-delay: -10s; }
.cloud.c2 { top: 30%; transform: scale(0.7); animation-duration: 95s; animation-delay: -40s; }
.cloud.c3 { top: 55%; transform: scale(1.3); animation-duration: 120s; animation-delay: -70s; }
.cloud.c4 { top: 75%; transform: scale(0.85); animation-duration: 85s; animation-delay: -25s; }
@keyframes drift {
  from { left: -180px; }
  to   { left: 110%; }
}
body.page-light .clouds { opacity: 0; }

/* honor visitors who ask their OS for less motion: hold the sky still. Stars
   freeze at their lit brightness rather than wherever the wink had them, so
   holding still never means an empty sky. */
@media (prefers-reduced-motion: reduce) {
  .stars i, .cloud { animation: none; }
  .stars i { opacity: var(--b); }
}

main, header, footer, section { position: relative; z-index: 1; }

.pixel {
  font-family: "Press Start 2P", "Courier New", monospace;
  letter-spacing: 0.02em;
  line-height: 1.5;
}

a { color: var(--accent2); }
a:hover { color: var(--accent); }

.wrap { max-width: 940px; margin: 0 auto; padding: 0 24px; }

/* Header */
.site-header { padding: 22px 0; }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 0.95rem; text-decoration: none; color: var(--text);
}
.brand-logo {
  height: 32px; width: 32px; border-radius: 7px; object-fit: cover;
}
.brand .cursor { color: var(--accent2); animation: blink 1.2s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.site-nav a {
  margin-left: 20px; text-decoration: none; color: var(--muted); font-size: 0.92rem;
}
.site-nav a:hover { color: var(--accent); }

/* Hero */
.hero { padding: 92px 0 64px; text-align: center; }
.hero h1 {
  font-size: clamp(1.15rem, 3.4vw, 1.9rem);
  color: var(--accent);
  margin-bottom: 26px;
  text-shadow: 3px 3px 0 var(--shadow);
}
.hero p.lede { font-size: 1.12rem; color: var(--muted); max-width: 620px; margin: 0 auto 14px; }
.hero .xp {
  display: inline-block; margin-top: 26px; padding: 10px 18px;
  border: 2px solid var(--border); border-radius: 8px;
  font-size: 0.62rem; color: var(--muted);
  background: var(--bg2);
  transition: background-color 0.6s ease, border-color 0.6s ease;
}
.hero .xp b { color: var(--accent2); }

/* Sections */
section.block { padding: 40px 0; }
section.block h2 {
  font-size: 0.95rem; color: var(--accent2); margin-bottom: 34px;
  text-transform: uppercase;
}
section.block h2::before { content: "▶ "; color: var(--accent); }

/* Product cards: level-select cartridges */
.products { display: grid; gap: 26px; }
.card {
  background: var(--card);
  border: 2px solid var(--border);
  border-radius: 14px;
  padding: 34px;
  box-shadow: 6px 6px 0 var(--shadow);
  transition: background-color 0.6s ease, border-color 0.6s ease, transform 0.25s ease, box-shadow 0.25s ease;
}
.card:hover { transform: translate(-2px, -2px); box-shadow: 9px 9px 0 var(--shadow); }
.card .card-top { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; }
.card h3 { font-size: 1.5rem; font-family: Georgia, serif; }
/* Product mark: the shipped app icon, 128px source shown small. Left to the
   browser's smooth downscale rather than image-rendering: pixelated, since the
   source art is already high-res and 128 does not divide evenly into the display
   size, so forcing nearest-neighbour only aliases the pixel grid. */
.card-logo {
  width: 52px; height: 52px; flex: none;
  border-radius: 9px;
}
/* name + tagline ride together beside the mark, so the tag chip can wrap away
   on a narrow card without splitting the two apart */
.card-id { display: flex; flex-direction: column; min-width: 0; }
.card-id h3 { line-height: 1.25; }
.card-actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.card .price { font-size: 0.7rem; color: var(--accent); margin: 14px 0; }
.card .tag {
  font-size: 0.55rem; padding: 6px 10px; border-radius: 6px;
  border: 1.5px solid var(--accent); color: var(--accent);
}
.card .tag.live { border-color: var(--accent2); color: var(--accent2); }
.card p { color: var(--muted); margin: 10px 0; }
.card ul { margin: 14px 0 18px 22px; color: var(--muted); }
.card li { margin: 7px 0; }
.card .tagline { font-style: italic; color: var(--accent); }
.badge {
  display: inline-block; margin-top: 8px; padding: 12px 20px;
  background: var(--accent2); color: var(--bg);
  border-radius: 8px; text-decoration: none; font-size: 0.62rem;
  transition: background-color 0.6s ease, color 0.6s ease;
}
.badge.soon { cursor: default; }

/* Converser now wears the site's dark palette with its dusty-rose accent. */
.card.converser {
  background: var(--card);
  border-color: var(--accent2);
  color: var(--text);
  box-shadow: 6px 6px 0 rgba(255, 143, 174, 0.25);
}
.card.converser:hover { box-shadow: 9px 9px 0 rgba(255, 143, 174, 0.25); }
.card.converser h3 { color: var(--text); }
.card.converser p, .card.converser li, .card.converser ul { color: var(--muted); }
.card.converser strong { color: var(--text); }
.card.converser .tag { border-color: var(--accent2); color: var(--accent2); }
.card.converser .tagline { color: var(--accent); }
.card.converser .badge { background: var(--accent2); color: var(--bg); }

/* YusaDM's counterpart to Converser's rose border: a gold pixel mosaic.
   Two background layers, the card fill clipped to padding-box and a checkerboard
   clipped to border-box, so only the border band shows the mosaic. The conic tile
   holds 2x2 squares, so a 12px tile over a 6px border is exactly one square thick
   all the way round. Done this way rather than border-image because border-image
   would drop the 14px radius the other cards share. */
.card.yusadm {
  border: 6px solid transparent;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    repeating-conic-gradient(var(--accent) 0% 25%, var(--accent-dim) 0% 50%) 0 0 / 12px 12px border-box;
  box-shadow: 6px 6px 0 rgba(230, 200, 138, 0.22);
}
.card.yusadm:hover { box-shadow: 9px 9px 0 rgba(230, 200, 138, 0.22); }

.card.locked { border-style: dashed; opacity: 0.85; }
.card.locked h3 { color: var(--muted); }
.card.locked .padlock { font-size: 1.4rem; }

/* Store grid. The homepage keeps full-width cards that carry the pitch; the shop
   is a browsing surface, so its cards go short and sit three across, close to the
   level-select the theme is borrowing from. Detail lives behind SEE MORE. */
#store-grid .products {
  /* min() rather than a bare 260px: below that the track would keep its minimum
     and push the page into a sideways scroll instead of shrinking. */
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  align-items: start;
}
#store-grid .card { padding: 22px; }
#store-grid .card h3 { font-size: 1.25rem; }
#store-grid .card p { font-size: 0.92rem; }
#store-grid .card-logo { width: 46px; height: 46px; }
/* A tile is ~225px of usable width and Press Start 2P is close to monospace-wide,
   so two chips side by side always overflowed into a ragged second row. Stacked
   full width instead, which reads as deliberate. */
#store-grid .card-actions { flex-direction: column; align-items: stretch; }
#store-grid .badge { text-align: center; margin-top: 0; }
#store-grid .card .price { font-size: 0.58rem; line-height: 1.9; margin: 12px 0; }
#store-grid .card .price .reg { color: var(--muted); }

/* Support */
.support-box { text-align: center; }
.support-box .email {
  font-size: 1.25rem; font-weight: 600; text-decoration: none;
}

/* Footer */
.site-footer {
  padding: 40px 0 48px; font-size: 0.88rem; color: var(--muted);
  border-top: 2px solid var(--border);
  transition: border-color 0.6s ease;
}
.site-footer .wrap { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
.site-footer a { color: var(--muted); text-decoration: none; margin-right: 18px; }
.site-footer a:hover { color: var(--accent); }
.site-footer .gg { font-size: 0.6rem; }

/* Legal pages (light, static) */
.legal { padding: 48px 0 80px; }
.legal h1 { font-size: 1.9rem; font-family: Georgia, serif; margin-bottom: 8px; }
.legal .meta { color: var(--muted); margin-bottom: 34px; font-size: 0.95rem; }
.legal h2 { font-size: 1.2rem; font-family: Georgia, serif; margin: 32px 0 10px; }
.legal p, .legal li { color: var(--muted); }
.legal ul { margin: 10px 0 10px 24px; }
.legal strong { color: var(--text); }
.backlink { display: inline-block; margin-bottom: 26px; text-decoration: none; font-size: 0.95rem; }
.legal table { border-collapse: collapse; margin: 16px 0; width: 100%; font-size: 0.92rem; }
.legal th, .legal td {
  border: 1px solid var(--border); padding: 9px 12px; text-align: left;
  color: var(--muted); vertical-align: top;
}
.legal th { color: var(--text); background: var(--bg2); }
/* Tables are OPAQUE, deliberately. The starfield and the drifting pixel clouds
   are fixed at z-index 0 and main content sits at z-index 1, but the content
   itself paints no background, so while these cells were translucent the stars
   twinkled and the cloud slabs slid along BEHIND the body text. Moving contrast
   under text you are trying to read is tiring, and it was reported as such.
   One backdrop on the table is the whole fix: painting order is table, then row,
   then cell, so everything below still layers exactly as it did, just against a
   solid colour instead of against the sky. */
table { background: var(--bg); }
/* Zebra banding. Site-wide rather than .legal-scoped so any future table gets it
   for free; the tint rides the ROW, so every cell in a row bands together. */
tbody tr:nth-child(even) { background: var(--stripe); }
/* Hero column: the "this is us" column of a comparison table (YusaDM, Premium).
   Applied as a table-level class so the markup says which table is a comparison,
   and the last column is the one that gets the treatment.
   Marked by TYPOGRAPHY ONLY. Owner ruling 2026-08-07: the earlier tinted cell
   and brightened side borders were a second colour block competing with the
   zebra banding, and read as harder on the eyes. So the cells now match their
   neighbours exactly, backdrop, stripe and borders alike, and the emphasis is
   carried entirely by the text. Do not reintroduce a background here.

   Gold marks the whole column; BOLD marks the header only. Second owner ruling
   the same day, after seeing it live: bolding the body cells too was fine on
   YusaDM, whose cells are one or two words ("Yes", "Yes, one queue"), but
   Converser's cells are full sentences, so a bold column became a slab of heavy
   gold prose. Weight is a header-level signal here, not a per-cell one. */
table.hero-last th:last-child,
table.hero-last td:last-child {
  color: var(--accent);
}
table.hero-last th:last-child { font-weight: 700; }
/* premium sub-heading: champagne gold, so the paid layer is visually separated from the
   free feature list above it rather than reading as one undifferentiated list */
.premium-heading { color: var(--accent); font-size: 0.85rem; margin: 36px 0 8px; }
.premium-note { color: var(--muted); font-size: 0.9rem; margin-bottom: 12px; }
.table-scroll { overflow-x: auto; margin: 16px 0; }
.table-scroll table { margin: 0; min-width: 560px; }
.table-note { font-size: 0.85rem; color: var(--muted); margin-top: 10px; }
/* long unbreakable strings (release SHA-256) must not widen the page on mobile */
.legal code { overflow-wrap: anywhere; }

/* Product screenshots: real captures in capture order, one frame at a time.
   JS adds .js and shows a single figure with prev/next arrows; without JS the
   figures simply stack, so the section still works with scripts disabled. */
.shots { margin-top: 6px; }
.shots figure { margin: 0 0 26px; }
.shots.js figure { display: none; margin: 0; }
/* one slide at a time, travelling left to right like a deck advancing. Direction-aware:
   Next brings the new slide in from the right, Back brings it in from the left, so the
   motion always matches the button that caused it. */
.shots.js figure.active { display: block; animation: shot-in-right 0.3s ease-out; }
.shots.js figure.active.back { animation-name: shot-in-left; }
@keyframes shot-in-right { from { opacity: 0; transform: translateX(34px); } to { opacity: 1; transform: none; } }
@keyframes shot-in-left  { from { opacity: 0; transform: translateX(-34px); } to { opacity: 1; transform: none; } }
.shots img {
  display: block; width: 100%; height: auto;
  border: 2px solid var(--border); border-radius: 8px;
  background: var(--bg);
}
/* Each capture keeps its OWN shape and size: a portrait shot is narrow and tall, a
   window shot is wide and short. An earlier letterbox forced every image into one
   fixed-height box to stop the arrows jumping, which left the window shots floating
   in dead space and the portrait stranded in 268px of empty width. Capped by HEIGHT
   so no slide towers over the page and the widths fall out of the real aspect ratio. */
.shots.js img { width: auto; height: auto; max-width: 100%; max-height: 360px; margin: 0 auto; }
/* full-size view on tap: at stage size the window captures are too small to read the UI */
.shots a { display: block; text-decoration: none; }
.shots a:hover img { border-color: var(--accent); }
.shots figcaption { margin-top: 10px; font-size: 0.85rem; color: var(--muted); }
.shots figcaption strong { color: var(--accent2); font-weight: normal; }
.shots.js figcaption { min-height: 3.6em; }
.shots.js { display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: center; }
.shot-stage { min-width: 0; }
.shot-nav {
  display: none;
  font-family: "Press Start 2P", "Courier New", monospace;
  background: var(--bg2); color: var(--accent);
  border: 2px solid var(--border); border-radius: 8px;
  padding: 14px 10px; font-size: 0.8rem; cursor: pointer;
}
.shot-nav:hover { border-color: var(--accent); color: var(--accent2); }
.shots.js .shot-nav { display: block; }
/* Slide position dots. Square, not round: this is the pixel-art theme, and a circle
   reads as a generic web carousel. Clickable, so any shot is one tap away. */
.shot-dots { display: flex; gap: 9px; justify-content: center; margin-top: 16px; }
.shot-dot {
  width: 11px; height: 11px; padding: 0; cursor: pointer;
  background: transparent; border: 2px solid var(--border); border-radius: 0;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.shot-dot:hover { border-color: var(--accent); }
.shot-dot.active { background: var(--accent2); border-color: var(--accent2); }
/* On a phone the side arrows were eating so much width that a 1917px window capture
   rendered 210px wide, too small to read. Drop them to their own row underneath so the
   slide gets the full card width. */
@media (max-width: 560px) {
  .shots.js {
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "stage stage" "prev next";
    gap: 10px;
  }
  .shot-stage { grid-area: stage; }
  .shots.js .shot-nav.prev { grid-area: prev; }
  .shots.js .shot-nav.next { grid-area: next; }
  .shot-nav { padding: 10px 6px; font-size: 0.7rem; }
}
/* the fade is decoration; honour a reduced-motion preference like the starfield does */
@media (prefers-reduced-motion: reduce) {
  .shots.js figure.active,
  .shots.js figure.active.back { animation: none; }
  .shot-dot { transition: none; }
}

@media (max-width: 560px) {
  .hero { padding: 64px 0 44px; }
  .card { padding: 24px; }
}
