# PROPYLAEA — asset provenance

Built 10 Oct 2026. Nothing is hotlinked, nothing is AI-generated, there are no people in any image. The architecture is
procedural geometry written for this page (`js/propylaea.js`): every step block, landing slab, crepidoma step, column drum,
capital, triglyph, metope, geison block, mutule, pediment course and wall course is modelled to size in code. It borrows
the rhythms of the Athenian Propylaea (a hexastyle Doric front whose middle intercolumniation is wider, three metopes over
it and two over the others; details in dark stone) and reproduces no real building and no inscription. Intact, never ruined.

## Round six (11 Oct 2026): the pediment's apex

Review note: the apex of the pediment was not flush; one side jutted past the other. The cause was in the geometry: each raking
cornice (geison and sima) was a box rotated to the slope from the eave to the apex, so on one side it lay above the
raking line and on the other it hung below it, and both apex ends were cut square to the slope, so one slope's end
overshot the centre line by 12 cm. Both slopes are now built by one function (`rakingMitred`), mirrored: each lies on
the raking line, its ends cut plumb, the apex as a mitre on the gable's centre line (a 4 mm joint at x = 0), the eaves
flush with the horizontal geison. Same six lengths a slope and the same draws from the random stream, so every other
stone is exactly as it was. The tympanum is unchanged (raising it into the soffit drew a lit sliver along the joint).
Before and after: `shots/compare-r6-apex.jpg`; the round-five raw stills are kept in `shots/before-r6/`. Every
fallback still was re-rendered (the first frames, the four landings, the court with a trio and a full orchestra, the
detail print, the open chair); the landings, court, detail and open-chair stills had still carried round three's
shading. Dev switch: `tools/harness.html?oldraking` renders round five's pediment for comparisons.

## Dimensions (real, so the scale reads)

| Element | Size |
|---|---|
| Stair | 4 flights of 10 risers; riser 12 cm, tread 45 cm (2R + T = 69 cm: a gentle monumental stair); landings 3.2 m; 48 m wide |
| Crepidoma | 3 steps of 30 × 55 cm; in the middle bay each split in two (15 cm), the top one a threshold course of dark stone |
| Columns | Doric, 8.80 m to the top of the abacus (the Propylaea's west columns), 1.56 m at the foot, 1.24 m under the capital; 20 segmental flutes meeting in sharp arrises; entasis 12 mm; 9 drums of varied height, each its own tone; hypotrachelion groove, three annulets, Classical echinus, abacus 1.74 m |
| Spacing | axes 3.6 m, the middle bay 5.4 m (as on the Propylaea's west front) |
| Entablature | architrave 1.10 m + taenia 0.10 with regulae and six guttae each; frieze 1.30 m of triglyphs (two glyphs, two half-glyphs) and recessed metopes; geison 0.55 m projecting 0.62 m with mutules; pediment at 13.5° |
| Court | 48 × 40 m, a precinct wall 7 m high either side of the gate; a stoa of twelve 6.2 m Doric columns across the far side |
| Ensemble | Portico's models at their published sizes (chair seat 47.5 cm; Manhasset-type stands, desk at 1.08 m; violin, viola, cello and double bass on their stands) |

## Code

| File | Source | Licence | Notes |
|---|---|---|---|
| `vendor/three-0.185.1/three.core.min.js`, `three.module.min.js`, `LICENSE` | npm `three@0.185.1`, `build/` (the copy vendored for Marbre and Theatron) | MIT | Pinned, unmodified. |
| `vendor/three-0.185.1/addons/loaders/HDRLoader.js` | same package, `examples/jsm/loaders/` | MIT | Unmodified. |
| `js/propylaea.js` | written for this concept | — | Stone pipeline after Theatron's (per-block tone and settlement, joints and eased arrises in the shader, ACES then a print grade); new: the stair with worn, dished treads and chipped nosings, the Doric order, the precinct, PCSS with the receiver plane taken from the geometric normal per vertex (rule 35), a fine shadow cascade for the ensemble blended per fragment so the sun is counted once (rule 33), the camera path. |
| `js/ensemble.js` | copied from Portico v2 (`concepts/portico/assets/js/ensemble.js`, round four) | — | Merged geometries keep their normals (here they are seen, not only cast shadows); each stand's part (paper) is a separate geometry. |
| `js/page.js` | written for this concept | — | Scroll → p, the words, the ensembles radiogroup, reduced motion, downshift, hooks. |

## Textures and light

| File | Source | Author | Licence | What was done |
|---|---|---|---|---|
| `tex/marble-albedo-1k.webp` | ambientCG **Concrete012**, **Rock004** and **Marble019**, 2K-JPG colour maps (https://ambientcg.com/view?id=Concrete012, …Rock004, …Marble019) | ambientCG (Lennart Demes) | CC0 1.0 | `tools/build_marble.py`: linear luminance; Theatron's weathered pair (Concrete012 0.62, Rock004 0.16) for the eroded, sugary surface, plus Marble019's veins (high-passed, smeared along the bedding) at 0.55; extremes eased (tanh); mean 0.5; greyscale 1024², WebP q84. Applied at true scale (one tile = 2.6 m). |
| `tex/marble-normal-1k.webp` | Concrete012 + Rock004 `NormalGL` | ambientCG | CC0 1.0 | UDN blend (0.72 / 0.38), renormalised, 1024², WebP q88; softened further in the shader on worn faces. |
| `tex/sky-hdr.js`, `tex/sky-bg.webp` | Poly Haven **Derelict Overpass**, 4K HDR (https://polyhaven.com/a/derelict_overpass); sky only | Greg Zaal | CC0 1.0 | `tools/build_sky.py` (round 3): chosen for its sun at 21.1° (the scene's is 20°), at full strength, with an altocumulus field above it, so the clouds are lit as the stone is. Decoded; luminance through the orange-red filter (0.62 R + 0.31 G + 0.07 B) for sky and sun alike; the ground and low hills below 3.5° replaced by the haze just above them (as Poly Haven's pure-sky versions do); sun disc removed (r < 14 px, highlights capped at 4.0); turned so its sun sits with the scene's (rule 39). Lighting: 256×128 RGBE as base64, lower hemisphere a sunlit marble ground. Background: ±80° about the sun, −10° to +76°, log-encoded 8-bit grey, 1820×979 WebP, shifted 1.1° in the shader. Sun 11.09 against 0.50 from the sky (both ×1.254): through the filter the blue skylight that fills the shade is weak, so shaded treads print at about 20% of sunlit (round 1: 24%, round 2: 34%; `shots/compare-r3-*`). A light polarizer deepening (0.2) in the sky shader. Round 2 used Table Mountain 2 (Pure Sky), sun at 7°; its source is kept in `tools/src/sky/`. |

Light: one sun 6° left of straight behind the gate, 20° high, never moving; the same sun's fine cascade over the ensemble;
the HDRI sky fill at its measured strength; the marble ground in the HDRI's lower half, but only where that ground is
actually in the sun: each stone fragment looks up the shadow map at nine points on the ground ahead of it, spread over its
footprint and turned each accumulated frame (round 3), so a
riser above a shaded tread, or a wall over its own shadow, gets only what sky-lit marble returns; a small local bounce near sunlit
floors (the feet of the columns, the risers); a translucency band beyond the terminator (Pentelic marble carries the low
sun a little way round its edges), lit only where an offset shadow lookup finds the sun just outside the stone. Round 4: a face turned from the sun takes none of it whatever its shadow lookup says (PCSS leaked on faces running
nearly parallel to the light); stone's specular fades out below 17° of incidence (GGX's grazing peak drew white flags on the
inner abaci, met edge-on by both sun and eye); the edge glow stays off faces turned down and, on the lit side of the
terminator, off flat faces; the ends of blocks in a course (geison, raking cornice) are marked as joint faces and take no sun. The sun's elevation is set by the stair: at 20° the light, coming down a 15° stair, still reaches the front of
every tread, and rays from the foot of the stair pass the colonnade at column height, so the column shadows run the whole
length of the stair. Print: ACES, then a gentler S-curve than round 2 (contrast 1.5 about 0.43): the light now carries the contrast. The
entablature and pediment (round 3): block-to-block value eased, a grey patina with rain streaks under every drip edge,
per-vertex occlusion and the normal map eased up there. Generated at runtime (code, no files): per-block value, settlement and wear; rain streaks; dark crusts where rain never
reaches (soffits, the upper shafts under the architrave, the porch) and paler rain-washed tops; chipped arrises and broken
nosings; grime in the creases. The engine's last pass averages up to eight jittered frames once the frame holds still
(Halton 2,3 sub-pixel offsets, the PCSS kernel turned each time), crossfades between ensembles (nothing glides), and adds a
lens's vignetting and a fine static grain, so the stills and the live frame carry the same finish.

## Fonts (concept only)

| File | Family | Licence | Production face to license |
|---|---|---|---|
| `fonts/italiana-latin.woff2` | Italiana (Google Fonts), Santiago Orozco | SIL OFL 1.1 (`fonts/OFL-Italiana.txt`) | Saol Standard Light (caps) or PP Editorial New |
| `fonts/mona-sans-latin.woff2`, `-latin-ext` | Mona Sans v4 (Google Fonts; variable wght, wdth), GitHub | SIL OFL 1.1 (`fonts/OFL-MonaSans.txt`) | Neue Haas Unica |
| `fonts/spectral-light-italic-latin.woff2`, `-latin-ext` | Spectral Light Italic 300 (Google Fonts), Production Type | SIL OFL 1.1 (`fonts/OFL-Spectral.txt`) | GT Sectra Fine Italic |

The caption was Cormorant Garamond Italic in round five's first build; the house style excludes Cormorant, so it is now
Spectral Light Italic (realism pass). Italiana and Mona Sans are as the design brief names them.

## The stills (first frame = fallback)

Rendered headless from this scene through `tools/harness.html` (`tools/stills.mjs`: Playwright Chromium, SwiftShader,
MSAA, the engine's own last pass: 4 jittered frames for the first-frame stills, 2 for the others), resized with Lanczos 3
and encoded with sharp (AVIF q56, WebP q82, mozjpeg q82). The first frame (realism pass): a photographer at the foot of
the stair, left of the middle, eye at 1.22 m, a 24 mm lens on full frame (51° vertical at 16:10), tilted up so the
verticals converge a little.

| Files | What | Used for |
|---|---|---|
| `img/propylaea-p0-wide-{2560,1280}`, `img/propylaea-p0-tall-{1170,780}` (.avif .webp .jpg) | the foot of the stair, desktop and phone reference frames | first paint, no WebGL, reduced motion |
| `img/seq-{1,2,3,4}-1600`, `img/seq-{trio,full}-1600` | the three landings, the gate, the court with a trio and with a full orchestra | reduced motion / no WebGL sequence |
| `img/detail-{1200,600}` | the order from the third landing | the print in Occasions |
| `img/open-chair-{1600,800}` | the trio's places in the court, the viola's chair empty | For musicians |

The live camera re-maps its reference projection exactly as CSS `object-fit: cover` crops each still. Measured at
1440×900 after round 3: mean absolute difference between the still and the live first frame 3.09/255 (phone
3.25/255), `shots/diff-*`.

## Byte budget (measured, `tools/verify.mjs`, files as served without compression)

| | requests | bytes |
|---|---|---|
| First view, desktop 1440×900 (realism pass, from the served files) | 16 | **1.97 MB**; about **1.14 MB** with gzip on the JS, HTML and the sky module |
| First view, phone 390×844 @2× | 16 | 1.93 MB (about 1.10 MB compressed) |
| Everything published (`index.html` + `assets/`), round 3 | — | 6.9 MB |

Scene: about 0.61 M triangles (stair 0.25 M, the two colonnades and the stoa 0.2 M). Phones and machines with four cores
or fewer take 2048 shadow maps and fewer PCSS taps; the pixel ratio steps down in flight if frames run long (rule 18).

## References studied (in `tools/refs/`, never published; `tools/` is not part of the page)

Wikimedia Commons, used only to judge realism (see `tools/refs/SOURCES.txt`): *The staircase leading to the Propylaea of the
Acropolis* (CC BY-SA 4.0); *Els Propileus de l'Acròpoli d'Atenes des de baix* (CC BY-SA 3.0); *The Doric columns of the
Propylaea on March 22, 2021* (CC BY-SA 2.0); *The Doric columns of the Propylaea on October 16, 2022* (CC BY-SA 4.0);
*Propylaia West DSC 3921-1 s* (CC BY-SA 4.0); *The western side of the Propylaea of the Acropolis on March 5, 2020*
(CC BY-SA 4.0). Requests used the VX business contact in the User-Agent, per Wikimedia policy.
