ClaudeThinksFinals

This commit is contained in:
2026-05-26 10:23:50 -04:00
parent 3b8b7796dd
commit e59b024b62
32 changed files with 10815 additions and 11 deletions

View File

@@ -131,10 +131,14 @@ Also shipped: `kind` (one categorical hue per particle type — primary/δ-ray/c
sweeper/V-decay), `kindlife` / `kindrise` (type sets the hue, lifecycle sets the sweeper/V-decay), `kindlife` / `kindrise` (type sets the hue, lifecycle sets the
*intensity* — fading toward, or rising into, the death), `psychedelic` (per-bubble *intensity* — fading toward, or rising into, the death), `psychedelic` (per-bubble
hue cycles, `hueCycles`), `cyanotype` (a full chemistry: overrides `paper()` + ink hue cycles, `hueCycles`), `cyanotype` (a full chemistry: overrides `paper()` + ink
for the blueprint look), and `magentarise` (a restrained example bundling a for the blueprint look), and `magentarise` (a **sweepable two-colour relationship**: a trace family by type +
magenta-family kind-scheme + rising intensity + a monochrome burnt-orange disk via rising intensity + a monochrome contrasting disk via `feature()`). Its pairing is
`feature()`). A palette is one registry entry; hooks: `ink`/`bubbleInk`/`paper`/ parameterised by three dials — **`traceHue`** (offset that rotates the whole trace
`feature`/`vign`. family while keeping the by-type spread), **`diskHue`** and **`diskSat`** (the
disk/feature accent, deliberately *not* touched by global hue-shift/saturation so it
reads as an independent second colour). Defaults (0 / 0.06 / 0.82) reproduce the
original magenta-vs-burnt-orange exactly. A palette is one registry entry; hooks:
`ink`/`bubbleInk`/`paper`/`feature`/`vign`.
**Saturation** is a global `saturation` dial applied in `resolvePalette` (about **Saturation** is a global `saturation` dial applied in `resolvePalette` (about
each colour's own luminance: 0 = grey, 1 = as-authored, >1 boosted), and each colour's own luminance: 0 = grey, 1 = as-authored, >1 boosted), and

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.3 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.9 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.9 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.9 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.9 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.9 MiB

View File

@@ -79,4 +79,43 @@ figcaption{padding:8px 10px;color:#e8e4d8}</style></head><body>
<figure><img src="52_aura.svg"><figcaption>⑧ The aura — chromatic halo around the trails; halation, breath<br><span style=color:#555>52_aura.svg · MESON-5113</span></figcaption></figure> <figure><img src="52_aura.svg"><figcaption>⑧ The aura — chromatic halo around the trails; halation, breath<br><span style=color:#555>52_aura.svg · MESON-5113</span></figcaption></figure>
<figure><img src="53_scanners-mark.svg"><figcaption>⑨ The scanner's mark — full grease-pencil hand: ring, arrow, Nº, angle<br><span style=color:#555>53_scanners-mark.svg · MESON-5113</span></figcaption></figure> <figure><img src="53_scanners-mark.svg"><figcaption>⑨ The scanner's mark — full grease-pencil hand: ring, arrow, Nº, angle<br><span style=color:#555>53_scanners-mark.svg · MESON-5113</span></figcaption></figure>
<figure><img src="54_the-strip.svg"><figcaption>⑩ The strip — film as object: sprockets, edge text, réseau, tape splice<br><span style=color:#555>54_the-strip.svg · MESON-5113</span></figcaption></figure> <figure><img src="54_the-strip.svg"><figcaption>⑩ The strip — film as object: sprockets, edge text, réseau, tape splice<br><span style=color:#555>54_the-strip.svg · MESON-5113</span></figcaption></figure>
</div>
<h1 style="margin-top:34px">Round 9 · same craft, different two-colour relationships</h1>
<p style="color:#777">all MESON-5113 · the ember-on-black craft frame held constant · only the trace-family hue (traceHue) and disk-accent hue (diskHue) change — a sweepable complementary pair</p><div class=grid>
<figure><img src="55_anchor-magenta-orange.svg"><figcaption>Magenta traces · burnt-orange disk — the anchor (= the original relationship)<br><span style=color:#555>55_anchor-magenta-orange.svg · traceHue 0 · diskHue 0.06</span></figcaption></figure>
<figure><img src="56_teal-rose.svg"><figcaption>Teal traces · rose disk — the inverse: cool trails, warm-pink anomaly<br><span style=color:#555>56_teal-rose.svg · traceHue 0.64 · diskHue 0.92</span></figcaption></figure>
<figure><img src="57_gold-deepblue.svg"><figcaption>★ Gold traces · deep-blue disk — fire vs ice, the warm/cool roles swapped<br><span style=color:#555>57_gold-deepblue.svg · traceHue 0.25 · diskHue 0.62</span></figcaption></figure>
<figure><img src="58_emerald-magenta.svg"><figcaption>Emerald traces · magenta disk — full complementary, spectral/radioactive<br><span style=color:#555>58_emerald-magenta.svg · traceHue 0.48 · diskHue 0.90</span></figcaption></figure>
<figure><img src="59_violet-chartreuse.svg"><figcaption>Violet traces · chartreuse disk — ultraviolet, electric, a green sun<br><span style=color:#555>59_violet-chartreuse.svg · traceHue 0.88 · diskHue 0.22</span></figcaption></figure>
<figure><img src="60_cyan-amber.svg"><figcaption>★ Cyan traces · amber disk — blueprint trails with a warm sun; calm, classic<br><span style=color:#555>60_cyan-amber.svg · traceHue 0.69 · diskHue 0.10</span></figcaption></figure>
<figure><img src="61_iceblue-crimson.svg"><figcaption>Ice-blue traces · crimson disk — stark, charged; the disk as a wound<br><span style=color:#555>61_iceblue-crimson.svg · traceHue 0.74 · diskHue 0.995</span></figcaption></figure>
<figure><img src="62_copper-teal.svg"><figcaption>★ Copper traces · teal disk — verdigris, oxidized metal, the most analog<br><span style=color:#555>62_copper-teal.svg · traceHue 0.21 · diskHue 0.48</span></figcaption></figure>
</div>
<h1 style="margin-top:34px">Round 10 · lighter grounds — for a living space</h1>
<p style="color:#777">MESON-5113 · positive (light) plate · the refined bubble/disk feel on neutral/warm/light paper instead of black</p><div class=grid>
<figure><img src="63_light-cream-magenta-orange.svg"><figcaption>Cream · magenta traces / burnt-orange disk — the warm relic<br><span style=color:#555>63_light-cream-magenta-orange.svg</span></figcaption></figure>
<figure><img src="64_light-neutral-copper-teal.svg"><figcaption>★ Neutral · copper traces / teal disk — sophisticated, gallery-calm<br><span style=color:#555>64_light-neutral-copper-teal.svg</span></figcaption></figure>
<figure><img src="65_light-cream-cyan-amber.svg"><figcaption>★ Cream · cyan traces / amber disk — cool trails, warm sun; most livable<br><span style=color:#555>65_light-cream-cyan-amber.svg</span></figcaption></figure>
<figure><img src="66_light-selenium-teal-rose.svg"><figcaption>Selenium · teal traces / rose disk — soft, airy<br><span style=color:#555>66_light-selenium-teal-rose.svg</span></figcaption></figure>
<figure><img src="67_light-warm-teal-amber.svg"><figcaption>Warm cream · teal traces / amber disk — cosy, toned-photo warmth<br><span style=color:#555>67_light-warm-teal-amber.svg</span></figcaption></figure>
</div>
<h1 style="margin-top:34px">Round 11 · plate position & weight</h1>
<p style="color:#777">copper/teal on neutral held constant · only the disk moves & resizes (shockX / shockY / shockSize)</p><div class=grid>
<figure><img src="68_pos-centered.svg"><figcaption>Centered — a symmetric mandala / eye<br><span style=color:#555>68_pos-centered.svg · shockY 0</span></figcaption></figure>
<figure><img src="69_pos-high-rising.svg"><figcaption>High / rising — disk lifts above the bundle (weakest)<br><span style=color:#555>69_pos-high-rising.svg · shockY 0.32</span></figcaption></figure>
<figure><img src="70_pos-deep-arc.svg"><figcaption>★ Deep low arc — the big semicircle anchor<br><span style=color:#555>70_pos-deep-arc.svg · shockY 0.85 · size 0.42</span></figcaption></figure>
<figure><img src="71_pos-thirds-left.svg"><figcaption>Thirds, lower-left — off-centre composition<br><span style=color:#555>71_pos-thirds-left.svg · shockX 0.48</span></figcaption></figure>
<figure><img src="72_pos-small-distant.svg"><figcaption>★ Small & distant — modest disk, lots of negative space<br><span style=color:#555>72_pos-small-distant.svg · size 0.2</span></figcaption></figure>
</div>
<h1 style="margin-top:34px">Round 12 · more / fewer interactions</h1>
<p style="color:#777">copper/teal on neutral · natural disk · only the event counts change (primaries / cosmics / bgEvents …)</p><div class=grid>
<figure><img src="73_few-sparse.svg"><figcaption>★ Fewer — a calm single event, breathing paper; contemplative<br><span style=color:#555>73_few-sparse.svg · primaries 9</span></figcaption></figure>
<figure><img src="74_many-dense.svg"><figcaption>More — a crowded, energetic archive<br><span style=color:#555>74_many-dense.svg · primaries 34</span></figcaption></figure>
</div>
<h1 style="margin-top:34px">Round 13 · living-room finalists — lively archive on four grounds</h1>
<p style="color:#777">MESON-5113 · the busier "lively archive" composition · each on one of the four light grounds, saturation held down so the crowded field stays airy</p><div class=grid>
<figure><img src="76_final-lively-cyan-amber-cream.svg"><figcaption>★ Cyan/amber · cream — most legible, classic cool-warm; my pick<br><span style=color:#555>76_final-lively-cyan-amber-cream.svg</span></figcaption></figure>
<figure><img src="75_final-lively-copper-teal-neutral.svg"><figcaption>Copper/teal · neutral — the design-object; gold field, calm teal anchor<br><span style=color:#555>75_final-lively-copper-teal-neutral.svg</span></figcaption></figure>
<figure><img src="77_final-lively-teal-rose-selenium.svg"><figcaption>Teal/rose · selenium — dreamiest; gentle even when busy<br><span style=color:#555>77_final-lively-teal-rose-selenium.svg</span></figcaption></figure>
<figure><img src="78_final-lively-magenta-cream.svg"><figcaption>Warm magenta · cream — cosiest & most energetic<br><span style=color:#555>78_final-lively-magenta-cream.svg</span></figcaption></figure>
</div></body></html> </div></body></html>

View File

@@ -57,6 +57,7 @@ export function renderCanvasPhoto(ctx, w, h, scene, params, opts = {}) {
const pt = paperTone(params, inv); const pt = paperTone(params, inv);
const pal = resolvePalette(params.palette, { const pal = resolvePalette(params.palette, {
inv, sat: params.saturation ?? 1, hue: (params.hueShift ?? 0) * 360, cycles: params.hueCycles ?? 3, inv, sat: params.saturation ?? 1, hue: (params.hueShift ?? 0) * 360, cycles: params.hueCycles ?? 3,
traceHue: params.traceHue ?? 0, diskHue: params.diskHue ?? 0.06, diskSat: params.diskSat ?? 0.82,
baseInk: P.ink, baseInk: P.ink,
basePaper: { flat: pt.flat, glowIn: pt.glowIn, glowOut: pt.glowOut }, // rgb arrays basePaper: { flat: pt.flat, glowIn: pt.glowIn, glowOut: pt.glowOut }, // rgb arrays
baseVign: pt.vign, baseVign: pt.vign,

View File

@@ -135,7 +135,10 @@ function kindColor(kind, inv) {
// purple→magenta→pink band (for the simplified "magenta family" feel) // purple→magenta→pink band (for the simplified "magenta family" feel)
// purple→magenta→pink band, nudged off the blue end (less blue in the purples) // purple→magenta→pink band, nudged off the blue end (less blue in the purples)
const MAG_HUE = { primary: 0.90, delta: 0.95, cosmic: 0.82, sweep: 0.86, vdecay: 0.79 }; const MAG_HUE = { primary: 0.90, delta: 0.95, cosmic: 0.82, sweep: 0.86, vdecay: 0.79 };
const burntOrange = (inv) => hslToRgb(0.06, 0.82, inv ? 0.42 : 0.54); // the contrasting feature/disk accent — a single monochrome hue. Defaults to the
// burnt-orange that pairs with the magenta family; `magentarise` exposes hue/sat as
// dials (diskHue/diskSat) so the trace-vs-disk colour relationship is sweepable.
const featureHue = (inv, hue = 0.06, sat = 0.82) => hslToRgb(hue, sat, inv ? 0.42 : 0.54);
// lifecycle: colour follows the particle from birth (life 0) to death (life 1). // lifecycle: colour follows the particle from birth (life 0) to death (life 1).
// birth = cool blue, ageing through cyan/green/gold, death = deep red. // birth = cool blue, ageing through cyan/green/gold, death = deep red.
function lifeColor(life, inv) { function lifeColor(life, inv) {
@@ -206,17 +209,21 @@ export const PALETTES = {
}, },
}, },
// simplified feel: type → a shade of purple/magenta/pink, intensity rises to // a complementary "two-colour relationship": type → a shade within a trace family
// glowing deaths (kindrise), with a monochrome burnt-orange disk as the contrast. // (default the purple/magenta/pink band), intensity rises to glowing deaths
// (kindrise), with a monochrome contrasting disk (default burnt orange). The whole
// trace family rotates by `traceHue` (keeping the by-type spread); the disk hue &
// saturation are `diskHue`/`diskSat` — so any trace-vs-disk pairing is sweepable.
magentarise: { magentarise: {
id: 'magentarise', label: 'Magenta by type · burnt-orange disk', id: 'magentarise', label: 'Trace family · contrasting disk',
bubbleInk: (b, e) => { bubbleInk: (b, e) => {
const t = Math.round(clamp(b.life, 0, 1) * 16) / 16; const t = Math.round(clamp(b.life, 0, 1) * 16) / 16;
const lo = e.inv ? 0.82 : 0.18; // faint birth const lo = e.inv ? 0.82 : 0.18; // faint birth
const hi = e.inv ? 0.46 : 0.62; // glowing death const hi = e.inv ? 0.46 : 0.62; // glowing death
return hslToRgb(MAG_HUE[b.track.kind] ?? 0.88, 0.55 + 0.30 * t, lo + (hi - lo) * t); const h = (((MAG_HUE[b.track.kind] ?? 0.88) + (e.traceHue ?? 0)) % 1 + 1) % 1;
return hslToRgb(h, 0.55 + 0.30 * t, lo + (hi - lo) * t);
}, },
feature: (e) => burntOrange(e.inv), // disk + furniture: burnt orange feature: (e) => featureHue(e.inv, e.diskHue ?? 0.06, e.diskSat ?? 0.82), // disk + furniture
}, },
// a complete "chemistry": overrides paper + ink together (deep Prussian-blue // a complete "chemistry": overrides paper + ink together (deep Prussian-blue

View File

@@ -43,6 +43,7 @@ export function buildPDF(scene, params, pageSize = 1728) {
const pt = paperTone(params, inv); const pt = paperTone(params, inv);
const pal = resolvePalette(params.palette, { const pal = resolvePalette(params.palette, {
inv, sat: params.saturation ?? 1, hue: (params.hueShift ?? 0) * 360, cycles: params.hueCycles ?? 3, inv, sat: params.saturation ?? 1, hue: (params.hueShift ?? 0) * 360, cycles: params.hueCycles ?? 3,
traceHue: params.traceHue ?? 0, diskHue: params.diskHue ?? 0.06, diskSat: params.diskSat ?? 0.82,
baseInk: inv ? [28, 24, 20] : [233, 228, 214], baseInk: inv ? [28, 24, 20] : [233, 228, 214],
basePaper: { flat: pt.flat, glowIn: pt.glowIn, glowOut: pt.glowOut }, baseVign: [0, 0, 0], basePaper: { flat: pt.flat, glowIn: pt.glowIn, glowOut: pt.glowOut }, baseVign: [0, 0, 0],
}); });

View File

@@ -38,6 +38,7 @@ export function renderSVG(scene, params, sizePx = 4800) {
const pt = paperTone(params, inv); const pt = paperTone(params, inv);
const pal = resolvePalette(params.palette, { const pal = resolvePalette(params.palette, {
inv, sat: params.saturation ?? 1, hue: (params.hueShift ?? 0) * 360, cycles: params.hueCycles ?? 3, inv, sat: params.saturation ?? 1, hue: (params.hueShift ?? 0) * 360, cycles: params.hueCycles ?? 3,
traceHue: params.traceHue ?? 0, diskHue: params.diskHue ?? 0.06, diskSat: params.diskSat ?? 0.82,
baseInk, basePaper: { flat: pt.flat, glowIn: pt.glowIn, glowOut: pt.glowOut }, baseVign: pt.vign, baseInk, basePaper: { flat: pt.flat, glowIn: pt.glowIn, glowOut: pt.glowOut }, baseVign: pt.vign,
}); });
const paperRGB = pal.paper(); // {flat,glowIn,glowOut} rgb arrays const paperRGB = pal.paper(); // {flat,glowIn,glowOut} rgb arrays

View File

@@ -57,6 +57,7 @@ export function paramsFromSeed(seed) {
showFiducials: chance(0.85), showBoundary: chance(0.7), showHeader: chance(0.9), showFiducials: chance(0.85), showBoundary: chance(0.7), showHeader: chance(0.9),
invert: true, palette: 'mono', saturation: 1.0, // canonical look is B&W; colour is opt-in invert: true, palette: 'mono', saturation: 1.0, // canonical look is B&W; colour is opt-in
hueShift: 0, hueCycles: 3, diskSpectrum: 0, halo: 0, haloHue: 0.55, hueShift: 0, hueCycles: 3, diskSpectrum: 0, halo: 0, haloHue: 0.55,
traceHue: 0, diskHue: 0.06, diskSat: 0.82, // magentarise: trace-family rotation + disk accent hue/sat
paperTone: 'cream', toneStrength: 1.0, paperBright: 1.0, glow: 0.5, paperTone: 'cream', toneStrength: 1.0, paperBright: 1.0, glow: 0.5,
annotate: 0, reseau: 0, filmEdge: false, splice: false, // media & hand layer (opt-in) annotate: 0, reseau: 0, filmEdge: false, splice: false, // media & hand layer (opt-in)
}; };

5
src/ui/controls.js vendored
View File

@@ -83,6 +83,9 @@ export const GROUPS = [
{ id: 'glow', label: 'Gas glow', min: 0, max: 1, step: 0.01, value: 0.5, mode: 'render' }, { id: 'glow', label: 'Gas glow', min: 0, max: 1, step: 0.01, value: 0.5, mode: 'render' },
{ id: 'halo', label: 'Chromatic halo', min: 0, max: 1, step: 0.01, value: 0, mode: 'render' }, { id: 'halo', label: 'Chromatic halo', min: 0, max: 1, step: 0.01, value: 0, mode: 'render' },
{ id: 'haloHue', label: 'Halo hue', min: 0, max: 1, step: 0.005, value: 0.55, mode: 'render' }, { id: 'haloHue', label: 'Halo hue', min: 0, max: 1, step: 0.005, value: 0.55, mode: 'render' },
{ id: 'traceHue', label: 'Trace family hue (magentarise)', min: 0, max: 1, step: 0.005, value: 0, mode: 'render' },
{ id: 'diskHue', label: 'Disk accent hue (magentarise)', min: 0, max: 1, step: 0.005, value: 0.06, mode: 'render' },
{ id: 'diskSat', label: 'Disk accent saturation (magentarise)', min: 0, max: 1, step: 0.01, value: 0.82, mode: 'render' },
], ],
}, },
{ {
@@ -97,7 +100,7 @@ export const GROUPS = [
export const SELECTS = [ export const SELECTS = [
{ {
id: 'palette', label: 'Ink palette (colour feel)', value: 'mono', mode: 'render', id: 'palette', label: 'Ink palette (colour feel)', value: 'mono', mode: 'render',
options: [['mono', 'Monochrome'], ['charge', 'Charge duotone'], ['beta', 'Velocity (β) spectral'], ['kind', 'By particle type'], ['kindlife', 'By type · faded by life'], ['kindrise', 'By type · intensify by life'], ['magentarise', 'Magenta family · burnt-orange disk'], ['lifecycle', 'Lifecycle (birth → death)'], ['psychedelic', 'Psychedelic (hue cycle)'], ['cyanotype', 'Cyanotype (blueprint)']], options: [['mono', 'Monochrome'], ['charge', 'Charge duotone'], ['beta', 'Velocity (β) spectral'], ['kind', 'By particle type'], ['kindlife', 'By type · faded by life'], ['kindrise', 'By type · intensify by life'], ['magentarise', 'Trace family · contrasting disk'], ['lifecycle', 'Lifecycle (birth → death)'], ['psychedelic', 'Psychedelic (hue cycle)'], ['cyanotype', 'Cyanotype (blueprint)']],
}, },
{ {
id: 'paperTone', label: 'Paper tone', value: 'cream', mode: 'render', id: 'paperTone', label: 'Paper tone', value: 'cream', mode: 'render',