/* LabUI — Industrial Dark Theme Font stack: IBM Plex Mono (monospace data), IBM Plex Sans (UI labels) Palette: bg-base #0b0e13 bg-panel #111620 bg-card #161d2e bg-raised #1c2540 border #2a3558 accent-blue #3b82f6 accent-cyan #00d4ff accent-green #22c55e text-primary #e2e8f0 text-muted #64748b danger #ef4444 warning #f59e0b */ * { font-family: "IBM Plex Sans", "Segoe UI", Tahoma, sans-serif; font-size: 12px; color: #e2e8f0; } QMainWindow, QDialog { background-color: #0b0e13; } /* ── Toolbar ─────────────────────────────────────────────────── */ QToolBar#mainToolbar { background-color: #0b0e13; border-bottom: 1px solid #2a3558; padding: 4px 8px; spacing: 6px; } QPushButton#runButton { background-color: #166534; color: #dcfce7; border: 1px solid #22c55e; border-radius: 4px; padding: 5px 16px; font-family: "IBM Plex Mono", monospace; font-weight: 600; letter-spacing: 0.5px; min-width: 90px; } QPushButton#runButton:checked { background-color: #7f1d1d; border-color: #ef4444; color: #fee2e2; } QPushButton#runButton:hover { background-color: #15803d; } QPushButton#runButton:checked:hover { background-color: #991b1b; } QPushButton#logButton { background-color: #1c2540; color: #94a3b8; border: 1px solid #2a3558; border-radius: 4px; padding: 5px 14px; font-family: "IBM Plex Mono", monospace; min-width: 80px; } QPushButton#logButton:enabled { color: #e2e8f0; border-color: #3b82f6; } QPushButton#logButton:checked { background-color: #7c2d12; border-color: #ef4444; color: #fee2e2; } QPushButton#addDeviceButton { background-color: #1e3a5f; color: #93c5fd; border: 1px solid #3b82f6; border-radius: 4px; padding: 5px 14px; } QPushButton#addDeviceButton:hover { background-color: #1d4ed8; color: #eff6ff; } QLabel#timeLabel { font-family: "IBM Plex Mono", monospace; font-size: 16px; font-weight: 700; color: #00d4ff; letter-spacing: 2px; padding-right: 8px; } /* ── Panels & Headers ────────────────────────────────────────── */ QLabel#panelHeader { background-color: #0f1521; color: #64748b; font-family: "IBM Plex Mono", monospace; font-size: 10px; font-weight: 700; letter-spacing: 2px; padding: 6px 0px; border-bottom: 1px solid #2a3558; } QWidget#alarmHeaderWidget { background-color: #0f1521; border-bottom: 1px solid #2a3558; } /* ── Device Cards ────────────────────────────────────────────── */ QScrollArea#deviceScroll { background-color: #0b0e13; border: none; border-right: 1px solid #2a3558; } QFrame#deviceCard { background-color: #161d2e; border: 1px solid #2a3558; border-radius: 6px; } QFrame#deviceCard:hover { border-color: #3b82f6; background-color: #1c2540; } QLabel#deviceIcon { font-size: 18px; } QLabel#deviceName { font-size: 13px; font-weight: 600; color: #e2e8f0; } QLabel#deviceSub { font-family: "IBM Plex Mono", monospace; font-size: 10px; color: #64748b; } QLabel#deviceChannelCount { font-size: 11px; color: #3b82f6; } QPushButton#configButton { background-color: #1c2540; color: #64748b; border: 1px solid #2a3558; border-radius: 3px; padding: 3px 10px; font-size: 11px; } QPushButton#configButton:hover { background-color: #1e3a5f; color: #93c5fd; border-color: #3b82f6; } /* ── Channel Readouts ────────────────────────────────────────── */ QFrame#channelReadout { background-color: #161d2e; border: 1px solid #1c2540; border-radius: 4px; } QFrame#channelReadout[alarm="true"] { border-color: #ef4444; background-color: #200d0d; } QLabel#readoutName { font-size: 11px; color: #64748b; } QLabel#readoutValue { font-family: "IBM Plex Mono", monospace; font-size: 15px; font-weight: 700; } QLabel#readoutUnit { font-family: "IBM Plex Mono", monospace; font-size: 10px; color: #475569; } QProgressBar#readoutBar { background-color: #1c2540; border: none; border-radius: 2px; } /* ── Alarm Panel ─────────────────────────────────────────────── */ QFrame#alarmEntry { background-color: #161d2e; border-radius: 3px; border: none; } QLabel#alarmMsg { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: #e2e8f0; } QLabel#alarmTs { font-family: "IBM Plex Mono", monospace; font-size: 10px; color: #475569; } QPushButton#clearAlarmsBtn { background: transparent; color: #64748b; border: none; font-size: 11px; padding: 4px 8px; } QPushButton#clearAlarmsBtn:hover { color: #ef4444; } /* ── Strip Chart controls ────────────────────────────────────── */ QPushButton#pauseButton { background-color: #1c2540; color: #64748b; border: 1px solid #2a3558; border-radius: 4px; padding: 4px 12px; } QPushButton#pauseButton:checked { background-color: #713f12; border-color: #f59e0b; color: #fef3c7; } /* ── Config / Dialog ─────────────────────────────────────────── */ QDialog { background-color: #111620; } QTabWidget::pane { background-color: #111620; border: 1px solid #2a3558; border-radius: 4px; } QTabBar::tab { background-color: #0b0e13; color: #64748b; border: 1px solid #2a3558; padding: 6px 16px; margin-right: 2px; } QTabBar::tab:selected { background-color: #1c2540; color: #e2e8f0; border-bottom: 2px solid #3b82f6; } QGroupBox { border: 1px solid #2a3558; border-radius: 4px; margin-top: 12px; padding-top: 8px; color: #64748b; font-size: 11px; font-weight: 600; letter-spacing: 0.5px; } QGroupBox::title { subcontrol-origin: margin; left: 8px; top: -6px; background-color: #111620; padding: 0 4px; } QLineEdit, QDoubleSpinBox, QSpinBox, QComboBox { background-color: #0b0e13; border: 1px solid #2a3558; border-radius: 3px; padding: 4px 8px; color: #e2e8f0; font-family: "IBM Plex Mono", monospace; min-height: 22px; } QLineEdit:focus, QDoubleSpinBox:focus, QSpinBox:focus, QComboBox:focus { border-color: #3b82f6; } QComboBox::drop-down { border: none; width: 20px; } QComboBox QAbstractItemView { background-color: #161d2e; border: 1px solid #3b82f6; selection-background-color: #1e3a5f; } QCheckBox { color: #94a3b8; spacing: 6px; } QCheckBox::indicator { width: 14px; height: 14px; border: 1px solid #2a3558; border-radius: 3px; background-color: #0b0e13; } QCheckBox::indicator:checked { background-color: #3b82f6; border-color: #3b82f6; } QPushButton#applyButton { background-color: #1e3a5f; color: #93c5fd; border: 1px solid #3b82f6; border-radius: 4px; padding: 6px 20px; font-weight: 600; } QPushButton#applyButton:hover { background-color: #1d4ed8; color: #eff6ff; } /* ── Digital output toggle ───────────────────────────────────── */ QPushButton#digitalOutBtn { background-color: #1c2540; color: #64748b; border: 1px solid #2a3558; border-radius: 4px; padding: 4px 14px; font-family: "IBM Plex Mono", monospace; min-width: 50px; } QPushButton#digitalOutBtn:checked { background-color: #166534; border-color: #22c55e; color: #dcfce7; } /* ── Scrollbars ──────────────────────────────────────────────── */ QScrollBar:vertical { background: #0b0e13; width: 6px; margin: 0; } QScrollBar::handle:vertical { background: #2a3558; border-radius: 3px; min-height: 20px; } QScrollBar::handle:vertical:hover { background: #3b82f6; } QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0; } QScrollBar:horizontal { height: 6px; background: #0b0e13; } QScrollBar::handle:horizontal { background: #2a3558; border-radius: 3px; min-width: 20px; } /* ── Splitter ────────────────────────────────────────────────── */ QSplitter::handle { background-color: #2a3558; } QSplitter::handle:hover { background-color: #3b82f6; } /* ── Status bar ──────────────────────────────────────────────── */ QStatusBar { background-color: #0b0e13; border-top: 1px solid #2a3558; color: #475569; font-family: "IBM Plex Mono", monospace; font-size: 11px; } /* ── General button default ──────────────────────────────────── */ QPushButton { background-color: #1c2540; color: #94a3b8; border: 1px solid #2a3558; border-radius: 4px; padding: 5px 12px; } QPushButton:hover { background-color: #1e3a5f; color: #e2e8f0; } QPushButton:pressed { background-color: #172554; } QPushButton:disabled { color: #334155; border-color: #1c2540; } QLabel { color: #94a3b8; } /* ══════════════════════════════════════════════════════════════ Devices Window ══════════════════════════════════════════════════════════════ */ QWidget#devWindowTitleBar { background-color: #0f1521; border-bottom: 1px solid #2a3558; } QLabel#devWindowTitle { font-family: "IBM Plex Mono", monospace; font-size: 11px; font-weight: 700; letter-spacing: 2px; color: #64748b; } QFrame#devWindowDivider { color: #2a3558; max-height: 1px; } /* ══════════════════════════════════════════════════════════════ Control Widgets — shared frame ══════════════════════════════════════════════════════════════ */ QFrame#controlWidget { background-color: #161d2e; border: 1px solid #2a3558; border-radius: 6px; } QFrame#controlWidget:hover { border-color: #3b82f6; } QWidget#controlWidgetHeader { background-color: #0f1521; border-radius: 5px 5px 0 0; border-bottom: 1px solid #2a3558; } QLabel#controlWidgetIcon { font-size: 13px; color: #3b82f6; padding-right: 4px; } QLabel#controlWidgetTitle { font-family: "IBM Plex Mono", monospace; font-size: 10px; font-weight: 700; letter-spacing: 1.5px; color: #64748b; } QWidget#controlWidgetBody { background-color: #161d2e; border-radius: 0 0 5px 5px; } /* ── On/Off Switch ─────────────────────────────────────────── */ QPushButton#switchBtn, QPushButton#switchBtnOff { background-color: #1c2540; color: #475569; border: 2px solid #2a3558; border-radius: 6px; font-family: "IBM Plex Mono", monospace; font-size: 18px; font-weight: 800; letter-spacing: 4px; min-height: 52px; } QPushButton#switchBtnOn { background-color: #14532d; color: #dcfce7; border: 2px solid #22c55e; border-radius: 6px; font-family: "IBM Plex Mono", monospace; font-size: 18px; font-weight: 800; letter-spacing: 4px; min-height: 52px; } QPushButton#switchBtnOff:hover { border-color: #64748b; color: #94a3b8; } QPushButton#switchBtnOn:hover { background-color: #166534; } QLabel#switchIndicatorOff { font-size: 18px; color: #334155; } QLabel#switchIndicatorOn { font-size: 18px; color: #22c55e; } QLabel#switchStateLbl { font-family: "IBM Plex Mono", monospace; font-size: 10px; font-weight: 700; letter-spacing: 1px; color: #475569; } /* ── Motor Control ─────────────────────────────────────────── */ QLabel#motorSpeedLbl { font-family: "IBM Plex Mono", monospace; font-size: 28px; font-weight: 700; color: #00d4ff; } QLabel#motorUnitLbl { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: #475569; padding-top: 12px; } QLabel#motorPctLbl { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: #475569; } QSlider#motorSlider::groove:horizontal, QSlider#pwmSlider::groove:horizontal { background: #1c2540; height: 6px; border-radius: 3px; } QSlider#motorSlider::handle:horizontal, QSlider#pwmSlider::handle:horizontal { background: #3b82f6; border: 2px solid #1d4ed8; width: 16px; height: 16px; margin: -5px 0; border-radius: 8px; } QSlider#motorSlider::sub-page:horizontal { background: #1d4ed8; border-radius: 3px; } QSlider#pwmSlider::sub-page:horizontal { background: #7c3aed; border-radius: 3px; } QSlider#motorSlider::handle:horizontal:hover, QSlider#pwmSlider::handle:horizontal:hover { background: #60a5fa; } QPushButton#motorDirBtn { background-color: #1c2540; color: #94a3b8; border: 1px solid #2a3558; border-radius: 4px; padding: 5px 10px; font-family: "IBM Plex Mono", monospace; font-size: 11px; } QPushButton#motorDirBtnRev { background-color: #2d1b69; color: #c4b5fd; border: 1px solid #7c3aed; border-radius: 4px; padding: 5px 10px; font-family: "IBM Plex Mono", monospace; font-size: 11px; } QPushButton#motorRunBtnOff { background-color: #1c2540; color: #64748b; border: 1px solid #2a3558; border-radius: 4px; padding: 5px 12px; font-family: "IBM Plex Mono", monospace; font-weight: 700; letter-spacing: 0.5px; } QPushButton#motorRunBtnOn { background-color: #166534; color: #dcfce7; border: 1px solid #22c55e; border-radius: 4px; padding: 5px 12px; font-family: "IBM Plex Mono", monospace; font-weight: 700; letter-spacing: 0.5px; } QPushButton#motorRunBtnOff:hover { border-color: #64748b; color: #94a3b8; } QPushButton#motorRunBtnOn:hover { background-color: #15803d; } /* ── Setpoint Control ──────────────────────────────────────── */ QLabel#spLabel { font-family: "IBM Plex Mono", monospace; font-size: 10px; font-weight: 700; color: #3b82f6; letter-spacing: 0.5px; } QLabel#pvLabel { font-family: "IBM Plex Mono", monospace; font-size: 10px; font-weight: 700; color: #22c55e; letter-spacing: 0.5px; } QLabel#errLabel { font-family: "IBM Plex Mono", monospace; font-size: 10px; font-weight: 700; color: #f59e0b; letter-spacing: 0.5px; } QLabel#pvValue, QLabel#errValue { font-family: "IBM Plex Mono", monospace; font-size: 12px; color: #94a3b8; } QDoubleSpinBox#spSpinbox { font-family: "IBM Plex Mono", monospace; font-size: 13px; font-weight: 600; color: #e2e8f0; background-color: #0b0e13; border: 1px solid #3b82f6; border-radius: 3px; padding: 3px 6px; } QPushButton#spStepBtn { background-color: #1e3a5f; color: #93c5fd; border: 1px solid #3b82f6; border-radius: 3px; font-size: 16px; font-weight: 700; padding: 0; } QPushButton#spStepBtn:hover { background-color: #1d4ed8; color: #eff6ff; } /* ── PWM Control ───────────────────────────────────────────── */ QLabel#pwmLabel { font-family: "IBM Plex Mono", monospace; font-size: 10px; color: #64748b; letter-spacing: 0.5px; } QLabel#pwmValue { font-family: "IBM Plex Mono", monospace; font-size: 13px; font-weight: 700; color: #c4b5fd; } QSpinBox#pwmFreqSpin { font-family: "IBM Plex Mono", monospace; font-size: 12px; background-color: #0b0e13; border: 1px solid #2a3558; border-radius: 3px; color: #e2e8f0; padding: 3px 6px; } /* ══════════════════════════════════════════════════════════════ Plot Config Button (toolbar) ══════════════════════════════════════════════════════════════ */ QPushButton#plotCfgButton { background-color: #1a1f35; color: #818cf8; border: 1px solid #4338ca; border-radius: 4px; padding: 5px 14px; font-weight: 600; } QPushButton#plotCfgButton:hover { background-color: #312e81; color: #e0e7ff; border-color: #6366f1; } QPushButton#plotCfgButton:checked { background-color: #312e81; color: #e0e7ff; border-color: #818cf8; } /* ══════════════════════════════════════════════════════════════ Plot Config Window ══════════════════════════════════════════════════════════════ */ QWidget#cfgTopBar { background-color: #0b0e13; border-bottom: 1px solid #2a3558; } QLabel#cfgTopBarTitle { font-family: "IBM Plex Mono", monospace; font-size: 12px; font-weight: 700; letter-spacing: 1.5px; color: #818cf8; } QCheckBox#cfgLiveChk { color: #94a3b8; font-size: 11px; spacing: 5px; } QWidget#cfgGlobalBar { background-color: #0f1521; border-bottom: 1px solid #1c2540; } QDoubleSpinBox#cfgGlobalSpin { font-family: "IBM Plex Mono", monospace; font-size: 12px; background: #0b0e13; border: 1px solid #2a3558; border-radius: 3px; color: #e2e8f0; padding: 3px 6px; } QWidget#cfgBottomBar { background-color: #0b0e13; border-top: 1px solid #2a3558; } /* ── Plot Block ──────────────────────────────────────────────── */ QFrame#plotBlock { background-color: #111620; border: 1px solid #2a3558; border-radius: 6px; } QFrame#plotBlock:hover { border-color: #4338ca; } QWidget#plotBlockHeader { background-color: #0d1117; border-radius: 5px 5px 0 0; border-bottom: 1px solid #2a3558; } QLineEdit#plotBlockTitle { font-family: "IBM Plex Mono", monospace; font-size: 12px; font-weight: 700; color: #c7d2fe; background: transparent; border: none; border-bottom: 1px solid transparent; padding: 2px 4px; } QLineEdit#plotBlockTitle:focus { border-bottom: 1px solid #4338ca; color: #e0e7ff; } QToolButton#plotMoveBtn { background-color: transparent; color: #475569; border: none; font-size: 11px; border-radius: 3px; } QToolButton#plotMoveBtn:hover { background-color: #1c2540; color: #94a3b8; } QToolButton#plotRemoveBtn { background-color: transparent; color: #475569; border: none; font-size: 12px; border-radius: 3px; } QToolButton#plotRemoveBtn:hover { background-color: #450a0a; color: #ef4444; } QWidget#plotBlockSettings { background-color: #111620; border-bottom: 1px solid #1c2540; } QLineEdit#plotYLabelEdit { font-family: "IBM Plex Mono", monospace; font-size: 11px; background: #0b0e13; border: 1px solid #2a3558; border-radius: 3px; color: #94a3b8; padding: 3px 6px; max-width: 140px; } QWidget#plotBlockTraces { background-color: #111620; border-radius: 0 0 5px 5px; } /* ── Trace Row ───────────────────────────────────────────────── */ QFrame#traceRow { background-color: #161d2e; border: 1px solid #1c2540; border-radius: 4px; } QFrame#traceRow:hover { border-color: #2a3558; background-color: #1c2540; } QLabel#traceSource { font-family: "IBM Plex Mono", monospace; font-size: 10px; color: #475569; } QLineEdit#traceLabel { font-family: "IBM Plex Mono", monospace; font-size: 11px; background: #0b0e13; border: 1px solid #1c2540; border-radius: 3px; color: #94a3b8; padding: 2px 6px; } QLineEdit#traceLabel:focus { border-color: #3b82f6; color: #e2e8f0; } QComboBox#traceStyleCb { font-family: "IBM Plex Mono", monospace; font-size: 10px; background: #0b0e13; border: 1px solid #1c2540; border-radius: 3px; color: #64748b; padding: 2px 4px; } QDoubleSpinBox#traceWidthSpin { font-family: "IBM Plex Mono", monospace; font-size: 10px; background: #0b0e13; border: 1px solid #1c2540; border-radius: 3px; color: #64748b; padding: 2px 4px; } QToolButton#traceRemoveBtn { background: transparent; color: #334155; border: none; font-size: 12px; border-radius: 3px; } QToolButton#traceRemoveBtn:hover { background-color: #450a0a; color: #ef4444; } /* ── Add trace button / channel picker ──────────────────────── */ QPushButton#addTraceBtn { background-color: #1c2540; color: #64748b; border: 1px dashed #2a3558; border-radius: 4px; padding: 4px 12px; font-size: 11px; } QPushButton#addTraceBtn:hover { background-color: #1e3a5f; color: #93c5fd; border-color: #3b82f6; border-style: solid; } QComboBox#channelPickerCb { font-family: "IBM Plex Mono", monospace; font-size: 11px; background: #0b0e13; border: 1px solid #2a3558; border-radius: 3px; color: #64748b; padding: 4px 8px; } QComboBox#channelPickerCb:focus { border-color: #3b82f6; } /* ══════════════════════════════════════════════════════════════ Signal Builder window / code editor ══════════════════════════════════════════════════════════════ */ QTabWidget#signalBuilderTabs::pane { background-color: #0b0e13; border: 1px solid #2a3558; } QTabWidget#signalBuilderTabs QTabBar::tab { background-color: #0b0e13; color: #475569; border: 1px solid #1c2540; padding: 6px 18px; font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: 0.5px; } QTabWidget#signalBuilderTabs QTabBar::tab:selected { background-color: #161d2e; color: #c7d2fe; border-bottom: 2px solid #818cf8; } QTextEdit#codeEditor { font-family: "IBM Plex Mono", monospace; font-size: 12px; background-color: #060810; color: #e2e8f0; border: 1px solid #2a3558; border-radius: 4px; padding: 6px; selection-background-color: #1e3a5f; } QTextEdit#codeEditor:focus { border-color: #818cf8; } /* ── Control panel header with device button ────────────────── */ QWidget#controlPanelHeader { background-color: #0f1521; border-bottom: 1px solid #2a3558; } QPushButton#devicesSmallBtn { background-color: transparent; color: #475569; border: 1px solid #2a3558; border-radius: 3px; font-size: 13px; padding: 0; } QPushButton#devicesSmallBtn:hover { background-color: #1c2540; color: #94a3b8; border-color: #3b82f6; }