/*
  The game site's own look: the Hall.

  Two things meet here. From the forum it keeps the material: basalt with its cloud of marble,
  brass for every line that works, warm pale ink, turquoise for light, and one engraved frieze
  where the page changes from the front door to the reading. From the entrance it keeps the
  character: the board's pixel face, plates with stepped corners that hang from a girder, a seal and
  a name made of dots, and heat. Heat is the one colour that moves: the seal, the burning name, the
  key you are pointing at.

  It shares the forum's palette and skin and none of its frame, so a page here is not a forum page.
  Order: tokens, page, header (beam, chains, plates, account), hero, frieze, keys, links, footer,
  narrow screens, preferences. The buttons, fields, chips and lamps are the kit's (components.css).
*/

/* ------------------------------------------------------------------ tokens */

:root {
  --ground: var(--basalt-0);
  --text: var(--ink);
  --text-dim: var(--ink-dim);
  --text-faint: var(--ink-faint);
  --amber: var(--brass);
  --amber-dim: var(--brass-mid);
  --amber-deep: var(--brass-lo);
  --tube: var(--arc);
  --reach: 1200px;
  --drop: 2.6rem;
  --ease: cubic-bezier(.16, 1, .3, 1);
}

/* ------------------------------------------------------------------ page */

html { background: var(--ground); }
/* The ground: riveted iron plates, drawn in pixels, kept dark enough to read on. */
body.hall {
  background:
    linear-gradient(180deg, #0d0d0d00, #0d0d0d99 60%, #0d0d0dcc),
    url("img/wall.svg") 0 0 / 144px 144px,
    var(--ground);
  color: var(--text);
  font: 400 .9375rem/1.7 var(--body);
  overflow-x: clip;
}
body.hall::before { content: none; }
body.hall::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 70;
  pointer-events: none;
  background: url("img/grain.webp") 0 0 / 256px 256px;
  opacity: .45;
}
.hall main { display: block; }
:where(.hall) a { color: var(--brass); }
:where(.hall) a:hover { color: var(--brass-hi); }
.hall ::selection { background: var(--brass); color: #191918; }
.hall :focus-visible { outline: 3px solid var(--tube); outline-offset: 2px; }
.reach { width: min(100% - 2.4rem, var(--reach)); margin-inline: auto; }

/* ------------------------------------------------------------------ header: beam, chains, plates */

.head { position: relative; z-index: 20; }
.landing .head { position: absolute; inset: 0 0 auto 0; }
.beam {
  position: relative;
  height: .75rem;
  background: linear-gradient(180deg, #5b564b 0, #2d2c2b 30%, #0f0e0e 100%);
  box-shadow: 0 1px 0 #000, 0 8px 14px #000b;
}
.beam::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, #f0d8a4 0 1px, #8b6c34 2px, transparent 2.6px) 0 50% / 6rem 100% repeat-x;
}
.beam::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; background: var(--brass-mid); opacity: .8; }

.head-row { display: flex; align-items: flex-start; gap: 1rem; width: min(100% - 1.6rem, 1500px); margin-inline: auto; }
.slabs { flex: 1 1 auto; min-width: 0; }
.slabs ul { display: flex; flex-wrap: wrap; justify-content: center; gap: .35rem clamp(.4rem, .9vw, .9rem); margin: 0; padding: 0; list-style: none; }
.slabs li, .acct-slab { position: relative; padding-top: var(--drop); filter: drop-shadow(0 4px 0 #000b); }
.slabs li::before, .slabs li::after, .acct-slab::before, .acct-slab::after {
  content: "";
  position: absolute;
  top: -1px;
  width: .75rem;
  height: calc(var(--drop) + 4px);
  background: url("img/chain.svg") center top / .75rem 1.5rem repeat-y;
  image-rendering: pixelated;
}
.slabs li::before, .acct-slab::before { left: 18%; }
.slabs li::after, .acct-slab::after { right: 18%; }

/* A plate: basalt in a brass rim, the corners stepped. Pointed at, it comes up to heat. */
.slab {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 3.1rem;
  padding: .4rem clamp(.8rem, 1.1vw, 1.2rem);
  font: 400 16px/1 var(--pixel);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  color: var(--brass);
  background: var(--brass-mid);
  clip-path: var(--step);
  transition: color 90ms steps(2), transform 300ms var(--ease);
  transform-origin: 50% calc(-1 * var(--drop));
}
.slab::before {
  content: "";
  position: absolute;
  inset: 2px;
  z-index: -1;
  background:
    linear-gradient(180deg, #ffffff10, transparent 45%),
    linear-gradient(#1b1a19e8, #141413f0),
    url("img/basalt.webp") 0 0 / 256px 256px;
  clip-path: var(--step);
  --s: 2px;
}
.slab .seal-glyph { width: 1.05rem; height: 1.05rem; flex: none; }
.slab-seal { display: inline-grid; place-items: center; }
.slab:hover { color: #180b03; transform: rotate(-.6deg); }
.slabs li:nth-child(even) .slab:hover { transform: rotate(.6deg); }
.slab:hover::before { background: var(--heat-2); }
.slab[aria-current] { color: #191918; }
.slab[aria-current]::before { background: var(--brass); }
.slab-play { color: #180b03; }
.slab-play::before { background: var(--heat-2); }
.slab-play:hover::before { background: var(--heat-3); }

.acct { flex: none; display: flex; align-items: flex-start; gap: .5rem clamp(.4rem, 1vw, .9rem); }
.acct-slab { display: block; }
.slab-quiet { color: var(--ink-dim); }
.acct-name { display: grid; padding-top: calc(var(--drop) + .35rem); font: .75rem/1.4 var(--ui); color: var(--ink-faint); text-align: right; }
.acct-name b { font: 400 14px/1.3 var(--pixel); letter-spacing: .04em; color: var(--brass-hi); }
.acct-form { margin: 0; }
.acct-form .slab { cursor: pointer; border: 0; }
.acct-sigil { padding-top: calc(var(--drop) + .15rem); }

.cmd { display: none; align-self: flex-start; padding-top: calc(var(--drop) + .5rem); }
@media (min-width: 1620px) { .cmd { display: block; } }
.cmdbar { position: relative; display: flex; align-items: center; gap: .4rem; margin: 0; }
.cmdbar .cmd-prompt { font: 400 16px/1 var(--pixel); color: var(--brass); }
.cmdbar input {
  width: clamp(7rem, 12vw, 11rem);
  padding: .4rem .6rem;
  font: 400 16px/1.2 var(--pixel);
  color: var(--ink);
  background: #0c0b0b;
  border: 0;
  border-radius: 0;
  box-shadow: inset 0 0 0 2px #000, inset 2px 2px 0 2px var(--well-lo), inset -2px -2px 0 2px var(--well-hi);
  caret-color: var(--heat-3);
}
.cmdbar input:focus { box-shadow: inset 0 0 0 2px #000, inset 2px 2px 0 2px var(--well-lo), inset -2px -2px 0 2px var(--heat-3); }
.cmdbar input::placeholder { color: var(--ink-faint); opacity: 1; }
.cmdbar .btn { display: none; }
.cmdbar .cmd-say { position: absolute; top: calc(100% + .45rem); right: 0; z-index: 30; width: max-content; max-width: 22rem; padding: .4rem .7rem; font: 14px/1.4 var(--pixel); color: var(--ink); background: #0c0b0b; box-shadow: inset 0 0 0 2px #000, inset 2px 2px 0 2px var(--bev-hi), inset -2px -2px 0 2px var(--bev-lo); }
.cmdbar .cmd-say:empty { display: none; }
.cmdbar-foot .cmd-say { top: auto; bottom: calc(100% + .45rem); left: 0; right: auto; }

/* ------------------------------------------------------------------ hero */

/* Marble in the dark, and a fire. The picture is the entrance; what it leaves is this: the forum's
   basalt, lit from below by the name burning. */
.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  align-items: center;
  min-height: clamp(30rem, 80vh, 46rem);
  min-height: clamp(30rem, 80svh, 46rem);
  padding: 8.5rem 1.2rem 4.5rem;
  overflow: hidden;
  background:
    radial-gradient(ellipse 62% 50% at 50% 56%, #ff741a30, transparent 72%),
    linear-gradient(#0d0d0dd8, #0d0d0de6),
    url("img/basalt.webp") 0 0 / 384px 384px,
    var(--ground);
}
/* Scanlines over the whole of it, as on the screen the entrance began on. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: repeating-linear-gradient(180deg, transparent 0 2px, #00000030 2px 4px);
}
.hero-embers { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.hero-inner { position: relative; z-index: 1; display: grid; justify-items: center; gap: 1.1rem; text-align: center; }

/* The seal, lit: three lines each broken at the middle, six bars of iron come up to heat. */
.lit-seal {
  width: clamp(4.5rem, 8vw, 6.5rem);
  height: auto;
  overflow: visible;
  filter: drop-shadow(0 0 2px #ffd9a0) drop-shadow(0 0 12px #ff741acc) drop-shadow(0 0 34px #ff5a1088);
  animation: seal-breathe 5.4s steps(18) infinite;
}
.lit-seal .b0, .lit-seal .b1 { fill: var(--heat-4); }
.lit-seal .b2, .lit-seal .b3 { fill: var(--heat-3); }
.lit-seal .b4, .lit-seal .b5 { fill: var(--heat-2); }
@keyframes seal-breathe {
  0%, 100% { opacity: 1; }
  34% { opacity: .9; }
  58% { opacity: .97; }
  80% { opacity: .92; }
}
html[data-fx="calm"] .lit-seal { animation: none; }

.logo { margin: 0; line-height: 1; width: 100%; display: grid; justify-items: center; }
/* The name: block lettering, each stroke two dots, and a fire drawn in characters on top of it. */
.logo-fire { position: relative; width: min(100%, 62rem); aspect-ratio: 71 / 24; }
.logo-art {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 33.3333%;
  overflow: visible;
  filter: drop-shadow(0 0 10px #ff741a77) drop-shadow(0 3px 0 #000);
  animation: letters-burn 2.2s steps(1) infinite;
}
.logo-art .b0 { fill: var(--heat-5); }
.logo-art .b1 { fill: var(--heat-4); }
.logo-art .b2 { fill: var(--heat-3); }
.logo-art .b3 { fill: var(--heat-2); }
@keyframes letters-burn {
  0%, 100% { filter: drop-shadow(0 0 10px #ff741a77) drop-shadow(0 3px 0 #000); }
  25% { filter: drop-shadow(0 0 16px #ff741aaa) drop-shadow(0 3px 0 #000); }
  60% { filter: drop-shadow(0 0 8px #ff741a55) drop-shadow(0 3px 0 #000); }
  80% { filter: drop-shadow(0 0 14px #ff741a99) drop-shadow(0 3px 0 #000); }
}
html[data-fx="calm"] .logo-art { animation: none; }
.logo-fire canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; filter: drop-shadow(0 0 4px #ff741a99); }
.logo:focus, .logo:focus-visible { outline: none; }
.tagline { margin: 0; font: 400 18px/1.4 var(--pixel); letter-spacing: .04em; color: var(--ink-dim); }
.tagline .cursor { display: inline-block; width: .55em; height: 1em; margin-left: .35em; vertical-align: -.12em; background: var(--heat-3); animation: cursor-blink 1s steps(1) infinite; }
@keyframes cursor-blink { 50% { opacity: 0; } }
html[data-fx="calm"] .tagline .cursor { animation: none; }

.hero-keys { display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem 1.4rem; margin-top: .6rem; }
.hero-state {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin: 0;
  font: 400 16px/1.2 var(--pixel);
  letter-spacing: .04em;
  color: var(--ink-dim);
}
.hero-state b { font-weight: 400; text-transform: uppercase; color: var(--tube); }

/* ------------------------------------------------------------------ frieze */

/* The band where the front door ends and the page begins: a walkway over a drop with the city beyond
   it (img/scene-concourse.svg, a tile, `--px` screen pixels to a pixel of art), and on it a crowd of
   hooded figures that website/concourse.js draws and keeps walking. */
.frieze {
  --px: 3;
  position: relative;
  z-index: 2;
  height: calc(var(--px) * 40px);
  overflow: hidden;
  background:
    linear-gradient(90deg, #0d0d0d 0, transparent 8%, transparent 92%, #0d0d0d 100%),
    url("img/scene-concourse.svg") 0 100% / auto calc(var(--px) * 40px) repeat-x,
    #0a0807;
  border-block: 2px solid var(--brass-mid);
  box-shadow: 0 0 0 2px #000, 0 10px 18px #0009;
}
.frieze canvas { position: absolute; left: 0; bottom: 0; image-rendering: pixelated; }

/* ------------------------------------------------------------------ keys and fields */

/* A key is its word between brackets. Pointed at, it fills with heat and the word goes dark. */
.key {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 11rem;
  min-height: 3.2rem;
  padding: .6rem 1.4rem;
  font: 400 20px/1 var(--pixel);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  color: var(--brass);
  cursor: pointer;
  background: #0c0b0b;
  border: 2px solid var(--brass-mid);
  transition: background-color 80ms steps(2), color 80ms steps(2), border-color 80ms steps(2);
}
.key::before { content: "["; margin-right: .6em; color: var(--brass-mid); }
.key::after { content: "]"; margin-left: .6em; color: var(--brass-mid); }
.key:hover { color: #170a02; background: var(--heat-3); border-color: var(--heat-4); }
.key:hover::before, .key:hover::after { color: #170a02; }
.key:active { transform: translateY(2px); }
.key-hot { color: var(--heat-4); border-color: var(--heat-2); box-shadow: 0 0 0 2px #000, 0 0 22px #ff741a55, inset 0 0 18px #ff741a22; animation: key-flicker 3.6s steps(24) infinite; }
.key-hot::before, .key-hot::after { color: var(--heat-2); }
.key-hot:hover { background: var(--heat-2); border-color: var(--heat-4); }
@keyframes key-flicker {
  0%, 100% { box-shadow: 0 0 0 2px #000, 0 0 22px #ff741a55, inset 0 0 18px #ff741a22; }
  40% { box-shadow: 0 0 0 2px #000, 0 0 30px #ff741a88, inset 0 0 22px #ff741a38; }
  70% { box-shadow: 0 0 0 2px #000, 0 0 18px #ff741a44, inset 0 0 14px #ff741a1a; }
}
html[data-fx="calm"] .key-hot { animation: none; }

/* ------------------------------------------------------------------ links */

/* A link that stands on a line of its own is given a target of 24 pixels or more. */
.linkline a, .more-line a, .hall .linkish { display: inline-block; padding-block: .3rem; }
.rows { margin: 0; padding: 0; list-style: none; }

/* ------------------------------------------------------------------ footer */

.foot {
  position: relative;
  margin-top: 3rem;
  padding: 2.4rem 0 1.4rem;
  background:
    linear-gradient(#0d0d0de8, #0d0d0df5),
    url("img/wall.svg") 0 0 / 144px 144px;
  border-top: 2px solid var(--brass-mid);
  box-shadow: inset 0 3px 0 #000;
}
.foot-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); gap: 1.4rem 2.5rem; }
.foot-name { margin: 0 0 .4rem; font: 400 24px/1.2 var(--pixel); letter-spacing: .12em; text-transform: uppercase; color: var(--brass-hi); }
.foot p { margin: 0; font: .875rem/1.6 var(--ui); color: var(--ink-dim); }
.foot ul { margin: 0; padding: 0; list-style: none; }
.foot li a { display: inline-block; padding: .2rem 0; font: 400 16px/1.4 var(--pixel); letter-spacing: .04em; text-decoration: none; }
.foot li a::before { content: "> "; color: var(--brass-mid); }
.foot li a:hover { text-decoration: underline; }
/* The lantern in the footer, in the board's block characters: the cap and handle dark, the frame
   brass, the glass shaded from orange at the edge to pale gold in the middle. */
.lamp-art { margin: .8rem 0 0; font: 400 16px/16px var(--pixel); color: var(--brass); }
.lamp-art .lc { color: var(--brass-lo); }
.lamp-art .lf { color: var(--brass-mid); }
.lamp-art .ga { color: var(--heat-2); }
.lamp-art .gb { color: var(--heat-3); }
.lamp-art .gc { color: var(--heat-4); }
.lamp-art .flame { animation: lamp-frames 1.2s steps(1) infinite; }
@keyframes lamp-frames { 0%, 100% { opacity: 1; } 33% { opacity: .75; } 66% { opacity: .92; } }
html[data-fx="calm"] .lamp-art .flame { animation: none; }
.foot-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .8rem 2rem; margin-top: 1.6rem; padding-top: 1rem; border-top: 2px solid var(--brass-deep); }
.pixel-link { font: 400 14px/1.4 var(--pixel); letter-spacing: .06em; text-transform: uppercase; }
.foot-credit { margin: 1rem 0 0; font: .75rem/1.5 var(--read); color: var(--ink-faint); }
.fxswitch { display: flex; align-items: center; gap: .3rem; margin: 0; padding: 0; border: 0; }
.fxswitch legend { float: left; padding: 0 .8rem 0 0; font: 400 14px/2rem var(--pixel); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
.fxswitch label { position: relative; margin: 0; }
.fxswitch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.fxswitch span { display: inline-flex; align-items: center; min-height: 2rem; padding: 0 .8rem; font: 400 16px/1 var(--pixel); letter-spacing: .06em; text-transform: uppercase; color: var(--brass); text-shadow: 2px 2px 0 #000; background: linear-gradient(var(--plate-a) 0 50%, var(--plate-b) 50% 100%); box-shadow: inset 0 0 0 2px #000, inset 2px 2px 0 2px var(--bev-hi), inset -2px -2px 0 2px var(--bev-lo); }
.fxswitch input:checked + span { color: var(--heat-ink); text-shadow: none; background: linear-gradient(var(--heat-4) 0 50%, var(--heat-3) 50% 100%); box-shadow: inset 0 0 0 2px #000, inset 2px 2px 0 2px var(--heat-5), inset -2px -2px 0 2px #b0561a; }
.fxswitch input:focus-visible + span { outline: 3px solid var(--tube); outline-offset: 2px; }
.fxswitch input:disabled:not(:checked) + span { opacity: .6; }

/* ------------------------------------------------------------------ narrow screens */

@media (max-width: 860px) {
  :root { --drop: 1.2rem; }
  .head-row { flex-wrap: wrap; justify-content: center; }
  .acct { flex: 1 0 100%; justify-content: center; }
  .acct-slab::before, .acct-slab::after { display: none; }
  .acct-slab { padding-top: .3rem; }
  .acct-name { padding-top: .3rem; }
  .slabs { flex: 1 0 100%; }
  .slabs ul { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem .5rem; }
  .slab { width: 100%; padding-inline: .5rem; font-size: 14px; letter-spacing: .02em; }
  /* The plates wrap to rows here, so the header takes its own height and the hero starts under it. */
  .landing .head { position: relative; }
  .hero { padding-top: 2.4rem; }
  .foot-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .slabs ul { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero { padding-top: 2rem; padding-bottom: 3.5rem; }
  .tagline { font-size: 16px; }
  .key { min-width: 10rem; }
  .frieze { --px: 2; }
}

/* ------------------------------------------------------------------ preferences */

@media (prefers-contrast: more) {
  body.hall::after, .hero::after { display: none; }
  .slab { background: var(--brass); }
}
@media (prefers-reduced-motion: reduce) {
  .slab, .key { transition: none; }
  .slab:hover { transform: none; }
  .key-hot, .lit-seal, .logo-art, .tagline .cursor, .hall .lamp-on::before, .lamp-art .flame { animation: none; }
}
