:root {
  --bg: #0d0f14;
  --panel: #161a22;
  --panel-2: #1e2430;
  --line: #2a3240;
  --ink: #e6e9ef;
  --muted: #8b95a7;
  --accent: #ffb454;
  --accent-ink: #1a1206;
  --danger: #ff6b6b;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
  background: var(--panel-2);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}

.muted { color: var(--muted); font-size: 0.9em; }
.warn { color: var(--accent); }
.num { text-align: right; }

/* --- chrome ---------------------------------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1.25rem;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}

.brand {
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: 0.02em;
  color: var(--ink);
}

.site-nav { display: flex; align-items: center; gap: 1rem; }
.who { color: var(--muted); font-size: 0.9em; display: flex; align-items: center; gap: 0.4rem; }

.badge {
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  text-transform: uppercase;
}

.site-main { max-width: 1000px; margin: 0 auto; padding: 1.5rem 1.25rem 4rem; }

/* --- flash ----------------------------------------------------------- */

.flash {
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  margin: 0 0 1.25rem;
  font-size: 0.92em;
}

.flash-notice { background: #17311f; border: 1px solid #2c5c37; color: #b7e8c4; }

.flash-alert {
  background: #331a1a;
  border: 1px solid #6b2f2f;
  color: #ffc9c9;
  white-space: pre-wrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* --- headings -------------------------------------------------------- */

.page-head h1 { margin: 0 0 0.35rem; font-size: 1.7rem; }
.lede { margin: 0 0 1.5rem; color: var(--muted); }
.play-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.play-head h1 { margin: 0 0 0.3rem; font-size: 1.6rem; }
.play-desc { color: var(--ink); }

/* --- gallery --------------------------------------------------------- */

.cart-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.cart-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.cart-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.cart-card-link { display: block; color: inherit; }
.cart-card-link:hover { text-decoration: none; }
.cart-card-body { padding: 0.9rem 1rem; }
.cart-card h2 { margin: 0 0 0.3rem; font-size: 1.05rem; }
.cart-card-meta { margin: 0; color: var(--muted); font-size: 0.83rem; }
.cart-card-desc { margin: 0.6rem 0 0; color: var(--muted); font-size: 0.88rem; }

.empty {
  background: var(--panel);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 2rem;
  text-align: center;
  color: var(--muted);
}

.console-note { margin-top: 2rem; color: var(--muted); font-size: 0.88rem; }

/* --- the game -------------------------------------------------------- */

.cart-embed {
  background: #000;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  /* DragonRuby's virtual canvas is 1280x720 and scales itself; the frame just
     has to hold that ratio so nothing is letterboxed or cropped. */
  aspect-ratio: 16 / 9;
  width: 100%;
}

.cart-embed-frame { width: 100%; height: 100%; border: 0; display: block; }

.embed-note { color: var(--muted); font-size: 0.85rem; margin: 0.6rem 0 2rem; }

.draft-banner {
  background: #3a2c10;
  border: 1px solid #6b5423;
  color: var(--accent);
  padding: 0.5rem 0.8rem;
  border-radius: var(--radius);
  font-size: 0.9em;
}

/* --- file list ------------------------------------------------------- */

.files { margin-top: 1rem; }
.files summary { cursor: pointer; color: var(--muted); font-size: 0.9rem; }
.file-table { width: 100%; border-collapse: collapse; margin-top: 0.75rem; font-size: 0.88rem; }
.file-table td { padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--line); }
.file-table td:first-child { width: 100%; }
/* The first column takes the slack, so keep a size on one line rather than
   letting it wrap into a second row of its own. */
.file-table .num { white-space: nowrap; }

/* --- one file, read --------------------------------------------------- */

/* The viewer lives inside the file list, on a page that also holds a running
   game. An empty frame takes no room at all; a loaded one is capped and
   scrolls, so reading a 3000-line file does not push the rest of the page off
   the screen. */
#file_viewer:empty { display: none; }
#file_viewer { display: block; margin-top: 0.75rem; }

.file-viewer-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.6rem;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  font-size: 0.85rem;
}
.file-viewer-head .muted { margin-left: auto; }
.file-viewer-close { font-size: 0.85rem; white-space: nowrap; }

.source {
  margin: 0;
  padding: 1rem;
  max-height: 60vh;
  overflow: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0 0 var(--radius) var(--radius);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre;
}

/* Rouge's shortnames: k keyword, s string, c1 comment, and so on. Colours live
   here rather than inline so the reader is themed like the rest of the site,
   and keyed off the accent the page already has. */
.source .k, .source .kd, .source .kn, .source .kp, .source .kr, .source .kt { color: var(--accent); }
.source .c, .source .c1, .source .cm, .source .cp, .source .cs { color: #6f7c92; font-style: italic; }
.source .s, .source .s1, .source .s2, .source .sb, .source .sc, .source .sd,
.source .se, .source .sh, .source .si, .source .sx, .source .sr, .source .ss { color: #9ece6a; }
.source .m, .source .mf, .source .mh, .source .mi, .source .il, .source .mo { color: #ff9e64; }
.source .nf, .source .fm { color: #7aa2f7; }
.source .nc, .source .nn, .source .no, .source .nd, .source .ni, .source .ne,
.source .nl, .source .py, .source .nv, .source .vc, .source .vg, .source .vi { color: #7dcfff; }
.source .nb, .source .bp { color: #bb9af7; }
.source .kc, .source .kd { color: #e0af68; }
.source .o, .source .ow { color: #a9b4c7; }
.source .p { color: #8b95a7; }
.source .err { color: var(--danger); }
/* Diff tokens, for a cart whose source is a patch. */
.source .gi { color: #9ece6a; }
.source .gd { color: var(--danger); }
.source .gh, .source .gu { color: var(--accent); font-weight: 600; }
.source .ge { font-style: italic; }
.source .gs { font-weight: 600; }

.file-image { margin: 0; }
.file-image img {
  max-width: 100%;
  /* Sprites are small and read better at their own size than blown up. */
  image-rendering: pixelated;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}

/* --- forms ----------------------------------------------------------- */

.upload-form {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
}

.field { margin-bottom: 1.1rem; }
.field label { display: block; margin-bottom: 0.35rem; font-weight: 600; font-size: 0.92rem; }
.field .muted { margin: 0.35rem 0 0; }

input[type="text"], input[type="email"], input[type="password"], input[type="file"], select {
  width: 100%;
  padding: 0.5rem 0.6rem;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  font: inherit;
}

input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

input[type="submit"], .link-button {
  background: var(--accent);
  color: var(--accent-ink);
  border: 0;
  border-radius: 8px;
  padding: 0.5rem 1rem;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

input[type="submit"]:hover, .link-button:hover { filter: brightness(1.08); }

.secondary { background: var(--panel-2) !important; color: var(--ink) !important; }
.link-button { padding: 0.35rem 0.7rem; font-size: 0.88rem; }
.play-actions { white-space: nowrap; }

.upload-help {
  margin-top: 2rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
}

.upload-help h2 { margin: 0 0 0.6rem; font-size: 1rem; }
.upload-help ul { margin: 0; padding-left: 1.1rem; color: var(--muted); font-size: 0.9rem; }
.upload-help li { margin-bottom: 0.4rem; }

/* --- auth ------------------------------------------------------------ */

.auth-card {
  max-width: 420px;
  margin: 2rem auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
}

.auth-card h1 { margin: 0 0 0.35rem; font-size: 1.35rem; }
.auth-card .lede { margin-bottom: 1.25rem; }
.auth-alt { margin: 1.1rem 0 0; color: var(--muted); font-size: 0.9rem; }

.form-errors {
  background: #331a1a;
  border: 1px solid #6b2f2f;
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
  margin-bottom: 1.1rem;
  color: #ffc9c9;
  font-size: 0.88rem;
}

.form-errors ul { margin: 0; padding-left: 1.1rem; }
/* --- documentation ---------------------------------------------------- */

/* Read out of the library's own comments, so the styles here are about making
   prose and code sit well together rather than about branding a page. */
.doc-section { margin: 2rem 0; }
.doc-section h2 {
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.4rem;
  margin: 0 0 1rem;
}
.doc-section h3 { font-size: 1rem; margin: 1.5rem 0 0.4rem; }

.doc-note {
  padding: 0.9rem 1.1rem;
  background: var(--panel);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.doc-note p { margin: 0; }

.doc-sample { margin: 0 0 1.75rem; }
.doc-sample p { margin: 0 0 0.6rem; }

/* A sample inside the documentation is read, not edited, so it is allowed to
   be as tall as it needs to be -- unlike the cart reader's capped box, whose job
   is to leave room for the game above it. */
.source.sample { border-radius: var(--radius); }
.source.full { max-height: none; border-radius: var(--radius); }

.doc-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.doc-table td { padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.doc-table td:first-child { white-space: nowrap; }
.doc-when { color: var(--muted); white-space: nowrap; }

.doc-methods { margin: 0; }
.doc-method { margin: 0 0 1.1rem; }
.doc-method dt { margin: 0 0 0.2rem; }
.doc-method dd { margin: 0 0 0 0.2rem; }
.doc-signature {
  display: inline-block;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  background: none;
  padding: 0;
}
.doc-method dd p { margin: 0 0 0.4rem; }
.doc .doc code { background: var(--panel-2); }

.doc-index { list-style: none; margin: 0; padding: 0; }
.doc-index li {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr auto;
  gap: 0.75rem;
  align-items: baseline;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--line);
}
.doc-index-summary { color: var(--muted); font-size: 0.86rem; }

/* --- downloads and keys ------------------------------------------------ */

.button-link {
  display: inline-block;
  padding: 0.45rem 0.9rem;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius);
  font-weight: 600;
}
.button-link:hover { text-decoration: none; filter: brightness(1.08); }

/* The one response in which a key exists. Given room to be copied, and marked
   so it cannot be mistaken for anything else on the page. */
.key-reveal {
  padding: 1rem 1.1rem;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  margin: 1rem 0;
}
.key-reveal-label {
  margin: 0 0 0.4rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.75rem;
  color: var(--accent);
}
.key-value {
  display: block;
  font-size: 0.9rem;
  word-break: break-all;
  background: none;
  padding: 0;
  user-select: all;
}
.key-reveal .muted { margin: 0.6rem 0 0; }

.doc-steps { margin: 0.75rem 0; padding-left: 1.3rem; }
.doc-steps li { margin-bottom: 0.4rem; }

.doc-endpoint { margin-top: 1rem; }
.doc-endpoint summary { cursor: pointer; color: var(--muted); font-size: 0.9rem; }
