/* sandboxgamers.com
 *
 * One file, no framework, no build step - the same bargain the games make.
 * Colours are the arena's: #0d1117 ground, #f0a020 amber. Every text pair
 * below clears 4.5:1 against the surface it sits on, which is why the muted
 * grey is #9daab8 and not the #6e7681 that looked nicer and failed.
 */

:root {
  --bg: #0d1117;
  --panel: #161b22;
  --panel-hi: #1c2430;
  --line: #263040;
  --text: #e6edf3;
  --muted: #9daab8;
  --amber: #f0a020;
  --amber-dim: #7a5210;
  --live: #3fb950;
  --busy: #f0a020;
  --down: #8b949e;
  --radius: 12px;
  --maxw: 1120px;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* The tunnel puts this page in front of people on cellular data, so the
   * background is a gradient rather than an image: nothing extra to fetch. */
  background-image:
    radial-gradient(120% 80% at 50% -20%, #17202c 0%, transparent 60%);
  background-repeat: no-repeat;
}

a { color: var(--amber); }
a:hover { color: #ffc257; }

/* Focus must be visible on every interactive thing, including the ones that
 * are styled to look like cards rather than links. */
:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--amber);
  color: #101010;
  padding: 10px 16px;
  font-weight: 700;
  z-index: 10;
}
.skip:focus {
  left: 8px;
  top: 8px;
}

/* ------------------------------- hero ------------------------------- */
.hero {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(40px, 9vw, 88px) 20px clamp(24px, 5vw, 40px);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 18px;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Pushes the account control to the far end of the brand row, so the wordmark
   stays left and the sign-in sits opposite it. `margin-left: auto` rather than
   `justify-content: space-between` on .brand, because the row also holds the
   mark and the site name and those two must stay together. Empty until
   account.js mounts into it, and it collapses to nothing if it never does. */
.account-slot {
  margin-left: auto;
}

/* The mark is drawn, not fetched: a tank track and a hull in two rules. */
.brand .mark {
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 7px;
  background: var(--panel-hi);
  border: 1px solid var(--line);
  position: relative;
}
.brand .mark::before {
  content: "";
  position: absolute;
  inset: auto 4px 5px 4px;
  height: 6px;
  border-radius: 2px;
  background: var(--amber);
}
.brand .mark::after {
  content: "";
  position: absolute;
  left: 7px;
  bottom: 12px;
  width: 9px;
  height: 5px;
  border-radius: 1px;
  background: var(--amber);
  box-shadow: 9px 1px 0 -1px var(--amber);
}

.hero h1 {
  margin: 0 0 16px;
  font-size: clamp(2rem, 6.2vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  max-width: 22ch;
}

.lede {
  margin: 0;
  max-width: 58ch;
  font-size: clamp(1rem, 2.2vw, 1.15rem);
  color: var(--muted);
}

/* ------------------------------- main ------------------------------- */
main {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 20px 64px;
}

main > h2 {
  margin: 8px 0 20px;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  scroll-margin-top: 16px;
}

.grid {
  list-style: none;
  margin: 0 0 56px;
  padding: 0;
  display: grid;
  gap: 20px;
  /* auto-fit rather than a media query: one card centres, two sit side by
   * side, and the eventual sixth wraps without anyone editing a breakpoint. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

/* ------------------------------- cards ------------------------------ */
.card {
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.card:hover { border-color: var(--amber-dim); }

/* Lift on hover only where a pointer can actually hover, and never for
 * someone who has asked for less motion. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card:hover { transform: translateY(-3px); }
}

.shot {
  display: block;
  background: #0a0e14;
  border-bottom: 1px solid var(--line);
  line-height: 0;
}
.shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 18px 18px 20px;
  gap: 10px;
}

.card h3 {
  margin: 0;
  font-size: 1.35rem;
  letter-spacing: -0.01em;
}
.card h3 a {
  color: var(--text);
  text-decoration: none;
}
.card h3 a:hover { color: var(--amber); }

.tagline {
  margin: 0;
  color: var(--amber);
  font-size: 0.95rem;
  font-weight: 600;
}

.blurb {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
}

.tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0 0;
  padding: 0;
}
.tags li {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--panel-hi);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 10px;
}

/* Pushed to the bottom so every card's status and button line up across the
 * row however long the blurbs are. */
.meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: auto 0 0;
  padding-top: 8px;
  font-size: 0.85rem;
  color: var(--muted);
}
.meta .seats { margin-left: auto; }

.dot {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--down);
}
.dot.busy {
  background: var(--busy);
  box-shadow: 0 0 0 3px rgba(240, 160, 32, 0.16);
}
.dot.idle {
  background: var(--live);
  box-shadow: 0 0 0 3px rgba(63, 185, 80, 0.16);
}
.dot.down, .dot.soon, .dot.pending { background: var(--down); }

.play {
  display: block;
  margin: 4px 0 0;
  padding: 12px 16px;
  border-radius: 8px;
  text-align: center;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-decoration: none;
  background: var(--amber);
  color: #10130f;
  border: 1px solid var(--amber);
}
.play:hover {
  background: #ffc257;
  color: #10130f;
}

/* Coming soon is prose, not a dead button: there is nowhere to go, and a
 * focusable control that does nothing wastes a keyboard user's time. */
.play.soon {
  background: transparent;
  border: 1px dashed var(--line);
  color: var(--muted);
  font-weight: 600;
  cursor: default;
}

/* ------------------------------- prose box -------------------------- */
.box {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(20px, 4vw, 32px);
}
.box h2 {
  margin: 0 0 12px;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
}
.box p {
  margin: 0 0 12px;
  color: var(--muted);
  max-width: 70ch;
}
.box p:last-child { margin-bottom: 0; }
.box strong { color: var(--text); }

/* ------------------------------- footer ----------------------------- */
footer {
  border-top: 1px solid var(--line);
  padding: 24px 20px 40px;
}
footer p {
  max-width: var(--maxw);
  margin: 0 auto;
  color: var(--muted);
  font-size: 0.9rem;
}

/* A phone in portrait gets the art shorter, so more than one card is on
 * screen at once and the page reads as a gallery rather than a stack. */
@media (max-width: 560px) {
  .shot img { aspect-ratio: 2 / 1; }
  .body { padding: 16px 16px 18px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
