diff --git a/public/js/app-paint.js b/public/js/app-paint.js
new file mode 100644
index 0000000..0f7a0c5
--- /dev/null
+++ b/public/js/app-paint.js
@@ -0,0 +1,222 @@
+/* ============================================================
+ AURA OS — Uygulama C: Neon Paint
+ HTML5 Canvas serbest çizim, 4 neon renk, temizle
+ ============================================================ */
+
+const PaintAppState = {};
+
+function paintBuildContent() {
+ const tpl = document.getElementById('tpl-paint');
+ if (tpl && tpl.content) {
+ return document.importNode(tpl.content, true).firstElementChild.innerHTML;
+ }
+ return [
+ '
'
+ ].join('');
+}
+
+/* Canvas çizim motoru */
+function initPaintCanvas(bodyEl, canvas) {
+ const ctx = canvas.getContext('2d');
+
+ // Neon efekt için ikinci "glow" offscreen canvas
+ const glowCanvas = document.createElement('canvas');
+ glowCanvas.width = canvas.width;
+ glowCanvas.height = canvas.height;
+ const glowCtx = glowCanvas.getContext('2d');
+ glowCanvas.style.display = 'none';
+ bodyEl.appendChild(glowCanvas);
+
+ // Durum
+ const state = {
+ drawing: false,
+ color: '#00ffcc',
+ lastX: 0,
+ lastY: 0,
+ lineWidth: 4,
+ erasing: false,
+ };
+
+ // Canvas içindeki noktayı hesapla (konumlandırma)
+ function getPos(e) {
+ const r = canvas.getBoundingClientRect();
+ const cx = canvas.width / r.width; // ölçekleme
+ const cy = canvas.height / r.height;
+ let clientX, clientY;
+ if (e.touches && e.touches.length) {
+ clientX = e.touches[0].clientX;
+ clientY = e.touches[0].clientY;
+ } else {
+ clientX = e.clientX;
+ clientY = e.clientY;
+ }
+ return {
+ x: (clientX - r.left) * cx,
+ y: (clientY - r.top) * cy,
+ };
+ }
+
+ /* Neon ışık saçılımı: çizgiyi birden çok katman çiziyoruz */
+ function neonStroke(x0, y0, x1, y1, color, width, erase) {
+ if (erase) {
+ // Silgi modu: ikisini de sil (normal ctx)
+ ctx.save();
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.strokeStyle = 'rgba(0,0,0,1)';
+ ctx.lineWidth = width;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(x0, y0);
+ ctx.lineTo(x1, y1);
+ ctx.stroke();
+ ctx.restore();
+ return;
+ }
+
+ // 1) Glow offscreen katmanı (geniş + düşük opaklık, blur ile bakılır)
+ glowCtx.save();
+ glowCtx.globalCompositeOperation = 'lighter';
+ glowCtx.strokeStyle = color;
+ glowCtx.shadowColor = color;
+ glowCtx.shadowBlur = 18;
+ glowCtx.lineWidth = width * 2.2;
+ glowCtx.lineCap = 'round';
+ glowCtx.lineJoin = 'round';
+ glowCtx.beginPath();
+ glowCtx.moveTo(x0, y0);
+ glowCtx.lineTo(x1, y1);
+ glowCtx.stroke();
+ glowCtx.restore();
+
+ // 2) Ana çizgiyi koyu neon tonda
+ glowCtx.save();
+ glowCtx.strokeStyle = color;
+ glowCtx.shadowBlur = 6;
+ glowCtx.lineWidth = width;
+ glowCtx.lineCap = 'round';
+ glowCtx.beginPath();
+ glowCtx.moveTo(x0, y0);
+ glowCtx.lineTo(x1, y1);
+ glowCtx.stroke();
+ glowCtx.restore();
+
+ // 3) Parlak merkez
+ glowCtx.save();
+ glowCtx.globalCompositeOperation = 'lighter';
+ glowCtx.strokeStyle = 'rgba(255,255,255,0.7)';
+ glowCtx.lineWidth = Math.max(1, width * 0.35);
+ glowCtx.lineCap = 'round';
+ glowCtx.beginPath();
+ glowCtx.moveTo(x0, y0);
+ glowCtx.lineTo(x1, y1);
+ glowCtx.stroke();
+ glowCtx.restore();
+
+ // 4) Glow canvas'ı ana canvas'a aktar
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(glowCanvas, 0, 0);
+ }
+
+ /* ---- Olaylar ---- */
+ function pointerDown(e) {
+ e.preventDefault();
+ const p = getPos(e);
+ state.drawing = true;
+ state.lastX = p.x;
+ state.lastY = p.y;
+ // nokta
+ neonStroke(p.x, p.y, p.x + 0.2, p.y + 0.2, state.color, state.lineWidth, state.erasing);
+ }
+
+ function pointerMove(e) {
+ if (!state.drawing) return;
+ e.preventDefault();
+ const p = getPos(e);
+ neonStroke(state.lastX, state.lastY, p.x, p.y, state.color, state.lineWidth, state.erasing);
+ state.lastX = p.x;
+ state.lastY = p.y;
+ }
+
+ function pointerEnd(e) {
+ state.drawing = false;
+ }
+
+ // Fare
+ canvas.addEventListener('mousedown', pointerDown);
+ window.addEventListener('mousemove', pointerMove);
+ window.addEventListener('mouseup', pointerEnd);
+
+ // Dokunmatik
+ canvas.addEventListener('touchstart', pointerDown, { passive: false });
+ canvas.addEventListener('touchmove', pointerMove, { passive: false });
+ canvas.addEventListener('touchend', pointerEnd);
+
+ // Sağ lob fare: silgi modu (contextmenu bastır)
+ canvas.addEventListener('contextmenu', (e) => e.preventDefault());
+
+ // Renk seçim butonları
+ const colorBtns = bodyEl.querySelectorAll('.color-btn');
+ colorBtns.forEach(btn => {
+ btn.addEventListener('click', () => {
+ state.color = btn.dataset.color;
+ state.erasing = false;
+ colorBtns.forEach(b => b.classList.remove('active'));
+ btn.classList.add('active');
+ // canvas imleci rengi
+ canvas.style.cursor = 'crosshair';
+ });
+ });
+
+ // Temizle butonu
+ const clearBtn = bodyEl.querySelector('.paint-clear-btn');
+ if (clearBtn) {
+ clearBtn.addEventListener('click', () => {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ glowCtx.clearRect(0, 0, glowCanvas.width, glowCanvas.height);
+ });
+ }
+
+ // Initial draw: boş arka planı
+ ctx.fillStyle = '#05060f';
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ glowCtx.fillStyle = '#05060f';
+ glowCtx.fillRect(0, 0, canvas.width, canvas.height);
+
+ // Shift silgiyi keskinleştir — imleç css
+ state.color = '#00ffcc';
+ canvas.style.cursor = 'crosshair';
+
+ return state;
+}
+
+registerApp('paint', {
+ name: 'Neon Paint',
+ icon: '🎨',
+ defaultWidth: 780,
+ defaultHeight: 520,
+ windowTitle: 'Neon Paint — Aura OS',
+ windowProps: { width: 780, height: 520 },
+
+ buildContent: paintBuildContent,
+
+ onLaunch(record, bodyEl) {
+ bodyEl.innerHTML = paintBuildContent();
+
+ const canvas = bodyEl.querySelector('.paint-canvas');
+ if (!canvas) return;
+
+ initPaintCanvas(bodyEl, canvas);
+ },
+});