347 lines
22 KiB
CSS
347 lines
22 KiB
CSS
:root {
|
|
--bg: #0a0c0e;
|
|
--panel: #111417;
|
|
--panel2: #0d1013;
|
|
--border: #1f2428;
|
|
--accent: #00e5ff;
|
|
--accent2: #ff3d71;
|
|
--warn: #ffaa00;
|
|
--ok: #00e096;
|
|
/* updated to match theme-dark overrides, so auto:dark equals manual dark */
|
|
--dim: #7a8490;
|
|
--text: #f0f2f5;
|
|
--label: #9faab7;
|
|
--mono: 'Share Tech Mono', monospace;
|
|
--sans: 'Barlow Condensed', sans-serif;
|
|
--logo-color: #ffffff;
|
|
/* Component tokens */
|
|
--header-bg: rgba(10,12,14,0.96);
|
|
--scanline: rgba(0,0,0,0.07);
|
|
--hover-desc-color: rgba(10,12,14,0.65);
|
|
/* Canvas */
|
|
--canvas-bg: #0d1013;
|
|
--canvas-fade: rgba(13,16,19,0.25);
|
|
--canvas-grid: rgba(31,36,40,0.6);
|
|
--canvas-center: rgba(58,64,80,0.5);
|
|
--canvas-idle-text: rgba(90,100,128,0.7);
|
|
--trail-rgb: 0,229,255;
|
|
--trail-idle-rgb: 58,64,80;
|
|
--canvas-dot: #00e5ff;
|
|
--canvas-dot-idle: #3a4050;
|
|
--canvas-dot-glow: rgba(0,229,255,0.35);
|
|
/* Tap flashes */
|
|
--tap-left: rgba(0,229,255,0.35);
|
|
--tap-right: rgba(255,61,113,0.35);
|
|
}
|
|
|
|
/* Light theme (explicit) */
|
|
:root.theme-light {
|
|
--bg: #f0f2f5;
|
|
--panel: #ffffff;
|
|
--panel2: #e8eaed;
|
|
--border: #b8bec8;
|
|
--accent: #006699;
|
|
--accent2: #c01a50;
|
|
--warn: #b36a00;
|
|
--ok: #007040;
|
|
--dim: #848ea4;
|
|
--text: #0f1118;
|
|
--label: #4e566e;
|
|
--logo-color: #0f1118;
|
|
--header-bg: rgba(240,242,245,0.96);
|
|
--scanline: rgba(0,0,0,0.03);
|
|
--hover-desc-color: rgba(240,242,245,0.7);
|
|
--canvas-bg: #e8eaed;
|
|
--canvas-fade: rgba(232,234,237,0.35);
|
|
--canvas-grid: rgba(195,200,210,0.7);
|
|
--canvas-center: rgba(155,162,178,0.6);
|
|
--canvas-idle-text: rgba(100,112,140,0.8);
|
|
--trail-rgb: 0,100,170;
|
|
--trail-idle-rgb: 155,162,178;
|
|
--canvas-dot: #0077aa;
|
|
--canvas-dot-idle: #a8b0c0;
|
|
--canvas-dot-glow: rgba(0,100,170,0.3);
|
|
--tap-left: rgba(0,100,170,0.35);
|
|
--tap-right: rgba(200,30,80,0.35);
|
|
}
|
|
|
|
|
|
/* Auto light (OS hint; explicit class overrides) */
|
|
@media (prefers-color-scheme: light) {
|
|
:root:not(.theme-dark) {
|
|
--bg: #f0f2f5;
|
|
--panel: #ffffff;
|
|
--panel2: #e8eaed;
|
|
--border: #b8bec8;
|
|
--accent: #006699;
|
|
--accent2: #c01a50;
|
|
--warn: #b36a00;
|
|
--ok: #007040;
|
|
--dim: #848ea4;
|
|
--text: #0f1118;
|
|
--label: #4e566e;
|
|
--logo-color: #0f1118;
|
|
--header-bg: rgba(240,242,245,0.96);
|
|
--scanline: rgba(0,0,0,0.03);
|
|
--hover-desc-color: rgba(240,242,245,0.7);
|
|
--canvas-bg: #e8eaed;
|
|
--canvas-fade: rgba(232,234,237,0.35);
|
|
--canvas-grid: rgba(195,200,210,0.7);
|
|
--canvas-center: rgba(155,162,178,0.6);
|
|
--canvas-idle-text: rgba(100,112,140,0.8);
|
|
--trail-rgb: 0,100,170;
|
|
--trail-idle-rgb: 155,162,178;
|
|
--canvas-dot: #0077aa;
|
|
--canvas-dot-idle: #a8b0c0;
|
|
--canvas-dot-glow: rgba(0,100,170,0.3);
|
|
--tap-left: rgba(0,100,170,0.35);
|
|
--tap-right: rgba(200,30,80,0.35);
|
|
}
|
|
}
|
|
|
|
* { box-sizing:border-box; margin:0; padding:0; }
|
|
body { background:var(--bg); color:var(--text); font-family:var(--mono); min-height:100vh; overflow-x:hidden; }
|
|
body::before { content:''; position:fixed; inset:0; pointer-events:none; z-index:9999;
|
|
background:repeating-linear-gradient(0deg,transparent,transparent 2px,var(--scanline) 2px,var(--scanline) 4px); }
|
|
|
|
header { border-bottom:1px solid var(--border); padding:16px 28px; display:flex; align-items:center; gap:20px; position:sticky; top:0; background:var(--header-bg); backdrop-filter:blur(10px); z-index:100; }
|
|
.logo { font-family:var(--sans); font-weight:900; font-size:22px; letter-spacing:0.08em; color:var(--logo-color); text-transform:uppercase; line-height:1; }
|
|
.logo span { color:var(--accent); }
|
|
.logo-sub { font-size:10px; color:var(--label); letter-spacing:0.25em; text-transform:uppercase; margin-top:3px; }
|
|
.header-right { margin-left:auto; display:flex; align-items:center; gap:10px; flex-wrap:wrap; justify-content:flex-end; }
|
|
|
|
.status-pill { display:flex; align-items:center; gap:8px; height:34px; padding:0 14px; border:1px solid var(--border); font-size:11px; letter-spacing:0.15em; text-transform:uppercase; color:var(--label); transition:all 0.3s; white-space:nowrap; }
|
|
.status-pill.connected { border-color:var(--ok); color:var(--ok); }
|
|
.status-pill.connecting { border-color:var(--warn); color:var(--warn); }
|
|
.dot { width:7px; height:7px; border-radius:50%; background:var(--dim); flex-shrink:0; }
|
|
.connected .dot { background:var(--ok); box-shadow:0 0 8px var(--ok); animation:pulse 2s infinite; }
|
|
.connecting .dot { background:var(--warn); box-shadow:0 0 8px var(--warn); animation:pulse 0.8s infinite; }
|
|
@keyframes pulse { 0%,100%{opacity:1}50%{opacity:0.3} }
|
|
@keyframes chgpulse { 0%,100%{opacity:1}50%{opacity:0.5} }
|
|
|
|
.btn { font-family:var(--sans); font-weight:700; font-size:13px; letter-spacing:0.15em; text-transform:uppercase; background:transparent; padding:8px 18px; cursor:pointer; transition:all 0.2s; position:relative; overflow:hidden; white-space:nowrap; }
|
|
.btn-connect { border:1px solid var(--accent); color:var(--accent); }
|
|
.btn-disconnect { border:1px solid var(--accent2); color:var(--accent2); }
|
|
.btn::before { content:''; position:absolute; inset:0; transform:scaleX(0); transform-origin:left; transition:transform 0.2s; }
|
|
.btn-connect::before { background:var(--accent); }
|
|
.btn-disconnect::before { background:var(--accent2); }
|
|
.btn:hover::before { transform:scaleX(1); }
|
|
.btn:hover { color:var(--bg); }
|
|
.btn span { position:relative; z-index:1; }
|
|
.btn:disabled { border-color:var(--dim); color:var(--dim); cursor:not-allowed; }
|
|
.btn:disabled::before { display:none; }
|
|
.btn:disabled:hover { color:var(--dim); }
|
|
.btn-debug { border:1px solid var(--dim); color:var(--label); min-width:52px; text-align:center; font-size:10px; height:34px; padding:0 10px; }
|
|
.btn-debug::before { background:var(--accent); }
|
|
.btn-theme { border:1px solid var(--dim); color:var(--label); min-width:72px; text-align:center; }
|
|
.btn-theme::before { background:var(--text); }
|
|
|
|
.batt-bar { display:flex; align-items:center; gap:8px; font-size:11px; color:var(--label); }
|
|
.batt-cells { display:flex; gap:2px; }
|
|
.batt-cell { width:9px; height:15px; border:1px solid var(--dim); background:transparent; transition:background 0.3s; }
|
|
.batt-cell.f { background:var(--ok); border-color:var(--ok); }
|
|
.batt-cell.f.warn { background:var(--warn); border-color:var(--warn); }
|
|
.batt-cell.f.crit { background:var(--accent2); border-color:var(--accent2); }
|
|
.batt-cell.f.charging { background:var(--accent); border-color:var(--accent); animation:chgpulse 1.2s ease-in-out infinite; }
|
|
.chg-badge { display:none; align-items:center; gap:4px; padding:3px 8px; font-size:10px; letter-spacing:0.15em; text-transform:uppercase; white-space:nowrap; border:1px solid; }
|
|
.chg-badge.charging { border-color:var(--accent); color:var(--accent); animation:chgpulse 1.6s ease-in-out infinite; }
|
|
.chg-badge.full { border-color:var(--ok); color:var(--ok); }
|
|
.chg-badge.show { display:flex; }
|
|
|
|
main { max-width:1440px; margin:0 auto; padding:32px 20px 80px; display:grid; grid-template-columns:1fr 1fr 380px; gap:16px; align-items:start; }
|
|
.col-left { display:grid; gap:12px; }
|
|
.col-mid { display:grid; gap:12px; }
|
|
.col-right { display:grid; gap:12px; position:sticky; top:80px; }
|
|
|
|
|
|
/* Responsive */
|
|
@media (max-width:1100px) {
|
|
main { grid-template-columns:1fr 380px; grid-template-rows:auto auto; }
|
|
.col-left { grid-column:1; grid-row:1; }
|
|
.col-mid { grid-column:1; grid-row:2; }
|
|
.col-right { grid-column:2; grid-row:1/3; }
|
|
}
|
|
@media (max-width:700px) {
|
|
main { grid-template-columns:1fr; }
|
|
.col-left, .col-mid, .col-right { grid-column:1; grid-row:auto; }
|
|
.col-right { position:static; }
|
|
}
|
|
|
|
.section-label { font-family:var(--sans); font-size:11px; font-weight:600; letter-spacing:0.3em; text-transform:uppercase; color:var(--label); padding:4px 0; border-bottom:1px solid var(--border); margin-bottom:4px; display:flex; align-items:center; gap:8px; }
|
|
.section-label::before { content:'//'; color:var(--accent); font-family:var(--mono); font-size:10px; }
|
|
|
|
.card { background:var(--panel); border:1px solid var(--border); padding:20px; position:relative; }
|
|
.card::before { content:''; position:absolute; top:0; left:0; width:3px; height:100%; background:var(--accent); opacity:0; transition:opacity 0.3s; }
|
|
.card:focus-within::before { opacity:1; }
|
|
|
|
.param { display:grid; grid-template-columns:190px 1fr auto; align-items:center; gap:14px; padding:12px 0; border-bottom:1px solid var(--border); }
|
|
.param:last-child { border-bottom:none; padding-bottom:0; }
|
|
.param:first-child { padding-top:0; }
|
|
.param-label { font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0.05em; text-transform:uppercase; }
|
|
.param-desc { font-size:10px; color:var(--label); margin-top:3px; }
|
|
.param-value { font-size:13px; color:var(--accent); min-width:52px; text-align:right; }
|
|
|
|
input[type=range] { -webkit-appearance:none; appearance:none; width:100%; height:2px; background:var(--border); outline:none; cursor:pointer; }
|
|
input[type=range]::-webkit-slider-thumb { -webkit-appearance:none; width:13px; height:13px; border-radius:0; background:var(--accent); cursor:pointer; transition:transform 0.15s; }
|
|
input[type=range]::-webkit-slider-thumb:hover { transform:scale(1.4); }
|
|
input[type=range]:disabled { opacity:0.35; }
|
|
input[type=range]:disabled::-webkit-slider-thumb { background:var(--dim); cursor:not-allowed; }
|
|
|
|
.segmented { display:flex; border:1px solid var(--border); }
|
|
.seg-btn { flex:1; padding:7px 8px; background:transparent; border:none; border-right:1px solid var(--border); font-family:var(--mono); font-size:10px; letter-spacing:0.1em; color:var(--label); cursor:pointer; text-transform:uppercase; transition:all 0.15s; }
|
|
.seg-btn:last-child { border-right:none; }
|
|
.seg-btn.active { background:var(--accent); color:var(--bg); font-weight:bold; }
|
|
.seg-btn:disabled { cursor:not-allowed; opacity:0.35; }
|
|
.charge-seg .seg-btn.active.slow { background:var(--warn); color:var(--bg); }
|
|
.charge-seg .seg-btn.active.fast { background:var(--accent2);color:#fff; }
|
|
|
|
.flip-row { display:flex; gap:16px; padding:12px 0; border-bottom:1px solid var(--border); align-items:center; }
|
|
.flip-row:last-child { border-bottom:none; }
|
|
.flip-label { font-family:var(--sans); font-size:13px; font-weight:600; text-transform:uppercase; flex:1; }
|
|
.toggle { position:relative; width:40px; height:22px; flex-shrink:0; }
|
|
.toggle input { display:none; }
|
|
.toggle-track { position:absolute; inset:0; background:var(--border); cursor:pointer; transition:background 0.2s; }
|
|
.toggle input:checked + .toggle-track { background:var(--accent); }
|
|
.toggle-thumb { position:absolute; top:3px; left:3px; width:16px; height:16px; background:#fff; transition:transform 0.2s; pointer-events:none; }
|
|
.toggle input:checked ~ .toggle-thumb { transform:translateX(18px); }
|
|
.toggle input:disabled + .toggle-track { cursor:not-allowed; opacity:0.4; }
|
|
|
|
.cmd-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
|
|
.cmd-btn { font-family:var(--sans); font-weight:700; font-size:13px; letter-spacing:0.12em; text-transform:uppercase; background:transparent; border:1px solid var(--border); color:var(--text); padding:14px; cursor:pointer; transition:all 0.2s; position:relative; overflow:hidden; text-align:left; display:flex; flex-direction:column; gap:5px; }
|
|
.cmd-btn .cmd-icon { font-size:20px; }
|
|
.cmd-btn .cmd-desc { font-family:var(--mono); font-size:9px; color:var(--label); letter-spacing:0.04em; text-transform:none; font-weight:400; }
|
|
.cmd-btn::before { content:''; position:absolute; inset:0; opacity:0; transition:opacity 0.2s; }
|
|
.cmd-btn:hover::before { opacity:1; }
|
|
.cmd-btn:hover { color:var(--bg); }
|
|
.cmd-btn:hover .cmd-desc { color:var(--hover-desc-color); }
|
|
.cmd-btn.calibrate::before { background:var(--accent); }
|
|
.cmd-btn.calibrate:hover { border-color:var(--accent); }
|
|
.cmd-btn.reset::before { background:var(--accent2); }
|
|
.cmd-btn.reset:hover { border-color:var(--accent2); }
|
|
.cmd-btn span { position:relative; z-index:1; }
|
|
.cmd-btn:disabled { opacity:0.3; cursor:not-allowed; }
|
|
.cmd-btn:disabled::before { display:none; }
|
|
.cmd-btn:disabled:hover { color:var(--text); border-color:var(--border); }
|
|
.cmd-btn:disabled:hover .cmd-desc { color:var(--label); }
|
|
|
|
.console { background:var(--panel2); border:1px solid var(--border); padding:14px; height:160px; overflow-y:auto; font-size:10.5px; line-height:1.85; }
|
|
.console::-webkit-scrollbar { width:3px; }
|
|
.console::-webkit-scrollbar-thumb { background:var(--dim); }
|
|
.log-line { display:flex; gap:10px; }
|
|
.log-time { color:var(--dim); flex-shrink:0; }
|
|
.log-msg { color:var(--text); }
|
|
.log-msg.ok { color:var(--ok); }
|
|
.log-msg.err { color:var(--accent2); }
|
|
.log-msg.warn { color:var(--warn); }
|
|
.log-msg.info { color:var(--accent); }
|
|
|
|
.viz-panel { background:var(--panel2); border:1px solid var(--border); padding:16px; }
|
|
.viz-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; }
|
|
.viz-title { font-family:var(--sans); font-size:11px; font-weight:600; letter-spacing:0.25em; text-transform:uppercase; color:var(--label); }
|
|
.orient-card { padding:12px; display:flex; flex-direction:column; align-items:center; }
|
|
#orientCanvas { display:block; width:100%; aspect-ratio:1; }
|
|
.viz-ctrl-btn { background:none; border:1px solid var(--border); color:var(--label); font-size:11px; line-height:1; padding:3px 8px; cursor:pointer; letter-spacing:0.05em; }
|
|
.viz-ctrl-btn:hover { border-color:var(--accent); color:var(--accent); }
|
|
.viz-live { font-size:9px; letter-spacing:0.2em; display:block; }
|
|
.viz-live.on { color:var(--accent2); animation:pulse 1.5s infinite; }
|
|
.viz-live.paused { color:var(--label); }
|
|
#vizCanvas { display:block; width:100%; background:var(--panel2); border:1px solid var(--border); cursor:crosshair; image-rendering:pixelated; }
|
|
.viz-axes { display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-top:10px; }
|
|
.axis-bar-wrap { display:flex; flex-direction:column; gap:3px; }
|
|
.axis-bar-label { font-size:9px; letter-spacing:0.15em; color:var(--label); text-transform:uppercase; display:flex; justify-content:space-between; }
|
|
.axis-bar-track { height:4px; background:var(--border); position:relative; }
|
|
.axis-bar-fill { position:absolute; top:0; height:100%; background:var(--accent); transition:width 0.05s, left 0.05s; }
|
|
.axis-bar-fill.neg { background:var(--accent2); }
|
|
.axis-bar-center { position:absolute; top:-2px; left:50%; width:1px; height:8px; background:var(--dim); }
|
|
|
|
.telem-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
|
|
.telem-cell { background:var(--panel2); border:1px solid var(--border); padding:12px 14px; }
|
|
.telem-val { font-family:var(--sans); font-size:24px; font-weight:700; color:var(--text); line-height:1; }
|
|
.telem-val.accent { color:var(--accent); }
|
|
.telem-val.warn { color:var(--warn); }
|
|
.telem-val.ok { color:var(--ok); }
|
|
.telem-lbl { font-size:9px; letter-spacing:0.2em; text-transform:uppercase; color:var(--label); margin-top:5px; }
|
|
|
|
.charge-info { display:grid; grid-template-columns:1fr 1fr 1fr; gap:0; margin-top:14px; border:1px solid var(--border); }
|
|
.ci-item { padding:10px 12px; text-align:center; border-right:1px solid var(--border); }
|
|
.ci-item:last-child { border-right:none; }
|
|
.ci-val { font-family:var(--sans); font-size:16px; font-weight:700; }
|
|
.ci-lbl { font-size:9px; letter-spacing:0.2em; text-transform:uppercase; color:var(--label); margin-top:3px; }
|
|
|
|
.overlay { display:none; position:fixed; inset:0; background:rgba(0,0,0,0.88); z-index:500; align-items:center; justify-content:center; }
|
|
.overlay.show { display:flex; }
|
|
.modal { background:var(--panel); border:1px solid var(--accent2); padding:28px; max-width:360px; width:100%; }
|
|
.modal h3 { font-family:var(--sans); font-size:18px; font-weight:700; color:var(--accent2); margin-bottom:10px; text-transform:uppercase; }
|
|
.modal p { font-size:11px; color:var(--label); line-height:1.8; margin-bottom:20px; }
|
|
.modal-btns { display:flex; gap:10px; }
|
|
.modal-btns button { flex:1; font-family:var(--sans); font-weight:700; font-size:12px; letter-spacing:0.1em; text-transform:uppercase; padding:10px; cursor:pointer; border:1px solid; transition:all 0.2s; background:transparent; }
|
|
.btn-cancel { border-color:var(--dim); color:var(--dim); }
|
|
.btn-cancel:hover { border-color:var(--text); color:var(--text); }
|
|
.btn-confirm { border-color:var(--accent2); color:var(--accent2); }
|
|
.btn-confirm:hover { background:var(--accent2); color:var(--bg); }
|
|
|
|
/* Debug modal */
|
|
.debug-modal { max-width:720px; padding:20px; border-color:var(--accent); }
|
|
.debug-modal h3 { color:var(--accent); margin-bottom:0; }
|
|
.debug-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:14px; }
|
|
.debug-close { background:none; border:1px solid var(--border); color:var(--label); font-size:14px; cursor:pointer; padding:2px 8px; font-family:var(--mono); }
|
|
.debug-close:hover { border-color:var(--text); color:var(--text); }
|
|
.debug-live { max-height:340px; overflow-y:auto; border:1px solid var(--border); margin-bottom:12px; }
|
|
.debug-table { width:100%; border-collapse:collapse; font-family:var(--mono); font-size:10px; }
|
|
.debug-table thead { position:sticky; top:0; background:var(--panel); z-index:1; }
|
|
.debug-table th { padding:4px 6px; text-align:right; color:var(--label); font-weight:400; border-bottom:1px solid var(--border); letter-spacing:0.1em; text-transform:uppercase; }
|
|
.debug-table td { padding:2px 6px; text-align:right; color:var(--text); border-bottom:1px solid color-mix(in srgb, var(--border) 40%, transparent); white-space:nowrap; }
|
|
.debug-table td:last-child { text-align:left; color:var(--label); }
|
|
.debug-table .shock-row td { color:var(--accent2); }
|
|
.debug-controls { display:flex; align-items:center; gap:10px; }
|
|
.debug-rec-btn { font-family:var(--mono); font-size:12px; font-weight:700; padding:6px 14px; cursor:pointer; border:1px solid var(--accent2); color:var(--accent2); background:transparent; letter-spacing:0.1em; }
|
|
.debug-rec-btn.recording { background:var(--accent2); color:var(--bg); animation:rec-pulse 1s infinite; }
|
|
@keyframes rec-pulse { 0%,100%{opacity:1} 50%{opacity:0.6} }
|
|
.debug-rec-count { font-family:var(--mono); font-size:10px; color:var(--label); }
|
|
.debug-ctrl-btn { font-family:var(--mono); font-size:10px; padding:5px 10px; cursor:pointer; border:1px solid var(--border); color:var(--label); background:transparent; }
|
|
.debug-ctrl-btn:hover { border-color:var(--text); color:var(--text); }
|
|
.debug-shock-badge { font-family:var(--mono); font-size:9px; letter-spacing:0.15em; padding:2px 8px; border:1px solid var(--border); color:var(--border); opacity:0.3; transition:all 0.15s; }
|
|
.debug-shock-badge.active { border-color:var(--accent2); color:var(--accent2); opacity:1; }
|
|
|
|
.no-ble { grid-column:1/-1; text-align:center; padding:80px 24px; }
|
|
.no-ble h2 { font-family:var(--sans); font-size:28px; font-weight:700; color:var(--accent2); margin-bottom:12px; }
|
|
.no-ble p { font-size:13px; color:var(--label); line-height:1.8; }
|
|
|
|
body.disconnected .card { opacity:0.45; pointer-events:none; transition:opacity 0.3s; }
|
|
body.disconnected .card.ota-card { opacity:1; pointer-events:auto; } /* OTA works when disconnected too */
|
|
body.disconnected .cmd-grid { opacity:0.45; pointer-events:none; transition:opacity 0.3s; }
|
|
|
|
.tap-key-row { display:flex; align-items:center; gap:10px; padding-top:12px; flex-wrap:wrap; }
|
|
.mod-btn { display:flex; align-items:center; gap:4px; cursor:pointer; font-family:var(--mono); font-size:10px; color:var(--label); user-select:none; }
|
|
.mod-btn input { display:none; }
|
|
.mod-btn span { padding:4px 8px; border:1px solid var(--border); background:transparent; transition:all 0.15s; }
|
|
.mod-btn input:checked + span { background:var(--accent); color:var(--bg); border-color:var(--accent); font-weight:bold; }
|
|
.mod-btn input:disabled + span { opacity:0.35; cursor:not-allowed; }
|
|
|
|
.restart-note { color:var(--warn); font-family:var(--mono); font-size:9px; }
|
|
|
|
|
|
.tap-flash { position:absolute; inset:0; pointer-events:none; opacity:0; transition:opacity 0.25s; }
|
|
.tap-flash.left { background:radial-gradient(circle at center, var(--tap-left) 0%, transparent 70%); }
|
|
.tap-flash.right { background:radial-gradient(circle at center, var(--tap-right) 0%, transparent 70%); }
|
|
.tap-flash.show { opacity:1; }
|
|
.viz-wrap { position:relative; }
|
|
|
|
/* ── OTA Firmware Update ── */
|
|
.ota-card { display:flex; flex-direction:column; gap:14px; }
|
|
.ota-notice { display:flex; gap:12px; align-items:flex-start; padding:10px 12px; background:color-mix(in srgb, var(--warn) 8%, var(--bg)); border-left:3px solid var(--warn); }
|
|
.ota-notice-icon { font-size:16px; color:var(--warn); flex-shrink:0; line-height:1.4; }
|
|
.ota-notice-title { font-family:var(--sans); font-size:11px; font-weight:700; color:var(--warn); letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px; }
|
|
.ota-notice-body { font-family:var(--mono); font-size:10px; color:var(--label); line-height:1.6; }
|
|
.ota-steps { font-family:var(--mono); font-size:10px; color:var(--label); line-height:1.9; margin:0; padding-left:18px; }
|
|
.ota-steps code { color:var(--text); }
|
|
.ota-steps strong { color:var(--text); }
|
|
.ota-steps em { color:var(--accent); font-style:normal; }
|
|
.ota-btn-row { display:grid; gap:8px; }
|
|
.ota-status-row { min-height:14px; }
|
|
.ota-status { font-family:var(--mono); font-size:10px; color:var(--label); }
|
|
.ota-status.ota-ok { color:var(--ok); }
|
|
.ota-status.ota-err { color:var(--accent2); }
|
|
.cmd-btn.ota-trigger::before { background:var(--accent); }
|
|
.cmd-btn.ota-trigger:hover { border-color:var(--accent); }
|