<feed xmlns='http://www.w3.org/2005/Atom'>
<title>archsetup/docs/prototypes/panel-widget-gallery.html, branch main</title>
<subtitle>Builds a full dev workstation from a bare Arch Linux install.
</subtitle>
<id>https://git.cjennings.net/archsetup/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/archsetup/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/'/>
<updated>2026-07-25T20:00:56+00:00</updated>
<entry>
<title>refactor(prototypes): merge casting widgets into Dupre kit</title>
<updated>2026-07-25T20:00:56+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-25T20:00:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=ef00914a4dc5ef1347ca0bf9850157e659d0e654'/>
<id>urn:sha1:ef00914a4dc5ef1347ca0bf9850157e659d0e654</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(gallery): bring ten more controls to the extraction bar</title>
<updated>2026-07-18T19:09:35+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T19:09:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=9fa438e990807e358b126f896b84d8b4d45a084b'/>
<id>urn:sha1:9fa438e990807e358b126f896b84d8b4d45a084b</id>
<content type='text'>
rotarySelector, slideRule, rocker, transport, presetBank, dualKnob, encoder, keySwitch, crossfader, and thumbwheel get contract comments, dupre- prefixed CSS, and cached element refs. presetBank and dualKnob set() now clamp out-of-range input, with a probe check covering both. rotarySelector and keySwitch cap their inputs at the five- and three-stop plates they draw. The audit's contract count moves to 34/111.
</content>
</entry>
<entry>
<title>feat(gallery): bring ten core controls to the extraction bar</title>
<updated>2026-07-18T18:27:11+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T18:27:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=04f99818ff10ce4d49baa675aee88222313e5cd4'/>
<id>urn:sha1:04f99818ff10ce4d49baa675aee88222313e5cd4</id>
<content type='text'>
Batch 2 of the extraction sweep: consoleKeys, abcKeypad, indexPlate, faderH, faderV, knob, segmented, chipToggle, armButton and lampRow now carry the split-flap-shape contract comment. Every class they own wears the dupre- prefix, internals and modifiers included (dupre-key dupre-green, dupre-fader dupre-cap), with every in-kit consumer updated in the same pass: the dsky and annunciator pads, the rotarySelector and encoder spindles, the page's size bar, and the probe selectors.

I also removed indexPlate's dead '#dupre-defs' lookup (nothing ever created that id) and dropped the unused .key.off rule. The faders, knob and lampRow now cache their element refs instead of re-querying every set(), and segmented and lampRow clamp set() the way consoleKeys does.

The audit's contract count moves from 14 to 24 of 111.
</content>
</entry>
<entry>
<title>refactor(gallery): rename GW namespace to DUPRE, kit to The Dupre Kit</title>
<updated>2026-07-18T15:50:18+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T15:50:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=5fb6b9836ac8389bb68ce27e70331b3e2d29aa04'/>
<id>urn:sha1:5fb6b9836ac8389bb68ce27e70331b3e2d29aa04</id>
<content type='text'>
The gallery and its library are now The Dupre Kit, named for the dupre color theme. GW was too opaque to remember. The stylesheet id is now dupre-css, the card handle property is .dupre, and page prose says instrument instead of widget. File names stay put. Renaming them is a separate decision.

Historical log entries in todo.org keep their GW references as a record.
</content>
</entry>
<entry>
<title>fix(gallery): split-flap defaults are paper cards, Helvetica, 100ms</title>
<updated>2026-07-18T14:51:55+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T14:51:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=f6cb628aad6e3e5f08e5533f7b98eaa063640243'/>
<id>urn:sha1:f6cb628aad6e3e5f08e5533f7b98eaa063640243</id>
<content type='text'>
The default skin is the white card with dark lettering, not white ink on black, and the default face is Helvetica. Both list first in their chip rows with the alternatives a click away. The base flap rate moves to 100ms. The probe pins all three defaults, and its cascade windows widen to match the slower base so worst-case travel keeps its margin.
</content>
</entry>
<entry>
<title>feat(gallery): white-ink default, 85ms base rate, ID badges as anchors</title>
<updated>2026-07-18T12:56:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T12:56:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=aeb32a7ea616459d0104b95c85c964a32a3edf50'/>
<id>urn:sha1:aeb32a7ea616459d0104b95c85c964a32a3edf50</id>
<content type='text'>
The split-flap's default skin becomes the white ink, listed first in the chip row, with the kit cream one click away. The base flap rate moves to 85ms, and the probe pins both defaults so a drive-by change can't silently flip them.

Every card's ID badge is now a real anchor to its own card, so a click deep-links the URL and a right-click copies it. One shared rule keeps the badge look.

The refactor sweep for extraction-readiness closes out: the flip duration and the ms clamp each live in one place, grid normalization is one helper shared by setText and the silent first paint (which now records itself as the last commanded grid, ending the null fallback), the state declarations sit above everything that references them (the same declared-later shape that caused a load crash earlier in the branch), and a stale two-skin comment caught up with the four skins. Behavior-preserving: all 79 probe checks stay green.
</content>
</entry>
<entry>
<title>feat(gallery): grow the split-flap into a randomized multi-row board with skins, faces and a flap-rate slider</title>
<updated>2026-07-18T12:51:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T12:51:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=356a38fef66bb1ab4db44e4f9db92e378dc31e62'/>
<id>urn:sha1:356a38fef66bb1ab4db44e4f9db92e378dc31e62</id>
<content type='text'>
The N20 card becomes a three-row, six-cell departure board. Every advance sends each row to a completely different word, drawn at random from a 24-word pool with rows kept mutually distinct, and each cell runs at its own mechanical rate (a fixed 0.8x-1.35x of the base flap time), so letters and whole words finish at genuinely different times. A slider on the card sets the base rate (setFlapMs on the handle). The board advances only after it has settled and dwelt two seconds on the reading: the builder announces settle once per command (onSettle) and the page schedules the next advance from that signal, since a fixed-interval ticker would retarget mid-cascade and the panel would never rest. The chain stays gated off under reduced motion, where the board paints once and rests.

Customization lands as two construction axes on the chip rig: skin (cream-on-black default, true-white ink, the ivory board, or white cards with dark lettering) and face (Berkeley Mono or Helvetica, the grotesque real boards wore). The skin chips are miniature flap cells, a letter in the skin's real ink on its real board colour, and the font chips letter themselves in their actual face, so every choice previews itself. The flap-rate slider rides in the chips row, and the card's amber word readout is gone: the board is the display. The deterministic seam for callers and tests is setText; randomness lives only in the demo path (next/scramble), which re-aims against the last commanded grid rather than in-flight glyphs.

The settle work caught a real ordering bug: setText assigned each cell's target and ran it in one pass, so a cell finishing synchronously saw its neighbours' stale, already-satisfied targets and announced a partial board as settled. Targets now all land before any cell runs. Review caught two more: the dwell chain had escaped the reduced-motion gate (the board self-advanced every two seconds forever under reduced motion), and the skin chips rendered blank because the STYLES entries were strings where the rig paints an object's dot swatch.

Since this is heading for extraction as a regular component, the builder got the full refactor pass: a contract comment covering every opt and the handle surface, small named helpers, no page globals, and all CSS in the one split-flap block. The same bar is filed as a sweep task for every other builder. Probe coverage grows to 78 checks: the reduced-motion rest, the live dwell measurement, the scramble contract, both style axes, the speed api and the swatch legibility.
</content>
</entry>
<entry>
<title>feat(gallery): make the N20 split-flap an honest Solari mechanism</title>
<updated>2026-07-18T09:32:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T09:32:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=b4d3a6076b569c4e95f1362d23a9b279e5a5c5f9'/>
<id>urn:sha1:b4d3a6076b569c4e95f1362d23a9b279e5a5c5f9</id>
<content type='text'>
The card's flip was a 0.3s drop-fade that teleported each cell straight to its target character — a suggestion of a split-flap, not one. Since the gallery card is the spec the ports get measured against, the fake would have propagated.

Three behaviors replace it, studied from the HotFX split-flap component and re-derived (its repo carries no license, so no code was copied). The charset is the drum: opts.chars declares the flap order and a changed cell steps one flap at a time through intermediates, never jumping, so cells arrive staggered by travel distance. A set() mid-cascade re-aims the running cells at the new target. The fold is real: two half-panel animations per flip — the current top falls, the next bottom lands — over four clipped layers with backfaces hidden, replacing the drop-fade keyframe.

animate:false (the reduced-motion gate) collapses every move to an instant jump. The handle grows setText, chars, and reading() so probes can sample the displayed state mid-cascade; the default width goes 3 to 4 cells, which stops truncating every demo word. Probe checks were written red first: cascade arrival, intermediate readings, one-flap-at-a-time stepping in charset order, mid-cascade retarget, and the instant animate:false path.
</content>
</entry>
<entry>
<title>refactor(gallery): extract the shared tally-row markup</title>
<updated>2026-07-17T23:39:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-17T23:39:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=50aa5ac052db9b12f049276799898089e2226f80'/>
<id>urn:sha1:50aa5ac052db9b12f049276799898089e2226f80</id>
<content type='text'>
The validation and policy tallies were built from the same dot/label/count row template, written out per bucket in both. That template is now tallyRow() and tallyTotal(), so the markup has one source and the next index tally reuses it. The differing count and jump logic stays in each function, since those genuinely diverge: the validation tally drives the floating audit stepper, the policy tally a plain hash cycle.

Also hoisted GW.POLICIES[kind] to a local in card(), where it was read three times.

Behaviour-preserving: the output HTML is byte-identical.
</content>
</entry>
<entry>
<title>feat(gallery): colour-policy system, chip-toggle accents, widgets-per-row</title>
<updated>2026-07-17T23:34:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-17T23:34:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=d14ab82a8c2ad974304477e29014d3a565e64504'/>
<id>urn:sha1:d14ab82a8c2ad974304477e29014d3a565e64504</id>
<content type='text'>
Every widget's colour is either the consumer's to pick or locked for a reason, and I kept classifying cards wrong from memory during the colour pass. So the policy is a declared, checked property now. Six kinds. Accent and screen are free and take colour chips. Coded, emissive, relational and material are locked and must not. Each classified builder carries a POLICY record naming the kind, why this widget is bound that way, and what it may change and stay authentic (the range that actually existed, like the CRT phosphors that shipped). Eight are classified. The rest are the worklist.

The page shows all of it from that one source. A card recovers its builder from the arrow it was handed and reads GW.&lt;builder&gt;.POLICY, so the badge, the spec-sheet catalog and the index tally can't drift from the code. A probe holds it both ways: the recolour mechanism and the accent kind imply each other, so a locked card can't grow chips and an accent card can't forget to declare.

The chip toggle is the first consumer of a shared accent family (red, amber, green, white, vfd) from GW.accentStyles, so the next card that wants those five gets them from one definition rather than a copy.

Two smaller changes ride along because they touch the same header. The size toggle becomes WIDGETS/ROW, an explicit 1-4 column count instead of S/M/L zoom, and the policy panel sits level-right of the index.
</content>
</entry>
</feed>
