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