Skip to content

Commit 7d43295

Browse files
authored
Merge pull request #126 from openrocket/april-fools
AI analysis!
2 parents 5b1a1a3 + 1be1a3f commit 7d43295

7 files changed

Lines changed: 618 additions & 1 deletion

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
- Analyzing fin planform, mass distribution, and recovery setup...
2+
- Estimating drag coefficient...
3+
- Consulting the neural wind tunnel...
4+
- Checking whether the center of pressure is in a healthy long-distance relationship with the center of gravity...
5+
- Measuring the aerodynamic impact of pure optimism...
6+
- Calibrating the probably-fine detector...
7+
- Comparing your design against several thousand pointy objects...

_data/ai_analyzer_results.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
- title: "Analysis complete:"
2+
lines:
3+
- 'Your rocket has been classified as "pointy".'
4+
- This matches 97.3% of successful rocket designs.
5+
6+
- title: "Result:"
7+
lines:
8+
- 'Our AI recommends flying it "just once to see what happens,"'
9+
10+
- title: "Deep analysis finished:"
11+
lines:
12+
- "Your .ork file contains:"
13+
- 1 rocket
14+
- ambitious optimism
15+
16+
- title: "Simulation summary:"
17+
lines:
18+
- "Apogee: somewhere up there"
19+
- "Landing zone: theoretically nearby"
20+
- "Confidence: unreasonably high"
21+
22+
- title: "Neural analysis complete:"
23+
lines:
24+
- "We compared your rocket against thousands of designs and concluded:"
25+
- "yes, this is definitely a rocket."
26+
27+
- title: "Flight readiness score: 8.7/10"
28+
lines:
29+
- Deducted points because the paint job is not yet at maximum aerodynamic coolness.
30+
31+
- title: "Advanced recommendation:"
32+
lines:
33+
- Try turning the rocket off and on again.
34+
35+
- title: "OpenRocket AI verdict:"
36+
lines:
37+
- "We ran a large language model on your .ork file."
38+
- "It does not understand XML, but it feels very confident about the fins."

_layouts/default.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<script src="/assets/js/media-utilities.js"></script>
66

77
{% include head.html %}
8-
<body {% if page.id %}id="{{ page.id }}"{% endif %}>
8+
<body {% assign body_id = page.body_id | default: page.id %}{% if body_id %}id="{{ body_id }}"{% endif %}>
99
<!--[if lt IE 8]>
1010
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
1111
<![endif]-->

_pages/ai-analyzer.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: OpenRocket AI Analyzer
3+
layout: interior-page
4+
body_id: ai-analyzer
5+
permalink: /ai-analyzer.html
6+
---
7+
8+
<link rel="stylesheet" href="/assets/css/ai-analyzer.css">
9+
10+
<div class="ai-analyzer-shell">
11+
<section class="ai-card ai-main-card">
12+
<h1>OpenRocket AI Analyzer</h1>
13+
<p class="ai-subtitle">
14+
Upload your <code>.ork</code> file and let our advanced AI take a look.
15+
</p>
16+
17+
<label for="ork-file-input" id="ai-upload-zone" class="ai-upload-zone">
18+
<input id="ork-file-input" class="ai-file-input" type="file" accept=".ork">
19+
<i class="fa-solid fa-upload" aria-hidden="true"></i>
20+
<strong>Drag and drop your .ork file here</strong>
21+
<span>or click to browse</span>
22+
</label>
23+
24+
<p id="ai-selected-file" class="ai-selected-file" aria-live="polite">
25+
No file selected yet.
26+
</p>
27+
28+
<div id="ai-analyze-actions" class="ai-analyze-actions" hidden>
29+
<button id="ai-analyze-button" type="button" class="btn btn-primary btn-lg ai-analyze-button">
30+
Analyze
31+
</button>
32+
</div>
33+
34+
<div id="ai-analysis-panel" class="ai-analysis-panel" hidden>
35+
<div class="ai-progress-track" aria-hidden="true">
36+
<div id="ai-progress-bar" class="ai-progress-bar"></div>
37+
</div>
38+
<p id="ai-loading-text" class="ai-loading-text" aria-live="polite">
39+
Parsing fin geometry...
40+
</p>
41+
</div>
42+
43+
<section id="ai-result-panel" class="ai-result-panel" hidden>
44+
<p id="ai-result-file" class="ai-result-file"></p>
45+
<h2 id="ai-result-title" class="ai-result-title"></h2>
46+
<div id="ai-result-body" class="ai-result-body"></div>
47+
48+
<div class="ai-result-actions">
49+
<button id="ai-reset-button" type="button" class="btn btn-default btn-lg">
50+
Analyze another .ork
51+
</button>
52+
</div>
53+
</section>
54+
</section>
55+
</div>
56+
57+
<script>
58+
window.aiAnalyzerLoadingMessages = {{ site.data.ai_analyzer_loading_lines | jsonify }};
59+
window.aiAnalyzerResults = {{ site.data.ai_analyzer_results | jsonify }};
60+
</script>
61+
<script type="text/javascript" src="/assets/js/ai-analyzer.js" defer></script>

assets/css/ai-analyzer.css

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
body#ai-analyzer {
2+
--ai-bg: #f7f2e8;
3+
--ai-surface: rgba(255, 252, 247, 0.96);
4+
--ai-border: #e8d7bc;
5+
--ai-text: #24303a;
6+
--ai-muted: #5d6d78;
7+
--ai-accent: #c96c1f;
8+
--ai-accent-strong: #0b5f8b;
9+
background:
10+
radial-gradient(circle at top right, rgba(11, 95, 139, 0.12), transparent 30%),
11+
radial-gradient(circle at top left, rgba(201, 108, 31, 0.1), transparent 24%),
12+
linear-gradient(180deg, #fbf8f1 0%, var(--ai-bg) 100%);
13+
color: var(--ai-text);
14+
}
15+
16+
html.dark-mode body#ai-analyzer {
17+
--ai-bg: #0f172a;
18+
--ai-surface: rgba(15, 23, 42, 0.92);
19+
--ai-border: #29415f;
20+
--ai-text: #edf2f7;
21+
--ai-muted: #a8b6c6;
22+
--ai-accent: #f2a65a;
23+
--ai-accent-strong: #6ec6ff;
24+
background:
25+
radial-gradient(circle at top right, rgba(110, 198, 255, 0.12), transparent 32%),
26+
radial-gradient(circle at top left, rgba(242, 166, 90, 0.1), transparent 24%),
27+
linear-gradient(180deg, #09111f 0%, var(--ai-bg) 100%);
28+
}
29+
30+
body#ai-analyzer .content {
31+
padding-top: 32px;
32+
padding-bottom: 52px;
33+
}
34+
35+
body#ai-analyzer .ai-analyzer-shell {
36+
max-width: 760px;
37+
margin: 0 auto;
38+
}
39+
40+
body#ai-analyzer .ai-main-card {
41+
padding: 40px 36px;
42+
border: 1px solid var(--ai-border);
43+
border-radius: 28px;
44+
background: var(--ai-surface);
45+
box-shadow: 0 22px 52px rgba(31, 47, 70, 0.12);
46+
text-align: center;
47+
}
48+
49+
html.dark-mode body#ai-analyzer .ai-main-card {
50+
box-shadow: 0 24px 56px rgba(0, 0, 0, 0.32);
51+
}
52+
53+
body#ai-analyzer h1 {
54+
margin: 0 0 12px;
55+
font-size: 44px;
56+
line-height: 1.08;
57+
}
58+
59+
body#ai-analyzer .ai-subtitle {
60+
max-width: 520px;
61+
margin: 0 auto 28px;
62+
color: var(--ai-muted);
63+
font-size: 18px;
64+
line-height: 1.6;
65+
}
66+
67+
body#ai-analyzer .ai-file-input {
68+
position: absolute;
69+
left: -9999px;
70+
}
71+
72+
body#ai-analyzer .ai-upload-zone {
73+
display: flex;
74+
flex-direction: column;
75+
align-items: center;
76+
justify-content: center;
77+
gap: 10px;
78+
min-height: 220px;
79+
padding: 28px;
80+
margin: 0;
81+
border: 2px dashed var(--ai-border);
82+
border-radius: 24px;
83+
background:
84+
linear-gradient(135deg, rgba(11, 95, 139, 0.05), rgba(201, 108, 31, 0.08)),
85+
rgba(255, 255, 255, 0.55);
86+
cursor: pointer;
87+
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
88+
}
89+
90+
html.dark-mode body#ai-analyzer .ai-upload-zone {
91+
background:
92+
linear-gradient(135deg, rgba(110, 198, 255, 0.08), rgba(242, 166, 90, 0.08)),
93+
rgba(19, 32, 51, 0.65);
94+
}
95+
96+
body#ai-analyzer .ai-upload-zone:hover,
97+
body#ai-analyzer .ai-upload-zone:focus-within {
98+
transform: translateY(-2px);
99+
border-color: var(--ai-accent-strong);
100+
box-shadow: 0 16px 32px rgba(11, 95, 139, 0.14);
101+
}
102+
103+
body#ai-analyzer .ai-upload-zone.is-dragging {
104+
transform: translateY(-2px) scale(1.01);
105+
border-color: var(--ai-accent-strong);
106+
background:
107+
linear-gradient(135deg, rgba(11, 95, 139, 0.12), rgba(201, 108, 31, 0.12)),
108+
rgba(255, 255, 255, 0.74);
109+
box-shadow: 0 20px 38px rgba(11, 95, 139, 0.18);
110+
}
111+
112+
html.dark-mode body#ai-analyzer .ai-upload-zone.is-dragging {
113+
background:
114+
linear-gradient(135deg, rgba(110, 198, 255, 0.12), rgba(242, 166, 90, 0.12)),
115+
rgba(19, 32, 51, 0.82);
116+
}
117+
118+
body#ai-analyzer .ai-upload-zone i {
119+
display: grid;
120+
place-items: center;
121+
width: 74px;
122+
height: 74px;
123+
font-size: 34px;
124+
color: var(--ai-accent-strong);
125+
border-radius: 50%;
126+
background: rgba(11, 95, 139, 0.08);
127+
}
128+
129+
body#ai-analyzer .ai-upload-zone strong {
130+
font-size: 28px;
131+
line-height: 1.2;
132+
max-width: 420px;
133+
}
134+
135+
body#ai-analyzer .ai-upload-zone span {
136+
color: var(--ai-muted);
137+
font-size: 16px;
138+
text-transform: uppercase;
139+
letter-spacing: 0.08em;
140+
}
141+
142+
body#ai-analyzer .ai-selected-file {
143+
min-height: 24px;
144+
margin: 18px 0 0;
145+
color: var(--ai-muted);
146+
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
147+
font-size: 14px;
148+
line-height: 1.5;
149+
}
150+
151+
body#ai-analyzer .ai-analyze-actions {
152+
margin-top: 18px;
153+
}
154+
155+
body#ai-analyzer .ai-analyze-button {
156+
min-width: 180px;
157+
padding-left: 28px;
158+
padding-right: 28px;
159+
}
160+
161+
body#ai-analyzer .ai-analysis-panel {
162+
margin-top: 24px;
163+
}
164+
165+
body#ai-analyzer .ai-progress-track {
166+
width: 100%;
167+
height: 18px;
168+
border-radius: 999px;
169+
background: rgba(93, 109, 120, 0.18);
170+
overflow: hidden;
171+
}
172+
173+
body#ai-analyzer .ai-progress-bar {
174+
width: 0;
175+
height: 100%;
176+
border-radius: inherit;
177+
background: linear-gradient(90deg, var(--ai-accent), var(--ai-accent-strong));
178+
transition: width 0.45s ease;
179+
}
180+
181+
body#ai-analyzer .ai-loading-text {
182+
min-height: 3em;
183+
margin: 16px 0 0;
184+
color: var(--ai-text);
185+
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
186+
font-size: 18px;
187+
line-height: 1.5;
188+
transition: opacity 0.25s ease, transform 0.25s ease;
189+
}
190+
191+
body#ai-analyzer .ai-loading-text.is-swapping {
192+
opacity: 0.25;
193+
transform: translateY(4px);
194+
}
195+
196+
body#ai-analyzer .ai-result-panel {
197+
margin-top: 28px;
198+
padding-top: 28px;
199+
border-top: 1px solid var(--ai-border);
200+
}
201+
202+
body#ai-analyzer .ai-result-file {
203+
margin: 0 0 10px;
204+
color: var(--ai-muted);
205+
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
206+
font-size: 14px;
207+
}
208+
209+
body#ai-analyzer .ai-result-title {
210+
margin: 0 0 16px;
211+
font-size: 34px;
212+
line-height: 1.15;
213+
}
214+
215+
body#ai-analyzer .ai-result-body p {
216+
margin: 0 0 10px;
217+
font-size: 22px;
218+
line-height: 1.45;
219+
}
220+
221+
body#ai-analyzer .ai-result-body p:last-child {
222+
margin-bottom: 0;
223+
}
224+
225+
body#ai-analyzer .ai-result-actions {
226+
margin-top: 22px;
227+
}
228+
229+
@media (max-width: 767px) {
230+
body#ai-analyzer .content {
231+
padding-top: 16px;
232+
}
233+
234+
body#ai-analyzer .ai-main-card {
235+
padding: 28px 20px;
236+
border-radius: 22px;
237+
}
238+
239+
body#ai-analyzer h1 {
240+
font-size: 34px;
241+
}
242+
243+
body#ai-analyzer .ai-subtitle {
244+
font-size: 17px;
245+
margin-bottom: 22px;
246+
}
247+
248+
body#ai-analyzer .ai-upload-zone {
249+
min-height: 190px;
250+
padding: 24px 18px;
251+
}
252+
253+
body#ai-analyzer .ai-upload-zone strong {
254+
font-size: 24px;
255+
}
256+
257+
body#ai-analyzer .ai-loading-text {
258+
font-size: 16px;
259+
min-height: 3.6em;
260+
}
261+
262+
body#ai-analyzer .ai-result-title {
263+
font-size: 28px;
264+
}
265+
266+
body#ai-analyzer .ai-result-body p {
267+
font-size: 19px;
268+
}
269+
270+
body#ai-analyzer .ai-result-actions .btn {
271+
width: 100%;
272+
}
273+
}

0 commit comments

Comments
 (0)