/* montebaur.tech — Interactive Morse code tree
 * Companion stylesheet for media/morse-viz/morse.js. The palette intentionally
 * mirrors mtb_tech_style.css so the visualization sits naturally inside the
 * dark site theme.
 */

/* The tree sits in the same kind of dark panel as the controls and
 * transcript rows below, so the three blocks share a visual rhythm. The
 * inset top highlight is a one-pixel light line that subtly suggests
 * depth without introducing new colours. */
.morse-viz {
  display: block;
  margin: 14px 0;
  padding: 12px 14px;
  background-color: #1c1c1c;
  border: 1px solid #3a3a3a;
  border-radius: 6px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

/* Static, two-column "Controls" cheat sheet shown above the tree. The
 * grid's middle 1px column is the vertical divider between input modes;
 * on narrow screens the columns wrap underneath each other and the
 * divider becomes a thin horizontal line below the first column. */
.morse-help {
  margin: 14px 0;
  padding: 10px 14px 12px;
  background-color: #1c1c1c;
  border: 1px solid #3a3a3a;
  border-radius: 6px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  font-family: sans-serif;
  font-size: 13px;
  color: #c4c4c4;
}

.morse-help-cols {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  gap: 0 18px;
}

/* The middle column is just the divider line. */
.morse-help-cols::before {
  content: "";
  grid-column: 2;
  grid-row: 1;
  background-color: #3a3a3a;
  width: 1px;
  justify-self: center;
}

.morse-help-col-title {
  font-weight: 600;
  color: #d7bb7d;
  margin-bottom: 4px;
}

.morse-help-col ul {
  margin: 0;
  padding-left: 18px;
  list-style: disc;
}

.morse-help-col li {
  margin: 2px 0;
}

/* Inline keycap-style chip for kbd hints inside the help panel. */
.morse-kbd {
  display: inline-block;
  padding: 0 6px;
  min-width: 16px;
  text-align: center;
  background-color: #2b2d35;
  border: 1px solid #6f6f6f;
  border-radius: 4px;
  font-family: monospace;
  font-size: 12px;
  color: #f3f3f3;
  line-height: 1.6;
}

/* On narrow viewports, drop the vertical divider and stack the columns. */
@media (max-width: 520px) {
  .morse-help-cols {
    grid-template-columns: 1fr;
    gap: 8px 0;
  }
  .morse-help-cols::before {
    display: none;
  }
}

.morse-svg {
  width: 100%;
  height: auto;
  display: block;
  /* Caps the rendered size on wide screens; on narrow screens the SVG
     scales down with its container thanks to width: 100%. */
  max-width: 620px;
  margin: 0 auto;
}

/* === Edges === */

.morse-edge {
  stroke: #6f6f6f;
  stroke-width: 1.4;
  stroke-linecap: round;
  fill: none;
  /* Smoothly cross-fade between inactive / active states instead of
     popping on each keystroke. */
  transition: stroke 140ms ease, stroke-width 140ms ease,
              filter 140ms ease;
}

/* === Nodes === */

.morse-shape {
  fill: #9a9a9a;
  stroke: none;
  transition: fill 140ms ease, filter 140ms ease;
}

.morse-shape-root {
  fill: #d7bb7d;
}

.morse-label {
  fill: #c4c4c4;
  font-family: sans-serif;
  font-size: 14px;
  font-weight: 600;
  user-select: none;
  transition: fill 140ms ease, filter 140ms ease;
}

/* === Active path / current node ===
 * The active path glows in the accent green; the current node (the leaf of
 * the path so far) glows in the warmer accent gold so it stands out against
 * the rest of the highlighted chain. The glow is a CSS drop-shadow filter
 * which follows each shape's outline, including the dash pills and the
 * triangular root.
 */

.morse-edge.active {
  stroke: #b5cea8;
  stroke-width: 2;
  filter: drop-shadow(0 0 3px #b5cea8);
}

.morse-shape.active {
  fill: #b5cea8;
  filter: drop-shadow(0 0 4px #b5cea8);
}

.morse-label.active {
  fill: #b5cea8;
}

.morse-shape.current,
.morse-label.current {
  fill: #d7bb7d;
}

.morse-shape.current {
  filter: drop-shadow(0 0 5px #d7bb7d);
  animation: morse-pulse 1.8s ease-in-out infinite alternate;
}

.morse-label.current {
  filter: drop-shadow(0 0 4px rgba(215, 187, 125, 0.6));
}

/* A slow, low-amplitude pulse on the current node. It's the only moving
 * thing on the page and only runs while the user has typed something, so
 * it suggests "live cursor" without becoming a distraction. */
@keyframes morse-pulse {
  from { filter: drop-shadow(0 0 4px rgba(215, 187, 125, 0.55)); }
  to   { filter: drop-shadow(0 0 8px rgba(215, 187, 125, 0.95)); }
}

@media (prefers-reduced-motion: reduce) {
  .morse-edge,
  .morse-shape,
  .morse-label {
    transition: none;
  }
  .morse-shape.current {
    animation: none;
  }
}

/* === Controls (status readout + buttons) === */

.morse-controls {
  margin: 14px 0;
  font-family: sans-serif;
}

.morse-status {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 28px;
  margin-bottom: 10px;
  padding: 8px 14px;
  background-color: #1c1c1c;
  border: 1px solid #3a3a3a;
  border-radius: 6px;
}

.morse-status-pair {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.morse-status-label {
  color: #979797;
  font-size: 14px;
}

/* The value spans share a fixed line-height so the row keeps the same
 * height whether they're empty (`\u00a0` placeholder set from JS) or
 * filled. Without this, switching from empty to a 22px monospace glyph
 * would push the whole status row taller. */
.morse-sequence,
.morse-letter,
.morse-key {
  font-family: monospace;
  font-weight: bold;
  display: inline-block;
  line-height: 1.2;
}

.morse-sequence {
  font-size: 18px;
  font-weight: normal;
  letter-spacing: 4px;
  color: #b5cea8;
  min-width: 90px;
}

.morse-letter {
  font-size: 22px;
  color: #d7bb7d;
  min-width: 22px;
}

/* Live indicator while X (or the on-screen "Key" button) is held: shows
 * `·` while the press is below the dot/dash threshold and `–` once the
 * press has crossed it. Empty when nothing is held; the fixed min-width
 * keeps the row from jumping horizontally as the glyph appears. */
.morse-key {
  font-size: 22px;
  color: #d7bb7d;
  min-width: 22px;
}

.morse-key.morse-key-dot {
  color: #b5cea8;
}

.morse-key.morse-key-dash {
  color: #d7bb7d;
}

.morse-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.morse-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background-color: #2b2d35;
  border: 1px solid #6f6f6f;
  border-radius: 6px;
  color: #f3f3f3;
  font-family: sans-serif;
  font-size: 14px;
  cursor: pointer;
  user-select: none;
  /* min-height keeps tap targets touch-friendly on mobile */
  min-height: 38px;
  transition: background-color 0.1s, border-color 0.1s;
}

.morse-btn:hover {
  background-color: #3a3d47;
  border-color: white;
}

.morse-btn:active {
  background-color: #4a4d57;
}

/* The keyer is press-and-hold rather than click. The :active pseudo-class
 * gives an extra accent ring so the held state is unmistakable. */
.morse-btn-key:active {
  background-color: #4a4d57;
  border-color: #b5cea8;
}

.morse-btn:focus-visible {
  outline: 2px solid #98e2ff;
  outline-offset: 2px;
}

.morse-btn-icon {
  font-size: 18px;
  line-height: 1;
  color: #b5cea8;
}

.morse-btn-backspace .morse-btn-icon {
  color: #c4c4c4;
}

/* === Transcript === */

.morse-transcript {
  margin: 14px 0;
  font-family: sans-serif;
}

.morse-transcript-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background-color: #1c1c1c;
  border: 1px solid #3a3a3a;
  border-radius: 6px;
}

.morse-transcript-label {
  color: #979797;
  font-size: 14px;
}

.morse-transcript-text {
  flex: 1 1 0;
  min-width: 100px;
  font-family: monospace;
  font-size: 18px;
  color: #b5cea8;
  letter-spacing: 1px;
  white-space: pre-wrap;
  word-break: break-word;
}

.morse-transcript-text.empty {
  color: #6f6f6f;
}

.morse-btn-clear {
  margin-left: auto;
}

.morse-btn-clear .morse-btn-icon {
  color: #c4c4c4;
  font-size: 14px;
}
