Editing a design
Colors, foundation anchors, palettes and modes, fonts, preview pages and click-to-edit.
On this page
Everything you can change in Systhema Design: the sidebar's six sections, the preview pages you check them on, and the inline click-to-edit panel.
What you can editLink to this section
The sidebar is an accordion of six sections, in order: Colors · Typography · Layout · Logo · Favicon · SEO. The accordion is multiple-open — you can expand several sections at once, and each section's header stays sticky as you scroll its body. On a first visit (no saved session yet) every section starts collapsed; which sections you have open, along with sidebar collapsed/expanded, device, view, color system, sidebar width, and editor theme, is remembered in your browser on refresh (color system falls back to Default when that mode is hidden or removed). Each collapsed section shows a one-line summary that reflects your current token and font values — not a static placeholder — so you can read the state of a section at a glance without expanding it.
| Section | What you control |
|---|---|
| Colors | A compact Hex / RGBA / OKLCH toggle sits above the three token tiers: Primitives · Foundations · Components. Primitive palettes are generated from a seed and expose a clickable semantic foundation anchor on each ramp stop; moving it shifts connected foundation references while detached raw values stay fixed (see Foundation anchors). Foundations are semantic tokens per color-system mode, edited through reference-aware fields with re-point, detach, re-link, and reset actions plus advisory APCA contrast hints. Components reference foundations and therefore inherit primitive and foundation changes automatically. Palette and mode rows support expand/collapse, duplicate, rename, reorder, and remove/hide; clicking a mode row selects it for the live preview. |
| Typography | A Figma-style per-style editor. The editing-breakpoint switcher (LG/MD/SM) sits at the top, followed by an always-visible Fonts block — stacked Heading and Body Fontsource comboboxes, plus Search / Upload text-link toggles for custom upload — see below. Next, an always-visible Scale block — base size, named or custom scale ratio (native select + ↺ reset in the same input-group shell; custom exposes a range slider plus a precise number field), line-height curve, and letter-spacing multiplier — each numeric control uses the layout-style [ value | reset ] group. Below that, every text style — h1–h6, body, lead, label, small, plus the Form variants — is a collapsible row with the full set of controls: Family · Weight · Size · Line height · Letter spacing, plus Text decoration (none / underline / line-through) and Text transform (none / uppercase / lowercase / capitalize). Family, Weight, Size, Line height, and Tracking each have their own link / detach control (the same model as colors): when linked, the property shows a read-only value inside a single bordered input group with a lock icon flush on the right (click to unlock and override); when detached, the editable control (number field, family combobox, or a weight select populated from the resolved font's available weights) shares that same group shell with an unlock icon on the right (click to lock back to the live source). Linked values follow their source live (Heading/Body font foundation for family/weight; modular scale for heading metrics; project defaults for body and form metrics). Detach snapshots the current value into a literal override you can edit; re-link drops the override and restores the live source. Heading sizes follow the modular scale by default until individually detached. Body and Form metrics default from the project's token export (Form variants reference body sizing) and can be overridden one property at a time per breakpoint. The heading ladder recomputes live in the preview (see the Typography preview page). |
| Layout | The editing-breakpoint switcher (LG/MD/SM) plus the core spatial knobs — grid gap, container margin, section padding-y, and the article & feature controls. Each numeric knob is a single bordered input group: the value field on the left and a reset icon (↺) flush on the right (disabled when the value matches the default). The screen-sizes, breakpoint-pixel, and spacing-function editors are gone: those values are derived from these knobs. |
| Logo | Header and footer logo slots with SVGO optimize on SVG upload (only the logo re-skins the live preview). When the opposite slot already has a logo, a Same as header / Same as footer link copies it into the active slot. |
| Favicon | App-icon source upload (SVG, PNG, or JPG) with a selected-file summary row (name · format · dimensions · size, with a ✕ to clear), an optional dark-mode variant (used by dark-scheme browsers — two SVG sources combine into one prefers-color-scheme SVG icon; raster sources ship as a light/dark <link> pair), an optional background with margins and corner radius — the radius only applies when a background is set, and never to the iOS mockup (iOS applies its own fixed mask; the exported apple-icon.png ships unrounded and opaque) — multi-context mockups, the generated icon-set file list, and a copy-pasteable favicon.meta.html head snippet (export only — no live preview re-skin). The exported set follows RealFaviconGenerator's lean shape — favicon.ico (16/32/48), an SVG favicon for SVG sources, favicon-96x96.png, a 180px apple-icon.png, and a site.webmanifest listing both plain (any) and safe-zone-padded (maskable) 192/512 PWA icons so Android's adaptive mask never clips the artwork — plus a machine-readable faviconDescription.json. The manifest name is taken from your SEO site name (then title). An optional dark theme color emits a prefers-color-scheme media pair of <meta name="theme-color"> tags. (Following RFG's own "less is more" baseline, the obsolete Safari pinned-tab mask-icon and Windows browserconfig.xml tiles are intentionally omitted.) |
| SEO | Title, description, URL (→ canonical / og:url + the preview domain), site name, og:title/og:description, an OG image with inline ratio + file-size checks and an og:image:alt, and twitter:card — with live social-preview cards (Facebook · X · LinkedIn · Pinterest · Discord · Slack · Google), character-count linting, and a "Get Code" output (<meta> HTML + Next metadata). |
Color referencesLink to this section
The Foundations and Components tabs share a Figma-style value field: a token's value is either a raw hex or a reference to another token. Each field is a single bordered input group — [ swatch | value | graph? | lock | reset ] — matching typography and layout controls. Foundation fields add one independent graph icon: Workflow means Auto and follows palette-anchor changes; Unplug means Manual and keeps the assignment fixed. When linked, the value shows the reference target (click to re-point via a floating reference-picker popover, grouped by tier); lock unlocks to a raw hex you can edit; reset (↺) reverts the leaf and graph relation to default (disabled when unchanged). When detached, the swatch and editable hex share the group with an unlock icon to link to a token. The picker opens with a search field at the top — type to filter by label, token path, or hex value (case-insensitive; empty search shows every group). Because references resolve through your edits, changing a primitive cascades live to every foundation and component that points at it, instantly in the preview. Exports preserve the link: a referenced token is emitted as a DTCG {…} alias string in the Figma-tokens export and in the customTokens config — never flattened to a hex.
Under the hood the editor materializes the default color graph plus your diff and resolves references through it (tokenGraph / resolveGraph / colorGraphLive in @systhemaui/core/design); a reference leaf in the diff is { $ref: '<path>' }, which the preview emits as a CSS var(--…) link.
Foundation anchorsLink to this section
Each primitive ramp has one semantic foundation anchor, shown by a checkmark on its color chip. Click another chip to make that stop the palette's main value. The editor shifts every Auto foundation connected to that palette by the same number of ramp positions, preserving each token's relative offset. Literal alpha colors that exactly match a primitive stop are inferred as raw followers and move until edited or marked Manual; other raw values and references to different palettes stay fixed. Component tokens continue to follow through their foundation references.
The baseline graph model is derived from the loaded default tokens rather than a fixed list of stops or mode names. For every primitive palette, the editor infers the semantic anchor from its foundation aliases; it also infers which palette controls background polarity, which shipped modes are the light and dark templates, every foundation's relative offset, and raw alpha colors that exactly follow a primitive stop. Replacing the app's default token set therefore replaces the anchor and light/dark graph logic automatically. With the current defaults this resolves to theme.600, light-mode base.0, and the default / dark templates.
The polarity ramp includes the 0 and 1000 bookends in the editor. Its shifts preserve immutable mode polarity: light-derived modes move toward darker stops, while dark-derived modes mirror the same distance toward lighter stops. Duplicating or renaming a mode carries that polarity with it, so crossing the ramp midpoint never reverses later edits. For example, with the current defaults, moving the base anchor from 0 to 100 changes a connected light surface-bg from base.50 to base.200, while a connected dark surface-bg moves from base.900 to base.700. Stops clamp at the ends of the ramp.
Anchor selection and mode polarity persist in the editor overlay and in config, project, agent, and Figma DTCG exports. New DTCG archives carry explicit Systhema Design metadata so unused or fully detached palettes retain their anchor; older archives fall back to reconstructing it from shifted aliases. Duplicate and rename operations carry the selection to the new palette key, while removing a palette removes its anchor metadata.
A palette seed lands exactly on the stop it classifies to, and seeding makes that stop the anchor. The seed field reads the seed back from the anchor stop, so it survives a reload and every export that carries the anchor, including a systhema.config.ts round trip. When the anchor stop no longer holds a value that classifies to it (a hand-edited stop), the field shows the 500 stop instead.
Managing palettes & color-system modesLink to this section
The three tiers aren't fixed to what Systhema ships — you can grow both the palette set and the mode set from inside the Colors editor.
- Primitive palettes. Beyond the shipped
themeandbase, the Primitives tab lets you add a palette (give it a name and a seed color — an 11-stop ramp is generated from the seed, the same waytheme/baseare), duplicate an existing palette, rename, reorder (drag the grip handle before each palette title — order persists and flows through Figma DTCG + project-zip exports), and remove author-added palettes.themeandbaseare required graph roots: they intentionally have no remove action and can only be renamed, duplicated, reordered, or reset. Each palette is a compact collapsible ramp editor with Expand all / Collapse all above the list; all start collapsed. Added palettes export everywhere — acolorPrimitives.primitives.<key>group in thecustomTokensconfig and a synthesizedprimitives.<key>node in the Figma DTCG bundle; a rename liketheme→apprewrites the palette toappand re-points every reference in all exported files, with no orphantheme. - colorSystem modes. The Foundations tab lists every visible mode as a collapsible panel. The canonical
defaultslot is fixed first and exposes only duplicate and reset actions: it cannot be dragged, renamed, or removed. Every other row has a drag grip and can be renamed, reordered belowdefault, duplicated, or removed. Its star action makes that mode the default by atomically swapping its complete color subtree, foundation graph relations, and polarity into thedefaultslot; the previous default is preserved in the chosen mode's former slot, directly afterdefault. One undo restores the entire swap. Opening a panel shows that mode's foundation color fields inside; you can edit any mode without switching the preview first. Click the label row to select the mode for the live preview (ui.previewTheme) — expanding is not required. The Components tab reuses the same compact mode rows (without chevrons) as a flat switcher; component token groups below target the selected mode only. You can also add a mode seeded from an existing one. The secondary bar's Color system selector lists these same live modes in export order. Added modes export everywhere — a new[data-theme="<mode>"]CSS block, acolorSystem.<mode>entry in thecustomTokensconfig, and a newcolorSystem.<mode>.tokens.jsonfile plus manifest mode in the Figma DTCG bundle. - Palettes and modes are shown by their token key. There are no friendly aliases — what you see (
theme,base,default,dark, or a key you choose) is exactly what the exported tokens use. - Rename rewrites the token key. Renaming a palette or a non-default mode is a real key change: the renamed palette's ramp is rewritten under the new key and every reference pointing at it is re-pointed to follow (so nothing dangles); renaming a mode moves its whole foundations/components subtree under the new key. The new key shows everywhere the palette or mode appears — the ramp header, the reference-picker groups, the mode manager rows, and the preview's color-system selector — and flows through to your exported
customTokens. - Protected roots. The required
themeandbasepalettes cannot be removed from the editor; renaming one still hides only its now-unreferenced old key as part of that key rewrite. ThedefaultcolorSystem slot is likewise structural and cannot be moved, renamed, or removed.darkand author-added modes remain removable; deleting a referenced palette or populated mode warns first, with a count of what will be affected. - ⚠️ On a PayloadCMS project, a mode key is stored content. Palettes are safe to rename freely, but a
colorSystemmode key (and alayout.bgslot key) is also the value your pages, posts, archives and themed blocks have saved in the database as their chosen theme. Renaming or removing one leaves that content pointing at a mode that no longer exists — and on Postgres the project's next schema push fails, because those fields are enum columns. Migrate the stored values before applying the design: see Database migrations → Renaming a stored design key. Adding, duplicating and reordering modes are unaffected.
FontsLink to this section
Fonts are chosen inside the Typography section's always-visible Fonts block. Heading and Body each have their own searchable Fontsource combobox in Search mode (mirrors Google Fonts and more) with live preview lines in the dropdown; variable fonts appear like any other family. Upload mode shows a separate drag-drop field per role; each converts TTF/OTF to woff2 entirely in the browser. Dropping a TTF/OTF onto either combobox auto-switches to Upload for that role. Picking a font loads it before the token updates, so the preview never flashes a fallback. Per-style Family and Weight reference these foundations by default (each property links and detaches independently), so changing the Heading or Body font cascades to every style property that's still linked.
Below the built-in Heading, Body, and Form roles, the Custom section creates author-defined text styles. Duplicate any existing row to snapshot its current family, weight, responsive size, line height, letter spacing, decoration, and transform, then name and edit the independent copy; Add custom style starts from the same raw values as Body. A style named Display Hero exports as a full textStyles['Display Hero'] composite connected to its own font and responsive-sizing variables, generates .text-display-hero, and appears automatically in the Typography preview. Removing it deletes the composite and its owned variables as one undoable transaction.
Preview pagesLink to this section
The preview renders one of five example pages, all built from real @systhemaui/next components on Systhema's default tokens, with realistic photography. Every page re-skins live as you edit.
| Page | What it shows |
|---|---|
| Landing | A full communications-studio marketing page (a faithful pure-TSX recreation of the Systhema demo site's default home page) — hero, an all-in-one services grid of icon cards, alternating feature splits, a portfolio gallery, an FAQ, and a get-in-touch close over an advanced footer. The broadest proof of a design's tone. |
| Typography | A role-labeled type specimen: Label, Heading H1–H6, Lead, Body, Small, and every author-created custom text style, each set in long copy that wraps multiple lines so line-heights and the heading ladder read clearly. |
| Components | A single-component explorer — pick a component from the secondary bar's Component picker and see it rendered alone, centered, with representative sample data and its variants. |
| Blog post | A single article: hero, cover image, and a rich-text body with headings, prose, inline links, an image, a blockquote, a video embed, and a button. |
| Blog archive | A listing page: page header, a filter bar (search, tag/category selects, active-filter chips), a three-column post-card grid, and a "Load more" button. |
The pages compose real @systhemaui/next components wrapped in <Article> and vary surfaces with layoutBackground only — they never set a theme/colorSystem/data-theme on an individual section, card, or hero. The color system is applied once at the preview root by the secondary bar's Color system selector, so a single switch re-skins the whole page consistently. Heroes use the dedicated Hero APIs (HeroSimple / HeroBackground / HeroFeature) for the page hero, never a Feature standing in as one.
Click-to-editLink to this section
Click-to-edit is always on. Hovering the preview highlights the element under the cursor and labels which tokens govern it; clicking opens a small scoped panel anchored to that element. Because the preview is a same-origin iframe, the overlay attaches its listeners to the iframe's document the moment it is live — wiring up on the systhema-preview-ready handshake the preview posts on mount (with a bounded retry as a fallback) — and it identifies preview nodes with a realm-safe element check rather than instanceof Element, which is always false across the iframe boundary. That combination is what makes clicking any preview element reliably open its scoped editor while preview links and buttons never navigate.
The panel is a real inline editor, scoped to exactly the tokens that govern the clicked element — the same reference-aware fields and number rows the sidebar uses, so edits re-skin the preview immediately and show up in the sidebar and in every export:
- Text (headings, body, lead, label, small, and author-created custom styles) — the full style grid: font family and weight, size, line height, tracking, and text decoration/transform. Built-in roles also expose their shared text-color token; custom styles edit their own generated font and responsive variables without inventing a color token they do not own. Clicking one specimen edits every use of that token-backed style.
- Buttons and cards — their component-tier color leaves (background, text/content, border) and their sizing variables (font size, paddings, radius).
- Sections — the layout background that section actually renders (main vs alternative, read off the element) plus section padding-Y, container margin, and article padding-X.
- Header & footer logos — see the slot's current logo, drop in a replacement (same SVGO/PNG pipeline as the sidebar Logo editor), or clear it, right in the popover.
- Navigation items and the open menu panel — their header token colors.
Header chips make the scope visible at a glance: sizing edits apply to the current editing breakpoint (shown as the matching device icon — desktop/tablet/mobile), and color edits apply to the color system you're currently previewing (shown by name). The sidebar accordion remains the deep path for advanced controls (full SVGO, palette management, and so on).
Real-time editingLink to this section
Every control commits live: numeric fields update the preview on each keystroke and on each arrow-key step, color and font pickers re-skin as you change them, and the heading ladder recomputes as you tune the scale. Text decoration and transform — once baked into each .text-<role> class at build time — are now editable and re-skin the preview live (the override sheet emits a matching .text-<role> rule). Number fields step Figma-style: pixel values use ↑/↓ for 1, Shift for 10, and Alt/⌥ for 0.1; tracking and Custom ratio use 0.1, 1, and 0.01 respectively.
Sidebar input groups (color value fields and reference-picker search, typography fonts/scale/style rows, palette/mode add forms, layout numeric knobs) share one shell: InputGroup / InputGroupField / InputGroupButton / InputGroupSelect in components/controls/, styled with Systhema form block tokens (--color-form-input-block-*, --form-input-block-*) via shell-theme.css. The outer box owns the border, focus ring, and overflow-hidden; inner swatches, text/number fields, native selects, comboboxes, and icon buttons stay borderless so corners don't bleed. shell-theme.css also tightens editor density — 28px row height (h-7), 8px horizontal padding (px-2), 12px/16px form-block typography (text-xs), and 28px icon segments (w-7) — by overriding --form-input-block-padding-* and --typography-form-block-* for the chrome only.