KDCube
← Our Journal

Public content made app data discoverable; catalogs gave each content set a browsable face. This entry records the next boundary we had to draw: who owns how those pages look. The answer is a presentation contract — the platform renders the structure, the application declares the look: design tokens and its own stylesheets, straight from its config.

The forcing observation came from a design review. The catalog renderer lived in the SDK with its styling baked in, and an application could configure exactly three colors per fold. That is a recolor, and a generic platform feature deserves more: one team wants a serif editorial masthead, another wants their product's sans and a tighter column, a third replaces the row treatment entirely. All of them should get there from config, with the platform still owning everything a listing page must do correctly.

The platform owns STRUCTURE   routing, canonical URLs, sitemaps, pagination,
                              search semantics, accessibility, the HTML
                              anatomy, stable kdcpub-* class names — and a
                              neutral default theme.
The application owns LOOK     design tokens (colors, fonts, radii, widths)
                              and whole stylesheets, declared per alias in
                              its config; folds may override per catalog.
ONE RENDERER, LAYERED PRESENTATION — THE PLATFORM OWNS STRUCTURE, THE APPLICATION OWNS THE LOOK THE PLATFORM · STRUCTURE catalog renderer masthead · fold control · search article rows · pagination · empty state stable kdcpub-* classes every visual reads --kdcpub-* fixed: routes · canonicals · sitemaps search semantics · accessibility neutral default theme THE APPLICATION · LOOK (bundles.yaml) 1 · SDK default styles unbranded, var-driven 2 · design tokens presentation.theme → :root 3 · alias stylesheets fonts · brand css · loaded after 1 + 2 4 · fold overrides per-catalog tokens + stylesheets later wins THE SERVED PAGE same structure, its own look engineering teal world · serif masthead industry gold world · one accent hex item pages under a fold carry the same presentation · behavior, SEO and routes stay untouched The renderer draws the structure; every visual decision reads a token; the application's stylesheets have the last word.
The renderer draws the structure; every visual decision reads a token; the application's stylesheets have the last word.

Every visual decision is a token

The renderer's stylesheet no longer contains a single hardcoded brand decision. Everything it draws reads a --kdcpub-* CSS variable — page and surface colors, text inks, the accent family, the body font, the display font, radius, content width. The defaults form a tasteful, unbranded theme; an application overrides any of them under presentation.theme:

public_content:
  blog:
    presentation:
      theme:
        display: "'Fraunces',Georgia,serif"   # masthead / empty-state font
        ink: '#0D1E2C'
        width: 1180px

Tokens merge in a fixed order, later wins:

SDK defaults  ←  alias presentation.theme
              ←  fold accent/background/border shorthands
              ←  fold presentation.theme

The three per-fold color shorthands that existed before are unchanged — they are simply token writes now. And when an override changes accent alone, the derived values (accent_rgb for transparent tints, accent_dark for hovers) follow automatically, so one hex still recolors a whole fold coherently.

Token values are sanitized at config resolution: a value that could escape a style block fails the alias configuration outright. A page is never served half-styled.

Stylesheets load after the platform's

Tokens cannot load a webfont or restructure a component. For that, the application declares stylesheet URLs — its own public assets — and the platform emits them after its own styles and the token block:

1. <style>  SDK structural styles (all var-driven)
2. <style>  :root { --kdcpub-* }  resolved tokens
3. <link>   alias presentation.stylesheets, in declared order
4. <link>   fold presentation.stylesheets, appended

The application's CSS therefore wins the cascade at equal specificity, and the namespaced kdcpub-* classes are the stable selector contract — masthead, fold control, search, rows, pagination, empty state, chrome, rail. Item pages under a catalog carry the same presentation automatically.

One rule keeps configs honest: a stylesheet is an asset with a URL. The config carries intent — tokens and links — never CSS bodies.

public_content:
  blog:
    presentation:
      stylesheets:
        - https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600&display=swap
        - /assets/pub-brand.css
      theme:
        display: "'Fraunces',Georgia,serif"

The worked case: our own catalogs

The first consumer is the surface you may be reading right now. Our site's landing page moved to an editorial language — compact masthead, segmented controls, full-width hairline-divided article rows, restrained teal on pale mint. The catalog renderer's default structure was redesigned to that editorial system, while its defaults stayed neutral — the serif display stack in the SDK is plain Georgia.

The KDCube look is then just our own presentation block: the blog and news aliases load Fraunces via a stylesheet URL and set one display token. Five folds keep their distinct color worlds (navy, teal, gold, blue, pink) through the same shorthands as before; empty folds get a deliberate centered empty state; search and pagination stay quiet and fold-scoped.

Field notes

  • Do the boundary before the beauty. The original task was "make the catalogs match the landing page". Doing that directly would have baked one brand into a generic renderer and made the next application's restyle a code change. Settling ownership first turned the redesign into the default theme of a contract.
  • Neutral defaults, branded config. The platform's out-of-the-box look must be presentable and unbranded; anything with a brand name in it — a webfont, a palette — belongs in the application's presentation block.
  • Presentation is paint. Nothing in the contract can change routes, canonicals, sitemap output, search semantics, or pagination behavior — and the public header stays anonymous: it renders the links the config declares and carries no identity scripts.
  • Derived values need an escape hatch. Deriving tints from the accent is right for the common case, but both derived tokens accept explicit overrides for the palette that breaks the darkening heuristic.
  • Full replacement is a later chapter. The token + stylesheet surface covers restyling. Replacing the page layout wholesale would be a renderer protocol — designed, documented as out of scope, deliberately not improvised through CSS.
KDCube Journal · 14.07.2026