[hidden] { display: none !important; } /* never let a component's display rule show something hidden */
/* Cream on near-black, or (light switch on) the exact inverse. */
@font-face {
  font-family: "Cianchlo";
  src: url("/fonts/cianchlo.otf") format("opentype");
  font-display: swap;
}
:root {
  --cream: #faf6ec; --cream-rgb: 250 246 236; --shade-rgb: 0 0 0; --danger: #7a3b33;
  --bg: #151110; --fg: var(--cream); --muted: var(--cream); --line: #2f2926;
  --card: #1d1715; --accent: var(--cream); --accent-fg: #151110; --chip: #2c2522;
  color-scheme: dark;
}
/* Light: every colour above inverted (255 minus each channel). Chosen with the switch, remembered per browser. */
:root[data-theme="light"] {
  --cream: #050913; --cream-rgb: 5 9 19; --shade-rgb: 255 255 255; --danger: #85c4cc;
  --bg: #eaeeef; --line: #d0d6d9;
  --card: #e2e8ea; --accent-fg: #eaeeef; --chip: #d3dadd;
  color-scheme: light;
}
* { box-sizing: border-box; }
body { margin: 0; color: var(--fg); font: 14px/1.5 "IBM Plex Mono", "Courier New", monospace; background: var(--bg); }
/* Textured background drawn by bg.js: two blurred grain layers blended through an irregular mask. Sits behind everything. */
#bg-texture { position: fixed; inset: 0; z-index: -1; pointer-events: none; background-size: 100% 100%; background-repeat: no-repeat; }
main { max-width: 760px; margin: 0 auto; padding: 24px 16px 64px; }
a { color: inherit; }
h1 { margin: 0; font: 400 64px/1 "Cianchlo", serif; color: var(--cream); letter-spacing: 0.01em; filter: blur(0.35px); width: max-content; } /* soft, printed-ink edges; only as wide as the word so it can't cover the Sign in button */
h2 { font-size: 14px; margin: 0 0 8px; }
.tag, .status, .muted { color: var(--muted); }
.tag { margin: -2px 0 0; font-size: 12px; }

.listen { display: grid; justify-items: center; padding: 56px 0 36px; }
.listen-btn {
  position: relative; width: 180px; height: 180px; border-radius: 50%; border: 0;
  /* Solid cream in the middle, fading out to the page colour at the edge */
  background: radial-gradient(circle closest-side, var(--cream) 0%, rgb(var(--cream-rgb) / 1) 80%, rgb(var(--cream-rgb) / 0.98) 83%, rgb(var(--cream-rgb) / 0.92) 86%, rgb(var(--cream-rgb) / 0.8) 89%, rgb(var(--cream-rgb) / 0.62) 92%, rgb(var(--cream-rgb) / 0.4) 95%, rgb(var(--cream-rgb) / 0.18) 97.5%, rgb(var(--cream-rgb) / 0) 100%);
  color: var(--accent-fg); font-family: inherit; font-size: 12px; line-height: 1.2; font-weight: 400; cursor: pointer;
}
.listen-btn:disabled { cursor: progress; }
.listen-btn .ring { position: absolute; inset: -8px; border-radius: 50%; border: 2px solid var(--accent); opacity: 0; }
.listen-btn.on .ring { animation: pulse 1.4s ease-out infinite; }
@keyframes pulse { from { transform: scale(0.95); opacity: 0.6; } to { transform: scale(1.2); opacity: 0; } }
.status { min-height: 1.5em; margin: 16px 0 0; text-align: center; font-size: 12px; }

.manual { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 12px 0; }
.manual summary { cursor: pointer; color: var(--muted); font-size: 12px; }
.manual form { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 8px; }
input, button { font: inherit; }
input[type=search], .manual input:not([type=file]) {
  flex: 1 1 160px; min-width: 0; padding: 8px 11px; font-size: 13px; border: 0; border-radius: 0;
  background: transparent; color: var(--fg); outline: none; -webkit-appearance: none; appearance: none;
}
input[type=search]:focus, .manual input:not([type=file]):focus { box-shadow: inset 0 0 0 1px var(--cream); }
input::placeholder { color: var(--muted); opacity: 0.6; }
.chips button {
  padding: 10px 16px; border: 0; border-radius: 8px; background: var(--accent); color: var(--accent-fg); cursor: pointer;
}
/* Search button: square, dashed, like the input boxes */
.manual button {
  display: inline-block; padding: 8px 15px; border: 0; border-radius: 0;
  background: transparent; color: var(--fg); font-size: 13px; line-height: 1.5; cursor: pointer;
}
.manual button:hover { box-shadow: inset 0 0 0 1px var(--cream); }

.track { display: flex; gap: 14px; align-items: center; margin: 20px 0 6px; }
.track img { width: 72px; height: 72px; border-radius: 6px; object-fit: cover; background: var(--chip); flex: none; }
.track h2 { font-size: 17px; margin: 2px 0 0; }
.track .artist { margin: 0 0 6px; font-size: 13px; }
.links { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 12px; }

.summary { margin: 18px 0 6px; font-size: 14px; }
.summary small { display: block; font-size: 11px; color: var(--muted); opacity: 0.75; }
.stations { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 16px; }
.stations button, .chips button.off {
  border: 0; border-radius: 999px; padding: 3px 9px; background: var(--chip); color: var(--fg); font-size: 11px; cursor: pointer;
}
.chips button { border-radius: 999px; padding: 3px 10px; font-size: 11px; }
.stations button.active { background: var(--accent); color: var(--accent-fg); }
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 8px; }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.toggle { font-size: 12px; color: var(--muted); }

.plays { list-style: none; margin: 0; padding: 0; }
.plays li { display: flex; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.plays img, .plays .ph { width: 48px; height: 48px; border-radius: 4px; object-fit: cover; flex: none; background: var(--chip); }
.plays .body { min-width: 0; flex: 1; }
.plays .show { font-weight: 600; overflow-wrap: anywhere; text-decoration: none; }
.plays .show:hover { text-decoration: underline; }
.plays .meta, .plays .as { font-size: 11px; color: var(--muted); }
.plays .at { font-variant-numeric: tabular-nums; }
.badge { display: inline-block; font-size: 10px; padding: 1px 6px; border-radius: 4px; background: var(--chip); color: var(--muted); }
.more { width: 100%; margin-top: 12px; padding: 10px; border: 1px solid var(--line); border-radius: 8px; background: none; color: var(--fg); cursor: pointer; }

.history { margin-top: 40px; }
.history ul { list-style: none; padding: 0; margin: 0; overflow-y: auto; overscroll-behavior: contain; } /* height set in app.js: 4 rows */
.history button { background: none; border: 0; padding: 6px 0; color: var(--fg); cursor: pointer; text-align: left; font: inherit; }
.history time { color: var(--muted); font-size: 11px; margin-left: 6px; }

/* Player */
body.playing main { padding-bottom: 260px; }
.player {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10;
  background: var(--card); border-top: 1px solid var(--line); box-shadow: 0 -6px 24px rgb(var(--shade-rgb) / 0.25);
}
.player-head { display: flex; align-items: center; gap: 8px; max-width: 760px; margin: 0 auto; padding: 8px 16px; }
.np { flex: 1; min-width: 0; display: grid; }
.np b, .np span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np span { font-size: 11px; color: var(--muted); }
.np-btn {
  flex: none; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: none;
  color: var(--fg); font-size: 12px; text-decoration: none; cursor: pointer;
}
.player-frame { max-width: 760px; margin: 0 auto; padding: 0 16px 10px; }
.player-frame iframe { display: block; width: 100%; border: 0; border-radius: 6px; }
.player-frame .yt { height: 200px; }
.player-frame .sc { height: 120px; }
.player-frame .mc { height: 60px; }
.player-frame p { margin: 4px 0 8px; color: var(--muted); font-size: 12px; }

/* Play buttons in the list */
.plays li { align-items: flex-start; }
.plays .thumb { position: relative; flex: none; width: 48px; height: 48px; padding: 0; border: 0; background: none; cursor: pointer; }
.plays .thumb img, .plays .thumb .ph { width: 48px; height: 48px; }
.plays .thumb::after {
  content: "▶"; position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--cream); background: rgb(var(--shade-rgb) / 0.35); border-radius: 4px; font-size: 14px;
}
.plays .thumb.noaudio::after { content: none; }
.plays li.now { background: var(--chip); }
.plays .show { background: none; border: 0; padding: 0; color: inherit; font: inherit; font-weight: 600; text-align: left; cursor: pointer; }
.plays .ext { font-size: 12px; color: var(--muted); text-decoration: none; margin-left: 4px; }

/* Tabs */
.tabs { display: flex; gap: 4px; margin: 32px 0 16px; border-bottom: 1px solid var(--line); }
.tabs button { padding: 6px 10px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); font: inherit; font-size: 13px; cursor: pointer; }
.tabs button[aria-selected="true"] { color: var(--fg); border-bottom-color: var(--fg); font-weight: 600; }

/* Mixes well with */
.mix-intro { font-size: 12px; margin: 0 0 10px; }
.mix { list-style: none; margin: 0; padding: 0; }
.mix > li { padding: 10px 0; border-top: 1px solid var(--line); }
.mix .row { display: flex; gap: 10px; align-items: center; }
.mix .name { flex: 1; min-width: 0; }
.mix .name b { font-weight: 600; }
.mix .counts { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 2px; }
.mix .dig { flex: none; padding: 6px 12px; border: 0; border-radius: 8px; background: var(--accent); color: var(--accent-fg); font-family: inherit; font-size: 12px; cursor: pointer; }
.mix details { margin-top: 4px; font-size: 11px; }
.mix summary { cursor: pointer; color: var(--muted); }
.mix details ul { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 4px; }
.mix details button { background: none; border: 0; padding: 0; color: var(--fg); font: inherit; text-align: left; cursor: pointer; }
.mix details button:hover { text-decoration: underline; }
.mix .links { margin-top: 4px; font-size: 11px; }
.history-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.history-head h2 { margin: 0; }
.player-frame .sc-big { height: 200px; }
.player-frame .tap-hint { margin: 0 0 8px; color: var(--cream); font-size: 12px; }
.track .ph { display: none; } /* no cover art (name searches): keep the text flush left */

/* Hand-drawn dashed outline, so the gaps can be wider than the browser's built-in dashed border.
   --dash is the dash length, --gap the space between dashes. */
input[type=search], .manual input:not([type=file]), .manual button {
  --dash: 4px; --gap: 6px;
  background-image:
    repeating-linear-gradient(90deg, var(--cream) 0 var(--dash), transparent var(--dash) calc(var(--dash) + var(--gap))),
    repeating-linear-gradient(90deg, var(--cream) 0 var(--dash), transparent var(--dash) calc(var(--dash) + var(--gap))),
    repeating-linear-gradient(180deg, var(--cream) 0 var(--dash), transparent var(--dash) calc(var(--dash) + var(--gap))),
    repeating-linear-gradient(180deg, var(--cream) 0 var(--dash), transparent var(--dash) calc(var(--dash) + var(--gap)));
  background-size: 100% 1px, 100% 1px, 1px 100%, 1px 100%;
  background-position: 0 0, 0 100%, 0 0, 100% 0;
  background-repeat: no-repeat;
}
.upload-link { text-decoration: underline; text-underline-offset: 2px; color: inherit; }
.file-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.mix .hear { display: flex; gap: 10px; align-items: center; margin-top: 6px; font-size: 12px; }
.mix .hear button { background: none; border: 0; padding: 0; color: var(--fg); font: inherit; cursor: pointer; }
.mix .hear-btn:hover, .mix .hear-next:hover { text-decoration: underline; }
.mix .hear-next { opacity: 0.7; }
.player-frame .yt-hint { margin: 6px 0 0; font-size: 11px; opacity: 0.7; }
.mix .hear-btn { text-align: left; }
.mix .hear-btn b { font-weight: 600; }
.mix .hear-next { white-space: nowrap; flex: none; }
.link-msg { margin: 0 0 6px; font-size: 12px; min-height: 0; }
.link-msg:empty { display: none; }

/* ---------- accounts ---------- */
header { position: relative; }
/* Top bar: everything that isn't the logo or the circle lives up here, so those two stay clean */
.topbar { position: relative; z-index: 6; border-bottom: 1px solid var(--line); font-size: 11px; }
.topbar-inner { max-width: 760px; margin: 0 auto; padding: 6px 16px; display: flex; align-items: center; gap: 12px; min-height: 26px; }
.top-actions { margin-left: auto; display: flex; align-items: center; gap: 12px; flex: none; }
.acct-btn {
  padding: 4px 0 4px 4px; /* flush with the right edge, as the logo is with the left */ border: 0; background: none; color: var(--fg);
  font: inherit; font-size: 11px; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.foot { margin: 48px 0 0; padding-top: 16px; border-top: 1px solid var(--line); text-align: center; font-size: 12px; }
.foot .dug { margin: 0 0 6px; opacity: 0.8; }
.foot-links { margin: 0; opacity: 0.6; }
.small { font-size: 11px; }

/* hearts */
.heart { flex: none; align-self: center; background: none; border: 0; padding: 4px 6px; color: var(--fg); font-size: 16px; line-height: 1; cursor: pointer; opacity: 0.55; }
.heart:hover, .heart.on { opacity: 1; }
.mix .hear .heart { font-size: 14px; padding: 0 4px; }

/* sheets (Your mulch, Sign in) */
body.sheet-open { overflow: hidden; }
.sheet { position: fixed; inset: 0; z-index: 20; background: rgb(var(--shade-rgb) / 0.6); display: flex; justify-content: center; align-items: flex-start; overflow-y: auto; padding: 40px 16px; }
.sheet[hidden] { display: none; }
.sheet-inner { width: 100%; max-width: 640px; background: var(--bg); border: 1px solid var(--line); padding: 18px 18px 22px; }
.sheet-inner.narrow { max-width: 440px; }
.sheet-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.sheet-head h2 { margin: 0; font: 400 26px/1 "Cianchlo", serif; }
.sheet .tabs { margin: 10px 0 14px; }
.sheet p { font-size: 13px; }
.check { display: flex; gap: 8px; align-items: flex-start; font-size: 12px; margin: 10px 0; cursor: pointer; }
.check input { margin-top: 2px; accent-color: var(--cream); }
.dev-form { display: grid; gap: 6px; margin: 14px 0; padding: 10px; border: 1px dashed var(--line); }
.dev-form p { margin: 0; }
.dev-form input { padding: 7px 10px; font-size: 13px; background: transparent; color: var(--fg); border: 1px solid var(--line); }
.dev-form button { padding: 7px; font-size: 12px; background: var(--chip); color: var(--fg); border: 0; cursor: pointer; }
.acct-actions { display: flex; gap: 8px; margin: 16px 0 8px; }
.np-btn.danger { border-color: var(--danger); }

/* favourites list */
#fav-filter { margin-bottom: 8px; }
.fav-list { list-style: none; margin: 0; padding: 0; }
.fav-list li { display: flex; gap: 8px; padding: 10px 0; border-top: 1px solid var(--line); font-size: 13px; }
.fav-play { flex: 1; min-width: 0; text-align: left; background: none; border: 0; padding: 0; color: var(--fg); font: inherit; cursor: pointer; }
.fav-play:hover b { text-decoration: underline; }
.fav-play .badge { margin-right: 4px; }

/* history */
.hist-list h3.h-year { font-size: 14px; margin: 14px 0 4px; }
.hist-list h4.h-month { font-size: 12px; margin: 10px 0 2px; font-weight: 600; opacity: 0.8; }
.hist-list .h-day { margin: 8px 0 2px; font-size: 11px; opacity: 0.6; }
.h-item { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 4px 0; color: var(--fg); font: inherit; font-size: 13px; cursor: pointer; }
.h-item:hover { text-decoration: underline; }
.later-btn { display: block; width: 100%; margin-top: 10px; padding: 8px; background: none; border: 0; color: var(--fg); font: inherit; font-size: 12px; text-decoration: underline; cursor: pointer; }

.oauth { display: grid; gap: 8px; margin: 14px 0 6px; }
.oauth-btn { display: block; padding: 10px 14px; text-align: center; text-decoration: none; color: var(--accent-fg); background: var(--accent); font-size: 13px; }
.email-form { display: grid; gap: 6px; margin: 10px 0 0; }
.email-form input { padding: 8px 10px; font: inherit; font-size: 13px; background: transparent; color: var(--fg); border: 1px dashed var(--cream); border-radius: 0; }
.email-form button { padding: 8px; font: inherit; font-size: 13px; background: none; color: var(--fg); border: 1px dashed var(--cream); cursor: pointer; }
.email-form button:hover { border-style: solid; }
.or { display: flex; align-items: center; gap: 8px; margin: 6px 0 4px; font-size: 11px; opacity: 0.7; }
.or::before, .or::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
#email-msg:empty { display: none; }

/* Tap to listen: a slow, subtle "breathing" while idle (stops while listening, and for people who prefer less motion).
   Only transform and opacity animate, so phones can run it smoothly without redrawing the circle each frame. */
@keyframes breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes glow    { 0%, 100% { opacity: 0; }         50% { opacity: 1; } }
.listen-btn { will-change: transform; }
.listen-btn::before {
  content: ""; position: absolute; inset: -22px; border-radius: 50%; z-index: -1; pointer-events: none; opacity: 0;
  background: radial-gradient(circle closest-side, rgb(var(--cream-rgb) / 0.16), rgb(var(--cream-rgb) / 0.06) 70%, rgb(var(--cream-rgb) / 0) 100%);
}
.listen-btn:not(.on):not(:disabled),
.listen-btn:not(.on):not(:disabled)::before { animation: breathe 4.2s cubic-bezier(0.37, 0, 0.63, 1) infinite; }
.listen-btn:not(.on):not(:disabled)::before { animation-name: glow; }
.listen-btn:hover, .listen-btn:hover::before { animation-play-state: paused; }
.listen { isolation: isolate; } /* keeps the glow layer behind the circle but above the page */
@media (prefers-reduced-motion: reduce) { .listen-btn, .listen-btn::before, .listen-btn .ring { animation: none !important; } }
/* The tagline in its own ruled band, between the listen circle and the search boxes */
.intro { margin-top: 28px; padding: 14px 0; border-top: 1px solid var(--line); text-align: center; }
.intro .tag { margin: 0; }
/* "Get the app" (phones only): quiet, there if you look for it */
.get-app { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 10px; white-space: nowrap; color: rgb(var(--cream-rgb) / 0.5); }
.get-app span { min-width: 0; }
.get-app button { flex: none; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; padding: 2px; }
.get-app-btn { text-decoration: underline; text-underline-offset: 3px; color: rgb(var(--cream-rgb) / 0.7) !important; }
.track-note { margin: -2px 0 8px; font-size: 11px; opacity: 0.75; }

/* "Where are you based?" */
.area-field { display: grid; gap: 6px; margin: 12px 0; font-size: 12px; }
.area-field select { padding: 7px 10px; font: inherit; font-size: 13px; color: var(--fg); background: var(--bg); border: 1px dashed var(--cream); border-radius: 0; }
.area-options { display: grid; gap: 6px; margin: 12px 0 4px; }
.area-opt { padding: 9px 12px; text-align: left; font: inherit; font-size: 13px; color: var(--fg); background: none; border: 1px dashed var(--cream); cursor: pointer; }
.area-opt:hover { border-style: solid; }
.city-input, .loc input { width: 100%; padding: 8px 10px; font: inherit; font-size: 13px; color: var(--fg); background: transparent; border: 1px dashed var(--cream); border-radius: 0; }
.london { margin: 10px 0 4px; }
.london p { margin: 0 0 6px; }
.london-chips { flex-wrap: wrap; }
.ask-save { width: 100%; margin-top: 12px; border: 0; cursor: pointer; font: inherit; font-size: 13px; }
.loc .np-btn { margin-top: 8px; }

/* Phones: artist / link, track and Search each on their own full-width line */
@media (max-width: 600px) {
  .manual form { flex-direction: column; align-items: stretch; }
  .manual form input:not([type=file]), .manual form button { flex: none; width: 100%; }
}

/* Light / dark switch, in the top right corner above Sign in */
.theme-btn { display: block; padding: 4px; border: 0; background: none; appearance: none; line-height: 0; cursor: pointer; }
.theme-btn .sw-track { display: block; position: relative; width: 26px; height: 14px; border: 1px dashed var(--fg); border-radius: 0; }
.theme-btn .sw-knob { position: absolute; top: 2px; left: 2px; width: 8px; height: 8px; background: var(--fg); transition: transform 0.2s; }
.theme-btn[aria-checked="true"] .sw-knob { transform: translateX(12px); }
@media (prefers-reduced-motion: reduce) { .theme-btn .sw-knob { transition: none; } }
