/* Shared layout for the two game pages under /pages: Blues Wanderer and
   Barrelhouse. Both are Forge Terminal pages wrapping pixel-art screenshots,
   and they had drifted into two near-identical <style> blocks before this file
   existed. Page-specific rules stay on the page; anything both need lives here.

   The gp- prefix is deliberate ("game page"): these pages sit outside the
   registry-driven project system, so the class names must not collide with
   projects-page.css. */

/* The prose measure, shared by the column and the heading that sits above it.
   They must resolve to the same number or the centering below misaligns. */
:root {
  --gp-measure: 62ch;
}

/* Pixel art must not be smoothed by the browser's default bilinear filter,
   or the whole point of the art is lost at any scale but 1:1. */
.gp-hero-shot {
  display: block;
  width: 100%;
  height: auto;
  max-height: min(46vh, 420px);
  object-fit: cover;
  /* Near the top rather than a third down. A title screen puts its wordmark in
     the upper fifth, and 30% sliced it in half at every width this page has
     been looked at. */
  object-position: center 8%;
  border-bottom: 1px solid var(--border-hairline);
  image-rendering: pixelated;
}

.gp-get {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-top: 22px;
}

.gp-get .button {
  font-size: 17px;
  padding: 16px 30px;
}

.gp-get-meta {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--muted-text);
  letter-spacing: 0.04em;
  margin: 0;
}

/* A status line where a download button would be, for a game with nothing to
   download yet. Same slot, same rhythm, no false affordance. */
.gp-status {
  margin-top: 22px;
  border-left: 2px solid var(--accent-deep);
  padding-left: 16px;
  max-width: 56ch;
}

.gp-status strong {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin-bottom: 4px;
}

.gp-status p {
  margin: 0;
  color: var(--muted-text);
}

.gp-facts {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 16px;
  max-width: 62ch;
}

.gp-facts li {
  border-left: 2px solid var(--accent-deep);
  padding-left: 16px;
}

.gp-facts strong {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin-bottom: 4px;
}

.gp-shots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 18px;
}

.gp-shots a {
  display: block;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius);
  overflow: hidden;
}

.gp-shots img {
  display: block;
  width: 100%;
  height: auto;
}

/* Portrait shots from a phone game. Left to the auto-fit grid above they
   stretch to a column's full width and tower over the page, so they get a
   narrower track and a cap on how tall any one of them can stand. */
.gp-shots--portrait {
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  align-items: start;
}

.gp-shots--portrait img {
  max-height: 70vh;
  width: 100%;
  object-fit: contain;
}

.gp-prose {
  max-width: var(--gp-measure);
}

/* styles.css zeroes the global p margin, and .gp-prose never restored one, so
   a multi paragraph block rendered as an unbroken wall. These are the values
   .markdown-content p already uses for the blog's long form prose, so the two
   read the same. The measure above is deliberate and stays. */
.gp-prose p {
  margin: 0 0 16px;
  line-height: 1.8;
}

.gp-prose p:last-child {
  margin-bottom: 0;
}

/* styles.css caps .lede at 38ch, which is right for a standalone intro line
   under a heading and wrong for the first paragraph of a prose block: it
   renders a visibly narrower column than the paragraphs directly beneath it.
   Inside .gp-prose the lede is a first paragraph, so it takes the prose width
   and keeps its size and color. */
.gp-prose .lede {
  max-width: none;
}

/* A portrait game has no landscape hero to run full bleed across the top, and
   cropping one to a 420px band shows a slice of a barrel and nothing else. So
   the phone-shaped screenshot sits beside the headline instead, at the size it
   was drawn for. It wraps under the text on a narrow screen. */
.gp-brand-split {
  display: flex;
  gap: 40px;
  align-items: center;
  flex-wrap: wrap;
}

.gp-brand-split .brand-text {
  flex: 1 1 34ch;
  min-width: 0;
}

.gp-phone {
  flex: 0 0 auto;
  width: min(260px, 62vw);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius);
  overflow: hidden;
  align-self: center;
}

.gp-phone img {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
}

/* A SHA-256 is 64 unbroken characters, which is wider than a 320px viewport at
   any readable size. Break it anywhere rather than letting one <code> push the
   whole page into a horizontal scroll. */
.gp-hash {
  display: block;
  margin: 6px 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted-text);
  word-break: break-all;
  overflow-wrap: anywhere;
}

/* Keep "SHA-256" whole. Browsers happily break after the hyphen, and a split
   acronym reads as a typo in the one place the page is asking to be trusted. */
.gp-nobreak { white-space: nowrap; }

/* --- Wide viewports ---------------------------------------------------------

   Every other page on this site fills a desktop monitor with a card grid.
   These three hold nothing but narrow blocks (a 62ch prose column, a 62ch
   fact list, a heading, a lone button), and .section sets padding without a
   measure, so all of it pinned to the left gutter with a void beside it at
   1900px. Centering the column is the fix. It is a no-op below the measure,
   where the column is already wider than the viewport, so the phone layout is
   untouched. The 62ch measure itself is deliberate and does not change.

   This centers every direct child rather than naming .gp-prose and friends,
   because the blocks that got stranded were the ones nobody thought to name:
   the bare <p> wrapping the "See the mechanics board" button sat at the far
   left of a section whose prose was centered. A rule that has to be extended
   by hand every time the markup grows is the same defect waiting to recur.

   The heading takes the prose measure rather than the site's 620px, because a
   heading and a column that do not share a left edge read as a mistake rather
   than as a choice. Both resolve ch against the same inherited font size, so
   the two edges land on the same pixel; that is what --gp-measure is for, and
   why nothing here may be given a font-size of its own. */
.section > * {
  max-width: var(--gp-measure);
  margin-inline: auto;
}

/* Screenshots are the one thing that should be wider than the text. They break
   out to the band .nav-content and .header-content already use, still centered
   on the same axis, so a grid wider than the prose above it reads as
   deliberate rather than as another alignment bug. Must stay after the rule
   above: same specificity, so order is what decides. */
.gp-shots {
  max-width: 1400px;
}

/* The clip is 1280 wide and pixel art is the one thing that must not be
   upscaled, so it stops at its native width instead of taking the screenshots'
   full band. Like .gp-shots this has to stay after the spine rule above:
   equal specificity, so source order is what decides. */
.gp-video {
  max-width: 1280px;
}

.gp-video-player {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius);
  /* The clip is letterboxed against its own frame while it loads and while a
     poster is showing, and the page ground is not black. */
  background: #000;
}

/* The caption is body text, so it keeps the prose measure the spine rule gives
   it rather than following the player out to 1280. Same split the screenshot
   grid and its heading already use.

   It deliberately sets NO font-size, and this is the trap the spine rule's
   comment warns about, caught here in rendering. --gp-measure is 62ch, and ch
   resolves against the element's OWN font size, so a 14px caption computes a
   narrower 62ch than the 16px heading above it and centers on a different left
   edge. It sat 38px right of the spine until the override came out. Anything
   that wants to be smaller has to give up the shared measure to get it. */
.gp-video-caption {
  margin-top: 12px;
  margin-bottom: 28px;
  color: var(--muted-text);
}

/* The hero card already spans the full width, but .brand's `auto 1fr` sized
   its first column to the text, stranding the title and lede at the card's
   left edge. One column instead, so the page has a single spine from the hero
   down. .gp-brand-split is a deliberate two column layout and keeps its own
   alignment, which is why it is excluded rather than special-cased below. */
.site-header .brand:not(.gp-brand-split) {
  grid-template-columns: 1fr;
}

.site-header .brand:not(.gp-brand-split) .brand-text {
  /* An auto inline margin on a grid item suppresses the stretch that would
     otherwise size it to its track, collapsing it to fit-content. Without
     this the hero text never reaches the measure and sits about 120px right
     of the column beneath it, which is the misalignment the centering was
     supposed to remove. */
  width: 100%;
  max-width: var(--gp-measure);
  margin-inline: auto;
}
