/* DriftFM shared UI layer.
 *
 * Design intent: Apple/Spotify-style restraint — one accent colour, one border
 * weight, one radius scale, dense rows, and type that stays legible at 12px
 * (system UI font for chrome, the brand face only for headings/logo).
 *
 * Loaded by every page; page-specific layout still lives in each template.
 */

:root{
  --bg:#0b0c10;
  --panel:#15161c;
  --panel2:#1c1d25;
  --text:#f1f2f7;
  --muted:#8e95a8;

  /* ------------------------------------------------------------- brand ------
   * "Citrine". The queue's picks are gems, and citrine is the gemstone nobody in
   * music has claimed: Spotify is green, Deezer purple, Discord blurple, YouTube
   * and Last.fm red, SoundCloud orange, Apple Music pink-red, Amazon cyan,
   * Pandora blue. Gold on a blue-black also reads premium where a flat red reads
   * like an error state.
   *
   * This block is the entire identity — every page inherits from here, so a
   * rebrand is one swap (see the alternates at the end of this file):
   *   --accent       the colour
   *   --accent2      its deeper half, for gradients and hover states
   *   --accent-ink   text and icons sitting ON the accent (not white: on a warm
   *                  accent white looks washed out, dark ink looks expensive)
   *   --accent-soft  faint fill behind active chips and the playing row
   *   --accent-line  borders around that fill
   *   --accent-glow  shadows under accent buttons
   *   --accent-tint  accent-coloured text on dark surfaces
   *   --accent-hover brightened accent for hover-only affordances
   */
  --accent:#f2b01e;
  --accent2:#d98a00;
  --accent-ink:#1b1204;
  --accent-soft:rgba(242,176,30,.12);
  --accent-line:rgba(242,176,30,.34);
  --accent-glow:rgba(242,176,30,.30);
  --accent-glow-strong:rgba(242,176,30,.45);
  --accent-tint:#ffe0a6;
  --accent-hover:#ffc53d;

  /* Structure */
  --line:rgba(255,255,255,.08);
  --line-strong:rgba(255,255,255,.16);
  --surface:rgba(255,255,255,.03);
  --surface-2:rgba(255,255,255,.06);
  --hover:rgba(255,255,255,.06);
  --info-soft:rgba(105,184,255,.12);
  --info-line:rgba(105,184,255,.32);

  --r-xs:6px;
  --r-sm:8px;
  --r-md:10px;
  --r-lg:14px;
  --r-pill:999px;
  --h-ctl:34px;
  --h-ctl-sm:28px;

  --font-ui:"Plus Jakarta Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,system-ui,sans-serif;
  --font-brand:"Outfit","Plus Jakarta Sans",-apple-system,"Segoe UI",sans-serif;
}

/* Links inherited the browser's blue, which reads as an artefact on a dark page. Accent for the
   colour, an underline only on hover so long lists of artist links stay quiet. */
/* Not .btn: an anchor styled as a button paints its own background, and forcing the accent colour
   made it accent-on-accent - invisible. Those keep whatever the button rules give them. */
a:not(.btn){color:var(--accent);text-decoration:none;}
a:not(.btn):hover{text-decoration:underline;}
a:not(.btn):visited{color:var(--accent);}
a.btn{color:var(--accent-ink);text-decoration:none;}
a.btn.ghost{color:var(--text);}


/* ----------------------------------------------------------- scrollbars -----
 * Thin everywhere: `scrollbar-width`/`scrollbar-color` cover Firefox and Chrome
 * 121+, and the WebKit pseudo-elements cover everything older. Where both are
 * understood the standard pair wins, so they never fight.
 */
*{scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.16) transparent;}
::-webkit-scrollbar{width:8px;height:8px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{
  background:rgba(255,255,255,.16);
  border-radius:var(--r-pill);
  border:2px solid transparent;
  background-clip:padding-box;
}
::-webkit-scrollbar-thumb:hover{background:var(--accent-line);background-clip:padding-box;}
::-webkit-scrollbar-corner{background:transparent;}

/* ----------------------------------------------------------- logo lockup ---
 * A cut citrine (the app's picks are "gems") next to a tightly tracked wordmark.
 * Every page includes templates/_logo.html so there is one definition; only the
 * surrounding `.logo` rule (font-size) differs per page.
 */
.logo-lockup{display:inline-flex;align-items:center;gap:.34em;}
.logo-gem{
  width:.92em;
  height:.92em;
  flex:0 0 auto;
  display:block;
  filter:drop-shadow(0 2px 7px var(--accent-glow));
}
.logo-word{font-family:var(--font-brand);letter-spacing:-.035em;}
.logo-fm{color:var(--accent);}

/* ---------------------------------------------------------------- icons ---
 * Material Symbols Rounded, served as one SVG sprite (/static/icons.svg).
 * Usage: <svg class="ic" aria-hidden="true"><use href="/static/icons.svg#ic-play"></use></svg>
 */
.ic{
  width:20px;
  height:20px;
  flex:0 0 auto;
  fill:currentColor;
  display:inline-block;
  vertical-align:-5px;
  pointer-events:none;
}
.ic-sm{width:16px;height:16px;vertical-align:-3px;}
.ic-lg{width:24px;height:24px;vertical-align:-6px;}
.ic-xl{width:32px;height:32px;vertical-align:-8px;}

/* --------------------------------------------------------- icon buttons --- */
.iconbtn{
  appearance:none;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:var(--h-ctl);
  height:var(--h-ctl);
  padding:0;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  background:transparent;
  color:var(--muted);
  cursor:pointer;
  text-decoration:none;
  transition:background .12s ease,color .12s ease,border-color .12s ease;
}
.iconbtn:hover{background:var(--hover);color:var(--text);}
.iconbtn:focus-visible{outline:2px solid var(--accent);outline-offset:1px;}
.iconbtn.is-on{color:var(--accent);}
.iconbtn.is-on:hover{background:var(--accent-soft);}
.iconbtn:disabled{opacity:.45;cursor:not-allowed;}
.iconbtn-sm{width:var(--h-ctl-sm);height:var(--h-ctl-sm);border-radius:var(--r-xs);}

/* ------------------------------------------------------ service icons -----
 * These logos have wildly different aspect ratios (Last.fm ships a wide
 * wordmark, YouTube is 4:3, the rest are square), so height drives the size and
 * width follows. Fixing both axes is what used to squash them.
 */
.service-link{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  opacity:.55;
  transition:opacity .12s ease;
}
.service-link:hover{opacity:1;}
.service-icon{height:15px;width:auto;display:block;}
.service-icon--wide{height:11px;}
.service-icon--square{height:16px;}

/* --------------------------------------------------------- tooltips -------
 * Rendered by /static/common.js: the first hover adopts a native `title` into
 * `data-tip` and shows this instead, so no browser tooltip ever appears.
 */
.drift-tip{
  position:fixed;
  z-index:1400;
  display:none;
  max-width:260px;
  padding:6px 9px;
  border:1px solid var(--line-strong);
  border-radius:var(--r-sm);
  background:rgba(24,26,34,.98);
  color:var(--text);
  font-family:var(--font-ui);
  font-size:12px;
  line-height:1.35;
  text-align:center;
  box-shadow:0 10px 26px rgba(0,0,0,.45);
  pointer-events:none;
}
.drift-tip.active{display:block;}
.drift-tip::after{
  content:"";
  position:absolute;
  left:50%;
  width:8px;
  height:8px;
  background:rgba(24,26,34,.98);
  transform:translateX(-50%) rotate(45deg);
}
.drift-tip[data-placement="bottom"]::after{
  top:-5px;
  border-top:1px solid var(--line-strong);
  border-left:1px solid var(--line-strong);
}
.drift-tip[data-placement="top"]::after{
  bottom:-5px;
  border-right:1px solid var(--line-strong);
  border-bottom:1px solid var(--line-strong);
}

/* ------------------------------------------------------------ toolbars --- */
.toolbar{
  display:flex;
  align-items:center;
  gap:6px;
  flex-wrap:wrap;
  font-family:var(--font-ui);
}
.toolbar-spacer{flex:1 1 auto;}

.seg{
  display:inline-flex;
  align-items:center;
  gap:2px;
  padding:2px;
  border:1px solid var(--line);
  border-radius:var(--r-pill);
  background:var(--surface);
}
.seg > .btn,
.seg > .deep-toggle,
.seg > .guided-btn{
  height:var(--h-ctl-sm);
  border:1px solid transparent;
  border-radius:var(--r-pill);
  background:transparent;
  box-shadow:none;
  color:var(--muted);
  font-family:var(--font-ui);
  font-size:13px;
  font-weight:500;
  padding:0 12px;
  display:inline-flex;
  align-items:center;
  gap:6px;
  cursor:pointer;
  transition:background .12s ease,color .12s ease;
}
.seg > .btn:hover,
.seg > .deep-toggle:hover,
.seg > .guided-btn:hover:not(.disabled){
  background:var(--hover);
  color:var(--text);
  transform:none;
  filter:none;
}
.seg > .deep-toggle.active,
.seg > .guided-btn:not(.disabled):not(.off){
  background:var(--accent-soft);
  border-color:var(--accent-line);
  color:var(--accent-tint);
}
.seg > .deep-toggle.off{background:transparent;border-color:transparent;color:var(--muted);}
.seg > .guided-btn.disabled{opacity:.5;}

/* ---------------------------------------------------------- track list ---
 * Rows are shared by the discover queue, favorites and shared queues so the
 * density stays identical everywhere.
 */
.tracklist{display:flex;flex-direction:column;gap:1px;font-family:var(--font-ui);}

/* The discover page reuses #grid (a card grid) as the queue container. Higher
   specificity so the queue is always a single dense column, and minmax(0,…)
   keeps nowrap text from forcing the column wider than the viewport. */
.grid.tracklist{
  display:flex;
  flex-direction:column;
  gap:2px;
  margin-top:14px;
  grid-template-columns:none;
  justify-content:flex-start;
  min-width:0;
}
.grid.tracklist > *{min-width:0;}

.track{
  display:flex;
  align-items:center;
  gap:10px;
  padding:5px 8px;
  border:1px solid transparent;
  border-radius:var(--r-md);
  transition:background .12s ease,border-color .12s ease;
}
.track:hover{background:var(--surface);border-color:var(--line);}
.track.playing{background:var(--accent-soft);border-color:var(--accent-line);}
.track.shimmer{
  background:linear-gradient(90deg,#1a1b23 0%,#24263a 50%,#1a1b23 100%);
  background-size:200% 100%;
  animation:shimmer 1.3s infinite;
}

/* Index doubles as the play button (Spotify): the number is replaced on hover,
   which keeps the row narrow without losing a big touch target. */
.track-slot{position:relative;width:26px;height:26px;flex:0 0 auto;display:grid;place-items:center;}
.track-num{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;}
.track-play{
  position:absolute;
  inset:0;
  display:none;
  place-items:center;
  padding:0;
  border:0;
  border-radius:50%;
  background:transparent;
  color:var(--text);
  cursor:pointer;
}
.track:hover .track-num,
.track:focus-within .track-num{visibility:hidden;}
.track:hover .track-play,
.track:focus-within .track-play,
.track.playing .track-play{display:grid;}
.track-play:hover{color:var(--accent);}

.track-cover{
  width:38px;
  height:38px;
  flex:0 0 auto;
  border-radius:var(--r-xs);
  object-fit:cover;
  background:var(--surface-2);
}

.track-main{
  flex:1 1 auto;
  min-width:0;
  display:flex;
  flex-direction:column;
  gap:1px;
}
/* Line 1: who it is, then what it is. */
.track-artist{
  min-width:0;
  font-size:13.5px;
  line-height:1.3;
  letter-spacing:-.1px;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.track-artist-name{font-weight:600;}
.track-artist-title{font-weight:500;color:#c9cfdd;}
.track-artist-title::before{
  content:"\2014";
  margin:0 7px;
  color:rgba(255,255,255,.28);
  font-weight:400;
}
/* Line 2: where the pick came from. */
.track-release{
  display:flex;
  align-items:center;
  gap:6px;
  min-width:0;
  font-size:12px;
  line-height:1.3;
  color:var(--muted);
}
.track-release:empty{display:none;}
.track-seed{
  display:inline-flex;
  align-items:center;
  gap:5px;
  flex:0 0 auto;
  min-width:0;
  padding:0;
  border:0;
  background:none;
  color:var(--accent-tint);
  font-family:var(--font-ui);
  font-size:12px;
  font-weight:600;
  cursor:pointer;
  max-width:min(240px,42vw);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.track-seed .seed-label{
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.track-seed:hover{color:#fff;text-decoration:underline;text-underline-offset:2px;}
.track-seed.active{color:var(--accent);}
.track-seed.loading{opacity:.6;cursor:progress;}

/* Detail popover: album, depth, genres and tags live here, not in the row. */
.track-popover{
  position:fixed;
  z-index:1000;
  display:none;
  width:min(300px,90vw);
  padding:12px 14px;
  border:1px solid var(--line-strong);
  border-radius:var(--r-md);
  background:rgba(18,19,27,.98);
  box-shadow:0 18px 44px rgba(0,0,0,.5);
  font-family:var(--font-ui);
  font-size:13px;
  color:var(--text);
}
.track-popover.active{display:block;}
.tp-title{font-weight:600;font-size:13px;letter-spacing:-.1px;}
.tp-artist{color:var(--muted);margin-top:1px;}
.tp-list{
  display:grid;
  grid-template-columns:auto minmax(0,1fr);
  gap:5px 12px;
  margin:10px 0 0;
  padding-top:10px;
  border-top:1px solid var(--line);
}
.tp-list dt{color:var(--muted);font-size:12px;white-space:nowrap;}
.tp-list dd{margin:0;min-width:0;overflow-wrap:anywhere;}
.tp-hint{color:var(--muted);font-size:11px;}
/* Values inside the popover: same inline tag treatment the row used to have. */
.track-popover .pl-tag{font-size:12px;color:var(--muted);}
.track-popover .pl-tag.pl-genre{color:#cfe9ff;}
.track-popover .pl-tag.pl-depth{font-variant-numeric:tabular-nums;}

/* Right-hand affordances: links dimmed-in, row actions revealed on hover.
   The first action is the save state, so it stays visible (dimmed) at rest. */
.track-links{display:flex;align-items:center;gap:8px;flex:0 0 auto;}
.track-actions{display:flex;align-items:center;gap:1px;flex:0 0 auto;}
.track-actions .iconbtn.is-on{opacity:1;}
@media (hover:hover){
  .track-actions .iconbtn{opacity:0;transition:opacity .12s ease,color .12s ease,background .12s ease;}
  .track-actions .iconbtn.keep-visible{opacity:.55;}
  .track:hover .track-actions .iconbtn,
  .track:focus-within .track-actions .iconbtn,
  .track-actions .iconbtn.is-on,
  .track-actions .iconbtn:focus-visible{opacity:1;}
}

@media (max-width:820px){
  .track{gap:9px;}
  .track-links{gap:6px;}
}
@media (max-width:760px){
  .track-slot{display:none;}
  .track-links{display:none;}
  .track-cover{width:36px;height:36px;}
  .track-actions .iconbtn{width:26px;height:26px;}
}
@media (max-width:620px){
  .track{gap:8px;}
  .track-seed{max-width:60vw;}
  /* Four row actions plus a cover is a lot of chrome for 390px: shrink them so
     the artist and title keep their room. */
  .track-actions{gap:0;}
  .track-actions .iconbtn{width:24px;height:24px;}
  .track-popover{width:min(320px,92vw);}
}

/* ------------------------------------------------------------- themes ------
 * The default identity is the :root block at the top of this file. These are the
 * alternates the in-app picker offers, and each is a complete token set, so a
 * theme can never half-apply. `data-theme` goes on <html> (set by the inline head
 * script in index.html and by common.js, so it lands before first paint).
 *
 * Ink is chosen for contrast rather than taste: every one of these clears 5.9:1
 * for text sitting on the accent, where the old red managed 4.2:1.
 */
[data-theme="ion"]{
  --accent:#ff3d8b; --accent2:#d81e6a; --accent-ink:#1b0210;
  --accent-soft:rgba(255,61,139,.12); --accent-line:rgba(255,61,139,.34);
  --accent-glow:rgba(255,61,139,.32); --accent-glow-strong:rgba(255,61,139,.46);
  --accent-tint:#ffd0e2; --accent-hover:#ff5c9d;
}
[data-theme="lagoon"]{
  --accent:#14c8b8; --accent2:#0b9c90; --accent-ink:#04211f;
  --accent-soft:rgba(20,200,184,.12); --accent-line:rgba(20,200,184,.34);
  --accent-glow:rgba(20,200,184,.30); --accent-glow-strong:rgba(20,200,184,.45);
  --accent-tint:#bdf3ec; --accent-hover:#2adfcb;
}
[data-theme="ice"]{
  --accent:#4cc3ff; --accent2:#1f9fe0; --accent-ink:#04212f;
  --accent-soft:rgba(76,195,255,.12); --accent-line:rgba(76,195,255,.34);
  --accent-glow:rgba(76,195,255,.28); --accent-glow-strong:rgba(76,195,255,.44);
  --accent-tint:#cdeaff; --accent-hover:#6fd0ff;
}
[data-theme="volt"]{
  --accent:#c6f13c; --accent2:#9ccb16; --accent-ink:#16210a;
  --accent-soft:rgba(198,241,60,.12); --accent-line:rgba(198,241,60,.32);
  --accent-glow:rgba(198,241,60,.26); --accent-glow-strong:rgba(198,241,60,.42);
  --accent-tint:#ecffb0; --accent-hover:#d6ff5c;
}
/* Achromatic on purpose: nothing to clash with cover art, and it leaves the
   artwork as the only colour on the page. The glow stays weak or white hazes. */
[data-theme="graphite"]{
  --accent:#e6e9f0; --accent2:#b9c0cf; --accent-ink:#14161c;
  --accent-soft:rgba(230,233,240,.10); --accent-line:rgba(230,233,240,.28);
  --accent-glow:rgba(230,233,240,.20); --accent-glow-strong:rgba(230,233,240,.34);
  --accent-tint:#f4f6fa; --accent-hover:#ffffff;
}
