780 lines
26 KiB
HTML
780 lines
26 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="es">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>VMS-Sailor Runtime · M/Y Aurora · Overview</title>
|
||
<link rel="icon" type="image/svg+xml" href="../brand/favicon.svg">
|
||
<link rel="stylesheet" href="_tokens.css">
|
||
<style>
|
||
body { overflow-x: hidden; }
|
||
.rt {
|
||
display: grid;
|
||
grid-template-rows: 64px 1fr 36px;
|
||
grid-template-columns: 240px 1fr;
|
||
grid-template-areas:
|
||
"topbar topbar"
|
||
"sidebar main"
|
||
"ticker ticker";
|
||
height: 100vh;
|
||
}
|
||
/* Topbar */
|
||
.topbar {
|
||
grid-area: topbar;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--s-5);
|
||
padding: 0 var(--s-5);
|
||
background: var(--c-midnight);
|
||
border-bottom: 1px solid var(--c-steel);
|
||
}
|
||
.vessel-id {
|
||
display: flex; align-items: center; gap: var(--s-3);
|
||
}
|
||
.vessel-id img { height: 32px; }
|
||
.vessel-id h1 {
|
||
margin: 0;
|
||
font-family: var(--f-display);
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: var(--c-foam);
|
||
line-height: 1;
|
||
}
|
||
.vessel-id .sub {
|
||
font-size: 11px;
|
||
color: var(--c-fog);
|
||
letter-spacing: 1.5px;
|
||
text-transform: uppercase;
|
||
}
|
||
.status-pill {
|
||
display: flex; align-items: center; gap: var(--s-2);
|
||
padding: 6px 14px;
|
||
background: rgba(0,224,138,0.12);
|
||
border: 1px solid rgba(0,224,138,0.4);
|
||
border-radius: var(--r-pill);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--c-ok);
|
||
letter-spacing: 0.5px;
|
||
}
|
||
.top-spacer { flex: 1; }
|
||
.top-meta {
|
||
display: flex; gap: var(--s-5); align-items: center;
|
||
font-family: var(--f-mono);
|
||
font-size: 12px;
|
||
color: var(--c-fog);
|
||
}
|
||
.top-meta strong { color: var(--c-sand); }
|
||
.alarm-chip {
|
||
display: flex; align-items: center; gap: var(--s-2);
|
||
padding: 6px 14px;
|
||
background: rgba(255,176,32,0.10);
|
||
border: 1px solid rgba(255,176,32,0.4);
|
||
border-radius: var(--r-pill);
|
||
font-size: 12px;
|
||
color: var(--c-warn);
|
||
font-weight: 700;
|
||
}
|
||
.user-chip {
|
||
display: flex; align-items: center; gap: var(--s-2);
|
||
padding: 6px 12px 6px 6px;
|
||
background: var(--c-steel);
|
||
border-radius: var(--r-pill);
|
||
font-size: 12px;
|
||
}
|
||
.avatar {
|
||
width: 26px; height: 26px;
|
||
border-radius: 50%;
|
||
background: var(--g-cyan);
|
||
color: #04111F;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-weight: 700;
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* Sidebar */
|
||
.sidebar {
|
||
grid-area: sidebar;
|
||
background: var(--c-midnight);
|
||
border-right: 1px solid var(--c-steel);
|
||
overflow-y: auto;
|
||
padding: var(--s-4) 0;
|
||
}
|
||
.sb-section { padding: var(--s-4) var(--s-3); }
|
||
.sb-title {
|
||
font-size: 10px; font-weight: 700; letter-spacing: 2px;
|
||
color: var(--c-fog); text-transform: uppercase;
|
||
margin-bottom: var(--s-2); padding-left: var(--s-2);
|
||
}
|
||
.nav-item {
|
||
display: flex; align-items: center; gap: var(--s-3);
|
||
padding: 10px 12px;
|
||
border-radius: var(--r-2);
|
||
color: var(--c-sand); font-size: 13px;
|
||
cursor: pointer;
|
||
transition: background 120ms;
|
||
}
|
||
.nav-item:hover { background: var(--c-steel); }
|
||
.nav-item.active {
|
||
background: linear-gradient(90deg, rgba(0,217,255,0.12), transparent);
|
||
color: var(--c-foam);
|
||
box-shadow: inset 2px 0 0 var(--c-cyan);
|
||
}
|
||
.nav-item .ic { color: var(--c-fog); }
|
||
.nav-item.active .ic { color: var(--c-cyan); }
|
||
.nav-item .count {
|
||
margin-left: auto;
|
||
font-family: var(--f-mono);
|
||
font-size: 11px;
|
||
color: var(--c-fog);
|
||
}
|
||
.nav-item .alarm-badge {
|
||
margin-left: auto;
|
||
padding: 2px 8px;
|
||
background: var(--c-emergency);
|
||
color: white;
|
||
border-radius: var(--r-pill);
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* Main */
|
||
.main {
|
||
grid-area: main;
|
||
padding: var(--s-5);
|
||
overflow-y: auto;
|
||
background: var(--g-deep-sea);
|
||
}
|
||
.page-title {
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
margin-bottom: var(--s-5);
|
||
}
|
||
.page-title h2 {
|
||
margin: 0;
|
||
font-family: var(--f-display);
|
||
font-size: 28px;
|
||
font-weight: 600;
|
||
color: var(--c-foam);
|
||
}
|
||
.page-title .sub {
|
||
color: var(--c-fog); font-size: 13px; margin-top: 4px;
|
||
}
|
||
.clock {
|
||
font-family: var(--f-mono);
|
||
font-size: 32px;
|
||
color: var(--c-foam);
|
||
letter-spacing: 1px;
|
||
text-align: right;
|
||
}
|
||
.clock .date {
|
||
font-size: 12px; color: var(--c-fog);
|
||
letter-spacing: 2px;
|
||
}
|
||
|
||
/* Grid de cards */
|
||
.grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(12, 1fr);
|
||
gap: var(--s-5);
|
||
}
|
||
.col-3 { grid-column: span 3; }
|
||
.col-4 { grid-column: span 4; }
|
||
.col-6 { grid-column: span 6; }
|
||
.col-8 { grid-column: span 8; }
|
||
.col-12 { grid-column: span 12; }
|
||
|
||
.stat {
|
||
background: var(--c-midnight);
|
||
border: 1px solid var(--c-steel);
|
||
border-radius: var(--r-3);
|
||
padding: var(--s-5);
|
||
box-shadow: var(--e-2);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.stat::before {
|
||
content: ""; position: absolute;
|
||
top: 0; left: 0; right: 0; height: 2px;
|
||
background: var(--c-iron);
|
||
}
|
||
.stat.accent-cyan::before { background: var(--g-cyan); }
|
||
.stat.accent-ok::before { background: var(--g-ok); }
|
||
.stat.accent-warn::before { background: var(--g-warn); }
|
||
|
||
.stat-header {
|
||
display: flex; justify-content: space-between; align-items: flex-start;
|
||
margin-bottom: var(--s-3);
|
||
}
|
||
.stat-label {
|
||
font-size: 11px; font-weight: 600; letter-spacing: 1.5px;
|
||
color: var(--c-fog); text-transform: uppercase;
|
||
}
|
||
.stat-value {
|
||
font-family: var(--f-mono);
|
||
font-size: 44px;
|
||
font-weight: 600;
|
||
color: var(--c-foam);
|
||
line-height: 1;
|
||
letter-spacing: -1px;
|
||
}
|
||
.stat-unit {
|
||
font-size: 16px;
|
||
color: var(--c-fog);
|
||
font-weight: 400;
|
||
margin-left: 4px;
|
||
}
|
||
.stat-trend {
|
||
display: flex; align-items: center; gap: 4px;
|
||
font-size: 12px;
|
||
font-family: var(--f-mono);
|
||
color: var(--c-fog);
|
||
margin-top: var(--s-2);
|
||
}
|
||
.stat-trend.up { color: var(--c-ok); }
|
||
.stat-trend.down { color: var(--c-warn); }
|
||
|
||
/* Engines card */
|
||
.engine-row {
|
||
display: grid;
|
||
grid-template-columns: 60px 1fr 110px;
|
||
gap: var(--s-4);
|
||
align-items: center;
|
||
padding: var(--s-3) 0;
|
||
border-bottom: 1px solid var(--c-steel);
|
||
}
|
||
.engine-row:last-child { border-bottom: none; }
|
||
.engine-label {
|
||
font-family: var(--f-mono);
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--c-foam);
|
||
}
|
||
.engine-state {
|
||
display: inline-block;
|
||
padding: 2px 8px;
|
||
background: rgba(0,224,138,0.12);
|
||
color: var(--c-ok);
|
||
border-radius: var(--r-pill);
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.5px;
|
||
margin-top: 2px;
|
||
}
|
||
.gauge-bar {
|
||
position: relative;
|
||
height: 8px;
|
||
background: var(--c-steel);
|
||
border-radius: var(--r-pill);
|
||
overflow: hidden;
|
||
}
|
||
.gauge-fill {
|
||
position: absolute;
|
||
inset: 0 auto 0 0;
|
||
background: var(--g-cyan);
|
||
border-radius: var(--r-pill);
|
||
box-shadow: 0 0 12px rgba(0,217,255,0.4);
|
||
}
|
||
.gauge-fill.warn { background: var(--g-warn); box-shadow: 0 0 12px rgba(255,176,32,0.4); }
|
||
.engine-meta {
|
||
display: flex; gap: var(--s-3);
|
||
font-size: 11px;
|
||
color: var(--c-fog);
|
||
margin-top: 4px;
|
||
font-family: var(--f-mono);
|
||
}
|
||
.engine-meta strong { color: var(--c-sand); }
|
||
.engine-rpm {
|
||
font-family: var(--f-mono);
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
color: var(--c-foam);
|
||
text-align: right;
|
||
}
|
||
.engine-rpm small { color: var(--c-fog); font-size: 11px; display: block; font-weight: 400; }
|
||
|
||
/* Roll/pitch */
|
||
.horizon {
|
||
width: 100%;
|
||
aspect-ratio: 1;
|
||
max-width: 280px;
|
||
margin: 0 auto;
|
||
position: relative;
|
||
}
|
||
.horizon-readout {
|
||
display: flex; justify-content: space-around;
|
||
margin-top: var(--s-4);
|
||
font-family: var(--f-mono);
|
||
}
|
||
.ro-block { text-align: center; }
|
||
.ro-block .lbl { color: var(--c-fog); font-size: 10px; letter-spacing: 2px; text-transform: uppercase; }
|
||
.ro-block .val { font-size: 26px; color: var(--c-foam); font-weight: 600; }
|
||
|
||
/* Recent alarms list */
|
||
.alarm-row {
|
||
display: grid;
|
||
grid-template-columns: 90px 1fr auto;
|
||
gap: var(--s-3);
|
||
padding: var(--s-3);
|
||
border-radius: var(--r-2);
|
||
align-items: center;
|
||
transition: background 120ms;
|
||
cursor: pointer;
|
||
}
|
||
.alarm-row:hover { background: var(--c-steel); }
|
||
.alarm-time {
|
||
font-family: var(--f-mono);
|
||
font-size: 11px;
|
||
color: var(--c-fog);
|
||
}
|
||
.alarm-msg {
|
||
font-size: 13px;
|
||
color: var(--c-sand);
|
||
}
|
||
.alarm-msg strong { color: var(--c-foam); }
|
||
.alarm-msg .src {
|
||
font-family: var(--f-mono);
|
||
font-size: 11px;
|
||
color: var(--c-cyan);
|
||
margin-right: 6px;
|
||
}
|
||
|
||
/* Tanks */
|
||
.tank {
|
||
display: flex; flex-direction: column; align-items: center;
|
||
gap: var(--s-2);
|
||
}
|
||
.tank-shell {
|
||
position: relative;
|
||
width: 70px;
|
||
height: 120px;
|
||
border: 2px solid var(--c-iron);
|
||
border-radius: 8px 8px 4px 4px;
|
||
overflow: hidden;
|
||
background: var(--c-abyss);
|
||
}
|
||
.tank-fill {
|
||
position: absolute;
|
||
left: 0; right: 0; bottom: 0;
|
||
background: linear-gradient(180deg, #1B7FB5 0%, #00D9FF 100%);
|
||
}
|
||
/* Surface highlight per fill color via currentColor on the fill */
|
||
.tank-fill { color: rgba(0,217,255,0.55); }
|
||
.tank-fill.warn { background: linear-gradient(180deg, #C0760F 0%, #FFB020 100%); color: rgba(255,176,32,0.55); }
|
||
.tank-fill.water { background: linear-gradient(180deg, #007F4E 0%, #00E08A 100%); color: rgba(0,224,138,0.55); }
|
||
.tank-fill.black { background: linear-gradient(180deg, #5A6B7F 0%, #94A3B8 100%); color: rgba(148,162,177,0.55); }
|
||
.tank-fill::before {
|
||
content: ""; position: absolute;
|
||
top: 0; left: 0; right: 0; height: 4px;
|
||
background: currentColor;
|
||
box-shadow: 0 0 6px currentColor;
|
||
pointer-events: none;
|
||
}
|
||
.tank-label { font-family: var(--f-mono); font-size: 11px; color: var(--c-fog); }
|
||
.tank-pct {
|
||
font-family: var(--f-mono);
|
||
font-size: 16px;
|
||
color: var(--c-foam);
|
||
font-weight: 600;
|
||
}
|
||
.tank-row {
|
||
display: flex; gap: var(--s-5); justify-content: space-around;
|
||
align-items: flex-end;
|
||
}
|
||
|
||
/* Ticker */
|
||
.ticker {
|
||
grid-area: ticker;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--s-5);
|
||
padding: 0 var(--s-5);
|
||
background: var(--c-midnight);
|
||
border-top: 1px solid var(--c-steel);
|
||
font-family: var(--f-mono);
|
||
font-size: 11px;
|
||
color: var(--c-fog);
|
||
}
|
||
.ticker .sep { color: var(--c-iron); }
|
||
.ticker .pulse {
|
||
width: 8px; height: 8px;
|
||
border-radius: 50%;
|
||
background: var(--c-ok);
|
||
box-shadow: 0 0 12px rgba(0,224,138,0.7);
|
||
animation: heartbeat 2s ease-in-out infinite;
|
||
}
|
||
@keyframes heartbeat {
|
||
0%, 100% { transform: scale(1); opacity: 1; }
|
||
50% { transform: scale(1.4); opacity: 0.6; }
|
||
}
|
||
.tk-spacer { flex: 1; }
|
||
.ic { width: 16px; height: 16px; stroke-width: 2; stroke: currentColor; fill: none; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="app-root rt">
|
||
|
||
<header class="topbar">
|
||
<div class="vessel-id">
|
||
<img src="../brand/logo-mark.svg" alt="">
|
||
<div>
|
||
<h1>M/Y Aurora</h1>
|
||
<div class="sub">Sunseeker 76 · 23.4 m</div>
|
||
</div>
|
||
</div>
|
||
<span class="status-pill">
|
||
<span class="dot ok"></span> Normal · todo en rango
|
||
</span>
|
||
<span class="top-spacer"></span>
|
||
<span class="alarm-chip">
|
||
<svg class="ic" viewBox="0 0 24 24"><path d="M12 9v4M12 17h.01"/><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg>
|
||
2 alarmas activas
|
||
</span>
|
||
<span class="chip">
|
||
<span class="dot cyan"></span>
|
||
Autoridad: <strong style="color:var(--c-cyan)">PUENTE</strong>
|
||
</span>
|
||
<span class="user-chip">
|
||
<span class="avatar">A</span>
|
||
Álvaro · <span style="color:var(--c-fog)">Admin</span>
|
||
</span>
|
||
</header>
|
||
|
||
<aside class="sidebar">
|
||
<div class="sb-section">
|
||
<div class="sb-title">Vistas</div>
|
||
<div class="nav-item active">
|
||
<svg class="ic" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
|
||
Overview
|
||
</div>
|
||
<div class="nav-item">
|
||
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 3v18M3 12h18"/></svg>
|
||
Mímicos
|
||
</div>
|
||
<div class="nav-item">
|
||
<svg class="ic" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><path d="M12 9v4M12 17h.01"/></svg>
|
||
Alarmas
|
||
<span class="alarm-badge">2</span>
|
||
</div>
|
||
<div class="nav-item">
|
||
<svg class="ic" viewBox="0 0 24 24"><polyline points="3 17 9 11 13 15 21 7"/></svg>
|
||
Trends
|
||
</div>
|
||
<div class="nav-item">
|
||
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><polyline points="12 6 12 12 15 14"/></svg>
|
||
Log Book
|
||
</div>
|
||
<div class="nav-item">
|
||
<svg class="ic" viewBox="0 0 24 24"><path d="M6 3v18M18 3v18"/><circle cx="12" cy="12" r="3"/></svg>
|
||
Trim & Maniobra
|
||
</div>
|
||
</div>
|
||
<div class="sb-section">
|
||
<div class="sb-title">Sistemas</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M5 12h2M17 12h2M12 5v2M12 17v2"/></svg> Máquina principal</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><path d="M13 2L3 14h7v8l10-12h-7V2z"/></svg> Generación eléctrica</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><path d="M12 2v10l4 4M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0z"/></svg> Combustible</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><path d="M6 8c0-4 6-6 6-6s6 2 6 6v3a6 6 0 0 1-12 0V8z"/></svg> Refrigeración</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><polyline points="12 6 12 12 8 14"/></svg> Sentinas</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><path d="M3 12h6l3-9 3 18 3-9h3"/></svg> HVAC</div>
|
||
<div class="nav-item"><svg class="ic" viewBox="0 0 24 24"><path d="M12 2v6M12 16v6M2 12h6M16 12h6M5 5l4 4M15 15l4 4M5 19l4-4M15 9l4-4"/></svg> Iluminación</div>
|
||
</div>
|
||
<div class="sb-section">
|
||
<div class="sb-title">Soporte</div>
|
||
<div class="nav-item">
|
||
<svg class="ic" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||
Auditoría VPN
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<main class="main">
|
||
<div class="page-title">
|
||
<div>
|
||
<h2>Estado general del buque</h2>
|
||
<div class="sub">Última actualización: hace 1.2 s · Sin desconexiones</div>
|
||
</div>
|
||
<div class="clock">
|
||
<div>03:42:18</div>
|
||
<div class="date">2026-05-17 · UTC-04</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid">
|
||
<!-- 4 stats -->
|
||
<div class="stat col-3 accent-cyan">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Combustible</span>
|
||
<span class="dot ok"></span>
|
||
</div>
|
||
<div class="stat-value">2,840<span class="stat-unit">L</span></div>
|
||
<div class="stat-trend down">▼ 18 L/h consumo medio</div>
|
||
</div>
|
||
|
||
<div class="stat col-3 accent-ok">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Generación</span>
|
||
<span class="dot ok"></span>
|
||
</div>
|
||
<div class="stat-value">28.4<span class="stat-unit">kW</span></div>
|
||
<div class="stat-trend">GEN_1 · 55% carga</div>
|
||
</div>
|
||
|
||
<div class="stat col-3 accent-ok">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Baterías</span>
|
||
<span class="dot ok"></span>
|
||
</div>
|
||
<div class="stat-value">27.8<span class="stat-unit">V</span></div>
|
||
<div class="stat-trend up">▲ Cargando 12 A</div>
|
||
</div>
|
||
|
||
<div class="stat col-3 accent-warn">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Sentinas</span>
|
||
<span class="dot warn"></span>
|
||
</div>
|
||
<div class="stat-value">12<span class="stat-unit">%</span></div>
|
||
<div class="stat-trend down">BILGE_MID en watch</div>
|
||
</div>
|
||
|
||
<!-- Motores -->
|
||
<div class="card col-8">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Máquina principal · 2× MTU 12V 2000 M96</span>
|
||
<a href="#" style="font-size:12px">Ver mímico →</a>
|
||
</div>
|
||
<div style="margin-top: var(--s-4);">
|
||
|
||
<div class="engine-row">
|
||
<div>
|
||
<div class="engine-label">ME_PORT</div>
|
||
<span class="engine-state">RUNNING</span>
|
||
</div>
|
||
<div>
|
||
<div class="gauge-bar"><div class="gauge-fill" style="width: 62%;"></div></div>
|
||
<div class="engine-meta">
|
||
<span>Aceite <strong>4.8 bar</strong></span>
|
||
<span>Coolant <strong>82°C</strong></span>
|
||
<span>Carga <strong>62%</strong></span>
|
||
<span>Horas <strong>1,284</strong></span>
|
||
</div>
|
||
</div>
|
||
<div class="engine-rpm">1,520 <small>rpm</small></div>
|
||
</div>
|
||
|
||
<div class="engine-row">
|
||
<div>
|
||
<div class="engine-label">ME_STBD</div>
|
||
<span class="engine-state">RUNNING</span>
|
||
</div>
|
||
<div>
|
||
<div class="gauge-bar"><div class="gauge-fill" style="width: 58%;"></div></div>
|
||
<div class="engine-meta">
|
||
<span>Aceite <strong>4.9 bar</strong></span>
|
||
<span>Coolant <strong>81°C</strong></span>
|
||
<span>Carga <strong>58%</strong></span>
|
||
<span>Horas <strong>1,287</strong></span>
|
||
</div>
|
||
</div>
|
||
<div class="engine-rpm">1,498 <small>rpm</small></div>
|
||
</div>
|
||
|
||
<div class="engine-row">
|
||
<div>
|
||
<div class="engine-label">GEN_1</div>
|
||
<span class="engine-state">RUNNING</span>
|
||
</div>
|
||
<div>
|
||
<div class="gauge-bar"><div class="gauge-fill warn" style="width: 88%;"></div></div>
|
||
<div class="engine-meta">
|
||
<span>L1 <strong>231 V</strong></span>
|
||
<span>Coolant <strong>89°C</strong></span>
|
||
<span>Carga <strong>88%</strong> ▲</span>
|
||
<span>Horas <strong>3,418</strong></span>
|
||
</div>
|
||
</div>
|
||
<div class="engine-rpm">1,800 <small>rpm</small></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Roll/pitch -->
|
||
<div class="card col-4">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Actitud (NMEA 2000 · PGN 127257)</span>
|
||
<span class="badge badge-ok">SAFE</span>
|
||
</div>
|
||
|
||
<div class="horizon">
|
||
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" style="width:100%;">
|
||
<defs>
|
||
<linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
|
||
<stop offset="0%" stop-color="#3A6BA8"/>
|
||
<stop offset="100%" stop-color="#1B3E6E"/>
|
||
</linearGradient>
|
||
<linearGradient id="sea" x1="0" y1="0" x2="0" y2="1">
|
||
<stop offset="0%" stop-color="#0A1A2E"/>
|
||
<stop offset="100%" stop-color="#04111F"/>
|
||
</linearGradient>
|
||
<clipPath id="circleClip">
|
||
<circle cx="100" cy="100" r="86"/>
|
||
</clipPath>
|
||
</defs>
|
||
<circle cx="100" cy="100" r="92" fill="none" stroke="#1A2B42" stroke-width="2"/>
|
||
<g clip-path="url(#circleClip)">
|
||
<g transform="rotate(-4 100 100)">
|
||
<rect x="0" y="0" width="200" height="100" fill="url(#sky)"/>
|
||
<rect x="0" y="100" width="200" height="100" fill="url(#sea)"/>
|
||
<line x1="0" y1="100" x2="200" y2="100" stroke="#00D9FF" stroke-width="1.5" opacity="0.7"/>
|
||
<g font-family="JetBrains Mono" font-size="9" fill="#E6EAF0">
|
||
<line x1="80" y1="80" x2="120" y2="80" stroke="#E6EAF0" stroke-width="1" opacity="0.6"/>
|
||
<text x="125" y="84">10°</text>
|
||
<line x1="80" y1="120" x2="120" y2="120" stroke="#E6EAF0" stroke-width="1" opacity="0.6"/>
|
||
<text x="125" y="124">10°</text>
|
||
</g>
|
||
</g>
|
||
</g>
|
||
<!-- Center cross -->
|
||
<g stroke="#00D9FF" stroke-width="2" fill="none">
|
||
<line x1="80" y1="100" x2="95" y2="100"/>
|
||
<line x1="105" y1="100" x2="120" y2="100"/>
|
||
<circle cx="100" cy="100" r="3" fill="#00D9FF"/>
|
||
</g>
|
||
<!-- Tick scale top -->
|
||
<g stroke="#7C8B9F" stroke-width="1">
|
||
<line x1="100" y1="8" x2="100" y2="16"/>
|
||
<line x1="50" y1="22" x2="56" y2="29" opacity="0.5"/>
|
||
<line x1="150" y1="22" x2="144" y2="29" opacity="0.5"/>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
|
||
<div class="horizon-readout">
|
||
<div class="ro-block">
|
||
<div class="lbl">Roll</div>
|
||
<div class="val">-4.1°</div>
|
||
</div>
|
||
<div class="ro-block">
|
||
<div class="lbl">Pitch</div>
|
||
<div class="val">+1.8°</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--c-steel); font-size: 11px; color: var(--c-fog); display:flex; justify-content: space-between; font-family: var(--f-mono);">
|
||
<span>Envelope ±10°</span>
|
||
<span>L3 trigger 18°</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tanques -->
|
||
<div class="card col-6">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Tanques estructurales</span>
|
||
<a href="#" style="font-size:12px">Detalle →</a>
|
||
</div>
|
||
<div class="tank-row" style="margin-top: var(--s-4);">
|
||
<div class="tank">
|
||
<div class="tank-shell">
|
||
<div class="tank-fill" style="height: 78%;"></div>
|
||
</div>
|
||
<div class="tank-pct">78%</div>
|
||
<div class="tank-label">FUEL 1</div>
|
||
</div>
|
||
<div class="tank">
|
||
<div class="tank-shell">
|
||
<div class="tank-fill" style="height: 64%;"></div>
|
||
</div>
|
||
<div class="tank-pct">64%</div>
|
||
<div class="tank-label">FUEL 2</div>
|
||
</div>
|
||
<div class="tank">
|
||
<div class="tank-shell">
|
||
<div class="tank-fill water" style="height: 91%;"></div>
|
||
</div>
|
||
<div class="tank-pct">91%</div>
|
||
<div class="tank-label">WATER</div>
|
||
</div>
|
||
<div class="tank">
|
||
<div class="tank-shell">
|
||
<div class="tank-fill warn" style="height: 12%;"></div>
|
||
</div>
|
||
<div class="tank-pct" style="color: var(--c-warn);">12%</div>
|
||
<div class="tank-label">BILGE</div>
|
||
</div>
|
||
<div class="tank">
|
||
<div class="tank-shell">
|
||
<div class="tank-fill black" style="height: 28%;"></div>
|
||
</div>
|
||
<div class="tank-pct">28%</div>
|
||
<div class="tank-label">BLACK</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Alarmas recientes -->
|
||
<div class="card col-6">
|
||
<div class="stat-header">
|
||
<span class="stat-label">Alarmas recientes</span>
|
||
<a href="#" style="font-size:12px">Ver todas (2) →</a>
|
||
</div>
|
||
<div style="margin-top: var(--s-3);">
|
||
<div class="alarm-row">
|
||
<span class="alarm-time">03:38:42</span>
|
||
<div class="alarm-msg">
|
||
<span class="src">GEN_1.COOLANT_TEMP</span>
|
||
<strong>89°C</strong> alta — aproximando límite 92°C
|
||
</div>
|
||
<span class="badge badge-low">LOW</span>
|
||
</div>
|
||
<div class="alarm-row">
|
||
<span class="alarm-time">03:31:17</span>
|
||
<div class="alarm-msg">
|
||
<span class="src">BILGE_MID.LEVEL</span>
|
||
Nivel <strong>12%</strong> — verificar bomba
|
||
</div>
|
||
<span class="badge badge-info">INFO</span>
|
||
</div>
|
||
<div class="alarm-row" style="opacity: 0.5;">
|
||
<span class="alarm-time">03:12:04</span>
|
||
<div class="alarm-msg">
|
||
<span class="src">ME_PORT.OIL_TEMP</span>
|
||
Recuperado a <strong>88°C</strong> · resolved
|
||
</div>
|
||
<span class="badge badge-muted">CLEARED</span>
|
||
</div>
|
||
<div class="alarm-row" style="opacity: 0.5;">
|
||
<span class="alarm-time">02:58:30</span>
|
||
<div class="alarm-msg">
|
||
<span class="src">SHORE_POWER.STATUS</span>
|
||
Transferencia a gen — desconexión muelle
|
||
</div>
|
||
<span class="badge badge-muted">CLEARED</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<footer class="ticker">
|
||
<span class="pulse"></span>
|
||
<span>WebSocket <strong style="color:var(--c-sand)">LIVE</strong></span>
|
||
<span class="sep">|</span>
|
||
<span>Latencia <strong style="color:var(--c-sand)">42 ms</strong></span>
|
||
<span class="sep">|</span>
|
||
<span>Driver Modbus RTU <strong style="color:var(--c-ok)">OK</strong></span>
|
||
<span class="sep">|</span>
|
||
<span>Driver NMEA 2000 <strong style="color:var(--c-ok)">OK</strong></span>
|
||
<span class="sep">|</span>
|
||
<span>Tags activos <strong style="color:var(--c-sand)">187</strong></span>
|
||
<span class="tk-spacer"></span>
|
||
<span><span class="dot cyan"></span> VPN soporte <strong>INACTIVA</strong></span>
|
||
<span class="sep">|</span>
|
||
<span>Telemetría <strong style="color:var(--c-ok)">activa</strong> (visible)</span>
|
||
<span class="sep">|</span>
|
||
<span>v0.1.0.dev0</span>
|
||
</footer>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|