Local user://settings.cfg meant zoom level didn't follow a student
across devices/browsers. Question bank and CCS text scale now live on
the user's study profile in Mongo (QuestionTextScale/CcsTextScale),
synced through a new PUT /api/profile/me/text-scale endpoint and the
existing preferences GET/cache already used for study preferences.
Both question_player.gd and ccs_service.gd read the synced value at
startup and react to AccountProfileService.profile_changed so a value
pulled down after login (or changed from another session) applies
without a restart. Backend validates the 0.85-1.35 range and updates
only the field(s) provided via a targeted $set, so it can't clobber
the other scale or the unrelated study-profile preferences.
Question bank and CCS case text-size (A-/A+) previously reset to 1.0
on every app launch. Both now load their saved scale from
user://settings.cfg at startup and save on every adjustment, mirroring
the existing pattern used for dark/light mode and sound preferences.
The "WHY OTHER OPTIONS ARE INCORRECT" aggregate section duplicated
explanations that selected wrong choices already showed inside their
own resolved follow-up quiz. Removed that section entirely; choices
the user never picked now get their "why incorrect" explanation
docked directly inside their own card (reusing the same followup
panel/attached-card styling), so every distractor's explanation lives
with its choice instead of in a separate list at the bottom.
The choice button above the panel already shows the letter badge,
choice text, and percentage, so repeating them in the panel header
was redundant now that the panel is docked inside the choice's card.
Keeps the collapse toggle, now named FollowupToggle since the old
FollowupSummary button it lived on is gone.
Now that the explanation panel is docked inside the correct choice's
own green card, the heading was redundant with the badge/border color
already conveying it's the correct answer.
Flag question now uses a clean vector flag (dark/light SVG variants,
replacing a hand-drawn pixel-art icon that got muddied by the shared
toolbar icon-tint override). Report question is now a megaphone
instead of a second flag glyph, since both toolbar buttons looked
identical before.
The correct-answer explanation and the wrong-answer follow-up quiz
previously rendered as separate bordered boxes sitting below the
entire choice list. Both now dock inside their own choice's card:
the explanation panel reparents onto the correct choice's row, the
follow-up panel was already there but visually detached. A shared
_attached_panel_box style drops the shared border/corner between the
choice button and its panel so they read as one continuous card.
Also drop a stale custom_minimum_size(0, 54) reset left over in
_set_choice_button_text from before the answer row redesign - it was
silently overriding the button's real 68px minimum height on every
question load and on every elimination/strikethrough toggle, which is
why choice rows never actually got taller and why striking a choice
through visibly shrank its card.
Fixes the large empty gap below the answer choices reported after the
answer-row redesign - the stem+choices VBox was pinned to the top of an
expand-filled scroll panel with all the leftover height sitting unused
below choice E. Now centers that block when unanswered and reverts to
top alignment once the explanation/review content grows underneath it.
StyleBoxFlat-drawn circles kept looking rough at this size even after
tuning corner detail/antialiasing, so the badges are now two small SVG
assets (outline and filled) tinted per-state via modulate instead -
crisp regardless of size. Also increased row height, badge size, and
margins across the board; the previous pass's padding bump was too
timid and the rows still read as cramped.
Unselected/eliminated choices now sit in a flat list with a thin
bottom divider instead of each getting its own bordered box, and only
the selected/correct/wrong choice pops out as a rounded, tinted card -
closer to the reference mockup and less visually busy than every
option looking like an separate boxed card.
A choice that was crossed out (right-click) and also happened to be
locked as the submitted-wrong choice, or revealed as the correct
answer, silently lost its strikethrough because the percentage-badge
branches took precedence over the elimination check in the same
if/elif chain. Decoupled the two so a choice can show both the
strikethrough and its reveal percentage at once.
Adds a full flashcards system: FSRS-based scheduling, cloze/basic
card types, CSV import/export, media storage, and study UI, wired
into navigation and the dashboard alongside existing question flows.