﻿/* The games page: the tabs, the loading skeleton, and what every game
   shares (the wall palette, carved recesses, engraved lettering). Each
   game's own styles live beside it in /future/<id>/<id>.css. */

:root {
  --danger-red: #7a2e2a;

  --win-top:    #b8a381;
  --win-left:   #cbb794;
  --win-right:  #dbcaa9;
  --win-bottom: #eadcbf;
  --win-edge:   #a8916e;
  --win-sill:   #e2d2b2;
  --win-drop:   rgba(60, 40, 25, 0.28);
  --win-inset:  rgba(40, 25, 15, 0.38);
  --win-shade:  rgba(60, 40, 25, 0.2);

  /* the sill: a top face that runs on from the reveal, then a front face */
  --sill-top:     #efe3c8;
  --sill-arris:   #fbf5e7;
  --sill-front:   #d6c3a0;
  --sill-front-dk:#c0ab86;

  /* carved recesses: four chiselled faces around a sunken floor */
  --cut-floor:  #f1e8d4;
  --cut-top:    #d3c1a0;
  --cut-left:   #dfd0b2;
  --cut-right:  #efe5cf;
  --cut-bottom: #fcf8ee;
  --cut-shade:  rgba(60, 40, 25, 0.22);
  --engrave-hi: rgba(255, 252, 244, 0.9);
}
html.dark {
  --danger-red: #c85444;

  --win-top:    #0b0a08;
  --win-left:   #13110d;
  --win-right:  #1f1b16;
  --win-bottom: #2b251d;
  --win-edge:   #3d3028;
  --win-sill:   #2a241c;
  --win-drop:   rgba(0, 0, 0, 0.6);
  --win-inset:  rgba(0, 0, 0, 0.7);
  --win-shade:  rgba(0, 0, 0, 0.45);

  --sill-top:     #322b21;
  --sill-arris:   #40372b;
  --sill-front:   #1e1914;
  --sill-front-dk:#15110d;

  --cut-floor:  #16140f;
  --cut-top:    #0a0907;
  --cut-left:   #0f0d0a;
  --cut-right:  #221e18;
  --cut-bottom: #2b261e;
  --cut-shade:  rgba(0, 0, 0, 0.55);
  --engrave-hi: rgba(255, 235, 200, 0.07);
}

/* The runner's world, read by the kit for every game that draws it.
   Dark mode gets its own night palette rather than the site's dark
   tokens, which sit too close together on a busy canvas. */
:root {
  --g-sky-top:   #e6d6b6;
  --g-sky-bot:   #f7eedb;
  --g-haze:      #f3e7cf;
  --g-mountain:  #8f9a98;
  --g-hill:      #7d9366;
  --g-ground:    #c9b08a;
  --g-path:      #e2d0ae;
  --g-pit:       #3a2c22;
  --g-ink:       #5c4033;
  --g-danger:    #8c2f28;
  --g-eye:       #f8f1e3;
  --g-celestial: #e8a945;
  --g-glow:      rgba(232, 169, 69, 0.22);
  --g-cloud:     #fffaf0;
  --g-star:      #fff6e0;
  --g-stone:     #a9a395;
  --g-wood:      #8d6b49;
  --g-rune:      #4fb8f0;
  --g-water:     #4f8189;
}
html.dark {
  --g-sky-top:   #0f1119;
  --g-sky-bot:   #2d2830;
  --g-haze:      #34303a;
  --g-mountain:  #4a5163;
  --g-hill:      #3f6b4f;
  --g-ground:    #4a3c2e;
  --g-path:      #6e5b45;
  --g-pit:       #0b0a09;
  --g-ink:       #efcf9f;
  --g-danger:    #f06a52;
  --g-eye:       #1a1814;
  --g-celestial: #f1e6cc;
  --g-glow:      rgba(241, 230, 204, 0.06);
  --g-cloud:     #4a4450;
  --g-star:      #f4ead2;
  --g-stone:     #8e8b84;
  --g-wood:      #a2805b;
  --g-rune:      #6fd6ff;
  --g-water:     #1b3a48;
}

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---- Carved: a recess chiselled into the wall. Four bevelled faces
   (shadowed above, lit below), a sunken floor and the soft shadow the
   upper lip casts onto it. ---- */
.carved {
  background: var(--cut-floor);
  border: 5px solid;
  border-color: var(--cut-top) var(--cut-right) var(--cut-bottom) var(--cut-left);
  box-shadow:
    inset 0 10px 14px -10px var(--cut-shade),
    inset 8px 0 12px -10px var(--cut-shade);
}

/* Engraved lettering: the cut catches light along its lower edge */
.engraved { text-shadow: 0 1px 0 var(--engrave-hi); }

.game-best-label {
  font-size: 0.75rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0.4;
  font-weight: 500;
  white-space: nowrap;
}

.game-best-score {
  font-family: "Jacquard 24", serif;
  font-size: 1.3rem;
  color: var(--accent);
  opacity: 0.55;
  letter-spacing: 1px;
}

/* A gold coin, beside amounts of gold */
.coin-glyph {
  display: inline-block;
  flex: none;
  width: 0.72em;
  height: 0.72em;
  border-radius: 50%;
  background: radial-gradient(circle at 36% 34%, #fff1bf 0 16%, #e3b64b 22% 60%, #a6782a 66%);
  box-shadow: inset 0 0 0 1px rgba(110, 70, 20, 0.35), 0 1px 0 var(--engrave-hi);
}
.game-best-wrap .coin-glyph { align-self: center; width: 0.8rem; height: 0.8rem; margin-right: -0.25rem; }

/* ---- Heading: the games set as titles on one rule; the open one is
   inked in full and underlined where it meets the rule. ---- */
.game-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.75rem 1.5rem 1.1rem;
}
.game-heading {
  width: 100%;
  max-width: 700px;
  border-bottom: 1px solid var(--border);
}
.game-tabs {
  display: flex;
  justify-content: center;
  gap: 2.4rem;
}
.game-tab {
  position: relative;
  display: inline-flex;
  align-items: flex-start;
  gap: 0.35rem;
  padding: 0 0.15rem 0.75rem;
  font-size: 2.2rem;
  line-height: 1.2;
  color: var(--accent);
  background: none;
  border: 0;
  cursor: pointer;
  opacity: 0.35;
  transition: opacity 0.2s ease;
}
.game-tab::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transition: transform 0.25s ease;
}
.game-tab:hover { opacity: 0.7; }
.game-tab[aria-selected="true"] { opacity: 1; cursor: default; }
.game-tab[aria-selected="true"]::after { transform: scaleX(1); }
.game-tab:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.game-tab-tag {
  margin-top: 0.45rem;
  font-family: 'EB Garamond', Georgia, serif;
  font-size: 0.62rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  font-weight: 500;
  opacity: 0.7;
}

/* a mouse and a wide window: the titles step back so the games get the room */
@media (min-width: 1001px) and (hover: hover) and (pointer: fine) {
  .game-wrap { padding: 0.9rem 1.5rem 0.7rem; }
  .game-heading { max-width: 460px; }
  .game-tabs { gap: 1.9rem; }
  .game-tab { font-size: 1.5rem; padding-bottom: 0.45rem; }
  .game-tab-tag { margin-top: 0.25rem; font-size: 0.55rem; }
}

.games { position: relative; }
.game-panel[hidden] { display: none; }
/* Laid out (so canvases can measure themselves) but unseen until its
   script has run and the skeleton steps aside. */
.game-panel.loading {
  position: absolute;
  inset: 0 0 auto;
  visibility: hidden;
  pointer-events: none;
}

/* ---- Skeleton: the rough shape of the game on its way in, on the same
   grid the games use, so nothing jumps when it arrives. ---- */
.game-skeleton {
  --side: 260px;
  --gw: clamp(480px, min(100vw - 2 * var(--side) - 9rem, (100svh - 350px) * 16 / 9), 1080px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--gw) minmax(0, 1fr);
  column-gap: 3rem;
  row-gap: 1.25rem;
  align-items: start;
  padding: 0 1.5rem 6rem;
}
.game-skeleton[hidden] { display: none !important; }
/* A placeholder bar: warm ground with a slow light passing over it */
.game-skeleton .skeleton, .game-run .skeleton, .game-shop .skeleton {
  display: inline-block;
  vertical-align: middle;
  border-radius: 3px;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 252, 240, 0.55) 50%, transparent 65%) 0 0 / 300% 100%,
    rgba(90, 70, 45, 0.1);
  animation: skeleton-shine 1.6s linear infinite;
}
@keyframes skeleton-shine { from { background-position: 100% 0, 0 0; } to { background-position: -50% 0, 0 0; } }
@media (prefers-reduced-motion: reduce) {
  .game-skeleton .skeleton, .game-run .skeleton, .game-shop .skeleton { animation: none; }
}
.game-skeleton .skeleton { display: block; width: 100%; height: 100%; }
.sk-side { grid-row: 2; width: min(100%, var(--side)); }
.sk-left  { grid-column: 1; justify-self: end; height: 15rem; }
.sk-right { grid-column: 3; justify-self: start; width: 64px; height: 84px; }
.sk-bests { grid-column: 2; grid-row: 1; display: flex; justify-content: flex-end; gap: 1.6rem; height: 1.3rem; }
.sk-bests .skeleton { width: 7rem; }
.sk-main { grid-column: 2; grid-row: 2; aspect-ratio: 16 / 9; }

@media (max-width: 1100px) {
  .game-skeleton {
    --gw: min(100%, 720px);
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    row-gap: 1rem;
  }
  .sk-bests, .sk-main, .sk-left { grid-column: 1; width: var(--gw); }
  .sk-bests { grid-row: 1; justify-content: flex-end; }
  .sk-main { grid-row: 2; }
  .sk-left { grid-row: 3; margin-top: 1rem; }
  .sk-right { display: none; }
}

/* Run: the window's reveal already in place, the scene shimmering inside.
   Sized like run.css, where the reveal and the board's padding sit outside
   their columns, so they do here too. */
.game-skeleton[data-shape="run"] .sk-main {
  width: 100%;
  aspect-ratio: auto;
  height: auto;
  border: 30px solid;
  border-color: var(--win-top) var(--win-right) var(--win-bottom) var(--win-left);
  margin-bottom: 49px;
}
.game-skeleton[data-shape="run"] .sk-main .skeleton { aspect-ratio: 16 / 9; height: auto; border-radius: 0; }
.game-skeleton[data-shape="run"] .sk-bests { flex-wrap: wrap; row-gap: 0.2rem; height: auto; }
.game-skeleton[data-shape="run"] .sk-bests .skeleton { height: 20px; }
.game-skeleton[data-shape="run"] .sk-left { grid-row: 2 / span 2; height: 16rem; }
.game-skeleton[data-shape="run"] .sk-left .skeleton { width: calc(100% + 2.8rem); }
@media (max-width: 1100px) {
  /* under the window and its hint */
  .game-skeleton[data-shape="run"] .sk-main { width: var(--gw); }
  .game-skeleton[data-shape="run"] .sk-left { grid-row: 3; margin-top: 4.5rem; justify-self: center; }
}
@media (max-width: 640px) {
  .game-skeleton[data-shape="run"] .sk-main { border-width: 16px; margin-bottom: 38px; }
  .game-skeleton[data-shape="run"] .sk-left { margin-top: 5.7rem; }
  .game-skeleton[data-shape="run"] .sk-left .skeleton { width: 100%; }
}

/* Words: the scene and its panels on the left, the board on the right */
.game-skeleton[data-shape="words"] {
  --g: clamp(200px, calc((100svh - 415px) * 0.8), 380px);
  --sw: clamp(340px, min((var(--g) * 1.25 - 45px) * 2.18, 100vw - var(--g) - 5.5rem), 600px);
  display: grid;
  grid-template-columns: var(--sw) var(--g);
  grid-template-rows: auto auto auto;
  justify-content: center;
  column-gap: 2.5rem;
  row-gap: 1rem;
  justify-items: stretch;
  padding: 0 1.5rem 1.5rem;
}
.game-skeleton[data-shape="words"] .sk-bests { grid-column: 1 / -1; grid-row: 1; width: auto; justify-content: space-between; }
.game-skeleton[data-shape="words"] .sk-bests .skeleton { width: 8rem; }
.game-skeleton[data-shape="words"] .sk-left { display: block; grid-column: 1; grid-row: 2; width: auto; height: auto; aspect-ratio: 170 / 98; margin: 0; justify-self: stretch; }
.game-skeleton[data-shape="words"] .sk-right { display: block; grid-column: 1; grid-row: 3; width: auto; height: 10rem; margin: 0; justify-self: stretch; }
.game-skeleton[data-shape="words"] .sk-main { grid-column: 2; grid-row: 2 / span 2; width: auto; aspect-ratio: auto; height: calc(var(--g) * 1.25 + 180px); }
@media (max-width: 1000px) {
  .game-skeleton[data-shape="words"] {
    --rem: calc(100svh - 360px);
    --g: clamp(160px, min(100vw - 2rem, var(--rem) * 0.45), 400px);
    grid-template-columns: min(100vw - 2rem, 560px);
    padding: 0 1rem 1rem;
    row-gap: 0.6rem;
  }
  .game-skeleton[data-shape="words"] .sk-right { display: none; }
  .game-skeleton[data-shape="words"] .sk-main { grid-column: 1; grid-row: 3; width: var(--g); justify-self: center; height: calc(var(--g) * 1.25 + 140px); }
}
@media (max-width: 640px) {
  /* the same sizes as the board's phone layout */
  .game-skeleton[data-shape="words"] {
    --g: min(100vw - 2rem, 440px);
    --ch: clamp(100px, (100svh - 300px) * 0.34, (min(100vw - 1rem, 600px) - 10px) * 0.4588);
    --th: clamp(30px, (100svh - var(--ch) - 348px) / 5, var(--g) / 4 - 0.75rem);
    grid-template-columns: min(100vw - 1rem, 600px);
    padding: 0 0.5rem 1rem;
    row-gap: 0.45rem;
  }
  .game-skeleton[data-shape="words"] .sk-left { aspect-ratio: auto; height: calc(var(--ch) + 38px); }
  .game-skeleton[data-shape="words"] .sk-main { height: calc(var(--th) * 5 + 180px); }
}


.game-error {
  text-align: center;
  padding: 3rem 1.5rem 6rem;
  color: var(--danger-red);
  font-style: italic;
}
.game-error[hidden] { display: none; }
.game-retry {
  margin-left: 0.6rem;
  padding: 0.2rem 0.9rem;
  font: inherit;
  font-style: normal;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
}
.game-retry:hover, .game-retry:focus-visible { border-color: var(--accent); outline: none; }

@media (max-width: 640px) {
  .game-wrap { padding: 0.3rem 1rem 0.35rem; }
  /* the site's bar, slimmer here so the game keeps the window */
  .nav-inner { height: 44px; padding: 0 1rem; }
  .nav-logo { font-size: 1.6rem; }
  .theme-toggle { width: 30px; height: 30px; }
  .game-tabs { gap: 1.3rem; }
  .game-tab { font-size: 1.15rem; padding-bottom: 0.3rem; gap: 0.2rem; }
  .game-tab-tag { margin-top: 0.15rem; font-size: 0.5rem; letter-spacing: 1.5px; }
}

/* Shop: the alcove beside the shelf of niches */
.game-skeleton[data-shape="shop"] {
  display: grid;
  grid-template-columns: 270px minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: clamp(2rem, 4vw, 3.5rem);
  row-gap: 1.25rem;
  width: min(100% - 3rem, 960px);
  margin: 0 auto;
  padding: 0 0 6rem;
  justify-items: stretch;
}
.game-skeleton[data-shape="shop"] .sk-bests { grid-column: 1 / -1; grid-row: 1; width: auto; }
.game-skeleton[data-shape="shop"] .sk-bests .skeleton + .skeleton { display: none; }
.game-skeleton[data-shape="shop"] .sk-left { display: block; grid-column: 1; grid-row: 2; width: 260px; height: 340px; justify-self: center; margin: 0; }
.game-skeleton[data-shape="shop"] .sk-left .skeleton { border-radius: 130px 130px 3px 3px; }
.game-skeleton[data-shape="shop"] .sk-main { grid-column: 2; grid-row: 2; width: auto; aspect-ratio: auto; height: 340px; }
.game-skeleton[data-shape="shop"] .sk-right { display: none; }
@media (max-width: 720px) {
  .game-skeleton[data-shape="shop"] { grid-template-columns: minmax(0, 1fr); }
  .game-skeleton[data-shape="shop"] .sk-left { grid-column: 1; width: 220px; height: 290px; }
  .game-skeleton[data-shape="shop"] .sk-main { grid-column: 1; grid-row: 3; height: 420px; }
}
.gold-icon{width:1em;height:1em;display:inline-block;vertical-align:-.1em;fill:currentColor;color:#e3b64b}
.game-best-label .gold-icon{margin-right:2px;transform:translateY(1px)}
