From d549f09601a84fae0726235a7fd4714c7c9673ba Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 5 Sep 2026 17:25:04 +0200 Subject: [PATCH 01/38] Design system iteration --- AGENTS.md | 5 + DESIGN_SYSTEM.md | 148 ++++++++++++++++++++++++++ src/routes/design-system/+page.svelte | 77 ++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 DESIGN_SYSTEM.md create mode 100644 src/routes/design-system/+page.svelte diff --git a/AGENTS.md b/AGENTS.md index 511d8d69..802e6b93 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,11 @@ Repository-specific guidance for coding agents working on Svedit. - Use `snake_case` for project-defined JavaScript and TypeScript identifiers. Keep web platform and Svelte APIs in their native `camelCase` form. - Prefer Tailwind classes and minimize custom CSS. For CSS custom properties, use Tailwind's arbitrary-value utilities, such as `text-(--editing)` and `border-(--editing)`, where applicable. +## UI verification + +- The user manually verifies UI changes. Do not use a browser, screenshots, or computer-use tools to verify the UI unless the user explicitly asks. +- Use appropriate code checks, such as formatting, linting, and Svelte diagnostics, without starting a browser-based verification workflow. + ## Architecture Svedit is a Svelte 5 rich content editor built around a graph-based document model. diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md new file mode 100644 index 00000000..cfc026b5 --- /dev/null +++ b/DESIGN_SYSTEM.md @@ -0,0 +1,148 @@ +# Editable design system + +Status: proposal for review. The first implementation milestone is text-only buttons. This document plans the work; it does not establish approved visual recipes yet. + +## Intent + +Editable should provide a beautiful generic foundation for many different websites. A user should be able to change only the colors and fonts in `src/app.css` and still get a coherent design. Its identity should come from typography, proportion, spacing, and clarity. + +- Use plain Tailwind utilities for visual recipes. +- Keep the visual language simple: flat fills, restrained shapes, clear hierarchy, and generous but purposeful spacing. +- Avoid decorative strokes, gradients, drop shadows, ornamental elements, and effects that depend on a particular background color. Functional boundaries, link underlines, and focus outlines are appropriate when they communicate something. +- Make colors and fonts interchangeable without requiring layout changes or font-specific pixel offsets. +- Prefer a small, deliberate set of variants over a large collection of barely different choices. +- Treat “perfect generic” as a quality goal to validate across themes, fonts, content, and input methods. + +## Where decisions live + +| Location | Responsibility | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `src/app.css` | Shared color and font tokens, and any approved global design primitives. | +| `/design-system`, implemented in `src/routes/design-system/+page.svelte` | Canonical rendered examples and their exact Tailwind markup. The source of truth for visual variants. | +| `DESIGN_SYSTEM.md` | Principles, rationale, implementation plan, and outstanding decisions. Link to approved recipes rather than maintaining a second copy here. | +| Application components | Semantics, behavior, editor integration, and composition, using the canonical visual recipes. | +| `AGENTS.md` | A short instruction directing agents to consult the design system before implementing or changing UI. | + +The reference page should contain ordinary HTML elements with literal Tailwind classes. Do not render application components, import button components, hide recipes behind class builders, or add a component API. Native hover, focus, active, and disabled styling belongs in the examples; application behavior does not. + +Each recipe needs a stable section anchor, a name, its intended use, a rendered example, and inspectable markup. If the page also displays code, keep it synchronized with the rendered example rather than maintaining two independent recipes. Supporting page organization must not obscure the actual HTML and classes. + +The page should work without a backend or editor session, including static deployments. Check routing, prerendering, and the root layout when adding it. Reserve `/design-system` explicitly because content currently uses a dynamic `[page_id]` route. + +## Current starting point + +- `src/app.css` already defines `--background`, `--foreground`, `--muted`, `--stroke`, `--muted-foreground`, `--accent`, and `--accent-foreground`, plus font families and `--button-border-radius`. +- Editing controls have their own `--editing` token family. Website buttons should use website tokens; decide the editor treatment separately. +- `Button.svelte` currently has primary, secondary, and link layouts. `NavButton.svelte` has primary and secondary layouts with different sizing. Other controls also define their own button styles. +- There is no dedicated `/design-system` route in the repository yet. +- Existing typography utilities and shadow tokens are historical starting points, not automatic approval for new recipes. Review them incrementally when their category is addressed. + +## Proportion and spacing + +Use the supplied LiftKit screenshots as references for two ideas: spacing should express relationships, and internal spacing should relate to typography. Closely related content gets smaller gaps; distinct groups get larger gaps. + +The screenshots show a scale of approximately `0.236`, `0.382`, `0.618`, `1`, `1.618`, `2.618`, and `4.236`, based on the golden ratio. They also show a button construction relating padding to text size. These are candidate design heuristics, not evidence that one ratio produces universally optimal interfaces. The cropped button diagram is insufficient to specify a complete CSS recipe, especially across different font metrics. + +For the first comparison: + +- Start with Tailwind's existing spacing steps; avoid introducing a second global spacing system before we have compared results. +- Compare one text-relative button candidate inspired by LiftKit against the simpler Tailwind baseline below. Keep font, color, and label identical so we can judge proportion. +- Use `rem` for page rhythm and minimum control dimensions; consider `em` for internal padding that should track label size. State the unit explicitly rather than treating them as interchangeable. +- Judge the space around visible letterforms, as well as the CSS line box. Allow enough line height for accents and different scripts; avoid per-font transforms or negative margins. +- Document the chosen values and their intended relationships after visual review. Consistency and usability take priority over mathematical purity. + +## First milestone: text-only buttons + +### Visual family + +Start with two core variants and review a third, quiet treatment alongside them: + +| Variant | Purpose | Proposed treatment | +| --------- | -------------------------------- | --------------------------------------------------------------------------------------------------------- | +| Primary | The main action in a local group | Solid `--accent` fill with `--accent-foreground` text. | +| Secondary | A supporting action | Transparent fill, `--foreground` text, and a functional thin boundary derived from the theme. | +| Quiet | A low-emphasis action | Transparent fill and `--foreground` text; use spacing and state treatment to make it usable as a control. | + +Primary and secondary should share typography, geometry, and padding. Hierarchy comes from treatment rather than making secondary buttons smaller. A quiet control should retain the same target geometry when placed beside them. + +The existing `link` layout needs an explicit decision: retain it as a separate underlined navigation treatment, or migrate it later. Do not silently reinterpret stored `link` layouts as quiet buttons. HTML semantics remain independent of appearance: actions use buttons; navigation uses anchors. + +Icons, icon-only buttons, loading indicators, split buttons, toggles, and destructive variants are outside this first milestone. + +### Initial geometry to compare + +These are proposed starting values, not approved recipes or research-derived constants. Pixel equivalents assume a 16px root font size. + +| Property | Starting proposal | Reason | +| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------ | +| Label | `font-sans`, `text-base`, `font-medium`, `leading-normal` | Readable text with room for varied font metrics. | +| Minimum dimensions | `min-h-11 min-w-11` (44px) | A generous baseline target that can grow with content. | +| Padding | `px-5 py-2.5` (20px / 10px) | A simple 2:1 horizontal-to-vertical starting proportion. | +| Shape | `rounded-(--button-border-radius)` | Reuse the existing token; review its current pill-like result. | +| Alignment | Inline flex, centered label, centered text | Natural content width and stable alignment. | +| Boundary | Reserve the same border width across filled and outlined variants | Avoid geometry changes between variants or states. | +| Group gap | `gap-3` (12px), wrapping when necessary | Separate targets without making related actions feel disconnected. | + +Minimum height is a floor, not an exact height. The proposed line height, padding, and border will normally produce a taller button. Compare that rendered result before choosing final values. + +Start with one default size. Add a compact navigation size or a larger call-to-action size only after demonstrating a real need. Size variants should form one family, rather than independent designs. + +Labels should use sentence case, preserve their full meaning, and size the button naturally. Test short and long labels. Permit wrapping when space is constrained, with height growing naturally; do not clip or ellipsize action text. Button groups can wrap or stack. Full-width layout is a composition choice, not a separate visual variant. + +### Theme and state rules + +- Resolve all colors through `app.css` tokens. No hardcoded white text, black overlays, or assumptions that the page is light. +- Treat theme colors as semantic pairs. Arbitrary color choices cannot guarantee readable contrast; validate the actual pairs and correct the theme when needed. +- Use an explicit focus outline with sufficient offset and contrast against the surrounding surface. Do not rely on a drop shadow for focus. Propose a website focus token only if the existing website tokens cannot express the requirement cleanly. +- Show default, hover, active, keyboard focus, and disabled states for each approved variant. Include focused-and-hovered examples so one state cannot hide another. +- Prefer flat color changes for hover and active. Avoid moving or scaling the button, changing border width, or reducing the opacity of the entire enabled control. Validate any token-derived color mixes before adopting them. +- Disabled controls must look distinct, retain legible labels as a design goal, and suppress enabled hover/active styling. Use native `disabled` for button specimens; disabled link behavior belongs to a later component decision. +- Start without animation. If transitions improve the result, keep them brief and limited to colors, with reduced-motion preferences respected. + +### Accessibility constraints + +Use accessibility standards as concrete constraints alongside visual judgment: + +- Normal-size labels need at least 4.5:1 text contrast in enabled states. See [WCAG text contrast](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html). +- Visual information needed to identify a control or state needs 3:1 contrast against adjacent colors. Not every decorative boundary is subject to this requirement; evaluate the information the button depends on. See [WCAG non-text contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html). +- WCAG 2.2 AA uses a 24 by 24 CSS pixel target minimum with exceptions. We propose a more generous 44 by 44 baseline, consistent with the enhanced AAA target criterion. Check the actual clickable shape, especially for short labels and rounded corners. See [minimum target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum) and [enhanced target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size-enhanced.html). +- Verify keyboard focus visibility, text enlargement, narrow-screen reflow, and forced-colors mode in the browser. Avoid fixed heights and outline removal that prevent these from working. + +These requirements constrain the design; they do not determine the aesthetically best padding, radius, or font weight. + +### Review specimens + +The button section should show the actual recipes across: + +- Primary, secondary, and the proposed quiet treatment, with all listed states. +- Light, dark, and chromatic themes using scoped overrides of the same tokens; examples on both background and muted surfaces. +- The default font plus a serif and a monospace substitution in the button font role, including fallback-font rendering. Theme and font comparisons must use identical recipe classes. +- Labels such as “OK”, “Save changes”, “Continue to checkout”, and accented or non-Latin text. +- Single buttons, paired actions, and wrapping groups at narrow widths, with enlarged text. + +Use static labeled specimens for inspecting states and real native elements for keyboard and pointer checks. Keep theme previews local to the reference page rather than introducing production theme-switching behavior. + +## Implementation sequence + +1. Review this proposal, particularly the variant set, baseline proportions, and corner shape. +2. Build `/design-system` with the button comparison specimens in plain Tailwind. Keep candidate recipes clearly marked until selected. +3. Review in-browser across the theme, font, content, and accessibility cases above. Choose one baseline and remove rejected candidates from the canonical recipe section. +4. Record the selected rationale here and add a concise lookup instruction to `AGENTS.md`: consult the page and its source before styling UI; add missing variants there first; update the recipe and affected consumers together. +5. Apply approved recipes to `Button.svelte` and `NavButton.svelte`, preserving document layouts, navigation semantics, and editor behavior. Update relevant README guidance when the customization workflow changes. +6. Expand category by category: typography and spacing, links, form controls, then recurring layout patterns. Address editor controls explicitly when their turn comes. + +## Keeping the source of truth useful + +Every new visual variant should have a concrete use case and a canonical example before application code adopts it. Components may differ in structure and behavior, but should not invent new padding, colors, radii, or state treatments for an existing variant. + +Literal Tailwind markup in the reference page means consumers will repeat classes. Accept that tradeoff for direct inspectability; prevent drift through review and by updating affected consumers with each recipe change. Do not introduce a shared button component merely to render the reference page. + +For each milestone, verify only what changed: visually inspect the relevant specimens, check native interactions and responsive behavior, and run the repository checks appropriate to implementation. A documentation-only proposal does not need application tests. + +## Decisions for the first review + +- Approve primary and secondary as the core family, with quiet as a candidate? +- Keep the current pill-like corner shape, or compare it with a softly rounded shape before choosing one default? +- Begin with the proposed default geometry and a single LiftKit-inspired comparison, then add sizes only when a use case requires them? + +All values above remain proposals until that visual review. The immediate deliverable is this plan; implementation follows as the next step. diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte new file mode 100644 index 00000000..0f8c6e72 --- /dev/null +++ b/src/routes/design-system/+page.svelte @@ -0,0 +1,77 @@ + + Design system · Editable + + + + +
+
+
+

Design system

+

+ A shared starting point for Editable. Simple styles, ready to use and adapt. +

+
+ +
+
+

Buttons

+

+ Standard size. Hover, press, or tab to explore the states. +

+
+ + +
+
+

Primary

+ + +
+ +
+

Secondary

+ + +
+ + +
+
+
+
From 7fa38f9ac38d872cfb4cbe735e958ae8dac54a5a Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 5 Sep 2026 17:47:44 +0200 Subject: [PATCH 02/38] Finalize buttons and add typography --- src/app.css | 38 +++---- src/routes/design-system/+page.svelte | 138 +++++++++++++++++++++++++- 2 files changed, 153 insertions(+), 23 deletions(-) diff --git a/src/app.css b/src/app.css index af57cd5a..4bd41e81 100644 --- a/src/app.css +++ b/src/app.css @@ -76,49 +76,51 @@ /* Typography system */ /******************************************************************/ -/* E.g. Heading1XL */ +/* Large display headings use medium weight; smaller headings use semibold. */ +/* Heading1XL */ @utility display-1 { - @apply font-sans text-6xl leading-tight tracking-tight text-balance lg:text-7xl; + @apply font-sans text-6xl leading-tight font-medium tracking-tight text-balance lg:text-7xl; } -/* E.g. Heading1 */ +/* Heading1 */ @utility display-2 { - @apply font-sans text-5xl leading-tight tracking-tight text-balance lg:text-6xl; + @apply font-sans text-5xl leading-tight font-medium tracking-tight text-balance lg:text-6xl; } -/* E.g. Heading2 */ +/* Heading2 */ @utility display-3 { - @apply font-sans text-4xl leading-tight tracking-tight text-balance lg:text-5xl; + @apply font-sans text-4xl leading-tight font-medium tracking-tight text-balance lg:text-5xl; } -/* E.g. Heading3 */ +/* Heading3 */ @utility display-4 { - @apply font-sans text-3xl leading-tight tracking-tight text-balance lg:text-4xl; + @apply font-sans text-3xl leading-tight font-semibold tracking-tight text-balance lg:text-4xl; } -/* E.g. Heading4, TitleGallery.title, ... */ +/* Heading4 and gallery titles */ @utility display-5 { - @apply font-sans text-2xl leading-tight tracking-tight text-balance lg:text-3xl; + @apply font-sans text-2xl leading-tight font-semibold tracking-tight text-balance lg:text-3xl; } -/* ParagraphSM, ListingItem.description, ... */ +/* Body text uses regular weight and a consistent 1.5 line height. */ +/* Small paragraphs and listing descriptions */ @utility body-sm { - @apply font-sans text-sm; + @apply font-sans text-sm leading-normal font-normal; } -/* Paragraph, ... */ +/* Standard paragraphs */ @utility body-base { - @apply font-sans text-base; + @apply font-sans text-base leading-normal font-normal; } -/* ParagraphLG, ... */ +/* Large paragraphs */ @utility body-lg { - @apply font-sans text-lg; + @apply font-sans text-lg leading-normal font-normal; } -/* ParagraphXL, ... */ +/* Introductory paragraphs */ @utility body-xl { - @apply font-sans text-xl lg:text-2xl; + @apply font-sans text-xl leading-normal font-normal lg:text-2xl; } /* EW-specific utils */ diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index 0f8c6e72..05d68c4a 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -17,6 +17,84 @@

+
+
+

Typography

+

+ A shared scale for headings and body text. +

+
+ + +
+
+

display-1

+

Make room for what matters.

+
+
+

display-2

+

Make room for what matters.

+
+
+

display-3

+

Make room for what matters.

+
+
+

display-4

+

Make room for what matters.

+
+
+

display-5

+

Make room for what matters.

+
+
+ + +
+
+

body-xl

+

+ Good design makes everyday things easier to understand. Clear words, comfortable + spacing, and a thoughtful hierarchy help people find what they need and decide what to + do next. +

+
+
+

body-lg

+

+ Good design makes everyday things easier to understand. Clear words, comfortable + spacing, and a thoughtful hierarchy help people find what they need and decide what to + do next. +

+
+
+

body-base

+

+ Good design makes everyday things easier to understand. Clear words, comfortable + spacing, and a thoughtful hierarchy help people find what they need and decide what to + do next. +

+
+
+

body-sm

+

+ Good design makes everyday things easier to understand. Clear words, comfortable + spacing, and a thoughtful hierarchy help people find what they need and decide what to + do next. +

+
+
+
+

Buttons

@@ -34,10 +112,10 @@

Primary

- + @@ -45,10 +123,10 @@

Secondary

- + @@ -66,7 +144,57 @@ --> + Continue + +
+
+
+ +
+
+

Small buttons

+

+ For navigation and compact layouts. +

+
+ + +
+
+

Primary

+ + +
+ +
+

Secondary

+ + +
+ +
+
+
+

Editor pills

+

+ Compact surfaces for tools, actions, and previews. +

+
+ +
+
+

Toolbar

+
+ +
+
+
+

Inline call to action

+ +
+ +
+
+
+

Variant selector and select parent

+ +
+ +
+
+ +
+
From a0267d54576ad1ae9c19965e24625147fdcf83c6 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 5 Sep 2026 21:39:10 +0200 Subject: [PATCH 04/38] Add formatting styles to the design system --- AGENTS.md | 2 + src/routes/design-system/+page.svelte | 81 +++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 957a8e7b..bcd2f445 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,6 +23,8 @@ Repository-specific guidance for coding agents working on Svedit. ## Design system +- Inline formatting styles (emphasis, strong, link, code, and highlight) are mutually exclusive. Never nest them or apply multiple styles to the same text. + - Consult `src/routes/design-system/+page.svelte` before styling UI. It is the visual reference for typography, buttons, and editor pills; shared tokens and typography utilities live in `src/app.css`. - Keep reference examples as explicit HTML, SVG, and Tailwind classes. Repetition is intentional; application components own behavior and may adapt the recipes when their interaction requires it. - Document new visual patterns in the reference page so future changes have a concrete example to follow. diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index 08b0e54a..d4677c0a 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -95,6 +95,87 @@ +
+
+

Inline formatting

+

+ Emphasis and detail within the flow of a sentence. +

+
+ + +
+
+

Emphasis · em

+ +

+ Start with what people actually need. +

+
+ +
+

Bold · strong

+ +

+ Keep the most important information easy to find. +

+
+ + + +
+

Code · code

+ +

+ Use font-medium + for button labels. +

+
+ +
+

Highlight · mark

+ +

+ Highlight the part worth remembering, not the whole paragraph. +

+
+
+
+

Buttons

From 96fee896cf138623803bae9cf1954e90201d7b4d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 5 Sep 2026 21:44:42 +0200 Subject: [PATCH 05/38] Include context menu and navigation links in the design system --- DESIGN_SYSTEM.md | 12 +++ src/app.css | 2 +- src/routes/design-system/+page.svelte | 142 +++++++++++++++++++++++--- 3 files changed, 138 insertions(+), 18 deletions(-) diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md index 9f656285..c9c7219a 100644 --- a/DESIGN_SYSTEM.md +++ b/DESIGN_SYSTEM.md @@ -139,6 +139,18 @@ The exact markup and classes live in `src/routes/design-system/+page.svelte`. Th The reference examples establish the proposed pill styling; the existing application pills have not yet been migrated. The user performs visual verification, including checking the shadow-free surfaces over images. Agents use code checks unless browser verification is explicitly requested. +### List popovers and rounding + +The `/design-system#popovers` section includes `popover-context-menu` (page actions and disabled items) and `popover-table-of-contents` (a bounded list of real section links). These are static visual references, not functioning popup components. + +- Pill shells use `--button-border-radius` directly. +- List shells use `min(1rem, var(--button-border-radius))`. The cap preserves space for aligned first and last rows; it is a design choice, not an accessibility requirement. +- Inner controls subtract the shell's padding and border from its radius, clamped at zero: `max(0px, calc(outer_radius - 0.25rem - 1px))`. The exact Tailwind expressions live in the reference page; `outer_radius` here is explanatory notation, not a new token. +- Rows share one shape, regular text, wrapping labels, and a 40px minimum height (44px for coarse pointers). The shell uses a solid background, a stroke border, and no shadow. +- Preserve focus clearance inside scrolling lists. Keep popup behavior and its associated semantics in consuming components. + +Setting `--button-border-radius: 0em` makes the reference buttons, pill shells, inner pill controls, and list surfaces square. This does not yet apply throughout the live application: existing toolbar and popover components still contain hardcoded rounding. Content image rounding remains a separate concern. + ### Original rollout plan 1. Review this proposal, particularly the variant set, baseline proportions, and corner shape. diff --git a/src/app.css b/src/app.css index 4bd41e81..7a14a09e 100644 --- a/src/app.css +++ b/src/app.css @@ -56,7 +56,7 @@ /* Foreground color for content displayed on the editing accent. */ --editing-foreground: var(--background); - /* Rounded corners for buttons and navigation items. */ + /* Rounded corners for controls; reference pills and popovers derive their shape from this. */ --button-border-radius: 3rem; /* Rounded corners for images. */ --image-border-radius: 2.2rem; diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index d4677c0a..716fe768 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -290,7 +290,8 @@

@@ -384,13 +385,13 @@ Use a group here; production toolbar keyboard behavior belongs to the consuming
+
+
+

List popovers

+

+ Compact lists with a shared surface and aligned rows. +

+
+ +
+
+

Context menu

+ +
+ +
+ +
+
+
+

Table of contents

+ + +
+
+
From ef1ee8c953345117954c402bc92f02e436fb168d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 5 Sep 2026 21:51:31 +0200 Subject: [PATCH 06/38] Smart adjustments to --button-border-radius setting --- DESIGN_SYSTEM.md | 4 ++++ src/app.css | 9 ++++++++- src/routes/design-system/+page.svelte | 9 +++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md index c9c7219a..33f92d3d 100644 --- a/DESIGN_SYSTEM.md +++ b/DESIGN_SYSTEM.md @@ -144,10 +144,14 @@ The reference examples establish the proposed pill styling; the existing applica The `/design-system#popovers` section includes `popover-context-menu` (page actions and disabled items) and `popover-table-of-contents` (a bounded list of real section links). These are static visual references, not functioning popup components. - Pill shells use `--button-border-radius` directly. +- The existing token is registered as an inherited `` in `app.css`. Assign a single nonnegative length such as `0em`, `0.5em`, or `3rem`; relative units resolve where the token is assigned, so smaller child text does not change the radius. No additional radius token is needed. - List shells use `min(1rem, var(--button-border-radius))`. The cap preserves space for aligned first and last rows; it is a design choice, not an accessibility requirement. - Inner controls subtract the shell's padding and border from its radius, clamped at zero: `max(0px, calc(outer_radius - 0.25rem - 1px))`. The exact Tailwind expressions live in the reference page; `outer_radius` here is explanatory notation, not a new token. - Rows share one shape, regular text, wrapping labels, and a 40px minimum height (44px for coarse pointers). The shell uses a solid background, a stroke border, and no shadow. - Preserve focus clearance inside scrolling lists. Keep popup behavior and its associated semantics in consuming components. +- Let the list shell itself scroll instead of adding a second rounded clipping wrapper. Adjust `--button-border-radius` directly to manually review the existing examples at different radii. + +The nested radius calculation keeps the corner centers aligned while the outer radius exceeds the inset. Below that inset, the inner radius becomes zero; retaining a rounded inner corner would produce a different curve. These rules target the documented padding, borders, and control sizes. Changing those dimensions requires updating the corresponding inset calculation. Setting `--button-border-radius: 0em` makes the reference buttons, pill shells, inner pill controls, and list surfaces square. This does not yet apply throughout the live application: existing toolbar and popover components still contain hardcoded rounding. Content image rounding remains a separate concern. diff --git a/src/app.css b/src/app.css index 7a14a09e..79516653 100644 --- a/src/app.css +++ b/src/app.css @@ -1,6 +1,13 @@ @import 'tailwindcss'; @plugin '@tailwindcss/forms'; +/* Resolve relative radius units where assigned, so nested controls inherit the same length. */ +@property --button-border-radius { + syntax: ''; + inherits: true; + initial-value: 0px; +} + @font-face { font-family: 'Inter'; src: url('/fonts/InterVariable.woff2') format('woff2'); @@ -57,7 +64,7 @@ --editing-foreground: var(--background); /* Rounded corners for controls; reference pills and popovers derive their shape from this. */ - --button-border-radius: 3rem; + --button-border-radius: 0rem; /* Rounded corners for images. */ --image-border-radius: 2.2rem; } diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index 716fe768..94eaa315 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -291,7 +291,8 @@ + -
-
-

Editor pills

-

- Compact surfaces for tools, actions, and previews. -

-
- -
-
-

Toolbar

-
- +
+

Toolbar

+
+ +
-
-
-

Inline call to action

- -
- +

Inline call to action

+ +
+ +
-
-
-

Variant selector and select parent

- -
- +

Variant selector and select parent

+ +
+ +
-
-
-
-
-
-
-

List popovers

-

- Compact lists with a shared surface and aligned rows. -

-
- -
-
-

Context menu

- -
- -
- +
+

Context menu

+ +
+ +
+ +
-
-
-

Table of contents

- - + +
-
-
- - + + + + From 0ba935795493e0188632cfaf92eea9d00c5a6cc2 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 6 Sep 2026 12:18:56 +0200 Subject: [PATCH 17/38] Apply design system to buttons --- src/app/components/Button.svelte | 14 ++++++++------ src/app/components/NavButton.svelte | 13 +++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/app/components/Button.svelte b/src/app/components/Button.svelte index 0538f439..12dc73b8 100644 --- a/src/app/components/Button.svelte +++ b/src/app/components/Button.svelte @@ -16,8 +16,9 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button flex min-w-[calc(1lh+24px)] items-center justify-center rounded-(--button-border-radius) bg-(--accent) px-6 py-3 text-sm text-(--accent-foreground) outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing)" - class:hover:opacity-80={render_as_link} + class="ew-button inline-flex min-h-11 max-w-full min-w-11 items-center justify-center rounded-(--button-border-radius) border border-transparent bg-(--accent) px-5 py-2 text-center text-base leading-6 font-medium wrap-anywhere text-(--accent-foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {render_as_link + ? 'cursor-pointer hover:bg-[color-mix(in_srgb,var(--accent),var(--accent-foreground)_20%)] active:bg-[color-mix(in_srgb,var(--accent),var(--accent-foreground)_30%)]' + : ''}" > @@ -28,8 +29,8 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button flex items-center justify-center rounded-(--button-border-radius) bg-(--background) px-4 py-3 text-sm text-(--foreground) outline-1 outline-(--foreground)/15 focus-visible:outline-(--editing) {render_as_link - ? 'hover:bg-(--foreground)/5' + class="ew-button inline-flex min-h-11 max-w-full min-w-11 items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent px-5 py-2 text-center text-base leading-6 font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {render_as_link + ? 'cursor-pointer hover:bg-(--muted) active:bg-(--foreground)/10' : ''}" > @@ -41,8 +42,9 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button flex items-center justify-center border-b border-(--foreground) py-3 text-sm text-(--foreground) outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing)" - class:hover:opacity-70={render_as_link} + class="ew-button inline-flex min-h-11 max-w-full min-w-6 items-center justify-start py-2.5 text-start text-base leading-6 font-medium wrap-anywhere text-(--foreground) underline decoration-1 underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) pointer-coarse:min-w-11 {render_as_link + ? 'hover:decoration-2 active:decoration-2' + : ''}" > diff --git a/src/app/components/NavButton.svelte b/src/app/components/NavButton.svelte index e8fb4d6d..b9f6f360 100644 --- a/src/app/components/NavButton.svelte +++ b/src/app/components/NavButton.svelte @@ -16,10 +16,11 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link && node.target !== '_self' ? node.target : undefined} - class="block rounded-(--button-border-radius) bg-(--accent) py-1 text-(--accent-foreground) outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing)" - class:hover:opacity-80={render_as_link} + class="inline-flex min-h-9 max-w-full min-w-9 items-center justify-center rounded-(--button-border-radius) border border-transparent bg-(--accent) px-3 py-1.5 text-center text-sm leading-5 font-medium wrap-anywhere text-(--accent-foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) pointer-coarse:min-h-11 pointer-coarse:min-w-11 {render_as_link + ? 'cursor-pointer hover:bg-[color-mix(in_srgb,var(--accent),var(--accent-foreground)_20%)] active:bg-[color-mix(in_srgb,var(--accent),var(--accent-foreground)_30%)]' + : ''}" > - + {/snippet} @@ -28,11 +29,11 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link && node.target !== '_self' ? node.target : undefined} - class="block rounded-(--button-border-radius) py-1 text-(--foreground) outline-1 outline-(--foreground)/15 focus-visible:outline-(--editing) {render_as_link - ? 'hover:bg-(--foreground)/5' + class="inline-flex min-h-9 max-w-full min-w-9 items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent px-3 py-1.5 text-center text-sm leading-5 font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) pointer-coarse:min-h-11 pointer-coarse:min-w-11 {render_as_link + ? 'cursor-pointer hover:bg-(--muted) active:bg-(--foreground)/10' : ''}" > - + {/snippet} From af4417216408ba07ecbb7ca0d3e46f716fcbc1c3 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 6 Sep 2026 12:26:41 +0200 Subject: [PATCH 18/38] Support small button layouts too --- src/app/components/Button.svelte | 22 +++++++++++++++++----- src/app/document_config.ts | 5 +++-- src/app/document_schema.ts | 6 +++++- src/routes/design-system/+page.svelte | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/app/components/Button.svelte b/src/app/components/Button.svelte index 12dc73b8..bf6e4d00 100644 --- a/src/app/components/Button.svelte +++ b/src/app/components/Button.svelte @@ -9,6 +9,18 @@ let node: Nodes['button'] = $derived(svedit.session.get(path)); let render_as_link = $derived(!svedit.editable && node.href); let layout = $derived(node.layout || 'primary'); + let button_variant = $derived(layout.replace('-small', '')); + let is_small = $derived(layout.endsWith('-small')); + let button_size = $derived( + is_small + ? 'min-h-9 min-w-9 px-3 py-1.5 text-sm leading-5 pointer-coarse:min-h-11 pointer-coarse:min-w-11' + : 'min-h-11 min-w-11 px-5 py-2 text-base leading-6' + ); + let link_size = $derived( + is_small + ? 'min-h-9 min-w-6 py-2 text-sm leading-5 pointer-coarse:min-h-11 pointer-coarse:min-w-11' + : 'min-h-11 min-w-6 py-2.5 text-base leading-6 pointer-coarse:min-w-11' + ); {#snippet primary()} @@ -16,7 +28,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button inline-flex min-h-11 max-w-full min-w-11 items-center justify-center rounded-(--button-border-radius) border border-transparent bg-(--accent) px-5 py-2 text-center text-base leading-6 font-medium wrap-anywhere text-(--accent-foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {render_as_link + class="ew-button inline-flex max-w-full items-center justify-center rounded-(--button-border-radius) border border-transparent bg-(--accent) text-center font-medium wrap-anywhere text-(--accent-foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {button_size} {render_as_link ? 'cursor-pointer hover:bg-[color-mix(in_srgb,var(--accent),var(--accent-foreground)_20%)] active:bg-[color-mix(in_srgb,var(--accent),var(--accent-foreground)_30%)]' : ''}" > @@ -29,7 +41,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button inline-flex min-h-11 max-w-full min-w-11 items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent px-5 py-2 text-center text-base leading-6 font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {render_as_link + class="ew-button inline-flex max-w-full items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent text-center font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {button_size} {render_as_link ? 'cursor-pointer hover:bg-(--muted) active:bg-(--foreground)/10' : ''}" > @@ -42,7 +54,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button inline-flex min-h-11 max-w-full min-w-6 items-center justify-start py-2.5 text-start text-base leading-6 font-medium wrap-anywhere text-(--foreground) underline decoration-1 underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) pointer-coarse:min-w-11 {render_as_link + class="ew-button inline-flex max-w-full items-center justify-start text-start font-medium wrap-anywhere text-(--foreground) underline decoration-1 underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {link_size} {render_as_link ? 'hover:decoration-2 active:decoration-2' : ''}" > @@ -51,9 +63,9 @@ {/snippet} - {#if layout === 'secondary'} + {#if button_variant === 'secondary'} {@render secondary()} - {:else if layout === 'link'} + {:else if button_variant === 'link'} {@render link()} {:else} {@render primary()} diff --git a/src/app/document_config.ts b/src/app/document_config.ts index b95ceb4a..fd7dc536 100644 --- a/src/app/document_config.ts +++ b/src/app/document_config.ts @@ -742,12 +742,13 @@ export const document_config = { button: function ( tr, _content = { content: '', marks: [], annotations: [] }, - _layout = 'primary' + layout = 'primary' ) { const new_button_id = tr.build('new_button', { new_button: { id: 'new_button', - type: 'button' + type: 'button', + layout } }); diff --git a/src/app/document_schema.ts b/src/app/document_schema.ts index fb7c6930..a01a82d8 100644 --- a/src/app/document_schema.ts +++ b/src/app/document_schema.ts @@ -200,7 +200,11 @@ export const document_schema = define_document_schema({ button: { kind: 'block', properties: { - layout: { type: 'string', values: ['primary', 'secondary', 'link'], default: 'primary' }, + layout: { + type: 'string', + values: ['primary', 'secondary', 'link', 'primary-small', 'secondary-small', 'link-small'], + default: 'primary' + }, href: { type: 'string' }, target: { type: 'string', default: '_self' }, label: { diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index a6c5f3a7..b353f1eb 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -11,7 +11,7 @@ Colors, fonts, and corner radius come from app.css. --> -
+

The Editable Design System

From 0dad00c5d3ccb2c75a864d8c2c13a6c7434c3182 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 6 Sep 2026 12:58:54 +0200 Subject: [PATCH 19/38] Make nav and descriptive listing conform to the design system --- src/app/components/Button.svelte | 2 +- .../components/DescriptiveListingItem.svelte | 8 +- src/app/components/ListingItem.svelte | 8 +- src/app/components/Nav.svelte | 26 +-- src/app/components/NavButton.svelte | 2 +- src/app/components/NavLink.svelte | 2 +- src/app/components/NavMedia.svelte | 14 +- src/app/components/ProseGridItem.svelte | 2 +- src/routes/design-system/+page.svelte | 153 +++++++++++++++++- 9 files changed, 187 insertions(+), 30 deletions(-) diff --git a/src/app/components/Button.svelte b/src/app/components/Button.svelte index bf6e4d00..a6ced320 100644 --- a/src/app/components/Button.svelte +++ b/src/app/components/Button.svelte @@ -41,7 +41,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button inline-flex max-w-full items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent text-center font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {button_size} {render_as_link + class="ew-button inline-flex max-w-full items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-[var(--secondary-button-background,transparent)] text-center font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {button_size} {render_as_link ? 'cursor-pointer hover:bg-(--muted) active:bg-(--foreground)/10' : ''}" > diff --git a/src/app/components/DescriptiveListingItem.svelte b/src/app/components/DescriptiveListingItem.svelte index 3abd1615..1b7d8485 100644 --- a/src/app/components/DescriptiveListingItem.svelte +++ b/src/app/components/DescriptiveListingItem.svelte @@ -17,13 +17,17 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="block py-4 outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing) sm:py-2 md:py-3" + class="group/listing-link block py-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) sm:py-2 md:py-3" use:reveal >
diff --git a/src/app/components/ListingItem.svelte b/src/app/components/ListingItem.svelte index 4ddd56f3..64ad6a5e 100644 --- a/src/app/components/ListingItem.svelte +++ b/src/app/components/ListingItem.svelte @@ -17,13 +17,17 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="block py-4 outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing) sm:py-2 md:py-3" + class="group/listing-link block py-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) sm:py-2 md:py-3" use:reveal >
diff --git a/src/app/components/Nav.svelte b/src/app/components/Nav.svelte index 5de65d16..7834c491 100644 --- a/src/app/components/Nav.svelte +++ b/src/app/components/Nav.svelte @@ -80,23 +80,25 @@
-
+
@@ -104,17 +106,17 @@
-
+
{#if mobile_nav_media_path} {/if}
-
+
{#if mobile_nav_cta_path} {/if} -
+
+
+

Descriptive listing

+

+ A linked row with a title, description, and optional metadata. Hover or press anywhere + on the row to strengthen the title underline; keyboard focus outlines the whole row. A + plain listing uses the same recipe with the description omitted. +

+
+ +
+
+ +
+
+

Boxed prose

+

+ Boxed items use a muted surface and pass + --secondary-button-background: var(--background) + to their children. Secondary buttons use that surface at rest and the muted surface on hover. + Outside a box, the button surface defaults to transparent. +

+
+
+
+

Make it your own

+

Start with the shared styles and adapt them to your site.

+ Explore buttons +
+
+
+
@@ -1176,6 +1312,13 @@ These destinations are real sections on this reference page. Application content >Disabled buttons +
  • + Descriptive listing +
  • Date: Sun, 6 Sep 2026 13:09:30 +0200 Subject: [PATCH 20/38] Make Toolbar styles conform to the design system --- src/app/components/NodeNavigator.svelte | 61 +------ src/app/components/Toolbar.svelte | 213 ++++++++++-------------- 2 files changed, 92 insertions(+), 182 deletions(-) diff --git a/src/app/components/NodeNavigator.svelte b/src/app/components/NodeNavigator.svelte index 63f6418c..ca0ae501 100644 --- a/src/app/components/NodeNavigator.svelte +++ b/src/app/components/NodeNavigator.svelte @@ -1,6 +1,6 @@ diff --git a/src/app/components/Nav.svelte b/src/app/components/Nav.svelte index 7834c491..67ffe55e 100644 --- a/src/app/components/Nav.svelte +++ b/src/app/components/Nav.svelte @@ -84,29 +84,29 @@ class:max-lg:hidden={!svedit.editable} >
  • - +
    -
    +
    {#if mobile_nav_media_path} {/if} @@ -116,7 +116,7 @@ {/if} @@ -804,7 +816,7 @@ @@ -815,7 +827,7 @@ Continue @@ -857,7 +869,7 @@
    @@ -866,7 +878,7 @@
    @@ -990,7 +1002,7 @@ >
  • Product
  • Quickstart
  • Manual
  • Contact
  • @@ -1040,12 +1052,12 @@ >
    @@ -1236,7 +1236,7 @@ Use a group here; production toolbar keyboard behavior belongs to the consuming type="button" aria-label="Select parent" title="Select parent" - class="inline-flex size-9 shrink-0 items-center justify-center rounded-[max(0px,calc(var(--button-border-radius)-0.25rem-1px))] border-0 bg-transparent p-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) enabled:cursor-pointer enabled:hover:bg-(--muted) enabled:active:bg-(--foreground)/10 disabled:cursor-default disabled:opacity-40 pointer-coarse:size-11" + class="inline-flex size-9 shrink-0 items-center justify-center rounded-[max(0px,calc(var(--button-border-radius)-0.25rem-1px))] border-0 bg-transparent p-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) enabled:cursor-pointer enabled:hover:bg-(--muted) enabled:active:bg-(--foreground)/10 disabled:cursor-default disabled:opacity-40" >
    From 7b1905f9e20b25ad212277227a3f1d621d12a4d3 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 7 Sep 2026 14:10:22 +0200 Subject: [PATCH 29/38] Fix Table Of Contents positioning --- src/app/components/TableOfContents.svelte | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app/components/TableOfContents.svelte b/src/app/components/TableOfContents.svelte index f3bd6300..99a482d5 100644 --- a/src/app/components/TableOfContents.svelte +++ b/src/app/components/TableOfContents.svelte @@ -129,10 +129,9 @@ From 87069291eacd38b91c3b8cc9300789af69ca7ca1 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 7 Sep 2026 14:32:40 +0200 Subject: [PATCH 30/38] Apply design system to page browser --- src/app/components/Drawer.svelte | 7 +- src/app/components/PageDeleteDialog.svelte | 54 ++----- src/app/components/PageUrlDialog.svelte | 83 +++------- src/app/components/PagesDrawer.svelte | 179 ++++++++------------- src/routes/design-system/+page.svelte | 59 +++++++ 5 files changed, 168 insertions(+), 214 deletions(-) diff --git a/src/app/components/Drawer.svelte b/src/app/components/Drawer.svelte index d0ac36cc..6d692a2c 100644 --- a/src/app/components/Drawer.svelte +++ b/src/app/components/Drawer.svelte @@ -351,8 +351,8 @@ width: 2.5rem; height: 0.32rem; background: var(--background); - border-radius: 9999px; - box-shadow: var(--shadow-sm); + border-radius: var(--button-border-radius); + border: 1px solid var(--stroke); } .drawer { @@ -392,8 +392,7 @@ height: var(--drawer-height); max-height: 95dvh; background: var(--background); - box-shadow: var(--shadow-xl); - border-top: 0.5px solid color-mix(in oklch, var(--foreground) 18%, transparent); + border-top: 1px solid var(--stroke); color: var(--foreground); padding-bottom: env(safe-area-inset-bottom); overflow: auto; diff --git a/src/app/components/PageDeleteDialog.svelte b/src/app/components/PageDeleteDialog.svelte index 65813676..5f7d4d2b 100644 --- a/src/app/components/PageDeleteDialog.svelte +++ b/src/app/components/PageDeleteDialog.svelte @@ -103,13 +103,18 @@ {/if}
    -
    @@ -105,10 +106,19 @@ {/if}
    - -
    @@ -137,24 +147,24 @@ position: fixed; inset: 50% auto auto 50%; transform: translate(-50%, -50%); - width: min(28rem, calc(100vw - 2rem)); + width: min(28rem, calc(100vw - 2.5rem)); + max-height: calc(100dvh - 2.5rem); + overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; - gap: 0.9rem; + gap: 1rem; border: 1px solid var(--stroke); - border-radius: 23px; + border-radius: min(1rem, var(--button-border-radius)); background: var(--background); color: var(--foreground); - box-shadow: - 0 1px 2px rgb(0 0 0 / 0.12), - 0 4px 16px rgb(0 0 0 / 0.08); + box-shadow: none; } .confirm-title { margin: 0; font-size: 1rem; - font-weight: 700; + font-weight: 500; } .confirm-error { @@ -172,58 +182,13 @@ .page-url-field { display: flex; align-items: center; - gap: 0.25rem; - padding: 0.75rem 0; + flex-wrap: wrap; + gap: 0.5rem; } .page-url-prefix { - font-size: 0.95rem; + font-size: 0.875rem; color: var(--muted-foreground); - white-space: nowrap; - } - - .page-url-input { - flex: 1; - min-width: 0; - border: 1px solid var(--stroke); - border-radius: 9999px; - background: var(--background); - color: var(--foreground); - padding: 0.5rem 0.65rem; - font-size: 0.95rem; - outline: none; - box-shadow: none; - } - - .page-url-input:focus { - border-color: var(--editing); - box-shadow: none; - } - - .confirm-btn { - border: 0; - border-radius: 9999px; - background: transparent; - color: inherit; - padding: 0.55rem 0.9rem; - cursor: pointer; - font-size: 0.9rem; - font-weight: 600; - outline: 1px solid transparent; - outline-offset: 1px; - } - - .confirm-btn:hover { - background: var(--muted); - } - - .confirm-btn:focus-visible { - background: var(--muted); - outline-color: var(--editing); - } - - .confirm-btn:disabled { - opacity: 0.6; - cursor: not-allowed; + overflow-wrap: anywhere; } diff --git a/src/app/components/PagesDrawer.svelte b/src/app/components/PagesDrawer.svelte index 87142729..782e4fa0 100644 --- a/src/app/components/PagesDrawer.svelte +++ b/src/app/components/PagesDrawer.svelte @@ -857,7 +857,7 @@ Updated: ${updated_at_label}`; +
    {/if} @@ -928,7 +938,13 @@ Updated: ${updated_at_label}`; a developer to remove that markdown page.

    - +
    {/if} @@ -958,7 +974,7 @@ Updated: ${updated_at_label}`; top: 0; z-index: 1; margin-inline: -0.4rem; - padding: 1rem 0 0.35rem; + padding: 1rem 0 0.5rem; background: var(--background); } @@ -970,16 +986,16 @@ Updated: ${updated_at_label}`; height: 2.75rem; padding: 0 0.78rem; border: 1px solid var(--stroke); - border-radius: 9999px; + border-radius: var(--button-border-radius); background: var(--background); box-shadow: none; cursor: text; transition: border-color 150ms ease; } + /* Keep search focus quiet while the result highlight identifies the Enter target. */ .search-input-shell:focus-within { - border-color: var(--editing); - box-shadow: none; + border-color: var(--muted-foreground); } .search-input-icon { @@ -996,7 +1012,8 @@ Updated: ${updated_at_label}`; background: transparent; color: var(--foreground); padding: 0; - font-size: 16px !important; + font-size: 1rem; + line-height: 1.5rem; outline: none; box-shadow: none; appearance: none; @@ -1044,8 +1061,9 @@ Updated: ${updated_at_label}`; .tree-row-shell::before { content: ''; position: absolute; - inset: 0 -0.4rem; - border-radius: 9999px; + inset: 0 -0.4rem 0 + max(-0.4rem, calc(var(--tree-guide-columns, 0) * var(--tree-indent-width, 1.3rem) - 0.4rem)); + border-radius: var(--button-border-radius); background: transparent; pointer-events: none; z-index: 0; @@ -1085,12 +1103,13 @@ Updated: ${updated_at_label}`; .tree-row::after { content: ''; position: absolute; - inset: 0 -0.4rem; - border-radius: 9999px; + inset: 0 -0.4rem 0 + max(-0.4rem, calc(var(--tree-guide-columns, 0) * var(--tree-indent-width, 1.3rem) - 0.4rem)); + border-radius: var(--button-border-radius); pointer-events: none; background: transparent; - outline: 1px solid transparent; - outline-offset: -1px; + outline: 2px solid transparent; + outline-offset: -2px; z-index: 3; } @@ -1102,10 +1121,6 @@ Updated: ${updated_at_label}`; background: var(--editing-muted); } - .tree-row-shell:hover .tree-row-keyboard-selected::after { - outline-color: var(--editing); - } - .tree-row:focus-visible::after, .tree-row-shell:focus-within .tree-row:focus-visible::after { outline-color: var(--editing); @@ -1120,19 +1135,14 @@ Updated: ${updated_at_label}`; .tree-row-keyboard-selected::before { content: ''; position: absolute; - inset: 0 -0.4rem; - border-radius: 9999px; + inset: 0 -0.4rem 0 + max(-0.4rem, calc(var(--tree-guide-columns, 0) * var(--tree-indent-width, 1.3rem) - 0.4rem)); + border-radius: var(--button-border-radius); pointer-events: none; background: var(--editing-muted); z-index: -1; } - .tree-row-keyboard-selected::after, - .tree-row-keyboard-selected:focus-visible::after, - .tree-row-shell:focus-within .tree-row-keyboard-selected:focus-visible::after { - outline-color: var(--editing); - } - .item-actions-btn { position: absolute; z-index: 4; @@ -1145,13 +1155,13 @@ Updated: ${updated_at_label}`; height: 2.25rem; transform: translateY(-50%); border: 0; - border-radius: 9999px; + border-radius: var(--button-border-radius); padding: 0; background: transparent; color: var(--foreground); cursor: pointer; - outline: 1px solid transparent; - outline-offset: 1px; + outline: 2px solid transparent; + outline-offset: 2px; pointer-events: auto; transition: background-color 150ms ease, @@ -1170,7 +1180,7 @@ Updated: ${updated_at_label}`; } .item-actions-btn:active { - transform: translateY(-50%) scale(0.95); + background: color-mix(in srgb, var(--foreground) 10%, transparent); } .page-illustration { @@ -1199,7 +1209,7 @@ Updated: ${updated_at_label}`; flex: 0 0 auto; margin: 0.25rem 0.35rem 0.25rem -0.15rem; background: var(--muted); - border-radius: 9999px; + border-radius: var(--button-border-radius); overflow: hidden; } @@ -1346,9 +1356,9 @@ Updated: ${updated_at_label}`; flex-direction: column; justify-content: center; gap: 0; - font-size: 0.9rem; - font-weight: 600; - line-height: 1.15; + font-size: 0.875rem; + font-weight: 500; + line-height: 1.25rem; color: inherit; padding-left: 0.75rem; } @@ -1377,7 +1387,7 @@ Updated: ${updated_at_label}`; align-items: center; justify-content: center; border: 1px solid currentColor; - border-radius: 3px; + border-radius: min(0.25rem, var(--button-border-radius)); background: transparent; color: var(--foreground); padding: 0 0.25rem; @@ -1386,8 +1396,8 @@ Updated: ${updated_at_label}`; line-height: 1; letter-spacing: 0.04em; cursor: pointer; - outline: 1px solid transparent; - outline-offset: 1px; + outline: 2px solid transparent; + outline-offset: 2px; } /* Red because a shadowed page is broken, not merely undiscoverable. */ @@ -1404,7 +1414,7 @@ Updated: ${updated_at_label}`; .item-actions-btn:focus-visible, .unlisted-badge:hover, .unlisted-badge:focus-visible { - background: var(--background); + background: var(--muted); } } @@ -1442,75 +1452,53 @@ Updated: ${updated_at_label}`; flex-direction: column; min-width: 11rem; margin: 0.5rem 0 0; - padding: 0.375rem; + padding: 0.25rem; + max-width: calc(100vw - 2.5rem); + max-height: calc(100dvh - 2.5rem); + overflow-y: auto; border: 1px solid var(--stroke); - border-radius: 1rem; + border-radius: min(1rem, var(--button-border-radius)); background: var(--background); color: var(--foreground); - box-shadow: - 0 1px 2px rgb(0 0 0 / 0.12), - 0 4px 16px rgb(0 0 0 / 0.08); - } - - .menu-item { - border: 0; - border-radius: 0.75rem; - background: transparent; - color: inherit; - text-align: left; - padding: 0.625rem 0.75rem; - cursor: pointer; - font-size: 0.875rem; - line-height: 1.25rem; - } - - .menu-item:hover, - .menu-item:focus-visible { - background: var(--muted); - outline: none; + box-shadow: none; } .menu-item-danger { color: color-mix(in oklch, red 65%, var(--foreground)); } - .menu-item-disabled { - color: var(--muted-foreground); - cursor: not-allowed; - } - .confirm-panel { position: fixed; inset: 50% auto auto 50%; transform: translate(-50%, -50%); - width: min(28rem, calc(100vw - 2rem)); + width: min(28rem, calc(100vw - 2.5rem)); + max-height: calc(100dvh - 2.5rem); + overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; - gap: 0.9rem; + gap: 1rem; border: 1px solid var(--stroke); - border-radius: 23px; + border-radius: min(1rem, var(--button-border-radius)); background: var(--background); color: var(--foreground); - box-shadow: - 0 1px 2px rgb(0 0 0 / 0.12), - 0 4px 16px rgb(0 0 0 / 0.08); + box-shadow: none; } .unlisted-info-panel { - width: min(24rem, calc(100vw - 2rem)); + width: min(24rem, calc(100vw - 2.5rem)); } .confirm-title { margin: 0; font-size: 1rem; - font-weight: 700; + font-weight: 500; } .confirm-message { margin: 0; - font-size: 0.92rem; - line-height: 1.45; + font-size: 0.875rem; + line-height: 1.5rem; color: var(--muted-foreground); } @@ -1520,33 +1508,6 @@ Updated: ${updated_at_label}`; gap: 0.75rem; } - .confirm-btn { - border: 0; - border-radius: 9999px; - background: transparent; - color: inherit; - padding: 0.55rem 0.9rem; - cursor: pointer; - font-size: 0.9rem; - font-weight: 600; - outline: 1px solid transparent; - outline-offset: 1px; - } - - .confirm-btn:hover { - background: var(--muted); - } - - .confirm-btn:focus-visible { - background: var(--muted); - outline-color: var(--editing); - } - - .confirm-btn:disabled { - opacity: 0.6; - cursor: not-allowed; - } - @media (max-width: 640px) { .draft-title { font-size: 0.68rem; @@ -1562,10 +1523,6 @@ Updated: ${updated_at_label}`; height: 1.05rem; } - .search-input { - font-size: 0.84rem; - } - .tree-row-shell:hover::before { background: transparent; } @@ -1574,10 +1531,6 @@ Updated: ${updated_at_label}`; background: var(--editing-muted); } - .tree-row-shell:hover .tree-row-keyboard-selected::after { - outline-color: var(--editing); - } - .tree-row-meta { display: flex; padding-left: 0.5rem; diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index 2b8654d6..00c6bbbb 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -1357,6 +1357,65 @@ The local href is a specimen destination. Production links retain their own dest
    +
    +
    +

    Page browser

    +

    + A muted editing fill marks the result Enter will open. Only keyboard-focused rows get a + ring, drawn inside the row to keep tree guides and adjacent rows clear. Search focus + uses a quiet border change. Action menus reuse the list popover recipe. +

    +
    +
    +
    +

    List popovers

    From d28fa1c2c4426b64bfb9410b0855d43586e7eb28 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 7 Sep 2026 14:58:39 +0200 Subject: [PATCH 31/38] Text input outlines in --editing color --- src/app/components/EditLink.svelte | 2 +- src/app/components/EditMedia.svelte | 2 +- src/app/components/PageUrlDialog.svelte | 2 +- src/app/components/PagesDrawer.svelte | 7 +++++-- src/routes/design-system/+page.svelte | 10 +++++----- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/app/components/EditLink.svelte b/src/app/components/EditLink.svelte index da94f0a2..c49898ef 100644 --- a/src/app/components/EditLink.svelte +++ b/src/app/components/EditLink.svelte @@ -184,7 +184,7 @@ type="url" bind:value={href_input_value} placeholder="https://example.com" - class="edit-link-input min-h-9 w-72 min-w-0 flex-1 rounded-[max(0px,calc(min(1rem,var(--button-border-radius))-0.25rem-1px))] border border-(--stroke) bg-(--background) px-3 py-1 text-base leading-6 text-(--foreground) focus:border-(--stroke) focus:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing)" + class="edit-link-input min-h-9 w-72 min-w-0 flex-1 rounded-[max(0px,calc(min(1rem,var(--button-border-radius))-0.25rem-1px))] border border-(--stroke) bg-(--background) px-3 py-1 text-base leading-6 text-(--foreground) outline-none focus:border-(--editing) focus:ring-0" onkeydown={handle_keydown} /> {#if app.has_backend} diff --git a/src/app/components/EditMedia.svelte b/src/app/components/EditMedia.svelte index d3ebc2e3..969f5be3 100644 --- a/src/app/components/EditMedia.svelte +++ b/src/app/components/EditMedia.svelte @@ -82,7 +82,7 @@ bind:value={alt_input_value} rows="3" placeholder="Describe the media for people using screen readers." - class="edit-media-textarea block w-72 max-w-full min-w-0 resize-none rounded-[max(0px,calc(min(1rem,var(--button-border-radius))-0.25rem-1px))] border border-(--stroke) bg-(--background) px-3 py-2 text-base leading-6 text-(--foreground) focus:border-(--stroke) focus:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing)" + class="edit-media-textarea block w-72 max-w-full min-w-0 resize-none rounded-[max(0px,calc(min(1rem,var(--button-border-radius))-0.25rem-1px))] border border-(--stroke) bg-(--background) px-3 py-2 text-base leading-6 text-(--foreground) outline-none focus:border-(--editing) focus:ring-0" onkeydown={handle_keydown} >
    diff --git a/src/app/components/PageUrlDialog.svelte b/src/app/components/PageUrlDialog.svelte index 67cedbb6..a67baab5 100644 --- a/src/app/components/PageUrlDialog.svelte +++ b/src/app/components/PageUrlDialog.svelte @@ -97,7 +97,7 @@ diff --git a/src/app/components/PagesDrawer.svelte b/src/app/components/PagesDrawer.svelte index 782e4fa0..add9abbe 100644 --- a/src/app/components/PagesDrawer.svelte +++ b/src/app/components/PagesDrawer.svelte @@ -995,7 +995,7 @@ Updated: ${updated_at_label}`; /* Keep search focus quiet while the result highlight identifies the Enter target. */ .search-input-shell:focus-within { - border-color: var(--muted-foreground); + border-color: var(--editing); } .search-input-icon { @@ -1411,7 +1411,10 @@ Updated: ${updated_at_label}`; @media (hover: hover) and (pointer: fine) { .item-actions-btn:hover, - .item-actions-btn:focus-visible, + .item-actions-btn:focus-visible { + background: var(--background); + } + .unlisted-badge:hover, .unlisted-badge:focus-visible { background: var(--muted); diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index 00c6bbbb..1ef9669e 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -1327,7 +1327,7 @@ The local href is a specimen destination. Production links retain their own dest

    Link and media prompts use an opaque surface with 4px padding, no shadow, and the button radius capped at 1rem. Fields and actions subtract the padding and border from that - radius. Text inputs and textareas use 16px text; keyboard focus uses the shared outline. + radius. Text inputs and textareas use 16px text and an editing-color border on focus.

    @@ -1338,7 +1338,7 @@ The local href is a specimen destination. Production links retain their own dest type="url" aria-label="Example link URL" value="https://example.com" - class="min-h-9 w-full min-w-0 rounded-[max(0px,calc(min(1rem,var(--button-border-radius))-0.25rem-1px))] border border-(--stroke) bg-(--background) px-3 py-1 text-base leading-6 text-(--foreground) focus:border-(--stroke) focus:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing)" + class="min-h-9 w-full min-w-0 rounded-[max(0px,calc(min(1rem,var(--button-border-radius))-0.25rem-1px))] border border-(--stroke) bg-(--background) px-3 py-1 text-base leading-6 text-(--foreground) outline-none focus:border-(--editing) focus:ring-0" />
    @@ -45,8 +47,15 @@ Page content

    - --background / - --foreground + --background + / + --foreground

    @@ -57,8 +66,15 @@

    Supporting text

    - --muted / - --muted-foreground + --muted + / + --muted-foreground

    @@ -68,8 +84,15 @@ Primary action or highlight

    - --accent / - --accent-foreground + --accent + / + --accent-foreground

    @@ -79,8 +102,15 @@ Active editing

    - --editing / - --editing-foreground + --editing + / + --editing-foreground

    @@ -90,8 +120,15 @@ Passive editing highlight

    - --editing-muted / - --editing + --editing-muted + / + --editing

    @@ -101,7 +138,12 @@

    Borders and dividers


    -

    --stroke

    +

    + --stroke +

    @@ -111,17 +153,30 @@

    Clear words.

    -

    font-sans · Inter

    +

    + font-sans · Inter +

    Clear words.

    - font-serif · Libertinos Serif Display + font-serif · Libertinos Serif Display

    Clear words.

    -

    font-mono · IBM Plex Mono

    +

    + font-mono · IBM Plex Mono +

    @@ -141,7 +196,12 @@ > Button -

    --button-border-radius

    +

    + --button-border-radius +

    Image corners
    -

    --image-border-radius

    +

    + --image-border-radius +

    @@ -183,10 +248,16 @@

    Page limiter

    - Center each block with mx-auto max-w-7xl, then add - px-5 sm:px-7 inside it. The width limit is 80rem (1280px), - including side padding: 1.25rem (20px) on small screens and 1.75rem (28px) from the 40rem - (640px) breakpoint, at the default root font size. + Center each block with mx-auto max-w-7xl, then add + px-5 sm:px-7 inside it. The width limit is 80rem (1280px), including side padding: 1.25rem (20px) on + small screens and 1.75rem (28px) from the 40rem (640px) breakpoint, at the default root font + size.

    @@ -233,9 +304,16 @@ layout. Alternating their positions adds variation while keeping shared alignment edges.

    - Narrow tracks use max-w-4xl (56rem / 896px) inside the - max-w-7xl page limiter (80rem / 1280px). These are maximum - widths, not fixed proportions. Both include the shared side padding. + Narrow tracks use max-w-4xl + (56rem / 896px) inside the + max-w-7xl page limiter (80rem / 1280px). These are maximum widths, not fixed proportions. Both include + the shared side padding.

    @@ -243,7 +321,10 @@
    - Narrow left · max-w-4xl + Narrow left · max-w-4xl
    @@ -260,7 +341,10 @@
    - Narrow center · mx-auto max-w-4xl + Narrow center · mx-auto max-w-4xl
    @@ -277,7 +361,10 @@
    - Narrow right · ml-auto max-w-4xl + Narrow right · ml-auto max-w-4xl
    @@ -482,11 +569,15 @@

    Sample block implementation

    - A top-level block receives its section context through mark, aliased to section. As in Prose.svelte, the block - derives its top and bottom padding from that context. No extra padding props are - needed. + >, aliased to + section. As in Prose.svelte, the block derives its top and bottom padding from that context. + No extra padding props are needed.

    @@ -527,26 +618,52 @@
    • No section mark: both edges are generous.
    • -
    • section.is_start: the top edge is generous.
    • -
    • section.is_end: the bottom edge is generous.
    • - section.is_middle: both edges are compact; the two - boundary checks already cover this case. + section.is_start: the top edge is generous. +
    • +
    • + section.is_end: the bottom edge is generous. +
    • +
    • + section.is_middle: both edges are compact; the two boundary checks already cover this case.
    • A one-block section is both the start and the end, so both edges are generous.

    - The app uses shared utilities in src/app.css for the - default rhythm: pt-block-generous, - pt-block-compact, and their - pb- equivalents. They apply the values above to existing elements - without adding a wrapper component. + The app uses shared utilities in src/app.css + for the default rhythm: + pt-block-generous, + pt-block-compact, and their + pb- equivalents. They apply the values above to existing elements without adding a wrapper component.

    For a custom rhythm, replace the default utility on that edge with explicit responsive - classes, such as pt-8 lg:pt-16. Avoid combining a default - utility with overrides on the same edge. Keep deliberate exceptions local: flush and - full-bleed figures have no vertical padding. + classes, such as pt-8 lg:pt-16. Avoid combining a default utility with overrides on the same edge. Keep deliberate + exceptions local: flush and full-bleed figures have no vertical padding.

    @@ -962,7 +1079,10 @@

    Boxed prose

    Boxed items use a muted surface and pass - --secondary-button-background: var(--background) + --secondary-button-background: var(--background) to their children. Secondary buttons use that surface at rest and the muted surface on hover. Outside a box, the button surface defaults to transparent.

    From 2ae3ca89d964c300d1afc84876a601be0d496030 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 7 Sep 2026 15:16:41 +0200 Subject: [PATCH 33/38] Improve spacing on the design system page --- src/routes/design-system/+page.svelte | 54 +++++++++++++++------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index 38c3a200..640e619b 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -20,7 +20,11 @@

    -
    +

    Foundations

    @@ -32,17 +36,17 @@

    -
    +

    Colors and surfaces

    Keep each surface with its foreground color. Neutral controls use the muted surface on hover and a 10% foreground tint on press. Primary actions and editing actions use their respective accent treatments.

    -
    -
    +
    +
    Page content
    @@ -58,9 +62,9 @@ >

    -
    +

    Secondary surface

    Supporting text

    @@ -77,9 +81,9 @@ >

    -
    +
    Primary action or highlight
    @@ -95,9 +99,9 @@ >

    -
    +
    Active editing
    @@ -113,9 +117,9 @@ >

    -
    +
    Passive editing highlight
    @@ -131,9 +135,9 @@ >

    -
    +

    Borders and dividers


    @@ -148,10 +152,10 @@
    -
    +

    Font families

    -
    -
    +
    +

    Clear words.

    · Inter

    -
    +

    Clear words.

    · Libertinos Serif Display

    -
    +

    Clear words.

    -
    +

    Corner radii

    Buttons and pill shells use the button radius. Popovers cap it at 1rem; their inner rows @@ -189,7 +193,9 @@ their own radius. Set either token to zero for square corners.

    -
    +
    <div class="mx-auto max-w-7xl">
     	<div class="px-5 sm:px-7">
     		Page content
    @@ -583,7 +589,7 @@
     					

    Sample prose block

    <script lang="ts">
     	import { Node, NodeArrayProperty } from 'svedit';
     	import type { DocumentPath, NodeArrayAttachmentContext } from 'svedit';
    
    From 383e9892d7cbed6001d63ce2582e7c324995c367 Mon Sep 17 00:00:00 2001
    From: Michael Aufreiter 
    Date: Mon, 7 Sep 2026 15:24:26 +0200
    Subject: [PATCH 34/38] Use generous block spacing for first section in design
     sytem
    
    ---
     src/routes/design-system/+page.svelte | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte
    index 640e619b..ecb3d472 100644
    --- a/src/routes/design-system/+page.svelte
    +++ b/src/routes/design-system/+page.svelte
    @@ -11,7 +11,7 @@
     	Colors, fonts, and corner radius come from app.css.
     -->
     
    -	
    +

    The Editable Design System

    From ef72f700a4a01a6f464159fc0b7332b738a69929 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 7 Sep 2026 18:58:36 +0200 Subject: [PATCH 35/38] Remove no longer needed --secondary-button-background contract --- AGENTS.md | 2 ++ src/app/components/Button.svelte | 2 +- src/app/components/NavButton.svelte | 2 +- src/app/components/ProseGridItem.svelte | 16 ++++++++++++++- src/routes/design-system/+page.svelte | 26 +++++++++++-------------- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7ca0d347..1ace93b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,8 @@ Repository-specific guidance for coding agents working on Svedit. - Use `snake_case` for project-defined JavaScript and TypeScript identifiers. Keep web platform and Svelte APIs in their native `camelCase` form. - Prefer Tailwind classes and minimize custom CSS. For CSS custom properties, use Tailwind's arbitrary-value utilities, such as `text-(--editing)` and `border-(--editing)`, where applicable. +- Prefix all project-defined CSS classes with `ew-`, including component, state, and custom utility classes. Standard Tailwind classes and classes required by third-party libraries retain their original names. + ## UI verification - The user manually verifies UI changes. Do not use a browser, screenshots, or computer-use tools to verify the UI unless the user explicitly asks. diff --git a/src/app/components/Button.svelte b/src/app/components/Button.svelte index c42949bb..d8700f10 100644 --- a/src/app/components/Button.svelte +++ b/src/app/components/Button.svelte @@ -41,7 +41,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="ew-button inline-flex max-w-full items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-[var(--secondary-button-background,transparent)] text-center font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {button_size} {render_as_link + class="ew-button ew-button-secondary inline-flex max-w-full items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent text-center font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {button_size} {render_as_link ? 'cursor-pointer hover:bg-(--muted) active:bg-(--foreground)/10' : ''}" > diff --git a/src/app/components/NavButton.svelte b/src/app/components/NavButton.svelte index 7446cf03..a1e06ce9 100644 --- a/src/app/components/NavButton.svelte +++ b/src/app/components/NavButton.svelte @@ -29,7 +29,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link && node.target !== '_self' ? node.target : undefined} - class="inline-flex min-h-9 max-w-full min-w-9 items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-[var(--secondary-button-background,transparent)] px-3 py-1.5 text-center text-sm leading-5 font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {render_as_link + class="inline-flex min-h-9 max-w-full min-w-9 items-center justify-center rounded-(--button-border-radius) border border-(--stroke) bg-transparent px-3 py-1.5 text-center text-sm leading-5 font-medium wrap-anywhere text-(--foreground) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--editing) {render_as_link ? 'cursor-pointer hover:bg-(--muted) active:bg-(--foreground)/10' : ''}" > diff --git a/src/app/components/ProseGridItem.svelte b/src/app/components/ProseGridItem.svelte index f4f53098..da52b7fa 100644 --- a/src/app/components/ProseGridItem.svelte +++ b/src/app/components/ProseGridItem.svelte @@ -45,7 +45,7 @@ {#snippet card()}
    @@ -61,3 +61,17 @@ {@render plain()} {/if} + + diff --git a/src/routes/design-system/+page.svelte b/src/routes/design-system/+page.svelte index ecb3d472..f9ed1ee7 100644 --- a/src/routes/design-system/+page.svelte +++ b/src/routes/design-system/+page.svelte @@ -880,7 +880,7 @@ @@ -939,7 +939,7 @@ @@ -983,7 +983,7 @@
    @@ -1001,7 +1001,7 @@
    @@ -1082,26 +1082,22 @@
    -

    Boxed prose

    +

    Boxed items

    - Boxed items use a muted surface and pass - --secondary-button-background: var(--background) - to their children. Secondary buttons use that surface at rest and the muted surface on hover. - Outside a box, the button surface defaults to transparent. + Boxed items use a muted surface. Their secondary buttons use the background color at + rest and the muted color on hover. This styling applies only to secondary buttons inside + the box.

    Make it your own

    Start with the shared styles and adapt them to your site.

    Explore buttons
    @@ -1183,7 +1179,7 @@ >
    - -

    Code · code