/* ============================================================================
   Schematics n' Scores — Generator console.
   The single control-panel language shared by the 2D (scores.html) and 3D
   (index.html) views, so the instrument feels like one machine across both.
   View-specific chrome (2D plate/table, 3D viewfinder/mobile) stays in-page.
   ========================================================================== */
@font-face{ font-family:"Space Grotesk"; src:url("/fonts/SpaceGrotesk-700.woff2") format("woff2"); font-weight:700; font-display:swap }
@font-face{ font-family:"Space Grotesk"; src:url("/fonts/SpaceGrotesk-500.woff2") format("woff2"); font-weight:500; font-display:swap }
@font-face{ font-family:"Space Grotesk"; src:url("/fonts/SpaceGrotesk-400.woff2") format("woff2"); font-weight:400; font-display:swap }
@font-face{ font-family:"Routed Gothic"; src:url("/fonts/routed-gothic.ttf") format("truetype"); font-display:swap }

:root{
  --paper:#f3f3f0; --table:#e7e6e1; --ink:#111110; --mute:#8f8f89; --line:#dedcd5;
  /* One static, minimal accent: a soft offset-black used for every active /
     hover / selected state. No palette-driven tint. */
  --accent:#1c1b18; --hot:#e5442d; --mark:#c7c5bc;
  --g:"Space Grotesk","Helvetica Neue",Arial,sans-serif; --mono:"Routed Gothic",ui-monospace,monospace;
  --rack-h:150px;
}
*{ box-sizing:border-box }
html,body{ margin:0; padding:0; height:100%; color:var(--ink); font:14px/1.5 var(--g); -webkit-font-smoothing:antialiased; overscroll-behavior:none }
::selection{ background:var(--accent); color:#fff }
.mono{ font-family:var(--mono) }

/* ---- top bar ---- */
.topbar{ position:fixed; top:0; left:0; right:0; height:52px; z-index:16; display:flex; align-items:center; gap:20px;
  padding:0 clamp(14px,3vw,32px); background:var(--paper); border-bottom:1px solid var(--line) }
.topbar .brand{ font-weight:700; font-size:13px; letter-spacing:.01em; text-transform:uppercase; color:var(--ink); text-decoration:none }
/* nav links match the homepage: hairline underline draws in on hover / current */
.topbar a.lnk{ position:relative; font-weight:500; font-size:13px; letter-spacing:.01em; text-transform:uppercase; color:var(--ink); text-decoration:none; padding-bottom:2px }
.topbar a.lnk::after{ content:""; position:absolute; left:0; bottom:-1px; width:100%; height:1px; background:var(--accent); transform:scaleX(0); transform-origin:left; transition:transform .28s cubic-bezier(.4,.8,.3,1) }
.topbar a.lnk:hover{ color:var(--accent) } .topbar a.lnk:hover::after{ transform:scaleX(1) }
.topbar a.lnk.here{ color:var(--accent) } .topbar a.lnk.here::after{ transform:scaleX(1) }
.topbar .tabs{ display:inline-flex; border:1px solid var(--line) }
.topbar .tabs a, .topbar .tabs span{ font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  padding:6px 12px; color:#333; text-decoration:none; border-left:1px solid var(--line); cursor:pointer }
.topbar .tabs :first-child{ border-left:0 }
.topbar .tabs .on{ background:var(--accent); color:#fff }
.topbar .sp{ flex:1 }

/* ---- the console (kept as #settings-panel for the engine) ---- */
#settings-panel{ position:fixed; left:0; right:0; bottom:0; z-index:15; background:var(--paper);
  border-top:1px solid var(--line); box-shadow:0 -14px 34px rgba(17,17,16,.08); transition:transform .24s ease }
#settings-panel.collapsed{ transform:translateY(100%) }
#settings-panel > header{ display:none }

/* primary rack */
.rack{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; padding:12px clamp(14px,3vw,32px) }
.grp{ display:flex; align-items:center; gap:8px }
.grp .lbl{ font-family:var(--mono); font-size:9px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute) }
.rack .sp{ flex:1 }
/* export group hugs the right edge — auto-margin keeps it right even when the
   rack wraps (a plain spacer would strand it at the left of the new line) */
.rack .export{ margin-left:auto }
.rack .div, .channels .div{ width:1px; align-self:stretch; background:var(--line); margin:2px }

.transport{ gap:5px }
#play-btn, #stop-btn{ font-family:var(--mono); font-size:12px; width:38px; height:34px; cursor:pointer;
  display:flex; align-items:center; justify-content:center; line-height:1;
  background:var(--ink); color:#fff; border:1px solid var(--ink); transition:background .18s,border-color .18s }
#stop-btn{ background:#fff; color:var(--ink) }
#play-btn:hover, #play-btn.playing{ background:var(--accent); border-color:var(--accent) }
#stop-btn:hover{ border-color:var(--ink) }

.seed .seed-value{ font-family:var(--mono); font-size:13px; letter-spacing:.1em; color:var(--ink); min-width:64px }
.seed-btn{ font-family:var(--mono); font-size:12px; width:32px; height:30px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; line-height:1;
  background:#fff; border:1px solid var(--line); color:var(--ink); transition:border-color .18s,color .18s }
.seed-btn:hover{ border-color:var(--accent); color:var(--accent) }
#btn-randomize-all{ font-family:var(--mono); font-size:10.5px; letter-spacing:.12em; text-transform:uppercase; cursor:pointer;
  display:inline-flex; align-items:center; gap:7px; line-height:1;
  background:var(--accent); color:#fff; border:1px solid var(--accent); padding:9px 14px; transition:filter .18s }
#btn-randomize-all:hover{ filter:brightness(1.08) }
#btn-randomize-all .dice{ font-size:13px; line-height:1; display:inline-flex; align-items:center }

.fader{ gap:9px }
.fader input[type=range]{ width:clamp(80px,10vw,150px) }
.value{ font-family:var(--mono); font-size:11px; color:var(--ink); min-width:34px; text-align:right; font-variant-numeric:tabular-nums }

input[type="range"]{ -webkit-appearance:none; appearance:none; height:16px; background:transparent; cursor:pointer }
input[type="range"]::-webkit-slider-runnable-track{ height:2px; background:var(--line) }
input[type="range"]::-moz-range-track{ height:2px; background:var(--line) }
input[type="range"]::-webkit-slider-thumb{ -webkit-appearance:none; appearance:none; height:14px; width:8px; background:var(--accent); border:0; margin-top:-6px; cursor:pointer }
input[type="range"]::-moz-range-thumb{ height:14px; width:8px; background:var(--accent); border:0; border-radius:0; cursor:pointer }

select{ background:#fff; border:1px solid var(--line); color:var(--ink); font:inherit; font-size:12px; padding:6px 8px; outline:none; cursor:pointer; border-radius:0 }
select:focus{ border-color:var(--accent) }

/* ---- themed dropdown (customSelect.js) — replaces the native <select> popup ---- */
.cselect{ position:relative; display:inline-flex }
.cs-native{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); border:0 }
.cs-trigger{ display:inline-flex; align-items:center; gap:10px; font:inherit; font-size:12px; line-height:1;
  background:#fff; border:1px solid var(--line); color:var(--ink); padding:7px 10px; cursor:pointer; min-width:96px; text-align:left; width:100% }
.cs-trigger:hover{ border-color:var(--ink) }
.cselect.open .cs-trigger{ border-color:var(--accent) }
.cs-label{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.cs-caret{ font-family:var(--mono); font-size:10px; color:var(--mute); margin-left:auto; transition:transform .2s }
.cselect.open .cs-caret{ transform:rotate(180deg); color:var(--accent) }
.cs-panel{ position:fixed; z-index:60; background:var(--paper); border:1px solid var(--line);
  box-shadow:0 -14px 34px rgba(17,17,16,.16); max-height:0; overflow:hidden; opacity:0; pointer-events:none; transition:opacity .15s }
.cselect.open .cs-panel{ max-height:min(300px,56vh); overflow-y:auto; opacity:1; pointer-events:auto }
.cs-opt{ display:block; width:100%; text-align:left; font:inherit; font-size:12px; background:none; border:0;
  color:#333; padding:8px 12px; cursor:pointer; white-space:nowrap }
.cs-opt:hover{ background:var(--line); color:var(--ink) }
.cs-opt.sel{ color:var(--accent) }
.cs-opt.sel::before{ content:"› "; color:var(--accent) }
input[type="text"]{ background:#fff; border:1px solid var(--line); color:var(--ink); padding:6px 8px; font:inherit; font-size:12px; outline:none; width:90px }
input[type="text"]:focus{ border-color:var(--accent) }

.btn{ font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase; cursor:pointer;
  background:#fff; border:1px solid var(--line); color:var(--ink); padding:8px 11px; transition:border-color .18s,color .18s }
.btn:hover{ border-color:var(--accent); color:var(--accent) }
#adv-toggle{ font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase; cursor:pointer;
  background:#fff; border:1px solid var(--line); color:var(--ink); padding:8px 12px; display:inline-flex; align-items:center; gap:7px; transition:background .18s,border-color .18s,color .18s }
#adv-toggle:hover, #adv-toggle.on{ background:var(--accent); border-color:var(--accent); color:#fff }
#adv-toggle .car{ transition:transform .22s } #adv-toggle.on .car{ transform:rotate(180deg) }

/* the long readout ("MASTER … / SEED …") lives on its own hairline row at the
   very bottom of the console, spanning the full width */
.masterline{ display:flex; gap:8px 18px; align-items:baseline; justify-content:space-between; flex-wrap:wrap;
  padding:7px clamp(14px,3vw,32px); border-top:1px solid var(--line);
  font-family:var(--mono); font-size:9.5px; letter-spacing:.05em; color:var(--mute) }
.masterline #seed-display{ color:var(--ink) }
.masterline #weights{ color:var(--mute) }
.masterline .mleft{ display:flex; align-items:center; gap:10px }
.masterline .seed-btn{ width:auto; height:auto; padding:2px 8px; font-size:12px }

/* channel strip (vocabularies) */
.channels{ display:flex; align-items:center; gap:9px; padding:0 clamp(14px,3vw,32px) 12px; flex-wrap:wrap }
.channels > .lbl{ font-family:var(--mono); font-size:9px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute) }
.vocab-toggles{ display:flex; flex-wrap:wrap; gap:4px }
.vocab-toggle{ position:relative; overflow:hidden; cursor:pointer; padding:6px 11px; border:1px solid var(--line); background:#fff; color:#555;
  font:inherit; font-size:11px; user-select:none; transition:border-color .15s,color .15s,background .15s }
.vocab-toggle:hover{ border-color:var(--ink); color:var(--ink) }
.vocab-toggle.active{ background:var(--accent); border-color:var(--accent); color:#fff }
.vocab-toggle .num{ font-family:var(--mono); font-size:9px; opacity:.6; margin-right:5px }
.vocab-toggle.active .num{ opacity:.85 }
/* hover-preview loading bar (JS injects the span; its transition-duration is set
   from JS to match the delay). mix-blend-mode keeps it visible on any button. */
.vocab-toggle .vload{ position:absolute; left:0; bottom:0; height:2px; width:100%; background:#fff;
  mix-blend-mode:difference; transform:scaleX(0); transform-origin:left; pointer-events:none; transition:transform 1.1s linear }
.vocab-toggle.vloading .vload{ transform:scaleX(1) }

/* the preview popup itself */
#vocab-preview[hidden]{ display:none }
#vocab-preview{ position:fixed; z-index:120; background:var(--paper); border:1px solid var(--line);
  box-shadow:0 18px 44px rgba(17,17,16,.24); padding:8px; pointer-events:none; animation:vp-in .14s ease }
@keyframes vp-in{ from{ opacity:0; transform:translateY(4px) } to{ opacity:1; transform:none } }
#vocab-preview .vp-canvas{ line-height:0; border:1px solid var(--line) }
/* override the 3D page's global `canvas{position:fixed;inset:0}` (the WebGL
   canvas) so the preview's p5 canvas sits inside the popup, not top-left. */
#vocab-preview .vp-canvas canvas{ display:block; position:static; inset:auto; z-index:auto; width:300px; height:184px }
#vocab-preview .vp-label{ font-family:var(--mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink); margin-top:7px; text-align:center }
.channels .anim{ margin-left:auto }

.check-row{ display:inline-flex; align-items:center; gap:8px; font-size:12px; color:#333; cursor:pointer }
.check-row input[type="checkbox"]{ appearance:none; -webkit-appearance:none; width:14px; height:14px; border:1px solid var(--line); background:#fff; cursor:pointer; position:relative; flex:0 0 auto }
.check-row input[type="checkbox"]:checked{ border-color:var(--accent); background:var(--accent) }
.check-row input[type="checkbox"]:checked::after{ content:"✓"; position:absolute; inset:0; display:grid; place-items:center; font-size:9px; color:#fff }
/* Tone unavailable for this palette: dashed box with a diagonal strike, so it
   reads as "not possible" at a glance. An available palette keeps the normal,
   clickable box. */
.check-row.disabled{ opacity:.6; cursor:not-allowed }
.check-row.disabled input[type="checkbox"]{ pointer-events:none; border-style:dashed; background:#f2f1ee }
.check-row.disabled input[type="checkbox"]::after{ content:""; position:absolute; inset:-1px;
  background:linear-gradient(45deg, transparent 44%, #9a9a94 44%, #9a9a94 56%, transparent 56%) }

/* advanced tray — drops UP from the rack, full width, ledger columns */
#advanced{ position:absolute; left:0; right:0; bottom:100%; background:var(--paper); border-top:1px solid var(--line);
  box-shadow:0 -18px 40px rgba(17,17,16,.10); max-height:0; overflow:hidden; transition:max-height .28s ease }
#advanced.open{ max-height:64vh; overflow-y:auto }
#advanced .apad{ display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:22px 30px; padding:20px clamp(14px,3vw,32px) 24px }
.acol > .alabel, .acol > .section-label, label.section-label{ display:block; font-family:var(--mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute); padding-bottom:10px; margin-bottom:12px; border-bottom:1px solid var(--line) }
.arow{ display:grid; grid-template-columns:88px 1fr auto; align-items:center; gap:8px; margin-bottom:9px; font-size:12px }
.arow .name{ font-family:var(--mono); font-size:9px; letter-spacing:.1em; text-transform:uppercase; color:var(--mute) }
.arow.full{ grid-template-columns:1fr }
.acol .check-row{ margin-bottom:8px }
.acol .btn{ width:100% }
.keys{ display:grid; grid-template-columns:auto 1fr; gap:4px 10px; font-size:11px; color:#444 }
.keys .k{ font-family:var(--mono); font-size:9px; letter-spacing:.06em; text-transform:uppercase; color:var(--mute) }

/* hide / show the console */
#settings-close{ position:absolute; top:10px; right:12px; z-index:2; background:none; border:0; color:var(--mute); font-size:13px; cursor:pointer; line-height:1 }
#settings-close:hover{ color:var(--accent) }
#settings-toggle{ position:fixed; bottom:14px; right:14px; z-index:14; width:36px; height:36px; cursor:pointer;
  background:var(--ink); color:#fff; border:1px solid var(--ink); font-size:15px; display:none }
#settings-panel.collapsed ~ #settings-toggle{ display:block }

/* toast */
#toast{ position:fixed; bottom:calc(var(--rack-h) + 20px); left:50%; transform:translateX(-50%); padding:8px 14px;
  background:var(--ink); color:#fff; border:1px solid var(--ink); font-family:var(--mono); font-size:11px; letter-spacing:.04em;
  opacity:0; pointer-events:none; transition:opacity .22s; max-width:80vw; text-align:center; z-index:20 }
#toast.show{ opacity:1 }

/* --- Export modal ------------------------------------------------------ */
/* A single Export button in the footer opens this centered panel. All export
   controls live here, so the advanced tray stays purely generative settings. */
.export-modal[hidden]{ display:none }
.export-modal{ position:fixed; inset:0; z-index:200; display:flex; align-items:center; justify-content:center }
.export-backdrop{ position:absolute; inset:0; background:rgba(17,17,16,.42) }
.export-dialog{ position:relative; z-index:1; width:min(440px,92vw); max-height:86vh; overflow-y:auto;
  background:var(--paper); border:1px solid var(--line); box-shadow:0 30px 80px rgba(17,17,16,.30);
  animation:export-in .16s ease }
@keyframes export-in{ from{ opacity:0; transform:translateY(6px) } to{ opacity:1; transform:none } }
.export-dialog > header{ display:flex; align-items:center; justify-content:space-between;
  padding:14px 18px; border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--paper) }
.export-dialog > header h3{ margin:0; font-family:var(--mono); font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink) }
#export-close{ background:none; border:0; color:var(--mute); cursor:pointer; font-size:15px; line-height:1; padding:2px }
#export-close:hover{ color:var(--accent) }
.export-body{ padding:16px 18px 20px }
.export-body section{ margin-bottom:18px }
.export-body section:last-child{ margin-bottom:0 }
.export-label{ display:block; font-family:var(--mono); font-size:9px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute); margin-bottom:8px }
.export-row{ display:flex; gap:8px; flex-wrap:wrap; align-items:center }
.export-row + .export-row{ margin-top:8px }
.export-row .btn{ flex:1 1 auto; min-width:96px }
.export-row .name{ font-family:var(--mono); font-size:9px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute); min-width:74px }
.export-row .cselect, .export-row select{ flex:1 1 auto }
.export-row .value{ font-family:var(--mono); font-size:11px; color:var(--ink) }
.export-hint{ margin:8px 0 0; font-size:11px; line-height:1.4; color:var(--mute) }

/* top row: image export on the left, small save/load params tucked on the right */
.export-cols{ display:flex; gap:18px; align-items:flex-start; margin-bottom:18px }
.export-cols .export-main{ flex:1 1 auto; margin:0 }
.export-cols .export-side{ flex:0 0 auto; margin:0 }
.export-side .export-side-row{ display:flex; flex-direction:column; gap:6px }
.btn.btn-sm{ font-size:9px; padding:6px 12px; min-width:66px }

/* community-journal hero: the special, colored share action */
.export-journal{ margin-top:2px; padding:15px 16px 16px; border:1px solid rgba(43,59,214,.32);
  background:rgba(43,59,214,.06) }
.export-journal .ej-title{ font-family:var(--mono); font-size:9.5px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--accent); margin-bottom:6px }
.export-journal .ej-sub{ font-size:11.5px; line-height:1.45; color:#4a4a45; margin:0 0 13px }
.btn-share{ width:100%; display:flex; align-items:center; justify-content:center; cursor:pointer;
  font-family:var(--mono); font-size:11px; letter-spacing:.13em; text-transform:uppercase;
  padding:13px 14px; background:var(--accent); border:1px solid var(--accent); color:#fff;
  transition:filter .18s, box-shadow .18s }
.btn-share:hover{ filter:brightness(1.4); box-shadow:0 4px 14px rgba(17,17,16,.22) }
/* the custom-select panel must clear the modal's stacking context */
.export-dialog .cs-panel{ z-index:210 }

/* video export confirm modal — settings review + render warnings */
#video-confirm-modal{ z-index:220 }
.vc-meta{ margin:0 0 15px }
.vc-meta > div{ display:flex; justify-content:space-between; align-items:baseline;
  padding:8px 0; border-bottom:1px solid var(--line) }
.vc-meta > div:first-child{ border-top:1px solid var(--line) }
.vc-meta dt{ font-family:var(--mono); font-size:9px; letter-spacing:.16em; text-transform:uppercase; color:var(--mute) }
.vc-meta dd{ margin:0; font-family:var(--mono); font-size:11px; color:var(--ink) }
.vc-warn{ border:1px solid var(--line); background:var(--table); padding:11px 13px; margin-bottom:14px }
.vc-warn p{ margin:0 0 7px; font-family:var(--mono); font-size:9px; letter-spacing:.14em; text-transform:uppercase; color:var(--mute) }
.vc-warn ul{ margin:0; padding-left:16px }
.vc-warn li{ font-size:11.5px; line-height:1.5; color:var(--ink) }
.vc-warn li + li{ margin-top:4px }
.vc-actions{ display:flex; gap:8px; margin-top:16px }
.vc-actions .btn{ flex:1 1 auto }
.vc-primary{ border-color:var(--accent); color:#fff; background:var(--accent) }
.vc-primary:hover{ filter:brightness(1.35); color:#fff }

@media(max-width:720px){ .readout{ display:none } }

/* mobile floating action bar — shared by both generator views; shown on phones
   via the media query below (each view wires ROLL / PLAY / EDIT / SHARE). */
#mobile-save-bar{ position:fixed; right:14px; bottom:14px; z-index:14; display:none; flex-direction:column; gap:8px }
#mobile-save-bar button{ display:flex; align-items:center; justify-content:center; gap:6px; min-width:64px; padding:10px 12px;
  background:rgba(10,10,10,.78); border:1px solid rgba(239,233,216,.22); color:#efe9d8; font:inherit; font-size:11px;
  letter-spacing:.12em; text-transform:uppercase; cursor:pointer; backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  transition:background .14s ease, border-color .14s ease }
#mobile-save-bar button:active{ background:rgba(43,59,214,.72); border-color:#2b3bd6 }
#mobile-save-bar button .ico{ font-size:13px; opacity:.85 }
#mobile-save-bar button .lbl{ font-weight:500 }
#mobile-save-bar button.dice{ background:rgba(43,59,214,.78); border-color:rgba(43,59,214,.95); color:#fafaf6 }
#mobile-save-bar button.dice .ico{ font-size:16px; opacity:1 }
#mobile-save-bar button.dice:active{ background:#2b3bd6 }

/* ---- mobile (phones) ---- */
@media (max-width: 768px){
  #mobile-save-bar{ display:flex }
  /* show the panel header + ✕ on mobile (hidden on desktop) so the drawer is
     clearly closeable — the ≡ toggle is covered when the drawer is open */
  #settings-panel > header{ display:flex !important; align-items:center; justify-content:space-between; padding:16px 18px 12px }
  /* the Share modal is journal-only on mobile — image/video/params exports are
     desktop features; keep just the "Share with the journal" section */
  #export-modal .export-body > *:not(.export-journal){ display:none }
  /* bigger touch targets for the range sliders */
  input[type="range"]{ height:24px }
  input[type="range"]::-webkit-slider-thumb{ height:22px; width:16px; margin-top:-10px }
  input[type="range"]::-moz-range-thumb{ height:22px; width:16px }
  /* top bar: drop the secondary nav links (brand still returns home) so the
     2D/3D toggle has room and is an easy tap; enlarge the tabs */
  .topbar{ gap:12px; padding:0 14px; justify-content:space-between }
  .topbar a.lnk{ display:none }
  .topbar .brand{ font-size:12px; white-space:nowrap }
  .topbar .tabs a, .topbar .tabs span{ padding:10px 18px; font-size:12px }
  /* the ≡ toggle is replaced by the EDIT button in the mobile bar */
  #settings-toggle{ display:none !important }
}
