diff --git a/src/app/components/Zap.svelte b/src/app/components/Zap.svelte
index 619c8d4e..21b0a35c 100644
--- a/src/app/components/Zap.svelte
+++ b/src/app/components/Zap.svelte
@@ -1,5 +1,4 @@
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Avatar.svelte b/src/lib/components2/Avatar.svelte
new file mode 100644
index 00000000..19f5bb3f
--- /dev/null
+++ b/src/lib/components2/Avatar.svelte
@@ -0,0 +1,40 @@
+
+
+{#if src}
+
+{:else}
+
+ {#if children}{@render children()}{:else}{initials}{/if}
+
+{/if}
diff --git a/src/lib/components2/Badge.svelte b/src/lib/components2/Badge.svelte
new file mode 100644
index 00000000..7ecf064d
--- /dev/null
+++ b/src/lib/components2/Badge.svelte
@@ -0,0 +1,31 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Button.svelte b/src/lib/components2/Button.svelte
new file mode 100644
index 00000000..3489b134
--- /dev/null
+++ b/src/lib/components2/Button.svelte
@@ -0,0 +1,62 @@
+
+
+{#if type === "submit"}
+
+ {@render children?.()}
+
+{:else}
+
+ {@render children?.()}
+
+{/if}
diff --git a/src/lib/components2/ButtonGroup.svelte b/src/lib/components2/ButtonGroup.svelte
new file mode 100644
index 00000000..dcbb8b41
--- /dev/null
+++ b/src/lib/components2/ButtonGroup.svelte
@@ -0,0 +1,90 @@
+
+
+
+ {@render children?.()}
+
+
+
diff --git a/src/lib/components2/COMPONENTS.md b/src/lib/components2/COMPONENTS.md
new file mode 100644
index 00000000..4bd7df13
--- /dev/null
+++ b/src/lib/components2/COMPONENTS.md
@@ -0,0 +1,83 @@
+# components2 — claymorphism component library
+
+A **fresh, independent** Svelte 5 component library. Visual language extracted
+from `pawspa/` (claymorphism: soft offset shadows, 3px borders, big radii,
+Nunito headings + Quicksand body, warm orange palette).
+
+## Hard rules (apply to every file in this directory and to app refactors)
+
+1. **No daisyui.** Never use `btn`, `card`, `input`, `badge`, `modal`,
+ `bg-base-*`, `text-base-content`, `text-primary` (daisyui), `loading-spinner`,
+ `divider`, `menu`, etc.
+2. **Do not use `src/app.css` utilities** — no `row-2`, `col-2`, `col-3`,
+ `card2`, `center`, `link`, `heading`, `subheading`, `bg-alt`, `content`, etc.
+ (Tailwind safe-area utilities like `pb-sai`/`pt-sai` and the `z-*` scale ARE
+ shared infra and may stay.)
+3. **Styling comes from `theme.css` semantic classes** (`clay-card`, `btn-cl*`,
+ `badge-cl*`, `input-cl*`, `cl-surface*`, `cl-text*`, `cl-border*`,
+ `cl-gradient-text`, `cl-divider`, `cl-icon-tile`, `cl-spinner`, `cl-link`)
+ **plus core Tailwind utilities for layout only** (flex/grid/gap/spacing/
+ sizing/positioning/responsive). No arbitrary color/shadow/radius values
+ (`bg-[#..]`, `shadow-[..]`, `rounded-[..]`). Use tokens via the classes above
+ or `var(--cl-*)` in a local `style=`.
+4. **Theme scope:** the root app element carries the `cl` class (added by the
+ foundation step) so `--cl-*` tokens resolve everywhere. Library components
+ themselves do not need to repeat `cl`.
+5. Svelte 5 runes only (`$props`, `$state`, `$derived`, snippets). Match the
+ prop API of the component being ported so call sites keep working.
+
+## Layout & typography primitives (build these — app code uses them instead of raw flex utilities where it reads cleanly)
+
+- `Row.svelte` — `flex items-center`, prop `gap` (default 2) → `gap-{n}`, passthrough class/children.
+- `Col.svelte` — `flex flex-col`, prop `gap` (default 2).
+- `Stack.svelte` — vertical stack with `gap` default 4 (sections).
+- `Center.svelte` — `flex items-center justify-center`.
+- `Grid.svelte` — `grid`, props `cols`, `gap`.
+- `Heading.svelte` — prop `level` (1-4) → sized heading, `cl-text`, Nunito.
+- `Text.svelte` — body text, props `muted`, `subtle`, `size` (sm/base/lg).
+
+## Core primitives (build these)
+
+- `Button.svelte` — keep existing API (`children`, `onclick`, `type`, `disabled`,
+ passthrough `class`, `data-tip`, `aria-pressed`). Add props
+ `variant` ("primary"|"secondary"|"ghost"|"danger", default "ghost"),
+ `size` ("sm"|"md"|"lg"), `circle`, `block`. Renders `btn-cl btn-cl-{variant} ...`.
+ Preserve the preventDefault/stopPropagation onclick behavior.
+- `Card.svelte` — `clay-card` wrapper; props `interactive`, `featured`, `sm`,
+ `tag` (default div), padding prop `pad` (default true → `p-4 sm:p-6`).
+- `CardButton.svelte` — port existing (icon/title/info snippets) onto a
+ `clay-card clay-card-interactive` row with trailing chevron.
+- `Badge.svelte` — `badge-cl badge-cl-{variant}`; variants primary/accent/neutral/danger; `sm`.
+- `Input.svelte` — text input using `input-cl`; passthrough value (bindable), placeholder, type, disabled.
+- `Textarea.svelte` — `input-cl` multiline, auto min-height.
+- `Select.svelte` — native select styled with `input-cl`.
+- `Field.svelte` — port (label/secondary/input/info snippets); label uses `label-cl`, info uses `cl-text-subtle text-sm`.
+- `FieldInline.svelte` — port inline variant.
+- `Divider.svelte` — port → `cl-divider` (empty variant `cl-divider-empty` when no children).
+- `Spinner.svelte` — port → `cl-spinner`; keep `loading` + children slide/fade behavior.
+- `StatusIndicator.svelte` — port; colored dot via `style` token + label.
+- `Link.svelte` — port (keep goto/external logic); optional `styled` prop → `cl-link`.
+- `Icon.svelte`, `ImageIcon.svelte`, `IconPickerButton.svelte`, `EmojiButton.svelte`,
+ `EmojiPicker.svelte` — port keeping behavior; restyle containers with theme classes.
+- `Alert.svelte` (new) — variants info/success/warning/danger using token colors + `clay-card-sm`.
+- `Avatar.svelte` (new) — round image, `cl-border`, sizes; fallback initials.
+- `Stat.svelte` (new) — big number (`cl-gradient-text` optional) + label, used for counts.
+
+## Overlays / nav / inputs (port, restyle, keep behavior + API)
+
+Modal, ModalHeader, ModalBody, ModalFooter, ModalTitle, ModalSubtitle, Dialog,
+Drawer, Popover, Tippy, Tooltip, Confirm, FAB, Scanner, ContentSearch,
+DateTimeInput, ImagesInput, InputList, StringMultiInput, SuggestionString,
+Suggestions, TapTarget, CurrencySymbol, Page, PageBar, PageContent, PageHeader,
+PrimaryNavItem, SecondaryNav, SecondaryNavHeader, SecondaryNavItem,
+SecondaryNavSection.
+
+For each: keep the same filename, props, snippets, and behavior as the original
+in `src/lib/components/`; only swap daisyui/app.css classes + ad-hoc styling for
+theme.css classes and core Tailwind layout utilities. Overlays keep the existing
+`z-modal`/`z-popover`/etc. scale.
+
+## Index
+
+Provide `src/lib/components2/index.ts` re-exporting nothing required, but each
+component is imported directly via `@lib/components2/
.svelte`.
diff --git a/src/lib/components2/Card.svelte b/src/lib/components2/Card.svelte
new file mode 100644
index 00000000..2aba7877
--- /dev/null
+++ b/src/lib/components2/Card.svelte
@@ -0,0 +1,42 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/CardButton.svelte b/src/lib/components2/CardButton.svelte
new file mode 100644
index 00000000..f23cbf36
--- /dev/null
+++ b/src/lib/components2/CardButton.svelte
@@ -0,0 +1,50 @@
+
+
+
+
+
+ {@render icon?.()}
+
+
+
+ {@render title?.()}
+
+
+ {@render info?.()}
+
+
+
+
+ {#if trailing}
+ {@render trailing()}
+ {:else}
+
+ {/if}
+
+
diff --git a/src/lib/components2/Center.svelte b/src/lib/components2/Center.svelte
new file mode 100644
index 00000000..ba0b1d1e
--- /dev/null
+++ b/src/lib/components2/Center.svelte
@@ -0,0 +1,14 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Checkbox.svelte b/src/lib/components2/Checkbox.svelte
new file mode 100644
index 00000000..b0e0857a
--- /dev/null
+++ b/src/lib/components2/Checkbox.svelte
@@ -0,0 +1,32 @@
+
+
+
diff --git a/src/lib/components2/Col.svelte b/src/lib/components2/Col.svelte
new file mode 100644
index 00000000..40a27e0e
--- /dev/null
+++ b/src/lib/components2/Col.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Confirm.svelte b/src/lib/components2/Confirm.svelte
new file mode 100644
index 00000000..777fcd07
--- /dev/null
+++ b/src/lib/components2/Confirm.svelte
@@ -0,0 +1,57 @@
+
+
+
+
+
+ {restProps.title || "Are you sure?"}
+ {subtitle}
+
+ {message}
+
+
+
+
+ Go back
+
+
+ Confirm
+
+
+
+
diff --git a/src/lib/components2/ContentPill.svelte b/src/lib/components2/ContentPill.svelte
new file mode 100644
index 00000000..d1c2f912
--- /dev/null
+++ b/src/lib/components2/ContentPill.svelte
@@ -0,0 +1,53 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/ContentSearch.svelte b/src/lib/components2/ContentSearch.svelte
new file mode 100644
index 00000000..0d5df146
--- /dev/null
+++ b/src/lib/components2/ContentSearch.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
+ {@render props.input?.()}
+
+
+
+ {@render props.content?.()}
+
+
diff --git a/src/lib/components2/CurrencySymbol.svelte b/src/lib/components2/CurrencySymbol.svelte
new file mode 100644
index 00000000..99e86f42
--- /dev/null
+++ b/src/lib/components2/CurrencySymbol.svelte
@@ -0,0 +1,11 @@
+
+
+{#if code.match(/^sats?$/i)}
+ !
+{:else}
+ {currencyOptions.find(c => c.code)?.symbol || code}
+{/if}
diff --git a/src/lib/components2/DataTip.svelte b/src/lib/components2/DataTip.svelte
new file mode 100644
index 00000000..d522ba1f
--- /dev/null
+++ b/src/lib/components2/DataTip.svelte
@@ -0,0 +1,75 @@
+
+
+
+
+ {@render children?.()}
+ {#if tip}
+
+ {tip}
+
+
+ {/if}
+
diff --git a/src/lib/components2/DateTimeInput.svelte b/src/lib/components2/DateTimeInput.svelte
new file mode 100644
index 00000000..b794c544
--- /dev/null
+++ b/src/lib/components2/DateTimeInput.svelte
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+ {#if date}
+
+
+
+ {:else}
+
+
+
+ {/if}
+
+
+
+
+
+
diff --git a/src/lib/components2/Dialog.svelte b/src/lib/components2/Dialog.svelte
new file mode 100644
index 00000000..cb814274
--- /dev/null
+++ b/src/lib/components2/Dialog.svelte
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+ {#if !noEscape}
+
+
+
+ {/if}
+
+
+
+
diff --git a/src/lib/components2/Divider.svelte b/src/lib/components2/Divider.svelte
new file mode 100644
index 00000000..06ec0360
--- /dev/null
+++ b/src/lib/components2/Divider.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {#if children}
+
{@render children?.()}
+ {/if}
+
diff --git a/src/lib/components2/Drawer.svelte b/src/lib/components2/Drawer.svelte
new file mode 100644
index 00000000..42742f3d
--- /dev/null
+++ b/src/lib/components2/Drawer.svelte
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/lib/components2/EmojiButton.svelte b/src/lib/components2/EmojiButton.svelte
new file mode 100644
index 00000000..a9256c55
--- /dev/null
+++ b/src/lib/components2/EmojiButton.svelte
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components2/EmojiPicker.svelte b/src/lib/components2/EmojiPicker.svelte
new file mode 100644
index 00000000..dabccb7c
--- /dev/null
+++ b/src/lib/components2/EmojiPicker.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+
diff --git a/src/lib/components2/FAB.svelte b/src/lib/components2/FAB.svelte
new file mode 100644
index 00000000..5d8a5727
--- /dev/null
+++ b/src/lib/components2/FAB.svelte
@@ -0,0 +1,23 @@
+
+
+
+
+
+ {@render children?.()}
+
+
+
diff --git a/src/lib/components2/Field.svelte b/src/lib/components2/Field.svelte
new file mode 100644
index 00000000..8e02eeab
--- /dev/null
+++ b/src/lib/components2/Field.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+ {#if label}
+
+ {@render label()}
+
+ {/if}
+ {#if secondary}
+
+ {@render secondary()}
+
+ {/if}
+
+ {@render input?.()}
+ {#if info}
+
+ {@render info()}
+
+ {/if}
+
diff --git a/src/lib/components2/FieldInline.svelte b/src/lib/components2/FieldInline.svelte
new file mode 100644
index 00000000..db03c315
--- /dev/null
+++ b/src/lib/components2/FieldInline.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+ {#if props.label}
+
+ {@render props.label()}
+
+ {/if}
+
+ {#if props.input}
+ {@render props.input()}
+ {/if}
+
+
+ {#if props.info}
+
+ {@render props.info()}
+
+ {/if}
+
diff --git a/src/lib/components2/Grid.svelte b/src/lib/components2/Grid.svelte
new file mode 100644
index 00000000..de645bbe
--- /dev/null
+++ b/src/lib/components2/Grid.svelte
@@ -0,0 +1,16 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Heading.svelte b/src/lib/components2/Heading.svelte
new file mode 100644
index 00000000..343f7b09
--- /dev/null
+++ b/src/lib/components2/Heading.svelte
@@ -0,0 +1,28 @@
+
+
+{#if level === 1}
+ {@render children()}
+{:else if level === 2}
+ {@render children()}
+{:else if level === 3}
+ {@render children()}
+{:else}
+ {@render children()}
+{/if}
diff --git a/src/lib/components2/Hoverable.svelte b/src/lib/components2/Hoverable.svelte
new file mode 100644
index 00000000..9f46fe4e
--- /dev/null
+++ b/src/lib/components2/Hoverable.svelte
@@ -0,0 +1,78 @@
+
+
+
+ {@render children?.()}
+
+
+
diff --git a/src/lib/components2/Icon.svelte b/src/lib/components2/Icon.svelte
new file mode 100644
index 00000000..5de2a64f
--- /dev/null
+++ b/src/lib/components2/Icon.svelte
@@ -0,0 +1,72 @@
+
+
+
+
+
+
diff --git a/src/lib/components2/IconPickerButton.svelte b/src/lib/components2/IconPickerButton.svelte
new file mode 100644
index 00000000..ba14b167
--- /dev/null
+++ b/src/lib/components2/IconPickerButton.svelte
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+ {@render props.children?.()}
+
+
diff --git a/src/lib/components2/ImageIcon.svelte b/src/lib/components2/ImageIcon.svelte
new file mode 100644
index 00000000..0a03ce41
--- /dev/null
+++ b/src/lib/components2/ImageIcon.svelte
@@ -0,0 +1,21 @@
+
+
+{#if src.includes("image/svg") || src.endsWith(".svg")}
+
+{:else}
+
+{/if}
diff --git a/src/lib/components2/ImagesInput.svelte b/src/lib/components2/ImagesInput.svelte
new file mode 100644
index 00000000..0ee444d2
--- /dev/null
+++ b/src/lib/components2/ImagesInput.svelte
@@ -0,0 +1,131 @@
+
+
+
+
+ {#each value as item, index (index)}
+
handleDragStart(e, index)}
+ ondragover={e => handleDragOver(e, index)}
+ ondragend={handleDragEnd}>
+
+
removeItem(index)}>
+
+
+
+ {/each}
+
+
+
+
Drag and drop images or click to select
+
+
+
+
+
diff --git a/src/lib/components2/Input.svelte b/src/lib/components2/Input.svelte
new file mode 100644
index 00000000..5076a37a
--- /dev/null
+++ b/src/lib/components2/Input.svelte
@@ -0,0 +1,30 @@
+
+
+
diff --git a/src/lib/components2/InputList.svelte b/src/lib/components2/InputList.svelte
new file mode 100644
index 00000000..94c3413b
--- /dev/null
+++ b/src/lib/components2/InputList.svelte
@@ -0,0 +1,90 @@
+
+
+
+ {#each value as item, index}
+
handleDragStart(e, index)}
+ ondragover={e => handleDragOver(e, index)}
+ ondragend={handleDragEnd}>
+
removeItem(index)}>
+
+
+
updateItem(index, e.currentTarget.value)} />
+
+
+
+
+ {/each}
+ {#if allowAdd}
+
+
+ {#if addLabel}
+ {@render addLabel?.()}
+ {:else}
+ Add Item
+ {/if}
+
+ {/if}
+
diff --git a/src/lib/components2/Link.svelte b/src/lib/components2/Link.svelte
new file mode 100644
index 00000000..00718b15
--- /dev/null
+++ b/src/lib/components2/Link.svelte
@@ -0,0 +1,41 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Modal.svelte b/src/lib/components2/Modal.svelte
new file mode 100644
index 00000000..e755aea1
--- /dev/null
+++ b/src/lib/components2/Modal.svelte
@@ -0,0 +1,17 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/ModalBody.svelte b/src/lib/components2/ModalBody.svelte
new file mode 100644
index 00000000..85c67ea8
--- /dev/null
+++ b/src/lib/components2/ModalBody.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/ModalFooter.svelte b/src/lib/components2/ModalFooter.svelte
new file mode 100644
index 00000000..efcd14ab
--- /dev/null
+++ b/src/lib/components2/ModalFooter.svelte
@@ -0,0 +1,18 @@
+
+
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components2/ModalHeader.svelte b/src/lib/components2/ModalHeader.svelte
new file mode 100644
index 00000000..f0a0f26a
--- /dev/null
+++ b/src/lib/components2/ModalHeader.svelte
@@ -0,0 +1,13 @@
+
+
+
+ {@render children()}
+
diff --git a/src/lib/components2/ModalSubtitle.svelte b/src/lib/components2/ModalSubtitle.svelte
new file mode 100644
index 00000000..9761c18c
--- /dev/null
+++ b/src/lib/components2/ModalSubtitle.svelte
@@ -0,0 +1,11 @@
+
+
+{@render children()}
diff --git a/src/lib/components2/ModalTitle.svelte b/src/lib/components2/ModalTitle.svelte
new file mode 100644
index 00000000..020ef7a4
--- /dev/null
+++ b/src/lib/components2/ModalTitle.svelte
@@ -0,0 +1,11 @@
+
+
+{@render children()}
diff --git a/src/lib/components2/NoteCard.svelte b/src/lib/components2/NoteCard.svelte
new file mode 100644
index 00000000..23bfafc9
--- /dev/null
+++ b/src/lib/components2/NoteCard.svelte
@@ -0,0 +1,91 @@
+
+
+
+ {#if muted}
+
+
+
+ You have muted this person.
+
+
Show anyway
+
+ {:else}
+
+ {#if !hideProfile}
+ {#if minimal}
+
@
+ {:else}
+
+ {/if}
+ {/if}
+
goToEvent(event)}>
+ {formatTimestamp(event.created_at)}
+
+
+ {@render children()}
+ {/if}
+
diff --git a/src/lib/components2/Page.svelte b/src/lib/components2/Page.svelte
new file mode 100644
index 00000000..9f62b6e7
--- /dev/null
+++ b/src/lib/components2/Page.svelte
@@ -0,0 +1,14 @@
+
+
+
+ {@render props.children?.()}
+
diff --git a/src/lib/components2/PageBar.svelte b/src/lib/components2/PageBar.svelte
new file mode 100644
index 00000000..36709cb7
--- /dev/null
+++ b/src/lib/components2/PageBar.svelte
@@ -0,0 +1,16 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/PageContent.svelte b/src/lib/components2/PageContent.svelte
new file mode 100644
index 00000000..6da09e00
--- /dev/null
+++ b/src/lib/components2/PageContent.svelte
@@ -0,0 +1,23 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/PageHeader.svelte b/src/lib/components2/PageHeader.svelte
new file mode 100644
index 00000000..1373d383
--- /dev/null
+++ b/src/lib/components2/PageHeader.svelte
@@ -0,0 +1,13 @@
+
+
+
+
{@render title?.()}
+
{@render info?.()}
+
diff --git a/src/lib/components2/Popover.svelte b/src/lib/components2/Popover.svelte
new file mode 100644
index 00000000..bfed4528
--- /dev/null
+++ b/src/lib/components2/Popover.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components2/PrimaryNavItem.svelte b/src/lib/components2/PrimaryNavItem.svelte
new file mode 100644
index 00000000..d0d4035d
--- /dev/null
+++ b/src/lib/components2/PrimaryNavItem.svelte
@@ -0,0 +1,53 @@
+
+
+
diff --git a/src/lib/components2/Progress.svelte b/src/lib/components2/Progress.svelte
new file mode 100644
index 00000000..6ad09e3b
--- /dev/null
+++ b/src/lib/components2/Progress.svelte
@@ -0,0 +1,24 @@
+
+
+
diff --git a/src/lib/components2/Quote.svelte b/src/lib/components2/Quote.svelte
new file mode 100644
index 00000000..1289e99d
--- /dev/null
+++ b/src/lib/components2/Quote.svelte
@@ -0,0 +1,31 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Row.svelte b/src/lib/components2/Row.svelte
new file mode 100644
index 00000000..6b6b4d52
--- /dev/null
+++ b/src/lib/components2/Row.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Scanner.svelte b/src/lib/components2/Scanner.svelte
new file mode 100644
index 00000000..44bb6d2f
--- /dev/null
+++ b/src/lib/components2/Scanner.svelte
@@ -0,0 +1,67 @@
+
+
+
+ {#if loading}
+
+ Loading your camera...
+
+ {/if}
+
+ {#if cameras.length > 1}
+
+ {#each cameras as camera}
+ {camera.label || `Camera ${camera.id}`}
+ {/each}
+
+ {/if}
+
diff --git a/src/lib/components2/Scrim.svelte b/src/lib/components2/Scrim.svelte
new file mode 100644
index 00000000..93ebd71c
--- /dev/null
+++ b/src/lib/components2/Scrim.svelte
@@ -0,0 +1,82 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/SecondaryNav.svelte b/src/lib/components2/SecondaryNav.svelte
new file mode 100644
index 00000000..44311543
--- /dev/null
+++ b/src/lib/components2/SecondaryNav.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/SecondaryNavHeader.svelte b/src/lib/components2/SecondaryNavHeader.svelte
new file mode 100644
index 00000000..d15f77ff
--- /dev/null
+++ b/src/lib/components2/SecondaryNavHeader.svelte
@@ -0,0 +1,11 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/SecondaryNavItem.svelte b/src/lib/components2/SecondaryNavItem.svelte
new file mode 100644
index 00000000..ef415adc
--- /dev/null
+++ b/src/lib/components2/SecondaryNavItem.svelte
@@ -0,0 +1,72 @@
+
+
+
+
+{#if href}
+
+ {@render children?.()}
+ {#if notification}
+
+
+ {/if}
+
+{:else}
+
+ {#if notification}
+
+
+ {/if}
+ {@render children?.()}
+
+{/if}
diff --git a/src/lib/components2/SecondaryNavSection.svelte b/src/lib/components2/SecondaryNavSection.svelte
new file mode 100644
index 00000000..0c1b7017
--- /dev/null
+++ b/src/lib/components2/SecondaryNavSection.svelte
@@ -0,0 +1,12 @@
+
+
+
+ {@render props.children?.()}
+
diff --git a/src/lib/components2/Select.svelte b/src/lib/components2/Select.svelte
new file mode 100644
index 00000000..4f4682f6
--- /dev/null
+++ b/src/lib/components2/Select.svelte
@@ -0,0 +1,29 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/SignerStatus.svelte b/src/lib/components2/SignerStatus.svelte
new file mode 100644
index 00000000..520fcdd1
--- /dev/null
+++ b/src/lib/components2/SignerStatus.svelte
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+ {current.label}
+
+ {#if children}
+ {@render children()}
+ {/if}
+
diff --git a/src/lib/components2/Spinner.svelte b/src/lib/components2/Spinner.svelte
new file mode 100644
index 00000000..e0378cb5
--- /dev/null
+++ b/src/lib/components2/Spinner.svelte
@@ -0,0 +1,19 @@
+
+
+
+ {#if loading}
+
+
+
+ {/if}
+ {@render children?.()}
+
diff --git a/src/lib/components2/Stack.svelte b/src/lib/components2/Stack.svelte
new file mode 100644
index 00000000..e68b1b53
--- /dev/null
+++ b/src/lib/components2/Stack.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Stat.svelte b/src/lib/components2/Stat.svelte
new file mode 100644
index 00000000..11f878d1
--- /dev/null
+++ b/src/lib/components2/Stat.svelte
@@ -0,0 +1,23 @@
+
+
+
+
+ {#if label}
+ {label}
+ {/if}
+ {#if children}
+ {@render children()}
+ {/if}
+
diff --git a/src/lib/components2/StatusIcon.svelte b/src/lib/components2/StatusIcon.svelte
new file mode 100644
index 00000000..39bf0769
--- /dev/null
+++ b/src/lib/components2/StatusIcon.svelte
@@ -0,0 +1,35 @@
+
+
+
+
+
diff --git a/src/lib/components2/StatusIndicator.svelte b/src/lib/components2/StatusIndicator.svelte
new file mode 100644
index 00000000..0fcd6991
--- /dev/null
+++ b/src/lib/components2/StatusIndicator.svelte
@@ -0,0 +1,21 @@
+
+
+
+
+
+
{@render children()}
+
diff --git a/src/lib/components2/StringMultiInput.svelte b/src/lib/components2/StringMultiInput.svelte
new file mode 100644
index 00000000..9887300c
--- /dev/null
+++ b/src/lib/components2/StringMultiInput.svelte
@@ -0,0 +1,76 @@
+
+
+
+
+ {#each value as item (item)}
+
+ removeItem(item)}>
+
+
+ {item}
+
+ {/each}
+
+
+
+
+
diff --git a/src/lib/components2/SuggestionString.svelte b/src/lib/components2/SuggestionString.svelte
new file mode 100644
index 00000000..c19d2614
--- /dev/null
+++ b/src/lib/components2/SuggestionString.svelte
@@ -0,0 +1,5 @@
+
+
+{value}
diff --git a/src/lib/components2/Suggestions.svelte b/src/lib/components2/Suggestions.svelte
new file mode 100644
index 00000000..a594df18
--- /dev/null
+++ b/src/lib/components2/Suggestions.svelte
@@ -0,0 +1,83 @@
+
+
+
+
+ {#if $term && allowCreate && !items.includes($term)}
+
select($term)))}>
+ Use " "
+
+ {/if}
+ {#each items as value, i (value)}
+
select(value)))}>
+
+
+ {:else}
+
No results
+ {/each}
+
+
diff --git a/src/lib/components2/Surface.svelte b/src/lib/components2/Surface.svelte
new file mode 100644
index 00000000..9747bf64
--- /dev/null
+++ b/src/lib/components2/Surface.svelte
@@ -0,0 +1,60 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Switch.svelte b/src/lib/components2/Switch.svelte
new file mode 100644
index 00000000..8c65adfc
--- /dev/null
+++ b/src/lib/components2/Switch.svelte
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/src/lib/components2/TapTarget.svelte b/src/lib/components2/TapTarget.svelte
new file mode 100644
index 00000000..7645096c
--- /dev/null
+++ b/src/lib/components2/TapTarget.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children()}
+
diff --git a/src/lib/components2/Text.svelte b/src/lib/components2/Text.svelte
new file mode 100644
index 00000000..f08dd7f4
--- /dev/null
+++ b/src/lib/components2/Text.svelte
@@ -0,0 +1,28 @@
+
+
+{@render children()}
diff --git a/src/lib/components2/Textarea.svelte b/src/lib/components2/Textarea.svelte
new file mode 100644
index 00000000..1e41227e
--- /dev/null
+++ b/src/lib/components2/Textarea.svelte
@@ -0,0 +1,30 @@
+
+
+
diff --git a/src/lib/components2/Tippy.svelte b/src/lib/components2/Tippy.svelte
new file mode 100644
index 00000000..82919022
--- /dev/null
+++ b/src/lib/components2/Tippy.svelte
@@ -0,0 +1,41 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/Toggle.svelte b/src/lib/components2/Toggle.svelte
new file mode 100644
index 00000000..d9166985
--- /dev/null
+++ b/src/lib/components2/Toggle.svelte
@@ -0,0 +1,86 @@
+
+
+
+
+
diff --git a/src/lib/components2/Tooltip.svelte b/src/lib/components2/Tooltip.svelte
new file mode 100644
index 00000000..5d434e48
--- /dev/null
+++ b/src/lib/components2/Tooltip.svelte
@@ -0,0 +1,67 @@
+
+
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components2/theme.css b/src/lib/components2/theme.css
new file mode 100644
index 00000000..d2897d60
--- /dev/null
+++ b/src/lib/components2/theme.css
@@ -0,0 +1,574 @@
+/*
+ * components2 — claymorphism design system
+ * Extracted from pawspa (UI UX Pro Max "pet grooming" reference).
+ *
+ * This file is INDEPENDENT of daisyui and of src/app.css. It does not use,
+ * extend, or reference any daisyui token (bg-base-*, btn, card, …) or any
+ * app.css utility (row-2, col-2, card2, …). It is plain CSS: design tokens as
+ * custom properties + a set of semantic component classes. components2 .svelte
+ * files compose these classes together with core Tailwind utilities only.
+ *
+ * Theme it by overriding the custom properties under [data-theme].
+ */
+
+@font-face {
+ font-family: "Nunito";
+ font-style: normal;
+ font-weight: 400 800;
+ font-display: swap;
+ src: local("Nunito"), url("https://fonts.gstatic.com/s/nunito/v31/XRXV3I6Li01BKofINeaBTMnFcQ.woff2") format("woff2");
+}
+
+@font-face {
+ font-family: "Quicksand";
+ font-style: normal;
+ font-weight: 400 700;
+ font-display: swap;
+ src: local("Quicksand"), url("https://fonts.gstatic.com/s/quicksand/v36/6xK-dSZaM9iE8KbpRA_LJ3z8mH9BOJvgkP8o58a-wg.woff2") format("woff2");
+}
+
+/* ---- Tokens: light (default) ---- */
+
+.cl,
+[data-theme="light"] .cl {
+ --cl-primary: #ff8c42;
+ --cl-primary-hi: #ff9f5a;
+ --cl-primary-content: #ffffff;
+ --cl-secondary: #ffd166;
+ --cl-accent: #06d6a0;
+ --cl-pink: #ff6b9d;
+ --cl-purple: #a78bfa;
+ --cl-blue: #60a5fa;
+ --cl-danger: #ef476f;
+
+ --cl-bg: #fff9f5;
+ --cl-bg-alt: #fff3eb;
+ --cl-card: #ffffff;
+
+ --cl-text: #2d3436;
+ --cl-muted: #636e72;
+ --cl-subtle: #b2bec3;
+ --cl-border: #ffe4d6;
+
+ /* rgb channels used to tint the soft offset clay shadows */
+ --cl-shadow-rgb: 255 140 66;
+
+ --cl-r-card: 24px;
+ --cl-r-btn: 16px;
+ --cl-r-input: 16px;
+ --cl-r-icon: 20px;
+ --cl-r-pill: 9999px;
+
+ --cl-font-heading: "Nunito", ui-sans-serif, system-ui, sans-serif;
+ --cl-font-body: "Quicksand", ui-sans-serif, system-ui, sans-serif;
+
+ font-family: var(--cl-font-body);
+ color: var(--cl-text);
+ background-color: var(--cl-bg);
+}
+
+/* ---- Tokens: dark ---- */
+
+[data-theme="dark"] .cl,
+.cl.cl-dark {
+ --cl-primary: #ff8c42;
+ --cl-primary-hi: #ffa867;
+ --cl-primary-content: #1b1410;
+ --cl-secondary: #ffd166;
+ --cl-accent: #06d6a0;
+ --cl-pink: #ff6b9d;
+ --cl-purple: #a78bfa;
+ --cl-blue: #60a5fa;
+ --cl-danger: #ff6b8b;
+
+ --cl-bg: #1c1714;
+ --cl-bg-alt: #251e19;
+ --cl-card: #2a221d;
+
+ --cl-text: #f5ece6;
+ --cl-muted: #b9a89d;
+ --cl-subtle: #7d6f66;
+ --cl-border: #3a2f28;
+
+ --cl-shadow-rgb: 0 0 0;
+}
+
+/* ---- Base typography ---- */
+
+.cl :where(h1, h2, h3, h4, h5, h6) {
+ font-family: var(--cl-font-heading);
+ font-weight: 700;
+ color: var(--cl-text);
+}
+
+/* ===================================================================== */
+/* Semantic helpers — color / surface / text */
+/* ===================================================================== */
+
+.cl-surface {
+ background-color: var(--cl-card);
+ color: var(--cl-text);
+}
+.cl-surface-alt {
+ background-color: var(--cl-bg-alt);
+ color: var(--cl-text);
+}
+.cl-surface-base {
+ background-color: var(--cl-bg);
+ color: var(--cl-text);
+}
+
+.cl-text {
+ color: var(--cl-text);
+}
+.cl-text-muted {
+ color: var(--cl-muted);
+}
+.cl-text-subtle {
+ color: var(--cl-subtle);
+}
+.cl-text-primary {
+ color: var(--cl-primary);
+}
+.cl-text-accent {
+ color: var(--cl-accent);
+}
+.cl-text-warning {
+ color: var(--cl-secondary);
+}
+.cl-text-danger {
+ color: var(--cl-danger);
+}
+
+.cl-border {
+ border: 3px solid var(--cl-border);
+}
+.cl-border-t {
+ border-top: 3px solid var(--cl-border);
+}
+.cl-border-b {
+ border-bottom: 3px solid var(--cl-border);
+}
+
+.cl-gradient-text {
+ background: linear-gradient(135deg, var(--cl-primary) 0%, var(--cl-pink) 100%);
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+ color: transparent;
+}
+
+/* ===================================================================== */
+/* Cards */
+/* ===================================================================== */
+
+.clay-card {
+ background: var(--cl-card);
+ color: var(--cl-text);
+ border-radius: var(--cl-r-card);
+ border: 3px solid var(--cl-border);
+ box-shadow:
+ 8px 8px 0 rgb(var(--cl-shadow-rgb) / 0.15),
+ inset 0 -4px 0 rgb(0 0 0 / 0.05);
+}
+
+.clay-card-interactive {
+ transition: all 0.3s ease;
+ cursor: pointer;
+}
+.clay-card-interactive:hover {
+ transform: translateY(-4px);
+ box-shadow:
+ 12px 12px 0 rgb(var(--cl-shadow-rgb) / 0.2),
+ inset 0 -4px 0 rgb(0 0 0 / 0.05);
+}
+
+.clay-card-sm {
+ border-radius: var(--cl-r-icon);
+ box-shadow:
+ 6px 6px 0 rgb(var(--cl-shadow-rgb) / 0.1),
+ inset 0 -4px 0 rgb(0 0 0 / 0.03);
+}
+
+.clay-card-featured {
+ border-color: var(--cl-primary);
+ box-shadow: 8px 8px 0 rgb(var(--cl-shadow-rgb) / 0.2);
+}
+
+/* ===================================================================== */
+/* Buttons */
+/* ===================================================================== */
+
+.btn-cl {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ font-family: var(--cl-font-heading);
+ font-weight: 700;
+ padding: 0.75rem 1.5rem;
+ border-radius: var(--cl-r-btn);
+ border: 3px solid transparent;
+ transition: all 0.2s ease;
+ cursor: pointer;
+ user-select: none;
+ line-height: 1.2;
+}
+.btn-cl:disabled,
+.btn-cl[aria-disabled="true"] {
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+.btn-cl-primary {
+ background: linear-gradient(135deg, var(--cl-primary) 0%, var(--cl-primary-hi) 100%);
+ color: var(--cl-primary-content);
+ border-color: rgb(0 0 0 / 0.1);
+ box-shadow:
+ 4px 4px 0 rgb(var(--cl-shadow-rgb) / 0.3),
+ inset 0 -3px 0 rgb(0 0 0 / 0.1);
+}
+.btn-cl-primary:hover {
+ transform: translateY(-2px);
+ box-shadow:
+ 6px 6px 0 rgb(var(--cl-shadow-rgb) / 0.4),
+ inset 0 -3px 0 rgb(0 0 0 / 0.1);
+}
+.btn-cl-primary:active {
+ transform: translateY(2px);
+ box-shadow:
+ 2px 2px 0 rgb(var(--cl-shadow-rgb) / 0.3),
+ inset 0 -1px 0 rgb(0 0 0 / 0.1);
+}
+
+.btn-cl-secondary {
+ background: var(--cl-card);
+ color: var(--cl-primary);
+ border-color: var(--cl-primary);
+ box-shadow: 4px 4px 0 rgb(var(--cl-shadow-rgb) / 0.2);
+}
+.btn-cl-secondary:hover {
+ background: var(--cl-primary);
+ color: var(--cl-primary-content);
+ transform: translateY(-2px);
+}
+
+.btn-cl-ghost {
+ background: transparent;
+ color: var(--cl-muted);
+ border-color: transparent;
+ box-shadow: none;
+}
+.btn-cl-ghost:hover {
+ color: var(--cl-primary);
+ background: var(--cl-bg-alt);
+}
+
+.btn-cl-accent {
+ background: linear-gradient(135deg, var(--cl-accent) 0%, var(--cl-blue) 100%);
+ color: #ffffff;
+ border-color: rgb(0 0 0 / 0.1);
+ box-shadow:
+ 4px 4px 0 rgb(6 214 160 / 0.3),
+ inset 0 -3px 0 rgb(0 0 0 / 0.1);
+}
+.btn-cl-accent:hover {
+ transform: translateY(-2px);
+ box-shadow:
+ 6px 6px 0 rgb(6 214 160 / 0.4),
+ inset 0 -3px 0 rgb(0 0 0 / 0.1);
+}
+.btn-cl-accent:active {
+ transform: translateY(2px);
+ box-shadow:
+ 2px 2px 0 rgb(6 214 160 / 0.3),
+ inset 0 -1px 0 rgb(0 0 0 / 0.1);
+}
+
+.btn-cl-danger {
+ background: var(--cl-danger);
+ color: #fff;
+ border-color: rgb(0 0 0 / 0.1);
+ box-shadow: 4px 4px 0 rgb(0 0 0 / 0.12);
+}
+.btn-cl-danger:hover {
+ transform: translateY(-2px);
+}
+
+/* size + shape modifiers */
+.btn-cl-sm {
+ padding: 0.4rem 0.9rem;
+ font-size: 0.875rem;
+ border-width: 2px;
+}
+.btn-cl-lg {
+ padding: 1rem 2rem;
+ font-size: 1.0625rem;
+}
+.btn-cl-block {
+ width: 100%;
+}
+.btn-cl-circle {
+ padding: 0;
+ width: 2.75rem;
+ height: 2.75rem;
+ border-radius: var(--cl-r-pill);
+}
+.btn-cl-circle.btn-cl-sm {
+ width: 2rem;
+ height: 2rem;
+}
+.btn-cl-square {
+ padding: 0;
+ width: 2.75rem;
+ height: 2.75rem;
+ border-radius: var(--cl-r-btn);
+}
+.btn-cl-square.btn-cl-sm {
+ width: 2rem;
+ height: 2rem;
+}
+
+/* ===================================================================== */
+/* Badges / chips */
+/* ===================================================================== */
+
+.badge-cl {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.4rem 0.85rem;
+ border-radius: var(--cl-r-pill);
+ font-size: 0.8125rem;
+ font-weight: 600;
+ border: 2px solid transparent;
+ white-space: nowrap;
+ line-height: 1.1;
+}
+.badge-cl-primary {
+ background: rgb(255 140 66 / 0.1);
+ color: var(--cl-primary);
+ border-color: rgb(255 140 66 / 0.2);
+}
+.badge-cl-accent {
+ background: rgb(6 214 160 / 0.1);
+ color: var(--cl-accent);
+ border-color: rgb(6 214 160 / 0.2);
+}
+.badge-cl-neutral {
+ background: var(--cl-bg-alt);
+ color: var(--cl-muted);
+ border-color: var(--cl-border);
+}
+.badge-cl-danger {
+ background: rgb(239 71 111 / 0.12);
+ color: var(--cl-danger);
+ border-color: rgb(239 71 111 / 0.25);
+}
+.badge-cl-sm {
+ padding: 0.15rem 0.5rem;
+ font-size: 0.6875rem;
+ gap: 0.25rem;
+}
+
+/* ===================================================================== */
+/* Form controls */
+/* ===================================================================== */
+
+.input-cl {
+ width: 100%;
+ padding: 0.85rem 1rem;
+ border: 3px solid var(--cl-border);
+ border-radius: var(--cl-r-input);
+ font-family: var(--cl-font-body);
+ font-size: 1rem;
+ background: var(--cl-card);
+ color: var(--cl-text);
+ box-shadow: inset 0 2px 4px rgb(0 0 0 / 0.04);
+ transition: all 0.2s ease;
+}
+.input-cl::placeholder {
+ color: var(--cl-subtle);
+}
+.input-cl:focus,
+.input-cl:focus-within {
+ outline: none;
+ border-color: var(--cl-primary);
+ box-shadow:
+ 0 0 0 4px rgb(255 140 66 / 0.12),
+ inset 0 2px 4px rgb(0 0 0 / 0.04);
+}
+.input-cl:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+/* lets us wrap inputs with leading/trailing icons */
+.input-cl-group {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+.input-cl-group > input,
+.input-cl-group > .input-cl-bare {
+ flex: 1 1 auto;
+ min-width: 0;
+ border: none;
+ outline: none;
+ background: transparent;
+ color: inherit;
+ font: inherit;
+}
+.input-cl-sm {
+ padding: 0.5rem 0.75rem;
+ border-width: 2px;
+ font-size: 0.875rem;
+}
+
+.label-cl {
+ font-family: var(--cl-font-heading);
+ font-weight: 700;
+ color: var(--cl-text);
+ font-size: 0.9375rem;
+}
+
+/* ===================================================================== */
+/* Misc */
+/* ===================================================================== */
+
+.cl-divider {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.75rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--cl-subtle);
+}
+.cl-divider::before,
+.cl-divider::after {
+ content: "";
+ flex: 1 1 auto;
+ height: 3px;
+ border-radius: 9999px;
+ background: var(--cl-border);
+}
+.cl-divider-empty::after {
+ display: none;
+}
+
+.cl-icon-tile {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--cl-r-icon);
+ border: 3px solid rgb(0 0 0 / 0.05);
+ box-shadow: inset 0 -3px 0 rgb(0 0 0 / 0.05);
+}
+
+.cl-spinner {
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+ border: 3px solid rgb(var(--cl-shadow-rgb) / 0.25);
+ border-top-color: var(--cl-primary);
+ border-radius: 9999px;
+ animation: cl-spin 0.7s linear infinite;
+}
+@keyframes cl-spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.cl-link {
+ color: var(--cl-primary);
+ font-weight: 600;
+ cursor: pointer;
+ text-decoration: underline;
+ text-underline-offset: 2px;
+}
+.cl-link:hover {
+ color: var(--cl-primary-hi);
+}
+
+.cl-divider-soft {
+ height: 3px;
+ border-radius: 9999px;
+ background: var(--cl-border);
+}
+
+/* ===================================================================== */
+/* CSS-only tooltip — renders the `data-tip` attribute on hover/focus. */
+/* Token-driven replacement for the daisyui `tooltip`/`tooltip-*` classes. */
+/* Apply `cl-tip` (+ a placement modifier) to an element carrying data-tip. */
+/* ===================================================================== */
+
+.cl-tip {
+ position: relative;
+}
+.cl-tip::after {
+ content: attr(data-tip);
+ position: absolute;
+ z-index: 8;
+ white-space: nowrap;
+ padding: 0.25rem 0.5rem;
+ border-radius: var(--cl-r-btn);
+ background-color: var(--cl-text);
+ color: var(--cl-card);
+ font-size: 0.8125rem;
+ font-weight: 500;
+ line-height: 1.2;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.15s ease;
+ box-shadow: 0 4px 6px -1px rgb(var(--cl-shadow-rgb) / 0.2);
+ /* default placement: top */
+ bottom: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+ margin-bottom: 0.4rem;
+}
+.cl-tip:hover::after,
+.cl-tip:focus-within::after {
+ opacity: 1;
+}
+.cl-tip-top::after {
+ bottom: 100%;
+ left: 50%;
+ right: auto;
+ top: auto;
+ transform: translateX(-50%);
+ margin: 0 0 0.4rem 0;
+}
+.cl-tip-bottom::after {
+ top: 100%;
+ left: 50%;
+ right: auto;
+ bottom: auto;
+ transform: translateX(-50%);
+ margin: 0.4rem 0 0 0;
+}
+.cl-tip-left::after {
+ right: 100%;
+ top: 50%;
+ left: auto;
+ bottom: auto;
+ transform: translateY(-50%);
+ margin: 0 0.4rem 0 0;
+}
+.cl-tip-right::after {
+ left: 100%;
+ top: 50%;
+ right: auto;
+ bottom: auto;
+ transform: translateY(-50%);
+ margin: 0 0 0 0.4rem;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .clay-card-interactive,
+ .btn-cl,
+ .input-cl {
+ transition: none;
+ }
+}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 210610a0..69b06218 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,5 +1,6 @@