diff --git a/package.json b/package.json
index 35a62cdf..b339ded6 100644
--- a/package.json
+++ b/package.json
@@ -79,6 +79,7 @@
"modern-normalize": "^3.0.1",
"runed": "^0.31.1",
"svelecte": "^5.3.0",
+ "svelte-sonner": "^1.0.7",
"wx-grid-data-provider": "^2.2.0",
"wx-svelte-grid": "^2.0.0",
"zod": "^4.1.5"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 055d92bb..d3095916 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -47,6 +47,9 @@ importers:
svelecte:
specifier: ^5.3.0
version: 5.3.0(svelte@5.38.7)
+ svelte-sonner:
+ specifier: ^1.0.7
+ version: 1.0.7(svelte@5.38.7)
wx-grid-data-provider:
specifier: ^2.2.0
version: 2.2.0
@@ -2390,6 +2393,11 @@ packages:
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ runed@0.28.0:
+ resolution: {integrity: sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==}
+ peerDependencies:
+ svelte: ^5.7.0
+
runed@0.29.2:
resolution: {integrity: sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA==}
peerDependencies:
@@ -2557,6 +2565,11 @@ packages:
typescript:
optional: true
+ svelte-sonner@1.0.7:
+ resolution: {integrity: sha512-1EUFYmd7q/xfs2qCHwJzGPh9n5VJ3X6QjBN10fof2vxgy8fYE7kVfZ7uGnd7i6fQaWIr5KvXcwYXE/cmTEjk5A==}
+ peerDependencies:
+ svelte: ^5.0.0
+
svelte-toolbelt@0.9.3:
resolution: {integrity: sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw==}
engines: {node: '>=18', pnpm: '>=8.7.0'}
@@ -5279,6 +5292,11 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
+ runed@0.28.0(svelte@5.38.7):
+ dependencies:
+ esm-env: 1.2.2
+ svelte: 5.38.7
+
runed@0.29.2(svelte@5.38.7):
dependencies:
esm-env: 1.2.2
@@ -5424,6 +5442,11 @@ snapshots:
sass: 1.92.1
typescript: 5.9.2
+ svelte-sonner@1.0.7(svelte@5.38.7):
+ dependencies:
+ runed: 0.28.0(svelte@5.38.7)
+ svelte: 5.38.7
+
svelte-toolbelt@0.9.3(svelte@5.38.7):
dependencies:
clsx: 2.1.1
diff --git a/src/app.scss b/src/app.scss
index e60ca740..7d9d4256 100644
--- a/src/app.scss
+++ b/src/app.scss
@@ -78,3 +78,35 @@ $font-size-base: 16px;
padding: 0;
cursor: pointer;
}
+
+// Toast notification overrides (svelte-sonner)
+[data-sonner-toaster] {
+ --normal-bg: var(--toast-bg);
+ --normal-text: var(--toast-text);
+ --normal-border: var(--toast-border);
+
+ --success-bg: var(--toast-success-bg);
+ --success-text: var(--toast-success-text);
+ --success-border: var(--toast-success-text);
+
+ --error-bg: var(--toast-error-bg);
+ --error-text: var(--toast-error-text);
+ --error-border: var(--toast-error-text);
+
+ --warning-bg: var(--toast-warning-bg);
+ --warning-text: var(--toast-warning-text);
+ --warning-border: var(--toast-warning-text);
+
+ --info-bg: var(--toast-info-bg);
+ --info-text: var(--toast-info-text);
+ --info-border: var(--toast-info-text);
+
+ font-family: var(--font-family);
+ z-index: 102; // Above dialogs (101)
+}
+
+[data-sonner-toast] {
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ font-size: 1.4rem;
+}
diff --git a/src/lib/components/ui/CopyableText.svelte b/src/lib/components/ui/CopyableText.svelte
index b92fab43..fce52c94 100644
--- a/src/lib/components/ui/CopyableText.svelte
+++ b/src/lib/components/ui/CopyableText.svelte
@@ -1,44 +1,35 @@
-