Calmer shop with payment choice, step-by-step phone back, sound/haptics that reach the phone, live streak flame
- Shop: subscription perks shown once (each card repeated them, «۳ سوال در روز» twice), plans as selectable rows with one big buy button, prices as «۷۹۸ هزار تومان», a single clear status card for subscribers. Checkout inside the Bazaar app offers «کارتِ بانکی» (default) or «کافهبازار» for packs with a SKU; «بهزودی در بازار» is gone. The gateway opens in the phone browser; status refreshes on return. - Back button: every back-able level (open sheet, pushed screen, non-home tab, shop list) owns exactly one history entry created right after the tap; back closes the sheet, then the screen, then returns to Home, then leaves the app. (A re-pushed trap is skipped by Chrome's history intervention.) - Sound: AudioContext unlocked on the first touch (it was created after a network wait, which WebView/Safari keep muted); softer notes, option tick, finish fanfare, streak whoosh. Haptics through the new TadrisinoAndroid.vibrate bridge when the APK has it, navigator.vibrate otherwise. - Streak: animated flame with lit / at-risk (grey) / frozen (ice) states on Home and the streak screen, a companion reminder when the streak is at risk or frozen, and a full-screen «روزِ پیاپی» celebration after the first lesson of the day (needs backend 9024c6b: streak.activeToday / lost). - Lessons: intro/example text with inline «۱. … ۲. …» renders as a numbered list (2,250 of 4,469 texts). - Quiz: duplicate React key on the answer bubble fixed. - android/MainActivity.kt: vibrate bridge and mediaPlaybackRequiresUserGesture=false. Not built; needs the next APK from the signing owner. Checked in headless Chrome against the local backend (shop as a subscriber with the Bazaar bridge stubbed, back sequences, quiz → streak celebration, frozen state). Not checked on a real phone or in the APK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -123,3 +123,13 @@
|
||||
/* نوارِ انتظارِ میانِ دو صفحه (MainApp → HoldBar). */
|
||||
@keyframes hold-bar { 0% { transform: translateX(120%); } 100% { transform: translateX(-320%); } }
|
||||
.hold-bar { animation: hold-bar 0.9s cubic-bezier(.4,0,.2,1) infinite; will-change: transform; }
|
||||
|
||||
/* شعلهی زنجیره (StreakFlame): دو لایه با ریتمِ متفاوت، از پایین تکان میخورند. */
|
||||
@keyframes flame-a { 0%, 100% { transform: scale(1, 1) skewX(0deg); } 33% { transform: scale(.97, 1.04) skewX(-2deg); } 66% { transform: scale(1.02, .97) skewX(2deg); } }
|
||||
@keyframes flame-b { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(.94, 1.08); } }
|
||||
.flame-outer { transform-box: fill-box; transform-origin: 50% 100%; animation: flame-a 1.4s ease-in-out infinite; }
|
||||
.flame-inner { transform-box: fill-box; transform-origin: 50% 100%; animation: flame-b .9s ease-in-out infinite; }
|
||||
@keyframes ice-glint { 0%, 70%, 100% { opacity: 0; } 80% { opacity: 1; } }
|
||||
.ice-glint { animation: ice-glint 2.8s ease-in-out infinite; }
|
||||
@keyframes spark-rise { 0% { transform: translateY(0) scale(1); opacity: 0; } 15% { opacity: 1; } 100% { transform: translateY(-180px) scale(.3); opacity: 0; } }
|
||||
.spark-rise { animation: spark-rise 1.8s ease-out infinite; }
|
||||
|
||||
Reference in New Issue
Block a user