ReviewOS

also looking at this

stacks/postline

fix: emit dynamic crosspost UI classes (crosswind safelist) + polish

#2
Merged chris wants to merge fix/crosspost-ui-polish into main
2 files +10 -2

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

resources/views/accounts.stxmodified+4-1
Changes to resources/views/accounts.stx
@@ -5,11 +5,14 @@
55
66@section('content')
77 <section class="grid gap-5" data-postline-page="accounts" data-testid="accounts-page">
8 <!-- Crosswind safelist: connection status-pill colors are set dynamically
9 via JS, so list them in static markup for the CSS scanner. -->
10 <div class="hidden text-amber-800 text-emerald-700 text-zinc-500 bg-amber-50 bg-emerald-50 border-amber-200 border-emerald-200 border-zinc-200" aria-hidden="true"></div>
811 <header class="flex gap-4 items-center justify-between min-h-11">
912 <div>
1013 <p class="mb-1.5 font-bold text-[11px] text-zinc-500 tracking-wider uppercase">Accounts</p>
1114 <h1 class="m-0 font-bold text-[22px] text-neutral-950 tracking-normal">Publishing drivers</h1>
12 <p class="mb-0 mt-1.5 text-[13px] text-zinc-600">Connect Bluesky and LinkedIn to publish and crosspost from Postline.</p>
15 <p class="mb-0 mt-1.5 text-[13px] text-zinc-600">Connect Bluesky, LinkedIn, and Instagram to publish and crosspost from Postline.</p>
1316 </div>
1417 </header>
1518
resources/views/index.stxmodified+6-1
Changes to resources/views/index.stx
@@ -5,6 +5,10 @@
55
66@section('content')
77 <section class="grid gap-3.5" data-postline-page="composer" data-testid="composer-page">
8 <!-- Crosswind safelist: utilities applied dynamically from the script below
9 (provider toggles, active-post highlight, connection summary, char
10 counter) must appear in static markup so the CSS scanner emits them. -->
11 <div class="hidden text-amber-700 text-emerald-800 text-neutral-950 text-red-700 text-white text-zinc-400 text-zinc-500 text-zinc-600 bg-emerald-400 bg-emerald-50 bg-emerald-500 bg-neutral-950 bg-white bg-zinc-100 bg-zinc-300 bg-zinc-50 hover:bg-white border-blue-300 border-emerald-200 border-neutral-950 border-zinc-200 shadow-sm cursor-not-allowed" aria-hidden="true"></div>
812 <div class="grid">
913 <section class="grid content-start grid-rows-[auto_auto_auto] self-start bg-white border border-zinc-200 rounded-2xl shadow-sm" aria-label="Post composer">
1014 <header class="flex flex-wrap gap-3 items-center justify-between p-3 border-b border-zinc-200">
@@ -162,7 +166,7 @@
162166 const renderProviderToggles = () => {
163167 if (!providerToggles) return
164168 if (providers.length === 0) {
165 providerToggles.innerHTML = '<span class="flex items-center px-2.5 min-h-8 text-xs text-zinc-400 bg-zinc-50 border border-zinc-200 rounded-xl">No accounts yet — connect one on Accounts.</span>'
169 providerToggles.innerHTML = '<a class="inline-flex items-center px-2.5 min-h-8 text-xs text-zinc-500 bg-zinc-50 hover:bg-white border border-zinc-200 rounded-xl transition-colors" href="/accounts" data-stx-link>No accounts yet — connect one →</a>'
166170 return
167171 }
168172 providerToggles.replaceChildren(...providers.map(createProviderToggle))
@@ -428,6 +432,7 @@
428432 const post = createPost(postCounter, options.text || '')
429433 postsRoot?.append(post)
430434 renamePosts()
435 applyMaxLength()
431436 selectPost(post, { skipSave: true })
432437 if (options.focus !== false) textareaFor(post)?.focus()
433438 if (options.announce !== false) setStatus(`Added post ${allPosts().length}.`, 'success')