body {
  margin: 0;
  background: #fff;
  color: #111;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, "Courier New", monospace;
  font-size: 1rem;
  line-height: 1.6;
}

main {
  padding: 2rem;
  overflow-x: auto;
}

p {
  margin: 0 0 1rem;
}

a {
  color: inherit;
}

/* shared boxes */

.box {
  border: 1px solid #111;
  padding: 1rem 1.5rem;
  width: fit-content;
}

.section-label {
  font-size: 0.75rem;
  font-weight: normal;
  text-transform: lowercase;
  letter-spacing: 0.15em;
  margin: 0 0 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #111;
}

.panel-header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.program-interface {
  display: flex;
  gap: 0.5rem;
}

.program-display {
  border: 1px solid #111;
  width: 6rem;
  height: 1.4rem;
  font-size: 0.65rem;
  display: flex;
  align-items: center;
  padding: 0 0.3rem;
}

/* page layout */

#control-panel {
  display: flex;
  align-items: stretch;
  padding: 0;
}

.panel-main {
  flex: 1 1 auto;
  min-width: 0;
  padding: 1rem 1.5rem;
  display: flex;
  flex-direction: column;
}

.page {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2rem;
}

.intro p {
  margin: 0 0 0.25rem;
}

.intro .back {
  margin-top: 0.75rem;
}

.easel {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* control panel: a single 24-column grid shared by the module row, the
   slider strip, and the jack strip, so sliders read as one evenly-spaced
   bank and modules/jacks align to the slider columns beneath them.
   columns 1-5 = sequential voltage sliders, column 6 = mod-random (no
   slider), columns 7-23 = the remaining 17 sliders, column 24 = the
   mix/reverb/master sub-panel. */

#control-panel {
  width: auto;
}

.rack {
  display: grid;
  grid-template-columns: repeat(22, 1fr);
  grid-template-rows: auto auto auto;
  column-gap: 0.7rem;
  row-gap: 0.75rem;
  align-items: start;
}

.modules {
  grid-column: 1 / -1;
  grid-row: 1;
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: repeat(3, auto);
  row-gap: 0.75rem;
  align-items: stretch;
}

.module {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  row-gap: 0.75rem;
  justify-items: center;
  align-items: start;
  width: 100%;
  border: 1px solid #111;
  box-sizing: border-box;
  padding: 0.25rem;
}

.module > h4 {
  grid-row: 1;
  width: 100%;
}

.module h4 {
  font-size: 0.62rem;
  font-weight: normal;
  text-transform: lowercase;
  letter-spacing: 0.06em;
  margin: 0;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid #111;
  text-align: center;
  white-space: normal;
  line-height: 1.3;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
}

/* per-section CV indicator meter (grayscale: white = 0, black = max) */
.cv-meter {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  border: 1px solid #111;
  background: #fff;
  flex: none;
}

.m-controls {
  grid-row: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}

.module > .wave-select {
  grid-row: 3;
  align-self: start;
}

#seq-random   { grid-column:  1 /  6; grid-row: 1 / 4; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; column-gap: 0.7rem; }
#mod-seq      { grid-column: 1 / 4; grid-row: 1 / 4; min-width: 0; }
#mod-random   { grid-column: 4 / 6; grid-row: 1 / 4; min-width: 0; }
#mod-eg       { grid-column:  6 /  9; grid-row: 1 / 4; }
#mod-pulser   { grid-column:  9 / 12; grid-row: 1 / 4; width: auto; margin: 0 0.65rem; }   /* ~half-col narrower, centered */
#mod-modosc   { grid-column: 12 / 16; grid-row: 1 / 4; }
#mod-compOsc  { grid-column: 16 / 20; grid-row: 1 / 4; width: auto; margin-right: 1.3rem; }   /* yield ~half-col to dlpg */
#mod-dlpg     { grid-column: 20 / 23; grid-row: 1 / 4; width: auto; margin-left: -1.3rem; }   /* left bound ~half-col back left (un-crop) */

.control-strip {
  grid-column: 1 / -1;
  grid-row: 2;
  display: grid;
  grid-template-columns: subgrid;
  align-items: end;
  justify-items: center;
}

.strip-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}

.strip-label {
  font-size: 0.55rem;
  letter-spacing: 0.05em;
  text-align: center;
  white-space: nowrap;
}

.side-box {
  border: none;
  border-left: 1px solid #111;
  padding: 1rem 0.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
}

.program-select {
  width: 6rem;
  height: 1.4rem;
  font-family: inherit;
  font-size: 0.65rem;
  background: #fff;
  color: #111;
  border: 1px solid #111;
  padding: 0 0.3rem;
  text-transform: lowercase;
}

/* seq/arp tempo-division dropdown (next to tempo mod) */
.rate-select {
  width: 3.2rem;
  height: 1.4rem;
  font-family: inherit;
  font-size: 0.6rem;
  background: #fff;
  color: #111;
  border: 1px solid #111;
  padding: 0 0.2rem;
}

.control-group {
  display: flex;
  flex-wrap: wrap;                /* very narrow -> controls wrap instead of clipping outside the box */
  gap: 0.6rem 0.55rem;           /* row-gap column-gap; tight enough that the busy mod-osc stays single-row */
  align-items: flex-start;
  justify-content: center;
  min-width: 0;
}

/* knobs */

.knob-control {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}

.knob {
  width: 2rem;
  height: 2rem;
  border: 2px solid #111;   /* uniform outline thickness across all knobs */
  border-radius: 50%;
  position: relative;
  flex: none;
  cursor: grab;
}

.knob.large {
  width: 3.2rem;
  height: 3.2rem;
}

.knob.medium {
  width: 2.4rem;
  height: 2.4rem;
}

.switch-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: center;
}

.knob::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 50%;
  width: 1px;
  height: 42%;
  background: #111;
  transform-origin: bottom center;
  transform: translateX(-50%) rotate(var(--rot, 0deg));
}

.knob-control label {
  font-size: 0.6rem;
  text-align: center;
  white-space: nowrap;
}

/* multi-position switches */

.switch-group {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-size: 0.58rem;
  white-space: nowrap;
}

.switch-group label {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  cursor: pointer;
}

.switch-group input {
  accent-color: #111;
  cursor: pointer;
  margin: 0;
}

.switch-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}

.switch-block .switch-title {
  font-size: 0.55rem;
  letter-spacing: 0.05em;
  text-align: center;
}

/* dlpg shared-label matrix */

.dlpg-matrix {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 0.25rem 0.5rem;
  align-items: center;
  font-size: 0.58rem;
  white-space: nowrap;
}

.dlpg-matrix input[type="radio"] {
  accent-color: #111;
  cursor: pointer;
  margin: 0;
  justify-self: center;
}

.dlpg-matrix .switch-title {
  text-align: center;
}

.dlpg-matrix > span {   /* center the mode labels (combination / amp) in their column */
  text-align: center;
}

/* pulser "one" momentary trigger button */

.pulser-one {
  grid-row: 3;
  align-self: end;
  justify-self: center;
  font-family: inherit;
  font-size: 0.55rem;
  text-transform: lowercase;
  background: #fff;
  color: #111;
  border: 1px solid #111;
  padding: 0.15rem 0.6rem;
  cursor: pointer;
}

.pulser-one:active {
  background: #111;
  color: #fff;
}

/* waveshape buttons */

.wave-select {
  display: flex;
  gap: 0.3rem;
}

.wave-btn {
  width: 1.3rem;
  height: 1.3rem;
  border: 1px solid #111;
  background: #fff;
  padding: 2px;
  cursor: pointer;
  flex: none;
}

.wave-btn svg {
  width: 100%;
  height: 100%;
  stroke: #111;
  fill: none;
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  display: block;
}

.wave-btn.active {
  background: #111;
}

.wave-btn.active svg {
  stroke: #fff;
}

/* jacks */

.jack-row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
}

.jack-control {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

.jack {
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 50%;
  border: 1px solid #111;
  flex: none;
}

.jack-control label {
  font-size: 0.52rem;
  text-align: center;
  white-space: nowrap;
}

.jack--red { background: #c0392b; }
.jack--blue { background: #3a6ea5; }
.jack--green { background: #4a9d5c; }
.jack--yellow { background: #d9c14a; }
.jack--purple { background: #9b85c4; }
.jack--orange { background: #d98a3d; }
.jack--white { background: #fff; }
.jack--black { background: #111; }
.jack--grey { background: #aaa; }

/* tiny line-art up-arrow above each black "mod" input, pointing at the word above it.
   absolutely positioned so it never affects layout (marked in JS by label text) */
.jack.mod-in { position: relative; }
.jack.mod-in::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(100% + 1px);
  transform: translateX(-50%);
  width: 6px;
  height: 10px;
  background: center / contain no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 10'%3E%3Cpath d='M3 10V1M1 3l2-2 2 2' fill='none' stroke='%23111' stroke-width='1'/%3E%3C/svg%3E");
  pointer-events: none;
}
/* the up-arrow replaces the redundant "mod" text; hide the label but keep its space (no layout shift) */
.jack.mod-in + label { visibility: hidden; }

.jack-strip {
  grid-column: 1 / -1;
  grid-row: 3;
  display: grid;
  grid-template-columns: subgrid;
  align-items: start;
  justify-items: center;
}

.jack-pair {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

/* sequential-voltage columns: a step-indicator light up top, the input jack
   dropped to the bottom row (even with the random/pressure outputs to the right) */
.seq-jack-col {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  gap: 0.3rem;
}

.seq-led {
  width: 0.7rem;
  height: 0.7rem;
}

/* sliders (vertical, matching nickkwas synth) */

.slider-control {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  min-width: 4rem;
}

.slider-control input[type="range"] {
  writing-mode: vertical-lr;
  direction: rtl;
  width: 4px;
  height: 80px;
  accent-color: #111;
}

/* env + pulser-period faders: colored fill ABOVE the dot (value increases downward) */
.slider-control input[type="range"].fill-up {
  direction: ltr;
}

.slider-control label {
  font-size: 0.6rem;
  text-align: center;
}

.slider-control.cap-blue input[type="range"] { accent-color: #3a6ea5; }

.step-toggle {
  appearance: none;
  -webkit-appearance: none;
  width: 0.65rem;
  height: 0.65rem;
  border: 1px solid #111;
  border-radius: 50%;
  background: #fff;
  cursor: pointer;
  margin: 0;
  flex: none;
}

.step-toggle:checked {
  background: #3a6ea5;
  border-color: #3a6ea5;
}
.slider-control.cap-orange input[type="range"] { accent-color: #d98a3d; }
.slider-control.cap-yellow input[type="range"] { accent-color: #d9c14a; }
.slider-control.cap-green input[type="range"] { accent-color: #4a9d5c; }
.slider-control.cap-red input[type="range"] { accent-color: #c0392b; }

/* preset display windows */

.preset-display {
  border: 1px solid #111;
  width: 4.5rem;
  height: 1.2rem;
}

/* led */

.led {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  border: 1px solid #111;
  background: #fff;
}

.led.on {
  background: #c0392b;
}

/* touch-activated voltage source + keyboard panel */

#touch-keyboard {
  width: auto;
}

.touch-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1.5rem;
  align-items: flex-start;
  margin-bottom: 1.5rem;
}

.touch-module {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}

/* a tight cluster of related modules that stays together within the spread-out row
   (e.g. add-to-pitch sits beside the preset voltage source it transposes) */
.touch-group {
  display: flex;
  gap: 1.5rem;
  align-items: flex-start;
}

.touch-module h4 {
  font-size: 0.62rem;
  font-weight: normal;
  text-transform: lowercase;
  letter-spacing: 0.06em;
  margin: 0;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid #111;
  text-align: center;
  white-space: normal;
  line-height: 1.3;
  width: 100%;
}

/* keyboard (same style as nickkwas, scaled to fill the panel width) */

.keyboard-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  font-size: 0.7rem;
}

.keyboard-controls button {
  font-family: inherit;
  font-size: 0.7rem;
  background: #fff;
  color: #111;
  border: 1px solid #111;
  padding: 0.25rem 0.5rem;
  cursor: pointer;
}

.keyboard-controls button:disabled {
  color: #aaa;
  border-color: #aaa;
  cursor: default;
}

.synth-keyboard {
  display: flex;
  width: 100%;
  user-select: none;
}

.key {
  border: 1px solid #111;
  height: 10rem;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  font-size: 0.7rem;
  padding-bottom: 0.4rem;
  cursor: pointer;
  background: #fff;
  color: #111;
}

.key.white {
  flex: 1 1 0;
}

.key.black {
  flex: none;
  width: 3.43%;
  height: 6rem;
  margin: 0 -1.715%;
  background: #111;
  color: #fff;
  position: relative;
  z-index: 1;
}

.key.active {
  background: #111;
  color: #fff;
}

.key.black.active {
  background: #555;
}

/* virtual patch cables */

#patch-layer {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 5;
  overflow: visible;
}

#patch-layer .cable {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  pointer-events: stroke;
  cursor: pointer;
  opacity: 0.85;
}

#patch-layer .cable:hover {
  stroke-width: 5;
  opacity: 1;
}

#patch-layer .cable.temp {
  pointer-events: none;
  opacity: 0.7;
  stroke-dasharray: 5 5;
}

.jack.jack-live {
  cursor: crosshair;
}

.jack.jack-live:hover {
  box-shadow: 0 0 0 2px rgba(17, 17, 17, 0.3);
}

.jack.patch-target {
  box-shadow: 0 0 0 2px #4a9d5c;
}

/* sh-101 style sequencer / arpeggiator */

.seqarp-grid {
  display: grid;
  grid-template-columns: repeat(8, auto);
  column-gap: 0.35rem;
  row-gap: 0.3rem;
  justify-items: center;
  align-items: end;
}

.seqarp-cell {
  grid-row: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
}

.seqarp-btn {
  font-family: inherit;
  font-size: 0.5rem;
  line-height: 1.15;
  text-transform: lowercase;
  background: #fff;
  color: #111;
  border: 1px solid #111;
  padding: 0.2rem 0.15rem;
  width: 2.4rem;
  min-height: 1.7rem;
  cursor: pointer;
  white-space: normal;
  text-align: center;
}

.seqarp-btn.on {
  background: #111;
  color: #fff;
}

.seqarp-bracket {
  grid-row: 2;
  font-size: 0.5rem;
  letter-spacing: 0.04em;
  text-align: center;
  border-top: 1px solid #111;
  padding-top: 0.15rem;
  width: 100%;
  align-self: start;
}

/* preset voltage source: knob centered above its momentary button */

.preset-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.preset-outs {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.preset-grid {
  display: flex;
  gap: 3.5rem;
  justify-content: center;
}

.preset-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4rem;
}

.preset-btn {
  width: 2.2rem;
  height: 1.2rem;
  border: 1px solid #111;
  background: #fff;
  color: #111;
  font-family: inherit;
  font-size: 0.6rem;
  padding: 0;
  cursor: pointer;
}

.preset-btn.active {
  background: #111;
  color: #fff;
}

.preset-keycap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
}

.preset-num {
  font-size: 0.6rem;
}
