commit 8e43d12eefc2da78504b1dbc063a0aa00cda9e3e
Author: root <root@hub.scroll.pub>
Date: 2024-12-28 06:45:31 +0000
Subject: Initial commit
diff --git a/body.html b/body.html
new file mode 100644
index 0000000..4eb02e2
--- /dev/null
+++ b/body.html
@@ -0,0 +1,46 @@
+<header>
+ <h1>Sip</h1>
+ <p class="tagline">Track your daily hydration journey</p>
+</header>
+
+<main>
+ <section class="water-display">
+ <div class="circle-progress">
+ <div class="water-level"></div>
+ <div class="stats">
+ <span id="current-ml">0</span>
+ <small>of</small>
+ <span id="goal-ml">2500</span>
+ <small>ml</small>
+ </div>
+ </div>
+ <div class="cups-display">
+ <span id="cups-count">0</span> cups
+ </div>
+ </section>
+
+ <section class="add-water">
+ <h2>Add Water</h2>
+ <div class="quick-add">
+ <button data-ml="250">1 Cup</button>
+ <button data-ml="500">500ml</button>
+ <button data-ml="750">750ml</button>
+ </div>
+ <div class="custom-add">
+ <input type="number" id="custom-amount" placeholder="Custom amount (ml)" min="0" max="2000">
+ <button id="add-custom">Add</button>
+ </div>
+ </section>
+
+ <section class="milestones" aria-live="polite">
+ <h2>Today's Achievements</h2>
+ <div id="achievements"></div>
+ </section>
+</main>
+
+<footer>
+ <nav>
+ <button id="reset" class="icon-button">Reset Day</button>
+ <button id="settings" class="icon-button">Settings</button>
+ </nav>
+</footer>
\ No newline at end of file
diff --git a/index.scroll b/index.scroll
new file mode 100644
index 0000000..8304ed5
--- /dev/null
+++ b/index.scroll
@@ -0,0 +1,8 @@
+buildHtml
+baseUrl https://sip.scroll.pub
+metaTags
+editButton /edit.html
+title Sip - Daily Water Tracking Made Simple
+style.css
+body.html
+script.js
\ No newline at end of file
diff --git a/prompt.json b/prompt.json
new file mode 100644
index 0000000..c1df017
--- /dev/null
+++ b/prompt.json
@@ -0,0 +1,20 @@
+{
+ "id": "msg_013ZMqMW5pek4XWJq7jf2Rx3",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "I'll suggest the domain \"sip.scroll.pub\" - it's short, memorable, and relates to drinking water.\n\n---domain---\nsip.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://sip.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Sip - Daily Water Tracking Made Simple\nstyle.css\nbody.html\nscript.js\n---body.html---\n<header>\n <h1>Sip</h1>\n <p class=\"tagline\">Track your daily hydration journey</p>\n</header>\n\n<main>\n <section class=\"water-display\">\n <div class=\"circle-progress\">\n <div class=\"water-level\"></div>\n <div class=\"stats\">\n <span id=\"current-ml\">0</span>\n <small>of</small>\n <span id=\"goal-ml\">2500</span>\n <small>ml</small>\n </div>\n </div>\n <div class=\"cups-display\">\n <span id=\"cups-count\">0</span> cups\n </div>\n </section>\n\n <section class=\"add-water\">\n <h2>Add Water</h2>\n <div class=\"quick-add\">\n <button data-ml=\"250\">1 Cup</button>\n <button data-ml=\"500\">500ml</button>\n <button data-ml=\"750\">750ml</button>\n </div>\n <div class=\"custom-add\">\n <input type=\"number\" id=\"custom-amount\" placeholder=\"Custom amount (ml)\" min=\"0\" max=\"2000\">\n <button id=\"add-custom\">Add</button>\n </div>\n </section>\n\n <section class=\"milestones\" aria-live=\"polite\">\n <h2>Today's Achievements</h2>\n <div id=\"achievements\"></div>\n </section>\n</main>\n\n<footer>\n <nav>\n <button id=\"reset\" class=\"icon-button\">Reset Day</button>\n <button id=\"settings\" class=\"icon-button\">Settings</button>\n </nav>\n</footer>\n---style.css---\n:root {\n --primary: #2196f3;\n --secondary: #e3f2fd;\n --accent: #1976d2;\n --text: #333;\n --background: #fff;\n --success: #4caf50;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n color: var(--text);\n background: var(--background);\n line-height: 1.6;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n}\n\nheader {\n text-align: center;\n padding: 2rem 1rem;\n background: linear-gradient(135deg, var(--primary), var(--accent));\n color: white;\n}\n\nh1 {\n font-size: 2.5rem;\n font-weight: 700;\n margin-bottom: 0.5rem;\n}\n\n.tagline {\n opacity: 0.9;\n}\n\nmain {\n flex: 1;\n padding: 2rem 1rem;\n max-width: 600px;\n margin: 0 auto;\n width: 100%;\n}\n\n.water-display {\n text-align: center;\n margin-bottom: 3rem;\n}\n\n.circle-progress {\n width: 200px;\n height: 200px;\n border-radius: 50%;\n border: 10px solid var(--secondary);\n position: relative;\n margin: 0 auto 1rem;\n overflow: hidden;\n}\n\n.water-level {\n position: absolute;\n bottom: 0;\n left: 0;\n width: 100%;\n background: var(--primary);\n transition: height 0.5s ease-out;\n}\n\n.stats {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1;\n font-size: 1.5rem;\n font-weight: 700;\n}\n\n.stats small {\n display: block;\n font-size: 0.875rem;\n opacity: 0.8;\n}\n\n.quick-add {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\nbutton {\n background: var(--primary);\n color: white;\n border: none;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n font-size: 1rem;\n cursor: pointer;\n transition: transform 0.2s, background-color 0.2s;\n}\n\nbutton:hover {\n background: var(--accent);\n transform: translateY(-2px);\n}\n\n.custom-add {\n display: flex;\n gap: 1rem;\n}\n\ninput {\n flex: 1;\n padding: 0.75rem;\n border: 2px solid var(--secondary);\n border-radius: 8px;\n font-size: 1rem;\n}\n\nh2 {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.milestones {\n margin-top: 2rem;\n}\n\nfooter {\n padding: 1rem;\n background: var(--secondary);\n}\n\nfooter nav {\n display: flex;\n justify-content: space-around;\n max-width: 600px;\n margin: 0 auto;\n}\n\n@media (max-width: 480px) {\n .quick-add {\n grid-template-columns: 1fr;\n }\n \n .custom-add {\n flex-direction: column;\n }\n}\n\n.achievement {\n padding: 1rem;\n background: var(--secondary);\n border-radius: 8px;\n margin-bottom: 1rem;\n animation: slideIn 0.3s ease-out;\n}\n\n@keyframes slideIn {\n from {\n transform: translateX(-100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const state = {\n currentMl: 0,\n goalMl: 2500,\n achievements: []\n };\n\n // Load saved data\n const savedData = localStorage.getItem('waterData');\n if (savedData) {\n const parsed = JSON.parse(savedData);\n if (isToday(new Date(parsed.date))) {\n state.currentMl = parsed.currentMl;\n state.achievements = parsed.achievements;\n updateDisplay();\n }\n }\n\n function isToday(date) {\n const today = new Date();\n return date.getDate() === today.getDate() &&\n date.getMonth() === today.getMonth() &&\n date.getFullYear() === today.getFullYear();\n }\n\n function updateDisplay() {\n // Update numbers\n document.getElementById('current-ml').textContent = state.currentMl;\n document.getElementById('cups-count').textContent = (state.currentMl / 250).toFixed(1);\n\n // Update water level visualization\n const percentage = (state.currentMl / state.goalMl) * 100;\n document.querySelector('.water-level').style.height = `${Math.min(percentage, 100)}%`;\n\n // Save to localStorage\n localStorage.setItem('waterData', JSON.stringify({\n currentMl: state.currentMl,\n achievements: state.achievements,\n date: new Date()\n }));\n\n // Check achievements\n checkMilestones();\n }\n\n function addWater(ml) {\n state.currentMl += ml;\n updateDisplay();\n \n // Add animation effect\n const circle = document.querySelector('.circle-progress');\n circle.style.transform = 'scale(1.05)';\n setTimeout(() => {\n circle.style.transform = 'scale(1)';\n }, 200);\n }\n\n function checkMilestones() {\n const milestones = [\n { ml: 1000, message: \"Great start! 1L reached! 💧\" },\n { ml: 2000, message: \"Halfway there! 2L achieved! 💪\" },\n { ml: state.goalMl, message: \"Daily goal reached! 🎉\" }\n ];\n\n milestones.forEach(milestone => {\n if (state.currentMl >= milestone.ml && \n !state.achievements.includes(milestone.ml)) {\n state.achievements.push(milestone.ml);\n showAchievement(milestone.message);\n }\n });\n }\n\n function showAchievement(message) {\n const achievementsDiv = document.getElementById('achievements');\n const achievement = document.createElement('div');\n achievement.className = 'achievement';\n achievement.textContent = message;\n achievementsDiv.prepend(achievement);\n }\n\n // Event Listeners\n document.querySelectorAll('.quick-add button').forEach(button => {\n button.addEventListener('click', () => {\n addWater(parseInt(button.dataset.ml));\n });\n });\n\n document.getElementById('add-custom').addEventListener('click', () => {\n const input = document.getElementById('custom-amount');\n const amount = parseInt(input.value);\n if (amount > 0) {\n addWater(amount);\n input.value = '';\n }\n });\n\n document.getElementById('reset').addEventListener('click', () => {\n if (confirm('Reset today\\'s water tracking?')) {\n state.currentMl = 0;\n state.achievements = [];\n document.getElementById('achievements').innerHTML = '';\n updateDisplay();\n }\n });\n\n // Initial display update\n updateDisplay();\n});\n---end---"
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 365,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 2583
+ }
+}
\ No newline at end of file
diff --git a/readme.scroll b/readme.scroll
new file mode 100644
index 0000000..4a72479
--- /dev/null
+++ b/readme.scroll
@@ -0,0 +1,2 @@
+# sip.scroll.pub
+Website generated by Claude from prompt: Design a user-friendly water tracker application that encourages daily hydration. Include the following features: a home screen displaying today's water intake in milliliters and cups, an input method for adding water consumption, a progress tracker with a daily goal, and creative visual or auditory feedback for achieving hydration milestones. Provide wireframes or a simple prototype to illustrate your concept. Assume the target audience is general users interested in maintaining good hydration habits.
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..27bbba0
--- /dev/null
+++ b/script.js
@@ -0,0 +1,109 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const state = {
+ currentMl: 0,
+ goalMl: 2500,
+ achievements: []
+ };
+
+ // Load saved data
+ const savedData = localStorage.getItem('waterData');
+ if (savedData) {
+ const parsed = JSON.parse(savedData);
+ if (isToday(new Date(parsed.date))) {
+ state.currentMl = parsed.currentMl;
+ state.achievements = parsed.achievements;
+ updateDisplay();
+ }
+ }
+
+ function isToday(date) {
+ const today = new Date();
+ return date.getDate() === today.getDate() &&
+ date.getMonth() === today.getMonth() &&
+ date.getFullYear() === today.getFullYear();
+ }
+
+ function updateDisplay() {
+ // Update numbers
+ document.getElementById('current-ml').textContent = state.currentMl;
+ document.getElementById('cups-count').textContent = (state.currentMl / 250).toFixed(1);
+
+ // Update water level visualization
+ const percentage = (state.currentMl / state.goalMl) * 100;
+ document.querySelector('.water-level').style.height = `${Math.min(percentage, 100)}%`;
+
+ // Save to localStorage
+ localStorage.setItem('waterData', JSON.stringify({
+ currentMl: state.currentMl,
+ achievements: state.achievements,
+ date: new Date()
+ }));
+
+ // Check achievements
+ checkMilestones();
+ }
+
+ function addWater(ml) {
+ state.currentMl += ml;
+ updateDisplay();
+
+ // Add animation effect
+ const circle = document.querySelector('.circle-progress');
+ circle.style.transform = 'scale(1.05)';
+ setTimeout(() => {
+ circle.style.transform = 'scale(1)';
+ }, 200);
+ }
+
+ function checkMilestones() {
+ const milestones = [
+ { ml: 1000, message: "Great start! 1L reached! 💧" },
+ { ml: 2000, message: "Halfway there! 2L achieved! 💪" },
+ { ml: state.goalMl, message: "Daily goal reached! 🎉" }
+ ];
+
+ milestones.forEach(milestone => {
+ if (state.currentMl >= milestone.ml &&
+ !state.achievements.includes(milestone.ml)) {
+ state.achievements.push(milestone.ml);
+ showAchievement(milestone.message);
+ }
+ });
+ }
+
+ function showAchievement(message) {
+ const achievementsDiv = document.getElementById('achievements');
+ const achievement = document.createElement('div');
+ achievement.className = 'achievement';
+ achievement.textContent = message;
+ achievementsDiv.prepend(achievement);
+ }
+
+ // Event Listeners
+ document.querySelectorAll('.quick-add button').forEach(button => {
+ button.addEventListener('click', () => {
+ addWater(parseInt(button.dataset.ml));
+ });
+ });
+
+ document.getElementById('add-custom').addEventListener('click', () => {
+ const input = document.getElementById('custom-amount');
+ const amount = parseInt(input.value);
+ if (amount > 0) {
+ addWater(amount);
+ input.value = '';
+ }
+ });
+
+ document.getElementById('reset').addEventListener('click', () => {
+ if (confirm('Reset today\'s water tracking?')) {
+ state.currentMl = 0;
+ state.achievements = [];
+ document.getElementById('achievements').innerHTML = '';
+ updateDisplay();
+ }
+ });
+
+ // Initial display update
+ updateDisplay();
+});
\ No newline at end of file
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..31cace4
--- /dev/null
+++ b/style.css
@@ -0,0 +1,175 @@
+:root {
+ --primary: #2196f3;
+ --secondary: #e3f2fd;
+ --accent: #1976d2;
+ --text: #333;
+ --background: #fff;
+ --success: #4caf50;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
+ color: var(--text);
+ background: var(--background);
+ line-height: 1.6;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+header {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: linear-gradient(135deg, var(--primary), var(--accent));
+ color: white;
+}
+
+h1 {
+ font-size: 2.5rem;
+ font-weight: 700;
+ margin-bottom: 0.5rem;
+}
+
+.tagline {
+ opacity: 0.9;
+}
+
+main {
+ flex: 1;
+ padding: 2rem 1rem;
+ max-width: 600px;
+ margin: 0 auto;
+ width: 100%;
+}
+
+.water-display {
+ text-align: center;
+ margin-bottom: 3rem;
+}
+
+.circle-progress {
+ width: 200px;
+ height: 200px;
+ border-radius: 50%;
+ border: 10px solid var(--secondary);
+ position: relative;
+ margin: 0 auto 1rem;
+ overflow: hidden;
+}
+
+.water-level {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ background: var(--primary);
+ transition: height 0.5s ease-out;
+}
+
+.stats {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 1;
+ font-size: 1.5rem;
+ font-weight: 700;
+}
+
+.stats small {
+ display: block;
+ font-size: 0.875rem;
+ opacity: 0.8;
+}
+
+.quick-add {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
+
+button {
+ background: var(--primary);
+ color: white;
+ border: none;
+ padding: 0.75rem 1rem;
+ border-radius: 8px;
+ font-size: 1rem;
+ cursor: pointer;
+ transition: transform 0.2s, background-color 0.2s;
+}
+
+button:hover {
+ background: var(--accent);
+ transform: translateY(-2px);
+}
+
+.custom-add {
+ display: flex;
+ gap: 1rem;
+}
+
+input {
+ flex: 1;
+ padding: 0.75rem;
+ border: 2px solid var(--secondary);
+ border-radius: 8px;
+ font-size: 1rem;
+}
+
+h2 {
+ margin-bottom: 1rem;
+ font-size: 1.25rem;
+}
+
+.milestones {
+ margin-top: 2rem;
+}
+
+footer {
+ padding: 1rem;
+ background: var(--secondary);
+}
+
+footer nav {
+ display: flex;
+ justify-content: space-around;
+ max-width: 600px;
+ margin: 0 auto;
+}
+
+@media (max-width: 480px) {
+ .quick-add {
+ grid-template-columns: 1fr;
+ }
+
+ .custom-add {
+ flex-direction: column;
+ }
+}
+
+.achievement {
+ padding: 1rem;
+ background: var(--secondary);
+ border-radius: 8px;
+ margin-bottom: 1rem;
+ animation: slideIn 0.3s ease-out;
+}
+
+@keyframes slideIn {
+ from {
+ transform: translateX(-100%);
+ opacity: 0;
+ }
+ to {
+ transform: translateX(0);
+ opacity: 1;
+ }
+}
\ No newline at end of file