Enhance the UI and UX for iphone view


## plugin:context7:context7
Use this server to fetch current documentation whenever the user asks about a library, framework, SDK, API, CLI tool, or cloud service -- even well-known ones like React, Next.js, Prisma, Express, Tailwind, Django, or Spring Boot. This includes API syntax, configuration, version migration, library-specific debugging, setup instructions, and CLI tool usage. Use even when you think you know the answer -- your training data may not reflect recent changes. Prefer this over web search for library docs.

Do not use for: refactoring, writing scripts from scratch, debugging business logic, code review, or general programming concepts.


- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so m…
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- simplify: Review changed code for reuse, quality, and efficiency, then fix any issues found.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo, defaults to 10m) - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep…
- schedule: Create, update, list, or run scheduled remote agents (triggers) that execute on a cron schedule. - When the user wants to schedule a recurring remote agent, set up automated tasks, create a cron job for Claude Code, or manage their scheduled agents/…
- claude-api: Build apps with the Claude API or Anthropic SDK.
TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`/`claude_agent_sdk`, or user asks to use Claude API, Anthropic SDKs, or Agent SDK.
DO NOT TRIGGER when: code imports `openai`/other AI SDK, ge…
- ralph-loop:help: Explain Ralph Loop plugin and available commands
- ralph-loop:cancel-ralph: Cancel active Ralph Loop
- ralph-loop:ralph-loop: Start Ralph Loop in current session
- code-review:code-review: Code review a pull request
- vercel:deploy: Deploy the current project to Vercel. Pass "prod" or "production" as argume…
- vercel:marketplace: Discover and install Vercel Marketplace integrations. Use to find databases…
- vercel:status: Show the status of the current Vercel project — recent deployments, linked …
- vercel:env: Manage Vercel environment variables. Commands include list, pull, add, remo…
- vercel:bootstrap: Bootstrap a repository with Vercel-linked resources by running preflight ch…
- vercel-plugin:marketplace: Discover and install Vercel Marketplace integrations. Use to find databases…
- vercel-plugin:bootstrap: Bootstrap a repository with Vercel-linked resources by running preflight ch…
- vercel-plugin:deploy: Deploy the current project to Vercel. Pass "prod" or "production" as argume…
- vercel-plugin:status: Show the status of the current Vercel project — recent deployments, linked …
- vercel-plugin:env: Manage Vercel environment variables. Commands include list, pull, add, remo…
- frontend-design:frontend-design: Create distinctive, production-grade frontend interfaces with high design q…
- vercel:auth: Authentication integration guidance — Clerk (native Vercel Marketplace), De…
- vercel:deployments-cicd: Vercel deployment and CI/CD expert guidance. Use when deploying, promoting,…
- vercel:vercel-functions: Vercel Functions expert guidance — Serverless Functions, Edge Functions, Fl…
- vercel:vercel-sandbox: Vercel Sandbox guidance — ephemeral Firecracker microVMs for running untrus…
- vercel:turbopack: Turbopack expert guidance. Use when configuring the Next.js bundler, optimi…
- vercel:marketplace: Vercel Marketplace expert guidance — discovering, installing, and building …
- vercel:next-forge: next-forge expert guidance — production-grade Turborepo monorepo SaaS start…
- vercel:verification: Full-story verification — infers what the user is building, then verifies t…
- vercel:workflow: Vercel Workflow DevKit (WDK) expert guidance. Use when building durable wor…
- vercel:knowledge-update: Corrects outdated LLM knowledge about the Vercel platform and introduces ne…
- vercel:ai-gateway: Vercel AI Gateway expert guidance. Use when configuring model routing, prov…
- vercel:chat-sdk: Vercel Chat SDK expert guidance. Use when building multi-platform chat bots…
- vercel:next-upgrade: Upgrade Next.js to the latest version following official migration guides a…
- vercel:vercel-agent: Vercel Agent guidance — AI-powered code review, incident investigation, and…
- vercel:shadcn: shadcn/ui expert guidance — CLI, component installation, composition patter…
- vercel:runtime-cache: Vercel Runtime Cache API guidance — ephemeral per-region key-value cache wi…
- vercel:routing-middleware: Vercel Routing Middleware guidance — request interception before cache, rew…
- vercel:ai-sdk: Vercel AI SDK expert guidance. Use when building AI-powered features — chat…
- vercel:react-best-practices: React best-practices reviewer for TSX files. Triggers after editing multipl…
- vercel:nextjs: Next.js App Router expert guidance. Use when building, debugging, or archit…
- vercel:bootstrap: Project bootstrapping orchestrator for repos that depend on Vercel-linked r…
- vercel:vercel-storage: Vercel storage expert guidance — Blob, Edge Config, and Marketplace storage…
- vercel:vercel-cli: Vercel CLI expert guidance. Use when deploying, managing environment variab…
- vercel:next-cache-components: Next.js 16 Cache Components guidance — PPR, use cache directive, cacheLife,…
- vercel:env-vars: Vercel environment variable expert guidance. Use when working with .env fil…
- vercel-plugin:vercel-agent: Vercel Agent guidance — AI-powered code review, incident investigation, and…
- vercel-plugin:react-best-practices: React best-practices reviewer for TSX files. Triggers after editing multipl…
- vercel-plugin:vercel-sandbox: Vercel Sandbox guidance — ephemeral Firecracker microVMs for running untrus…
- vercel-plugin:next-upgrade: Upgrade Next.js to the latest version following official migration guides a…
- vercel-plugin:auth: Authentication integration guidance — Clerk (native Vercel Marketplace), De…
- vercel-plugin:chat-sdk: Vercel Chat SDK expert guidance. Use when building multi-platform chat bots…
- vercel-plugin:vercel-storage: Vercel storage expert guidance — Blob, Edge Config, and Marketplace storage…
- vercel-plugin:ai-gateway: Vercel AI Gateway expert guidance. Use when configuring model routing, prov…
- vercel-plugin:knowledge-update: Corrects outdated LLM knowledge about the Vercel platform and introduces ne…
- vercel-plugin:routing-middleware: Vercel Routing Middleware guidance — request interception before cache, rew…
- vercel-plugin:vercel-cli: Vercel CLI expert guidance. Use when deploying, managing environment variab…
- vercel-plugin:runtime-cache: Vercel Runtime Cache API guidance — ephemeral per-region key-value cache wi…
- vercel-plugin:deployments-cicd: Vercel deployment and CI/CD expert guidance. Use when deploying, promoting,…
- vercel-plugin:workflow: Vercel Workflow DevKit (WDK) expert guidance. Use when building durable wor…
- vercel-plugin:bootstrap: Project bootstrapping orchestrator for repos that depend on Vercel-linked r…
- vercel-plugin:shadcn: shadcn/ui expert guidance — CLI, component installation, composition patter…
- vercel-plugin:marketplace: Vercel Marketplace expert guidance — discovering, installing, and building …
- vercel-plugin:nextjs: Next.js App Router expert guidance. Use when building, debugging, or archit…
- vercel-plugin:turbopack: Turbopack expert guidance. Use when configuring the Next.js bundler, optimi…
- vercel-plugin:verification: Full-story verification — infers what the user is building, then verifies t…
- vercel-plugin:next-cache-components: Next.js 16 Cache Components guidance — PPR, use cache directive, cacheLife,…
- vercel-plugin:env-vars: Vercel environment variable expert guidance. Use when working with .env fil…
- vercel-plugin:ai-sdk: Vercel AI SDK expert guidance. Use when building AI-powered features — chat…
- vercel-plugin:vercel-functions: Vercel Functions expert guidance — Serverless Functions, Edge Functions, Fl…


Let me explore the project structure first.


Bash

List files in home directory


Applications
ascs-homework-tracker
CLAUDE_CODE_BUNDLE.md
claude-dashboard
course-dashboard.html
Desktop
dewa-ai-dashboard
Documents
Downloads
Library
Movies
Music
my-workspace
Pictures
pl-instagram-tracker
Projects
Public
Sites
skills-lock.json
[rerun: b1]


ls /Users/khalidbinkalban/Projects && ls /Users/khalidbinkalban/my-workspace

List files in Projects and my-workspace directories


dewa-pr-tracker
finally
client
data
dist
node_modules
package-lock.json
package.json
README.md
server
[rerun: b2]


ls /Users/khalidbinkalban/dewa-ai-dashboard && ls /Users/khalidbinkalban/claude-dashboard && ls /Users/khalidbinkalban/Projects/dewa-pr-tracker && ls /Users/khalidbinkalban/Projects/finally

List contents of multiple project directories


dist
index.html
node_modules
package-lock.json
package.json
postcss.config.js
src
tailwind.config.js
vite.config.js
backend
frontend
leaderboard
package.json
PROMPT.md
Caddyfile
config.py
dashboard.py
database.py
dewa_tracker.db
proxy.py
requirements.txt
scheduler.py
scraper.py
start.sh
venv
backend
CLAUDE.md
LICENSE
planning
README.md
[result-id: r1]
[rerun: b3]


cat /Users/khalidbinkalban/.claude/projects/-Users-khalidbinkalban/memory/MEMORY.md 2>/dev/null || echo "No MEMORY.md found"

Check memory for project context


No MEMORY.md found
[rerun: b4]


ls /Users/khalidbinkalban/.claude/projects/-Users-khalidbinkalban/ 2>/dev/null || echo "No memory directory"

Check memory directory


1a5076c8-bbce-43e9-b029-8f5f2472f179.jsonl
28892ad8-bdf8-4f33-82c8-f0983e35341f.jsonl
3db42580-585e-4344-9519-51ba70d42f4f.jsonl
5b26ebf8-14dc-49a4-bd48-6b6847fc4c4f
5b26ebf8-14dc-49a4-bd48-6b6847fc4c4f.jsonl
71a37317-500a-4359-a09b-ea4c74a3ac86.jsonl
7e09fdd0-3bf7-4fd4-953f-b8434ec56a57
7e09fdd0-3bf7-4fd4-953f-b8434ec56a57.jsonl
7e106da0-3fec-4eb4-8d49-d2445d1bb8df
7e106da0-3fec-4eb4-8d49-d2445d1bb8df.jsonl
8784356f-5e65-4e77-8c04-6153db780412
8784356f-5e65-4e77-8c04-6153db780412.jsonl
8a4ad50c-138f-4aea-b1a8-e7ab539f45d9.jsonl
958cf910-74d9-47a3-ab2e-975fd4f3f189.jsonl
9c2884bf-f643-470f-8cfa-453af3ae1826
9c2884bf-f643-470f-8cfa-453af3ae1826.jsonl
a3eeb830-97f7-4e10-8ded-705230a8220b.jsonl
b1db84cf-8d18-462b-a602-b4a501380110.jsonl
b8a417d9-4c38-43aa-9f78-45d2d13b63d0
b8a417d9-4c38-43aa-9f78-45d2d13b63d0.jsonl
ba4277a8-d085-43f3-9d34-aaf6c40d9022.jsonl
bb94fa2d-4842-4f4e-8832-6b053493b455.jsonl
c3652f64-4e33-42cc-91db-d0ed4e8ca0a9.jsonl
c43e9f65-9ee6-4b01-a2fe-5fa5bcf38110.jsonl
c84d2694-1d33-4c9a-a5d9-81c650a29aae.jsonl
cdc22b60-4df8-4f7c-ace8-61f7d0b2c015.jsonl
d5bf28de-b596-4a81-9145-ff88ec3550ba
d5bf28de-b596-4a81-9145-ff88ec3550ba.jsonl
e7059dc4-4bd5-47d7-8ab7-df82b52595f7
e7059dc4-4bd5-47d7-8ab7-df82b52595f7.jsonl
e9828279-7904-4890-bbfb-97b1991837ff.jsonl
fe79025b-edd3-49fe-ad41-6a3a45ae94c8.jsonl
memory
vercel-plugin
[result-id: r2]
[rerun: b5]


Which project should I enhance the iPhone UI/UX for? I can see several projects in your home directory:

1. **`dewa-ai-dashboard`** — appears to be a dashboard with Tailwind/Vite
2. **`claude-dashboard`** — another dashboard
3. **`ascs-homework-tracker`**
4. **`pl-instagram-tracker`**
5. **`Projects/dewa-pr-tracker`** / **`Projects/finally`**
6. **`course-dashboard.html`** — standalone HTML file

Which one would you like me to work on?


PLAYER_NAME=Khalid Bin Kalban python3 ~/.claude/push_stats.py

Failed with non-blocking status code: /bin/sh: Bin: command not found


List ascs-homework-tracker contents


dist
index.html
node_modules
package-lock.json
package.json
src
vercel.json
vite.config.js
[rerun: b6]


List src directory


App.css
App.jsx
data
hooks
icons
lib
main.jsx
[rerun: b7]


ls /Users/khalidbinkalban/ascs-homework-tracker/src/data && ls /Users/khalidbinkalban/ascs-homework-tracker/src/hooks && ls /Users/khalidbinkalban/ascs-homework-tracker/src/lib

List subdirectories


constants.js
useTasks.js
firebase.js
[rerun: b8]


1	:root {
2	  --bg: #f0f2f7;
3	  --surface: #ffffff;
4	  --surface-2: #f5f7fa;
5	  --border: #eaecf0;
6	  --border-light: #eeeeee;
7	  --text-primary: #1a1a1a;
8	  --text-secondary: #888888;
9	  --text-muted: #bbbbbb;
10	  --overdue-bg: #fff8f8;
11	  --spinner-track: #e0e0e0;
12	  --kid-mini-bg: #e8e8e8;
13	}
14
15	[data-theme="dark"] {
16	  --bg: #0f1117;
17	  --surface: #1a1d27;
18	  --surface-2: #22263a;
19	  --border: #2e3347;
20	  --border-light: #2a2d3e;
21	  --text-primary: #e8eaf0;
22	  --text-secondary: #8b92a5;
23	  --text-muted: #5a6278;
24	  --overdue-bg: #2a1a1a;
25	  --spinner-track: #2e3347;
26	  --kid-mini-bg: #2e3347;
27	}
28
29	*, *::before, *::after {
30	  box-sizing: border-box;
31	  margin: 0;
32	  padding: 0;
33	  -webkit-tap-highlight-color: transparent;
34	}
35
36	body {
37	  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
38	  background: var(--bg);
39	  min-height: 100vh;
40	  -webkit-font-smoothing: antialiased;
41	  transition: background 0.25s ease;
42	}
43
44	.app {
45	  max-width: 860px;
46	  margin: 0 auto;
47	  padding: 14px 14px 36px;
48	}
49
50	/* ─── Loading Screen ─── */
51	.loading-screen {
52	  min-height: 100vh;
53	  display: flex;
54	  align-items: center;
55	  justify-content: center;
56	  background: var(--bg);
57	}
58
59	.loading-inner {
60	  display: flex;
61	  flex-direction: column;
62	  align-items: center;
63	  gap: 14px;
64	}
65
66	.loading-logo {
67	  width: 64px;
68	  height: 64px;
69	  background: linear-gradient(135deg, #1D9E75, #185FA5);
70	  border-radius: 18px;
71	  display: flex;
72	  align-items: center;
73	  justify-content: center;
74	  font-size: 18px;
75	  font-weight: 900;
76	  color: white;
77	  letter-spacing: -0.5px;
78	}
79
80	.loading-spinner {
81	  width: 28px;
82	  height: 28px;
83	  border: 3px solid var(--spinner-track);
84	  border-top-color: #1D9E75;
85	  border-radius: 50%;
86	  animation: spin 0.8s linear infinite;
87	}
88
89	@keyframes spin {
90	  to { transform: rotate(360deg); }
91	}
92
93	.loading-text {
94	  font-size: 14px;
95	  color: var(--text-secondary);
96	  font-weight: 500;
97	}
98
99	/* ─── Header ─── */
100	.header {
101	  border-radius: 20px;
102	  padding: 18px 20px 16px;
103	  color: white;
104	  margin-bottom: 16px;
105	  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
106	}
107
108	.header-top {
109	  display: flex;
110	  align-items: flex-start;
111	  justify-content: space-between;
112	  gap: 10px;
113	  flex-wrap: wrap;
114	  margin-bottom: 14px;
115	}
116
117	.header-logo {
118	  display: flex;
119	  align-items: center;
120	  gap: 12px;
121	}
122
123	.logo-box {
124	  width: 50px;
125	  height: 50px;
126	  background: rgba(255, 255, 255, 0.2);
127	  backdrop-filter: blur(6px);
128	  border-radius: 14px;
129	  display: flex;
130	  align-items: center;
131	  justify-content: center;
132	  font-size: 14px;
133	  font-weight: 900;
134	  letter-spacing: -0.5px;
135	  flex-shrink: 0;
136	  border: 1.5px solid rgba(255, 255, 255, 0.3);
137	}
138
139	.school-name {
140	  font-size: 14px;
141	  font-weight: 700;
142	  line-height: 1.3;
143	}
144
145	.app-subtitle {
146	  font-size: 12px;
147	  opacity: 0.85;
148	  margin-top: 2px;
149	}
150
151	.header-date-col {
152	  display: flex;
153	  flex-direction: column;
154	  align-items: flex-end;
155	  gap: 3px;
156	}
157
158	.header-date {
159	  font-size: 11px;
160	  opacity: 0.8;
161	  white-space: nowrap;
162	}
163
164	.header-clock {
165	  display: flex;
166	  align-items: center;
167	  gap: 4px;
168	  font-size: 13px;
169	  font-weight: 700;
170	  font-variant-numeric: tabular-nums;
171	  letter-spacing: 0.5px;
172	  opacity: 0.95;
173	}
174
175	.header-badges {
176	  display: flex;
177	  align-items: center;
178	  gap: 5px;
179	  margin-top: 2px;
180	  justify-content: flex-end;
181	}
182
183	.sync-badge {
184	  display: flex;
185	  align-items: center;
186	  gap: 3px;
187	  background: rgba(255, 255, 255, 0.18);
188	  border-radius: 99px;
189	  padding: 2px 7px;
190	  font-size: 10px;
191	  font-weight: 700;
192	  letter-spacing: 0.3px;
193	}
194
195	.theme-toggle {
196	  display: flex;
197	  align-items: center;
198	  justify-content: center;
199	  width: 26px;
200	  height: 20px;
201	  background: rgba(255, 255, 255, 0.18);
202	  border: none;
203	  border-radius: 99px;
204	  cursor: pointer;
205	  color: white;
206	  padding: 0;
207	  transition: background 0.2s;
208	}
209
210	.theme-toggle:hover {
211	  background: rgba(255, 255, 255, 0.3);
212	}
213
214	.header-progress {
215	  background: rgba(255, 255, 255, 0.15);
216	  border-radius: 10px;
217	  padding: 10px 12px;
218	}
219
220	.progress-label {
221	  display: flex;
222	  justify-content: space-between;
223	  font-size: 11px;
224	  font-weight: 600;
225	  opacity: 0.9;
226	  margin-bottom: 6px;
227	}
228
229	.progress-pct { font-weight: 800; }
230
231	.progress-track {
232	  height: 7px;
233	  background: rgba(255, 255, 255, 0.25);
234	  border-radius: 99px;
235	  overflow: hidden;
236	}
237
238	.progress-fill {
239	  height: 100%;
240	  background: rgba(255, 255, 255, 0.9);
241	  border-radius: 99px;
242	  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
243	  min-width: 4px;
244	}
245
246	/* ─── Kid Switcher ─── */
247	.kid-switcher {
248	  display: flex;
249	  gap: 12px;
250	  margin-bottom: 16px;
251	}
252
253	.kid-btn {
254	  flex: 1;
255	  padding: 14px 10px 12px;
256	  border-radius: 18px;
257	  border: 2px solid transparent;
258	  cursor: pointer;
259	  text-align: center;
260	  transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1);
261	  background: var(--surface-2);
262	}
263
264	.kid-btn.active {
265	  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
266	  transform: translateY(-1px);
267	}
268
269	.kid-avatar-wrap {
270	  display: flex;
271	  justify-content: center;
272	  margin-bottom: 6px;
273	  line-height: 0;
274	}
275
276	.kid-name {
277	  display: block;
278	  font-size: 16px;
279	  font-weight: 800;
280	  letter-spacing: -0.3px;
281	}
282
283	.kid-grade {
284	  display: block;
285	  font-size: 11px;
286	  color: var(--text-secondary);
287	  margin-bottom: 8px;
288	}
289
290	.kid-mini-progress {
291	  height: 4px;
292	  background: var(--kid-mini-bg);
293	  border-radius: 99px;
294	  overflow: hidden;
295	  margin-bottom: 8px;
296	  width: 70%;
297	  margin-left: auto;
298	  margin-right: auto;
299	}
300
301	.kid-mini-fill {
302	  height: 100%;
303	  border-radius: 99px;
304	  transition: width 0.5s ease;
305	  min-width: 3px;
306	}
307
308	.kid-badges {
309	  display: flex;
310	  justify-content: center;
311	  gap: 4px;
312	  flex-wrap: wrap;
313	}
314
315	/* ─── Calendar ─── */
316	.calendar-section { margin-bottom: 16px; }
317
318	.section-label {
319	  display: inline-flex;
320	  align-items: center;
321	  gap: 5px;
322	  font-size: 12px;
323	  font-weight: 700;
324	  color: var(--text-secondary);
325	  text-transform: uppercase;
326	  letter-spacing: 0.6px;
327	  margin-bottom: 8px;
328	}
329
330	.calendar-row {
331	  display: flex;
332	  gap: 6px;
333	}
334
335	.day-btn {
336	  flex: 1;
337	  padding: 9px 4px 7px;
338	  border-radius: 14px;
339	  border: 2px solid;
340	  cursor: pointer;
341	  text-align: center;
342	  background: var(--surface);
343	  transition: all 0.2s ease;
344	  min-width: 0;
345	}
346
347	.day-btn.active {
348	  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
349	  transform: translateY(-1px);
350	}
351
352	.day-name {
353	  display: block;
354	  font-size: 10px;
355	  font-weight: 700;
356	  letter-spacing: 0.3px;
357	  text-transform: uppercase;
358	  margin-bottom: 3px;
359	}
360
361	.day-num {
362	  display: block;
363	  font-size: 18px;
364	  font-weight: 800;
365	  line-height: 1;
366	  margin-bottom: 4px;
367	}
368
369	.day-count {
370	  display: inline-block;
371	  font-size: 9px;
372	  font-weight: 700;
373	  padding: 2px 5px;
374	  border-radius: 99px;
375	}
376
377	.day-summary {
378	  margin-top: 10px;
379	  padding: 10px 14px;
380	  border-radius: 12px;
381	  background: var(--surface);
382	  border: 1px solid var(--border-light);
383	}
384
385	.day-summary-label {
386	  display: block;
387	  font-size: 11px;
388	  font-weight: 700;
389	  margin-bottom: 6px;
390	}
391
392	.day-summary-tasks {
393	  display: flex;
394	  flex-wrap: wrap;
395	  gap: 5px;
396	}
397
398	.day-task-chip {
399	  display: inline-flex;
400	  align-items: center;
401	  gap: 4px;
402	  font-size: 11px;
403	  padding: 3px 9px;
404	  border-radius: 20px;
405	  font-weight: 600;
406	}
407
408	/* ─── Stats ─── */
409	.stats-row {
410	  display: flex;
411	  gap: 10px;
412	  margin-bottom: 16px;
413	}
414
415	.stat-card {
416	  flex: 1;
417	  padding: 12px 8px;
418	  border-radius: 14px;
419	  text-align: center;
420	  background: var(--surface);
421	  border-top: 3px solid;
422	}
423
424	.stat-dot {
425	  display: block;
426	  width: 6px;
427	  height: 6px;
428	  border-radius: 50%;
429	  margin: 0 auto 4px;
430	}
431
432	.stat-num {
433	  display: block;
434	  font-size: 28px;
435	  font-weight: 800;
436	  line-height: 1;
437	  margin-bottom: 3px;
438	}
439
440	.stat-label {
441	  display: block;
442	  font-size: 10px;
443	  font-weight: 700;
444	  text-transform: uppercase;
445	  letter-spacing: 0.4px;
446	}
447
448	/* ─── Tabs + Add ─── */
449	.tab-row {
450	  display: flex;
451	  gap: 8px;
452	  align-items: center;
453	  margin-bottom: 14px;
454	}
455
456	.tab-btn {
457	  display: inline-flex;
458	  align-items: center;
459	  gap: 6px;
460	  padding: 10px 16px;
461	  border-radius: 22px;
462	  border: none;
463	  cursor: pointer;
464	  font-weight: 700;
465	  font-size: 13px;
466	  transition: all 0.2s ease;
467	  background: var(--surface-2);
468	  color: var(--text-secondary);
469	}
470
471	.tab-count {
472	  display: inline-block;
473	  font-size: 11px;
474	  font-weight: 800;
475	  padding: 2px 7px;
476	  border-radius: 99px;
477	  background: var(--border);
478	  color: var(--text-secondary);
479	}
480
481	.add-btn {
482	  margin-left: auto;
483	  display: inline-flex;
484	  align-items: center;
485	  gap: 5px;
486	  padding: 10px 18px;
487	  border-radius: 22px;
488	  border: none;
489	  cursor: pointer;
490	  font-weight: 800;
491	  font-size: 13px;
492	  color: white;
493	  transition: all 0.2s ease;
494	}
495
496	.add-btn:active { transform: scale(0.96); }
497
498	/* ─── Form ─── */
499	.form-card {
500	  background: var(--surface);
501	  border: 1.5px solid;
502	  border-radius: 18px;
503	  padding: 18px;
504	  margin-bottom: 16px;
505	  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
506	}
507
508	.form-header {
509	  display: flex;
510	  align-items: center;
511	  justify-content: space-between;
512	  margin-bottom: 14px;
513	}
514
515	.form-title {
516	  display: inline-flex;
517	  align-items: center;
518	  gap: 6px;
519	  font-size: 14px;
520	  font-weight: 800;
521	}
522
523	.form-close {
524	  width: 28px;
525	  height: 28px;
526	  border-radius: 50%;
527	  border: 1.5px solid var(--border-light);
528	  background: var(--surface-2);
529	  cursor: pointer;
530	  color: var(--text-secondary);
531	  display: flex;
532	  align-items: center;
533	  justify-content: center;
534	  flex-shrink: 0;
535	}
536
537	.form-grid {
538	  display: grid;
539	  grid-template-columns: 1fr 1fr;
540	  gap: 10px;
541	}
542
543	.form-field {
544	  display: flex;
545	  flex-direction: column;
546	  gap: 5px;
547	}
548
549	.form-field.full-span { grid-column: 1 / -1; }
550
551	.form-label {
552	  font-size: 11px;
553	  font-weight: 700;
554	  color: var(--text-secondary);
555	  text-transform: uppercase;
556	  letter-spacing: 0.4px;
557	}
558
559	.form-field select,
560	.form-field input {
561	  padding: 10px 12px;
562	  border-radius: 10px;
563	  border: 1.5px solid var(--border);
564	  font-size: 13px;
565	  width: 100%;
566	  background: var(--surface);
567	  color: var(--text-primary);
568	  transition: border-color 0.2s;
569	  outline: none;
570	  -webkit-appearance: none;
571	  appearance: none;
572	}
573
574	.form-field select:focus,
575	.form-field input:focus { border-color: var(--text-secondary); }
576
577	.type-toggle { display: flex; gap: 8px; }
578
579	.type-opt {
580	  flex: 1;
581	  display: inline-flex;
582	  align-items: center;
583	  justify-content: center;
584	  gap: 5px;
585	  padding: 10px;
586	  border-radius: 10px;
587	  border: 1.5px solid;
588	  cursor: pointer;
589	  font-size: 13px;
590	  font-weight: 600;
591	  transition: all 0.2s ease;
592	}
593
594	.form-actions {
595	  display: flex;
596	  gap: 8px;
597	  margin-top: 14px;
598	}
599
600	.save-btn {
601	  flex: 1;
602	  display: inline-flex;
603	  align-items: center;
604	  justify-content: center;
605	  gap: 6px;
606	  padding: 12px;
607	  border-radius: 12px;
608	  border: none;
609	  color: white;
610	  font-weight: 800;
611	  cursor: pointer;
612	  font-size: 14px;
613	  transition: all 0.2s ease;
614	}
615
616	.save-btn:disabled { cursor: not-allowed; opacity: 0.7; }
617
618	.cancel-btn {
619	  padding: 12px 20px;
620	  border-radius: 12px;
621	  border: 1.5px solid var(--border);
622	  background: var(--surface);
623	  cursor: pointer;
624	  font-size: 14px;
625	  font-weight: 600;
626	  color: var(--text-secondary);
627	}
628
629	/* ─── Task List ─── */
630	.task-list {
631	  display: flex;
632	  flex-direction: column;
633	  gap: 10px;
634	}
635
636	.task-card {
637	  background: var(--surface);
638	  border-radius: 16px;
639	  border: 1.5px solid var(--border);
640	  border-left: 4px solid;
641	  padding: 13px 14px;
642	  display: flex;
643	  align-items: flex-start;
644	  gap: 12px;
645	  transition: all 0.2s ease;
646	  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
647	}
648
649	.task-card:active { transform: scale(0.99); }
650	.task-card.overdue { background: var(--overdue-bg); border-color: #F09595; }
651	.task-card.done { opacity: 0.7; }
652
653	.task-icon {
654	  width: 44px;
655	  height: 44px;
656	  border-radius: 12px;
657	  display: flex;
658	  align-items: center;
659	  justify-content: center;
660	  flex-shrink: 0;
661	}
662
663	.task-icon svg { display: block; }
664
665	.task-body {
666	  flex: 1;
667	  min-width: 0;
668	}
669
670	.task-title {
671	  font-weight: 700;
672	  font-size: 14px;
673	  color: var(--text-primary);
674	  margin-bottom: 6px;
675	  line-height: 1.35;
676	  transition: color 0.2s;
677	}
678
679	.task-meta {
680	  display: flex;
681	  flex-wrap: wrap;
682	  gap: 5px;
683	  align-items: center;
684	}
685
686	.badge {
687	  display: inline-flex;
688	  align-items: center;
689	  gap: 4px;
690	  font-size: 10px;
691	  padding: 3px 8px;
692	  border-radius: 20px;
693	  font-weight: 700;
694	}
695
696	.badge-dot {
697	  width: 5px;
698	  height: 5px;
699	  border-radius: 50%;
700	  flex-shrink: 0;
701	}
702
703	.task-due {
704	  display: inline-flex;
705	  align-items: center;
706	  gap: 3px;
707	  font-size: 11px;
708	  font-weight: 500;
709	}
710
711	.task-source {
712	  display: inline-flex;
713	  align-items: center;
714	  gap: 3px;
715	  font-size: 10px;
716	  color: var(--text-muted);
717	  font-weight: 500;
718	}
719
720	.task-actions {
721	  display: flex;
722	  flex-direction: column;
723	  gap: 5px;
724	  flex-shrink: 0;
725	  align-items: flex-end;
726	}
727
728	.task-actions select {
729	  font-size: 11px;
730	  padding: 6px 7px;
731	  border-radius: 9px;
732	  border: 1.5px solid;
733	  background: var(--surface);
734	  color: var(--text-primary);
735	  cursor: pointer;
736	  outline: none;
737	  max-width: 110px;
738	  -webkit-appearance: none;
739	  appearance: none;
740	}
741
742	.remove-btn {
743	  display: flex;
744	  align-items: center;
745	  justify-content: center;
746	  width: 28px;
747	  height: 26px;
748	  border-radius: 8px;
749	  border: 1px solid var(--border-light);
750	  background: var(--surface);
751	  color: #E24B4A;
752	  cursor: pointer;
753	  transition: all 0.15s;
754	}
755
756	.remove-btn:hover {
757	  background: #fff0f0;
758	  border-color: #E24B4A;
759	}
760
761	/* ─── Empty State ─── */
762	.empty-state {
763	  text-align: center;
764	  padding: 36px 20px;
765	  border-radius: 18px;
766	  border: 2px dashed;
767	}
768
769	.empty-icon {
770	  display: flex;
771	  justify-content: center;
772	  margin-bottom: 10px;
773	  opacity: 0.6;
774	}
775
776	.empty-title {
777	  font-size: 18px;
778	  font-weight: 800;
779	  margin-bottom: 4px;
780	  color: var(--text-primary);
781	}
782
783	.empty-sub {
784	  font-size: 13px;
785	  color: var(--text-muted);
786	  margin-bottom: 16px;
787	}
788
789	.empty-add-btn {
790	  display: inline-flex;
791	  align-items: center;
792	  gap: 5px;
793	  padding: 11px 24px;
794	  border-radius: 22px;
795	  border: none;
796	  color: white;
797	  font-size: 14px;
798	  font-weight: 700;
799	  cursor: pointer;
800	  transition: all 0.2s ease;
801	}
802
803	.empty-add-btn:active { transform: scale(0.97); }
804
805	/* ─── Footer ─── */
806	.footer {
807	  display: flex;
808	  align-items: center;
809	  justify-content: center;
810	  gap: 6px;
811	  margin-top: 28px;
812	  padding: 12px;
813	  font-size: 12px;
814	  color: var(--text-muted);
815	}
816
817	.footer-dot { opacity: 0.5; }
818
819	/* ─── Responsive ─── */
820	@media (max-width: 520px) {
821	  .app { padding: 10px 10px 28px; }
822	  .header { padding: 15px 16px 14px; border-radius: 16px; }
823	  .school-name { font-size: 12px; }
824	  .logo-box { width: 44px; height: 44px; font-size: 12px; border-radius: 12px; }
825	  .kid-switcher { gap: 8px; }
826	  .kid-btn { padding: 12px 8px 10px; border-radius: 14px; }
827	  .kid-name { font-size: 14px; }
828	  .calendar-row { gap: 5px; }
829	  .day-btn { border-radius: 12px; padding: 8px 2px 6px; }
830	  .day-num { font-size: 16px; }
831	  .form-grid { grid-template-columns: 1fr; }
832	  .form-field.full-span { grid-column: 1; }
833	  .stats-row { gap: 7px; }
834	  .stat-num { font-size: 24px; }
835	  .task-card { padding: 11px 12px; gap: 10px; }
836	  .task-icon { width: 38px; height: 38px; border-radius: 10px; }
837	  .task-title { font-size: 13px; }
838	  .tab-btn { padding: 9px 12px; font-size: 12px; gap: 5px; }
839	  .add-btn { padding: 9px 14px; }
840	  .task-actions select { max-width: 95px; font-size: 10px; }
841	}
842
843	@media (max-width: 380px) {
844	  .header-date { display: none; }
845	  .school-name { font-size: 11px; }
846	}
847
[result-id: r3]

:root {
  --bg: #f0f2f7;
  --surface: #ffffff;
  --surface-2: #f5f7fa;
  --border: #eaecf0;
  --border-light: #eeeeee;
  --text-primary: #1a1a1a;
  --text-secondary: #888888;
  --text-muted: #bbbbbb;
  --overdue-bg: #fff8f8;
  --spinner-track: #e0e0e0;
  --kid-mini-bg: #e8e8e8;
}

[data-theme="dark"] {
  --bg: #0f1117;
  --surface: #1a1d27;
  --surface-2: #22263a;
  --border: #2e3347;
  --border-light: #2a2d3e;
  --text-primary: #e8eaf0;
  --text-secondary: #8b92a5;
  --text-muted: #5a6278;
  --overdue-bg: #2a1a1a;
  --spinner-track: #2e3347;
  --kid-mini-bg: #2e3347;
}

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  transition: background 0.25s ease;
}

.app {
  max-width: 860px;
  margin: 0 auto;
  padding: 14px 14px 36px;
}

/* ─── Loading Screen ─── */
.loading-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
}

.loading-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.loading-logo {
  width: 64px;
  height: 64px;
  background: linear-gradient(135deg, #1D9E75, #185FA5);
  border-radius: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: 900;
  color: white;
  letter-spacing: -0.5px;
}

.loading-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--spinner-track);
  border-top-color: #1D9E75;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loading-text {
  font-size: 14px;
  color: var(--text-secondary);
  font-weight: 500;
}

/* ─── Header ─── */
.header {
  border-radius: 20px;
  padding: 18px 20px 16px;
  color: white;
  margin-bottom: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
}

.header-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.header-logo {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo-box {
  width: 50px;
  height: 50px;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(6px);
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 900;
  letter-spacing: -0.5px;
  flex-shrink: 0;
  border: 1.5px solid rgba(255, 255, 255, 0.3);
}

.school-name {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
}

.app-subtitle {
  font-size: 12px;
  opacity: 0.85;
  margin-top: 2px;
}

.header-date-col {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}

.header-date {
  font-size: 11px;
  opacity: 0.8;
  white-space: nowrap;
}

.header-clock {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
  opacity: 0.95;
}

.header-badges {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 2px;
  justify-content: flex-end;
}

.sync-badge {
  display: flex;
  align-items: center;
  gap: 3px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 99px;
  padding: 2px 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
}

.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 20px;
  background: rgba(255, 255, 255, 0.18);
  border: none;
  border-radius: 99px;
  cursor: pointer;
  color: white;
  padding: 0;
  transition: background 0.2s;
}

.theme-toggle:hover {
  background: rgba(255, 255, 255, 0.3);
}

.header-progress {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  padding: 10px 12px;
}

.progress-label {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 600;
  opacity: 0.9;
  margin-bottom: 6px;
}

.progress-pct { font-weight: 800; }

.progress-track {
  height: 7px;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 99px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 99px;
  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  min-width: 4px;
}

/* ─── Kid Switcher ─── */
.kid-switcher {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}

.kid-btn {
  flex: 1;
  padding: 14px 10px 12px;
  border-radius: 18px;
  border: 2px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  background: var(--surface-2);
}

.kid-btn.active {
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
  transform: translateY(-1px);
}

.kid-avatar-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 6px;
  line-height: 0;
}

.kid-name {
  display: block;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -0.3px;
}

.kid-grade {
  display: block;
  font-size: 11px;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.kid-mini-progress {
  height: 4px;
  background: var(--kid-mini-bg);
  border-radius: 99px;
  overflow: hidden;
  margin-bottom: 8px;
  width: 70%;
  margin-left: auto;
  margin-right: auto;
}

.kid-mini-fill {
  height: 100%;
  border-radius: 99px;
  transition: width 0.5s ease;
  min-width: 3px;
}

.kid-badges {
  display: flex;
  justify-content: center;
  gap: 4px;
  flex-wrap: wrap;
}

/* ─── Calendar ─── */
.calendar-section { margin-bottom: 16px; }

.section-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 8px;
}

.calendar-row {
  display: flex;
  gap: 6px;
}

.day-btn {
  flex: 1;
  padding: 9px 4px 7px;
  border-radius: 14px;
  border: 2px solid;
  cursor: pointer;
  text-align: center;
  background: var(--surface);
  transition: all 0.2s ease;
  min-width: 0;
}

.day-btn.active {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  transform: translateY(-1px);
}

.day-name {
  display: block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  margin-bottom: 3px;
}

.day-num {
  display: block;
  font-size: 18px;
  font-weight: 800;
  line-height: 1;
  margin-bottom: 4px;
}

.day-count {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  padding: 2px 5px;
  border-radius: 99px;
}

.day-summary {
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--border-light);
}

.day-summary-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  margin-bottom: 6px;
}

.day-summary-tasks {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.day-task-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  padding: 3px 9px;
  border-radius: 20px;
  font-weight: 600;
}

/* ─── Stats ─── */
.stats-row {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
}

.stat-card {
  flex: 1;
  padding: 12px 8px;
  border-radius: 14px;
  text-align: center;
  background: var(--surface);
  border-top: 3px solid;
}

.stat-dot {
  display: block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin: 0 auto 4px;
}

.stat-num {
  display: block;
  font-size: 28px;
  font-weight: 800;
  line-height: 1;
  margin-bottom: 3px;
}

.stat-label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* ─── Tabs + Add ─── */
.tab-row {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 14px;
}

.tab-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  border-radius: 22px;
  border: none;
  cursor: pointer;
  font-weight: 700;
  font-size: 13px;
  transition: all 0.2s ease;
  background: var(--surface-2);
  color: var(--text-secondary);
}

.tab-count {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 99px;
  background: var(--border);
  color: var(--text-secondary);
}

.add-btn {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 10px 18px;
  border-radius: 22px;
  border: none;
  cursor: pointer;
  font-weight: 800;
  font-size: 13px;
  color: white;
  transition: all 0.2s ease;
}

.add-btn:active { transform: scale(0.96); }

/* ─── Form ─── */
.form-card {
  background: var(--surface);
  border: 1.5px solid;
  border-radius: 18px;
  padding: 18px;
  margin-bottom: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
}

.form-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.form-title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 800;
}

.form-close {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid var(--border-light);
  background: var(--surface-2);
  cursor: pointer;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.form-field.full-span { grid-column: 1 / -1; }

.form-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.form-field select,
.form-field input {
  padding: 10px 12px;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  font-size: 13px;
  width: 100%;
  background: var(--surface);
  color: var(--text-primary);
  transition: border-color 0.2s;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.form-field select:focus,
.form-field input:focus { border-color: var(--text-secondary); }

.type-toggle { display: flex; gap: 8px; }

.type-opt {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 10px;
  border-radius: 10px;
  border: 1.5px solid;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  transition: all 0.2s ease;
}

.form-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}

.save-btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 12px;
  border-radius: 12px;
  border: none;
  color: white;
  font-weight: 800;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s ease;
}

.save-btn:disabled { cursor: not-allowed; opacity: 0.7; }

.cancel-btn {
  padding: 12px 20px;
  border-radius: 12px;
  border: 1.5px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-secondary);
}

/* ─── Task List ─── */
.task-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.task-card {
  background: var(--surface);
  border-radius: 16px;
  border: 1.5px solid var(--border);
  border-left: 4px solid;
  padding: 13px 14px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  transition: all 0.2s ease;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
}

.task-card:active { transform: scale(0.99); }
.task-card.overdue { background: var(--overdue-bg); border-color: #F09595; }
.task-card.done { opacity: 0.7; }

.task-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.task-icon svg { display: block; }

.task-body {
  flex: 1;
  min-width: 0;
}

.task-title {
  font-weight: 700;
  font-size: 14px;
  color: var(--text-primary);
  margin-bottom: 6px;
  line-height: 1.35;
  transition: color 0.2s;
}

.task-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  padding: 3px 8px;
  border-radius: 20px;
  font-weight: 700;
}

.badge-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
}

.task-due {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  font-weight: 500;
}

.task-source {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 10px;
  color: var(--text-muted);
  font-weight: 500;
}

.task-actions {
  display: flex;
  flex-direction: column;
  gap: 5px;
  flex-shrink: 0;
  align-items: flex-end;
}

.task-actions select {
  font-size: 11px;
  padding: 6px 7px;
  border-radius: 9px;
  border: 1.5px solid;
  background: var(--surface);
  color: var(--text-primary);
  cursor: pointer;
  outline: none;
  max-width: 110px;
  -webkit-appearance: none;
  appearance: none;
}

.remove-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
  border-radius: 8px;
  border: 1px solid var(--border-light);
  background: var(--surface);
  color: #E24B4A;
  cursor: pointer;
  transition: all 0.15s;
}

.remove-btn:hover {
  background: #fff0f0;
  border-color: #E24B4A;
}

/* ─── Empty State ─── */
.empty-state {
  text-align: center;
  padding: 36px 20px;
  border-radius: 18px;
  border: 2px dashed;
}

.empty-icon {
  display: flex;
  justify-content: center;
  margin-bottom: 10px;
  opacity: 0.6;
}

.empty-title {
  font-size: 18px;
  font-weight: 800;
  margin-bottom: 4px;
  color: var(--text-primary);
}

.empty-sub {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 16px;
}

.empty-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 11px 24px;
  border-radius: 22px;
  border: none;
  color: white;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s ease;
}

.empty-add-btn:active { transform: scale(0.97); }

/* ─── Footer ─── */
.footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 28px;
  padding: 12px;
  font-size: 12px;
  color: var(--text-muted);
}

.footer-dot { opacity: 0.5; }

/* ─── Responsive ─── */
@media (max-width: 520px) {
  .app { padding: 10px 10px 28px; }
  .header { padding: 15px 16px 14px; border-radius: 16px; }
  .school-name { font-size: 12px; }
  .logo-box { width: 44px; height: 44px; font-size: 12px; border-radius: 12px; }
  .kid-switcher { gap: 8px; }
  .kid-btn { padding: 12px 8px 10px; border-radius: 14px; }
  .kid-name { font-size: 14px; }
  .calendar-row { gap: 5px; }
  .day-btn { border-radius: 12px; padding: 8px 2px 6px; }
  .day-num { font-size: 16px; }
  .form-grid { grid-template-columns: 1fr; }
  .form-field.full-span { grid-column: 1; }
  .stats-row { gap: 7px; }
  .stat-num { font-size: 24px; }
  .task-card { padding: 11px 12px; gap: 10px; }
  .task-icon { width: 38px; height: 38px; border-radius: 10px; }
  .task-title { font-size: 13px; }
  .tab-btn { padding: 9px 12px; font-size: 12px; gap: 5px; }
  .add-btn { padding: 9px 14px; }
  .task-actions select { max-width: 95px; font-size: 10px; }
}

@media (max-width: 380px) {
  .header-date { display: none; }
  .school-name { font-size: 11px; }
}


1	import { useState, useEffect } from "react";
2	import {
3	  Calendar,
4	  FileText,
5	  Layers,
6	  Plus,
7	  X,
8	  Check,
9	  AlertTriangle,
10	  Bell,
11	  Heart,
12	  GraduationCap,
13	  Send,
14	  Wifi,
15	  Clock,
16	  Moon,
17	  Sun,
18	} from "lucide-react";
19	import { KIDS, DAYS, STATUSES, SUBJECTS, SOURCES } from "./data/constants";
20	import { useTasks } from "./hooks/useTasks";
21	import { FIREBASE_READY } from "./lib/firebase";
22	import { KidAvatar } from "./icons/KidAvatar";
23	import { SubjectIcon } from "./icons/SubjectIcon";
24	import "./App.css";
25
26	function getWeekDates() {
27	  const today = new Date();
28	  const monday = new Date(today);
29	  monday.setDate(today.getDate() - ((today.getDay() + 6) % 7));
30	  return Array.from({ length: 5 }, (_, i) => {
31	    const d = new Date(monday);
32	    d.setDate(monday.getDate() + i);
33	    return d;
34	  });
35	}
36
37	function useLiveClock() {
38	  const [now, setNow] = useState(() => new Date());
39	  useEffect(() => {
40	    const id = setInterval(() => setNow(new Date()), 1000);
41	    return () => clearInterval(id);
42	  }, []);
43	  return now;
44	}
45
46	function SourceIcon({ source, size = 11 }) {
47	  if (source === "Telegram") return <Send size={size} style={{ flexShrink: 0 }} />;
48	  if (source === "Edunation") return <GraduationCap size={size} style={{ flexShrink: 0 }} />;
49	  return null;
50	}
51
52	const EMPTY_FORM = {
53	  subject: "",
54	  title: "",
55	  status: "new",
56	  due: "",
57	  source: "Telegram",
58	  type: "homework",
59	};
60
61	export default function App() {
62	  const [activeKid, setActiveKid] = useState("abdulla");
63	  const [activeDay, setActiveDay] = useState(() => {
64	    const d = new Date().getDay();
65	    return d >= 1 && d <= 5 ? d - 1 : 0;
66	  });
67	  const [activeTab, setActiveTab] = useState("homework");
68	  const [showForm, setShowForm] = useState(false);
69	  const [form, setForm] = useState(EMPTY_FORM);
70
71	  const [dark, setDark] = useState(() => localStorage.getItem("ascs-theme") === "dark");
72
73	  useEffect(() => {
74	    document.documentElement.setAttribute("data-theme", dark ? "dark" : "light");
75	    localStorage.setItem("ascs-theme", dark ? "dark" : "light");
76	  }, [dark]);
77
78	  const { tasks, synced, addTask, updateStatus, removeTask } = useTasks();
79	  const today = useLiveClock();
80	  const weekDates = getWeekDates();
81	  const kid = KIDS.find((k) => k.id === activeKid);
82	  const kidTasks = tasks[activeKid] || [];
83	  const filtered = kidTasks.filter((t) => t.type === activeTab);
84	  const dayTasks = kidTasks.filter(
85	    (t) => new Date(t.due + "T00:00:00").toDateString() === weekDates[activeDay]?.toDateString()
86	  );
87
88	  const stats = {
89	    new: kidTasks.filter((t) => t.status === "new").length,
90	    inprogress: kidTasks.filter((t) => t.status === "inprogress").length,
91	    completed: kidTasks.filter((t) => t.status === "completed").length,
92	  };
93
94	  const totalDone = stats.completed;
95	  const progressPct = kidTasks.length > 0 ? Math.round((totalDone / kidTasks.length) * 100) : 0;
96
97	  function handleAddTask() {
98	    if (!form.title || !form.subject || !form.due) return;
99	    addTask(activeKid, form);
100	    setForm(EMPTY_FORM);
101	    setShowForm(false);
102	    setActiveTab(form.type);
103	  }
104
105	  function openForm() {
106	    setForm({ ...EMPTY_FORM, type: activeTab });
107	    setShowForm(true);
108	    setTimeout(() => {
109	      document.querySelector(".form-card")?.scrollIntoView({ behavior: "smooth", block: "nearest" });
110	    }, 80);
111	  }
112
113	  // Loading screen while Firebase syncs
114	  if (!synced) {
115	    return (
116

117

118
ASCS

119

120
Syncing homework tracker…

121

122

123	    );
124	  }
125
126	  return (
127

128	      {/* Header */}
129	      <header
130	        className="header"
131	        style={{ background: `linear-gradient(135deg, ${kid.color} 0%, #185FA5 100%)` }}
132	      >
133

134

135
ASCS

136

137
American School of Creativity Science

138
Homework Tracker

139

140

141

142

143	              {today.toLocaleDateString("en-US", {
144	                weekday: "short",
145	                month: "short",
146	                day: "numeric",
147	                year: "numeric",
148	              })}
149

150

151	              <Clock size={11} style={{ opacity: 0.8 }} />
152
153	                {today.toLocaleTimeString("en-US", {
154	                  hour: "2-digit",
155	                  minute: "2-digit",
156	                  second: "2-digit",
157	                })}
158
159

160

161	              {FIREBASE_READY && (
162

163	                  <Wifi size={10} />
164	                  Live
165

166	              )}
167	              <button className="theme-toggle" onClick={() => setDark((d) => !d)} title="Toggle theme">
168	                {dark ? <Sun size={12} /> : <Moon size={12} />}
169	              </button>
170

171

172

173
174	        {/* Progress bar */}
175

176

177	            {kid.name}'s Overall Progress
178	            {progressPct}%
179

180

181	            <div className="progress-fill" style={{ width: `${progressPct}%` }} />
182

183

184
185
186	      {/* Kid Switcher */}
187

188	        {KIDS.map((k) => {
189	          const kTasks = tasks[k.id] || [];
190	          const kDone = kTasks.filter((t) => t.status === "completed").length;
191	          const kPct = kTasks.length > 0 ? Math.round((kDone / kTasks.length) * 100) : 0;
192	          return (
193	            <button
194	              key={k.id}
195	              className={`kid-btn ${activeKid === k.id ? "active" : ""}`}
196	              style={{
197	                borderColor: activeKid === k.id ? k.color : "transparent",
198	                background: activeKid === k.id ? k.light : undefined,
199	              }}
200	              onClick={() => setActiveKid(k.id)}
201	            >
202

203	                <KidAvatar id={k.id} size={activeKid === k.id ? 46 : 40} />
204

205	              {k.name}
206	              {k.grade}
207

208	                <div className="kid-mini-fill" style={{ width: `${kPct}%`, background: k.color }} />
209

210

211	                {STATUSES.map((s) => {
212	                  const cnt = kTasks.filter((t) => t.status === s.id).length;
213	                  return cnt > 0 ? (
214
215	                      {cnt}
216
217	                  ) : null;
218	                })}
219

220	            </button>
221	          );
222	        })}
223

224
225	      {/* Weekly Calendar */}
226

227

228	          <Calendar size={13} strokeWidth={2} />
229	          This Week
230

231

232	          {weekDates.map((d, i) => {
233	            const isToday = d.toDateString() === today.toDateString();
234	            const dayCount = kidTasks.filter(
235	              (t) => new Date(t.due + "T00:00:00").toDateString() === d.toDateString()
236	            ).length;
237	            const doneCount = kidTasks.filter(
238	              (t) =>
239	                new Date(t.due + "T00:00:00").toDateString() === d.toDateString() &&
240	                t.status === "completed"
241	            ).length;
242	            return (
243	              <button
244	                key={i}
245	                className={`day-btn ${activeDay === i ? "active" : ""} ${isToday ? "today" : ""}`}
246	                style={{
247	                  borderColor:
248	                    activeDay === i ? kid.color : isToday ? kid.color + "66" : "#e5e8f0",
249	                  background:
250	                    activeDay === i ? kid.color : isToday ? kid.light : undefined,
251	                }}
252	                onClick={() => setActiveDay(i)}
253	              >
254
258	                  {DAYS[i]}
259
260
266	                  {d.getDate()}
267
268	                {dayCount > 0 && (
269
277	                    {doneCount}/{dayCount}
278
279	                )}
280	              </button>
281	            );
282	          })}
283

284	        {dayTasks.length > 0 && (
285	          <div
286	            className="day-summary"
287	            style={{ borderLeft: `3px solid ${kid.color}` }}
288	          >
289
290	              Due{" "}
291	              {weekDates[activeDay]?.toLocaleDateString("en-US", {
292	                weekday: "short",
293	                month: "short",
294	                day: "numeric",
295	              })}
296	              :
297
298

299	              {dayTasks.map((t) => {
300	                const st = STATUSES.find((s) => s.id === t.status);
301	                return (
302
303	                    <SubjectIcon subject={t.subject} size={11} strokeWidth={2} />
304	                    {t.title.length > 28 ? t.title.slice(0, 28) + "…" : t.title}
305
306	                );
307	              })}
308

309

310	        )}
311

312
313	      {/* Stats */}
314

315	        {STATUSES.map((s) => (
316	          <div key={s.id} className="stat-card" style={{ background: s.bg, borderTop: `3px solid ${s.dot}` }}>
317
318	            {stats[s.id]}
319	            {s.label}
320

321	        ))}
322

323
324	      {/* Tabs + Add button */}
325

326	        {["homework", "project"].map((tab) => (
327	          <button
328	            key={tab}
329	            className={`tab-btn ${activeTab === tab ? "active" : ""}`}
330	            style={{
331	              background: activeTab === tab ? kid.color : undefined,
332	              color: activeTab === tab ? "white" : undefined,
333	              boxShadow: activeTab === tab ? `0 4px 14px ${kid.color}44` : "none",
334	            }}
335	            onClick={() => setActiveTab(tab)}
336	          >
337	            {tab === "homework" ? <FileText size={14} strokeWidth={2} /> : <Layers size={14} strokeWidth={2} />}
338	            {tab === "homework" ? "Homework" : "Projects"}
339
346	              {kidTasks.filter((t) => t.type === tab).length}
347
348	          </button>
349	        ))}
350	        <button
351	          className="add-btn"
352	          style={{ background: kid.color, boxShadow: `0 4px 14px ${kid.color}66` }}
353	          onClick={openForm}
354	        >
355	          <Plus size={18} strokeWidth={2.5} />
356	          Add
357	        </button>
358

359
360	      {/* Add Form */}
361	      {showForm && (
362

363

364

365	              <Plus size={15} strokeWidth={2.5} />
366	              New {form.type === "homework" ? "Homework" : "Project"} for {kid.name}
367

368	            <button className="form-close" onClick={() => setShowForm(false)}>
369	              <X size={13} />
370	            </button>
371

372

373

374	              Subject
375	              <select
376	                value={form.subject}
377	                onChange={(e) => setForm((f) => ({ ...f, subject: e.target.value }))}
378	                style={{ borderColor: form.subject ? kid.color : "#ddd" }}
379	              >
380	                <option value="">Select subject…</option>
381	                {SUBJECTS[activeKid].map((s) => (
382	                  <option key={s}>{s}</option>
383	                ))}
384	              </select>
385

386

387	              Status
388	              <select
389	                value={form.status}
390	                onChange={(e) => setForm((f) => ({ ...f, status: e.target.value }))}
391	                style={{ borderColor: kid.color }}
392	              >
393	                {STATUSES.map((s) => (
394	                  <option key={s.id} value={s.id}>{s.label}</option>
395	                ))}
396	              </select>
397

398

399	              Assignment description
400	              <input
401	                placeholder="e.g. Read chapter 3 and answer questions…"
402	                value={form.title}
403	                onChange={(e) => setForm((f) => ({ ...f, title: e.target.value }))}
404	                style={{ borderColor: form.title ? kid.color : "#ddd" }}
405	              />
406

407

408	              Due Date
409	              <input
410	                type="date"
411	                value={form.due}
412	                onChange={(e) => setForm((f) => ({ ...f, due: e.target.value }))}
413	                style={{ borderColor: form.due ? kid.color : "#ddd" }}
414	              />
415

416

417	              Source
418	              <select
419	                value={form.source}
420	                onChange={(e) => setForm((f) => ({ ...f, source: e.target.value }))}
421	                style={{ borderColor: kid.color }}
422	              >
423	                {SOURCES.map((s) => (
424	                  <option key={s}>{s}</option>
425	                ))}
426	              </select>
427

428

429	              Type
430

431	                {["homework", "project"].map((t) => (
432	                  <button
433	                    key={t}
434	                    className={`type-opt ${form.type === t ? "selected" : ""}`}
435	                    style={{
436	                      background: form.type === t ? kid.color : "transparent",
437	                      color: form.type === t ? "white" : "#666",
438	                      borderColor: form.type === t ? kid.color : "#ddd",
439	                    }}
440	                    onClick={() => setForm((f) => ({ ...f, type: t }))}
441	                    type="button"
442	                  >
443	                    {t === "homework"
444	                      ? <><FileText size={13} strokeWidth={2} /> Homework</>
445	                      : <><Layers size={13} strokeWidth={2} /> Project</>
446	                    }
447	                  </button>
448	                ))}
449

450

451

452

453	            <button
454	              className="save-btn"
455	              style={{
456	                background: form.title && form.subject && form.due ? kid.color : "#ccc",
457	                boxShadow: form.title && form.subject && form.due ? `0 4px 14px ${kid.color}55` : "none",
458	              }}
459	              onClick={handleAddTask}
460	              disabled={!form.title || !form.subject || !form.due}
461	            >
462	              <Check size={16} strokeWidth={2.5} />
463	              Save Assignment
464	            </button>
465	            <button className="cancel-btn" onClick={() => setShowForm(false)}>
466	              Cancel
467	            </button>
468

469

470	      )}
471
472	      {/* Task List */}
473

474	        {filtered.length === 0 ? (
475

479

480	              {activeTab === "homework"
481	                ? <FileText size={44} strokeWidth={1.2} />
482	                : <Layers size={44} strokeWidth={1.2} />
483	              }
484

485

486	              No {activeTab}s yet!
487

488
Tap + Add to get started

489	            <button
490	              className="empty-add-btn"
491	              style={{ background: kid.color, boxShadow: `0 4px 14px ${kid.color}55` }}
492	              onClick={openForm}
493	            >
494	              <Plus size={14} strokeWidth={2.5} />
495	              Add {activeTab === "homework" ? "Homework" : "Project"}
496	            </button>
497

498	        ) : (
499	          filtered.map((task) => {
500	            const st = STATUSES.find((s) => s.id === task.status);
501	            const dueDate = new Date(task.due + "T00:00:00");
502	            const isOverdue = dueDate < today && task.status !== "completed";
503	            const isDueToday = dueDate.toDateString() === today.toDateString();
504	            return (
505	              <div
506	                key={task.id}
507	                className={`task-card ${isOverdue ? "overdue" : ""} ${task.status === "completed" ? "done" : ""}`}
508	                style={{
509	                  borderLeft: `4px solid ${isOverdue ? "#E24B4A" : task.status === "completed" ? "#639922" : kid.color}`,
510	                }}
511	              >
512

513	                  <SubjectIcon subject={task.subject} size={20} color={kid.dark} strokeWidth={1.7} />
514

515

516

523	                    {task.title}
524

525

526
527	                      <SubjectIcon subject={task.subject} size={10} color={kid.dark} strokeWidth={2} />
528	                      {task.subject}
529
530
531
532	                      {st.label}
533
534
541	                      {isOverdue
542	                        ? <AlertTriangle size={11} strokeWidth={2} />
543	                        : isDueToday
544	                        ? <Bell size={11} strokeWidth={2} />
545	                        : <Calendar size={11} strokeWidth={2} />
546	                      }
547	                      {isOverdue ? "Overdue · " : isDueToday ? "Today · " : ""}
548	                      {dueDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })}
549
550
551	                      <SourceIcon source={task.source} size={10} />
552	                      {task.source}
553
554

555

556

557	                  <select
558	                    value={task.status}
559	                    style={{ borderColor: kid.color + "88", color: kid.dark }}
560	                    onChange={(e) => updateStatus(activeKid, task.id, e.target.value)}
561	                  >
562	                    {STATUSES.map((s) => (
563	                      <option key={s.id} value={s.id}>{s.label}</option>
564	                    ))}
565	                  </select>
566	                  <button className="remove-btn" onClick={() => removeTask(activeKid, task.id)} title="Remove">
567	                    <X size={11} strokeWidth={2.5} />
568	                  </button>
569

570

571	            );
572	          })
573	        )}
574

575
576
577	        ASCS Homework Tracker
578	        •
579	        <Heart size={12} fill="currentColor" style={{ color: "#F87171" }} />
580	        for Abdulla & Salama
581
582

583	  );
584	}
585
[result-id: r4]

import { useState, useEffect } from "react";
import {
  Calendar,
  FileText,
  Layers,
  Plus,
  X,
  Check,
  AlertTriangle,
  Bell,
  Heart,
  GraduationCap,
  Send,
  Wifi,
  Clock,
  Moon,
  Sun,
} from "lucide-react";
import { KIDS, DAYS, STATUSES, SUBJECTS, SOURCES } from "./data/constants";
import { useTasks } from "./hooks/useTasks";
import { FIREBASE_READY } from "./lib/firebase";
import { KidAvatar } from "./icons/KidAvatar";
import { SubjectIcon } from "./icons/SubjectIcon";
import "./App.css";

function getWeekDates() {
  const today = new Date();
  const monday = new Date(today);
  monday.setDate(today.getDate() - ((today.getDay() + 6) % 7));
  return Array.from({ length: 5 }, (_, i) => {
    const d = new Date(monday);
    d.setDate(monday.getDate() + i);
    return d;
  });
}

function useLiveClock() {
  const [now, setNow] = useState(() => new Date());
  useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  return now;
}

function SourceIcon({ source, size = 11 }) {
  if (source === "Telegram") return <Send size={size} style={{ flexShrink: 0 }} />;
  if (source === "Edunation") return <GraduationCap size={size} style={{ flexShrink: 0 }} />;
  return null;
}

const EMPTY_FORM = {
  subject: "",
  title: "",
  status: "new",
  due: "",
  source: "Telegram",
  type: "homework",
};

export default function App() {
  const [activeKid, setActiveKid] = useState("abdulla");
  const [activeDay, setActiveDay] = useState(() => {
    const d = new Date().getDay();
    return d >= 1 && d <= 5 ? d - 1 : 0;
  });
  const [activeTab, setActiveTab] = useState("homework");
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(EMPTY_FORM);

  const [dark, setDark] = useState(() => localStorage.getItem("ascs-theme") === "dark");

  useEffect(() => {
    document.documentElement.setAttribute("data-theme", dark ? "dark" : "light");
    localStorage.setItem("ascs-theme", dark ? "dark" : "light");
  }, [dark]);

  const { tasks, synced, addTask, updateStatus, removeTask } = useTasks();
  const today = useLiveClock();
  const weekDates = getWeekDates();
  const kid = KIDS.find((k) => k.id === activeKid);
  const kidTasks = tasks[activeKid] || [];
  const filtered = kidTasks.filter((t) => t.type === activeTab);
  const dayTasks = kidTasks.filter(
    (t) => new Date(t.due + "T00:00:00").toDateString() === weekDates[activeDay]?.toDateString()
  );

  const stats = {
    new: kidTasks.filter((t) => t.status === "new").length,
    inprogress: kidTasks.filter((t) => t.status === "inprogress").length,
    completed: kidTasks.filter((t) => t.status === "completed").length,
  };

  const totalDone = stats.completed;
  const progressPct = kidTasks.length > 0 ? Math.round((totalDone / kidTasks.length) * 100) : 0;

  function handleAddTask() {
    if (!form.title || !form.subject || !form.due) return;
    addTask(activeKid, form);
    setForm(EMPTY_FORM);
    setShowForm(false);
    setActiveTab(form.type);
  }

  function openForm() {
    setForm({ ...EMPTY_FORM, type: activeTab });
    setShowForm(true);
    setTimeout(() => {
      document.querySelector(".form-card")?.scrollIntoView({ behavior: "smooth", block: "nearest" });
    }, 80);
  }

  // Loading screen while Firebase syncs
  if (!synced) {
    return (

ASCS

Syncing homework tracker…

    );
  }

  return (

      {/* Header */}
      <header
        className="header"
        style={{ background: `linear-gradient(135deg, ${kid.color} 0%, #185FA5 100%)` }}
      >

ASCS

American School of Creativity Science

Homework Tracker

              {today.toLocaleDateString("en-US", {
                weekday: "short",
                month: "short",
                day: "numeric",
                year: "numeric",
              })}

              <Clock size={11} style={{ opacity: 0.8 }} />

                {today.toLocaleTimeString("en-US", {
                  hour: "2-digit",
                  minute: "2-digit",
                  second: "2-digit",
                })}

              {FIREBASE_READY && (

                  <Wifi size={10} />
                  Live

              )}
              <button className="theme-toggle" onClick={() => setDark((d) => !d)} title="Toggle theme">
                {dark ? <Sun size={12} /> : <Moon size={12} />}
              </button>

        {/* Progress bar */}

            {kid.name}'s Overall Progress
            {progressPct}%

            <div className="progress-fill" style={{ width: `${progressPct}%` }} />

      {/* Kid Switcher */}

        {KIDS.map((k) => {
          const kTasks = tasks[k.id] || [];
          const kDone = kTasks.filter((t) => t.status === "completed").length;
          const kPct = kTasks.length > 0 ? Math.round((kDone / kTasks.length) * 100) : 0;
          return (
            <button
              key={k.id}
              className={`kid-btn ${activeKid === k.id ? "active" : ""}`}
              style={{
                borderColor: activeKid === k.id ? k.color : "transparent",
                background: activeKid === k.id ? k.light : undefined,
              }}
              onClick={() => setActiveKid(k.id)}
            >

                <KidAvatar id={k.id} size={activeKid === k.id ? 46 : 40} />

              {k.name}
              {k.grade}

                <div className="kid-mini-fill" style={{ width: `${kPct}%`, background: k.color }} />

                {STATUSES.map((s) => {
                  const cnt = kTasks.filter((t) => t.status === s.id).length;
                  return cnt > 0 ? (

                      {cnt}

                  ) : null;
                })}

            </button>
          );
        })}

      {/* Weekly Calendar */}

          <Calendar size={13} strokeWidth={2} />
          This Week

          {weekDates.map((d, i) => {
            const isToday = d.toDateString() === today.toDateString();
            const dayCount = kidTasks.filter(
              (t) => new Date(t.due + "T00:00:00").toDateString() === d.toDateString()
            ).length;
            const doneCount = kidTasks.filter(
              (t) =>
                new Date(t.due + "T00:00:00").toDateString() === d.toDateString() &&
                t.status === "completed"
            ).length;
            return (
              <button
                key={i}
                className={`day-btn ${activeDay === i ? "active" : ""} ${isToday ? "today" : ""}`}
                style={{
                  borderColor:
                    activeDay === i ? kid.color : isToday ? kid.color + "66" : "#e5e8f0",
                  background:
                    activeDay === i ? kid.color : isToday ? kid.light : undefined,
                }}
                onClick={() => setActiveDay(i)}
              >

                  {DAYS[i]}

                  {d.getDate()}

                {dayCount > 0 && (

                    {doneCount}/{dayCount}

                )}
              </button>
            );
          })}

        {dayTasks.length > 0 && (
          <div
            className="day-summary"
            style={{ borderLeft: `3px solid ${kid.color}` }}
          >

              Due{" "}
              {weekDates[activeDay]?.toLocaleDateString("en-US", {
                weekday: "short",
                month: "short",
                day: "numeric",
              })}
              :

              {dayTasks.map((t) => {
                const st = STATUSES.find((s) => s.id === t.status);
                return (

                    <SubjectIcon subject={t.subject} size={11} strokeWidth={2} />
                    {t.title.length > 28 ? t.title.slice(0, 28) + "…" : t.title}

                );
              })}

        )}

      {/* Stats */}

        {STATUSES.map((s) => (
          <div key={s.id} className="stat-card" style={{ background: s.bg, borderTop: `3px solid ${s.dot}` }}>

            {stats[s.id]}
            {s.label}

        ))}

      {/* Tabs + Add button */}

        {["homework", "project"].map((tab) => (
          <button
            key={tab}
            className={`tab-btn ${activeTab === tab ? "active" : ""}`}
            style={{
              background: activeTab === tab ? kid.color : undefined,
              color: activeTab === tab ? "white" : undefined,
              boxShadow: activeTab === tab ? `0 4px 14px ${kid.color}44` : "none",
            }}
            onClick={() => setActiveTab(tab)}
          >
            {tab === "homework" ? <FileText size={14} strokeWidth={2} /> : <Layers size={14} strokeWidth={2} />}
            {tab === "homework" ? "Homework" : "Projects"}

              {kidTasks.filter((t) => t.type === tab).length}

          </button>
        ))}
        <button
          className="add-btn"
          style={{ background: kid.color, boxShadow: `0 4px 14px ${kid.color}66` }}
          onClick={openForm}
        >
          <Plus size={18} strokeWidth={2.5} />
          Add
        </button>

      {/* Add Form */}
      {showForm && (

              <Plus size={15} strokeWidth={2.5} />
              New {form.type === "homework" ? "Homework" : "Project"} for {kid.name}

            <button className="form-close" onClick={() => setShowForm(false)}>
              <X size={13} />
            </button>

              Subject
              <select
                value={form.subject}
                onChange={(e) => setForm((f) => ({ ...f, subject: e.target.value }))}
                style={{ borderColor: form.subject ? kid.color : "#ddd" }}
              >
                <option value="">Select subject…</option>
                {SUBJECTS[activeKid].map((s) => (
                  <option key={s}>{s}</option>
                ))}
              </select>

              Status
              <select
                value={form.status}
                onChange={(e) => setForm((f) => ({ ...f, status: e.target.value }))}
                style={{ borderColor: kid.color }}
              >
                {STATUSES.map((s) => (
                  <option key={s.id} value={s.id}>{s.label}</option>
                ))}
              </select>

              Assignment description
              <input
                placeholder="e.g. Read chapter 3 and answer questions…"
                value={form.title}
                onChange={(e) => setForm((f) => ({ ...f, title: e.target.value }))}
                style={{ borderColor: form.title ? kid.color : "#ddd" }}
              />

              Due Date
              <input
                type="date"
                value={form.due}
                onChange={(e) => setForm((f) => ({ ...f, due: e.target.value }))}
                style={{ borderColor: form.due ? kid.color : "#ddd" }}
              />

              Source
              <select
                value={form.source}
                onChange={(e) => setForm((f) => ({ ...f, source: e.target.value }))}
                style={{ borderColor: kid.color }}
              >
                {SOURCES.map((s) => (
                  <option key={s}>{s}</option>
                ))}
              </select>

              Type

                {["homework", "project"].map((t) => (
                  <button
                    key={t}
                    className={`type-opt ${form.type === t ? "selected" : ""}`}
                    style={{
                      background: form.type === t ? kid.color : "transparent",
                      color: form.type === t ? "white" : "#666",
                      borderColor: form.type === t ? kid.color : "#ddd",
                    }}
                    onClick={() => setForm((f) => ({ ...f, type: t }))}
                    type="button"
                  >
                    {t === "homework"
                      ? <><FileText size={13} strokeWidth={2} /> Homework</>
                      : <><Layers size={13} strokeWidth={2} /> Project</>
                    }
                  </button>
                ))}

            <button
              className="save-btn"
              style={{
                background: form.title && form.subject && form.due ? kid.color : "#ccc",
                boxShadow: form.title && form.subject && form.due ? `0 4px 14px ${kid.color}55` : "none",
              }}
              onClick={handleAddTask}
              disabled={!form.title || !form.subject || !form.due}
            >
              <Check size={16} strokeWidth={2.5} />
              Save Assignment
            </button>
            <button className="cancel-btn" onClick={() => setShowForm(false)}>
              Cancel
            </button>

      )}

      {/* Task List */}

        {filtered.length === 0 ? (

              {activeTab === "homework"
                ? <FileText size={44} strokeWidth={1.2} />
                : <Layers size={44} strokeWidth={1.2} />
              }

              No {activeTab}s yet!

Tap + Add to get started

            <button
              className="empty-add-btn"
              style={{ background: kid.color, boxShadow: `0 4px 14px ${kid.color}55` }}
              onClick={openForm}
            >
              <Plus size={14} strokeWidth={2.5} />
              Add {activeTab === "homework" ? "Homework" : "Project"}
            </button>

        ) : (
          filtered.map((task) => {
            const st = STATUSES.find((s) => s.id === task.status);
            const dueDate = new Date(task.due + "T00:00:00");
            const isOverdue = dueDate < today && task.status !== "completed";
            const isDueToday = dueDate.toDateString() === today.toDateString();
            return (
              <div
                key={task.id}
                className={`task-card ${isOverdue ? "overdue" : ""} ${task.status === "completed" ? "done" : ""}`}
                style={{
                  borderLeft: `4px solid ${isOverdue ? "#E24B4A" : task.status === "completed" ? "#639922" : kid.color}`,
                }}
              >

                  <SubjectIcon subject={task.subject} size={20} color={kid.dark} strokeWidth={1.7} />

                    {task.title}

                      <SubjectIcon subject={task.subject} size={10} color={kid.dark} strokeWidth={2} />
                      {task.subject}

                      {st.label}

                      {isOverdue
                        ? <AlertTriangle size={11} strokeWidth={2} />
                        : isDueToday
                        ? <Bell size={11} strokeWidth={2} />
                        : <Calendar size={11} strokeWidth={2} />
                      }
                      {isOverdue ? "Overdue · " : isDueToday ? "Today · " : ""}
                      {dueDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })}

                      <SourceIcon source={task.source} size={10} />
                      {task.source}

                  <select
                    value={task.status}
                    style={{ borderColor: kid.color + "88", color: kid.dark }}
                    onChange={(e) => updateStatus(activeKid, task.id, e.target.value)}
                  >
                    {STATUSES.map((s) => (
                      <option key={s.id} value={s.id}>{s.label}</option>
                    ))}
                  </select>
                  <button className="remove-btn" onClick={() => removeTask(activeKid, task.id)} title="Remove">
                    <X size={11} strokeWidth={2.5} />
                  </button>

            );
          })
        )}

        ASCS Homework Tracker
        •
        <Heart size={12} fill="currentColor" style={{ color: "#F87171" }} />
        for Abdulla & Salama

  );
}


1	<!DOCTYPE html>
2
3
4	    <meta charset="UTF-8" />
5	    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6	    <title>ASCS Homework Tracker</title>
7	    <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>" />
8
9
10

11
12
13
14
[result-id: r5]

<!DOCTYPE html>

    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ASCS Homework Tracker</title>
    <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>" />


Now I have a full picture of the app. Let me implement comprehensive iPhone improvements.


Edit

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ASCS Homework Tracker</title>
    <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="default" />
    <meta name="apple-mobile-web-app-title" content="ASCS Tracker" />
    <meta name="theme-color" content="#1D9E75" />
    <title>ASCS Homework Tracker</title>
    <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>" />


The file /Users/khalidbinkalban/ascs-homework-tracker/index.html has been updated successfully.

    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="default" />
    <meta name="apple-mobile-web-app-title" content="ASCS Tracker" />
    <meta name="theme-color" content="#1D9E75" />
    <title>ASCS Homework Tracker</title>
    <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>" />

<!DOCTYPE html>

    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ASCS Homework Tracker</title>
    <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>" />

-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

+    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />

+    <meta name="apple-mobile-web-app-capable" content="yes" />

+    <meta name="apple-mobile-web-app-status-bar-style" content="default" />

+    <meta name="apple-mobile-web-app-title" content="ASCS Tracker" />

+    <meta name="theme-color" content="#1D9E75" />


Now enhance the CSS with all iPhone improvements:


@media (max-width: 380px) {
  .header-date { display: none; }
  .school-name { font-size: 11px; }
}

@media (max-width: 380px) {
  .header-date { display: none; }
  .school-name { font-size: 11px; }
}

/* ─── iPhone / Mobile UX Enhancements ─── */

/* Safe area: push content below notch / Dynamic Island */
body {
  padding-top: env(safe-area-inset-top, 0px);
}

/* Home indicator bottom padding */
.app {
  padding-bottom: calc(36px + env(safe-area-inset-bottom, 0px));
}

/* Eliminate 300ms tap delay on all interactive elements */
button, select, input, a {
  touch-action: manipulation;
}

@media (max-width: 520px) {
  /* Respect safe area + home indicator */
  .app {
    padding: 10px 12px calc(32px + env(safe-area-inset-bottom, 0px));
  }

  /* ── Sticky tab row: glass effect so content scrolls under ── */
  .tab-row {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--bg);
    margin: 0 -12px 14px;
    padding: 8px 12px;
    box-shadow: 0 1px 0 var(--border), 0 4px 20px rgba(0, 0, 0, 0.06);
    transition: box-shadow 0.2s;
  }

  /* Equal-width tab buttons fill available space */
  .tab-btn {
    flex: 1;
    justify-content: center;
  }

  /* ── Prevent iOS auto-zoom on input focus (must be ≥ 16px) ── */
  .form-field select,
  .form-field input {
    font-size: 16px;
    padding: 12px 14px;
    border-radius: 12px;
  }

  /* ── Task card: CSS grid so actions move to a full-width bottom row ── */
  .task-card {
    display: grid;
    grid-template-columns: 38px 1fr;
    column-gap: 10px;
    row-gap: 0;
    align-items: start;
    padding: 12px;
  }

  .task-icon {
    grid-column: 1;
    grid-row: 1;
    align-self: start;
  }

  .task-body {
    grid-column: 2;
    grid-row: 1;
  }

  /* Actions row: full-width, separated by a hairline */
  .task-actions {
    grid-column: 1 / 3;
    grid-row: 2;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border-light);
  }

  .task-actions select {
    flex: 1;
    max-width: none;
    font-size: 16px;
    height: 40px;
    padding: 0 10px;
    border-radius: 10px;
  }

  /* Easier to tap remove button */
  .remove-btn {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    flex-shrink: 0;
  }

  /* Bigger theme toggle tap target */
  .theme-toggle {
    width: 38px;
    height: 32px;
  }

  /* Hide live clock — saves header height on small screens */
  .header-clock {
    display: none;
  }

  /* Taller day buttons for easier tapping */
  .day-btn {
    padding: 10px 3px 8px;
  }

  /* Kid buttons: ensure minimum comfortable tap height */
  .kid-btn {
    min-height: 130px;
  }
}

@media (max-width: 390px) {
  /* iPhone SE / iPhone standard width */
  .tab-btn span:not(.tab-count) {
    display: none; /* show only icon + count on very small screens */
  }

  .tab-btn {
    gap: 4px;
    padding: 9px 10px;
  }

  .school-name {
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}