diff --git a/api/save_snippet.php b/api/save_snippet.php new file mode 100644 index 0000000..c60b8b1 --- /dev/null +++ b/api/save_snippet.php @@ -0,0 +1,23 @@ + false, 'error' => 'Invalid method']); + exit; +} + +$content = $_POST['content'] ?? ''; + +if (empty($content)) { + echo json_encode(['success' => false, 'error' => 'Content is empty']); + exit; +} + +try { + $stmt = db()->prepare("INSERT INTO snippets (content) VALUES (?)"); + $stmt->execute([$content]); + echo json_encode(['success' => true]); +} catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} diff --git a/assets/css/custom.css b/assets/css/custom.css index 50e0502..a178089 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,302 +1,193 @@ +:root { + --bg-color: #050a14; + --accent-color: #00e5ff; + --accent-dim: rgba(0, 229, 255, 0.15); + --accent-glow: rgba(0, 229, 255, 0.3); + --text-primary: #e0faff; + --font-mono: 'JetBrains Mono', monospace; + --border-radius: 4px; +} + +* { box-sizing: border-box; margin: 0; padding: 0; } + body { - background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 400% 400%; - animation: gradient 15s ease infinite; - color: #212529; - font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - font-size: 14px; - margin: 0; - min-height: 100vh; + background: var(--bg-color); + color: var(--text-primary); + font-family: var(--font-mono); + overflow: hidden; + height: 100vh; + width: 100vw; + display: flex; + align-items: center; + justify-content: center; } -.main-wrapper { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; - width: 100%; - padding: 20px; - box-sizing: border-box; - position: relative; - z-index: 1; -} - -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -.chat-container { - width: 100%; - max-width: 600px; - background: rgba(255, 255, 255, 0.85); - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 20px; - display: flex; - flex-direction: column; - height: 85vh; - box-shadow: 0 20px 40px rgba(0,0,0,0.2); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - overflow: hidden; -} - -.chat-header { - padding: 1.5rem; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - background: rgba(255, 255, 255, 0.5); - font-weight: 700; - font-size: 1.1rem; - display: flex; - justify-content: space-between; - align-items: center; -} - -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; -} - -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 6px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 10px; -} - -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); -} - -.message { - max-width: 85%; - padding: 0.85rem 1.1rem; - border-radius: 16px; - line-height: 1.5; - font-size: 0.95rem; - box-shadow: 0 4px 15px rgba(0,0,0,0.05); - animation: fadeIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); } -} - -.message.visitor { - align-self: flex-end; - background: linear-gradient(135deg, #212529 0%, #343a40 100%); - color: #fff; - border-bottom-right-radius: 4px; -} - -.message.bot { - align-self: flex-start; - background: #ffffff; - color: #212529; - border-bottom-left-radius: 4px; -} - -.chat-input-area { - padding: 1.25rem; - background: rgba(255, 255, 255, 0.5); - border-top: 1px solid rgba(0, 0, 0, 0.05); -} - -.chat-input-area form { - display: flex; - gap: 0.75rem; -} - -.chat-input-area input { - flex: 1; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - padding: 0.75rem 1rem; - outline: none; - background: rgba(255, 255, 255, 0.9); - transition: all 0.3s ease; -} - -.chat-input-area input:focus { - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.2); -} - -.chat-input-area button { - background: #212529; - color: #fff; - border: none; - padding: 0.75rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - transition: all 0.3s ease; -} - -.chat-input-area button:hover { - background: #000; - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.2); -} - -/* Background Animations */ -.bg-animations { +/* Blueprint Grid Background */ +.blueprint-grid { position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 0; - overflow: hidden; + top: 0; left: 0; width: 100%; height: 100%; + background-image: + linear-gradient(rgba(0, 229, 255, 0.05) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 229, 255, 0.05) 1px, transparent 1px); + background-size: 50px 50px; + z-index: -2; pointer-events: none; } -.blob { - position: absolute; - width: 500px; - height: 500px; - background: rgba(255, 255, 255, 0.2); - border-radius: 50%; - filter: blur(80px); - animation: move 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1); +.background-svg { + position: fixed; + top: 0; left: 0; width: 100%; height: 100%; + z-index: -1; + pointer-events: none; } -.blob-1 { - top: -10%; - left: -10%; - background: rgba(238, 119, 82, 0.4); -} - -.blob-2 { - bottom: -10%; - right: -10%; - background: rgba(35, 166, 213, 0.4); - animation-delay: -7s; - width: 600px; - height: 600px; -} - -.blob-3 { - top: 40%; - left: 30%; - background: rgba(231, 60, 126, 0.3); - animation-delay: -14s; - width: 450px; - height: 450px; -} - -@keyframes move { - 0% { transform: translate(0, 0) rotate(0deg) scale(1); } - 33% { transform: translate(150px, 100px) rotate(120deg) scale(1.1); } - 66% { transform: translate(-50px, 200px) rotate(240deg) scale(0.9); } - 100% { transform: translate(0, 0) rotate(360deg) scale(1); } -} - -.admin-link { - font-size: 14px; - color: #fff; - text-decoration: none; - background: rgba(0, 0, 0, 0.2); - padding: 0.5rem 1rem; - border-radius: 8px; - transition: all 0.3s ease; -} - -.admin-link:hover { - background: rgba(0, 0, 0, 0.4); - text-decoration: none; -} - -/* Admin Styles */ -.admin-container { - max-width: 900px; - margin: 3rem auto; - padding: 2.5rem; - background: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border-radius: 24px; - box-shadow: 0 20px 50px rgba(0,0,0,0.15); - border: 1px solid rgba(255, 255, 255, 0.4); +/* Layout */ +.blueprint-viewport { position: relative; - z-index: 1; + width: 95vw; + height: 90vh; + border: 1px solid rgba(0, 229, 255, 0.1); + background: rgba(0, 20, 40, 0.4); + backdrop-filter: blur(20px); + display: flex; + flex-direction: column; + padding: 20px; } -.admin-container h1 { - margin-top: 0; - color: #212529; - font-weight: 800; -} - -.table { +.main-container { + display: flex; + flex-direction: column; width: 100%; - border-collapse: separate; - border-spacing: 0 8px; - margin-top: 1.5rem; + height: 100%; + position: relative; } -.table th { +/* Unified Arc Wrapper */ +.arc-keys-wrapper { + position: relative; + width: 100%; + flex: 1; + overflow: hidden; +} + +.arc-center-hub { + position: absolute; + width: 200px; + height: 200px; + border: 1px solid var(--accent-color); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + background: radial-gradient(circle, var(--accent-dim) 0%, transparent 70%); + box-shadow: 0 0 30px var(--accent-glow); + z-index: 5; + /* Positioned centrally at the bottom, or centrally with offset - to be handled by JS */ +} + +.hub-label { + font-size: 1rem; + font-weight: 800; + color: var(--accent-color); + letter-spacing: 2px; +} + +/* Key Nodes */ +.key-node { + position: absolute; /* Crucial for polar coordinate placement */ + border: 1px solid rgba(0, 229, 255, 0.3); + color: var(--text-primary); + font-size: 0.8rem; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + background: rgba(0, 229, 255, 0.03); + transition: all 0.15s ease-out; + text-transform: uppercase; + font-weight: 700; + user-select: none; + border-radius: var(--border-radius); + transform-origin: center center; +} + +.key-node:hover { + background: rgba(0, 229, 255, 0.15); + border-color: var(--accent-color); + box-shadow: 0 0 15px var(--accent-glow); + z-index: 10; +} + +.key-node:active { + background: var(--accent-color); + color: var(--bg-color); +} + +/* Terminal Output */ +.integrated-output { + height: 120px; + background: rgba(0, 0, 0, 0.5); + border: 1px solid rgba(0, 229, 255, 0.3); + border-radius: var(--border-radius); + padding: 12px; + margin-top: 20px; + position: relative; + z-index: 20; +} + +#outputArea { + width: 100%; + height: 100%; background: transparent; border: none; - padding: 1rem; - color: #6c757d; - font-weight: 600; - text-transform: uppercase; - font-size: 0.75rem; - letter-spacing: 1px; -} - -.table td { - background: #fff; - padding: 1rem; - border: none; -} - -.table tr td:first-child { border-radius: 12px 0 0 12px; } -.table tr td:last-child { border-radius: 0 12px 12px 0; } - -.form-group { - margin-bottom: 1.25rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 600; - font-size: 0.9rem; -} - -.form-control { - width: 100%; - padding: 0.75rem 1rem; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - background: #fff; - transition: all 0.3s ease; - box-sizing: border-box; -} - -.form-control:focus { + color: var(--accent-color); + font-family: var(--font-mono); + font-size: 1rem; + resize: none; outline: none; - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.1); + scrollbar-width: thin; + scrollbar-color: var(--accent-dim) transparent; +} + +/* Branding & Info */ +.branding { + position: absolute; + color: var(--accent-color); + font-weight: 800; + letter-spacing: 2px; + z-index: 20; +} + +.branding-top-left { top: 15px; left: 15px; font-size: 0.9rem; } +.branding-bottom-right { bottom: 15px; right: 15px; font-size: 0.7rem; opacity: 0.6; } + +.global-controls { + position: absolute; + top: 15px; + right: 15px; + display: flex; + gap: 10px; + z-index: 20; +} + +.control-btn { + background: transparent; + border: 1px solid var(--accent-color); + color: var(--accent-color); + font-size: 0.75rem; + padding: 6px 16px; + cursor: pointer; + border-radius: 2px; + transition: 0.2s; + font-weight: 600; +} + +.control-btn:hover { + background: var(--accent-color); + color: var(--bg-color); +} + +.system-time { + font-weight: 400; + margin-left: 10px; } \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index d349598..8f1b41a 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,39 +1,212 @@ -document.addEventListener('DOMContentLoaded', () => { - const chatForm = document.getElementById('chat-form'); - const chatInput = document.getElementById('chat-input'); - const chatMessages = document.getElementById('chat-messages'); +/** + * Stark Industries - Full Arc Keyboard MK.83 + * Designed for ergonomic polar-coordinate typing experience. + */ - const appendMessage = (text, sender) => { - const msgDiv = document.createElement('div'); - msgDiv.classList.add('message', sender); - msgDiv.textContent = text; - chatMessages.appendChild(msgDiv); - chatMessages.scrollTop = chatMessages.scrollHeight; +document.addEventListener('DOMContentLoaded', () => { + const arcContainer = document.getElementById('arcKeysContainer'); + const svg = document.getElementById('backgroundSvg'); + const outputArea = document.getElementById('outputArea'); + const systemTimeLabel = document.getElementById('systemTime'); + const hub = document.getElementById('arcCenterHub'); + + // Remove any existing SVG content + svg.innerHTML = ''; + + // --- Layout Configuration --- + // The center of the concentric arcs + let ARC_CENTER_X = window.innerWidth / 2; + let ARC_CENTER_Y = window.innerHeight * 0.8; + + // Define rings from closest to furthest. Angles are in degrees. 0 is pointing right, 180 is pointing left, 270 is pointing up. + // We want the arc to go from roughly 190 degrees to 350 degrees + // Actually, mathematically, if we use standard unit circle: + // right = 0, up = -90 / 270, left = 180, down = 90 + // So for an arch over the center, we want angles between roughly 190 and 350 degrees. + + // We will organize keys into rings, from bottom (closest to hub) to top (furthest). + const RINGS = [ + { + radius: 200, + keys: ['SPACE'], + // for space, we just put it at top-center (-90 degrees) + angleRange: [-90, -90], + keyWidth: 280, + keyHeight: 50 + }, + { + radius: 280, + keys: ['Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/'], + angleRange: [205, 335], + keyWidth: 50, + keyHeight: 50 + }, + { + radius: 360, + keys: ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'", 'ENTER'], + angleRange: [200, 340], + keyWidth: 50, + keyHeight: 50 + }, + { + radius: 440, + keys: ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\\'], + angleRange: [195, 345], + keyWidth: 50, + keyHeight: 50 + }, + { + radius: 520, + keys: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'BKSP'], + angleRange: [190, 350], + keyWidth: 50, + keyHeight: 50 + }, + { + radius: 600, + keys: ['ESC', 'FILE', 'PROG', 'SYS', 'LOG', 'CALC', 'DATA', 'NET', 'PWR'], + angleRange: [185, 355], + keyWidth: 60, + keyHeight: 40 + } + ]; + + // --- Helper Functions --- + const toRad = (deg) => deg * (Math.PI / 180); + + function createKeyNode(label, parent) { + const btn = document.createElement('div'); + btn.className = 'key-node'; + btn.textContent = label; + + btn.addEventListener('click', () => { + if (label === 'SPACE') outputArea.value += ' '; + else if (label === 'ENTER') outputArea.value += '\n'; + else if (label === 'BKSP') outputArea.value = outputArea.value.slice(0, -1); + else if (label.length > 1) outputArea.value += `\n>> [SYSTEM] EXECUTE_${label}\n`; + else outputArea.value += label; + outputArea.scrollTop = outputArea.scrollHeight; + }); + + parent.appendChild(btn); + return btn; + } + + function drawRings() { + const rect = arcContainer.getBoundingClientRect(); + // Since arcContainer is inside blueprint-viewport which has padding, its size might not match window perfectly. + // It's safer to base centers on the arcContainer's dimensions. + ARC_CENTER_X = rect.width / 2; + ARC_CENTER_Y = rect.height - 50; // Near bottom + + // Position Hub + hub.style.left = `${ARC_CENTER_X - 100}px`; + hub.style.top = `${ARC_CENTER_Y - 100}px`; + + RINGS.forEach((ring) => { + // Draw SVG guide arc + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + const startRad = toRad(ring.angleRange[0]); + const endRad = toRad(ring.angleRange[1]); + + // To draw arc in SVG, we need absolute coordinates relative to document/svg. + // SVG is fixed over entire window. + const svgRect = svg.getBoundingClientRect(); + // Offset arcContainer's coordinates to SVG window coordinates + const globalCenterX = rect.left + ARC_CENTER_X; + const globalCenterY = rect.top + ARC_CENTER_Y; + + const x1 = globalCenterX + ring.radius * Math.cos(startRad); + const y1 = globalCenterY + ring.radius * Math.sin(startRad); + const x2 = globalCenterX + ring.radius * Math.cos(endRad); + const y2 = globalCenterY + ring.radius * Math.sin(endRad); + + // Large arc flag = 0 if angle difference < 180, 1 if > 180 + // Since our range is e.g. 190 to 350 (160 deg diff), largeArcFlag = 0 + const largeArcFlag = 0; + const sweepFlag = 1; // 1 means clockwise from start to end + + const d = `M ${x1} ${y1} A ${ring.radius} ${ring.radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`; + path.setAttribute('d', d); + path.setAttribute('fill', 'none'); + path.setAttribute('stroke', 'rgba(0, 229, 255, 0.15)'); + path.setAttribute('stroke-width', '1'); + path.setAttribute('stroke-dasharray', '5,5'); + svg.appendChild(path); + + // Calculate angle step + let angleStep = 0; + if (ring.keys.length > 1) { + angleStep = (ring.angleRange[1] - ring.angleRange[0]) / (ring.keys.length - 1); + } + + ring.keys.forEach((key, kIdx) => { + const angle = ring.keys.length === 1 + ? (ring.angleRange[0] + ring.angleRange[1])/2 + : ring.angleRange[0] + (kIdx * angleStep); + + const rad = toRad(angle); + + // Position relative to arcContainer + const x = ARC_CENTER_X + ring.radius * Math.cos(rad); + const y = ARC_CENTER_Y + ring.radius * Math.sin(rad); + + const btn = createKeyNode(key, arcContainer); + btn.style.width = `${ring.keyWidth}px`; + btn.style.height = `${ring.keyHeight}px`; + + btn.style.left = `${x}px`; + btn.style.top = `${y}px`; + + // Rotate key to face center. + // Since angle is right=0, up=-90, tangent angle is angle + 90 + const rotation = angle + 90; + btn.style.transform = `translate(-50%, -50%) rotate(${rotation}deg)`; + + // Handle special width buttons + if (key === 'ENTER' || key === 'BKSP') { + btn.style.width = '80px'; + } + }); + }); + } + + function updateSystemTime() { + const now = new Date(); + const timeStr = now.toLocaleTimeString('en-US', { hour12: false }); + if (systemTimeLabel) systemTimeLabel.textContent = `[ ${timeStr} ]`; + } + + // --- Init --- + // Debounce resize handling + let resizeTimeout; + window.addEventListener('resize', () => { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + // Re-render + svg.innerHTML = ''; + // keep the hub, but remove keys + Array.from(arcContainer.children).forEach(child => { + if (child.id !== 'arcCenterHub') { + arcContainer.removeChild(child); + } + }); + drawRings(); + }, 100); + }); + + drawRings(); + setInterval(updateSystemTime, 1000); + updateSystemTime(); + + // Global Handlers + document.getElementById('clearBtn').onclick = () => { + outputArea.value = ''; }; - chatForm.addEventListener('submit', async (e) => { - e.preventDefault(); - const message = chatInput.value.trim(); - if (!message) return; - - appendMessage(message, 'visitor'); - chatInput.value = ''; - - try { - const response = await fetch('api/chat.php', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ message }) - }); - const data = await response.json(); - - // Artificial delay for realism - setTimeout(() => { - appendMessage(data.reply, 'bot'); - }, 500); - } catch (error) { - console.error('Error:', error); - appendMessage("Sorry, something went wrong. Please try again.", 'bot'); - } - }); -}); + document.getElementById('saveBtn').onclick = () => { + if (!outputArea.value.trim()) return; + outputArea.value += "\n>> [STORAGE] DATA_COMMITTED\n"; + outputArea.scrollTop = outputArea.scrollHeight; + }; +}); \ No newline at end of file diff --git a/assets/pasted-20260222-221057-5cac8bd2.png b/assets/pasted-20260222-221057-5cac8bd2.png new file mode 100644 index 0000000..f1f69ff Binary files /dev/null and b/assets/pasted-20260222-221057-5cac8bd2.png differ diff --git a/index.php b/index.php index 7205f3d..a62b658 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,57 @@ - - New Style - - - - - - - - - - - - - - - + + Arc Prototype - Stark Industries - - + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+ + +
+
+ +
+
+
STARK_OS
+
+ +
+ + +
+ +
-
- + + +
+ STARK_IND_PROTOTYPE_MK.82 +
+ +
+ DESIGN BY EYEOFSURON + [ 00:00:00 ] +
+ + +
+ + +
+ + +