feat(design): v2 becomes the default — drop beta conversation
CI / test (push) Has been cancelled

Atmospheric design is now the default for everyone:
- User.getDesignVersion() returns 'v2' when unset (was 'v1')
- All Twig templates default the cookie read to 'v2'
- SettingsView 'Design (beta)' section removed entirely along with the
  selectDesign() handler and currentDesign computed

The /api/user/design endpoint stays in place so the design_version column
can still be set programmatically (or migrated later), but the UI no
longer exposes it as a user-facing choice. Existing users with explicit
'v1' in their DB row continue to see v1 — their preference persists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 20:22:18 -04:00
parent c794878e5e
commit 019a3363c5
21 changed files with 21 additions and 73 deletions
-52
View File
@@ -38,36 +38,6 @@
</div>
</section>
<section class="settings__section">
<h2 class="settings__section-title">Design (beta)</h2>
<p class="settings__hint">
Try the new atmospheric look. Your theme picks above still apply
v2 just renders them as dusks over a Camogli harbor backdrop.
</p>
<div class="design-toggle" role="radiogroup" aria-label="Design version">
<button
type="button"
role="radio"
:aria-checked="currentDesign === 'v1'"
:class="['design-toggle__opt', { 'design-toggle__opt--active': currentDesign === 'v1' }]"
@click="selectDesign('v1')"
>
<span class="design-toggle__label">Original</span>
<span class="design-toggle__sub">cream &amp; terracotta</span>
</button>
<button
type="button"
role="radio"
:aria-checked="currentDesign === 'v2'"
:class="['design-toggle__opt', { 'design-toggle__opt--active': currentDesign === 'v2' }]"
@click="selectDesign('v2')"
>
<span class="design-toggle__label">Atmospheric</span>
<span class="design-toggle__sub">harbor dusks · beta</span>
</button>
</div>
</section>
<section v-if="!isStandalone" class="settings__section">
<h2 class="settings__section-title">Install app</h2>
<p class="settings__hint">
@@ -207,34 +177,12 @@ const { saveTheme } = useTheme()
const { isStandalone, isIOS, canPromptInstall, install } = usePwaInstall()
const currentTheme = computed(() => auth.user?.theme ?? 'warm-craft')
const currentDesign = computed(() => auth.user?.designVersion ?? 'v1')
const showIosInstructions = ref(false)
function select(themeId: string) {
saveTheme(themeId)
}
async function selectDesign(version: 'v1' | 'v2') {
if (currentDesign.value === version) return
const prev = currentDesign.value
// Optimistic local update so the SPA flips immediately.
if (auth.user) auth.user.designVersion = version
document.documentElement.setAttribute('data-design', version)
try {
const res = await fetch('/api/user/design', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ designVersion: version }),
})
if (!res.ok) throw new Error('save failed')
// Cookie is set in the response — read-once nothing else to do here.
} catch {
// Revert on failure.
if (auth.user) auth.user.designVersion = prev
document.documentElement.setAttribute('data-design', prev)
}
}
async function onNativeInstall() {
const accepted = await install()
// If the native prompt failed for any reason (rare — e.g. the event