Added Week 2

This commit is contained in:
HangerThem 2026-07-02 19:45:41 +02:00
parent db8cef826e
commit ff5746216e
13 changed files with 2114 additions and 2 deletions

View file

@ -0,0 +1,42 @@
import { injectIntoHtml } from "../utils/inject";
export function injectPartials(injections) {
return {
name: "inject-partials",
transformIndexHtml(html) {
return injectIntoHtml(html, injections, {
onMissing: (key, occurrence) => this.warn(`[inject-partials] Marker "${key}" (occurrence: ${occurrence}) not found — skipping.`),
});
},
};
}
export const partials = [
{
key: "<body>",
placement: "after",
type: "html",
path: "src/partials/navigation.html",
optional: true,
},
{
key: "</head>",
placement: "before",
type: "string",
value: "<link rel='stylesheet' href='/src/style.css' />",
optional: true,
},
{
key: "<!--BLINK-->",
placement: "replace",
type: "html",
path: "src/partials/blink.html",
occurrence: "all",
optional: true,
},
{
key: "</head>",
placement: "before",
type: "string",
value: "<link rel='icon' type='image/svg+xml' href='/favicon.svg' />",
optional: true,
},
];

View file

@ -23,10 +23,10 @@
@keyframes scanline {
from {
transform: translateY(-100%);
background-position: 0 0;
}
to {
transform: translateY(100vh);
background-position: 0 -10px;
}
}
@ -62,6 +62,7 @@ body::before {
rgba(0, 0, 0, 0.18) 2px,
rgba(0, 0, 0, 0.18) 4px
);
animation: scanline 1s linear infinite;
}
/* vignette */

View file

@ -0,0 +1,86 @@
import fs from "fs/promises";
import path from "path";
// ─── Helpers ──────────────────────────────────────────────────────────────────
function nthIndexOf(haystack, needle, n) {
let index = -1;
let remaining = n;
let searchFrom = 0;
while (remaining > 0) {
index = haystack.indexOf(needle, searchFrom);
if (index === -1)
return -1;
searchFrom = index + 1;
remaining--;
}
return index;
}
function applyInjection(html, content, markerIndex, markerLength, placement) {
switch (placement) {
case "before":
return html.slice(0, markerIndex) + content + html.slice(markerIndex);
case "after": {
const after = markerIndex + markerLength;
return html.slice(0, after) + content + html.slice(after);
}
case "replace":
return (html.slice(0, markerIndex) +
content +
html.slice(markerIndex + markerLength));
}
}
// ─── Core ─────────────────────────────────────────────────────────────────────
export async function resolveContent(injection) {
if (injection.type === "html") {
try {
return await fs.readFile(path.resolve(injection.path), "utf-8");
}
catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`[inject] Failed to read "${injection.path}": ${message}`);
}
}
return injection.value;
}
export async function injectIntoHtml(html, injections, options = {}) {
const contents = await Promise.all(injections.map(resolveContent));
for (let i = 0; i < injections.length; i++) {
const injection = injections[i];
const content = contents[i];
const occurrence = injection.occurrence ?? 1;
const handleMissing = () => {
if (injection.optional)
return;
if (options.onMissing) {
options.onMissing(injection.key, occurrence);
}
else {
throw new Error(`[inject] Marker "${injection.key}" (occurrence: ${occurrence}) not found.`);
}
};
if (occurrence === "all") {
const indices = [];
let searchFrom = 0;
let idx;
while ((idx = html.indexOf(injection.key, searchFrom)) !== -1) {
indices.push(idx);
searchFrom = idx + 1;
}
if (indices.length === 0) {
handleMissing();
continue;
}
for (let j = indices.length - 1; j >= 0; j--) {
html = applyInjection(html, content, indices[j], injection.key.length, injection.placement);
}
}
else {
const markerIndex = nthIndexOf(html, injection.key, occurrence);
if (markerIndex === -1) {
handleMissing();
continue;
}
html = applyInjection(html, content, markerIndex, injection.key.length, injection.placement);
}
}
return html;
}

View file

@ -0,0 +1,18 @@
# Week 2 — HTML & the DOM
## What is HTML?
HTML (HyperText Markup Language) is the language of the web. It's a way to structure content on a page using tags. For example:
```html
<h1>My First Heading</h1>
<p>This is a paragraph.</p>
```
This tells the browser to display a heading and a paragraph. HTML is not a programming language — it doesn't have logic or variables. It's a markup language that describes the structure of content.
## The DOM — Document Object Model
When the browser loads an HTML page, it parses the HTML and creates a tree-like structure called the **DOM** (Document Object Model). The DOM represents the page as a hierarchy of nodes, where each node corresponds to an element in the HTML. For example, the HTML above would create a DOM with a root node containing an `<h1>` node and a `<p>` node.
The DOM allows JavaScript to interact with the page. You can use JavaScript to read and modify the DOM, which is how you create dynamic web pages. For example, you could use JavaScript to change the text of the heading or add new paragraphs.

View file

@ -0,0 +1,8 @@
# Demo — Login Form
This demo is a simple static HTML page with a login form. It doesn't actually authenticate — it just shows how HTML looks and how to inspect it in the browser. Use this as a starting point to explore HTML structure and the DOM.
## Setup
1. Create a new file `index.html` with the following content:
2. Open `index.html` in your browser

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1205 1489" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-637.795276,-1062.992126)">
<path d="M1438.786,2082.716C1516.014,2100.591 1597.463,2157.495 1629.921,2244.094L1606.299,2267.717L1842.52,2362.205C1842.52,2362.205 1456.693,2551.181 1240.157,2551.181C1023.622,2551.181 637.795,2362.205 637.795,2362.205L874.016,2267.717L850.394,2244.094C882.624,2157.76 964.005,2100.945 1041.599,2082.781L1042.113,2083.267C1042.437,2126.727 1040.809,2167.549 984.763,2199.62C981.725,2201.359 979.764,2204.507 979.541,2208C979.319,2211.493 980.866,2214.864 983.659,2216.974L1233.88,2405.95C1237.595,2408.756 1242.72,2408.756 1246.435,2405.95L1496.656,2216.974C1499.452,2214.862 1500.999,2211.487 1500.773,2207.99C1500.547,2204.494 1498.579,2201.346 1495.535,2199.611C1439.336,2167.588 1439.064,2126.254 1438.321,2083.155L1438.786,2082.716ZM1062.909,2078.752C1062.937,2078.748 1062.965,2078.744 1062.992,2078.74L1062.992,2034.591C1124.438,2084.815 1182.363,2110.049 1240.085,2110.349C1297.843,2110.648 1355.819,2086.015 1417.323,2035.048L1417.323,2078.74C1417.351,2078.744 1417.378,2078.748 1417.406,2078.752C1417.406,2078.816 1417.407,2078.88 1417.408,2078.945C1418.35,2126.917 1418.146,2172.564 1472.018,2209.474L1240.157,2384.584L1008.29,2209.468C1062.288,2172.529 1063.347,2127.246 1062.909,2078.752ZM1046.315,1992.299C1015.307,1960.668 951.364,1881.827 945.338,1764.704C945.686,1696.837 945.154,1626.01 956.684,1577.021C960.369,1561.361 965.238,1548.056 972.036,1538.151C977.823,1529.72 984.994,1523.938 994.251,1522.009C999.082,1521.002 1002.544,1516.744 1002.543,1511.809C1002.531,1452.034 1011.909,1417.895 1029.679,1399.765C1046.485,1382.617 1070.438,1381.311 1098.125,1384.333C1140.127,1388.917 1190.146,1404.086 1240.151,1404.117C1290.117,1404.149 1340.096,1389.023 1382.078,1384.457C1409.755,1381.446 1433.705,1382.754 1450.527,1399.887C1468.311,1417.999 1477.724,1452.102 1477.772,1511.82C1477.775,1514.579 1478.872,1517.225 1480.823,1519.177L1525.262,1563.615L1535.791,1746.434C1535.672,1746.967 1535.552,1747.499 1535.433,1748.031C1535.801,1873.601 1467.453,1958.339 1434.576,1991.819C1434.297,1992.035 1434.026,1992.268 1433.765,1992.516C1365.519,2057.446 1302.999,2089.842 1240.193,2089.516C1177.331,2089.189 1114.758,2056.128 1046.475,1992.445C1046.422,1992.396 1046.369,1992.347 1046.315,1992.299ZM926.59,1652.334C896.118,1496.07 872.145,1363.569 944.882,1334.646L933.071,1275.591C968.889,1183.558 1112.502,1098.08 1122.047,1098.425C1125.139,1095.057 1107.895,1119.302 1110.236,1145.669C1164.578,1110.609 1225.478,1090.63 1311.024,1062.992C1279.007,1091.861 1269.19,1106.153 1263.78,1133.858C1339.529,1095.815 1389.386,1093.302 1488.189,1098.425C1436.472,1115.509 1425.761,1127.379 1405.512,1169.291C1461.627,1147.493 1525.996,1155.678 1594.488,1169.291C1548.403,1176.1 1536.091,1182.467 1523.622,1204.724C1603.741,1228.324 1612.995,1239.101 1671.26,1275.591C1607.254,1313.263 1592.676,1328.483 1570.866,1358.268C1597.696,1408.021 1578.567,1541.111 1552.25,1669.876L1545.833,1558.456C1545.686,1555.905 1544.606,1553.496 1542.799,1551.689L1498.584,1507.475C1497.99,1442.369 1485.151,1405.414 1465.393,1385.291C1444.239,1363.746 1414.63,1359.96 1379.826,1363.745C1338.505,1368.239 1289.341,1383.315 1240.164,1383.284C1190.941,1383.254 1141.73,1368.135 1100.385,1363.623C1065.557,1359.822 1035.941,1363.613 1014.801,1385.182C995.407,1404.969 982.709,1441.018 981.766,1504.062C959.33,1512.865 944.63,1537.298 936.404,1572.248C931.025,1595.104 928.156,1622.599 926.59,1652.334Z" style="fill:rgb(90,191,0);"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>ICC By-law 182.32</title>
</head>
<body>
<h1>ICC By-law 182.32</h1>
<p>
<em
>All personnel must be cleared for deep-space operations before being
assigned to any vessel or station beyond the Sol system.</em
>
</p>
</body>
</html>

View file

@ -0,0 +1,247 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Enlistment</title>
</head>
<body>
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="profile.html">Profile</a></li>
<li><a href="form.html">Form</a></li>
</ul>
</nav>
<div class="container">
<h1>Personnel Enlistment</h1>
<form>
<fieldset>
<legend>Biological Identity</legend>
<div class="field">
<label for="fullname">Full legal name</label>
<input
id="fullname"
type="text"
placeholder="e.g. Ellen L. Ripley"
required
/>
</div>
<div class="field">
<label for="email"
>Comm address <abbr title="Electronic Mail">(email)</abbr></label
>
<input
id="email"
type="email"
placeholder="unit@weyland-yutani.com"
required
/>
</div>
<div class="field">
<label for="dob"
>Date of birth
<abbr title="Earth Standard Calendar">(ESC)</abbr></label
>
<input id="dob" type="date" />
</div>
<div class="field">
<label for="phone">Contact frequency</label>
<input
id="phone"
type="tel"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
placeholder="123-456-7890"
/>
</div>
<div class="field">
<label for="website"
>Personnel dossier
<abbr title="Uniform Resource Locator">(URL)</abbr></label
>
<input id="website" type="url" placeholder="https://" />
</div>
<div class="field">
<label for="gender">Biological classification</label>
<select id="gender">
<option value="">-- Unspecified --</option>
<option>Non-binary</option>
<option>Female</option>
<option>Male</option>
<option>Other</option>
<option>Prefer not to say</option>
<option>Synthetic (non-applicable)</option>
</select>
</div>
<div class="field">
<label for="origin">Colony of origin</label>
<input id="origin" list="colonies" placeholder="Begin typing…" />
<datalist id="colonies">
<option value="Earth (Sol III)"></option>
<option value="LV-426 (Acheron)"></option>
<option value="LV-223"></option>
<option value="Fiorina 161"></option>
<option value="Origae-6"></option>
<option value="Fury 161"></option>
</datalist>
</div>
<div class="field">
<label for="bio">Operative profile</label>
<textarea
id="bio"
rows="3"
maxlength="200"
placeholder="Summarise your operational history…"
></textarea>
</div>
</fieldset>
<fieldset>
<legend>Operational Preferences</legend>
<div class="field">
<label for="volume">Alert volume</label>
<input id="volume" type="range" min="0" max="100" value="50" />
</div>
<div class="field">
<label for="favcolor">Suit beacon color</label>
<input id="favcolor" type="color" value="#7dff40" />
</div>
<div class="field">
<label for="avatar">Biometric photo</label>
<input id="avatar" type="file" accept="image/*" />
</div>
<div class="field">
<span>Preferred dispatch channel</span>
<label>
<input type="radio" name="contact" value="email" checked />
Comm burst
</label>
<label>
<input type="radio" name="contact" value="phone" />
Voice channel
</label>
<label>
<input type="radio" name="contact" value="mail" />
Physical dispatch
</label>
</div>
<div class="field">
<span>Mission specialisations</span>
<label>
<input type="checkbox" name="interests" value="tech" />
Systems engineering
</label>
<label>
<input type="checkbox" name="interests" value="recon" />
Recon &amp; surveillance
</label>
<label>
<input type="checkbox" name="interests" value="medical" />
Medical &amp; biosafety
</label>
<label>
<input type="checkbox" name="interests" value="combat" />
Combat operations
</label>
<label>
<input type="checkbox" name="interests" value="xeno" />
Xenobiology
</label>
</div>
<div class="field">
<label for="seniority">Clearance tier</label>
<output id="seniorityOutput" for="seniority">3</output>
<input
id="seniority"
type="range"
min="0"
max="10"
value="3"
oninput="seniorityOutput.value = seniority.value"
/>
</div>
</fieldset>
<fieldset>
<legend>Access Credentials</legend>
<div class="field">
<label for="username">Operative callsign</label>
<input
id="username"
type="text"
minlength="3"
placeholder="min. 3 characters"
required
/>
</div>
<div class="field">
<label for="password">Auth passphrase</label>
<input
id="password"
type="password"
minlength="6"
placeholder="min. 6 characters"
required
/>
</div>
<div class="field">
<label for="storage">Assigned storage allocation</label>
<meter
id="storage"
value="32"
min="0"
max="100"
low="70"
high="90"
optimum="0"
>
32%
</meter>
</div>
</fieldset>
<div>
<input id="ToS" type="checkbox" />
<label for="ToS">
I acknowledge and accept the
<a href="#">Weyland-Yutani Personnel Directive 937</a>.
</label>
</div>
<details>
<summary>How is my data processed?</summary>
<p>
All personnel data is logged to MU-TH-UR 6000 and retained for the
duration of active service. Records may be accessed by
<abbr title="Weyland-Yutani Corporation">W-Y</abbr> command under
standing Order 937. Crew are advised: all other priorities are
rescinded.
</p>
</details>
<div class="actions">
<button type="submit">Enlist</button>
<button type="reset">Clear</button>
</div>
</form>
</div>
</body>
</html>

View file

@ -0,0 +1,443 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Eternum Sanguinius | MU-TH-UR 6000</title>
</head>
<body>
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="profile.html">Profile</a></li>
<li><a href="form.html">Form</a></li>
</ul>
</nav>
<div class="container">
<header>
<h1>MU-TH-UR 6000</h1>
<address>
Weyland-Yutani Corporation &mdash; Deep Space Relay Node
<code>USCSS-NOSTROMO-180924609</code><br />
<a href="mailto:comms@weyland-yutani.com">comms@weyland-yutani.com</a>
</address>
<p>
Uplink established:
<time datetime="2183-11-22T04:17:00Z">2183-11-22 // 04:17 UTC</time>
</p>
</header>
<hr />
<!-- Incoming transmission: video + audio -->
<section>
<h2>Incoming Transmission</h2>
<figure>
<video width="100%" controls poster="transmission-poster.svg" muted>
<source src="transmission.mp4" type="video/mp4" />
<source src="transmission.webm" type="video/webm" />
<track
kind="captions"
src="transmission.vtt"
srclang="en"
label="English"
/>
<p>
Your terminal does not support video playback.
<a href="transmission.mp4">Download transmission</a>.
</p>
</video>
<figcaption>
Encrypted burst from <code>LV-426 // ACHERON</code> &mdash; origin
timestamp unknown. Signal classified non-natural by MU-TH-UR 6000.
</figcaption>
</figure>
<audio controls>
<source src="signal.ogg" type="audio/ogg" />
<source src="signal.mp3" type="audio/mpeg" />
Raw audio feed unavailable on this terminal.
</audio>
</section>
<hr />
<!-- Sector map with clickable areas -->
<section>
<h2>Sector Chart &mdash; Zeta II Reticuli</h2>
<figure>
<img
src="sector-map.svg"
alt="Zeta II Reticuli sector map showing LV-426 and surrounding bodies"
width="800"
usemap="#sectormap"
/>
<map name="sectormap">
<!-- Derelict vessel on LV-426 surface -->
<area
shape="poly"
coords="480,286,500,246,520,286"
class="background-color: red;"
href="profile.html#log"
alt="Derelict vessel"
title="JUGGERNAUT-01 — DERELICT VESSEL"
/>
<!-- LV-426 Acheron — primary destination -->
<area
shape="circle"
coords="490,310,36"
href="profile.html"
alt="LV-426 Acheron"
title="LV-426 // ACHERON — DESTINATION"
/>
<!-- LV-223 — restricted -->
<area
shape="circle"
coords="240,80,24"
href="#"
alt="LV-223"
title="LV-223 — ACCESS RESTRICTED"
/>
<!-- Zeta II Reticuli A — primary star -->
<area
shape="circle"
coords="200,180,28"
href="#"
alt="Zeta II Reticuli A"
title="ζ² RETICULI A — STELLAR BODY"
/>
<!-- Zeta II Reticuli B — companion star -->
<area
shape="circle"
coords="290,170,20"
href="#"
alt="Zeta II Reticuli B"
title="ζ² RETICULI B — STELLAR BODY"
/>
<!-- Catch-all: uncharted deep space -->
<area
shape="default"
href="#"
alt="Uncharted sector"
title="DEEP SPACE — SECTOR UNCHARTED"
/>
</map>
<figcaption>
Interactive sector chart. Select a body for operational data.
<wbr />Coordinates expressed in
<abbr title="Galactic Standard Reference Frame">GSRF</abbr>.
</figcaption>
</figure>
</section>
<hr />
<!-- Raw MU-TH-UR terminal output -->
<section>
<h2>Terminal Output</h2>
<p>
To query MU-TH-UR directly, press
<kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>M</kbd>. Last command issued:
</p>
<pre><samp>MU-TH-UR 6000 // QUERY INTERFACE v4.1
&gt; <kbd>STATUS ALL</kbd>
LIFE SUPPORT......OK
HYPERSLEEP........OK
REACTOR CORE......WARN — output at 29%
SPECIMEN HOLD.....CLASSIFIED
&gt; <kbd>DECRYPT ORDER-937</kbd>
ACCESS DENIED — SCIENCE OFFICER EYES ONLY</samp></pre>
<p>
Error code returned:
<samp>ERR_<var>MODULE</var>_<var>CLEARANCE</var>_INSUFFICIENT</samp>.
Replace <var>MODULE</var> and <var>CLEARANCE</var> with your assigned
values before resubmitting.
</p>
</section>
<hr />
<!-- Crew manifest table with colgroup -->
<section>
<h2>Crew Manifest</h2>
<table>
<caption>
USCSS Nostromo — Active Personnel
<small
>(authenticated
<time datetime="2183-11-22">2183-11-22</time>)</small
>
</caption>
<colgroup>
<col class="col-callsign" />
<col class="col-role" />
<col class="col-clearance" />
<col class="col-vitals" />
<col class="col-status" />
</colgroup>
<thead>
<tr>
<th scope="col">Callsign</th>
<th scope="col">Role</th>
<th scope="col">Clearance</th>
<th scope="col">Vitals</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Ripley</strong></td>
<td>Warrant Officer</td>
<td><code>LVL-4</code></td>
<td>
<meter
value="97"
min="0"
max="100"
low="40"
high="70"
optimum="100"
>
97%
</meter>
</td>
<td><span class="badge badge--ok">ACTIVE</span></td>
</tr>
<tr>
<td><strong>Dallas</strong></td>
<td>Captain</td>
<td><code>LVL-5</code></td>
<td>
<meter
value="94"
min="0"
max="100"
low="40"
high="70"
optimum="100"
>
94%
</meter>
</td>
<td><span class="badge badge--ok">ACTIVE</span></td>
</tr>
<tr>
<td>
<ruby>Ash<rt>HDS-0X1</rt></ruby>
</td>
<td>Science Officer</td>
<td><code>LVL-6</code></td>
<td>
<meter
value="100"
min="0"
max="100"
low="40"
high="70"
optimum="100"
>
100%
</meter>
</td>
<td><span class="badge badge--warn">SYNTHETIC</span></td>
</tr>
<tr>
<td><strong>Kane</strong></td>
<td>Executive Officer</td>
<td><code>LVL-4</code></td>
<td>
<meter
value="14"
min="0"
max="100"
low="40"
high="70"
optimum="100"
>
14%
</meter>
</td>
<td><span class="badge badge--crit">CRITICAL</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
Manifest sealed under MU-TH-UR authority &mdash; unauthorised
amendments constitute breach of
<abbr title="Interstellar Commerce Commission">ICC</abbr>
statute <code>12.7-ALPHA</code>.
</td>
</tr>
</tfoot>
</table>
</section>
<hr />
<!-- Debrief progress -->
<section>
<h2>Mission Debrief &mdash; Completion</h2>
<dl>
<dt>Section A &mdash; Incident report</dt>
<dd>
<progress value="100" max="100">100%</progress>
</dd>
<dt>Section B &mdash; Specimen data</dt>
<dd>
<progress value="3" max="10">30%</progress>
</dd>
<dt>Section C &mdash; Crew psychological assessment</dt>
<dd>
<progress max="10">Not started</progress>
</dd>
</dl>
<p>
Complete all sections before
<time datetime="2183-12-01">2183-12-01</time> or your service contract
will be <em>suspended</em>.
</p>
</section>
<hr />
<!-- Embedded ICC regulation iframe -->
<section>
<h2>
<abbr title="Interstellar Commerce Commission">ICC</abbr>
Regulation Reference
</h2>
<p>
Regulation ISCC By-law 182.32 requires all commercial vessels to
investigate signals of potential intelligent origin. Full text
rendered below via secure relay:
</p>
<iframe
src="bylaw-182.html"
title="ICC By-law 182.32 — Duty to Investigate"
width="100%"
height="160"
sandbox="allow-same-origin"
>
Terminal does not support inline document rendering.
<a href="bylaw-182.html">Open document directly</a>.
</iframe>
</section>
<hr />
<!-- Alert dialog trigger -->
<section>
<h2>Emergency Protocols</h2>
<p>
Initiate shipwide alert or open the emergency channel below. All
actions are logged to <code>MU-TH-UR</code>.
</p>
<button
type="button"
onclick="document.getElementById('alertDialog').showModal()"
>
Trigger Alert
</button>
<dialog id="alertDialog">
<h3>Confirm Shipwide Alert</h3>
<p>
This will broadcast a <strong>General Alert</strong> to all crew
stations and log the event under your operative
<abbr title="Identification">ID</abbr>. This action
<em>cannot</em> be undone.
</p>
<menu>
<li>
<button
type="button"
onclick="document.getElementById('alertDialog').close()"
>
Abort
</button>
</li>
<li>
<button type="button">Confirm broadcast</button>
</li>
</menu>
</dialog>
</section>
<hr />
<!-- Canvas: reactor readout -->
<section>
<h2>Reactor Output &mdash; Live Readout</h2>
<canvas id="reactorCanvas" width="400" height="80">
Canvas readout unavailable. Reactor at
<strong>29%</strong> output.
</canvas>
<script>
const canvas = document.getElementById("reactorCanvas")
if (canvas.getContext) {
const ctx = canvas.getContext("2d")
const w = canvas.width
const h = canvas.height
const pct = 0.29
ctx.strokeStyle = "#4a7a00"
ctx.lineWidth = 1
ctx.strokeRect(0, 0, w, h)
const gradient = ctx.createLinearGradient(0, 0, w * pct, 0)
gradient.addColorStop(0, "#ff4040")
gradient.addColorStop(1, "#c4ff00")
ctx.fillStyle = gradient
ctx.fillRect(1, 1, (w - 2) * pct, h - 2)
ctx.fillStyle = "#fff"
ctx.font = '12px "Share Tech Mono", monospace'
ctx.fillText("REACTOR OUTPUT: 29% ██ WARN", 8, h / 2 + 5)
}
</script>
</section>
<hr />
<aside>
<h2>MU-TH-UR Advisory</h2>
<blockquote>
<p>
This terminal is the exclusive property of
<strong>Weyland-Yutani Corporation</strong>. Unauthorised access
violates
<abbr title="Interstellar Commerce Commission">ICC</abbr>
Statute <code>12.7-ALPHA</code>.
<bdi>&#x202E;tcerroc si redrO</bdi>
&mdash; all other priorities rescinded.
</p>
<footer>
&mdash; MU-TH-UR 6000 // AUTO-DISPATCH //
<time datetime="2183-11-22T04:17:00Z">04:17 UTC</time>
</footer>
</blockquote>
</aside>
<hr />
<footer>
<small>
&copy; 2183 Weyland-Yutani Corporation. All rights reserved.
<q>Building Better Worlds</q> is a registered trademark. MU-TH-UR 6000
operates under <abbr title="Hyperdyne Systems">HDS</abbr> licence
<code>MU6K-7741-ESA</code>.
</small>
</footer>
</div>
</body>
</html>

View file

@ -0,0 +1,222 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Eternum Sanguinius | Profile</title>
</head>
<body>
<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="profile.html">Profile</a></li>
<li><a href="form.html">Form</a></li>
</ul>
</nav>
<div class="container">
<h1>Profile</h1>
<div class="profile">
<figure>
<img
src="avatar.svg"
alt="Profile picture of Eternum Sanguinius"
width="128"
/>
<figcaption>Unit ID: ES-7741</figcaption>
</figure>
<div class="profile-info">
<h2>Eternum Sanguinius</h2>
<p>
<abbr title="Electronic Mail">Email</abbr>:
<a href="mailto:eternum@sanguinius.com">eternum@sanguinius.com</a>
</p>
<p>
Status: <strong>Active</strong> &mdash;
<em>Cleared for deep-space operations</em>
</p>
<p>Designation: <code>ES-7741-ALPHA</code></p>
<p>
Last sync:
<time datetime="2183-11-22T04:17:00Z">2183-11-22 // 04:17 UTC</time>
</p>
</div>
</div>
<hr />
<section>
<h2>Clearance &amp; Ratings</h2>
<table>
<thead>
<tr>
<th scope="col">System</th>
<th scope="col">Access Level</th>
<th scope="col">Integrity</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>MU-TH-UR 6000</td>
<td>ADMIN</td>
<td>
<meter
value="91"
min="0"
max="100"
low="40"
high="75"
optimum="100"
>
91%
</meter>
</td>
<td><span class="badge badge--ok">NOMINAL</span></td>
</tr>
<tr>
<td>Atmospheric Processor</td>
<td>WRITE</td>
<td>
<meter
value="58"
min="0"
max="100"
low="40"
high="75"
optimum="100"
>
58%
</meter>
</td>
<td><span class="badge badge--warn">DEGRADED</span></td>
</tr>
<tr>
<td>Hypersleep Chamber</td>
<td>READ</td>
<td>
<meter
value="22"
min="0"
max="100"
low="40"
high="75"
optimum="100"
>
22%
</meter>
</td>
<td><span class="badge badge--crit">CRITICAL</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">Last audit: Stardate 2183.326</td>
</tr>
</tfoot>
</table>
</section>
<hr />
<section>
<h2>Mission Log</h2>
<ol>
<li>
<article>
<header>
<h3>LV-426 Survey — Sector 7G</h3>
<p><time datetime="2183-10-31">2183-10-31</time></p>
</header>
<p>
Anomalous <mark>biosignature detected</mark> at grid reference
<code>7G-NW-04</code>. Sample extraction aborted per
<abbr title="Weyland-Yutani Corporation">W-Y</abbr> directive
Order 937.
</p>
<footer>
<details>
<summary>Classified addendum</summary>
<p>
Secondary objective: retrieve specimen. Crew expendable. All
other priorities rescinded.
</p>
</details>
</footer>
</article>
</li>
<li>
<article>
<header>
<h3>
Derelict Vessel Boarding — Ref. <code>JUGGERNAUT-01</code>
</h3>
<p><time datetime="2183-11-01">2183-11-01</time></p>
</header>
<p>
Hull breach at <code>FR-9</code>. Structural integrity
<del>within acceptable parameters</del>
<ins>below minimum threshold</ins>. Recommend immediate
evacuation.
</p>
</article>
</li>
</ol>
</section>
<hr />
<section>
<h2>Biometric Snapshot</h2>
<dl>
<dt>Heart rate</dt>
<dd>62 <abbr title="beats per minute">bpm</abbr></dd>
<dt>Core temperature</dt>
<dd>36.8 °C</dd>
<dt>O<sub>2</sub> saturation</dt>
<dd>98%</dd>
<dt>Neural load</dt>
<dd>
<meter value="74" min="0" max="100" low="60" high="85" optimum="40">
74%
</meter>
</dd>
<dt>Radiation exposure</dt>
<dd>0.4 <abbr title="millisieverts">mSv</abbr> <sup>[1]</sup></dd>
</dl>
<p>
<small>
<sup>[1]</sup> Cumulative dose since last decontamination cycle.
Acceptable limit: 20 mSv/year per
<abbr title="International Commission on Radiological Protection"
>ICRP</abbr
>.
</small>
</p>
</section>
<hr />
<aside>
<h2>System Notice</h2>
<blockquote>
<p>
You have
<strong>3 unacknowledged alerts</strong>
requiring immediate attention. Report to nearest
<abbr title="Medical Officer">M.O.</abbr> station.
</p>
<footer>&mdash; MU-TH-UR 6000 // AUTO-DISPATCH</footer>
</blockquote>
</aside>
</div>
</body>
</html>

View file

@ -0,0 +1,151 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 250" width="400" height="250"
style="background:#0a0a00; font-family:'Share Tech Mono','Courier New',monospace;">
<defs>
<!-- Star field noise pattern -->
<filter id="glow">
<feGaussianBlur stdDeviation="2.5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-strong">
<feGaussianBlur stdDeviation="4" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-red">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<radialGradient id="starA" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#ffe8a0"/>
<stop offset="60%" stop-color="#c4a000" stop-opacity="0.6"/>
<stop offset="100%" stop-color="#c4a000" stop-opacity="0"/>
</radialGradient>
<radialGradient id="starB" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#ffd080"/>
<stop offset="60%" stop-color="#a07800" stop-opacity="0.6"/>
<stop offset="100%" stop-color="#a07800" stop-opacity="0"/>
</radialGradient>
<radialGradient id="lv426glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#5abf00" stop-opacity="0.4"/>
<stop offset="100%" stop-color="#5abf00" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- Grid lines -->
<g stroke="#1a2a00" stroke-width="0.5" opacity="0.6">
<line x1="0" y1="50" x2="400" y2="50"/>
<line x1="0" y1="100" x2="400" y2="100"/>
<line x1="0" y1="150" x2="400" y2="150"/>
<line x1="0" y1="200" x2="400" y2="200"/>
<line x1="80" y1="0" x2="80" y2="250"/>
<line x1="160" y1="0" x2="160" y2="250"/>
<line x1="240" y1="0" x2="240" y2="250"/>
<line x1="320" y1="0" x2="320" y2="250"/>
</g>
<!-- Outer border -->
<rect x="1" y="1" width="398" height="248" fill="none" stroke="#4a7a00" stroke-width="1"/>
<!-- Corner markers -->
<g stroke="#4a7a00" stroke-width="1" fill="none">
<polyline points="1,16 1,1 16,1"/>
<polyline points="384,1 399,1 399,16"/>
<polyline points="1,234 1,249 16,249"/>
<polyline points="384,249 399,249 399,234"/>
</g>
<!-- Background stars (decorative) -->
<g fill="#2a4a00" opacity="0.8">
<circle cx="30" cy="20" r="0.8"/>
<circle cx="75" cy="60" r="0.6"/>
<circle cx="130" cy="35" r="0.9"/>
<circle cx="180" cy="80" r="0.6"/>
<circle cx="220" cy="25" r="0.7"/>
<circle cx="290" cy="55" r="0.8"/>
<circle cx="350" cy="30" r="0.6"/>
<circle cx="370" cy="90" r="0.9"/>
<circle cx="50" cy="120" r="0.7"/>
<circle cx="110" cy="155" r="0.6"/>
<circle cx="170" cy="195" r="0.8"/>
<circle cx="310" cy="170" r="0.7"/>
<circle cx="360" cy="210" r="0.6"/>
<circle cx="40" cy="200" r="0.9"/>
<circle cx="95" cy="230" r="0.6"/>
<circle cx="260" cy="220" r="0.7"/>
<circle cx="145" cy="110" r="0.5"/>
<circle cx="330" cy="125" r="0.6"/>
<circle cx="200" cy="140" r="0.5"/>
<circle cx="60" cy="165" r="0.7"/>
</g>
<!-- Orbit ring around binary pair -->
<ellipse cx="120" cy="90" rx="55" ry="18" fill="none" stroke="#2a4a00" stroke-width="0.5" stroke-dasharray="3,3"/>
<!-- Zeta II Reticuli A — primary star (coords: cx=100, cy=90, r=14 for map area) -->
<circle cx="100" cy="90" r="28" fill="url(#starA)" opacity="0.5"/>
<circle cx="100" cy="90" r="10" fill="#ffe8a0" filter="url(#glow-strong)"/>
<circle cx="100" cy="90" r="6" fill="#fff5cc"/>
<text x="100" y="115" text-anchor="middle" fill="#a07800" font-size="7" letter-spacing="0.05em">ζ² RET-A</text>
<!-- Zeta II Reticuli B — companion star (coords: cx=145, cy=85, r=10 for map area) -->
<circle cx="145" cy="85" r="20" fill="url(#starB)" opacity="0.4"/>
<circle cx="145" cy="85" r="7" fill="#ffd080" filter="url(#glow)"/>
<circle cx="145" cy="85" r="4" fill="#ffe8b0"/>
<text x="145" y="107" text-anchor="middle" fill="#806000" font-size="7" letter-spacing="0.05em">ζ² RET-B</text>
<!-- LV-223 — restricted (coords: cx=120, cy=40, r=12 for map area) -->
<circle cx="120" cy="40" r="18" fill="#1a0000" opacity="0.5"/>
<circle cx="120" cy="40" r="8" fill="#3a0000" filter="url(#glow-red)"/>
<circle cx="120" cy="40" r="5" fill="#5a1000"/>
<!-- Restriction crosshatch -->
<g stroke="#7a2000" stroke-width="0.8" opacity="0.8">
<line x1="113" y1="33" x2="127" y2="47"/>
<line x1="127" y1="33" x2="113" y2="47"/>
</g>
<circle cx="120" cy="40" r="8" fill="none" stroke="#7a2000" stroke-width="0.8" stroke-dasharray="2,2"/>
<text x="120" y="58" text-anchor="middle" fill="#7a2000" font-size="7" letter-spacing="0.05em">LV-223</text>
<text x="120" y="67" text-anchor="middle" fill="#5a1000" font-size="6">[RESTRICTED]</text>
<!-- LV-426 Acheron — primary destination (coords: cx=245, cy=155, r=18 for map area) -->
<circle cx="245" cy="155" r="36" fill="url(#lv426glow)"/>
<!-- Orbit ring -->
<circle cx="245" cy="155" r="26" fill="none" stroke="#2a4a00" stroke-width="0.5" stroke-dasharray="2,2"/>
<circle cx="245" cy="155" r="14" fill="#0a1a00" stroke="#4a7a00" stroke-width="0.8"/>
<circle cx="245" cy="155" r="10" fill="#1a2a00"/>
<!-- Surface texture suggestion -->
<circle cx="241" cy="151" r="3" fill="#2a4a00" opacity="0.6"/>
<circle cx="250" cy="158" r="2" fill="#2a4a00" opacity="0.4"/>
<circle cx="238" cy="160" r="2.5" fill="#1e3800" opacity="0.5"/>
<!-- Pulsing ring indicator -->
<circle cx="245" cy="155" r="18" fill="none" stroke="#5abf00" stroke-width="0.8" stroke-dasharray="4,2" opacity="0.7"/>
<text x="245" y="182" text-anchor="middle" fill="#a8ff40" font-size="8" letter-spacing="0.08em" filter="url(#glow)">LV-426</text>
<text x="245" y="192" text-anchor="middle" fill="#5abf00" font-size="6.5" letter-spacing="0.05em">ACHERON</text>
<!-- Target crosshair -->
<g stroke="#5abf00" stroke-width="0.6" opacity="0.6">
<line x1="235" y1="155" x2="229" y2="155"/>
<line x1="255" y1="155" x2="261" y2="155"/>
<line x1="245" y1="145" x2="245" y2="139"/>
<line x1="245" y1="165" x2="245" y2="171"/>
</g>
<!-- Derelict vessel marker on LV-426 surface -->
<g transform="translate(258,143)">
<polygon points="0,-5 4,3 -4,3" fill="none" stroke="#c4ff00" stroke-width="0.8" opacity="0.8"/>
<text x="6" y="4" fill="#c4ff00" font-size="5.5" opacity="0.8">DERELICT</text>
</g>
<!-- Default zone label -->
<text x="340" y="200" text-anchor="middle" fill="#2a4a00" font-size="6.5" letter-spacing="0.05em">DEEP SPACE</text>
<text x="340" y="210" text-anchor="middle" fill="#1a3000" font-size="6">[UNCHARTED]</text>
<!-- Scan line sweep (decorative) -->
<line x1="2" y1="0" x2="2" y2="250" stroke="#5abf00" stroke-width="0.4" opacity="0.15"/>
<!-- Title bar -->
<text x="8" y="13" fill="#4a7a00" font-size="7" letter-spacing="0.1em">WEYLAND-YUTANI // NAVCOM // ZETA II RETICULI</text>
<!-- Coord readout bottom -->
<text x="8" y="243" fill="#2a4a00" font-size="6.5" letter-spacing="0.08em">REF: GSRF-ZR2 // SCALE 1:4.2×10¹² km</text>
<text x="392" y="243" text-anchor="end" fill="#2a4a00" font-size="6.5">SYS:NOMINAL</text>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

View file

@ -0,0 +1,758 @@
:root {
--font-mono: "Share Tech Mono", "Courier New", monospace;
--color-primary: #5abf00;
--color-bright: #a8ff40;
--color-brighter: #d4ff80;
--color-brightest: #c4ff00;
--color-red: #ff4040;
--color-dark: #0a0a00;
--color-border: #4a7a00;
--color-border-dark: #2a4a00;
--color-border-bright: #7dff40;
--color-border-medium: #8abf00;
--shadow-text: 0 0 5px rgba(90, 191, 0, 0.3);
--shadow-text-bright: 0 0 6px rgba(140, 255, 60, 0.4);
--shadow-text-h1:
0 0 10px rgba(140, 255, 60, 0.55), 0 0 22px rgba(140, 255, 60, 0.2);
--shadow-glow-light: 0 0 6px rgba(140, 255, 60, 0.6);
--shadow-glow-optimum: 0 0 6px rgba(140, 255, 60, 0.5);
--shadow-glow-suboptimum: 0 0 6px rgba(196, 255, 0, 0.5);
--shadow-glow-bad: 0 0 6px rgba(255, 64, 64, 0.5);
--shadow-input-text: 0 0 4px rgba(120, 255, 60, 0.3);
--shadow-button-inset-rest:
inset 0 0 8px rgba(100, 200, 0, 0.05), 0 0 6px rgba(100, 200, 0, 0.1);
--shadow-button-inset-hover:
inset 0 0 12px rgba(100, 200, 0, 0.1), 0 0 10px rgba(100, 200, 0, 0.2);
--color-placeholder: #315b00;
--color-bg-button-hover: rgba(100, 200, 0, 0.08);
}
* {
font-family: var(--font-mono);
color: var(--color-primary);
text-shadow: var(--shadow-text);
margin: 0;
padding: 0;
box-sizing: border-box;
line-height: 1.85;
}
/* scanlines */
body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
background: repeating-linear-gradient(
0deg,
transparent 0px,
transparent 2px,
rgba(0, 0, 0, 0.18) 2px,
rgba(0, 0, 0, 0.18) 4px
);
animation: scanline 2s linear infinite;
}
/* vignette */
body::after {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9998;
background: radial-gradient(
ellipse at center,
transparent 55%,
rgba(0, 0, 0, 0.65) 100%
);
}
nav {
border-bottom: 1px solid #2a4a00;
padding: 0.5rem;
margin-bottom: 1rem;
width: 100%;
display: flex;
justify-content: center;
position: fixed;
top: 0;
left: 0;
background-color: var(--color-dark);
z-index: 1000;
}
nav ul {
list-style: none;
display: flex;
gap: 1.5rem;
}
nav a {
text-transform: uppercase;
font-size: 0.8rem;
border-bottom: none;
}
nav a:hover {
color: var(--color-brighter);
text-shadow: var(--shadow-text-bright);
text-decoration: underline;
}
h1 {
font: 2rem;
color: var(--color-bright);
text-shadow: var(--shadow-text-h1);
animation: flicker 8s infinite;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: var(--color-dark);
padding: 2rem 0;
margin-top: 3rem;
}
form {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
fieldset {
padding: 0.5rem;
padding-top: 0;
display: flex;
flex-direction: column;
gap: 0.5rem;
border: 1px solid var(--color-border);
}
legend {
font: 0.6rem;
text-transform: uppercase;
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
}
a {
border-bottom: 1px solid var(--color-border);
text-decoration: none;
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
}
a:hover {
border-color: var(--color-border-medium);
color: var(--color-brighter);
}
button {
background-color: transparent;
border: 1px solid var(--color-border);
padding: 1.25rem 0.5rem;
font: 0.6rem;
text-transform: uppercase;
cursor: pointer;
font-family: var(--font-mono);
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
box-shadow: var(--shadow-button-inset-rest);
}
button::before {
content: "▶\00a0";
font: 0.7rem;
color: var(--color-border);
}
button:hover {
box-shadow: var(--shadow-button-inset-hover);
background: var(--color-bg-button-hover);
border-color: var(--color-border-bright);
}
button[type="reset"]::before {
content: "↺\00a0";
}
.actions {
display: flex;
gap: 0.5rem;
}
.actions button {
flex: 1;
}
input,
textarea {
background-color: transparent;
border: none;
border-bottom: 1px solid var(--color-border-dark);
padding: 0.24rem 0;
font: 0.6rem;
outline: none;
font-family: var(--font-mono);
color: var(--color-border-bright);
caret-color: var(--color-bright);
text-shadow: var(--shadow-input-text);
width: 100%;
}
input:focus,
textarea:focus,
select:focus {
border-color: var(--color-border-bright);
}
input::placeholder,
textarea::placeholder {
color: var(--color-placeholder);
}
textarea {
border: 1px solid var(--color-border-dark);
padding: 0.5rem;
resize: vertical;
}
select {
border: 1px solid var(--color-border);
padding: 0.25rem;
background-color: transparent;
}
select option {
background-color: var(--color-dark);
}
/* checkboxes & radios */
input[type="checkbox"],
input[type="radio"] {
background-color: transparent;
border: 1px solid var(--color-border-bright);
accent-color: var(--color-bright);
width: auto;
cursor: pointer;
}
.field label:has(input[type="radio"]),
.field label:has(input[type="checkbox"]) {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.8rem;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
/* range slider */
input[type="range"] {
-webkit-appearance: none;
appearance: none;
height: 2px;
background: var(--color-border-dark);
border: none;
padding: 0;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 10px;
height: 10px;
background: var(--color-bright);
box-shadow: var(--shadow-glow-light);
cursor: pointer;
border-radius: 0;
}
input[type="range"]::-moz-range-thumb {
width: 10px;
height: 10px;
background: var(--color-bright);
box-shadow: var(--shadow-glow-light);
cursor: pointer;
border: none;
border-radius: 0;
}
/* color swatch */
input[type="color"] {
border: 1px solid var(--color-border);
padding: 0.15rem;
height: 1.6rem;
width: 3rem;
cursor: pointer;
}
/* file input */
input[type="file"] {
border: 1px dashed var(--color-border);
padding: 0.4rem;
font-size: 0.7rem;
}
input[type="file"]::file-selector-button {
background-color: transparent;
border: 1px solid var(--color-border);
color: var(--color-bright);
font-family: var(--font-mono);
text-transform: uppercase;
font-size: 0.7rem;
padding: 0.3rem 0.5rem;
margin-right: 0.5rem;
cursor: pointer;
}
input[type="file"]::file-selector-button:hover {
background: var(--color-bg-button-hover);
border-color: var(--color-border-bright);
}
/* datalist-backed input keeps default text styling, no change needed */
meter {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 0.6rem;
border: 1px solid var(--color-border);
background: transparent;
}
meter::-webkit-meter-bar {
background: transparent;
border: none;
}
meter::-webkit-meter-optimum-value {
background: var(--color-bright);
box-shadow: var(--shadow-glow-optimum);
}
meter::-webkit-meter-suboptimum-value {
background: var(--color-brightest);
box-shadow: var(--shadow-glow-suboptimum);
}
meter::-webkit-meter-even-less-good-value {
background: var(--color-red);
box-shadow: var(--shadow-glow-bad);
}
/* Firefox: color applied via pseudo-class on the meter itself */
meter:-moz-meter-optimum::-moz-meter-bar {
background: var(--color-bright);
box-shadow: var(--shadow-glow-optimum);
}
meter:-moz-meter-sub-optimum::-moz-meter-bar {
background: var(--color-brightest);
box-shadow: var(--shadow-glow-suboptimum);
}
meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
background: var(--color-red);
box-shadow: var(--shadow-glow-bad);
}
/* output element */
output {
font-size: 0.6rem;
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
}
/* details/summary */
details {
border: 1px solid var(--color-border-dark);
padding: 0.4rem 0.5rem;
font-size: 0.6rem;
}
summary {
cursor: pointer;
color: var(--color-bright);
text-transform: uppercase;
text-shadow: var(--shadow-text-bright);
}
summary:hover {
color: var(--color-brighter);
}
details p {
margin-top: 0.5rem;
font-size: 0.6rem;
line-height: 1.6;
}
.container {
min-width: 400px;
}
.field {
display: flex;
flex-direction: column;
gap: 0.15rem;
}
/* ── Profile header ─────────────────────────────────────── */
.profile {
display: flex;
align-items: flex-start;
gap: 1.5rem;
margin-bottom: 1rem;
}
figure {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
flex-shrink: 0;
}
figcaption {
font-size: 0.55rem;
text-transform: uppercase;
color: var(--color-border);
text-shadow: none;
}
img {
border: 1px solid var(--color-border);
padding: 0.25rem;
box-shadow:
0 0 8px rgba(90, 191, 0, 0.2),
0 0 20px rgba(90, 191, 0, 0.07);
display: block;
}
.profile-info {
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.profile-info h2 {
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
font-size: 1.1rem;
margin-bottom: 0.25rem;
}
/* ── Shared section headings ────────────────────────────── */
section > h2,
aside > h2 {
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
text-transform: uppercase;
font-size: 0.9rem;
margin-bottom: 0.5rem;
letter-spacing: 0.1em;
}
/* ── HR divider ─────────────────────────────────────────── */
hr {
border: none;
border-top: 1px solid var(--color-border-dark);
margin: 1rem 0;
}
/* ── Table ──────────────────────────────────────────────── */
table {
width: 100%;
border-collapse: collapse;
font-size: 0.7rem;
}
th,
td {
border: 1px solid var(--color-border-dark);
padding: 0.3rem 0.5rem;
text-align: left;
}
thead th {
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
text-transform: uppercase;
letter-spacing: 0.08em;
border-color: var(--color-border);
}
tfoot td {
color: var(--color-border);
text-shadow: none;
font-size: 0.7rem;
border-color: var(--color-border-dark);
}
tbody tr:hover {
background: rgba(90, 191, 0, 0.04);
}
/* ── Badges ─────────────────────────────────────────────── */
.badge {
font-size: 0.6rem;
text-transform: uppercase;
letter-spacing: 0.1em;
padding: 0.1rem 0.35rem;
border: 1px solid;
}
.badge--ok {
color: var(--color-bright);
border-color: var(--color-border);
text-shadow: var(--shadow-glow-optimum);
}
.badge--warn {
color: var(--color-brightest);
border-color: #6a7a00;
text-shadow: var(--shadow-glow-suboptimum);
}
.badge--crit {
color: var(--color-red);
border-color: #7a2000;
text-shadow: var(--shadow-glow-bad);
animation: flicker 3s infinite;
}
/* ── Mission log ────────────────────────────────────────── */
ol {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.75rem;
padding: 0;
}
article {
border: 1px solid var(--color-border-dark);
padding: 0.5rem;
}
article header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--color-border-dark);
margin-bottom: 0.4rem;
padding-bottom: 0.2rem;
}
article header h3 {
font-size: 0.7rem;
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
text-transform: uppercase;
}
article header p {
font-size: 0.6rem;
color: var(--color-border);
text-shadow: none;
}
article > p {
font-size: 0.7rem;
line-height: 1.6;
}
article footer {
margin-top: 0.5rem;
}
mark {
background: rgba(168, 255, 64, 0.15);
color: var(--color-bright);
text-shadow: var(--shadow-glow-optimum);
padding: 0 0.2rem;
}
del {
color: var(--color-border);
text-shadow: none;
text-decoration-color: var(--color-border);
}
ins {
color: var(--color-red);
text-shadow: var(--shadow-glow-bad);
text-decoration: none;
}
ins::before {
content: "→ ";
opacity: 0.6;
}
/* ── Definition list ────────────────────────────────────── */
dl {
display: grid;
grid-template-columns: max-content 1fr;
gap: 0.15rem 1rem;
font-size: 0.7rem;
}
dt {
color: var(--color-border-medium);
text-shadow: none;
text-transform: uppercase;
font-size: 0.7rem;
letter-spacing: 0.05em;
align-self: center;
}
dd {
color: var(--color-primary);
}
dd meter {
margin-top: 0.3rem;
}
/* ── Aside / blockquote ─────────────────────────────────── */
aside {
border: 1px solid var(--color-border);
padding: 0.5rem;
box-shadow:
inset 0 0 12px rgba(90, 191, 0, 0.04),
0 0 8px rgba(90, 191, 0, 0.08);
}
blockquote {
border-left: 2px solid var(--color-border);
padding-left: 0.75rem;
}
blockquote p {
font-size: 0.7rem;
line-height: 1.6;
}
blockquote footer {
margin-top: 0.35rem;
font-size: 0.7rem;
color: var(--color-border);
text-shadow: none;
text-transform: uppercase;
letter-spacing: 0.08em;
}
/* ── Inline semantics ───────────────────────────────────── */
strong {
color: var(--color-bright);
text-shadow: var(--shadow-text-bright);
}
em {
color: var(--color-primary);
font-style: normal;
opacity: 0.75;
}
small {
font-size: 0.7rem;
color: var(--color-border);
text-shadow: none;
display: block;
margin-top: 0.5rem;
line-height: 1.5;
}
abbr {
text-decoration: underline dotted var(--color-border);
cursor: help;
}
code {
color: var(--color-brightest);
text-shadow: var(--shadow-glow-suboptimum);
font-size: 0.7rem;
}
time {
color: var(--color-border-medium);
text-shadow: none;
font-size: 0.7rem;
}
sup,
sub {
font-size: 0.7rem;
color: var(--color-border-medium);
text-shadow: none;
}
/* ── Section spacing ────────────────────────────────────── */
section,
aside {
margin-bottom: 0.25rem;
}
@keyframes flicker {
0%,
95%,
100% {
opacity: 1;
}
96% {
opacity: 0.85;
}
97% {
opacity: 1;
}
98% {
opacity: 0.9;
}
99% {
opacity: 1;
}
}
@keyframes scanline {
from {
background-position: 0 0;
}
to {
background-position: 0 -10px;
}
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}

View file

@ -0,0 +1,111 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 360" width="640" height="360"
style="background:#0a0a00; font-family:'Share Tech Mono','Courier New',monospace;">
<defs>
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-strong">
<feGaussianBlur stdDeviation="6" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<!-- Scanline pattern -->
<pattern id="scanlines" x="0" y="0" width="2" height="4" patternUnits="userSpaceOnUse">
<rect x="0" y="2" width="2" height="2" fill="rgba(0,0,0,0.25)"/>
</pattern>
<radialGradient id="vignette" cx="50%" cy="50%" r="70%">
<stop offset="0%" stop-color="transparent"/>
<stop offset="100%" stop-color="rgba(0,0,0,0.75)"/>
</radialGradient>
</defs>
<!-- Outer border -->
<rect x="1" y="1" width="638" height="358" fill="none" stroke="#4a7a00" stroke-width="1.5"/>
<!-- Corner markers -->
<g stroke="#4a7a00" stroke-width="1.5" fill="none">
<polyline points="1,24 1,1 24,1"/>
<polyline points="616,1 639,1 639,24"/>
<polyline points="1,336 1,359 24,359"/>
<polyline points="616,359 639,359 639,336"/>
</g>
<!-- Static noise bars -->
<g opacity="0.04">
<rect x="2" y="60" width="636" height="3" fill="#5abf00"/>
<rect x="2" y="140" width="636" height="2" fill="#5abf00"/>
<rect x="2" y="220" width="636" height="4" fill="#5abf00"/>
<rect x="2" y="290" width="636" height="2" fill="#5abf00"/>
</g>
<!-- Signal waveform across middle -->
<polyline
points="20,180 40,180 45,160 55,200 65,170 75,190 85,180 100,180 108,155 118,205 128,175 138,185 148,180 165,180 172,148 182,212 192,168 202,192 212,180 230,180 238,158 248,202 258,172 268,188 278,180 295,180 303,152 313,208 323,170 333,190 343,180 360,180 368,162 378,198 388,174 398,186 408,180 425,180 433,156 443,204 453,174 463,186 473,180 490,180 498,154 508,206 518,172 528,190 538,180 555,180 563,160 573,200 583,174 593,186 603,180 620,180"
fill="none" stroke="#5abf00" stroke-width="1.2" opacity="0.5"/>
<!-- Central transmission symbol -->
<!-- Outer rings -->
<circle cx="320" cy="180" r="120" fill="none" stroke="#2a4a00" stroke-width="0.8" stroke-dasharray="4,4" opacity="0.4"/>
<circle cx="320" cy="180" r="90" fill="none" stroke="#2a4a00" stroke-width="0.8" stroke-dasharray="3,3" opacity="0.5"/>
<circle cx="320" cy="180" r="60" fill="none" stroke="#4a7a00" stroke-width="1" stroke-dasharray="5,3" opacity="0.6"/>
<circle cx="320" cy="180" r="30" fill="none" stroke="#4a7a00" stroke-width="1" opacity="0.7"/>
<!-- Crosshair lines -->
<g stroke="#2a4a00" stroke-width="0.8" opacity="0.5">
<line x1="200" y1="180" x2="440" y2="180"/>
<line x1="320" y1="60" x2="320" y2="300"/>
</g>
<!-- Inner glow core -->
<circle cx="320" cy="180" r="18" fill="#0a1a00" stroke="#5abf00" stroke-width="1.5"/>
<circle cx="320" cy="180" r="10" fill="#5abf00" opacity="0.3" filter="url(#glow-strong)"/>
<circle cx="320" cy="180" r="5" fill="#a8ff40" filter="url(#glow)"/>
<!-- Tick marks on outer ring -->
<g stroke="#4a7a00" stroke-width="1" opacity="0.6">
<line x1="320" y1="60" x2="320" y2="72"/>
<line x1="320" y1="288" x2="320" y2="300"/>
<line x1="200" y1="180" x2="212" y2="180"/>
<line x1="428" y1="180" x2="440" y2="180"/>
<line x1="235" y1="95" x2="242" y2="102"/>
<line x1="405" y1="95" x2="398" y2="102"/>
<line x1="235" y1="265" x2="242" y2="258"/>
<line x1="405" y1="265" x2="398" y2="258"/>
</g>
<!-- Top header bar -->
<rect x="2" y="2" width="636" height="22" fill="#0a0a00" opacity="0.8"/>
<text x="16" y="16" fill="#4a7a00" font-size="9" letter-spacing="0.12em">WEYLAND-YUTANI CORP // ENCRYPTED BURST TRANSMISSION // ORIGIN: LV-426</text>
<!-- Status indicators top right -->
<g fill="#2a4a00" font-size="8" letter-spacing="0.08em">
<text x="580" y="16" fill="#7a2000">● REC</text>
</g>
<!-- Bottom bar -->
<rect x="2" y="336" width="636" height="22" fill="#0a0a00" opacity="0.8"/>
<text x="16" y="350" fill="#4a7a00" font-size="9" letter-spacing="0.1em">SIGNAL ORIGIN: NON-NATURAL // STARDATE 2183.326 // DECRYPTION: PENDING</text>
<!-- Left side labels -->
<g fill="#2a4a00" font-size="7.5" letter-spacing="0.08em">
<text x="16" y="90" transform="rotate(-90,16,90)" fill="#2a4a00">FREQ: 3.72 GHz</text>
</g>
<!-- AWAITING DECRYPTION text -->
<text x="320" y="148" text-anchor="middle" fill="#4a7a00" font-size="8" letter-spacing="0.15em">TRANSMISSION RECEIVED</text>
<text x="320" y="230" text-anchor="middle" fill="#5abf00" font-size="11" letter-spacing="0.2em" filter="url(#glow)">AWAITING DECRYPTION</text>
<text x="320" y="248" text-anchor="middle" fill="#2a4a00" font-size="7.5" letter-spacing="0.12em">PRESS PLAY TO INITIATE PLAYBACK</text>
<!-- Play button hint -->
<polygon points="306,258 306,272 318,265" fill="#4a7a00" opacity="0.6"/>
<rect x="320" y="258" width="3" height="14" fill="#4a7a00" opacity="0.6"/>
<rect x="325" y="258" width="3" height="14" fill="#4a7a00" opacity="0.6"/>
<!-- Scanlines overlay -->
<rect x="0" y="0" width="640" height="360" fill="url(#scanlines)"/>
<!-- Vignette -->
<rect x="0" y="0" width="640" height="360" fill="url(#vignette)"/>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB