/*
  DiMastro — Virtual Oscilloscope (staging preview)
  --------------------------------------------------
  Loaded after bench-calculators.css. Adds the two component types that
  page doesn't already have: range sliders and the scope canvas. Everything
  else on this page (fields, result cards, warning note, header) reuses the
  existing .tbc-* classes untouched.
*/

/* The tick-ring numbers around Champ/Marshall/Vox/AC4 knobs are absolutely
   positioned and can extend past their own column on narrow viewports.
   Without this, that overflow widens the page's scrollable area, which
   throws off .dm-page's centering (margin: 0 auto) and clips content on
   the right. Scoped to this page only -- doesn't touch the shared
   sitewide stylesheet. */
html, body { overflow-x: hidden; }


.vs-slider-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 6px;
}
.vs-slider-row .tbc-field-label { margin: 0; }
.vs-slider-val {
  font-family: var(--tbc-font-mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tbc-glow);
}

.vs-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  border-radius: 999px;
  background: var(--tbc-border);
  outline: none;
  margin: 4px 0 2px;
}
.vs-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--tbc-glow);
  border: 2px solid var(--tbc-panel);
  cursor: pointer;
}
.vs-range::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--tbc-glow);
  border: 2px solid var(--tbc-panel);
  cursor: pointer;
}

.vs-scope {
  position: relative;
  padding: 0;
  margin-bottom: 18px;
  background: transparent;
  box-shadow: none;
}
.vs-scope-inner {
  background: linear-gradient(155deg, #9a9b9f 0%, #7d7e82 100%);
  border-radius: 10px;
  padding: 10px;
  box-shadow: inset 0 2px 5px rgba(0,0,0,0.5);
}
.vs-scope canvas { display: block; width: 100%; height: auto; border-radius: 3px; }

.vs-compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 10px;
}
.vs-compare-card {
  background: var(--tbc-panel);
  border: 1px solid var(--tbc-border-soft);
  border-radius: var(--tbc-radius-sm);
  padding: 10px 12px;
}
.vs-compare-card .who {
  font-family: var(--tbc-font-mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tbc-ink-faint);
  margin: 0 0 4px;
}
.vs-compare-card .num {
  font-family: var(--tbc-font-mono);
  font-size: 15px;
  font-weight: 700;
  color: var(--tbc-ink);
}

@media (max-width: 640px) {
  .vs-compare { grid-template-columns: 1fr; }
}

/* ── scope + pitch knob row, wrapped in a single card ── */
.vs-scope-card {
  background: rgb(69 69 69 / 80%);
  border: 1.5px solid #919191;
  border-radius: var(--tbc-radius-sm);
  padding: 16px;
  margin-bottom: 18px;
}
.vs-scope-row {
  display: flex;
  align-items: flex-start;
  gap: 18px;
}
.vs-scope-row .vs-scope { flex: 1 1 auto; margin-bottom: 0; min-width: 0; }
.vs-pitch-col {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  width: 84px;
}
.vs-pitch-col .ts-ctl-name { color: var(--tbc-ink-muted); }
.vs-pitch-col .ts-ctl {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 84px;
  min-height: 0;
}
.vs-pitch-col .ts-ctl-num {
  color: var(--tbc-glow);
  text-shadow: none;
  white-space: nowrap;
  font-size: 11px;
  line-height: 1.25;
  min-height: 2.5em;
  max-width: 84px;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}
.vs-knob-sm { width: 44px; height: 44px; }

@media (max-width: 640px) {
  .vs-scope-row { flex-direction: column; }
  .vs-pitch-col { flex-direction: row; flex-wrap: wrap; justify-content: center; width: auto; gap: 14px; }
}

/* ── graphical knobs, ported from the Tone Stack Calculator's .ts-knob
   widget: real rotating knob images, per-brand faceplate colors and
   badge, same drag/keyboard/wheel interaction. ── */
.ts-controls { margin-top: 4px; }

.ts-knobs-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: 18px 30px;
  padding: 16px 20px;
  background:
    linear-gradient(180deg, var(--face-hi, #d2d5df) 0%, var(--face-mid, #bfbfc5) 45%, var(--face-lo, #898885) 100%);
  border: 1.5px solid var(--face-outline, #498aa5);
  border-radius: var(--tbc-radius-sm);
  outline: 1.5px solid var(--face-outline, #498aa5);
  outline-offset: 4px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), inset 0 -1px 0 rgba(0, 0, 0, .15);
  transition: background .2s ease, border-color .2s ease, outline-color .2s ease;
}

/* Champ / Marshall / Vox / AC4: the tick ring's top-of-scale number
   overhangs above the knob's own box on every screen size -- extra top
   padding keeps it clear of the card edge instead of touching it. */
.ts-knobs-row--ticked { padding-top: 38px; }
/* All profiles: Volume + tone knobs as equal siblings, centered in the
   space to the right of the badge with even spacing between each knob. */
.ts-knobs-pair {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  flex: 1 1 auto;
  min-width: 0;
}
/* 2-knob chrome-plate profiles (Champ, Tweed Deluxe): narrower plate,
   centered in the space beside the badge. Knob gap/size unchanged --
   only the plate's own width and position shrink to fit its content. */
/* Two-layer centering fix. A single element can't both (a) claim the
   real leftover width beside the badge, via flex-grow, AND (b) have a
   narrower visual width with margin:auto centering -- once flex-grow
   fills the item's box to its grown size, margin:auto has no leftover
   space left within that box to center against; it only centers the
   box itself within the row, which flex-grow already made full-width.
   So: outer = plain, invisible, flex:1 1 auto (claims the real leftover
   width, row-level justify-content:flex-start stops it being eaten by
   space-between); inner .ts-knobs-pair--narrow = the actual visually
   narrow plate, centered via the outer's own justify-content:center. */
.ts-knobs-row--narrow-plate {
  justify-content: flex-start;
}
.ts-knobs-pair--narrow-outer {
  display: flex;
  justify-content: center;
  flex: 1 1 auto;
  min-width: 0;
}
.ts-knobs-pair--narrow {
  flex: 0 1 auto;
  max-width: 100%;
}

/* Champ / Marshall / Vox / AC4: small chrome plate under Volume + Tone
   knobs and their numbers only — tweed faceplate remains the background
   of the whole row. Brushed chrome: bright horizontal band through the
   middle, slightly darker top/bottom, soft edge highlight like real
   stamped metal. */
.ts-knobs-row--ticked .ts-knobs-pair--chrome {
  gap: 36px; /* wider than the 28px default -- extra breathing room so
                tick-ring numbers on adjacent knobs (Bassman's 4-knob
                row) can't crowd each other on narrower/lower-DPI displays. */
}
.ts-knobs-pair--chrome {
  position: relative;
  padding: 28px 36px 18px;
  margin: 4px 8px;
  border-radius: 10px;
  background:
    /* lengthwise brushed highlight (bright middle) */
    linear-gradient(90deg,
      rgba(0, 0, 0, .14) 0%,
      rgba(255, 255, 255, .08) 18%,
      rgba(255, 255, 255, .38) 50%,
      rgba(255, 255, 255, .08) 82%,
      rgba(0, 0, 0, .14) 100%),
    /* vertical shade: darker top & bottom, bright mid */
    linear-gradient(180deg,
      #8a909a 0%,
      #c4cad4 20%,
      #f0f3f8 48%,
      #c0c6d0 80%,
      #7e848e 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .85),
    inset 0 -1px 0 rgba(0, 0, 0, .28),
    inset 1px 0 0 rgba(255, 255, 255, .25),
    inset -1px 0 0 rgba(0, 0, 0, .12),
    0 0 0 1px rgba(60, 70, 85, .35),
    0 2px 5px rgba(0, 0, 0, .28),
    0 1px 0 rgba(255, 255, 255, .15);
}
/* Bassman desktop: tighter padding than the standard chrome plate --
   frees up room for its 4 knobs beside the (now shorter) badge. */
.ts-knobs-pair--compact {
  padding: 24px 20px 16px !important;
}
/* Tighter than the general 36px chrome-plate gap -- with knobs locked
   to a 66px column at 0.68 scale, this much space is no longer needed
   to keep tick labels from crowding, and the extra gap just looked
   sparse. Scoped to Bassman only, not Champ/Tweed Deluxe. */
.ts-knobs-row--ticked .ts-knobs-pair--compact {
  gap: 22px;
}
/* Bassman desktop: slightly smaller knobs (with their tick rings) so
   all 4 comfortably fit the compact plate without crowding the edges.
   Mobile is unaffected -- its own more specific rule already wins. */
.ts-knobs-pair--compact > .ts-ctl {
  width: 66px;
  flex: 0 0 66px;
}
.ts-knobs-pair--compact > .ts-ctl .ts-knob-wrap {
  transform: scale(0.68);
  transform-origin: center center;
}
.ts-knobs-pair--compact > .ts-ctl .ts-knob-wrap + .ts-ctl-name {
  margin-top: 10px;
}
.ts-knobs-pair--chrome .ts-ctl-name,
.ts-knobs-pair--chrome .ts-ctl-num,
.ts-knobs-pair--chrome .ts-ctl-db,
.ts-knobs-pair--chrome .ts-knob-tick-num {
  color: #1a1e24 !important;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .5) !important;
}
.ts-knobs-pair--chrome .ts-knob-tick-mark {
  background: #1a1e24 !important;
}

/* Vox profiles: same plate shape and 3-tone illumination (dark top/
   bottom, lit middle) as the light chrome plate above, but a dark
   brown/maroon tone matching the real AC30/AC15 panel surround, with
   light cream text instead of dark for contrast. */
.ts-knobs-pair--chrome-dark {
  position: relative;
  padding: 28px 36px 18px;
  margin: 4px 8px;
  border-radius: 10px;
  border: 2.5px solid #c8b99e;
  outline: 2.5px solid #c8b99e;
  outline-offset: -8px;
  flex: 0 1 50%;
  max-width: 50%;
  margin-left: auto;
  margin-right: auto;
  background:
    linear-gradient(90deg,
      rgba(0, 0, 0, .12) 0%,
      rgba(255, 255, 255, .02) 18%,
      rgba(255, 255, 255, .05) 50%,
      rgba(255, 255, 255, .02) 82%,
      rgba(0, 0, 0, .12) 100%),
    linear-gradient(180deg,
      #363232 0%,
      #423e3d 20%,
      #524e4c 48%,
      #423e3d 80%,
      #363232 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    inset 0 -1px 0 rgba(0, 0, 0, .5),
    inset 1px 0 0 rgba(255, 255, 255, .05),
    inset -1px 0 0 rgba(0, 0, 0, .3),
    0 2px 5px rgba(0, 0, 0, .35),
    0 1px 0 rgba(255, 255, 255, .05);
}
/* AC30: same shape/plate as above, but a red plate and white double
   border instead of the neutral dark plate + cream border. */
.ts-knobs-pair--chrome-red {
  position: relative;
  padding: 28px 36px 18px;
  margin: 4px 8px;
  border-radius: 10px;
  border: 2.5px solid #ffffff;
  outline: 2.5px solid #ffffff;
  outline-offset: -8px;
  flex: 0 1 50%;
  max-width: 50%;
  margin-left: auto;
  margin-right: auto;
  background:
    linear-gradient(90deg,
      rgba(0, 0, 0, .22) 0%,
      rgba(255, 255, 255, .02) 18%,
      rgba(255, 255, 255, .06) 50%,
      rgba(255, 255, 255, .02) 82%,
      rgba(0, 0, 0, .22) 100%),
    linear-gradient(180deg,
      #3a0f11 0%,
      #571519 20%,
      #7a1d22 48%,
      #571519 80%,
      #3a0f11 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    inset 0 -1px 0 rgba(0, 0, 0, .5),
    inset 1px 0 0 rgba(255, 255, 255, .05),
    inset -1px 0 0 rgba(0, 0, 0, .3),
    0 2px 5px rgba(0, 0, 0, .35),
    0 1px 0 rgba(255, 255, 255, .05);
}
.ts-knobs-pair--chrome-red .ts-ctl-name,
.ts-knobs-pair--chrome-red .ts-ctl-num,
.ts-knobs-pair--chrome-red .ts-ctl-db,
.ts-knobs-pair--chrome-red .ts-knob-tick-num {
  color: #f4ece9 !important;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .6) !important;
}
.ts-knobs-pair--chrome-red .ts-knob-tick-mark {
  background: #f4ece9 !important;
}
.ts-knobs-pair--chrome-dark .ts-ctl-name,
.ts-knobs-pair--chrome-dark .ts-ctl-num,
.ts-knobs-pair--chrome-dark .ts-ctl-db,
.ts-knobs-pair--chrome-dark .ts-knob-tick-num {
  color: #f4ece9 !important;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .6) !important;
}
.ts-knobs-pair--chrome-dark .ts-knob-tick-mark {
  background: #f4ece9 !important;
}

/* Champ (and any profile with panelBg): tweed / fabric faceplate.
   Background image is applied inline from JS. */
.ts-knobs-row--textured {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), inset 0 -1px 0 rgba(0, 0, 0, .35);
}
.ts-knobs-row--textured .ts-ctl-name,
.ts-knobs-row--textured .ts-ctl-num {
  color: var(--face-text, #2a2210);
  text-shadow: 0 1px 0 rgba(255,255,255,0.25), 0 1px 2px rgba(0,0,0,0.35);
}

/* Blackface faceplate: dark panel, light legends, silver edge */
.ts-knobs-row--blackface {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .12),
    inset 0 -1px 0 rgba(0, 0, 0, .55),
    0 0 0 1px rgba(255, 255, 255, .06);
}
.ts-knobs-row--blackface .ts-ctl-name,
.ts-knobs-row--blackface .ts-ctl-num {
  color: var(--face-text, #f0efe9);
  text-shadow: 0 1px 1px rgba(0, 0, 0, .85);
}

/* Silverface faceplate: brushed aluminum, dark legends, teal edge.
   (Inner section frame and pointer arrows removed — clean panel.) */
.ts-knobs-row--silverface {
  background:
    linear-gradient(90deg,
      rgba(0, 0, 0, .14) 0%,
      rgba(255, 255, 255, .08) 18%,
      rgba(255, 255, 255, .38) 50%,
      rgba(255, 255, 255, .08) 82%,
      rgba(0, 0, 0, .14) 100%),
    linear-gradient(180deg,
      #8a909a 0%,
      #c4cad4 20%,
      #f0f3f8 48%,
      #c0c6d0 80%,
      #7e848e 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .85),
    inset 0 -1px 0 rgba(0, 0, 0, .28),
    inset 1px 0 0 rgba(255, 255, 255, .25),
    inset -1px 0 0 rgba(0, 0, 0, .12),
    0 0 0 1px rgba(60, 70, 85, .35),
    0 2px 5px rgba(0, 0, 0, .28),
    0 1px 0 rgba(255, 255, 255, .15);
}
.ts-knobs-row--silverface .ts-ctl-name,
.ts-knobs-row--silverface .ts-ctl-num {
  color: var(--face-text, #1a1e24);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .5);
}

.ts-badge-wrap { flex: 0 0 auto; display: flex; justify-content: flex-start; align-items: center; min-width: 40px; }
.ts-badge-wrap--name { flex: 0 1 auto; min-width: 0; max-width: 46%; }
/* All badge photos share the same width; height follows each image's
   own aspect ratio rather than a fixed height per style. Keeps every
   amp's nameplate visually the same "size" on the panel regardless of
   whether it's a wide riveted plate or a squarish two-line badge. */
.ts-badge { width: 150px; height: auto; max-width: 100%; display: block; object-fit: contain; }
/* Tweed Deluxe / Bassman: same badge height as Champ instead of the
   uniform-width system, per explicit request -- each badge's own width
   now follows its own aspect ratio at that fixed height. */
.ts-badge--champ-height { width: auto !important; height: 33px !important; max-width: 220px !important; }
/* Bassman desktop: slightly shorter than champ-height, and a tighter
   max-width -- frees up horizontal room for the 4-knob plate beside it.
   Mobile is unaffected (handled separately by mobile-row scaling). */
.ts-badge--bassman { width: auto !important; height: 27px !important; max-width: 185px !important; }
.ts-badge-wrap--sm { flex: 0 0 auto; justify-content: flex-start; min-width: 0; }
.ts-badge-wrap--script { flex: 0 0 auto; justify-content: flex-start; min-width: 0; }

/* Faceplate model lettering — era style match (not official logo art) */
.ts-panel-name {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  line-height: 1.05;
  user-select: none;
  pointer-events: none;
}
.ts-panel-name-brand {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.ts-panel-name-model {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Blackface: cream silk-screen on black */
.ts-panel-name--blackface .ts-panel-name-brand {
  font-family: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  font-style: italic;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: none;
  color: #f4f1e6;
  text-shadow: 0 1px 1px rgba(0,0,0,.75);
}
.ts-panel-name--blackface .ts-panel-name-model {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: #f4f1e6;
  text-shadow: 0 1px 1px rgba(0,0,0,.75);
}

/* Silverface: dark print on aluminum */
.ts-panel-name--silverface .ts-panel-name-brand {
  font-family: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  font-style: italic;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: none;
  color: #1a1e24;
  text-shadow: 0 1px 0 rgba(255,255,255,.4);
}
.ts-panel-name--silverface .ts-panel-name-model {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: #1a1e24;
  text-shadow: 0 1px 0 rgba(255,255,255,.35);
}

/* Tweed Champ */
.ts-panel-name--tweed .ts-panel-name-brand {
  font-family: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  font-style: italic;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: none;
  color: #2a2210;
  text-shadow: 0 1px 0 rgba(255,255,255,.25);
}
.ts-panel-name--tweed .ts-panel-name-model {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: #2a2210;
  text-shadow: 0 1px 0 rgba(255,255,255,.2);
}

/* Vox */
.ts-panel-name--vox .ts-panel-name-brand {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.28em;
  color: #f4ece9;
  text-shadow: 0 1px 1px rgba(0,0,0,.55);
}
.ts-panel-name--vox .ts-panel-name-model {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 36px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: #f4ece9;
  text-shadow: 0 1px 1px rgba(0,0,0,.55);
}

/* AC4: cream tolex background needs dark lettering, not the light
   lettering the red/black tolex variants use. */
.ts-panel-name--vox-cream .ts-panel-name-brand {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.28em;
  color: #3a2f1f;
  text-shadow: 0 1px 0 rgba(255,255,255,.25);
}
.ts-panel-name--vox-cream .ts-panel-name-model {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 36px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: #3a2f1f;
  text-shadow: 0 1px 0 rgba(255,255,255,.25);
}

/* Marshall */
.ts-panel-name--marshall .ts-panel-name-brand {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: #241a0e;
  text-shadow: 0 1px 0 rgba(255,255,255,.25);
}
.ts-panel-name--marshall .ts-panel-name-model {
  font-family: "Gill Sans", "Gill Sans MT", "Trebuchet MS", "Segoe UI", sans-serif;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: #241a0e;
  text-shadow: 0 1px 0 rgba(255,255,255,.2);
}

.ts-knobs-group { display: flex; flex-wrap: nowrap; justify-content: center; gap: 18px 26px; flex-shrink: 0; }

@media (max-width: 640px) {
  /* Column: badge on top, knobs group fills and centers below */
  .ts-knobs-row {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-start;
    gap: 20px;
  }
  .ts-badge-wrap,
  .ts-badge-wrap--sm,
  .ts-badge-wrap--name {
    flex: 0 0 auto;
    width: 100%;
    max-width: 100%;
    justify-content: center;
  }
  .ts-badge,
  .ts-badge--sm {
    margin-left: auto;
    margin-right: auto;
  }
  .ts-panel-name { align-items: center; text-align: center; }

  /* Extra side padding so tick numbers clear the card edge */
  .ts-knobs-row--ticked {
    padding-left: 20px;
    padding-right: 20px;
    padding-top: 28px;
  }

  /* Volume on its own row; all tone knobs share one row below.
     Equal size for every knob; even vertical/horizontal gaps.
     Group centers under the badge. */
  .ts-knobs-pair {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-content: center;
    align-items: flex-start;
    gap: 28px 14px;
    width: 100%;
    flex: 1 1 auto;
  }
  /* Same size for Volume and every tone knob */
  .ts-knobs-pair > .ts-ctl {
    width: 78px;
    flex: 0 0 78px;
  }
  /* Volume alone on the first row (full width, content centered) --
     except mobileSingleRow profiles (Bassman), which keep all knobs
     together in one row instead. */
  .ts-knobs-pair:not(.ts-knobs-pair--mobile-row) > .ts-ctl:first-child {
    flex: 1 0 100%;
    width: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  /* Ticked profiles: uniform scale so 3 tone knobs fit one row */
  .ts-knobs-row--ticked .ts-knobs-pair > .ts-ctl .ts-knob-wrap {
    transform: scale(0.82);
    transform-origin: center center;
  }
  .ts-knobs-row--ticked .ts-knobs-pair > .ts-ctl .ts-knob-wrap + .ts-ctl-name {
    margin-top: 8px;
  }
  /* The 36px desktop gap (Bassman tick-safety) and the compact plate
     padding are both desktop-oriented fixes -- reset to mobile-sized
     values here, or Bassman's tone-trio row doesn't fit and Bass wraps
     to its own third row. */
  .ts-knobs-row--ticked .ts-knobs-pair--chrome {
    gap: 14px 8px;
  }
  .ts-knobs-pair--compact {
    padding: 24px 10px 12px !important;
  }
  /* mobileSingleRow (Bassman): all 4 knobs in one row needs smaller
     knobs, a tighter column width, and reduced plate padding than the
     3-knob-row default above -- the plate's own 36px side padding alone
     would otherwise eat most of the available mobile width. */
  .ts-knobs-row--ticked .ts-knobs-pair--mobile-row {
    flex-wrap: nowrap;
    gap: 18px;
    padding-left: 10px !important;
    padding-right: 10px !important;
  }
  .ts-knobs-pair--mobile-row > .ts-ctl {
    width: 44px;
    flex: 0 0 44px;
  }
  .ts-knobs-pair--mobile-row > .ts-ctl .ts-knob-wrap {
    transform: scale(0.46);
    transform-origin: center center;
  }
  .ts-knobs-pair--mobile-row > .ts-ctl .ts-knob-wrap + .ts-ctl-name {
    margin-top: -8px;
  }
  .ts-knobs-pair--mobile-row > .ts-ctl .ts-ctl-name,
  .ts-knobs-pair--mobile-row > .ts-ctl .ts-ctl-num {
    font-size: 9px;
  }
  /* Chrome-plate amps (Champ/AC4/AC30): keep plate centered */
  .ts-knobs-pair--chrome,
  .ts-knobs-pair--chrome-dark,
  .ts-knobs-pair--chrome-red,
  .ts-knobs-pair--narrow-outer,
  .ts-knobs-pair--narrow {
    width: auto;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
  }
}

.ts-ctl { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 84px; }
.ts-ctl[data-disabled="true"] { opacity: .45; }

.ts-knobs-row .ts-ctl-name {
  font-family: var(--tbc-font-display); font-size: 12px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--face-text, #232427);
}

.ts-knob { position: relative; width: 64px; height: 64px; cursor: ns-resize; touch-action: none; border-radius: 50%; }

/* Static numbered dial ring -- Champ, Marshall, Vox/AC4. The ring sits
   behind the knob and never rotates; only the knob face does, same as a
   real chicken-head knob against a printed panel scale. */
.ts-knob-wrap { position: relative; width: 64px; height: 64px; }
.ts-knob-ticks { position: absolute; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; }
.ts-knob-tick-mark {
  position: absolute;
  width: 2px; height: 5px;
  border-radius: 1px;
  opacity: .95;
  box-shadow: 0 0 1.5px rgba(0, 0, 0, .7);
}
.ts-knob-tick-num {
  position: absolute;
  transform: translate(-50%, -50%);
  font: 700 8px var(--tbc-font-mono, monospace);
  line-height: 1;
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
/* The 0/10 tick labels sit at the bottom-left/bottom-right of the ring and
   overhang below the knob's own box -- push the name down clear of them
   (only when a tick ring is present; untouched otherwise). */
.ts-knob-wrap + .ts-ctl-name { margin-top: 16px; }
.ts-knob-face { display: block; width: 100%; height: 100%; pointer-events: none; user-select: none; -webkit-user-drag: none; }
.ts-knob:focus-visible { outline: 2px solid var(--tbc-glow); outline-offset: 3px; }
.ts-knob[aria-disabled="true"] { cursor: default; }

.ts-ctl-num { font: 700 12.5px var(--tbc-font-mono); color: var(--face-text, #232427); text-shadow: 0 1px 2px rgba(0,0,0,0.25); }

/* ── signal generator: same card treatment as the scope, wrapping the
   frequency-preset dropdown + the 7-segment LED readout ── */
.vs-siggen-card {
  background: rgb(69 69 69 / 80%);
  border: 1.5px solid #919191;
  border-radius: var(--tbc-radius-sm);
  padding: 16px;
  margin-bottom: 18px;
}
.vs-siggen-row {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  margin-bottom: 0;
}
.vs-siggen-select { flex: 1 1 auto; min-width: 0; margin-bottom: 0; }

.vs-seg-card {
  flex: 0 0 auto;
  background: var(--tbc-panel-raised);
  border: 1px solid var(--tbc-border-soft);
  border-radius: var(--tbc-radius-sm);
  padding: 8px;
}
.vs-seg-frame {
  padding: 3px;
  border-radius: 5px;
  background: linear-gradient(155deg, #6b6d72 0%, #38393c 55%, #232427 100%);
  box-shadow: inset 0 1px 1px rgba(255,255,255,0.25), inset 0 -1px 1px rgba(0,0,0,0.5);
}
.vs-seg-panel {
  background: #0a0806;
  border-radius: 3px;
  padding: 7px 10px;
  display: flex;
  justify-content: center;
}
.vs-seg-display { display: flex; gap: 3px; }
.vs-seg-digit-svg { display: block; flex: none; }

@media (max-width: 640px) {
  .vs-siggen-row { flex-direction: column; align-items: stretch; }
  .vs-seg-card { align-self: center; }
}

/* Dark theme: light labels on gray instrument cards */
.vs-siggen-card .tbc-field-label,
.vs-scope-card .tbc-field-label,
.vs-siggen-card .tbc-field,
.vs-scope-card .ts-ctl-name {
  color: #f0ebe3;
}
.vs-pitch-col .ts-ctl-name {
  color: #e8e0d4;
}
.vs-compare-card .who {
  color: #c9bcae;
}

/* Light theme: instrument cards go light */
[data-theme="light"] .vs-siggen-card,
[data-theme="light"] .vs-scope-card {
  background: #e8e4de !important;
  border-color: #b8aea0 !important;
}
[data-theme="light"] .vs-siggen-card .tbc-field-label,
[data-theme="light"] .vs-scope-card .tbc-field-label,
[data-theme="light"] .vs-siggen-card .tbc-field,
[data-theme="light"] .vs-scope-card .ts-ctl-name,
[data-theme="light"] .vs-pitch-col .ts-ctl-name {
  color: #2a221c !important;
}
[data-theme="light"] .vs-pitch-col .ts-ctl-num {
  color: #c45e1a !important;
}
[data-theme="light"] .vs-compare-card {
  background: #ffffff !important;
  border-color: #c9b79a !important;
}
[data-theme="light"] .vs-compare-card .who {
  color: #5c4a38 !important;
}
[data-theme="light"] .vs-compare-card .num {
  color: #1f1812 !important;
}

/* Title on its own full-width row so it does not wrap beside the badge */
#virtual-oscilloscope > .tbc-header {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
#virtual-oscilloscope .tbc-header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
#virtual-oscilloscope .tbc-title {
  width: 100%;
  max-width: none;
  white-space: nowrap;
  font-size: clamp(18px, 5.8vw, 26px);
  line-height: 1.2;
  margin: 0 0 2px;
}
#virtual-oscilloscope .tbc-sub {
  max-width: none;
  width: 100%;
}

/* Brand badges — same chrome pills as Tone Stack Simulator */
.vo-amp-pick { display: flex; flex-direction: column; gap: 12px; }
.vo-brand-tabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
}
.vo-brand-tabs button {
  flex: 1 1 0;
  min-width: 0;
  font-family: var(--tbc-font-display);
  color: var(--tbc-ink-faint);
  background: linear-gradient(180deg, #2a2a2c 0%, #161616 55%, #0a0a0a 100%);
  border: 1px solid #000;
  border-radius: 10px;
  padding: 8px 8px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 5px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .1), inset 0 -3px 4px rgba(0, 0, 0, .55);
}
.vo-brand-tabs button[aria-selected="true"] {
  background: linear-gradient(180deg, var(--tab-hi, #d2d5df) 0%, var(--tab-mid, #bfbfc5) 55%, var(--tab-lo, #898885) 100%);
  border-color: var(--tab-outline, #498aa5);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .4), inset 0 -2px 3px rgba(0, 0, 0, .2);
}
.vo-brand-badge {
  height: 22px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  display: block;
  filter: brightness(1.25) contrast(1.05) drop-shadow(0 1px 1px rgba(0, 0, 0, .6));
}
.vo-brand-tabs button[data-key="fender"] .vo-brand-badge {
  filter: brightness(1.7) contrast(1.05) drop-shadow(0 1px 1px rgba(0, 0, 0, .6));
}
.vo-brand-tabs button[data-key="vox"] .vo-brand-badge,
.vo-brand-tabs button[aria-selected="true"][data-key="vox"] .vo-brand-badge {
  filter: brightness(.82) contrast(1.05) drop-shadow(0 1px 1px rgba(0, 0, 0, .6));
}
