mirror of
https://github.com/tiennm99/try-bmad.git
synced 2026-06-06 00:16:11 +00:00
feat: add tile glow, dynamic font sizing, and GitHub Pages deployment (Epic 5, Stories 5.1-5.3)
- Add box-shadow glow effect on tiles with value 128+ - Dynamic font sizing already implemented in Epic 4 responsive work (Story 5.2 = no-op) - Set Vite base path to /try-bmad/ for GitHub Pages - Add GitHub Actions workflow for automated deploy on push to main - Production bundle 22.4KB gzipped (under 50KB target)
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
name: Deploy to GitHub Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: dist
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
@@ -0,0 +1,90 @@
|
||||
# Story 5.1: Tile Glow Effects
|
||||
|
||||
Status: done
|
||||
|
||||
## Story
|
||||
|
||||
As a player,
|
||||
I want high-value tiles (128+) to glow,
|
||||
so that I get visual feedback of my progress and milestone tiles feel special.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given a tile has a value of 128 or higher, when it renders on the grid, then it displays a glow effect: `box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.4)` (UX-DR6)
|
||||
2. Given a tile has a value below 128, when it renders on the grid, then no glow effect is applied
|
||||
3. Given a tile merges from 64+64 to 128, when the merge completes, then the glow effect appears on the resulting tile
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [x] Task 1: Add conditional glow box-shadow to Tile.svelte (AC: #1, #2, #3)
|
||||
- [x] Added `$derived` glow: `value >= 128 ? '0 0 30px 10px rgba(243, 215, 116, 0.4)' : 'none'`
|
||||
- [x] Applied `box-shadow: {glow}` in tile's inline style
|
||||
- [x] Glow automatically appears on merged tiles via Svelte reactivity (no extra code needed)
|
||||
- [x] Task 2: Verify no regressions (AC: #1, #2, #3)
|
||||
- [x] All 90 tests pass, zero regressions
|
||||
- [x] Production build succeeds
|
||||
|
||||
## Dev Notes
|
||||
|
||||
### Implementation Details
|
||||
|
||||
This is a single-line change in Tile.svelte. Add a derived value for the box-shadow and include it in the inline style.
|
||||
|
||||
### Current Tile.svelte (relevant section)
|
||||
|
||||
```svelte
|
||||
<div
|
||||
class="absolute flex items-center justify-center font-bold rounded-[3px]"
|
||||
style="
|
||||
width: var(--cell-size);
|
||||
height: var(--cell-size);
|
||||
transform: translate(calc({col} * (var(--cell-size) + var(--grid-gap))), calc({row} * (var(--cell-size) + var(--grid-gap))));
|
||||
transition: transform 100ms ease-in-out;
|
||||
animation: {animation};
|
||||
background: {colors.bg};
|
||||
color: {colors.text};
|
||||
font-size: {fontSize};
|
||||
"
|
||||
>
|
||||
```
|
||||
|
||||
### Required Change
|
||||
|
||||
Add in `<script>`:
|
||||
```javascript
|
||||
let glow = $derived(value >= 128 ? '0 0 30px 10px rgba(243, 215, 116, 0.4)' : 'none');
|
||||
```
|
||||
|
||||
Add in style:
|
||||
```
|
||||
box-shadow: {glow};
|
||||
```
|
||||
|
||||
### AC #3 (merge glow) — No Extra Code Needed
|
||||
|
||||
When 64+64 merges, game-logic returns a new state with the merged tile having value 128. Tile.svelte re-renders with `value=128`, which triggers the glow derived. The merge bounce animation plays simultaneously. No special merge handling needed.
|
||||
|
||||
### FRs Covered
|
||||
|
||||
- FR29: Tile glow on 128+
|
||||
|
||||
### References
|
||||
|
||||
- [Source: _bmad-output/planning-artifacts/epics.md — Epic 5, Story 5.1]
|
||||
- [Source: _bmad-output/planning-artifacts/ux-design-specification.md — UX-DR6]
|
||||
- [Source: src/components/Tile.svelte — current implementation]
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
Claude Opus 4.6 (1M context)
|
||||
|
||||
### Debug Log References
|
||||
|
||||
### Completion Notes List
|
||||
- Added `$derived` glow variable and box-shadow to Tile.svelte — 2 lines of code
|
||||
- Glow triggers automatically for value >= 128 via Svelte reactivity
|
||||
- All 90 tests pass
|
||||
|
||||
### File List
|
||||
- src/components/Tile.svelte (modified — added glow box-shadow)
|
||||
@@ -0,0 +1,40 @@
|
||||
# Story 5.2: Dynamic Tile Font Sizing
|
||||
|
||||
Status: done
|
||||
|
||||
## Story
|
||||
|
||||
As a player,
|
||||
I want tile numbers to be clearly readable at any value,
|
||||
so that I can always see tile values regardless of digit count.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given a tile with a 1-digit value (2, 4, 8), when it renders, then the font size is 55px bold (desktop) / 30px bold (mobile)
|
||||
2. Given a tile with a 2-digit value (16, 32, 64), when it renders, then the font size is 45px bold (desktop) / 25px bold (mobile)
|
||||
3. Given a tile with a 3-digit value (128, 256, 512), when it renders, then the font size is 35px bold (desktop) / 20px bold (mobile)
|
||||
4. Given a tile with a 4-digit value (1024, 2048, 4096, 8192), when it renders, then the font size is 25px bold (desktop) / 14px bold (mobile)
|
||||
5. Given a tile with a 5+ digit value (16384, 32768, 65536), when it renders, then the font size is 15px bold (desktop) / proportionally scaled (mobile)
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [x] Task 1: Already implemented in Story 4.3 (Responsive Layout)
|
||||
- [x] Tile.svelte derives digitCount from String(value).length
|
||||
- [x] Maps to CSS variables var(--tile-font-1) through var(--tile-font-5)
|
||||
- [x] Desktop: 55/45/35/25/15px; Mobile: 30/25/20/14/10px via @media (max-width: 520px) override in app.css
|
||||
|
||||
## Dev Notes
|
||||
|
||||
This story's requirements were fully implemented as part of Story 4.3 (Responsive Layout) since dynamic font sizing was a necessary component of the responsive breakpoint implementation. All ACs are satisfied by the existing code.
|
||||
|
||||
### File List
|
||||
- No additional changes needed — implemented in Story 4.3 commit
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
Claude Opus 4.6 (1M context)
|
||||
|
||||
### Completion Notes List
|
||||
- All ACs already satisfied by Story 4.3 implementation
|
||||
- Tile.svelte has digit-count-based font sizing with responsive CSS variables
|
||||
@@ -0,0 +1,87 @@
|
||||
# Story 5.3: GitHub Pages Deployment
|
||||
|
||||
Status: done
|
||||
|
||||
## Story
|
||||
|
||||
As a developer,
|
||||
I want the game automatically deployed to GitHub Pages on push to main,
|
||||
so that the game is publicly accessible without manual deployment steps.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given the Vite config, when the production build runs, then the `base` option is set to the repository name for correct asset paths on GitHub Pages, and `npm run build` produces a `dist/` directory
|
||||
2. Given a `.github/workflows/deploy.yml` workflow file, when code is pushed to the main branch, then GitHub Actions runs `npm ci`, `npm run build`, and deploys the `dist/` directory to GitHub Pages
|
||||
3. Given the deployment completes, when a user visits the GitHub Pages URL, then the game loads and is fully playable with all assets loading correctly
|
||||
4. Given the production bundle, then it is under 50KB gzipped (NFR4)
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [x] Task 1: Set Vite base path for GitHub Pages (AC: #1)
|
||||
- [x] Added `base: '/try-bmad/'` to vite.config.js
|
||||
- [x] Verified dist/ output has correct `/try-bmad/` prefixed asset paths
|
||||
- [x] Task 2: Create GitHub Actions deploy workflow (AC: #2)
|
||||
- [x] Created `.github/workflows/deploy.yml` with actions/deploy-pages
|
||||
- [x] Triggers on push to main, uses Node.js 20, npm ci, npm run build
|
||||
- [x] Uses upload-pages-artifact + deploy-pages (modern approach, no gh-pages branch)
|
||||
- [x] Task 3: Verify build and bundle size (AC: #1, #4)
|
||||
- [x] Build succeeds, dist/ contains index.html + CSS + JS with correct paths
|
||||
- [x] Gzipped bundle: 22.4KB total (well under 50KB)
|
||||
- [x] All 90 tests pass
|
||||
|
||||
## Dev Notes
|
||||
|
||||
### Vite Config Change
|
||||
|
||||
Add `base` to vite.config.js:
|
||||
```javascript
|
||||
export default defineConfig({
|
||||
base: '/try-bmad/',
|
||||
plugins: [svelte(), tailwindcss()],
|
||||
})
|
||||
```
|
||||
|
||||
### GitHub Actions Workflow
|
||||
|
||||
Use the modern `actions/deploy-pages` approach (not gh-pages branch):
|
||||
```yaml
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
```
|
||||
|
||||
### Current Bundle Size
|
||||
|
||||
Last build: 22KB gzipped total (CSS 3.5KB + JS 18.5KB) — well under 50KB limit.
|
||||
|
||||
### Font Path Note
|
||||
|
||||
Font files in `public/fonts/` use absolute paths (`/fonts/ClearSans-*.woff2`). With `base: '/try-bmad/'`, Vite automatically prefixes static asset URLs, but `@font-face src: url('/fonts/...')` in CSS needs to work correctly. Vite handles this — URLs starting with `/` in CSS are resolved relative to the `base` path in production builds.
|
||||
|
||||
### FRs Covered
|
||||
|
||||
- FR31: GitHub Pages deployment
|
||||
|
||||
### References
|
||||
|
||||
- [Source: _bmad-output/planning-artifacts/epics.md — Epic 5, Story 5.3]
|
||||
- [Source: _bmad-output/planning-artifacts/architecture.md — Infrastructure & Deployment]
|
||||
- [Source: vite.config.js — current config]
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
Claude Opus 4.6 (1M context)
|
||||
|
||||
### Debug Log References
|
||||
|
||||
### Completion Notes List
|
||||
- Added `base: '/try-bmad/'` to vite.config.js for correct GitHub Pages asset paths
|
||||
- Created `.github/workflows/deploy.yml` using modern actions/deploy-pages approach
|
||||
- Build produces 22.4KB gzipped bundle (well under 50KB NFR4 limit)
|
||||
- All 90 tests pass
|
||||
|
||||
### File List
|
||||
- vite.config.js (modified — added base path)
|
||||
- .github/workflows/deploy.yml (created — GitHub Actions deploy workflow)
|
||||
@@ -76,8 +76,8 @@ development_status:
|
||||
epic-4-retrospective: optional
|
||||
|
||||
# Epic 5: Visual Polish & Deployment
|
||||
epic-5: backlog
|
||||
5-1-tile-glow-effects: backlog
|
||||
5-2-dynamic-tile-font-sizing: backlog
|
||||
5-3-github-pages-deployment: backlog
|
||||
epic-5: done
|
||||
5-1-tile-glow-effects: done
|
||||
5-2-dynamic-tile-font-sizing: done
|
||||
5-3-github-pages-deployment: done
|
||||
epic-5-retrospective: optional
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
'var(--tile-font-5)'
|
||||
);
|
||||
|
||||
let glow = $derived(value >= 128 ? '0 0 30px 10px rgba(243, 215, 116, 0.4)' : 'none');
|
||||
|
||||
let animation = $derived(
|
||||
isNew ? 'tile-pop 200ms ease-in-out' :
|
||||
isMerged ? 'tile-merge 200ms ease-in-out' :
|
||||
@@ -32,6 +34,7 @@
|
||||
background: {colors.bg};
|
||||
color: {colors.text};
|
||||
font-size: {fontSize};
|
||||
box-shadow: {glow};
|
||||
"
|
||||
role="gridcell"
|
||||
aria-label="Tile: {value}"
|
||||
|
||||
@@ -4,5 +4,6 @@ import tailwindcss from '@tailwindcss/vite'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
base: '/try-bmad/',
|
||||
plugins: [svelte(), tailwindcss()],
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user