/*
 * PowerPointless.
 *
 * Built for a projector in the back room of a bar, which sets almost every
 * decision here: type big enough to read from the back, contrast high enough
 * to survive a cheap lamp and the house lights being half up, and no webfont
 * or CDN anywhere, because the deck must not look different on the night the
 * venue wifi is bad.
 *
 * The red is the one in the room already -- the exit sign and the record
 * light on the camera at the back.
 */
:root {
  --ink: #0e0f13;
  --stage: #15161a;
  --bone: #f4f2ed;
  --muted: #8a8e9b;
  --signal: #e2342b;
  --line: #262830;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font: 16px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

/* ── Home ─────────────────────────────────────────────────────────────── */

.wrap { max-width: 56rem; margin: 0 auto; padding: 4rem 1.5rem 6rem; }

.brand {
  font-size: clamp(2.75rem, 9vw, 5rem);
  line-height: 0.95;
  font-weight: 800;
  letter-spacing: -0.03em;
  margin: 0;
}
.brand span { color: var(--signal); }

.lede {
  margin: 1.25rem 0 3rem;
  font-size: clamp(1.05rem, 2.4vw, 1.35rem);
  color: var(--muted);
  max-width: 34ch;
}

/* The form is a plain block: .ask and .dials each lay themselves out, and
   leaving the old flex rule here made them siblings competing for one row,
   which pushed the button onto its own line with 300px to spare. */
form { display: block; }

input[type="text"] {
  flex: 1 1 22rem;
  min-width: 0;
  background: var(--stage);
  border: 2px solid var(--line);
  color: var(--bone);
  font: inherit;
  font-size: 1.35rem;
  padding: 1rem 1.15rem;
  border-radius: 2px;
}
input[type="text"]:focus {
  outline: none;
  border-color: var(--signal);
}
input::placeholder { color: #5a5e6b; }

button, .btn {
  background: var(--signal);
  color: #fff;
  border: 0;
  font: inherit;
  font-size: 1.15rem;
  font-weight: 700;
  padding: 1rem 1.75rem;
  border-radius: 2px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}
button:hover, .btn:hover { filter: brightness(1.12); }
.btn--quiet {
  background: transparent;
  color: var(--muted);
  border: 2px solid var(--line);
  font-weight: 600;
}
.btn--quiet:hover { color: var(--bone); border-color: var(--muted); filter: none; }

.error { color: var(--signal); margin: 1rem 0 0; font-weight: 600; }

.past { margin-top: 4.5rem; border-top: 1px solid var(--line); padding-top: 1.5rem; }
.past h2 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  margin: 0 0 1.25rem;
  font-weight: 700;
}
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; list-style: none; margin: 0; padding: 0; }
.chips a {
  display: block;
  background: var(--stage);
  border: 1px solid var(--line);
  padding: 0.5rem 0.9rem;
  border-radius: 2px;
  text-decoration: none;
  font-size: 0.95rem;
  /* Someone will type a paragraph. The chip must not become the page. */
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chips a:hover { border-color: var(--signal); color: #fff; }
.empty { color: var(--muted); margin: 0; }

/* ── Slideshow ────────────────────────────────────────────────────────── */

.show { height: 100dvh; display: flex; flex-direction: column; }

.stage {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  min-height: 0;
}

/*
 * A fixed 16:9 box that scales to whatever it is projected on, so what is on
 * the screen is what is in the downloaded file. Type is sized in cqw against
 * the slide rather than the viewport: the layout has to hold at any projector
 * size, and a slide that reflows between the laptop and the room is a slide
 * nobody has rehearsed.
 */
.slide {
  width: min(100%, calc((100dvh - 7rem) * 16 / 9));
  aspect-ratio: 16 / 9;
  /* --bg, --ink, --muted and --accent are set per slide, inline, from the
     deck's palette and the photograph's own colour. Nothing below may
     hard-code a colour, or the slide stops matching its own deck. */
  background: var(--bg);
  color: var(--ink);
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 6%;
  container-type: inline-size;
}
.slide[hidden] { display: none; }

.words { position: relative; z-index: 2; min-width: 0; }

.slide h1 { font-size: 9cqw; line-height: 1.02; margin: 0; letter-spacing: -0.03em; font-weight: 800; color: var(--ink); }
.slide h2 { font-size: 6.2cqw; line-height: 1.08; margin: 0; letter-spacing: -0.02em; font-weight: 800; color: var(--ink); }
.slide p { font-size: 2.6cqw; color: var(--muted); margin: 1.2em 0 0; max-width: 40ch; }

/* A photograph behind the words needs a scrim, or the words are gone. */
.slide .bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
/* Weighted toward the side the words are on, rather than a flat wash: a slab
   of grey over the whole picture hides the photograph, and the photograph is
   the joke. */
.has-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(100deg, rgba(0,0,0,.82) 0%, rgba(0,0,0,.62) 45%, rgba(0,0,0,.38) 100%);
}
.slide--quote.has-bg::after,
.slide--question.has-bg::after,
.slide--big.has-bg::after,
.slide--title.has-bg::after {
  /* These are centred, so the darkening has to be even. */
  background: radial-gradient(ellipse at center, rgba(0,0,0,.76) 0%, rgba(0,0,0,.6) 100%);
}

/* ── Title ────────────────────────────────────────────────────────────── */

.kicker {
  margin-top: 1.6em;
  font-size: 1.8cqw;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted);
}

/* ── Statement ────────────────────────────────────────────────────────── */

.slide--statement.is-right,
.slide--statement.is-left { flex-direction: row; align-items: center; gap: 6%; }
.slide--statement.is-left { flex-direction: row-reverse; }
.slide--statement.is-right .words,
.slide--statement.is-left .words { flex: 1 1 0; }
.slide--statement figure {
  flex: 0 0 42%;
  margin: 0;
  align-self: stretch;
  display: flex;
}
.slide--statement img { width: 100%; height: 100%; object-fit: cover; }
/* Overlaid, the words sit on the photograph and get more room. */
.slide--statement.is-overlay h2 { font-size: 7cqw; max-width: 15ch; }

/* ── Quote ────────────────────────────────────────────────────────────── */

.slide--quote { align-items: center; text-align: center; }
.slide--quote .words { max-width: 84%; }
.slide--quote h2 { font-size: 5cqw; }
.attrib { margin-top: 1.4em; font-size: 2.4cqw; color: var(--accent); font-weight: 600; }

/* ── Big number ───────────────────────────────────────────────────────── */

.slide--big { align-items: center; text-align: center; }
.slide--big .kicker { margin: 0 0 0.6em; }
.stat {
  font-size: 20cqw;
  line-height: 0.88;
  font-weight: 800;
  letter-spacing: -0.045em;
  color: var(--accent);
  /* The figure is the slide. Tabular digits stop it shifting between decks. */
  font-variant-numeric: tabular-nums;
}
.slide--big p { margin: 0.5em auto 0; color: var(--ink); max-width: 24ch; font-size: 3cqw; }

/* ── Question ─────────────────────────────────────────────────────────── */

.slide--question { align-items: center; text-align: center; }
.slide--question h2 { font-size: 8cqw; max-width: 14ch; }

/* ── Chart ────────────────────────────────────────────────────────────── */

.slide--chart { justify-content: flex-start; padding-top: 7%; }
.slide--chart h2 { font-size: 5.4cqw; }
.plot {
  display: flex; align-items: flex-end; gap: 2.5cqw;
  flex: 1; margin-top: 5cqw; min-height: 0; position: relative; z-index: 2;
}
.bar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
.bar i { display: block; background: var(--accent); width: 100%; }
.bar .v { font-size: 2.2cqw; font-weight: 800; text-align: center; margin-bottom: .4em; color: var(--ink); }
.bar .l { font-size: 1.9cqw; color: var(--muted); text-align: center; margin-top: .5em; }

/* ── Lists: the mid-deck lessons and the closing asks ─────────────────── */

.slide ul { margin: 1.4em 0 0; padding: 0; list-style: none; }
.slide li { font-size: 3.2cqw; margin: .55em 0; font-weight: 600; color: var(--ink); }
/* A hairline rule per item: structure that says "these are separate claims",
   which is exactly what the performer has to defend one at a time. Drawn in
   the slide's own ink so it works on a light ground as well as a dark one. */
.slide--list li { border-top: 1px solid color-mix(in srgb, var(--ink) 22%, transparent); padding-top: .5em; }

.credit {
  position: absolute; right: 2%; bottom: 1.5%;
  font-size: 1.3cqw; color: rgba(255,255,255,.45); z-index: 3;
  max-width: 45%; text-align: right;
}

/* ── Controls ─────────────────────────────────────────────────────────── */

.bar-controls {
  display: flex; align-items: center; gap: 1rem;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.nav { display: flex; gap: 0.5rem; }
.nav button {
  background: var(--stage); border: 2px solid var(--line); color: var(--bone);
  font-size: 1.4rem; line-height: 1; padding: 0.55rem 1.1rem; font-weight: 700;
}
.nav button:hover:not(:disabled) { border-color: var(--signal); filter: none; }
.nav button:disabled { opacity: 0.3; cursor: default; }

.counter { font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 700; letter-spacing: .05em; }
.said { flex: 1; min-width: 0; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.said b { color: var(--bone); font-weight: 700; }
.actions { display: flex; gap: 0.5rem; }
.actions .btn { font-size: 0.95rem; padding: 0.6rem 1rem; }

:focus-visible { outline: 3px solid var(--signal); outline-offset: 2px; }

@media (max-width: 620px) {
  .slide--statement.is-right, .slide--statement.is-left { flex-direction: column; justify-content: center; }
  .slide--statement figure { flex: 0 0 38%; width: 100%; }
  .said { display: none; }
}

/* ── Building a deck ──────────────────────────────────────────────────── */

body.is-building { overflow: hidden; }

.building {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  background: rgba(14, 15, 19, 0.94);
  padding: 2rem;
  text-align: center;
}
.building[hidden] { display: none; }

.building__inner { max-width: 30rem; }

/* Five slide-shaped bars that fill one after another. The deck is what is
   being waited for, so that is what the indicator shows. */
.building__slides {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  margin-bottom: 2rem;
}
.building__slides i {
  display: block;
  width: 3.4rem;
  aspect-ratio: 16 / 9;
  border: 2px solid var(--line);
  background: linear-gradient(to right, var(--signal) 50%, transparent 50%) right / 200% 100% no-repeat;
  animation: fill 2.6s ease-in-out infinite;
}
.building__slides i:nth-child(2) { animation-delay: 0.16s; }
.building__slides i:nth-child(3) { animation-delay: 0.32s; }
.building__slides i:nth-child(4) { animation-delay: 0.48s; }
.building__slides i:nth-child(5) { animation-delay: 0.64s; }

@keyframes fill {
  0%, 10%   { background-position: right; }
  45%, 65%  { background-position: left; }
  100%      { background-position: right; }
}

.building__word {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--bone);
}
.building__step {
  margin: 0;
  color: var(--muted);
  font-size: 1rem;
  letter-spacing: 0.02em;
}

input[readonly] { opacity: 0.6; }
button:disabled { opacity: 0.5; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  /* No sweep. The bars stay filled, so the panel still reads as "working"
     rather than as a frozen page. */
  .building__slides i { animation: none; background-position: left; }
}

/* ── The two dials ────────────────────────────────────────────────────── */

.ask { display: flex; gap: 0.75rem; flex-wrap: wrap; }

.dials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.75rem 2.5rem;
  margin-top: 1.75rem;
}

.dial { display: block; }

.dial__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.7rem;
}
.dial__head output {
  font-size: 1.05rem;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 700;
  color: var(--bone);
  font-variant-numeric: tabular-nums;
}

.dial__note {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.9rem;
  color: var(--muted);
  /* Reserved, so the layout does not jump as the label changes length. */
  min-height: 1.35em;
}

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 0.4rem;
  border-radius: 2px;
  background: linear-gradient(to right, var(--signal) var(--pct, 50%), var(--line) var(--pct, 50%));
  cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 50%;
  background: var(--bone);
  border: 3px solid var(--signal);
  cursor: grab;
}
input[type="range"]::-moz-range-thumb {
  width: 1.3rem;
  height: 1.3rem;
  border: 3px solid var(--signal);
  border-radius: 50%;
  background: var(--bone);
  cursor: grab;
}
input[type="range"]::-moz-range-track { background: transparent; }

.said em { font-style: normal; color: var(--muted); opacity: .75; margin-left: .5rem; }

/* ── Synopsis ─────────────────────────────────────────────────────────── */

.synopsis { margin: 1.25rem 0 2.5rem; max-width: 46ch; }
.synopsis p { margin: 0 0 0.9rem; font-size: 1.12rem; line-height: 1.55; color: #c9cdd6; }
.synopsis p:first-child { font-size: 1.35rem; color: var(--bone); }
/* The mechanics, set apart from the description of the game itself. */
.synopsis__how {
  font-size: 0.98rem !important;
  color: var(--muted) !important;
  border-left: 2px solid var(--line);
  padding-left: 1rem;
  margin-top: 1.4rem !important;
}
