V2
This commit is contained in:
+126
-19
@@ -118,7 +118,7 @@ body.maximized .app-shell {
|
||||
transition: transform 0.15s, background 0.15s, border-color 0.15s;
|
||||
}
|
||||
.button:hover, .icon-button:hover {
|
||||
transform: translateY(-1px);
|
||||
transform: none;
|
||||
border-color: rgba(255, 255, 255, 0.18);
|
||||
background: #293237;
|
||||
}
|
||||
@@ -500,15 +500,15 @@ body[data-app-state="connecting"] .status-line .status-dot {
|
||||
}
|
||||
body[data-app-state="connected_disarmed"] .status-line .status-dot {
|
||||
background: var(--cyan);
|
||||
box-shadow: 0 0 6px rgba(114, 216, 232, 0.6);
|
||||
box-shadow: none;
|
||||
}
|
||||
body[data-app-state="armed"] .status-line .status-dot {
|
||||
background: var(--acid);
|
||||
box-shadow: 0 0 6px rgba(201, 242, 119, 0.65);
|
||||
box-shadow: none;
|
||||
}
|
||||
body[data-app-state="link_degraded"] .status-line .status-dot {
|
||||
background: var(--red);
|
||||
box-shadow: 0 0 6px rgba(240, 149, 139, 0.65);
|
||||
box-shadow: none;
|
||||
}
|
||||
.status-line p {
|
||||
margin: 0;
|
||||
@@ -603,10 +603,11 @@ body[data-app-state="link_degraded"] .status-line .status-dot {
|
||||
|
||||
/* ── Engage / Disarm Slot Above Joysticks ── */
|
||||
.engage-header-zone {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 42px;
|
||||
min-height: 76px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.zone-label {
|
||||
@@ -617,13 +618,13 @@ body[data-app-state="link_degraded"] .status-line .status-dot {
|
||||
}
|
||||
@property --engage-progress {
|
||||
syntax: "<percentage>";
|
||||
inherits: false;
|
||||
inherits: true;
|
||||
initial-value: 0%;
|
||||
}
|
||||
.engage-button {
|
||||
--engage-progress: 0%;
|
||||
min-width: 166px;
|
||||
height: 38px;
|
||||
height: 44px;
|
||||
padding: 0 24px;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
@@ -653,15 +654,26 @@ body[data-app-state="link_degraded"] .status-line .status-dot {
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
}
|
||||
.arm:not(.charging):not(.state-transition) .engage-label { animation: engage-shimmer 2.8s linear infinite; }
|
||||
.arm:not(:disabled):not(.charging):not(.canceling):not(.state-transition) .engage-label { animation: engage-shimmer 4.8s linear infinite; }
|
||||
.engage-progress-label {
|
||||
color: #a9ed72;
|
||||
clip-path: inset(0 calc(100% - var(--engage-progress)) 0 0);
|
||||
transition: clip-path .06s linear, opacity .18s ease;
|
||||
transition: opacity .18s ease;
|
||||
}
|
||||
.state-transition .engage-face { opacity: .2; transform: translateY(-2px); }
|
||||
.engage-face { transition: opacity .14s ease, transform .14s ease; }
|
||||
@keyframes engage-shimmer { from{background-position:160% 0} to{background-position:-90% 0} }
|
||||
.state-transition .engage-face { animation: state-label .24s ease-out; }
|
||||
@keyframes state-label { from {opacity:.35} to {opacity:1} }
|
||||
@keyframes engage-shimmer { 0%,35%{background-position:160% 0} 80%,100%{background-position:-90% 0} }
|
||||
.engage-button:hover { transform:none; }
|
||||
.engage-button.pending { background:#405346; border-color:#516e56; }
|
||||
.engage-button.pending .engage-label { color:#f4f6f3; background:none; }
|
||||
.engage-button.pending .engage-progress-label { opacity:0; }
|
||||
.control-status { grid-column:1/-1; min-height:28px; margin:6px 0 0; font-size:12px; line-height:1.4; color:#64716a; transition:color .18s ease; }
|
||||
.control-status.is-error { color:#a23931; }
|
||||
.controls-grid { transition:opacity .18s ease; }
|
||||
.heave-track[data-commanded="true"] .heave-center { background:#3d5145; }
|
||||
.heave-track .heave-center, .heave-fill { transition:background-color .12s linear; }
|
||||
body[data-telemetry-stale="true"] #battery-fill { opacity:.35; }
|
||||
#battery-fill { transition:width .25s linear, opacity .18s ease; }
|
||||
.subtle { background: #e2e6e1; color: #28302c; border: 1px solid rgba(0, 0, 0, 0.08); }
|
||||
.subtle:hover { background: #d7dcd5; }
|
||||
|
||||
@@ -832,7 +844,7 @@ body[data-app-state="link_degraded"] .status-line .status-dot {
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.heave-knob:active, .heave-knob.pressed {
|
||||
scale: 0.93;
|
||||
filter: brightness(.83);
|
||||
}
|
||||
|
||||
.control-card footer {
|
||||
@@ -978,7 +990,7 @@ body[data-app-state="link_degraded"] .status-line .status-dot {
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
APP-STATE CONDITIONAL GATING
|
||||
══════════════════════════════════════════════════════════════════ */
|
||||
body:not([data-app-state="armed"]) .controls-grid {
|
||||
body:not([data-controls-enabled="true"]) .controls-grid {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
@@ -991,10 +1003,6 @@ button:disabled {
|
||||
}
|
||||
button:disabled::after { display: none !important; }
|
||||
|
||||
body[data-app-state="disconnected"] #engage,
|
||||
body[data-app-state="connecting"] #engage,
|
||||
body[data-app-state="link_degraded"] #engage,
|
||||
body[data-app-state="connecting"] #connect,
|
||||
body[data-app-state="disconnected"] button[data-open="motors-modal"],
|
||||
body[data-app-state="connecting"] button[data-open="motors-modal"],
|
||||
body[data-app-state="link_degraded"] button[data-open="motors-modal"] {
|
||||
@@ -1003,8 +1011,107 @@ body[data-app-state="link_degraded"] button[data-open="motors-modal"] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* A pending or unknown armed state must stay legible, even without a link. */
|
||||
#engage.danger:disabled, #engage.pending:disabled { opacity:1 !important; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after { animation:none !important; transition:none !important; }
|
||||
}
|
||||
|
||||
@media (max-width: 950px) {
|
||||
.app-shell { grid-template-columns: 210px minmax(0, 1fr); }
|
||||
.controls-grid { grid-template-columns: minmax(230px, 1fr) 150px; }
|
||||
.controls-workspace { padding: 8px 12px; }
|
||||
}
|
||||
|
||||
/* Compact control surface: interactive content is never a native drag region. */
|
||||
.app-shell { grid-template-columns:260px minmax(0,1fr); }
|
||||
.sidebar-deck { position:relative; padding:20px; gap:18px; background:linear-gradient(160deg,#333,#242424); }
|
||||
.sidebar-drag-surface { position:absolute; inset:0; cursor:grab; }
|
||||
.sidebar-deck > :not(.sidebar-drag-surface) { position:relative; pointer-events:none; }
|
||||
.sidebar-deck :is(button,select,input,a,.rov-stage,.activity-history) { pointer-events:auto; }
|
||||
.deck-connection { gap:12px; padding-bottom:16px; }
|
||||
.port-row select { height:36px; font-size:12px; border-radius:999px; background:#3a3a3a; }
|
||||
.icon-button { width:34px; height:34px; background:#3a3a3a; }
|
||||
body #connect, body #connect:hover, body #connect.is-connected, body #connect.is-connecting {
|
||||
width:100%; min-width:0; height:62px; padding:0 14px; align-self:stretch;
|
||||
background:#fff !important; color:#303030 !important; border:0 !important;
|
||||
border-radius:999px; box-shadow:none !important; font-size:30px; font-weight:300; letter-spacing:-.025em;
|
||||
}
|
||||
body #connect .btn-label { animation:none; }
|
||||
.telemetry-zone { gap:20px; }
|
||||
.rov-stage { height:clamp(180px,32vh,250px); min-height:180px; touch-action:none; }
|
||||
.model-card { justify-content:flex-start; }
|
||||
.rov-stage::before { display:none; }
|
||||
.model-tools button { font-size:12px; padding:7px 11px; }
|
||||
.battery-card small { font-size:12px; }
|
||||
.battery-card strong { font-size:23px; }
|
||||
.battery-card i { font-size:12px; }
|
||||
.activity-heading { display:flex; align-items:center; justify-content:space-between; font-size:14px; font-weight:650; color:#eee; margin:8px 0 0; }
|
||||
.activity-heading .logs-link { font-size:14px; font-weight:650; color:#eee; }
|
||||
.activity-history { list-style:none; padding:0; margin:0; display:grid; gap:4px; }
|
||||
.activity-history li { font-size:12px; font-weight:300; line-height:1.25; color:#999; overflow-wrap:anywhere; }
|
||||
.activity-history #status-text { color:#fff; font-size:12px; font-weight:300; }
|
||||
.activity-history li[hidden] { display:none; }
|
||||
.controls-workspace { padding:8px 20px 16px; background:#f6f6f6; }
|
||||
.primary-control-zone { grid-template-rows:120px minmax(0,1fr) 52px; }
|
||||
.engage-header-zone { display:block; position:relative; height:120px; min-height:0; margin:0; padding:0; }
|
||||
body #engage { width:calc(100% + 40px); margin-left:-20px; height:104px; padding:0 20px; border:0; border-radius:0; background:transparent; box-shadow:none; }
|
||||
body #engage:hover, body #engage.pending, body #engage.danger { background:transparent; border:0; }
|
||||
#engage::before, #engage::after { display:none; }
|
||||
body #engage { align-items:flex-end; padding-bottom:12px; }
|
||||
.engage-face > span { font-family:"Segoe UI Variable Display","Segoe UI",Arial,sans-serif; font-size:clamp(64px,7.3vw,90px); font-weight:200; letter-spacing:.015em; line-height:1; padding-bottom:.22em; margin-bottom:-.22em; }
|
||||
#engage .engage-label { color:#777; background:none; animation:none; }
|
||||
.engage-sheen-label { color:#fff; pointer-events:none; opacity:0; mask-image:linear-gradient(105deg,transparent 40%,#000 49%,#000 51%,transparent 60%); mask-size:300% 100%; mask-repeat:no-repeat; -webkit-mask-image:linear-gradient(105deg,transparent 40%,#000 49%,#000 51%,transparent 60%); -webkit-mask-size:300% 100%; -webkit-mask-repeat:no-repeat; }
|
||||
#engage:is(.arm,.danger):not(:disabled):not(.charging):not(.canceling):not(.state-transition) .engage-sheen-label { opacity:1; animation:engage-sweep 2.2s linear infinite; }
|
||||
@keyframes engage-sweep { from {mask-position:100% 0;-webkit-mask-position:100% 0} to {mask-position:0% 0;-webkit-mask-position:0% 0} }
|
||||
.engage-progress-label { color:#4cce73; clip-path:none; filter:drop-shadow(0 0 2px rgba(76,206,115,.3)); mask-image:linear-gradient(to right,#000 calc(var(--engage-progress) - 8%),transparent var(--engage-progress)); -webkit-mask-image:linear-gradient(to right,#000 calc(var(--engage-progress) - 8%),transparent var(--engage-progress)); }
|
||||
#engage.charged .engage-progress-label { mask-image:none; -webkit-mask-image:none; }
|
||||
#engage.pending .engage-label { color:#5a8753; background:none; }
|
||||
#engage.danger .engage-label { color:#171717; }
|
||||
#engage:focus-visible { outline:2px solid #8d9991; outline-offset:-6px; }
|
||||
.control-status { position:absolute; z-index:2; top:100%; left:0; right:0; margin:0; min-height:0; text-align:center; font-size:12px; max-height:48px; overflow:auto; background:#f6f6f6; }
|
||||
.control-status[hidden] { display:none; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.engage-sheen-label { display:none; }
|
||||
}
|
||||
.controls-grid {
|
||||
--joy-size:min(54vh,calc(100vw - 480px),460px);
|
||||
--joy-circle-d:calc(var(--joy-size) * .86);
|
||||
grid-template-columns:var(--joy-size) 112px; gap:24px;
|
||||
justify-content:center; align-content:center;
|
||||
}
|
||||
.control-card { border:0; border-radius:0; box-shadow:none; background:transparent; padding:0; }
|
||||
.control-card header { align-items:center; min-height:20px; }
|
||||
.control-card small, .key-hint { font-size:12px; }
|
||||
.key-hint { background:transparent; }
|
||||
.control-card footer { height:22px; font-size:13px; margin:0; }
|
||||
.vertical-card footer { justify-content:center; text-align:center; }
|
||||
.vertical-card footer b { display:inline-block; width:4ch; text-align:right; font-variant-numeric:tabular-nums; }
|
||||
.joystick-pad,.heave-pad { padding:0; flex:none; }
|
||||
.vertical-control { font-size:11px; gap:4px; }
|
||||
.heave-track { width:58px; border-radius:999px; background:#eaeaea; border-color:#d6d6d6; }
|
||||
.heave-knob { width:76px; height:40px; border-radius:999px; background:linear-gradient(145deg,#737373,#454545); }
|
||||
.heave-fill { left:22px; right:22px; background:#999; }
|
||||
.control-toolbar { display:flex; justify-content:center; align-items:center; gap:16px; padding-top:12px; }
|
||||
.control-toolbar .output-limit { width:auto; flex-direction:row; align-items:center; font-size:13px; gap:12px; color:#777; }
|
||||
.control-toolbar .output-limit span { flex:0 0 128px; width:128px; gap:8px; align-items:baseline; justify-content:space-between; }
|
||||
.control-toolbar .output-limit b { display:inline-block; flex:0 0 4ch; width:4ch; text-align:right; color:#333; font-variant-numeric:tabular-nums; }
|
||||
.control-toolbar .range-pill { width:175px; grid-template-columns:28px 1fr 28px; height:40px; background:#e7e7e7; border:0; }
|
||||
.control-toolbar .range-pill button { width:28px; height:40px; color:#666; font-size:22px; }
|
||||
.control-toolbar .range-pill input[type="range"] { background:#c4c4c4; height:20px; background-clip:content-box; padding:8px 0; }
|
||||
.control-toolbar .range-pill input[type="range"]::-webkit-slider-thumb { width:18px; height:18px; background:#858585; }
|
||||
.control-toolbar .config-btn { width:auto; height:40px; padding:0 18px; font-size:13px; background:#e7e7e7; color:#444; border:0; border-radius:999px; }
|
||||
.workspace-topbar { height:40px; min-height:40px; }
|
||||
.window-actions { gap:5px; }
|
||||
.window-actions button { width:42px; height:38px; border-radius:999px; }
|
||||
.window-actions button svg { width:20px; height:20px; }
|
||||
body:not([data-controls-enabled="true"]) .controls-grid { opacity:.65; }
|
||||
@media (max-height:610px) {
|
||||
.primary-control-zone { grid-template-rows:100px minmax(0,1fr) 52px; }
|
||||
.engage-header-zone { height:100px; }
|
||||
body #engage { height:84px; }
|
||||
.controls-grid { --joy-size:min(49vh,calc(100vw - 480px),420px); }
|
||||
.sidebar-deck { gap:12px; padding-top:14px; padding-bottom:14px; }
|
||||
.telemetry-zone { gap:12px; }
|
||||
.activity-history { gap:4px; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user