Repository navigation
Description
Extends #2146 (programs-as-websites). This is an EXPANSION design: #2146 lets programs be websites; this issue designs the markup & styling model those programs are written in, so one source renders correctly as a website, as a GUI app, and as a native app.
Problem
If programs-as-websites can only be written in raw HTML/CSS, authors carry web-platform complexity everywhere and the same program cannot become a native-feeling GUI app. If instead we invent a purely abstract UI language, authors lose the web's power and familiarity. We need both layers, plus a styling model that survives translation across targets.
Layer 1 — Raw HTML/CSS always supported
- Raw HTML and CSS are always valid and always supported, on every target where they make sense; the semantic layer below is an addition, never a replacement or a gate.
- Rules for mixing: semantic markup and raw HTML/CSS can coexist in one program; specify precedence, escaping/sanitisation, and what raw HTML degrades to on native targets (webview embedding? translation? explicit fallback content?).
- No feature of the semantic layer may require giving up a raw-HTML escape hatch.
Layer 2 — Semantic markup for common website concepts
- A simpler semantic markup covering the common website/program concepts: page/section, navigation, headings/text, links, forms (fields, validation, submission), buttons/actions, lists/tables/data display, cards, dialogs, media, and application concepts that carry forward into GUI apps (menus, toolbars, sidebars, tabs, settings/preferences, master-detail).
- Semantic elements describe intent and structure, not presentation: e.g. a form is a form — the target decides how a form looks.
- Authoring ergonomics: the semantic markup should be writable by hand, diff-friendly, and a strict subset in spirit of what HTML authors already know (names/attributes mapped from HTML where possible).
- Accessibility semantics are intrinsic: every semantic element carries its ARIA/native accessibility role by construction, on every target.
- Data binding / state hooks: how semantic markup connects to program state and actions without embedding target-specific code.
Style-override mapping (the core design)
Styling is expressed as semantic style assertions — e.g. "this form is green" — and each target renders the assertion in its own idiom:
- HTML/web target: the assertion renders as Tailwind classes (the web rendering of the design's style tokens/utilities). Specify the assertion → Tailwind mapping table, specificity/override order, and how it composes with raw CSS.
- GUI app target (custom-rendered): the same assertion may render as a custom image button / fully custom-drawn control — the design must allow a target to substitute a wholly custom presentation (image, canvas-drawn, themed asset) for a semantic element + style assertion.
- Native app target: the same assertion renders as an OS-standard button/control — Mac, Windows, or GNOME-adaptive: the control follows the host OS human-interface conventions (shape, focus, keyboard, high-contrast, dark mode) while still honouring the semantic assertion as far as the platform allows (e.g. accent colour/tint), and the design must state what happens when an assertion conflicts with platform conventions (platform wins for behaviour; assertion wins for identity/brand colour — or the reverse: decide and document).
- Define the style vocabulary: colour roles (not raw hex in semantic assertions — named roles/tokens with per-target values), typography roles, spacing/density, emphasis/variant (primary, destructive, subtle), state styles (hover/focus/disabled/error), and dark/light/high-contrast variants.
- Cascade: semantic assertions < per-target overrides < raw CSS (web) — or a different order; specify it, plus how conflicts are reported to authors (linting/tooling).
Per-target customisation points (without forking the content)
- A program has one content/semantic source. Targets customise via: theme/token files per target, override maps (element + assertion → target presentation), target-specific asset substitution (e.g. image buttons), and conditional inclusion blocks (target-only embellishments that never carry essential content).
- Explicitly forbidden pattern: copying the whole page per target. The design must show, with a worked example, one form rendered to (a) Tailwind HTML, (b) a custom-image-button GUI app, and (c) a native Mac/Windows/GNOME app — from the same source.
- Responsive/adaptive behaviour: layout assertions (stack vs. side-by-side, density) that each target interprets for its form factor.
Compilation / rendering architecture
- Where does translation happen: compile-time per target, runtime interpreter, or hybrid? Specify the pipeline from semantic source → per-target artefact.
- Conformance: a test suite of semantic documents with expected renderings per target (structural/accessibility-tree expectations for native targets, class/DOM expectations for web).
- Tooling: preview across targets, assertion-coverage warnings ("this assertion has no native mapping; platform default will be used").
Non-goals
- A new general-purpose programming language — this is markup and styling only, within id(serve): design — how does a program appear as a website? (program-only ports, mixed ports, path mounts) #2146's program model.
- Pixel-identical rendering across targets — native targets should look native, not identical.
Decomposition sketch
Follow-on design tickets to be filed from this issue:
- Semantic markup vocabulary v1 — element set for website + GUI concepts, authoring syntax.
- Style assertion vocabulary — colour/typography/spacing/state roles and tokens.
- Web rendering: assertion → Tailwind mapping, cascade with raw CSS, mixing rules with raw HTML.
- Native rendering: assertion → OS-standard controls (Mac / Windows / GNOME), platform-conflict rules.
- Custom GUI rendering: wholly custom presentations (image buttons, drawn controls) as first-class overrides.
- Per-target customisation system: themes, override maps, asset substitution, conditional blocks — with the worked three-target example.
- Rendering pipeline & conformance suite: compile/runtime split, per-target expected-output tests, author tooling/linting.
Open questions
- Syntax home for semantic markup: HTML-like tags, a Markdown-adjacent syntax, or an s-expression/DSL form — which best serves id(serve): design — how does a program appear as a website? (program-only ports, mixed ports, path mounts) #2146 authors?
- How large is the v1 element set? Which GUI concepts (menus? tabs? master-detail?) are truly in v1 vs. deferred?
- Tailwind as the web rendering: pinned version, and are generated classes ever author-visible/editable?
- When a semantic assertion has no native equivalent, is silent platform-default acceptable, or must the author be warned at build time?
- Raw HTML on native targets: webview fallback, translation of a subset, or author-supplied fallback content — pick per element class.
- Who owns token values for OS-adaptive rendering in dark/high-contrast modes — the program's theme or the OS?
Program note: expansion-style design — a later pass breaks this into the follow-on design tickets above, then implementation tickets. Relatives: #2146.
Activity
dezren39 commentedon Nov 5, 2026
Gap pass (WS-F, 2026-11-04): this issue's decomposition sketch is now filed.
Each follow-on design ticket named in the sketch above was filed as its own issue (label
app/id), so the acceptance item “Follow-on design tickets filed from the Decomposition sketch” can now be checked:Exception, where applicable: any sketch item already answered by a later filing is noted in the pass worklog rather than duplicated. Design prioritisation is now independent per ticket; implementation timing is a separate decision.
dezren39 commentedon Nov 5, 2026
agent-note:v1
dezren39 commentedon Nov 5, 2026
agent-note:v1
Triage 2026-11-05 (task 10112): this is an umbrella expansion-design issue, and it is already decomposed — no new tickets needed and nothing is silently unlinked.
Verified at triage:
source/creator+app/id. Addedkind/design+priority/normalto match its parent id(serve): design — how does a program appear as a website? (program-only ports, mixed ports, path mounts) #2146's taxonomy.Ordering for the follow-ons (dependencies, not a schedule):
This umbrella stays open until the follow-ons resolve; implementation tickets are a separate later decision per the gap-pass note. No blocker on Drew.
dezren39 commentedon Nov 5, 2026
🤖 Agent note · done