/* step-mode.css — the guided reference finder (js/step-mode.js).
   Everything here keys off the same theme tokens as style.css, so all ten themes,
   light/dark, and the corner/texture axes apply to Step Mode for free. */

/* ── Find-mode switch (Fast / Step), above the search form ───────────────── */
.find-mode-bar {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 4px 0 6px;
}
.find-mode-bar .fm-cap {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-mut); font-weight: 600;
}
.fm-seg {
  display: inline-flex; gap: 3px; padding: 4px;
  border: 1px solid var(--line); border-radius: 100px; background: var(--inset);
}
/* Padding was tuned for two buttons; a third (Song) pushed the segment wider than
   the plugin's narrowest window, so it wraps rather than overflowing. */
.fm-seg { flex-wrap: wrap; justify-content: center; }
.fm-seg button {
  border: 0; border-radius: 100px; cursor: pointer; padding: 9px 18px;
  font-size: 13px; font-weight: 600; background: transparent; color: var(--ink-dim);
  transition: background .18s ease, color .18s ease, box-shadow .18s ease;
}
.fm-seg button.active { background: var(--panel); color: var(--accent); box-shadow: var(--shadow-sm); }
.fm-tagline { text-align: center; font-size: 13px; color: var(--ink-mut); padding: 0 20px 10px; }

/* ── Motion ──────────────────────────────────────────────────────────────
   Records drift like objects in zero gravity: four elliptical orbits, each also
   rolling and breathing in scale so the group reads as depth rather than as a
   sheet of sliding tiles.

   TWO THINGS DECIDE WHETHER THIS READS AS MOVEMENT AT ALL, and both were got
   wrong before (the stage was twice reported as "static"):

   1. NEVER STOP. The earlier paths were four waypoints on `ease-in-out`, which
      applies per SEGMENT — the record decelerated to a standstill four times per
      lap. Motion that halts is read as "static, occasionally glitching". These
      are eight waypoints sampled off an ellipse and played `linear`, so speed is
      constant and the direction only ever curves. That alone does more for the
      illusion than any amount of extra amplitude.
   2. SPEED IS PATH LENGTH ÷ DURATION, not duration alone. A 30px arc over 26s is
      ~1px/second and invisible. These laps are 134-143px, so 8-14s puts every
      record at 10-18px/second — unhurried, but plainly moving. Below ~8px/s it
      starts reading as broken again; that is the floor, not a style choice.

   Each orbit travels in ONE vertical direction only (drift1/drift4 rise,
   drift2/drift3 fall) and every slot is assigned accordingly: top-row records
   fall, bottom-row records rise. The stage clips (overflow: hidden), and this
   makes overrunning its edge structurally impossible instead of a per-slot sum
   that has to be re-checked by hand. Horizontal travel is capped at 30px, which
   clears the narrowest stage the plugin can show. Every path ends where it
   began, so the loop never jumps. */
@keyframes sm-drift1 {   /* rises, clockwise — for records near the bottom edge */
  0%     { transform: translate(0, 0)         rotate(-2deg)   scale(1);    }
  12.5%  { transform: translate(21px, -4px)   rotate(1.5deg)  scale(1.01); }
  25%    { transform: translate(30px, -14px)  rotate(3deg)    scale(1.03); }
  37.5%  { transform: translate(21px, -24px)  rotate(1.5deg)  scale(1.04); }
  50%    { transform: translate(0, -28px)     rotate(-2deg)   scale(1.05); }
  62.5%  { transform: translate(-21px, -24px) rotate(-5.5deg) scale(1.04); }
  75%    { transform: translate(-30px, -14px) rotate(-7deg)   scale(1.03); }
  87.5%  { transform: translate(-21px, -4px)  rotate(-5.5deg) scale(1.01); }
  100%   { transform: translate(0, 0)         rotate(-2deg)   scale(1);    }
}
@keyframes sm-drift2 {   /* falls, counter-clockwise — for records near the top */
  0%     { transform: translate(0, 0)         rotate(2deg)    scale(1);    }
  12.5%  { transform: translate(-20px, 4px)   rotate(-1.5deg) scale(1.01); }
  25%    { transform: translate(-28px, 15px)  rotate(-3deg)   scale(1.03); }
  37.5%  { transform: translate(-20px, 26px)  rotate(-1.5deg) scale(1.04); }
  50%    { transform: translate(0, 30px)      rotate(2deg)    scale(1.05); }
  62.5%  { transform: translate(20px, 26px)   rotate(5.5deg)  scale(1.04); }
  75%    { transform: translate(28px, 15px)   rotate(7deg)    scale(1.03); }
  87.5%  { transform: translate(20px, 4px)    rotate(5.5deg)  scale(1.01); }
  100%   { transform: translate(0, 0)         rotate(2deg)    scale(1);    }
}
@keyframes sm-drift3 {   /* falls, clockwise */
  0%     { transform: translate(0, 0)         rotate(-1deg)   scale(1);    }
  12.5%  { transform: translate(18px, 5px)    rotate(2.5deg)  scale(1.01); }
  25%    { transform: translate(26px, 16px)   rotate(4deg)    scale(1.03); }
  37.5%  { transform: translate(18px, 27px)   rotate(2.5deg)  scale(1.04); }
  50%    { transform: translate(0, 32px)      rotate(-1deg)   scale(1.05); }
  62.5%  { transform: translate(-18px, 27px)  rotate(-4.5deg) scale(1.04); }
  75%    { transform: translate(-26px, 16px)  rotate(-6deg)   scale(1.03); }
  87.5%  { transform: translate(-18px, 5px)   rotate(-4.5deg) scale(1.01); }
  100%   { transform: translate(0, 0)         rotate(-1deg)   scale(1);    }
}
@keyframes sm-drift4 {   /* rises, counter-clockwise */
  0%     { transform: translate(0, 0)         rotate(3deg)    scale(1);    }
  12.5%  { transform: translate(-21px, -4px)  rotate(-0.5deg) scale(1.01); }
  25%    { transform: translate(-29px, -13px) rotate(-2deg)   scale(1.03); }
  37.5%  { transform: translate(-21px, -22px) rotate(-0.5deg) scale(1.04); }
  50%    { transform: translate(0, -26px)     rotate(3deg)    scale(1.05); }
  62.5%  { transform: translate(21px, -22px)  rotate(6.5deg)  scale(1.04); }
  75%    { transform: translate(29px, -13px)  rotate(8deg)    scale(1.03); }
  87.5%  { transform: translate(21px, -4px)   rotate(6.5deg)  scale(1.01); }
  100%   { transform: translate(0, 0)         rotate(3deg)    scale(1);    }
}
@keyframes sm-eq   { 0%,100% { height: 24%; } 50% { height: 100%; } }
@keyframes sm-fade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
/* The guidance pulse: whatever the user should press next wears this. */
@keyframes sm-glow {
  0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent),
                        0 10px 26px color-mix(in srgb, var(--accent) 24%, transparent); }
  50%     { box-shadow: 0 0 0 12px transparent,
                        0 12px 32px color-mix(in srgb, var(--accent) 42%, transparent); }
}
.sm-glow { animation: sm-glow 1.7s ease-in-out infinite; }
.sm-fade { animation: sm-fade .4s ease both; }

/* The drift is deliberately NOT listed here. It is the identity of this screen —
   the design has no reduced-motion rule at all, and suppressing it is what made a
   correctly-deployed stage look completely static (Windows ships with "Animation
   effects" off for plenty of people, and that is what this query reports). What
   stays suppressed is the attention-grabbing stuff: the pulsing guidance glow, the
   entrance slide and the equaliser bars. Those flash or repeat quickly, which is
   the class of motion the setting actually exists to stop; a 30px drift over 20
   seconds is not. */
@media (prefers-reduced-motion: reduce) {
  .sm-glow, .sm-fade, .sm-eq i, .sm-mini { animation: none !important; }
}

/* Positioning context for the mini player, which parks in the section's top-left. */
#step-section { padding-bottom: 40px; position: relative; }
/* The pill floats in the gutter beside the centred content. In a window too narrow for
   that gutter — a plugin-sized one — it would land on the step heading instead, so
   reserve a band above the content for it. The widest column is .sm-narrow (840px);
   below ~980px there is no longer room for the pill either side of it. */
#step-section.has-mini { padding-top: 58px; }
@media (min-width: 980px) { #step-section.has-mini { padding-top: 0; } }

/* ── Mini player ──────────────────────────────────────────────────────────
   The record tapped on the welcome stage keeps playing while the producer answers
   the questions, so its control has to outlive that stage: cover art + a play/stop
   toggle, top left. Fades out on "Find my references", when the results take over. */
.sm-mini {
  position: absolute; top: 0; left: 0; z-index: 5;
  padding: 5px; border-radius: 13px;
  border: 1px solid var(--line); background: var(--panel);
  box-shadow: var(--shadow-sm);
  animation: sm-mini-in .28s ease both;
  transition: opacity .26s ease, transform .26s ease;   /* MINI_FADE_MS in step-mode.js */
}
.sm-mini.is-leaving { opacity: 0; transform: translateY(-8px); pointer-events: none; }
.sm-mini-btn {
  display: block; position: relative; width: 42px; height: 42px; padding: 0;
  border: 0; border-radius: 9px; overflow: hidden; cursor: pointer;
  background: var(--bg-2) center / cover no-repeat;   /* cover set via data-cover (CSP) */
}
/* Scrim so the ▶ / equaliser stays legible on a bright cover. */
.sm-mini-btn::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(0, 0, 0, .42); transition: background .15s ease;
}
.sm-mini-btn:hover::after { background: rgba(0, 0, 0, .58); }
.sm-mini-ico {
  position: absolute; inset: 0; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 12px; line-height: 1;
}
.sm-mini-ico .sm-eq   { height: 15px; gap: 2px; }
.sm-mini-ico .sm-eq i { width: 3px; }
@keyframes sm-mini-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.sm-narrow    { max-width: 840px; margin: 0 auto; }
.sm-narrower  { max-width: 720px; margin: 0 auto; }
.sm-narrowest { max-width: 680px; margin: 0 auto; }

.sm-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 12px;
}
.sm-h1 { font-size: 40px; line-height: 1.1; letter-spacing: -.02em; margin: 0 0 14px; }
.sm-h2 { font-size: 28px; line-height: 1.15; letter-spacing: -.01em; margin: 0; }
.sm-sub { font-size: 15px; line-height: 1.5; color: var(--ink-dim); margin: 8px 0 0; }
.sm-lede { font-size: 16px; line-height: 1.55; color: var(--ink-dim); margin: 0 0 8px; }
.sm-tip { font-size: 12px; color: var(--ink-mut); }
.sm-count { color: var(--accent); font-weight: 600; }
.sm-head { text-align: center; margin: 8px 0 26px; }
.sm-head .sm-sub { margin-top: 10px; }

/* ── Welcome stage: floating records around the invitation ───────────────── */
.sm-stage {
  position: relative; height: 540px; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow);
  background: radial-gradient(120% 120% at 50% 0%, var(--panel), var(--bg-2));
}
/* Record placement lives HERE, not in a style="" attribute, because the app's CSP
   sets style-src without 'unsafe-inline' — inline style attributes are silently
   dropped in production, which collapsed every record to a 0x0 invisible box while
   the rest of the (class-driven) page looked perfectly fine. The only value JS
   still sets is the cover image URL, applied via CSSOM, which CSP does allow.
   The middle band (~24-76% across, ~28-72% down) belongs to the copy: nothing may
   be placed there. Slots 8-15 are the denser second ring, dropped on narrow stages
   where the fixed-width copy spans most of the width.

   ORBIT CHOICE IS NOT DECORATIVE. drift1/drift4 only ever rise, drift2/drift3 only
   ever fall, so a record near the top of the stage MUST take a falling orbit and
   one near the bottom a rising one. Everything is `linear`: a drift that eases is
   a drift that stops, and a stopped record reads as a static one. */
.sm-art-slot { position: absolute; will-change: transform; }
.sm-slot-0  { top: 9%;  left: 5%;  width: 122px; height: 122px; animation: sm-drift3 11.2s linear 0s     infinite; }
.sm-slot-1  { top: 11%; left: 79%; width: 94px;  height: 94px;  animation: sm-drift2 9.6s  linear -3.1s  infinite; }
.sm-slot-2  { top: 58%; left: 5%;  width: 106px; height: 106px; animation: sm-drift1 13.2s linear -6.4s  infinite; }
.sm-slot-3  { top: 60%; left: 80%; width: 114px; height: 114px; animation: sm-drift4 8.4s  linear -1.7s  infinite; }
.sm-slot-4  { top: 3%;  left: 41%; width: 78px;  height: 78px;  animation: sm-drift2 12s   linear -8.2s  infinite; }
.sm-slot-5  { top: 73%; left: 35%; width: 86px;  height: 86px;  animation: sm-drift4 10.4s linear -4.5s  infinite; }
.sm-slot-6  { top: 40%; left: 85%; width: 72px;  height: 72px;  animation: sm-drift1 14s   linear -10.3s infinite; }
.sm-slot-7  { top: 36%; left: 13%; width: 66px;  height: 66px;  animation: sm-drift3 8.8s  linear -2.6s  infinite; }
.sm-slot-8  { top: 20%; left: 21%; width: 58px;  height: 58px;  animation: sm-drift2 12.8s linear -7.1s  infinite; }
.sm-slot-9  { top: 78%; left: 63%; width: 74px;  height: 74px;  animation: sm-drift1 9.2s  linear -5.3s  infinite; }
.sm-slot-10 { top: 4%;  left: 64%; width: 62px;  height: 62px;  animation: sm-drift3 11.6s linear -9.4s  infinite; }
/* left 5%, not 1-3%: the orbits reach 30px sideways and the stage clips at its edge. */
.sm-slot-11 { top: 46%; left: 5%;  width: 58px;  height: 58px;  animation: sm-drift2 8s    linear -1.2s  infinite; }
.sm-slot-12 { top: 82%; left: 11%; width: 68px;  height: 68px;  animation: sm-drift4 13.6s linear -11.5s infinite; }
.sm-slot-13 { top: 16%; left: 89%; width: 52px;  height: 52px;  animation: sm-drift1 10s   linear -3.8s  infinite; }
.sm-slot-14 { top: 67%; left: 20%; width: 60px;  height: 60px;  animation: sm-drift3 12.4s linear -6.9s  infinite; }
.sm-slot-15 { top: 82%; left: 46%; width: 56px;  height: 56px;  animation: sm-drift4 10.8s linear -2.2s  infinite; }

/* Fallback covers: shown until (or instead of) real artwork, so an empty catalog
   or a failed /api/discover still reads as a wall of records. */
.sm-slot-0  .sm-art { background-image: linear-gradient(145deg, #e8a04b, #c2492f); }
.sm-slot-1  .sm-art { background-image: linear-gradient(145deg, #4b8ec2, #1d2b4a); }
.sm-slot-2  .sm-art { background-image: linear-gradient(145deg, #d8865f, #7a3b2e); }
.sm-slot-3  .sm-art { background-image: linear-gradient(145deg, #5aa469, #234b34); }
.sm-slot-4  .sm-art { background-image: linear-gradient(145deg, #b06fb0, #3a1d4a); }
.sm-slot-5  .sm-art { background-image: linear-gradient(145deg, #e0b64b, #8a5a1f); }
.sm-slot-6  .sm-art { background-image: linear-gradient(145deg, #5aa0c8, #22415e); }
.sm-slot-7  .sm-art { background-image: linear-gradient(145deg, #d86b49, #a12f2f); }
.sm-slot-8  .sm-art { background-image: linear-gradient(145deg, #c98a3a, #6b4416); }
.sm-slot-9  .sm-art { background-image: linear-gradient(145deg, #4fae86, #1e4d3b); }
.sm-slot-10 .sm-art { background-image: linear-gradient(145deg, #8a5aa6, #3d2450); }
.sm-slot-11 .sm-art { background-image: linear-gradient(145deg, #3f7fb3, #1b3a55); }
.sm-slot-12 .sm-art { background-image: linear-gradient(145deg, #d86b49, #7d2f22); }
.sm-slot-13 .sm-art { background-image: linear-gradient(145deg, #e0b64b, #7a5a12); }
.sm-slot-14 .sm-art { background-image: linear-gradient(145deg, #5aa0c8, #1f3f57); }
.sm-slot-15 .sm-art { background-image: linear-gradient(145deg, #b06fb0, #4a2456); }
.sm-art {
  position: relative; width: 100%; height: 100%; border-radius: 14px; overflow: hidden;
  cursor: pointer; background-color: var(--panel-2); box-shadow: 0 10px 26px rgba(0,0,0,.22);
  transition: box-shadow .3s ease, transform .3s ease;
}
.sm-art:hover { transform: scale(1.04); }
.sm-art.is-playing {
  transform: scale(1.06);
  box-shadow: 0 0 0 3px var(--accent), 0 14px 32px color-mix(in srgb, var(--accent) 36%, transparent);
}
/* Vinyl grooves over the cover art. */
.sm-art-grooves {
  position: absolute; inset: 0; opacity: .55;
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.12) 0 1px, transparent 1px 5px);
}
.sm-art-center { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.sm-play {
  width: 40px; height: 40px; border-radius: 50%; background: rgba(24,20,17,.5);
  backdrop-filter: blur(4px); color: #fff; display: flex; align-items: center;
  justify-content: center; font-size: 14px; padding-left: 3px;
}
.sm-eq { display: flex; align-items: flex-end; gap: 3px; height: 26px; }
.sm-eq i { width: 4px; background: #fff; border-radius: 2px; animation: sm-eq .7s ease-in-out infinite; }
.sm-eq i:nth-child(1) { height: 60%;  animation-delay: 0s; }
.sm-eq i:nth-child(2) { height: 100%; animation-delay: .18s; }
.sm-eq i:nth-child(3) { height: 45%;  animation-delay: .32s; }
.sm-eq i:nth-child(4) { height: 80%;  animation-delay: .1s; }
/* No title/artist caption on the records: they are wallpaper, not a listing — the
   name would compete with the headline and clutter a screen whose whole job is to
   say "press this". The track is still announced to screen readers through the
   button's aria-label. */

.sm-welcome-copy {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  pointer-events: none; padding: 0 24px;
}
/* isolate: gives the scrim below a stacking context to sit in, so it lands above
   the drifting records but underneath the copy. */
.sm-welcome-copy { isolation: isolate; }
.sm-welcome-inner { pointer-events: auto; max-width: 520px; position: relative; }
/* The records move, so no fixed layout can promise they'll never pass behind the
   text. This soft halo of the stage's own colour keeps the copy readable when one
   drifts close, without reading as a panel. */
.sm-welcome-inner::before {
  content: ""; position: absolute; inset: -30px -52px; z-index: -1; pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    var(--panel) 45%,
    color-mix(in srgb, var(--panel) 72%, transparent) 70%,
    transparent 100%);
}

/* The second, denser ring of records only fits once the stage is wide enough that
   the fixed-width copy no longer spans most of it. */
@media (max-width: 1100px) {
  .sm-slot-8, .sm-slot-9, .sm-slot-10, .sm-slot-11,
  .sm-slot-12, .sm-slot-13, .sm-slot-14, .sm-slot-15 { display: none; }
}
/* Handwritten aside — the one informal voice in the UI. */
.sm-hand {
  font-family: 'Caveat', 'Segoe Script', cursive; font-size: 20px; font-weight: 600;
  color: var(--accent); margin-bottom: 24px; transform: rotate(-1.5deg);
}
.sm-cta {
  border: 0; border-radius: 14px; background: var(--accent); color: var(--on-accent);
  font-size: 16px; font-weight: 600; padding: 15px 34px; cursor: pointer;
  box-shadow: 0 8px 24px color-mix(in srgb, var(--accent) 28%, transparent);
}

/* ── Category picker ─────────────────────────────────────────────────────── */
.sm-cat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.sm-cat {
  position: relative; text-align: left; cursor: pointer; border: 1px solid var(--line);
  border-radius: 16px; background: var(--panel); padding: 18px;
  display: flex; flex-direction: column; gap: 6px;
  box-shadow: var(--shadow-sm); transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}
.sm-cat:hover { border-color: var(--line-2); }
.sm-cat.is-on {
  border: 2px solid var(--accent); background: var(--panel-2); padding: 17px;
  box-shadow: 0 8px 22px color-mix(in srgb, var(--accent) 16%, transparent);
}
.sm-cat-ico   { font-size: 24px; color: var(--accent); line-height: 1; }
.sm-cat-label { font-size: 16px; font-weight: 600; color: var(--ink); }
.sm-cat-desc  { font-size: 13px; color: var(--ink-mut); }
.sm-check {
  position: absolute; top: 14px; right: 14px; width: 22px; height: 22px; border-radius: 6px;
  border: 1px solid var(--line-2); color: #fff; display: flex; align-items: center;
  justify-content: center; font-size: 13px;
}
.sm-cat.is-on .sm-check, .sm-refcard.is-on .sm-check { background: var(--accent); border-color: var(--accent); }
.sm-check-round { position: static; border-radius: 50%; flex: 0 0 auto; }

.sm-or { display: flex; align-items: center; gap: 14px; margin: 22px 0; }
.sm-or::before, .sm-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.sm-or span {
  font-size: 11px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-mut);
}
.sm-refcard {
  width: 100%; text-align: left; cursor: pointer; border: 1px solid var(--line);
  border-radius: 16px; background: var(--panel); padding: 18px 20px;
  display: flex; align-items: center; gap: 16px; transition: border-color .16s ease, background .16s ease;
}
.sm-refcard.is-on { border: 2px solid var(--accent); background: var(--panel-2); padding: 17px 19px; }
.sm-refcard-ico   { font-size: 26px; color: var(--accent); }
.sm-refcard-body  { flex: 1; }
.sm-refcard-title { display: block; font-size: 16px; font-weight: 600; color: var(--ink); }
.sm-refcard-desc  { display: block; font-size: 13px; color: var(--ink-mut); margin-top: 2px; }

/* ── Question card + progress ────────────────────────────────────────────── */
.sm-progress-head { display: flex; justify-content: space-between; align-items: center; margin: 8px 0 10px; }
.sm-progress-head .sm-eyebrow { margin: 0; }
.sm-progress-count { font-size: 12px; color: var(--ink-mut); font-variant-numeric: tabular-nums; }
.sm-progress { height: 6px; border-radius: 100px; background: var(--inset); overflow: hidden; margin-bottom: 26px; }
.sm-progress-fill { height: 100%; border-radius: 100px; background: var(--accent); transition: width .3s ease; }
.sm-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 34px;
}
.sm-card-head { display: flex; align-items: center; gap: 12px; }
.sm-card-ico  { font-size: 26px; color: var(--accent); line-height: 1; }
.sm-card .sm-sub { margin-bottom: 26px; }

/* ── BPM step ────────────────────────────────────────────────────────────── */
.sm-bpm { display: flex; flex-direction: column; align-items: center; gap: 24px; }
.sm-bpm-readout { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.sm-bpm-big { display: flex; align-items: baseline; gap: 10px; }
.sm-bpm-big .num { font-size: 64px; font-weight: 700; line-height: 1; color: var(--accent); letter-spacing: .02em; }
.sm-bpm-unit { font-size: 16px; font-weight: 600; color: var(--ink-mut); }
.sm-pill {
  font-size: 14px; font-weight: 600; color: var(--ink-dim);
  background: var(--inset); border-radius: 100px; padding: 8px 18px; display: inline-block;
}
.sm-knobs { display: flex; gap: 44px; align-items: flex-start; }
.sm-knob { display: flex; flex-direction: column; align-items: center; gap: 9px; user-select: none; }
.sm-knob-label { font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-dim); }
.sm-knob-val   { font-size: 14px; font-weight: 700; color: var(--accent); margin-top: -3px; }
.sm-checkline { display: inline-flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 500; color: var(--ink-dim); cursor: pointer; }
.sm-checkline input { accent-color: var(--accent); width: 17px; height: 17px; }

/* ── Key step ────────────────────────────────────────────────────────────── */
.sm-key-step { display: flex; flex-direction: column; gap: 24px; }
.sm-field-label { font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-dim); margin-bottom: 10px; }
.sm-key-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.sm-key {
  border: 1px solid var(--line-2); border-radius: 10px; cursor: pointer; padding: 12px 0;
  font-size: 15px; font-weight: 600; background: var(--panel); color: var(--ink);
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.sm-key:hover { border-color: var(--accent); }
.sm-key.is-on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.sm-key-row { display: flex; align-items: flex-end; gap: 28px; flex-wrap: wrap; }
.sm-seg { display: inline-flex; gap: 3px; border-radius: 100px; background: var(--inset); padding: 3px; }
.sm-seg button {
  border: 0; border-radius: 100px; cursor: pointer; padding: 9px 20px;
  font-size: 13px; font-weight: 600; background: transparent; color: var(--ink-dim);
}
.sm-seg button.is-on { background: var(--accent); color: var(--on-accent); }
.sm-camelot { margin-left: auto; text-align: right; }
.sm-camelot-cap { font-size: 11px; color: var(--ink-mut); }
.sm-camelot-big { font-size: 26px; font-weight: 700; color: var(--accent-2); line-height: 1.1; }
.sm-camelot .sm-pill { font-size: 13px; padding: 5px 12px; margin-top: 5px; }

/* ── Chip + free-text steps ──────────────────────────────────────────────── */
.sm-chipbar {
  display: flex; min-height: 52px; flex-wrap: wrap; align-items: center; gap: 6px;
  border: 2px solid var(--line-2); border-radius: var(--radius-sm); background: var(--inset);
  padding: 8px 10px; transition: border-color .16s ease;
}
.sm-chipbar.is-filled, .sm-textarea.is-filled, .sm-drop.is-filled { border-color: var(--accent); }
.sm-chip {
  display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line-2);
  border-radius: 100px; background: var(--panel); padding: 6px 6px 6px 12px;
  font-size: 13px; font-weight: 500; color: var(--ink);
}
.sm-chip button {
  border: 0; background: var(--inset); border-radius: 50%; width: 18px; height: 18px;
  cursor: pointer; color: var(--ink-dim); font-size: 12px; line-height: 1;
}
.sm-chip-input {
  flex: 1; min-width: 140px; height: 32px; border: 0; background: transparent;
  padding: 4px; font-size: 14px; color: var(--ink); outline: none;
}
.sm-sug-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.sm-sug {
  border: 1px dashed var(--line-2); border-radius: 100px; background: var(--panel);
  color: var(--ink-dim); font-size: 12px; font-weight: 500; padding: 7px 13px; cursor: pointer;
}
.sm-sug:hover { border-color: var(--accent); color: var(--accent); }

/* Artist photos (Spotify / Apple / Deezer) on the artist step's chips and
   suggestions, so two acts with similar names are told apart at a glance. */
.sm-chip.has-av { padding-left: 5px; }
.sm-sug.has-av  { padding-left: 5px; gap: 7px; display: inline-flex; align-items: center; }
.sm-av {
  width: 22px; height: 22px; flex: 0 0 auto; border-radius: 50%;
  object-fit: cover; background: var(--inset); display: inline-block; vertical-align: middle;
}
.sm-chip.has-av .sm-av { margin-right: 2px; }
.sm-card .sm-tip { margin-top: 8px; }
.sm-textarea {
  width: 100%; border: 2px solid var(--line-2); border-radius: 14px; background: var(--inset);
  padding: 14px 16px; font-size: 15px; line-height: 1.5; color: var(--ink);
  resize: vertical; outline: none; font-family: inherit; transition: border-color .16s ease;
}
.sm-drop {
  display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center;
  border: 2px dashed var(--line-2); border-radius: 16px; padding: 40px 24px; background: var(--inset);
}
.sm-drop-ico  { font-size: 40px; color: var(--accent); }
.sm-drop-name { font-size: 17px; font-weight: 600; color: var(--ink); }

/* ── Step navigation ─────────────────────────────────────────────────────── */
.sm-nav { display: flex; justify-content: space-between; align-items: center; margin-top: 24px; }
.sm-nav-right { display: flex; align-items: center; gap: 12px; }
.sm-btn-ghost {
  border: 1px solid var(--line-2); background: var(--panel); color: var(--ink-dim);
  border-radius: var(--radius-sm); padding: 13px 24px; font-size: 14px; font-weight: 600; cursor: pointer;
}
.sm-btn-primary {
  border: 0; border-radius: var(--radius-sm); background: var(--accent); color: var(--on-accent);
  font-size: 15px; font-weight: 600; padding: 14px 32px; cursor: pointer;
}
.sm-btn-primary.is-disabled { background: var(--ink-mut); opacity: .55; cursor: not-allowed; }
.sm-skip { border: 0; background: transparent; color: var(--ink-mut); font-size: 13px; font-weight: 500; cursor: pointer; text-decoration: underline; }
.sm-btn-link { border: 0; background: transparent; color: var(--ink-mut); font-size: 13px; font-weight: 500; cursor: pointer; }

/* ── Review ──────────────────────────────────────────────────────────────── */
.sm-review {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
}
.sm-review-row { display: flex; align-items: center; gap: 16px; padding: 18px 22px; border-bottom: 1px solid var(--line); }
.sm-review-row:last-child { border-bottom: 0; }
.sm-review-ico   { font-size: 20px; color: var(--accent); width: 24px; text-align: center; }
.sm-review-label { width: 150px; flex: 0 0 auto; font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-mut); }
.sm-review-value { flex: 1; font-size: 15px; font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.sm-edit { border: 1px solid var(--line-2); background: var(--panel); color: var(--ink-dim); border-radius: 100px; padding: 6px 14px; font-size: 12px; font-weight: 600; cursor: pointer; }
.sm-depth { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px; margin-top: 22px; }
.sm-depth .sm-field-label { margin-bottom: 0; }
.sm-depth-hint { font-size: 12px; color: var(--ink-mut); flex: 1 1 100%; }
.sm-finish { display: flex; flex-direction: column; align-items: center; gap: 14px; margin-top: 28px; }
.sm-btn-find {
  border: 0; border-radius: 16px; background: var(--accent); color: var(--on-accent);
  font-size: 18px; font-weight: 600; padding: 18px 48px; cursor: pointer;
  box-shadow: 0 10px 28px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Fast Mode's artist chips carry the same photo (style.css owns .chip itself;
   this only adds the avatar, so the two modes look like one product). */
.chip.chip-av { padding-left: 5px; }
.chip .chip-img {
  width: 20px; height: 20px; flex: 0 0 auto; border-radius: 50%;
  object-fit: cover; background: var(--inset);
}

/* ── "Your search": the folded Fast Mode form above the results ──────────── */
.search-summary {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  width: 100%; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 16px; background: var(--panel);
  box-shadow: var(--shadow-sm); padding: 14px 18px; margin-bottom: 18px;
}
.search-summary .ss-cap { font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim); }
.search-summary .ss-chip {
  display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line-2);
  border-radius: 100px; background: var(--bg-2); padding: 5px 12px; font-size: 13px; font-weight: 500; color: var(--ink);
}
.search-summary .ss-chip i { color: var(--accent); font-style: normal; }
.search-summary .ss-toggle { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--accent); }
.search-summary .ss-chev { display: inline-block; transition: transform .2s ease; }
.search-summary[aria-expanded="true"] .ss-chev { transform: rotate(180deg); }

/* ── Fit to the window ────────────────────────────────────────────────────
   Step Mode's promise is that you always know what to press next, and the way that
   broke was vertical. The plugin's editor opens at 1180x760 and can be dragged down
   to 720x480; the category grid and the taller question cards ran past the bottom of
   that, so Next was below the fold with nothing on screen to say it existed. Producers
   reported not knowing what to do — on the screen built to answer exactly that.

   So a Step Mode screen never grows the page. It fills the window and splits in three
   (js/step-mode.js `screen()`): the question stays overhead, the Back/Next row stays
   underfoot, and only the middle scrolls — and only when it genuinely cannot fit,
   after the height tiers below have had their say.

   `main` is the app's scroll surface, so it has to stop scrolling for any of this to
   mean anything: app.js puts .step-fit on <body> for exactly as long as #step-section
   is the visible section. Everything here is scoped to that class, so if the two ever
   disagree the fallback is the OLD behaviour — a tall page inside a scrolling main —
   rather than a collapsed layout. That is also why .sm-stage keeps its fixed height
   below and only gets a flexible one here: the records inside it are absolutely
   positioned, so a stage that fell back to auto height would collapse to nothing. */
body.mixer.step-fit main {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* main reserves a band at the bottom for the fixed #player-bar. Step Mode never
     shows it — its records play through a bare <audio> and its own mini pill — so in
     here that band is 118px of dead space (142px in the plugin). */
  padding-bottom: var(--pad);
}
body.mixer.step-fit #step-section {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;          /* without this the section refuses to shrink below its content */
  padding-bottom: 0;
}
/* Shrink-to-fit, never grow: on a roomy window the screen is its natural height, so
   the card and its nav still sit together in the middle rather than being flung to
   opposite edges. Only when the window is too short does the body start scrolling.

   `width: 100%` is load-bearing. The width wrappers centre with `margin: 0 auto`, and an
   auto cross-axis margin on a flex item switches off `align-items: stretch` — without it
   the screen sizes to its own content instead of to .sm-narrow's 840px, quietly making
   every column narrower, and therefore taller, than it was designed to be. */
.sm-screen { display: flex; flex-direction: column; min-height: 0; width: 100%; }
.sm-screen-head, .sm-screen-foot { flex: 0 0 auto; }
.sm-screen-body {
  flex: 0 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  /* Sideways room for the cards' own drop shadow, which an overflow container would
     otherwise clip flat; the negative margin keeps the column exactly as wide as it
     was. Deliberately no vertical padding — a scroll container counts that in its
     scrollHeight, which made syncFit() see a few px of phantom overflow and draw the
     foot's divider on screens that fit perfectly well. */
  padding: 0 5px; margin: 0 -5px;
}
/* The foot only becomes a bar once there is something scrolling underneath it. */
.sm-screen.is-scrolling .sm-screen-foot {
  border-top: 1px solid var(--line);
  box-shadow: 0 -10px 20px -16px rgba(0, 0, 0, .6);
}
.sm-screen.is-scrolling .sm-nav,
.sm-screen.is-scrolling .sm-finish { margin-top: 14px; }

/* The welcome stage is the one screen that grows: it has no foot (its CTA sits in the
   middle of the stage) and the drifting records read better filling the window than
   boxed at a fixed height. Centred, so a tall screen doesn't leave it hanging at top.
   min-height 340px is not cosmetic — every orbit above is cleared against it (see the
   .sm-slot-N table), and a shorter stage would let records clip through its edge. */
body.mixer.step-fit .sm-screen--stage { flex: 1 1 auto; }
body.mixer.step-fit .sm-screen--stage .sm-screen-body {
  flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center;
}
body.mixer.step-fit .sm-stage {
  flex: 1 1 auto; height: auto; min-height: 340px; max-height: 560px;
}

/* Seven categories in threes is three rows; in fours it is two, and that row is worth
   ~100px — the difference between the picker fitting outright and not, at every window
   size from the plugin's 480px minimum to a desktop browser. Measured at the 840px
   column: four cards are 200px wide and every label still sits on one line. Below 860px
   the column is too narrow to take it and the rules further down step in. */
@media (min-width: 860px) {
  .sm-cat-grid { grid-template-columns: repeat(4, 1fr); }
}

/* ── Short windows ────────────────────────────────────────────────────────
   The pinned foot guarantees Next is REACHABLE; these tiers are what keep it from
   being reachable only by scrolling. Type, padding and the big readouts all come down
   so a whole question still fits the plugin's default 760px-tall window, and nearly
   all of one fits its 480px minimum. They key off viewport HEIGHT, not width, so a
   laptop browser gets the same treatment as a short plugin window — which is the point:
   this was reported on the web as well. js/step-mode.js shrinks the knobs on the same
   two thresholds. */
@media (max-height: 820px) {
  .find-mode-bar { padding: 2px 0 4px; }
  .fm-tagline { font-size: 12px; padding-bottom: 6px; }
  .sm-head { margin: 2px 0 16px; }
  .sm-h1 { font-size: 32px; }
  .sm-h2 { font-size: 23px; }
  .sm-lede { font-size: 15px; }
  .sm-hand { font-size: 18px; margin-bottom: 16px; }
  .sm-cta { padding: 13px 28px; }
  .sm-cat { padding: 14px; gap: 4px; }
  .sm-cat.is-on { padding: 13px; }
  .sm-cat-ico { font-size: 20px; }
  .sm-or { margin: 14px 0; }
  .sm-refcard { padding: 14px 16px; }
  .sm-refcard.is-on { padding: 13px 15px; }
  .sm-card { padding: 20px 22px; }
  .sm-card .sm-sub { margin-bottom: 16px; }
  .sm-progress { margin-bottom: 18px; }
  .sm-nav { margin-top: 16px; }
  /* The tempo question is the tallest of the seven — two knobs under a 64px readout —
     and these few px are the difference between it fitting the plugin's default 760px
     window outright and being 24px short of it. */
  .sm-bpm { gap: 13px; }
  .sm-bpm-readout { gap: 6px; }
  .sm-knob { gap: 6px; }
  .sm-bpm-big .num { font-size: 44px; }
  .sm-key-step { gap: 18px; }
  .sm-key { padding: 9px 0; }
  .sm-review-row { padding: 12px 18px; }
  .sm-depth { margin-top: 16px; }
  .sm-finish { margin-top: 18px; gap: 10px; }
  .sm-btn-find { font-size: 17px; padding: 15px 38px; }
}
@media (max-height: 640px) {
  /* Both of these say what the mode/card already shows, and dropping them turns three
     rows of category cards into two — the difference between fitting and not. */
  .fm-tagline { display: none; }
  .sm-cat-desc, .sm-refcard-desc { display: none; }
  .sm-h1 { font-size: 26px; }
  .sm-lede { font-size: 14px; }
  .sm-hand { font-size: 16px; margin-bottom: 12px; }
  .sm-cat { padding: 12px; }
  .sm-cat.is-on { padding: 11px; }
  .sm-card { padding: 16px; }
  .sm-card .sm-sub { margin-bottom: 14px; }
  .sm-bpm { gap: 12px; }
  .sm-bpm-big .num { font-size: 38px; }
  .sm-knobs { gap: 32px; }
  .sm-review-row { padding: 9px 14px; }
  .sm-nav { margin-top: 12px; }
  .sm-btn-find { font-size: 16px; padding: 13px 30px; }
}
/* Squeezed right down (the plugin can be dragged to 480px tall). The head and foot
   never scroll, so past a point they have to give ground or they leave the middle
   nothing at all — which is worse than a terse heading: you'd be pressing Next on a
   question you can't see. The h2 still says what the screen is for. */
@media (max-height: 540px) {
  .sm-head { margin: 0 0 10px; }
  .sm-head .sm-sub, .sm-tip { display: none; }
  .sm-eyebrow { margin-bottom: 6px; }
  .sm-h2 { font-size: 19px; }
  .sm-card { padding: 13px; }
  .sm-card .sm-sub { margin-bottom: 10px; font-size: 13px; }
  .sm-progress { margin-bottom: 12px; }
  .sm-nav { margin-top: 10px; }
  .sm-btn-ghost, .sm-btn-primary { padding: 10px 18px; }
  .sm-review-row { padding: 7px 12px; }
  .sm-depth { margin-top: 12px; }
  .sm-finish { margin-top: 10px; gap: 6px; }
  .sm-btn-find { font-size: 15px; padding: 11px 26px; }
}

/* ── Narrow / plugin widths ──────────────────────────────────────────────── */
@media (max-width: 900px) {
  .sm-cat-grid { grid-template-columns: repeat(2, 1fr); }
  .sm-stage { height: 460px; }
  .sm-h1 { font-size: 32px; }
  .sm-card { padding: 24px; }
  .sm-knobs { gap: 28px; }
  .sm-review-label { width: 110px; }
}
@media (max-width: 640px) {
  .sm-cat-grid { grid-template-columns: 1fr; }
  .sm-key-grid { grid-template-columns: repeat(4, 1fr); }
  .sm-camelot { margin-left: 0; text-align: left; }
  .sm-review-row { flex-wrap: wrap; }
}
