@atmo-dev/kit 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -429
- package/dist/components/AccountMenu.svelte +7 -7
- package/dist/components/Avatar.svelte +1 -1
- package/dist/components/Badge.svelte +3 -3
- package/dist/components/Button.svelte +4 -3
- package/dist/components/Checkbox.svelte +31 -1
- package/dist/{events → components}/DatePicker.svelte +3 -3
- package/dist/components/ExternalEmbed.svelte +9 -6
- package/dist/components/GrainAlbumPicker.svelte +18 -9
- package/dist/components/GrainAlbumView.svelte +15 -6
- package/dist/components/Heading.svelte +1 -1
- package/dist/components/IconRail.svelte +11 -9
- package/dist/components/InlineEditor.svelte +3 -3
- package/dist/components/InsetImage.svelte +1 -1
- package/dist/components/Label.svelte +1 -1
- package/dist/components/LinkCard.svelte +6 -4
- package/dist/components/Modal.svelte +3 -3
- package/dist/components/NestedComments.svelte +9 -6
- package/dist/components/PhotoGrid.svelte +1 -1
- package/dist/components/Popover.svelte +1 -1
- package/dist/components/PostComposer.svelte +2 -2
- package/dist/components/PostContent.svelte +11 -9
- package/dist/components/PostVideo.svelte +1 -1
- package/dist/components/RichText.svelte +19 -7
- package/dist/components/Select.svelte +5 -2
- package/dist/components/Select.svelte.d.ts +2 -0
- package/dist/components/SocialClientPicker.svelte +1 -1
- package/dist/components/StreamplacePicker.svelte +1 -1
- package/dist/components/Subheading.svelte +4 -2
- package/dist/components/Surface.svelte +3 -2
- package/dist/components/Tabs.svelte +2 -2
- package/dist/{events → components}/TimePicker.svelte +10 -7
- package/dist/{events → components}/TimezonePicker.svelte +15 -7
- package/dist/components/ToggleGroup.svelte +1 -1
- package/dist/components/ToggleGroupItem.svelte +1 -1
- package/dist/components/UserProfile.svelte +16 -9
- package/dist/components/WorkspaceSidebar.svelte +1 -1
- package/dist/components/legal/LegalDocument.svelte +9 -3
- package/dist/components/legal/LegalFooter.svelte +2 -2
- package/dist/components/login/ActorSearchField.svelte +10 -6
- package/dist/components/login/AtmosphereApps.svelte +1 -1
- package/dist/components/login/LoginForm.svelte +15 -9
- package/dist/components/login/PermissionFields.svelte +9 -2
- package/dist/components/login/RecentAccounts.svelte +5 -3
- package/dist/events/EventAttendees.svelte +9 -3
- package/dist/events/EventCard.svelte +7 -5
- package/dist/events/EventComments.svelte +3 -3
- package/dist/events/EventEditor.svelte +20 -9
- package/dist/events/EventRsvp.svelte +10 -6
- package/dist/events/EventView.svelte +21 -7
- package/dist/events/StarterPackButton.svelte +3 -3
- package/dist/events/ThemePicker.svelte +7 -7
- package/dist/events/ThumbnailPresets.svelte +1 -1
- package/dist/events/VodPlayer.svelte +1 -1
- package/dist/events/editor/LinksSection.svelte +7 -3
- package/dist/events/editor/LocationSection.svelte +1 -1
- package/dist/events/editor/RecurringModal.svelte +6 -4
- package/dist/events/editor/ThemeSection.svelte +3 -1
- package/dist/events/event-view/EventDateBlock.svelte +3 -3
- package/dist/events/event-view/EventHostedBy.svelte +6 -2
- package/dist/events/event-view/EventLinksList.svelte +2 -2
- package/dist/events/event-view/EventLocationBlock.svelte +9 -5
- package/dist/events/event-view/EventLocationMap.svelte +4 -2
- package/dist/events/schedule/ConferenceTimetable.svelte +7 -7
- package/dist/events/schedule/DaySchedule.svelte +2 -2
- package/dist/events/schedule/ScheduleEventCell.svelte +2 -2
- package/dist/events/themes/Matrix.svelte +12 -6
- package/dist/events.d.ts +5 -5
- package/dist/events.js +6 -5
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/social/mention-suggestions.js +4 -4
- package/dist/styles.d.ts +2 -2
- package/dist/styles.js +2 -2
- package/dist/theme.css +23 -44
- package/dist/theme.js +4 -12
- package/package.json +1 -1
- /package/dist/{events → components}/DatePicker.svelte.d.ts +0 -0
- /package/dist/{events → components}/DateTimePicker.svelte +0 -0
- /package/dist/{events → components}/DateTimePicker.svelte.d.ts +0 -0
- /package/dist/{events → components}/ImageDropper.svelte +0 -0
- /package/dist/{events → components}/ImageDropper.svelte.d.ts +0 -0
- /package/dist/{events → components}/TimePicker.svelte.d.ts +0 -0
- /package/dist/{events → components}/TimezonePicker.svelte.d.ts +0 -0
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
>{replacing ? 'Replace stream' : 'Add stream'}</Button
|
|
88
88
|
>
|
|
89
89
|
</div>
|
|
90
|
-
{#if replacing}<p class="mt-3 text-sm text-
|
|
90
|
+
{#if replacing}<p class="mt-3 text-sm text-base-600 dark:text-base-400">
|
|
91
91
|
This replaces the current Streamplace link.
|
|
92
92
|
</p>{/if}
|
|
93
93
|
{#if error}<p class="mt-3 text-sm text-red-600 dark:text-red-400" role="alert">{error}</p>{/if}
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
this={`h${level}`}
|
|
18
18
|
{...rest}
|
|
19
19
|
bind:this={ref}
|
|
20
|
-
class={cn(
|
|
21
|
-
|
|
20
|
+
class={cn(
|
|
21
|
+
'm-0 text-lg leading-snug font-medium tracking-tight text-base-950 dark:text-base-50',
|
|
22
|
+
className
|
|
23
|
+
)}>{@render children?.()}</svelte:element
|
|
22
24
|
>
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
bind:this={ref}
|
|
29
29
|
data-slot="surface"
|
|
30
30
|
class={cn(
|
|
31
|
-
'rounded-panel p-6 text-
|
|
32
|
-
variant === 'recessed' &&
|
|
31
|
+
'rounded-panel p-6 text-base-950 dark:text-base-50',
|
|
32
|
+
variant === 'recessed' &&
|
|
33
|
+
'border border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] shadow-[inset_0_2px_4px_color-mix(in_srgb,var(--base-950)_8%,transparent),inset_0_5px_12px_color-mix(in_srgb,var(--base-950)_2%,transparent)] dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-950 dark:shadow-[inset_0_2px_4px_#0006,inset_0_5px_12px_#0002]',
|
|
33
34
|
as === 'button' &&
|
|
34
35
|
cn(
|
|
35
36
|
'cursor-pointer touch-manipulation disabled:pointer-events-none disabled:opacity-45',
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
<Primitive.Root {...rest} bind:value class={cn('min-w-0', className)}>
|
|
30
30
|
<Primitive.List
|
|
31
31
|
aria-label={label}
|
|
32
|
-
class="flex w-fit max-w-full flex-wrap items-center gap-1 rounded-[12px_14px_11px_13px] border border-
|
|
32
|
+
class="flex w-fit max-w-full flex-wrap items-center gap-1 rounded-[12px_14px_11px_13px] border border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] p-1 shadow-[inset_0_2px_4px_color-mix(in_srgb,var(--base-950)_8%,transparent)] dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-950 dark:shadow-[inset_0_2px_4px_#0006]"
|
|
33
33
|
>
|
|
34
34
|
{#each items as item (item.value)}<Primitive.Trigger
|
|
35
35
|
value={item.value}
|
|
36
36
|
disabled={item.disabled}
|
|
37
37
|
class={cn(
|
|
38
|
-
'cursor-pointer rounded-[8px_10px_7px_9px] px-3.5 py-1.75 text-[.8125rem] leading-normal text-
|
|
38
|
+
'cursor-pointer rounded-[8px_10px_7px_9px] px-3.5 py-1.75 text-[.8125rem] leading-normal text-base-600 hover:text-base-950 disabled:cursor-default disabled:opacity-45 data-[state=active]:bg-base-50 data-[state=active]:text-base-950 dark:text-base-400 dark:hover:text-base-50 dark:data-[state=active]:bg-base-900 dark:data-[state=active]:text-base-50',
|
|
39
39
|
focus
|
|
40
40
|
)}>{item.label}</Primitive.Trigger
|
|
41
41
|
>{/each}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import { TimeField } from 'bits-ui';
|
|
3
3
|
import { Time } from '@internationalized/date';
|
|
4
4
|
import { untrack } from 'svelte';
|
|
5
|
-
import
|
|
5
|
+
import Icon from './Icon.svelte';
|
|
6
|
+
import IconButton from './IconButton.svelte';
|
|
7
|
+
import Popover from './Popover.svelte';
|
|
6
8
|
import { Clock } from '@sketchyicons/svelte';
|
|
7
9
|
|
|
8
10
|
let {
|
|
@@ -59,7 +61,7 @@
|
|
|
59
61
|
</script>
|
|
60
62
|
|
|
61
63
|
<div
|
|
62
|
-
class="flex h-11 items-center gap-1 rounded-ui border border-
|
|
64
|
+
class="flex h-11 items-center gap-1 rounded-ui border border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] px-2 text-sm text-base-950 shadow-[inset_0_2px_4px_color-mix(in_srgb,var(--base-950)_8%,transparent),inset_0_5px_12px_color-mix(in_srgb,var(--base-950)_2%,transparent)] focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-accent-700 hover:border-base-400 dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-950 dark:text-base-50 dark:shadow-[inset_0_2px_4px_#0006,inset_0_5px_12px_#0002] dark:focus-within:outline-accent-300 dark:hover:border-base-700"
|
|
63
65
|
>
|
|
64
66
|
<TimeField.Root
|
|
65
67
|
bind:value={internalValue}
|
|
@@ -71,10 +73,11 @@
|
|
|
71
73
|
<TimeField.Label class="sr-only">{label}</TimeField.Label>
|
|
72
74
|
<TimeField.Input class="whitespace-nowrap">
|
|
73
75
|
{#snippet children({ segments })}{#each segments as segment, i (segment.part + i)}
|
|
74
|
-
{#if segment.part === 'literal'}<span class="text-
|
|
76
|
+
{#if segment.part === 'literal'}<span class="text-base-600 dark:text-base-400"
|
|
77
|
+
>{segment.value}</span
|
|
75
78
|
>{:else}<TimeField.Segment
|
|
76
79
|
part={segment.part}
|
|
77
|
-
class="rounded px-0.5 hover:bg-
|
|
80
|
+
class="rounded px-0.5 hover:bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] focus:bg-accent-50 focus:outline-none dark:hover:bg-base-950 dark:focus:bg-[color-mix(in_srgb,var(--accent-950)_65%,var(--base-950))]"
|
|
78
81
|
>{segment.value}</TimeField.Segment
|
|
79
82
|
>{/if}
|
|
80
83
|
{/each}{/snippet}
|
|
@@ -101,15 +104,15 @@
|
|
|
101
104
|
<div bind:this={listEl}>
|
|
102
105
|
{#each slots as slot (slot.key)}<button
|
|
103
106
|
type="button"
|
|
104
|
-
class="flex w-full items-center justify-between gap-4 rounded-ui px-3 py-1.5 text-left text-sm text-
|
|
107
|
+
class="flex w-full items-center justify-between gap-4 rounded-ui px-3 py-1.5 text-left text-sm text-base-950 hover:bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] aria-pressed:bg-accent-50 aria-pressed:text-accent-700 dark:text-base-50 dark:hover:bg-base-950 dark:aria-pressed:bg-[color-mix(in_srgb,var(--accent-950)_65%,var(--base-950))] dark:aria-pressed:text-accent-300"
|
|
105
108
|
aria-pressed={value === slot.key}
|
|
106
109
|
data-selected={value === slot.key ? '' : undefined}
|
|
107
110
|
onclick={() => {
|
|
108
111
|
value = slot.key;
|
|
109
112
|
isOpen = false;
|
|
110
113
|
}}
|
|
111
|
-
>{slot.label}{#if durationLabel(slot.key)}<span
|
|
112
|
-
>{durationLabel(slot.key)}</span
|
|
114
|
+
>{slot.label}{#if durationLabel(slot.key)}<span
|
|
115
|
+
class="text-xs text-base-600 dark:text-base-400">{durationLabel(slot.key)}</span
|
|
113
116
|
>{/if}</button
|
|
114
117
|
>{/each}
|
|
115
118
|
</div>
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import Button from './Button.svelte';
|
|
3
|
+
import Icon from './Icon.svelte';
|
|
4
|
+
import Input from './Input.svelte';
|
|
5
|
+
import Popover from './Popover.svelte';
|
|
3
6
|
import { Globe } from '@sketchyicons/svelte';
|
|
4
7
|
let { value = $bindable('') }: { value: string } = $props();
|
|
5
8
|
let isOpen = $state(false);
|
|
@@ -38,12 +41,12 @@
|
|
|
38
41
|
{#snippet trigger({ props })}<Button
|
|
39
42
|
{...props}
|
|
40
43
|
variant="secondary"
|
|
41
|
-
class="min-h-11 w-full justify-start gap-2.5 border-
|
|
44
|
+
class="min-h-11 w-full justify-start gap-2.5 border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] px-3 text-xs shadow-[inset_0_2px_4px_color-mix(in_srgb,var(--base-950)_8%,transparent),inset_0_5px_12px_color-mix(in_srgb,var(--base-950)_2%,transparent)] hover:border-base-400 dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-950 dark:shadow-[inset_0_2px_4px_#0006,inset_0_5px_12px_#0002] dark:hover:border-base-700"
|
|
42
45
|
aria-label={`Timezone: ${value}`}
|
|
43
46
|
>
|
|
44
|
-
<Icon img={Globe} size={17} class="text-
|
|
47
|
+
<Icon img={Globe} size={17} class="text-base-600 dark:text-base-400" />
|
|
45
48
|
<span class="min-w-0 flex-1 truncate text-left">{getCityName(value)}</span>
|
|
46
|
-
<span class="shrink-0 text-
|
|
49
|
+
<span class="shrink-0 text-base-600 dark:text-base-400">{getOffset(value)}</span>
|
|
47
50
|
</Button>{/snippet}
|
|
48
51
|
<Input
|
|
49
52
|
type="search"
|
|
@@ -55,14 +58,19 @@
|
|
|
55
58
|
<div class="max-h-60 overflow-y-auto">
|
|
56
59
|
{#each filtered as tz (tz)}<button
|
|
57
60
|
type="button"
|
|
58
|
-
class="flex w-full items-center justify-between gap-3 rounded-ui px-3 py-2 text-left text-xs text-
|
|
61
|
+
class="flex w-full items-center justify-between gap-3 rounded-ui px-3 py-2 text-left text-xs text-base-950 hover:bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] aria-pressed:bg-accent-50 aria-pressed:text-accent-700 dark:text-base-50 dark:hover:bg-base-950 dark:aria-pressed:bg-[color-mix(in_srgb,var(--accent-950)_65%,var(--base-950))] dark:aria-pressed:text-accent-300"
|
|
59
62
|
aria-pressed={value === tz}
|
|
60
63
|
onclick={() => {
|
|
61
64
|
value = tz;
|
|
62
65
|
isOpen = false;
|
|
63
66
|
search = '';
|
|
64
|
-
}}
|
|
67
|
+
}}
|
|
68
|
+
><span>{getCityName(tz)}</span><span class="text-base-600 dark:text-base-400"
|
|
69
|
+
>{getOffset(tz)}</span
|
|
70
|
+
></button
|
|
65
71
|
>{/each}
|
|
66
|
-
{#if !filtered.length}<p class="p-3 text-xs text-
|
|
72
|
+
{#if !filtered.length}<p class="p-3 text-xs text-base-600 dark:text-base-400">
|
|
73
|
+
No results
|
|
74
|
+
</p>{/if}
|
|
67
75
|
</div>
|
|
68
76
|
</Popover>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
bind:value
|
|
25
25
|
data-size={size}
|
|
26
26
|
class={cn(
|
|
27
|
-
'inline-flex flex-wrap gap-1 rounded-ui bg-
|
|
27
|
+
'inline-flex flex-wrap gap-1 rounded-ui bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] p-1 shadow-[inset_0_2px_4px_color-mix(in_srgb,var(--base-950)_8%,transparent),inset_0_5px_12px_color-mix(in_srgb,var(--base-950)_2%,transparent)] dark:bg-base-950 dark:shadow-[inset_0_2px_4px_#0006,inset_0_5px_12px_#0002]',
|
|
28
28
|
className
|
|
29
29
|
)}
|
|
30
30
|
>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<ToggleGroup.Item
|
|
17
17
|
{...rest}
|
|
18
18
|
class={cn(
|
|
19
|
-
'cursor-pointer rounded-ui px-3 py-1.5 text-xs font-medium text-
|
|
19
|
+
'cursor-pointer rounded-ui px-3 py-1.5 text-xs font-medium text-base-600 transition-colors duration-(--atmo-duration) hover:text-base-950 disabled:pointer-events-none disabled:opacity-45 data-[state=on]:bg-base-50 data-[state=on]:text-accent-700 motion-reduce:transition-none dark:text-base-400 dark:hover:text-base-50 dark:data-[state=on]:bg-base-900 dark:data-[state=on]:text-accent-300',
|
|
20
20
|
focus,
|
|
21
21
|
size === 'xs' && 'px-2 py-1 text-[.6875rem]',
|
|
22
22
|
className
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
let pronouns = $derived(profile.pronouns?.trim().toLowerCase());
|
|
51
51
|
</script>
|
|
52
52
|
|
|
53
|
-
<section class={cn('min-w-0 text-
|
|
53
|
+
<section class={cn('min-w-0 text-base-950 dark:text-base-50', className)} aria-label="Profile">
|
|
54
54
|
{#if banner}
|
|
55
55
|
<div
|
|
56
56
|
data-slot="profile-banner"
|
|
57
|
-
class="relative aspect-3/1 w-full overflow-hidden rounded-panel bg-
|
|
57
|
+
class="relative aspect-3/1 w-full overflow-hidden rounded-panel bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] dark:bg-base-950"
|
|
58
58
|
>
|
|
59
59
|
<img
|
|
60
60
|
src={banner}
|
|
@@ -75,7 +75,10 @@
|
|
|
75
75
|
{name}
|
|
76
76
|
src={safeProfileUrl(profile.avatar)}
|
|
77
77
|
size={96}
|
|
78
|
-
class={cn(
|
|
78
|
+
class={cn(
|
|
79
|
+
'relative size-20 sm:size-24',
|
|
80
|
+
banner && '-mt-10 ring-4 ring-base-50 sm:-mt-12 dark:ring-base-925'
|
|
81
|
+
)}
|
|
79
82
|
/>
|
|
80
83
|
<div class={cn('flex flex-wrap items-center gap-2', banner && 'pt-3')}>
|
|
81
84
|
<Button {href} target="_blank" rel="noopener noreferrer" variant="secondary" size="sm">
|
|
@@ -88,7 +91,9 @@
|
|
|
88
91
|
<h1 class="text-2xl font-semibold tracking-tight wrap-anywhere sm:text-3xl">
|
|
89
92
|
<bdi>{name}</bdi>
|
|
90
93
|
</h1>
|
|
91
|
-
<div
|
|
94
|
+
<div
|
|
95
|
+
class="mt-1 flex flex-wrap items-baseline gap-x-3 gap-y-1 text-sm text-base-600 dark:text-base-400"
|
|
96
|
+
>
|
|
92
97
|
{#if profile.handle}<a
|
|
93
98
|
{href}
|
|
94
99
|
target="_blank"
|
|
@@ -103,7 +108,7 @@
|
|
|
103
108
|
{#each displayedMetrics as metric (metric.label)}
|
|
104
109
|
{#if metric.value !== undefined}<div class="flex gap-1">
|
|
105
110
|
<dd class="font-semibold">{metric.value.toLocaleString('en')}</dd>
|
|
106
|
-
<dt class="text-
|
|
111
|
+
<dt class="text-base-600 dark:text-base-400">{metric.label}</dt>
|
|
107
112
|
</div>{/if}
|
|
108
113
|
{/each}
|
|
109
114
|
</dl>
|
|
@@ -114,7 +119,7 @@
|
|
|
114
119
|
href={segment.href}
|
|
115
120
|
target={segment.href.startsWith('/') ? undefined : '_blank'}
|
|
116
121
|
rel={segment.href.startsWith('/') ? undefined : 'noopener noreferrer nofollow ugc'}
|
|
117
|
-
class="text-
|
|
122
|
+
class="text-accent-700 underline decoration-accent-700/40 underline-offset-2 hover:decoration-accent-700 dark:text-accent-300 dark:decoration-accent-300/40 dark:hover:decoration-accent-300"
|
|
118
123
|
>{segment.text}</a
|
|
119
124
|
>{:else}{segment.text}{/if}{/each}
|
|
120
125
|
</p>
|
|
@@ -123,11 +128,13 @@
|
|
|
123
128
|
<ul aria-label="Profile links" class="mt-4 flex flex-wrap gap-2">
|
|
124
129
|
{#each links as link (link.url)}
|
|
125
130
|
<li class="max-w-full min-w-0">
|
|
126
|
-
<
|
|
131
|
+
<Button
|
|
127
132
|
href={link.url}
|
|
128
133
|
target="_blank"
|
|
129
134
|
rel="noopener noreferrer nofollow ugc"
|
|
130
|
-
|
|
135
|
+
variant="secondary"
|
|
136
|
+
size="sm"
|
|
137
|
+
class="max-w-full"
|
|
131
138
|
>
|
|
132
139
|
{#if link.icon && failedLinkIcons[link.url] !== link.icon}
|
|
133
140
|
<img
|
|
@@ -143,7 +150,7 @@
|
|
|
143
150
|
/>
|
|
144
151
|
{/if}
|
|
145
152
|
<span class="min-w-0 wrap-anywhere">{link.title || new URL(link.url).hostname}</span>
|
|
146
|
-
</
|
|
153
|
+
</Button>
|
|
147
154
|
</li>
|
|
148
155
|
{/each}
|
|
149
156
|
</ul>
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
style={style ?? undefined}
|
|
72
72
|
data-slot="workspace-sidebar"
|
|
73
73
|
class={cn(
|
|
74
|
-
'top-[calc(var(--atmo-nav-top,0px)+12px)] bottom-3 left-3 flex h-auto max-h-none w-[min(280px,calc(100%-24px))] max-w-none translate-x-0 translate-y-0 flex-col overflow-hidden rounded-[21px_18px_23px_19px] bg-
|
|
74
|
+
'top-[calc(var(--atmo-nav-top,0px)+12px)] bottom-3 left-3 flex h-auto max-h-none w-[min(280px,calc(100%-24px))] max-w-none translate-x-0 translate-y-0 flex-col overflow-hidden rounded-[21px_18px_23px_19px] bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] p-3 shadow-[inset_0_2px_4px_color-mix(in_srgb,var(--base-950)_8%,transparent),inset_0_5px_12px_color-mix(in_srgb,var(--base-950)_2%,transparent)] sm:p-3 dark:bg-base-950 dark:shadow-[inset_0_2px_4px_#0006,inset_0_5px_12px_#0002] [&>header]:mb-3 [&>header]:px-2 [&>header]:pt-2 [&>header_h2]:text-sm',
|
|
75
75
|
className
|
|
76
76
|
)}
|
|
77
77
|
>
|
|
@@ -13,11 +13,17 @@
|
|
|
13
13
|
const uid = $props.id();
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
|
-
<article
|
|
16
|
+
<article
|
|
17
|
+
{...rest}
|
|
18
|
+
class={cn(
|
|
19
|
+
'mx-auto max-w-3xl px-6 py-10 text-sm leading-7 text-base-950 dark:text-base-50',
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
>
|
|
17
23
|
<header class="mb-8">
|
|
18
24
|
<h1 class="m-0 text-3xl font-semibold tracking-tight">{document.title}</h1>
|
|
19
25
|
{#if document.updated}
|
|
20
|
-
<p class="mt-3 text-
|
|
26
|
+
<p class="mt-3 text-base-600 dark:text-base-400">
|
|
21
27
|
Last updated: <time datetime={document.updated}>{document.updated}</time>
|
|
22
28
|
</p>
|
|
23
29
|
{/if}
|
|
@@ -44,7 +50,7 @@
|
|
|
44
50
|
<li>
|
|
45
51
|
{#if safeLegalHref(link.href, true)}<a
|
|
46
52
|
href={safeLegalHref(link.href, true)}
|
|
47
|
-
class="rounded underline underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-focus"
|
|
53
|
+
class="rounded underline underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-accent-700 dark:focus-visible:outline-accent-300"
|
|
48
54
|
>{link.label}</a
|
|
49
55
|
>{:else}{link.label}{/if}
|
|
50
56
|
</li>
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
const showReportAction = $derived(links.report !== false && !!reportAction);
|
|
18
18
|
const items = $derived(legalFooterItems(showReportAction ? { ...links, report: false } : links));
|
|
19
19
|
const linkClass =
|
|
20
|
-
'rounded text-inherit underline-offset-4 hover:text-
|
|
20
|
+
'rounded text-inherit underline-offset-4 hover:text-base-950 dark:hover:text-base-50 hover:underline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-accent-700 dark:focus-visible:outline-accent-300';
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
23
|
{#if items.length || showReportAction}
|
|
24
|
-
<footer {...rest} class={cn('py-8 text-xs text-
|
|
24
|
+
<footer {...rest} class={cn('py-8 text-xs text-base-600 dark:text-base-400', className)}>
|
|
25
25
|
<nav aria-label="Legal and contact">
|
|
26
26
|
<ul class="m-0 flex list-none flex-wrap items-center justify-center gap-x-5 gap-y-3 p-0">
|
|
27
27
|
{#each items as item, index (index)}
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
<Icon
|
|
146
146
|
img={AtSign}
|
|
147
147
|
size={18}
|
|
148
|
-
class="pointer-events-none absolute top-[13px] left-3 z-1 text-
|
|
148
|
+
class="pointer-events-none absolute top-[13px] left-3 z-1 text-base-600 dark:text-base-400"
|
|
149
149
|
/>
|
|
150
150
|
{#if searchActors}
|
|
151
151
|
<Combobox.Root
|
|
@@ -190,12 +190,12 @@
|
|
|
190
190
|
sideOffset={6}
|
|
191
191
|
collisionPadding={12}
|
|
192
192
|
style={inherited}
|
|
193
|
-
class="z-70 max-h-[min(20rem,var(--bits-combobox-content-available-height))] w-(--bits-combobox-anchor-width) min-w-52 overflow-y-auto overscroll-contain rounded-ui border border-
|
|
193
|
+
class="z-70 max-h-[min(20rem,var(--bits-combobox-content-available-height))] w-(--bits-combobox-anchor-width) min-w-52 overflow-y-auto overscroll-contain rounded-ui border border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] p-1.5 font-sans text-base-950 outline-none dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-975 dark:text-base-50"
|
|
194
194
|
>
|
|
195
195
|
{#each results as actor (actor.did)}<Combobox.Item
|
|
196
196
|
value={actor.handle}
|
|
197
197
|
label={actor.handle}
|
|
198
|
-
class="flex min-h-14 cursor-pointer items-center gap-3 rounded-ui px-2.5 py-2 outline-none data-highlighted:bg-accent-
|
|
198
|
+
class="flex min-h-14 cursor-pointer items-center gap-3 rounded-ui px-2.5 py-2 outline-none data-highlighted:bg-accent-50 data-highlighted:text-accent-700 dark:data-highlighted:bg-[color-mix(in_srgb,var(--accent-950)_65%,var(--base-950))] dark:data-highlighted:text-accent-300"
|
|
199
199
|
><Avatar
|
|
200
200
|
name={actorName(actor)}
|
|
201
201
|
src={actor.avatar}
|
|
@@ -203,7 +203,8 @@
|
|
|
203
203
|
aria-hidden="true"
|
|
204
204
|
/><span class="grid min-w-0 gap-0.5"
|
|
205
205
|
><strong class="truncate text-[.8125rem] font-medium">{actorName(actor)}</strong
|
|
206
|
-
>{#if actor.displayName}<span
|
|
206
|
+
>{#if actor.displayName}<span
|
|
207
|
+
class="truncate text-xs text-base-600 dark:text-base-400"
|
|
207
208
|
>@{actor.handle}</span
|
|
208
209
|
>{/if}</span
|
|
209
210
|
></Combobox.Item
|
|
@@ -214,7 +215,7 @@
|
|
|
214
215
|
{#if status === 'loading'}<Icon
|
|
215
216
|
img={LoaderCircle}
|
|
216
217
|
size={16}
|
|
217
|
-
class="pointer-events-none absolute top-3.5 right-3 text-
|
|
218
|
+
class="pointer-events-none absolute top-3.5 right-3 text-base-600 motion-safe:animate-spin dark:text-base-400"
|
|
218
219
|
/>{/if}
|
|
219
220
|
{:else}<Input
|
|
220
221
|
{id}
|
|
@@ -232,7 +233,10 @@
|
|
|
232
233
|
data-autofocus
|
|
233
234
|
class="pl-10"
|
|
234
235
|
/>{/if}
|
|
235
|
-
{#if message}<p
|
|
236
|
+
{#if message}<p
|
|
237
|
+
id={`${uid}-status`}
|
|
238
|
+
class="mt-2 text-xs leading-relaxed text-base-600 dark:text-base-400"
|
|
239
|
+
>
|
|
236
240
|
{message}
|
|
237
241
|
</p>{/if}
|
|
238
242
|
<span class="sr-only" role="status">{announcement}</span>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<!-- Existing brand marks, not replacement UI icons. Static: no endless decorative motion. -->
|
|
14
14
|
<div class="flex items-center justify-between gap-2 py-2" aria-hidden="true">
|
|
15
15
|
{#each apps as src (src)}<span
|
|
16
|
-
class="size-5 shrink-0 bg-
|
|
16
|
+
class="size-5 shrink-0 bg-base-600 [mask-size:contain] [mask-position:center] [mask-repeat:no-repeat] opacity-70 sm:size-6 dark:bg-base-400"
|
|
17
17
|
class:scale-125={src === muSocial}
|
|
18
18
|
style:mask-image={`url("${src}")`}
|
|
19
19
|
></span>{/each}
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
bind:this={ref}
|
|
251
251
|
aria-label={rest['aria-label'] ?? headingText}
|
|
252
252
|
aria-busy={busy}
|
|
253
|
-
class={cn('grid w-full min-w-0 gap-4 text-
|
|
253
|
+
class={cn('grid w-full min-w-0 gap-4 text-base-950 dark:text-base-50', className)}
|
|
254
254
|
data-slot="login-form"
|
|
255
255
|
novalidate
|
|
256
256
|
onsubmit={(event) => {
|
|
@@ -266,7 +266,9 @@
|
|
|
266
266
|
tabindex={step === 'login' ? undefined : -1}
|
|
267
267
|
class="text-[1.375rem] leading-snug tracking-tight outline-none">{headingText}</Heading
|
|
268
268
|
>
|
|
269
|
-
{#if descriptionText}<p
|
|
269
|
+
{#if descriptionText}<p
|
|
270
|
+
class="text-[.8125rem] leading-relaxed text-base-600 dark:text-base-400"
|
|
271
|
+
>
|
|
270
272
|
{descriptionText}
|
|
271
273
|
</p>{/if}
|
|
272
274
|
</header>{/if}
|
|
@@ -290,7 +292,7 @@
|
|
|
290
292
|
>
|
|
291
293
|
{:else}
|
|
292
294
|
{#if selected}<div
|
|
293
|
-
class="flex min-h-15 items-center gap-3 rounded-ui border border-
|
|
295
|
+
class="flex min-h-15 items-center gap-3 rounded-ui border border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] py-2 pr-2 pl-3 dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-975"
|
|
294
296
|
data-slot="selected-account"
|
|
295
297
|
>
|
|
296
298
|
<Avatar
|
|
@@ -300,8 +302,8 @@
|
|
|
300
302
|
aria-hidden="true"
|
|
301
303
|
/><span class="grid min-w-0 flex-1 gap-0.5"
|
|
302
304
|
><strong class="truncate text-[.8125rem] font-medium">{actorName(selected)}</strong
|
|
303
|
-
>{#if selected.displayName}<span
|
|
304
|
-
>@{selected.handle}</span
|
|
305
|
+
>{#if selected.displayName}<span
|
|
306
|
+
class="truncate text-xs text-base-600 dark:text-base-400">@{selected.handle}</span
|
|
305
307
|
>{/if}</span
|
|
306
308
|
><IconButton
|
|
307
309
|
label={`Clear @${selected.handle}`}
|
|
@@ -336,8 +338,10 @@
|
|
|
336
338
|
/>{/if}</Button
|
|
337
339
|
>
|
|
338
340
|
{/if}
|
|
339
|
-
{#if signup}<div
|
|
340
|
-
|
|
341
|
+
{#if signup}<div
|
|
342
|
+
class="grid gap-3 border-t border-base-300 pt-4 dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))]"
|
|
343
|
+
>
|
|
344
|
+
<p class="text-[.8125rem] text-base-600 dark:text-base-400">Don't have an account?</p>
|
|
341
345
|
<Button
|
|
342
346
|
variant="secondary"
|
|
343
347
|
disabled={busy}
|
|
@@ -346,7 +350,9 @@
|
|
|
346
350
|
>
|
|
347
351
|
</div>{/if}
|
|
348
352
|
{:else if step === 'permissions'}
|
|
349
|
-
{#if pending}<p
|
|
353
|
+
{#if pending}<p
|
|
354
|
+
class="flex min-w-0 items-center gap-2 text-xs text-base-600 dark:text-base-400"
|
|
355
|
+
>
|
|
350
356
|
<span class="shrink-0">Logging in as</span>
|
|
351
357
|
{#if pending.actor}<Avatar
|
|
352
358
|
name={actorName(pending.actor)}
|
|
@@ -371,7 +377,7 @@
|
|
|
371
377
|
{#if error}<p
|
|
372
378
|
id={`${uid}-error`}
|
|
373
379
|
role="alert"
|
|
374
|
-
class="red flex items-start gap-2 text-xs leading-relaxed text-
|
|
380
|
+
class="red flex items-start gap-2 text-xs leading-relaxed text-accent-700 dark:text-accent-300"
|
|
375
381
|
>
|
|
376
382
|
<Icon img={TriangleAlert} size={16} class="mt-0.5 shrink-0" />{error}
|
|
377
383
|
</p>{/if}
|
|
@@ -23,7 +23,11 @@
|
|
|
23
23
|
<legend class="sr-only">Requested permissions</legend>
|
|
24
24
|
{#each permissions as permission, index (permission.id)}
|
|
25
25
|
<div class="flex items-start gap-3">
|
|
26
|
-
<Icon
|
|
26
|
+
<Icon
|
|
27
|
+
img={permission.icon ?? ShieldCheck}
|
|
28
|
+
size={20}
|
|
29
|
+
class="mt-1 shrink-0 text-base-600 dark:text-base-400"
|
|
30
|
+
/>
|
|
27
31
|
<div class="min-w-0 flex-1 space-y-1.5">
|
|
28
32
|
<Label
|
|
29
33
|
id={`${uid}-${index}-label`}
|
|
@@ -32,7 +36,10 @@
|
|
|
32
36
|
>
|
|
33
37
|
{permission.label}{permission.required ? ' (required)' : ''}
|
|
34
38
|
</Label>
|
|
35
|
-
<p
|
|
39
|
+
<p
|
|
40
|
+
id={`${uid}-${index}-description`}
|
|
41
|
+
class="text-xs leading-relaxed text-base-600 dark:text-base-400"
|
|
42
|
+
>
|
|
36
43
|
{permission.description}
|
|
37
44
|
</p>
|
|
38
45
|
</div>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
<div class="grid gap-2" bind:this={root} aria-label="Recent accounts">
|
|
31
31
|
{#each accounts as actor, index (actor.did)}<div
|
|
32
|
-
class="flex min-w-0 items-center gap-1 rounded-ui border border-
|
|
32
|
+
class="flex min-w-0 items-center gap-1 rounded-ui border border-base-300 bg-[color-mix(in_srgb,var(--base-100)_75%,var(--base-200))] dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] dark:bg-base-975"
|
|
33
33
|
>
|
|
34
34
|
<Button
|
|
35
35
|
data-account
|
|
@@ -41,8 +41,10 @@
|
|
|
41
41
|
>
|
|
42
42
|
<Avatar name={actorName(actor)} src={actor.avatar} size={34} aria-hidden="true" />
|
|
43
43
|
<span class="grid min-w-0 flex-1 gap-0.5"
|
|
44
|
-
><strong class="truncate text-[.8125rem] font-medium text-
|
|
45
|
-
|
|
44
|
+
><strong class="truncate text-[.8125rem] font-medium text-base-950 dark:text-base-50"
|
|
45
|
+
>{actorName(actor)}</strong
|
|
46
|
+
>{#if actor.displayName}<span class="truncate text-xs text-base-600 dark:text-base-400"
|
|
47
|
+
>@{actor.handle}</span
|
|
46
48
|
>{/if}</span
|
|
47
49
|
><Icon img={ArrowRight} size={16} />
|
|
48
50
|
</Button>
|
|
@@ -102,7 +102,10 @@
|
|
|
102
102
|
>
|
|
103
103
|
<p class="mb-2 text-sm text-base-900 dark:text-base-50">
|
|
104
104
|
<span class="font-bold">{goingCount}</span>
|
|
105
|
-
<span
|
|
105
|
+
<span
|
|
106
|
+
class="text-xs font-semibold tracking-wider text-base-600 uppercase dark:text-base-400"
|
|
107
|
+
>Going</span
|
|
108
|
+
>
|
|
106
109
|
</p>
|
|
107
110
|
<div class="flex items-center">
|
|
108
111
|
<div class="flex flex-wrap -space-y-2 -space-x-4 pr-4">
|
|
@@ -139,7 +142,10 @@
|
|
|
139
142
|
>
|
|
140
143
|
<p class="mb-2 text-sm text-base-900 dark:text-base-50">
|
|
141
144
|
<span class="font-bold">{interestedCount}</span>
|
|
142
|
-
<span
|
|
145
|
+
<span
|
|
146
|
+
class="text-xs font-semibold tracking-wider text-base-600 uppercase dark:text-base-400"
|
|
147
|
+
>Interested</span
|
|
148
|
+
>
|
|
143
149
|
</p>
|
|
144
150
|
<div class="flex items-center">
|
|
145
151
|
<div class="flex flex-wrap -space-y-2 -space-x-4 pr-4">
|
|
@@ -188,7 +194,7 @@
|
|
|
188
194
|
{person.name}
|
|
189
195
|
</p>
|
|
190
196
|
{#if person.handle}
|
|
191
|
-
<p class="truncate text-xs text-
|
|
197
|
+
<p class="truncate text-xs text-base-600 dark:text-base-400">
|
|
192
198
|
@{person.handle}
|
|
193
199
|
</p>
|
|
194
200
|
{/if}
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
|
|
87
87
|
<a
|
|
88
88
|
href={eventUrl(event, actor)}
|
|
89
|
-
class="group grid grid-cols-[5rem_minmax(0,1fr)] gap-3 rounded-ui outline-offset-4 transition-colors focus-visible:outline-2 focus-visible:outline-
|
|
89
|
+
class="group grid grid-cols-[5rem_minmax(0,1fr)] gap-3 rounded-ui outline-offset-4 transition-colors focus-visible:outline-2 focus-visible:outline-accent-700 sm:grid-cols-[6rem_minmax(0,1fr)] sm:gap-3.5 dark:focus-visible:outline-accent-300"
|
|
90
90
|
>
|
|
91
91
|
<div class="w-full">
|
|
92
92
|
{#if thumbnail}
|
|
@@ -94,11 +94,11 @@
|
|
|
94
94
|
src={thumbnail.url}
|
|
95
95
|
alt={thumbnail.alt}
|
|
96
96
|
loading="lazy"
|
|
97
|
-
class="block aspect-square w-full rounded-[14px_12px_15px_13px] border border-
|
|
97
|
+
class="block aspect-square w-full rounded-[14px_12px_15px_13px] border border-base-300 object-cover dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))]"
|
|
98
98
|
/>
|
|
99
99
|
{:else}
|
|
100
100
|
<div
|
|
101
|
-
class="aspect-square w-full overflow-hidden rounded-[14px_12px_15px_13px] border border-
|
|
101
|
+
class="aspect-square w-full overflow-hidden rounded-[14px_12px_15px_13px] border border-base-300 dark:border-[color-mix(in_srgb,var(--base-800)_80%,var(--base-950))] [&>svg]:h-full [&>svg]:w-full"
|
|
102
102
|
>
|
|
103
103
|
<Avatar
|
|
104
104
|
size={96}
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
</div>
|
|
113
113
|
|
|
114
114
|
<div class="min-w-0 self-center">
|
|
115
|
-
<p class="flex items-center gap-1.5 text-xs font-medium text-
|
|
115
|
+
<p class="flex items-center gap-1.5 text-xs font-medium text-base-600 dark:text-base-400">
|
|
116
116
|
<Icon img={CalendarDays} size={14} class="shrink-0" />
|
|
117
117
|
{#if isOngoing && event.endsAt}
|
|
118
118
|
Ends {formatEndsAt(event.endsAt)}
|
|
@@ -132,7 +132,9 @@
|
|
|
132
132
|
<span class="line-clamp-2">{event.name}</span>
|
|
133
133
|
</h3>
|
|
134
134
|
{#if location || mode}
|
|
135
|
-
<p
|
|
135
|
+
<p
|
|
136
|
+
class="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-base-600 dark:text-base-400"
|
|
137
|
+
>
|
|
136
138
|
{#if location}
|
|
137
139
|
<span class="inline-flex max-w-full min-w-0 items-center gap-1.5" title={location}>
|
|
138
140
|
<Icon img={MapPin} size={14} class="shrink-0" />
|
|
@@ -80,11 +80,11 @@
|
|
|
80
80
|
{/if}
|
|
81
81
|
|
|
82
82
|
{#if loading}
|
|
83
|
-
<p class="text-sm text-
|
|
83
|
+
<p class="text-sm text-base-600 dark:text-base-400">Loading comments…</p>
|
|
84
84
|
{:else if errorMessage}
|
|
85
|
-
<p class="text-sm text-
|
|
85
|
+
<p class="text-sm text-base-600 dark:text-base-400">{errorMessage}</p>
|
|
86
86
|
{:else if comments.length === 0}
|
|
87
|
-
<p class="text-sm text-
|
|
87
|
+
<p class="text-sm text-base-600 dark:text-base-400">No comments yet.</p>
|
|
88
88
|
{:else}
|
|
89
89
|
<div class="not-prose comments-no-divider">
|
|
90
90
|
<NestedComments {comments} {socialClient} />
|