/* Dijkstra Labs site, "night screening" skin.
   Dark and cinematic: a film still fills the top of each page, the title sits
   on it in the wordmark's typeface, and everything below stays quiet.
   Each page sets --accent on <body>; heroes and cards set their own.
   WordPress port: this file and the theme's templates are the whole skin; the
   content lives in the Dijkstra Labs Releases plugin, so the look can be
   redone without touching it. Kept in step with static/site.css by hand. */

:root {
  --bg: #0c0c0e;
  --panel: #17171b;
  --ink: #ecebe7;
  --soft: #d5d3cd;
  --muted: #9a9891;
  --line: #2c2c33;
  --todo: #d9a441;
  --accent: #e2603f;
  /* Titles were set in the wordmark's typeface (BOEING-style), but its web
     licence is unchecked and it was only ever used from the machine, so
     visitors never saw it. Until that is cleared everyone gets Inter, shipped
     with the theme (assets/fonts, OFL), so the site looks the same everywhere.
     To bring it back: add an @font-face for it and put it first in --display. */
  --display: "Inter", system-ui, sans-serif;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* Inter 4, Latin subset (covers the umlaut in Tescrealität). OFL: fonts/Inter-OFL.txt */
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/inter-regular.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/inter-semibold.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/inter-bold.woff2") format("woff2"); }

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 1rem/1.7 var(--sans);
  -webkit-text-size-adjust: 100%;
}

img, svg { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
a:focus-visible, button:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

h2 {
  margin: 0 0 1rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted);
}

.wrap { width: min(100% - 2rem, 60rem); margin-inline: auto; }
.wrap--narrow { width: min(100% - 2rem, 34rem); }
.block { margin-top: 2.5rem; }

/* Notes for content that is still missing; they go once the JSON is filled. */
.todo { color: var(--todo); font-size: .9rem; }

/* The display face has no umlauts: draw the two dots over the base letter. */
.uml { position: relative; }
.uml::after {
  content: "";
  position: absolute;
  top: -.03em;
  left: .4em;
  width: .14em;
  height: .1em;
  background: currentColor;
  box-shadow: .27em 0 0 currentColor;
  transform: skewX(-38deg);
}

/* ---------- Hero (release pages and landing) ---------- */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: min(78vh, 40rem);
  /* Without a still the hero is a dark field lit by the accent. */
  background: radial-gradient(120% 90% at 80% 0%, color-mix(in srgb, var(--accent) 45%, #000) 0%, #000 70%) center / cover no-repeat;
}
/* Darken top and bottom so the logo and title stay readable on any still. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgb(12 12 14 / .6) 0%, rgb(12 12 14 / 0) 30%, rgb(12 12 14 / .25) 55%, var(--bg) 100%);
}
.hero > * { position: relative; z-index: 1; }

.hero__logo { display: block; width: min(42vw, 11rem); padding-top: 1.4rem; color: #fff; }
.play {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  margin-top: 1.3rem;
  padding: .75rem 1.3rem .75rem 1rem;
  border-radius: 999px;
  background: var(--accent);
  color: #0c0c0e;
  font-weight: 700;
  text-decoration: none;
}
.play::before {
  content: "";
  border-style: solid;
  border-width: .45rem 0 .45rem .75rem;
  border-color: transparent transparent transparent currentColor;
}
a.play:hover { filter: brightness(1.12); }
.play.is-todo { background: none; border: 1px dashed var(--todo); color: var(--todo); font-weight: 400; }
.play.is-todo::before { display: none; }

/* Landing page: the wordmark large, the newest release named under it. */
.hero--home { min-height: min(64vh, 30rem); justify-content: flex-end; text-align: center; }
.brand { margin: 0; padding: 4rem 0 0; color: #fff; }
.brand svg { width: min(100%, 24rem); margin-inline: auto; }
.latest { display: block; padding: 2rem 0 1.5rem; text-decoration: none; }
.latest__label { display: block; font-size: .75rem; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); }
.latest__title { display: block; margin-top: .3rem; font: 400 clamp(1.2rem, 5vw, 1.9rem)/1.1 var(--display); color: var(--accent); }
.latest:hover .latest__title { color: #fff; }

/* ---------- Links and cards ---------- */

.links { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }

.btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.2rem;
  padding: .6rem 1rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  font-weight: 600;
  text-decoration: none;
  transition: border-color .15s, color .15s;
}
a.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.is-todo { background: none; border-style: dashed; color: var(--muted); }
.btn__note { font-size: .8rem; font-weight: 400; color: var(--todo); }

.cards { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.card {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 1rem;
  align-items: center;
  padding: .5rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  text-decoration: none;
  transition: border-color .15s;
}
.card:hover { border-color: var(--accent); }
.card__text { display: grid; }
.card__title { font-size: 1.15rem; font-weight: 600; color: var(--accent); overflow-wrap: anywhere; }
.card__sub, .card__date { font-size: .9rem; color: var(--muted); }

.cover { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 6px; }
.cover--blank { display: grid; place-items: center; padding: 12%; background: #000; border: 1px solid var(--line); color: var(--accent); }
.cover--blank svg { width: 100%; }

/* ---------- Release page: cover over the hero, then one column ---------- */

/* The hero is a backdrop here: shorter, holding only the logo. */
.hero--release { min-height: clamp(18rem, 50vh, 28rem); justify-content: flex-start; }

.release-head {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* The cover rides up over the bottom of the hero by about half its height. */
.release-head > .cover {
  width: min(100%, 24rem);
  margin-top: calc(-1 * min(100vw - 2rem, 24rem) / 2);
  border-radius: 8px;
  box-shadow: 0 1.5rem 3rem rgb(0 0 0 / .55);
}
.release-head__title {
  /* Wider than the column below it (centred flex items overflow evenly), so a
     long one-word title still fits on one line. */
  width: min(100vw - 2rem, 60rem);
  margin: 1.8rem 0 0;
  /* About one em per letter in the display face, so the line is divided by the
     letter count (--len) to keep a one-word title on one line. */
  font: 400 min(4.5rem, calc((min(100vw, 60rem) - 2.4rem) / (var(--len, 12) * 1.05)))/1.05 var(--display);
  letter-spacing: -.01em;
  overflow-wrap: anywhere;
}
.release-head__sub { margin: .5rem 0 0; font-size: clamp(1rem, 2.6vw, 1.3rem); color: var(--accent); }
.release-head__date { margin: .3rem 0 0; font-size: .85rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.release-head .links { width: 100%; margin-top: 2rem; text-align: left; }

/* Bandcamp player (Listen): full column width, Bandcamp's "large" height without artwork. */
.listen { width: 100%; margin-top: 2rem; }
.listen__player { display: block; width: 100%; height: 120px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }

.blurb { font-size: 1.25rem; line-height: 1.55; }
.blurb p { margin: 0 0 1em; }
.blurb > :last-child { margin-bottom: 0; }
.verse { margin: 0 0 1.6rem; white-space: pre-line; font-size: 1.1rem; color: var(--soft); }
.verse--chorus { padding-left: 1rem; border-left: 2px solid var(--accent); color: var(--ink); }

/* Credits: one small muted line until opened. */
.credits { margin-top: 2.5rem; font-size: .8rem; color: var(--muted); }
.credits summary {
  display: inline-block; cursor: pointer; list-style: none;
  font-size: .7rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
}
.credits summary::-webkit-details-marker { display: none; }
.credits summary::after { content: " +"; }
.credits[open] summary::after { content: " \2212"; }
.credits summary:hover, .credits summary:focus-visible { color: var(--ink); }
.credits__group { margin: 1rem 0 0; padding: 0; list-style: none; line-height: 1.6; }
.credits__head { margin-bottom: .2rem; color: var(--soft); font-weight: 600; }
.credits__role { color: var(--soft); }
.credits a { color: var(--soft); text-underline-offset: 2px; }

/* While the film plays in the hero, the cover stops overlapping it. */
.film-playing .release-head > .cover { margin-top: 2rem; }

.pager {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: .9rem;
  color: var(--muted);
}
.pager a { text-decoration: none; overflow-wrap: anywhere; }
.pager a:hover { color: var(--accent); }
.pager__right { margin-left: auto; text-align: right; }

.foot { padding: 3rem 1rem 2.5rem; text-align: center; font-size: .85rem; color: var(--muted); }

/* ---------- Loop clip and in-page film (site.js) ---------- */

/* The silent loop fills the hero behind the darkening gradient (::after),
   with the still as its poster. Beats `.hero > *` on specificity. */
.hero > .hero__loop {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

/* No loop clip: the still drifts instead (a slow push-in and sideways drift,
   eased there and back over 8 s) under a moving film grain. ::before is the
   moving layer, so the hero clips it; ::after's gradient stays on top. The
   grain is SVG noise, nudged to a new spot every 0.1 s. */
.hero--drift { overflow: hidden; }
.hero--drift::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 .13'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    var(--still);
  background-size: 240px 240px, cover;
  background-position: 0 0, center;
  transform-origin: center;
  will-change: transform;
  animation: dn-drift 4s ease-in-out infinite alternate, dn-grain .6s steps(1) infinite;
}
@keyframes dn-drift {
  from { transform: scale(1) translateX(0); }
  to   { transform: scale(1.08) translateX(1.6%); }
}
@keyframes dn-grain {
  0%   { background-position: 0 0, center; }
  17%  { background-position: -61px 37px, center; }
  33%  { background-position: 83px -112px, center; }
  50%  { background-position: -127px -29px, center; }
  67%  { background-position: 41px 151px, center; }
  83%  { background-position: 109px -73px, center; }
}

/* Playing: the hero gives way to a 16:9 player, as tall as the hero was. */
.hero.is-playing { min-height: 0; display: block; background: #000; }
.hero.is-playing::after { display: none; }
.hero.is-playing > :not(.hero__film) { display: none; }
.hero__film {
  position: relative;
  width: min(100%, calc(min(78vh, 40rem) * 16 / 9));
  margin-inline: auto;
  aspect-ratio: 16 / 9;
}
.hero__film iframe { display: block; width: 100%; height: 100%; border: 0; }
.hero__film-close {
  position: absolute;
  top: .6rem;
  right: .6rem;
  padding: .35rem .9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(12 12 14 / .8);
  color: var(--ink);
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}
.hero__film-close:hover { border-color: var(--accent); color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  /* Less motion: the still (the hero background) shows instead of the loop. */
  .hero > .hero__loop { display: none; }
  .hero--drift::before { animation: none; }
}
