/* The theme colours are registered as colours, so a change of album can fade them into each other
   instead of switching at once (see html at the end of this file). */
@property --bg { syntax: "<color>"; inherits: true; initial-value: #000; }
@property --fg { syntax: "<color>"; inherits: true; initial-value: #f5f5f7; }
@property --muted { syntax: "<color>"; inherits: true; initial-value: #86868b; }
@property --text { syntax: "<color>"; inherits: true; initial-value: #86868b; }
@property --line { syntax: "<color>"; inherits: true; initial-value: transparent; }
@property --accent { syntax: "<color>"; inherits: true; initial-value: #d8d2c6; }
@property --accent-2 { syntax: "<color>"; inherits: true; initial-value: #8f8b84; }
@property --glow-strong { syntax: "<color>"; inherits: true; initial-value: transparent; }
@property --term { syntax: "<color>"; inherits: true; initial-value: #fff; }
@property --pop { syntax: "<color>"; inherits: true; initial-value: #1d1d22; }

/* The one web font (the wordmark's) lives on this site, not on Google's servers, so opening a page sends no visitor's
   address elsewhere. SIL Open Font License (assets/fonts/OFL-Figtree.txt); latin and latin-ext subsets only. */
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 500; font-display: swap;
    src: url("assets/fonts/figtree-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 500; font-display: swap;
    src: url("assets/fonts/figtree-500-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* Neutral defaults; script.js re-tints all of these from the album's colours. */
:root {
    --bg: #000;
    --fg: #f5f5f7;
    --muted: #86868b;
    --line: rgba(255, 255, 255, 0.12);
    --glass: rgba(255, 255, 255, 0.07);
    --glass-hover: rgba(255, 255, 255, 0.13);
    --glass-edge: rgba(255, 255, 255, 0.22);
    --pop: #1d1d22;
    --text: var(--muted); /* body text; the theme sets its own from the cover */
    --accent: #d8d2c6;
    --accent-2: #8f8b84;
    --glow-strong: rgba(0, 0, 0, 0.5);
    --cover-a: #888;
    --cover-b: #333;
    --term: #fff;

    /* the sheen on the disc: the only colour of the brand itself */
    --s1: #ff8fcf;
    --s2: #ffcf86;
    --s3: #a8f0c0;
    --s4: #86d2ff;
    --s5: #b39cff;
    --sheen: conic-gradient(from 200deg, transparent 0deg 4deg, var(--s1) 14deg, var(--s2) 24deg, var(--s3) 34deg, var(--s4) 44deg, var(--s5) 54deg, transparent 68deg 180deg, var(--s1) 194deg, var(--s2) 204deg, var(--s3) 214deg, var(--s4) 224deg, var(--s5) 234deg, transparent 248deg 360deg);

    --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --brand: "Figtree", ui-rounded, -apple-system, "Helvetica Neue", sans-serif;
    --ease: cubic-bezier(0.25, 0.1, 0.25, 1);
    --page-ease: cubic-bezier(0.22, 0.8, 0.24, 1);
    --turn-ease: cubic-bezier(0.3, 0.42, 0.14, 1); /* turning a page: an unhurried start and a long, soft landing */
    --gutter: clamp(20px, 5vw, 64px);
    --measure: 760px;
    --wm-top: 26px; /* the wordmark's size once it has moved to the top of the cover page */
    --wm-y: 64px;   /* and the height of its centre there */
}

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

html, body {
    height: 100%;
    overscroll-behavior: none; /* no browser back-swipe while turning pages */
}

body {
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font);
    font-size: 17px;
    letter-spacing: -0.022em;
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
    transition: background-color 1.6s var(--ease);
}

a { color: inherit; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.eyebrow {
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--accent);
}

/* ---------- Backdrop: the cover, dissolved into light ---------- */

.backdrop {
    position: fixed;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

/* on the last page tomorrow's cover takes over the light */
body.tomorrow #backdrop.loaded { opacity: 0; }
body.tomorrow #backdrop-next.loaded { opacity: 0.7; }
body:not(.tomorrow) #backdrop-next { opacity: 0; }

.backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 80% 70% at 50% 45%, transparent, var(--bg) 120%),
        color-mix(in srgb, var(--bg) 40%, transparent);
    transition: opacity 2s var(--ease);
}

body.tomorrow .backdrop::after { opacity: 0.6; }
/* In the chapters a very soft light in the cover's two colours drifts behind the text,
   so even a pale or single-coloured cover lends the page colour and depth. */
.aura {
    position: fixed;
    inset: -20%;
    pointer-events: none;
    background:
        radial-gradient(40% 45% at 22% 28%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%),
        radial-gradient(45% 50% at 80% 75%, color-mix(in srgb, var(--accent-2) 20%, transparent), transparent 70%);
    opacity: 0;
    transition: opacity 2s var(--ease);
    animation: drift 60s ease-in-out infinite alternate-reverse;
}

body.in-chapter .aura { opacity: 1; }

@keyframes drift {
    from { transform: scale(1) rotate(0deg); }
    to { transform: scale(1.15) rotate(8deg); }
}

/* ---------- The logo: disc and wordmark ---------- */

.disc {
    --s: 200px;
    --disc: #1b1a22;
    --disc-hi: #2c2a36;
    display: block;
    position: relative;
    flex: none;
    width: var(--s);
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(closest-side, var(--disc-hi), var(--disc) 72%);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
    -webkit-mask: radial-gradient(closest-side, transparent 14.5%, #000 15.2%);
            mask: radial-gradient(closest-side, transparent 14.5%, #000 15.2%);
}

.disc .sheen {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--sheen);
    opacity: 0.92;
    mix-blend-mode: screen;
    filter: blur(calc(var(--s) * 0.012));
    transform: rotate(var(--rot, 0deg));
    transition: transform 0.9s var(--page-ease);
    -webkit-mask: radial-gradient(closest-side, transparent 16%, #000 46%, #000 97%, transparent 100%);
            mask: radial-gradient(closest-side, transparent 16%, #000 46%, #000 97%, transparent 100%);
}

.disc .hub {
    position: absolute;
    inset: 31%;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

/* the big CD on the cover page: polished chrome, bright and glossy, the light caught in soft bands that show it turning.
   No blend modes or filters here: they can draw dark bars while it spins in some browsers. */
.disc.chrome {
    background:
        radial-gradient(closest-side, transparent 95.5%, rgba(255, 255, 255, 0.95) 97.5%, rgba(150, 154, 164, 0.7) 100%),
        radial-gradient(closest-side, rgba(255, 255, 255, 0.5) 15%, transparent 32%),
        conic-gradient(from 20deg, #ffffff, #c3c7cf 12.5%, #ffffff 25%, #c3c7cf 37.5%, #ffffff 50%, #c3c7cf 62.5%, #ffffff 75%, #c3c7cf 87.5%, #ffffff);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
    will-change: transform;
    backface-visibility: hidden;
}

.disc.chrome .sheen { mix-blend-mode: normal; filter: none; opacity: 0.42; }
.disc.chrome .hub { box-shadow: inset 0 0 0 1px rgba(30, 34, 44, 0.14), 0 0 0 1px rgba(255, 255, 255, 0.7); }

.wm {
    font-family: var(--brand);
    font-weight: 500;
    letter-spacing: -0.035em;
    line-height: 1;
    white-space: nowrap;
}

/* the o of "of" is a disc */
.o {
    display: inline-block;
    width: 0.56em;
    height: 0.56em;
    margin: 0 0.015em 0 0.02em;
    /* a round letter dips just below the baseline, like the o of the typeface; sitting exactly on it looks cut off */
    vertical-align: -0.02em;
    border-radius: 50%;
    background: var(--sheen), currentColor;
    -webkit-mask: radial-gradient(closest-side, transparent 30%, #000 33%);
            mask: radial-gradient(closest-side, transparent 30%, #000 33%);
}

.lockup {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    font-size: clamp(24px, 3.4vw, 34px);
    color: var(--fg);
}

.lockup.small { font-size: 15px; gap: 0.55em; }

/* ---------- Chrome ---------- */

.topbar {
    position: fixed;
    inset: 0 0 auto 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: max(20px, env(safe-area-inset-top)) var(--gutter) 20px;
    font-size: 14px;
    z-index: 3;
    transition: opacity 0.8s var(--ease);
    pointer-events: none;
}

#counter { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* text scrolling under the top bar and the page buttons fades out instead of colliding with them */
.topbar::before, .pager::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    z-index: -1;
    pointer-events: none;
}

.topbar::before { top: 0; height: 120%; background: linear-gradient(var(--bg) 35%, transparent); }
.pager::before { bottom: calc(-1 * max(24px, env(safe-area-inset-bottom))); height: 130px; background: linear-gradient(transparent, var(--bg) 75%); }
body.tomorrow .pager::before, body.tomorrow .topbar::before { opacity: 0; }

.is-hidden {
    opacity: 0 !important;
    pointer-events: none !important;
}

.pager {
    position: fixed;
    left: 0;
    right: 0;
    bottom: max(24px, env(safe-area-inset-bottom));
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 var(--gutter);
    z-index: 5;
    pointer-events: none;
    transition: opacity 0.9s var(--ease), visibility 0s;
}

/* on the logo, before the album has been opened, there is nothing to turn yet */
body.intro-shut .pager {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.5s var(--ease), visibility 0s linear 0.5s;
}

.nav {
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(1.8);
    -webkit-backdrop-filter: blur(20px) saturate(1.8);
    color: var(--fg);
    cursor: pointer;
    pointer-events: auto;
    transition: opacity 0.6s var(--ease), background 0.25s, transform 0.25s var(--ease);
}

.nav:hover { background: var(--glass-hover); }
.nav:active { transform: scale(0.94); }
.nav:focus-visible, .dots button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.nav svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.dots {
    display: flex;
    gap: 2px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(1.8);
    -webkit-backdrop-filter: blur(20px) saturate(1.8);
    pointer-events: auto;
}

.dots button {
    width: 18px;
    height: 28px;
    border: 0;
    background: none;
    cursor: pointer;
    display: grid;
    place-items: center;
}

.dots button::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: var(--fg);
    opacity: 0.28;
    transition: width 0.6s var(--page-ease), opacity 0.4s;
}

.dots button[aria-current="true"]::before { width: 14px; opacity: 0.95; }

/* ---------- Pages ---------- */

/* clip, not hidden: nothing may ever scroll the stack of pages sideways */
.deck { position: fixed; inset: 0; overflow: hidden; overflow: clip; }

/* Pages sit side by side like spreads in a magazine. Scroll down to read, swipe sideways to turn. */
.slide {
    position: absolute;
    inset: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    touch-action: pan-y;
    scrollbar-width: none;
    padding: 96px var(--gutter) 132px;
    transform: translate3d(calc(var(--offset, 0) * 100% + var(--drag, 0px)), 0, 0);
    transition: transform 1.45s var(--turn-ease), opacity 1.45s var(--turn-ease);
    will-change: transform;
}

.slide::-webkit-scrollbar { display: none; }

.slide.far { visibility: hidden; transition: none; }
.slide:not(.active) { opacity: 0.35; }
.deck.dragging .slide { transition: none; }
.deck.flick .slide { transition-duration: 1.15s; transition-timing-function: cubic-bezier(0.2, 0.62, 0.18, 1); }

/* margin:auto centres short content and still lets long content scroll */
.slide > * { margin: auto; }
.slide.page { display: flex; }

/* the words fade up a moment after the page lands */
.slide .rise {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.9s var(--ease), transform 1.1s var(--page-ease);
}

.slide.active .rise { opacity: 1; transform: none; }
.slide.active .rise:nth-child(2) { transition-delay: 0.08s; }
.slide.active .rise:nth-child(3) { transition-delay: 0.16s; }
.slide.active .rise:nth-child(n + 4) { transition-delay: 0.24s; }

/* Cover page: first the logo alone, then today's album */

.slide.front-slide {
    display: block;
    padding: 0;
}

.front-slide > * { margin: 0; }

/* the stretch of scrolling over which the CD goes in and the album comes up */
.intro-runway { height: 55vh; height: 55dvh; }

.intro {
    /* rounded to whole pixels in pairs, so the disc's centre falls on a pixel and it turns without wobbling */
    --cd: min(320px, 34vh);
    --cd: round(min(320px, 34vh), 2px);
    position: sticky;
    top: 0;
    z-index: 1;
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(28px, 5vh, 48px);
    pointer-events: none;
}

.insert { display: grid; justify-items: center; }

/* only the upper half of the CD shows above the slot */
.cd-window {
    width: calc(var(--cd) + 40px);
    height: calc(var(--cd) / 2);
    overflow: hidden;
    display: grid;
    justify-items: center;
}

/* --in: how far it has gone back into the slot */
.cd { transform: translateY(calc(var(--in, 0) * (var(--cd) / 2 + 12px))); }

.cd .disc {
    --s: var(--cd);
    animation: eject 1.6s var(--page-ease) 0.2s both;
}

@keyframes eject {
    from { translate: 0 52%; }
    to { translate: 0 0; }
}

/* the slot: a thin dark line with a glint on its lower lip */
.slot {
    width: calc(var(--cd) * 1.16);
    height: 4px;
    margin-top: -1px;
    border-radius: 999px;
    background: linear-gradient(#000, #111114);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.9), 0 1px 0 rgba(255, 255, 255, 0.16);
}

.intro-wm {
    font-size: clamp(44px, 6vw, 72px);
    color: var(--fg);
    transform-origin: center;
    will-change: transform;
}

.scroll-hint {
    position: absolute;
    bottom: max(84px, 10vh);
    display: grid;
    justify-items: center;
    gap: 14px;
    font-size: 15px;
    color: var(--muted);
}

/* a big, slow arrow in a glass circle: this page is opened downwards. Pressing it opens the album too. */
.open-album {
    width: 56px;
    height: 56px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(1.8);
    -webkit-backdrop-filter: blur(20px) saturate(1.8);
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--fg);
    cursor: pointer;
    pointer-events: auto;
    animation: nudge 2.6s var(--ease) infinite;
    transition: background 0.25s;
}

.open-album:hover { background: var(--glass-hover); }
.open-album:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.open-album svg {
    width: 28px;
    height: 28px;
    fill: none;
    stroke: var(--fg);
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

@keyframes nudge {
    0%, 100% { transform: translateY(0); opacity: 0.6; }
    50% { transform: translateY(10px); opacity: 1; }
}

.front {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    width: 100%;
    max-width: 1080px;
    margin: 0 auto;
    padding: 104px var(--gutter) 132px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(32px, 5vh, 56px);
}

/* the album fades and rises in; on the children, so the snap point itself never moves */
.front > * {
    opacity: var(--reveal, 0);
    transform: translateY(calc((1 - var(--reveal, 0)) * 48px));
}

.front .date {
    position: absolute;
    top: 86px;
    left: 0;
    right: 0;
    font-size: 15px;
    color: var(--muted);
    text-align: center;
}

.album {
    display: flex;
    align-items: center;
    gap: clamp(36px, 6vw, 96px);
    width: 100%;
}

.cover {
    position: relative;
    flex: 0 0 auto;
    display: flex;
    align-items: flex-end;
    width: min(50vh, 440px);
    aspect-ratio: 1;
    overflow: hidden;
    padding: 24px;
    border-radius: 14px;
    background: linear-gradient(135deg, var(--cover-a), var(--cover-b));
    box-shadow: 0 40px 120px -30px var(--glow-strong), 0 20px 40px -20px rgba(0, 0, 0, 0.6);
    text-decoration: none;
    transition: transform 0.6s var(--page-ease);
}

a.cover:hover { transform: scale(1.012); }
a.cover:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.cover img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.6s ease;
}

.cover.loaded img { opacity: 1; }

.cover .initials {
    font-size: 72px;
    font-weight: 700;
    letter-spacing: -0.05em;
    line-height: 1;
    color: rgba(255, 255, 255, 0.9);
    mix-blend-mode: overlay;
}

.album-info { flex: 1; min-width: 0; }

.album-title {
    margin-top: 8px;
    font-size: clamp(44px, 5.6vw, 80px);
    font-weight: 700;
    line-height: 1.03;
    letter-spacing: -0.04em;
    overflow-wrap: break-word;
}

.album-title.long { font-size: clamp(32px, 3.6vw, 52px); }

.album-artist {
    margin-top: 8px;
    font-size: clamp(22px, 2.2vw, 28px);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--muted);
}

.meta {
    margin-top: 18px;
    font-size: 15px;
    color: var(--muted);
}

.meta span + span::before { content: "·"; margin: 0 0.55em; }

.tagline {
    margin-top: 28px;
    max-width: 440px;
    font-size: 19px;
    line-height: 1.47;
    color: var(--fg);
}

/* Listening links: logos only */

.platforms {
    display: flex;
    gap: 10px;
    margin-top: 32px;
}

.platforms a {
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(1.8);
    -webkit-backdrop-filter: blur(20px) saturate(1.8);
    color: var(--fg);
    transition: background 0.25s, transform 0.25s var(--ease);
}

.platforms a:hover { background: var(--glass-hover); transform: translateY(-1px); }
.platforms a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.platforms svg { width: 18px; height: 18px; fill: currentColor; }

.turn-hint {
    font-size: 14px;
    color: var(--muted);
    text-align: center;
}

/* Chapters */

.chapter { width: 100%; max-width: var(--measure); }

.chapter-title {
    margin-top: 10px;
    font-size: clamp(40px, 5.2vw, 68px);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.04em;
}

.chapter-title.year {
    font-size: clamp(96px, 16vw, 200px);
    letter-spacing: -0.06em;
    line-height: 0.95;
    background: linear-gradient(100deg, var(--fg) 30%, var(--accent) 70%, var(--accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.chapter-sub {
    margin-top: 14px;
    font-size: clamp(21px, 2.3vw, 28px);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--muted);
}

.chapter-body { margin-top: 44px; }

.chapter p.text {
    font-size: clamp(18px, 1.5vw, 21px);
    line-height: 1.58;
    letter-spacing: -0.012em;
    color: var(--text);
}


.chapter p.text + p.text { margin-top: 1.1em; }

.pull { margin: 52px 0; }

.pull p {
    font-size: clamp(28px, 3vw, 40px);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.03em;
    color: var(--fg);
}

.pull cite {
    display: block;
    margin-top: 16px;
    font-size: 15px;
    font-style: normal;
    color: var(--muted);
}

.photo { margin: 52px 0; }

.photo img {
    display: block;
    width: 100%;
    max-height: 70vh;
    object-fit: cover;
    border-radius: 18px;
    background: var(--glass);
    box-shadow: 0 30px 80px -40px var(--glow-strong);
}

.photo figcaption {
    margin-top: 14px;
    font-size: 14px;
    line-height: 1.45;
    color: var(--muted);
}

.photo figcaption a, .video figcaption a { color: var(--muted); opacity: 0.7; text-decoration: none; }
.photo figcaption a:hover { opacity: 1; text-decoration: underline; }
/* the credit splits into photographer (file page) and licence (licence text); together they keep the old link's look */
.photo figcaption .credit { opacity: 0.7; }
.photo figcaption .credit a { opacity: 1; }

/* photos beside the text, hanging into the margin on wide screens */
.photo.left, .photo.right { width: 46%; margin-top: 8px; margin-bottom: 22px; }
.photo.left { float: left; margin-right: 34px; }
.photo.right { float: right; margin-left: 34px; }
.photo.left img, .photo.right img { max-height: none; }

@media (min-width: 1200px) {
    .photo.left { margin-left: -150px; }
    .photo.right { margin-right: -150px; }
}

.photo.wide, .pull, .video, .listen-for, .player, .facts, .stats, .voices, .awards { clear: both; }
.chapter-body::after { content: ""; display: block; clear: both; }

.video { margin: 52px 0; }

.video .frame {
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: 18px;
    background: var(--glass);
    box-shadow: 0 30px 80px -40px var(--glow-strong);
}

.video iframe { display: block; width: 100%; height: 100%; border: 0; }

a.frame { position: relative; display: block; cursor: pointer; }
a.frame img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.8s var(--page-ease), filter 0.4s; }
a.frame:hover img { transform: scale(1.02); filter: brightness(0.85); }
a.frame:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.video .play {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 72px;
    height: 72px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(20px) saturate(1.6);
    -webkit-backdrop-filter: blur(20px) saturate(1.6);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25);
    transform: translate(-50%, -50%);
    transition: transform 0.4s var(--page-ease), background 0.3s;
}

a.frame:hover .play { transform: translate(-50%, -50%) scale(1.08); background: rgba(0, 0, 0, 0.5); }
.video .play svg { width: 28px; height: 28px; margin-left: 4px; fill: #fff; }

.video figcaption { margin-top: 14px; font-size: 14px; color: var(--muted); }

/* a name with a short note on hover: tinted, with a small dot right after it */
.term {
    position: relative;
    color: var(--term);
    cursor: help;
    outline: none;
    transition: color 0.25s;
}

/* the dot that says: point at me. Set as text, so it always sits the same small step behind the word and never wraps away from it. */
.term::after {
    content: "\2022";
    margin-left: 0.08em;
    font-size: 0.95em;
    line-height: 0;
    vertical-align: 0.26em;
    color: var(--accent);
}

.term::before {
    content: attr(data-tip);
    position: absolute;
    left: 50%;
    bottom: calc(100% + 10px);
    z-index: 4;
    width: max-content;
    max-width: 280px;
    padding: 10px 14px;
    border-radius: 14px;
    background: var(--pop);
    box-shadow: 0 12px 40px -12px rgba(0, 0, 0, 0.7), inset 0 0 0 1px var(--line);
    font-size: 14px;
    font-weight: 400;
    line-height: 1.4;
    letter-spacing: -0.01em;
    color: var(--fg);
    text-align: left;
    white-space: normal;
    opacity: 0;
    transform: translate(-50%, 6px);
    transition: opacity 0.25s var(--ease), transform 0.35s var(--page-ease);
    pointer-events: none;
}

.term:hover::before, .term:focus-visible::before { opacity: 1; transform: translate(-50%, 0); }
.term:hover, .term:focus-visible { color: var(--fg); }
.term:focus-visible { box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 60%, transparent); border-radius: 4px; }

.read-on {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 64px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    font-size: 17px;
    font-weight: 600;
    cursor: pointer;
}

.read-on:hover { text-decoration: underline; }
.read-on:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }

/* Under the Hood: things to listen for */

.listen-for { margin-top: 56px; }

.listen-for h3 {
    font-size: 21px;
    font-weight: 600;
    letter-spacing: -0.02em;
}

.listen-for ul { list-style: none; margin-top: 20px; display: grid; gap: 22px; }

.listen-for li {
    position: relative;
    padding-left: 22px;
    font-size: 17px;
    line-height: 1.5;
    color: var(--text);
}

.listen-for li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent);
}

.listen-for li b { display: block; font-weight: 600; color: var(--fg); }

/* Track by Track: a small player that skips through the songs */

.player {
    margin-top: 44px;
    padding: clamp(24px, 4vw, 40px);
    border-radius: 28px;
    background: var(--glass);
    backdrop-filter: blur(30px) saturate(1.6);
    -webkit-backdrop-filter: blur(30px) saturate(1.6);
    box-shadow: inset 0 0 0 1px var(--line);
}

/* all tracks share one grid cell, so the card keeps the height of the longest */
.player-tracks { display: grid; }

.track {
    grid-area: 1 / 1;
    opacity: 0;
    visibility: hidden;
    transform: translateX(24px);
    transition: opacity 0.5s var(--ease), transform 0.7s var(--page-ease), visibility 0s linear 0.7s;
}

.track.before { transform: translateX(-24px); }

.track.current {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0.12s, 0.12s, 0s;
}

.track .no {
    font-size: 14px;
    font-weight: 600;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.track h3 {
    margin-top: 8px;
    font-size: clamp(28px, 3.2vw, 40px);
    font-weight: 700;
    line-height: 1.08;
    letter-spacing: -0.035em;
}

.track p {
    margin-top: 18px;
    font-size: clamp(17px, 1.4vw, 19px);
    line-height: 1.58;
    color: var(--text);
}

.controls {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-top: 32px;
}

.controls button.skip {
    flex: none;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: var(--glass);
    color: var(--fg);
    cursor: pointer;
    transition: background 0.25s, transform 0.25s var(--ease), opacity 0.3s;
}

.controls button.skip:hover { background: var(--glass-hover); }
.controls button.skip:active { transform: scale(0.92); }
.controls button.skip:disabled { opacity: 0.3; cursor: default; }
.controls button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.controls svg { width: 18px; height: 18px; fill: currentColor; }

.timeline { flex: 1; min-width: 0; padding-top: 16px; }

.rail {
    position: relative;
    height: 22px;
    cursor: pointer;
}

.rail::before, .fill {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    height: 3px;
    border-radius: 999px;
    transform: translateY(-50%);
}

.rail::before { right: 0; background: color-mix(in srgb, var(--fg) 18%, transparent); }

.fill {
    width: var(--at, 0%);
    background: var(--accent);
    transition: width 0.8s var(--page-ease);
}

/* the song on screen: its share of the album, lit up between its dot and the next */
.segment {
    position: absolute;
    top: 50%;
    left: var(--at, 0%);
    width: var(--len, 0%);
    height: 7px;
    border-radius: 999px;
    transform: translateY(-50%);
    background: color-mix(in srgb, var(--accent) 45%, transparent);
    transition: left 0.8s var(--page-ease), width 0.8s var(--page-ease);
    pointer-events: none;
}

/* a dot where each song begins */
.mark {
    position: absolute;
    top: 50%;
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: color-mix(in srgb, var(--fg) 40%, var(--bg));
    cursor: pointer;
    transition: background 0.4s, transform 0.25s var(--ease);
}

.mark::after { content: ""; position: absolute; inset: -8px; }
.mark:hover { transform: scale(1.35); }

/* title and length of a song when you point at its dot */
.mark::before {
    content: attr(data-tip);
    position: absolute;
    left: 50%;
    bottom: calc(100% + 12px);
    padding: 6px 10px;
    border-radius: 10px;
    background: var(--pop);
    box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.7), inset 0 0 0 1px var(--line);
    font: 500 12px/1.3 var(--font);
    letter-spacing: 0;
    color: var(--fg);
    white-space: nowrap;
    opacity: 0;
    transform: translate(-50%, 4px) scale(calc(1 / 1.35));
    transition: opacity 0.2s var(--ease), transform 0.3s var(--page-ease);
    pointer-events: none;
}

.mark:hover::before, .mark:focus-visible::before { opacity: 1; transform: translate(-50%, 0) scale(calc(1 / 1.35)); }
.mark.done { background: var(--accent); }

/* the playhead rests at the start of the song on screen */
.knob {
    position: absolute;
    top: 50%;
    left: var(--at, 0%);
    width: 16px;
    height: 16px;
    margin: -8px 0 0 -8px;
    border-radius: 50%;
    background: var(--fg);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 30%, transparent), 0 2px 10px rgba(0, 0, 0, 0.45);
    transition: left 0.8s var(--page-ease);
    pointer-events: none;
}

.times {
    display: flex;
    justify-content: space-between;
    margin-top: 2px;
    font-size: 12px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* The year: three to six headlines from the world the album was released into, set like a front page */

.facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 52px 48px;
    margin-top: 60px;
}

.fact {
    position: relative;
    padding-top: 22px;
    border-top: 1px solid var(--line);
}

/* a short stroke of colour draws itself along the rule as the story comes into view */
.fact::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    width: 56px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent), var(--accent-2));
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 1.4s var(--page-ease) 0.3s;
}

.fact.shown::before { transform: none; }

.fact-icon {
    flex: none;
    width: 22px;
    height: 22px;
    fill: none;
    stroke: var(--accent);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.fact h3 {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: clamp(21px, 2vw, 24px);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.025em;
}

.fact p {
    margin-top: 10px;
    font-size: 17px;
    line-height: 1.58;
    color: var(--text);
}

/* an odd number of stories: the first one runs across the full width */
.facts.odd .fact:first-child { grid-column: 1 / -1; }
/* in the year the topics open the chapter and the text follows them, one block's distance apart */
.chapter-body > .facts:first-child { margin-top: 0; }
.facts + p.text { margin-top: 52px; }

/* things that fade up as they are scrolled into view; the second of a pair a moment later */
.reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity 1s var(--ease), transform 1.3s var(--page-ease);
    transition-delay: var(--delay, 0s);
}

.reveal.shown { opacity: 1; transform: none; }

/* A few numbers drawn as bars */

.stats { display: grid; gap: 40px; margin: 52px 0; }

.stat figcaption {
    margin-bottom: 16px;
    font-size: 15px;
    color: var(--muted);
}

.bar {
    display: grid;
    grid-template-columns: 120px minmax(0, 1fr) 140px;
    align-items: center;
    gap: 16px;
    margin-top: 12px;
}

.bar .name { font-size: 16px; font-weight: 600; }

.track-bar {
    height: 12px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--glass);
}

.track-bar span {
    display: block;
    width: var(--w);
    height: 100%;
    border-radius: inherit;
    background: color-mix(in srgb, var(--fg) 32%, transparent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 1.6s var(--page-ease) 0.5s;
}

.bar.lead .track-bar span { background: linear-gradient(90deg, var(--accent-2), var(--accent)); }
.slide.active .track-bar span { transform: none; }

.bar .value {
    font-size: 16px;
    font-weight: 600;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.stat .source { margin-top: 10px; font-size: 12px; color: var(--muted); }

/* The Verdict: the critics' voices, set between the paragraphs, now to the left, now to the right */

.voices {
    display: grid;
    gap: 40px;
    margin: 60px 0;
}

.voice { max-width: 78%; }
.voice.left { justify-self: start; }
.voice.right { justify-self: end; }

@media (min-width: 1200px) {
    .voice.left { margin-left: -56px; }
    .voice.right { margin-right: -56px; }
}

/* a large opening mark in the album's colour */
.voice::before {
    content: "\201C";
    display: block;
    height: 0.42em;
    font-size: 76px;
    line-height: 0.9;
    color: var(--accent);
    opacity: 0.8;
}

.voice p {
    font-style: italic;
    font-size: clamp(23px, 2.3vw, 29px);
    line-height: 1.28;
    letter-spacing: -0.005em;
    color: var(--fg);
}

.voice.short p { font-size: clamp(28px, 3vw, 38px); line-height: 1.2; }
.voice p::after { content: "\201D"; }

.voice cite {
    display: block;
    margin-top: 14px;
    font-style: normal;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent);
}

.voice cite span {
    display: block;
    margin-top: 3px;
    font-weight: 400;
    letter-spacing: 0.04em;
    text-transform: none;
    font-size: 13px;
    color: var(--muted);
}

/* Awards: one small trophy for every win, drawn in the album's colour */

/* set apart as a small pane of liquid glass: clear, a bright hairline edge, light catching its top */
.awards {
    width: fit-content;
    max-width: 100%;
    margin: 44px 0;
    padding: 20px 26px 22px;
    border-radius: 22px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--glass-edge) 30%, transparent), transparent 55%), var(--glass);
    backdrop-filter: blur(28px) saturate(1.8);
    -webkit-backdrop-filter: blur(28px) saturate(1.8);
    box-shadow:
        inset 0 0 0 0.5px var(--glass-edge),
        inset 0 1px 0 color-mix(in srgb, var(--glass-edge) 80%, transparent),
        0 18px 50px -24px rgba(0, 0, 0, 0.45);
}

.awards-list {
    display: flex;
    flex-wrap: wrap;
    gap: 22px 40px;
}

.award { max-width: 260px; }

.trophies { display: flex; flex-wrap: wrap; gap: 6px; min-height: 40px; }

.trophies span {
    display: block;
    width: 30px;
    height: 38px;
    color: var(--accent);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.6s var(--ease), transform 0.8s var(--page-ease);
    transition-delay: calc(0.4s + var(--i) * 0.09s);
}

.slide.active .trophies span { opacity: 1; transform: none; }

.trophies svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.award figcaption { margin-top: 10px; }

/* a nomination: the same trophy, only as a faint outline */
.award.nominated .trophies span { color: var(--muted); }
.slide.active .award.nominated .trophies span { opacity: 0.55; }
.award.nominated .trophies svg { stroke-dasharray: 2 2.2; }

.nominee {
    display: block;
    margin-bottom: 2px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
}
.award b { font-size: 16px; font-weight: 600; letter-spacing: -0.015em; }
.award .when { margin-left: 0.6em; font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums; }
.award ul { list-style: none; margin-top: 8px; display: grid; gap: 3px; }
.award li { font-size: 13px; line-height: 1.4; color: var(--muted); }

/* ---------- Tomorrow ---------- */

.slide-tomorrow { padding: 0; overflow: hidden; }
.slide-tomorrow > * { margin: 0; }

/* "Sources" lifts the whole last page up and brings today's sources in from below. */
.tomorrow-screen,
.sources { transition: transform 1.3s var(--page-ease); }
.tomorrow-screen { position: absolute; inset: 0; }

.sources-open {
    position: absolute;
    right: var(--gutter);
    bottom: calc(max(24px, env(safe-area-inset-bottom)) + 9px);
    z-index: 2;
    border: 0;
    background: none;
    padding: 6px 0;
    font: inherit;
    font-size: 13px;
    letter-spacing: 0.02em;
    color: var(--muted);
    cursor: pointer;
    transition: color 0.4s var(--ease), opacity 0.6s var(--ease);
}
.sources-open:hover { color: var(--fg); }

.sources {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    padding: 96px var(--gutter) 160px;
    background: color-mix(in srgb, var(--bg) 72%, transparent);
}
.sources-inner { max-width: 640px; margin: 0 auto; }
.sources h2 { font-size: clamp(28px, 4vw, 40px); font-weight: 600; letter-spacing: -0.02em; margin: 18px 0 8px; }
.sources-intro { color: var(--muted); margin: 0 0 28px; }
.sources h3 {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 32px 0 10px;
}
.sources ol { list-style: none; margin: 0; padding: 0; }
.sources li { padding: 10px 0; border-top: 1px solid var(--line); font-size: 15px; line-height: 1.4; }
.sources li a { color: var(--fg); text-decoration: none; }
.sources li a:hover { text-decoration: underline; text-underline-offset: 3px; }
.sources li span { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }
.sources-close {
    border: 0;
    background: var(--glass);
    color: var(--fg);
    font: inherit;
    font-size: 13px;
    border-radius: 999px;
    padding: 7px 14px;
    cursor: pointer;
    transition: background 0.3s var(--ease);
}
.sources-close:hover { background: var(--glass-hover); }

.tomorrow-stage {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    perspective: 1400px;
}

.clock {
    position: absolute;
    top: clamp(84px, 14vh, 140px);
    right: var(--gutter);
    text-align: right;
    font-size: 14px;
    color: var(--muted);
}

.timer {
    display: block;
    margin-top: 4px;
    font-size: clamp(30px, 3.4vw, 44px);
    font-weight: 600;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    color: var(--fg);
    text-decoration: none;
}

.flow {
    position: relative;
    width: min(38vh, 340px, 64vw);
    aspect-ratio: 1;
    transform: scale(var(--breathe, 1));
}

.flow-label {
    position: absolute;
    /* wider than the cover it sits on, so the gradient text is never clipped */
    left: -50%;
    right: -50%;
    bottom: calc(100% + 28px - 0.2em);
    text-align: center;
    font-size: clamp(30px, 3.2vw, 44px);
    font-weight: 700;
    line-height: 1;
    padding-bottom: 0.2em; /* room for descenders (y, g, p) inside the gradient text, which is clipped to the box */
    letter-spacing: -0.04em;
    background: linear-gradient(100deg, var(--fg) 30%, var(--accent) 75%, var(--accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    white-space: nowrap;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 1s var(--ease) 0.9s, transform 1.2s var(--page-ease) 0.9s;
}

.slide-tomorrow.settled .flow-label { opacity: 1; transform: none; }

.flow-item {
    position: absolute;
    inset: 0;
    border: 0;
    padding: 0;
    border-radius: 12px;
    background: linear-gradient(135deg, var(--a, #555), var(--b, #222));
    box-shadow: 0 40px 100px -24px var(--glow-strong), 0 20px 40px -20px rgba(0, 0, 0, 0.6);
    transition: transform 1.6s var(--page-ease), opacity 1.2s var(--ease), filter 1.2s var(--ease);
}

.flow-item img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }

/* Cover flow: today steps aside, tomorrow moves to the centre */
.flow-next { opacity: 0; cursor: pointer; }
.flow-today { transform: none; cursor: pointer; }

.slide-tomorrow.settled .flow-next { transform: none; opacity: 1; }
.flow-today:focus-visible, .flow-next:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* tapping a cover shows where to listen to that album */
.flow-links {
    position: absolute;
    left: -24%;
    top: calc(100% + 18px);
    transform: translate(-50%, 8px);
    display: grid;
    justify-items: center;
    gap: 10px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.5s var(--ease), transform 0.7s var(--page-ease);
    white-space: nowrap;
}

.flow-links.open { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.flow-links p { font-size: 13px; color: var(--muted); }
.flow-links .platforms { margin-top: 0; }
.next-links { left: 50%; top: calc(100% + 30px); }

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

@media (max-width: 860px) {
    .slide { padding: 76px var(--gutter) 116px; }

    .album {
        flex-direction: column;
        align-items: flex-start;
        gap: 28px;
    }

    .cover { width: min(100%, 40vh); padding: 18px; }
    .tagline { margin-top: 20px; font-size: 17px; }
    .platforms { margin-top: 24px; }

    .chapter-body { margin-top: 30px; }
    .photo.left, .photo.right { float: none; width: 100%; margin: 38px 0; }
    .bar { grid-template-columns: 90px minmax(0, 1fr); }
    .bar .value { grid-column: 2; text-align: left; margin-top: -6px; font-size: 14px; }
    .front .date { top: 70px; }
    .pull, .photo { margin: 38px 0; }

    .facts { grid-template-columns: minmax(0, 1fr); gap: 40px; }
    .voice { max-width: 88%; }

    .clock { top: 72px; }
    .flow { width: min(64vw, 36vh); }
    /* the flow is 64vw wide and centred, so its left edge sits 18vw in from the screen */
    .today-links { left: calc(var(--gutter) - 18vw); justify-items: start; transform: translate(0, 8px); }
    .today-links.open { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .slide { transition-duration: 0.45s; }
    .slide .rise, .track { transform: none !important; }
    .cd .disc { animation-duration: 0.6s; }
    .reveal { transform: none; }
    .flow-item { transition-duration: 0.6s; }
}

/* ---------- Phones in portrait ---------- */

/* the note card that replaces hover notes on touch screens */
.note-card {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: calc(max(24px, env(safe-area-inset-bottom)) + 56px);
    z-index: 6;
    padding: 14px 16px 15px;
    border-radius: 18px;
    background: var(--pop);
    backdrop-filter: blur(24px) saturate(1.6);
    -webkit-backdrop-filter: blur(24px) saturate(1.6);
    box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.8), inset 0 0 0 1px var(--line);
    font-size: 15px;
    line-height: 1.45;
    color: var(--fg);
    opacity: 0;
    transform: translateY(12px);
    pointer-events: none;
    transition: opacity 0.3s var(--ease), transform 0.5s var(--page-ease);
}

.note-card.open { opacity: 1; transform: none; }
.note-card b { display: block; margin-bottom: 2px; color: var(--accent); font-weight: 600; }

@media (hover: none) {
    /* no hover bubbles on touch screens; the note card takes over */
    .term::before, .mark::before { display: none; }
}

@media (max-width: 600px) {
    :root {
        --gutter: 20px;
        --wm-top: 22px;
        --wm-y: 52px;
    }

    .page-name { display: none; }
    .topbar { padding-top: max(16px, env(safe-area-inset-top)); padding-bottom: 16px; }
    .lockup.small { font-size: 14px; }

    .slide { padding: 72px var(--gutter) 120px; }

    /* cover page */
    .intro { --cd: min(260px, 64vw, 32vh); --cd: round(min(260px, 64vw, 32vh), 2px); }
    .intro-wm { font-size: clamp(36px, 10.5vw, 46px); }
    .scroll-hint { bottom: max(72px, 9vh); }
    .front { padding: 96px var(--gutter) 112px; justify-content: flex-start; gap: 20px; }
    .front .date { top: 72px; font-size: 14px; }
    .album { gap: 22px; }
    /* the cover shrinks on shorter phones, so the whole page fits below the wordmark instead of sliding under it */
    .cover { width: min(100%, 420px, max(160px, 100dvh - 530px)); padding: 16px; border-radius: 12px; }
    .album-title { font-size: clamp(40px, 12vw, 52px); }
    .album-title.long { font-size: clamp(30px, 8.5vw, 38px); }
    .album-artist { font-size: 21px; }
    .meta { margin-top: 12px; font-size: 14px; }
    .tagline { font-size: 17px; }
    .platforms a { width: 42px; height: 42px; }
    .front .read-on { margin-top: 4px; }
    /* on a phone the cover page is centred, cover and words alike, so nothing hangs to one side */
    .album { align-items: center; text-align: center; }
    .tagline { margin-left: auto; margin-right: auto; }
    .platforms { justify-content: center; }

    /* chapters */
    .chapter-title { font-size: clamp(34px, 10vw, 44px); line-height: 1.06; }
    .chapter-title.year { font-size: clamp(96px, 30vw, 132px); }
    .chapter-sub { font-size: 20px; }
    .chapter-body { margin-top: 28px; }
    .chapter p.text { font-size: 17px; line-height: 1.6; }
    .pull { margin: 36px 0; }
    .pull p { font-size: 26px; }
    .photo, .photo.left, .photo.right, .video { margin: 32px calc(-1 * var(--gutter) + 8px); width: auto; }
    .photo img, .video .frame { border-radius: 14px; }
    .photo figcaption, .video figcaption { padding: 0 12px; font-size: 13px; }
    .read-on { margin-top: 48px; }
    .listen-for li { font-size: 16px; }

    /* track player */
    .player { margin-top: 28px; padding: 22px 18px 18px; border-radius: 24px; }
    .track h3 { font-size: 28px; }
    .track p { font-size: 16px; }
    .controls { gap: 10px; margin-top: 24px; }
    .controls button.skip { width: 40px; height: 40px; }
    .mark { width: 8px; height: 8px; margin: -4px 0 0 -4px; }
    .mark::after { inset: -6px -3px; }

    /* the year and the verdict */
    .facts { gap: 34px; margin-top: 40px; }
    .fact { padding-top: 18px; }
    .fact h3 { font-size: 21px; }
    .fact p { font-size: 16px; }
    .voices { gap: 30px; margin: 40px 0; }
    .voice { max-width: 92%; }
    .voice p { font-size: 22px; }
    .voice.short p { font-size: 26px; }
    .voice::before { font-size: 60px; }
    .awards { margin: 32px 0; padding: 18px 18px 20px; border-radius: 20px; }
    .awards-list { gap: 20px 28px; }
    .award { max-width: none; flex: 1 1 130px; }
    .trophies span { width: 24px; height: 30px; }

    /* tomorrow */
    .clock { top: 64px; right: var(--gutter); }
    .timer { font-size: 30px; }
    .flow { width: min(62vw, 34vh); margin-top: 40px; }
    .flow-label { font-size: 28px; bottom: calc(100% + 22px - 0.2em); }
    .flow-links .platforms a { width: 40px; height: 40px; }
    .next-links { top: calc(100% + 26px); }
}

/* ---------- The current design: these rules refine the ones above (they were tried out on pilot albums first) ---------- */

/* the logo is white every day, whatever the album; so is the album's title, the one other name on the cover page */
.wm, .lockup, .album-title { color: #f5f5f7; }

/* a change of album fades all of the page's colours into the new ones over the same time as the backdrop */
html {
    transition: --bg 2s var(--ease), --fg 2s var(--ease), --muted 2s var(--ease), --text 2s var(--ease), --line 2s var(--ease),
        --accent 2s var(--ease), --accent-2 2s var(--ease), --glow-strong 2s var(--ease), --term 2s var(--ease), --pop 2s var(--ease);
}

/* a page turn that commits at once and lands softly, with no hanging in between */
.slide { transition-duration: 1.1s; transition-timing-function: cubic-bezier(0.16, 0.84, 0.3, 1); }
.deck.flick .slide { transition-duration: 0.9s; transition-timing-function: cubic-bezier(0.16, 0.84, 0.3, 1); }
.deck.dragging .slide { transition: none; }

/* Headings belong to their page: they are there while it is dragged in and only brighten with it,
   one even fade, instead of appearing late and moving into place. */
.slide .rise { opacity: 1; transform: none; transition: none; }
.slide:not(.active) { opacity: 0.3; }
.slide { transition-property: transform, opacity; }

/* the year: the icons carry the topics, no rules above them */
.fact { border-top: 0; padding-top: 0; }
.fact::before { display: none; }

/* Awards on one grid: every prize gets a column of the same width, its trophies on one line of the same height,
   so names, years and categories line up across. When more prizes come than fit side by side, they wrap into
   further rows of the same columns, with the same gap down as across; nothing leaves the page. */
.awards-list {
    display: grid;
    grid-template-columns: repeat(var(--cols, 1), 190px); /* --cols: as many as fit, set by setupAwards() */
    gap: 32px;
}
.awards { padding: 24px; } /* one inset on every side */
.award { max-width: none; }
.trophies { flex-wrap: nowrap; gap: 4px; height: 38px; min-height: 0; align-items: flex-end; }
.award figcaption { margin-top: 12px; }

/* Tomorrow: a cover flow. The album at the side stands a little smaller, with clear space between the two;
   pressing it brings it to the middle. */
.flow-item { transition: transform 2.2s var(--page-ease), opacity 1.6s var(--ease), filter 1.6s var(--ease); }
.slide-tomorrow.settled.back .flow-today { transform: none; }
.slide-tomorrow.turned .flow-label { transition: opacity 0.4s var(--ease); }
.flow-label.swap { opacity: 0 !important; }
/* Covers are shown unchanged (Spotify's terms, and an altered cover is no longer the label's own picture): the flow
   only slides, scales and fades them, flat, without a turn, a reflection or dimming. The cover at the side is smaller. */
/* tomorrow's cover fades in from the place at the side, so no cover is ever half off the screen */
.flow-next { transform: translate3d(104%, 0, 0) scale(0.62); }
.slide-tomorrow.settled .flow-today { transform: translate3d(-104%, 0, 0) scale(0.62); }
.slide-tomorrow.settled.back .flow-next { transform: translate3d(104%, 0, 0) scale(0.62); }
/* whichever album stands in the middle shows its listening links under it */
.slide-tomorrow.back .today-links { left: 50%; top: calc(100% + 30px); justify-items: center; transform: translate(-50%, 8px); }
.slide-tomorrow.back .today-links.open { transform: translate(-50%, 0); }
body.tomorrow.focus-today #backdrop.loaded { opacity: 0.7; }
body.tomorrow.focus-today #backdrop-next.loaded { opacity: 0; }

@media (max-width: 860px) {
    /* on a phone the covers are a little smaller, so the one at the side keeps clear space next to the middle one */
    .flow { width: min(46vw, 30vh); margin-left: 14vw; }
    /* the flow sits a little right of centre to make room; its title and today's links stay where they were */
    .flow-label { left: calc(-50% - 7vw); right: calc(-50% + 7vw); }
    .today-links { left: calc(var(--gutter) - (114vw - min(46vw, 30vh)) / 2); }
    /* flat, the cover at the side is a little smaller and closer on a phone, so it stays whole on the screen */
    .slide-tomorrow.settled .flow-today { transform: translate3d(-90%, 0, 0) scale(0.5); }
    .slide-tomorrow.settled.back .flow-next { transform: translate3d(90%, 0, 0) scale(0.5); }
    /* before Tomorrow settles the flow still stands right of centre, so tomorrow's cover starts a little nearer */
    .flow-next { transform: translate3d(60%, 0, 0) scale(0.5); }
    /* turned back, the flow moves over to the other side, so tomorrow's cover now has the room */
    .flow { transition: margin-left 2.2s var(--page-ease); }
    /* the title moves against the flow at the same pace, so it stays in the middle of the screen throughout */
    .flow-label { transition: left 2.2s var(--page-ease), right 2.2s var(--page-ease), opacity 1s var(--ease) 0.9s, transform 1.2s var(--page-ease) 0.9s; }
    .slide-tomorrow.turned .flow-label { transition: left 2.2s var(--page-ease), right 2.2s var(--page-ease), opacity 0.4s var(--ease); }
    .slide-tomorrow.back .flow { margin-left: -14vw; }
    .slide-tomorrow.back .flow-label { left: calc(-50% + 7vw); right: calc(-50% - 7vw); }
}

@media (max-width: 600px) {
    .awards { padding: 20px; }
    .awards-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 20px; }
}

/* The year as a counter: the figures keep their width while they run, so the number never jitters */
.count { font-variant-numeric: tabular-nums; }

/* the year's topics stand as text alone */
.fact-icon { display: none; }

/* the small logo is the way home */
.topbar .lockup.home { pointer-events: auto; cursor: pointer; }
.topbar .lockup.home:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 6px; }

/* The closing page: one line of thanks in the cover's light colour, a lot of quiet around it,
   and tomorrow's ripples already moving faintly behind. */
.slide-thanks { display: grid; place-items: center; padding: 0; overflow: hidden; }
.slide-thanks > * { margin: 0; }
.thanks { position: relative; display: grid; justify-items: center; gap: 18px; padding: 0 var(--gutter); text-align: center; }
.thanks-line { font-size: clamp(34px, 4.4vw, 56px); font-weight: 600; line-height: 1.1; letter-spacing: -0.035em; color: var(--fg); }
.thanks-sub { font-size: 17px; color: var(--muted); }
/* the page buttons are showing here, unlike on the logo page, so the hint keeps the same clear space above them.
   Tomorrow's arrow down to the listening page stands in the same place, so the way on is always in one spot. */
.slide-thanks .scroll-hint,
.slide-tomorrow .scroll-hint { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 68px); }
.slide-tomorrow .scroll-hint { left: 0; right: 0; z-index: 1; pointer-events: none; }
/* while a cover's listening links are open under it, the arrow makes room for them */
.slide-tomorrow .scroll-hint { transition: opacity 0.4s var(--ease), visibility 0s; }
.slide-tomorrow:has(.flow-links.open) .scroll-hint { opacity: 0; visibility: hidden; transition: opacity 0.4s var(--ease), visibility 0s linear 0.4s; }

/* Tomorrow below the closing page: going on is a step down. The closing page rises away, tomorrow comes up
   from below, and the page dots, which count only today's pages, step aside. */
.slide-tomorrow { transform: translate3d(0, calc(min(var(--offset, 0), 1) * 100%), 0); transition-duration: 1.4s; }
body.below #thanks { transform: translate3d(0, -100%, 0); transition-duration: 1.4s; }
body.below .pager { opacity: 0; visibility: hidden; transition: opacity 0.5s var(--ease), visibility 0s linear 0.5s; }

/* One typeface for everything but the wordmark: the critics' quotes are the body face in its italic,
   so a quote reads as the same voice leaning in, not as a second font. */
.voice::before, .voice p, button { font-family: var(--font); }
.voice p { letter-spacing: -0.02em; }
.voice::before { font-weight: 700; } /* the body face's quote mark only reads as a mark when it has weight */

/* Sheets. Sources sits bottom right on the closing page, Impressum · Privacy bottom left on the cover page:
   mirrored, on the line of the page buttons, each where that page has no button. A sheet lifts its page away
   and comes up in its place, with the page movement, and the page buttons step aside meanwhile. */
.sheet-links { position: absolute; bottom: calc(max(24px, env(safe-area-inset-bottom)) + 9px); z-index: 2; display: flex; gap: 20px; }
.sheet-links.right { right: var(--gutter); }
/* the cover page's column is centred and narrower than the screen, so its left edge is measured from the screen's */
.sheet-links.left { left: calc((100% - 100vw) / 2 + var(--gutter)); }
.sheet-links .sources-open { position: static; }
/* On the phone the row is too narrow for "Impressum · Privacy" beside the page dots, so both quiet links move one
   row up, above the page buttons (40 px) with the page's own gap (20 px), and the cover page leaves that room free */
@media (max-width: 600px) {
    .sheet-links { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 40px + 20px); }
    .front { padding-bottom: 160px; }
    /* the page is exactly one screen tall and the cover gives way to the text: however many lines the title and
       the blurb take, the cover shrinks (to 160 px at least) until everything fits, so the link never sits on the dots */
    .front { height: 100dvh; }
    .album { flex: 0 1 auto; min-height: 0; }
    .cover { width: auto; height: min(100vw - 2 * var(--gutter), 420px, max(160px, 100dvh - 578px)); flex: 0 1 auto; min-height: 160px; }
    /* the critics' left-right turn needs room; on the phone it would only be a small offset, so every quote
       starts on the text's own edge, like the rest of the column */
    .voices .voice { max-width: none; justify-self: stretch; }
}
.sheet {
    position: fixed;
    z-index: 4;
    visibility: hidden;
    transition: transform 1.1s cubic-bezier(0.16, 0.84, 0.3, 1), visibility 0s linear 1.1s;
}
.sheet.open { transform: translate3d(0, -100%, 0); visibility: visible; transition-delay: 0s; }
body.sheet-open .slide.active { transform: translate3d(0, -100%, 0); }
body.sheet-page .pager::before { opacity: 0; }
body.sheet-open .pager { opacity: 0; visibility: hidden; transition: opacity 0.5s var(--ease), visibility 0s linear 0.5s; }
/* Impressum · Privacy's two tabs are pills like Back: the one showing sits on glass, the other stays quiet until pointed at */
.legal-tabs { display: flex; gap: 8px; margin: 20px 0 24px; }
.legal-tab {
    border: 0;
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: 13px;
    border-radius: 999px;
    padding: 7px 14px;
    cursor: pointer;
    transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.legal-tab:hover { color: var(--fg); }
.legal-tab[aria-selected="true"] { background: var(--glass); color: var(--fg); }
.legal-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* the top bar carries only the logo: no page name, no page number */
#counter { display: none; }

/* The kaleidoscope behind the last pages: fixed under the pages, so they move over it while it stays where it is.
   It takes the place of the ripples there. On the closing page it is softened by a blur, which clears with its colour. */
.kaleido { position: fixed; inset: 0; pointer-events: none; filter: blur(var(--blur, 0px)); transition: filter 2s var(--ease); }
.kaleido canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

/* The listening page, one step below Tomorrow: Tomorrow rises away, and this page comes up with the same movement,
   holding only the kaleidoscope's controls at the bottom, their last row on the line of the page buttons.
   A tap or drag anywhere else plays with the lines, so the page itself takes no touch gestures of the browser's. */
body.listening #tomorrow { transform: translate3d(0, -100%, 0); }
.listen {
    position: fixed;
    inset: 0;
    z-index: 2;
    visibility: hidden;
    transform: translate3d(0, 100%, 0);
    transition: transform 1.4s cubic-bezier(0.16, 0.84, 0.3, 1), visibility 0s linear 1.4s;
}
body.listening .listen { visibility: visible; transform: none; transition-delay: 0s; }
.listen { touch-action: none; -webkit-user-select: none; user-select: none; }
/* nothing scrolls here, so the top bar needs no fade */
body.listening .topbar::before { opacity: 0; }
.listen-controls {
    position: absolute;
    left: 0;
    right: 0;
    bottom: max(24px, env(safe-area-inset-bottom));
    display: grid;
    justify-items: center;
    gap: 16px;
    padding: 0 var(--gutter);
    cursor: auto;
    transition: opacity 0.4s var(--ease);
}
/* seven dials in one row; on a phone, four and three, centred */
.dials { display: grid; grid-template-columns: repeat(6, minmax(0, 120px)); gap: 14px 24px; width: 100%; justify-content: center; }
/* Shuffle, Draw and Auto side by side under the dials, with the gap of the Impressum · Privacy tabs; Draw and Auto, when on, are
   filled in the light colour, so it is plain to see. While Auto runs, the controls stay in view to watch them move. */
.listen.auto .listen-controls.asleep { opacity: 1; }
.listen-pills { display: flex; gap: 8px; }
.draw-toggle[aria-pressed="true"], .draw-toggle[aria-pressed="true"]:hover { background: var(--fg); color: var(--bg); }
.listen.drawing { cursor: crosshair; }
/* shuffle and Draw are pills like Back and the Impressum · Privacy tabs */
.shuffle, .draw-toggle {
    border: 0;
    background: var(--glass);
    color: var(--fg);
    font: inherit;
    font-size: 13px;
    border-radius: 999px;
    padding: 7px 14px;
    cursor: pointer;
    transition: background 0.3s var(--ease);
}
.shuffle:hover, .draw-toggle:hover { background: var(--glass-hover); }
.shuffle:focus-visible, .draw-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 600px) {
    .dials { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 16px; }
    .dials .dial { flex: 0 0 calc((100% - 32px) / 3); }
}
.listen-controls.asleep { opacity: 0; transition-duration: 1.2s; }
.dial { display: grid; justify-items: center; gap: 6px; font-size: 13px; letter-spacing: 0.02em; color: var(--muted); cursor: pointer; }
/* a thin line and a small round knob */
.dial input {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 20px;
    margin: 0;
    background: none;
    cursor: pointer;
    touch-action: none;
}
.dial input::-webkit-slider-runnable-track { height: 1px; background: var(--muted); opacity: 0.6; }
.dial input::-moz-range-track { height: 1px; background: var(--muted); }
.dial input::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; margin-top: -5.5px; border: 0; border-radius: 50%; background: var(--fg); }
.dial input::-moz-range-thumb { width: 12px; height: 12px; border: 0; border-radius: 50%; background: var(--fg); }
.dial input:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }
/* Mirrors snaps to whole numbers: while it moves, its number pops up above the knob, in place of the label */
.dial { position: relative; }
.dial > span { transition: opacity 0.3s var(--ease); }
.dial-count {
    position: absolute;
    top: -4px;
    left: calc(6px + var(--at, 0) * (100% - 12px));
    transform: translate(-50%, 4px);
    min-width: 26px;
    padding: 3px 8px;
    border-radius: 999px;
    background: var(--glass);
    box-shadow: inset 0 0 0 0.5px var(--glass-edge);
    color: var(--fg);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.dial.telling > span:first-child { opacity: 0; }
/* a dial that snaps shows its stops as small dots on its line, like the songs' dots on the track line */
.dial-stops { position: absolute; left: 0; right: 0; bottom: 10px; height: 0; pointer-events: none; }
.dial-stops i {
    position: absolute;
    left: calc(6px + var(--at) * (100% - 12px));
    width: 5px;
    height: 5px;
    margin: -2.5px 0 0 -2.5px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--fg) 40%, transparent);
}
.dial.telling .dial-count { opacity: 1; transform: translate(-50%, 0); }
/* streaming logos in pure white: Spotify allows its logo only in green, white or black, unchanged */
.platforms a { color: #fff; }
/* photo credits under Sources: the licence link keeps the grey of the line it sits in */
.sources li span a { color: inherit; }
/* the light behind the pages, from the album's two colours only: soft fields that drift like the old blurred cover did */
.backdrop .glow {
    position: absolute;
    inset: -25%;
    opacity: 0;
    transition: opacity 2s var(--ease);
    animation: drift 45s ease-in-out infinite alternate;
    background:
        radial-gradient(38% 42% at 30% 32%, var(--a), transparent 72%),
        radial-gradient(44% 48% at 70% 68%, var(--b), transparent 72%),
        radial-gradient(36% 40% at 72% 26%, color-mix(in oklab, var(--a) 55%, var(--b)), transparent 72%);
    filter: saturate(1.5);
}
.backdrop .glow.loaded { opacity: 0.6; }
/* video before it plays: no picture from YouTube, a field in the album's colours with the title, and a note below */
.video .poster {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    padding: 22px 24px;
    background:
        radial-gradient(70% 90% at 25% 20%, color-mix(in srgb, var(--cover-a) 45%, var(--bg)), transparent),
        linear-gradient(135deg, color-mix(in srgb, var(--cover-a) 30%, var(--bg)), color-mix(in srgb, var(--cover-b) 40%, var(--bg)));
    color: #fff;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.02em;
    transition: filter 0.4s;
}
a.frame:hover .poster { filter: brightness(0.85); }
.yt-note { display: block; margin-top: 4px; opacity: 0.7; }
.yt-note button { all: unset; cursor: pointer; }
.yt-note button:hover { text-decoration: underline; }
.yt-note button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
