UI readability pass and Bazaar in-app purchase bridge
- muted text #9e9ec0 -> #727299 (contrast 2.6 -> 4.5 on white); tab labels 11px - map: chapter titles wrap to two lines instead of being cut off - reduced-motion respected (MotionConfig + CSS), focus-visible ring, no pull-to-refresh, short vibration on correct/wrong answers - src/lib/bazaar.ts: bridge to the Android WebView wrapper; checkout uses Bazaar IAP only inside that app, Zarinpal everywhere else (unchanged) - android/: WebView wrapper with Poolakey; written but never built Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -43,12 +43,29 @@ function tone(frequency: number, start: number, duration: number, volume = 0.05)
|
||||
osc.stop(t + duration + 0.02);
|
||||
}
|
||||
|
||||
/**
|
||||
* لرزشِ کوتاه کنارِ صدا، با همان کلیدِ «صدا» خاموش میشود. فقط اندروید/کروم دارد؛
|
||||
* Safariِ آیفون `vibrate` ندارد و اینجا هیچ کاری نمیکند.
|
||||
*/
|
||||
function buzz(pattern: number | number[]) {
|
||||
if (!soundEnabled() || typeof navigator.vibrate !== 'function') return;
|
||||
try {
|
||||
navigator.vibrate(pattern);
|
||||
} catch {
|
||||
/* بعضی WebViewها بیاجازه throw میکنند؛ لرزش فقط تزئینی است */
|
||||
}
|
||||
}
|
||||
|
||||
export const sounds = {
|
||||
tick: () => tone(720, 0, 0.045, 0.04),
|
||||
correct: () => {
|
||||
tone(660, 0, 0.12);
|
||||
tone(990, 0.1, 0.18);
|
||||
buzz(30);
|
||||
},
|
||||
wrong: () => {
|
||||
tone(220, 0, 0.25, 0.06);
|
||||
buzz([40, 60, 40]);
|
||||
},
|
||||
wrong: () => tone(220, 0, 0.25, 0.06),
|
||||
finish: () => [523, 659, 784, 1047].forEach((f, i) => tone(f, i * 0.11, 0.2)),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user