Skip to content

Instantly share code, notes, and snippets.

@johnnylambada
Created September 16, 2026 05:39
Show Gist options
  • Select an option

  • Save johnnylambada/2a04aa9f94568e69e047108bd23ffb73 to your computer and use it in GitHub Desktop.

Select an option

Save johnnylambada/2a04aa9f94568e69e047108bd23ffb73 to your computer and use it in GitHub Desktop.
Begin tactical display doctrine study — standalone UI mock
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
<title>Begin — Tactical Display Doctrine Study</title>
<style>
:root {
--void:#050607; --deck:#0a0d0c; --panel:#101512; --panel2:#151b17;
--line:#29362d; --line2:#425546; --ink:#d5decf; --muted:#829184;
--data:#74df83; --bright:#c9ffc8; --amber:#e49b48; --gold:#d7b665;
--blue:#7dcce8; --hostile:#ee6c73; --warning:#ffb43f; --dead:#69736b;
--lcars1:#c58a5c; --lcars2:#a998d0; --lcars3:#7a9fbc;
--mono:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,monospace;
--sans:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
}
* { box-sizing:border-box }
html,body { margin:0; min-height:100%; background:var(--void); color:var(--ink) }
body { font-family:var(--mono); font-size:13px; line-height:1.3; overflow:hidden }
button { font:inherit }
.app { height:100vh; height:100dvh; padding:10px; display:grid; grid-template-columns:94px minmax(0,1fr); grid-template-rows:58px minmax(0,1fr) 46px; gap:7px; background:
radial-gradient(circle at 60% 15%,rgba(44,70,54,.18),transparent 34%),var(--void) }
/* TNG supplies the frame, not the tactical marks. */
.mast { grid-column:1/-1; display:grid; grid-template-columns:94px 1fr auto; gap:7px; min-width:0 }
.elbow { background:var(--lcars1); border-radius:28px 0 0 0; position:relative }
.elbow:after { content:""; position:absolute; right:0; bottom:0; width:25px; height:24px; background:var(--void); border-radius:16px 0 0 0 }
.titlebar { background:var(--lcars1); color:#12100d; border-radius:0 0 18px 0; display:flex; align-items:center; gap:14px; padding:0 18px; min-width:0 }
.brand { font:800 20px/1 var(--sans); letter-spacing:.22em; white-space:nowrap }
.mission { font-weight:800; letter-spacing:.08em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.clock { color:#33251b; margin-left:auto; white-space:nowrap }
.alert-state { min-width:210px; border:1px solid #593337; color:var(--hostile); background:#1a0d0f; border-radius:0 4px 4px 0; padding:8px 13px; display:flex; align-items:center; justify-content:space-between; gap:12px }
.alert-state b { color:#ffd9d6; letter-spacing:.1em }
.pulse { width:8px; height:8px; border-radius:50%; background:var(--hostile); box-shadow:0 0 10px var(--hostile); flex:none }
.rail { grid-row:2; display:flex; flex-direction:column; gap:5px; min-height:0 }
.rail button { min-height:47px; border:0; border-radius:0 13px 13px 0; background:#28312a; color:#aeb9ad; text-align:left; padding:6px 9px; cursor:pointer; font-size:10px; letter-spacing:.08em; position:relative }
.rail button span { display:block; margin-top:2px; color:#68756a; font-size:9px; letter-spacing:0 }
.rail button.active { background:var(--lcars2); color:#111; font-weight:900 }
.rail button.active span { color:#383044 }
.rail button:nth-child(2) { background:#493034; color:#ef9ca1 }
.rail button:nth-child(2).active { background:var(--hostile); color:#16090a }
.rail .spacer { flex:1 }
.rail .mode { min-height:31px; background:#304550; color:var(--blue) }
main { grid-row:2; grid-column:2; min-width:0; min-height:0; overflow:hidden }
.station { display:none; height:100%; min-height:0 }
.station.active { display:grid }
#command { grid-template-columns:minmax(410px,1.35fr) minmax(300px,.85fr); gap:7px }
#weapons { grid-template-columns:minmax(440px,1.1fr) minmax(360px,.9fr); gap:7px }
.column { display:flex; flex-direction:column; gap:7px; min-width:0; min-height:0 }
.panel { background:linear-gradient(145deg,var(--panel),#0b0e0c); border:1px solid var(--line); min-width:0; position:relative; overflow:hidden }
.panel:before { content:""; position:absolute; top:0; left:0; width:54px; height:2px; background:var(--lcars3) }
.panel-head { min-height:31px; padding:7px 10px 6px; border-bottom:1px solid var(--line); display:flex; align-items:center; justify-content:space-between; gap:10px; color:var(--gold); letter-spacing:.12em; font-size:10px }
.panel-head .micro { color:var(--muted); letter-spacing:.02em }
.panel-body { padding:9px 10px }
.grow { flex:1; min-height:0 }
.grow .panel-body { height:calc(100% - 31px) }
.eyebrow { font-size:9px; letter-spacing:.14em; color:var(--muted) }
.big-number { font:800 25px/1 var(--sans); color:var(--bright) }
.tiny { font-size:10px; color:var(--muted) }
.amber { color:var(--amber) } .hostile { color:var(--hostile) } .friendly { color:var(--blue) } .good { color:var(--data) }
.scope { height:100%; min-height:310px; position:relative; background:#060907; overflow:hidden }
.scope svg { display:block; width:100%; height:100% }
.scope-tools { position:absolute; left:10px; top:9px; display:flex; gap:4px; z-index:2 }
.scope-tools button,.chip { color:var(--muted); background:#0c120e; border:1px solid var(--line); min-height:28px; padding:3px 8px; cursor:pointer }
.scope-tools button.on,.chip.on { color:#07100a; background:var(--data); border-color:var(--data); font-weight:bold }
.scope-legend { position:absolute; left:10px; bottom:8px; display:flex; flex-wrap:wrap; gap:12px; color:var(--muted); font-size:9px }
.legend-mark { display:inline-flex; align-items:center; gap:5px }
.diamond { width:9px; height:9px; border:1px solid var(--hostile); transform:rotate(45deg) }
.dome { width:11px; height:8px; border:1px solid var(--blue); border-radius:8px 8px 1px 1px }
.track-label { font:9px var(--mono); paint-order:stroke; stroke:#050607; stroke-width:3px; stroke-linejoin:round }
.track { cursor:pointer }
.track .select-ring { opacity:0 }
.track.selected .select-ring { opacity:1 }
.contact-card { padding:9px 10px; border-left:4px solid var(--hostile); background:#130d0e }
.contact-title { display:flex; align-items:baseline; gap:8px }
.contact-title strong { color:#ffd8d3; font:800 19px var(--sans); letter-spacing:.04em }
.track-id { color:var(--hostile); font-weight:bold }
.contact-grid { display:grid; grid-template-columns:repeat(5,1fr); gap:8px; margin-top:8px }
.datum b { display:block; color:var(--ink); margin-top:2px; font-size:12px }
.status-row { display:flex; gap:5px; flex-wrap:wrap; margin-top:8px }
.status-lamp { padding:3px 7px; border:1px solid var(--line); color:var(--muted); font-size:9px; letter-spacing:.08em }
.status-lamp.hot { color:#190c0d; background:var(--hostile); border-color:var(--hostile); font-weight:bold }
.status-lamp.warn { color:#1b1304; background:var(--warning); border-color:var(--warning); font-weight:bold }
.tracks { width:100%; border-collapse:collapse }
.tracks th { color:var(--muted); font-size:9px; font-weight:normal; letter-spacing:.1em; text-align:left; padding:0 5px 5px }
.tracks td { padding:6px 5px; border-top:1px solid var(--line); white-space:nowrap }
.tracks tr { cursor:pointer }
.tracks tr.selected { background:#251416 }
.tracks tr.selected td:first-child { box-shadow:inset 3px 0 var(--hostile) }
.tracks .id { color:var(--hostile); font-weight:bold }
.state { border:1px solid var(--warning); color:var(--warning); font-size:9px; padding:2px 4px }
.readiness { display:grid; grid-template-columns:1.1fr 1fr 1fr 1fr; gap:1px; background:var(--line) }
.readiness > div { background:var(--panel); padding:9px }
.readiness strong { display:block; margin-top:3px; color:var(--bright); font-size:15px }
.shield-strip { display:grid; grid-template-columns:repeat(6,1fr); gap:4px; margin-top:9px }
.shield { height:9px; background:#243027; position:relative }
.shield i { display:block; height:100%; background:var(--data) }
.shield.low i { background:var(--hostile) }
.shield-labels { display:grid; grid-template-columns:repeat(6,1fr); gap:4px; color:var(--muted); font-size:9px; text-align:center; margin-top:3px }
/* Weapons borrows TOS: discrete lamps and machinery with TNG grouping. */
.weapon-tabs { display:grid; grid-template-columns:repeat(3,1fr); gap:4px }
.weapon-tabs button { min-height:42px; color:var(--muted); background:#151a16; border:1px solid var(--line); text-align:left; padding:5px 9px; cursor:pointer }
.weapon-tabs button.active { color:#10110e; background:var(--lcars1); border-color:var(--lcars1); font-weight:bold }
.weapon-tabs small { display:block; margin-top:2px; font-weight:normal }
.silhouette { display:grid; grid-template-columns:1fr 165px; gap:10px; align-items:center }
.ship-svg { width:100%; height:230px }
.bank-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:5px }
.bank { border:1px solid var(--line); padding:7px; background:#0b0e0c }
.bank .lamp { width:8px; height:8px; background:var(--data); box-shadow:0 0 7px rgba(116,223,131,.7); display:inline-block; margin-right:6px }
.bank strong { color:var(--bright) }
.solution { display:grid; grid-template-columns:1.15fr .85fr; gap:7px }
.solution-score { border-left:5px solid var(--warning); padding-left:10px }
.solution-score strong { font:800 31px/1 var(--sans); color:var(--warning) }
.envelope { margin-top:7px; height:11px; background:#242b25; position:relative }
.envelope .reach { position:absolute; inset:0 auto 0 0; width:19%; background:var(--data) }
.envelope .target { position:absolute; top:-4px; left:49%; height:19px; width:2px; background:var(--hostile) }
.execute { width:100%; min-height:48px; border:0; color:#1a1204; background:var(--warning); font-weight:900; margin-top:9px; cursor:pointer; letter-spacing:.05em }
.execute:before { content:"△ "; font-size:15px }
.weapons-list { display:grid; grid-template-columns:repeat(4,1fr); gap:5px }
.weapon-cell { border:1px solid var(--line); background:#0b0e0c; padding:8px }
.weapon-cell b { color:var(--bright) }
.footer { grid-column:1/-1; display:grid; grid-template-columns:94px minmax(0,1fr) 300px; gap:7px }
.footer-cap { background:var(--lcars3); border-radius:0 0 0 22px }
.event { border:1px solid var(--line); background:#090d0a; padding:6px 10px; display:flex; align-items:center; gap:12px; overflow:hidden }
.event b { color:var(--gold); white-space:nowrap }
.event span { color:var(--data); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.step { border:0; background:var(--lcars3); color:#0a1013; font-weight:900; letter-spacing:.1em; cursor:pointer; border-radius:0 0 18px 0 }
@media (max-width:820px) {
body { overflow:auto }
.app { min-height:100dvh; height:auto; padding:6px; display:grid; grid-template-columns:1fr; grid-template-rows:49px auto 48px; gap:6px; padding-bottom:64px }
.mast { grid-column:1; grid-template-columns:42px minmax(0,1fr); gap:4px }
.elbow { border-radius:20px 0 0 0 }
.titlebar { padding:0 10px; border-radius:0 0 12px 0 }
.brand { font-size:16px }.mission { display:none }.clock { font-size:10px }
.alert-state { position:fixed; top:auto; bottom:54px; left:6px; right:6px; min-width:0; z-index:10; min-height:38px; box-shadow:0 -5px 20px #000 }
.rail { position:fixed; z-index:12; left:0; right:0; bottom:0; height:50px; padding:4px 6px calc(4px + env(safe-area-inset-bottom)); background:#050607; display:grid; grid-template-columns:repeat(7,1fr); gap:3px }
.rail button { min-height:42px; border-radius:7px 7px 0 0; text-align:center; padding:4px 1px; font-size:9px }
.rail button span,.rail .spacer,.rail .mode { display:none }
main { grid-row:2; grid-column:1; overflow:visible }
#command,#weapons { grid-template-columns:1fr; height:auto }
.column { overflow:visible }
.scope { height:355px; min-height:355px }
.contact-grid { grid-template-columns:repeat(3,1fr) }
.tracks th:nth-child(4),.tracks td:nth-child(4) { display:none }
.readiness { grid-template-columns:repeat(2,1fr) }
.footer { display:none }
.silhouette { grid-template-columns:1fr; }
.ship-svg { height:200px }
.solution { grid-template-columns:1fr }
.weapons-list { grid-template-columns:repeat(2,1fr) }
}
</style>
<div class="app">
<header class="mast">
<div class="elbow"></div>
<div class="titlebar"><span class="brand">BEGIN</span><span class="mission">TACTICAL OPERATIONS / USS LEXINGTON</span><span class="clock">CY 11 · GAME 41</span></div>
<div class="alert-state"><span><b>RED CONDITION</b><br><small>3 HOSTILE TRACKS ENGAGING</small></span><i class="pulse"></i></div>
</header>
<nav class="rail" aria-label="Stations">
<button class="station-nav active" data-station="command">CMD<span>command</span></button>
<button>THRT<span>threat</span></button>
<button>HELM<span>flight</span></button>
<button>NAV<span>sensors</span></button>
<button class="station-nav" data-station="weapons">WPN<span>fire control</span></button>
<button>ENG<span>systems</span></button>
<button>COMMS<span>traffic</span></button>
<div class="spacer"></div>
<button class="mode">NIGHT / 02</button>
</nav>
<main>
<section id="command" class="station active">
<div class="column">
<article class="panel grow">
<div class="panel-head"><span>TACTICAL PICTURE</span><span class="micro">RANGE 20,000 · TRACK-UP · AUTO</span></div>
<div class="panel-body scope">
<div class="scope-tools"><button class="on">TRACKS</button><button>VECTORS</button><button>WEAPONS</button></div>
<svg viewBox="0 0 720 500" preserveAspectRatio="xMidYMid meet" aria-label="Tactical plot">
<defs><filter id="glow"><feGaussianBlur stdDeviation="2" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge></filter></defs>
<g fill="none" stroke="#263229" stroke-width="1">
<circle cx="360" cy="260" r="62"/><circle cx="360" cy="260" r="124"/><circle cx="360" cy="260" r="186"/><circle cx="360" cy="260" r="238"/>
<path d="M360 18v484M118 260h484"/><path d="M189 89l342 342M531 89L189 431" stroke-dasharray="2 6"/>
</g>
<g fill="#738078" font-family="monospace" font-size="9"><text x="367" y="35">000</text><text x="580" y="253">090</text><text x="367" y="487">180</text><text x="125" y="253">270</text></g>
<g stroke="#74df83" fill="none" filter="url(#glow)"><path d="M360 260l38-38"/><circle cx="360" cy="260" r="7"/><path d="M348 251h24v18h-24z"/></g>
<text x="374" y="277" fill="#74df83" class="track-label">LEX / F-00</text>
<g class="track selected" data-track="gargoyle" transform="translate(468 360)">
<circle class="select-ring" r="25" fill="none" stroke="#ffb43f" stroke-dasharray="4 3"/>
<path d="M0-13L14 0 0 13-14 0Z" fill="#17090b" stroke="#ee6c73" stroke-width="2"/>
<path d="M-6 0h12M0-6v12" stroke="#ee6c73"/><path d="M0 0l-41-54" stroke="#ee6c73"/>
<path d="M-20-20L-44-44M-44-44h10M-44-44v10" stroke="#ffb43f"/>
<text x="18" y="-8" fill="#ee6c73" class="track-label">H-03 GARGOYLE</text><text x="18" y="5" fill="#d5decf" class="track-label">DR / W5.5 / 10,048</text>
</g>
<g class="track" data-track="cromoer" transform="translate(476 315)">
<circle class="select-ring" r="22" fill="none" stroke="#ffb43f" stroke-dasharray="4 3"/>
<path d="M0-11L12 0 0 11-12 0Z" fill="#17090b" stroke="#ee6c73" stroke-width="2"/><path d="M-5 0h10" stroke="#ee6c73"/><path d="M0 0l-48-41" stroke="#ee6c73"/>
<text x="15" y="-4" fill="#ee6c73" class="track-label">H-02 CROMOER</text>
</g>
<g class="track" data-track="freen" transform="translate(523 396)">
<circle class="select-ring" r="22" fill="none" stroke="#ffb43f" stroke-dasharray="4 3"/>
<path d="M0-11L12 0 0 11-12 0Z" fill="#17090b" stroke="#ee6c73" stroke-width="2"/><path d="M-5 0h10" stroke="#ee6c73"/><path d="M0 0l-27-42" stroke="#ee6c73"/>
<text x="15" y="-4" fill="#ee6c73" class="track-label">H-01 FREEN</text>
</g>
<g transform="translate(404 215)"><path d="M-10 4V0a10 10 0 0120 0v4Z" fill="#071114" stroke="#7dcce8" stroke-width="2"/><path d="M0 0l34-20" stroke="#7dcce8"/><text x="14" y="13" fill="#7dcce8" class="track-label">F-07 ALTAIR</text></g>
<g transform="translate(315 306)"><path d="M-10 4V0a10 10 0 0120 0v4Z" fill="#071114" stroke="#7dcce8"/><text x="13" y="4" fill="#7dcce8" class="track-label">F-04 VENUS</text></g>
<g fill="#ee6c73" filter="url(#glow)"><circle cx="425" cy="330" r="3"/><circle cx="438" cy="343" r="3"/><circle cx="455" cy="348" r="3"/></g>
<g stroke="#ee6c73" stroke-width="1"><path d="M425 330l-38-42"/><path d="M438 343l-45-48"/><path d="M455 348l-52-43"/></g>
<text x="446" y="371" fill="#ee6c73" class="track-label">3 × KTX / INBOUND</text>
</svg>
<div class="scope-legend"><span class="legend-mark"><i class="dome"></i> FRIEND</span><span class="legend-mark"><i class="diamond"></i> HOSTILE</span><span>○ SELECTED</span><span>— 1 CYCLE VECTOR</span></div>
</div>
</article>
<article class="panel">
<div class="panel-head"><span>DESIGNATED TRACK</span><span class="micro">OBSERVED 1 CYCLE AGO</span></div>
<div class="contact-card">
<div class="contact-title"><span class="track-id">H-03</span><strong id="target-name">GARGOYLE</strong><span id="target-class" class="muted">DREADNOUGHT</span></div>
<div class="contact-grid">
<div class="datum"><span class="eyebrow">RANGE</span><b id="target-range">10,048</b></div><div class="datum"><span class="eyebrow">BEARING</span><b id="target-bearing">138°</b></div>
<div class="datum"><span class="eyebrow">CLOSING</span><b id="target-closing" class="hostile">514 / CY</b></div><div class="datum"><span class="eyebrow">ASPECT</span><b>SHIELD 4</b></div><div class="datum"><span class="eyebrow">CONFIDENCE</span><b>TRACKED</b></div>
</div>
<div class="status-row"><span class="status-lamp hot">ATTACKING US</span><span class="status-lamp warn">WEAPONS IN RANGE</span><span class="status-lamp">SCAN STALE</span></div>
</div>
</article>
</div>
<div class="column">
<article class="panel">
<div class="panel-head"><span>THREAT ORDER</span><span class="micro">AUTO / VALID CY 11</span></div>
<div class="panel-body"><table class="tracks">
<thead><tr><th>TRACK</th><th>RANGE</th><th>CLOSE</th><th>STATE</th></tr></thead>
<tbody>
<tr class="selected" data-row="gargoyle"><td><span class="id">H-03</span> GARGOYLE</td><td>10,048</td><td class="hostile">514</td><td><span class="state">ENGAGING</span></td></tr>
<tr data-row="cromoer"><td><span class="id">H-02</span> CROMOER</td><td>11,343</td><td class="hostile">797</td><td><span class="state">ENGAGING</span></td></tr>
<tr data-row="freen"><td><span class="id">H-01</span> FREEN</td><td>15,450</td><td class="hostile">243</td><td><span class="state">ENGAGING</span></td></tr>
</tbody></table></div>
</article>
<article class="panel">
<div class="panel-head"><span>SHIP READINESS</span><span class="micro">LEXINGTON / F-00</span></div>
<div class="readiness"><div><span class="eyebrow">CONDITION</span><strong>100%</strong></div><div><span class="eyebrow">RESIDUAL</span><strong>+188</strong></div><div><span class="eyebrow">COURSE</span><strong>045°</strong></div><div><span class="eyebrow">WARP</span><strong>4.0</strong></div></div>
<div class="panel-body"><div class="eyebrow">SHIELD EFFECTIVE / FACING INDICATOR</div><div class="shield-strip"><div class="shield"><i style="width:100%"></i></div><div class="shield low"><i style="width:23%"></i></div><div class="shield"><i style="width:100%"></i></div><div class="shield"><i style="width:100%"></i></div><div class="shield"><i style="width:100%"></i></div><div class="shield"><i style="width:100%"></i></div></div><div class="shield-labels"><span>1·100</span><span class="hostile">2·23</span><span>3·100</span><span class="friendly">4◂·100</span><span>5·100</span><span>6·100</span></div></div>
</article>
<article class="panel grow">
<div class="panel-head"><span>CAPTAIN'S SUMMARY</span><span class="micro">DECISION SUPPORT</span></div>
<div class="panel-body"><div class="eyebrow">IMMEDIATE</div><p><b class="hostile">3 hostile torpedoes</b> converge on shields 2 and 4. Nearest approach in <b class="amber">2.2 cycles</b>.</p><div class="eyebrow">TACTICAL</div><p>Gargoyle is nearest. Phaser envelope in <b class="amber">16 cycles</b>; Mark VII torpedoes can reach now.</p><div class="eyebrow">NAVIGATION</div><p>Manual helm. Current course <b>045°</b> opens range from all three hostile tracks.</p><div class="status-row"><button class="chip on">OPEN THREAT</button><button class="chip">SCAN H-03</button><button class="chip">DESIGNATE FOR WPN</button></div></div>
</article>
</div>
</section>
<section id="weapons" class="station">
<div class="column">
<div class="weapon-tabs"><button class="active">PHASERS<small>4 / 4 CHARGED</small></button><button>TORPEDOES<small>0 / 6 LOADED</small></button><button>PROBES<small>0 / 3 LOADED</small></button></div>
<article class="panel grow">
<div class="panel-head"><span>WEAPON STATUS / PHASER BANKS</span><span class="micro">LEXINGTON HC-07</span></div>
<div class="panel-body silhouette">
<svg class="ship-svg" viewBox="0 0 410 260" aria-label="Lexington weapon geometry">
<g fill="none" stroke="#314238"><path d="M205 20c-63 0-108 34-108 76 0 30 23 53 61 65v68l47 18 47-18v-68c38-12 61-35 61-65 0-42-45-76-108-76z"/><path d="M158 161l-34 60M252 161l34 60"/></g>
<g stroke="#74df83" fill="#08100a"><circle cx="132" cy="73" r="21"/><circle cx="278" cy="73" r="21"/><circle cx="139" cy="140" r="21"/><circle cx="271" cy="140" r="21"/></g>
<g fill="#c9ffc8" font-family="monospace" text-anchor="middle" font-size="12"><text x="132" y="77">P1</text><text x="278" y="77">P2</text><text x="139" y="144">P3</text><text x="271" y="144">P4</text></g>
<g fill="#74df83"><circle cx="132" cy="47" r="4"/><circle cx="278" cy="47" r="4"/><circle cx="139" cy="114" r="4"/><circle cx="271" cy="114" r="4"/></g>
<g fill="#121813" stroke="#59675d"><rect x="166" y="34" width="12" height="23"/><rect x="180" y="31" width="12" height="23"/><rect x="194" y="29" width="12" height="23"/><rect x="208" y="29" width="12" height="23"/><rect x="222" y="31" width="12" height="23"/><rect x="236" y="34" width="12" height="23"/></g>
<g fill="#121813" stroke="#59675d"><path d="M180 225l8 14h-16z"/><path d="M205 231l8 14h-16z"/><path d="M230 225l8 14h-16z"/></g>
<text x="205" y="104" fill="#d7b665" text-anchor="middle" font-family="monospace" font-size="11">LEXINGTON</text><text x="205" y="120" fill="#829184" text-anchor="middle" font-family="monospace" font-size="9">HEAVY CRUISER</text>
</svg>
<div class="bank-grid"><div class="bank"><span class="lamp"></span><b>P1</b><br><small>100% READY</small></div><div class="bank"><span class="lamp"></span><b>P2</b><br><small>100% READY</small></div><div class="bank"><span class="lamp"></span><b>P3</b><br><small>100% READY</small></div><div class="bank"><span class="lamp"></span><b>P4</b><br><small>100% READY</small></div></div>
</div>
</article>
</div>
<div class="column">
<article class="panel">
<div class="panel-head"><span>FIRE-CONTROL SOLUTION</span><span class="micro">DESIGNATED H-03</span></div>
<div class="panel-body">
<div class="contact-title"><span class="track-id">H-03</span><strong>GARGOYLE</strong><span class="muted">DREADNOUGHT</span></div>
<div class="solution"><div><div class="contact-grid" style="grid-template-columns:repeat(3,1fr)"><div class="datum"><span class="eyebrow">RANGE</span><b>10,048</b></div><div class="datum"><span class="eyebrow">MARK</span><b>093°</b></div><div class="datum"><span class="eyebrow">BANK REACH</span><b>2,000</b></div></div><div class="envelope"><span class="reach"></span><span class="target"></span></div><div class="tiny" style="display:flex;justify-content:space-between;margin-top:4px"><span>0</span><span class="good">PHASER ENVELOPE</span><span class="hostile">H-03 10,048</span><span>20K</span></div></div><div class="solution-score"><span class="eyebrow">SOLUTION</span><strong>NO SHOT</strong><br><span class="hostile">8,048 beyond reach</span></div></div>
<button class="execute">FIRE ALL BANKS — NO EFFECT / CONFIRM</button><div class="tiny amber" style="margin-top:5px">Permitted by the engine; no bank can reach the designated track.</div>
</div>
</article>
<article class="panel grow">
<div class="panel-head"><span>BANK CONTROL</span><span class="micro">SPREAD 20° · MARK 093°</span></div>
<div class="panel-body"><div class="weapons-list"><div class="weapon-cell"><span class="eyebrow">BANK P1</span><br><b>READY</b><br><span class="tiny">100% charge</span></div><div class="weapon-cell"><span class="eyebrow">BANK P2</span><br><b>READY</b><br><span class="tiny">100% charge</span></div><div class="weapon-cell"><span class="eyebrow">BANK P3</span><br><b>READY</b><br><span class="tiny">100% charge</span></div><div class="weapon-cell"><span class="eyebrow">BANK P4</span><br><b>READY</b><br><span class="tiny">100% charge</span></div></div><div class="status-row" style="margin-top:12px"><button class="chip">− SPREAD</button><span class="big-number">20°</span><button class="chip">+ SPREAD</button><button class="chip on">ALL BANKS</button></div><p class="tiny" style="margin-top:16px">Affiliation stays with the track. Weapon readiness stays with the machinery. Amber means the order is legal but tactically ineffective.</p></div>
</article>
</div>
</section>
</main>
<footer class="footer"><div class="footer-cap"></div><div class="event"><b>LAST ORDER / CY 11</b><span>Coming to course 45 · Venus firing 1 torpedo · Altair firing 4 torpedoes</span></div><button class="step">STEP ▸</button></footer>
</div>
<script>
const tracks = {
gargoyle:{name:'GARGOYLE',cls:'DREADNOUGHT',range:'10,048',bearing:'138°',closing:'514 / CY'},
cromoer:{name:'CROMOER',cls:'BATTLE CRUISER',range:'11,343',bearing:'136°',closing:'797 / CY'},
freen:{name:'FREEN',cls:'BATTLE CRUISER',range:'15,450',bearing:'157°',closing:'243 / CY'}
};
function selectTrack(id) {
document.querySelectorAll('.track').forEach(x=>x.classList.toggle('selected',x.dataset.track===id));
document.querySelectorAll('[data-row]').forEach(x=>x.classList.toggle('selected',x.dataset.row===id));
const t=tracks[id];
document.querySelector('#target-name').textContent=t.name;
document.querySelector('#target-class').textContent=t.cls;
document.querySelector('#target-range').textContent=t.range;
document.querySelector('#target-bearing').textContent=t.bearing;
document.querySelector('#target-closing').textContent=t.closing;
}
document.querySelectorAll('.track').forEach(x=>x.addEventListener('click',()=>selectTrack(x.dataset.track)));
document.querySelectorAll('[data-row]').forEach(x=>x.addEventListener('click',()=>selectTrack(x.dataset.row)));
document.querySelectorAll('.station-nav').forEach(b=>b.addEventListener('click',()=>{
document.querySelectorAll('.station-nav').forEach(x=>x.classList.remove('active'));
document.querySelectorAll('.station').forEach(x=>x.classList.remove('active'));
b.classList.add('active'); document.querySelector('#'+b.dataset.station).classList.add('active');
}));
document.querySelectorAll('.scope-tools button,.weapon-tabs button').forEach(b=>b.addEventListener('click',()=>{
[...b.parentElement.children].forEach(x=>x.classList.remove('on','active'));
b.classList.add(b.closest('.weapon-tabs')?'active':'on');
}));
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment