/* ombaware — gruvbox dark.
 *
 * House rule, per the spec: no gradients, no glow, no effects. That means no
 * linear-gradient, no box-shadow, no text-shadow, no filter, no transition, no
 * animation, and no border-radius. Depth is background steps plus 1px borders,
 * which is how gruvbox is meant to read anyway. The only opacity below 1 is the
 * anti-stuck slice, which the spec explicitly calls translucent.
 *
 * Every colour is a var(--gb-*) written onto :root by js/theme.js.
 */

* { box-sizing: border-box; }

html, body {
    margin: 0;
    height: 100%;
    overflow: hidden;
    background: var(--gb-bg0h);
    color: var(--gb-fg1);
    font: 13px/1.4 ui-monospace, "Cascadia Mono", Consolas, "DejaVu Sans Mono", monospace;
}

body { display: flex; flex-direction: column; }

main { flex: 1; min-height: 0; display: flex; }
.view { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.view[hidden] { display: none; }

/* ---------- controls ---------- */

button, select, input {
    font: inherit;
    color: var(--gb-fg1);
    background: var(--gb-bg1);
    border: 1px solid var(--gb-bg2);
    padding: 4px 10px;
    border-radius: 0;
}

button { cursor: pointer; min-height: 30px; }
button:hover:not(:disabled) { background: var(--gb-bg2); }
button:active:not(:disabled) { background: var(--gb-bg3); }
button:disabled, input:disabled, select:disabled {
    color: var(--gb-bg4);
    background: var(--gb-bg0);
    cursor: default;
}
button.ghost { background: var(--gb-bg0); color: var(--gb-fg4); }
button.toggle[aria-pressed="true"] { background: var(--gb-bg3); color: var(--gb-fg0); }
button.wide { width: 100%; }
button.primary { background: var(--gb-nAqua); color: var(--gb-bg0h); border-color: var(--gb-aqua); }
button.primary:hover:not(:disabled) { background: var(--gb-aqua); }
/* Same specificity as button:disabled and declared later, so it has to repeat
 * the disabled look or a busy primary button still reads as clickable. */
button.primary:disabled { background: var(--gb-bg0); color: var(--gb-bg4); border-color: var(--gb-bg2); }

input[type="number"] { width: 7em; text-align: right; }

input[type="range"] {
    -webkit-appearance: none; appearance: none;
    background: transparent; padding: 0; border: 0; height: 18px;
}
input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: var(--gb-bg2); }
input[type="range"]::-moz-range-track { height: 4px; background: var(--gb-bg2); }
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 12px; height: 18px; margin-top: -7px; background: var(--gb-orange); border: 0;
}
input[type="range"]::-moz-range-thumb { width: 12px; height: 18px; background: var(--gb-orange); border: 0; border-radius: 0; }
input[type="range"]:disabled::-webkit-slider-thumb { background: var(--gb-bg4); }
input[type="range"]:disabled::-moz-range-thumb { background: var(--gb-bg4); }

.group { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
/* display:flex outranks the UA rule for [hidden], so restate it. Without this
 * both toolbars show at once. */
.group[hidden] { display: none; }
.sep { width: 1px; align-self: stretch; background: var(--gb-bg2); margin: 2px 4px; }
.spacer { flex: 1; }
.muted { color: var(--gb-fg4); }
.warn { color: var(--gb-yellow); }
.field { display: flex; gap: 6px; align-items: center; color: var(--gb-fg4); }
.hint { color: var(--gb-fg4); }

/* ---------- toolbar ---------- */

.toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 8px; padding: 6px 8px;
    background: var(--gb-bg0);
    border-bottom: 1px solid var(--gb-bg2);
    flex-wrap: wrap;
}
.toolbar-left, .toolbar-right { display: flex; align-items: center; gap: 8px; }

.status { padding: 0 6px; }
.status-off { color: var(--gb-red); }
.status-on { color: var(--gb-green); }
.status-busy { color: var(--gb-yellow); }

/* ---------- configurator ---------- */

#view-configurator { overflow-y: auto; }
.cfg-stack {
    display: flex; flex-direction: column; gap: 8px;
    padding: 8px; max-width: 760px; width: 100%; margin: 0 auto;
}
.panel { background: var(--gb-bg0); border: 1px solid var(--gb-bg2); padding: 8px; }

.notice {
    margin: 0;
    padding: 8px;
    background: var(--gb-bg0);
    border: 1px solid var(--gb-bg3);
    border-left: 3px solid var(--gb-yellow);
    color: var(--gb-fg2);
}

/* ---------- blackbox ---------- */

.bb-header {
    display: flex; align-items: center; gap: 10px;
    padding: 5px 8px;
    background: var(--gb-bg0);
    border-bottom: 1px solid var(--gb-bg2);
}

.bb-body { flex: 1; min-height: 0; display: flex; }

.graph-display {
    position: relative; flex: 1; min-width: 0;
    background: #000;
    overflow: hidden;
    touch-action: none;
    cursor: grab;
}
.graph-display.dragging { cursor: grabbing; }
.graph-display > video,
.graph-display > canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.graph-display > video { object-fit: contain; background: #000; }
.graph-display > canvas { z-index: 1; }

.seekbar-fixed {
    position: absolute; top: 0; bottom: 0; left: 50%;
    width: 2px; margin-left: -1px;
    background: var(--gb-red);
    z-index: 2; pointer-events: none;
}

.overlays { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.overlay {
    position: absolute; pointer-events: auto;
    background: var(--gb-bg0h); border: 1px solid var(--gb-bg2);
    padding: 6px; cursor: move;
}
.overlay[hidden] { display: none; }

.empty {
    position: absolute; inset: 0; z-index: 2;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px; text-align: center; pointer-events: none;
}
/* display:flex above outranks the UA rule for [hidden], so say it again. */
.empty[hidden] { display: none; }
.graph-display.drop-target { outline: 2px dashed var(--gb-aqua); outline-offset: -6px; }

/* The legend must be exactly as tall as the graph canvas, because both are laid
 * out by the same layoutRows() call. Anything stealing height from .legend-rows
 * (a button in the flow, padding) shifts every row out of step with its graph,
 * so the rows own the whole box and the button floats over the bottom corner. */
.legend {
    width: 230px; flex: none;
    position: relative;
    background: var(--gb-bg0);
    border-left: 1px solid var(--gb-bg2);
}
.legend-rows { position: absolute; inset: 0; }
.legend > button { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; }
.legend-row {
    position: absolute; left: 0; right: 0;
    padding: 2px 6px; overflow: hidden;
    border-bottom: 1px solid var(--gb-bg1);
}
.legend-title { color: var(--gb-fg4); font-size: 11px; }
.legend-item { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.legend-swatch { width: 10px; height: 2px; flex: none; }
.legend-name { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.legend-value { color: var(--gb-fg0); }

.video-sync { height: 12px; background: var(--gb-bg0); position: relative; }
.video-bar {
    position: absolute; top: 2px; bottom: 2px;
    background: var(--gb-nBlue); border: 1px solid var(--gb-blue);
    cursor: ew-resize; touch-action: none;
}

.timeline {
    display: block; width: 100%; height: 44px; flex: none;
    background: var(--gb-bg0); border-top: 1px solid var(--gb-bg2);
    touch-action: none; cursor: pointer;
}

.bb-footer {
    display: flex; gap: 16px; align-items: center;
    padding: 4px 8px; flex: none;
    background: var(--gb-bg0); border-top: 1px solid var(--gb-bg2);
}

/* ---------- dialogs ---------- */

dialog {
    background: var(--gb-bg0);
    color: var(--gb-fg1);
    border: 1px solid var(--gb-bg3);
    border-radius: 0;
    padding: 0;
    max-width: min(760px, 94vw);
    max-height: 90vh;
}
dialog::backdrop { background: rgba(0, 0, 0, 0.6); }

.dlg-head {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 8px 12px;
    background: var(--gb-bg1); border-bottom: 1px solid var(--gb-bg2);
}
.dlg-title { color: var(--gb-fg0); }
.dlg-body { padding: 12px; overflow: auto; max-height: 66vh; }
.dlg-foot {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 8px 12px;
    background: var(--gb-bg1); border-top: 1px solid var(--gb-bg2);
}

/* config popup */
.cfg-group { margin-bottom: 14px; }
.cfg-group > h3 {
    margin: 0 0 6px; padding-bottom: 3px;
    font-size: 12px; font-weight: normal; color: var(--gb-yellow);
    border-bottom: 1px solid var(--gb-bg2);
}
/* label, slider, number, unit, help — five columns for five children, or the
 * help button wraps onto a row of its own and stretches. */
.cfg-row { display: grid; grid-template-columns: 11em 1fr auto auto auto; gap: 8px; align-items: center; margin-bottom: 4px; }
.cfg-row > label { overflow: hidden; text-overflow: ellipsis; }
.cfg-unit { color: var(--gb-fg4); width: 3.5em; }
.cfg-help { grid-column: 1 / -1; color: var(--gb-fg4); font-size: 11px; padding: 0 0 4px 2px; }

/* read-only config, as recorded in a log header */
.cfg-view-row { display: grid; grid-template-columns: 13em 7em 3.5em 1fr; gap: 8px; align-items: baseline; }
.cfg-view-value { text-align: right; color: var(--gb-fg1); }
.cfg-view-row.changed .cfg-view-key,
.cfg-view-row.changed .cfg-view-value { color: var(--gb-purple); }
.cfg-view-default { font-size: 11px; }
.cfg-help[hidden] { display: none; }
.help-btn { min-height: 0; padding: 0 6px; background: var(--gb-bg0); color: var(--gb-fg4); }

/* joystick */
.joy-wrap { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.joy { touch-action: none; background: var(--gb-bg0h); border: 1px solid var(--gb-bg2); }

/* remote log picker */
.log-list { width: 100%; border-collapse: collapse; }
.log-list th { text-align: left; color: var(--gb-fg4); font-weight: normal; border-bottom: 1px solid var(--gb-bg2); }
.log-list td, .log-list th { padding: 3px 8px 3px 0; }
.log-list tr[aria-selected="true"] { background: var(--gb-bg2); }
.log-list tbody tr { cursor: pointer; }
.log-list tbody tr:hover { background: var(--gb-bg1); }

.progress { height: 10px; background: var(--gb-bg1); border: 1px solid var(--gb-bg2); }
.progress > div { height: 100%; background: var(--gb-aqua); }

/* graph setup */
.gs-graph { border: 1px solid var(--gb-bg2); margin-bottom: 8px; }
.gs-graph-head { display: flex; align-items: center; gap: 8px; padding: 4px 8px; background: var(--gb-bg1); }
.gs-graph-head > span { flex: 1; color: var(--gb-fg0); }
.gs-fields { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 8px; }
.gs-chip { display: flex; align-items: center; gap: 5px; padding: 2px 6px; background: var(--gb-bg1); border: 1px solid var(--gb-bg2); }
.gs-chip button { min-height: 0; padding: 0 4px; background: none; border: 0; color: var(--gb-fg4); }
.gs-dot { width: 8px; height: 8px; flex: none; }

/* ---------- help mode ---------- */

/* The dimmer is the only translucent surface in the app, and it is the point of
 * the mode: everything recedes except what the pointer is describing. */
#help-overlay {
    position: fixed; inset: 0; z-index: 60;
    background: rgba(29, 32, 33, 0.72);
    cursor: help;
}
#help-overlay[hidden] { display: none; }

#help-marker {
    position: fixed;
    border: 2px solid var(--gb-yellow);
    pointer-events: none;
}
#help-marker[hidden] { display: none; }

#help-tip {
    position: fixed;
    max-width: 34ch;
    padding: 6px 9px;
    background: var(--gb-bg0);
    border: 1px solid var(--gb-bg4);
    border-left: 3px solid var(--gb-yellow);
    color: var(--gb-fg1);
    pointer-events: none;
}
#help-tip[hidden] { display: none; }

.hl-orange { color: var(--gb-orange); }
.hl-aqua { color: var(--gb-aqua); }
.hl-yellow { color: var(--gb-yellow); }
.hl-red { color: var(--gb-red); }
.hl-green { color: var(--gb-green); }
.hl-blue { color: var(--gb-blue); }
.hl-purple { color: var(--gb-purple); }
.hl-gray { color: var(--gb-gray); }

#btn-help[aria-pressed="true"] { background: var(--gb-bg3); color: var(--gb-fg0); }

/* ---------- toasts ---------- */

.toasts { position: fixed; right: 10px; bottom: 10px; z-index: 50; display: flex; flex-direction: column; gap: 6px; }
.toast { background: var(--gb-bg1); border: 1px solid var(--gb-bg3); border-left: 3px solid var(--gb-aqua); padding: 6px 10px; max-width: 46ch; }
.toast.err { border-left-color: var(--gb-red); }
.toast.warn { border-left-color: var(--gb-yellow); }

/* ---------- narrow screens ---------- */

@media (max-width: 720px) {
    .toolbar { padding: 4px; }
    .legend { display: none; }
    .bb-header { flex-wrap: wrap; }
    .bb-footer { gap: 8px; font-size: 12px; flex-wrap: wrap; }
}
