fuzzyworld

shadow-zone / commit

Hide real-world validation section

7ef360833969df9303e2d1461e69d433e6ea116b · Pavel Safronov · 2026-06-11 20:24:37 -0700 · parents 0ed883872a21

Hide real-world validation section

Validation UI (select + results panel) is hidden via inline
display:none pending a proper data-fetch workflow. The JS wiring
is preserved so it can be re-enabled without code changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
 index.html | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 278 insertions(+)

diff --git a/index.html b/index.html
new file mode 100644
index 0000000..885b4a5
--- /dev/null
+++ b/index.html
@@ -0,0 +1,278 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>Seismic Shadow Zone</title>
+  <style>
+    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+    body {
+      background: #0a0a14;
+      color: #d0d0e0;
+      font-family: system-ui, sans-serif;
+      font-size: 14px;
+      min-height: 100vh;
+      display: flex;
+      flex-direction: column;
+    }
+
+    h1 {
+      padding: 10px 16px;
+      font-size: 18px;
+      font-weight: 600;
+      border-bottom: 1px solid #2a2a40;
+      color: #e8e8ff;
+    }
+
+    #app {
+      flex: 1;
+      display: flex;
+      flex-direction: row;
+    }
+
+    #canvas-wrap {
+      flex: 1;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding: 12px;
+    }
+
+    canvas {
+      display: block;
+      max-width: 100%;
+      max-height: 100%;
+    }
+
+    #sidebar {
+      width: 280px;
+      flex-shrink: 0;
+      padding: 16px;
+      border-left: 1px solid #2a2a40;
+      overflow-y: auto;
+      display: flex;
+      flex-direction: column;
+      gap: 14px;
+    }
+
+    .control-group {
+      display: flex;
+      flex-direction: column;
+      gap: 4px;
+    }
+
+    label {
+      font-size: 12px;
+      color: #a0a0c0;
+      display: flex;
+      justify-content: space-between;
+    }
+
+    label span {
+      color: #e0e0ff;
+      font-variant-numeric: tabular-nums;
+    }
+
+    input[type=range] {
+      width: 100%;
+      accent-color: #6496ff;
+    }
+
+    select {
+      width: 100%;
+      background: #16162a;
+      color: #d0d0e0;
+      border: 1px solid #3a3a58;
+      border-radius: 4px;
+      padding: 4px 6px;
+      font-size: 13px;
+    }
+
+    hr {
+      border: none;
+      border-top: 1px solid #2a2a40;
+    }
+
+    #shadow-zone-info, #validation-info {
+      background: #16162a;
+      border: 1px solid #3a3a58;
+      border-radius: 4px;
+      padding: 8px 10px;
+      font-size: 13px;
+      line-height: 1.6;
+      color: #c0c0e0;
+    }
+
+    #validation-info code {
+      background: #0e0e20;
+      border: 1px solid #3a3a58;
+      border-radius: 3px;
+      padding: 2px 5px;
+      font-family: monospace;
+      font-size: 12px;
+      color: #80c0ff;
+    }
+
+    #shadow-tooltip {
+      position: fixed;
+      display: none;
+      background: #16162a;
+      border: 1px solid #3a3a58;
+      border-radius: 4px;
+      padding: 5px 10px;
+      font-size: 12px;
+      color: #d0d0e0;
+      pointer-events: none;
+      z-index: 100;
+      white-space: nowrap;
+    }
+
+    #description-details > summary {
+      cursor: pointer;
+      list-style: none;
+      font-size: 12px;
+      color: #a0a0c0;
+      user-select: none;
+      display: flex;
+      align-items: center;
+      gap: 6px;
+    }
+
+    #description-details > summary::-webkit-details-marker { display: none; }
+
+    #description-details > summary::before {
+      content: '▶';
+      font-size: 8px;
+      color: #5858a0;
+      display: inline-block;
+      transition: transform 0.15s;
+      flex-shrink: 0;
+    }
+
+    #description-details[open] > summary::before {
+      transform: rotate(90deg);
+    }
+
+    #description {
+      margin-top: 8px;
+      font-size: 12px;
+      color: #7878a0;
+      line-height: 1.65;
+    }
+
+    #description a {
+      color: #6496ff;
+      text-decoration: none;
+    }
+
+    #description a:hover {
+      text-decoration: underline;
+    }
+
+    .preview-badge {
+      background: #1e1e36;
+      border: 1px solid #4a4a68;
+      border-radius: 3px;
+      color: #8888aa;
+      font-size: 10px;
+      padding: 1px 5px;
+      vertical-align: middle;
+      letter-spacing: 0.02em;
+    }
+
+    @media (max-width: 700px) {
+      #app { flex-direction: column; }
+      #sidebar { width: 100%; border-left: none; border-top: 1px solid #2a2a40; }
+    }
+  </style>
+</head>
+<body>
+  <h1>🌍 Seismic Shadow Zone</h1>
+  <div id="app">
+    <div id="canvas-wrap">
+      <canvas id="canvas" width="600" height="600" style="display:block;"></canvas>
+    </div>
+    <div id="sidebar">
+
+      <div class="control-group">
+        <label>Preset</label>
+        <select id="preset">
+          <option value="earth">🌍 Earth (PREM-like)</option>
+          <option value="solid">🪨 Solid Earth</option>
+          <option value="water-core">💧 Water Core</option>
+          <option value="giant-core">🔴 Giant Core</option>
+          <option value="tiny-core">🔵 Tiny Core</option>
+          <option value="fast-core">⚡ Fast Core</option>
+        </select>
+      </div>
+
+      <details id="description-details">
+        <summary>About</summary>
+        <div id="description">
+          <p>When an earthquake occurs, seismic waves travel through Earth's interior. The liquid outer core refracts P-waves away from their straight-line path, leaving a shadow zone — a band where no direct P arrivals are detected. S-waves cannot propagate through liquid at all, so they are blocked entirely beyond ~105°. The exact boundaries shift with core size and composition; try the presets to explore how structure shapes the shadow.</p>
+          <p style="margin-top:6px"><a href="https://en.wikipedia.org/wiki/Shadow_zone" target="_blank" rel="noopener">Wikipedia: Shadow zone ↗</a></p>
+        </div>
+      </details>
+
+      <hr />
+
+      <div class="control-group">
+        <label>Outer core radius (km) <span id="outer-core-radius-val">3480</span></label>
+        <input type="range" id="outer-core-radius" min="100" max="6000" step="10" value="3480" />
+      </div>
+
+      <div class="control-group">
+        <label>Core P-vel top (km/s) <span id="outer-core-v-top-val">8.0</span></label>
+        <input type="range" id="outer-core-v-top" min="1.0" max="15.0" step="0.1" value="8.0" />
+      </div>
+
+      <div class="control-group">
+        <label>Core P-vel bottom (km/s) <span id="outer-core-v-bottom-val">10.4</span></label>
+        <input type="range" id="outer-core-v-bottom" min="1.0" max="15.0" step="0.1" value="10.4" />
+      </div>
+
+      <div class="control-group">
+        <label>Inner core radius (km) <span id="inner-core-radius-val">1220</span></label>
+        <input type="range" id="inner-core-radius" min="0" max="3000" step="10" value="1220" />
+      </div>
+
+      <div class="control-group">
+        <label>Inner core P-vel (km/s) <span id="inner-core-v-val">11.3</span></label>
+        <input type="range" id="inner-core-v" min="1.0" max="15.0" step="0.1" value="11.3" />
+      </div>
+
+      <hr />
+
+      <div class="control-group">
+        <label>Wave type</label>
+        <select id="wave-type">
+          <option value="P">P-waves</option>
+          <option value="S">S-waves</option>
+          <option value="both">Both</option>
+        </select>
+      </div>
+
+      <div class="control-group">
+        <label>Number of rays <span id="num-rays-val">60</span></label>
+        <input type="range" id="num-rays" min="10" max="1000" step="5" value="60" />
+      </div>
+
+      <hr />
+
+      <div id="shadow-zone-info">Shadow zone: computing…</div>
+
+      <hr style="display:none" />
+
+      <div class="control-group" style="display:none">
+        <label>Real-world validation <span class="preview-badge">Preview</span></label>
+        <select id="earthquake-select"></select>
+      </div>
+
+      <div id="validation-info" style="display:none"></div>
+
+    </div>
+  </div>
+  <script type="module" src="/src/main.ts"></script>
+</body>
+</html>