/* Slot the Horde: the site is a week of The Sentinel, Nelson City's paper,
   lying on a dark desk. The paper is the city's side of the story; the green
   plaques and the slot machine are yours. Everything is cut on a 4px grid so
   it sits with the game's pixel art. */

@font-face { font-family: "Kingdom"; src: url("fonts/Kingdom_v1.4.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Newsgeek"; src: url("fonts/Newsgeek.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Newsgeek Serif"; src: url("fonts/NewsgeekSerif.ttf") format("truetype"); font-display: swap; }

:root {
  /* The desk: the game's night purple. */
  --desk: #120b18;
  --desk-2: #1a1124;
  --desk-line: #2d1d40;
  /* Newsprint, fresh to filthy. */
  --paper: #e9e1ce;
  --paper-worn: #dfd5bd;
  --paper-grimy: #cdc0a2;
  --ink: #1a151b;
  --ink-soft: #51474c;
  /* The machine. */
  --cab: #32453a;
  --cab-dark: #151e19;
  --cab-black: #040404;
  --cab-light: #496c57;
  --mint: #cee9d9;
  --blood: #b3202a;
  --blood-dark: #84161e;
  --amber: #e9a63a;

  --bar: 56px;
  --gut: clamp(12px, 4vw, 72px);   /* desk showing either side of a sheet */
  --pad: clamp(16px, 3vw, 44px);   /* a sheet's own margin */
  --s: 3; /* slot machine: screen pixels per art pixel */
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--bar) + 16px); overflow-x: clip; }

body {
  margin: 0;
  color: var(--mint);
  font: 16px/1.5 "Newsgeek", ui-monospace, monospace;
  /* A two-tone dither, like the game's backdrops. */
  background-color: var(--desk);
  background-image:
    linear-gradient(45deg, var(--desk-2) 25%, transparent 25%, transparent 75%, var(--desk-2) 75%),
    linear-gradient(45deg, var(--desk-2) 25%, transparent 25%, transparent 75%, var(--desk-2) 75%);
  background-size: 8px 8px;
  background-position: 0 0, 4px 4px;
  overflow-x: hidden;
  -webkit-font-smoothing: none;
}

img, video, canvas { display: block; max-width: 100%; }
a { color: inherit; }
p, ul, h1, h2, h3, figure, blockquote { margin: 0; padding: 0; }
ul { list-style: none; }
h1, h2, h3 { font-weight: 400; }
:focus-visible { outline: 4px solid var(--amber); outline-offset: 4px; }

/* ---------- The bar across the top ---------- */
.hud {
  position: fixed; inset: 0 0 auto 0; z-index: 30;
  height: var(--bar);
  display: flex; align-items: center; gap: 24px;
  padding: 0 clamp(12px, 3vw, 32px);
  background: var(--desk);
  border-bottom: 4px solid var(--desk-line);
  text-transform: uppercase;
  transition: transform .2s steps(4);
}
.hud.hide { transform: translateY(-100%); }

.studio { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--mint); }
.studio img { width: 32px; height: 32px; mix-blend-mode: screen; image-rendering: pixelated; }

.hud nav { display: flex; gap: 20px; margin-left: auto; }
.hud nav a { text-decoration: none; color: #9c8fae; padding: 4px 0; border-bottom: 4px solid transparent; }
.hud nav a b { font-weight: 400; color: var(--amber); margin-right: 4px; }
.hud nav a:hover, .hud nav a.here { color: var(--mint); border-color: var(--blood); }

.tally {
  display: flex; align-items: center; gap: 8px;
  min-width: 80px; padding: 4px 12px 4px 8px;
  background: var(--cab-dark); border: 4px solid var(--cab);
  color: var(--amber); font-size: 16px; line-height: 24px;
}
.tally img { width: 24px; height: 24px; image-rendering: pixelated; }
.tally b { font-weight: 400; }
.tally.bump { animation: bump .25s steps(3); }
@keyframes bump { 50% { transform: translateY(-4px); background: var(--cab); } }

.buy {
  background: var(--blood); color: #fff; text-decoration: none;
  padding: 8px 16px; box-shadow: 4px 4px 0 #000;
}
.buy:hover { background: var(--blood-dark); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block; padding: 12px 24px;
  font: 32px/1 "Newsgeek", monospace; text-transform: uppercase; text-decoration: none;
  color: #fff; background: var(--blood);
  border: 4px solid var(--ink);
  box-shadow: 8px 8px 0 var(--ink);
  transition: transform .1s steps(2), box-shadow .1s steps(2);
}
.btn:hover { transform: translate(-4px, -4px); box-shadow: 12px 12px 0 var(--ink); }
.btn:active { transform: translate(4px, 4px); box-shadow: 4px 4px 0 var(--ink); }

/* ---------- A sheet of newspaper ---------- */
main { padding-top: calc(var(--bar) + 24px); }

.sheet {
  position: relative;
  width: min(1440px, 100% - 2 * var(--gut));
  margin: 0 auto 112px;
  color: var(--ink);
}
/* The hard shadow under a sheet: the same torn outline, pushed down and right. */
.sheet::before {
  content: ""; position: absolute; inset: 0;
  background: #000; opacity: .55;
  transform: translate(12px, 12px);
  clip-path: var(--tear, none);
}
.sheet-in {
  position: relative;
  padding: 16px var(--pad) 56px;
  background-color: var(--paper);
  /* Faint print dots. */
  background-image: radial-gradient(rgba(26, 21, 27, .07) 1px, transparent 1.5px);
  background-size: 4px 4px;
  clip-path: var(--tear, none);
}
/* Only the front page lets things hang off its edge (the headline card, the machine). */
.sheet:not(.front) .sheet-in { overflow: hidden; }
.sheet[data-wear="1"] .sheet-in { background-color: var(--paper-worn); }
.sheet[data-wear="2"] .sheet-in { background-color: var(--paper-grimy); }

/* Sheets lie a little off-centre, and land with a couple of hard steps. */
@media (min-width: 1100px) {
  .shift-l { left: -28px; }
  .shift-r { left: 36px; }
}
.js .sheet:not(.front) { transform: translate(0, 48px); opacity: 0; }
.js .sheet.in { transform: none; opacity: 1; transition: transform .28s steps(4), opacity .12s steps(2); }

/* Blood and dirt, painted by script.js as small pixel maps. */
.stain {
  position: absolute; z-index: 0; pointer-events: none;
  image-rendering: pixelated; mix-blend-mode: multiply;
}
/* The front page only bleeds once your horde has done some biting. */
.stain.late-1, .stain.late-2 { display: none; }
.bled-1 .late-1, .bled-2 .late-2 { display: block; }

/* ---------- Newspaper furniture ---------- */
.masthead {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end; gap: 16px;
  padding-bottom: 4px;
}
.paper-name { font: 96px/1 "Kingdom", serif; text-align: center; grid-column: 2; }

.dateline {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 4px 0; margin-bottom: 16px;
  border-top: 4px solid var(--ink); border-bottom: 4px double var(--ink);
  text-transform: uppercase;
}
.dateline .name { font: 32px/24px "Kingdom", serif; text-transform: none; }

.headline {
  font: 96px/.9 "Newsgeek Serif", serif; text-transform: uppercase;
  margin: 4px 0 12px;
}
.headline.huge { font-size: 128px; }
.sub { font: 32px/1.1 "Newsgeek Serif", serif; margin-bottom: 24px; padding-bottom: 16px; border-bottom: 4px solid var(--ink); }

.copy { max-width: 520px; }
.copy p { margin-bottom: 12px; }
.copy p:first-child::first-letter { font: 48px/40px "Newsgeek Serif", serif; float: left; padding: 4px 6px 0 0; }
.copy.lone { margin-bottom: 28px; }

.photo { position: relative; z-index: 1; }
.photo .frame { border: 4px solid var(--ink); background: #000; overflow: hidden; }
.photo video, .photo img { width: 100%; height: auto; }
.photo figcaption { padding-top: 8px; color: var(--ink-soft); }
.photo figcaption::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 8px; background: var(--ink-soft); }



/* ---------- Your side of the story: a plate off the machine ---------- */
.plaque {
  position: relative; z-index: 1;
  padding: 20px 24px 22px;
  color: var(--mint);
  background: var(--cab-dark);
  border: 4px solid var(--cab-black);
  box-shadow: inset 0 0 0 4px var(--cab), inset 0 0 0 8px var(--cab-black), 8px 8px 0 rgba(0, 0, 0, .6);
}
/* Rivets in the corners. */
.plaque::before, .plaque::after {
  content: ""; position: absolute; top: 12px; width: 4px; height: 4px;
  background: var(--cab-light);
}
.plaque::before { left: 12px; }
.plaque::after { right: 12px; }
.plaque h3 { font: 48px/1 "Kingdom", serif; color: var(--amber); margin: 4px 0 12px; }
.plaque p { font-size: 24px; line-height: 32px; }

/* ---------- Tuesday: the front page ---------- */
.front-grid {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) calc(112px * var(--s));
  gap: 28px; align-items: start;
}
.lede h1 img { width: 100%; max-width: 420px; height: auto; image-rendering: pixelated; }
.deck { font: 32px/1.1 "Newsgeek Serif", serif; margin: 20px 0 24px; }
.cta { margin-bottom: 24px; }
.lede .btn { white-space: nowrap; }
.fine { color: var(--ink-soft); text-transform: uppercase; }
.cabinet { grid-column: 2; grid-row: 1; z-index: 2; }
.district { grid-column: 1 / -1; grid-row: 2; }

/* The city photo: day, night on top of it, then the live street scene. */
.city-view { position: relative; aspect-ratio: 16 / 9; }
.city-view img, .city-view canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.city-view .night { opacity: var(--night, 0); transition: opacity 4s linear; }

/* On a wide screen the photo runs the full width of the page, with the
   headline pasted over its left side and the machine standing on its right. */
@media (min-width: 1100px) {
  .front-grid { display: block; }
  .city-view { aspect-ratio: 2.2 / 1; }
  .city-view img, .city-view canvas { inset: auto; left: 0; top: 50%; height: auto; aspect-ratio: 16 / 9; transform: translateY(-50%); }
  .lede {
    position: absolute; z-index: 2; left: -20px; top: 20px; width: 392px;
    padding: 16px 20px 12px;
    background: var(--paper); border: 4px solid var(--ink);
    box-shadow: 8px 8px 0 rgba(0, 0, 0, .55);
  }
  .lede h1 img { max-width: 300px; }
  .lede .deck { margin: 12px 0 20px; }
  .lede .cta { margin-bottom: 16px; }
  .cabinet { position: absolute; right: calc(16px - var(--pad) - var(--gut)); bottom: -76px; }
  .front .also { margin-top: 28px; padding-right: calc(112px * var(--s) - 60px); }
}

/* The machine stands on the desk with one foot on the paper. */
.machine {
  position: relative;
  width: calc(112px * var(--s)); height: calc(133px * var(--s));
  filter: drop-shadow(calc(3px * var(--s)) calc(3px * var(--s)) 0 rgba(0, 0, 0, .5));
}
.machine.hit { animation: hit .3s steps(6); }
@keyframes hit {
  20% { transform: translate(calc(-1px * var(--s)), 0); }
  40% { transform: translate(calc(1px * var(--s)), calc(1px * var(--s))); }
  60% { transform: translate(calc(-1px * var(--s)), 0); }
  80% { transform: translate(calc(1px * var(--s)), 0); }
}
.machine .cab {
  position: absolute; inset: 0;
  background: url("img/machine/cabinet.png") 0 0 / calc(125px * var(--s)) calc(133px * var(--s)) no-repeat;
  image-rendering: pixelated;
}
.machine .reels {
  position: absolute; left: calc(12px * var(--s)); top: calc(42px * var(--s));
  width: calc(70px * var(--s)); height: calc(65px * var(--s));
  max-width: none; image-rendering: pixelated;
}
.machine .count {
  position: absolute; top: calc(30px * var(--s)); height: calc(9px * var(--s));
  display: grid; place-items: center;
  font-size: calc(8px * (var(--s) - 1)); line-height: 1; color: var(--mint);
}
.machine .pulls { left: calc(16px * var(--s)); width: calc(16px * var(--s)); }
.machine .horde { left: calc(37px * var(--s)); width: calc(20px * var(--s)); color: var(--amber); }
.lever {
  --f: 0; /* frame of the pull, 0 to 5 */
  position: absolute; left: calc(84px * var(--s)); top: calc(48px * var(--s));
  width: calc(28px * var(--s)); height: calc(70px * var(--s));
  padding: 0; border: 0; cursor: grab; touch-action: none;
  background: url("img/machine/lever.png") no-repeat;
  background-size: calc(750px * var(--s)) calc(133px * var(--s));
  background-position: calc((-84px - var(--f) * 125px) * var(--s)) calc(-48px * var(--s));
  image-rendering: pixelated;
}
.lever:active { cursor: grabbing; }
.lever:disabled { cursor: default; }
.lever:focus-visible { outline-offset: 0; }
.nudge {
  position: absolute; left: calc(84px * var(--s)); top: calc(34px * var(--s));
  width: calc(28px * var(--s)); text-align: center;
  font: 32px/1 "Kingdom", serif; color: var(--amber);
  text-shadow: 2px 2px 0 #000, -2px 0 0 #000, 0 -2px 0 #000;
  animation: nudge .8s steps(2) infinite;
  pointer-events: none;
}
.nudge::after { content: ""; display: block; width: 0; height: 0; margin: 2px auto 0; border: 8px solid transparent; border-top-color: var(--amber); }
@keyframes nudge { 50% { transform: translateY(8px); } }
.machine.used .nudge { display: none; }

.ticker {
  width: calc(96px * var(--s)); min-height: 64px; margin-top: 8px;
  color: var(--mint); background: var(--cab-dark);
  border: 4px solid var(--cab-black); box-shadow: inset 0 0 0 4px var(--cab), 8px 8px 0 rgba(0, 0, 0, .5);
  padding: 8px 12px;
}
.ticker b { font-weight: 400; color: var(--amber); }

/* One line of the day's other news, under the photo. */
.also {
  display: flex; flex-wrap: wrap; gap: 4px 28px;
  margin-top: 20px; padding-top: 8px;
  border-top: 4px double var(--ink); color: var(--ink-soft);
}
.also b { font-weight: 400; text-transform: uppercase; color: var(--ink); }
.also > span + span::before { content: "+ "; color: var(--blood); }
.nb { white-space: nowrap; }

/* ---------- Inside pages ---------- */
.spread { display: grid; gap: 28px; align-items: start; }
.spread.wide-left { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.spread.wide-right { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.side { display: grid; gap: 24px; }
/* The plates hang off the edge of the column, onto the photo. */
@media (min-width: 1100px) {
  .wide-left .plaque { margin-left: -64px; margin-top: 40px; z-index: 1; }
  .wide-right .plaque { margin-right: -64px; margin-top: 24px; z-index: 1; }
}

.advert {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 0; align-items: center;
  margin-top: 36px; padding: 28px 20px 20px;
  border: 4px dashed var(--ink); position: relative;
}
.advert-tag {
  position: absolute; top: -14px; left: 16px; padding: 0 8px;
  background: var(--paper-worn); text-transform: uppercase; color: var(--ink-soft);
}
.advert .plaque { margin-left: -24px; }

.quote {
  max-width: 980px; margin-bottom: 28px;
  font: 32px/1.15 "Newsgeek Serif", serif;
  padding: 12px 0 12px 20px; border-left: 12px solid var(--blood);
}

.specials { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; margin-bottom: 28px; }
.special {
  position: relative; z-index: 1; padding: 16px 16px 20px;
  color: var(--mint); background: var(--cab-dark);
  border: 4px solid var(--cab-black);
  box-shadow: inset 0 0 0 4px var(--cab), 8px 8px 0 rgba(0, 0, 0, .6);
  border-top: 12px solid var(--hue);
  transition: transform .1s steps(2);
}
.special:hover { transform: translate(-4px, -4px); }
.special .icon {
  display: block; width: 64px; height: 64px; margin: 4px 0 8px;
  background: url("img/machine/symbols.png") calc(var(--i) * -64px) 0 / 320px 64px no-repeat;
  image-rendering: pixelated;
}
.special .said { position: absolute; top: 20px; right: 16px; color: var(--hue); font-size: 16px; }
.special h3 { font: 48px/1 "Kingdom", serif; color: var(--hue); margin-bottom: 8px; }
.stamp {
  position: absolute; right: 8px; bottom: 8px; padding: 2px 8px;
  font: 400 16px/20px "Newsgeek", monospace; text-transform: uppercase;
  color: #ff5a64; border: 4px solid #ff5a64; background: var(--cab-dark);
  transform: rotate(-8deg); display: none;
}
.special.got .stamp { display: block; animation: stamp .2s steps(3); }
@keyframes stamp { from { transform: rotate(-8deg) scale(2.4); opacity: 0; } }

.sightings { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; align-items: start; }

/* Sunday's photos: one big, the rest as a contact sheet. */
.contact { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.shot { display: block; text-decoration: none; color: var(--ink-soft); }
.shot.big { grid-column: span 2; grid-row: span 2; }
.shot img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border: 4px solid var(--ink); }
.shot span { display: block; padding: 6px 0 4px; }
.shot:hover img, .shot:focus-visible img { border-color: var(--blood); }
.shot:hover span { color: var(--ink); }

/* ---------- The demo: off the paper, onto the desk ---------- */
.play { position: relative; text-align: center; padding: 24px 20px 140px; }
.play h2 { font: 128px/1 "Kingdom", serif; color: var(--amber); text-shadow: 8px 8px 0 #000; margin-bottom: 16px; }
.play > p:not(.scrap) { max-width: 640px; margin: 0 auto 40px; font-size: 24px; line-height: 32px; }
.btn.big { font-size: 48px; padding: 20px 44px; border-color: #000; box-shadow: 8px 8px 0 #000; }
.btn.big:hover { box-shadow: 12px 12px 0 #000; }
.btn.big:active { box-shadow: 4px 4px 0 #000; }
.scrap {
  display: inline-block; margin-bottom: 28px; padding: 8px 20px;
  font: 32px/1 "Newsgeek Serif", serif; text-transform: uppercase;
  color: var(--ink); background: var(--paper-grimy);
  transform: rotate(-3deg); box-shadow: 4px 4px 0 #000;
  clip-path: polygon(0 0, 100% 0, 100% 62%, 97% 62%, 97% 100%, 3% 100%, 3% 80%, 0 80%);
}

footer {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px 24px;
  padding: 20px clamp(12px, 3vw, 32px);
  background: #0b0610; border-top: 4px solid var(--desk-line);
  color: #9c8fae; text-transform: uppercase;
}
footer .credit { flex-basis: 100%; text-transform: none; color: #6f6480; }

/* ---------- Photo viewer ---------- */
.lightbox {
  padding: 0; border: 4px solid var(--paper); background: #000; color: var(--paper);
  max-width: min(1600px, 94vw); max-height: 94vh; overflow: visible;
}
.lightbox::backdrop { background: rgba(8, 4, 12, .92); }
.lightbox img { max-height: calc(94vh - 60px); width: auto; margin: 0 auto; }
.lightbox p { padding: 8px 56px 8px 12px; }
.lightbox button {
  position: absolute; width: 48px; height: 48px;
  font: 32px/1 "Newsgeek", monospace; color: #fff; background: var(--blood);
  border: 4px solid #000; cursor: pointer;
}
.lightbox .prev { left: -28px; top: 45%; }
.lightbox .next { right: -28px; top: 45%; }
.lightbox .shut { right: -28px; top: -28px; }

/* ---------- Smaller screens ---------- */
@media (max-width: 1280px) {
  .headline { font-size: 80px; }
  .headline.huge { font-size: 96px; }
  .hud nav a b { display: none; }
}

@media (max-width: 1099px) {
  .hud nav { display: none; }
  .tally { margin-left: auto; }
  .spread.wide-left, .spread.wide-right, .advert { grid-template-columns: minmax(0, 1fr); }
  .spread.wide-right .photo { order: -1; }
  .advert .plaque { margin: -24px 0 0 20px; }
  .specials { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .contact { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .sheet { margin-bottom: 72px; }
  .sheet::before { transform: translate(8px, 8px); }
  .paper-name { font-size: 64px; grid-column: 1 / -1; }
  .headline, .headline.huge { font-size: 48px; }
  .sub { font-size: 16px; line-height: 24px; text-transform: uppercase; }
  .front-grid { grid-template-columns: minmax(0, 1fr); }
  .lede h1 img { max-width: 300px; }
  .cabinet { grid-column: 1; grid-row: 3; justify-self: center; }
  /* Show the middle of the city rather than all of it very small. */
  .district .frame { aspect-ratio: 4 / 3; }
  .city-view img, .city-view canvas { inset: 0 auto auto 50%; width: auto; height: 100%; max-width: none; transform: translateX(-50%); aspect-ratio: 16 / 9; }
  .plaque h3, .special h3 { font-size: 32px; }
  .plaque p { font-size: 16px; line-height: 24px; }
  .quote { font-size: 16px; line-height: 24px; }
  .sightings { grid-template-columns: minmax(0, 1fr); }
  .play h2 { font-size: 64px; }
  .btn { font-size: 16px; padding: 12px 16px; }
  .btn.big { font-size: 32px; padding: 16px 24px; }
  .studio span { display: none; }
  /* Less blood where the page is all text. */
  .stain:nth-of-type(odd) { display: none; }
  .lightbox .prev { left: 4px; } .lightbox .next { right: 4px; } .lightbox .shut { right: 4px; top: 4px; }
}

@media (max-width: 420px) {
  .specials, .contact { grid-template-columns: minmax(0, 1fr); }
  .shot.big { grid-column: auto; grid-row: auto; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
  .js .sheet:not(.front) { transform: none; opacity: 1; }
}
