Build and Push Docker Image / build-and-push (push) Successful in 35s
The editor div was inside #tab-docs (.tab-panel) whose ancestor chain could trap position:fixed. Moving it to a sibling of <section> so the full-screen overlay covers the entire viewport unconditionally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
372 lines
18 KiB
HTML
372 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Homeschool</title>
|
|
<link rel="stylesheet" href="styles.css">
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Background decorations -->
|
|
<div class="page-confetti" aria-hidden="true">
|
|
<span style="left:4%;top:12%;animation-duration:4.2s;animation-delay:0s">⭐</span>
|
|
<span style="left:89%;top:7%;animation-duration:5.1s;animation-delay:1.3s">📚</span>
|
|
<span style="left:13%;top:78%;animation-duration:3.8s;animation-delay:2.2s">✏️</span>
|
|
<span style="left:80%;top:72%;animation-duration:4.7s;animation-delay:0.6s">🌈</span>
|
|
<span style="left:47%;top:4%;animation-duration:5.5s;animation-delay:1.9s">🎨</span>
|
|
<span style="left:93%;top:44%;animation-duration:3.5s;animation-delay:3.1s">⭐</span>
|
|
<span style="left:2%;top:52%;animation-duration:4.9s;animation-delay:0.3s">🌟</span>
|
|
<span style="left:60%;top:90%;animation-duration:4.4s;animation-delay:2.7s">📝</span>
|
|
<span style="left:38%;top:8%;animation-duration:4.6s;animation-delay:0.9s">✂️</span>
|
|
<span style="left:6%;top:30%;animation-duration:5.3s;animation-delay:1.6s">📖</span>
|
|
<span style="left:85%;top:33%;animation-duration:4.0s;animation-delay:2.4s">🏆</span>
|
|
<span style="left:71%;top:18%;animation-duration:5.8s;animation-delay:0.4s">🖍️</span>
|
|
<span style="left:22%;top:60%;animation-duration:3.9s;animation-delay:3.3s">📐</span>
|
|
<span style="left:50%;top:95%;animation-duration:4.8s;animation-delay:1.1s">💡</span>
|
|
<span style="left:63%;top:63%;animation-duration:5.2s;animation-delay:2.0s">🎒</span>
|
|
<span style="left:30%;top:88%;animation-duration:4.3s;animation-delay:0.7s">🔬</span>
|
|
<span style="left:91%;top:82%;animation-duration:3.6s;animation-delay:1.8s">📏</span>
|
|
<span style="left:8%;top:90%;animation-duration:5.0s;animation-delay:2.9s">🌍</span>
|
|
<span style="left:77%;top:50%;animation-duration:4.5s;animation-delay:0.2s">🔔</span>
|
|
<span style="left:42%;top:75%;animation-duration:5.6s;animation-delay:3.5s">🖌️</span>
|
|
</div>
|
|
|
|
<!-- Kid picker -->
|
|
<section id="view-home" class="view">
|
|
<h1 class="app-title" id="school-name-title">🎓 Homeschool</h1>
|
|
<p class="subtitle">Who's learning today?</p>
|
|
<div id="kid-cards" class="kid-cards"></div>
|
|
<p id="no-kids" class="hint" hidden>No kids yet — a parent needs to add them.</p>
|
|
<a class="parent-dash-card" href="admin.html">🔐 Parent dashboard</a>
|
|
<img id="school-logo" src="" alt="School logo" hidden>
|
|
</section>
|
|
|
|
<!-- Kid home: Today's work + nav -->
|
|
<section id="view-kid" class="view" hidden>
|
|
<div class="kid-hero">
|
|
<div class="kid-topbar">
|
|
<button class="back-btn" data-nav="home">← Switch</button>
|
|
<div class="kid-topbar-actions">
|
|
<button id="icon-picker-btn" class="theme-picker-btn" aria-label="Change my animal">🐾</button>
|
|
<button id="theme-picker-btn" class="theme-picker-btn" aria-label="Pick my color">🎨</button>
|
|
<button id="bg-picker-btn" class="theme-picker-btn" aria-label="Pick my background">🖼️</button>
|
|
</div>
|
|
</div>
|
|
<h1 id="kid-greeting"></h1>
|
|
</div>
|
|
<div id="theme-dots" class="theme-dots" hidden>
|
|
<button class="theme-dot theme-blue" data-theme="blue" title="Blue"></button>
|
|
<button class="theme-dot theme-green" data-theme="green" title="Green"></button>
|
|
<button class="theme-dot theme-purple" data-theme="purple" title="Purple"></button>
|
|
<button class="theme-dot theme-orange" data-theme="orange" title="Orange"></button>
|
|
<button class="theme-dot theme-pink" data-theme="pink" title="Pink"></button>
|
|
<button class="theme-dot theme-red" data-theme="red" title="Red"></button>
|
|
<button class="theme-dot theme-teal" data-theme="teal" title="Teal"></button>
|
|
<button class="theme-dot theme-yellow" data-theme="yellow" title="Yellow"></button>
|
|
<button class="theme-dot theme-indigo" data-theme="indigo" title="Indigo"></button>
|
|
</div>
|
|
<div id="icon-grid" class="icon-grid" hidden></div>
|
|
<div id="bg-pattern-panel" class="bg-pattern-panel" hidden>
|
|
<button class="bg-pattern-btn active" data-pattern="none" title="Plain"></button>
|
|
<button class="bg-pattern-btn" data-pattern="dots" title="Dots"></button>
|
|
<button class="bg-pattern-btn" data-pattern="stripes" title="Stripes"></button>
|
|
<button class="bg-pattern-btn" data-pattern="grid" title="Grid"></button>
|
|
<button class="bg-pattern-btn" data-pattern="stars" title="Stars"></button>
|
|
<button class="bg-pattern-btn" data-pattern="bubbles" title="Bubbles"></button>
|
|
</div>
|
|
|
|
<div class="kid-nav">
|
|
<button class="nav-pill active" data-tab="today"><span class="np-icon">📋</span><span class="np-label">Today</span></button>
|
|
<button class="nav-pill" data-tab="courses"><span class="np-icon">📚</span><span class="np-label">Courses</span></button>
|
|
<button class="nav-pill" data-tab="spelling"><span class="np-icon">✏️</span><span class="np-label">Spelling</span></button>
|
|
<button class="nav-pill" data-tab="inbox"><span class="np-icon">📬</span><span class="np-label">Inbox<span id="inbox-badge" class="feedback-badge" hidden></span></span></button>
|
|
<button class="nav-pill" data-tab="docs"><span class="np-icon">📝</span><span class="np-label">Docs</span></button>
|
|
</div>
|
|
|
|
<div id="tab-today" class="tab-panel">
|
|
<div id="today-list" class="today-list"></div>
|
|
<p id="today-empty" class="hint" hidden>Nothing scheduled for today — check My Courses for anything else to work on!</p>
|
|
</div>
|
|
|
|
<div id="tab-courses" class="tab-panel" hidden>
|
|
<div id="course-cards" class="course-cards"></div>
|
|
<p id="courses-empty" class="hint" hidden>Not enrolled in any courses yet.</p>
|
|
</div>
|
|
|
|
<div id="tab-spelling" class="tab-panel" hidden>
|
|
<div id="kid-week" class="week-card"></div>
|
|
<div class="big-actions">
|
|
<button id="btn-practice" class="big-btn practice">✏️ Practice</button>
|
|
<button id="btn-test" class="big-btn test">⭐ Friday Test</button>
|
|
<button id="btn-print-list" class="big-btn print-list">🖨 Print my words</button>
|
|
</div>
|
|
<div id="kid-test-history"></div>
|
|
</div>
|
|
|
|
<div id="tab-inbox" class="tab-panel" hidden>
|
|
<div class="inbox-subtabs">
|
|
<button class="inbox-subtab active" data-sub="new">📬 New<span id="inbox-new-badge" class="feedback-badge" hidden></span></button>
|
|
<button class="inbox-subtab" data-sub="graded">📂 Graded</button>
|
|
</div>
|
|
<div id="inbox-sub-new">
|
|
<div id="inbox-list"></div>
|
|
<p id="inbox-empty" class="hint" hidden>No new grades — check back after your parent reviews your work!</p>
|
|
</div>
|
|
<div id="inbox-sub-graded" hidden>
|
|
<div id="graded-list"></div>
|
|
<p id="graded-empty" class="hint" hidden>No graded items yet.</p>
|
|
</div>
|
|
|
|
<div class="msg-thread-wrap">
|
|
<h2 class="msg-thread-title">💬 Messages</h2>
|
|
<div id="msg-thread" class="msg-thread"></div>
|
|
<form id="msg-compose" class="msg-compose">
|
|
<textarea id="msg-input" class="msg-input" placeholder="Write a message to your parent…" rows="2"></textarea>
|
|
<button type="submit" class="msg-send-btn">Send ➤</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="tab-docs" class="tab-panel" hidden>
|
|
<div id="docs-list-view">
|
|
<div class="docs-toolbar">
|
|
<button id="btn-new-doc" class="docs-new-btn">+ New Document</button>
|
|
</div>
|
|
<form id="docs-new-form" class="docs-new-form" hidden>
|
|
<input id="docs-new-title" class="docs-new-input" type="text" placeholder="Document title…" maxlength="120" autocomplete="off">
|
|
<button type="submit" class="docs-new-btn">Create</button>
|
|
<button type="button" id="btn-docs-new-cancel" class="docs-cancel-btn">Cancel</button>
|
|
</form>
|
|
<div id="docs-list"></div>
|
|
<p id="docs-empty" class="hint" hidden>No documents yet — tap + New Document to start writing!</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Docs full-screen editor overlay (outside section so fixed positioning is never trapped) -->
|
|
<div id="docs-editor-view" hidden>
|
|
<div class="docs-editor-toolbar">
|
|
<button id="btn-docs-back" class="docs-back-btn">← Back</button>
|
|
<span id="docs-editor-title" class="docs-editor-title-text"></span>
|
|
<button id="btn-docs-submit" class="docs-submit-btn">Submit to Parent ✓</button>
|
|
</div>
|
|
<div id="docs-editor-frame"></div>
|
|
</div>
|
|
|
|
<!-- All-done celebration overlay -->
|
|
<div id="celebration-overlay" hidden>
|
|
<div id="celebration-content">
|
|
<div class="celebration-emoji">🎉</div>
|
|
<h2>All done for today!</h2>
|
|
<div id="streak-display"></div>
|
|
<button id="celebration-close" class="check-btn">High five! ✋</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Birthday celebration overlay -->
|
|
<div id="birthday-overlay" hidden>
|
|
<div id="birthday-content">
|
|
<div class="birthday-balloons" aria-hidden="true">🎈🎈🎈</div>
|
|
<div class="birthday-cake">🎂</div>
|
|
<h2 id="birthday-heading">Happy Birthday!</h2>
|
|
<p id="birthday-message" class="birthday-message"></p>
|
|
<button id="birthday-close" class="check-btn">Thanks! 🎉</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Course detail: units + items -->
|
|
<section id="view-course" class="view" hidden>
|
|
<button class="back-btn" data-back="course">← Back</button>
|
|
<h1 id="course-title"></h1>
|
|
<div id="course-units"></div>
|
|
</section>
|
|
|
|
<!-- Lesson viewer -->
|
|
<section id="view-lesson" class="view" hidden>
|
|
<button class="back-btn" data-back="lesson">← Back</button>
|
|
<div class="item-card">
|
|
<p class="item-kicker" id="lesson-kicker"></p>
|
|
<h1 id="lesson-title"></h1>
|
|
<button id="lesson-print-btn" class="secondary small" style="float:right;margin-bottom:.5rem">🖨 Print</button>
|
|
<div id="lesson-body" class="lesson-body"></div>
|
|
<button id="lesson-done-btn" class="check-btn">Done reading ✓</button>
|
|
<div id="lesson-next-actions" class="next-actions" hidden></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Assignment viewer -->
|
|
<section id="view-assignment" class="view" hidden>
|
|
<button class="back-btn" data-back="assignment">← Back</button>
|
|
<div class="item-card">
|
|
<p class="item-kicker" id="assignment-kicker"></p>
|
|
<h1 id="assignment-title"></h1>
|
|
<button id="assignment-print-btn" class="secondary small" style="float:right;margin-bottom:.5rem">🖨 Print</button>
|
|
<p id="assignment-points" class="points-label"></p>
|
|
<div id="assignment-body" class="lesson-body"></div>
|
|
<div id="assignment-evidence-section" hidden>
|
|
<details id="assignment-evidence-details" class="evidence-form">
|
|
<summary>📎 Add evidence (photo or notes)</summary>
|
|
<div class="evidence-inner">
|
|
<textarea id="assignment-evidence-notes" placeholder="Notes about your work…" rows="3"></textarea>
|
|
<div class="evidence-photo-row">
|
|
<button type="button" id="assignment-photo-btn" class="secondary small">📷 Add photo</button>
|
|
<input type="file" id="assignment-photo-input" accept="image/*" capture="environment" hidden>
|
|
<span id="assignment-photo-status" class="hint"></span>
|
|
</div>
|
|
<label class="checkbox-label evidence-note-label">
|
|
<select id="assignment-student-note">
|
|
<option value="">I felt good about this</option>
|
|
<option value="needs_help">🙋 I need help with this</option>
|
|
<option value="not_sure">🤔 I did it but I'm not sure</option>
|
|
</select>
|
|
</label>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
<button id="assignment-done-btn" class="check-btn">Mark as done ✓</button>
|
|
<div id="assignment-status" class="status-banner" hidden></div>
|
|
<div id="assignment-comment" class="parent-comment" hidden></div>
|
|
<div id="assignment-next-actions" class="next-actions" hidden></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Quiz -->
|
|
<section id="view-quiz" class="view" hidden>
|
|
<button class="back-btn" data-back="quiz">← Back</button>
|
|
<div class="item-card">
|
|
<p class="item-kicker" id="quiz-kicker"></p>
|
|
<h1 id="quiz-title"></h1>
|
|
<p id="quiz-instructions" class="quiz-instructions" hidden></p>
|
|
<form id="quiz-form"></form>
|
|
<div id="quiz-result" class="status-banner" hidden></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Flashcards -->
|
|
<section id="view-flashcards" class="view" hidden>
|
|
<button class="back-btn" data-back="flashcards">← Stop</button>
|
|
<p id="flash-progress" class="progress-label"></p>
|
|
<div class="progress-track"><div id="flash-bar" class="progress-fill"></div></div>
|
|
|
|
<div id="flash-card" class="word-card flip-card">
|
|
<p class="prompt" id="flash-deck-name"></p>
|
|
<div class="flash-face" id="flash-front"></div>
|
|
<div class="flash-face" id="flash-back" hidden></div>
|
|
<button id="flash-reveal" class="check-btn">Show answer</button>
|
|
<div id="flash-grade-buttons" class="flash-grade-row" hidden>
|
|
<button id="flash-again" class="grade-btn again">🔁 Study more</button>
|
|
<button id="flash-got-it" class="grade-btn got-it">✅ Got it!</button>
|
|
</div>
|
|
</div>
|
|
<div id="flash-done" class="done-card" hidden></div>
|
|
</section>
|
|
|
|
<!-- Word list preview (shown before practice starts) -->
|
|
<section id="view-word-preview" class="view" hidden>
|
|
<button class="back-btn" data-back="word-preview">← Back</button>
|
|
<div class="word-card">
|
|
<h2 id="word-preview-title" class="preview-title"></h2>
|
|
<p class="prompt">Here are your spelling words:</p>
|
|
<ol id="word-preview-list" class="word-preview-list"></ol>
|
|
<button id="word-preview-start" class="check-btn">Ready! Start Practice →</button>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Practice (spelling) -->
|
|
<section id="view-practice" class="view" hidden>
|
|
<button class="back-btn" data-back="practice">← Back</button>
|
|
<p id="practice-progress" class="progress-label"></p>
|
|
<div class="progress-track"><div id="practice-bar" class="progress-fill"></div></div>
|
|
|
|
<div id="practice-card" class="word-card">
|
|
<button id="btn-speak" class="speak-btn" title="Hear the word again">🔊 Say it again</button>
|
|
<p id="practice-prompt" class="prompt">Listen, then type the word:</p>
|
|
<div id="feedback" class="feedback"></div>
|
|
<form id="practice-form" autocomplete="off">
|
|
<input id="practice-input" class="spell-input" type="text" autocomplete="off"
|
|
autocapitalize="off" autocorrect="off" spellcheck="false" aria-label="Type the word">
|
|
<button type="submit" class="check-btn">Check ✓</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="practice-done" class="done-card" hidden></div>
|
|
</section>
|
|
|
|
<!-- Friday test (spelling) -->
|
|
<section id="view-test" class="view" hidden>
|
|
<button class="back-btn" data-back="test">← Back</button>
|
|
<p id="test-progress" class="progress-label"></p>
|
|
<div class="progress-track"><div id="test-bar" class="progress-fill test-fill"></div></div>
|
|
|
|
<div id="test-card" class="word-card">
|
|
<p id="test-listening" class="test-listening-state">🔊 Listen carefully…</p>
|
|
<div id="test-form-row" hidden>
|
|
<button id="btn-test-speak" class="speak-btn speak-btn-prominent">🔊 Hear it again</button>
|
|
<p class="prompt">Now spell the word:</p>
|
|
<form id="test-form" autocomplete="off">
|
|
<input id="test-input" class="spell-input" type="text" autocomplete="off"
|
|
autocapitalize="off" autocorrect="off" spellcheck="false" aria-label="Spell the word">
|
|
<button type="submit" class="check-btn">Next →</button>
|
|
</form>
|
|
<button id="btn-test-prev" class="speak-btn" style="margin-top:.75rem" hidden>← Previous word</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="test-done" class="done-card" hidden></div>
|
|
</section>
|
|
|
|
<!-- Crossword -->
|
|
<section id="view-crossword" class="view" hidden>
|
|
<button class="back-btn" data-back="crossword">← Back</button>
|
|
<div class="item-card">
|
|
<p class="item-kicker cw-kicker"></p>
|
|
<h1 class="cw-title"></h1>
|
|
<p id="cw-hint" class="hint" hidden>Click a square to start — click the same square again to switch Across ↔ Down. Use arrow keys to move and Tab to jump to the next word.</p>
|
|
<div class="cw-layout">
|
|
<div class="cw-grid-wrap">
|
|
<div class="cw-grid"></div>
|
|
</div>
|
|
<div class="cw-sidebar">
|
|
<div class="cw-clues">
|
|
<h3>Across</h3>
|
|
<ol class="cw-clue-list" id="cw-across-list"></ol>
|
|
</div>
|
|
<div class="cw-clues">
|
|
<h3>Down</h3>
|
|
<ol class="cw-clue-list" id="cw-down-list"></ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="cw-actions" id="cw-actions" hidden>
|
|
<button id="cw-check-btn" class="check-btn">Check answers ✓</button>
|
|
<button id="cw-print-btn" class="secondary" style="margin-left:.5rem">🖨 Print worksheet</button>
|
|
</div>
|
|
<div id="cw-result" class="status-banner" hidden></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Worksheet -->
|
|
<section id="view-worksheet" class="view" hidden>
|
|
<button class="back-btn" data-back="worksheet">← Back</button>
|
|
<div class="item-card">
|
|
<p class="item-kicker" id="ws-kicker"></p>
|
|
<h1 id="ws-title"></h1>
|
|
<div id="ws-header" class="ws-header" hidden>
|
|
<span>Name: <input id="ws-name" class="ws-name-input" type="text" autocomplete="name" placeholder="Your name"></span>
|
|
<span>Date: <input id="ws-date" class="ws-date-input" type="text"></span>
|
|
</div>
|
|
<form id="ws-form" autocomplete="off"></form>
|
|
<div id="ws-result" class="status-banner" hidden></div>
|
|
<div class="ws-actions" id="ws-actions" hidden>
|
|
<button id="ws-submit-btn" class="check-btn">Submit ✓</button>
|
|
<button id="ws-print-btn" class="secondary">🖨 Print blank</button>
|
|
<button id="ws-paper-btn" class="secondary">📄 I handed in my paper copy</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|