﻿/* ============================================================
   LUV KIZZIN
   ============================================================ */

:root {
  --bg:        #08070a;
  --bg-2:      #0d0c10;
  --bg-3:      #131218;
  --fg:        #ece8df;
  --fg-2:      #9c978c;
  --fg-3:      #5d594f;
  --line:      rgba(236, 232, 223, 0.13);
  --line-2:    rgba(236, 232, 223, 0.26);
  --acc:       #e2311c;
  --acc-soft:  rgba(226, 49, 28, 0.16);
  --baby:      #89cff0;
  --sel-bg:    var(--acc);
  --sel-fg:    #fff;

  /* display: a didone. the thick to thin contrast is where the money is.
     text: a quiet grotesk that stays out of the way.
     label: the same grotesk, tracked wide, never a monospace. */
  --f-serif: 'Bodoni Moda', 'Didot', 'Bodoni MT', 'Playfair Display', Georgia, serif;
  --f-sans: 'Instrument Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --f-mono: 'Instrument Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  --pad: clamp(18px, 4.4vw, 68px);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-2: cubic-bezier(0.7, 0, 0.2, 1);
  --pbar: 0px;
}

[data-theme='light'] {
  --bg:        #e9e5dc;
  --bg-2:      #e2ddd2;
  --bg-3:      #d8d2c5;
  --fg:        #14120e;
  --fg-2:      #56514a;
  --fg-3:      #918a7e;
  --line:      rgba(20, 18, 14, 0.16);
  --line-2:    rgba(20, 18, 14, 0.34);
  --acc:       #b8180a;
  --acc-soft:  rgba(184, 24, 10, 0.13);
  --baby:      #3f9ac9;   /* holds the same read against bone paper */
  --sel-fg:    #f5f1e8;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scrollbar-color: var(--fg-2) var(--bg-2);   /* firefox */
  scrollbar-width: thin;
}
.rm html, html.rm { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.5;
  overflow-x: hidden;
  padding-bottom: var(--pbar);
  transition: background 0.5s var(--ease), color 0.5s var(--ease);
  -webkit-font-smoothing: antialiased;
}

body.lock { overflow: hidden; }

::selection { background: var(--sel-bg); color: var(--sel-fg); }

/* a hard slab, no radius anywhere, sitting in a channel of its own.
   the border trick with padding-box is what keeps the thumb thin
   while leaving the full 13px as grabbable target. */
::-webkit-scrollbar { width: 13px; height: 13px; }
::-webkit-scrollbar-track { background: var(--bg-2); }
::-webkit-scrollbar-thumb {
  background: var(--fg-2);
  background-clip: padding-box;
  border: 5px solid transparent;
  border-top: 0;
  border-bottom: 0;
  min-height: 44px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--acc);
  background-clip: padding-box;
  border-left-width: 3px;
  border-right-width: 3px;
}
::-webkit-scrollbar-thumb:active { background: var(--fg); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: var(--bg-2); }

h1, h2, h3, p, blockquote, figure { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; }
canvas { display: block; }

:focus-visible {
  outline: 1px solid var(--acc);
  outline-offset: 4px;
}

.skip {
  position: fixed;
  top: -100px; left: var(--pad);
  z-index: 999;
  padding: 10px 16px;
  background: var(--fg); color: var(--bg);
  font-family: var(--f-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.14em;
  transition: top 0.3s var(--ease);
}
.skip:focus { top: 14px; }

/* nothing lives behind the page. the type carries it. */

/* ------------------------------------------------------------
   the pointer

   not a ring chasing the mouse. the mark itself is pinned to the
   pixel with no lag at all, which is what precision feels like,
   and the weight is carried by a caption that trails behind and
   tells you what the thing under you actually does. the mark is
   the same red square the nav and the ticker use, so the pointer
   belongs to the same set of parts as everything else.

   only ever built on a fine pointer, and torn out on first touch.
   ------------------------------------------------------------ */

@media (hover: hover) and (pointer: fine) {
  html.nocur, html.nocur * { cursor: none !important; }
}

.cur, .curl {
  position: fixed;
  top: 0; left: 0;
  z-index: 960;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
  will-change: transform;
}
.cur.live, .curl.live { opacity: 1; }

.cur__m {
  position: absolute;
  top: 0; left: 0;
  width: 10px; height: 10px;
  margin: -5px 0 0 -5px;
  border: 1px solid var(--fg);
  transform: rotate(45deg);
  transition: width 0.35s var(--ease), height 0.35s var(--ease),
              margin 0.35s var(--ease), transform 0.45s var(--ease),
              background 0.3s, border-color 0.3s;
}
.cur.hot .cur__m {
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  background: var(--acc);
  border-color: var(--acc);
  transform: rotate(0deg);
}
.cur.down .cur__m { transform: rotate(45deg) scale(0.5); }
.cur.hot.down .cur__m { transform: rotate(0deg) scale(0.65); }

/* no chip, no panel, no border. the caption is set in the same
   didone italic as the name at the top of the page, and a halo of
   the page colour behind it keeps it readable over anything without
   putting a box around it. it wipes in the way the rest of the site
   does, so the pointer is written in the same hand as the type. */
.curl {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 400;
  font-variation-settings: 'opsz' 14, 'wght' 420;
  font-size: 19px;
  line-height: 1;
  letter-spacing: 0;
  color: var(--fg);
  white-space: nowrap;
  text-shadow:
    0 0 10px var(--bg),
    0 0 22px var(--bg),
    0 2px 30px var(--bg);
  clip-path: inset(-40% 100% -40% 0);
  transition: opacity 0.3s var(--ease), clip-path 0.5s var(--ease);
}
.curl.on { clip-path: inset(-40% -25% -40% 0); }

/* ------------------------------------------------------------
   boot screen
   ------------------------------------------------------------ */

.boot {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--pad);
  gap: 22px;
  transition: transform 1s var(--ease-2), opacity 0.6s ease 0.35s;
}
.boot.done { transform: translate3d(0, -101%, 0); opacity: 0; pointer-events: none; }
html:not(.js) .boot { display: none; }

.boot__grid {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.boot__count {
  color: var(--fg);
  font-family: var(--f-serif);
  font-weight: 500;
  font-size: clamp(44px, 13vw, 150px);
  letter-spacing: -0.01em;
  line-height: 0.82;
  font-variant-numeric: tabular-nums;
}
.boot__tag {
  font-family: var(--f-mono);
  font-size: clamp(11px, 2.4vw, 15px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-2);
  max-width: 40ch;
}

/* ------------------------------------------------------------
   top bar
   ------------------------------------------------------------ */

.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 800;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px var(--pad);
  transition: transform 0.55s var(--ease), background 0.4s, padding 0.4s var(--ease);
}
.topbar.stuck {
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  padding-top: 11px; padding-bottom: 11px;
}
/* the bar stays with you the whole way down. it never hides. */

.mark {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--f-serif);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
  transition: color 0.35s;
}
.mark:hover { color: var(--acc); }

.topnav {
  position: relative;
  display: flex;
  gap: clamp(14px, 2.4vw, 34px);
}
.topnav a {
  position: relative;
  font-family: var(--f-mono);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-3);
  padding: 4px 0;
  transition: color 0.35s;
}
.topnav a:hover, .topnav a.active { color: var(--fg); }

/* one marker for the whole bar. it slides to whichever section you
   are standing in, and previews the one you are pointing at. */
.topnav__dot {
  position: absolute;
  left: 0; bottom: -3px;
  width: 5px; height: 5px;
  margin-left: -2.5px;
  background: var(--acc);
  opacity: 0;
  transform: translate3d(0, 0, 0) rotate(45deg) scale(0.3);
  transition: transform 0.55s var(--ease), opacity 0.35s var(--ease);
  pointer-events: none;
}
.topnav__dot.on { opacity: 1; }

/* no track, no capsule. two words, the live one is simply lit. */
.switch {
  display: inline-flex;
  align-items: center;
  gap: 13px;
  cursor: pointer;
}
.switch__o {
  position: relative;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-3);
  transition: color 0.35s;
}
.switch__o::after {
  content: '';
  position: absolute;
  left: 50%; bottom: -6px;
  width: 3px; height: 3px;
  margin-left: -1.5px;
  background: var(--acc);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.3s, transform 0.4s var(--ease);
}
.switch:hover .switch__o { color: var(--fg-2); }

/* the bar holds a mark, three links and two words, so on a phone it
   tightens rather than dropping anything. it used to shed links by
   position, which broke the moment the marker span became the first
   child and the tag link went: it was hiding beats and pricin and
   leaving contact on its own. nothing here counts children now. */
@media (max-width: 800px) {
  .topbar { gap: 8px; }
  .topnav { gap: clamp(11px, 3vw, 18px); }
  .topnav a { font-size: 10px; letter-spacing: 0.1em; }
  .switch { gap: 8px; }
  .switch__o { font-size: 9.5px; letter-spacing: 0.1em; }
  .mark { font-size: 17px; }
}
@media (max-width: 420px) {
  .topbar { padding-left: 14px; padding-right: 14px; }
  .topnav { gap: 10px; }
  .topnav a { font-size: 9.5px; letter-spacing: 0.07em; }
  .switch { gap: 7px; }
  .switch__o { font-size: 9px; letter-spacing: 0.07em; }
  .mark { font-size: 16px; }
}
[data-theme='dark'] .switch__o[data-t='dark'],
[data-theme='light'] .switch__o[data-t='light'] { color: var(--fg); }
[data-theme='dark'] .switch__o[data-t='dark']::after,
[data-theme='light'] .switch__o[data-t='light']::after { opacity: 1; transform: scale(1); }

/* ------------------------------------------------------------
   hero
   ------------------------------------------------------------ */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  padding: clamp(120px, 24vh, 260px) var(--pad) clamp(28px, 5vh, 54px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}

/* on a phone the lockup is capped by the column width, not by the
   height, so it cannot grow into a full screen. sitting it at the
   bottom of one left a dead field above it. centred, with the top
   padding cut back to just clearing the bar, the space falls either
   side of the name instead of all above it. */
@media (max-width: 760px) {
  .hero {
    justify-content: center;
    min-height: 88svh;        /* lets the ticker peek, which invites the scroll */
    padding-top: 84px;
    padding-bottom: clamp(24px, 4vh, 40px);
  }
}

/* ------------------------------------------------------------
   the logotype

   two words, two voices: a didone italic over a tracked grotesk.

   set as svg on purpose. a line box is not the shape of the letters
   inside it. bodoni's box runs 1.525em tall around caps that are
   0.75em, and its italic V paints 0.1em past its own advance width,
   so every css correction for that was arithmetic on a number the
   font never promised. a viewBox taken from getBBox is the ink
   itself: the element and the letters become the same rectangle,
   both words end on the same right edge for free, and there is
   nothing left to clip.
   ------------------------------------------------------------ */

.hero__title {
  position: relative;
  margin: 0 0 clamp(26px, 5vh, 54px);
  max-width: 100%;
}
.hero__title .mask {
  display: block;
  /* wipes vertically. the sideways bleed is only as wide as the
     swell on a kick needs, so nothing can run off the column. */
  clip-path: inset(0 -8% 0 0);
}
.hero__title .mask + .mask { margin-top: var(--wm-gap, 0.02em); }

.wm {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;              /* room for the swell on a kick */
}
.wm text {
  fill: currentColor;
  text-rendering: geometricPrecision;
}

.hero__title .up {
  transform: translate3d(0, 104%, 0);
  animation: rise 1.2s var(--ease) forwards;
  animation-delay: 0.15s;
}
.hero__title .mask:nth-child(3) .up { animation-delay: 0.3s; }

/* each word carries a live axis, driven off the low end of whatever
   beat is playing. at rest they sit exactly here. */
/* bodoni carries an optical size axis, and at a 100px font size the
   browser helpfully picks opsz 96, the display cut, whose hairlines
   are drawn to almost nothing. that is what was breaking up on the
   right of the U and the V. pinning opsz low asks for the text cut
   instead, which is the same skeleton with hairlines that survive
   a real screen, and a whisker of stroke insures the rest. */
.luv {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 500;
  font-variation-settings: 'opsz' 14, 'wght' 500;
  font-size: 100px;
  letter-spacing: -0.015em;
  stroke: currentColor;
  stroke-width: 0.35;
  paint-order: stroke fill;
}
/* same face as LUV, held apart by size and tracking rather than by
   changing typeface */
.kizzin {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 500;
  font-variation-settings: 'opsz' 14, 'wght' 500;
  font-size: 100px;
  letter-spacing: 0.205em;
  stroke: currentColor;
  stroke-width: 0.35;
  paint-order: stroke fill;
}

.sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
@keyframes rise {
  to { transform: translate3d(0, 0, 0); }
}
html.rm .hero__title .up { animation: none; transform: none; }

.hero__foot {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
}
/* not a sentence any more, a list of disciplines. so it is set the
   way every other label on the site is set: small, tracked wide,
   uppercase, with the slashes carrying the one accent colour. the
   separators are drawn by css so the markup stays just the words. */
.hero__blurb {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 clamp(9px, 1vw, 15px);
  max-width: none;
  font-family: var(--f-sans);
  font-size: clamp(10.5px, 1.02vw, 13px);
  font-weight: 500;
  letter-spacing: 0.2em;
  line-height: 1.9;
  text-transform: uppercase;
  color: var(--fg-2);
}
[data-theme='dark'] .hero__blurb { color: #b6b1a6; }

.hero__blurb span + span::before {
  content: '/';
  margin-right: clamp(9px, 1vw, 15px);
  color: var(--acc);
  font-weight: 400;
  letter-spacing: 0;
}
.hero__acts { display: flex; align-items: center; gap: clamp(16px, 3vw, 40px); }

/* the whole site speaks one hover language: a bracket closes around
   whatever you are pointing at. no sweeps, no sliding fills. */
.lnk {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 11px 0;
  color: var(--fg);
  transition: color 0.35s;
}
.lnk::before, .lnk::after {
  font-family: var(--f-serif);
  font-size: 1.55em;
  font-weight: 400;
  line-height: 0;
  color: var(--acc);
  opacity: 0;
  transition: opacity 0.3s, transform 0.5s var(--ease);
}
.lnk::before { content: '['; transform: translate3d(9px, 0, 0); }
.lnk::after  { content: ']'; transform: translate3d(-9px, 0, 0); }
.lnk:hover { color: var(--acc); }
.lnk:hover::before, .lnk:hover::after { opacity: 1; transform: none; }
.lnk--big { font-size: 13px; }

/* ------------------------------------------------------------
   ticker
   ------------------------------------------------------------ */

.ticker {
  overflow: hidden;
  padding: 18px 0;
  background: var(--bg-2);
}
.ticker__row {
  display: flex;
  width: max-content;
  animation: slide 42s linear infinite;
}
.ticker:hover .ticker__row { animation-play-state: paused; }
.ticker__row span {
  display: inline-flex;
  align-items: center;
  gap: 26px;
  padding-right: 26px;
  white-space: nowrap;
  font-family: var(--f-serif);
  font-style: italic;
  font-size: clamp(19px, 3.2vw, 34px);
  color: var(--fg-2);
}
.ticker__row span b {
  width: 5px; height: 5px;
  background: var(--acc);
  display: inline-block;
  transform: rotate(45deg);
}
@keyframes slide { to { transform: translate3d(-50%, 0, 0); } }
html.rm .ticker__row { animation: none; }

/* ------------------------------------------------------------
   sections
   ------------------------------------------------------------ */

.sec { padding: clamp(70px, 12vh, 150px) var(--pad); position: relative; }
.sec--rates { background: var(--bg-2); }

.sec__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(16px, 4vw, 60px);
  align-items: end;
  margin-bottom: clamp(44px, 7vw, 92px);
}
.sec__title {
  font-family: var(--f-serif);
  font-weight: 500;
  font-size: clamp(38px, 7.4vw, 96px);
  line-height: 0.92;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
.sec__title em {
  font-style: italic;
  font-weight: 400;
  text-transform: lowercase;
  letter-spacing: 0;
}

/* one heading set in script. caps and tracking are both wrong for a
   connected hand, so both come off, and it needs a size bump since
   a script's lowercase sits far smaller than bodoni's caps. */
.sec__title--script {
  font-family: 'Great Vibes', 'Snell Roundhand', 'Apple Chancery', cursive;
  font-weight: 400;
  font-size: clamp(52px, 9.6vw, 128px);
  line-height: 1.05;
  letter-spacing: normal;
  text-transform: none;
  /* the g reaches back past where the word starts, so the line is
     nudged in far enough for its swash to live inside the box */
  padding-left: 0.09em;
  padding-right: 0.08em;
}
.sec__title--script em {
  font-style: normal;
  text-transform: none;
  color: var(--acc);
}
/* the wipe needs more bleed here: script ascenders and descenders
   swing well outside the line box. the class is doubled so these
   outrank the generic title rules further down the file. */
.sec__title.sec__title--script[data-reveal] { clip-path: inset(-28% 100% -28% -10%); }
.sec__title.sec__title--script[data-reveal].in { animation-name: titleClipScript; }

/* no red edge on this one. it works riding across flat capitals but
   looks wrong crossing a script, where the letters join and the
   baseline never sits still. the wipe alone brings it in. */
.sec__title.sec__title--script[data-reveal]::before,
.sec__title.sec__title--script[data-reveal].in::before {
  content: none;
  animation: none;
}
@keyframes titleClipScript {
  to { clip-path: inset(-28% -4% -28% -10%); }
}
.sec__note {
  max-width: 46ch;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--fg-2);
  padding-bottom: 8px;
}
@media (max-width: 860px) {
  .sec__head { grid-template-columns: 1fr; gap: 18px; align-items: start; }
}

/* ------------------------------------------------------------
   filters
   ------------------------------------------------------------ */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(14px, 2.6vw, 30px);
  margin-bottom: 26px;
}
.fbtn {
  position: relative;
  font-family: var(--f-mono);
  font-size: 11.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--fg-3);
  cursor: pointer;
  padding: 3px 0;
  transition: color 0.3s;
}
.fbtn sup {
  font-size: 8.5px;
  vertical-align: super;
  margin-left: 4px;
  opacity: 0.6;
}
.fbtn::before {
  content: '';
  position: absolute;
  left: -12px; top: 50%;
  width: 5px; height: 5px;
  margin-top: -2.5px;
  background: var(--acc);
  transform: rotate(45deg) scale(0);
  transition: transform 0.4s var(--ease);
}
.fbtn:hover { color: var(--fg); }
.fbtn.on { color: var(--fg); }
.fbtn.on::before { transform: rotate(45deg) scale(1); }

/* ------------------------------------------------------------
   track list
   ------------------------------------------------------------ */

.trk {
  position: relative;
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) 190px 62px;
  align-items: center;
  gap: 14px;
  padding: 22px 14px 22px 6px;
  cursor: pointer;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease), padding 0.45s var(--ease);
  overflow: hidden;
  isolation: isolate;
}
.trk::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--bg-3);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.55s var(--ease);
  z-index: 0;
}
.trk > * { position: relative; z-index: 1; }
.trk:hover::before { transform: scaleX(1); }
.trk:hover { padding-left: 18px; }

.trk[hidden] { display: none; }
.trk.enter { opacity: 0; transform: translate3d(0, 14px, 0); }

.trk__i {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--fg-3);
  letter-spacing: 0.08em;
  position: relative;
  display: flex;
  align-items: center;
  height: 16px;
}
.trk__n { transition: opacity 0.25s; }
.trk:hover .trk__n { opacity: 0; }
.trk__i::after {
  content: '';
  position: absolute;
  left: 2px; top: 50%;
  margin-top: -5px;
  width: 0; height: 0;
  border-left: 8px solid var(--acc);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.3s, transform 0.4s var(--ease);
}
.trk:hover .trk__i::after { opacity: 1; transform: translateX(0); }

.trk__name {
  font-family: var(--f-serif);
  font-size: clamp(18px, 2.6vw, 27px);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: uppercase;
  transition: color 0.3s;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trk__style, .trk__len {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--fg-3);
  transition: color 0.3s;
}
.trk__style { color: var(--fg-2); }
.trk__len { text-align: right; }
.trk:hover .trk__name { color: var(--acc); }
.trk:hover .trk__style, .trk:hover .trk__len { color: var(--fg-2); }

.trk.playing::before { transform: scaleX(1); background: var(--bg-3); }
.trk.playing { padding-left: 18px; }
.trk.playing .trk__name { color: var(--acc); }
.trk.playing .trk__n { opacity: 0; }
.trk.playing .trk__i::after { opacity: 0; }
.trk.playing .eq { opacity: 1; }

.eq {
  position: absolute;
  left: 2px; top: 50%;
  margin-top: -6px;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 12px;
  opacity: 0;
  transition: opacity 0.3s;
}
.eq b {
  width: 2px;
  background: var(--acc);
  height: 4px;
  animation: eq 0.9s ease-in-out infinite;
}
.eq b:nth-child(2) { animation-delay: 0.18s; }
.eq b:nth-child(3) { animation-delay: 0.36s; }
.eq b:nth-child(4) { animation-delay: 0.09s; }
@keyframes eq { 0%, 100% { height: 3px; } 50% { height: 12px; } }
.trk.playing.paused .eq b { animation-play-state: paused; }

.trk.missing { cursor: not-allowed; }
.trk.missing .trk__name { color: var(--fg-3); text-decoration: line-through; text-decoration-thickness: 1px; }
.trk.missing:hover .trk__i::after { opacity: 0; }
.trk.missing .trk__len::after { content: ' n/a'; color: var(--acc); }

/* the list opens short so a phone is not handed thirty rows to
   scroll past. big tap target, and it speaks the same bracket
   language as every other control on the site. */
.more {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 10px;
  width: 100%;
  margin-top: 26px;
  padding: 20px 0;
  font-family: var(--f-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-2);
  cursor: pointer;
  transition: color 0.35s;
}
.more::before, .more::after {
  font-family: var(--f-serif);
  font-size: 1.55em;
  line-height: 0;
  color: var(--acc);
  opacity: 0;
  transition: opacity 0.3s, transform 0.5s var(--ease);
}
.more::before { content: '['; transform: translate3d(9px, 0, 0); }
.more::after  { content: ']'; transform: translate3d(-9px, 0, 0); }
.more:hover { color: var(--fg); }
.more:hover::before, .more:hover::after { opacity: 1; transform: none; }
.more__n {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 400;
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fg-3);
}
.more[hidden] { display: none; }

/* the list is a taste, not the catalogue, so it says so and gives
   you somewhere to go. same shape as the line under the rates. */
.tracks__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-top: clamp(26px, 4vw, 44px);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--fg-2);
}
.tracks__foot p { max-width: 46ch; }

.tracks__hint {
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  margin-top: 26px;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.tracks__hint span { position: relative; padding-left: 13px; }
.tracks__hint span::before {
  content: '';
  position: absolute;
  left: 0; top: 6px;
  width: 3px; height: 3px;
  background: var(--acc);
}

@media (max-width: 900px) {
  .trk { grid-template-columns: 34px minmax(0, 1fr) auto; grid-row-gap: 5px; padding: 16px 6px; }
  .trk__name { grid-column: 2; white-space: normal; }
  .trk__len { grid-column: 3; grid-row: 1; }
  .trk__style { grid-column: 2 / -1; grid-row: 2; }
}

/* ------------------------------------------------------------
   rates
   ------------------------------------------------------------ */

.rate {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(14px, 3vw, 44px);
  align-items: center;
  padding: clamp(26px, 4vw, 46px) 6px;
  transition: padding 0.5s var(--ease);
}
.rate:hover { padding-left: 16px; }

.rate__name {
  font-family: var(--f-serif);
  font-size: clamp(27px, 4.7vw, 56px);
  font-weight: 500;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  line-height: 1;
  margin-bottom: 12px;
  transition: color 0.35s;
}
.rate:hover .rate__name { color: var(--acc); }
.rate__desc {
  max-width: 48ch;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--fg-2);
}
.rate__price {
  display: flex;
  align-items: flex-start;
  font-family: var(--f-serif);
  font-weight: 600;
  font-size: clamp(36px, 6.2vw, 76px);
  letter-spacing: -0.01em;
  line-height: 0.9;
  position: relative;
  font-variant-numeric: tabular-nums;
}
.rate__price .cur {
  font-style: italic;
  font-weight: 400;
  font-size: 0.44em;
  color: var(--acc);
  margin-right: 0.12em;
  padding-top: 0.16em;
}
.rate__alt {
  position: absolute;
  right: 0; top: calc(100% + 9px);
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3);
  white-space: nowrap;
}
.rate__alt::before { content: '/ '; color: var(--acc); }

/* the one number that is not a number */
.rate__price--ask .num {
  color: var(--acc);
  font-style: italic;
  padding-right: 0.06em;
}

/* the bottle deal is a trade, not a price, so it is set apart */
.rate--odd .rate__name { font-style: italic; text-transform: none; }
.rate__price--swap .num { color: var(--acc); }
.rate__price--swap .rate__alt::before { content: '/ '; }

/* the bottle itself, named in the display face so it stands out of
   the sentence, in a blue that belongs to nothing else on the site.
   no brackets and nothing on hover: the word is already doing the
   work, and the pointer caption says where it goes. */
.narcisse {
  font-family: var(--f-serif);
  font-weight: 700;
  font-variation-settings: 'opsz' 14, 'wght' 700;
  font-size: 1.16em;
  letter-spacing: 0;
  color: var(--baby);
}

.rates__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-top: 26px;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3);
}

@media (max-width: 720px) {
  .rate { grid-template-columns: minmax(0, 1fr); }
  .rate__price {
    grid-column: 1;
    margin-top: 18px;
    align-items: baseline;
    flex-wrap: wrap;
  }
  .rate__alt { position: static; display: block; margin: 10px 0 0 6px; align-self: end; }
}

/* ------------------------------------------------------------
   arrivals

   content is uncovered by a hard horizontal edge rather than
   floated up on a fade. nothing drifts, nothing blurs: the edge
   passes and the thing is simply there.
   ------------------------------------------------------------ */

[data-reveal] {
  clip-path: inset(0 100% 0 0);
  opacity: 0;
}
[data-reveal].in {
  clip-path: inset(0 -1% 0 0);
  opacity: 1;
  transition: clip-path 0.95s var(--ease), opacity 0.35s linear;
}
.trk[data-reveal].in {
  transition: clip-path 0.8s var(--ease), opacity 0.3s linear,
              padding 0.45s var(--ease);
}

/* section titles get the edge itself: a red rule rides the reveal
   across the word and leaves at the far side */
.sec__title[data-reveal] {
  position: relative;
  clip-path: inset(-14% 100% -14% 0);
}
.sec__title[data-reveal].in {
  animation: titleClip 0.95s var(--ease) forwards;
  transition: opacity 0.2s linear;
}
.sec__title[data-reveal]::before {
  content: '';
  position: absolute;
  inset: -14% 0;
  background: linear-gradient(90deg, transparent calc(100% - 5px), var(--acc) calc(100% - 5px));
  transform: translate3d(-100%, 0, 0);
  opacity: 0;
  pointer-events: none;
}
.sec__title[data-reveal].in::before { animation: titleEdge 0.95s var(--ease) forwards; }

@keyframes titleClip {
  to { clip-path: inset(-14% -2% -14% 0); }
}
@keyframes titleEdge {
  0%   { transform: translate3d(-100%, 0, 0); opacity: 1; }
  86%  { opacity: 1; }
  100% { transform: translate3d(1%, 0, 0); opacity: 0; }
}

html.rm [data-reveal],
html.rm .sec__title[data-reveal] { opacity: 1; clip-path: none; animation: none; }
html.rm .sec__title[data-reveal]::before { display: none; }

/* ------------------------------------------------------------
   tag section
   ------------------------------------------------------------ */

.tagsec {
  position: relative;
  padding: clamp(80px, 16vh, 190px) var(--pad);
  text-align: center;
  overflow: hidden;
  background:
    radial-gradient(90% 120% at 50% 50%, var(--bg-2) 0%, var(--bg) 72%);
}
.tagsec__label {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: clamp(22px, 4vw, 40px);
}
.tagsec__quote {
  display: flex;
  flex-direction: column;
  align-items: center;   /* each line boxes to its own text, so the
                            light maps to the words and not to the
                            empty space either side of them */
  gap: 0.04em;
  font-family: var(--f-serif);
  font-weight: 500;
  /* sized to keep the longest line on one row at every width: it
     was landing exactly on the column edge and wrapping, which put
     a word on its own line and broke the read-along mapping */
  font-size: clamp(16px, 5.6vw, 80px);
  line-height: 1.06;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
.tagsec__l { white-space: nowrap; }
.tagsec__l { position: relative; display: block; }
.tagsec__l--em {
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
  word-spacing: 0.22em;   /* the italic runs its words together */
  color: var(--acc);
}
.tagsec__l .w { display: inline-block; }
/* the tag reads itself. nothing happens until you play it, and then
   the words light from the left exactly as fast as the audio says
   them, one line handing over to the next. no jitter, no offset
   copies, no chromatic aberration: the only motion is the sound
   arriving. at rest it is simply type. */
/* the easter egg gives nothing away: no hand, no hover, no colour */
[data-nocur] { cursor: default; }

.tagsec__l { --lit: var(--fg); --dim: var(--fg-3); }
.tagsec__l--em { --lit: var(--acc); }

.tagsec__quote.reading .tagsec__l {
  /* the soft edge has to be narrower than the gap between two words,
     or the first letter of the next word starts glowing while the
     light is still finishing the one before it */
  background-image: linear-gradient(
    90deg,
    var(--lit) 0%,
    var(--lit) calc(var(--p, 0) * 100%),
    var(--dim) calc(var(--p, 0) * 100% + 1%),
    var(--dim) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
html.rm .tagsec__quote.reading .tagsec__l { background-image: none; color: var(--lit); }

/* corner marks that push out to the edges instead of a fill sliding up */
.tagsec__play {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 13px;
  margin-top: clamp(30px, 5vw, 52px);
  padding: 18px 34px;
  font-family: var(--f-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-2);
  cursor: pointer;
  transition: color 0.35s, letter-spacing 0.55s var(--ease);
}
.tagsec__play::before, .tagsec__play::after {
  content: '';
  position: absolute;
  width: 15px; height: 15px;
  border: 1px solid var(--line-2);
  transition: transform 0.55s var(--ease), border-color 0.35s;
}
.tagsec__play::before {
  top: 0; left: 0;
  border-right: 0; border-bottom: 0;
  transform: translate3d(11px, 11px, 0);
}
.tagsec__play::after {
  bottom: 0; right: 0;
  border-left: 0; border-top: 0;
  transform: translate3d(-11px, -11px, 0);
}
.tagsec__play:hover { color: var(--fg); letter-spacing: 0.26em; }
.tagsec__play:hover::before,
.tagsec__play:hover::after { transform: none; border-color: var(--acc); }
.tagsec__play.on .tri { animation: triFlash 0.6s ease infinite; }
@keyframes triFlash { 50% { opacity: 0.25; } }

.tri {
  width: 0; height: 0;
  border-left: 9px solid var(--acc);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  transition: border-color 0.3s;
}
.tri--l { transform: rotate(180deg); }

.tagsec__sig {
  margin-top: clamp(34px, 6vw, 64px);
  font-family: var(--f-serif);
  font-style: italic;
  font-size: 15px;
  letter-spacing: 0.4em;
  color: var(--fg-3);
}

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

.socials { margin-top: clamp(14px, 2vw, 26px); }
.socials a {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: clamp(20px, 3vw, 30px) 6px;
  transition: padding 0.5s var(--ease), color 0.35s;
  overflow: hidden;
  isolation: isolate;
}
.socials a > * { position: relative; z-index: 1; }
.socials a::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--bg-3);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.55s var(--ease);
  z-index: 0;
}
.socials a:hover::before { transform: scaleX(1); }
.socials a:hover { padding-left: 18px; color: var(--acc); }
.socials__t {
  position: relative;
  font-family: var(--f-serif);
  font-size: clamp(22px, 3.7vw, 42px);
  font-weight: 500;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
/* no brackets on these. the row already fills and shifts on hover,
   which is enough, and the marks were crowding the names. */
.socials__h {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--fg-3);
}
@media (max-width: 680px) {
  .socials a { grid-template-columns: minmax(0, 1fr) auto; }
  .socials__h { display: none; }
}

/* ------------------------------------------------------------
   footer
   ------------------------------------------------------------ */

.foot {
  padding: clamp(34px, 5vw, 58px) var(--pad) calc(clamp(34px, 5vw, 58px) + env(safe-area-inset-bottom));
  background: var(--bg-2);
}
.foot__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-2);
}
.foot__mid { color: var(--fg-3); text-align: center; }
.foot__row--sm {
  margin-top: 26px;
  color: var(--fg-3);
  font-size: 10px;
}
.foot__up {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: color 0.3s;
}
.foot__up::before, .foot__up::after {
  font-family: var(--f-serif);
  font-size: 1.5em;
  line-height: 0;
  color: var(--acc);
  opacity: 0;
  transition: opacity 0.3s, transform 0.45s var(--ease);
}
.foot__up::before { content: '['; transform: translate3d(7px, 0, 0); }
.foot__up::after  { content: ']'; transform: translate3d(-7px, 0, 0); }
.foot__up:hover { color: var(--fg); }
.foot__up:hover::before,
.foot__up:hover::after { opacity: 1; transform: none; }
@media (max-width: 780px) {
  .foot__row { flex-direction: column; align-items: flex-start; gap: 12px; text-align: left; }
  .foot__mid { text-align: left; }
  .foot__row--sm { flex-direction: row; align-items: center; }
}

/* ------------------------------------------------------------
   player bar
   ------------------------------------------------------------ */

.player {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 850;
  background: var(--bg-2);
  background: color-mix(in srgb, var(--bg-2) 88%, transparent);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: 0 -30px 60px -30px rgba(0, 0, 0, 0.55);
  transform: translate3d(0, 105%, 0);
  transition: transform 0.65s var(--ease);
  padding-bottom: env(safe-area-inset-bottom);
}
.player.up { transform: none; }
.player__inner {
  display: grid;
  grid-template-columns: 46px 210px minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(12px, 2vw, 26px);
  padding: 12px var(--pad);
}

.player__pp {
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  cursor: pointer;
  position: relative;
}
.player__pp .tri {
  border-left-width: 15px;
  border-top-width: 10px;
  border-bottom-width: 10px;
  transition: transform 0.4s var(--ease);
}
.player__pp:hover .tri { transform: scale(1.16); }
.player__pp .bars { display: none; gap: 4px; transition: transform 0.4s var(--ease); }
.player__pp .bars b { width: 4px; height: 19px; background: var(--acc); display: block; }
.player__pp:hover .bars { transform: scale(1.16); }
.player.playing .player__pp .tri { display: none; }
.player.playing .player__pp .bars { display: flex; }

.player__meta { min-width: 0; }
.player__title {
  display: block;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player__sub {
  display: block;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-top: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* the grab area is deliberately taller than the drawing: the canvas
   is 54px but the block around it is closer to 74, so the wave is
   easy to catch without the bar growing much */
.player__wave {
  position: relative;
  min-width: 0;
  padding: 10px 0;
  cursor: ew-resize;
  touch-action: none;      /* let a drag scrub instead of scrolling */
}
.player__wave canvas { width: 100%; height: 54px; }
.player__wave.scrub { cursor: grabbing; }
.player__t {
  position: absolute;
  bottom: -3px;
  font-family: var(--f-mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: var(--fg-3);
  pointer-events: none;
}
.player__t--a { left: 0; }
.player__t--b { right: 0; }

.player__side { display: flex; align-items: center; gap: 12px; }
.player__nav {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.3s;
}
.player__nav:hover { opacity: 1; }
.player__nav .tri { border-left-color: var(--fg); border-left-width: 7px; border-top-width: 5px; border-bottom-width: 5px; }

/* volume is a stepped meter, not a slider on a rail. the native
   input is still there, invisible, so drag and arrow keys work. */
.vol { position: relative; width: 78px; height: 22px; }
.vol__bars {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: 3px;
  pointer-events: none;
}
.vol__bars b {
  flex: 1;
  background: var(--fg-3);
  opacity: 0.4;
  transition: opacity 0.2s, background 0.25s;
}
.vol__bars b:nth-child(1) { height: 26%; }
.vol__bars b:nth-child(2) { height: 38%; }
.vol__bars b:nth-child(3) { height: 50%; }
.vol__bars b:nth-child(4) { height: 62%; }
.vol__bars b:nth-child(5) { height: 74%; }
.vol__bars b:nth-child(6) { height: 87%; }
.vol__bars b:nth-child(7) { height: 100%; }
.vol__bars b.on { opacity: 1; background: var(--fg); }
.vol:hover .vol__bars b.on { background: var(--acc); }

.vol input {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  background: none;
  cursor: ew-resize;
  outline: none;
}
.vol input::-webkit-slider-thumb { -webkit-appearance: none; width: 6px; height: 100%; background: none; }
.vol input::-moz-range-thumb { width: 6px; height: 100%; background: none; border: 0; }

.player__close {
  position: relative;
  width: 22px; height: 22px;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.3s, transform 0.4s var(--ease);
}
.player__close::before, .player__close::after {
  content: '';
  position: absolute;
  left: 3px; top: 50%;
  width: 16px; height: 1px;
  background: currentColor;
}
.player__close::before { transform: rotate(45deg); }
.player__close::after { transform: rotate(-45deg); }
.player__close:hover { opacity: 1; transform: rotate(90deg); }

@media (max-width: 1000px) {
  .player__inner { grid-template-columns: 42px minmax(0, 1fr) auto; grid-row-gap: 8px; }
  .player__wave { grid-column: 1 / -1; grid-row: 2; padding: 8px 0; }
  .player__wave canvas { height: 44px; }
  .player__side .vol { display: none; }
}
@media (max-width: 560px) {
  .player__inner { padding: 10px var(--pad) 14px; }
  .player__nav { display: none; }
}

/* ------------------------------------------------------------
   scramble helper
   ------------------------------------------------------------ */

[data-scramble] { display: inline-block; }

/* ------------------------------------------------------------
   the label voice. small, tracked, medium weight, tabular figures.
   applied last so it wins over the individual rules above.
   ------------------------------------------------------------ */

.topnav a, .switch__o, .fbtn, .trk__style, .trk__len, .rate__alt, .rates__foot, .tracks__hint,
.tagsec__label, .socials__h, .foot__row, .player__sub,
.player__t, .boot__grid, .boot__tag, .skip, .vol {
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.boot__count, .rate__price, .trk__len, .player__t { font-feature-settings: 'tnum' 1; }
