Files
bookhoard/templates/setup_templ.go
T
John O'Keefe d5bb874651 feat(themes): Omarchy catalog, 12 light themes, Dark/Light Appearance picker
Expand the catalog from 11 themes (10 dark, 1 light) to 37 (24/13):
all 18 remaining Omarchy defaults (palettes from each theme's
colors.toml) plus 8 canonical light themes (Tokyo Night Day, Solarized
Light, One Light, Ayu Light, GitHub Light, Gruvbox Light, Everforest
Light, Kanagawa Lotus). Lupine leads the light list as the default
light theme; the app default stays tokyo-night.

Appearance panel: Dark/Light segmented filter (SSR-initialized from the
user's current theme), scrollable theme list, Bookshelf section pinned;
active row revealed on open. Light themes carry color-scheme: light and
the soft-shadow token set. Public-page theme selects get Dark/Light
optgroups. New moon/sun icons.

tailwind.config: safelist the new theme ids — Tailwind v3 purges custom
@layer base class selectors that appear in no scanned content file, so
an unsafelisted id silently ships without its CSS (found the hard way).

theme.ts: applyTheme now swaps only theme-* classes (changing theme
from the login select no longer wipes min-h-screen) and keeps the class
in sync on <html> for the new ThemeFlashGuard — a pre-paint inline
script on the four public pages that applies the saved theme before
first paint.

Kanagawa's UI accent uses crystalBlue (#7e9cd8) instead of Omarchy's
foreground-as-accent so links stay distinguishable from text.
2026-10-18 12:08:07 -04:00

193 lines
22 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.1020
package templates
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
func Setup() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = ThemeFlashGuard().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Setup - Bookhoard</title><script src=\"/static/htmx.min.js\"></script><script type=\"module\" src=\"/static/main.js\"></script><link href=\"/static/style.css\" rel=\"stylesheet\"><link rel=\"icon\" type=\"image/svg+xml\" href=\"/static/favicon.svg\"></head><body class=\"theme-tokyo-night min-h-screen\" x-data=\"setupWizard\" x-init=\"initSetup()\"><div class=\"mx-auto container px-4 py-8 max-w-2xl\"><div class=\"text-center mb-8\"><span class=\"inline-grid place-items-center h-14 w-14 rounded-2xl mx-auto mb-4\" style=\"background-color: var(--accent-muted); color: var(--accent);\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("library", "h-7 w-7").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span><h1 class=\"text-4xl font-bold mb-2 tracking-tight\" style=\"color: var(--text-primary)\">Welcome to Bookhoard</h1><p class=\"text-lg\" style=\"color: var(--text-secondary)\">Let's get your library set up.</p></div><div class=\"flex items-center justify-center mb-8 gap-2\"><template x-for=\"n in 4\" :key=\"n\"><div class=\"flex items-center gap-2\"><div class=\"w-10 h-10 rounded-full grid place-items-center font-bold text-sm transition-all\" :class=\"currentStep >= n ? 'bg-[var(--accent)] text-[var(--bg-primary)]' : 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border)]'\"><template x-if=\"currentStep > n\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("check", "h-5 w-5").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</template><span x-show=\"currentStep <= n\" x-text=\"n\"></span></div><div x-text=\"['Admin', 'Libraries', 'Folders', 'Scan'][n-1]\" class=\"text-sm hidden sm:inline\" :style=\"currentStep >= n ? 'color: var(--text-primary)' : 'color: var(--text-secondary)'\"></div><div x-show=\"n < 4\" class=\"w-8 h-0.5 mx-1\" :class=\"currentStep > n ? 'bg-[var(--accent)]' : 'bg-[var(--border)]'\"></div></div></template></div><div x-show=\"errorMsg\" class=\"mb-4 card p-4 text-sm\" style=\"border-color: var(--status-danger); background-color: color-mix(in srgb, var(--status-danger) 12%, transparent); color: var(--status-danger);\"><span x-text=\"errorMsg\"></span></div><!-- ==================== STEP 1: Create Admin ==================== --><div x-show=\"currentStep === 1\" class=\"card p-6\"><h2 class=\"text-2xl font-bold mb-2\" style=\"color: var(--text-primary)\">Create Administrator Account</h2><p class=\"mb-6\" style=\"color: var(--text-secondary)\">This first account will have full admin privileges.</p><form @submit.prevent=\"submitAdmin()\"><div class=\"mb-6 card p-4\" style=\"background-color: var(--bg-primary);\"><label for=\"base-url\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Server URL (Base URL)</label> <input type=\"url\" id=\"base-url\" x-model=\"admin.baseUrl\" placeholder=\"https://books.example.com\" class=\"input mt-2\" required><p class=\"text-sm mt-2\" style=\"color: var(--text-secondary)\">The public URL of your Bookhoard instance. Used for device sync, OPDS feed, and API endpoints.</p></div><div class=\"mb-4\"><label for=\"email\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Email</label> <input type=\"email\" id=\"email\" x-model=\"admin.email\" class=\"input mt-2\" required></div><div class=\"mb-4\"><label for=\"username\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Username</label> <input type=\"text\" x-model=\"admin.username\" id=\"username\" class=\"input mt-2\" required></div><div class=\"grid grid-cols-2 gap-4 mb-4\"><div><label for=\"first-name\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">First Name</label> <input type=\"text\" id=\"first-name\" x-model=\"admin.firstName\" placeholder=\"Optional\" class=\"input mt-2\"></div><div><label for=\"last-name\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Last Name</label> <input type=\"text\" id=\"last-name\" x-model=\"admin.lastName\" placeholder=\"Optional\" class=\"input mt-2\"></div></div><div id=\"password-requirements\" class=\"mb-4 card p-4 text-sm\" style=\"background-color: var(--bg-primary);\"><p class=\"font-semibold mb-2\" style=\"color: var(--text-primary)\">Password Requirements:</p><ul class=\"space-y-1\" style=\"color: var(--text-secondary)\"><li id=\"req-length\" class=\"flex items-center gap-2\"><span class=\"requirement-icon\">○</span> At least 8 characters</li><li id=\"req-upper\" class=\"flex items-center gap-2\"><span class=\"requirement-icon\">○</span> One uppercase letter</li><li id=\"req-lower\" class=\"flex items-center gap-2\"><span class=\"requirement-icon\">○</span> One lowercase letter</li><li id=\"req-number\" class=\"flex items-center gap-2\"><span class=\"requirement-icon\">○</span> One number</li><li id=\"req-special\" class=\"flex items-center gap-2\"><span class=\"requirement-icon\">○</span> One special character</li><li id=\"req-match\" class=\"flex items-center gap-2\"><span class=\"requirement-icon\">○</span> Passwords match</li></ul></div><div class=\"mb-4\"><label for=\"password\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Password</label> <input type=\"password\" x-model=\"admin.password\" id=\"password\" class=\"input mt-2\" required></div><div class=\"mb-6\"><label for=\"confirm-password\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Confirm Password</label> <input type=\"password\" x-model=\"admin.confirmPassword\" id=\"confirm-password\" class=\"input mt-2\" required></div><button type=\"submit\" id=\"register-btn\" class=\"btn btn-primary w-full\" :disabled=\"loading\" x-text=\"loading ? 'Creating…' : 'Create Admin Account'\"></button></form></div><!-- ==================== STEP 2: Create Libraries ==================== --><div x-show=\"currentStep === 2\" class=\"card p-6\"><h2 class=\"text-2xl font-bold mb-2\" style=\"color: var(--text-primary)\">Create Libraries</h2><p class=\"mb-6\" style=\"color: var(--text-secondary)\">Add one or more media libraries. You can always add more later.</p><div x-show=\"libraries.length > 0\" class=\"mb-6 space-y-2\"><template x-for=\"(lib, idx) in libraries\" :key=\"lib.id\"><div class=\"card p-3 flex items-center justify-between\" style=\"background-color: var(--bg-primary);\"><div class=\"flex items-center gap-3\"><span class=\"grid place-items-center h-9 w-9 rounded-xl\" style=\"background-color: var(--accent-muted); color: var(--accent);\"><span class=\"inline-flex\" x-show=\"lib.type === 'ebooks'\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("book", "h-5 w-5").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</span> <span class=\"inline-flex\" x-show=\"lib.type === 'comics'\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("book-open", "h-5 w-5").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</span> <span class=\"inline-flex\" x-show=\"lib.type === 'manga'\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("library", "h-5 w-5").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</span></span><div><p class=\"font-medium\" style=\"color: var(--text-primary)\" x-text=\"lib.name\"></p><p class=\"text-xs capitalize\" style=\"color: var(--text-secondary)\" x-text=\"lib.type\"></p></div></div><button type=\"button\" @click=\"removeLibrary(idx)\" class=\"icon-btn\" style=\"color: var(--status-danger);\" aria-label=\"Remove library\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("trash", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</button></div></template></div><form @submit.prevent=\"addLibrary()\" class=\"space-y-4 card p-4\" style=\"background-color: var(--bg-primary);\"><div><label for=\"lib-name\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Library Name</label> <input type=\"text\" id=\"lib-name\" x-model=\"newLibrary.name\" placeholder=\"My Ebook Library\" class=\"input mt-2\" required></div><div><label for=\"lib-type\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Library Type</label> <select id=\"lib-type\" x-model=\"newLibrary.type\" class=\"input mt-2\"><option value=\"ebooks\">Ebooks</option> <option value=\"comics\">Comics</option> <option value=\"manga\">Manga</option></select></div><div><label for=\"lib-desc\" class=\"block text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Description (optional)</label> <input type=\"text\" id=\"lib-desc\" x-model=\"newLibrary.description\" placeholder=\"Optional\" class=\"input mt-2\"></div><button type=\"submit\" class=\"btn btn-secondary w-full\" :disabled=\"loading || !newLibrary.name.trim()\" x-text=\"loading ? 'Creating…' : '+ Add This Library'\"></button></form><div class=\"flex justify-between mt-6\"><button type=\"button\" @click=\"currentStep = 1\" class=\"btn btn-secondary\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("arrow-left", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "Back</button> <button type=\"button\" @click=\"currentStep = 3\" class=\"btn btn-primary\"><span x-text=\"libraries.length > 0 ? 'Next: Configure Folders' : 'Skip – Continue'\"></span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("arrow-right", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</button></div></div><!-- ==================== STEP 3: Configure Folders ==================== --><div x-show=\"currentStep === 3\" class=\"card p-6\"><h2 class=\"text-2xl font-bold mb-2\" style=\"color: var(--text-primary)\">Configure Library Folders</h2><p class=\"mb-6\" style=\"color: var(--text-secondary)\">Add the filesystem folders where your media files are stored.</p><div x-show=\"libraries.length === 0\" class=\"text-center py-8\" style=\"color: var(--text-secondary)\"><p>No libraries created. You can add folders later from the admin panel.</p></div><div class=\"space-y-6\"><template x-for=\"lib in libraries\" :key=\"lib.id\"><div class=\"card p-4\" style=\"background-color: var(--bg-primary);\"><div class=\"flex items-center gap-2 mb-3\"><span class=\"grid place-items-center h-8 w-8 rounded-lg\" style=\"background-color: var(--accent-muted); color: var(--accent);\"><span class=\"inline-flex\" x-show=\"lib.type === 'ebooks'\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("book", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</span> <span class=\"inline-flex\" x-show=\"lib.type === 'comics'\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("book-open", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</span> <span class=\"inline-flex\" x-show=\"lib.type === 'manga'\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("library", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</span></span><h4 class=\"font-semibold\" style=\"color: var(--text-primary)\" x-text=\"lib.name\"></h4></div><div class=\"space-y-1 mb-3\" x-show=\"lib.folders && lib.folders.length > 0\"><template x-for=\"(folder, fIdx) in (lib.folders || [])\" :key=\"folder\"><div class=\"flex items-center justify-between p-2 rounded-lg text-sm\" style=\"background-color: var(--bg-secondary);\"><span class=\"flex items-center gap-2 truncate\" style=\"color: var(--text-primary)\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("folder", "h-4 w-4 shrink-0").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<span class=\"truncate\" x-text=\"folder\"></span></span> <button type=\"button\" @click=\"removeFolder(lib.id, folder, fIdx)\" class=\"icon-btn shrink-0\" style=\"color: var(--status-danger);\" aria-label=\"Remove folder\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("trash", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</button></div></template></div><div class=\"flex gap-2\"><input type=\"text\" :placeholder=\"'/path/to/' + lib.type\" :id=\"'folderInput-' + lib.id\" class=\"input flex-1 text-sm\"> <button type=\"button\" @click=\"showFolderBrowser('folderInput-' + lib.id)\" class=\"btn btn-secondary px-3 text-xs\">Browse</button> <button type=\"button\" @click=\"addFolderToLibrary(lib)\" class=\"btn btn-primary px-3 text-xs\">Add</button></div></div></template></div><div class=\"flex justify-between mt-6\"><button type=\"button\" @click=\"currentStep = 2\" class=\"btn btn-secondary\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("arrow-left", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "Back</button> <button type=\"button\" @click=\"currentStep = 4\" class=\"btn btn-primary\">Next: Scan")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("arrow-right", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</button></div></div><!-- ==================== STEP 4: Scan & Finish ==================== --><div x-show=\"currentStep === 4\" class=\"card p-6\"><h2 class=\"text-2xl font-bold mb-2\" style=\"color: var(--text-primary)\">Scan & Finish</h2><p class=\"mb-6\" style=\"color: var(--text-secondary)\">Review your configuration and start the initial scan.</p><div class=\"space-y-3 mb-6\"><div class=\"card p-4\" style=\"background-color: var(--bg-primary);\"><p class=\"text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Server URL</p><p style=\"color: var(--text-primary)\" x-text=\"admin.baseUrl\"></p></div><div class=\"card p-4\" style=\"background-color: var(--bg-primary);\"><p class=\"text-xs uppercase tracking-wide font-medium mb-1\" style=\"color: var(--text-secondary)\">Administrator</p><p style=\"color: var(--text-primary)\" x-text=\"admin.username + ' (' + admin.email + ')'\"></p></div><div class=\"card p-4\" style=\"background-color: var(--bg-primary);\"><p class=\"text-xs uppercase tracking-wide font-medium mb-2\" style=\"color: var(--text-secondary)\">Libraries (<span x-text=\"libraries.length\"></span>)</p><template x-for=\"lib in libraries\" :key=\"lib.id\"><div class=\"flex items-start justify-between text-sm py-1\"><div class=\"flex items-center gap-2\"><span style=\"color: var(--text-primary)\" x-text=\"lib.name\"></span> <span class=\"chip\" x-text=\"lib.type\"></span></div><div class=\"text-right\" style=\"color: var(--text-secondary)\"><span x-text=\"(lib.folders || []).length + ' folder(s)'\"></span></div></div></template></div></div><div x-show=\"scanStarted\" class=\"mb-6 space-y-3\"><h3 class=\"font-semibold\" style=\"color: var(--text-primary)\">Scan Progress</h3><div id=\"library-progress-list\" class=\"space-y-3\"><template x-for=\"job in scanJobs\" :key=\"job.jobId\"><div class=\"card p-3\" style=\"background-color: var(--bg-primary);\"><div class=\"flex justify-between items-center mb-2\"><span class=\"font-medium\" style=\"color: var(--text-primary)\" x-text=\"job.libraryName\"></span> <span class=\"text-sm\" style=\"color: var(--text-secondary)\" x-text=\"job.statusText\"></span></div><div class=\"w-full rounded-full h-2\" style=\"background-color: var(--bg-secondary)\"><div class=\"h-2 rounded-full transition-all duration-500\" :style=\"'width: ' + job.progress + '%; background-color: var(--accent);'\"></div></div></div></template></div><div x-show=\"scanComplete\" class=\"card p-4 text-sm\" style=\"border-color: var(--status-success); background-color: color-mix(in srgb, var(--status-success) 12%, transparent); color: var(--status-success);\">Initial scan complete! Your libraries are ready to use.</div></div><div class=\"flex justify-between mt-6\"><button type=\"button\" @click=\"currentStep = 3\" class=\"btn btn-secondary\" :disabled=\"loading\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("arrow-left", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "Back</button><div class=\"flex gap-3\"><button x-show=\"!scanStarted\" type=\"button\" @click=\"startScan()\" class=\"btn btn-primary\" :disabled=\"loading\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("sync", "h-4 w-4").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "Start Scan</button> <button x-show=\"scanStarted && !scanComplete\" type=\"button\" @click=\"finishSetup()\" class=\"btn btn-secondary\" :disabled=\"loading\">Skip to Dashboard</button> <button x-show=\"scanComplete\" type=\"button\" @click=\"finishSetup()\" class=\"btn btn-primary\" :disabled=\"loading\" x-text=\"loading ? 'Finishing…' : 'Go to Dashboard'\"></button></div></div></div></div><div id=\"folder-browser-modal\" class=\"hidden fixed inset-0 z-50 flex items-center justify-center p-4\" style=\"background-color: var(--surface-overlay);\"><div class=\"card p-6 w-full max-w-md mx-4\"><div class=\"flex justify-between items-center mb-4\"><h2 class=\"text-xl font-bold\" style=\"color: var(--text-primary)\">Browse Folders</h2><button type=\"button\" @click=\"hideFolderBrowser()\" class=\"icon-btn\" aria-label=\"Close\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Icon("close", "h-5 w-5").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</button></div><div id=\"folder-browser-content\"></div></div></div></body></html>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate