/* ============================================================
   Epi · stylesheet
   ============================================================
   The design language: near-black lacquer panels, one gold.
   Everything warm-toned sits on four surface steps (page, card,
   panel, well) and one accent; text runs Space Grotesk with the
   Cinzel wordmark as the single serif voice.

   Fonts are bundled as woff2 and served from the resource
   provider -- a plugin window must not depend on a CDN being
   reachable from inside a DAW.
   ============================================================ */

@font-face {
  font-family: 'Cinzel';
  src: url('cinzel-var.woff2') format('woff2');
  font-weight: 400 600;
  font-display: swap;
}
@font-face {
  font-family: 'Space Grotesk';
  src: url('spacegrotesk-var.woff2') format('woff2');
  font-weight: 300 600;
  font-display: swap;
}

:root {
  --page:   #050504;
  --card-a: #100f0d;
  --card-b: #0a0a08;
  --panel:  #0e0d0a;
  --well:   #0b0b09;
  --well2:  #0a0a08;
  --line:   #221f16;
  --line2:  #262217;
  --line3:  #2a261c;
  --gold:   #caa45e;
  --gold-hi:#e6cf8e;
  --ink:    #e8e4da;
  --dim:    #8d8776;
  --faint:  #736c5a;
  --ghost:  #5d5747;
  --mute:   #4f4a3c;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  width: 100%; height: 100%;
  background: var(--page);
  overflow: hidden;
  font-family: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
}

#root  { width: 100%; height: 100%; }
#stage { position: absolute; inset: 0; }

/* The fixed design canvas, uniformly scaled to the window by index.html. */
#plugin {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 1180px;
  background: linear-gradient(180deg, var(--card-a), var(--card-b));
  border: 1px solid var(--line3);
  border-radius: 14px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(202, 164, 94, .12);
  overflow: hidden;
}

/* ---- header ---- */
.hdr {
  display: flex; align-items: center; gap: 24px;
  padding: 18px 26px 14px;
}
.hdr .brand { min-width: 200px; }
.hdr .name {
  font-family: 'Cinzel', serif;
  font-size: 30px; font-weight: 500;
  letter-spacing: .32em; line-height: 1;
  color: var(--gold);
}
.hdr .tag {
  font-size: 8.5px; letter-spacing: .3em;
  color: var(--faint); margin-top: 5px;
  text-transform: uppercase;
}
.hdr .mid { flex: 1; display: flex; justify-content: center; }

.presetbar {
  display: flex; align-items: center; gap: 2px;
  background: var(--well); border: 1px solid var(--line2);
  border-radius: 999px; padding: 4px 6px;
}
.presetbar .pbtn {
  background: none; border: none; cursor: pointer;
  color: var(--dim); font-size: 14px; padding: 4px 10px;
  font-family: inherit;
}
.presetbar .pbtn:hover { color: var(--ink); }
.presetbar .pname {
  width: 190px; text-align: center; cursor: pointer;
  font-size: 13px; letter-spacing: .08em; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.presetbar .pname:hover { color: var(--gold-hi); }
.presetbar .dirty { color: var(--gold); }
.presetbar .psave {
  background: #17150f; border: 1px solid #3a3120;
  border-radius: 999px; color: var(--gold);
  font-family: inherit; font-size: 9.5px; letter-spacing: .2em;
  padding: 6px 14px; cursor: pointer;
}
.presetbar .psave:hover { background: #211d13; }

.hdr .right {
  min-width: 200px;
  display: flex; align-items: center; justify-content: flex-end; gap: 16px;
}
.hdr .meters {
  display: flex; gap: 4px; align-items: flex-end;
  height: 56px; padding-bottom: 12px;
}
.hdr .mtrack {
  width: 5px; height: 44px; background: #15130e;
  border-radius: 3px; position: relative; overflow: hidden;
}
.hdr .mfill {
  position: absolute; left: 0; right: 0; bottom: 0; height: 0%;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold));
}

/* ---- visualizer card ---- */
.vizcard {
  position: relative; margin: 0 26px;
  border: 1px solid var(--line); border-radius: 10px;
  background: radial-gradient(120% 140% at 50% -20%, #16140f 0%, #0b0a08 60%, #080807 100%);
  overflow: hidden;
}
.vizcard canvas { display: block; cursor: pointer; touch-action: none; }
.viz-top {
  position: absolute; top: 8px; left: 14px;
  display: flex; align-items: center; gap: 12px;
}
.viz-note {
  font-size: 8.5px; letter-spacing: .24em; color: var(--ghost);
  text-transform: uppercase;
}
.viz-hint {
  position: absolute; top: 10px; right: 14px;
  font-size: 8.5px; letter-spacing: .18em; color: var(--ghost);
  text-transform: uppercase;
}

/* Segmented mode / model switch, shared by the viz toggle and panels. */
.seg {
  display: flex; gap: 2px;
  background: var(--well2); border: 1px solid var(--line);
  border-radius: 6px; padding: 2px;
}
.seg button {
  border: none; border-radius: 4px; padding: 3px 10px;
  font-family: inherit; font-weight: 500;
  font-size: 8px; letter-spacing: .16em;
  cursor: pointer; background: transparent; color: var(--dim);
  text-transform: uppercase;
}
.seg button.on { background: var(--gold); color: var(--well); }
.seg.wide { border-radius: 7px; padding: 3px; gap: 3px; }
.seg.wide button { flex: 1; padding: 5px 0; font-size: 8.5px; letter-spacing: .14em; border-radius: 5px; }

/* ---- rack ---- */
/* The card is centred on a fixed design canvas and scaled to the window,
   so its HEIGHT is load-bearing: let the rack follow its content and the
   whole instrument re-centres and re-scales every time the instrument
   changes. Measured, the five racks wanted 378, 314, 309, 314 and 307 px,
   which moved the card 35 px up the screen between the tines and the clav
   and took the header, the harp and the panels with it -- and, because the
   card is scaled to fit, resized all of it on the way. The rack is held at
   the tallest of them, the tine bench at 400 design px; the panels stretch
   into it, which is what align-items already asks for. Raise this if a
   panel ever needs a row the tine bench does not have. */
.rack {
  display: flex; gap: 12px; align-items: stretch;
  margin: 14px 26px 0;
  min-height: 400px;
}
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 13px 12px 10px;
  min-width: 0;
}
.panel.f-action { flex: 1.35; }
.panel.f-tine   { flex: 1.35; }
.panel.f-pickup { flex: 1.15; }
.panel.f-amp    { flex: 1.35; }
.panel.f-fx     { flex: 1.0; }

/* Panel header: title, a rule that takes up the slack, a workshop button and
   a readout. The narrowest panel gives it 176 px, and the title, button and
   readout together used to need 173 of that BEFORE the three 10 px gaps -- so
   the rule collapsed to nothing and the readout was still clipped off the
   edge ("-0.70 mm" lost its unit). Measured across all five instruments, the
   spacing and tracking below leave 11 px spare in the tightest header instead
   of overflowing the widest by 26. The readout sits at 8 px, which is the
   same tier as the workshop button and the control labels. */
.phead {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 10px;
}
.phead h2 {
  margin: 0; font-size: 10px; font-weight: 500;
  letter-spacing: .16em; color: var(--gold);
  text-transform: uppercase;
}
.phead .hrule { flex: 1 1 0; min-width: 0; height: 1px; background: var(--line); }
.phead .hmeta {
  font-size: 8px; color: var(--faint); letter-spacing: .04em;
  white-space: nowrap; font-variant-numeric: tabular-nums;
}

.krow {
  display: flex; flex-wrap: wrap;
  gap: 2px 4px; justify-content: center;
}

/* ---- knob ---- */
.knob {
  width: 62px;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  cursor: ns-resize; touch-action: none;
}
.knob .klabel {
  font-size: 8.5px; letter-spacing: .13em; color: var(--dim);
  white-space: nowrap; text-transform: uppercase;
}
.knob .kval {
  font-size: 9.5px; color: var(--gold);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.knob .dial.dragging + .klabel { color: var(--ink); }

.k-body   { fill: var(--well); stroke: #2c2920; stroke-width: 1; }
.k-track  { stroke: #1e1c15; }
.k-arc    { stroke: var(--gold); }
.k-point  { stroke: #ece5d3; }

/* ---- faders (levels-style) ---- */
.fader {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  cursor: ns-resize; touch-action: none;
}
.fader .ftrack {
  width: 7px; height: 78px; background: #17150f;
  border-radius: 4px; position: relative; overflow: hidden;
}
.fader .ffill {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold));
}
.fader .flabel { font-size: 8.5px; letter-spacing: .13em; color: var(--dim); text-transform: uppercase; }
.fader .fval   { font-size: 9.5px; color: var(--gold); font-variant-numeric: tabular-nums; }

/* ---- live bars (vibrato L/R) ---- */
.hbar { width: 100%; padding: 2px 6px; }
.hbrow { display: flex; justify-content: space-between; }
.hblabel { font-size: 8px; letter-spacing: .14em; color: var(--dim); text-transform: uppercase; }
.hbval   { font-size: 8.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
.hbtrack {
  height: 3px; margin-top: 3px; background: #17150f;
  border-radius: 2px; overflow: hidden;
}
.hbfill { height: 100%; width: 0%; background: linear-gradient(90deg, var(--gold), var(--gold-hi)); }
.bars { display: flex; gap: 8px; margin-top: 6px; }

/* ---- cycling selector ---- */
.cyc { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.cyclabel { font-size: 8px; letter-spacing: .16em; color: var(--dim); text-transform: uppercase; }
.cycbody {
  display: flex; align-items: center; gap: 2px;
  background: var(--well2); border: 1px solid var(--line); border-radius: 6px;
  padding: 2px 4px;
}
.cycarrow {
  background: none; border: none; color: var(--dim);
  font-size: 12px; cursor: pointer; padding: 1px 6px; font-family: inherit;
}
.cycarrow:hover { color: var(--gold); }
.cycval {
  min-width: 64px; text-align: center;
  font-size: 9px; letter-spacing: .12em; color: var(--gold);
  text-transform: uppercase;
}

.prow { display: flex; justify-content: center; margin-bottom: 8px; }

.note {
  margin-top: 8px; text-align: center;
  font-size: 8px; letter-spacing: .14em; color: var(--mute);
  text-transform: uppercase;
}

/* ---- footer ---- */
.footer {
  display: flex; justify-content: space-between;
  padding: 10px 28px 12px;
  font-size: 8.5px; letter-spacing: .18em; color: var(--mute);
  text-transform: uppercase;
}

/* ---- preset browser modal ---- */
.modal-back {
  position: absolute; inset: 0; z-index: 50;
  background: rgba(3, 3, 2, .72);
  display: flex; align-items: center; justify-content: center;
}
.modal {
  width: 460px; max-height: 520px;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, #12100c, var(--card-b));
  border: 1px solid var(--line3); border-radius: 12px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .8);
  overflow: hidden;
}
.mhead {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px 10px; border-bottom: 1px solid var(--line);
}
.mhead h3 {
  margin: 0; font-size: 11px; font-weight: 500;
  letter-spacing: .26em; color: var(--gold); text-transform: uppercase;
}
.mhead button {
  background: none; border: none; color: var(--dim);
  font-size: 13px; cursor: pointer; font-family: inherit;
}
.mhead button:hover { color: var(--ink); }
.mlist { flex: 1; overflow-y: auto; padding: 6px 8px; }
.msec {
  font-size: 8px; letter-spacing: .22em; color: var(--ghost);
  padding: 8px 10px 4px; text-transform: uppercase;
}
.mrow {
  display: flex; align-items: center; justify-content: space-between;
  padding: 7px 10px; border-radius: 7px; cursor: pointer;
  font-size: 12px; letter-spacing: .06em;
}
.mrow:hover { background: #16140e; }
.mrow.cur { background: #1b1810; color: var(--gold-hi); }
.mrow .cat { font-size: 8px; letter-spacing: .18em; color: var(--ghost); display: flex; gap: 6px; align-items: center; }
.mdel { background: none; border: none; color: var(--ghost); cursor: pointer; font-size: 10px; font-family: inherit; }
.mdel:hover { color: #d88; }
.msave {
  display: flex; gap: 8px; padding: 12px 14px;
  border-top: 1px solid var(--line);
}
.msave input {
  flex: 1; background: var(--well); border: 1px solid var(--line2);
  border-radius: 7px; color: var(--ink); padding: 8px 12px;
  font-family: inherit; font-size: 12px; outline: none;
}
.msave input:focus { border-color: #3a3120; }
.msave button {
  background: #17150f; border: 1px solid #3a3120; border-radius: 7px;
  color: var(--gold); font-family: inherit; font-size: 9.5px;
  letter-spacing: .2em; padding: 8px 16px; cursor: pointer;
}
.msave button:hover { background: #211d13; }

/* ---- scrollbars in the modal ---- */
.mlist::-webkit-scrollbar { width: 8px; }
.mlist::-webkit-scrollbar-thumb { background: #26221a; border-radius: 4px; }
.mlist::-webkit-scrollbar-track { background: transparent; }

/* ---- tine workshop ---- */
.wsmodal { width: 1010px; max-height: none; }
.wsactions { display: flex; align-items: center; gap: 10px; }
.wsreset {
  background: #17150f; border: 1px solid #3a3120; border-radius: 999px;
  color: var(--gold); font-family: inherit; font-size: 8.5px;
  letter-spacing: .18em; padding: 5px 12px; cursor: pointer;
}
.wsreset:hover { background: #211d13; }
.wsbody { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 12px; }
.wslane canvas { display: block; cursor: crosshair; touch-action: none;
  border: 1px solid var(--line); border-radius: 8px; background: var(--well2); }
.wshead { display: flex; align-items: baseline; gap: 10px; margin-bottom: 5px; }
.wstitle { font-size: 9.5px; letter-spacing: .24em; color: var(--gold); }
.wsmeta  { font-size: 8.5px; letter-spacing: .1em; color: var(--faint); flex: 1; }
.wsread  { font-size: 9px; color: var(--dim); font-variant-numeric: tabular-nums; min-width: 110px; text-align: right; }
.wsnote  { text-align: center; font-size: 8px; letter-spacing: .14em; color: var(--mute); }
.wsopen {
  background: none; border: 1px solid #3a3120; border-radius: 999px;
  color: var(--gold); font-family: inherit; font-size: 8px;
  letter-spacing: .08em; padding: 3px 7px; cursor: pointer;
  flex: 0 0 auto; white-space: nowrap;
}
.wsopen:hover { background: #17150f; }

.wstools { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.wstoollabel { font-size: 8px; letter-spacing: .2em; color: var(--ghost); margin-right: 2px; }
.wsrootlbl { margin-left: 8px; }
.wschip {
  background: var(--well2); border: 1px solid var(--line); border-radius: 5px;
  color: var(--dim); font-family: inherit; font-size: 8px; letter-spacing: .12em;
  padding: 4px 8px; cursor: pointer;
}
.wschip:hover { color: var(--gold); border-color: #3a3120; }

/* ---- sustain pedal lamp ---- */
.pedal-lamp {
  position: absolute; bottom: 62px; right: 14px;
  display: flex; align-items: center; gap: 5px;
  font-size: 8px; letter-spacing: .18em; color: var(--ghost);
  pointer-events: none;
}
.pedal-lamp .led {
  width: 6px; height: 6px; border-radius: 50%;
  background: #241f14; border: 1px solid #322a19;
}
.pedal-lamp.on { color: var(--gold); }
.pedal-lamp.on .led {
  background: var(--gold);
  box-shadow: 0 0 6px rgba(202, 164, 94, .8);
}

/* ---- cabinet workshop ---- */
.wscabknobs {
  display: flex; justify-content: center; gap: 26px;
  padding: 10px 0 4px;
}

/* Material row: the selector sits under the resonator knobs; the warning
   states the transducer fact in the panel's own voice, slightly lifted. */
.matrow { margin-top: 2px; }
.matrow .note.warn { color: #b08d4a; }

/* Clavinet rockers: four latching switches in a row. */
.wsrockers { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; }
.wsrocker { padding: 6px 10px; font-size: 9px; letter-spacing: .12em;
  background: #17140f; color: var(--mute); border: 1px solid #2c271d;
  border-radius: 4px; cursor: pointer; }
.wsrocker.on { color: #caa45e; border-color: #caa45e; background: #221c11; }

/* Body bench row: material cycler beside a small size knob.
   Wraps, because two cyclers do not fit side by side in a panel and must not
   try. The panel's inner width is 190 px; a cycler is 104 px, so a pair needs
   217. Squeezing them in would cap the value box at about 58 px and the
   longest option -- KEY BED's "FRESH FELT" -- renders at 59.5, so it would be
   clipped on the one setting somebody most needs to read. Wrapping costs a
   line of height, which the panel has, and stays correct if an option is ever
   renamed to something longer. */
.bodyrow { display: flex; align-items: center; justify-content: center;
           gap: 8px; flex-wrap: wrap; }
.bodyrow .knob { width: 46px; }
.bodyrow .kval { display: none; }
.bodysize .knob { width: 52px; }

/* Velocity curve editor. */
.wsvcanvas { display: block; margin: 10px auto; background: #14110c; border: 1px solid #2c271d; border-radius: 6px; touch-action: none; cursor: crosshair; }
.wsvmode { font-size: 8px; letter-spacing: .12em; color: var(--mute); margin-left: 10px; }
.wschip.on { color: #caa45e; border-color: #caa45e; }

/* The mic stage: a top-down field below the instrument outline. */
.wstage { display: block; background: #141210; border: 1px solid #2a2419;
          border-radius: 6px; margin: 8px 0; user-select: none; }
.wstagetxt { font-size: 8px; letter-spacing: 0.12em;
             fill: rgba(255,255,255,0.3); }
.wstagemic { font-size: 8px; font-weight: 700; fill: #14100a;
             pointer-events: none; }
