:root {
  --paper: #eeebe4;
  --paper-2: #e5e1d8;
  --ink: #131313;
  --muted: #6f6b63;

  --s: clamp(150px, min(34vh, 62vw), 320px);   /* record size */
  --edge: clamp(16px, 5vw, 64px);
  --pad-t: calc(var(--s) * 0.32);               /* headroom for a pulled record */
  --pad-b: max(26px, calc(var(--s) * .09));    /* room for the near edge, which grows in perspective */
  /* The shelf is a row of real sleeves in 3D: each one stands upright, turned so its
     right edge is nearest you, and the camera looks down on the row from above. */
  --turn: -34deg;                               /* how far each sleeve is turned (negative: right edge nearest) */
  --tip: -19deg;                                /* camera height: negative looks down onto the tops */
  --persp: calc(var(--s) * 3);                  /* keep in sync with PERSP in main.js */
  --depth: calc(var(--s) * .05);                /* sleeve thickness: the top edge and spine you see */
  --step: .5;                                   /* how much of each sleeve shows before the one in front covers it */

  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --sans: "Inter Tight", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --snap: cubic-bezier(.2, 0, 0, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html {
  background: var(--paper);
  color: var(--ink);
  scrollbar-gutter: stable;
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
}
html.is-intro { overflow: hidden; }

body { font-family: var(--sans); font-size: 16px; line-height: normal; background: var(--paper); }
a { color: inherit; }
button { font: inherit; color: inherit; }

/* ---------- Stage ---------- */

.stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto auto;
  grid-template-columns: minmax(0, 1fr);
  padding-bottom: 28px;
}

.top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 22px var(--edge);
}
.logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.logo-mark { width: 22px; height: 16px; fill: currentColor; }
.nav { display: flex; gap: clamp(16px, 3vw, 36px); }
.nav a {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  position: relative;
}
.nav a::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -3px;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform .3s ease;
}
.nav a:hover::after { transform: scaleX(1); transform-origin: left; }

/* ---------- Shelf ---------- */

.shelf { position: relative; align-self: center; min-width: 0; }

.scroller {
  position: relative;
  z-index: 1;
  overflow-x: auto;
  overflow-y: hidden;
  padding: var(--pad-t) 0 var(--pad-b);
  scrollbar-width: none;
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
}
.scroller::-webkit-scrollbar { display: none; }
.scroller.dragging { cursor: grabbing; }

.track {
  list-style: none;
  display: flex;
  width: max-content;
  margin: 0 auto;
  padding: 0;
}

/* Each sleeve stands just in front of the one to its right, covering that one's far side.
   Slots only hold the pieces; the invisible .hit button is what the pointer and keyboard use. */
.slot {
  position: relative;
  z-index: var(--z);
  flex: none;
  width: calc(var(--s) * var(--step));
  height: var(--s);
  pointer-events: none;
}

.card, .hit {
  position: absolute;
  left: 0; top: 0;
  transform-origin: 50% 50%;
}
.card { transform-style: preserve-3d; }
.card {
  width: var(--s);
  height: var(--s);
  --tx: 0%; --ty: 0%; --rz: 0deg; --ry: 0deg;
  transform: translate(var(--tx), var(--ty)) rotate(var(--rz)) perspective(var(--persp)) rotateX(var(--tip)) rotateY(calc(var(--turn) + var(--ry)));
  transition: transform .75s cubic-bezier(.22, 1, .36, 1);
}

/* the sleeve's resting footprint: hovering it never moves, so a lifted sleeve can't flicker */
.hit {
  width: var(--s);
  height: var(--s);
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
  transform: perspective(var(--persp)) rotateX(var(--tip)) rotateY(var(--turn));
}
.hit:focus { outline: none; }

/* the sleeve's thickness: a lit top edge and a shaded spine on the near (right) side.
   Each reaches 1px past the cover's edge so the faces meet without a hairline gap. */
.s-top, .s-side { position: absolute; }
.s-top {
  left: 0; top: -1px;
  width: 100%;
  height: calc(var(--depth) + 1px);
  transform-origin: 50% 1px;
  transform: rotateX(-90deg);
  background: color-mix(in srgb, var(--bg) 72%, #fff);
}
.s-side {
  right: -1px; top: 0;
  width: calc(var(--depth) + 1px);
  height: 100%;
  transform-origin: calc(100% - 1px) 50%;
  transform: rotateY(-90deg);
  background: color-mix(in srgb, var(--bg) 64%, #000);
}

/* pull the sleeve up out of the row, each its own way (per-album values set in main.js);
   it stays behind the one in front */
.slot:hover .card,
.slot:has(.hit:focus-visible) .card { --ty: calc(var(--lift) * -1); --rz: var(--lean); --tx: var(--shift); --ry: var(--twist); }
/* its neighbours give way a little: the one in front eases left, the one behind eases right */
.slot:has(+ .slot:hover) .card,
.slot:has(+ .slot .hit:focus-visible) .card { --tx: -3.5%; --rz: -1.2deg; --ry: -3deg; }
.slot:hover + .slot .card,
.slot:has(.hit:focus-visible) + .slot .card { --tx: 3.5%; --rz: 1.2deg; --ry: 3deg; }
.slot:has(.hit:focus-visible) .cover { outline: 2px solid var(--ink); outline-offset: 4px; }

/* ---------- Covers ---------- */

.cover {
  position: absolute;
  inset: 0;
  overflow: hidden;
  container-type: size;
  background: var(--bg);
  color: var(--ink-c);
  text-align: left;
}
.cover svg, .cover img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  object-fit: cover;
  -webkit-user-drag: none;
}
/* a hairline so pale sleeves still read as objects against the paper */
.cover::after {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .07);
  pointer-events: none;
}
/* labels sit top-right: the near side, the part that stays in view in the row */
.c-no, .c-title {
  position: absolute;
  right: 7cqw;
  z-index: 1;
  text-align: right;
}
.c-no {
  top: 6.5cqw;
  font-family: var(--mono);
  font-size: 4.2cqw;
  line-height: 1;
  letter-spacing: .06em;
}
.c-title {
  top: 12.5cqw;
  left: 50cqw;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 7cqw;
  line-height: 1;
  letter-spacing: -.02em;
}

/* ---------- Caption & controls ---------- */

.caption {
  display: flex;
  align-items: flex-end;
  gap: clamp(16px, 2.4vw, 32px);
  padding: 10px var(--edge) 0;
  min-height: clamp(64px, 9vw, 108px);
}
.cap-no {
  font-family: var(--mono);
  font-size: clamp(44px, 7.2vw, 100px);
  line-height: .78;
  letter-spacing: -.05em;
  font-weight: 400;
}
.cap-title {
  font-size: clamp(22px, 2.6vw, 38px);
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.05;
}
.cap-meta, .count, .eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.cap-meta { margin-top: 6px; }

.controls {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 22px var(--edge) 0;
}
.count { flex: none; min-width: 9ch; }
.progress { flex: 1; height: 1px; background: rgba(0,0,0,.18); position: relative; }
.progress i {
  position: absolute; top: -1px; left: 0;
  height: 3px; width: 20%;
  background: var(--ink);
}
.arrows { display: flex; gap: 8px; }
.arrow {
  width: 40px; height: 40px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  font-size: 16px;
  transition: background .2s, color .2s;
}
.arrow:hover { background: var(--ink); color: var(--paper); }
.arrow:disabled { opacity: .25; pointer-events: none; }

/* ---------- About / contact ---------- */

.about, .contact { padding: clamp(72px, 12vh, 140px) var(--edge); }
.about { border-top: 2px solid var(--ink); }
.statement {
  max-width: 20ch;
  margin: 18px 0 clamp(40px, 7vh, 72px);
  font-size: clamp(34px, 5.6vw, 84px);
  line-height: .98;
  letter-spacing: -.035em;
  font-weight: 600;
  text-wrap: balance;
}
.about-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: clamp(28px, 6vw, 96px);
  font-size: clamp(17px, 1.4vw, 20px);
  line-height: 1.5;
  max-width: 1100px;
}
.services { list-style: none; font-family: var(--mono); font-size: 14px; text-transform: uppercase; letter-spacing: .06em; }
.services li { padding: 10px 0; border-bottom: 1px solid rgba(0,0,0,.18); }
.services li:first-child { border-top: 1px solid rgba(0,0,0,.18); }

.contact { background: var(--ink); color: var(--paper); }
.contact .eyebrow { color: #9a968e; }
.mail {
  display: inline-block;
  margin: 18px 0 clamp(56px, 10vh, 120px);
  font-size: clamp(30px, 6vw, 92px);
  font-weight: 600;
  letter-spacing: -.035em;
  text-decoration: none;
  overflow-wrap: anywhere;
  border-bottom: 3px solid transparent;
  transition: border-color .25s;
}
.mail:hover { border-color: currentColor; }
.foot {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #9a968e;
}

/* ---------- Intro ---------- */

.intro {
  position: fixed;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  display: none;
}
.is-intro .intro { display: block; pointer-events: auto; cursor: pointer; }

/* The intro drives the shelf's own sleeves (see main.js), so these rules only apply while it
   runs. Each sleeve starts as a black bar: the artwork shows through a clip-path window, and the
   black is a set of .ink layers. While a bar is solid black its spine and top carry no colour, and
   once the bars turn the black reaches 1px past each edge (set in main.js) so nothing bleeds through
   the anti-aliasing where faces meet. */
.ink { display: none; }
.is-intro .ink { display: block; position: absolute; inset: 0; background: var(--ink); z-index: 2; }
.is-intro .card { transition: none; }
/* the turned barcode's near end swings beyond the shelf box, so while the intro runs the shelf's
   clip reaches further (extra padding, cancelled by negative margin, so nothing moves) */
.is-intro .scroller {
  padding-top: calc(var(--pad-t) + 160px);
  padding-bottom: calc(var(--pad-b) + 160px);
  margin-block: -160px;
}
/* the loop's extra copies wait until the sleeves have landed, then fade in */
.slot.clone { transition: opacity .7s ease .15s; }
.is-intro .slot.clone { opacity: 0; transition: none; }
.is-intro .card.inked .cover { visibility: hidden; }
.is-intro .card.inked .s-top, .is-intro .card.inked .s-side { background: none; }
.is-intro .card.clear .ink { display: none; }

.readout {
  position: absolute;
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0;
  line-height: 1;
}
.readout span { opacity: 0; }
.readout span.on { opacity: 1; }


.skip {
  position: absolute;
  right: var(--edge); bottom: 24px;
  border: 0; background: none;
  font-family: var(--mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
}

/* page chrome waits for the records to land */
.fade { transition: opacity .9s ease var(--d, 0s), transform .9s cubic-bezier(.2,.8,.2,1) var(--d, 0s); }
.top.fade { --d: .1s; }
.caption.fade { --d: .25s; }
.controls.fade { --d: .4s; }
.is-intro .fade { opacity: 0; transform: translateY(8px); transition-duration: .25s; transition-delay: 0s; }
.is-intro:not(.intro-live) .track { visibility: hidden; }

/* ---------- Detail ---------- */

.detail {
  margin: auto;
  width: min(980px, calc(100vw - 32px));
  max-height: calc(100svh - 32px);
  border: 0;
  background: var(--paper);
  color: var(--ink);
  overflow: auto;
}
.detail::backdrop { background: rgba(19,19,19,.6); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.detail[open] .d-inner { animation: pull .3s var(--snap) both; }
@keyframes pull {
  from { transform: translateY(40px) scale(.97); opacity: 0; }
}
.d-inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.d-cover { position: relative; aspect-ratio: 1; }
.d-info { padding: clamp(24px, 4vw, 48px); display: flex; flex-direction: column; }
.d-no { font-family: var(--mono); font-size: 13px; letter-spacing: .1em; color: var(--muted); }
.d-title { font-size: clamp(30px, 4vw, 52px); line-height: 1; letter-spacing: -.03em; margin: 10px 0 24px; }
.d-meta { border-top: 1px solid rgba(0,0,0,.18); margin-bottom: 24px; }
.d-meta div { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid rgba(0,0,0,.18); }
.d-meta dt { font-family: var(--mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.d-meta dd { text-align: right; }
.d-summary { font-size: 17px; line-height: 1.55; margin-bottom: 20px; }
.d-link { font-family: var(--mono); font-size: 13px; letter-spacing: .06em; text-transform: uppercase; }
.d-link[hidden] { display: none; }
.d-nav { margin-top: auto; padding-top: 28px; display: flex; justify-content: space-between; }
.d-nav button, .d-close { border: 0; background: none; cursor: pointer; }
.d-nav button { font-family: var(--mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
.d-nav button:hover { text-decoration: underline; }
.d-close {
  position: absolute; top: 10px; right: 12px;
  width: 40px; height: 40px;
  font-size: 28px; line-height: 1;
}

/* ---------- Small screens ---------- */

@media (max-width: 720px) {
  .about-cols { grid-template-columns: 1fr; }
  .d-inner { grid-template-columns: 1fr; }
  .nav a:first-child { display: none; }
  .progress { display: none; }
  .controls { justify-content: space-between; }
}

@media (prefers-reduced-motion: reduce) {
  .card, .fade { transition-duration: .01s !important; }
  .detail[open] .d-inner { animation: none; }
}
