diff --git a/AGENTS.md b/AGENTS.md index 511d8d69..1ace93b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,9 +13,26 @@ Repository-specific guidance for coding agents working on Svedit. ## Code style +- Use tabs for indentation throughout the project, including code snippets in documentation and design system examples. Preserve spaces only where the file format requires them. - 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. +- Use appropriate code checks, such as formatting, linting, and Svelte diagnostics, without starting a browser-based verification workflow. + +## 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 the [design system source](src/routes/design-system/+page.svelte) before styling UI. With the development server running, the user can open [the design system in a browser](http://localhost:5173/design-system) to inspect typography, spacing, buttons, and editor pills, and inspect the source for their recipes. Shared tokens and typography utilities live in `src/app.css`. Follow the UI verification rules above for agent browser use. +- When customizing an Editable site, prefer updating the design system first, then adopting those changes in the actual site components. This gives agents and people working manually a concrete reference to implement consistently. +- 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. + ## 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..33f92d3d --- /dev/null +++ b/DESIGN_SYSTEM.md @@ -0,0 +1,181 @@ +# 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 + +### Editor pill references + +The `/design-system#pills` section now contains four concrete, static references: + +| Reference anchor | Example | Intended use | +| ----------------------- | --------------------------------------------------- | ----------------------------------------------- | +| `pill-toolbar` | New page, browse, edit, and more actions | Grouped page tools. | +| `pill-inline-action` | Create link | A single contextual editing action. | +| `pill-variant-selector` | Select parent, divider, Gallery, and mixed status | Two related selection controls in one surface. | +| `pill-link-preview` | Thumbnail fallback, Why Editable?, edit, and remove | A navigable preview with separate link actions. | + +The exact markup and classes live in `src/routes/design-system/+page.svelte`. These references use flat, opaque surfaces and functional borders instead of shadows. Individual controls receive focus; the surrounding pill does not. The preview includes an initials fallback for its thumbnail slot. Positioning, menus, editor commands, and keyboard behavior remain responsibilities of consuming components. + +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. +- 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. + +### Original rollout plan + +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/README.md b/README.md index 54db6ba7..34fe775a 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ From here on, `git push` saves your work to your own repo. To bring in Editable ### Styling +With the development server running, open the [design system](http://localhost:5173/design-system) in your browser to explore typography, spacing, buttons, and editor pills. Inspect its [source code](src/routes/design-system/+page.svelte) for the corresponding markup and styles. + +When customizing your Editable site, ideally update the design system first, then apply those changes to the actual site components. This gives you a concrete visual reference to work from and helps keep the site consistent, whether you build it with an agent or edit the code manually. + Adjust the colors and fonts directly in `src/app.css`: ```css @@ -635,7 +639,6 @@ Create `src/app/components/Hero.svelte`. It reads the node at `path`, renders ea import { get_svedit_context } from '#app/svedit_context.js'; import MediaProperty from './MediaProperty.svelte'; - const svedit = get_svedit_context(); let { path }: { path: DocumentPath } = $props(); let node: Nodes['hero'] = $derived(svedit.session.get(path)); @@ -664,12 +667,12 @@ Create `src/app/components/Hero.svelte`. It reads the node at `path`, renders ea
{#if layout === 'side-by-side'} -
+
{@render text()}
{@render media()}
{:else} -
+
{@render text()}
{@render media()}
diff --git a/src/app.css b/src/app.css index af57cd5a..9df801c4 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'); @@ -56,7 +63,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; @@ -69,77 +76,79 @@ --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; - --shadow-sm: 0 2px 4px -1px oklch(0 0 0 / 0.12), 0 1px 2px -1px oklch(0 0 0 / 0.12); - --shadow-xl: 0 20px 25px -5px oklch(0 0 0 / 0.12), 0 8px 10px -6px oklch(0 0 0 / 0.12); } /* 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 */ +/* Vertical block spacing */ /******************************************************************/ -@utility pt-section-wide { +/* Defaults for each edge. Replace the utility with explicit classes for custom spacing. */ +@utility pt-block-generous { @apply pt-10 sm:pt-14 md:pt-16 lg:pt-28; } -@utility pt-section-narrow { +@utility pt-block-compact { @apply pt-4 lg:pt-7; } -@utility pb-section-wide { +@utility pb-block-generous { @apply pb-10 sm:pb-14 md:pb-16 lg:pb-28; } -@utility pb-section-narrow { +@utility pb-block-compact { @apply pb-4 lg:pb-7; } +/* EW-specific utilities */ @utility ew-bg-checkerboard { background: linear-gradient( diff --git a/src/app/app_context.ts b/src/app/app_context.ts index bb506d08..86b523e2 100644 --- a/src/app/app_context.ts +++ b/src/app/app_context.ts @@ -1,10 +1,12 @@ -import { getContext } from 'svelte'; +import { getContext, type Snippet } from 'svelte'; /** * The app-level context provided by App.svelte: server-derived flags plus * the auth dialog state and its handlers. */ export type AppContext = { + /** Optional body for read-only routes using the shared site layout. */ + readonly page_content?: Snippet; readonly has_backend: boolean; readonly can_edit: boolean; readonly is_admin: boolean; diff --git a/src/app/components/Accordion.svelte b/src/app/components/Accordion.svelte index 677eb14f..09177f63 100644 --- a/src/app/components/Accordion.svelte +++ b/src/app/components/Accordion.svelte @@ -7,20 +7,20 @@ let { path, mark: section = null } = $props(); let node: Nodes['accordion'] = $derived(svedit.session.get(path)); let accordion_layout = $derived(node.layout || 'narrow-left'); - let padding_top_wide = $derived(!section || section?.is_start); - let padding_bottom_wide = $derived(!section || section?.is_end); + let padding_top_generous = $derived(!section || section.is_start); + let padding_bottom_generous = $derived(!section || section.is_end); {#snippet narrow_left()} -
+
-
+
@@ -30,14 +30,14 @@ {#snippet narrow_center()} -
+
-
+
@@ -47,14 +47,14 @@ {#snippet narrow_right()} -
+
-
+
@@ -64,12 +64,12 @@ {#snippet full_width()} -
+
@@ -82,12 +82,12 @@ {#snippet two_columns()} -
+
diff --git a/src/app/components/App.svelte b/src/app/components/App.svelte index 8c9685b5..fcd13256 100644 --- a/src/app/components/App.svelte +++ b/src/app/components/App.svelte @@ -1,5 +1,5 @@ {#snippet primary()} @@ -27,9 +40,9 @@ @@ -40,18 +53,19 @@ {/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/components/CaptionedFigure.svelte b/src/app/components/CaptionedFigure.svelte index 93b81188..42d742c9 100644 --- a/src/app/components/CaptionedFigure.svelte +++ b/src/app/components/CaptionedFigure.svelte @@ -9,8 +9,8 @@ let node: Nodes['captioned_figure'] = $derived(svedit.session.get(path)); let media_node = $derived(svedit.session.get([...path, 'media'])); let render_as_link = $derived(!svedit.editable && node.href); - let padding_top_wide = $derived(!section || section?.is_start); - let padding_bottom_wide = $derived(!section || section?.is_end); + let padding_top_generous = $derived(!section || section.is_start); + let padding_bottom_generous = $derived(!section || section.is_end); @@ -18,8 +18,8 @@
{content} diff --git a/src/app/components/DescriptiveGallery.svelte b/src/app/components/DescriptiveGallery.svelte index 96273e35..520cd078 100644 --- a/src/app/components/DescriptiveGallery.svelte +++ b/src/app/components/DescriptiveGallery.svelte @@ -7,17 +7,17 @@ const svedit = get_svedit_context(); let node: Nodes['descriptive_gallery'] = $derived(svedit.session.get(path)); let layout = $derived(node.layout || 'cards'); - let padding_top_wide = $derived(!section || section?.is_start); - let padding_bottom_wide = $derived(!section || section?.is_end); + let padding_top_generous = $derived(!section || section.is_start); + let padding_bottom_generous = $derived(!section || section.is_end); -
+
@@ -49,7 +53,7 @@ this={render_as_link ? 'a' : 'div'} href={render_as_link ? node.href : undefined} target={render_as_link ? node.target : undefined} - class="flex items-center gap-5 outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing) sm:gap-7" + class="group/gallery-link flex items-center gap-5 outline-1 outline-transparent focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-(--editing) sm:gap-7" use:reveal >
diff --git a/src/app/components/DescriptiveListing.svelte b/src/app/components/DescriptiveListing.svelte index 488a2338..b6889e38 100644 --- a/src/app/components/DescriptiveListing.svelte +++ b/src/app/components/DescriptiveListing.svelte @@ -7,20 +7,20 @@ let { path, mark: section = null } = $props(); let node: Nodes['descriptive_listing'] = $derived(svedit.session.get(path)); let listing_layout = $derived(node.layout || 'narrow-left'); - let padding_top_wide = $derived(!section || section?.is_start); - let padding_bottom_wide = $derived(!section || section?.is_end); + let padding_top_generous = $derived(!section || section.is_start); + let padding_bottom_generous = $derived(!section || section.is_end); {#snippet narrow_left()} -
+
-
+
@@ -30,14 +30,14 @@ {#snippet narrow_center()} -
+
-
+
@@ -47,14 +47,14 @@ {#snippet narrow_right()} -
+
-
+
@@ -64,12 +64,12 @@ {#snippet full_width()} -
+
@@ -82,12 +82,12 @@ {#snippet two_columns()} -
+
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/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/EditLink.svelte b/src/app/components/EditLink.svelte index ba90cc88..c49898ef 100644 --- a/src/app/components/EditLink.svelte +++ b/src/app/components/EditLink.svelte @@ -171,28 +171,26 @@ -
-
-
+
+
+
{#if app.has_backend}
-
-
diff --git a/src/app/components/Page.svelte b/src/app/components/Page.svelte index c4c38914..2810ff0a 100644 --- a/src/app/components/Page.svelte +++ b/src/app/components/Page.svelte @@ -142,7 +142,11 @@ /> {/if}
- + {#if !svedit.editable && app.page_content} + {@render app.page_content()} + {:else} + + {/if}