commit 8cd86f88fd557cd33e7f7fc4a7e261618f71425b
Author: root <root@hub.scroll.pub> Date: 2025-01-13 18:26:03 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..bf4fb70 --- /dev/null +++ b/body.html @@ -0,0 +1,22 @@ +<main class="editor-container"> + <nav class="toolbar"> + <button class="menu-btn" aria-label="Menu">☰</button> + <div class="toolbar-actions"> + <button class="action-btn" id="newBtn" aria-label="New document"> + <span class="icon">📄</span> + </button> + <button class="action-btn" id="downloadBtn" aria-label="Download"> + <span class="icon">💾</span> + </button> + </div> + </nav> + + <div class="editor-wrapper"> + <textarea id="editor" spellcheck="true" placeholder="Start typing..." aria-label="Text editor"></textarea> + </div> + + <footer class="status-bar"> + <span id="wordCount">0 words</span> + <span id="charCount">0 characters</span> + </footer> +</main> diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..0a84127 --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://ink.scroll.pub +metaTags +editButton /edit.html +title Ink - Minimal Dark Text Editor +style.css +body.html +script.js diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..fc84551 --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_01CY1PWLdtpPf4PMbtVbLtU9", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "Let me create a minimal dark text editor called \"Ink\" - simple and elegant.\n\n---domain---\nink.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://ink.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Ink - Minimal Dark Text Editor\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n<main class=\"editor-container\">\n <nav class=\"toolbar\">\n <button class=\"menu-btn\" aria-label=\"Menu\">☰</button>\n <div class=\"toolbar-actions\">\n <button class=\"action-btn\" id=\"newBtn\" aria-label=\"New document\">\n <span class=\"icon\">📄</span>\n </button>\n <button class=\"action-btn\" id=\"downloadBtn\" aria-label=\"Download\">\n <span class=\"icon\">💾</span>\n </button>\n </div>\n </nav>\n \n <div class=\"editor-wrapper\">\n <textarea id=\"editor\" spellcheck=\"true\" placeholder=\"Start typing...\" aria-label=\"Text editor\"></textarea>\n </div>\n\n <footer class=\"status-bar\">\n <span id=\"wordCount\">0 words</span>\n <span id=\"charCount\">0 characters</span>\n </footer>\n</main>\n\n---style.css---\n:root {\n --bg-primary: #1a1a1a;\n --bg-secondary: #252525;\n --text-primary: #e0e0e0;\n --text-secondary: #b0b0b0;\n --accent: #646cff;\n --transition: all 0.3s ease;\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, 'Segoe UI', Roboto, sans-serif;\n background: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.6;\n height: 100vh;\n overflow: hidden;\n}\n\n.editor-container {\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n\n.toolbar {\n background: var(--bg-secondary);\n padding: 0.8rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n}\n\n.toolbar-actions {\n display: flex;\n gap: 0.5rem;\n}\n\nbutton {\n background: transparent;\n border: none;\n color: var(--text-primary);\n padding: 0.5rem;\n border-radius: 4px;\n cursor: pointer;\n transition: var(--transition);\n}\n\nbutton:hover {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.editor-wrapper {\n flex: 1;\n padding: 1rem;\n overflow: hidden;\n}\n\n#editor {\n width: 100%;\n height: 100%;\n background: var(--bg-primary);\n color: var(--text-primary);\n border: none;\n resize: none;\n padding: 1rem;\n font-size: 1.1rem;\n line-height: 1.6;\n border-radius: 4px;\n}\n\n#editor:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--accent);\n}\n\n.status-bar {\n background: var(--bg-secondary);\n padding: 0.5rem 1rem;\n display: flex;\n justify-content: flex-end;\n gap: 1rem;\n font-size: 0.9rem;\n color: var(--text-secondary);\n}\n\n@media (max-width: 768px) {\n .editor-wrapper {\n padding: 0.5rem;\n }\n \n #editor {\n font-size: 1rem;\n padding: 0.8rem;\n }\n \n .toolbar {\n padding: 0.5rem;\n }\n}\n\n@media (prefers-color-scheme: light) {\n :root {\n --bg-primary: #ffffff;\n --bg-secondary: #f5f5f5;\n --text-primary: #1a1a1a;\n --text-secondary: #666666;\n }\n}\n\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const editor = document.getElementById('editor');\n const wordCount = document.getElementById('wordCount');\n const charCount = document.getElementById('charCount');\n const newBtn = document.getElementById('newBtn');\n const downloadBtn = document.getElementById('downloadBtn');\n\n function updateCounts() {\n const text = editor.value;\n const words = text.trim() ? text.trim().split(/\\s+/).length : 0;\n const chars = text.length;\n \n wordCount.textContent = `${words} words`;\n charCount.textContent = `${chars} characters`;\n }\n\n function createNewDocument() {\n if (editor.value && !confirm('Discard current document?')) return;\n editor.value = '';\n updateCounts();\n editor.focus();\n }\n\n function downloadText() {\n if (!editor.value.trim()) return;\n \n const blob = new Blob([editor.value], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n \n a.href = url;\n a.download = `document-${new Date().toISOString().slice(0,10)}.txt`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n }\n\n // Auto-save functionality\n function saveToLocalStorage() {\n localStorage.setItem('ink-editor-content', editor.value);\n }\n\n function loadFromLocalStorage() {\n const saved = localStorage.getItem('ink-editor-content');\n if (saved) editor.value = saved;\n updateCounts();\n }\n\n // Event listeners\n editor.addEventListener('input', () => {\n updateCounts();\n saveToLocalStorage();\n });\n\n editor.addEventListener('keydown', (e) => {\n if (e.key === 'Tab') {\n e.preventDefault();\n const start = editor.selectionStart;\n const end = editor.selectionEnd;\n editor.value = editor.value.substring(0, start) + ' ' + editor.value.substring(end);\n editor.selectionStart = editor.selectionEnd = start + 2;\n }\n });\n\n newBtn.addEventListener('click', createNewDocument);\n downloadBtn.addEventListener('click', downloadText);\n\n // Initial load\n loadFromLocalStorage();\n editor.focus();\n});\n\n---end---\n\nThis creates a beautiful, minimal dark text editor with the following features:\n\n1. Clean, modern dark interface with accent colors\n2. Word and character count\n3. Auto-save functionality\n4. Download capability\n5. New document creation\n6. Mobile-responsive design\n7. Light/dark mode support based on system preferences\n8. Smooth animations and transitions\n9. Proper tab handling\n10. Accessible buttons with aria-labels\n11. Clean, semantic HTML structure\n12. Minimal and focused UI\n\nThe editor uses CSS variables for theming, has proper spacing and typography, and includes subtle animations for interactions. It's both beautiful and functional while maintaining simplicity." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 278, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 1931 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..b0440e9 --- /dev/null +++ b/readme.scroll @@ -0,0 +1,3 @@ +# ink.scroll.pub + +website generated by Claude from prompt: a basic, minimal, dark text editor \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..5aa5b01 --- /dev/null +++ b/script.js @@ -0,0 +1,72 @@ +document.addEventListener('DOMContentLoaded', () => { + const editor = document.getElementById('editor'); + const wordCount = document.getElementById('wordCount'); + const charCount = document.getElementById('charCount'); + const newBtn = document.getElementById('newBtn'); + const downloadBtn = document.getElementById('downloadBtn'); + + function updateCounts() { + const text = editor.value; + const words = text.trim() ? text.trim().split(/\s+/).length : 0; + const chars = text.length; + + wordCount.textContent = `${words} words`; + charCount.textContent = `${chars} characters`; + } + + function createNewDocument() { + if (editor.value && !confirm('Discard current document?')) return; + editor.value = ''; + updateCounts(); + editor.focus(); + } + + function downloadText() { + if (!editor.value.trim()) return; + + const blob = new Blob([editor.value], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + + a.href = url; + a.download = `document-${new Date().toISOString().slice(0,10)}.txt`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + } + + // Auto-save functionality + function saveToLocalStorage() { + localStorage.setItem('ink-editor-content', editor.value); + } + + function loadFromLocalStorage() { + const saved = localStorage.getItem('ink-editor-content'); + if (saved) editor.value = saved; + updateCounts(); + } + + // Event listeners + editor.addEventListener('input', () => { + updateCounts(); + saveToLocalStorage(); + }); + + editor.addEventListener('keydown', (e) => { + if (e.key === 'Tab') { + e.preventDefault(); + const start = editor.selectionStart; + const end = editor.selectionEnd; + editor.value = editor.value.substring(0, start) + ' ' + editor.value.substring(end); + editor.selectionStart = editor.selectionEnd = start + 2; + } + }); + + newBtn.addEventListener('click', createNewDocument); + downloadBtn.addEventListener('click', downloadText); + + // Initial load + loadFromLocalStorage(); + editor.focus(); +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..75deac3 --- /dev/null +++ b/style.css @@ -0,0 +1,115 @@ +:root { + --bg-primary: #1a1a1a; + --bg-secondary: #252525; + --text-primary: #e0e0e0; + --text-secondary: #b0b0b0; + --accent: #646cff; + --transition: all 0.3s ease; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; + height: 100vh; + overflow: hidden; +} + +.editor-container { + display: flex; + flex-direction: column; + height: 100vh; +} + +.toolbar { + background: var(--bg-secondary); + padding: 0.8rem; + display: flex; + justify-content: space-between; + align-items: center; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); +} + +.toolbar-actions { + display: flex; + gap: 0.5rem; +} + +button { + background: transparent; + border: none; + color: var(--text-primary); + padding: 0.5rem; + border-radius: 4px; + cursor: pointer; + transition: var(--transition); +} + +button:hover { + background: rgba(255, 255, 255, 0.1); +} + +.editor-wrapper { + flex: 1; + padding: 1rem; + overflow: hidden; +} + +#editor { + width: 100%; + height: 100%; + background: var(--bg-primary); + color: var(--text-primary); + border: none; + resize: none; + padding: 1rem; + font-size: 1.1rem; + line-height: 1.6; + border-radius: 4px; +} + +#editor:focus { + outline: none; + box-shadow: 0 0 0 2px var(--accent); +} + +.status-bar { + background: var(--bg-secondary); + padding: 0.5rem 1rem; + display: flex; + justify-content: flex-end; + gap: 1rem; + font-size: 0.9rem; + color: var(--text-secondary); +} + +@media (max-width: 768px) { + .editor-wrapper { + padding: 0.5rem; + } + + #editor { + font-size: 1rem; + padding: 0.8rem; + } + + .toolbar { + padding: 0.5rem; + } +} + +@media (prefers-color-scheme: light) { + :root { + --bg-primary: #ffffff; + --bg-secondary: #f5f5f5; + --text-primary: #1a1a1a; + --text-secondary: #666666; + } +}