ui: rename tone "Novice" → "Pro"; fit tone-toggle to longest option

User-visible relabel only. Backend tone value stays NOVICE — no API
contract change, no migration on stored user.digest_tone, the
glossary/plain-prose depth of analysis is unchanged. The marketing
intent is that "Pro" reads better than "Novice" on the dashboard
header; landing/pricing/privacy copy still uses the word "Novice" in
flowing prose, so leaving those alone keeps the existing explanations
coherent until they get a copy pass.

Toggle width: the popup expansion (positioned left:0/right:0) is
sized by the container, which previously sized to the active button.
When "Pro" was active the popup was too narrow to fit "Intermediate".
Bumped .tone-toggle button min-width to 10em so both buttons reserve
enough room for the longest label regardless of which one is active.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Giorgio Gilestro 2026-05-29 11:17:43 +02:00
parent f57c863145
commit 71155a67be
3 changed files with 11 additions and 2 deletions

View file

@ -157,6 +157,11 @@ body.drawer-open .drawer-backdrop { opacity: 1; }
.tone-toggle button + button, .tone-toggle button + button,
.theme-toggle button + button, .theme-toggle button + button,
.lang-toggle button + button { border-left: 1px solid var(--border); } .lang-toggle button + button { border-left: 1px solid var(--border); }
/* The tone-toggle's longer option ("Intermediate", 12 chars) needs more
room than the shared 5.5em min-width. We size both buttons to fit the
longest one so the popup width (set by container width via left/right:0)
doesn't get clipped when only the short "Pro" label is active. */
.tone-toggle button { min-width: 10em; }
.tone-toggle button:hover, .tone-toggle button:hover,
.theme-toggle button:hover, .theme-toggle button:hover,
.lang-toggle button:hover { color: var(--accent); } .lang-toggle button:hover { color: var(--accent); }

View file

@ -234,10 +234,14 @@
<a href="/log" class="{% if request.url.path.startswith('/log') %}active{% endif %}">Log</a> <a href="/log" class="{% if request.url.path.startswith('/log') %}active{% endif %}">Log</a>
</nav> </nav>
<div class="header-right"> <div class="header-right">
{# The "Pro" label maps to the NOVICE tone server-side — kept that
way to avoid touching every stored user preference and API
contract. The mode itself (glossary tooltips + plainer
framing) is unchanged; only the display label changes. #}
<div id="tone-toggle" class="tone-toggle" data-tone="INTERMEDIATE" <div id="tone-toggle" class="tone-toggle" data-tone="INTERMEDIATE"
role="group" aria-label="Explanation level"> role="group" aria-label="Explanation level">
<button type="button" data-value="NOVICE" <button type="button" data-value="NOVICE"
onclick="cassandraSetTone('NOVICE')">Novice</button> onclick="cassandraSetTone('NOVICE')">Pro</button>
<button type="button" data-value="INTERMEDIATE" <button type="button" data-value="INTERMEDIATE"
onclick="cassandraSetTone('INTERMEDIATE')">Intermediate</button> onclick="cassandraSetTone('INTERMEDIATE')">Intermediate</button>
</div> </div>

View file

@ -185,7 +185,7 @@
<div class="settings-row__value"> <div class="settings-row__value">
<div style="display:flex; gap:14px;"> <div style="display:flex; gap:14px;">
<label><input type="radio" name="digest-tone" value="NOVICE" <label><input type="radio" name="digest-tone" value="NOVICE"
{% if (user.digest_tone or 'INTERMEDIATE') == 'NOVICE' %}checked{% endif %}> Novice</label> {% if (user.digest_tone or 'INTERMEDIATE') == 'NOVICE' %}checked{% endif %}> Pro</label>
<label><input type="radio" name="digest-tone" value="INTERMEDIATE" <label><input type="radio" name="digest-tone" value="INTERMEDIATE"
{% if (user.digest_tone or 'INTERMEDIATE') == 'INTERMEDIATE' %}checked{% endif %}> Intermediate</label> {% if (user.digest_tone or 'INTERMEDIATE') == 'INTERMEDIATE' %}checked{% endif %}> Intermediate</label>
</div> </div>