/* portfolio.css — miakandijames.com/portfolio
 *
 * A thin layer on top of shell.css. It defines NO colour of its own: every
 * value below is one of the roles the shell already set, so a palette change is
 * still one edit in one file.
 *
 * THE ONE DECISION THIS FILE MAKES
 *   The screen is --deep in BOTH themes. wander-output.md §1 draws the line
 *   between the shell and a tool as a change of ground — grey field for looking,
 *   deep blue for working — and the shell already honours it in miniature: every
 *   card's icon tile is --deep in light and in dark alike. The game is the one
 *   working object on this page, so it gets the working ground, and it keeps it
 *   when the page around it goes dark. Flipping it would make the screen a
 *   surface rather than a place, and the stars would lose the ground they were
 *   measured against: lavender 4.34:1, sage 4.91:1, nile 6.67:1 on --deep.
 */

/* ---- the holding plane ----
 *
 * The shell's .hero-plane is now a link and carries cursor, lift and a state
 * label with it. This page's opening plane is just text, so it takes the hero's
 * measurements without its behaviour rather than inheriting a pressable look
 * that leads nowhere. */
.hold-plane {
  /* Even top and bottom, where the shell's hero is 48/64. The extra bottom
   * there is carrying a state label; this plane holds three short lines and
   * the deeper foot just read as the text sitting high in an empty box. */
  padding: var(--s7);
  max-width: 760px;
}

/* --measure-lede is 420px, which is the right measure for a lede of two or
 * three lines. This one is a single 48-character sentence, and at 420 it broke
 * after "while" — a line break in the middle of a clause, on the only sentence
 * on the page. It gets the room to stay whole. */
.hold-plane .lede { max-width: none; }

/* ---- the game: a band, not a box ----
 *
 * The screen runs edge to edge, the way the nav band does. That means the words
 * around it have nowhere to hide, so the section takes --band as its ground —
 * the same move .collection makes in shell.css, and the same reason it is legal:
 * --band is opaque, so the page's one hard rule (no text on the star field) is
 * kept. The star field goes back to framing the planes above and below.
 */
.gather {
  background: var(--band);
  border-block: var(--border) solid var(--rule-firm);
  padding-block: var(--s6);
}

/* The head and the readout align to the same spine as the nav and the shelf, so
 * the word GATHERING starts under the wordmark rather than floating free. */
.gather > .wrap { max-width: var(--shelf); padding-inline: var(--shelf-gutter); }

.game-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
}

.game-head .eyebrow { margin: 0 0 var(--s4); }

.game-how {
  margin: 0 0 var(--s4);
  font-family: var(--mono);
  font-size: var(--t1);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink);        /* 5.64:1 light / 9.80:1 dark, on --band */
}

/* The sky.
 *
 * HEIGHT IS SET, NOT DERIVED. An aspect ratio was right when the screen was a
 * 720px box; at full bleed it is a trap — 3:2 across a 1280px window is an
 * 853px-tall wall of blue that pushes the footer off the screen entirely and
 * gets worse on a wider monitor. A clamped height keeps the band a band at
 * every width, and the script reads the real box rather than assuming a shape.
 *
 * Square corners, hairline above and below: it meets the edge of the window, so
 * a rounded corner would leave four slivers of band showing through and read as
 * a mistake rather than a decision. */
.screen {
  position: relative;
  height: clamp(220px, 34vh, 380px);
  margin-block: var(--s2) var(--s5);
  overflow: hidden;
  background: var(--deep);
  border-block: var(--border) solid var(--rule-firm);
  box-shadow: inset 0 1px 0 rgba(247, 245, 240, .22);
}

/* The screen is focusable, so it owes a visible focus ring like everything
 * else on the page. --nile is the dark theme's --focus and the only one of the
 * three that is legible against the deep ground in both themes (6.67:1).
 * Inset, because an outset ring on a full-bleed element is clipped by the
 * window on the left and right and would only draw two of its four sides. */
.screen:focus-visible {
  outline: 3px solid var(--nile);
  outline-offset: -3px;
}

.screen canvas {
  display: block;
  touch-action: none;   /* a finger steering the basket must not scroll the page */
  width: 100%;
  height: 100%;
  /* The art is drawn small and blown up. Without this the browser smooths it
   * and the whole point — that every star is a readable square — is lost. */
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}

/* The start curtain. Nothing on this page moves until it is pressed:
 * wander-output.md §5 makes constant motion a requirement, not a preference,
 * and a game that runs itself in the corner of the eye is exactly the thing
 * that rule is about. Pressing it is consent. */
.screen-start {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 0;
  padding: var(--s5);
  /* --deep, deepened, over --deep. Not a new colour: the same blue with the
     value pulled down so the words sit clear of whatever is behind them.
     --paper on this measures 10.6:1. */
  background: rgba(12, 42, 110, .72);
  color: var(--paper);
  font: inherit;
  font-family: var(--mono);
  font-size: var(--t2);
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: opacity .2s ease;
}

.screen-start span {
  border-bottom: 2px solid var(--paper);
  padding-bottom: var(--s1);
}

.screen-start[hidden] { display: none; }

@media (hover: hover) {
  .screen-start:hover { background: rgba(12, 42, 110, .60); }
}

.screen-start:focus-visible {
  outline: 2px solid var(--nile);
  outline-offset: -6px;
}

.game-status {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--t2);
  letter-spacing: .08em;
  color: var(--ink);
}

@media (max-width: 720px) {
  .hold-plane { padding: var(--s6) var(--s5); }
  .gather { padding-block: var(--s5); }
  .gather > .wrap { padding-inline: var(--s4); }

  /* A short band on a short screen leaves the stars no room to fall, so the
   * phone gets a taller slice of the viewport than the desktop does. */
  .screen { height: clamp(260px, 42vh, 340px); }

  /* Both labels fit on one 375px line now that the plane's padding is gone,
   * and that is the problem: two mono strings at the same size and tracking,
   * flush to opposite edges, read as one run-on line rather than a label and a
   * hint. Stacked they are two things again. */
  .game-head { display: block; }
  .game-head .eyebrow { margin-bottom: var(--s2); }
  .game-how { margin-bottom: var(--s4); }
}
