inset-0 flex relies on display:flex being restored after Livewire removes
display:none — display type ambiguous in that moment. Explicit 50%/50%
translate centering is display-independent and always correct.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CSS opacity on parent compounds to all children, spinner can't escape it.
disabled:opacity-60 → disabled:opacity-100 (keeps button at full color
while loading, cursor:wait signals busy state). Text fades via
wire:loading.class="opacity-50" on label span only.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Keep label in DOM with opacity-50 during loading, spinner sits as
absolute inset-0 overlay. Button width stays constant, no jump.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Button: wire:loading.remove on label (DOM removal, no z-index fight)
spinner span is normal flex child — button's own flex centers it
SVG: track circle opacity 25% + 3/4 arc via stroke-dasharray 42.4/56.6,
stroke-linecap round, rotated -90deg so arc starts at top
- AI prompt: explicitly flags sparse data (<3 links or <10 clicks),
requires every claim reference a specific slug, forbids generic padding
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Prompt respects user locale (de/en/fr/es/it/pt) — responds in user's language
- Rewrite prompt: domain pattern analysis, low-click diagnosis, no generic advice
- Include total clicks + link count for context
- max_tokens 512 → 800 for richer output
- Button spinner: h-5 w-5 (was h-4 w-4), bg-inherit to cover label text cleanly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BUG 1: blocking script in <head> reads localStorage before first paint; CSS rule html[data-sidebar-collapsed] .skel-sidebar{width:64px} eliminates width flash
- BUG 2: sidebar store gains mobileOpen/toggleMobile()/closeMobile(); hamburger calls toggleMobile(); backdrop and sidebar :style use mobileOpen; SPA navigated handler calls closeMobile()
- BUG 3: text-purple → text-accent in AI Insights view (text-purple is undefined)
- BUG 4: ui/button.blade.php — spinner is now absolute inset-0 overlay; content fades to opacity-40 via wire:loading.class instead of hiding
- BUG 5: insights generate button and QR modal save/cancel migrated to x-ui.button component
- BUG 6: QR modal Styling/Frame/Advanced sections replaced from <details> (destroyed by Livewire re-render) to Alpine x-data{open:false} divs with x-show — state survives wire:model.live updates
- BUG 7: updateActiveNav() now checks el.dataset.navExact; Dashboard <a> gets data-nav-exact="1" so it only activates on exact pathname match
- BUG 8: bio_pages.theme JSON applied in public show.blade.php via inline CSS vars (4 presets: dark/light/purple/blue); EditBioPage gains theme property with preset selector in modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Workspace.getRouteKeyName()='ulid' so route() generates ULID URLs not ID
- QR modal 4xl→5xl; import QRCode in @script→window.QRCode (no ESM in @script)
- Bio slug unique rule scoped to (workspace_id, domain_id) not global
- updateActiveNav uses URL.pathname not raw getAttribute('href') (absolute URL fix)
- Add resources/views/components/ui/copy-button.blade.php Alpine component
- Analytics Index.render/baseQuery use $workspaceId not require_workspace() — prevents RuntimeException on Livewire action calls without middleware
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>