Files
solvecraft/docs/render-materials
jyviko 419bbcda0e Shared UI crates: the token contract as a shared crate, solidcraft-theme (#13384)
* Layers: a Shared crate class, and cargo xtask shared builds each one on its own (#12935)

A Shared crate depends only on other Shared crates, solidcore and external crates (UI
toolkits included); any layered or testkit crate may use one. The layer check reports a
Shared crate's dependency on an app crate, of any kind. cargo xtask shared checks each
Shared crate's manifest (workspace lints, licence, README) and that no include_str! or
include_bytes! reaches outside it, then builds and tests it with its Shared dependencies in
a scratch workspace of its own. cargo xtask ci runs it after the layer check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: the widget registry is a shared crate, ui-registry (#12936)

The handle, rect and count registry that UI tests, scenarios and the control channel read
moves out of scenario into solidcraft-ui-registry, the first Shared crate. The kit publishes
into it directly; scenario re-exports it, so scenarios, scripts and the rest of ui-egui are
unchanged and every handle keeps its name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Theme: the tab accent takes the tab, the sketch and the tool as data (#12938)

TabAccent::publish takes the open tab, whether a sketch is being edited and whether a tool
or dialog is active, instead of SolveApp; SolveApp::publish_tab_accent works the three out
in one place. scoped_panel_tokens is public, so a host can draw any component in another
palette or accent. The theme and its tests no longer name SolveApp, Services or workspace.
Accents are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: Preferences search is a kit module, settings_search (#13256)

prefs_search moves whole into ui_kit::settings_search: it filters any settings page the
kit draws, and SolidCraft's Preferences window is one use of it. It publishes its handles
into the widget registry and reads the same wall clock as before (web_time), so no kit
file calls the app for search any more. Every caller uses the new path; state ids, handle
names, matches and scores are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: the kit owns the menu entry and the list width (#13257)

Item (a command or ui.* action with its label, shortcut, icon, params, children, swatch
and tip) and LIST_W move from context_menu into ui_kit::menu, with the same serde form, so
the control channel's menu report is byte-identical. context_menu keeps building
SolidCraft's entries (cmd, and act over Item::action) and returns kit Items. No kit file
refers to context_menu any more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: number parsing and recent colours in the kit, expression support passed in by the host (#13258)

parse_number (decimal point or comma, Unicode minus) moves from prefs into the kit's
fields, and recent_colors moves whole into ui_kit::recent_colors beside the colour picker.
The kit no longer knows the expression language: a host installs an Expressions (is this
a literal, is this a unit, complete or step this text) per egui context, and fields read
it for label drags and completion. SolidCraft installs DocExpressions, built on doc::expr
and params_dialog::complete, when the app first draws into a context. Behaviour in the app
is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: navigation-bar values and the horizontal wheel in the kit (#13259)

The bar's edge, size, idle and button-kind values move beside the bar's drawing in
ui_kit::navigation as NavigationEdge, NavigationSize, NavigationIdle and NavigationKind (the
kit already has a container Edge). Serde names are unchanged, so saved preferences load as
before. take_horizontal_wheel moves into the theme picker, its only caller. SolidCraft's
slot table stays in navigation_bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: layout mode and card geometry in the kit, input shield set by the host (#13260)

LayoutMode (with its per-context publish and current), the card gap and the panic-free
clamp move into the kit's containers and panels, and Cards into stages. Cards::new takes
the workspace width instead of reading the ribbon's constant. The flag that says a report
covers the 3D view is now the kit's (input_blocked, set_input_blocked); the app's CadInput
guard sets it, and issue_report's own copy is gone. Serde names are unchanged, so saved
preferences load as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: continuity rows leave the kit, the navigator figure takes its axes as input (#13261)

continuity_row and its explained and tip variants are CAD controls over the kernel's
Continuity: they move beside their callers in dialogs_surface, still drawn with the kit's
choice_row. The Preferences navigator figure takes its axes (screen direction and depth)
as NavigatorAxis input; SolidCraft computes them from its default camera. dashed_line is
painter geometry and moves into ui_kit::dash with its test. No kit file uses the engine,
the record or the viewport outside tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* UI kit: length fields take unit scaling and length parsing from the host (#13270)

The kit's length field converted millimetres to and from the design's units through three
prefs helpers. Those are the host's unit rules, so Expressions gains unit_scale,
length_number and parse_length_mm, and length_drag reads them from the context.
DocExpressions implements them with the same prefs helpers, so the app is unchanged. With
nothing installed the field edits plain millimetres. No kit file calls prefs outside
tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Colour: the sRGB rule and the analysis palette are a shared crate, solidcraft-color (#13291)

geom's srgb module (the one sRGB transfer function every encode and decode goes through)
moves whole into solidcraft-color with its tests, and so does AnalysisColors, the analysis
palette the theme fills and the renderer reads. render, doc, io, engine, gpu and ui-egui use
the crate; there is no re-export at the old paths. The theme's unused material_color wrapper
is removed, so no non-test theme code names solidcraft_engine. Values are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Material editor: the Remove buttons are translated (material.editor.remove)

The editor's two Remove buttons called tr("Remove"), which looks up an id, so they read
"Remove" in every language. They use a new id, material.editor.remove, whose text in each
locale is the one that locale already gives the plain Remove button
prefs.network_host_remove (33 of 35 catalogs have it; the other two show English, as now).
The label-literal guard found it once the file's import named tr directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Shared UI crates: ui-text, the message catalogs' machinery as a shared crate (#13290)

bidi, Catalog, Locale, lookup, formatting, labels and language choice move from ui-egui's
i18n into solidcraft-ui-text, a Shared crate any front end can use. The host installs its
catalogs once; with none installed every id reads as itself. SolidCraft's 35 catalogs, the
build script that merges them, and the adapters that read engine types (diagnostic,
tr_engine_error, and the given-name and browser-label vocabulary as the LocaleNames trait)
stay in the app's i18n. The app installs its catalogs when it starts, when an app is built
and in the widget test context. Call sites use the crate's path, with no re-export at the
old one; messages, ids and fallbacks are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* i18n tests: the painted-English sweeps install the catalogs themselves (#13290)

no_english_is_painted_where_the_language_has_a_translation and
the_sweep_reports_english_only_where_a_translation_exists read translations without installing the
app's catalogs, so they passed only when another test in the same process had installed them first
(run alone, every id read as itself).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Theme: the icon palette leaves Tokens; the icon renderer owns it (#13304)

A theme file's icon palette was a field of Tokens, so the token set depended on the icon roles
ui-egui's build script generates. It is now the icon renderer's per-thread state
(icon_svg::set_theme_palette), set alongside the theme's palette by theme::set_file_palette, and
theme_files resolves it with resolve_icon_palette (the same overlay merge as the tokens) and
exports it as an argument. Rendered pixels, theme files and exports are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Shared UI crates: the token contract as a shared crate, solidcraft-theme (#13304)

Tokens with SolidCraft's light and dark values in code (palettes.rs moves in from
assets/styles/ui, with the eight primary strokes it shared with the icon artwork written as
icon_strokes), colour vision, TabAccent, contrast checks, apply/visuals and the per-thread and
per-context theme state move into crates/theme, class Shared. It holds no data files and does not
depend on theme files or icon roles; with nothing set, components draw with the built-in tokens.

The theme system stays in ui-egui's theme module: the custom-theme glue (prepared theme, tab
targets and their fade, blur intent), publish_tab (was TabAccent::publish, which now stores its
result through TabAccent::set_current and set_published), set_file_palette, ViewportTheme.
ui-egui's build script no longer generates the primary-stroke constants; an icon test holds the
crate's literals equal to palette.toml's. Call sites use solidcraft_theme paths with no
re-export (one rename pass). Tokens, theme files and rendered pixels are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Theme: the icon lint and the docs read palettes.rs at crates/theme (#13304)

lint_icons.py compared the icon review page with assets/styles/ui/palettes.rs, which moved into
solidcraft-theme; it reads crates/theme/src/palettes.rs now (cargo xtask icons passes again), and
the READMEs, docs and test comments name the new path. set_custom and scoped_tokens say they set
tokens only, so a host with an icon renderer sets its palette too; the field contrast test applies
each built-in theme with set_file_palette, as the app does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

* Theme: format the field contrast test (#13304)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUXeKQRurMYJST9eSZWKzW

---------

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 17:01:03 +00:00
..

SolidCraft rendering and appearance catalog — v0.2

An English, clean-room product specification for the personal render/materials fork.

This contribution defines what to build and how to verify it: 600 appearance concepts, 280 lighting recipes, 280 environments, 120 renderer capabilities, 56 UX requirements and 36 requirements for a future animation and dynamics module. It also supplies numeric preset specifications, scene combinations, current-contract setup examples, and native SELENE reconstruction and validation tools.

The preset set contains 82 future specifications: 10 quality profiles, 24 studio rigs, 24 environment recipes and 24 complete scene combinations. Six additional current-contract setup examples and six analytic physics fixtures support integration and review.

The catalog is a content and implementation backlog. Its entries are not installed shaders, HDR maps, measured materials, completed terrain assets or evidence of renderer support. The numeric recipes have the status specified_unbound: an executor adapter, resources and validation are still required. No production renderer or animation code is changed by this package.

Start here

Document Purpose
Catalog index Browse every material, lighting recipe and environment by stable ID and family.
Materials guide Domain coverage, appearance authoring and SELENE material roles.
Lighting guide Light recipes, contribution ownership and studio presets.
Environments guide Procedural stages, lunar environments and environment presets.
Preset contract Quality tiers, composition rules, units and runtime availability.
UX plan A few-click workflow with deeper controls available in context.
UI integration Exact alignment with the implemented SolidCraft redesign: ribbon groups, existing icons/tokens, library, inspector, responsiveness and accessibility.
Renderer plan Quality foundations, expensive features and evidence for competitive claims.
SELENE Improved showcase source selection, lunar stills, model upgrades and future sample-handling dynamics.
Native SELENE package Pinned source, functional derivative, native verification and render preparation, plus the broader appearance/scene specifications.
Implementation handoff Integration tasks, boundaries, priorities and acceptance gates.
Clean-room record Authorship, sources, exclusions and future asset-admission rules.
Sources Public specifications, scientific facts and pinned project references.

Machine-readable source of truth

materials.json, lighting.json and environments.json hold the concept inventory. capabilities.json, ux.json, simulation-requirements.json and roadmap.json hold requirements and sequencing. quality-presets.json, studio-presets.json, environment-presets.json and scene-presets.json hold future preset intent. baseline-setup-commands.json contains six examples using the already documented render.settings.set shape. selene-bindings.json retains the historical v7 inventory only; the active improved source is selected by assets/render/selene/source-lock.json. Meanwhile, lunar-physics-fixtures.json contains analytic checks for future simulation work.

The UI integration contract pins 21 project source files across the fixed integration base and the observed 0.18.4 design reference. It records current command/icon mappings, proposed groups, disclosure, quality recommendations and twelve acceptance cases. It registers no UI or commands.

JSON is authoritative for identifiers, counts and recipe values. Markdown explains policy and provides a readable index. Python scripts are optional development tooling for authoring and validation; they are not an application runtime or a proposed replacement for SolidCraft's Rust implementation.

Run the package validator from the repository root:

python3 docs/render-materials/validate_catalog.py

It checks data and specification consistency. It does not execute the render engine, measure a material, simulate granular mechanics or establish photorealism.

Identity and scope

Existing MAT-001–MAT-200, LUZ-001–LUZ-200 and ENV-001–ENV-200 retain their semantic identity from the earlier planning inventory. The LUZ prefix is retained as a stable identifier; all names, descriptions, documentation and UI wording in this package are English. New material families occupy MAT-201–MAT-600; lighting and environments extend through 280.

P0 means foundational or first-pack candidate, P1 means expansion after the foundation, and P2 means specialized or later work. Priority is a planning judgment, not availability. Low/Medium/High cost is a relative authoring/rendering estimate, not a hardware benchmark. Dependency lists express minimum intended capabilities and must be refined when a recipe is bound to a concrete executor.

The first shipped pack should be smaller than the full inventory: select approximately 40–60 verified appearances, 20–30 rigs and 20–30 environments, then expand by validated family. The catalog target of 1,160 content concepts must never be presented as 1,160 production-ready assets.

Design decisions

  • Keep engineering material, render appearance, and simulation/contact properties independent and explicitly linked when appropriate.
  • Preserve real CAD dimensions in millimeters, angles in radians and Z-up orientation. Convert once at a documented SI physics boundary.
  • Use one scene description across preview, final output and automation, with visible differences when an executor supports less.
  • Give each lighting contribution one owner. A luminous surface and a sampling proxy must not emit twice.
  • Save recipes as versioned resources, instance overrides and an immutable resolved render request.
  • Prefer procedural, original assets for the foundation. AI can propose source maps or backgrounds; each output still needs provenance, material reconstruction and validation.
  • Build the SELENE still before the animation module. A strong still provides a material, geometry, color and light reference for later frames.

Repository placement

The requested integration base is 0xlillith/solidcraft, branch lab/render-materials, inspected at 93a2922c5ee272fb605703ae84c05825b4a74607. The catalog work is isolated in docs/render-catalog-selene, tracked by issue #2 and PR #3. The native SELENE continuation is isolated in showcase/selene-functional, based on catalog commit 10ada1b45a4eb285ce752ac72f9aaa968ff8b5c4.

The implementation already under way in the other thread remains the authority for runtime behavior. Resolve this specification against the code that actually lands there; do not infer support from the existence of a catalog row.

Prepared resource continuation

The SELENE package contains original numerical appearance recipes, reviewable scene configuration and the current native reconstruction workflow. Its opaque PBR projections can be inspected through the supplied swatch command script. Advanced optics, terrain generators and final-quality output remain gated on actual executor support and validation.

The owner supplied the improved SELENE-showcase.solidcraft. The source lock is now pinned_native; SOURCE.md records its exact hash, author provenance, retained notices and runtime compatibility. The current native work adds mechanism improvements and a Raspberry Pi 5 visual reconstruction through reproducible SolidCraft commands. The native validation record identifies the saved derivative, executor, completed checks and remaining limits. The broader catalog remains unbound, and historical v7 remains excluded as a substitute.