Skip to content

id: design: Markup & styling model for programs-as-websites — semantic markup, style-override mapping #5679

Open

Description

@dezren39

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

Decomposition sketch

Follow-on design tickets to be filed from this issue:

  1. Semantic markup vocabulary v1 — element set for website + GUI concepts, authoring syntax.
  2. Style assertion vocabulary — colour/typography/spacing/state roles and tokens.
  3. Web rendering: assertion → Tailwind mapping, cascade with raw CSS, mixing rules with raw HTML.
  4. Native rendering: assertion → OS-standard controls (Mac / Windows / GNOME), platform-conflict rules.
  5. Custom GUI rendering: wholly custom presentations (image buttons, drawn controls) as first-class overrides.
  6. Per-target customisation system: themes, override maps, asset substitution, conditional blocks — with the worked three-target example.
  7. 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

  1. added
    source/creatorFiled by the new-issue-creator job
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    on Nov 4, 2026
  2. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    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.

  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/triageQueue packet kind: verify, reproduce, and route this item
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    on Nov 5, 2026
  4. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    agent-note:v1

  5. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    agent-note:v1

    • task: 10112
    • state: done (triaged)
    • lane: code-h (direct)

    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:

    Ordering for the follow-ons (dependencies, not a schedule):

    1. id: design: semantic markup vocabulary v1 (from #5679) #5849 + id: design: style assertion vocabulary (from #5679) #5850 first — the markup and style vocabularies are the inputs every rendering ticket maps from; the open questions on syntax home and v1 element-set size live in id: design: semantic markup vocabulary v1 (from #5679) #5849.
    2. id: design: web rendering: assertion → Tailwind mapping (from #5679) #5851 / id: design: native rendering: assertion → OS-standard controls (from #5679) #5852 / id: design: custom GUI rendering as first-class overrides (from #5679) #5853 next, in parallel — each maps the settled vocabularies to one target class.
    3. id: design: per-target customisation system (from #5679) #5854 after the rendering tickets — override maps and asset substitution are defined against them.
    4. id: design: rendering pipeline & conformance suite (from #5679) #5855 last — the pipeline and conformance suite encode the settled mappings as tests.

    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.

  6. added
    kind/designA design proposal (design-architect): multi-step, phased, decision-bearing
    priority/normalOrdinary priority (the default)
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 5, 2026
  7. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)kind/designA design proposal (design-architect): multi-step, phased, decision-bearingpriority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions