/* --- Triad Trainer overrides -------------------------------------------------
   Everything structural (header, controls, fretboard grid, note circles, legend,
   left-handed view) comes from /static/triad_explorer/styles.css, which this page
   links first. Only the trainer-specific pieces live here.
   --------------------------------------------------------------------------- */

/* The explorer only ever styles `.hidden` per element id (e.g. #views-menu.hidden),
   so the trainer needs the generic rule for its own panels. */
.hidden {
    display: none !important;
}

/* --- Transport row ------------------------------------------------------- */

/* Root and scale sit side by side in the key group. Stacked, they would add a second
   row to the control card and push the transport down the page. */
.key-scale-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.trainer-transport {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.trainer-transport select,
.trainer-transport input[type="number"] {
    padding: 6px 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #f9f9f9;
    font-size: 14px;
    cursor: pointer;
}

/* The progression strip stands where the "Drill:" label used to be, so it copies the
   label's metrics exactly: removing the label must not close up the two button rows. */
.drill-progress {
    /* Exactly the metrics of a .control-group label (18px line box + 8px margin), so
       swapping the label for the strip cannot change the card's height by a pixel. */
    min-height: 18px;
    line-height: 18px;
    margin-bottom: 8px;
    font-size: 15px;
    font-weight: bold;
    letter-spacing: 1px;
    color: #777;
    white-space: nowrap;
    overflow: hidden;
}

/* Only progression mode reacts to a click (it draws another progression). */
.drill-progress.clickable {
    cursor: pointer;
}

.drill-progress.clickable:hover .numeral.current {
    text-decoration: underline;
}

/* The current chord is a filled pill, so it reads as a marker on a fixed line rather
   than as a numeral that replaced the others. */
.drill-progress .numeral.current {
    background-color: #3498db;
    color: #fff;
    border-radius: 3px;
    padding: 0 4px;
}

/* The progression's name is part of the fixed frame, so it sits between the quiet grey
   of the other numerals and the highlighted current one. */
.drill-progress .prog-name {
    color: #555;
    font-weight: bold;
}

/* A chord that position locking has left with no playable octave. */
.drill-progress .numeral.skipped {
    color: #ccc;
    text-decoration: line-through;
}

.drill-progress .sep {
    margin: 0 6px;
    color: #ccc;
    font-weight: normal;
}

/* Toolbar Tap button: sets the tempo, then shows it briefly. */
#tap-btn {
    min-width: 74px;
    font-weight: bold;
}

#tap-btn.showing-tempo {
    background-color: #3498db;
    border-color: #3498db;
    color: #fff;
}

/* The click-arm button lights while the click is armed; it follows Play. */
.click-arm-btn {
    font-size: 18px;
    line-height: 1;
    color: #333;
}

.click-arm-btn.active {
    background-color: #3498db;
    border-color: #3498db;
    color: #fff;
}

/* The metronome dial is a read-out now — the click is armed from the toolbar —
   so it must not look clickable. */
#metronome-button {
    cursor: default;
}

/* A control that cannot act (Play while no adjacent triple is free) must look inert. */
button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Muted strings recede, matching Triad Explorer. */
.string-name-label.muted {
    color: #bbb;
}

/* The beats control carries a short label ("2 beats"), so give it room. */
#beats-select {
    min-width: 104px;
}

/* --- Note layers -------------------------------------------------------- */

/* Two stacked layers inside #note-overlay-container: the optional grey key-tone
   layer and the always-present active-chord layer. Both fill the overlay exactly,
   so note coordinates are identical to before. */
.note-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

#active-note-layer {
    z-index: 2;
}

/* The key-tone layer must sit *under* the chord. Its notes inherit z-index 5 from the
   shared explorer stylesheet, and a positioned element with z-index auto does not create
   a stacking context, so those notes would paint above #active-note-layer (z-index 2) and
   bury the coloured chord notes under grey ones. Giving the layer its own context keeps
   everything inside it below the chord. */
#background-note-layer {
    z-index: 1;
}

/* A/B labels for the octaves of the current chord. */
#position-badge-layer {
    z-index: 3;
}

.position-badge {
    position: absolute;
    top: 2px;
    transform: translateX(-50%);
    padding: 1px 7px;
    border-radius: 9px;
    background-color: #2c3e50;
    color: #fff;
    font-size: 11px;
    font-weight: bold;
    line-height: 14px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* The overlay is mirrored in left-handed view; flip the badge text back upright. */
.left-handed-view .position-badge {
    transform: translateX(-50%) scaleX(-1);
}

/* The unit label sits between the input and the mode selector. */
.trainer-transport .unit {
    font-size: 13px;
    color: #555;
    margin-left: -4px;
}

/* Play and Pause are icon buttons, so their box is stated explicitly rather than being
   derived from a text label: the two must match each other exactly, and still line up
   with the text buttons beside them (8px padding + 13.33px line box + 1px border).
   The `.trainer-transport` prefix is load-bearing: the explorer stylesheet's
   `.control-group button` rule sets the grey face and is more specific than a bare
   class selector. */
.trainer-transport .transport-icon-btn {
    width: 40px;
    height: 34px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    line-height: 1;
    border-radius: 4px;
    border: 1px solid #3498db;
    background-color: #3498db;
    color: #fff;
    cursor: pointer;
    transition: all 0.2s ease-in-out;
}

.trainer-transport .transport-icon-btn:hover {
    filter: brightness(1.06);
}

/* Play is the primary action. While a run is active it becomes Stop, and says so in red
   exactly as the old text button did. */
#play-btn {
    font-weight: bold;
}

#play-btn.playing {
    background-color: #e74c3c;
    border-color: #e74c3c;
}

/* Pause is a secondary action: outlined while idle, filled while the run is frozen. */
#pause-btn {
    background-color: #f9f9f9;
    border-color: #ccc;
    color: #333;
}

#pause-btn.paused {
    background-color: #3498db;
    border-color: #3498db;
    color: #fff;
}

/* Step advances without starting the clock: always available, so it gets its own colour
   rather than borrowing the blue that means "start something". */
#step-btn {
    font-weight: bold;
    border: 1px solid #27ae60;
    background-color: #27ae60;
    color: #fff;
    transition: all 0.2s ease-in-out;
}

#step-btn:hover:not(:disabled) {
    background-color: #2eb567;
    border-color: #2eb567;
}

.trainer-checkbox {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 13px;
    color: #333;
    cursor: pointer;
}

/* --- Drill row and beat indicator --------------------------------------- */

/* The drill row spans the full width under the selectors: it holds the transport,
   the interval controls and the metronome trigger. */
.control-group-wide {
    flex-basis: 100%;
    margin-top: 4px;
}

/* Vertical rule separating the drill controls from the metronome controls. */
.trainer-sep {
    width: 1px;
    align-self: stretch;
    min-height: 24px;
    background-color: #ddd;
    margin: 0 4px;
}

.metro-label {
    font-weight: bold;
    font-size: 13px;
    color: #333;
}

/* One dot per beat until the next chord change, lighting cumulatively. The dots
   reuse the shared `.beat-dot` styling from the metronome. Hidden until playing so
   an idle row of empty dots does not look like dead UI. */
.drill-beat-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    height: 12px;
    margin: 8px auto 0 auto;
    opacity: 0;
    transition: opacity 0.15s ease-in-out;
}

.drill-beat-dots.active {
    opacity: 1;
}

.drill-beat-dots .beat-dot {
    width: 12px;
    height: 12px;
}

/* --- Fretboard ---------------------------------------------------------- */

/* 80px per fret means a 15-fret neck is wider than most windows. Scrolling keeps
   every fret reachable instead of clipping the high frets off the right edge. */
#fretboard-scroll {
    overflow-x: auto;
    overflow-y: hidden;
    max-width: 100%;
    /* Room for the board's drop shadow, which would otherwise be clipped by the
       scroll container. */
    padding: 10px 0 14px;
}

/* Inside the scroll wrapper the board is centred by the wrapper, so its own
   vertical margins (which would be clipped) are removed. */
#fretboard-scroll .fretboard-container {
    margin: 0 auto;
}

/* Defensive geometry: script.js positions each string absolutely, so `top` is the
   only per-string value it sets. Without this rule the strings would ALSO be laid
   out by the flexbox on #strings-and-frets, which pushes them outside the board. */
#strings-and-frets .string {
    position: absolute;
    width: 100%;
}

/* Open-string (fret 0) notes are drawn at x = -25px, which is exactly where the
   explorer puts its string labels, so the label disappears behind the dot. The
   trainer widens the board's left gutter and moves the labels outwards, leaving the
   fret-0 column and the label column both readable.
   Scoped to the right-handed view: the shared stylesheet's left-handed rules flip
   these offsets and already provide the matching gutter on the other side. */
#fretboard:not(.left-handed-view) {
    padding-left: 78px;
}

#fretboard:not(.left-handed-view) #note-overlay-container {
    left: 78px;
}

#fretboard:not(.left-handed-view) .string-name-label {
    left: -52px;
}

/* --- Detail panel ------------------------------------------------------- */

#trainer-detail {
    max-width: 900px;
    margin: 0 auto 20px auto;
    padding: 12px 18px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
    text-align: center;
}

#detail-headline {
    display: flex;
    justify-content: center;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 18px;
    font-weight: bold;
    color: #2c3e50;
}

#detail-inversion,
#detail-frets {
    font-size: 13px;
    font-weight: normal;
    color: #7f8c8d;
}

#detail-notes {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 10px;
}

.detail-note {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border: 1px solid #eee;
    border-radius: 20px;
    background-color: #fafafa;
    font-size: 14px;
}

.detail-swatch {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex-shrink: 0;
}

.detail-note-name {
    font-weight: bold;
}

.detail-interval {
    color: #555;
}

.detail-interval-name {
    color: #888;
    font-size: 12px;
}

.detail-position {
    color: #aaa;
    font-size: 12px;
    border-left: 1px solid #ddd;
    padding-left: 8px;
}

/* Errors and notices about the current selection. */
#status-caption {
    min-height: 16px;
    margin-top: 8px;
    font-size: 13px;
    color: #7f8c8d;
}

/* Blockers and failures are called out; plain information is not. */
#status-caption.caption-warning {
    color: #e74c3c;
}

/* --- Notes -------------------------------------------------------------- */

/* The three active notes get a dark halo so they read instantly against the
   greyed-out background notes. */
.note.trainer-active {
    box-shadow: 0 0 0 3px rgba(44, 62, 80, 0.75), 0 4px 10px rgba(0, 0, 0, 0.35);
    z-index: 6;
}

/* --- Position chips ----------------------------------------------------- */

#position-select button {
    min-width: 54px;
    /* "fret 12" must not wrap onto two lines. */
    white-space: nowrap;
}

/* String-set chips are labelled with note names ("G–B–E"), so they need to be
   wider than the 50px the explorer's shared button-grid rule imposes. */
/* An inversion or position that does not exist for the current chord/string set
   is disabled rather than silently doing nothing. */
.button-grid button:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
