/***
 * The EPSWave theme, shared by every page.
 *
 * This used to be a <style> block inside index.html. It moved out when the
 * librarian became a second page, because two pages carrying their own copy of
 * a hand written dark theme drift apart within about a week.
 *
 * Bootstrap 4 has no dark theme, so what follows is a set of explicit
 * overrides for the components in use. If you add a Bootstrap component to any
 * page, check it against body.dark before calling it done.
 */

/* Everything below is scoped to body.dark.

   color-scheme covers the parts the browser draws itself and no rule of
   ours can reach: scrollbars, number input spinners, and in Firefox the
   popup list of a <select>. Without it Firefox leaves all of those
   white on the dark page. */
body.dark { color-scheme: dark; background-color: #12151a; color: #c8ced6; }
body.dark h2, body.dark h5, body.dark h6,
body.dark b, body.dark strong { color: #e6ebf1; }
body.dark .modal-content { background-color: #1b1f26; border-color: #2b323c; }
body.dark .modal-header, body.dark .modal-footer { border-color: #2b323c; }
body.dark .modal-body hr { border-top-color: #2b323c; }
/* Bootstrap's close button is a black glyph with a white text-shadow,
   which on a dark panel leaves a faint smudge and nothing else. */
body.dark .close { color: #e6ebf1; text-shadow: none; opacity: .7; }
body.dark .close:hover { color: #ffffff; opacity: 1; }
body.dark .card { background-color: #1b1f26; border-color: #2b323c; }
body.dark .card-header { background-color: #232830; border-color: #2b323c; color: #e6ebf1; }
body.dark .form-control,
body.dark .custom-select,
body.dark textarea.form-control { background-color: #0f1319; color: #d5dbe3; border-color: #333b47; }
body.dark .form-control:focus,
body.dark .custom-select:focus { background-color: #0f1319; color: #eef2f6; border-color: #4a5568; }
body.dark .form-control::placeholder { color: #6b7482; }
body.dark .input-group-text { background-color: #232830; color: #c8ced6; border-color: #333b47; }
body.dark .custom-file-label { background-color: #0f1319; color: #a9b2bd; border-color: #333b47; }
body.dark .custom-file-label::after { background-color: #232830; color: #d5dbe3; border-color: #333b47; }
body.dark .dropdown-menu { background-color: #1b1f26; border-color: #333b47; }
body.dark .dropdown-item { color: #c8ced6; }
body.dark .dropdown-item:hover, body.dark .dropdown-item:focus { background-color: #2a303a; color: #ffffff; }
body.dark .dropdown-item.disabled { color: #5d6673; }
body.dark .dropdown-divider { border-top-color: #333b47; }
body.dark .btn-outline-secondary { color: #aeb6c0; border-color: #3c4553; }
body.dark .btn-outline-secondary:hover { background-color: #2f3640; color: #ffffff; border-color: #4a5568; }
body.dark .btn-secondary { background-color: #4a5568; border-color: #4a5568; }
body.dark .alert-warning { background-color: #3a3320; color: #f0d9a0; border-color: #5c4f2c; }
body.dark .alert-secondary { background-color: #232830; color: #c8ced6; border-color: #333b47; }
body.dark .alert-success { background-color: #1c3323; color: #a7dbb4; border-color: #2f5b3c; }
body.dark .alert-danger { background-color: #3a2124; color: #eda9ae; border-color: #5f3238; }
body.dark .text-muted { color: #8b95a1 !important; }
body.dark .custom-control-label { color: #c8ced6; }
body.dark a { color: #6fb8ff; }

/* Wavesample name fields, dressed as the synth's own display.

   The EPS shows upper case only, so the field is upper cased here as
   well as in the JS that feeds it: the CSS keeps what is on screen
   honest even for a keystroke the input handler has not seen yet.
   Letter spacing keeps a little air between the twelve character cells,
   the way the FIP 22AM5R glass does. Swapping the face out later means
   changing the url and the family name here and nothing else. */
@font-face {
    font-family: 'EnsoniqVFD';
    src: url('./fonts/EnsoniqVFD-Organic.otf') format('opentype');
    font-display: swap;
}
.eps-name {
    font-family: 'EnsoniqVFD', monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
/* Qualified with .form-control so it outranks Bootstrap's
   .form-control-sm, which the fields under the Create buttons carry and
   which would otherwise set the size back to 0.875rem.

   Bootstrap sizes inputs as 1.5em plus padding. This face does not fill
   its em square, so that formula leaves a band of empty glass above and
   below the segments. Line-height 1 and a short pad hug the electrodes;
   height:auto stops the sm group from stretching the box back open. */
.eps-name.form-control,
.form-control-sm.eps-name,
.input-group-sm > .form-control.eps-name {
    font-size: 1.15rem;
    line-height: 1;
    height: auto;
    padding: 0.15rem 0.4rem;
}
.input-group-sm:has(> .eps-name) > .input-group-prepend > .input-group-text {
    height: auto;
    padding-top: 0.15rem;
    padding-bottom: 0.15rem;
}
/* Light mode: a passive LCD, dark segments on a grey green panel. */
.eps-name.form-control {
    background-color: #cfd8b9;
    color: #1e2416;
    border-color: #9aa585;
}
.eps-name.form-control:focus {
    background-color: #d9e2c2;
    color: #1e2416;
    border-color: #7c8869;
    box-shadow: none;
}
/* Dark mode: the vacuum fluorescent display it actually is. The glow is
   a text-shadow rather than a filter so the characters stay crisp. */
body.dark .eps-name.form-control,
body.dark .eps-name.form-control:focus {
    background-color: #000000;
    color: #3dff9e;
    border-color: #26463a;
    text-shadow: 0 0 6px rgba(61, 255, 158, 0.55);
}
body.dark .eps-name.form-control:focus { border-color: #3dff9e; box-shadow: none; }
body.dark .eps-name.form-control::placeholder { color: #17663f; text-shadow: none; }
.eps-name.form-control::placeholder { color: #7b8768; }

/* Wave editor toolbar. Bootstrap's justify-content-between shares the
   free space out between the button groups, so anything on the row that
   changes width — as the readout used to, every time you zoomed — walks
   the buttons sideways under the pointer. The groups pack to the left
   and stay put. */
.we-toolbar { justify-content: flex-start; }

/* Waveform on the left, frequency domain on the right, sharing the row
   evenly. Both are flex items at a zero basis with min-width:0, so
   neither canvas can claim more than its half from its own intrinsic
   width, and hiding the spectrum gives the whole row back to the
   waveform with nothing else to adjust. */
.we-split { display: flex; align-items: stretch; }
.we-split > canvas { flex: 1 1 0; min-width: 0; }
.we-split > .we-spectrum { margin-left: 0.5rem; }

/* The scroll bar under the toolbar belongs to the waveform, so with the
   spectrum showing it stops where the waveform does rather than running
   on under a display it has nothing to do with. Half the row less half
   the gap between the two canvases, matching the flex split above.
   Qualified with .custom-range to outrank Bootstrap's width:100%. */
.custom-range.we-scroll-half { width: calc(50% - 0.25rem); }

/* The Spectrum checkbox shares a row with button groups, so it needs
   centring against them rather than sitting on the text baseline. */
.we-spec-toggle { display: inline-flex; align-items: center; }
.we-spec-toggle .custom-control-label { white-space: nowrap; }

/* The readout under the canvas. Two rows, both of them reserved whether
   or not they have anything to say, so that a selection appearing or an
   edit reporting itself cannot move the page: the length and the scale
   on top, the selected range and any status underneath.

   width:0 with min-width:100% is the point of the block. It lays out at
   the full width of the canvas above it, but it offers nothing to the
   intrinsic width of the column it sits in — Bootstrap's columns are
   flex items with no min-width:0 of their own, so a line of text that
   will not wrap can otherwise widen the column past its share and shove
   its neighbours sideways. Everything here ellipsizes into the width it
   is given instead. */
.we-readout {
    width: 0;
    min-width: 100%;
    margin-top: 0.25rem;
    line-height: 1.15rem;
}
.we-readout small { font-size: 0.75rem; }
.we-readout-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    min-width: 0;
    min-height: 1.15rem;
}
/* Both halves are laid out at zero basis so neither can push the other
   off its end of the row. */
.we-readout .we-info {
    flex: 1 1 0;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Tabular figures so the division numbers do not jitter as they count. */
.we-readout .we-scale {
    flex: 0 1 auto;
    min-width: 0;
    padding-left: 0.75rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: right;
    font-variant-numeric: tabular-nums;
    cursor: help;
}
.we-readout .we-detail {
    display: block;
    min-height: 1.15rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The status panel above the tabs, in the same typeface and the same two
   palettes as the name fields, because it is the same idea: this is what
   the machine is doing, shown the way the machine would show it. One
   panel for the page rather than one per tab, since a transfer runs for
   minutes and the tab that started it is often not the one on screen by
   the time it ends. */
.eps-lcd {
    font-family: 'EnsoniqVFD', monospace;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.5rem 0.75rem;
    border: 1px solid #9aa585;
    border-radius: 0.25rem;
    background-color: #cfd8b9;
    color: #1e2416;
}
.eps-lcd-line {
    font-size: 1.2rem;
    /* Reserved, so an empty status does not shorten the panel and move the
       tabs under the pointer. */
    min-height: 1.6rem;
    line-height: 1.6rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.eps-lcd-bar {
    height: 0.5rem;
    margin-top: 0.4rem;
    border: 1px solid #9aa585;
    background-color: #bcc6a4;
    overflow: hidden;
}
.eps-lcd-bar > div {
    height: 100%;
    width: 0;
    background-color: #1e2416;
    transition: width 0.2s linear;
}
/* Nothing running: the trough stays, so the panel keeps its height, but
   it reads as off rather than as nought percent of something. */
.eps-lcd-bar.eps-progress-idle { opacity: 0.35; }

/* Debug mode folds the page away between the status panel and the probes, so
 * that a probe session is the ports, the status, the probes and the log with
 * nothing in between. Applied by EPSWaveUI.hideBetween, and !important because
 * some of what it covers is shown by Bootstrap's own display utilities. */
.eps-debug-hidden { display: none !important; }

body.dark .eps-lcd {
    background-color: #000000;
    color: #3dff9e;
    border-color: #26463a;
    text-shadow: 0 0 6px rgba(61, 255, 158, 0.55);
}
body.dark .eps-lcd-bar {
    background-color: #06120c;
    border-color: #26463a;
}
body.dark .eps-lcd-bar > div {
    background-color: #3dff9e;
    box-shadow: 0 0 6px rgba(61, 255, 158, 0.55);
}

/* MIDI activity lights, one in each port label: green for what arrives, red
   for what leaves. Off is a dark recessed dot rather than nothing at all,
   because a light that never lights only means something if you can see it
   sitting there not lighting — which is the whole question when someone is
   working out why a transfer is doing nothing. */
.eps-led {
    display: inline-block;
    width: 0.6rem;
    height: 0.6rem;
    margin-left: 0.45rem;
    vertical-align: middle;
    border-radius: 50%;
    background-color: #cfd4da;
    border: 1px solid rgba(0, 0, 0, 0.3);
    /* Lighting is instant, going dark takes a moment. A single short packet
       is over in well under one frame, so a symmetric transition would be a
       flash nobody sees. */
    transition: background-color 0.3s ease-out, box-shadow 0.3s ease-out;
}
.eps-led-on { transition: none; }
.eps-led-in.eps-led-on {
    background-color: #2ee66b;
    box-shadow: 0 0 6px rgba(46, 230, 107, 0.9);
}
.eps-led-out.eps-led-on {
    background-color: #ff3b30;
    box-shadow: 0 0 6px rgba(255, 59, 48, 0.9);
}
/* Deliberately not themed. Dark mode recolours the panels around these, but an
   unlit light wants to stay a light grey dot in both: sunk to the background it
   is invisible, and a light you cannot find when it is off tells you nothing
   when it fails to come on. */

/* The waveform tabs. The close cross only appears on the tab it belongs
   to, so a strip of eight is a strip of names rather than a row of
   crosses. */
.wave-tabs .nav-link { cursor: pointer; padding-right: 0.5rem; }
.wave-tab-close {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0 0.25rem;
    opacity: 0;
    font-weight: bold;
}
.wave-tabs .nav-item:hover .wave-tab-close,
.wave-tabs .nav-link.active .wave-tab-close { opacity: 0.55; }
.wave-tab-close:hover { opacity: 1 !important; color: #dc3545; }
/* Dragging a tab reorders it, and the order is what a transwave is
   concatenated in, so it wants to look draggable. */
.wave-tab { cursor: grab; }
.wave-tab-dragging { opacity: 0.4; }
.wave-tab-add { font-weight: bold; }

/* Expanded event log. The height is the viewport less the room the card
   header, the checkbox row and the page margins take, so the textarea
   fills what is left of the screen and the whole card still fits
   without the page itself scrolling. rows= on the textarea loses to
   this, which is the point. */
#log.log-expanded { height: calc(100vh - 13rem); min-height: 12rem; }
