git-hash-art 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ name: Deploy git-hash-art-www
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ bump-www:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Extract version from release tag
12
+ id: version
13
+ run: |
14
+ VERSION="${GITHUB_REF_NAME#v}"
15
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
16
+
17
+ - name: Clone git-hash-art-www
18
+ uses: actions/checkout@v4
19
+ with:
20
+ repository: gfargo/git-hash-art-www
21
+ token: ${{ secrets.WWW_DEPLOY_PAT }}
22
+ path: www
23
+
24
+ - name: Setup Node.js
25
+ uses: actions/setup-node@v4
26
+ with:
27
+ node-version: 20
28
+
29
+ - name: Install pnpm
30
+ uses: pnpm/action-setup@v4
31
+ with:
32
+ run_install: false
33
+
34
+ - name: Update git-hash-art dependency
35
+ working-directory: www
36
+ run: |
37
+ pnpm install git-hash-art@${{ steps.version.outputs.version }}
38
+
39
+ - name: Commit and push
40
+ working-directory: www
41
+ run: |
42
+ git config user.name "github-actions[bot]"
43
+ git config user.email "github-actions[bot]@users.noreply.github.com"
44
+ git add package.json pnpm-lock.yaml
45
+ git diff --cached --quiet && echo "No changes to commit" && exit 0
46
+ git commit -m "chore: bump git-hash-art to v${{ steps.version.outputs.version }}"
47
+ git push
package/ALGORITHM.md CHANGED
@@ -9,10 +9,11 @@ Hash String
9
9
 
10
10
  ├─► Seed (mulberry32 PRNG)
11
11
 
12
- ├─► Archetype Selection (1 of 17 visual personalities)
12
+ ├─► Archetype Selection (1 of 17 visual personalities, ~15% chance of blending two)
13
13
 
14
14
  ├─► Color Scheme (palette mode + temperature mode + contrast enforcement)
15
15
  │ └─► Color Hierarchy (dominant 60% / secondary 25% / accent 15%)
16
+ │ └─► Per-Layer Palette Evolution (±20° hue drift across layers)
16
17
 
17
18
  ├─► Shape Palette (affinity-curated primary / supporting / accent shapes)
18
19
 
@@ -30,15 +31,19 @@ Hash String
30
31
  1a. Background Luminance → contrast enforcement threshold
31
32
  1b. Layered Background (archetype-coherent shapes + concentric rings)
32
33
  1c. Background Pattern Layer (dot grid / diagonal lines / tessellation)
33
- 2. Composition Mode Selection
34
+ 2. Composition Mode Selection (6 modes including golden-spiral)
34
35
  2b. Symmetry Mode Selection (none / bilateral / quad)
35
36
  3. Focal Points (rule-of-thirds biased) + Void Zones
36
- 4. Flow Field Initialization
37
+ 3b. Void Zone Decoration (halos, scattered dots, concentric rings)
38
+ 4. Flow Field Initialization (simplex noise FBM)
39
+ 4a. Noise Size Modulation (terrain-like size variation from noise field)
37
40
  4b. Hero Shape (palette-aware, affinity-styled)
38
41
  5. Shape Layers (× N layers, archetype-tuned)
39
42
  │ ├─ Blend Mode (per-layer compositing)
40
43
  │ ├─ Render Style (affinity-aware per shape)
41
44
  │ ├─ Depth-of-Field (stroke thinning + contrast reduction on far layers)
45
+ │ ├─ Color Palette Evolution (per-layer hue drift via evolveHierarchy)
46
+ │ ├─ Focal Depth Boost (nesting/constellation chance ↑ near focal points)
42
47
  │ ├─ Position (composition mode + focal bias + density check)
43
48
  │ ├─ Shape Selection (palette-driven with size constraints)
44
49
  │ ├─ Hero Avoidance Field (nearby shapes orient toward hero)
@@ -46,21 +51,29 @@ Hash String
46
51
  │ ├─ Atmospheric Depth (desaturation on later layers)
47
52
  │ ├─ Temperature Contrast (foreground opposite to background)
48
53
  │ ├─ Styling (transparency, glow, gradients, HSL jitter)
54
+ │ ├─ Shadow & Highlight (drop shadow + specular highlight per shape)
49
55
  │ ├─ Organic Edges (~15% watercolor bleed)
56
+ │ ├─ Edge Erosion (watercolor + hand-drawn styles get irregular boundary bites)
50
57
  │ ├─ 5a. Tangent Placement (~25% nudge toward nearest shape edge)
51
58
  │ ├─ 5b. Shape Mirroring (~40% of basic shapes get reflected copies)
52
59
  │ ├─ 5c. Size Echo (~20% of large shapes spawn trailing copies)
53
60
  │ ├─ 5d. Recursive Nesting (~15% of large shapes, palette-aware)
54
61
  │ └─ 5e. Shape Constellations (~12% of large shapes, pre-composed groups)
62
+ 5f. Layered Masking / Cutout Portals (~18% of images)
55
63
  6. Flow-Line Pass (variable color, pressure, branching)
56
- 6b. Symmetry Mirroring (bilateral-x, bilateral-y, or quad)
57
- 7. Noise Texture Overlay
58
- 8. Vignette (radial edge darkening)
59
- 9. Organic Connecting Curves
60
- 10. Post-Processing
64
+ 6b. Motion/Energy Lines (directional bursts from shapes)
65
+ 6c. Layered Transparency / Glazing (~20% of shapes get multi-pass redraws)
66
+ 7. Symmetry Mirroring (bilateral-x, bilateral-y, or quad)
67
+ 8. Noise Texture Overlay
68
+ 9. Vignette (radial edge darkening)
69
+ 10. Organic Connecting Curves
70
+ 11. Post-Processing
61
71
  ├─ Color Grading (unified tone overlay)
62
72
  ├─ Chromatic Aberration (neon/cosmic/ethereal only)
63
- └─ Bloom (neon/cosmic only)
73
+ ├─ Bloom (neon/cosmic only)
74
+ └─ Gradient Map (~35% chance, luminance-mapped two-color overlay)
75
+ 11b. Generative Borders (archetype-driven decorative frames)
76
+ 12. Signature Mark (deterministic geometric chop mark)
64
77
  ```
65
78
 
66
79
  ## 1. Deterministic RNG
@@ -74,6 +87,16 @@ rng() → float in [0, 1)
74
87
 
75
88
  The old approach extracted 2-char hex pairs from the hash (only ~20 unique values in a 40-char hash). Mulberry32 produces a full 32-bit uniform stream from any seed, eliminating correlation artifacts.
76
89
 
90
+ ### Simplex Noise Field
91
+
92
+ In addition to the scalar RNG, the pipeline creates a **2D simplex noise** function seeded from the hash (with a separate salt so it's independent of the main RNG stream). This produces smooth, organic spatial variation across the canvas.
93
+
94
+ The raw simplex noise is layered into **Fractal Brownian Motion (FBM)** with 3 octaves (lacunarity 2.0, gain 0.5), which adds multi-scale detail — large sweeping gradients overlaid with finer turbulence.
95
+
96
+ The noise field drives two systems:
97
+ - **Flow field angles:** `flowAngle(x, y)` samples the FBM at each position, producing organic, non-repeating directional fields. This replaces the old sinusoidal field which produced visible periodic patterns.
98
+ - **Size modulation:** `noiseSizeModulation(x, y)` samples the raw simplex noise to create terrain-like size variation (0.7×–1.3×). Shapes in "high noise" regions are larger; shapes in "low noise" regions are smaller. This creates natural density clusters without explicit clustering logic.
99
+
77
100
  ## 2. Archetype System
78
101
 
79
102
  Before any rendering begins, the hash deterministically selects one of 17 **visual archetypes** — fundamentally different rendering personalities that override key parameters. This is the primary mechanism for visual diversity: two hashes that select different archetypes will look like they came from entirely different generators.
@@ -126,6 +149,18 @@ Each archetype controls:
126
149
 
127
150
  **celestial** — Boosts sacred geometry and cosmic shapes (crescent, geodesicDome, mandala, flowerOfLife, spirograph, fibonacciSpiral). Neon palette on dark background with heavy glow (2.5×) and deep layering (5 layers) creates a starfield-like composition with luminous geometric forms.
128
151
 
152
+ ### Archetype Blending
153
+
154
+ ~15% of hashes trigger **archetype blending**, where two archetypes are interpolated to create a hybrid personality. `blendArchetypes(primary, secondary, ratio)` works as follows:
155
+
156
+ - **Blend ratio:** 25–50% (the secondary archetype never dominates)
157
+ - **Numeric parameters** (`gridSize`, `layers`, `baseOpacity`, `minShapeSize`, etc.) are linearly interpolated between the two archetypes
158
+ - **Style arrays** (`preferredStyles`) are merged — the primary's styles come first, then any unique styles from the secondary
159
+ - **Categorical parameters** (`backgroundStyle`, `paletteMode`) use the primary's value when the blend ratio is below 50%, otherwise the secondary's
160
+ - **Boolean parameters** (`heroShape`) use the primary's value
161
+
162
+ This creates subtle hybrid personalities — e.g., a blend of `neon-glow` and `organic-flow` might produce glowing shapes with heavy flow lines and earth-toned neon outlines.
163
+
129
164
  ## 3. Color Scheme
130
165
 
131
166
  Color generation uses the `color-scheme` library seeded from the hash, then applies archetype-specific palette modes.
@@ -141,6 +176,17 @@ Color generation uses the `color-scheme` library seeded from the hash, then appl
141
176
  | pastel-light | Soft pastels on light backgrounds |
142
177
  | earth | Muted warm naturals |
143
178
  | high-contrast | Black + white + one accent color |
179
+ | split-complementary | Base hue + two colors flanking the complement (±30°) |
180
+ | analogous-accent | Tight cluster of 3 analogous hues + 1 distant accent |
181
+ | limited-palette | Only 3 colors — risograph-print feel |
182
+
183
+ ### New Harmony Mode Details
184
+
185
+ **split-complementary** — Instead of a single complement (180° opposite), this mode uses two colors at ±30° from the complement. This creates strong contrast like complementary schemes but with more nuance and less visual tension. The base hue gets a tint variant for 5 total colors.
186
+
187
+ **analogous-accent** — Three hues within a tight 30–70° arc (15–35° step between each) create a harmonious, low-contrast base. A single accent color at 150–210° away provides a pop of contrast. This produces compositions that feel cohesive with one surprising element.
188
+
189
+ **limited-palette** — Only 3 colors total, spaced roughly 120° apart with slight randomization. Mimics the look of risograph or screen-printed art where ink colors are limited. The constraint forces the hierarchy system to work harder, producing bold, graphic compositions.
144
190
 
145
191
  ### Color Hierarchy
146
192
 
@@ -173,6 +219,16 @@ The scheme detects whether the background leans warm or cool, then shifts foregr
173
219
 
174
220
  Every shape color is checked against the background luminance. If the contrast ratio is too low, the color is lightened or darkened to ensure visibility.
175
221
 
222
+ ### Color Palette Evolution
223
+
224
+ Colors aren't static across layers — they evolve. `evolveHierarchy(hierarchy, layerFraction)` applies a progressive hue rotation to the entire color hierarchy as rendering moves through layers:
225
+
226
+ - **Total drift:** ±20° across the full layer stack (direction determined by the dominant color's initial hue)
227
+ - **Per-layer rotation:** `layerFraction × 20°` applied via `hueRotate(color, degrees)`, which converts to HSL, shifts the hue, and converts back
228
+ - **Effect:** Early layers lean toward the original palette; later layers drift toward adjacent hues on the color wheel
229
+
230
+ This creates a subtle color journey across the depth of the image — warm reds in the background might shift toward orange-gold in the foreground, giving the composition a sense of temporal progression without breaking palette coherence.
231
+
176
232
  ## 4. Shape Affinity System
177
233
 
178
234
  Not all shapes look equally good at all sizes or in all combinations. The affinity system replaces naive random shape selection with intentional curation.
@@ -281,6 +337,13 @@ Each image uses one of 5 composition strategies for shape placement:
281
337
  | grid-subdivision | Canvas divided into 3–5 cells; shapes placed within random cells |
282
338
  | clustered | 3–5 cluster centers; shapes scatter around the nearest cluster |
283
339
  | flow-field | Uniform random placement (rotation driven by flow field) |
340
+ | golden-spiral | Shapes placed along a logarithmic golden-angle spiral from center outward |
341
+
342
+ ### Golden Spiral Detail
343
+
344
+ The `golden-spiral` mode uses the **golden angle** (~137.5°) to space shapes around the center. Each shape's angular position is `index × goldenAngle` with slight random jitter (±0.3 radians). The radial distance uses a square-root distribution (`√(t) × maxRadius`) which ensures even area coverage — shapes don't bunch up at the center or leave gaps at the edges.
345
+
346
+ This produces the same phyllotactic pattern seen in sunflower seed heads and pinecone spirals. Combined with the size power curve, it creates compositions where large shapes anchor the center and smaller shapes spiral outward in a naturally pleasing arrangement.
284
347
 
285
348
  ### Symmetry
286
349
 
@@ -297,6 +360,16 @@ Symmetry is applied by drawing the canvas image onto itself with `scale(-1, 1)`
297
360
 
298
361
  1–2 **void zones** are placed randomly. Shapes landing inside a void zone have an 85% chance of being skipped, creating breathing room in the composition.
299
362
 
363
+ ### Void Zone Decoration
364
+
365
+ Void zones aren't left completely empty — they receive subtle decorative elements that acknowledge the negative space:
366
+
367
+ - **Halo ring:** A thin circular stroke at the void zone's boundary using the accent color at 6–12% opacity
368
+ - **Scattered dots (~50% chance):** 5–12 tiny dots (1–3px) scattered randomly inside the void zone at 4–10% opacity, creating a dust-like texture
369
+ - **Inner concentric ring (~30% chance):** A smaller ring at 40–70% of the void zone radius at 3–8% opacity
370
+
371
+ These decorations are subtle enough to preserve the breathing room while preventing void zones from feeling like rendering errors.
372
+
300
373
  ## 8. Hero Shape
301
374
 
302
375
  When the archetype enables `heroShape` and the RNG roll passes (60% chance), a dominant focal element is drawn at the first focal point:
@@ -321,6 +394,16 @@ The core of the image: `layers` passes (archetype-controlled, typically 2–5),
321
394
  - **Atmospheric desaturation:** Later layers are progressively desaturated (up to 30%) to simulate depth
322
395
  - **Depth-of-field:** Later layers get thinner strokes (down to 40% of base width) and reduced contrast (up to 20% opacity reduction), simulating camera focus falloff
323
396
 
397
+ ### Focal Depth Boost
398
+
399
+ Shapes near focal points receive enhanced detail via `focalDetailBoost()`:
400
+
401
+ - **Nesting chance:** Boosted from the base 15% up to 15–30% for shapes within 25% of canvas size from a focal point
402
+ - **Constellation chance:** Boosted from the base 12% up to 12–22% near focal points
403
+ - **Boost strength:** Proportional to proximity — shapes right at the focal point get the full boost, shapes at the edge of the influence radius get minimal boost
404
+
405
+ This creates a natural depth-of-detail effect where the areas your eye is drawn to (focal points) contain the most intricate shape compositions.
406
+
324
407
  ### Per-Shape Pipeline
325
408
 
326
409
  For each shape in a layer:
@@ -336,7 +419,27 @@ For each shape in a layer:
336
419
  9. **Contrast enforcement:** Fill and stroke colors checked against background luminance
337
420
  10. **Styling:** Affinity-aware render style, optional glow (sacred shapes 45% base chance × archetype multiplier), optional radial gradient fill (30% chance)
338
421
  11. **Organic edges:** 15% of `fill-and-stroke` shapes are promoted to `watercolor` style
339
- 12. **Light direction:** Non-glowing shapes get a subtle shadow offset along the consistent light angle
422
+ 12. **Shadow & highlight:** Each shape receives a directional drop shadow and specular highlight based on the consistent light angle (see below)
423
+
424
+ ### Shadow & Highlight System
425
+
426
+ Every shape receives lighting effects based on a single consistent light direction (random angle, fixed for the entire image):
427
+
428
+ **Drop Shadow:**
429
+ - Offset: 3.5% of shape size along the opposite of the light direction
430
+ - Blur radius: 6% of shape size
431
+ - Color: `rgba(0,0,0,0.12)` — subtle enough to add depth without muddying colors
432
+ - Applied via Canvas `shadowOffset` + `shadowBlur` properties before the shape is drawn
433
+ - Shapes with glow effects use the glow instead (no double-shadow)
434
+
435
+ **Specular Highlight:**
436
+ - Position: 15% of shape size along the light direction from center
437
+ - Radius: 35% of shape size
438
+ - Gradient: white at 18% opacity → 5% → 0% (radial falloff)
439
+ - Composited via `soft-light` to interact naturally with the shape's fill color
440
+ - Only applied to shapes larger than 15px (tiny shapes don't benefit)
441
+
442
+ The combination creates a subtle 3D effect where shapes appear to float above the background, with consistent lighting across the entire composition.
340
443
 
341
444
  ### 5a. Tangent Placement
342
445
 
@@ -377,9 +480,23 @@ The mirror copy is drawn at 70% opacity and 95% size (decreasing for radial-4),
377
480
 
378
481
  Each member shape uses hierarchy colors with HSL jitter and affinity-aware render styles. Members that fall outside the canvas bounds are skipped.
379
482
 
483
+ ### 5f. Layered Masking / Cutout Portals
484
+
485
+ ~18% of images receive 1–3 **portal cutouts** — shape-sized windows that paint over the foreground layers with a background wash, creating a "peek through" depth effect.
486
+
487
+ The process for each portal:
488
+
489
+ 1. **Position:** Biased toward an existing placed shape (with slight random offset), so portals appear in visually active areas rather than empty space
490
+ 2. **Shape:** Selected from the shape palette at the portal's size fraction, so the cutout shape is palette-coherent
491
+ 3. **Clip and fill:** The shape is used as a clip region, then a radial gradient (derived from the background colors with HSL jitter) is painted over the foreground at 60–95% opacity. This "erases" the foreground shapes within the portal boundary and replaces them with a soft background wash
492
+ 4. **Inner texture (~50%):** Tiny scattered dots inside the portal at low opacity add subtle depth to the wash
493
+ 5. **Border ring:** A subtle stroke outline at 106% of the portal size (15–35% opacity) frames the window, drawn outside the clip so it sits on top of everything
494
+
495
+ The variable opacity (60–95%) means some portals are translucent peeks while others fully reveal the background, creating varied depth effects without punching actual transparent holes in the canvas.
496
+
380
497
  ## 10. Render Styles
381
498
 
382
- Each shape is drawn using one of 14 render styles:
499
+ Each shape is drawn using one of 15 render styles:
383
500
 
384
501
  | Style | Description |
385
502
  | ----- | ----------- |
@@ -397,6 +514,7 @@ Each shape is drawn using one of 14 render styles:
397
514
  | wood-grain | 20% base tint + clipped parallel wavy lines at a random angle, simulating wood texture |
398
515
  | marble-vein | 35% soft base + clipped branching vein lines that drift and fork, simulating marble stone |
399
516
  | fabric-weave | 15% ghost base + clipped interlocking horizontal and vertical thread lines at alternating opacities |
517
+ | hand-drawn | Fill + 2–3 wobbly offset stroke passes simulating a hand-drawn sketch |
400
518
 
401
519
  ### Texture Fill Details
402
520
 
@@ -414,17 +532,57 @@ The 4 new texture fills (noise-grain, wood-grain, marble-vein, fabric-weave) all
414
532
 
415
533
  **fabric-weave** draws horizontal threads at full spacing, then vertical threads at half-spacing offsets, creating an over-under weave pattern. The two thread directions use different opacities (55% vs 45%) and colors (stroke vs fill) for visual distinction.
416
534
 
535
+ ### Hand-Drawn Style
536
+
537
+ The `hand-drawn` style simulates a sketchy, imprecise outline:
538
+
539
+ 1. **Base fill:** Standard fill of the shape
540
+ 2. **Wobbly strokes (2–3 passes):** Each pass redraws the shape's outline with a small random offset (1–3px) and slightly varied line width, creating the impression of a hand tracing the same line multiple times
541
+ 3. **Opacity variation:** Each pass uses 40–70% opacity so the overlapping strokes build up naturally
542
+
543
+ This style works particularly well on organic shapes (circle, triangle, blob) where the wobble feels intentional rather than broken.
544
+
545
+ ### Layered Transparency / Glazing
546
+
547
+ ~20% of shapes receive **glazing** — 2–3 additional fill-only passes drawn immediately after the main shape:
548
+
549
+ - Each pass is progressively smaller (85% → 72% → 61% of the original size)
550
+ - Each pass is progressively more opaque (adding 5–10% opacity per pass)
551
+ - Only the fill is redrawn (no stroke), creating a pigment-pooling effect where the center of the shape appears richer and more saturated
552
+
553
+ This simulates the traditional oil painting technique of building up translucent layers to create depth and luminosity.
554
+
555
+ ### Motion / Energy Lines
556
+
557
+ Short directional line bursts radiate from shapes to suggest movement and energy:
558
+
559
+ - **Trigger:** Always for `dense-chaotic`, `cosmic`, `neon-glow`, and `bold-graphic` archetypes; ~25% random chance for others
560
+ - **Count:** 3–6 lines per shape
561
+ - **Length:** 8–20% of the shape's size
562
+ - **Direction:** Radiating outward from the shape center at evenly-spaced angles with ±15° jitter
563
+ - **Style:** Thin lines (0.5–1.5px) using the shape's stroke color at 15–35% opacity, tapering toward the ends
564
+
565
+ Motion lines are drawn after the main shape layers but before symmetry mirroring, so they participate in any bilateral/quad reflections.
566
+
417
567
  ### Watercolor Detail
418
568
 
419
- The watercolor style simulates wet media through 4 passes:
569
+ The watercolor style simulates wet media through 5 passes:
420
570
  1. **Base wash:** Shape drawn at 108% scale, 15% opacity — soft bleed beyond the boundary
421
571
  2. **Offset washes:** 4–5 passes with radial displacement (random angle, up to 5% of size) — organic edge irregularity
422
572
  3. **Edge darkening:** Shape drawn at 85–93% scale with lightened fill — simulates pigment pooling at boundaries where the inner area dries lighter
423
- 4. **Delicate stroke:** Thin outline (60% of normal width) at 25% opacity
573
+ 4. **Edge erosion:** 6–14 small circular bites erased along the shape boundary using `destination-out` compositing at 60–90% opacity. Bites are placed at 85–110% of the shape's edge radius with sizes 2–6% of the shape, creating the irregular, feathered edges characteristic of real watercolor on textured paper
574
+ 5. **Delicate stroke:** Thin outline (60% of normal width) at 25% opacity
575
+
576
+ ### Hand-Drawn Edge Erosion
577
+
578
+ The `hand-drawn` style also receives organic edge erosion after its wobbly stroke passes:
579
+ - 4–10 small circular bites erased along the boundary at 90–110% of the edge radius
580
+ - Bite sizes are slightly smaller than watercolor (1.5–4.5% of shape size) for a rougher, torn-paper feel
581
+ - Combined with the wobbly multi-pass strokes, this creates shapes that look like they were drawn on rough paper with a slightly dry pen
424
582
 
425
583
  ## 11. Flow Lines
426
584
 
427
- Flow lines follow a sinusoidal vector field defined by `flowAngle(x, y)`. The archetype's `flowLineMultiplier` controls count (0× = none, up to 4× = heavy).
585
+ Flow lines follow a **simplex noise** vector field defined by `flowAngle(x, y)`. The field is generated from a seeded 2D simplex noise function layered with 3-octave Fractal Brownian Motion (FBM) for organic, non-repeating patterns. The archetype's `flowLineMultiplier` controls count (0× = none, up to 4× = heavy).
428
586
 
429
587
  Each flow line:
430
588
  - Starts at a random position
@@ -461,3 +619,43 @@ Only for `neon-glow`, `cosmic`, and `ethereal` archetypes. The canvas is drawn o
461
619
  ### Bloom
462
620
 
463
621
  Only for `neon-glow` and `cosmic` archetypes. The canvas is redrawn with `shadowBlur` at 30px (scaled) and white shadow color, composited via `screen` at 8% opacity. This creates a soft glow around bright areas.
622
+
623
+ ### Gradient Map
624
+
625
+ ~35% of images receive a **gradient map** post-processing pass — a technique borrowed from Photoshop that maps the image's luminance through a two-color gradient:
626
+
627
+ - **Dark color:** The hierarchy's dominant color
628
+ - **Light color:** The hierarchy's accent color
629
+ - **Application:** A linear gradient (top = dark, bottom = light) is painted over the entire canvas using `color` compositing mode at 6–12% opacity
630
+ - **Effect:** Shadows take on the dominant color's hue while highlights shift toward the accent, creating a cohesive tonal relationship across the entire image
631
+
632
+ The `color` blend mode only affects hue and saturation (not luminance), so the gradient map tints the image without changing its brightness structure. At 6–12% opacity, the effect is subtle — it unifies the color temperature without overpowering the original palette.
633
+
634
+ ### Generative Borders
635
+
636
+ After all post-processing, archetype-appropriate decorative borders are drawn to frame the composition. The border style is keyed on the archetype name, with a separate RNG (seeded with salt 314) for deterministic border patterns:
637
+
638
+ | Archetype Group | Border Style |
639
+ | --------------- | ------------ |
640
+ | geometric, op-art, shattered-glass | Clean ruled double lines with corner ornaments (small squares with diagonal crosses) |
641
+ | botanical, organic-flow, watercolor-wash | Organic vine tendrils curling inward from edges, with small leaf dots at tendril ends |
642
+ | celestial, cosmic, neon-glow | Subtle arcs along top/bottom edges + scattered 4-point stars in the border region |
643
+ | minimal, monochrome-ink, stipple-portrait | Single thin rule — understated elegance |
644
+ | Others | No border (intentional — not every image needs framing) |
645
+
646
+ Border elements use hierarchy colors at very low opacity (10–25%) so they frame without competing with the main composition. The border padding is 2.5% of the shorter canvas dimension.
647
+
648
+ ## 13. Signature Mark
649
+
650
+ The final rendering step places a small deterministic **chop mark** (inspired by East Asian seal stamps) in the bottom-right corner of the canvas:
651
+
652
+ - **RNG isolation:** Uses a separate RNG seeded with a salt of 42, so the signature is independent of all other rendering decisions
653
+ - **Position:** Bottom-right corner with a small margin (3% of canvas size)
654
+ - **Size:** 1.5–2.5% of the shorter canvas dimension
655
+ - **Structure:**
656
+ 1. Outer circle ring (stroke-only) at 12–20% opacity
657
+ 2. 2–4 inner lines crossing the circle at unique angles derived from the hash, creating a distinctive geometric pattern
658
+ 3. Center dot at slightly higher opacity
659
+ - **Color:** Uses the accent color from the hierarchy at very low opacity so it's visible but never distracting
660
+
661
+ The signature is unique per hash (different inner line patterns) but always recognizable as a chop mark, giving each generated image a subtle artist's stamp.
package/CHANGELOG.md CHANGED
@@ -4,12 +4,30 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [0.10.1](https://github.com/gfargo/git-hash-art/compare/0.10.0...0.10.1)
8
+
9
+ - feat: shadow/highlight system, generative borders, gradient map, edge erosion [`#19`](https://github.com/gfargo/git-hash-art/pull/19)
10
+ - feat: simplex noise flow fields, color harmony modes, golden spiral composition, layered masking [`#18`](https://github.com/gfargo/git-hash-art/pull/18)
11
+ - fix: portal cutouts use clip-and-fill instead of destination-out [`aecdd14`](https://github.com/gfargo/git-hash-art/commit/aecdd14c0d5ddf52d0394c714d2815679263b961)
12
+ - add GitHub Actions workflow for deployment [`4a6ac42`](https://github.com/gfargo/git-hash-art/commit/4a6ac426d1678f5ff83cbe4c4ddc9ce2a2a0c260)
13
+
14
+ #### [0.10.0](https://github.com/gfargo/git-hash-art/compare/0.9.0...0.10.0)
15
+
16
+ > 19 March 2026
17
+
18
+ - feat: color palette evolution, edge treatment, glazing, motion lines, archetype blending, focal depth, signature mark [`#17`](https://github.com/gfargo/git-hash-art/pull/17)
19
+ - feat: color palette evolution, edge treatment, negative space, glazing, motion lines, archetype blending, focal depth, signature mark [`b496771`](https://github.com/gfargo/git-hash-art/commit/b49677108ae170fef9c1108d40d7db6995efb48c)
20
+ - chore: release v0.10.0 [`38f1d2e`](https://github.com/gfargo/git-hash-art/commit/38f1d2e3b60c921b651be9319e685f77df1ad93b)
21
+
7
22
  #### [0.9.0](https://github.com/gfargo/git-hash-art/compare/0.8.0...0.9.0)
8
23
 
24
+ > 19 March 2026
25
+
9
26
  - feat: new archetypes, depth-of-field, texture fills, constellations, background patterns [`#16`](https://github.com/gfargo/git-hash-art/pull/16)
10
27
  - docs: update ALGORITHM.md with visual quality improvements [`#15`](https://github.com/gfargo/git-hash-art/pull/15)
11
28
  - feat: add 4 archetypes, depth-of-field, texture fills, constellations, background patterns [`7f9b0fc`](https://github.com/gfargo/git-hash-art/commit/7f9b0fcbc4a17272dd6a62371e037fb0555c830b)
12
29
  - add version comparison script [`9301176`](https://github.com/gfargo/git-hash-art/commit/9301176b4f1fe0af85d5d7f85e58db9be10ec382)
30
+ - chore: release v0.9.0 [`32311c2`](https://github.com/gfargo/git-hash-art/commit/32311c2fda12dbcb388e77d9e2faba380d3b0c29)
13
31
 
14
32
  #### [0.8.0](https://github.com/gfargo/git-hash-art/compare/0.7.0...0.8.0)
15
33