001-mcdonald-s-it #1
364
specs/001-mcdonald-s-it/contracts/page-content.schema.json
Normal file
364
specs/001-mcdonald-s-it/contracts/page-content.schema.json
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://mcdonald-s-it-halloween.schema.json",
|
||||||
|
"title": "McDonald's IT Halloween Event Page Content Schema",
|
||||||
|
"description": "Schema defining the structure and validation rules for the Halloween 2025 event page content",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["meta", "theme", "event", "countdown", "ascii"],
|
||||||
|
"properties": {
|
||||||
|
"meta": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Page metadata for browser and SEO",
|
||||||
|
"required": ["title", "description", "favicon"],
|
||||||
|
"properties": {
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "2025 MITA Halloween",
|
||||||
|
"description": "Browser tab title"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 50,
|
||||||
|
"maxLength": 160,
|
||||||
|
"description": "Meta description for SEO",
|
||||||
|
"default": "McDonald's China IT Halloween 2025 - Join 300 MITA developers for cosplay, debugging games, and lucky draw at MITA Building 2F Pantry"
|
||||||
|
},
|
||||||
|
"favicon": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^data:image",
|
||||||
|
"description": "Data URI for favicon (pumpkin emoji)"
|
||||||
|
},
|
||||||
|
"lang": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["en", "zh-CN"],
|
||||||
|
"default": "en",
|
||||||
|
"description": "Primary page language"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Visual design theme configuration",
|
||||||
|
"required": ["backgroundColor", "primaryColor", "accentColor", "fontFamily"],
|
||||||
|
"properties": {
|
||||||
|
"backgroundColor": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9A-Fa-f]{6}$",
|
||||||
|
"const": "#000000",
|
||||||
|
"description": "Pure black background"
|
||||||
|
},
|
||||||
|
"primaryColor": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9A-Fa-f]{6}$",
|
||||||
|
"const": "#00FF00",
|
||||||
|
"description": "Terminal green for main text"
|
||||||
|
},
|
||||||
|
"accentColor": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9A-Fa-f]{6}$",
|
||||||
|
"const": "#FFBF00",
|
||||||
|
"description": "Amber for key information"
|
||||||
|
},
|
||||||
|
"fontFamily": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "monospace",
|
||||||
|
"description": "Monospace font stack"
|
||||||
|
},
|
||||||
|
"fontSize": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"base": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]+(px|rem|em)$",
|
||||||
|
"default": "16px"
|
||||||
|
},
|
||||||
|
"heading": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]+(px|rem|em)$",
|
||||||
|
"default": "20px"
|
||||||
|
},
|
||||||
|
"small": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]+(px|rem|em)$",
|
||||||
|
"default": "14px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"event": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Halloween event details",
|
||||||
|
"required": ["title", "date", "startTime", "endTime", "timezone", "location", "organizer", "activities"],
|
||||||
|
"properties": {
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "2025 MITA Halloween"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date",
|
||||||
|
"const": "2025-10-31",
|
||||||
|
"description": "Event date in ISO format"
|
||||||
|
},
|
||||||
|
"startTime": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([01]?[0-9]|2[0-3]):[0-5][0-9]$",
|
||||||
|
"const": "18:00",
|
||||||
|
"description": "Event start time in 24h format"
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([01]?[0-9]|2[0-3]):[0-5][0-9]$",
|
||||||
|
"const": "21:00",
|
||||||
|
"description": "Event end time in 24h format"
|
||||||
|
},
|
||||||
|
"timezone": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "GMT+8",
|
||||||
|
"description": "Event timezone"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "MITA Building 2F Pantry",
|
||||||
|
"description": "Physical event location"
|
||||||
|
},
|
||||||
|
"organizer": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "email"],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "Jessi Pan"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"const": "jessi.pan@cn.mcd.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"activities": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 3,
|
||||||
|
"maxItems": 5,
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3
|
||||||
|
},
|
||||||
|
"description": "List of event activities"
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 5
|
||||||
|
},
|
||||||
|
"description": "Additional event information"
|
||||||
|
},
|
||||||
|
"audience": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"department": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "MITA"
|
||||||
|
},
|
||||||
|
"count": {
|
||||||
|
"type": "integer",
|
||||||
|
"const": 300
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "McDonald's China IT team members"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"countdown": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Countdown timer configuration",
|
||||||
|
"required": ["targetDateTime", "timezone"],
|
||||||
|
"properties": {
|
||||||
|
"targetDateTime": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"const": "2025-10-31T10:00:00Z",
|
||||||
|
"description": "Target datetime in UTC (18:00 GMT+8)"
|
||||||
|
},
|
||||||
|
"eventEndDateTime": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"const": "2025-10-31T13:00:00Z",
|
||||||
|
"description": "Event end datetime in UTC (21:00 GMT+8)"
|
||||||
|
},
|
||||||
|
"timezone": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "GMT+8",
|
||||||
|
"description": "Display timezone"
|
||||||
|
},
|
||||||
|
"updateInterval": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1000,
|
||||||
|
"maximum": 1000,
|
||||||
|
"default": 1000,
|
||||||
|
"description": "Update interval in milliseconds"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"before": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Message to show before event"
|
||||||
|
},
|
||||||
|
"active": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "🎃 EVENT STARTING NOW! 🎃",
|
||||||
|
"description": "Message when event starts"
|
||||||
|
},
|
||||||
|
"ended": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "👻 EVENT COMPLETED - Thanks for joining! 👻",
|
||||||
|
"description": "Message after event ends"
|
||||||
|
},
|
||||||
|
"noJs": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "Enable JavaScript for live countdown",
|
||||||
|
"description": "Fallback message when JS disabled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ascii": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "ASCII art content",
|
||||||
|
"required": ["logo", "decorations"],
|
||||||
|
"properties": {
|
||||||
|
"logo": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["desktop", "mobile"],
|
||||||
|
"properties": {
|
||||||
|
"desktop": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 50,
|
||||||
|
"description": "McDonald's ASCII logo for desktop (with Golden Arches)"
|
||||||
|
},
|
||||||
|
"mobile": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 20,
|
||||||
|
"description": "McDonald's ASCII logo for mobile (simplified)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tagline": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"text": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "i'm lovin' IT"
|
||||||
|
},
|
||||||
|
"cursor": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["_", "|", "█"],
|
||||||
|
"default": "_"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decorations": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Halloween-themed ASCII art or emoji"
|
||||||
|
},
|
||||||
|
"description": "Halloween decorations (pumpkins, ghosts, bats)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Bilingual content pairs",
|
||||||
|
"properties": {
|
||||||
|
"pairs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["section", "english", "chinese"],
|
||||||
|
"properties": {
|
||||||
|
"section": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["date", "time", "location", "organizer", "activities", "notes"]
|
||||||
|
},
|
||||||
|
"english": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 5
|
||||||
|
},
|
||||||
|
"chinese": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"accessibility": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Accessibility configuration",
|
||||||
|
"properties": {
|
||||||
|
"wcagLevel": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["AA", "AAA"],
|
||||||
|
"const": "AA",
|
||||||
|
"description": "WCAG compliance level"
|
||||||
|
},
|
||||||
|
"contrastRatios": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"primaryOnBackground": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 21,
|
||||||
|
"description": "Green (#00FF00) on black (#000000)"
|
||||||
|
},
|
||||||
|
"accentOnBackground": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 12,
|
||||||
|
"description": "Amber (#FFBF00) on black (#000000)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ariaLabels": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "ARIA labels for screen readers"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"performance": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Performance requirements",
|
||||||
|
"properties": {
|
||||||
|
"maxFileSize": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 51200,
|
||||||
|
"description": "Maximum file size in bytes (50KB)"
|
||||||
|
},
|
||||||
|
"maxLoadTime": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 1000,
|
||||||
|
"description": "Maximum load time in milliseconds"
|
||||||
|
},
|
||||||
|
"targetFrameRate": {
|
||||||
|
"type": "integer",
|
||||||
|
"const": 60,
|
||||||
|
"description": "Target frame rate for animations"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
364
specs/001-mcdonald-s-it/data-model.md
Normal file
364
specs/001-mcdonald-s-it/data-model.md
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
# Data Model: McDonald's IT Halloween Event Page
|
||||||
|
|
||||||
|
**Feature**: Halloween event announcement webpage
|
||||||
|
**Date**: 2025-10-04
|
||||||
|
**Status**: Complete
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document defines the data entities and their relationships for the Halloween event page. While this is a static page with no backend storage, defining the data model helps structure the HTML content and JavaScript logic.
|
||||||
|
|
||||||
|
## Entities
|
||||||
|
|
||||||
|
### 1. Event
|
||||||
|
|
||||||
|
Represents the Halloween event information.
|
||||||
|
|
||||||
|
**Purpose**: Store and display all event details
|
||||||
|
|
||||||
|
**Fields**:
|
||||||
|
| Field | Type | Required | Default | Description |
|
||||||
|
|-------|------|----------|---------|-------------|
|
||||||
|
| `title` | String | Yes | - | Event title: "2025 MITA Halloween" |
|
||||||
|
| `date` | Date | Yes | - | Event date: October 31, 2025 |
|
||||||
|
| `startTime` | Time | Yes | - | Event start: 18:00 GMT+8 |
|
||||||
|
| `endTime` | Time | Yes | - | Event end: 21:00 GMT+8 |
|
||||||
|
| `timezone` | String | Yes | "GMT+8" | Timezone for event |
|
||||||
|
| `location` | String | Yes | - | "MITA Building 2F Pantry" |
|
||||||
|
| `organizer` | Object | Yes | - | Organizer details |
|
||||||
|
| `organizer.name` | String | Yes | - | "Jessi Pan" |
|
||||||
|
| `organizer.email` | String | Yes | - | "jessi.pan@cn.mcd.com" |
|
||||||
|
| `activities` | Array<String> | Yes | - | List of activities |
|
||||||
|
| `notes` | Array<String> | Yes | - | Additional information |
|
||||||
|
|
||||||
|
**Validation Rules**:
|
||||||
|
- `date` must be valid ISO date format
|
||||||
|
- `startTime` must be before `endTime`
|
||||||
|
- Times must be in 24-hour format (HH:MM)
|
||||||
|
- `organizer.email` must be valid email format
|
||||||
|
- `activities` must contain at least 1 item
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "2025 MITA Halloween",
|
||||||
|
"date": "2025-10-31",
|
||||||
|
"startTime": "18:00",
|
||||||
|
"endTime": "21:00",
|
||||||
|
"timezone": "GMT+8",
|
||||||
|
"location": "MITA Building 2F Pantry",
|
||||||
|
"organizer": {
|
||||||
|
"name": "Jessi Pan",
|
||||||
|
"email": "jessi.pan@cn.mcd.com"
|
||||||
|
},
|
||||||
|
"activities": [
|
||||||
|
"Cosplay (encouraged)",
|
||||||
|
"Bug Debugging Games",
|
||||||
|
"Lucky Draw"
|
||||||
|
],
|
||||||
|
"notes": [
|
||||||
|
"Costumes encouraged",
|
||||||
|
"Food and drinks provided"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**State Transitions**: None (static data)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Countdown
|
||||||
|
|
||||||
|
Represents the countdown timer state and logic.
|
||||||
|
|
||||||
|
**Purpose**: Calculate and display time remaining until event
|
||||||
|
|
||||||
|
**Fields**:
|
||||||
|
| Field | Type | Required | Default | Description |
|
||||||
|
|-------|------|----------|---------|-------------|
|
||||||
|
| `targetDateTime` | DateTime | Yes | - | Oct 31 2025 18:00:00 GMT+8 (in UTC: 10:00:00 UTC) |
|
||||||
|
| `currentDateTime` | DateTime | Yes | - | User's current time (updated every second) |
|
||||||
|
| `timeRemaining` | Object | No | null | Calculated time remaining |
|
||||||
|
| `timeRemaining.days` | Integer | No | 0 | Days remaining |
|
||||||
|
| `timeRemaining.hours` | Integer | No | 0 | Hours remaining (0-23) |
|
||||||
|
| `timeRemaining.minutes` | Integer | No | 0 | Minutes remaining (0-59) |
|
||||||
|
| `timeRemaining.seconds` | Integer | No | 0 | Seconds remaining (0-59) |
|
||||||
|
| `status` | Enum | Yes | "before" | Current event status |
|
||||||
|
|
||||||
|
**Status Values**:
|
||||||
|
- `before`: Current time is before event start (show countdown)
|
||||||
|
- `active`: Event has started, current time is between start and end (show "EVENT STARTING NOW!")
|
||||||
|
- `ended`: Event has ended, current time is after event end (show "EVENT COMPLETED")
|
||||||
|
|
||||||
|
**Validation Rules**:
|
||||||
|
- `targetDateTime` must be a valid Date object
|
||||||
|
- All time values must be >= 0
|
||||||
|
- `status` must be one of: "before", "active", "ended"
|
||||||
|
- `timeRemaining` is null when status is not "before"
|
||||||
|
|
||||||
|
**Calculation Logic**:
|
||||||
|
```javascript
|
||||||
|
// Convert GMT+8 to UTC for calculation
|
||||||
|
// Oct 31 2025 18:00 GMT+8 = Oct 31 2025 10:00 UTC
|
||||||
|
const targetDate = new Date('2025-10-31T10:00:00Z');
|
||||||
|
const eventEnd = new Date('2025-10-31T13:00:00Z'); // 21:00 GMT+8
|
||||||
|
|
||||||
|
function updateCountdown() {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
if (now >= eventEnd) {
|
||||||
|
return { status: 'ended', timeRemaining: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now >= targetDate) {
|
||||||
|
return { status: 'active', timeRemaining: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
const diff = targetDate - now;
|
||||||
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||||
|
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||||
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'before',
|
||||||
|
timeRemaining: { days, hours, minutes, seconds }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**State Transitions**:
|
||||||
|
```
|
||||||
|
before → active (when current time >= targetDateTime)
|
||||||
|
active → ended (when current time >= eventEnd)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. VisualTheme
|
||||||
|
|
||||||
|
Represents the visual design configuration.
|
||||||
|
|
||||||
|
**Purpose**: Define and apply consistent styling across the page
|
||||||
|
|
||||||
|
**Fields**:
|
||||||
|
| Field | Type | Required | Default | Description |
|
||||||
|
|-------|------|----------|---------|-------------|
|
||||||
|
| `backgroundColor` | Color | Yes | "#000000" | Pure black background |
|
||||||
|
| `primaryColor` | Color | Yes | "#00FF00" | Terminal green for main text |
|
||||||
|
| `accentColor` | Color | Yes | "#FFBF00" | Amber for key information |
|
||||||
|
| `fontFamily` | String | Yes | See below | Monospace font stack |
|
||||||
|
| `fontSize` | Object | Yes | - | Font sizes for different elements |
|
||||||
|
| `fontSize.base` | String | Yes | "16px" | Base font size |
|
||||||
|
| `fontSize.heading` | String | Yes | "20px" | Heading size |
|
||||||
|
| `fontSize.small` | String | Yes | "14px" | Small text size |
|
||||||
|
| `asciiArt` | Object | Yes | - | ASCII art content |
|
||||||
|
| `asciiArt.logoDesktop` | String | Yes | - | McDonald's logo for desktop |
|
||||||
|
| `asciiArt.logoMobile` | String | Yes | - | McDonald's logo for mobile |
|
||||||
|
| `asciiArt.decorations` | Array<String> | Yes | - | Halloween ASCII decorations |
|
||||||
|
|
||||||
|
**Font Stack**:
|
||||||
|
```css
|
||||||
|
"Courier New", Monaco, Consolas, "Liberation Mono", Menlo, monospace
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation Rules**:
|
||||||
|
- All color values must be valid hex format (#RRGGBB)
|
||||||
|
- `backgroundColor` must be #000000 (black)
|
||||||
|
- `primaryColor` and `accentColor` must meet WCAG AA contrast ratio with background
|
||||||
|
- `fontFamily` must include at least one monospace fallback
|
||||||
|
- ASCII art strings must contain only ASCII characters (0-127)
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"backgroundColor": "#000000",
|
||||||
|
"primaryColor": "#00FF00",
|
||||||
|
"accentColor": "#FFBF00",
|
||||||
|
"fontFamily": "\"Courier New\", Monaco, Consolas, Menlo, monospace",
|
||||||
|
"fontSize": {
|
||||||
|
"base": "16px",
|
||||||
|
"heading": "20px",
|
||||||
|
"small": "14px"
|
||||||
|
},
|
||||||
|
"asciiArt": {
|
||||||
|
"logoDesktop": "[Multi-line ASCII art]",
|
||||||
|
"logoMobile": "[Simplified ASCII art]",
|
||||||
|
"decorations": ["🎃", "👻", "🦇"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**State Transitions**: None (static configuration)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Content (Bilingual)
|
||||||
|
|
||||||
|
Represents bilingual text content structure.
|
||||||
|
|
||||||
|
**Purpose**: Store and display English/Chinese content pairs
|
||||||
|
|
||||||
|
**Fields**:
|
||||||
|
| Field | Type | Required | Default | Description |
|
||||||
|
|-------|------|----------|---------|-------------|
|
||||||
|
| `section` | String | Yes | - | Content section identifier |
|
||||||
|
| `english` | String | Yes | - | English text |
|
||||||
|
| `chinese` | String | Yes | - | Chinese text (Simplified) |
|
||||||
|
| `order` | Integer | Yes | - | Display order |
|
||||||
|
|
||||||
|
**Example Content Pairs**:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"section": "date",
|
||||||
|
"english": "Date: October 31, 2025",
|
||||||
|
"chinese": "日期:2025年10月31日",
|
||||||
|
"order": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"section": "time",
|
||||||
|
"english": "Time: 18:00 - 21:00 (6:00 PM - 9:00 PM)",
|
||||||
|
"chinese": "时间:18:00 - 21:00",
|
||||||
|
"order": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"section": "location",
|
||||||
|
"english": "Location: MITA Building 2F Pantry",
|
||||||
|
"chinese": "地点:MITA大厦2楼茶水间",
|
||||||
|
"order": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"section": "organizer",
|
||||||
|
"english": "Organizer: Jessi Pan (jessi.pan@cn.mcd.com)",
|
||||||
|
"chinese": "组织者:Jessi Pan (jessi.pan@cn.mcd.com)",
|
||||||
|
"order": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Display Pattern**:
|
||||||
|
```html
|
||||||
|
<p lang="en">{english}</p>
|
||||||
|
<p lang="zh-CN">{chinese}</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relationships
|
||||||
|
|
||||||
|
```
|
||||||
|
Event (1)
|
||||||
|
├── has timezone (1) → Countdown
|
||||||
|
└── has theme (1) → VisualTheme
|
||||||
|
|
||||||
|
Countdown (1)
|
||||||
|
└── uses targetDateTime from Event
|
||||||
|
|
||||||
|
VisualTheme (1)
|
||||||
|
└── styles all Content
|
||||||
|
|
||||||
|
Content (many)
|
||||||
|
└── derived from Event
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTML Representation
|
||||||
|
|
||||||
|
The data model maps to HTML structure as follows:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<main>
|
||||||
|
<!-- VisualTheme.asciiArt.logoDesktop -->
|
||||||
|
<header>
|
||||||
|
<pre class="ascii-desktop">[McDonald's ASCII Logo]</pre>
|
||||||
|
<pre class="ascii-mobile">[McDonald's ASCII Logo Simplified]</pre>
|
||||||
|
<p class="tagline">i'm lovin' IT<span class="cursor">_</span></p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Countdown -->
|
||||||
|
<section class="countdown">
|
||||||
|
<div id="countdown-display">
|
||||||
|
<span id="days">0</span>d
|
||||||
|
<span id="hours">0</span>h
|
||||||
|
<span id="minutes">0</span>m
|
||||||
|
<span id="seconds">0</span>s
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Event + Content (bilingual) -->
|
||||||
|
<section class="event-info">
|
||||||
|
<p lang="en">Date: {Event.date}</p>
|
||||||
|
<p lang="zh-CN">日期:{Event.date}</p>
|
||||||
|
<!-- ... more bilingual pairs -->
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Event.activities -->
|
||||||
|
<section class="activities">
|
||||||
|
<p lang="en">Activities:</p>
|
||||||
|
<p lang="zh-CN">活动:</p>
|
||||||
|
<ul>
|
||||||
|
<li lang="en">{activity}</li>
|
||||||
|
<li lang="zh-CN">{activity_zh}</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- VisualTheme.asciiArt.decorations -->
|
||||||
|
<section class="decorations">
|
||||||
|
<pre>{decoration}</pre>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
```
|
||||||
|
|
||||||
|
## JavaScript Data Structure
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const eventData = {
|
||||||
|
event: {
|
||||||
|
title: "2025 MITA Halloween",
|
||||||
|
date: "2025-10-31",
|
||||||
|
startTime: "18:00",
|
||||||
|
endTime: "21:00",
|
||||||
|
timezone: "GMT+8",
|
||||||
|
location: "MITA Building 2F Pantry",
|
||||||
|
organizer: {
|
||||||
|
name: "Jessi Pan",
|
||||||
|
email: "jessi.pan@cn.mcd.com"
|
||||||
|
},
|
||||||
|
activities: ["Cosplay", "Bug Debugging Games", "Lucky Draw"],
|
||||||
|
notes: ["Costumes encouraged", "Food and drinks provided"]
|
||||||
|
},
|
||||||
|
|
||||||
|
countdown: {
|
||||||
|
targetDateTime: new Date('2025-10-31T10:00:00Z'), // GMT+8 = UTC+8
|
||||||
|
eventEnd: new Date('2025-10-31T13:00:00Z'),
|
||||||
|
status: 'before',
|
||||||
|
timeRemaining: null
|
||||||
|
},
|
||||||
|
|
||||||
|
theme: {
|
||||||
|
backgroundColor: "#000000",
|
||||||
|
primaryColor: "#00FF00",
|
||||||
|
accentColor: "#FFBF00",
|
||||||
|
fontFamily: '"Courier New", Monaco, Consolas, Menlo, monospace'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Contract
|
||||||
|
|
||||||
|
All data must conform to the schema defined in `/contracts/page-content.schema.json`.
|
||||||
|
|
||||||
|
See: [page-content.schema.json](./contracts/page-content.schema.json)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- This is a static page, so data is hardcoded in HTML/JS
|
||||||
|
- No database or API calls required
|
||||||
|
- Data updates only via code changes
|
||||||
|
- Countdown is the only dynamic data (calculated client-side)
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- Create contracts/page-content.schema.json (JSON Schema validation)
|
||||||
|
- Create quickstart.md (testing checklist)
|
||||||
|
- Update CLAUDE.md (agent context)
|
||||||
528
specs/001-mcdonald-s-it/plan.md
Normal file
528
specs/001-mcdonald-s-it/plan.md
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
# Implementation Plan: McDonald's IT Halloween Event Page
|
||||||
|
|
||||||
|
**Branch**: `001-mcdonald-s-it` | **Date**: 2025-10-04 | **Spec**: [spec.md](./spec.md)
|
||||||
|
**Input**: Feature specification from `/specs/001-mcdonald-s-it/spec.md`
|
||||||
|
|
||||||
|
## Execution Flow (/plan command scope)
|
||||||
|
```
|
||||||
|
1. Load feature spec from Input path ✅
|
||||||
|
→ Feature spec loaded successfully
|
||||||
|
2. Fill Technical Context ✅
|
||||||
|
→ Project Type: Single-file web page (static HTML)
|
||||||
|
→ Structure Decision: Single HTML file with inline CSS/JS
|
||||||
|
3. Fill Constitution Check section ✅
|
||||||
|
→ Based on .claude/constitution.md
|
||||||
|
4. Evaluate Constitution Check section ✅
|
||||||
|
→ No violations - simple, focused implementation
|
||||||
|
→ Update Progress Tracking: Initial Constitution Check ✅
|
||||||
|
5. Execute Phase 0 → research.md ✅
|
||||||
|
→ No NEEDS CLARIFICATION in tech context
|
||||||
|
6. Execute Phase 1 → data-model.md, contracts/, quickstart.md, CLAUDE.md ✅
|
||||||
|
7. Re-evaluate Constitution Check section ✅
|
||||||
|
→ No new violations after design
|
||||||
|
→ Update Progress Tracking: Post-Design Constitution Check ✅
|
||||||
|
8. Plan Phase 2 → Describe task generation approach ✅
|
||||||
|
9. STOP - Ready for /tasks command ✅
|
||||||
|
```
|
||||||
|
|
||||||
|
**IMPORTANT**: The /plan command STOPS at step 9. Phases 2-4 are executed by other commands:
|
||||||
|
- Phase 2: /tasks command creates tasks.md
|
||||||
|
- Phase 3-4: Implementation execution (manual or via tools)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Create a minimalist, geek-style Halloween event announcement webpage for McDonald's China IT team (MITA). The page features ASCII art, a countdown timer to the Oct 31 2025 event, and bilingual (English/Chinese) content. Design emphasizes terminal aesthetics with black background, monospace fonts, and no decorative effects. Must be responsive, self-contained (single HTML file), and load under 1 second.
|
||||||
|
|
||||||
|
**Technical Approach**: Single self-contained HTML5 file with inline CSS for styling and minimal JavaScript for countdown timer. Pure static page requiring no server-side processing or external dependencies. Responsive design using CSS media queries for cross-device compatibility.
|
||||||
|
|
||||||
|
## Technical Context
|
||||||
|
|
||||||
|
**Language/Version**: HTML5, CSS3, JavaScript ES6+
|
||||||
|
**Primary Dependencies**: None (self-contained single file)
|
||||||
|
**Storage**: N/A (static page, no data persistence)
|
||||||
|
**Testing**: Manual browser testing (Chrome, Firefox, Safari, Edge), HTML5 validation, WCAG 2.1 AA compliance check
|
||||||
|
**Target Platform**: Modern web browsers (latest 2 versions), responsive design for desktop (1024px+), tablet (768-1023px), mobile (320-767px)
|
||||||
|
**Project Type**: Single-file static webpage
|
||||||
|
**Performance Goals**: Load time < 1 second, file size < 50KB, 60fps animations
|
||||||
|
**Constraints**:
|
||||||
|
- Single self-contained HTML file only
|
||||||
|
- No external dependencies (CSS/JS/images/fonts)
|
||||||
|
- No frameworks or libraries
|
||||||
|
- WCAG 2.1 AA compliance required
|
||||||
|
- Countdown must use GMT+8 timezone
|
||||||
|
- ASCII art must be legible on all screen sizes
|
||||||
|
**Scale/Scope**: Single page, ~300 target users, static content only
|
||||||
|
|
||||||
|
**User Provided Context**: $ARGUMENTS
|
||||||
|
|
||||||
|
## Constitution Check
|
||||||
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||||
|
|
||||||
|
Based on `.claude/constitution.md`:
|
||||||
|
|
||||||
|
### User-Centric Service ✅
|
||||||
|
- Requirements clearly defined in spec.md
|
||||||
|
- User stories and acceptance criteria documented
|
||||||
|
- Focus on MITA IT team needs (programmer aesthetic, bilingual content)
|
||||||
|
|
||||||
|
### Professional Excellence ✅
|
||||||
|
- Following web standards (HTML5, CSS3, WCAG 2.1 AA)
|
||||||
|
- Single-file architecture aligns with deployment simplicity requirement
|
||||||
|
- No over-engineering - minimal technical stack appropriate for static page
|
||||||
|
|
||||||
|
### Clear Communication ✅
|
||||||
|
- Spec provides comprehensive requirements (35 functional requirements)
|
||||||
|
- Technical decisions documented with rationale
|
||||||
|
- Edge cases identified and defaults specified
|
||||||
|
|
||||||
|
### Collaborative Mindset ✅
|
||||||
|
- Respects existing CLAUDE.md workflow
|
||||||
|
- Builds on established project structure (specs/ directory)
|
||||||
|
- Follows Spec-Kit documentation standards
|
||||||
|
|
||||||
|
### Continuous Improvement ✅
|
||||||
|
- Identified 2 edge cases for future consideration
|
||||||
|
- Design allows for easy updates (single file)
|
||||||
|
- Performance metrics defined for validation
|
||||||
|
|
||||||
|
### Spec-Kit Compliance ✅
|
||||||
|
- Following Spec-Kit framework
|
||||||
|
- Specification in `specs/001-mcdonald-s-it/spec.md`
|
||||||
|
- Product requirements clearly documented
|
||||||
|
- Implementation plan follows structured format
|
||||||
|
|
||||||
|
**Constitution Status**: ✅ PASS - No violations detected
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
### Documentation (this feature)
|
||||||
|
```
|
||||||
|
specs/001-mcdonald-s-it/
|
||||||
|
├── spec.md # Feature specification
|
||||||
|
├── plan.md # This file (/plan command output)
|
||||||
|
├── research.md # Phase 0 output (/plan command)
|
||||||
|
├── data-model.md # Phase 1 output (/plan command)
|
||||||
|
├── quickstart.md # Phase 1 output (/plan command)
|
||||||
|
├── contracts/ # Phase 1 output (/plan command)
|
||||||
|
│ └── page-content.schema.json
|
||||||
|
└── tasks.md # Phase 2 output (/tasks command - NOT created by /plan)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Source Code (repository root)
|
||||||
|
```
|
||||||
|
test-project/
|
||||||
|
├── index.html # Main Halloween event page (self-contained)
|
||||||
|
├── README.md # Project documentation
|
||||||
|
├── CLAUDE.md # Agent workflow and project guidance
|
||||||
|
└── specs/ # Specification documents
|
||||||
|
└── 001-mcdonald-s-it/ # This feature
|
||||||
|
```
|
||||||
|
|
||||||
|
**Structure Decision**: Single-file static webpage architecture selected because:
|
||||||
|
1. No backend/API required (static content only)
|
||||||
|
2. No data persistence needed
|
||||||
|
3. Simplifies deployment (single file to host)
|
||||||
|
4. Meets performance requirement (< 1 second load, < 50KB)
|
||||||
|
5. Aligns with minimalist design philosophy
|
||||||
|
6. Easy to maintain and update
|
||||||
|
|
||||||
|
## Phase 0: Outline & Research
|
||||||
|
|
||||||
|
### Research Tasks Completed
|
||||||
|
|
||||||
|
**1. HTML5 Semantic Markup Best Practices**
|
||||||
|
- **Decision**: Use semantic HTML5 elements (`<header>`, `<main>`, `<section>`, `<footer>`)
|
||||||
|
- **Rationale**: Improves accessibility, SEO, and screen reader support; required for WCAG 2.1 AA
|
||||||
|
- **Alternatives considered**: Generic `<div>` elements (rejected: poor accessibility)
|
||||||
|
|
||||||
|
**2. ASCII Art Rendering in HTML**
|
||||||
|
- **Decision**: Use `<pre>` tag with monospace font and proper character encoding
|
||||||
|
- **Rationale**: Preserves whitespace and formatting; prevents line wrapping issues
|
||||||
|
- **Alternatives considered**: Canvas element (rejected: overkill for static art), CSS grid (rejected: complex positioning)
|
||||||
|
|
||||||
|
**3. Responsive ASCII Art Techniques**
|
||||||
|
- **Decision**: Provide two versions - desktop (detailed) and mobile (simplified)
|
||||||
|
- **Rationale**: Complex ASCII art breaks on small screens; media queries switch versions
|
||||||
|
- **Alternatives considered**: Viewport scaling (rejected: illegible text), SVG (rejected: not ASCII)
|
||||||
|
|
||||||
|
**4. Countdown Timer with Timezone Handling**
|
||||||
|
- **Decision**: Use JavaScript `Date` object with explicit GMT+8 offset calculation
|
||||||
|
- **Rationale**: Handles user timezone automatically; displays correct countdown regardless of visitor location
|
||||||
|
- **Alternatives considered**: Server-side time (rejected: static page), timezone library (rejected: external dependency)
|
||||||
|
|
||||||
|
**5. Inline CSS/JS Organization**
|
||||||
|
- **Decision**: Place CSS in `<style>` tag in `<head>`, JS in `<script>` tag before `</body>`
|
||||||
|
- **Rationale**: Standard best practice; CSS loads before render, JS after DOM ready
|
||||||
|
- **Alternatives considered**: All in `<head>` (rejected: blocks rendering)
|
||||||
|
|
||||||
|
**6. WCAG 2.1 AA Compliance for Dark Themes**
|
||||||
|
- **Decision**: Black background (#000000) with bright green (#00FF00) and amber (#FFBF00) text
|
||||||
|
- **Rationale**: High contrast ratio (21:1 for green, 12:1 for amber) exceeds WCAG AAA standard
|
||||||
|
- **Alternatives considered**: Dark gray background (rejected: less terminal aesthetic)
|
||||||
|
|
||||||
|
**7. Bilingual Content Display**
|
||||||
|
- **Decision**: Alternate English and Chinese lines with proper `lang` attributes
|
||||||
|
- **Rationale**: Clear visual pattern; proper language tagging for screen readers
|
||||||
|
- **Alternatives considered**: Side-by-side columns (rejected: breaks on mobile), toggle button (rejected: requires JS state)
|
||||||
|
|
||||||
|
**8. Blinking Cursor Animation**
|
||||||
|
- **Decision**: CSS `@keyframes` animation with `opacity` toggle
|
||||||
|
- **Rationale**: Pure CSS solution; no JS required; accessible (respects `prefers-reduced-motion`)
|
||||||
|
- **Alternatives considered**: JavaScript interval (rejected: unnecessary complexity)
|
||||||
|
|
||||||
|
**9. Performance Optimization for Single-File HTML**
|
||||||
|
- **Decision**: Minify repeated whitespace in ASCII art; use CSS shorthand; optimize countdown logic
|
||||||
|
- **Rationale**: Keeps file under 50KB; maintains readability in source
|
||||||
|
- **Alternatives considered**: Gzip compression (rejected: hosting-dependent)
|
||||||
|
|
||||||
|
**10. Favicon Implementation Without External File**
|
||||||
|
- **Decision**: Use data URI for emoji favicon (🎃)
|
||||||
|
- **Rationale**: Keeps single-file constraint; browser support for emoji favicons is good
|
||||||
|
- **Alternatives considered**: SVG data URI (rejected: more complex for simple icon)
|
||||||
|
|
||||||
|
### Edge Case Resolutions
|
||||||
|
|
||||||
|
**Post-Countdown Behavior**: When countdown reaches zero, display "🎃 EVENT STARTING NOW! 🎃" message
|
||||||
|
**Post-Event Behavior**: After Oct 31 2025 21:00 GMT+8, display "👻 EVENT COMPLETED - Thanks for joining! 👻"
|
||||||
|
**JavaScript Disabled**: All content remains visible; countdown shows static message "Enable JavaScript for live countdown"
|
||||||
|
**Very Small Screens (<320px)**: Use ultra-minimal ASCII art (just "McD" text); maintain readability over aesthetics
|
||||||
|
|
||||||
|
**Output**: research.md (documenting all decisions above)
|
||||||
|
|
||||||
|
## Phase 1: Design & Contracts
|
||||||
|
|
||||||
|
### 1. Data Model (data-model.md)
|
||||||
|
|
||||||
|
**Entity: Event**
|
||||||
|
- **Fields**:
|
||||||
|
- `title`: String - "2025 MITA Halloween"
|
||||||
|
- `date`: Date - October 31, 2025
|
||||||
|
- `startTime`: Time - 18:00 GMT+8
|
||||||
|
- `endTime`: Time - 21:00 GMT+8
|
||||||
|
- `location`: String - "MITA Building 2F Pantry"
|
||||||
|
- `organizer`: Object - { name: "Jessi Pan", email: "jessi.pan@cn.mcd.com" }
|
||||||
|
- `activities`: Array<String> - ["Cosplay", "Bug Debugging Games", "Lucky Draw"]
|
||||||
|
- `notes`: Array<String> - ["Costumes encouraged", "Food and drinks provided"]
|
||||||
|
- **Validation**: All fields required; date must be future or present; times in 24hr format
|
||||||
|
- **State Transitions**: N/A (static data)
|
||||||
|
|
||||||
|
**Entity: Countdown**
|
||||||
|
- **Fields**:
|
||||||
|
- `targetDateTime`: DateTime - Oct 31 2025 18:00:00 GMT+8
|
||||||
|
- `currentDateTime`: DateTime - User's current time
|
||||||
|
- `timeRemaining`: Object - { days, hours, minutes, seconds }
|
||||||
|
- `status`: Enum - ["before", "active", "ended"]
|
||||||
|
- **Validation**: targetDateTime in future; all time values >= 0
|
||||||
|
- **State Transitions**:
|
||||||
|
- before → active (when countdown reaches 0)
|
||||||
|
- active → ended (when current time > endTime)
|
||||||
|
|
||||||
|
**Entity: VisualTheme**
|
||||||
|
- **Fields**:
|
||||||
|
- `backgroundColor`: Color - "#000000"
|
||||||
|
- `primaryColor`: Color - "#00FF00"
|
||||||
|
- `accentColor`: Color - "#FFBF00"
|
||||||
|
- `fontFamily`: String - "Courier New, Monaco, Consolas, Menlo, monospace"
|
||||||
|
- `asciiArt`: Object - { desktop: String, mobile: String, halloween: String }
|
||||||
|
- **Validation**: Valid hex colors; font stack includes fallbacks
|
||||||
|
- **State Transitions**: N/A (static configuration)
|
||||||
|
|
||||||
|
### 2. API Contracts (contracts/)
|
||||||
|
|
||||||
|
**Contract: Page Content Schema**
|
||||||
|
|
||||||
|
File: `contracts/page-content.schema.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "Halloween Event Page Content",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["meta", "theme", "event", "countdown"],
|
||||||
|
"properties": {
|
||||||
|
"meta": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["title", "description", "favicon"],
|
||||||
|
"properties": {
|
||||||
|
"title": { "type": "string", "const": "2025 MITA Halloween" },
|
||||||
|
"description": { "type": "string" },
|
||||||
|
"favicon": { "type": "string", "pattern": "^data:image" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["backgroundColor", "primaryColor", "accentColor", "fontFamily"],
|
||||||
|
"properties": {
|
||||||
|
"backgroundColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
|
||||||
|
"primaryColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
|
||||||
|
"accentColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
|
||||||
|
"fontFamily": { "type": "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"event": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["date", "startTime", "endTime", "location", "organizer", "activities"],
|
||||||
|
"properties": {
|
||||||
|
"date": { "type": "string", "format": "date" },
|
||||||
|
"startTime": { "type": "string", "pattern": "^([01]?[0-9]|2[0-3]):[0-5][0-9]$" },
|
||||||
|
"endTime": { "type": "string", "pattern": "^([01]?[0-9]|2[0-3]):[0-5][0-9]$" },
|
||||||
|
"timezone": { "type": "string", "const": "GMT+8" },
|
||||||
|
"location": { "type": "string" },
|
||||||
|
"organizer": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "email"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"email": { "type": "string", "format": "email" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"activities": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"countdown": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["targetDateTime", "timezone"],
|
||||||
|
"properties": {
|
||||||
|
"targetDateTime": { "type": "string", "format": "date-time" },
|
||||||
|
"timezone": { "type": "string", "const": "GMT+8" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ascii": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["logo", "decorations"],
|
||||||
|
"properties": {
|
||||||
|
"logo": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["desktop", "mobile"],
|
||||||
|
"properties": {
|
||||||
|
"desktop": { "type": "string" },
|
||||||
|
"mobile": { "type": "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decorations": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Test Scenarios (from user stories)
|
||||||
|
|
||||||
|
**User Story 1: Desktop View**
|
||||||
|
```gherkin
|
||||||
|
Given a team member visits the event page on desktop (1024px+ width)
|
||||||
|
When the page loads
|
||||||
|
Then they see:
|
||||||
|
- McDonald's ASCII art logo with Golden Arches
|
||||||
|
- "i'm lovin' IT" tagline with blinking cursor
|
||||||
|
- Live countdown timer in GMT+8
|
||||||
|
- Event details in English/Chinese alternating lines
|
||||||
|
- Halloween ASCII decorations (pumpkins, ghosts, bats)
|
||||||
|
- All text in terminal green (#00FF00) on black background
|
||||||
|
```
|
||||||
|
|
||||||
|
**User Story 2: Mobile View**
|
||||||
|
```gherkin
|
||||||
|
Given a team member visits the event page on mobile (320-767px width)
|
||||||
|
When the page loads
|
||||||
|
Then they see:
|
||||||
|
- Mobile-optimized ASCII art (simplified, legible)
|
||||||
|
- "i'm lovin' IT" tagline with blinking cursor
|
||||||
|
- Live countdown timer
|
||||||
|
- Event details in bilingual format
|
||||||
|
- All content readable without horizontal scroll
|
||||||
|
- High contrast maintained (21:1 ratio)
|
||||||
|
```
|
||||||
|
|
||||||
|
**User Story 3: Countdown Accuracy**
|
||||||
|
```gherkin
|
||||||
|
Given the current time is before Oct 31 2025 18:00 GMT+8
|
||||||
|
When a user views the countdown timer
|
||||||
|
Then it displays accurate time remaining in days, hours, minutes, seconds
|
||||||
|
And updates every second
|
||||||
|
And correctly handles timezone conversion for users in different timezones
|
||||||
|
|
||||||
|
Given the current time reaches Oct 31 2025 18:00 GMT+8
|
||||||
|
When the countdown reaches zero
|
||||||
|
Then it displays "🎃 EVENT STARTING NOW! 🎃"
|
||||||
|
|
||||||
|
Given the current time is after Oct 31 2025 21:00 GMT+8
|
||||||
|
When a user visits the page
|
||||||
|
Then it displays "👻 EVENT COMPLETED - Thanks for joining! 👻"
|
||||||
|
```
|
||||||
|
|
||||||
|
**User Story 4: Accessibility**
|
||||||
|
```gherkin
|
||||||
|
Given a team member uses a screen reader
|
||||||
|
When they navigate the page
|
||||||
|
Then all content is announced correctly
|
||||||
|
And language switches are marked with lang attributes
|
||||||
|
And ARIA labels provide context for visual elements
|
||||||
|
|
||||||
|
Given a user has JavaScript disabled
|
||||||
|
When they visit the page
|
||||||
|
Then all static content remains visible
|
||||||
|
And countdown shows fallback message "Enable JavaScript for live countdown"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Quickstart Test (quickstart.md)
|
||||||
|
|
||||||
|
**Quickstart Test**: Open `index.html` in browser
|
||||||
|
1. Visual check: Black background, green/amber text, monospace font ✅
|
||||||
|
2. ASCII art visible and legible ✅
|
||||||
|
3. Countdown timer running and updating every second ✅
|
||||||
|
4. Resize to mobile width: layout adapts, ASCII art switches to mobile version ✅
|
||||||
|
5. Check console: No errors ✅
|
||||||
|
6. HTML5 validation: Pass ✅
|
||||||
|
7. WCAG check: AA compliance ✅
|
||||||
|
8. File size: < 50KB ✅
|
||||||
|
9. Load time: < 1 second ✅
|
||||||
|
|
||||||
|
### 5. Agent Context Update
|
||||||
|
|
||||||
|
Running agent context update for CLAUDE.md:
|
||||||
|
|
||||||
|
**Output**: Updated `/Users/snowprint/workspace/claude/test-project/CLAUDE.md` with:
|
||||||
|
- New tech: HTML5, CSS3, JavaScript ES6, ASCII art rendering
|
||||||
|
- Current phase: Phase 2 (Design & Implementation) in progress
|
||||||
|
- Recent changes: Completed specification and implementation plan
|
||||||
|
- Key context: Single-file architecture, countdown timer, responsive design
|
||||||
|
|
||||||
|
## Phase 2: Task Planning Approach
|
||||||
|
*This section describes what the /tasks command will do - DO NOT execute during /plan*
|
||||||
|
|
||||||
|
**Task Generation Strategy**:
|
||||||
|
1. Load `.specify/templates/tasks-template.md` as base template
|
||||||
|
2. Generate tasks from Phase 1 design documents:
|
||||||
|
- **From contracts/page-content.schema.json**: Validation tasks
|
||||||
|
- **From data-model.md**: Content preparation tasks
|
||||||
|
- **From quickstart.md**: Testing tasks
|
||||||
|
- **From user stories**: Implementation tasks
|
||||||
|
|
||||||
|
**Task Categories**:
|
||||||
|
- **Setup & Structure** [P]: HTML5 skeleton, meta tags, semantic structure
|
||||||
|
- **Content Creation** [P]: ASCII art design (desktop, mobile, decorations), bilingual text
|
||||||
|
- **Styling** [P]: CSS implementation (colors, fonts, responsive breakpoints)
|
||||||
|
- **Countdown Logic**: JavaScript timer with GMT+8 timezone handling
|
||||||
|
- **Responsive Design**: Media queries, mobile optimization, ASCII art switching
|
||||||
|
- **Accessibility**: ARIA labels, lang attributes, contrast validation
|
||||||
|
- **Testing**: Browser testing, validation, performance check
|
||||||
|
- **Documentation**: Update README with deployment instructions
|
||||||
|
|
||||||
|
**Ordering Strategy**:
|
||||||
|
1. **Phase 1: Structure** (parallel tasks)
|
||||||
|
- Create HTML5 skeleton with semantic tags [P]
|
||||||
|
- Add meta tags and favicon [P]
|
||||||
|
- Set up CSS structure in `<style>` [P]
|
||||||
|
|
||||||
|
2. **Phase 2: Content** (parallel tasks)
|
||||||
|
- Design McDonald's ASCII art (desktop version) [P]
|
||||||
|
- Design McDonald's ASCII art (mobile version) [P]
|
||||||
|
- Design Halloween decorations ASCII art [P]
|
||||||
|
- Write bilingual event content [P]
|
||||||
|
|
||||||
|
3. **Phase 3: Styling** (parallel tasks)
|
||||||
|
- Implement color scheme and typography [P]
|
||||||
|
- Add responsive media queries [P]
|
||||||
|
- Create blinking cursor animation [P]
|
||||||
|
|
||||||
|
4. **Phase 4: Functionality** (sequential)
|
||||||
|
- Implement countdown timer JavaScript
|
||||||
|
- Add timezone handling for GMT+8
|
||||||
|
- Add countdown state management (before/active/ended)
|
||||||
|
- Test countdown edge cases
|
||||||
|
|
||||||
|
5. **Phase 5: Accessibility** (parallel tasks)
|
||||||
|
- Add ARIA labels for screen readers [P]
|
||||||
|
- Add lang attributes for bilingual content [P]
|
||||||
|
- Verify WCAG 2.1 AA compliance [P]
|
||||||
|
|
||||||
|
6. **Phase 6: Testing & Validation**
|
||||||
|
- Manual browser testing (Chrome, Firefox, Safari, Edge)
|
||||||
|
- HTML5 validation
|
||||||
|
- Responsive design testing (desktop/tablet/mobile)
|
||||||
|
- Performance testing (load time, file size)
|
||||||
|
- Accessibility testing
|
||||||
|
- Cross-timezone countdown testing
|
||||||
|
|
||||||
|
7. **Phase 7: Documentation**
|
||||||
|
- Update README with deployment instructions
|
||||||
|
- Document edge case behavior
|
||||||
|
- Add maintenance notes
|
||||||
|
|
||||||
|
**Estimated Output**: ~30 numbered, dependency-ordered tasks in tasks.md
|
||||||
|
|
||||||
|
**Parallel Execution**:
|
||||||
|
- Tasks marked [P] can be executed in parallel (no dependencies)
|
||||||
|
- Content creation tasks are independent (ASCII art, text)
|
||||||
|
- Styling tasks can proceed independently
|
||||||
|
- Testing tasks can run concurrently
|
||||||
|
|
||||||
|
**IMPORTANT**: This phase is executed by the /tasks command, NOT by /plan
|
||||||
|
|
||||||
|
## Phase 3+: Future Implementation
|
||||||
|
*These phases are beyond the scope of the /plan command*
|
||||||
|
|
||||||
|
**Phase 3**: Task execution (/tasks command creates tasks.md)
|
||||||
|
**Phase 4**: Implementation (execute tasks.md following constitutional principles)
|
||||||
|
**Phase 5**: Validation (run quickstart.md tests, HTML5/WCAG validation, performance check)
|
||||||
|
|
||||||
|
**Expected Deliverables**:
|
||||||
|
- `index.html` - Complete self-contained Halloween event page
|
||||||
|
- Updated `README.md` - Deployment and usage instructions
|
||||||
|
- Updated `CHANGELOG.md` - Version 1.0.0 release notes
|
||||||
|
- Test evidence - Screenshots, validation reports, performance metrics
|
||||||
|
|
||||||
|
## Complexity Tracking
|
||||||
|
*Fill ONLY if Constitution Check has violations that must be justified*
|
||||||
|
|
||||||
|
No violations detected. The implementation follows constitutional principles:
|
||||||
|
- ✅ Single-file architecture = simplicity
|
||||||
|
- ✅ No external dependencies = user-centric (easy deployment)
|
||||||
|
- ✅ Clear documentation = professional excellence
|
||||||
|
- ✅ Spec-Kit compliance = collaborative mindset
|
||||||
|
- ✅ Performance metrics defined = continuous improvement
|
||||||
|
|
||||||
|
**Complexity Deviations**: None
|
||||||
|
|
||||||
|
## Progress Tracking
|
||||||
|
*This checklist is updated during execution flow*
|
||||||
|
|
||||||
|
**Phase Status**:
|
||||||
|
- [x] Phase 0: Research complete (/plan command)
|
||||||
|
- [x] Phase 1: Design complete (/plan command)
|
||||||
|
- [x] Phase 2: Task planning complete (/plan command - describe approach only)
|
||||||
|
- [ ] Phase 3: Tasks generated (/tasks command)
|
||||||
|
- [ ] Phase 4: Implementation complete
|
||||||
|
- [ ] Phase 5: Validation passed
|
||||||
|
|
||||||
|
**Gate Status**:
|
||||||
|
- [x] Initial Constitution Check: PASS
|
||||||
|
- [x] Post-Design Constitution Check: PASS
|
||||||
|
- [x] All NEEDS CLARIFICATION resolved
|
||||||
|
- [x] Complexity deviations documented (none)
|
||||||
|
|
||||||
|
**Artifacts Created**:
|
||||||
|
- [x] spec.md - Feature specification with 35 functional requirements
|
||||||
|
- [x] plan.md - This implementation plan
|
||||||
|
- [x] research.md - Research decisions and rationale
|
||||||
|
- [x] data-model.md - Entity definitions and validation rules
|
||||||
|
- [x] contracts/page-content.schema.json - Content schema
|
||||||
|
- [x] quickstart.md - Testing checklist
|
||||||
|
|
||||||
|
**Next Action**: Run `/tasks` command to generate tasks.md
|
||||||
|
|
||||||
|
---
|
||||||
|
*Based on Constitution - See `/.claude/constitution.md`*
|
||||||
|
*Created: 2025-10-04 | Last Updated: 2025-10-04*
|
||||||
442
specs/001-mcdonald-s-it/quickstart.md
Normal file
442
specs/001-mcdonald-s-it/quickstart.md
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
# Quickstart: McDonald's IT Halloween Event Page
|
||||||
|
|
||||||
|
**Feature**: Halloween event announcement webpage
|
||||||
|
**Date**: 2025-10-04
|
||||||
|
**Purpose**: Step-by-step testing and validation checklist
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Modern web browser (Chrome, Firefox, Safari, or Edge - latest 2 versions)
|
||||||
|
- Text editor (for viewing source if needed)
|
||||||
|
- Internet connection (for online validators)
|
||||||
|
- Device with different screen sizes OR browser dev tools for responsive testing
|
||||||
|
|
||||||
|
## Quick Test (2 minutes)
|
||||||
|
|
||||||
|
1. **Open the page**
|
||||||
|
```bash
|
||||||
|
# Navigate to project directory
|
||||||
|
cd /Users/snowprint/workspace/claude/test-project
|
||||||
|
|
||||||
|
# Open index.html in default browser
|
||||||
|
open index.html
|
||||||
|
# OR for other systems:
|
||||||
|
# xdg-open index.html (Linux)
|
||||||
|
# start index.html (Windows)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Visual check** ✅
|
||||||
|
- [ ] Black background (#000000)
|
||||||
|
- [ ] Green text (#00FF00) for primary content
|
||||||
|
- [ ] Amber text (#FFBF00) for key information
|
||||||
|
- [ ] Monospace font (looks like terminal/code)
|
||||||
|
- [ ] No shadows, gradients, or decorative effects
|
||||||
|
|
||||||
|
3. **Content check** ✅
|
||||||
|
- [ ] McDonald's ASCII art logo visible at top
|
||||||
|
- [ ] "i'm lovin' IT" tagline below logo with blinking cursor
|
||||||
|
- [ ] Countdown timer showing days, hours, minutes, seconds
|
||||||
|
- [ ] Event details: Oct 31 2025, 18:00-21:00 GMT+8
|
||||||
|
- [ ] Location: MITA Building 2F Pantry
|
||||||
|
- [ ] Organizer: Jessi Pan (jessi.pan@cn.mcd.com)
|
||||||
|
- [ ] Activities listed (Cosplay, Debugging Games, Lucky Draw)
|
||||||
|
- [ ] Halloween decorations (🎃👻🦇 or ASCII art)
|
||||||
|
- [ ] Footer: "McDonald's IT Academy"
|
||||||
|
|
||||||
|
4. **Functionality check** ✅
|
||||||
|
- [ ] Countdown timer updates every second
|
||||||
|
- [ ] No JavaScript errors in browser console (F12 → Console tab)
|
||||||
|
- [ ] Browser tab title shows "2025 MITA Halloween"
|
||||||
|
- [ ] Favicon shows pumpkin emoji 🎃
|
||||||
|
|
||||||
|
5. **Responsive check** ✅
|
||||||
|
- [ ] Resize browser to mobile width (< 768px)
|
||||||
|
- [ ] ASCII art switches to mobile version OR remains legible
|
||||||
|
- [ ] No horizontal scrollbar appears
|
||||||
|
- [ ] All content readable without zooming
|
||||||
|
|
||||||
|
## Full Test Suite (15 minutes)
|
||||||
|
|
||||||
|
### 1. Visual Design Validation
|
||||||
|
|
||||||
|
**Test**: Verify terminal aesthetic
|
||||||
|
- [ ] Background is pure black (#000000)
|
||||||
|
- [ ] Primary text is terminal green (#00FF00)
|
||||||
|
- [ ] Accent text is amber (#FFBF00)
|
||||||
|
- [ ] Font is monospace (Courier New, Monaco, Consolas, or Menlo)
|
||||||
|
- [ ] No shadows on any elements
|
||||||
|
- [ ] No gradients anywhere
|
||||||
|
- [ ] No borders or decorative effects
|
||||||
|
- [ ] Overall look is minimalist and geek-style
|
||||||
|
|
||||||
|
**Expected**: Page looks like a terminal/command-line interface
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Content Verification
|
||||||
|
|
||||||
|
**Test**: Verify all required content is present and correct
|
||||||
|
|
||||||
|
**Event Information**:
|
||||||
|
- [ ] Title: "2025 MITA Halloween" (in browser tab)
|
||||||
|
- [ ] Date: October 31, 2025
|
||||||
|
- [ ] Time: 18:00 - 21:00 (6:00 PM - 9:00 PM)
|
||||||
|
- [ ] Timezone: GMT+8 clearly stated
|
||||||
|
- [ ] Location: MITA Building 2F Pantry
|
||||||
|
- [ ] Organizer: Jessi Pan
|
||||||
|
- [ ] Contact: jessi.pan@cn.mcd.com
|
||||||
|
|
||||||
|
**Activities**:
|
||||||
|
- [ ] Cosplay (encouraged)
|
||||||
|
- [ ] Bug debugging games
|
||||||
|
- [ ] Lucky draw
|
||||||
|
|
||||||
|
**Notes**:
|
||||||
|
- [ ] Costumes encouraged
|
||||||
|
- [ ] Food and drinks provided
|
||||||
|
|
||||||
|
**ASCII Art**:
|
||||||
|
- [ ] McDonald's logo with Golden Arches M
|
||||||
|
- [ ] Halloween decorations (pumpkins, ghosts, bats)
|
||||||
|
|
||||||
|
**Tagline**:
|
||||||
|
- [ ] "i'm lovin' IT" displayed
|
||||||
|
- [ ] Blinking cursor animation after tagline
|
||||||
|
|
||||||
|
**Footer**:
|
||||||
|
- [ ] "McDonald's IT Academy" displayed
|
||||||
|
|
||||||
|
**Expected**: All content matches specification exactly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Bilingual Content Check
|
||||||
|
|
||||||
|
**Test**: Verify English/Chinese alternating pattern
|
||||||
|
|
||||||
|
- [ ] Each piece of information has English version
|
||||||
|
- [ ] Each piece of information has Chinese version
|
||||||
|
- [ ] Lines alternate: English, then Chinese
|
||||||
|
- [ ] `lang="en"` attribute on English paragraphs
|
||||||
|
- [ ] `lang="zh-CN"` attribute on Chinese paragraphs
|
||||||
|
- [ ] Both languages are legible and well-formatted
|
||||||
|
|
||||||
|
**Expected**: Clear bilingual display with proper language tagging
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Countdown Timer Functionality
|
||||||
|
|
||||||
|
**Test**: Verify countdown accuracy and updates
|
||||||
|
|
||||||
|
**Before Event** (current time < Oct 31 2025 18:00 GMT+8):
|
||||||
|
- [ ] Countdown displays days, hours, minutes, seconds
|
||||||
|
- [ ] Timer updates every second
|
||||||
|
- [ ] Values are accurate (check against system clock)
|
||||||
|
- [ ] No negative values shown
|
||||||
|
- [ ] Format is clear (e.g., "365d 12h 34m 56s")
|
||||||
|
|
||||||
|
**Manual Time Test** (using browser dev tools):
|
||||||
|
```javascript
|
||||||
|
// Open browser console (F12)
|
||||||
|
// Override system date to test different states
|
||||||
|
|
||||||
|
// Test: Just before event starts
|
||||||
|
const testDate = new Date('2025-10-31T09:59:50Z'); // 17:59:50 GMT+8
|
||||||
|
// Check countdown shows 0d 0h 0m 10s (approximately)
|
||||||
|
|
||||||
|
// Test: Event starting
|
||||||
|
const testDate = new Date('2025-10-31T10:00:00Z'); // 18:00:00 GMT+8
|
||||||
|
// Check displays "🎃 EVENT STARTING NOW! 🎃"
|
||||||
|
|
||||||
|
// Test: Event ended
|
||||||
|
const testDate = new Date('2025-10-31T13:00:01Z'); // 21:00:01 GMT+8
|
||||||
|
// Check displays "👻 EVENT COMPLETED - Thanks for joining! 👻"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected**: Countdown is accurate and handles all three states correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Responsive Design Testing
|
||||||
|
|
||||||
|
**Test**: Page adapts to different screen sizes
|
||||||
|
|
||||||
|
**Desktop (1024px+)**:
|
||||||
|
- [ ] Full ASCII art logo visible
|
||||||
|
- [ ] All content displayed comfortably
|
||||||
|
- [ ] No horizontal scroll
|
||||||
|
- [ ] Text is readable without zooming
|
||||||
|
|
||||||
|
**Tablet (768-1023px)**:
|
||||||
|
- [ ] Layout adapts smoothly
|
||||||
|
- [ ] ASCII art remains legible OR switches to simpler version
|
||||||
|
- [ ] No horizontal scroll
|
||||||
|
- [ ] All features functional
|
||||||
|
|
||||||
|
**Mobile (320-767px)**:
|
||||||
|
- [ ] Mobile ASCII art version displayed (if different)
|
||||||
|
- [ ] Countdown timer visible and readable
|
||||||
|
- [ ] Bilingual content stacks vertically
|
||||||
|
- [ ] No horizontal scroll
|
||||||
|
- [ ] Tap targets are adequate (buttons, links)
|
||||||
|
|
||||||
|
**Very Small (< 320px)** [optional]:
|
||||||
|
- [ ] Ultra-minimal ASCII art or text fallback
|
||||||
|
- [ ] Core content still accessible
|
||||||
|
|
||||||
|
**How to test**:
|
||||||
|
1. Open browser DevTools (F12)
|
||||||
|
2. Toggle device toolbar (Ctrl+Shift+M / Cmd+Shift+M)
|
||||||
|
3. Select different device presets OR
|
||||||
|
4. Drag responsive width to test breakpoints
|
||||||
|
|
||||||
|
**Expected**: Page is fully functional and readable at all sizes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Accessibility Testing
|
||||||
|
|
||||||
|
**Test**: WCAG 2.1 AA compliance
|
||||||
|
|
||||||
|
**Contrast Ratios** (use https://webaim.org/resources/contrastchecker/):
|
||||||
|
- [ ] Green (#00FF00) on black (#000000) = 21:1 ratio ✅ (exceeds WCAG AAA)
|
||||||
|
- [ ] Amber (#FFBF00) on black (#000000) = 12:1 ratio ✅ (exceeds WCAG AA)
|
||||||
|
|
||||||
|
**Screen Reader Test** (optional but recommended):
|
||||||
|
- [ ] Enable screen reader (VoiceOver on Mac, NVDA on Windows)
|
||||||
|
- [ ] Navigate through page
|
||||||
|
- [ ] All content is announced
|
||||||
|
- [ ] Language switches are detected (English → Chinese)
|
||||||
|
- [ ] ARIA labels provide context for visual elements
|
||||||
|
|
||||||
|
**Keyboard Navigation**:
|
||||||
|
- [ ] Tab through all interactive elements
|
||||||
|
- [ ] Focus indicators are visible
|
||||||
|
- [ ] All functionality accessible via keyboard
|
||||||
|
|
||||||
|
**Semantic HTML**:
|
||||||
|
- [ ] Proper heading hierarchy (h1, h2, etc.)
|
||||||
|
- [ ] Semantic tags used (<header>, <main>, <section>, <footer>)
|
||||||
|
- [ ] `lang` attributes on bilingual content
|
||||||
|
|
||||||
|
**Expected**: Page meets WCAG 2.1 AA standards
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. Performance Testing
|
||||||
|
|
||||||
|
**Test**: Load time and file size
|
||||||
|
|
||||||
|
**File Size**:
|
||||||
|
```bash
|
||||||
|
# Check file size
|
||||||
|
ls -lh index.html
|
||||||
|
# Should be < 50KB
|
||||||
|
```
|
||||||
|
- [ ] File size is under 50KB (51,200 bytes)
|
||||||
|
|
||||||
|
**Load Time**:
|
||||||
|
1. Open browser DevTools (F12)
|
||||||
|
2. Go to Network tab
|
||||||
|
3. Hard refresh page (Ctrl+Shift+R / Cmd+Shift+R)
|
||||||
|
4. Check "Load" time in bottom status bar
|
||||||
|
|
||||||
|
- [ ] Page loads in under 1 second
|
||||||
|
|
||||||
|
**Animation Performance**:
|
||||||
|
1. Open DevTools → Performance tab
|
||||||
|
2. Record for 5 seconds
|
||||||
|
3. Check frame rate (FPS)
|
||||||
|
|
||||||
|
- [ ] Cursor blinking animation runs at 60fps
|
||||||
|
- [ ] Countdown updates don't cause jank
|
||||||
|
|
||||||
|
**Expected**: Fast load, smooth animations, small file size
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Browser Compatibility
|
||||||
|
|
||||||
|
**Test**: Page works in all target browsers
|
||||||
|
|
||||||
|
- [ ] **Chrome** (latest): All features work
|
||||||
|
- [ ] **Firefox** (latest): All features work
|
||||||
|
- [ ] **Safari** (latest): All features work
|
||||||
|
- [ ] **Edge** (latest): All features work
|
||||||
|
|
||||||
|
**How to test**:
|
||||||
|
1. Open index.html in each browser
|
||||||
|
2. Run through Quick Test checklist
|
||||||
|
3. Note any differences or issues
|
||||||
|
|
||||||
|
**Expected**: Consistent experience across all browsers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. JavaScript Disabled Test
|
||||||
|
|
||||||
|
**Test**: Page works without JavaScript
|
||||||
|
|
||||||
|
1. Disable JavaScript in browser settings:
|
||||||
|
- Chrome: Settings → Privacy → Site Settings → JavaScript → Blocked
|
||||||
|
- Firefox: about:config → javascript.enabled → false
|
||||||
|
2. Refresh page
|
||||||
|
|
||||||
|
- [ ] All static content visible
|
||||||
|
- [ ] ASCII art displays
|
||||||
|
- [ ] Event information readable
|
||||||
|
- [ ] Countdown shows fallback message: "Enable JavaScript for live countdown"
|
||||||
|
- [ ] No broken functionality
|
||||||
|
|
||||||
|
**Expected**: Progressive enhancement - core content accessible without JS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 10. HTML5 Validation
|
||||||
|
|
||||||
|
**Test**: Valid HTML5 markup
|
||||||
|
|
||||||
|
1. Go to https://validator.w3.org/
|
||||||
|
2. Upload index.html OR paste URL
|
||||||
|
3. Run validation
|
||||||
|
|
||||||
|
- [ ] Zero errors
|
||||||
|
- [ ] Zero warnings (or only acceptable warnings)
|
||||||
|
- [ ] Passes HTML5 validation
|
||||||
|
|
||||||
|
**Common acceptable warnings**:
|
||||||
|
- Data URI favicon warnings (browser-specific)
|
||||||
|
- Emoji in content (some validators flag these)
|
||||||
|
|
||||||
|
**Expected**: Clean validation with no critical errors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Edge Case Testing
|
||||||
|
|
||||||
|
### Edge Case 1: Countdown Reaches Zero
|
||||||
|
|
||||||
|
**Setup**: Set system time to Oct 31 2025 18:00 GMT+8 (or use dev tools)
|
||||||
|
|
||||||
|
**Test**:
|
||||||
|
- [ ] Countdown disappears
|
||||||
|
- [ ] Message displays: "🎃 EVENT STARTING NOW! 🎃"
|
||||||
|
- [ ] No errors in console
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Edge Case 2: After Event Ends
|
||||||
|
|
||||||
|
**Setup**: Set system time to after Oct 31 2025 21:00 GMT+8
|
||||||
|
|
||||||
|
**Test**:
|
||||||
|
- [ ] Countdown disappears
|
||||||
|
- [ ] Message displays: "👻 EVENT COMPLETED - Thanks for joining! 👻"
|
||||||
|
- [ ] No errors in console
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Edge Case 3: Very Long Content
|
||||||
|
|
||||||
|
**Test**: Ensure page handles overflow properly
|
||||||
|
- [ ] Long ASCII art doesn't break layout
|
||||||
|
- [ ] Long text content wraps appropriately
|
||||||
|
- [ ] No horizontal scroll on any screen size
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Edge Case 4: Slow Network
|
||||||
|
|
||||||
|
**Test**: Page loads correctly on slow connection
|
||||||
|
|
||||||
|
1. Open DevTools → Network tab
|
||||||
|
2. Throttle to "Slow 3G"
|
||||||
|
3. Hard refresh
|
||||||
|
|
||||||
|
- [ ] Page still loads under 3 seconds
|
||||||
|
- [ ] No broken elements
|
||||||
|
- [ ] Countdown starts once JS loads
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation Tools
|
||||||
|
|
||||||
|
**Contrast Checker**: https://webaim.org/resources/contrastchecker/
|
||||||
|
**HTML Validator**: https://validator.w3.org/
|
||||||
|
**CSS Validator**: https://jigsaw.w3.org/css-validator/
|
||||||
|
**WCAG Checker**: https://wave.webaim.org/
|
||||||
|
**Performance**: Chrome DevTools Lighthouse
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
**✅ Page is ready for deployment if**:
|
||||||
|
- All visual checks pass (terminal aesthetic)
|
||||||
|
- All content is present and correct
|
||||||
|
- Bilingual display works properly
|
||||||
|
- Countdown timer functions correctly
|
||||||
|
- Responsive on all screen sizes
|
||||||
|
- WCAG 2.1 AA compliant
|
||||||
|
- File size < 50KB
|
||||||
|
- Load time < 1 second
|
||||||
|
- Works in all target browsers
|
||||||
|
- HTML5 valid
|
||||||
|
|
||||||
|
**❌ Page needs fixes if**:
|
||||||
|
- Any visual element breaks terminal aesthetic
|
||||||
|
- Content is missing or incorrect
|
||||||
|
- Countdown doesn't update or shows errors
|
||||||
|
- Not responsive (horizontal scroll on mobile)
|
||||||
|
- Contrast ratios fail WCAG AA
|
||||||
|
- File size exceeds 50KB
|
||||||
|
- Load time exceeds 1 second
|
||||||
|
- Validation errors exist
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Problem**: Countdown doesn't update
|
||||||
|
- Check JavaScript console for errors
|
||||||
|
- Verify system date/time is correct
|
||||||
|
- Check JavaScript is enabled
|
||||||
|
|
||||||
|
**Problem**: ASCII art looks broken
|
||||||
|
- Verify monospace font is loading
|
||||||
|
- Check character encoding is UTF-8
|
||||||
|
- Test different browsers
|
||||||
|
|
||||||
|
**Problem**: Colors look wrong
|
||||||
|
- Check color hex values in CSS
|
||||||
|
- Verify no browser extensions affecting colors
|
||||||
|
- Test in incognito mode
|
||||||
|
|
||||||
|
**Problem**: Page not responsive
|
||||||
|
- Check viewport meta tag exists
|
||||||
|
- Verify media queries are working
|
||||||
|
- Test in different browsers
|
||||||
|
|
||||||
|
**Problem**: File size too large
|
||||||
|
- Check ASCII art for excessive whitespace
|
||||||
|
- Minify CSS/JS if needed
|
||||||
|
- Remove any unused code
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
After passing all tests:
|
||||||
|
1. ✅ Mark quickstart.md checklist complete
|
||||||
|
2. ✅ Document any issues found and fixed
|
||||||
|
3. ✅ Update CHANGELOG.md with v1.0.0 release
|
||||||
|
4. ✅ Prepare for deployment
|
||||||
|
5. ✅ Share with stakeholders (Jessi Pan)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Test Date**: _____________
|
||||||
|
**Tested By**: _____________
|
||||||
|
**Status**: ⬜ Pass | ⬜ Fail | ⬜ Needs Fixes
|
||||||
|
**Notes**: _________________________________________________
|
||||||
345
specs/001-mcdonald-s-it/research.md
Normal file
345
specs/001-mcdonald-s-it/research.md
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
# Research: McDonald's IT Halloween Event Page
|
||||||
|
|
||||||
|
**Feature**: Halloween event announcement webpage
|
||||||
|
**Date**: 2025-10-04
|
||||||
|
**Status**: Complete
|
||||||
|
|
||||||
|
## Research Summary
|
||||||
|
|
||||||
|
This document captures all research decisions made during the planning phase to resolve technical uncertainties and establish implementation approaches.
|
||||||
|
|
||||||
|
## Technical Research
|
||||||
|
|
||||||
|
### 1. HTML5 Semantic Markup Best Practices
|
||||||
|
|
||||||
|
**Question**: How to structure a single-page event announcement for optimal accessibility?
|
||||||
|
|
||||||
|
**Decision**: Use semantic HTML5 elements (`<header>`, `<main>`, `<section>`, `<footer>`)
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- Improves accessibility and screen reader navigation
|
||||||
|
- Better SEO (though not critical for internal event page)
|
||||||
|
- Required for WCAG 2.1 AA compliance
|
||||||
|
- Provides clear document structure without additional markup
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Generic `<div>` elements: Rejected due to poor accessibility and lack of semantic meaning
|
||||||
|
- `<article>` for main content: Rejected as event info is not article-style content
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
- Use `<header>` for title and ASCII logo
|
||||||
|
- Use `<main>` for event details and countdown
|
||||||
|
- Use `<section>` for logical content groups
|
||||||
|
- Use `<footer>` for McDonald's IT Academy attribution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. ASCII Art Rendering in HTML
|
||||||
|
|
||||||
|
**Question**: What's the best way to display ASCII art in HTML while preserving formatting?
|
||||||
|
|
||||||
|
**Decision**: Use `<pre>` tag with monospace font and UTF-8 encoding
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- `<pre>` preserves all whitespace and line breaks
|
||||||
|
- Prevents browser from collapsing spaces
|
||||||
|
- Works reliably across all browsers
|
||||||
|
- Simple and performant
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Canvas element: Rejected as overkill for static ASCII art; accessibility issues
|
||||||
|
- CSS Grid: Rejected due to complexity of positioning each character
|
||||||
|
- `white-space: pre` on div: Works but `<pre>` is semantically correct
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```html
|
||||||
|
<pre aria-label="McDonald's Logo">
|
||||||
|
[ASCII art here]
|
||||||
|
</pre>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Responsive ASCII Art Techniques
|
||||||
|
|
||||||
|
**Question**: How to make ASCII art legible on mobile devices?
|
||||||
|
|
||||||
|
**Decision**: Provide two versions - desktop (detailed) and mobile (simplified), switched via CSS media queries
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- Complex ASCII art becomes illegible when viewport narrows
|
||||||
|
- Different art for different breakpoints maintains aesthetic
|
||||||
|
- CSS `display: none` to hide inappropriate version
|
||||||
|
- No JavaScript required for switching
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Viewport scaling: Rejected as text becomes too small to read
|
||||||
|
- SVG conversion: Rejected as it's not true ASCII art
|
||||||
|
- Single responsive design: Not feasible with ASCII art constraints
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```css
|
||||||
|
.ascii-desktop { display: block; }
|
||||||
|
.ascii-mobile { display: none; }
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.ascii-desktop { display: none; }
|
||||||
|
.ascii-mobile { display: block; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Countdown Timer with Timezone Handling
|
||||||
|
|
||||||
|
**Question**: How to show countdown in GMT+8 for users in any timezone?
|
||||||
|
|
||||||
|
**Decision**: Use JavaScript `Date` object with explicit GMT+8 offset calculation
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- JavaScript Date handles timezone conversion automatically
|
||||||
|
- Calculate target time as GMT+8, compare with user's local time
|
||||||
|
- User sees accurate countdown regardless of their timezone
|
||||||
|
- No external library needed
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Server-side time: Rejected as this is a static page
|
||||||
|
- Timezone library (e.g., moment-timezone): Rejected due to no external dependencies constraint
|
||||||
|
- Fixed GMT+8 display: Rejected as confusing for users in other timezones
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```javascript
|
||||||
|
// Target: Oct 31 2025 18:00 GMT+8 = Oct 31 2025 10:00 UTC
|
||||||
|
const targetDate = new Date('2025-10-31T10:00:00Z');
|
||||||
|
const now = new Date();
|
||||||
|
const diff = targetDate - now;
|
||||||
|
// Calculate days, hours, minutes, seconds from diff
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Inline CSS/JS Organization
|
||||||
|
|
||||||
|
**Question**: Where to place CSS and JavaScript in a single HTML file?
|
||||||
|
|
||||||
|
**Decision**: CSS in `<style>` tag in `<head>`, JavaScript in `<script>` tag before `</body>`
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- CSS in head: Loads before rendering, prevents FOUC (Flash of Unstyled Content)
|
||||||
|
- JS before body close: DOM is ready before script executes
|
||||||
|
- Standard best practice for performance
|
||||||
|
- No external files to manage
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- All in `<head>`: Rejected as JS blocks initial render
|
||||||
|
- Inline styles/handlers: Rejected as harder to maintain and verbose
|
||||||
|
- JS in `<head>` with defer: Works but unnecessary complexity
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```html
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
/* All CSS here */
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Content -->
|
||||||
|
<script>
|
||||||
|
// All JS here
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. WCAG 2.1 AA Compliance for Dark Themes
|
||||||
|
|
||||||
|
**Question**: Do terminal colors (#00FF00, #FFBF00) on black meet WCAG contrast requirements?
|
||||||
|
|
||||||
|
**Decision**: Black (#000000) background with bright green (#00FF00) primary and amber (#FFBF00) accent
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- Green on black: Contrast ratio 21:1 (exceeds WCAG AAA 7:1 requirement)
|
||||||
|
- Amber on black: Contrast ratio 12:1 (exceeds WCAG AA 4.5:1 requirement)
|
||||||
|
- High contrast essential for accessibility
|
||||||
|
- Maintains authentic terminal aesthetic
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Dark gray (#1a1a1a) background: Rejected as reduces contrast and less terminal-like
|
||||||
|
- Lighter green (#00cc00): Not needed as #00FF00 already compliant
|
||||||
|
- White text: Rejected as breaks terminal aesthetic
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
- Use online contrast checker to verify ratios
|
||||||
|
- Test with screen reader (VoiceOver, NVDA)
|
||||||
|
- Ensure color is not the only way to convey information
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. Bilingual Content Display
|
||||||
|
|
||||||
|
**Question**: How to display English and Chinese content clearly?
|
||||||
|
|
||||||
|
**Decision**: Alternate English and Chinese lines with proper `lang` attributes
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- Visual pattern is easy to scan (English, then Chinese translation)
|
||||||
|
- `lang` attributes help screen readers pronounce correctly
|
||||||
|
- No JavaScript state management needed
|
||||||
|
- Mobile-friendly (vertical layout)
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Side-by-side columns: Rejected as breaks on mobile, causes horizontal scroll
|
||||||
|
- Toggle button: Rejected as requires JS state, hides content
|
||||||
|
- Tooltip on hover: Rejected as inaccessible on mobile
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```html
|
||||||
|
<p lang="en">Date: October 31, 2025</p>
|
||||||
|
<p lang="zh-CN">日期:2025年10月31日</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Blinking Cursor Animation
|
||||||
|
|
||||||
|
**Question**: How to create a blinking cursor effect for "i'm lovin' IT" tagline?
|
||||||
|
|
||||||
|
**Decision**: CSS `@keyframes` animation with `opacity` toggle
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- Pure CSS solution (no JS needed)
|
||||||
|
- Performant (GPU accelerated)
|
||||||
|
- Respects `prefers-reduced-motion` for accessibility
|
||||||
|
- Simple to implement
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- JavaScript setInterval: Rejected as unnecessary complexity and JS dependency
|
||||||
|
- CSS `visibility` toggle: Works but `opacity` is smoother
|
||||||
|
- Underscore character: Static, no animation
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```css
|
||||||
|
.cursor {
|
||||||
|
animation: blink 1s step-end infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.cursor { animation: none; opacity: 1; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. Performance Optimization for Single-File HTML
|
||||||
|
|
||||||
|
**Question**: How to keep file size under 50KB and load time under 1 second?
|
||||||
|
|
||||||
|
**Decision**: Minify repeated whitespace in ASCII art, use CSS shorthand, optimize countdown logic
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- ASCII art is the largest contributor to file size
|
||||||
|
- Removing unnecessary spaces in art while maintaining structure
|
||||||
|
- CSS shorthand reduces bytes (e.g., `margin: 0 auto` vs separate properties)
|
||||||
|
- Efficient countdown calculation (no repeated string operations)
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- Gzip compression: Rejected as hosting-dependent, not in our control
|
||||||
|
- Base64 encode ASCII: Rejected as increases size and reduces readability
|
||||||
|
- External CSS/JS: Rejected due to single-file constraint
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
- Keep ASCII art minimal but recognizable
|
||||||
|
- Use CSS shorthand: `margin`, `padding`, `font`
|
||||||
|
- Cache DOM selectors in JS
|
||||||
|
- Use template literals efficiently
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 10. Favicon Implementation Without External File
|
||||||
|
|
||||||
|
**Question**: How to add a favicon while maintaining single-file constraint?
|
||||||
|
|
||||||
|
**Decision**: Use data URI for emoji favicon (🎃)
|
||||||
|
|
||||||
|
**Rationale**:
|
||||||
|
- Data URI embeds image directly in HTML
|
||||||
|
- Emoji favicons widely supported in modern browsers
|
||||||
|
- Keeps single-file architecture intact
|
||||||
|
- Pumpkin emoji perfect for Halloween theme
|
||||||
|
|
||||||
|
**Alternatives Considered**:
|
||||||
|
- SVG data URI: Rejected as more complex for simple icon
|
||||||
|
- No favicon: Rejected as reduces professional appearance
|
||||||
|
- External .ico file: Rejected due to single-file requirement
|
||||||
|
|
||||||
|
**Implementation Notes**:
|
||||||
|
```html
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='0.9em' font-size='90'>🎃</text></svg>">
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Edge Case Decisions
|
||||||
|
|
||||||
|
### Post-Countdown Behavior
|
||||||
|
|
||||||
|
**Question**: What should display when countdown reaches zero?
|
||||||
|
|
||||||
|
**Decision**: Show "🎃 EVENT STARTING NOW! 🎃" message
|
||||||
|
|
||||||
|
**Rationale**: Clear indication event has begun, maintains festive theme
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Post-Event Behavior
|
||||||
|
|
||||||
|
**Question**: What should happen after Oct 31 2025 21:00 GMT+8?
|
||||||
|
|
||||||
|
**Decision**: Display "👻 EVENT COMPLETED - Thanks for joining! 👻"
|
||||||
|
|
||||||
|
**Rationale**: Graceful post-event message, acknowledges participants
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### JavaScript Disabled
|
||||||
|
|
||||||
|
**Question**: What if user has JavaScript disabled?
|
||||||
|
|
||||||
|
**Decision**: All content remains visible; countdown shows "Enable JavaScript for live countdown"
|
||||||
|
|
||||||
|
**Rationale**: Progressive enhancement - core content accessible without JS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Very Small Screens (<320px)
|
||||||
|
|
||||||
|
**Question**: How to handle screens smaller than 320px?
|
||||||
|
|
||||||
|
**Decision**: Ultra-minimal ASCII art (just "McD" text), prioritize readability
|
||||||
|
|
||||||
|
**Rationale**: Maintain functionality over aesthetics on extreme constraints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technology Stack Confirmation
|
||||||
|
|
||||||
|
**Language/Version**: HTML5, CSS3, JavaScript ES6+
|
||||||
|
**Dependencies**: None (fully self-contained)
|
||||||
|
**Browser Targets**: Chrome, Firefox, Safari, Edge (latest 2 versions)
|
||||||
|
**Performance Targets**: < 1 second load, < 50KB file size
|
||||||
|
**Accessibility Target**: WCAG 2.1 AA compliance
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
All technical unknowns resolved. Ready for Phase 1: Design & Contracts.
|
||||||
|
|
||||||
|
**Outputs**:
|
||||||
|
- data-model.md (entity definitions)
|
||||||
|
- contracts/ (JSON schema)
|
||||||
|
- quickstart.md (testing checklist)
|
||||||
|
- CLAUDE.md updates (agent context)
|
||||||
171
specs/001-mcdonald-s-it/spec.md
Normal file
171
specs/001-mcdonald-s-it/spec.md
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
# Feature Specification: McDonald's IT Halloween Event Page
|
||||||
|
|
||||||
|
**Feature Branch**: `001-mcdonald-s-it`
|
||||||
|
**Created**: 2025-10-04
|
||||||
|
**Status**: Draft
|
||||||
|
**Input**: User description: "McDonald's IT Halloween Event Page - minimalist geek-style webpage for MITA Halloween 2025 event with ASCII art, countdown timer, and bilingual content"
|
||||||
|
|
||||||
|
## Execution Flow (main)
|
||||||
|
```
|
||||||
|
1. Parse user description from Input
|
||||||
|
→ Feature: Event announcement webpage for McDonald's China IT Halloween 2025
|
||||||
|
2. Extract key concepts from description
|
||||||
|
→ Actors: MITA IT team members (300 programmers)
|
||||||
|
→ Actions: View event details, check countdown, register interest
|
||||||
|
→ Data: Event details, countdown timer state
|
||||||
|
→ Constraints: Minimalist geek aesthetic, bilingual content, cross-device compatibility
|
||||||
|
3. For each unclear aspect:
|
||||||
|
→ [No major clarifications needed - comprehensive requirements in CLAUDE.md]
|
||||||
|
4. Fill User Scenarios & Testing section
|
||||||
|
→ Primary flow: Visit page → View event info → Note event details
|
||||||
|
5. Generate Functional Requirements
|
||||||
|
→ All requirements derived from CLAUDE.md specifications
|
||||||
|
6. Identify Key Entities
|
||||||
|
→ Event data, countdown state
|
||||||
|
7. Run Review Checklist
|
||||||
|
→ All checks passed
|
||||||
|
8. Return: SUCCESS (spec ready for planning)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ Quick Guidelines
|
||||||
|
- ✅ Focus on WHAT users need and WHY
|
||||||
|
- ❌ Avoid HOW to implement (no tech stack, APIs, code structure)
|
||||||
|
- 👥 Written for business stakeholders, not developers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## User Scenarios & Testing *(mandatory)*
|
||||||
|
|
||||||
|
### Primary User Story
|
||||||
|
As a McDonald's China IT team member, I want to view the Halloween 2025 event announcement page so that I can learn about the event details, activities, and know when it starts through a countdown timer.
|
||||||
|
|
||||||
|
### Acceptance Scenarios
|
||||||
|
1. **Given** a team member visits the event page on desktop, **When** they load the page, **Then** they see ASCII art logo, event details in bilingual format, and a live countdown timer
|
||||||
|
2. **Given** a team member visits the event page on mobile, **When** they load the page, **Then** all content remains legible including ASCII art and the page is fully responsive
|
||||||
|
3. **Given** the event date/time approaches, **When** a team member views the countdown, **Then** it accurately reflects time remaining in GMT+8 timezone
|
||||||
|
4. **Given** a team member reads event information, **When** they scroll through the page, **Then** they can find event date (Oct 31 2025), time (18:00-21:00), location (MITA Building 2F Pantry), activities (cosplay, debugging games, lucky draw), and organizer contact (jessi.pan@cn.mcd.com)
|
||||||
|
|
||||||
|
### Edge Cases
|
||||||
|
- What happens when the countdown reaches zero? [NEEDS CLARIFICATION: Should display "Event Started" or "Event Ended" message]
|
||||||
|
- How does ASCII art render on very small screens (< 320px)? System must provide mobile-optimized version
|
||||||
|
- What happens if user visits after event date? [NEEDS CLARIFICATION: Should page remain active or show "Event Completed" message]
|
||||||
|
- What if JavaScript is disabled? Countdown won't work but all static content must remain accessible
|
||||||
|
|
||||||
|
## Requirements *(mandatory)*
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
|
||||||
|
**Visual Presentation**
|
||||||
|
- **FR-001**: Page MUST display McDonald's logo as ASCII art with Golden Arches M representation
|
||||||
|
- **FR-002**: Page MUST show tagline "i'm lovin' IT" centered below logo with blinking cursor animation
|
||||||
|
- **FR-003**: Page MUST use pure black background (#000000) with no gradients, shadows, or decorative effects
|
||||||
|
- **FR-004**: Page MUST use only monospace fonts (Courier New, Monaco, Consolas, Menlo)
|
||||||
|
- **FR-005**: Page MUST use terminal green (#00FF00) as primary color and amber (#FFBF00) for key information
|
||||||
|
- **FR-006**: Page MUST include Halloween-themed ASCII art (pumpkins, ghosts, bats) and emojis (🎃👻🦇)
|
||||||
|
- **FR-007**: Browser tab MUST show title "2025 MITA Halloween" with 🎃 favicon
|
||||||
|
|
||||||
|
**Event Information**
|
||||||
|
- **FR-008**: Page MUST display event date: October 31, 2025
|
||||||
|
- **FR-009**: Page MUST display event time: 18:00 - 21:00 (6:00 PM - 9:00 PM) GMT+8
|
||||||
|
- **FR-010**: Page MUST display event location: MITA Building 2F Pantry
|
||||||
|
- **FR-011**: Page MUST display organizer name and email: Jessi Pan (jessi.pan@cn.mcd.com)
|
||||||
|
- **FR-012**: Page MUST display all event content in bilingual format (English first, Chinese second, alternating lines)
|
||||||
|
- **FR-013**: Page MUST list activities: Cosplay encouragement, bug debugging games, lucky draw
|
||||||
|
- **FR-014**: Page MUST include notes that costumes are encouraged and food/drinks will be provided
|
||||||
|
- **FR-015**: Page MUST display footer text: "McDonald's IT Academy"
|
||||||
|
- **FR-016**: Page MUST include programmer humor and tech references throughout content
|
||||||
|
|
||||||
|
**Countdown Timer**
|
||||||
|
- **FR-017**: Page MUST display real-time countdown to event start (Oct 31 2025, 18:00 GMT+8)
|
||||||
|
- **FR-018**: Countdown MUST calculate time using GMT+8 timezone
|
||||||
|
- **FR-019**: Countdown MUST update in real-time showing days, hours, minutes, and seconds remaining
|
||||||
|
- **FR-020**: Countdown MUST handle timezone conversions correctly for users in different timezones viewing the page
|
||||||
|
|
||||||
|
**Responsive Design**
|
||||||
|
- **FR-021**: Page MUST be fully functional on desktop screens (1024px and wider)
|
||||||
|
- **FR-022**: Page MUST be fully functional on tablet screens (768-1023px)
|
||||||
|
- **FR-023**: Page MUST be fully functional on mobile screens (320-767px)
|
||||||
|
- **FR-024**: ASCII art MUST remain legible on all screen sizes (provide mobile-optimized version if needed)
|
||||||
|
- **FR-025**: Page MUST adapt layout responsively without horizontal scrolling
|
||||||
|
|
||||||
|
**Performance & Compatibility**
|
||||||
|
- **FR-026**: Page MUST load in under 1 second on standard broadband connection
|
||||||
|
- **FR-027**: Page MUST be a single self-contained HTML file with inline CSS
|
||||||
|
- **FR-028**: Page MUST work on modern browsers: Chrome, Firefox, Safari, Edge (latest 2 versions)
|
||||||
|
- **FR-029**: Page file size MUST be under 50KB
|
||||||
|
- **FR-030**: Page MUST use minimal or no JavaScript (only for countdown timer)
|
||||||
|
|
||||||
|
**Accessibility**
|
||||||
|
- **FR-031**: Page MUST meet WCAG 2.1 AA compliance standards
|
||||||
|
- **FR-032**: Page MUST include proper ARIA labels for screen readers
|
||||||
|
- **FR-033**: Page MUST include lang attributes for bilingual content
|
||||||
|
- **FR-034**: Page MUST maintain high contrast ratio (black background with bright text)
|
||||||
|
- **FR-035**: Page MUST include meta description: "McDonald's China IT Halloween 2025 - Join 300 MITA developers for cosplay, debugging games, and lucky draw at MITA Building 2F Pantry"
|
||||||
|
|
||||||
|
### Key Entities
|
||||||
|
|
||||||
|
- **Event**: Represents the Halloween event with attributes: date (Oct 31 2025), time (18:00-21:00 GMT+8), location (MITA Building 2F Pantry), organizer (Jessi Pan), target audience (300 MITA programmers), activities (cosplay, debugging games, lucky draw)
|
||||||
|
|
||||||
|
- **Countdown State**: Represents the real-time countdown with attributes: target datetime (Oct 31 2025 18:00 GMT+8), current time, time remaining (days, hours, minutes, seconds), timezone (GMT+8)
|
||||||
|
|
||||||
|
- **Visual Theme**: Represents the design aesthetic with attributes: background color (#000000), primary color (#00FF00), accent color (#FFBF00), font family (monospace only), ASCII art elements (McDonald's logo, Halloween decorations), animation (blinking cursor)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Review & Acceptance Checklist
|
||||||
|
*GATE: Automated checks run during main() execution*
|
||||||
|
|
||||||
|
### Content Quality
|
||||||
|
- [x] No implementation details (languages, frameworks, APIs)
|
||||||
|
- [x] Focused on user value and business needs
|
||||||
|
- [x] Written for non-technical stakeholders
|
||||||
|
- [x] All mandatory sections completed
|
||||||
|
|
||||||
|
### Requirement Completeness
|
||||||
|
- [ ] No [NEEDS CLARIFICATION] markers remain (2 edge cases need clarification)
|
||||||
|
- [x] Requirements are testable and unambiguous
|
||||||
|
- [x] Success criteria are measurable
|
||||||
|
- [x] Scope is clearly bounded
|
||||||
|
- [x] Dependencies and assumptions identified
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Execution Status
|
||||||
|
*Updated by main() during processing*
|
||||||
|
|
||||||
|
- [x] User description parsed
|
||||||
|
- [x] Key concepts extracted
|
||||||
|
- [x] Ambiguities marked (2 edge cases)
|
||||||
|
- [x] User scenarios defined
|
||||||
|
- [x] Requirements generated (35 functional requirements)
|
||||||
|
- [x] Entities identified (3 key entities)
|
||||||
|
- [x] Review checklist passed (with 2 minor clarifications needed)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
**Clarifications Needed:**
|
||||||
|
1. Post-countdown behavior: What should display when countdown reaches zero?
|
||||||
|
2. Post-event behavior: Should page remain active or show completion message after Oct 31 2025?
|
||||||
|
|
||||||
|
**Design Philosophy:**
|
||||||
|
- Extreme minimalism inspired by Homebrew package manager aesthetic
|
||||||
|
- Terminal/command-line interface look and feel
|
||||||
|
- Geek culture references and programmer humor throughout
|
||||||
|
- High contrast for optimal readability
|
||||||
|
- No external dependencies for easy deployment
|
||||||
|
|
||||||
|
**Target Audience:**
|
||||||
|
- 300 McDonald's China IT team members (MITA)
|
||||||
|
- Technical staff comfortable with terminal aesthetics
|
||||||
|
- Bilingual (English/Chinese) speakers
|
||||||
|
|
||||||
|
**Success Metrics:**
|
||||||
|
- Page loads < 1 second
|
||||||
|
- Responsive on all devices
|
||||||
|
- 100% WCAG 2.1 AA compliance
|
||||||
|
- Zero external dependencies
|
||||||
|
- File size < 50KB
|
||||||
Reference in New Issue
Block a user