Commit Graph
134 Commits
Author SHA1 Message Date
tiennm99 a4e603bb59 fix: update loto submodule for vite patch 2026-07-02 09:11:24 +07:00
tiennm99 8f7aad1ba5 fix(deps): resolve vite dependabot advisories 2026-06-23 15:25:26 +07:00
tiennm99 d31cdcda4a fix(deps): resolve dependabot advisories 2026-06-03 09:38:29 +07:00
dependabot[bot] db76628bad chore(deps-dev): bump @sveltejs/kit in the minor-and-patch group (#20)
Bumps the minor-and-patch group with 1 update: [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit).


Updates `@sveltejs/kit` from 2.60.1 to 2.61.1
- [Release notes](https://github.com/sveltejs/kit/releases)
- [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.61.1/packages/kit)

---
updated-dependencies:
- dependency-name: "@sveltejs/kit"
  dependency-version: 2.61.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-02 10:19:41 +07:00
dependabot[bot] 6275e02a63 chore(deps): bump actions/upload-pages-artifact from 3 to 5 (#21)
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 3 to 5.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v5)

---
updated-dependencies:
- dependency-name: actions/upload-pages-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-02 10:19:24 +07:00
dependabot[bot] 9b73cdb4f9 chore(deps-dev): bump globals from 15.15.0 to 17.6.0 (#18)
Bumps [globals](https://github.com/sindresorhus/globals) from 15.15.0 to 17.6.0.
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v15.15.0...v17.6.0)

---
updated-dependencies:
- dependency-name: globals
  dependency-version: 17.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:36:28 +07:00
dependabot[bot] 866a331eb5 chore(deps-dev): bump vite from 7.3.3 to 8.0.14 (#19)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.3 to 8.0.14.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.14/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.14
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:30:24 +07:00
dependabot[bot] c2b6fc3c2d chore(deps-dev): bump eslint from 9.39.4 to 10.4.0 (#16)
Bumps [eslint](https://github.com/eslint/eslint) from 9.39.4 to 10.4.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.4...v10.4.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 10.4.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:30:19 +07:00
dependabot[bot] 60c21cdf3e chore(deps-dev): bump @sveltejs/vite-plugin-svelte from 6.2.4 to 7.1.2 (#17)
Bumps [@sveltejs/vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte/tree/HEAD/packages/vite-plugin-svelte) from 6.2.4 to 7.1.2.
- [Release notes](https://github.com/sveltejs/vite-plugin-svelte/releases)
- [Changelog](https://github.com/sveltejs/vite-plugin-svelte/blob/main/packages/vite-plugin-svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/vite-plugin-svelte/commits/@sveltejs/vite-plugin-svelte@7.1.2/packages/vite-plugin-svelte)

---
updated-dependencies:
- dependency-name: "@sveltejs/vite-plugin-svelte"
  dependency-version: 7.1.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:23:53 +07:00
dependabot[bot] 2e63cd63d1 chore(deps-dev): bump @eslint/js from 9.39.4 to 10.0.1 (#15)
Bumps [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) from 9.39.4 to 10.0.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v10.0.1/packages/js)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 10.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:23:49 +07:00
dependabot[bot] 87803c06b4 chore(deps-dev): bump eslint-plugin-svelte from 2.46.1 to 3.17.1 (#14)
Bumps [eslint-plugin-svelte](https://github.com/sveltejs/eslint-plugin-svelte/tree/HEAD/packages/eslint-plugin-svelte) from 2.46.1 to 3.17.1.
- [Release notes](https://github.com/sveltejs/eslint-plugin-svelte/releases)
- [Changelog](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/eslint-plugin-svelte/commits/eslint-plugin-svelte@3.17.1/packages/eslint-plugin-svelte)

---
updated-dependencies:
- dependency-name: eslint-plugin-svelte
  dependency-version: 3.17.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:23:45 +07:00
dependabot[bot] 41094c61b1 chore(deps): bump pnpm/action-setup from 4 to 6 (#11)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4 to 6.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v4...v6)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:23:42 +07:00
dependabot[bot] ac0d0ea8d0 chore(deps): bump actions/checkout from 4 to 6 (#12)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:08:45 +07:00
dependabot[bot] f1015a2088 chore(deps): bump actions/deploy-pages from 4 to 5 (#10)
Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:08:40 +07:00
dependabot[bot] b44f5bd09a chore(deps): bump actions/configure-pages from 5 to 6 (#9)
Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 5 to 6.
- [Release notes](https://github.com/actions/configure-pages/releases)
- [Commits](https://github.com/actions/configure-pages/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/configure-pages
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:08:37 +07:00
dependabot[bot] 8f557d9a75 chore(deps): bump actions/setup-node from 4 to 6 (#8)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:08:33 +07:00
dependabot[bot] 98731beead chore(deps-dev): bump the minor-and-patch group with 3 updates (#13)
Bumps the minor-and-patch group with 3 updates: [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit), [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@sveltejs/kit` from 2.59.1 to 2.61.0
- [Release notes](https://github.com/sveltejs/kit/releases)
- [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.61.0/packages/kit)

Updates `svelte` from 5.55.5 to 5.55.9
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/svelte@5.55.9/packages/svelte)

Updates `vitest` from 4.1.5 to 4.1.7
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.7/packages/vitest)

---
updated-dependencies:
- dependency-name: "@sveltejs/kit"
  dependency-version: 2.61.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: svelte
  dependency-version: 5.55.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: vitest
  dependency-version: 4.1.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 18:08:17 +07:00
tiennm99 6992de06e2 chore: add dependabot config (#7) 2026-05-23 10:48:53 +07:00
tiennm99 cbb20a5860 fix(ci): remove duplicate pnpm version spec conflicting with packageManager 2026-05-13 10:54:58 +07:00
tiennm99 25847faf8e chore(ci): bump node to 24 2026-05-13 10:52:19 +07:00
tiennm99 0485e09f68 chore: migrate from npm to pnpm 2026-05-13 10:21:00 +07:00
tiennm99 874710c3ef docs: write substantive README 2026-05-11 20:17:09 +07:00
tiennm99 6c9433c02e docs(plans): record Play Store rollout sequence + session progress 2026-05-10 03:01:35 +07:00
tiennm99 07bbefee0b feat(ci): optional Play Store auto-publish on release tags
Adds a gated step in release.yml that uploads the signed AAB to the
Google Play Console internal track when PLAY_SERVICE_ACCOUNT_JSON is
configured. No-op if the secret is missing, so existing tag releases
keep working unchanged.

Default track is 'internal' for safety; change to alpha/beta/production
once trusted. Promotion can also be done via Play Console UI.

First Play Store upload must still be manual (Google policy).
2026-05-10 02:57:35 +07:00
tiennm99 f842deb46c feat(android): make APK installable on BlueStacks and other emulators
- Declare touchscreen/faketouch/screen.portrait/screen.landscape as
  uses-feature required=false so emulators (BlueStacks reports faketouch)
  and Play Store device filters do not exclude the app.
- Drop explicit webContentsDebuggingEnabled override so Capacitor
  auto-enables WebView inspection in debug builds (chrome://inspect over
  ADB) and disables in release.
- Document the install + troubleshoot path in README.
2026-05-10 02:45:26 +07:00
tiennm99 df1bcdced1 fix(ci): bump JDK to 21 (Capacitor 8 compiles with sourceCompatibility 21) 2026-05-10 02:11:32 +07:00
tiennm99 b2c839c902 fix(ci): bump Node to 22 (Capacitor 8 CLI requires >=22) 2026-05-10 02:05:06 +07:00
tiennm99 7840aa419d feat: migrate to Capacitor wrapper for fully-offline Android
Replace the native Kotlin/Compose port with a Capacitor 8 wrapper around
the upstream loto SvelteKit PWA. Loto is consumed as a git submodule and
its static build is bundled into the APK at sync time. The wrapper has
no INTERNET permission, so fully offline is enforced rather than
conventional.

- loto/ submodule pinned to dfb1c1e
- android/ scaffolded by cap add android; signing wired via env vars
- All 184 voice MP3s + service worker bundled in assets/public/
- CI checkouts submodule, runs npm build, then Gradle inside android/
- Native port preserved in git history at e7fb3d0 and 8b8d46e
2026-05-10 02:03:16 +07:00
tiennm99 0d3d822b36 feat(seo): expand meta tags + PWA manifest for GitHub Pages
- app.html: add format-detection=telephone=no so mobile browsers
  stop auto-linking 2-digit bingo numbers as tel: links.
- app.html: rewrite description to mention Bingo 90, Vietnamese
  voice, offline play; add application-name + apple-mobile-web-app-title.
- app.html: add Open Graph (og:type, locale, site_name, title,
  description, url, image) + Twitter summary card. URLs hardcoded
  to https://tiennm99.github.io/loto/ to match the GH Pages target.
- app.html: add explicit <link rel="icon"> alongside apple-touch-icon.
- manifest.webmanifest: add stable id "/loto/", expanded description,
  and categories ["games", "entertainment"].
2026-05-10 00:37:10 +07:00
tiennm99 4d89366deb chore(plans): sweep shipped plan folders and orphaned reports
Apply the policy stated in plans/todo.md ("all prior plan folders
have been deleted") that had drifted: remove three completed plan
folders (auto-call-countdown, both-mode-state-consistency,
switch-deploy-to-github-pages) and the reports tied to them.

Also remove pre-shipping audits that referenced the now-deleted
Cloudflare _headers / CSP setup, plus the just-actioned
cloudflare-legacy cleanup audit. Keep the evergreen Lô Tô rules
researcher report.

Refresh todo.md hand-off header to reflect the GitHub Pages target.
2026-05-10 00:36:54 +07:00
tiennm99 777b2dbaec refactor: drop dead code left over from Cloudflare era
- Remove vietnamese-number.js + test: build-time Python script
  (generate-audio.py) is the sole spec for pre-baked MP3s; runtime
  no longer reads the JS module.
- Remove resetMaster() export: only ever called from tests; inline
  the two-line body at test sites.
- Update Python docstring to drop the JS-mirror reference.
- Rewrite stale "CF Pages root" comment in svelte.config.js.
2026-05-10 00:36:39 +07:00
tiennm99 8fc3ec6ebd ci(deploy): switch from Cloudflare Pages to GitHub Pages
Migrate build and deployment pipeline from Cloudflare Pages to GitHub Pages.
Adds production-ready deploy workflow in deploy-github-pages.yml with proper
artifact handling. Removes Cloudflare-specific tooling: wrangler config, _headers,
_redirects, and CSP hash injection scripts (no longer needed with GitHub Pages
static hosting). Updates package.json build scripts and all project documentation
to reflect new deployment target and simplified architecture.
2026-05-09 23:25:06 +07:00
tiennm99 a06cbd2675 fix(settings): hide "Báo Chờ / Kinh" toggle in master mode
Master-only mode never mounts PlayerBoard, so no Chờ/Kinh detection
fires — the toggle does nothing. Hide both it and its child
"Đọc thêm số đang chờ" sub-toggle in master mode to avoid the dead
control. Visible in player and both modes as before.
2026-04-30 21:53:25 +07:00
tiennm99 74a235a401 revert(player): bring back the gradient cross-slash style
The SVG-line replacement from the gradient-cleanup refactor (commit
635a4c3) drew the slash on the main diagonal (top-left → bottom-right)
and stopped at the inset:6px box edge — visually disconnected from the
cell vertices. The original CSS gradient stripe goes corner-to-corner
of the inset box on the anti-diagonal (the natural slash direction
for Vietnamese lô tô), with a clip-path reveal animation that reads
as "drawing" the slash.

- Restore .cell-crossed / .cell-crossed-win pseudo classes
- Replace the inline <svg> markup with a single <span> + class
- Restore cross-draw keyframes (clip-path inset reveal)
- prefers-reduced-motion: keep slash drawn, drop the reveal animation
2026-04-30 21:48:50 +07:00
tiennm99 dbed8aa664 chore(plans): add waiting-cell research + brainstorm reports 2026-04-30 21:41:50 +07:00
tiennm99 02d492c29c feat(player): center "Chờ N" chip + pulse the awaited cell
The toast above the card was disconnected from where the user actually
looks (the 9×9 grid). Two-part redesign per /ck:research + /ck:brainstorm:

- Chip moved to the vertical center of the card with bg-amber-500/75 +
  backdrop-blur-sm + pointer-events-none on the wrapper. Taps still
  pass through to the cells underneath; auto-hide stays at 5s.
- Persistent 1.6s breathing pulse on the cell holding the awaited
  number — amber inset ring + soft outer glow, dimmed in
  prefers-reduced-motion to a static ring. Material 3-style cadence
  picked over scale-bounce because the grid is dense and bouncing
  cells would smudge neighbours.

Pulses scale to multiple simultaneous waiting rows (Set-keyed by
"row,col"). aria-label gains "đang chờ" so screen readers pick it up.
2026-04-30 21:41:39 +07:00
tiennm99 3d988e1fc4 refactor(active-tab): rename tab-lock to active-tab for clarity
The "lock" framing was misleading — there's no OS-level mutex; this is
a soft coordinator that decides which tab is the active one. Rename
makes the role obvious at the import site.

- file: tab-lock.svelte.js → active-tab.svelte.js (+ test)
- export: tabLock → activeTab
- field: .frozen → .inactive (positive form: this tab is inactive)
- fn: startTabLock → watchActiveTab
- fn: reclaimTab → claimActiveTab
- BroadcastChannel name: loto_tab_lock → loto_active_tab

No behavior change. Banner copy already updated separately.
2026-04-30 21:34:06 +07:00
tiennm99 64e496b777 fix(tab-lock): formalize banner copy
Drop casual loanword 'Tap', use neutral formal Vietnamese for the freeze banner shown to all users (not just internal team).
2026-04-30 21:25:30 +07:00
tiennm99 7a4a4e0450 chore(plans): add voice + multi-tab brainstorm report 2026-04-30 21:22:31 +07:00
tiennm99 2f4efd1cab feat(tab-lock): single-tab guard via BroadcastChannel
Two tabs of the app on the same origin both running auto-call would
double-draw, double-write `loto_master`, and overlap audio. New tab
now broadcasts a claim; old tab freezes itself with a fullscreen
overlay ("Loto đã mở ở tab khác. Tap để chuyển về tab này.") and the
user can tap to take it back — handover broadcasts a fresh claim,
freezing the other tab in turn.

Mounted in +layout.svelte's onMount so the cleanup closes the channel
on HMR / route changes. No-op in legacy iOS Safari (≤15.4) without
BroadcastChannel — silently falls through to the prior behavior.
2026-04-30 21:22:23 +07:00
tiennm99 9e9c68bff6 fix(voice): suppress "Chờ {số}" in both mode
Master is the audio owner in both mode and is already calling numbers
aloud, so the player-side "Chờ N" announcement that fires right after
a master call confused listeners — they couldn't tell which number was
the active draw vs the awaited row.

- voice.js playWaiting: gate `speakNumber` on `mode !== "both"`
- SettingsButton: hide the "Đọc thêm số đang chờ" toggle in both mode

The bare-word "Chờ" still plays so the host knows a row is one cell
away. Setting persists across mode toggles — the gate is at the call
site, not in storage.
2026-04-30 21:22:18 +07:00
tiennm99 dbf93e29dd chore(plans): add both-mode consistency plan + audit reports 2026-04-30 21:10:58 +07:00
tiennm99 64a2f7b515 refactor(state): replace call-bus with shared master-store for both-mode
Single-slot bus carried only the latest draw, so any state event off-bus
(player regen, master "Ván mới", reload, mode toggle, throttled tab)
silently lost history. Symptom the host hit: regenerating the player
board mid-game wiped all prior auto-crosses.

- master-store.svelte.js: lifted {called, remaining} out of MasterPanel
  into shared reactive $state, persisted to loto_master, hydrated once
  in +layout.svelte's onMount so panels mount with consistent state
- player-auto-cross.js: new applyMasterCalls helper using cursor-by-index
  (vs the retired Date.now-based at timestamp), so callers can pass
  lastHandledIndex: 0 to replay master's full history on demand
- PlayerBoard:
  - Reads masterState.called directly; cursor advances strictly
  - manualUnticks Set tracks user-initiated unticks of called numbers,
    suppressing re-cross on replay; persisted to loto_manualUnticks
  - "Tạo bảng mới" replays masterState.called onto fresh grid (in both)
  - "Xoá đánh dấu" clears + immediately replays in both mode
  - Master "Ván mới" detected by called length transitioning >0 → 0,
    force-clears player crossed + manualUnticks (locked product call)
- Killed call-bus.svelte.js + auto-tick.js and their tests; helper
  surface is fully covered by master-store.test.js (9) and
  player-auto-cross.test.js (10), plus 6 new manualUnticks cases in
  game-logic.test.js (134 tests passing, was 123 before this refactor)

Targets findings F1, F2, F4, F6, F7, F8, F10 from the 2026-04-30
both-mode consistency audit. F9 (voice ownership) and #20 (multi-tab)
remain out of scope — separate plans to follow.
2026-04-30 21:10:51 +07:00
tiennm99 2b6a8c91f1 fix(master): break effect_update_depth_exceeded loop in countdown
Two $effects were reading state they also wrote, turning each into its
own dependency:

- AutoCountdown reset effect: `now = tickStart` read tickStart after
  writing it. Use a local snapshot so neither rune is read post-write.
- MasterPanel auto-call effect: `tickCount++` read tickCount. Drop the
  bump here — AutoCountdown's reset effect already re-baselines on the
  rising edge of `running` and on `duration` change, so re-arms remain
  covered. handleDrawNext keeps its per-draw bump (not in effect scope).
2026-04-30 19:47:22 +07:00
tiennm99 1e89137fa6 chore(plans): add countdown indicator plan + review report 2026-04-30 19:32:09 +07:00
tiennm99 7eb96808b0 feat(master): add auto-call countdown indicator
Visible countdown ring + seconds number above the hero token while
auto-call runs. Host now sees exactly when the next number fires
instead of staring at a static caption.

- AutoCountdown.svelte: pure visual component, props-driven, rAF loop,
  SVG ring via stroke-dashoffset, prefers-reduced-motion fallback
- MasterPanel.svelte: tickCount $state bumped per draw + on every
  (re-)arm of the auto-call $effect (covers speed-slider mid-run)
2026-04-30 19:32:02 +07:00
tiennm99 7f5b4bac95 chore: add Apache-2.0 license 2026-04-29 21:33:26 +07:00
tiennm99 04e4cf7a41 chore: add Apache-2.0 license 2026-04-29 21:33:25 +07:00
tiennm99 e80087c339 chore(plans): record 260429-1511 upstream-sync plan + reports
Plan directory and recon/code-review reports for the 6-commit
upstream sync from tiennm99/loto @ 2fb35f2.
2026-04-29 16:26:23 +07:00
tiennm99 593c270211 refactor: KinhModal title color to solid amber (palette refactor)
- Remove gradient brush from "Kinh!" title, use solid BrandAmber600.
- Align with solid-color palette refactor (phase 03).
- Update button and text colors to new palette.

Upstream: a60ea08
2026-04-29 16:25:01 +07:00