/* sleeve.css
   The record in its sleeve: one side, one stream, one screen.
   Everything is placed against the scene itself (container units), so the
   composition holds at any window size, zoom level or phone orientation. */

html:has(body.home) { background: var(--side); }

body.home {
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--side);
}

.sleeve {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: var(--side);
  container: sleeve / size;

  /* Landscape: the disc sits right of centre, cropped by three edges. */
  --pad: clamp(14px, 3.2cqw, 44px);
  --bar-top: clamp(10px, 3.2cqh, 36px);
  --bar-h: clamp(44px, 7cqh, 60px);
  --title: min(11.6cqw, 16cqh);
  --title-top: calc(var(--bar-top) + var(--bar-h) + 3.2cqh);
  --title-h: calc(var(--title) * 1.68);
  --title-left: var(--pad);
  --list-h: clamp(52px, 8.6cqh, 76px);
  --list-bottom: clamp(10px, 3.2cqh, 34px);
  --frame: clamp(6px, .62cqw, 10px);
  /* The note holds one line on every side, so it never changes size. The
     height reserved for it in the layout is its real height. */
  --note-font: clamp(.875rem, .7rem + .32cqw, 1.125rem);
  --note-h: calc(var(--note-lines, 1) * 1.3 * var(--note-font) + .95rem);
  --deck-gap: clamp(8px, 1.6cqh, 16px);
  --player-w: min(44cqw, calc((100cqh - var(--title-top) - var(--title-h) - 2.5cqh - var(--note-h) - var(--deck-gap) - var(--list-h) - var(--list-bottom) - 2 * var(--frame)) * 16 / 9 + 2 * var(--frame)));
  --player-h: calc((var(--player-w) - 2 * var(--frame)) * 9 / 16 + 2 * var(--frame));
  --deck-bottom: calc(var(--list-bottom) + var(--list-h) + var(--deck-gap));
  /* The disc starts two and a half ems into the title, so on every side at
     least one whole letter of the longer line is printed on the vinyl. It is
     sized to stay cropped by the right edge while its label stays whole. */
  --edge: calc(var(--pad) + 2.5 * var(--title));
  --disc-d: min(calc((100cqw - var(--pad) - var(--edge)) / .66), max(134cqh, calc(108cqw - var(--edge))));
  --disc-cx: calc(var(--edge) + var(--disc-d) / 2);
  --disc-cy: 48cqh;
}

/* The outgoing sleeve: painted in the previous colour and pulled away. */
.sleeve-off {
  position: absolute;
  inset: 0;
  visibility: hidden;
  will-change: transform;
}

/* Ink on the sleeve (the title, the stamp) is printed twice: once in black,
   and once more in the sleeve colour, clipped to the disc. Wherever the
   lettering runs onto the vinyl it changes colour and stays readable. */
.titles {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.titles--cut {
  z-index: 10;
  clip-path: circle(calc(var(--disc-d) / 2) at var(--disc-cx) var(--disc-cy));
  color: var(--side);
}

.brand--cut {
  position: absolute;
  top: var(--bar-top);
  left: var(--pad);
  height: var(--bar-h);
}

.title {
  position: absolute;
  top: var(--title-top);
  left: var(--title-left);
  font: 900 var(--title) / .84 var(--sans);
  font-stretch: 62%;
  letter-spacing: -.01em;
  text-transform: uppercase;
  white-space: nowrap;
}

.title .line {
  display: block;
  clip-path: inset(-.07em -2em);
}

.title .line > span { display: block; }

/* Vinyl. Flat black with the gaps between tracks; no shine. */
.disc {
  position: absolute;
  top: calc(var(--disc-cy) - var(--disc-d) / 2);
  left: calc(var(--disc-cx) - var(--disc-d) / 2);
  width: var(--disc-d);
  height: var(--disc-d);
  border-radius: 50%;
  background: radial-gradient(closest-side,
    var(--ink) 0 35.5%, var(--groove) 35.7% 36.1%,
    var(--ink) 36.3% 51.9%, var(--groove) 52.1% 52.5%,
    var(--ink) 52.7% 66.3%, var(--groove) 66.5% 66.9%,
    var(--ink) 67.1% 82.1%, var(--groove) 82.3% 82.7%,
    var(--ink) 82.9% 97.3%, var(--groove) 97.5% 97.9%,
    var(--ink) 98.1% 100%);
}

.label {
  position: absolute;
  inset: 34%;
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink);
  container: label / size;
}

.label-rim {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.label-rim text {
  fill: currentColor;
  font: 700 7.2px var(--sans);
  font-stretch: 116%;
  letter-spacing: .09em;
  text-transform: uppercase;
}

.label-letter {
  position: absolute;
  top: 13.5cqw;
  right: 0;
  left: 0;
  font: 900 34cqw / 1 var(--sans);
  font-stretch: 62%;
  text-align: center;
}

.label-hole {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 6.6cqw;
  height: 6.6cqw;
  border-radius: 50%;
  background: var(--side);
  translate: -50% -50%;
}

.label-name {
  position: absolute;
  top: 59cqw;
  right: 8cqw;
  left: 8cqw;
  font: 900 8.4cqw / 1 var(--sans);
  font-stretch: 68%;
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
}

.label-meta {
  position: absolute;
  top: 70.5cqw;
  right: 0;
  left: 0;
  font: 500 3.5cqw / 1.55 var(--mono);
  font-stretch: 86%;
  letter-spacing: .03em;
  text-align: center;
}

/* A small label keeps the letter and the name; the fine print would fall
   under 11px, so it is left off. */
@container label (max-width: 319px) {
  .label-rim,
  .label-meta { display: none; }
  .label-letter { top: 9cqw; font-size: 40cqw; }
  .label-name { top: 61cqw; right: 5cqw; left: 5cqw; font-size: 9.6cqw; }
}

@container label (max-width: 129px) {
  .label-name { display: none; }
  .label-letter { top: 4cqw; font-size: 38cqw; }
  .label-hole { width: 8cqw; height: 8cqw; }
}

/* Header: stamp on the left, navigation sticker on the right. */
.bar {
  position: absolute;
  top: var(--bar-top);
  right: var(--pad);
  left: var(--pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--bar-h);
}

.home .menu-toggle {
  position: relative;
  z-index: 20;
}

@media (min-width: 761px) {
  .home .nav {
    position: relative;
    z-index: 20;
  }
}

/* The stamp can sit on colour or on vinyl, so its focus ring has two tones. */
.home .bar .brand:focus-visible { box-shadow: 0 0 0 9px var(--paper); }

.home .stamp { font-size: min(clamp(1.6rem, 1.2rem + .9cqw, 2.4rem), calc(var(--bar-h) * .56)); }
.home .brand-words { font-size: clamp(.75rem, .58rem + .3cqw, 1rem); }
@media (min-width: 761px) {
  .home .nav a { font-size: clamp(.75rem, .58rem + .3cqw, 1rem); }
}

/* The menu lies on vinyl in one layout and on the sleeve colour in another.
   A hovered link is drawn like the current side in the tracklist: black, type
   in the colour of the side, and a paper edge so it never merges with vinyl. */
.home .nav a:hover {
  background: var(--ink);
  box-shadow: inset 0 0 0 4px var(--paper);
  color: var(--side);
}

.home .nav a:hover:focus-visible {
  outline-color: var(--side);
  outline-offset: -9px;
}

/* The note: a paper strip along the top edge of the player frame, exactly as
   wide as the frame. */
.note {
  position: absolute;
  z-index: 5;
  bottom: calc(var(--deck-bottom) + var(--player-h));
  left: var(--pad);
  width: var(--player-w);
  min-height: var(--note-h);
  padding: .5rem calc(var(--frame) + .3rem) .45rem;
  background: var(--paper);
  font: 500 var(--note-font) / 1.3 var(--sans);
}

/* Shown in place of the note when the player has not answered. */
.note-help a,
.no-js a { font-weight: 700; }
.is-silent [data-note] { display: none; }

.deck {
  position: absolute;
  bottom: var(--deck-bottom);
  left: var(--pad);
  width: var(--player-w);
}

.player {
  padding: var(--frame);
  background: var(--paper);
}

.player iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  background: var(--ink);
}

/* Tracklist: the four sides on one paper strip. The current side is black. */
.sides {
  position: absolute;
  z-index: 6;
  right: var(--pad);
  bottom: var(--list-bottom);
  left: var(--pad);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: 3px;
  height: var(--list-h);
  background: var(--ink);
}

.sides a {
  display: grid;
  align-content: center;
  gap: .22rem;
  min-width: 0;
  padding: 0 clamp(.6rem, 1.5cqw, 1.3rem);
  background: var(--paper);
  text-decoration: none;
}

.sides .k { font-size: clamp(.6875rem, .56rem + .22cqw, .875rem); letter-spacing: .08em; text-transform: uppercase; }

.sides .n {
  overflow: hidden;
  font: 900 clamp(1.05rem, 2cqw, 1.7rem) / 1 var(--sans);
  font-stretch: 68%;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.sides [data-side-link="a"] { --cell: var(--side-a); }
.sides [data-side-link="b"] { --cell: var(--side-b); }
.sides [data-side-link="c"] { --cell: var(--side-c); }
.sides [data-side-link="d"] { --cell: var(--side-d); }

/* A paper edge stays round every cell, so the strip keeps its outline when
   the black cell lies over the vinyl. */
.sides a:hover {
  background: var(--cell);
  box-shadow: inset 0 0 0 4px var(--paper);
}

.sides a[aria-current] {
  background: var(--ink);
  box-shadow: inset 0 0 0 4px var(--paper);
  color: var(--side);
}

.sides a:focus-visible { outline-offset: -9px; }
.sides a[aria-current]:focus-visible { outline-color: var(--side); }

/* Portrait: title on top, the label in the gap, the player full width. */
@media (orientation: portrait) {
  .sleeve {
    --pad: clamp(14px, 4cqw, 28px);
    --bar-top: 12px;
    --bar-h: 44px;
    --title: min(19.2cqw, 12cqh);
    --title-top: calc(var(--bar-top) + var(--bar-h) + 1.8cqh);
    --list-h: clamp(52px, 7cqh, 68px);
    --list-bottom: 14px;
    --frame: 6px;
    --deck-gap: 10px;
    --player-w: min(100cqw - 2 * var(--pad), 36cqh * 16 / 9);
    --band-top: calc(var(--title-top) + var(--title-h));
    --band: calc(100cqh - var(--deck-bottom) - var(--player-h) - var(--note-h) - var(--band-top));
    --label-d: clamp(72px, var(--band) - 20px, 38cqw);
    --disc-d: calc(var(--label-d) / .32);
    --disc-cx: calc(100cqw - var(--pad) - var(--label-d) / 2);
    --disc-cy: calc(var(--band-top) + var(--band) / 2);
  }

  .sides a {
    place-content: center;
    padding: 0;
  }

  .sides .k { font-size: clamp(1.25rem, 6cqw, 1.75rem); font-weight: 700; letter-spacing: 0; }
  .sides .k-word,
  .sides .n {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* Short portrait (a small phone with the browser bars showing): there is no
   room for the label between title and player, so the disc becomes an edge. */
@media (orientation: portrait) and (max-height: 600px) {
  .sleeve {
    --title: min(19.2cqw, 11cqh);
    --disc-d: 150cqw;
    --disc-cx: 104cqw;
    --disc-cy: 46cqh;
  }

  .label { display: none; }
}

/* Short landscape (a phone on its side, or a heavily zoomed window):
   the player takes the left, the title moves beside it onto the vinyl. */
@media (orientation: landscape) and (max-height: 560px) {
  .sleeve {
    --pad: 12px;
    --bar-top: 8px;
    --bar-h: 44px;
    --list-h: 44px;
    --list-bottom: 8px;
    --frame: 5px;
    --deck-gap: 8px;
    --band-top: calc(var(--bar-top) + var(--bar-h) + 8px);
    --room: calc(100cqh - var(--band-top) - var(--deck-bottom));
    --player-w: min(56cqw, calc((var(--room) - 2 * var(--frame)) * 16 / 9 + 2 * var(--frame)));
    --title-left: calc(var(--pad) + var(--player-w) + 16px);
    --title: min(calc((100cqw - var(--title-left) - var(--pad)) / 4.75), 20cqh);
    --title-top: var(--band-top);
    --note-lines: 2;
    --disc-d: 230cqh;
    --disc-cx: calc(100cqw + 30cqh);
    --disc-cy: 110cqh;
  }

  .label { display: none; }

  .deck {
    top: var(--band-top);
    bottom: auto;
  }

  .note {
    top: calc(var(--title-top) + var(--title-h) + 10px);
    bottom: auto;
    left: var(--title-left);
    width: min(100cqw - var(--title-left) - var(--pad), 20rem);
  }

  .sides a { gap: .1rem; }
  .sides .n { font-size: 1rem; }
}

@media (orientation: landscape) and (max-height: 560px) and (max-width: 760px) {
  .home .brand-words { display: none; }
}

/* The flip. Driven from sleeve.js with the Web Animations API; these rules
   only cover what must not move when motion is turned down. */
@media (prefers-reduced-motion: reduce) {
  .sleeve-off { display: none; }
}
