/* ============================================================================
 * Theme palettes — colour-only tokens. Surfaces, ink levels, four semantic
 * accents (signal / transient / partial / decay), warn, and an --on-accent
 * contrast token. Selected per-document via the data-theme attribute on
 * <html>. The bare :root keeps Tungsten Lab as the default so any page rendered
 * without a resolved theme still gets the production colours.
 *
 * Non-colour tokens (--radius, --border alias, etc.) live in main.css :root.
 * ============================================================================ */

[data-theme="acid-lab"] {
  --bg:        #0a0b0d;
  --bg-2:      #111316;
  --panel:     #15181c;
  --panel-2:   #1b1f24;
  --line:      #242930;
  --ink:       #f0eee8;
  --ink-2:     #d8d6cd;
  --ink-3:     #b9b6a9;
  --accent:    #d4ff3a;
  --accent-2:  #ff4d2e;
  --accent-3:  #5eb8ff;
  --accent-4:  #c38fff;
  --warn:      #ffb84d;
  --on-accent: #0a0b0d;
}

[data-theme="surgical-cyan"] {
  --bg:        #0a0d10;
  --bg-2:      #10141a;
  --panel:     #151a21;
  --panel-2:   #1b2129;
  --line:      #242b34;
  --ink:       #ecf1f5;
  --ink-2:     #d2d9e0;
  --ink-3:     #aab2bd;
  --accent:    #4ee2c5;
  --accent-2:  #ff5c8a;
  --accent-3:  #ffcf6a;
  --accent-4:  #b69bff;
  --warn:      #ffb84d;
  --on-accent: #0a0d10;
}

[data-theme="nordic-frost"] {
  --bg:        #1b212c;
  --bg-2:      #222a36;
  --panel:     #2a3340;
  --panel-2:   #313c4b;
  --line:      #3b4757;
  --ink:       #eceff4;
  --ink-2:     #e2e7ef;
  --ink-3:     #bcc5d2;
  --accent:    #88c0d0;
  --accent-2:  #bf616a;
  --accent-3:  #81a1c1;
  --accent-4:  #b48ead;
  --warn:      #ebcb8b;
  --on-accent: #1b212c;
}

:root,
[data-theme="tungsten-lab"] {
  --bg:        #0d0a08;
  --bg-2:      #14110d;
  --panel:     #1a1612;
  --panel-2:   #221c16;
  --line:      #2e271f;
  --ink:       #f4ece0;
  --ink-2:     #e0d6c4;
  --ink-3:     #b8ad9a;
  --accent:    #f4b860;
  --accent-2:  #e8503f;
  --accent-3:  #6fb7b2;
  --accent-4:  #cda2d1;
  --warn:      #f4b860;
  --on-accent: #0d0a08;
}

[data-theme="phosphor-scope"] {
  --bg:        #06090a;
  --bg-2:      #0b1012;
  --panel:     #10171a;
  --panel-2:   #161f23;
  --line:      #1e2a2f;
  --ink:       #d8f0e2;
  --ink-2:     #bcd6c8;
  --ink-3:     #93ac9e;
  --accent:    #6cffb0;
  --accent-2:  #ff7a59;
  --accent-3:  #6dd0ff;
  --accent-4:  #c7a4ff;
  --warn:      #ffd470;
  --on-accent: #06090a;
}

[data-theme="studio-calibration"] {
  --bg:        #0c0c0e;
  --bg-2:      #131316;
  --panel:     #18181c;
  --panel-2:   #1e1e23;
  --line:      #2a2a30;
  --ink:       #efeff2;
  --ink-2:     #d6d6db;
  --ink-3:     #abacb4;
  --accent:    #ffd24c;
  --accent-2:  #ff4f6a;
  --accent-3:  #4cc3ff;
  --accent-4:  #b389ff;
  --warn:      #ffb84d;
  --on-accent: #0c0c0e;
}

[data-theme="tokyo-twilight"] {
  --bg:        #0d101a;
  --bg-2:      #141826;
  --panel:     #1a2034;
  --panel-2:   #222842;
  --line:      #2c3550;
  --ink:       #e6eaff;
  --ink-2:     #ccd2ec;
  --ink-3:     #9aa1c4;
  --accent:    #7eecc1;
  --accent-2:  #ff6e8a;
  --accent-3:  #7aa2ff;
  --accent-4:  #c4a8ff;
  --warn:      #f0c66b;
  --on-accent: #0d101a;
}

[data-theme="carbon-mercury"] {
  --bg:        #0a0a0c;
  --bg-2:      #101013;
  --panel:     #15151a;
  --panel-2:   #1c1c22;
  --line:      #26262e;
  --ink:       #f0f2f5;
  --ink-2:     #d4d6dc;
  --ink-3:     #a7aab1;
  --accent:    #9ad8ff;
  --accent-2:  #d7b890;
  --accent-3:  #a8b3c0;
  --accent-4:  #b9a8c4;
  --warn:      #e8c674;
  --on-accent: #0a0a0c;
}

[data-theme="solarized-forge"] {
  --bg:        #001f27;
  --bg-2:      #002b36;
  --panel:     #073642;
  --panel-2:   #0d4856;
  --line:      #16606b;
  --ink:       #fdf6e3;
  --ink-2:     #b6c0c0;
  --ink-3:     #8b9da3;
  --accent:    #b58900;
  --accent-2:  #dc322f;
  --accent-3:  #268bd2;
  --accent-4:  #6c71c4;
  --warn:      #cb4b16;
  --on-accent: #fdf6e3;
}

[data-theme="gruvbox-material"] {
  --bg:        #1d2021;
  --bg-2:      #282828;
  --panel:     #32302f;
  --panel-2:   #3c3836;
  --line:      #504945;
  --ink:       #ebdbb2;
  --ink-2:     #e0d2b3;
  --ink-3:     #c2b39c;
  --accent:    #b8bb26;
  --accent-2:  #fb4934;
  --accent-3:  #83a598;
  --accent-4:  #d3869b;
  --warn:      #fabd2f;
  --on-accent: #1d2021;
}

[data-theme="bauhaus-triad"] {
  --bg:        #0b0b0d;
  --bg-2:      #131315;
  --panel:     #1a1a1e;
  --panel-2:   #212126;
  --line:      #2c2c32;
  --ink:       #f1efe9;
  --ink-2:     #d6d3ca;
  --ink-3:     #aeaba2;
  --accent:    #ffd84d;
  --accent-2:  #e6483a;
  --accent-3:  #3f7dd6;
  --accent-4:  #b76cd9;
  --warn:      #f0a830;
  --on-accent: #0b0b0d;
}

/* Colour tokens (--bg, --ink, --accent, …) live in themes.css and are
   selected per-document via the data-theme attribute on <html>. This block
   carries only the structural/contrast aliases that depend on those tokens. */
:root{
  --radius: 2px;
  /* Aliases used by server-side pages, cards, tables and popups. These were
     previously written as bare `var(--x){…}` rules (invalid selectors) and so
     never applied, leaving every popup transparent. Define them properly. */
  --border: var(--line);
  --bg-card: var(--bg-2);
  --bg-plot: var(--panel);
  /* Semantic aliases used by the forum-preview component and the /scale page.
     These had no fallback at the use sites, so an undefined token left muted
     captions and preview text inheriting full-bright --ink (the "missing
     colour scheme"). Map them onto the theme tokens so they follow data-theme. */
  --muted: var(--ink-3);
  --text: var(--ink);
  --surface: var(--bg-2);
  --danger: var(--accent-2);
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{background:var(--bg);color:var(--ink);font-family:'Fraunces',serif;font-weight:400;min-height:100vh;overflow-x:hidden}
/* Global theme-contrast control. A CSS contrast() filter on the ROOT element is
   the one documented exception that does NOT establish a containing block for
   fixed/absolute descendants, so the position:fixed header keeps pinning to the
   viewport. --contrast defaults to 1 (identity); the profile picker drives it
   and persists the choice in localStorage (cf_contrast), applied early by the
   boot script in src/server/app.js to avoid a flash. Independent of the
   waterfall floor/ceiling sliders. The brightness slider on the same profile
   row drives --brightness plus a gradual invert (--invert ramps 0→1 with a
   matching 0→180° --hue rotation to preserve hues) that eases the whole root
   into a light colour scheme as the slider climbs; all default to identity. */
html{filter:contrast(var(--contrast,1)) brightness(var(--brightness,1)) invert(var(--invert,0)) hue-rotate(var(--hue,0deg))}
body{
  background:
    radial-gradient(ellipse at 10% 0%, rgba(212,255,58,0.04), transparent 50%),
    radial-gradient(ellipse at 90% 100%, rgba(94,184,255,0.04), transparent 50%),
    var(--bg);
  background-attachment: fixed;
  /* The header is position:fixed (below) and pinned to the top of the viewport
     on every page; this padding reserves its height so page content starts
     beneath it instead of under it. --header-h is re-measured by _nav.eta. */
  padding-top: var(--header-h, 150px);
}
/* grain overlay */
body::before{
  content:'';position:fixed;inset:0;pointer-events:none;z-index:1;opacity:.35;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/><feColorMatrix values='0 0 0 0 0.9 0 0 0 0 0.9 0 0 0 0 0.85 0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
/* Section headings on server-rendered content pages (library, pricing, forum,
   cymbal/scale bodies) read in the signal accent so titles are easy to scan.
   Modal/popup titles use h3 and stay in --ink. */
h2{color:var(--accent)}
/* Plain content links — forum posts, legal pages, footers, popups and any SSR
   anchor that doesn't carry its own colour class — used to fall back to the
   browser's default dark-blue (link) / purple (visited), which are unreadable
   on the dark surfaces. Default them to a very light, readable colour; the
   browser underline still marks them as links. Styled link classes (.btn,
   .btn-mini, .nav-auth a, .byline a, accent links, …) win on specificity and
   keep their own colour. */
a{color:var(--ink-2)}
a:visited{color:var(--ink-3)}
a:hover{color:var(--accent)}
/* Form <select> menus default to the library filter look (dark surface) across
   the whole platform instead of the browser's white native chooser. This is a
   low-specificity base; component-specific select rules below still override
   per-property where they set one. */
select{background:var(--bg-card);color:var(--ink);border:1px solid var(--border);border-radius:var(--radius);padding:0.4rem 0.6rem;font-family:inherit;font-size:0.85rem}
select option{background:var(--bg-card);color:var(--ink)}
.mono{font-family:'JetBrains Mono',ui-monospace,monospace;font-weight:400;letter-spacing:.02em}
.tiny{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-2);font-weight:600}
.upp{text-transform:uppercase;letter-spacing:.12em}

header{
  position:fixed;top:0;left:0;right:0;z-index:50;
  border-bottom:1px solid var(--line);
  padding:24px 32px 18px;
  min-height:150px;
  display:grid;grid-template-columns:1fr auto;align-items:center;gap:24px;
  /* Solid backdrop so page content scrolls cleanly underneath the fixed header. */
  background:linear-gradient(180deg, rgba(0,0,0,.3), transparent), var(--bg);
}
/* Centred cymbal preview in the title bar (out of grid flow). Shown on hover
   over a library cymbal strip and pinned while a cymbal is analysed. Up to two
   photos sit side by side, each filling the full header height. */
.header-cymbal{
  position:absolute;left:50%;top:0;bottom:0;transform:translateX(-50%);
  display:none;flex-direction:row;align-items:center;justify-content:center;gap:10px;
  padding:12px 0;pointer-events:none;max-width:46%;z-index:1;
}
.header-cymbal.show{display:flex}
.header-cymbal .header-cymbal-img{
  height:100%;width:auto;max-width:100%;object-fit:cover;
  border:1px solid var(--line);border-radius:3px;background:var(--panel);
  box-shadow:0 6px 22px rgba(0,0,0,.55);
  /* Container is pointer-events:none so it never eats clicks on the nav; the
     images opt back in so hovering one can raise the enlarged popup below. */
  pointer-events:auto;cursor:zoom-in;
}
/* Enlarged floating preview of the header cymbal photo, anchored just below the
   header on hover. Mirrors .photo-hover-pop on the cymbal page but lives here so
   it is available on every page (the header is universal chrome). */
.header-cymbal-pop{
  position:fixed;z-index:300;pointer-events:none;display:none;
  height:min(70vh,520px);width:auto;max-width:90vw;max-height:80vh;
  object-fit:contain;border:1px solid var(--accent);border-radius:4px;
  background:var(--bg);box-shadow:0 12px 48px rgba(0,0,0,.6);
}
.header-title{text-align:left}
header h1 a{color:inherit;text-decoration:none}
header .left{display:flex;flex-direction:column;gap:6px}
header h1{
  font-family:'Fraunces',serif;font-weight:900;
  font-size:clamp(40px,7vw,92px);line-height:.85;letter-spacing:-.03em;
  font-variation-settings:"opsz" 144;
}
header h1 em{font-style:italic;font-weight:300;color:var(--accent);display:inline-block;margin-left:-2em}
header h1 .mirror-word{display:inline-block;transform:scaleX(-1);opacity:.45}
header .byline{margin-top:8px;letter-spacing:.12em}
header .byline a{color:var(--ink-2);text-decoration:none;border-bottom:1px dotted var(--ink-3)}
header .byline a:hover{color:var(--accent);border-bottom-color:var(--accent)}
header .right{display:flex;flex-direction:column;align-items:flex-end;gap:4px;text-align:right}
header .right .mono{font-size:11px;color:var(--ink-2)}
header .dot{display:inline-block;width:8px;height:8px;background:var(--accent);border-radius:50%;box-shadow:0 0 12px var(--accent);animation:blink 2s ease-in-out infinite}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.3}}

/* ── Primary navigation — detailed plate buttons ──────────────────────────
   Library + Analysis flank the title on the left; Forum + Profile on the
   right. Each ref is a bordered "plate"; the active page fills lime, hover
   reveals an accent edge-tick. The take/analysis workbench reuses .nav-cell
   in a packed 2×2 via .main-nav/.nav-grid. */
.nav-side{display:flex;align-items:stretch;gap:8px}
.nav-side.nav-left{justify-content:flex-start}
.nav-side.nav-right{justify-content:flex-end}
.nav-side-stack{display:flex;flex-direction:column;align-items:flex-end;gap:8px}

.nav-cell{
  display:flex;align-items:center;justify-content:center;gap:7px;
  min-width:116px;padding:13px 18px;
  font-family:'JetBrains Mono',monospace;font-size:14px;font-weight:400;
  letter-spacing:.16em;text-transform:uppercase;white-space:nowrap;
  color:var(--ink-2);text-decoration:none;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  position:relative;overflow:hidden;
  transition:color .15s ease,background .15s ease,border-color .15s ease;
}
.nav-cell::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:var(--accent);transform:scaleY(0);transform-origin:bottom;
  transition:transform .15s ease;
}
.nav-cell:hover{color:var(--ink);border-color:var(--ink-3);background:var(--panel-2)}
.nav-cell:hover::before{transform:scaleY(1)}
.nav-cell.active{color:var(--ink);background:rgba(255,140,90,0.18);border-color:rgba(255,140,90,0.5)}
.nav-cell.active::before{transform:scaleY(0)}

.nav-count{
  display:none;min-width:18px;height:16px;padding:0 5px;border-radius:8px;
  background:var(--accent-3);color:#0a0b0d;font-size:10px;line-height:16px;
  text-align:center;font-weight:700;
}
.nav-count.show{display:inline-block}
.nav-cell.active .nav-count{background:var(--ink);color:#0a0b0d}

.nav-auth{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.08em;color:var(--ink-2);text-align:right}
.nav-auth a{color:var(--ink-2);text-decoration:none;border-bottom:1px dotted var(--ink-3)}
.nav-auth a:hover{color:var(--accent);border-bottom-color:var(--accent)}

main{position:relative;z-index:2;padding:32px;max-width:1800px;margin:0 auto}

/* Library body: upload button + card grid in a row */
.library-body{display:flex;align-items:flex-start;gap:8px}
.lib-upload-btn{
  flex-shrink:0;width:72px;min-height:64px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  border:1px dashed var(--accent);color:var(--accent);cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  transition:background .15s ease;padding:10px 6px;text-align:center;
}
.lib-upload-btn:hover{background:rgba(212,255,58,0.08)}
.lib-upload-btn svg{width:16px;height:16px;flex-shrink:0}
#fileInput{display:none}
#libraryContainer{flex:1;min-width:0}
.library.drag .library-body{outline:1px solid var(--accent);background:rgba(212,255,58,0.02)}
.btn{
  font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  padding:14px 22px;background:var(--accent);color:var(--on-accent);border:none;cursor:pointer;
  transition:all .2s ease;font-weight:500;
}
.btn:hover{filter:brightness(1.08);transform:translate(-1px,-1px);box-shadow:3px 3px 0 var(--ink)}
.btn:disabled{opacity:.3;cursor:not-allowed;transform:none;box-shadow:none}
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
.btn.ghost:hover{background:var(--panel);border-color:var(--accent);box-shadow:none}

/* Take manager */
.takes{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:28px}
.take{
  display:flex;align-items:center;gap:10px;padding:8px 14px;border:1px solid var(--line);
  background:var(--panel);font-family:'JetBrains Mono',monospace;font-size:11px;
}
.take .zone-select{background:var(--bg-2);color:var(--ink);border:1px solid var(--line);padding:4px 6px;font-family:'JetBrains Mono',monospace;font-size:10px}
.take .x{cursor:pointer;color:var(--ink-3);padding:0 4px}
.take .x:hover{color:var(--accent-2)}
.take.active{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}

/* Section */
.section{margin-bottom:48px}

.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.grid-4{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
@media(min-width:1200px){.grid-4{grid-template-columns:repeat(2,1fr)}}

.plot-card{
  background:var(--panel);border:1px solid var(--line);
  display:flex;flex-direction:column;
}
.plot-card .card-head{
  padding:14px 18px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;
  background:linear-gradient(180deg, var(--panel-2), var(--panel));
}
.plot-card .card-head .title{font-family:'Fraunces',serif;font-size:13px;font-weight:600;letter-spacing:-.01em;color:var(--accent)}
.plot-card .card-head .meta{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--ink-3);letter-spacing:.1em;text-transform:uppercase}
.plot-card .card-head{gap:10px}
/* margin-left:auto pushes the Discuss button to the far right while letting the
   title and meta pack together on the left (auto margin overrides space-between). */
.plot-card .card-head .card-discuss{margin-left:auto;flex:0 0 auto;white-space:nowrap}
.plot-card .card-head .card-discuss.cf-has-thread{border-color:var(--accent-3);color:var(--accent-3)}
.plot-card .plot{min-height:320px;position:relative}
.plot-card.tall .plot{min-height:540px}
/* The waterfall is a 3-D surface; give it a taller frame so zooming-in crops
   less of the rotated surface against the plot boundary. The ~1080px cap +
   centering live on a WRAPPER, never on the Plotly render div itself: gl3d
   positions its WebGL canvas off the render div's geometry, so a max-width +
   auto-margins on #p_waterfall made the div recenter whenever the page border
   moved (e.g. a scrollbar toggling on a take swap), painting the scene off to
   the side ("jumps far right"). Keeping the render div full-width at left:0 of a
   centered wrapper pins that geometry so it can't drift. */
.plot-card.wf-card .wf-plot-wrap{max-width:1080px;margin:0 auto;width:100%}
.plot-card.wf-card .plot{min-height:720px;width:100%}

/* Controls row */
/* Controls row — appears ABOVE the plot inside a card (parameters at top) */
.controls-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center;padding:12px 18px;background:var(--bg-2);border-bottom:1px solid var(--line);font-family:'JetBrains Mono',monospace;font-size:11px}
.controls-row label{color:var(--ink-2);display:flex;align-items:center;gap:8px}
.controls-row input[type=range]{accent-color:var(--accent);width:120px}
.controls-row select{background:var(--panel);color:var(--ink);border:1px solid var(--line);padding:4px 8px;font-family:inherit;font-size:inherit}
.controls-row .val{color:var(--accent);min-width:40px;display:inline-block}
.controls-row-tight{gap:14px}
/* Scroll-line chooser — revealed (hidden attr removed) when "Display scroll" is
   ticked; lays out inline like the rest of the controls row. */
.wf-scroll-opts{display:inline-flex;align-items:center;gap:14px}
.wf-scroll-opts[hidden]{display:none}
.wf-scroll-opts input[type=color]{width:28px;height:20px;padding:0;border:1px solid var(--line);background:var(--panel);cursor:pointer}

/* Dial widget — vertical drag / wheel / dbl-click reset. The hidden range
   input adjacent to .dial is the source of truth; the dial dispatches input
   events on it so existing listeners keep working. */
.dial-wrap{display:inline-flex;align-items:center;gap:8px;color:var(--ink-2)}
.dial{width:34px;height:34px;cursor:ns-resize;touch-action:none;user-select:none;display:inline-block;flex:0 0 auto}
.dial svg{width:100%;height:100%;display:block;overflow:visible}
.dial .dial-track{stroke:var(--line);stroke-width:3;fill:none;stroke-linecap:round}
.dial .dial-arc{stroke:var(--accent);stroke-width:3;fill:none;stroke-linecap:round;transition:stroke .15s ease}
.dial .dial-tick{stroke:var(--ink);stroke-width:2;stroke-linecap:round;transform-origin:16px 16px}
.dial:hover .dial-arc,.dial.active .dial-arc{stroke:var(--accent)}
.dial:hover .dial-tick,.dial.active .dial-tick{stroke:var(--accent)}
.dial-meta{display:inline-flex;flex-direction:column;line-height:1.2;gap:2px}
.dial-meta .dial-label{color:var(--ink-3);font-size:10px;letter-spacing:.08em;text-transform:uppercase}
.dial-meta .val{min-width:0}

/* Visual group: gamma dial + colorscale dropdown share a framed container. */
.dial-group{display:inline-flex;align-items:center;gap:12px;padding:6px 12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--panel)}
.dial-group-select{display:inline-flex;align-items:center;gap:6px;color:var(--ink-3);font-size:10px;letter-spacing:.08em;text-transform:uppercase}
.dial-group-select select{text-transform:none;letter-spacing:0;font-size:11px;color:var(--ink)}

/* Partial table */
.data-table{
  width:100%;border-collapse:collapse;font-family:'JetBrains Mono',monospace;font-size:11px;
  background:var(--bg-2);
}
.data-table th,.data-table td{padding:8px 12px;border-bottom:1px solid var(--line);text-align:left}
.data-table th{color:var(--ink-3);font-weight:400;letter-spacing:.15em;text-transform:uppercase;font-size:10px}
.data-table tr:hover td{background:var(--panel)}
.beat-flag{color:var(--accent-2);font-weight:500}

.export-bar{display:flex;gap:8px;padding:12px 18px;border-top:1px solid var(--line);background:var(--bg-2)}

.loader{
  position:fixed;inset:0;z-index:100;display:none;
  align-items:center;justify-content:center;
  background:rgba(10,11,13,.55);backdrop-filter:blur(3px);
}
.loader.show{display:flex;animation:loader-fadein 150ms ease both}
@keyframes loader-fadein{from{opacity:0}to{opacity:1}}
.loader .core{
  background:var(--panel);border:1px solid var(--line);
  padding:28px 36px;text-align:center;min-width:260px;max-width:380px;
  box-shadow:0 8px 32px rgba(0,0,0,.65);
}
.loader .ring{
  width:44px;height:44px;border:1px solid var(--line);border-top-color:var(--accent);border-radius:50%;
  animation:spin 1.2s linear infinite;margin:0 auto 16px;
}
@keyframes spin{to{transform:rotate(360deg)}}
.loader h4{font-family:'Fraunces',serif;font-style:italic;font-weight:300;font-size:22px;margin-bottom:4px}
.loader .loader-title{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--ink-3);margin-bottom:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.loader .step{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--ink-2);letter-spacing:.15em;text-transform:uppercase}
.loader .progress-bar{width:100%;height:1px;background:var(--line);margin:16px 0 0;overflow:hidden}
.loader .progress-bar div{height:100%;background:var(--accent);width:0%;transition:width .3s ease}
.loader .loader-note{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--ink-3);margin-top:14px;font-style:italic}

.empty-state{
  text-align:center;padding:80px 20px;color:var(--ink-3);
  font-family:'Fraunces',serif;font-style:italic;font-size:18px;
  border:1px dashed var(--line);
}

footer{
  position:relative;z-index:2;border-top:1px solid var(--line);padding:24px 32px;
  display:flex;justify-content:space-between;align-items:center;margin-top:40px;
  font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--ink-3);letter-spacing:.15em;text-transform:uppercase;
}

/* Plotly overrides */
.js-plotly-plot .plotly .modebar{background:transparent !important}

.comparison-panel{display:none;margin-top:16px}
.comparison-panel.show{display:block}

.toggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer;color:var(--ink-2)}
.toggle input{accent-color:var(--accent)}

/* Zone badge colors */

/* --- Library --- */
.library{margin-bottom:28px}
.library-head{display:flex;align-items:baseline;gap:16px;margin-bottom:12px}
.library-head .title{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--accent-3)}
.library-head .count{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--accent)}
.library-head .hint{font-family:'Fraunces',serif;font-style:italic;color:var(--ink-3);font-size:13px;flex:1;text-align:right}
.library-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:8px}
.lib-card{
  border:1px solid var(--line);background:var(--panel);padding:10px 10px 9px;cursor:pointer;
  position:relative;transition:all .15s ease;display:flex;flex-direction:column;gap:6px;
}
.lib-card:hover{border-color:var(--ink-3);background:var(--panel-2)}
.lib-card.active{border-color:var(--accent);background:linear-gradient(180deg, rgba(212,255,58,0.06), var(--panel));box-shadow:inset 0 0 0 1px var(--accent)}
.lib-card .name{font-family:'Fraunces',serif;font-size:13px;font-weight:600;letter-spacing:-.01em;color:var(--ink);padding-right:18px;line-height:1.25}
.card-badges{display:flex;flex-wrap:wrap;gap:3px;margin-top:2px}
.card-badge{
  font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.08em;text-transform:uppercase;
  padding:2px 6px;border:1px solid var(--line);color:var(--ink-3);background:var(--bg-2);
}
.lib-card.active .card-badge{border-color:rgba(212,255,58,0.3);color:var(--accent)}
.lib-card .remove{
  position:absolute;top:8px;right:8px;width:22px;height:22px;display:grid;place-items:center;
  color:var(--ink-3);cursor:pointer;font-size:14px;line-height:1;border-radius:50%;z-index:2;
}
.lib-card .remove:hover{color:var(--accent-2);background:rgba(255,77,46,0.1)}
.lib-card .status-dot{width:6px;height:6px;border-radius:50%;background:var(--ink-3);display:inline-block;margin-right:6px;vertical-align:middle}
.lib-card.active .status-dot{background:var(--accent);box-shadow:0 0 6px var(--accent)}
.lib-card.pending .status-dot{background:var(--warn);animation:blink 1s infinite}
.lib-avg-card{border:1px dashed var(--accent-3);background:rgba(94,184,255,.04)}
.lib-avg-card:hover{border-color:var(--accent-3);background:rgba(94,184,255,.08)}
.lib-avg-card.active{border-color:var(--accent-3);background:linear-gradient(180deg,rgba(94,184,255,.10),var(--panel));box-shadow:inset 0 0 0 1px var(--accent-3)}
.lib-avg-card .name{color:var(--accent-3);font-style:italic}
.avg-dot{background:var(--accent-3) !important}
.lib-avg-card.active .avg-dot{box-shadow:0 0 6px var(--accent-3) !important}
.avg-meta{margin-top:1px;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;color:var(--ink-3)}
.library-avg-row{margin-top:6px;padding-top:6px;border-top:1px dashed var(--line)}
.lib-empty{
  padding:28px;text-align:center;color:var(--ink-3);font-family:'Fraunces',serif;font-style:italic;font-size:14px;
  border:1px dashed var(--line);background:var(--bg-2);
}

/* --- Plot description block (appears BELOW the plot — description at bottom) --- */
.plot-intro{
  background:var(--bg-2);padding:12px 20px;
  font-family:'Fraunces',serif;font-size:14px;line-height:1.6;color:var(--ink-2);
  font-weight:400;
}
/* When inside a card (below the plot), add a top border */
.plot-card > .plot-intro{border-top:1px solid var(--line)}
/* When outside a card (section-level, appears below all cards), full border */
.section > .plot-intro{border:1px solid var(--line);margin-top:16px}
.plot-intro strong{color:var(--ink);font-weight:600;font-style:italic}
.plot-intro .tag{
  display:inline-block;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent);margin-right:8px;
}

/* --- Tabs --- */
.tabs-nav{
  position:sticky;top:var(--header-h,150px);z-index:40;
  background:rgba(10,11,13,0.92);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  margin:0 -32px 0;
  display:flex;flex-direction:column;
}
.group-strip{
  display:flex;overflow-x:auto;scrollbar-width:none;
  padding:0 32px;
  border-bottom:1px solid var(--line);
  background:rgba(64,192,192,.07);
}
.group-strip::-webkit-scrollbar{display:none}
.group-btn{
  flex-shrink:0;
  font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.28em;text-transform:uppercase;
  background:transparent;color:#ff6600;border:none;border-bottom:2px solid transparent;
  padding:9px 22px 7px;cursor:pointer;transition:color .15s ease, border-color .15s ease;
  white-space:nowrap;font-weight:500;
}
.group-btn:hover{color:var(--ink)}
.group-btn.active{color:#ff6600;border-bottom-color:#ff6600}
.tab-strip{
  display:flex;overflow-x:auto;scrollbar-width:thin;
  padding:0 32px;
  background:rgba(64,192,192,.04);
}
.tab-strip::-webkit-scrollbar{height:3px}
.tab-strip::-webkit-scrollbar-thumb{background:var(--line)}
.tab-btn{
  flex-shrink:0;
  font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.15em;text-transform:uppercase;
  background:transparent;color:var(--ink-3);border:none;border-bottom:2px solid transparent;
  padding:16px 22px 14px;cursor:pointer;transition:color .15s ease, border-color .15s ease;
  display:flex;align-items:center;gap:10px;white-space:nowrap;
  font-weight:400;
}
.tab-btn:hover{color:var(--ink)}
.tab-btn.active{color:var(--accent);border-bottom-color:var(--accent)}
.tab-btn.group-hidden{display:none}
.tab-btn .tab-num{display:none}
.tab-btn .tab-label{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.28em;text-transform:uppercase;font-weight:500;font-style:normal}

.tab-panel{display:none;padding-top:28px}
.tab-panel.active{display:block}
.tab-panel.empty > .section{display:none} /* hide plot content; shared empty state shows above */
.tab-panel.gating > .section{display:none} /* hide plot content while waiting on pipeline gate */

/* When tabs exist, remove .section bottom margin collisions */
.tab-panel .section{margin-bottom:0}
.tab-panel .section-head{margin-top:0}

/* Sticky top block = header + upload + desc + library + status */
.pinned-top{position:relative}

/* --- Qualifiers panel --- */
#qualCymbalContainer,#qualTakeContainer{padding-top:16px}

.qual-nav{
  display:flex;flex-wrap:wrap;gap:4px;margin-bottom:16px;
}
.qual-cat-btn{
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.28em;text-transform:uppercase;
  padding:7px 18px;background:var(--panel-2);color:var(--ink-3);
  border:1px solid var(--line);cursor:pointer;transition:all .15s ease;
}
.qual-cat-btn:hover{color:var(--ink);border-color:var(--ink-3)}
.qual-cat-btn.active{color:var(--accent);border-color:var(--accent);background:rgba(212,255,58,0.06)}

.qual-cat-panel{display:none}
.qual-cat-panel.active{display:block}

.qual-grid{
  border:1px solid var(--line);
  display:flex;flex-direction:column;
}
.qual-row{
  display:grid;grid-template-columns:200px 1fr;
  border-bottom:1px solid var(--line);
  background:var(--panel);
  min-height:44px;
}
.qual-row:last-child{border-bottom:none}
.qual-row:hover{background:var(--panel-2)}
.qual-label{
  padding:10px 18px;
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--ink-3);border-right:1px solid var(--line);
  display:flex;align-items:center;
}
.qual-chips{
  display:flex;flex-wrap:wrap;gap:6px;padding:8px 14px;align-items:center;
}
.qual-chip{
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.08em;
  padding:4px 12px;
  background:transparent;color:var(--ink-3);border:1px solid var(--line);
  cursor:pointer;transition:all .15s ease;
}
.qual-chip:hover{color:var(--ink);border-color:var(--ink-3);background:var(--panel-2)}
.qual-chip.selected{color:var(--on-accent);background:var(--accent);border-color:var(--accent)}
.qual-text{
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.04em;
  padding:4px 10px;width:120px;
  background:transparent;color:var(--ink-2);
  border:1px dashed var(--line);
  transition:border-color .15s ease,color .15s ease;
}
.qual-text:not(:placeholder-shown){color:var(--on-accent);background:var(--accent);border-color:var(--accent);border-style:solid}
.qual-text:focus{outline:none;border-color:var(--accent);border-style:solid;color:var(--ink)}
.qual-text:not(:placeholder-shown):focus{color:var(--on-accent)}
.qual-text::placeholder{color:var(--ink-3);font-style:italic}

/* --- File details read-only panel in qualifiers --- */
.qual-file-details{padding-top:4px}
.qual-fd-val{
  font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--ink);
  letter-spacing:.02em;word-break:break-all;
}
.qual-fd-empty{padding:20px;color:var(--ink-3);font-style:italic;font-size:13px}

/* ── Library: cymbal tree ─────────────────────────────────────────────────── */
.lib-cymbal-section{margin-bottom:6px;border:1px solid var(--line);background:var(--panel)}
.lib-cymbal-header{
  display:flex;align-items:center;gap:8px;padding:7px 10px;
  cursor:pointer;user-select:none;border-bottom:1px solid var(--line);
  background:var(--panel-2);
}
.lib-cymbal-header:hover{background:var(--bg-2)}
.lib-cymbal-header.unassigned{opacity:.65}
.lib-toggle{font-size:10px;color:var(--ink-3);flex-shrink:0}
.lib-cymbal-name{
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);flex:1;
}
.lib-take-count{color:var(--ink-3);flex-shrink:0}
.lib-cymbal-del{
  color:var(--ink-3);cursor:pointer;font-size:13px;line-height:1;
  padding:0 2px;border-radius:2px;flex-shrink:0;
}
.lib-cymbal-del:hover{color:var(--accent-2);background:rgba(255,77,46,.1)}
.lib-cymbal-body{padding:6px 6px 4px}
.lib-new-cymbal{
  margin-top:4px;width:100%;padding:7px;
  background:transparent;color:var(--ink-3);
  border:1px dashed var(--line);cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;
  transition:all .15s ease;
}
.lib-new-cymbal:hover{color:var(--accent);border-color:var(--accent);background:rgba(212,255,58,.04)}
.lib-assign-btn{
  position:absolute;top:5px;right:20px;
  background:transparent;border:none;color:var(--ink-3);
  cursor:pointer;font-size:15px;line-height:1;padding:2px 4px;
  border-radius:2px;z-index:2;
}
.lib-assign-btn:hover{color:var(--accent);background:rgba(212,255,58,.08)}
.lib-card{position:relative}
.lib-assign-menu{
  position:absolute;z-index:100;min-width:160px;
  background:var(--panel-2);border:1px solid var(--line);
  box-shadow:0 4px 16px rgba(0,0,0,.5);
}
.lib-assign-item{
  padding:8px 14px;cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:10px;
  letter-spacing:.08em;color:var(--ink-2);
}
.lib-assign-item:hover{background:var(--bg-2);color:var(--ink)}
.lib-assign-item.current{color:var(--accent)}
.lib-assign-item.new{color:var(--ink-3);border-top:1px solid var(--line)}
.lib-assign-item.new:hover{color:var(--accent)}

/* ── Qualifiers panel ─────────────────────────────────────────────────────── */
.qualifiers-panel{display:flex;flex-direction:column}

/* Lossy-format warning banner (server mode only) */
.lossy-banner{
  background:#b87e00;color:#fff;
  padding:10px 18px;border-radius:3px;
  margin:12px 0 4px;font-size:13px;line-height:1.5;
}

/* ── Button helpers (used by server-side pages) ────────────────────────── */
.btn-primary{
  display:inline-block;padding:0.45rem 1.1rem;
  background:var(--accent,#c0916a);color:var(--on-accent);border:none;
  border-radius:3px;cursor:pointer;font-family:'JetBrains Mono',monospace;
  font-size:0.8rem;font-weight:600;text-decoration:none;
}
.btn-primary:hover{filter:brightness(1.1);}

/* Secondary button — outline variant, for non-primary actions next to a
   .btn-primary (e.g. "Batch upload" beside "+ New cymbal"). */
.btn-secondary{
  display:inline-flex;align-items:center;gap:0.4em;padding:0.45rem 1.1rem;
  background:transparent;color:var(--accent,#c0916a);
  border:1px solid var(--accent,#c0916a);
  border-radius:3px;cursor:pointer;font-family:'JetBrains Mono',monospace;
  font-size:0.8rem;font-weight:600;text-decoration:none;
  transition:background .12s,color .12s;
}
.btn-secondary:hover{background:var(--accent,#c0916a);color:var(--on-accent);}

/* ── Modal dialogs & popups ───────────────────────────────────────────────
   The universal `*{margin:0}` reset above strips the UA `margin:auto` that
   centres a modal <dialog>, leaving popups pinned to the top-left. Restore it,
   and give every dialog the opaque card surface plus a real dimmed, blurred
   backdrop. Per-dialog inline styles still tune width/padding on top of this. */
dialog{
  margin:auto;
  border:1px solid var(--border);
  background:var(--bg-card);
  color:var(--ink);
  border-radius:var(--radius);
  box-shadow:0 24px 64px -20px rgba(0,0,0,.8);
}
dialog::backdrop{
  background:rgba(8,9,11,.62);
  -webkit-backdrop-filter:blur(3px);
  backdrop-filter:blur(3px);
}

/* ── Mobile responsive — breakpoints ──────────────────────────────────── */

/* Header: collapse the 3-column grid to a stack on small screens */
@media(max-width:768px){
  header{
    grid-template-columns:1fr;
    grid-template-rows:auto auto auto;
    text-align:center;
    gap:10px;
  }
  header .left{ align-items:center; }
  header .right{ align-items:center; text-align:center; }
  /* Centre the flanking nav groups when the header collapses to a stack. */
  .nav-side{ justify-content:center; flex-wrap:wrap; }
  .nav-side-stack{ align-items:center; }
  .nav-auth{ text-align:center; }
  .nav-cell{ flex:1 1 auto; min-width:128px; }
}

/* Library: stack upload button above card grid */
@media(max-width:600px){
  .library-body{ flex-direction:column; }
  .lib-upload-btn{ width:100%; min-height:48px; }
  #libraryContainer{ width:100%; }
  .library-grid{ grid-template-columns:repeat(auto-fill,minmax(80px,1fr)); }
}

/* Analysis tab strip: horizontally scrollable on mobile */
@media(max-width:768px){
  .tab-strip{ flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .tab-strip::-webkit-scrollbar{ height:3px; }
  .tab-item{ flex-shrink:0; }
}

/* Controls row: stack vertically on very small screens */
@media(max-width:480px){
  .controls-row{ flex-direction:column; align-items:flex-start; gap:8px; }
}

/* Two-column / four-column grids: single column on mobile */
@media(max-width:600px){
  .grid-2,.grid-4{ grid-template-columns:1fr !important; }
}

/* Qualifiers grid: stack label + input vertically */
@media(max-width:480px){
  .qual-grid{ grid-template-columns:1fr !important; }
  .q-row{ flex-direction:column; align-items:flex-start; }
  .q-row label{ width:auto; }
}

/* Forum post body: prevent overflow from long URLs / code */
.post-body{ word-break:break-word; overflow-wrap:anywhere; }
.post-body pre{ overflow-x:auto; max-width:100%; }

/* Admin table: horizontally scrollable wrapper */
@media(max-width:900px){
  .admin-table-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
}

/* Library tree drawer: full-width on narrow viewports */
@media(max-width:768px){
  .cymbal-node{ border-bottom:1px solid var(--line); }
}

/* Profile / form pages: full-width inputs */
@media(max-width:600px){
  .legal-body,
  main[style*="max-width"]{
    padding:1rem !important;
  }
  form input, form textarea, form select{
    font-size:16px; /* prevent iOS zoom */
  }
}

/* Cymbal directory cards: single column on phones */
@media(max-width:480px){
  #cymbalGrid{
    grid-template-columns:1fr !important;
  }
}

/* ── Library: add-to-pool toggle on each cymbal card ───────────────────── */
.pool-toggle{
  font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;
  padding:6px 10px;cursor:pointer;background:transparent;color:var(--ink-2);
  border:1px solid var(--line);border-radius:2px;transition:all .15s ease;white-space:nowrap;
}
.pool-toggle:hover{color:var(--ink);border-color:var(--ink-3)}
.pool-toggle.in-pool{color:var(--on-accent);background:var(--accent);border-color:var(--accent)}

/* ── Analysis: comparison pool ─────────────────────────────────────────── */
.pool-bar{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  flex-wrap:wrap;margin-bottom:1.25rem;
}
.pool-bar .count{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--accent);letter-spacing:.12em;text-transform:uppercase;font-weight:600}
.pool-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1rem}
.pool-card{position:relative;padding:1rem;display:flex;flex-direction:column;gap:0.5rem}
.pool-card .pool-remove{
  position:absolute;top:8px;right:10px;width:24px;height:24px;display:grid;place-items:center;
  color:var(--ink-3);cursor:pointer;font-size:16px;line-height:1;border-radius:50%;background:transparent;border:none;
}
.pool-card .pool-remove:hover{color:var(--accent-2);background:rgba(255,77,46,.1)}
.pool-card .pc-name{font-family:'Fraunces',serif;font-weight:600;font-size:1.05rem;padding-right:24px}
.pool-card .pc-spec{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--ink-2);letter-spacing:.04em}
.pool-card .pc-spec b{color:var(--ink-3);font-weight:600}
.pool-card .pc-actions{display:flex;gap:0.5rem;margin-top:0.5rem}
.pool-empty{
  text-align:center;padding:64px 20px;color:var(--ink-2);
  font-family:'Fraunces',serif;font-style:italic;font-size:16px;border:1px dashed var(--line);
}
.pool-empty a{color:var(--accent)}

/* Nav: stretch the 2x2 grid full-width when the header stacks on mobile */
@media(max-width:768px){
  .main-nav{align-items:center;width:100%}
  .nav-grid{width:100%;max-width:340px}
}

/* ── Forum accordion (/forum) — single-page Sections › Threads › Posts ──── */
#forumTree{display:flex;flex-direction:column;gap:10px}
.acc-section{border:1px solid var(--line);background:var(--panel)}
.acc-section-head,.acc-thread-head{
  display:flex;align-items:center;gap:10px;cursor:pointer;user-select:none;padding:12px 16px;
}
.acc-section-head{background:linear-gradient(180deg,var(--panel-2),var(--panel))}
.acc-section-head:hover,.acc-thread-head:hover{background:var(--panel-2)}
.acc-arrow{flex:0 0 auto;width:12px;color:var(--ink-3);font-size:10px;line-height:1;display:inline-block;transition:transform .15s ease}
.acc-arrow::before{content:'\25B8'} /* ▸ */
.acc-section.open > .acc-section-head .acc-arrow,
.acc-thread.open  > .acc-thread-head  .acc-arrow{transform:rotate(90deg)}
.acc-section-title{font-family:'Fraunces',serif;font-weight:600;font-size:1rem}
.acc-thread-title{flex:1;min-width:0;font-weight:500;overflow:hidden;text-overflow:ellipsis}
.acc-section-meta,.acc-thread-meta{color:var(--ink-3);white-space:nowrap}
.acc-section-meta{margin-left:auto}
.acc-thread-meta{margin-left:8px}
.acc-section-actions,.acc-thread-actions{flex:0 0 auto;display:flex;gap:6px;align-items:center}
.acc-section-actions{margin-left:12px}
.acc-thread-actions{margin-left:10px}

.acc-section-body{display:none;border-top:1px solid var(--line);max-height:75vh;overflow:auto}
.acc-section.open > .acc-section-body{display:block}
.acc-thread{border-bottom:1px solid var(--line)}
.acc-thread:last-child{border-bottom:none}
.acc-thread-head{padding-left:26px}
.acc-thread-body{display:none;padding:0 16px 16px 26px}
.acc-thread.open > .acc-thread-body{display:block}
.acc-posts{display:flex;flex-direction:column;gap:12px}
.acc-empty{opacity:.5;padding:14px 26px}
.acc-tags{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:10px}
.acc-tag{padding:1px 6px;border-radius:2px;background:var(--line);color:var(--ink-2)}
.acc-badge{display:inline-block;padding:1px 6px;border:1px solid var(--line);border-radius:2px;color:var(--ink-3);margin-right:4px}
.acc-locked{opacity:.5}

.acc-post{border:1px solid var(--line);background:var(--bg-2);padding:12px 14px}
.acc-post-head{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:8px}
.acc-post-author{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.acc-post-author img{width:24px;height:24px;border-radius:50%;object-fit:cover}
.acc-post-tier{display:inline-block;padding:1px 6px;border:1px solid var(--line);border-radius:2px;color:var(--ink-3)}
.acc-post-tier[data-role="researcher"]{color:var(--accent);border-color:var(--accent)}
.acc-post-tier[data-role="admin"]{color:var(--ink);border-color:var(--ink-2);background:var(--panel-2)}
.acc-post-userposts{color:var(--ink-3)}
.acc-post-tools{display:flex;gap:10px;align-items:center;color:var(--ink-3)}
.acc-post-tools a{color:var(--ink-3)}
.acc-post-tools a:hover{color:var(--accent)}
.acc-post-edited{opacity:.4;margin-top:6px}
.acc-load-older{display:block;width:100%;margin:12px 0 0;padding:6px;background:none;border:1px dashed var(--line);
  color:var(--ink-3);cursor:pointer;font-family:'JetBrains Mono',monospace;font-size:11px}
.acc-load-older:hover{border-color:var(--accent);color:var(--accent)}

/* Forum accordion colour coding — each section (topic) carries its own hue via
   --sec-rgb, set on the .acc-section[data-section] and inherited down to its
   threads and posts so the whole Section › Thread › Post column reads in one
   colour family, distinct from the neighbouring topics. Threads sit one alpha
   step deeper than the section head, posts one deeper still. Scoped to
   #forumTree so it never touches the library's own lib-row-* colouring. */
#forumTree > .acc-section                          { --sec-rgb:195,143,255; }   /* fallback / new sections */
#forumTree > .acc-section[data-section="cymbals"]  { --sec-rgb:94,184,255; }    /* blue   */
#forumTree > .acc-section[data-section="pools"]    { --sec-rgb:124,214,150; }   /* green  */
#forumTree > .acc-section[data-section="analyses"] { --sec-rgb:200,150,255; }   /* purple */
#forumTree > .acc-section[data-section="science"]  { --sec-rgb:198,222,92; }    /* lime   */
#forumTree > .acc-section[data-section="bugs"]     { --sec-rgb:255,140,90; }    /* orange */

#forumTree > .acc-section > .acc-section-head{
  background:linear-gradient(180deg,
    rgba(var(--sec-rgb),0.12),
    rgba(var(--sec-rgb),0.03) 60%,
    rgba(0,0,0,0.10));
  border-left:3px solid rgba(var(--sec-rgb),0.6);
}
#forumTree > .acc-section > .acc-section-head:hover{
  background:linear-gradient(180deg,
    rgba(var(--sec-rgb),0.19),
    rgba(var(--sec-rgb),0.05) 60%,
    rgba(0,0,0,0.10));
}
#forumTree > .acc-section > .acc-section-head > .acc-section-title{color:rgb(var(--sec-rgb))}

#forumTree .acc-thread > .acc-thread-head{
  background:linear-gradient(180deg,
    rgba(var(--sec-rgb),0.08),
    rgba(var(--sec-rgb),0.02) 60%,
    rgba(0,0,0,0.18));
  border-left:3px solid rgba(var(--sec-rgb),0.5);
}
#forumTree .acc-thread > .acc-thread-head:hover{
  background:linear-gradient(180deg,
    rgba(var(--sec-rgb),0.14),
    rgba(var(--sec-rgb),0.04) 60%,
    rgba(0,0,0,0.18));
}
#forumTree .acc-thread > .acc-thread-head > .acc-thread-title{color:rgb(var(--sec-rgb))}

#forumTree .acc-post{border-left:3px solid rgba(var(--sec-rgb),0.45)}

.btn-mini{background:none;border:1px solid var(--line);color:var(--ink-2);cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:11px;padding:3px 9px;border-radius:2px}
.btn-mini:hover{border-color:var(--accent);color:var(--accent)}
/* A Discuss button whose thread already exists ("In Forum") — blueish tint. */
.btn-mini.cf-has-thread{border-color:var(--accent-3);color:var(--accent-3)}
.btn-mini.cf-has-thread:hover{border-color:var(--accent-3);color:var(--accent-3);filter:brightness(1.15)}
/* Forum hover previews (transcript tooltip + first-comment composer). */
.forum-preview{
  position:absolute;z-index:60;max-width:460px;min-width:300px;
  background:var(--surface,var(--panel));border:1px solid var(--border);
  border-radius:6px;box-shadow:0 6px 24px rgba(0,0,0,.25);
  padding:.65rem .8rem;font-size:.85rem;line-height:1.4;
}
/* One post per block: the author's name on its own row, then the (2-line capped)
   comment beneath it; blocks are separated by a hairline rule. */
.forum-preview .fp-row{
  display:flex;flex-direction:column;gap:.15rem;
  margin:0;padding:.45rem 0;border-bottom:1px solid var(--border);
}
.forum-preview .fp-row:first-child{padding-top:0}
.forum-preview .fp-row:last-child{padding-bottom:0;border-bottom:none}
.forum-preview .fp-user{font-weight:600;color:var(--accent-3)}
.forum-preview .fp-text{
  color:var(--text);display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.forum-preview .fp-more{text-align:center;color:var(--muted)}
.forum-preview .fp-more-top{margin-bottom:.3rem}
.forum-preview .fp-error{color:var(--danger,#e06c75);margin-top:.35rem;font-size:.75rem}
.forum-compose .fp-input{
  width:100%;min-height:4.5rem;resize:vertical;box-sizing:border-box;
  background:var(--panel);color:var(--text);border:1px solid var(--border);
  border-radius:4px;padding:.35rem .45rem;font-family:'JetBrains Mono',monospace;font-size:.78rem;
}
.forum-compose .fp-actions{display:flex;justify-content:space-between;align-items:center;margin-top:.4rem}
.forum-compose .fp-open{
  background:none;border:none;color:var(--accent-3);cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;text-decoration:underline;padding:0;
}
/* Reverse "Go to Analysis" link rendered as a btn-mini anchor. */
a.acc-origin{display:inline-block;text-decoration:none;line-height:1.4}

/* ── Library accordion (/library) — reuses the forum acc-* chrome ───────── */
/* Platform-wide play counter shown in each cymbal strip — kept neutral grey so
   it recedes behind the (now bolder) action buttons. */
.lib-plays{color:var(--ink-3);letter-spacing:.06em;white-space:nowrap;font-weight:600}
/* Library action buttons: a touch larger and more prominent than the forum's
   default btn-mini, so Edit / Analyse / Discuss / Rename / Delete read clearly. */
#libRoot .btn-mini{font-size:12px;padding:4px 11px;color:var(--ink);border-color:var(--ink-3)}
#libRoot .btn-mini:hover{border-color:var(--accent);color:var(--accent)}
#libRoot .btn-mini.cf-has-thread{color:var(--accent-3);border-color:var(--accent-3)}
.lib-poolpublic{display:inline-flex;align-items:center;gap:4px;cursor:pointer;color:var(--ink-2);user-select:none}
.lib-poolpublic input{cursor:pointer;margin:0}
.lib-tree{display:flex;flex-direction:column;gap:10px}
.lib-tree:empty{display:none}
.acc-takes{display:flex;flex-direction:column;gap:8px;padding:10px 16px 14px 26px}
.acc-take{display:flex;align-items:center;justify-content:space-between;gap:10px;
  border:1px solid var(--line);background:var(--bg-2);padding:8px 12px;
  text-decoration:none;color:inherit}
.acc-take:hover{border-color:var(--accent)}

/* Level-coloured rows: user=blue, cymbal=lime, take=orange, pool=lilac. Each
   level layers a translucent hue over a progressively darker panel base so the
   nesting reads visually: the user band is the lightest tint, the cymbal band
   sits one shade deeper, the take leaves deeper still. The border-left and
   title keep the same hue but at low alpha — present without shouting. */
.lib-row-user > .acc-section-head{
  background:linear-gradient(180deg,
    rgba(94,184,255,0.09),
    rgba(94,184,255,0.03) 60%,
    rgba(0,0,0,0.10));
  border-left:3px solid rgba(94,184,255,0.55);
}
.lib-row-user > .acc-section-head:hover{
  background:linear-gradient(180deg,
    rgba(94,184,255,0.16),
    rgba(94,184,255,0.05) 60%,
    rgba(0,0,0,0.10));
}
.lib-row-user > .acc-section-head > .acc-section-title{color:var(--accent-3)}

.lib-row-cymbal > .acc-section-head,
.lib-row-cymbal > .acc-thread-head{
  background:linear-gradient(180deg,
    rgba(212,255,58,0.07),
    rgba(212,255,58,0.02) 60%,
    rgba(0,0,0,0.22));
  border-left:3px solid rgba(212,255,58,0.5);
}
.lib-row-cymbal > .acc-section-head:hover,
.lib-row-cymbal > .acc-thread-head:hover{
  background:linear-gradient(180deg,
    rgba(212,255,58,0.13),
    rgba(212,255,58,0.04) 60%,
    rgba(0,0,0,0.22));
}
.lib-row-cymbal > .acc-section-head > .acc-section-title,
.lib-row-cymbal > .acc-thread-head  > .acc-thread-title{color:var(--accent)}
.lib-row-cymbal > .acc-section-head > .acc-section-title .acc-section-sub,
.lib-row-cymbal > .acc-thread-head  > .acc-thread-title  .acc-section-sub{color:var(--ink-3)}

.lib-row-take{
  background:linear-gradient(180deg,
    rgba(255,77,46,0.06),
    rgba(255,77,46,0.015) 50%,
    rgba(0,0,0,0.35));
  border-left:3px solid rgba(255,77,46,0.45);
  transition:background .15s ease,border-left-color .15s ease;
}
.lib-row-take:hover{
  background:linear-gradient(180deg,
    rgba(255,77,46,0.12),
    rgba(255,77,46,0.03) 50%,
    rgba(0,0,0,0.35));
  border-left-color:rgba(255,77,46,0.75);
}
.lib-row-take.acc-take-static:hover{border-left-color:rgba(255,77,46,0.75)}
.lib-row-take .lib-take-name{color:var(--accent-2);font-weight:500}

.lib-row-pool > .acc-section-head{
  background:linear-gradient(180deg,
    rgba(195,143,255,0.09),
    rgba(195,143,255,0.03) 60%,
    rgba(0,0,0,0.10));
  border-left:3px solid rgba(195,143,255,0.55);
}
.lib-row-pool > .acc-section-head:hover{
  background:linear-gradient(180deg,
    rgba(195,143,255,0.16),
    rgba(195,143,255,0.05) 60%,
    rgba(0,0,0,0.10));
}
.lib-row-pool > .acc-section-head > .acc-section-title{color:var(--accent-4)}

/* MyPool — the fleeting default. Dotted border + subtle dashed left edge so
   it reads as "ephemeral" next to the solid-edged saved pools. */
.lib-row-mypool > .acc-section-head{
  border-left-style:dashed;
  background:linear-gradient(180deg,
    rgba(195,143,255,0.12),
    rgba(195,143,255,0.04) 60%,
    rgba(0,0,0,0.08));
}
.lib-row-mypool > .acc-section-head > .acc-section-title{font-style:italic}

/* Take row: structured fields */
.lib-take-fields{display:flex;align-items:center;gap:10px;min-width:0;flex:1;flex-wrap:wrap}
.lib-take-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lib-take-actions{flex:0 0 auto;display:flex;gap:6px;align-items:center}

/* User tier + post-count chips on Public Library owner rows.
   Reuses the forum acc-post-tier styling. */
.lib-user-chips{display:inline-flex;gap:6px;align-items:center;margin-left:8px;flex-wrap:wrap}
.lib-user-chip{display:inline-block;padding:1px 6px;border:1px solid var(--line);border-radius:2px;color:var(--ink-3)}
.lib-user-chip[data-role="researcher"]{color:var(--accent);border-color:var(--accent)}
.lib-user-chip[data-role="admin"]{color:var(--ink);border-color:var(--ink-2);background:var(--panel-2)}

/* Add-to-Pool popup: pool accordion with 8-slot grid */
.pool-pick-modal{border:1px solid var(--line);background:var(--bg-card);color:inherit;
  border-radius:4px;padding:1.25rem 1.5rem;min-width:380px;max-width:520px}
.pool-pick-list{display:flex;flex-direction:column;gap:6px;margin:0.75rem 0;
  max-height:60vh;overflow:auto}
.pool-pick-pool{border:1px solid var(--line);background:var(--bg-2)}
.pool-pick-pool-head{display:flex;align-items:center;gap:10px;cursor:pointer;
  user-select:none;padding:8px 12px}
.pool-pick-pool-head:hover{background:var(--panel-2)}
.pool-pick-pool-head .acc-arrow{flex:0 0 auto}
.pool-pick-pool.open > .pool-pick-pool-head .acc-arrow{transform:rotate(90deg)}
.pool-pick-pool-name{flex:1;color:var(--accent-4);font-weight:500}
.pool-pick-pool-meta{color:var(--ink-3)}
.pool-pick-slots{display:none;grid-template-columns:repeat(4,1fr);gap:6px;
  padding:8px 12px 12px}
.pool-pick-pool.open > .pool-pick-slots{display:grid}
.pool-pick-slot{display:flex;flex-direction:column;align-items:stretch;gap:2px;
  border:1px solid var(--line);background:var(--bg);color:inherit;
  padding:6px 8px;cursor:pointer;border-radius:2px;text-align:left;
  font-family:inherit;font-size:11px;min-height:40px;transition:border-color .15s,color .15s}
.pool-pick-slot:hover{border-color:var(--accent-2);color:var(--accent-2)}
.pool-pick-slot-num{color:var(--ink-3);font-family:'JetBrains Mono',monospace}
.pool-pick-slot-body{color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pool-pick-slot-empty .pool-pick-slot-body{color:var(--ink-3);font-style:italic}
.acc-take-main{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acc-take-status{flex:0 0 auto;color:var(--ink-3);white-space:nowrap}
.acc-take-unavail{opacity:.5;cursor:default}
.acc-take-unavail:hover{border-color:var(--line)}
.acc-take-static{cursor:default}
.acc-take-static:hover{border-color:var(--line)}
.lib-play{flex:0 0 auto;background:none;border:1px solid var(--line);color:var(--ink-2);
  padding:2px 8px;cursor:pointer;font-size:0.78rem;line-height:1.6;border-radius:2px;
  font-family:inherit;transition:border-color .15s,color .15s}
.lib-play:hover{border-color:var(--accent);color:var(--accent)}
.lib-play.playing{border-color:var(--accent);color:var(--accent)}
.lib-take-scale{flex:0 0 auto;background:none;border:1px solid var(--line);color:var(--ink-2);
  padding:2px 8px;cursor:pointer;font-size:0.78rem;line-height:1.6;border-radius:2px;
  font-family:inherit;text-decoration:none;white-space:nowrap;
  transition:border-color .15s,color .15s}
.lib-take-scale:hover{border-color:var(--accent);color:var(--accent)}
.lib-combo{display:inline-flex;align-items:center;gap:4px}
.lib-combo-method{background:var(--bg-2);border:1px solid var(--line);color:var(--ink-2);border-radius:2px;padding:2px 4px;font-size:.72rem;font-family:inherit}
.acc-section-sub{color:var(--ink-3);font-weight:400;font-style:italic}
.lib-bookmark{background:none;border:none;cursor:pointer;font-size:1.05rem;line-height:1;padding:0 2px}

/* Compose dock — the single, context-aware input docked below the accordion */
.compose-dock{position:sticky;bottom:0;z-index:5;margin-top:14px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:2px;
  padding:12px 14px;display:flex;flex-direction:column;gap:8px}
.compose-context{color:var(--ink-3)}
.compose-context strong{color:var(--ink);font-style:italic}
.compose-newfields{display:flex;gap:8px}
.compose-newfields input{flex:1}
.compose-dock textarea{width:100%;resize:vertical;min-height:54px}
.compose-dock textarea,
.compose-dock input[type="text"],
.acc-edit-form textarea{
  font-size:15px;line-height:1.5;font-family:'Fraunces',serif;
  background:#e8e8e8;color:#1c1c1c;border:1px solid var(--line);
  padding:8px 10px;border-radius:2px;
}
.compose-dock textarea::placeholder,
.compose-dock input[type="text"]::placeholder,
.acc-edit-form textarea::placeholder{color:#6e6e6e}
.compose-actions{display:flex;align-items:center;gap:10px;justify-content:flex-end}
.compose-error{color:var(--accent-2);margin-right:auto}
#composePost[disabled]{opacity:.4;cursor:not-allowed}

/* Forum post body: Markdown rendering inside accordion posts */
.post-body{line-height:1.6}
.post-body pre{background:var(--bg);padding:.75rem 1rem;border-radius:2px}
.post-body code{background:var(--bg);padding:.1em .3em;border-radius:2px}
.post-body blockquote{border-left:3px solid var(--line);margin:0;padding-left:1rem;opacity:.75}

@media(max-width:600px){
  .acc-section-meta,.acc-thread-meta{display:none}
  .acc-section-body{max-height:none}
  .compose-newfields{flex-direction:column}
}

/* ── Prefetch pulse ────────────────────────────────────────────────────────── */
.cf-slot-chip.prefetching{animation:slot-pulse 1.4s ease-in-out infinite}
@keyframes slot-pulse{0%,100%{opacity:1}50%{opacity:.3}}

/* ── Profile page ──────────────────────────────────────────────────────────── */
/* Role chip in the identity header and the member directory. */
.role-badge{
  display:inline-block;padding:2px 8px;border-radius:999px;
  background:rgba(255,140,90,0.14);border:1px solid rgba(255,140,90,0.45);
  color:var(--ink);font-weight:600;letter-spacing:.12em;
}
.stat-strip a:hover{color:var(--accent)}
.stat-strip strong{color:var(--ink);font-weight:600}

/* Owner-only Account zone: clearly demarcated from the public profile above. */
.owner-settings{
  margin-top:3.5rem;padding:1.75rem;border-radius:var(--radius);
  border:1px solid var(--line);border-top:3px solid var(--accent);
  background:var(--panel);
}
.owner-settings-head{
  display:flex;align-items:baseline;gap:0.75rem;flex-wrap:wrap;
  margin-bottom:1.5rem;padding-bottom:0.75rem;border-bottom:1px solid var(--line);
}
.owner-card{
  margin-bottom:1.25rem;padding:1.1rem 1.25rem;border-radius:var(--radius);
  border:1px solid var(--line);border-left:3px solid var(--accent);
  background:var(--bg);
}
.owner-card:last-child{margin-bottom:0}

/* ── Microtonal scale-extractor page (/scale) ─────────────────────────────── */
main.scale-page{max-width:1200px}
.scale-controls{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:0.9rem 1.25rem;align-items:end;
  padding:1rem 1.1rem;margin-bottom:1.25rem;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--bg-card);
}
.scale-ctl{display:flex;flex-direction:column;gap:0.3rem;font-size:0.8rem}
.scale-ctl > span{color:var(--muted);font-family:'JetBrains Mono',monospace;font-size:0.72rem}
.scale-ctl input[type=range]{width:100%}
.scale-ctl input[type=number],.scale-ctl select{
  background:var(--bg);color:var(--ink);border:1px solid var(--line);
  border-radius:3px;padding:0.35rem 0.45rem;font-family:'JetBrains Mono',monospace;
}
.scale-ctl em{color:var(--accent);font-style:normal}
.scale-range{display:flex;gap:0.4rem}
.scale-range input{width:100%}
/* transposition kinds: a single flush-left full-width row under the controls */
.scale-ctl-kinds{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:0.35rem 0.9rem}
.scale-ctl-kinds > span{color:var(--muted);font-family:'JetBrains Mono',monospace;font-size:0.72rem}
.scale-kinds{display:flex;flex-wrap:wrap;gap:0.35rem 0.9rem;align-items:center}
.scale-kinds label{
  display:flex;align-items:center;gap:0.3rem;cursor:pointer;
  color:var(--ink);font-family:'JetBrains Mono',monospace;font-size:0.72rem;
}
.scale-kinds input{accent-color:var(--accent);margin:0}
/* small titlebar: cymbal photo + name */
.scale-titlebar{display:flex;align-items:center;gap:1rem;margin-bottom:0.6rem}
.scale-thumb{height:64px;width:64px;object-fit:cover;border-radius:6px;border:1px solid var(--line);flex-shrink:0}
.scale-titletext h1{margin:0;font-size:1.35rem;line-height:1.1}
.scale-subj{display:flex;flex-wrap:wrap;gap:0.4rem 0.8rem;margin-top:0.25rem}
.scale-cymbal{color:var(--ink)}
.scale-take{color:var(--muted)}
.scale-cymbal + .scale-take::before{content:'· ';margin-right:0.25rem;color:var(--muted)}
/* header cymbal/take pickers — switch the page's subject without leaving it */
.scale-pick{display:flex;flex-wrap:wrap;gap:0.5rem 0.9rem;margin-top:0.4rem}
.scale-pick-ctl{display:flex;align-items:center;gap:0.4rem;font-size:0.78rem;color:var(--muted)}
.scale-pick-ctl > span{font-family:'JetBrains Mono',monospace;font-size:0.72rem}
.scale-pick-ctl select{font-family:inherit;font-size:0.78rem;color:var(--ink);
  background:var(--bg-card);border:1px solid var(--line);border-radius:6px;
  padding:0.25rem 0.4rem;max-width:14rem}
.scale-pick-ctl select:hover{border-color:var(--accent)}
.scale-desc{color:var(--muted);font-size:0.82rem;line-height:1.5;margin:0 0 1rem}
.scale-desc b:first-child{color:var(--ink)}
/* synth selector + formant params + transport, one row */
.scale-synthbar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:0.8rem 1.25rem;
  padding:0.7rem 0.9rem;margin-bottom:1rem;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--bg-card)}
.scale-synth-params{display:flex;flex-wrap:wrap;gap:0.6rem 1.25rem;flex:1 1 auto}
.scale-fmt{display:flex;flex-direction:column;gap:0.3rem;font-size:0.8rem;flex:1 1 220px;min-width:200px}
.scale-fmt > span{color:var(--muted);font-family:'JetBrains Mono',monospace;font-size:0.72rem}
.scale-fmt b{color:var(--accent);font-weight:500}
.scale-transport{display:flex;flex-wrap:wrap;gap:0.4rem;align-items:center}

/* deck: player cards + value grid share one column template so they align */
.scale-deck{--scale-ndeg:8;margin-bottom:1.25rem}
.scale-deck .scale-slots,.scale-deck .scale-vgrid{
  display:grid;grid-template-columns:3.4rem repeat(var(--scale-ndeg),minmax(0,1fr));align-items:stretch}
.scale-deck .scale-slots{gap:0.4rem;margin-bottom:0.5rem}
.scale-slot-spacer{grid-column:1}
.scale-slot{
  display:flex;flex-direction:column;gap:0.1rem;align-items:flex-start;min-width:0;
  border:1px solid var(--line);border-radius:6px;padding:0.35rem 0.45rem;
  background:var(--bg-card);cursor:pointer;text-align:left;font-family:'JetBrains Mono',monospace;
}
.scale-slot:hover{border-color:var(--accent)}
.scale-slot.playing{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.scale-slot > span{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.scale-slot .k{font-size:0.66rem;color:var(--muted);
  display:flex;align-items:center;justify-content:space-between}
.scale-slot .play{font-size:0.6rem;color:var(--muted);opacity:0.55;transition:opacity .12s,color .12s}
.scale-slot:hover .play{color:var(--accent);opacity:1}
.scale-slot.playing .play{color:var(--accent);opacity:1}
.scale-slot .note{font-size:0.84rem;color:var(--accent);font-weight:500}
.scale-slot .note small{font-size:0.6rem;color:var(--muted);font-weight:400}
.scale-slot .hz{font-size:0.64rem;color:var(--muted)}
.scale-deck-foot{display:flex;justify-content:space-between;align-items:center;
  flex-wrap:wrap;gap:0.5rem;margin:0.3rem 0 0.5rem}
/* borderless so columns line up exactly with the cards above (no inset) */
.scale-deck .scale-vgrid{gap:0.3rem 0.4rem;
  font-family:'JetBrains Mono',monospace;font-size:0.72rem}
.scale-vgrid .vlab{grid-column:1;color:var(--muted);text-align:right;
  white-space:nowrap;align-self:center;padding-right:0.3rem}
.scale-vgrid .vcell{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  color:var(--ink);align-self:center;
  border-bottom:1px solid var(--line);padding:0.18rem 0.35rem;background:var(--bg-card)}
.scale-vgrid .vcell small{color:var(--muted)}
.scale-vgrid .vhead{color:var(--accent);font-weight:500}
@media (max-width:760px){
  .scale-deck .scale-slots,.scale-deck .scale-vgrid{grid-template-columns:2.6rem repeat(var(--scale-ndeg),minmax(0,1fr))}
  .scale-vgrid{font-size:0.66rem}
}
/* mode toggle (what keys 1–8 play) */
.scale-mode{display:flex;flex-wrap:wrap;gap:0.4rem;align-items:center}
.scale-modebtn{
  background:var(--bg);color:var(--muted);border:1px solid var(--line);
  border-radius:3px;padding:0.3rem 0.55rem;cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:0.72rem;
}
.scale-modebtn:hover{background:var(--bg-2)}
.scale-modebtn.active{color:var(--accent);border-color:var(--accent);background:var(--bg-2)}
.scale-plot-wrap{
  border:1px solid var(--line);border-radius:var(--radius);
  background:var(--bg-card);padding:0.5rem;margin-bottom:1.25rem;
}
.scale-tradscales{margin-bottom:1.25rem}
.scale-export{display:flex;gap:0.4rem;flex-wrap:wrap}
.scale-btn{
  background:var(--bg);color:var(--accent);border:1px solid var(--line);
  border-radius:3px;padding:0.35rem 0.6rem;cursor:pointer;
  font-family:'JetBrains Mono',monospace;font-size:0.75rem;
}
.scale-btn:hover{background:var(--bg-2)}
.scale-playdeg{background:none;border:1px solid var(--line);border-radius:3px;
  color:var(--accent);cursor:pointer;padding:0.1rem 0.35rem;font-size:0.7rem}
.scale-playdeg:hover{background:var(--bg-2)}
/* chord auditions get a bigger, easier-to-hit transport button */
.scale-playchord{font-size:1rem;line-height:1;padding:0.3rem 0.7rem;border-radius:4px;
  align-self:center}
/* nearest traditional scales: a 2-up grid so six matches read compactly */
#nearestScales{display:grid;grid-template-columns:repeat(2,1fr);gap:0.6rem}
@media(max-width:640px){#nearestScales{grid-template-columns:1fr}}
.scale-match{margin-bottom:0;padding:0.55rem 0.65rem;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--bg-card);position:relative;overflow:hidden}
.scale-match.best{border-color:var(--accent)}
.scale-match-bar{position:absolute;left:0;top:0;bottom:0;width:100%;
  background:rgba(128,128,128,0.06);z-index:0}
.scale-match-bar span{display:block;height:100%;background:rgba(120,200,120,0.12)}
.scale-match.best .scale-match-bar span{background:rgba(80,220,120,0.18)}
.scale-match-head,.scale-match-meta,.scale-match-note{position:relative;z-index:1}
.scale-match-head{display:flex;justify-content:space-between;align-items:baseline;gap:0.5rem}
.scale-match-meta{color:var(--muted);margin-top:0.15rem}
.scale-match-note{opacity:0.7;margin-top:0.25rem}
.scale-warn{color:var(--warn)}
/* nearest Western chord */
.scale-chord{margin-bottom:1.25rem}
#chordEst{display:grid;grid-template-columns:repeat(3,1fr);gap:0.6rem}
@media(max-width:640px){#chordEst{grid-template-columns:1fr}}
.scale-chord-item{position:relative;overflow:hidden;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--bg-card);padding:0.55rem 0.65rem}
.scale-chord-item.best{border-color:var(--accent)}
.scale-chord-bar{position:absolute;left:0;top:0;bottom:0;width:100%;
  background:rgba(128,128,128,0.06);z-index:0}
.scale-chord-bar span{display:block;height:100%;background:rgba(120,200,120,0.12)}
.scale-chord-item.best .scale-chord-bar span{background:rgba(80,220,120,0.18)}
.scale-chord-head,.scale-chord-notes{position:relative;z-index:1}
.scale-chord-head{display:flex;align-items:baseline;gap:0.4rem}
.scale-chord-head b{font-size:1.05rem;color:var(--accent)}
.scale-chord-pct{margin-left:auto;color:var(--muted)}
.scale-chord-notes{color:var(--muted);margin-top:0.25rem}
