/* Mountain Valley Software archive -- shared styles.
 *
 * One stylesheet rather than the per-page inlining used on the Alphaworks site:
 * this site has 27 documents, 23 of them generated, so duplicating the chrome
 * into each would mean 27 copies to keep in step. One extra request is the
 * cheaper trade here.
 *
 * The artwork is the only saturated colour on the page. Everything else stays
 * out of its way. */

:root {
  /* One palette: the page is white everywhere, on every page, regardless of the
     visitor's OS light/dark preference. The previous dark default and its
     prefers-color-scheme switch were removed deliberately -- do not reinstate
     them without also re-checking the button and accent contrasts below. */
  --bg: #ffffff;
  --surface: #f6f5f2;       /* panels and inputs must be tinted to read against
                               a pure-white page -- white-on-white vanishes */
  --surface-2: #edebe6;
  --line: #e4e0d9;
  --line-strong: #c9c3b8;
  --text: #1a1a1c;
  --muted: #5d5d66;
  --accent: #a8551a;
  --accent-dim: #c98a4e;
  --mat: #f0eeea;           /* behind artwork -- a shade off the page so the
                               frame around each scan is visible */

  /* White on this accent clears WCAG AA at 5.3:1; the hover shade is darker
     still. Both were measured, not guessed. */
  --btn-bg: #a8551a;
  --btn-bg-hover: #8c4514;
  --btn-fg: #ffffff;

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --wrap: 1100px;
  --gutter: 16px;
  --radius: 4px;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.15; letter-spacing: -0.02em; font-weight: 650; margin: 0; }
h1 { font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem); }
h2 { font-size: clamp(1.3rem, 1.1rem + 0.8vw, 1.6rem); }
h3 { font-size: 1.05rem; letter-spacing: -0.01em; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--text); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

/* Visually hidden, still read by screen readers and search engines. The home
   page is a single image, so its <h1> lives here -- a document with no heading
   at all is close to unusable with assistive tech. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* Home page -- the Flagstone Manor map, and nothing else. Sized to its own
   native 1169px rather than the 1100px content column, since it is the page. */
.map-page { margin: 0 auto; max-width: 1169px; padding: 0 var(--gutter); }
.map-page img { display: block; width: 100%; height: auto; border-radius: var(--radius); }

/* Skip link -------------------------------------------------------------- */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--surface); color: var(--text);
  padding: 10px 16px; border: 1px solid var(--line-strong);
}
.skip:focus { left: var(--gutter); top: 8px; }

/* Masthead ----------------------------------------------------------------
 * The banner runs the full width of the viewport rather than sitting inside
 * .wrap -- it is the artwork, not chrome. Its own cream sky and near-black
 * ground strip meet the page top and bottom, so no border is needed between
 * the banner and the nav beneath it. */
.site-head { background: var(--bg); border-bottom: 1px solid var(--line); }

.masthead { display: block; background: #f5f0dd; }
.masthead img {
  display: block; width: 100%; height: auto;
  /* Downscaled at every viewport, so smooth beats nearest-neighbour here even
     though the castle and gravestone are pixel art. */
  image-rendering: auto;
}
/* The banner scales with the page at every width -- one proportional rule, no
   breakpoint crop. The whole scene (castle, wordmark, gravestone) is therefore
   visible on a phone as well as a desktop, at 6.63:1 throughout. */

/* The rule under the nav runs edge to edge like the banner above it; inset to
   the content width it read as a stray line under a full-bleed image. */
.site-head .wrap {
  display: flex; align-items: center; justify-content: center;
  gap: 16px; flex-wrap: wrap; padding-block: 12px;
}

.site-nav { display: flex; gap: 4px; flex-wrap: wrap; justify-content: center; }
.site-nav a {
  color: var(--muted); text-decoration: none;
  padding: 6px 10px; border-radius: var(--radius);
  font-size: 0.94rem;
}
.site-nav a:hover { color: var(--text); background: var(--surface); }
.site-nav a[aria-current="page"] { color: var(--text); background: var(--surface); }

/* Footer ----------------------------------------------------------------- */
.site-foot {
  margin-top: 80px; padding: 32px 0 0;
  border-top: 1px solid var(--line);
  color: var(--muted); font-size: 0.88rem;
}
/* One centred line now, not two columns. */
.site-foot .wrap { text-align: center; }
.site-foot p { margin: 0; }

/* Credit band. Black with white text in both themes -- deliberately fixed
   rather than tokenised, echoing the navy bar that closed every page of the
   2007 site. Runs full-bleed and flush to the bottom of the document. */
.site-credit {
  margin-top: 32px;
  padding: 18px var(--gutter);
  background: #000;
  color: #fff;
  text-align: center;
}
.site-credit p { margin: 0; font-size: 0.9rem; line-height: 1.5; }

/* Generic sections ------------------------------------------------------- */
main { padding-top: 48px; }
.section { margin-top: 64px; }
.section > h2 { margin-bottom: 6px; }
.section-note { color: var(--muted); font-size: 0.95rem; margin-bottom: 24px; max-width: 62ch; }
.lede { font-size: 1.12rem; color: var(--text); max-width: 64ch; }
.prose { max-width: 66ch; }
.prose h2 { margin-top: 2em; margin-bottom: 0.4em; }

/* Artwork -----------------------------------------------------------------
 * Two scaling rules, and they are not interchangeable:
 *   .art-pixel -- C64 captures, <=16 colours. Nearest-neighbour keeps the
 *                 pixel grid honest.
 *   .art-scan  -- photographs of printed artwork. Smoothed; pixelating a
 *                 halftone scan just looks broken.
 * Sources top out at 320x300 (covers) and 384x282 (screens), so nothing is
 * blown up to hero size -- the layout carries the page, not the scale. */
.art-pixel { image-rendering: pixelated; }
.art-scan  { image-rendering: auto; }

.mat {
  display: block;            /* it is a <span> inside <a>/<figure>, so this is load-bearing */
  background: var(--mat);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.mat img { display: block; width: 100%; height: auto; }

/* Game grid -------------------------------------------------------------- */
.grid {
  display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  list-style: none; margin: 0; padding: 0;
}
.card { display: flex; flex-direction: column; }
.card a {
  text-decoration: none; color: inherit;
  display: flex; flex-direction: column; gap: 10px; height: 100%;
}
.card .mat { transition: border-color .15s ease; }
.card a:hover .mat { border-color: var(--accent); }
.card a:hover .card-title { color: var(--accent); }
.card-shot { aspect-ratio: 16 / 15; background: var(--mat); }
.card-shot img { width: 100%; height: 100%; object-fit: contain; }
.card-title {
  font-weight: 600; font-size: 0.98rem; line-height: 1.3;
  /* Reserve two lines so a wrapping title does not push its metadata out of
     step with the rest of the row. */
  min-height: 2.6em;
}
.card-meta { color: var(--muted); font-size: 0.82rem; line-height: 1.4; }
/* The badge takes its own line -- inline, it wrapped mid-phrase into the
   platform name ("UNRELEASED Commodore / 64"). */
.card-meta .badge { display: block; width: max-content; margin-bottom: 5px; }

/* auto-fill with a 190px minimum drops to a single column under ~400px, which
   turns a 23-item gallery into 23 screens of scrolling. Phones get two. */
@media (max-width: 560px) {
  .grid { grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .card-title { min-height: 0; }
}

/* Each platform group is its own grid, so they need separating -- and a
   `display` rule outranks the UA's [hidden], hence the explicit none. */
.grid + .grid { margin-top: 34px; }
.grid[hidden] { display: none; }

.grid--featured { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 620px) { .grid--featured { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 960px) { .grid--featured { grid-template-columns: repeat(6, 1fr); } }

.card-empty {
  display: grid; place-items: center; height: 100%;
  color: var(--muted); font-size: 0.8rem; text-align: center; padding: 16px;
}

/* The modern conversion panel. Set apart from the archival sections above it:
   it is the one part of a game page that is not a historical artefact. */
.port {
  display: grid; gap: 24px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px;
}
@media (min-width: 720px) {
  .port { grid-template-columns: 260px 1fr; align-items: start; }
}
.port-art { margin: 0; }
.port .prose p { margin-top: 0; }
.port .filelist { margin-bottom: 0; }

/* Buttons ---------------------------------------------------------------- */
.btn {
  font: inherit; font-weight: 600; cursor: pointer;
  background: var(--btn-bg); color: var(--btn-fg); border: 1px solid var(--btn-bg);
  border-radius: var(--radius); padding: 10px 20px;
}
.btn:hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); }
.btn[disabled] { opacity: .55; cursor: default; }

/* Badges + filters ------------------------------------------------------- */
.badge {
  display: inline-block; font-size: 0.72rem; letter-spacing: 0.06em;
  text-transform: uppercase; font-weight: 600;
  padding: 3px 7px; border-radius: 3px;
  border: 1px solid var(--line-strong); color: var(--muted);
}
.badge-unreleased { border-color: var(--accent-dim); color: var(--accent); }

.filters { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 32px; padding: 0; }
.filters button {
  font: inherit; font-size: 0.9rem;
  background: transparent; color: var(--muted);
  border: 1px solid var(--line-strong); border-radius: 999px;
  padding: 5px 14px; cursor: pointer;
}
.filters button:hover { color: var(--text); border-color: var(--muted); }
.filters button[aria-pressed="true"] {
  background: var(--btn-bg); border-color: var(--btn-bg); color: var(--btn-fg);
}

/* Game detail ------------------------------------------------------------ */
.back { display: inline-block; font-size: 0.9rem; color: var(--muted); text-decoration: none; }
.back:hover { color: var(--accent); }

.game-head { display: grid; gap: 32px; margin-top: 20px; }
@media (min-width: 760px) {
  .game-head { grid-template-columns: 300px 1fr; align-items: start; }
}
.game-meta { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 20px; }
.game-blurb { font-size: 1.06rem; }
.game-blurb .src { display: block; margin-top: 12px; color: var(--muted); font-size: 0.85rem; }
.game-head .dated { margin-top: 20px; }
/* Sits under a cover that is not an archive scan -- a modern stand-in has to
   be labelled where it is shown, not further down the page. */
.cover-note { margin: 10px 0 0; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }
.game-head .section-note { margin-bottom: 0.5em; }

.figs { display: grid; gap: 20px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
figure { margin: 0; }
figcaption { margin-top: 8px; color: var(--muted); font-size: 0.84rem; }

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px;
}
.panel h2 { margin-bottom: 8px; }

/* Body text with a panel alongside it. Single column until there is genuinely
   room for two -- .prose is capped at 66ch, so below about 900px a sidebar
   would squeeze the measure rather than sit beside it. */
.with-aside { display: grid; gap: 40px; align-items: start; }
@media (min-width: 900px) {
  .with-aside { grid-template-columns: minmax(0, 1fr) 320px; gap: 48px; }
  /* Sticks alongside the text as it scrolls -- it is the call to action on this
     page, and the page is long. */
  .aside-panel { position: sticky; top: 24px; }
}
.aside-panel h2 { font-size: 1.15rem; }
.aside-panel p { font-size: 0.95rem; }

.filelist { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.filelist a { text-decoration: none; font-weight: 550; }
.filelist a:hover { text-decoration: underline; }
.filelist .hint { color: var(--muted); font-weight: 400; font-size: 0.86rem; }

.verbs { font-family: var(--mono); font-size: 0.88rem; color: var(--text); }
/* Document scans --------------------------------------------------------- */
.docs { display: grid; gap: 26px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.docs .mat { background: #fff; }
.docs a { display: block; text-decoration: none; }
.docs a:hover .mat { border-color: var(--accent); }

/* Forms ------------------------------------------------------------------ */
.field { display: grid; gap: 6px; margin-bottom: 18px; max-width: 46rem; }
.field label { font-size: 0.9rem; color: var(--muted); }
.field input, .field textarea {
  font: inherit; color: var(--text); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 10px 12px; width: 100%;
}
.field textarea { min-height: 170px; resize: vertical; }
.form-status { margin-top: 14px; font-size: 0.95rem; }
.form-status[data-state="error"] { color: #b3261e; }

.hp { position: absolute; left: -9999px; }

@media (max-width: 520px) {
  body { font-size: 16px; }
  main { padding-top: 32px; }
  .section { margin-top: 48px; }
}
