From ff5746216e89af7077d7aa754098a97a0a25f8fb Mon Sep 17 00:00:00 2001 From: HangerThem Date: Thu, 2 Jul 2026 19:45:41 +0200 Subject: [PATCH] Added Week 2 --- .../demo/src/plugins/injectPartials.js | 42 + .../demo/src/style.css | 5 +- .../demo/src/utils/inject.js | 86 ++ block-01/week-02-html_and_the_dom/README.md | 18 + .../week-02-html_and_the_dom/demo/README.md | 8 + .../week-02-html_and_the_dom/demo/avatar.svg | 7 + .../demo/bylaw-182.html | 18 + .../week-02-html_and_the_dom/demo/form.html | 247 ++++++ .../week-02-html_and_the_dom/demo/index.html | 443 ++++++++++ .../demo/profile.html | 222 +++++ .../demo/sector-map.svg | 151 ++++ .../week-02-html_and_the_dom/demo/style.css | 758 ++++++++++++++++++ .../demo/transmission-poster.svg | 111 +++ 13 files changed, 2114 insertions(+), 2 deletions(-) create mode 100644 block-01/week-01-the_web_under_the_hood/demo/src/plugins/injectPartials.js create mode 100644 block-01/week-01-the_web_under_the_hood/demo/src/utils/inject.js create mode 100644 block-01/week-02-html_and_the_dom/README.md create mode 100644 block-01/week-02-html_and_the_dom/demo/README.md create mode 100644 block-01/week-02-html_and_the_dom/demo/avatar.svg create mode 100644 block-01/week-02-html_and_the_dom/demo/bylaw-182.html create mode 100644 block-01/week-02-html_and_the_dom/demo/form.html create mode 100644 block-01/week-02-html_and_the_dom/demo/index.html create mode 100644 block-01/week-02-html_and_the_dom/demo/profile.html create mode 100644 block-01/week-02-html_and_the_dom/demo/sector-map.svg create mode 100644 block-01/week-02-html_and_the_dom/demo/style.css create mode 100644 block-01/week-02-html_and_the_dom/demo/transmission-poster.svg diff --git a/block-01/week-01-the_web_under_the_hood/demo/src/plugins/injectPartials.js b/block-01/week-01-the_web_under_the_hood/demo/src/plugins/injectPartials.js new file mode 100644 index 0000000..f720077 --- /dev/null +++ b/block-01/week-01-the_web_under_the_hood/demo/src/plugins/injectPartials.js @@ -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: "", + placement: "after", + type: "html", + path: "src/partials/navigation.html", + optional: true, + }, + { + key: "", + placement: "before", + type: "string", + value: "", + optional: true, + }, + { + key: "", + placement: "replace", + type: "html", + path: "src/partials/blink.html", + occurrence: "all", + optional: true, + }, + { + key: "", + placement: "before", + type: "string", + value: "", + optional: true, + }, +]; diff --git a/block-01/week-01-the_web_under_the_hood/demo/src/style.css b/block-01/week-01-the_web_under_the_hood/demo/src/style.css index 2d20f2a..2fcb849 100644 --- a/block-01/week-01-the_web_under_the_hood/demo/src/style.css +++ b/block-01/week-01-the_web_under_the_hood/demo/src/style.css @@ -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 */ diff --git a/block-01/week-01-the_web_under_the_hood/demo/src/utils/inject.js b/block-01/week-01-the_web_under_the_hood/demo/src/utils/inject.js new file mode 100644 index 0000000..da1fc1d --- /dev/null +++ b/block-01/week-01-the_web_under_the_hood/demo/src/utils/inject.js @@ -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; +} diff --git a/block-01/week-02-html_and_the_dom/README.md b/block-01/week-02-html_and_the_dom/README.md new file mode 100644 index 0000000..92dbf32 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/README.md @@ -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 +

My First Heading

+

This is a paragraph.

+``` + +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 `

` node and a `

` 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. diff --git a/block-01/week-02-html_and_the_dom/demo/README.md b/block-01/week-02-html_and_the_dom/demo/README.md new file mode 100644 index 0000000..e0aa2c7 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/README.md @@ -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 \ No newline at end of file diff --git a/block-01/week-02-html_and_the_dom/demo/avatar.svg b/block-01/week-02-html_and_the_dom/demo/avatar.svg new file mode 100644 index 0000000..5ab5153 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/avatar.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/block-01/week-02-html_and_the_dom/demo/bylaw-182.html b/block-01/week-02-html_and_the_dom/demo/bylaw-182.html new file mode 100644 index 0000000..937f464 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/bylaw-182.html @@ -0,0 +1,18 @@ + + + + + + + ICC By-law 182.32 + + +

ICC By-law 182.32

+

+ All personnel must be cleared for deep-space operations before being + assigned to any vessel or station beyond the Sol system. +

+ + diff --git a/block-01/week-02-html_and_the_dom/demo/form.html b/block-01/week-02-html_and_the_dom/demo/form.html new file mode 100644 index 0000000..602ab20 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/form.html @@ -0,0 +1,247 @@ + + + + + + + Enlistment + + + +
+

Personnel Enlistment

+
+
+ Biological Identity + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + + + + + + + + +
+ +
+ + +
+
+ +
+ Operational Preferences + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ Preferred dispatch channel + + + +
+ +
+ Mission specialisations + + + + + +
+ +
+ + 3 + +
+
+ +
+ Access Credentials + +
+ + +
+ +
+ + +
+ +
+ + + 32% + +
+
+ +
+ + +
+ +
+ How is my data processed? +

+ All personnel data is logged to MU-TH-UR 6000 and retained for the + duration of active service. Records may be accessed by + W-Y command under + standing Order 937. Crew are advised: all other priorities are + rescinded. +

+
+ +
+ + +
+
+
+ + diff --git a/block-01/week-02-html_and_the_dom/demo/index.html b/block-01/week-02-html_and_the_dom/demo/index.html new file mode 100644 index 0000000..1e3ef22 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/index.html @@ -0,0 +1,443 @@ + + + + + + + Eternum Sanguinius | MU-TH-UR 6000 + + + + +
+
+

MU-TH-UR 6000

+
+ Weyland-Yutani Corporation — Deep Space Relay Node + USCSS-NOSTROMO-180924609
+ comms@weyland-yutani.com +
+

+ Uplink established: + +

+
+ +
+ + +
+

Incoming Transmission

+
+ +
+ Encrypted burst from LV-426 // ACHERON — origin + timestamp unknown. Signal classified non-natural by MU-TH-UR 6000. +
+
+ + +
+ +
+ + +
+

Sector Chart — Zeta II Reticuli

+
+ Zeta II Reticuli sector map showing LV-426 and surrounding bodies + + + Derelict vessel + + + LV-426 Acheron + + + LV-223 + + + Zeta II Reticuli A + + + Zeta II Reticuli B + + + Uncharted sector + +
+ Interactive sector chart. Select a body for operational data. + Coordinates expressed in + GSRF. +
+
+
+ +
+ + +
+

Terminal Output

+

+ To query MU-TH-UR directly, press + Ctrl + Alt + M. Last command issued: +

+
MU-TH-UR 6000 // QUERY INTERFACE v4.1
+> STATUS ALL
+LIFE SUPPORT......OK
+HYPERSLEEP........OK
+REACTOR CORE......WARN — output at 29%
+SPECIMEN HOLD.....CLASSIFIED
+> DECRYPT ORDER-937
+ACCESS DENIED — SCIENCE OFFICER EYES ONLY
+ +

+ Error code returned: + ERR_MODULE_CLEARANCE_INSUFFICIENT. + Replace MODULE and CLEARANCE with your assigned + values before resubmitting. +

+
+ +
+ + +
+

Crew Manifest

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ USCSS Nostromo — Active Personnel + (authenticated + ) +
CallsignRoleClearanceVitalsStatus
RipleyWarrant OfficerLVL-4 + + 97% + + ACTIVE
DallasCaptainLVL-5 + + 94% + + ACTIVE
+ AshHDS-0X1 + Science OfficerLVL-6 + + 100% + + SYNTHETIC
KaneExecutive OfficerLVL-4 + + 14% + + CRITICAL
+ Manifest sealed under MU-TH-UR authority — unauthorised + amendments constitute breach of + ICC + statute 12.7-ALPHA. +
+
+ +
+ + +
+

Mission Debrief — Completion

+
+
Section A — Incident report
+
+ 100% +
+
Section B — Specimen data
+
+ 30% +
+
Section C — Crew psychological assessment
+
+ Not started +
+
+ +

+ Complete all sections before + or your service contract + will be suspended. +

+
+ +
+ + +
+

+ ICC + Regulation Reference +

+

+ Regulation ISCC By-law 182.32 requires all commercial vessels to + investigate signals of potential intelligent origin. Full text + rendered below via secure relay: +

+ +
+ +
+ + +
+

Emergency Protocols

+

+ Initiate shipwide alert or open the emergency channel below. All + actions are logged to MU-TH-UR. +

+ + + +

Confirm Shipwide Alert

+

+ This will broadcast a General Alert to all crew + stations and log the event under your operative + ID. This action + cannot be undone. +

+ +
  • + +
  • +
  • + +
  • +
    +
    +
    + +
    + + +
    +

    Reactor Output — Live Readout

    + + Canvas readout unavailable. Reactor at + 29% output. + + +
    + +
    + + + +
    + +
    + + © 2183 Weyland-Yutani Corporation. All rights reserved. + Building Better Worlds is a registered trademark. MU-TH-UR 6000 + operates under HDS licence + MU6K-7741-ESA. + +
    +
    + + diff --git a/block-01/week-02-html_and_the_dom/demo/profile.html b/block-01/week-02-html_and_the_dom/demo/profile.html new file mode 100644 index 0000000..965f9a7 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/profile.html @@ -0,0 +1,222 @@ + + + + + + + Eternum Sanguinius | Profile + + + + +
    +

    Profile

    + +
    +
    + Profile picture of Eternum Sanguinius +
    Unit ID: ES-7741
    +
    + +
    +

    Eternum Sanguinius

    +

    + Email: + eternum@sanguinius.com +

    +

    + Status: Active — + Cleared for deep-space operations +

    +

    Designation: ES-7741-ALPHA

    +

    + Last sync: + +

    +
    +
    + +
    + +
    +

    Clearance & Ratings

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SystemAccess LevelIntegrityStatus
    MU-TH-UR 6000ADMIN + + 91% + + NOMINAL
    Atmospheric ProcessorWRITE + + 58% + + DEGRADED
    Hypersleep ChamberREAD + + 22% + + CRITICAL
    Last audit: Stardate 2183.326
    +
    + +
    + +
    +

    Mission Log

    +
      +
    1. +
      +
      +

      LV-426 Survey — Sector 7G

      +

      +
      +

      + Anomalous biosignature detected at grid reference + 7G-NW-04. Sample extraction aborted per + W-Y directive + Order 937. +

      +
      +
      + Classified addendum +

      + Secondary objective: retrieve specimen. Crew expendable. All + other priorities rescinded. +

      +
      +
      +
      +
    2. +
    3. +
      +
      +

      + Derelict Vessel Boarding — Ref. JUGGERNAUT-01 +

      +

      +
      +

      + Hull breach at FR-9. Structural integrity + within acceptable parameters + below minimum threshold. Recommend immediate + evacuation. +

      +
      +
    4. +
    +
    + +
    + +
    +

    Biometric Snapshot

    +
    +
    Heart rate
    +
    62 bpm
    + +
    Core temperature
    +
    36.8 °C
    + +
    O2 saturation
    +
    98%
    + +
    Neural load
    +
    + + 74% + +
    + +
    Radiation exposure
    +
    0.4 mSv [1]
    +
    + +

    + + [1] Cumulative dose since last decontamination cycle. + Acceptable limit: 20 mSv/year per + ICRP. + +

    +
    + +
    + + +
    + + diff --git a/block-01/week-02-html_and_the_dom/demo/sector-map.svg b/block-01/week-02-html_and_the_dom/demo/sector-map.svg new file mode 100644 index 0000000..7220a51 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/sector-map.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ζ² RET-A + + + + + + ζ² RET-B + + + + + + + + + + + + LV-223 + [RESTRICTED] + + + + + + + + + + + + + + LV-426 + ACHERON + + + + + + + + + + + + DERELICT + + + + DEEP SPACE + [UNCHARTED] + + + + + + WEYLAND-YUTANI // NAVCOM // ZETA II RETICULI + + + REF: GSRF-ZR2 // SCALE 1:4.2×10¹² km + SYS:NOMINAL + + \ No newline at end of file diff --git a/block-01/week-02-html_and_the_dom/demo/style.css b/block-01/week-02-html_and_the_dom/demo/style.css new file mode 100644 index 0000000..8632a99 --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/style.css @@ -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; + } +} diff --git a/block-01/week-02-html_and_the_dom/demo/transmission-poster.svg b/block-01/week-02-html_and_the_dom/demo/transmission-poster.svg new file mode 100644 index 0000000..37fbc5b --- /dev/null +++ b/block-01/week-02-html_and_the_dom/demo/transmission-poster.svg @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WEYLAND-YUTANI CORP // ENCRYPTED BURST TRANSMISSION // ORIGIN: LV-426 + + + + ● REC + + + + + SIGNAL ORIGIN: NON-NATURAL // STARDATE 2183.326 // DECRYPTION: PENDING + + + + FREQ: 3.72 GHz + + + + TRANSMISSION RECEIVED + AWAITING DECRYPTION + PRESS PLAY TO INITIATE PLAYBACK + + + + + + + + + + + + + \ No newline at end of file