···
225
-
<div class="mx-auto flex h-screen max-w-2xl flex-col p-4">
226
-
<div class="mb-6 flex shrink-0 items-center justify-between">
228
-
<h1 class="text-3xl font-bold tracking-tight">nucleus</h1>
229
-
<div class="mt-1 flex gap-2">
230
-
<div class="h-1 w-11 rounded-full bg-(--nucleus-accent)"></div>
231
-
<div class="h-1 w-8 rounded-full bg-(--nucleus-accent2)"></div>
225
+
<div class="mx-auto max-w-2xl">
226
+
<!-- Sticky header -->
227
+
<div class="sticky top-0 z-10 bg-(--nucleus-bg) p-4">
228
+
<div class="mb-6 flex items-center justify-between">
230
+
<h1 class="text-3xl font-bold tracking-tight">nucleus</h1>
231
+
<div class="mt-1 flex gap-2">
232
+
<div class="h-1 w-11 rounded-full bg-(--nucleus-accent)"></div>
233
+
<div class="h-1 w-8 rounded-full bg-(--nucleus-accent2)"></div>
237
+
onclick={() => (isSettingsOpen = true)}
238
+
class="group rounded-sm bg-(--nucleus-accent)/7 p-2 text-(--nucleus-accent) transition-all hover:scale-110 hover:shadow-lg"
239
+
aria-label="settings"
241
+
<Icon class="group-hover:hidden" icon="heroicons:cog-6-tooth" width={28} />
242
+
<Icon class="hidden group-hover:block" icon="heroicons:cog-6-tooth-solid" width={28} />
235
-
onclick={() => (isSettingsOpen = true)}
236
-
class="group rounded-sm bg-(--nucleus-accent)/7 p-2 text-(--nucleus-accent) transition-all hover:scale-110 hover:shadow-lg"
237
-
aria-label="settings"
239
-
<Icon class="group-hover:hidden" icon="heroicons:cog-6-tooth" width={28} />
240
-
<Icon class="hidden group-hover:block" icon="heroicons:cog-6-tooth-solid" width={28} />
244
-
<div class="shrink-0 space-y-4">
245
-
<div class="flex min-h-16 items-stretch gap-2">
247
-
client={viewClient}
248
-
accounts={$accounts}
250
-
onAccountSelected={handleAccountSelected}
251
-
onLogout={handleLogout}
246
+
<!-- Composer and error disclaimer (above thread list, not scrollable) -->
247
+
<div class="space-y-4">
248
+
<div class="flex min-h-16 items-stretch gap-2">
250
+
client={viewClient}
251
+
accounts={$accounts}
253
+
onAccountSelected={handleAccountSelected}
254
+
onLogout={handleLogout}
254
-
{#if selectedClient}
255
-
<div class="flex-1">
257
-
client={selectedClient}
258
-
onPostSent={(post) => posts.get(selectedDid!)?.set(post.uri, post)}
265
-
class="flex flex-1 items-center justify-center rounded-sm border-2 border-(--nucleus-accent)/20 bg-(--nucleus-accent)/4 px-4 py-2.5 backdrop-blur-sm"
267
-
<p class="text-sm opacity-80">select or add an account to post</p>
257
+
{#if selectedClient}
258
+
<div class="flex-1">
260
+
client={selectedClient}
261
+
onPostSent={(post) => posts.get(selectedDid!)?.set(post.uri, post)}
268
+
class="flex flex-1 items-center justify-center rounded-sm border-2 border-(--nucleus-accent)/20 bg-(--nucleus-accent)/4 px-4 py-2.5 backdrop-blur-sm"
270
+
<p class="text-sm opacity-80">select or add an account to post</p>
275
+
{#if !loadData.client.ok}
276
+
<div class="error-disclaimer">
278
+
<Icon class="inline h-12 w-12" icon="heroicons:exclamation-triangle-16-solid" />
279
+
{loadData.client.error}
272
-
{#if !loadData.client.ok}
273
-
<div class="error-disclaimer">
275
-
<Icon class="inline h-12 w-12" icon="heroicons:exclamation-triangle-16-solid" />
276
-
{loadData.client.error}
class="h-[4px] w-full rounded-full border-0"
style="background: linear-gradient(to right, var(--nucleus-accent), var(--nucleus-accent2));"
288
-
class="mt-4 overflow-y-scroll [scrollbar-color:var(--nucleus-accent)_transparent]"
289
-
bind:this={scrollContainer}
291
+
<!-- Thread list (page scrolls as a whole) -->
292
+
<div class="mt-4 [scrollbar-color:var(--nucleus-accent)_transparent]" bind:this={scrollContainer}>
{#if $accounts.length > 0}
{@render renderThreads()}