diff --git a/web/src/app.css b/web/src/app.css
index f19f899d..0bec7dc2 100644
--- a/web/src/app.css
+++ b/web/src/app.css
@@ -80,6 +80,47 @@
--color-shadow-inner-subtle: #e5e7eb;
--shadow-menu: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
+
+ /* --- alpha --- */
+ --color-alpha-light-5: color-mix(in srgb, var(--color-background-default) 5%, transparent);
+ --color-alpha-light-10: color-mix(in srgb, var(--color-background-default) 10%, transparent);
+ --color-alpha-light-15: color-mix(in srgb, var(--color-background-default) 15%, transparent);
+ --color-alpha-light-20: color-mix(in srgb, var(--color-background-default) 20%, transparent);
+ --color-alpha-light-25: color-mix(in srgb, var(--color-background-default) 25%, transparent);
+ --color-alpha-light-30: color-mix(in srgb, var(--color-background-default) 30%, transparent);
+ --color-alpha-light-35: color-mix(in srgb, var(--color-background-default) 35%, transparent);
+ --color-alpha-light-40: color-mix(in srgb, var(--color-background-default) 40%, transparent);
+ --color-alpha-light-45: color-mix(in srgb, var(--color-background-default) 45%, transparent);
+ --color-alpha-light-50: color-mix(in srgb, var(--color-background-default) 50%, transparent);
+ --color-alpha-light-55: color-mix(in srgb, var(--color-background-default) 55%, transparent);
+ --color-alpha-light-60: color-mix(in srgb, var(--color-background-default) 60%, transparent);
+ --color-alpha-light-65: color-mix(in srgb, var(--color-background-default) 65%, transparent);
+ --color-alpha-light-70: color-mix(in srgb, var(--color-background-default) 70%, transparent);
+ --color-alpha-light-75: color-mix(in srgb, var(--color-background-default) 75%, transparent);
+ --color-alpha-light-80: color-mix(in srgb, var(--color-background-default) 80%, transparent);
+ --color-alpha-light-85: color-mix(in srgb, var(--color-background-default) 85%, transparent);
+ --color-alpha-light-90: color-mix(in srgb, var(--color-background-default) 90%, transparent);
+ --color-alpha-light-95: color-mix(in srgb, var(--color-background-default) 95%, transparent);
+
+ --color-alpha-dark-5: color-mix(in srgb, var(--color-foreground-default) 5%, transparent);
+ --color-alpha-dark-10: color-mix(in srgb, var(--color-foreground-default) 10%, transparent);
+ --color-alpha-dark-15: color-mix(in srgb, var(--color-foreground-default) 15%, transparent);
+ --color-alpha-dark-20: color-mix(in srgb, var(--color-foreground-default) 20%, transparent);
+ --color-alpha-dark-25: color-mix(in srgb, var(--color-foreground-default) 25%, transparent);
+ --color-alpha-dark-30: color-mix(in srgb, var(--color-foreground-default) 30%, transparent);
+ --color-alpha-dark-35: color-mix(in srgb, var(--color-foreground-default) 35%, transparent);
+ --color-alpha-dark-40: color-mix(in srgb, var(--color-foreground-default) 40%, transparent);
+ --color-alpha-dark-45: color-mix(in srgb, var(--color-foreground-default) 45%, transparent);
+ --color-alpha-dark-50: color-mix(in srgb, var(--color-foreground-default) 50%, transparent);
+ --color-alpha-dark-55: color-mix(in srgb, var(--color-foreground-default) 55%, transparent);
+ --color-alpha-dark-60: color-mix(in srgb, var(--color-foreground-default) 60%, transparent);
+ --color-alpha-dark-65: color-mix(in srgb, var(--color-foreground-default) 65%, transparent);
+ --color-alpha-dark-70: color-mix(in srgb, var(--color-foreground-default) 70%, transparent);
+ --color-alpha-dark-75: color-mix(in srgb, var(--color-foreground-default) 75%, transparent);
+ --color-alpha-dark-80: color-mix(in srgb, var(--color-foreground-default) 80%, transparent);
+ --color-alpha-dark-85: color-mix(in srgb, var(--color-foreground-default) 85%, transparent);
+ --color-alpha-dark-90: color-mix(in srgb, var(--color-foreground-default) 90%, transparent);
+ --color-alpha-dark-95: color-mix(in srgb, var(--color-foreground-default) 95%, transparent);
}
@layer base {
diff --git a/web/src/lib/components/profile/FollowButton.svelte b/web/src/lib/components/profile/FollowButton.svelte
index 4389c095..4249503c 100644
--- a/web/src/lib/components/profile/FollowButton.svelte
+++ b/web/src/lib/components/profile/FollowButton.svelte
@@ -1,4 +1,5 @@
+{#snippet content()}
+ {#if loading}
+
+ {:else}
+ {#if Icon}
+
+ {/if}
+ {#if children}
+ {@render children()}
+ {/if}
+ {/if}
+{/snippet}
+
{#if href}
-
- {#if loading}
-
- {:else if children}
- {@render children()}
- {/if}
+ {@render content()}
{:else}
{/if}
diff --git a/web/src/lib/components/ui/ButtonCard.svelte b/web/src/lib/components/ui/ButtonCard.svelte
index df5f120d..5cab483c 100644
--- a/web/src/lib/components/ui/ButtonCard.svelte
+++ b/web/src/lib/components/ui/ButtonCard.svelte
@@ -2,13 +2,24 @@
import { tv, type VariantProps } from "tailwind-variants";
export const buttonCard = tv({
- base: "flex cursor-pointer select-none items-start gap-3 rounded p-3 text-left no-underline transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
+ base: "flex gap-3 rounded-(--btn-radius) [--btn-radius:var(--radius-sm)] px-4 py-3 w-48 h-40 cursor-pointer select-none no-underline transition-colors duration-150 ease-in-out \
+ hover:no-underline \
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus \
+ disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
variants: {
variant: {
default: "border border-border-default bg-background-default hover:bg-background-subtle",
- ghost: "bg-transparent hover:bg-background-inset"
+ ghost: "border border-transparent bg-transparent hover:bg-background-inset"
}
},
+ compoundVariants: [
+ // raised variants draw inset depth via a ::before layer.
+ {
+ variant: "default",
+ class:
+ "relative z-0 before:absolute before:inset-0 before:-z-10 before:rounded-[max(calc(var(--btn-radius)-2px),0px)] before:content-[''] before:shadow-[inset_0_-2px_0_0_var(--color-shadow-inner-subtle)] before:transition-all before:duration-150 hover:before:shadow-[inset_0_-2px_0_0_var(--color-shadow-inner-strong-hover)] active:translate-y-0.5 active:before:shadow-[inset_0_2px_2px_0_var(--color-shadow-inner-subtle)] disabled:active:translate-y-0"
+ }
+ ],
defaultVariants: {
variant: "default"
}
@@ -18,7 +29,7 @@
+{#snippet content()}
+
+ {#if title}
+
+ {#if Icon}
+
+ {/if}
+ {title}
+
+ {/if}
+ {#if description}
+
{description}
+ {/if}
+
+{/snippet}
+
{#if href}
-
- {#if Icon}
-
- {/if}
- {#if children}
- {@render children()}
- {:else}
-
- {#if title}
- {title}
- {/if}
- {#if description}
- {description}
- {/if}
-
- {/if}
+ {@render (children ?? content)()}
{:else}
{/if}
diff --git a/web/src/lib/components/ui/ButtonGroup.svelte b/web/src/lib/components/ui/ButtonGroup.svelte
index 4838bb14..ac5a55da 100644
--- a/web/src/lib/components/ui/ButtonGroup.svelte
+++ b/web/src/lib/components/ui/ButtonGroup.svelte
@@ -7,7 +7,11 @@
spaced: {
true: "gap-2",
false:
- "gap-0 [&>*]:relative [&>*:not(:first-child)]:-ml-px [&>*:not(:first-child)]:rounded-l-none [&>*:not(:last-child)]:rounded-r-none [&>*:hover]:z-10 [&>*:focus-visible]:z-10"
+ "gap-0 \
+ [&>*]:relative \
+ [&>*:not(:first-child)]:[--btn-radius-l:0px] [&>*:not(:first-child)]:-ml-px \
+ [&>*:not(:last-child)]:[--btn-radius-r:0px] \
+ [&>*:hover]:z-10 [&>*:focus-visible]:z-10"
}
},
defaultVariants: {
diff --git a/web/src/lib/components/ui/Checkbox.svelte b/web/src/lib/components/ui/Checkbox.svelte
index 0cf875d7..4fb159ef 100644
--- a/web/src/lib/components/ui/Checkbox.svelte
+++ b/web/src/lib/components/ui/Checkbox.svelte
@@ -22,7 +22,7 @@
}: Props = $props();
const labelClasses = $derived(
- `inline-flex items-center gap-2 cursor-pointer ${disabled ? "cursor-not-allowed text-foreground-disabled" : ""} ${className ?? ""}`
+ `inline-flex items-center gap-2 ${disabled ? "text-foreground-disabled hover:pointer-events-none" : "cursor-pointer"} ${className ?? ""}`
);
@@ -33,15 +33,22 @@
bind:checked
bind:indeterminate
{disabled}
- class="peer size-4 shrink-0 appearance-none rounded border border-border-strong bg-background-default transition-colors duration-150 hover:bg-background-subtle checked:border-foreground-default checked:bg-foreground-default indeterminate:border-foreground-default indeterminate:bg-foreground-default focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground-default disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-50"
+ class="peer size-4 shrink-0 appearance-none rounded border border-border-default bg-background-default transition-colors duration-150 \
+ hover:bg-background-inset hover:cursor-pointer \
+ checked:border-foreground-default checked:bg-foreground-default checked:hover:bg-gray-700 \
+ indeterminate:border-foreground-default indeterminate:bg-foreground-default indeterminate:hover:bg-gray-700 \
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground-default \
+ disabled:hover:bg-background-default disabled:hover:pointer-events-none"
{...rest}
/>
diff --git a/web/src/lib/components/ui/Field.stories.svelte b/web/src/lib/components/ui/Field.stories.svelte
index 35baa6e6..f0592292 100644
--- a/web/src/lib/components/ui/Field.stories.svelte
+++ b/web/src/lib/components/ui/Field.stories.svelte
@@ -22,55 +22,65 @@
-
-
-
+ {#snippet template(args)}
+
+
+
+ {/snippet}
-
-
-
-
+
+ {#snippet template(args)}
+
+
+
+ {/snippet}
-
-
-
-
+
+ {#snippet template(args)}
+
+
+
+ {/snippet}
-
-
-
+ {#snippet template(args)}
+
+
+
+ {/snippet}
-
-
-
+ {#snippet template(args)}
+
+
+
+ {/snippet}
diff --git a/web/src/lib/components/ui/Field.svelte b/web/src/lib/components/ui/Field.svelte
index ce7d6337..e2ab58d9 100644
--- a/web/src/lib/components/ui/Field.svelte
+++ b/web/src/lib/components/ui/Field.svelte
@@ -27,15 +27,15 @@
{#if label}
-
diff --git a/web/src/lib/components/ui/Input.svelte b/web/src/lib/components/ui/Input.svelte
index 8b007375..5498db0e 100644
--- a/web/src/lib/components/ui/Input.svelte
+++ b/web/src/lib/components/ui/Input.svelte
@@ -2,7 +2,7 @@
import { tv, type VariantProps } from "tailwind-variants";
export const inputField = tv({
- base: "flex items-center gap-2 rounded border bg-background-default px-3 py-2 text-sm transition-colors",
+ base: "flex items-center gap-2 rounded border bg-background-default px-2 py-1 min-h-8 transition-colors",
variants: {
error: {
false:
diff --git a/web/src/lib/components/ui/Logo.stories.svelte b/web/src/lib/components/ui/Logo.stories.svelte
index e4c1f3d5..99e290d1 100644
--- a/web/src/lib/components/ui/Logo.stories.svelte
+++ b/web/src/lib/components/ui/Logo.stories.svelte
@@ -18,9 +18,34 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/lib/components/ui/Logo.svelte b/web/src/lib/components/ui/Logo.svelte
index e502c4d6..7cc1a17d 100644
--- a/web/src/lib/components/ui/Logo.svelte
+++ b/web/src/lib/components/ui/Logo.svelte
@@ -8,7 +8,32 @@
{#if wordmark}
-
+
{:else}
-
+
{/if}
diff --git a/web/src/routes/+error.svelte b/web/src/routes/+error.svelte
index cba5243c..ab92e6a8 100644
--- a/web/src/routes/+error.svelte
+++ b/web/src/routes/+error.svelte
@@ -1,4 +1,5 @@