MridulNegi2005 commited on
Commit
488b143
·
1 Parent(s): 06c14d8

docs: add training metrics, wheel SVG, and legacy docs

Browse files
docs/README_legacy.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project Mahoraga
2
+
3
+ This is a controlled reinforcement learning environment designed to demonstrate adaptive intelligence via a resistance trade-off system.
4
+
5
+ ## Project Structure
6
+
7
+ - `env/`: Contains the core logic for the environment, state handling, enemy behavior, and mechanics.
8
+ - `utils/`: Contains constants and validators for actions.
9
+ - `tests/`: Contains manual basic sanity tests to verify correct environment behavior.
10
+ - `main.py`: Entry point to run a single manual episode with random actions.
docs/SYSTEM_REPORT.md ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project Mahoraga — Complete System Report
2
+
3
+ > **Version**: 1.0 (Post-Merge)
4
+ > **Branch**: `main` (fully merged from `phase1-env-setup`)
5
+ > **Tests**: 143/143 passing
6
+ > **Date**: 2026-04-25
7
+
8
+ ---
9
+
10
+ ## 1. Project Overview
11
+
12
+ **Project Mahoraga** is a reinforcement learning environment where an AI agent ("Mahoraga") learns adaptive combat through a resistance trade-off system. Named after Jujutsu Kaisen's Mahoraga — a shikigami that adapts to any attack — the system trains an LLM (Qwen 2.5 3B) to make tactical decisions in a turn-based combat loop.
13
+
14
+ **Core Loop**: `Observe → Adapt → Accumulate → Punish`
15
+
16
+ The agent must:
17
+ 1. Observe enemy attack patterns
18
+ 2. Build resistance to the correct attack category
19
+ 3. Accumulate adaptation stacks
20
+ 4. Execute Judgment Strike for burst damage at the right moment
21
+
22
+ **This is NOT a game.** It is a clean, testable RL environment designed for LLM fine-tuning via reward-weighted SFT.
23
+
24
+ ---
25
+
26
+ ## 2. Architecture Breakdown
27
+
28
+ ```
29
+ project_mahoraga/
30
+ ├── env/
31
+ │ ├── mahoraga_env.py # Main environment orchestrator
32
+ │ ├── mechanics.py # Resistance, damage, action math
33
+ │ ├── enemy.py # CurriculumEnemy (3-phase AI)
34
+ │ ├── rewards.py # 6-component composable reward system
35
+ │ ├── state.py # State dict builder
36
+ │ └── gym_wrapper.py # Gymnasium-compatible wrapper
37
+ ├── utils/
38
+ │ ├── constants.py # All game constants and mappings
39
+ │ └── validators.py # Action validation
40
+ ├── tests/
41
+ │ ├── test_env.py # 110 core tests
42
+ │ └── test_gym_wrapper.py # 33 wrapper tests
43
+ ├── notebooks/
44
+ │ ├── mahoraga_training.py # Training notebook (source)
45
+ │ └── mahoraga_training.ipynb # Training notebook (Kaggle)
46
+ ├── scripts/
47
+ │ └── random_agent_gym.py # Random agent demo
48
+ ├── app.py # Gradio interactive UI
49
+ ├── main.py # CLI episode runner
50
+ └── README.md
51
+ ```
52
+
53
+ ### Module Details
54
+
55
+ #### `env/mahoraga_env.py` — Environment Orchestrator
56
+ - `MahoragaEnv(debug=False)` — main class
57
+ - `reset()` → returns state dict
58
+ - `step(action)` → returns `(state, reward, done, info)`
59
+ - Coordinates enemy attacks, agent actions, reward computation
60
+ - Tracks: HP, resistances, adaptation stack, heal cooldown, last adapted category
61
+
62
+ #### `env/mechanics.py` — Core Math
63
+ - `new_resistances()` — creates `{PHYSICAL: 0, CE: 0, TECHNIQUE: 0}`
64
+ - `apply_resistance_change(res, type)` — +40 target, -20 others, clamp [0,80]
65
+ - `compute_enemy_damage(category, res, ignore_armor)` — damage formula
66
+ - `compute_judgment_damage(last_adapted, enemy_cat)` — adaptation-match burst
67
+ - `apply_action_effects(...)` — dispatches action 0-4
68
+ - `check_correct_adaptation(action, category)` — validates adaptation
69
+
70
+ #### `env/enemy.py` — CurriculumEnemy
71
+ - Single `CurriculumEnemy` class with 3-phase behavior
72
+ - `get_attack(turn_number, resistances)` → `{category, subtype, damage, ignore_armor}`
73
+ - Phase selection based on turn number
74
+
75
+ #### `env/rewards.py` — Composable Rewards
76
+ - 6 independent functions + 1 aggregator
77
+ - Returns dict, NOT a single scalar
78
+ - `compute_rewards(info, state, action, done)` → dict
79
+
80
+ #### `env/state.py` — State Builder
81
+ - Converts internal uppercase keys to lowercase for RL observation
82
+ - `build_state_dict(...)` → dict with 7 keys
83
+
84
+ #### `env/gym_wrapper.py` — Gymnasium Interface
85
+ - `MahoragaGymEnv(gym.Env)` wraps `MahoragaEnv`
86
+ - `Discrete(5)` action space, `Dict` observation space
87
+ - Encodes categoricals to integers for neural networks
88
+
89
+ #### `app.py` — Gradio UI
90
+ - Interactive combat arena with 5 action buttons
91
+ - Displays HP, resistances, stack, cooldown, combat log
92
+ - Launch: `python app.py`
93
+
94
+ ---
95
+
96
+ ## 3. Core Mechanics
97
+
98
+ ### Resistance System
99
+ Three categories: **PHYSICAL**, **CE**, **TECHNIQUE**. Range: [0, 80].
100
+
101
+ When agent adapts to a category:
102
+ - Target category: **+40**
103
+ - Other categories: **-20**
104
+ - All clamped to [0, 80]
105
+
106
+ Higher resistance = less damage from that category.
107
+
108
+ ### Action Space (0–4)
109
+
110
+ | Action | Name | Effect |
111
+ |--------|------|--------|
112
+ | 0 | Adapt PHYSICAL | +40 PHYSICAL res, -20 others |
113
+ | 1 | Adapt CE | +40 CE res, -20 others |
114
+ | 2 | Adapt TECHNIQUE | +40 TECHNIQUE res, -20 others |
115
+ | 3 | Judgment Strike | Deal damage, consume stacks, reset res |
116
+ | 4 | Regeneration | +300 HP, 3-turn cooldown |
117
+
118
+ ### Adaptation Stack
119
+ - +1 when agent correctly adapts to current enemy attack category
120
+ - Consumed by Judgment Strike: each stack adds +50 damage
121
+ - Reset to 0 after Judgment Strike
122
+
123
+ ### Judgment Strike Logic
124
+ **Condition**: Burst (350 dmg) if `last_adapted_category == current_enemy_category`
125
+ **Otherwise**: Base (100 dmg)
126
+ **Total**: `burst_or_base + (stacks × 50)`
127
+ **After**: Resistances reset to 0, stacks reset to 0
128
+
129
+ ### Heal Cooldown
130
+ - Heals +300 HP (capped at MAX_HP=1200)
131
+ - 3-turn cooldown after use
132
+ - Does NOT reset resistances
133
+ - If used while on cooldown → wasted turn (action nullified)
134
+
135
+ ### Damage Formula
136
+ ```
137
+ resistance = category_resistance
138
+ if ignore_armor:
139
+ resistance = resistance × 0.8 # 20% bypass (PIERCE only)
140
+ damage = base_damage × (1 - resistance / 100)
141
+ ```
142
+
143
+ ### HP Configuration
144
+ | Entity | HP |
145
+ |--------|----|
146
+ | Agent (Mahoraga) | 1200 |
147
+ | Enemy | 1000 |
148
+
149
+ ---
150
+
151
+ ## 4. Enemy System — CurriculumEnemy
152
+
153
+ Three-phase curriculum designed for progressive learning:
154
+
155
+ ### Phase 1: Tutorial (Turns 1–5)
156
+ - Always attacks with **PHYSICAL**
157
+ - Agent learns basic adaptation against a single category
158
+ - Predictable — builds confidence
159
+
160
+ ### Phase 2: Pattern (Turns 6–15)
161
+ - Cycles: **PHYSICAL → CE → TECHNIQUE**
162
+ - 15% random injection (picks random category instead of pattern)
163
+ - Agent learns to predict cycling patterns and handle surprises
164
+
165
+ ### Phase 3: Adaptive (Turns 16–25)
166
+ - **Targets the agent's lowest resistance category**
167
+ - Reads `resistances` dict, picks `min(resistances, key=resistances.get)`
168
+ - Agent must learn balanced defense or get exploited
169
+ - If no resistances provided, falls back to random
170
+
171
+ ### Subtypes
172
+ Each category has 3 subtypes (visual/variation only):
173
+
174
+ | Category | Subtypes |
175
+ |----------|----------|
176
+ | PHYSICAL | SLASH, IMPACT, **PIERCE** |
177
+ | CE | BLAST, WAVE, BEAM |
178
+ | TECHNIQUE | SPIKE, DELAYED, PATTERN |
179
+
180
+ **PIERCE** is special: `ignore_armor=True` → bypasses 20% of resistance.
181
+
182
+ ### Attack Dict Schema (LOCKED)
183
+ ```python
184
+ {
185
+ "category": "PHYSICAL" | "CE" | "TECHNIQUE",
186
+ "subtype": "SLASH" | "IMPACT" | ... ,
187
+ "damage": int,
188
+ "ignore_armor": bool
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 5. Reward System
195
+
196
+ Six independent components computed per step. Final reward = sum of all components.
197
+
198
+ | Component | Formula | Purpose | Typical Range |
199
+ |-----------|---------|---------|---------------|
200
+ | **Survival** | `-(damage_taken / 100)` | Penalize taking damage | [-2.2, 0] |
201
+ | **Combat** | `+(damage_dealt / 100)` | Reward dealing damage | [0, 4.5] |
202
+ | **Adaptation** | `+1.5` if correct, else `0` | **Strongest signal** — correct resistance match | {0, 1.5} |
203
+ | **Anti-Cowardice** | `-1.0` if heal at >70% HP | Prevent heal spam exploit | {-1.0, 0} |
204
+ | **Efficiency** | `+0.5` if damage >= 200 | Encourage big hits | {0, 0.5} |
205
+ | **Terminal** | `+5.0` win / `-5.0` loss | Strong episode-end signal | {-5.0, 0, 5.0} |
206
+
207
+ ### Why Each Exists
208
+ - **Survival**: Without it, agent ignores defense
209
+ - **Combat**: Without it, agent never attacks
210
+ - **Adaptation**: Core learning signal — the entire point of Mahoraga
211
+ - **Anti-Cowardice**: Agent discovers healing is "safe" and spams it; this prevents that
212
+ - **Efficiency**: Encourages building stacks before striking instead of weak Judgments
213
+ - **Terminal**: Large signal at episode boundary for credit assignment
214
+
215
+ ### Reward Breakdown
216
+ Every `step()` returns `info["reward_breakdown"]` with all 6 components as a dict. This is critical for debugging and analysis.
217
+
218
+ ---
219
+
220
+ ## 6. Training Pipeline
221
+
222
+ ### Model: Qwen 2.5 3B Instruct (via Unsloth)
223
+ - 4-bit quantized loading
224
+ - LoRA: r=16, targets q/k/v/o_proj, no bias
225
+ - max_seq_length: 1024
226
+
227
+ ### Prompt Design
228
+ ```
229
+ You are Mahoraga, an adaptive combat agent...
230
+ Current State: HP, resistances, last attack, turn
231
+ Available Actions: 0-4 with descriptions + strategy hints
232
+ → Return ONLY a single integer (0-4)
233
+ ```
234
+
235
+ ### Rollout Loop
236
+ 1. Reset env
237
+ 2. For each turn: build prompt → generate → parse action → env.step()
238
+ 3. Collect trajectory: `{prompt, response, action, reward, state, info}`
239
+ 4. Track: total reward, correct adaptation rate, win/loss
240
+
241
+ ### Reward-Weighted SFT (GRPO-style)
242
+ Instead of PPO (complex, unstable on T4s), uses reward-weighted supervised fine-tuning:
243
+ - Collect episodes with current model
244
+ - Weight actions by reward: **>1.0 → 3 copies**, **>0 → 2**, **>-1.5 → 1**, **else → skip**
245
+ - Fine-tune via SFTTrainer on weighted dataset
246
+ - Repeat for N iterations
247
+
248
+ ### Training Loop
249
+ ```
250
+ for iteration in range(5):
251
+ episodes = collect_episodes(10)
252
+ dataset = reward_weight(episodes)
253
+ sft_train(model, dataset)
254
+ save_checkpoint()
255
+ log_metrics()
256
+ ```
257
+
258
+ ### Checkpoints & Metrics
259
+ - LoRA weights saved per iteration: `/kaggle/working/checkpoints/iteration_N/`
260
+ - Metrics JSON: avg_reward, win_rate, avg_steps, adapt_rate
261
+ - Plot: 3-panel chart (reward, win rate, adaptation rate vs iteration)
262
+
263
+ ---
264
+
265
+ ## 7. UI System (Gradio)
266
+
267
+ ### Structure
268
+ - 5 action buttons (Adapt×3, Judgment, Heal) + Reset
269
+ - Two columns: Agent stats (HP, resistances, stack, cooldown) | Enemy stats (HP, turn, reward)
270
+ - Monospace combat log
271
+
272
+ ### State Mapping
273
+ UI reads directly from `MahoragaEnv` instance — no intermediary layer.
274
+
275
+ ### Log Format
276
+ ```
277
+ Turn X:
278
+ Enemy:
279
+ → [Subtype] ([Category])
280
+ Mahoraga:
281
+ → [Action]
282
+ Result:
283
+ → Damage: Y | Correct Adaptation: YES/NO | Stack: Z
284
+ → Reward: R.RR
285
+ ```
286
+
287
+ ---
288
+
289
+ ## 8. Data Flow
290
+
291
+ ```
292
+ ┌─────────┐ ┌──────────┐ ┌───────�� ┌────────┐ ┌─────┐
293
+ │ State │───▶│ Prompt │───▶│ Model │───▶│ Action │───▶│ Env │
294
+ │ Dict │ │ Builder │ │ (LLM) │ │ Parser │ │ │
295
+ └─────────┘ └──────────┘ └───────┘ └────────┘ └──┬──┘
296
+
297
+ ┌───────────────────────────────────────────────────────┘
298
+
299
+
300
+ ┌──────────┐ ┌──────────┐ ┌──────────────┐
301
+ │ Rewards │───▶│ Dataset │───▶│ SFT Trainer │
302
+ │ (6 comp) │ │ (weight) │ │ (LoRA update)│
303
+ └──────────┘ └──────────┘ └──────────────┘
304
+ ```
305
+
306
+ 1. **State** → 7-key dict (HP, resistances, last attack, turn, etc.)
307
+ 2. **Prompt** → Natural language with state + action descriptions
308
+ 3. **Model** → Generates single integer 0-4
309
+ 4. **Parser** → Extracts int, fallback to 0
310
+ 5. **Env** → Applies action, computes damage, checks termination
311
+ 6. **Rewards** → 6 independent components, summed to scalar
312
+ 7. **Dataset** → High-reward actions duplicated, low-reward filtered
313
+ 8. **Training** → SFT on weighted dataset updates LoRA weights
314
+
315
+ ---
316
+
317
+ ## 9. Key Design Decisions
318
+
319
+ | Decision | Rationale |
320
+ |----------|-----------|
321
+ | **Unified schema** (`category/damage/ignore_armor`) | Two teams used different field names; unified to prevent silent bugs |
322
+ | **CurriculumEnemy** | Progressive difficulty prevents early collapse; Phase 3 forces balanced play |
323
+ | **Adaptation-match Judgment** | Old threshold-based burst was exploitable; matching requires tactical awareness |
324
+ | **Composable rewards (NOT monolithic)** | Debugging, tuning, and analysis require visibility into individual signals |
325
+ | **Reward-weighted SFT over PPO** | PPO on T4 GPUs with LLMs is unstable; GRPO-style SFT is simpler and proven |
326
+ | **Asymmetric HP (1200 vs 1000)** | Slight agent advantage encourages exploration; symmetric HP led to agent always losing |
327
+ | **Heal does NOT reset resistances** | Prevents heal+reset exploit that nullifies adaptation investment |
328
+
329
+ ---
330
+
331
+ ## 10. Known Risks / Edge Cases
332
+
333
+ | Risk | Description | Mitigation |
334
+ |------|-------------|------------|
335
+ | **Reward imbalance** | Adaptation (+1.5) may dominate over combat signals | Monitor adapt_rate; if >80%, reduce adaptation reward |
336
+ | **Over-adaptation** | Agent may only adapt, never attack | Terminal reward (-5.0 loss) penalizes passive play |
337
+ | **Phase 3 exploit** | Agent could learn to keep all resistances equal to confuse Phase 3 | Phase 3 picks min, so equal res still gets attacked |
338
+ | **Training instability** | SFT on small datasets can overfit | Use gradient accumulation, low LR (2e-5), 1 epoch per iter |
339
+ | **Heal spam** | Agent learns heal is safe | Anti-cowardice penalty (-1.0) + cooldown (3 turns) |
340
+ | **Wasted turns** | Heal on cooldown wastes a turn | Action nullified, no positive rewards possible |
341
+ | **PIERCE bypass** | 20% resistance bypass can surprise agent | Only 1/3 chance of PIERCE subtype, negligible long-term |
342
+ | **Zero reward on notebook** | Cloning wrong branch (main vs phase1-env-setup) | Notebook has `--branch phase1-env-setup` + assertion check |
343
+
344
+ ---
345
+
346
+ ## 11. How to Run
347
+
348
+ ### Local Environment
349
+ ```bash
350
+ cd project_mahoraga
351
+ python main.py # Run random episode
352
+ python tests/test_env.py # Run 110 core tests
353
+ python tests/test_gym_wrapper.py # Run 33 gym tests
354
+ ```
355
+
356
+ ### Gradio UI
357
+ ```bash
358
+ cd project_mahoraga
359
+ python app.py # Opens browser at localhost:7860
360
+ ```
361
+
362
+ ### Kaggle Training
363
+ 1. Upload `notebooks/mahoraga_training.ipynb` to Kaggle
364
+ 2. Enable **GPU** (2× T4)
365
+ 3. Run all 14 cells in order
366
+ 4. Model saves to `/kaggle/working/mahoraga_lora_final`
367
+
368
+ ### Debug Mode
369
+ ```python
370
+ env = MahoragaEnv(debug=True)
371
+ # Prints reward breakdown every step
372
+ ```
373
+
374
+ ---
375
+
376
+ ## 12. Future Improvements
377
+
378
+ | Area | Improvement | Effort |
379
+ |------|-------------|--------|
380
+ | **Training** | Replace reward-weighted SFT with true GRPO/PPO | High |
381
+ | **Enemy** | Add Phase 4: combo attacks (multi-type per turn) | Medium |
382
+ | **Enemy** | Better randomness model (Markov chain instead of uniform) | Medium |
383
+ | **Rewards** | Dynamic reward scaling based on training progress | Medium |
384
+ | **Multi-agent** | Two Mahoraga agents competing | High |
385
+ | **Observation** | Add enemy history buffer (last N attacks) to state | Low |
386
+ | **UI** | Add resistance bar charts, HP progress graphs | Low |
387
+ | **Eval** | Automated benchmark suite (win rate vs each phase) | Medium |
388
+ | **Deploy** | HuggingFace Spaces deployment for Gradio UI | Low |
389
+
390
+ ---
391
+
392
+ ## 13. Git History
393
+
394
+ ```
395
+ ec92cdd MERGE: Unified schema, CurriculumEnemy, Gradio UI
396
+ c8f2f7c CRITICAL FIX: Clone correct branch + debug mode
397
+ cfb710a Phase 5: Kaggle training notebook
398
+ e9f91da Phase 4: Gymnasium wrapper
399
+ fd4d842 Phase 3: Composable reward system
400
+ b27a5b7 Phase 2: Enemy subtypes
401
+ 5ed57fe Patch: Judgment/heal/HP fixes
402
+ 832e7c6 Phase 1: Core environment
403
+ 22712d1 Initial commit
404
+ ```
405
+
406
+ ---
407
+
408
+ ## 14. Constants Reference
409
+
410
+ ```python
411
+ MAX_HP = 1200 # Agent HP
412
+ ENEMY_HP = 1000 # Enemy HP
413
+ MAX_TURNS = 25
414
+ ADAPT_INCREASE = 40 # Resistance gain on adapt
415
+ ADAPT_DECREASE = 20 # Resistance loss on others
416
+ RESISTANCE_MAX = 80
417
+ JUDGMENT_BASE_DAMAGE = 100
418
+ JUDGMENT_BURST_DAMAGE = 350
419
+ HEAL_AMOUNT = 300
420
+ HEAL_COOLDOWN = 3
421
+ ARMOR_BYPASS_RATIO = 0.2 # PIERCE effect
422
+ PHASE_1_END = 5
423
+ PHASE_2_END = 15
424
+ PHASE_2_DEVIATION = 0.15
425
+ ```
426
+
427
+ ---
428
+
429
+ *This report is a complete knowledge transfer document. A new engineer or AI model should be able to understand, modify, and extend the system using only this document and the source code.*
docs/mahoraga_wheel.svg ADDED

Git LFS Details

  • SHA256: aca66ee9493cc3aa29835f02c94eb57a4f1ac71545daf0180f58b66eb23b2225
  • Pointer size: 129 Bytes
  • Size of remote file: 4.79 kB
docs/stitch_aero_dashboard.html ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+
3
+ <html class="dark" lang="en"><head>
4
+ <meta charset="utf-8"/>
5
+ <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
6
+ <title>Combat Dashboard - Aero-Tactical</title>
7
+ <script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&amp;display=swap" rel="stylesheet"/>
9
+ <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
10
+ <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
11
+ <script id="tailwind-config">
12
+ tailwind.config = {
13
+ darkMode: "class",
14
+ theme: {
15
+ extend: {
16
+ "colors": {
17
+ "surface-dim": "#0b1120",
18
+ "secondary-container": "#1e293b",
19
+ "primary-container": "#1e3a8a",
20
+ "on-secondary-container": "#cbd5e1",
21
+ "surface-variant": "#1e293b",
22
+ "on-background": "#f8fafc",
23
+ "surface-container-lowest": "#020617",
24
+ "on-secondary": "#020617",
25
+ "on-tertiary-fixed": "#020617",
26
+ "inverse-surface": "#f8fafc",
27
+ "on-tertiary": "#020617",
28
+ "primary-fixed-dim": "#3b82f6",
29
+ "surface-tint": "#0ea5e9",
30
+ "surface": "#0f172a",
31
+ "on-tertiary-fixed-variant": "#020617",
32
+ "tertiary-fixed-dim": "#1e293b",
33
+ "on-error": "#020617",
34
+ "inverse-on-surface": "#020617",
35
+ "secondary-fixed-dim": "#64748b",
36
+ "on-secondary-fixed-variant": "#020617",
37
+ "on-primary-fixed": "#020617",
38
+ "tertiary-fixed": "#334155",
39
+ "inverse-primary": "#1e3a8a",
40
+ "on-primary-container": "#dbeafe",
41
+ "tertiary-container": "#1e293b",
42
+ "secondary": "#64748b",
43
+ "tertiary": "#94a3b8",
44
+ "on-primary-fixed-variant": "#020617",
45
+ "on-error-container": "#fecaca",
46
+ "surface-container-low": "#0b1120",
47
+ "on-surface-variant": "#94a3b8",
48
+ "surface-bright": "#1e293b",
49
+ "secondary-fixed": "#94a3b8",
50
+ "surface-container-highest": "#334155",
51
+ "on-surface": "#f8fafc",
52
+ "primary": "#00f6ff",
53
+ "background": "#0b1120",
54
+ "on-primary": "#000000",
55
+ "outline-variant": "#334155",
56
+ "error-container": "#7f1d1d",
57
+ "outline": "#475569",
58
+ "on-secondary-fixed": "#020617",
59
+ "error": "#f87171",
60
+ "surface-container": "#0f172a",
61
+ "on-tertiary-container": "#00f6ff",
62
+ "primary-fixed": "#bfdbfe",
63
+ "surface-container-high": "#1e293b"
64
+ },
65
+ "borderRadius": {
66
+ "DEFAULT": "0.125rem",
67
+ "lg": "0.25rem",
68
+ "xl": "0.5rem",
69
+ "full": "0.75rem"
70
+ },
71
+ "spacing": {
72
+ "gutter": "20px",
73
+ "sm": "8px",
74
+ "lg": "24px",
75
+ "xl": "40px",
76
+ "unit": "4px",
77
+ "margin": "32px",
78
+ "md": "16px",
79
+ "xs": "4px"
80
+ },
81
+ "fontFamily": {
82
+ "body-md": ["Inter"],
83
+ "label-caps": ["Inter"],
84
+ "mono-data": ["monospace"],
85
+ "display": ["Inter"],
86
+ "h1": ["Inter"],
87
+ "h2": ["Inter"],
88
+ "body-lg": ["Inter"]
89
+ },
90
+ "fontSize": {
91
+ "body-md": ["16px", { "lineHeight": "1.5", "fontWeight": "400" }],
92
+ "label-caps": ["12px", { "lineHeight": "1", "letterSpacing": "0.05em", "fontWeight": "600" }],
93
+ "mono-data": ["14px", { "lineHeight": "1.4", "fontWeight": "500" }],
94
+ "display": ["48px", { "lineHeight": "1.1", "letterSpacing": "-0.02em", "fontWeight": "700" }],
95
+ "h1": ["32px", { "lineHeight": "1.2", "letterSpacing": "-0.01em", "fontWeight": "600" }],
96
+ "h2": ["24px", { "lineHeight": "1.3", "fontWeight": "600" }],
97
+ "body-lg": ["18px", { "lineHeight": "1.6", "fontWeight": "400" }]
98
+ }
99
+ }
100
+ }
101
+ }
102
+ </script>
103
+ <style>
104
+ .glass-panel {
105
+ background-color: rgba(15, 23, 42, 0.65);
106
+ backdrop-filter: blur(12px);
107
+ border: 1px solid rgba(255, 255, 255, 0.1);
108
+ }
109
+ </style>
110
+ <style>
111
+ @keyframes mahoraga-click {
112
+ 0% { transform: rotate(0deg); }
113
+ 100% { transform: rotate(45deg); }
114
+ }
115
+ .animate-mahoraga-click {
116
+ animation: mahoraga-click 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
117
+ }
118
+ .mahoraga-wheel-spoke {
119
+ transform-origin: center;
120
+ }
121
+ </style></head>
122
+ <body class="bg-background text-on-background font-body-md text-body-md antialiased overflow-x-hidden">
123
+ <!-- TopAppBar -->
124
+ <header class="fixed top-0 w-full z-50 border-b border-slate-700/50 bg-[#0b1120]/80 backdrop-blur-md text-slate-300 shadow-none flex justify-between items-center h-14 px-8 max-w-full">
125
+ <div class="flex items-center gap-4">
126
+ <span class="text-lg font-black tracking-tighter text-slate-100 uppercase">AERO-TACTICAL</span>
127
+ </div>
128
+ <div class="flex items-center gap-6">
129
+ <div class="flex items-center gap-4 font-inter text-xs tracking-widest uppercase font-semibold text-slate-400">
130
+ <button class="hover:bg-slate-800/50 transition-colors p-2 rounded-DEFAULT"><span class="material-symbols-outlined">notifications_active</span></button>
131
+ <button class="hover:bg-slate-800/50 transition-colors p-2 rounded-DEFAULT"><span class="material-symbols-outlined">settings</span></button>
132
+ <button class="hover:bg-slate-800/50 transition-colors p-2 rounded-DEFAULT"><span class="material-symbols-outlined">account_circle</span></button>
133
+ </div>
134
+ <button class="bg-primary text-on-primary font-label-caps text-label-caps px-4 py-2 rounded-DEFAULT hover:opacity-90 transition-opacity">
135
+ SYSTEM READY
136
+ </button>
137
+ </div>
138
+ </header>
139
+ <!-- SideNavBar -->
140
+ <nav class="hidden md:flex fixed left-0 top-0 h-screen w-64 border-r border-slate-700/50 bg-[#0b1120]/90 backdrop-blur-xl flex-col py-20 px-4 z-40">
141
+ <div class="mb-8 px-4">
142
+ <h2 class="text-xl font-bold text-slate-100 tracking-tight">STRAT-COM</h2>
143
+ <p class="font-inter text-sm tracking-tight text-slate-400 mt-1">Sector 7G - Active</p>
144
+ </div>
145
+ <button class="bg-surface-tint text-on-primary font-label-caps text-label-caps w-full py-3 rounded-DEFAULT mb-8 hover:opacity-90 transition-opacity">
146
+ NEW DEPLOYMENT
147
+ </button>
148
+ <div class="flex-1 flex flex-col gap-2">
149
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight" href="#">
150
+ <span class="material-symbols-outlined">radar</span> Tactical Map
151
+ </a>
152
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight" href="#">
153
+ <span class="material-symbols-outlined">hub</span> Fleet Comms
154
+ </a>
155
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight" href="#">
156
+ <span class="material-symbols-outlined">inventory_2</span> Logistics
157
+ </a>
158
+ <a class="bg-slate-800 text-[#00f6ff] border-l-2 border-[#00f6ff] font-medium px-4 py-3 flex items-center gap-3 transition-all rounded-r-DEFAULT translate-x-1 font-inter text-sm tracking-tight" href="#">
159
+ <span class="material-symbols-outlined">videocam</span> Surveillance
160
+ </a>
161
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight" href="#">
162
+ <span class="material-symbols-outlined">analytics</span> Mission Intel
163
+ </a>
164
+ </div>
165
+ <div class="mt-auto flex flex-col gap-2 border-t border-slate-700/50 pt-4">
166
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight" href="#">
167
+ <span class="material-symbols-outlined">help</span> Support
168
+ </a>
169
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight" href="#">
170
+ <span class="material-symbols-outlined">keyboard</span> Terminal
171
+ </a>
172
+ <a class="text-slate-400 px-4 py-3 flex items-center gap-3 hover:bg-slate-800 transition-all rounded-DEFAULT font-inter text-sm tracking-tight mt-4 text-error" href="#">
173
+ <span class="material-symbols-outlined">logout</span> Log Out
174
+ </a>
175
+ </div>
176
+ </nav>
177
+ <!-- Main Content Canvas -->
178
+ <main class="pt-20 md:pl-72 pr-8 pb-12 min-h-screen">
179
+ <div class="max-w-7xl mx-auto space-y-gutter">
180
+ <!-- Header Section -->
181
+ <div class="flex justify-between items-end mb-margin">
182
+ <div>
183
+ <h1 class="font-h1 text-h1 text-on-surface">Surveillance Feed</h1>
184
+ <p class="font-body-md text-body-md text-on-surface-variant mt-2">Monitoring Subject Alpha engagement parameters.</p>
185
+ </div>
186
+ <div class="text-right">
187
+ <span class="font-label-caps text-label-caps text-on-tertiary-container uppercase block mb-1">Status</span>
188
+ <span class="font-mono-data text-mono-data text-on-surface bg-surface-container px-3 py-1 rounded-DEFAULT border border-outline-variant">ACTIVE ENGAGEMENT</span>
189
+ </div>
190
+ </div>
191
+ <!-- Bento Grid Layout -->
192
+ <div class="grid grid-cols-1 lg:grid-cols-12 gap-gutter">
193
+ <!-- Target Status (Span 8) -->
194
+ <div class="lg:col-span-8 glass-panel rounded-xl p-lg flex flex-col">
195
+ <div class="flex justify-between items-center mb-6 border-b border-outline-variant/30 pb-4">
196
+ <h2 class="font-h2 text-h2 text-on-surface flex items-center gap-2">
197
+ <span class="material-symbols-outlined text-outline">target</span> Target Status: Enemy
198
+ </h2>
199
+ <span class="font-mono-data text-mono-data text-outline">ID: E-9942</span>
200
+ </div>
201
+ <div class="flex-1 flex flex-col justify-center gap-6">
202
+ <div class="flex items-center justify-between">
203
+ <span class="font-label-caps text-label-caps text-on-surface-variant uppercase">Structural Integrity</span>
204
+ <span class="font-mono-data text-mono-data text-on-surface">42.8%</span>
205
+ </div>
206
+ <div class="w-full bg-surface-container-high h-2 rounded-full overflow-hidden">
207
+ <div class="bg-primary h-full rounded-full" style="width: 42.8%;"></div>
208
+ </div>
209
+ <div class="grid grid-cols-3 gap-4 mt-4">
210
+ <div class="bg-surface p-4 rounded-lg border border-outline-variant/20">
211
+ <span class="font-label-caps text-label-caps text-on-surface-variant block mb-2">Distance</span>
212
+ <span class="font-mono-data text-mono-data text-on-surface text-lg">14.2m</span>
213
+ </div>
214
+ <div class="bg-surface p-4 rounded-lg border border-outline-variant/20">
215
+ <span class="font-label-caps text-label-caps text-on-surface-variant block mb-2">Velocity</span>
216
+ <span class="font-mono-data text-mono-data text-on-surface text-lg">340 m/s</span>
217
+ </div>
218
+ <div class="bg-surface p-4 rounded-lg border border-outline-variant/20">
219
+ <span class="font-label-caps text-label-caps text-on-surface-variant block mb-2">Threat Level</span>
220
+ <span class="font-mono-data text-mono-data text-error font-bold text-lg">CRITICAL</span>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ <!-- Engine Core (Span 4) -->
226
+ <div class="lg:col-span-4 glass-panel rounded-xl p-lg flex flex-col">
227
+ <div class="flex justify-between items-center mb-6 border-b border-outline-variant/30 pb-4">
228
+ <h2 class="font-body-lg text-body-lg font-semibold text-on-surface flex items-center gap-2">
229
+ <span class="material-symbols-outlined text-outline">memory</span> Core: Mahoraga
230
+ </h2>
231
+ </div>
232
+ <div class="flex-1 flex flex-col gap-4">
233
+ <div class="flex justify-between items-center p-3 bg-surface rounded-lg border border-outline-variant/20">
234
+ <span class="font-label-caps text-label-caps text-on-surface-variant">Adaptation Rate</span>
235
+ <span class="font-mono-data text-mono-data text-on-tertiary-container font-bold">+2.4%/s</span>
236
+ </div>
237
+ <div class="flex justify-between items-center p-3 bg-surface rounded-lg border border-outline-variant/20">
238
+ <span class="font-label-caps text-label-caps text-on-surface-variant">Wheel Rotation</span>
239
+ <span class="font-mono-data text-mono-data text-on-surface">3/8</span>
240
+ </div>
241
+ <div class="flex justify-between items-center p-3 bg-surface rounded-lg border border-outline-variant/20">
242
+ <span class="font-label-caps text-label-caps text-on-surface-variant">Energy Output</span>
243
+ <span class="font-mono-data text-mono-data text-on-surface">104.2 GW</span>
244
+ </div>
245
+ <div class="mt-auto pt-4">
246
+ <div class="w-full h-[120px] bg-surface rounded-lg border border-outline-variant/20 relative overflow-hidden" data-alt="Abstract visualization of a spinning gear or wheel mechanism, composed of thin, precise technical lines in slate and subtle orange, on a clean, light frost background">
247
+ <!-- Placeholder for complex technical visualization -->
248
+ <div class="absolute inset-0 flex items-center justify-center"><div class="relative w-24 h-24 animate-mahoraga-click">
249
+ <svg class="w-full h-full text-primary opacity-80" viewbox="0 0 100 100">
250
+ <circle class="opacity-30" cx="50" cy="50" fill="none" r="45" stroke="currentColor" stroke-dasharray="2 2" stroke-width="1"></circle>
251
+ <circle cx="50" cy="50" fill="none" r="8" stroke="currentColor" stroke-width="2"></circle>
252
+ <circle cx="50" cy="50" fill="none" r="35" stroke="currentColor" stroke-width="0.5"></circle>
253
+ <g class="mahoraga-wheel-spoke">
254
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
255
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
256
+ </g>
257
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(45deg);">
258
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
259
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
260
+ </g>
261
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(90deg);">
262
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
263
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
264
+ </g>
265
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(135deg);">
266
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
267
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
268
+ </g>
269
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(180deg);">
270
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
271
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
272
+ </g>
273
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(225deg);">
274
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
275
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
276
+ </g>
277
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(270deg);">
278
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
279
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
280
+ </g>
281
+ <g class="mahoraga-wheel-spoke" style="transform: rotate(315deg);">
282
+ <line stroke="currentColor" stroke-width="2" x1="50" x2="50" y1="15" y2="42"></line>
283
+ <circle cx="50" cy="12" fill="currentColor" r="3"></circle>
284
+ </g>
285
+ </svg>
286
+ <div class="absolute inset-0 flex items-center justify-center">
287
+ <div class="w-1 h-1 bg-primary rounded-full animate-ping"></div>
288
+ </div>
289
+ </div></div>
290
+ </div>
291
+ </div>
292
+ </div>
293
+ </div>
294
+ <!-- Big Moments Card (Span 12) -->
295
+ <div class="lg:col-span-12 glass-panel rounded-xl p-xl border-l-4 border-l-tertiary-container relative overflow-hidden flex items-center justify-between bg-gradient-to-r from-surface-container-low to-surface-container-lowest">
296
+ <div class="z-10">
297
+ <span class="font-label-caps text-label-caps text-on-tertiary-container tracking-widest block mb-2"><span class="material-symbols-outlined text-xs align-middle mr-2 text-primary">refresh</span>TACTICAL ANALYSIS UPDATE</span>
298
+ <h2 class="font-display text-display text-on-surface tracking-tight uppercase">JUDGMENT STRIKE - ADAPTED</h2>
299
+ <p class="font-body-md text-body-md text-on-surface-variant mt-4 max-w-2xl">Subject has successfully analyzed and developed countermeasures to the incoming blunt force trauma attack pattern. Defensive parameters updated.</p>
300
+ </div>
301
+ <div class="z-10 hidden md:block">
302
+ <span class="material-symbols-outlined text-[80px] text-tertiary-container opacity-20">shield_lock</span>
303
+ </div>
304
+ </div>
305
+ <!-- Resistances & Counters (Span 6) -->
306
+ <div class="lg:col-span-6 glass-panel rounded-xl p-lg flex flex-col">
307
+ <div class="flex justify-between items-center mb-6 border-b border-outline-variant/30 pb-4">
308
+ <h2 class="font-body-lg text-body-lg font-semibold text-on-surface flex items-center gap-2">
309
+ <span class="material-symbols-outlined text-outline">security</span> Active Resistances
310
+ </h2>
311
+ </div>
312
+ <div class="space-y-3">
313
+ <div class="flex items-center justify-between p-3 bg-surface rounded-lg border border-outline-variant/20">
314
+ <div class="flex items-center gap-3">
315
+ <span class="material-symbols-outlined text-outline-variant">water_drop</span>
316
+ <span class="font-body-md text-body-md text-on-surface">Hydro-Kinetics</span>
317
+ </div>
318
+ <span class="font-label-caps text-label-caps bg-surface-container-high px-2 py-1 rounded text-on-surface-variant">IMMUNE</span>
319
+ </div>
320
+ <div class="flex items-center justify-between p-3 bg-surface rounded-lg border border-outline-variant/20">
321
+ <div class="flex items-center gap-3">
322
+ <span class="material-symbols-outlined text-outline-variant">local_fire_department</span>
323
+ <span class="font-body-md text-body-md text-on-surface">Thermal Output</span>
324
+ </div>
325
+ <span class="font-label-caps text-label-caps bg-surface-container-high px-2 py-1 rounded text-on-surface-variant">94% MITIGATION</span>
326
+ </div>
327
+ <div class="flex items-center justify-between p-3 bg-surface rounded-lg border border-outline-variant/20">
328
+ <div class="flex items-center gap-3">
329
+ <span class="material-symbols-outlined text-outline-variant">electric_bolt</span>
330
+ <span class="font-body-md text-body-md text-on-surface">Electromagnetic</span>
331
+ </div>
332
+ <span class="font-label-caps text-label-caps bg-surface-container-high px-2 py-1 rounded text-on-surface-variant">ANALYZING...</span>
333
+ </div>
334
+ </div>
335
+ </div>
336
+ <!-- Event Log (Span 6) -->
337
+ <div class="lg:col-span-6 glass-panel rounded-xl p-lg flex flex-col h-[320px]">
338
+ <div class="flex justify-between items-center mb-4 border-b border-outline-variant/30 pb-4">
339
+ <h2 class="font-body-lg text-body-lg font-semibold text-on-surface flex items-center gap-2">
340
+ <span class="material-symbols-outlined text-outline">list_alt</span> Turn Log
341
+ </h2>
342
+ <button class="text-on-surface-variant hover:text-on-surface"><span class="material-symbols-outlined text-sm">filter_list</span></button>
343
+ </div>
344
+ <div class="flex-1 overflow-y-auto space-y-4 pr-2">
345
+ <div class="flex gap-4 items-start">
346
+ <span class="font-mono-data text-mono-data text-outline-variant text-xs mt-1 w-16">14:02:44</span>
347
+ <div class="flex-1 border-l border-outline-variant/30 pl-4 pb-2"><span class="material-symbols-outlined text-[10px] align-middle mr-1 text-primary animate-spin">published_with_changes</span>
348
+ <span class="font-label-caps text-label-caps text-on-tertiary-container block mb-1">ADAPTATION COMPLETE</span>
349
+ <p class="font-body-md text-body-md text-on-surface text-sm">Mahoraga wheel completed rotation. Strike countered.</p>
350
+ </div>
351
+ </div>
352
+ <div class="flex gap-4 items-start">
353
+ <span class="font-mono-data text-mono-data text-outline-variant text-xs mt-1 w-16">14:02:41</span>
354
+ <div class="flex-1 border-l border-outline-variant/30 pl-4 pb-2">
355
+ <span class="font-label-caps text-label-caps text-error block mb-1">INCOMING ATTACK DETECTED</span>
356
+ <p class="font-body-md text-body-md text-on-surface text-sm">Enemy initiated Judgment Strike sequence.</p>
357
+ </div>
358
+ </div>
359
+ <div class="flex gap-4 items-start">
360
+ <span class="font-mono-data text-mono-data text-outline-variant text-xs mt-1 w-16">14:02:35</span>
361
+ <div class="flex-1 border-l border-outline-variant/30 pl-4 pb-2">
362
+ <span class="font-label-caps text-label-caps text-on-surface-variant block mb-1">POSITION UPDATE</span>
363
+ <p class="font-body-md text-body-md text-on-surface text-sm">Target distance decreased by 4.2m.</p>
364
+ </div>
365
+ </div>
366
+ <div class="flex gap-4 items-start">
367
+ <span class="font-mono-data text-mono-data text-outline-variant text-xs mt-1 w-16">14:02:20</span>
368
+ <div class="flex-1 border-l border-outline-variant/30 pl-4 pb-2">
369
+ <span class="font-label-caps text-label-caps text-on-surface-variant block mb-1">SCAN COMPLETE</span>
370
+ <p class="font-body-md text-body-md text-on-surface text-sm">Initial environment parameters mapped.</p>
371
+ </div>
372
+ </div>
373
+ </div>
374
+ </div>
375
+ </div>
376
+ </div>
377
+ </main>
378
+ </body></html>
docs/stitch_aero_screenshot.png ADDED

Git LFS Details

  • SHA256: 55c79ae13b66bfe6fc8af0d856eac6b004faaa66060d3ad9743daecb222e90de
  • Pointer size: 130 Bytes
  • Size of remote file: 78 kB
docs/training_metrics.png ADDED

Git LFS Details

  • SHA256: ffd2f62b19e394466288ecb7d66167ee13403bab2f0f42d0cb7f398c93e7ea7b
  • Pointer size: 131 Bytes
  • Size of remote file: 473 kB