/*
 * style.css — MiniMaze's cards and HUD, made of the toy itself.
 *
 * Every card is a piece of the maze: a light plank in a walnut frame, a
 * brass rim inside the frame, a brass screw in each corner, and letters
 * engraved into the wood. The wood is not imitated here — main.js paints it
 * once for the board (render/board-mesh.js) and passes the same canvases in
 * as --wood-light and --wood-dark, so the menus are cut from the same plank
 * the marble rolls on. Each has a flat colour fallback for the moment
 * before that runs. Brass is for whatever you press, walnut for the quieter
 * choice beside it: equal in size, different in metal (hub §2).
 *
 * No web fonts (hub §1): a book serif from the system with a real fallback
 * down to `serif`, and no emoji; the tick on a finished maze is drawn.
 *
 * The corner — menu, sound, fullscreen — is three brass knobs fixed top
 * right on every screen (hub §2), and every card keeps clear of it: below
 * it on a tall screen, beside it on a sideways phone (--corner-room).
 */

:root {
  --walnut: #1d140d;
  --ink: #4a2a12; /* engraved letters */
  --ink-hi: rgba(255, 238, 206, 0.55); /* the lit lower lip of an engraving */
  --wood-light: linear-gradient(#ddb07a, #d4a46c);
  --wood-dark: linear-gradient(#7a4a26, #6a3e1f);
  --brass: #d8a640;
  --brass-hi: #f3cf7a;
  --birch: #f2dcb6;
  --muted: #c4a57f;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
    Georgia, "Times New Roman", serif;
  --body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  --tap: 48px;
  /* What the corner takes from the top right: three plates, two gaps, the
     12px inset, and a little air. Cards and the HUD keep out of it. */
  --corner-gap: 8px;
  --corner-room: calc(3 * var(--tap) + 2 * var(--corner-gap) + 24px);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--walnut);
  color: var(--birch);
  font-family: var(--body);
  font-size: 15px;
  -webkit-text-size-adjust: 100%;
}

[hidden] {
  display: none !important;
}

/*
 * A game, not a document (hub §2): nothing selects, no callout, no tap
 * flash, no double-tap zoom; js/touch-guard.js is the half CSS cannot
 * promise. Text fields get selection back — there are none yet, but the
 * day one arrives it must be typable.
 */
html,
body {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
input,
textarea,
[contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* The board. touch-action:none because a drag here is a tilt, and a
   browser that decides the same gesture is a scroll takes the board with
   it. */
#view {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  outline: none;
}

/* Overlay layer, padded by the safe areas so nothing below needs to know a
   notch exists. Click-through except where something is actually drawn. */
#ui {
  position: fixed;
  inset: 0;
  pointer-events: none;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
    env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

#hud {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  left: calc(env(safe-area-inset-left, 0px) + 12px);
  right: calc(env(safe-area-inset-right, 0px) + var(--corner-room));
  min-height: var(--tap);
  display: flex;
  align-items: center;
  gap: 12px;
  pointer-events: none;
}
#hud > * {
  pointer-events: auto;
}

/* THE CORNER: menu, sound, fullscreen, left to right, over every card. */
#corner {
  position: absolute;
  z-index: 2;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  right: calc(env(safe-area-inset-right, 0px) + 12px);
  display: flex;
  gap: var(--corner-gap);
  pointer-events: auto;
}

/* Brass, engraved: the nameplate screwed to the front of a real labyrinth. */
.plate {
  padding: 5px 14px 6px;
  border-radius: 6px;
  font: italic 700 1rem var(--serif);
  color: #3a2408;
  text-shadow: 0 1px 0 rgba(255, 240, 190, 0.6);
  background: linear-gradient(#f3cf7a, #c8922f 60%, #b07f26);
  border: 1px solid #7a5418;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 2px 4px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  flex: none;
  padding: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f6d98c, #c8922f 55%, #8f6420);
  border: 1px solid #6e4a14;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 2px 5px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
/* [hidden] loses to display:flex without this (hub §2, hit three times). */
.icon-button[hidden] {
  display: none;
}
.icon-button svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: #3a2408;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Each toggle carries both pictures; aria-pressed picks one, so what is
   drawn and what a screen reader hears cannot drift. */
#sound-btn[aria-pressed="true"] .icon-waves,
#sound-btn:not([aria-pressed="true"]) .icon-slash,
#screen-toggle[aria-pressed="true"] .icon-expand,
#screen-toggle:not([aria-pressed="true"]) .icon-contract {
  display: none;
}
.icon-button:focus-visible {
  outline: 3px solid var(--birch);
  outline-offset: 3px;
}

/* A walnut tag with a brass edge, hung at the bottom. */
#hint {
  position: absolute;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 18px);
  transform: translateX(-50%);
  margin: 0;
  max-width: calc(100% - 32px);
  padding: 8px 18px;
  border-radius: 10px;
  background: var(--wood-dark), #6a3e1f;
  background-size: 300px;
  border: 2px solid var(--brass);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.45);
  font-family: var(--serif);
  color: var(--birch);
  text-align: center;
  opacity: 0;
  transition: opacity 0.4s;
  pointer-events: none;
}
#hint.show {
  opacity: 1;
}

/* ---- the cards: a plank in a frame ---- */

.card {
  --screw: radial-gradient(
    circle,
    #fbe3a2 0 1.5px,
    #d8a640 2.5px 4px,
    #7a5418 4.5px 5px,
    transparent 5.5px
  );
  pointer-events: auto;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(360px, calc(100% - 32px));
  /* Centred, but clear of the corner above and the same again below. */
  max-height: calc(100% - 2 * (var(--tap) + 22px));
  overflow: auto; /* a safety net on very short viewports, not a plan */
  padding: 26px 26px 24px;
  text-align: center;
  border: 12px solid transparent;
  border-radius: 18px;
  /* Top to bottom: four screws, the plank inside the frame, the frame. */
  background:
    var(--screw) left 6px top 6px / 12px 12px no-repeat padding-box,
    var(--screw) right 6px top 6px / 12px 12px no-repeat padding-box,
    var(--screw) left 6px bottom 6px / 12px 12px no-repeat padding-box,
    var(--screw) right 6px bottom 6px / 12px 12px no-repeat padding-box,
    var(--wood-light) center / 380px padding-box,
    var(--wood-dark) center / 300px border-box;
  box-shadow:
    inset 0 0 0 2px var(--brass),
    inset 0 4px 10px rgba(60, 30, 5, 0.35),
    0 18px 40px rgba(0, 0, 0, 0.6);
}
.card.wide {
  width: min(520px, calc(100% - 32px));
}

.card h1,
.card h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.01em;
  /* Engraved: a dark cut with the light catching its lower lip. */
  text-shadow:
    0 1px 0 var(--ink-hi),
    0 -1px 0 rgba(40, 20, 5, 0.35);
}
.card h1 {
  font-size: 2.7rem;
}
.card h2 {
  font-size: 2rem;
}
.card .tag {
  margin: 6px 0 18px;
  font-family: var(--serif);
  font-style: italic;
  color: #6a4020;
  font-size: 1.05rem;
  text-shadow: 0 1px 0 var(--ink-hi);
}
.card .best {
  margin: -10px 0 18px;
  font: 700 1rem var(--serif);
  color: #8a5a10;
  text-shadow: 0 1px 0 var(--ink-hi);
}

/* One column of peers, one width (hub §2: a logical group lines up). */
.actions {
  display: grid;
  gap: 10px;
  justify-items: stretch;
}

/* Brass for the way in; walnut for the quieter choice, the same size. */
.go {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 10px 18px;
  font: 700 1.2rem var(--serif);
  color: #2a1a0c;
  text-shadow: 0 1px 0 rgba(255, 240, 190, 0.55);
  background: linear-gradient(#f6d98c, #d8a640 55%, #b8862c);
  border: 1px solid #7a5418;
  border-radius: 10px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    0 3px 0 #6e4a14,
    0 5px 8px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}
.go.alt {
  color: var(--birch);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
  background: var(--wood-dark) center / 300px, #6a3e1f;
  border: 2px solid var(--brass);
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 160, 0.25),
    0 3px 0 #3b2312,
    0 5px 8px rgba(0, 0, 0, 0.3);
}
.go:active {
  transform: translateY(2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 1px 0 #6e4a14;
}
.go[hidden] {
  display: none;
}
.go:focus-visible,
.tile:focus-visible {
  outline: 3px solid #2a1a0c;
  outline-offset: 3px;
}

/*
 * THE WAY BACK TO THE ARCADE (hub §2, "One button"): the last thing on the
 * start and pause cards. Brass is the way in and walnut the quieter choice;
 * the way out is neither — no fill at all, just an outline cut into the
 * plank in the engraving's own ink, because leaving is never the recommended
 * action. Full column width, set a little further down than the gap between
 * the other items, so it is never read as one more setting. The arrow is the
 * hub's shared glyph, stroked like the plate's three bars.
 */
.go.exit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 20px;
  color: var(--ink);
  text-shadow: 0 1px 0 var(--ink-hi);
  background: transparent;
  border: 2px solid rgba(74, 42, 18, 0.7);
  box-shadow: inset 0 1px 0 var(--ink-hi), 0 1px 0 var(--ink-hi);
}
.go.exit:hover {
  background: rgba(74, 42, 18, 0.08);
}
.go.exit:active {
  transform: translateY(1px);
  background: rgba(74, 42, 18, 0.14);
  box-shadow: inset 0 1px 0 var(--ink-hi);
}
.go.exit:disabled {
  cursor: default;
  opacity: 0.7;
}
.go.exit[hidden] {
  display: none;
}
.go.exit svg {
  flex: none;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- the picker: every maze a numbered walnut block ---- */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
  gap: 10px;
  margin: 16px 0 18px;
}
.tile {
  position: relative;
  aspect-ratio: 1;
  min-height: var(--tap);
  padding: 0;
  border-radius: 10px;
  background: var(--wood-dark) center / 240px, #6a3e1f;
  border: 2px solid #4f2d14;
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 160, 0.25),
    0 3px 0 #3b2312;
  cursor: pointer;
}
.tile .n {
  font: 700 1.45rem var(--serif);
  color: var(--brass-hi);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.6);
}
/* Finished: the block gets a brass face, and a tick drawn in the corner. */
.tile.done {
  background: linear-gradient(#f6d98c, #d8a640 55%, #b8862c);
  border-color: #7a5418;
}
.tile.done .n {
  color: #3a2408;
  text-shadow: 0 1px 0 rgba(255, 240, 190, 0.6);
}
.tile.done::after {
  content: "";
  position: absolute;
  right: 7px;
  top: 5px;
  width: 6px;
  height: 11px;
  border: solid #2f6b2a;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
}
.tile:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 #3b2312;
}

/*
 * THE LANGUAGE ROW (hub §2, "Two languages"), in the menu panel and nowhere
 * else: language and sound are settings, set once, so they live behind the
 * three bars and the title card spends its room on the ways in and the way
 * out (the owner, 2026-10-11). A small engraved caption over two equal blocks, the same
 * walnut-and-brass pair as the tiles: walnut until chosen, brass once it
 * is, so the choice reads in metal rather than size. Each carries its flag
 * (the hub's exact art) and its own name in its own language.
 */
.lang-row {
  margin-top: 16px;
}
.lang-caption {
  display: block;
  margin-bottom: 6px;
  font: italic 700 0.95rem var(--serif);
  color: var(--ink);
  text-shadow: 0 1px 0 var(--ink-hi);
}
.seg {
  display: flex;
  gap: 10px;
}
.seg-btn {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 10px;
  font: 700 1rem var(--serif);
  color: var(--birch);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
  background: var(--wood-dark) center / 240px, #6a3e1f;
  border: 2px solid #4f2d14;
  border-radius: 10px;
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 160, 0.25),
    0 3px 0 #3b2312;
  cursor: pointer;
}
.seg-btn[aria-pressed="true"] {
  color: #2a1a0c;
  text-shadow: 0 1px 0 rgba(255, 240, 190, 0.55);
  background: linear-gradient(#f6d98c, #d8a640 55%, #b8862c);
  border-color: #7a5418;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    0 3px 0 #6e4a14;
}
.seg-btn:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 #3b2312;
}
.seg-btn:focus-visible {
  outline: 3px solid #2a1a0c;
  outline-offset: 3px;
}
.seg-btn .flag {
  flex: none;
  width: 24px;
  height: 16px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.seg-btn span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * THE MENU PANEL's two volume rows (hub §2, "Two volumes"): an engraved
 * caption, a brass rail with a brass knob, and the number beside it. The
 * captions share one gutter so both rails start at the same x.
 */
.menu-settings {
  margin-top: 16px;
}
.vol-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
}
.vol-row label {
  flex: 0 0 5.6em;
  text-align: left;
  font: italic 700 0.95rem var(--serif);
  color: var(--ink);
  text-shadow: 0 1px 0 var(--ink-hi);
}
.vol-row output {
  flex: 0 0 2.2em;
  text-align: right;
  font: 700 0.95rem var(--serif);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.vol-row input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
  height: 40px;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}
.vol-row input[type="range"]::-webkit-slider-runnable-track {
  height: 8px;
  border-radius: 4px;
  background: var(--wood-dark) center / 240px, #6a3e1f;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6), 0 1px 0 var(--ink-hi);
}
.vol-row input[type="range"]::-moz-range-track {
  height: 8px;
  border-radius: 4px;
  background: #6a3e1f;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6), 0 1px 0 var(--ink-hi);
}
.vol-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 26px;
  height: 26px;
  margin-top: -9px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f6d98c, #c8922f 55%, #8f6420);
  border: 1px solid #6e4a14;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.45);
}
.vol-row input[type="range"]::-moz-range-thumb {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f6d98c, #c8922f 55%, #8f6420);
  border: 1px solid #6e4a14;
}
.vol-row input[type="range"]:focus-visible {
  outline: 3px solid #2a1a0c;
  outline-offset: 2px;
  border-radius: 6px;
}
/* In the menu panel the language caption sits on the volume captions'
   edge: above its two blocks on a tall screen, where "English" needs the
   whole width, and in their gutter on a sideways phone (below). */
.menu-settings .lang-row {
  margin-top: 10px;
}
.menu-settings .lang-caption {
  text-align: left;
}
.vol-hint {
  margin: 2px 0 0;
  font: italic 0.85rem/1.3 var(--serif);
  color: #6a4020;
  text-shadow: 0 1px 0 var(--ink-hi);
}

/*
 * UPDATE READY (js/update.js), on the title card only. A notice pinned to the
 * plank rather than another brass button: it is not a way into a maze, so it
 * must not look like one, and it sits below the two that are. A dashed brass
 * rule round a slightly darker patch of the same wood, the words engraved.
 */
#update {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 8px 12px;
  border: 2px dashed var(--brass);
  border-radius: 10px;
  background: rgba(74, 42, 18, 0.12);
  font-family: var(--serif);
  text-align: center;
  cursor: pointer;
}
#update:active {
  background: rgba(74, 42, 18, 0.2);
}
#update:focus-visible {
  outline: 3px solid #2a1a0c;
  outline-offset: 3px;
}
.update-title {
  display: block;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
  text-shadow: 0 1px 0 var(--ink-hi);
}
.update-sub {
  display: block;
  margin-top: 2px;
  font-style: italic;
  font-size: 0.85rem;
  color: #6a4020;
}

/* Which build is actually serving this session, scratched small into the
   bottom of the title plank. */
#build {
  margin: 12px 0 -8px;
  font: italic 0.75rem var(--serif);
  color: rgba(74, 42, 18, 0.6);
}

/*
 * A phone on its side: 300–430px tall. The corner is beside the cards here
 * rather than above them, so every card is centred in what is left once
 * --corner-room is taken off the right, and may use nearly the full height.
 * Titles shrink, the start card's actions stand side by side as equals, the
 * menu panel becomes two columns laid over the same markup by grid area
 * (maxgear's shape), and the picker spreads into fewer, wider rows.
 */
@media (orientation: landscape) and (max-height: 500px) {
  :root {
    --tap: 44px;
  }
  .card {
    left: calc(50% - var(--corner-room) / 2);
    max-height: calc(100% - 20px);
    padding: 14px 20px 14px;
    width: min(520px, calc(100% - 32px - var(--corner-room)));
  }
  .card.wide {
    width: min(720px, calc(100% - 32px - var(--corner-room)));
  }
  .card h1 {
    font-size: 2rem;
  }
  .card h2 {
    font-size: 1.5rem;
  }
  .card .tag {
    margin: 2px 0 10px;
  }
  .actions {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }
  .go {
    min-height: 40px;
    padding: 6px 12px;
    font-size: 1.05rem;
  }
  /* The menu panel: title and actions down the left, the volumes and the
     language down the right, the way out under them. */
  #pause {
    width: min(680px, calc(100% - 32px - var(--corner-room)));
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    grid-template-areas:
      "head set"
      "act  set"
      "act  exit";
    grid-template-rows: auto auto 1fr;
    column-gap: 22px;
    align-content: start;
    align-items: start;
  }
  #pause .menu-head {
    grid-area: head;
  }
  #pause .menu-actions {
    grid-area: act;
    grid-template-columns: none;
  }
  #pause .menu-settings {
    grid-area: set;
    margin-top: 0;
  }
  #pause .go.exit {
    grid-area: exit;
    align-self: end;
  }
  .vol-row {
    min-height: 36px;
  }
  /* One gutter for all three captions in the right column. */
  .vol-row label,
  .menu-settings .lang-caption {
    flex: 0 0 4.6em;
  }
  .menu-settings .seg {
    min-width: 0;
  }
  .menu-settings .seg-btn {
    gap: 6px;
    padding: 4px 8px;
  }
  .vol-row input[type="range"] {
    height: 36px;
  }
  .lang-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
  }
  .lang-caption {
    margin: 0;
    flex: none;
  }
  .seg {
    flex: 1 1 auto;
  }
  .seg-btn {
    min-height: 38px;
    padding: 4px 10px;
  }
  /* The way out keeps its own line, full width, just less air above it. */
  .go.exit {
    margin-top: 12px;
  }
  .tiles {
    grid-template-columns: repeat(9, 1fr);
    gap: 8px;
    margin: 10px 0 12px;
  }
  .tile {
    aspect-ratio: auto;
    height: 44px;
  }
  /* The notice and the build line would push the title card off the bottom;
     fold the notice to one line and tuck the build line closer. */
  #update {
    margin-top: 10px;
    padding: 5px 10px;
  }
  .update-sub {
    display: inline;
    margin: 0 0 0 0.5em;
  }
  .update-title {
    display: inline;
  }
  #build {
    margin: 6px 0 -6px;
  }
}

/*
 * The opening sting: js/intro.js's canvas, which the script creates and
 * removes. Above everything — the cards, the corner's knobs — because for
 * its three seconds it is a curtain over the whole page; a tap anywhere on
 * it skips, and touch-action keeps that tap from becoming a scroll or a
 * zoom. Reduced motion never creates it at all.
 */
#intro {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 20;
  touch-action: none;
  cursor: pointer;
}

#crash {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: #7a1d12;
  color: #fff;
  font: 13px/1.4 var(--body);
  z-index: 10;
}
