Brand and design · Specs

Engagement system — "a bit addictive", within limits

Quests, XP, streaks, levels, achievements, notifications, haptics and motion per moment.

The core loop is already the best hook. You say something, get one concrete thing to change, say it again, and see the difference (the before/after block). Everything below amplifies that loop. Nothing below replaces it. All mechanics follow ADR-001 D4 (XP, streak, levels) and D10 (allowed / not allowed).

Mechanics

Mechanic Where Rule (source) Design
Daily quest Home ink card One article per day in a practice language, plan theme applied (today_quest) Lime XP badge, 3-step path (read / retell / compress) showing the real stage, focus chip "Last advice: Conclusion first", one coral CTA. Completed state shows the round 1 → 2 result (CCR-2) and offers free practice.
XP Quest badge, completion, level bar 15 / 20 / 10 / +10 improve; daily cap 165; 50 % on repeats within 7 days; diagnostic once (D4) Completion lists every line, including the bonus you didn't get (struck through: "when take two scores higher"), so the rule is learnable rather than a slot machine.
XP bar fill Completion level card level_before → level_after Lime fill on an ink capsule, 900 ms emphasized ease, 600 ms delay after the trophy. Striped "gain" segment. Selection haptic tick every 10 XP (max 8 ticks).
Level-up Full-screen overlay thresholds L2 100 … L10 2700, titles per D4 Ink overlay, lime badge pops (spring), 8 rays, "You’re now a Concise Speaker", XP to next. Heavy impact → success haptic. Shown once per settlement (replayed suppresses it).
Streak Home pill, completion tile, Profile +1 on the first completed session of a local day; ≥ 20 h guard (D4) Amber flame, outline when not done today, filled when done. Completion tile shows "+1" with a rigid haptic.
Streak freeze Streak-risk card, notification 1 per 7-day milestone, max 2, consumed automatically (D4). Freeze UI is v1.1 (D7). v1 only mentions it to remove pressure ("If today doesn’t work out, you still have 1 streak freeze") and confirms after use (CCR-8). No buying, no repairing.
Streak at risk Home after 20:00, one notification streak.at_risk Calm amber card: "Not yet today — 10 minutes is enough". Never "You'll lose…".
Before/after block Every completion round1_overall → round2_overall, durations, overall_delta The signature moment: ink block, round 2 in lime with a count-up from the round-1 value. When there's no improvement it stays neutral white. "Shorter but lost points" adds the missed point in amber. Session delta and ability change are separate tiles, so a +11 session never looks like +11 ability.
"You did it ✓" Top of feedback achieved_previous_action (D9) First thing on screen, green, soft haptic. This is the progression hook: advice → attempt → recognition.
Achievements Completion sheet, Growth row D10 list: First Win, Conclusion First ×3, 3-Day, 7-Day, 10 Sessions, Efficiency +10, Compressed ×5 Lime tile, sheet after the trophy (queued, one at a time), locked ones show progress "4 / 5".
Weekly quests Profile, completion card retell 5 / compress 3 / follow advice 3; Monday reset in user tz Progress bars with XP. Counting rules are spelled out on the weekly screen. XP semantics need CCR-10.
Micro-skill mastery Growth grid achieved / suggested over the last 10 sessions (D9) Pips per suggestion (green = done). The current focus is outlined. Untried skills are visible but empty: curiosity, not failure.
"Next trend point" hook Growth chart growth.next_unlock + partial current week (CCR-5) Dashed ring where this week's point will appear, plus a lock pill "Train tomorrow to unlock this week’s point".
14-day plan Plan, paywall calendar, quest tag D9 "14-day plan · Day 3" tag on the quest; day 7 review, day 14 re-test against the starting score.
Language variety Library, Growth chips D13 Practising in a second language is framed as a choice ("Practice languages"), never as an upsell or a separate streak.

Notifications (max one per local day, total)

Priority if several qualify on the same day: trial-ending (a billing notice the user must get) > result-ready (only if the user left processing) > plan/daily reminder > streak-risk. Once one is sent, the rest are dropped for that day, so a trial-ending day sends no reminder. Quiet hours 22:00–08:00 (except result-ready within 10 min of submit). Time zone follows me.timezone.

Trigger Time en zh-Hans Key
Daily reminder settings.reminder_time Today’s 10 minutes: {article title} 今天的 10 分钟:{title} notif.daily.body
Plan day reminder_time while a plan is active Plan day {n} · today: {skill} 计划第 {n} 天 · 今天练「{skill}」 notif.daily.body.plan
Focus reminder_time, no plan Try “{skill}” today: {instruction} 今天试试「{skill}」:{instruction} notif.daily.body.focus
Streak risk 20:00 if not done and the daily wasn't sent {n} days in a row. There’s still time today — 10 minutes is enough. 连续 {n} 天了。今天还有时间,10 分钟就够。 notif.risk.body (+ .freeze)
Result ready when assessed, if the user left processing Your feedback is ready: {summary} 反馈好了:{summary} notif.result_ready.body
Trial ending day before billing, 10:00 Your trial ends tomorrow… cancel today… you won’t be charged. 试用明天结束… notif.trial_ending.body

Rules: never a notification on the day of a completed session (except result-ready). No "we miss you" re-engagement series in v1. Two ignored streak-risk notifications in a row → stop streak-risk until the next completed session.

Haptics and motion per moment

Moment Motion (reduced-motion variant) Haptic
Record start button colour → coral 160 ms; rings start breathing 1600 ms (rings static) impact medium
Pause / resume button swap 160 ms impact light
Auto-stop sheet slides up 400 ms (cross-fade) warning
Assessment ready processing → feedback push; ring arc draws 1200 ms (instant) success
"You did it ✓" banner fade + 8 pt rise 240 ms (fade) soft impact
Evidence tap row tint 160 ms; playback selection
Diagnostic reveal score counts 0 → N 1200 ms, dimensions stagger 80 ms (instant) success at the end
Trophy pop: scale .4 → 1, rotate −20° → −6°, spring 900 ms; 6 rays (fade only) success
Round-2 count-up r1 → r2 over 1200 ms after 500 ms (instant) —
XP fill 900 ms emphasized after 600 ms (instant) selection every 10 XP, max 8
Streak +1 "+1" fades in after the XP fill impact heavy (once)
Level-up overlay fade 240 ms, badge spring, 8 rays (fade only) heavy → success +120 ms
Achievement sheet sheet 400 ms after the level-up is dismissed (fade) success
Paywall slider detent projection number cross-fade 160 ms; bar slides 400 ms (instant) selection
Purchase success toast spring success

All celebrations are skippable (tap anywhere completes the animation) and never block the CTA for more than 1.2 s.

Dark patterns we explicitly do NOT use

  1. Guilt or shame copy. No "Your streak will die", "You're falling behind", "Don't give up on yourself".
  2. Fake scarcity and countdowns. None on the paywall or anywhere else.
  3. Decoy pricing, crossed-out reference prices, or "most popular" claims without data.
  4. More than one notification a day, re-engagement spam, or badge-count manipulation.
  5. Loss-framed streak repair purchases (pay to restore a streak). Freezes are earned, never sold.
  6. Variable-ratio rewards. XP is deterministic and fully itemised. No loot boxes or random bonuses.
  7. False praise. The headline is conditional on the verdict. "Shorter but lost points" gets no trophy. A regression is called normal, not failure.
  8. Hidden or delayed close. The hard paywall is openly hard: no fake close button. Every other sheet is dismissible immediately.
  9. Confirmshaming on "Not now", cancel, or delete. All are neutral verbs.
  10. Infinite feed / autoplay. After a session, the next step is a choice (Progress / Home). We never auto-start another article.
  11. Social comparison leaderboards. Benchmarks appear only on the paywall, labelled, with sample sizes, and never rank individuals.
  12. Dark defaults. Notifications need explicit opt-in. Analytics never include content. Audio retention defaults to 30 days, not "forever".