/* VENDORED COPY of _Shared-Code/wave-view/src — do not edit here. canonical-sha256: d7cacfe5c526a5b8814c7bb07ab1e64601f6fbccfb088b45304d63059f05c3f4 */
/* ══════════════════════════════════════════════════════════════════════════
   CANONICAL SOURCE — _Shared-Code/wave-view/src/waveview.css

   The universal wave view's CHROME: the dock, the dropdown-band chips, the
   toolbar, the wave-edits band, the ruler, the minimap, the lane, the resize
   handle and the new-clip form. It is as much "the wave view" as waveview.js
   is, so it lives in the same place and is vendored the same way.

   THE COLOUR SEAM. This file names ONLY --wv-* custom properties. It contains
   no colour literal of any kind — no hex, no rgb(), no named colour — and
   `sync.py check` fails the build if one appears. That is the whole
   enforcement: a seat can only ever change the wave view's COLOUR, because
   colour is the only thing it is given a handle on. Every structural
   value — sizes, spacing, order, radii, the switch travel — lives here, once.

   Each seat defines the --wv-* block for itself (see TOKENS.md). Nothing else
   about this file may differ between seats.

   Edit HERE, then run:  python3 _Shared-Code/wave-view/sync.py push
   ══════════════════════════════════════════════════════════════════════════ */

/* ---- the dropdown-band chip row ----------------------------------------- */
/* The wave view's own toggles ride together as one strip: wave tools, wave
   edits, minimap, and the view itself. Understated until their band is open,
   when they warm to the accent. */
.tr-bartoggles { display: flex; align-items: center; gap: 0.35rem; }
/* Hairline between the two families in the strip: the host's chrome rows to
   its left, the wave's own to its right. Without it they read as unrelated
   glyphs. Sits inside .tr-bartoggles, so it travels with the strip. */
.tr-bartogglesep { flex: none; width: 1px; height: 1.05rem; background: var(--wv-border); }

.tr-wavedock { margin-top: 0; position: relative; }
.tr-wavetoggle {
  display: inline-flex; align-items: center; gap: 0.15rem;
  font: inherit; font-size: 0.8rem; line-height: 1;
  padding: 0.2rem 0.45rem;
  border: 1px solid var(--wv-border);
  border-radius: 6px;
  background: none;
  color: var(--wv-muted);
  cursor: pointer;
}
.tr-wavetoggle:hover { border-color: var(--wv-ink); color: var(--wv-ink); }
.tr-wavetoggle[aria-expanded="true"] { color: var(--wv-accent); border-color: var(--wv-accent); }
/* a MODE chip (the help toggle) lights by aria-pressed, same dress as an open band */
.tr-wavetoggle[aria-pressed="true"] { color: var(--wv-accent); border-color: var(--wv-accent); }
.tr-wavetoggle svg { display: block; }
.tr-wavetoggle-caret { font-size: 0.7rem; }

.tr-waverow { padding: 0 0.3rem; position: relative; margin-top: 0.35rem; }
.tr-waverow[hidden] { display: none; }

/* ---- the transport ------------------------------------------------------- */
/* Gone as a strip (owner ruling, 2026-07-30, superseding "what stayed above
   the lane is play"): play and its extras moved INTO the sill, at its left
   end, and folded means folded — see the sill section below. */
.tr-waveicon[hidden] { display: none; }

/* Wave edits band (owner ruling, July 22): its own dropdown for the tools that
   rewrite the audio, sitting between the display bar and the minimap. Left-
   packed with a muted label, so it reads as a labelled group that grows
   rightward as more destructive edits join gain. */
.tr-waveedit[hidden] { display: none; }
.tr-waveedit {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.3rem;
}
.tr-waveedit-label {
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: var(--wv-muted);
  text-transform: lowercase;
}
.tr-waveedit button {
  font: inherit; font-size: 0.78rem; padding: 0.16rem 0.6rem;
  border: 1px solid var(--wv-border); border-radius: 6px;
  background: var(--wv-surface); color: var(--wv-ink); cursor: pointer;
}
.tr-waveedit button:hover { background: var(--wv-surface-hover); }

/* zoom in/fit/out fused into one segmented control */
.tr-wavezoom { display: inline-flex; gap: 0; border: 1px solid var(--wv-border); border-radius: 6px; overflow: hidden; }
.tr-wavezoom button {
  font: inherit;
  font-size: 0.78rem;
  padding: 0.12rem 0.55rem;
  border: 0;
  border-right: 1px solid var(--wv-border);
  background: var(--wv-surface);
  color: var(--wv-ink);
  cursor: pointer;
}
.tr-wavezoom button:last-child { border-right: 0; }
.tr-wavezoom button:hover { background: var(--wv-surface-hover); }

/* the two extra zoom actions (zoom-to-selection, zoom-back) as icon buttons */
.tr-waveicon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.16rem 0.4rem;
  border: 1px solid var(--wv-border);
  border-radius: 6px;
  background: var(--wv-surface);
  color: var(--wv-ink);
  cursor: pointer;
  line-height: 0;
}
.tr-waveicon:hover { background: var(--wv-surface-hover); }
.tr-waveicon:disabled { opacity: 0.4; cursor: default; }
.tr-waveicon svg { display: block; }
.tr-wavesep { width: 1px; height: 18px; background: var(--wv-border); align-self: center; }
.tr-wavetog {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  color: var(--wv-muted);
  white-space: nowrap;
}
.tr-wavetog[hidden] { display: none; }
.tr-wavetog select {
  font: inherit; font-size: 0.76rem; color: var(--wv-ink);
  background: var(--wv-surface); border: 1px solid var(--wv-border);
  border-radius: 6px; padding: 0.1rem 0.3rem;
}

/* soft on/off switch in place of the bare checkbox (on = the accent) */
.tr-waveswitch { cursor: pointer; }
.tr-waveswitch input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 28px;
  height: 16px;
  margin: 0;
  border-radius: 9px;
  background: var(--wv-border);
  position: relative;
  cursor: pointer;
  transition: background 0.12s;
}
.tr-waveswitch input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--wv-knob);
  transition: left 0.12s;
}
.tr-waveswitch input[type="checkbox"]:checked { background: var(--wv-accent); }
.tr-waveswitch input[type="checkbox"]:checked::after { left: 14px; }
.tr-waveswitch input[type="checkbox"]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--wv-focus-ring);
}

/* the shortcuts hint lives in a popover on this help bubble */
.tr-wavehelp {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--wv-border);
  border-radius: 50%;
  background: var(--wv-surface);
  color: var(--wv-muted);
  font-size: 0.72rem;
  cursor: help;
}
.tr-wavehelp:hover { background: var(--wv-surface-hover); }
.tr-wavehelp-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  width: max-content;
  max-width: 300px;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--wv-border);
  border-radius: 6px;
  background: var(--wv-panel);
  color: var(--wv-ink);
  font-size: 0.68rem;
  line-height: 1.45;
  text-align: left;
  white-space: normal;
  box-shadow: 0 4px 14px var(--wv-shadow);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-2px);
  transition: opacity 0.12s, transform 0.12s;
  z-index: 20;
}
.tr-wavehelp:hover .tr-wavehelp-pop,
.tr-wavehelp:focus .tr-wavehelp-pop,
.tr-wavehelp:focus-visible .tr-wavehelp-pop {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* The transport, in the sill (owner ruling, 2026-07-30): the play disc at the
   LEFT end; the volume mockingbird and the speed turtle at the RIGHT end, past
   the right-packed toggles (owner ruling, 2026-07-31). One notch smaller than
   the strip it replaces — 20px of sill is the whole height budget. */
.tr-wave-playback { display: inline-flex; align-items: center; gap: 0.4rem; min-width: 0; }
.tr-wave-playback > button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0; flex: none;
  border: 1px solid var(--wv-border); border-radius: 50%;
  background: var(--wv-accent); color: var(--wv-accent-ink); cursor: pointer;
}
.tr-wave-playback > button:hover { background: var(--wv-accent-hover); }
.tr-wave-playback > button svg { display: block; width: 11px; height: 11px; }
.tr-wave-playback > button svg path,
.tr-wave-playback > button svg rect { fill: var(--wv-accent-ink); stroke: var(--wv-accent-ink); }

/* ---- ruler, lane, minimap ------------------------------------------------ */
.tr-waveruler {
  display: block;
  width: 100%;
  height: 16px;
  margin-top: 0.3rem; /* sits below the overview minimap, hugging the wave */
  cursor: ew-resize;
  touch-action: none;
  background: var(--wv-ground); /* dark ground, matching the wave (owner ruling July 18) */
}
.tr-wave {
  position: relative;
  height: 150px; /* the opening height — the bottom-edge handle grows it */
  border: 1px solid var(--wv-border);
  border-radius: 6px;
  background: var(--wv-ground);
  overflow: hidden;
  cursor: text; /* the classic insert cursor over open wave, like OcenAudio */
  touch-action: none;
  outline: none;
}
.tr-wave:focus-visible { box-shadow: 0 0 0 2px var(--wv-focus-ring); }
.tr-wave canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

/* ---- the sill ------------------------------------------------------------ */
/* The toggles, in a strip at the lane's FOOT (owner rulings, 2026-07-29 / 30).
   It sits inside the lane's border but spans the PLOT only — `left` and `width`
   come from custom properties the module publishes, because only the module
   knows where the plot begins (it moves with the channel rail on a stereo file).
   So it touches nothing you can click: not the wave above it, not the dB or
   meter gutters beside it, not the ruler or the minimap, which are a pan surface
   and a jump surface respectively.

   The lane's canvas is NOT overlaid — `laneArea()` shrinks the drawn height by
   exactly --wv-sill-h, so the strip sits over bare ground. Nothing is covered. */
.tr-wavesill {
  position: absolute;
  left: var(--wv-plot-x, 0px);
  width: var(--wv-plot-w, 100%);
  bottom: 0;
  height: var(--wv-sill-h, 20px);
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0 0.3rem;
  overflow: hidden;           /* never grow the lane; drop what will not fit */
  background: color-mix(in srgb, var(--wv-bar) 5%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--wv-scale) 22%, transparent);
  /* it is chrome, and must not read as a thing you can sweep */
  cursor: default;
}
.tr-wavesill[hidden] { display: none; }
/* folded: the strip goes, and one affordance stays so there is a way back */
/* folded: gone entirely. The fold button is not in here — it rides the edge row
   below the lane — so there is nothing left to keep on screen, and the lane gets
   every pixel back (owner report, 2026-07-30: a folded strip still took space). */
.tr-wavesill.tr-sill-folded { display: none; }

/* groups that come and go with what the recording can do. Positions are fixed:
   these appear and vanish in place and never re-order. */
.tr-sillgroup { display: inline-flex; align-items: center; gap: 0.35rem; }
.tr-sillgroup[hidden] { display: none; }
.tr-sillspacer { flex: 1 1 auto; min-width: 0.2rem; }
.tr-silllabel {
  font-family: var(--wv-mono);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  color: var(--wv-muted);
  white-space: nowrap;
}

/* Everything in the sill is one notch smaller than the same control was in the
   band — 20px of height is the whole budget, and it was accepted on the
   understanding that it buys the wave back when folded. */
.tr-wavesill .tr-wavetog { font-size: 0.68rem; gap: 0.22rem; }
.tr-wavesill .tr-wavetog select { font-size: 0.66rem; padding: 0 0.2rem; border-radius: 4px; }
.tr-wavesill .tr-wavezoom { border-radius: 4px; }
.tr-wavesill .tr-wavezoom button { font-size: 0.66rem; padding: 0 0.35rem; }
.tr-wavesill .tr-waveicon { padding: 0.05rem 0.25rem; border-radius: 4px; }
.tr-wavesill .tr-wavehelp { width: 15px; height: 15px; font-size: 0.6rem; }
.tr-wavesill .tr-waveswitch input[type="checkbox"] { width: 22px; height: 12px; border-radius: 7px; }
.tr-wavesill .tr-waveswitch input[type="checkbox"]::after { width: 8px; height: 8px; }
.tr-wavesill .tr-waveswitch input[type="checkbox"]:checked::after { left: 12px; }

/* ---- the transport extras, in the sill ----------------------------------- */
/* The volume mockingbird and the speed turtle — universal since 2026-07-30.
   They were ᏗᎪᏣᎳᎩᏍᎩ's slot extras; TOKENS.md records how seat 2's copy of them
   quietly drifted, which is why they are canonical now. Laid INLINE: the old
   strip's readout-above-the-bar column was three rows, and the sill is one.
   The steppers flank their bar (◀ bar ▶) instead of riding under it. */
.tr-volctl, .tr-speedctl { display: inline-flex; align-items: center; gap: 0.3rem; color: var(--wv-muted); min-width: 0; }
.tr-volctl .tr-volicon {
  display: inline-flex; align-items: center;
  border: none; background: none; padding: 0; margin: 0;
  color: inherit; cursor: pointer;
}
.tr-volctl .tr-volicon svg { display: block; width: 18px; height: 15px; }
.tr-volctl.boosted .tr-volicon { color: var(--wv-accent); } /* the bird warms with a boost */
.tr-volctl .val, .tr-speedctl .val {
  font-family: var(--wv-mono);
  font-size: 0.6rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; text-align: center;
  color: var(--wv-ink);
}
/* "200% (+6.0 dB)" reserves its widest reading, so the bar never shifts */
.tr-volctl .val { min-width: 3.9rem; }
.tr-speedctl .val { min-width: 2.1rem; }
/* a slim custom track + ball — native accent-color can't be sized down. A 4px
   track with the accent fill painted up to the thumb via --p (set in JS). */
.tr-volctl input[type="range"],
.tr-speedctl input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 4.6rem; height: 12px; margin: 0;
  background: transparent; cursor: pointer; --p: 100%;
}
.tr-volctl input[type="range"]::-webkit-slider-runnable-track,
.tr-speedctl input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 999px;
  background: linear-gradient(to right, var(--wv-accent) var(--p), var(--wv-border) var(--p));
}
.tr-volctl input[type="range"]::-webkit-slider-thumb,
.tr-speedctl input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; margin-top: -3.5px;
  width: 11px; height: 11px; border: none; border-radius: 50%; background: var(--wv-accent-hover);
}
.tr-volctl input[type="range"]::-moz-range-track,
.tr-speedctl input[type="range"]::-moz-range-track {
  height: 4px; border-radius: 999px; background: var(--wv-border);
}
.tr-volctl input[type="range"]::-moz-range-progress,
.tr-speedctl input[type="range"]::-moz-range-progress {
  height: 4px; border-radius: 999px; background: var(--wv-accent);
}
.tr-volctl input[type="range"]::-moz-range-thumb,
.tr-speedctl input[type="range"]::-moz-range-thumb {
  width: 11px; height: 11px; border: none; border-radius: 50%; background: var(--wv-accent-hover);
}
/* a boosted bar reads in the accent so it's obviously above the file's own
   level; muted greys out */
.tr-volctl.boosted .val { color: var(--wv-accent); }
.tr-volctl.muted .val { color: var(--wv-muted); }
.tr-step {
  background: none; border: none; margin: 0; padding: 0 1px;
  color: var(--wv-muted); font-size: 0.55rem; line-height: 1; cursor: pointer;
}
.tr-step:hover { color: var(--wv-accent); }
.tr-step:focus-visible { outline: 2px solid var(--wv-focus-ring); outline-offset: 1px; border-radius: 3px; }
/* Both turtles ride in the markup (the module may not name his shell's
   colours — the seam) and CSS shows one: in his shell at normal speed, out
   of it while a set speed is live. */
.tr-speedbtn {
  padding: 0 2px; border: none; background: none; cursor: pointer;
  display: inline-flex; align-items: center; line-height: 0;
}
.tr-speedbtn svg { display: block; width: 26px; height: 17px; }
.tr-speedbtn .tr-turtle-out { display: none; }
.tr-speedctl.open .tr-turtle-in { display: none; }
.tr-speedctl.open .tr-turtle-out { display: block; }
/* the speed set's space is ALWAYS reserved beside the turtle — to his LEFT now
   that he ends the sill — so clicking him only reveals it and nothing in the
   sill ever shifts (owner ruling, July 19). visibility (not display) keeps the
   width held; .open unhides. */
.tr-speedctl .tr-speedset { display: inline-flex; align-items: center; gap: 0.3rem; visibility: hidden; }
.tr-speedctl.open .tr-speedset { visibility: visible; }
/* The speed bar is BIPOLAR (owner ruling, July 20): 1× is dead centre, so the
   accent runs OUT FROM THE MIDDLE to the thumb rather than up from the left
   edge. --a/--b are the two stops (set in waveview.js); the first layer is
   the centre tick, so 1× can be found without reading the number. */
.tr-speedctl input[type="range"] { --a: 50%; --b: 50%; }
.tr-speedctl input[type="range"]::-webkit-slider-runnable-track {
  background:
    linear-gradient(to right, transparent calc(50% - 0.5px),
      color-mix(in srgb, var(--wv-knob) 75%, transparent) calc(50% - 0.5px),
      color-mix(in srgb, var(--wv-knob) 75%, transparent) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    linear-gradient(to right, var(--wv-border) var(--a), var(--wv-accent) var(--a),
      var(--wv-accent) var(--b), var(--wv-border) var(--b));
}
/* Firefox fills its own progress from the left, which a bipolar bar must not
   do — blank it and paint the same two-stop gradient on the track instead. */
.tr-speedctl input[type="range"]::-moz-range-track {
  background:
    linear-gradient(to right, transparent calc(50% - 0.5px),
      color-mix(in srgb, var(--wv-knob) 75%, transparent) calc(50% - 0.5px),
      color-mix(in srgb, var(--wv-knob) 75%, transparent) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    linear-gradient(to right, var(--wv-border) var(--a), var(--wv-accent) var(--a),
      var(--wv-accent) var(--b), var(--wv-border) var(--b));
}
.tr-speedctl input[type="range"]::-moz-range-progress { background: transparent; }
.tr-speedctl.slowed .val,
.tr-speedctl.boosted .val { color: var(--wv-accent); }

/* ---- the lane's bottom edge ---------------------------------------------- */
/* Two jobs in one row: the height grip, and the sill's fold button at the right
   end — sitting under the meter column, off the waveform entirely. The row is
   as tall as the GRIP alone (owner report, 2026-07-31: the fold button's full
   height here read as empty space between the sill and the transcript) — the
   button bottom-aligns and pokes up over the meter gutter's foot, which is a
   readout, not a click surface. */
.tr-waveedge {
  display: flex;
  /* bottom-aligned so the grip's hairline is the dock's LAST pixel row: with the
     row centred, the line floated above the row's own bottom and the host's
     panel edge showed as a second rule a few pixels under it (owner report,
     2026-07-30 — "those should really be the same line") */
  align-items: flex-end;
  gap: 0.3rem;
  margin-top: 0;
  height: 9px; /* the grip's height — the taller fold button overflows upward */
}
.tr-waveedge .tr-waveresize { flex: 1 1 auto; margin-top: 0; }

.tr-sillfold {
  flex: none;
  /* the lane is position:relative and would paint over the button's overflow;
     lift it one notch so the part riding up the meter gutter stays visible */
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 15px;
  padding: 0;
  border: 1px solid var(--wv-border);
  border-radius: 4px;
  background: none;
  color: var(--wv-muted);
  font: inherit;
  font-size: 0.6rem;
  line-height: 1;
  cursor: pointer;
}
.tr-sillfold:hover { color: var(--wv-ink); border-color: var(--wv-ink); }
.tr-sillfold[aria-expanded="false"] { color: var(--wv-accent); border-color: var(--wv-accent); }

/* the destructive band says out loud what it does — the one place a warning
   earns its space (owner ruling, 2026-07-30: separation is the safety) */
.tr-waveedit-warn {
  font-family: var(--wv-mono);
  font-size: 0.63rem;
  color: var(--wv-accent);
  white-space: nowrap;
}
.tr-wavemini {
  display: block;
  width: 100%;
  height: 30px; /* fixed overview strip — the resize handle grows the lane, not this */
  margin-top: 0.3rem;
  border: 1px solid var(--wv-border);
  border-radius: 5px;
  background: var(--wv-ground);
  cursor: pointer;
  touch-action: none;
}
.tr-wavemini[hidden] { display: none; }

/* Draggable bottom edge (owner ruling, July 16): the expanded panel's bottom
   line is a grab handle — drag down to grow the waveform lane, up to shrink
   back (js/waveview.js clamps). Height resets each load, display-toggle
   parity. */
.tr-waveresize {
  height: 9px;
  margin-top: 0.15rem;
  cursor: ns-resize;
  touch-action: none;
  /* the rule sits at the BOTTOM of the grab area, not through its middle, so it
     coincides with the dock's edge instead of hovering above it — one line where
     the wave ends and the transcript begins. The 8px above stay grabbable. */
  background: linear-gradient(to bottom, transparent 8px, var(--wv-rule) 8px, var(--wv-rule) 9px);
}
.tr-waveresize:hover,
.tr-waveresize.dragging {
  background: linear-gradient(to bottom, transparent 7px, var(--wv-rule-strong) 7px, var(--wv-rule-strong) 9px);
}
.tr-waveresize:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--wv-focus-ring); }

/* ---- the new-clip form --------------------------------------------------- */
.tr-newclip { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.35rem; }
.tr-newclip[hidden] { display: none; }
.tr-newclip .t {
  font-family: var(--wv-mono);
  font-size: 0.72rem;
  color: var(--wv-muted);
  white-space: nowrap;
}
.tr-newclip input {
  flex: 1;
  min-width: 8rem;
  font: inherit;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--wv-border);
  border-radius: 6px;
  background: var(--wv-surface);
  color: var(--wv-ink);
}
.tr-newclip button {
  font: inherit; font-size: 0.78rem; padding: 0.2rem 0.7rem;
  border: 1px solid var(--wv-border); border-radius: 6px;
  background: var(--wv-surface); color: var(--wv-ink); cursor: pointer;
}
.tr-newclip button:hover { border-color: var(--wv-accent); }
/* the gain form's dB field — a small right-aligned number, not the newclip
   text box's stretching line */
.tr-gainval { display: flex; align-items: center; gap: 0.3rem; font-size: 0.85rem; }
.tr-newclip .tr-gainval input { flex: none; width: 4.5rem; text-align: right; }
