diff --git a/README.md b/README.md index 051799d..7a3ced9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # CodeSnip — Next-Generation Code & Prompt Manager

- Version + Version Electron MIT License

diff --git a/index.html b/index.html index a2aa599..9a32c8e 100644 --- a/index.html +++ b/index.html @@ -1,296 +1,453 @@ - - - - - - - CodeSnip - Kod ve Prompt Deposu - - - - - - -
-
- CodeSnip - Kod ve Prompt Deposu -
- - -
- - - -
-
- -
- - -
-
-

Tüm Kodlar

-
-
- -
- -
-
- - - -
- -
-
- - - -
-
-
- - -
- -
-
Hızlı Ekleme: +dil kod_içeriği
-
-
-
-
Kopyalandı!
- - - - - - - - - - - + + + + + + + CodeSnip - Kod ve Prompt Deposu + + + + + + +
+
+ CodeSnip +
+ + +
+ + + +
+
+ +
+ + +
+
+

Tüm Kodlar

+
+
+ +
+ +
+
+ + + +
+ +
+
+ + + + +
+
+
+ + +
+ +
+
Hızlı Ekleme: +dil kod_içeriği
+
+
+
+
Kopyalandı!
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/main.js b/main.js index 2f00555..2b0dd83 100644 --- a/main.js +++ b/main.js @@ -1,75 +1,126 @@ -const { app, BrowserWindow, globalShortcut, ipcMain } = require('electron'); -const path = require('path'); - -let mainWindow; - -function createWindow() { - mainWindow = new BrowserWindow({ - width: 1200, - height: 800, - icon: path.join(__dirname, 'icon.ico'), - frame: false, // Custom titlebar için çerçeveyi kaldırdık - webPreferences: { - nodeIntegration: true, - contextIsolation: false - } - }); - - // Menüyü güvenli bir şekilde fonksiyon içinde kaldırıyoruz - mainWindow.setMenu(null); - mainWindow.loadFile('index.html'); - - mainWindow.on('closed', () => { - mainWindow = null; - }); -} - -// 🎛️ Frontend'den (index.html) gelen Pencere Buton Kontrolleri -ipcMain.on('window-minimize', () => { - if (mainWindow) mainWindow.minimize(); -}); - -ipcMain.on('window-maximize', () => { - if (mainWindow) { - if (mainWindow.isMaximized()) { - mainWindow.unmaximize(); - } else { - mainWindow.maximize(); - } - } -}); - -ipcMain.on('window-close', () => { - if (mainWindow) mainWindow.close(); -}); - -// 🎹 Uygulama hazır olduğunda tetiklenen alan -app.whenReady().then(() => { - createWindow(); - - // Global Kısayol Kaydı (Ctrl + Shift + S) - globalShortcut.register('CommandOrControl+Shift+S', () => { - if (mainWindow) { - if (mainWindow.isMinimized()) mainWindow.restore(); - mainWindow.show(); - mainWindow.focus(); - - // Frontend sürecine spotlight sinyali gönder - mainWindow.webContents.send('global-spotlight-trigger'); - } - }); - - app.on('activate', () => { - if (BrowserWindow.getAllWindows().length === 0) createWindow(); - }); -}); - -// Tüm pencereler kapandığında uygulamayı kapat -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') app.quit(); -}); - -// Uygulama tamamen kapatılırken kısayolları hafızadan temizle -app.on('will-quit', () => { - globalShortcut.unregisterAll(); +const { app, BrowserWindow, globalShortcut, ipcMain, dialog } = require('electron'); +const path = require('path'); +const fs = require('fs'); + +let mainWindow; + +function createWindow() { + const isMac = process.platform === 'darwin'; + + mainWindow = new BrowserWindow({ + width: 1200, + height: 800, + icon: path.join(__dirname, 'icon.ico'), + frame: false, + titleBarStyle: isMac ? 'hidden' : 'default', + trafficLightPosition: isMac ? { x: 18, y: 18 } : undefined, + webPreferences: { + nodeIntegration: true, + contextIsolation: false + } + }); + + mainWindow.setMenu(null); + mainWindow.loadFile('index.html'); + // mainWindow.webContents.toggleDevTools(); + + mainWindow.on('closed', () => { + mainWindow = null; + }); +} + +// Pencere Buton Kontrolleri +ipcMain.on('window-minimize', () => { + if (mainWindow) mainWindow.minimize(); +}); + +ipcMain.on('window-maximize', () => { + if (mainWindow) { + if (mainWindow.isMaximized()) { + mainWindow.unmaximize(); + } else { + mainWindow.maximize(); + } + } +}); + +ipcMain.on('window-close', () => { + if (mainWindow) mainWindow.close(); +}); + +// 💾 JSON Dışa Aktarma (Export) Handleri +ipcMain.handle('export-data', async (event, dataString) => { + const { canceled, filePath } = await dialog.showSaveDialog(mainWindow, { + title: 'CodeSnip Verilerini Yedekle', + defaultPath: path.join(app.getPath('downloads'), 'codesnip_backup_26Q3.1.json'), + filters: [ + { name: 'JSON Dosyası', extensions: ['json'] } + ] + }); + + if (canceled || !filePath) { + return { success: false, message: 'Yedekleme iptal edildi.' }; + } + + try { + fs.writeFileSync(filePath, dataString, 'utf-8'); + return { success: true, message: 'Veriler başarıyla yedeklendi!' }; + } catch (error) { + return { success: false, message: `Hata oluştu: ${error.message}` }; + } +}); + +// 📂 EKSİK OLAN KISIM EKLENDİ: JSON İçe Aktarma (Import) Handleri +ipcMain.handle('import-data', async () => { + try { + const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, { + title: 'CodeSnip Yedeği Seçin', + properties: ['openFile'], + filters: [ + { name: 'JSON Dosyaları', extensions: ['json'] }, + { name: 'Tüm Dosyalar', extensions: ['*'] } + ] + }); + + if (canceled || filePaths.length === 0) { + return { success: false, message: 'İçe aktarma iptal edildi.' }; + } + + const filePath = filePaths[0]; + const rawData = fs.readFileSync(filePath, 'utf-8'); + + // Yüklenen dosyanın geçerli bir JSON olup olmadığını doğrula + JSON.parse(rawData); + + return { success: true, data: rawData }; + } catch (error) { + return { success: false, message: 'Seçilen dosya geçerli bir JSON yedeği değil veya okunamadı!' }; + } +}); + +// Uygulama Başlatma Alanı +app.whenReady().then(() => { + createWindow(); + + globalShortcut.register('CommandOrControl+Shift+S', () => { + if (mainWindow) { + if (mainWindow.isMinimized()) mainWindow.restore(); + mainWindow.show(); + mainWindow.focus(); + + mainWindow.webContents.send('global-spotlight-trigger'); + } + }); + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); +}); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') app.quit(); +}); + +app.on('will-quit', () => { + globalShortcut.unregisterAll(); }); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 647dfa5..14f947e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,27 @@ { - "name": "codesnip-app", - "version": "1.0.0", + "name": "CodeSnip-26Q3.1", + "version": "26.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "codesnip-app", - "version": "1.0.0", + "name": "CodeSnip-26Q3.1", + "version": "26.3.1", "devDependencies": { - "electron": "^31.0.0", + "electron": "^43.0.0", "electron-builder": "^26.15.3" } }, + "node_modules/@electron-internal/extract-zip": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@electron-internal/extract-zip/-/extract-zip-1.0.4.tgz", + "integrity": "sha512-Zr1Vs7E9tpCNhZHDAbFVXc2gEVCG9RqPDjrno5+bdgB6LRAuvgyMHJut4NCVyYwtAieapMzc3fiQ3CSTi75ARg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=22.12.0" + } + }, "node_modules/@electron/asar": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz", @@ -116,25 +126,48 @@ } }, "node_modules/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-5.0.0.tgz", + "integrity": "sha512-pjoBpru1KdEtcExBnuHAP1cAc/5faoedw0hzJkL3o4/IJp7HNF1+fbrdxT3gMYRX2oJfvnA/WXeCTVQpYYxyJA==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", + "env-paths": "^3.0.0", + "graceful-fs": "^4.2.11", "progress": "^2.0.3", - "semver": "^6.2.0", + "semver": "^7.6.3", "sumchecker": "^3.0.1" }, "engines": { - "node": ">=12" + "node": ">=22.12.0" }, "optionalDependencies": { - "global-agent": "^3.0.0" + "undici": "^7.24.4" + } + }, + "node_modules/@electron/get/node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@electron/get/node_modules/undici": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.18.1" } }, "node_modules/@electron/notarize": { @@ -677,13 +710,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", - "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", + "version": "24.13.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz", + "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/responselike": { @@ -696,17 +729,6 @@ "@types/node": "*" } }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@xmldom/xmldom": { "version": "0.8.13", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", @@ -1074,16 +1096,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1574,6 +1586,7 @@ "integrity": "sha512-O3zJUFUYHJKgzPqioHxfxzBzlSC1eXCSr79gMSBKBP5AgjjpmrydMsMLotEg9fAJF36vdUncb+4ndRNxoPdlSQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "app-builder-lib": "26.15.3", "builder-util": "26.15.3", @@ -1690,22 +1703,22 @@ } }, "node_modules/electron": { - "version": "31.7.7", - "resolved": "https://registry.npmjs.org/electron/-/electron-31.7.7.tgz", - "integrity": "sha512-HZtZg8EHsDGnswFt0QeV8If8B+et63uD6RJ7I4/xhcXqmTIbI08GoubX/wm+HdY0DwcuPe1/xsgqpmYvjdjRoA==", + "version": "43.0.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-43.0.0.tgz", + "integrity": "sha512-PV60GsWU6qufhuOhw3n+Yix3WPDcqDtBqE8orbEQGQGHEkgp9o/JCPgb7L4vIL0r1HnfPdqSRtboOTqbDkcFDQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^20.9.0", - "extract-zip": "^2.0.1" + "@electron-internal/extract-zip": "^1.0.1", + "@electron/get": "^5.0.0", + "@types/node": "^24.9.0" }, "bin": { - "electron": "cli.js" + "electron": "cli.js", + "install-electron": "install.js" }, "engines": { - "node": ">= 12.20.55" + "node": ">= 22.12.0" } }, "node_modules/electron-builder": { @@ -1999,27 +2012,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2044,16 +2036,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -2129,21 +2111,6 @@ "node": ">= 6" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2298,20 +2265,6 @@ "node": ">=10.0" } }, - "node_modules/global-agent/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/globalthis": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", @@ -2858,19 +2811,6 @@ "node": ">=22.12.0" } }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-api-version": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.1.tgz", @@ -2881,19 +2821,6 @@ "semver": "^7.3.5" } }, - "node_modules/node-api-version/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-gyp": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", @@ -2929,19 +2856,6 @@ "node": ">=20" } }, - "node_modules/node-gyp/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-gyp/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", @@ -3076,13 +2990,6 @@ "url": "https://github.com/sponsors/jet2jet" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3433,13 +3340,16 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-compare": { @@ -3510,19 +3420,6 @@ "node": ">=10" } }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3815,9 +3712,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, @@ -4008,17 +3905,6 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 8ddf3c7..8ccf73b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,15 @@ { - "name": "codesnip-app", - "version": "26Q2.5", + "name": "CodeSnip-26Q3.1", + "version": "26.3.1", + "description": "Geliştiriciler için modern ve performanslı kod yönetim aracı.", + "author": "Selim ", + "homepage": "https://github.com/Light-Bulb-Team/CodeSnip", "main": "main.js", - "license": "MIT", "scripts": { "start": "electron .", - "dist": "electron-builder --windows" + "dist:win": "electron-builder --windows", + "dist:linux": "electron-builder --linux", + "dist:all": "electron-builder --windows --linux" }, "build": { "appId": "com.selim.codesnip", @@ -14,8 +18,19 @@ "target": "portable", "icon": "icon.ico" }, + "linux": { + "target": [ + "tar.gz" + ], + "icon": "icon.png", + "category": "Development" + }, "directories": { "output": "dist" } + }, + "devDependencies": { + "electron": "^43.0.0", + "electron-builder": "^26.15.3" } } diff --git a/renderer.js b/renderer.js index eb013f8..413c0b1 100644 --- a/renderer.js +++ b/renderer.js @@ -1,685 +1,828 @@ -const { ipcRenderer } = require('electron'); - -let currentCategory = 'all'; -let currentLang = 'tr'; - -const defaultInitialSnips = [ - { id: 'snip-1', title: 'HTML Koyu Mod Temeli', category: 'web', code: '\n\n\n

Hello, World!

\n\n', isFavorite: false }, - { id: 'snip-2', title: 'CSS Flexbox Ortalaması', category: 'web', code: '.ortala {\n display: flex;\n justify-content: center;\n align-items: center;\n}', isFavorite: false }, - { id: 'snip-3', title: 'CSS Cam Efekti (Liquid Glass)', category: 'web', code: '.liquid_glass {\n background: rgba(255, 255, 255, 0.05);\n backdrop-filter: blur(10px);\n border-radius: 12px;\n border: 1px solid rgba(255, 255, 255, 0.1);\n}', isFavorite: false }, - { id: 'snip-4', title: 'AI Kod Düzenleyici Promptu', category: 'ai', code: '"Sen uzman bir yazılımcısın. Sana vereceğim kod bloklarındaki hataları bul, optimize et ve en temiz haliyle bana sadece kod olarak ver."', isFavorite: false }, - { id: 'snip-5', title: 'Karakter Simülasyon Promptu', category: 'ai', code: '"Seninle bir rol yapacağız. Sen tamamen bir işletim sistemi (örneğin bilge bir Linux Terminali) gibi davranacaksın."', isFavorite: false }, - { id: 'snip-6', title: 'Otomatik Eritici Malzemeleri', category: 'minecraft', code: '- 2x Sandık (Chest)\n- 2x Huni (Hopper)\n- 1x Fırın (Furnace)', isFavorite: false }, - { id: 'snip-7', title: 'Köylü Zombiyi İyileştirme', category: 'minecraft', code: '1. Zombi köylüye "Halsizlik İksiri" fırlat.\n2. "Büyülü Altın Elma" ile sağ tıkla.', isFavorite: false }, - { id: 'snip-8', title: 'Hızlı Sistem Özeti (Fastfetch)', category: 'unix', code: 'sudo apt install fastfetch && fastfetch', isFavorite: false }, - { id: 'snip-9', title: 'Paket Güncelleme Komutu', category: 'unix', code: 'sudo apt update && sudo apt upgrade', isFavorite: false }, - { id: 'snip-10', title: 'Windows Terminal List Comprehension', category: 'windows_terminal', code: 'numbers = [1, 2, 3, 4, 5]\nsquares = [x**2 for x in numbers]\nprint(squares)', isFavorite: false } -]; - -// Tek bir merkezi DOMContentLoaded yönetimi -document.addEventListener("DOMContentLoaded", () => { - if (!localStorage.getItem('all_snippets_data')) { - localStorage.setItem('all_snippets_data', JSON.stringify(defaultInitialSnips)); - } - loadSettings(); - renderSnips(); - loadNotes(); - - // Sürüm 26Q2.5 Buton Event Listener Bağlantıları - const exportBtn = document.getElementById('exportBtn'); - const importBtn = document.getElementById('importBtn'); - if (exportBtn) exportBtn.addEventListener('click', exportCodeSnipData); - if (importBtn) importBtn.addEventListener('click', importCodeSnipData); - - // Pencere Kontrolleri - const minBtn = document.getElementById('min-btn'); - const maxBtn = document.getElementById('max-btn'); - const closeBtn = document.getElementById('close-btn'); - - if (minBtn) { minBtn.addEventListener('click', () => { ipcRenderer.send('window-minimize'); }); } - if (maxBtn) { maxBtn.addEventListener('click', () => { ipcRenderer.send('window-maximize'); }); } - if (closeBtn) { closeBtn.addEventListener('click', () => { ipcRenderer.send('window-close'); }); } - - // İlk açılışta menüdeki "Tüm Kodlar" butonuna active sınıfı ver - const allCodesBtn = document.querySelector('.sidebar-menu li:first-child'); - if (allCodesBtn) { - allCodesBtn.classList.add('active'); - } -}); - -function renderSnips() { - const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - const container = document.getElementById('snip-list-container'); - if (!container) return; - container.innerHTML = ''; - - const settingGlass = document.getElementById('setting-glass'); - const settingFontSize = document.getElementById('setting-font-size'); - const settingWrap = document.getElementById('setting-wrap'); - - const glassEnabled = settingGlass ? settingGlass.checked : true; - const fontSize = settingFontSize ? settingFontSize.value : '14px'; - const wrapEnabled = settingWrap ? settingWrap.checked : false; - const glassClass = glassEnabled ? 'liquid_glass' : 'no-glass'; - - allSnips.forEach(snip => { - if (currentCategory === 'favorites' && !snip.isFavorite) { - return; - } else if (currentCategory !== 'all' && currentCategory !== 'favorites' && snip.category !== currentCategory) { - return; - } - - const card = document.createElement('div'); - card.className = `snip-card ${glassClass} fade-in`; - card.setAttribute('data-category', snip.category); - - const safeCode = snip.code.replace(/&/g, '&').replace(//g, '>'); - const copyBtnText = currentLang === 'tr' ? 'Kopyala' : 'Copy'; - const deleteBtnText = currentLang === 'tr' ? 'Sil' : 'Delete'; - const editBtnText = currentLang === 'tr' ? 'Düzenle' : 'Edit'; - const shareBtnText = currentLang === 'tr' ? 'Paylaş' : 'Share'; - - const favIcon = snip.isFavorite ? '★' : '☆'; - const favClass = snip.isFavorite ? 'fav-active' : ''; - - const lineCount = snip.code.split('\n').length; - const charCount = snip.code.length; - const linesTxt = currentLang === 'tr' ? 'satır' : 'lines'; - const charsTxt = currentLang === 'tr' ? 'karakter' : 'characters'; - - let langClass = 'language-none'; - if (snip.category === 'web') { - langClass = snip.code.trim().startsWith('<') ? 'language-html' : 'language-css'; - } else if (snip.category === 'unix') { - langClass = 'language-bash'; - } else if (snip.category === 'ai') { - langClass = 'language-javascript'; - } else if (snip.category === 'windows_terminal') { - langClass = 'language-bash'; - } - - card.innerHTML = ` -
-

${snip.title}

-
- - - - - -
-
-
${safeCode}
-
- ${lineCount} ${linesTxt}${charCount} ${charsTxt} -
- `; - container.appendChild(card); - }); - - updateBadges(allSnips); - - if (typeof Prism !== 'undefined') { - Prism.highlightAll(); - } -} - -function kartiKopruyeDonustur(id) { - const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - const snip = allSnips.find(s => s.id === id); - - if (!snip) return; - - const kartVerisi = { - title: snip.title, - code: snip.code, - category: snip.category - }; - - try { - const jsonMetni = JSON.stringify(kartVerisi); - const sifreliKopru = btoa(encodeURIComponent(jsonMetni).replace(/%([0-9A-F]{2})/g, function (match, p1) { - return String.fromCharCode('0x' + p1); - })); - - const tamPaylasimMetni = `import:${sifreliKopru}`; - - navigator.clipboard.writeText(tamPaylasimMetni).then(() => { - alert(currentLang === 'tr' ? "Kod paylaşım köprüsü panoya kopyalandı! Arkadaşına gönderebilirsin." : "Code share bridge copied to clipboard!"); - }); - } catch (err) { - console.error("Paylaşım kodu oluşturulamadı:", err); - } -} - -function hariciKartEkle(title, code, category) { - let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - const newId = 'snip-' + Date.now(); - - allSnips.push({ id: newId, title, category, code, isFavorite: false }); - - localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); - renderSnips(); -} - -window.toggleFavorite = function (id) { - let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - const snip = allSnips.find(s => s.id === id); - if (snip) { - snip.isFavorite = !snip.isFavorite; - localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); - renderSnips(); - } -} - -window.deleteSnip = function (id) { - const confirmMsg = currentLang === 'tr' ? 'Bu kod kartını silmek istediğinize emin misiniz?' : 'Are you sure you want to delete this snippet?'; - if (confirm(confirmMsg)) { - let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - allSnips = allSnips.filter(snip => snip.id !== id); - localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); - renderSnips(); - } -} - -window.editCard = function (cardId) { - const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - const snip = allSnips.find(s => s.id === cardId); - - if (snip) { - document.getElementById('edit-snip-id').value = snip.id; - document.getElementById('new-title').value = snip.title; - document.getElementById('new-category').value = snip.category; - document.getElementById('new-code').value = snip.code; - - document.getElementById('panel-form-title').innerText = currentLang === 'tr' ? 'Kod Kartını Düzenle' : 'Edit Snippet Card'; - document.getElementById('form-save-btn').innerText = currentLang === 'tr' ? 'Güncelle' : 'Update'; - - document.getElementById('add-form-panel').style.display = 'block'; - document.getElementById('new-title').focus(); - } -} - -window.saveSnipAction = function () { - const editId = document.getElementById('edit-snip-id').value; - const title = document.getElementById('new-title').value.trim(); - const category = document.getElementById('new-category').value; - const code = document.getElementById('new-code').value.trim(); - - if (!title || !code) return; - - let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; - - if (editId) { - allSnips = allSnips.map(snip => { - if (snip.id === editId) { - return { ...snip, title, category, code }; - } - return snip; - }); - } else { - const newId = 'snip-' + Date.now(); - allSnips.push({ id: newId, title, category, code, isFavorite: false }); - } - - localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); - closeFormPanel(); - renderSnips(); -} - -window.toggleAddForm = function () { - document.getElementById('edit-snip-id').value = ''; - document.getElementById('new-title').value = ''; - document.getElementById('new-code').value = ''; - document.getElementById('panel-form-title').innerText = currentLang === 'tr' ? 'Yeni Kod Kartı Oluştur' : 'Create New Snippet Card'; - document.getElementById('form-save-btn').innerText = currentLang === 'tr' ? 'Kaydet' : 'Save'; - - const panel = document.getElementById('add-form-panel'); - panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; -} - -window.closeFormPanel = function () { - document.getElementById('add-form-panel').style.display = 'none'; -} - -window.toggleSettingsModal = function () { - const modal = document.getElementById('settings-modal'); - modal.style.display = modal.style.display === 'none' ? 'flex' : 'none'; -} - -window.reloadApp = function () { - window.location.reload(); -} - -function applySettings() { - const settingTheme = document.getElementById('setting-theme'); - const settingGlass = document.getElementById('setting-glass'); - const settingFontSize = document.getElementById('setting-font-size'); - const settingLang = document.getElementById('setting-lang'); - const settingToast = document.getElementById('setting-toast'); - const settingWrap = document.getElementById('setting-wrap'); - - const theme = settingTheme ? settingTheme.value : 'dark'; - const glass = settingGlass ? settingGlass.checked : true; - const fontSize = settingFontSize ? settingFontSize.value : '14px'; - const lang = settingLang ? settingLang.value : 'tr'; - const toastEnabled = settingToast ? settingToast.checked : true; - const wrapEnabled = settingWrap ? settingWrap.checked : false; - - document.body.className = theme === 'dark' ? 'dark-theme' : 'light-theme'; - - const sidebar = document.querySelector('.sidebar'); - const addPanel = document.getElementById('add-form-panel'); - const modalContent = document.querySelector('.modal-content'); - - if (sidebar) { - if (glass) sidebar.classList.add('liquid_glass'); - else sidebar.classList.remove('liquid_glass'); - } - if (addPanel) { - if (glass) addPanel.classList.add('liquid_glass'); - else addPanel.classList.remove('liquid_glass'); - } - if (modalContent) { - if (glass) modalContent.classList.add('liquid_glass'); - else modalContent.classList.remove('liquid_glass'); - } - - currentLang = lang; - document.querySelectorAll('.lang-txt').forEach(el => { - el.innerText = el.getAttribute(`data-${lang}`) || el.innerText; - }); - - const searchInput = document.getElementById('search-input'); - if (searchInput) searchInput.placeholder = lang === 'tr' ? 'Kod veya prompt ara...' : 'Search code or prompt...'; - - const newTitle = document.getElementById('new-title'); - if (newTitle) newTitle.placeholder = lang === 'tr' ? 'Başlık' : 'Title'; - - const newCode = document.getElementById('new-code'); - if (newCode) newCode.placeholder = lang === 'tr' ? 'Kod bloğunu buraya yapıştır...' : 'Paste code block here...'; - - const scratchPad = document.getElementById('scratchpad'); - if (scratchPad) scratchPad.placeholder = lang === 'tr' ? 'Notları buraya karala...' : 'Scratch your notes here...'; - - localStorage.setItem('app_settings', JSON.stringify({ theme, glass, fontSize, lang, toastEnabled, wrapEnabled })); - renderSnips(); -} - -function loadSettings() { - const saved = JSON.parse(localStorage.getItem('app_settings')); - if (saved) { - if (saved.theme && document.getElementById('setting-theme')) document.getElementById('setting-theme').value = saved.theme; - if (saved.glass !== undefined && document.getElementById('setting-glass')) document.getElementById('setting-glass').checked = saved.glass; - if (saved.fontSize && document.getElementById('setting-font-size')) document.getElementById('setting-font-size').value = saved.fontSize; - if (saved.lang && document.getElementById('setting-lang')) document.getElementById('setting-lang').value = saved.lang; - if (saved.toastEnabled !== undefined && document.getElementById('setting-toast')) document.getElementById('setting-toast').checked = saved.toastEnabled; - if (saved.wrapEnabled !== undefined && document.getElementById('setting-wrap')) document.getElementById('setting-wrap').checked = saved.wrapEnabled; - } - applySettings(); -} - -window.copyCode = function (id, event) { - const codeText = document.getElementById(id).innerText; - navigator.clipboard.writeText(codeText); - - const btn = event.target; - btn.innerText = currentLang === 'tr' ? "Kopyalandı!" : "Copied!"; - - const settingToast = document.getElementById('setting-toast'); - const toastEnabled = settingToast ? settingToast.checked : true; - if (toastEnabled) { - const toast = document.getElementById('toast-notification'); - if (toast) { - toast.innerText = currentLang === 'tr' ? "Kod panoya kopyalandı!" : "Code copied to clipboard!"; - toast.classList.add('show'); - setTimeout(() => toast.classList.remove('show'), 2000); - } - } - - setTimeout(() => { - btn.innerText = currentLang === 'tr' ? "Kopyala" : "Copy"; - }, 1500); -} - -window.filterCategory = function (category, element) { - currentCategory = category; - document.getElementById('search-input').value = ''; - document.querySelectorAll('.nav-item').forEach(btn => btn.classList.remove('active')); - element.classList.add('active'); - - const titleMap = { - all: { tr: 'Tüm Kodlar', en: 'All Snippets' }, - favorites: { tr: 'Favori Kodlarım', en: 'Favorite Snippets' }, - web: { tr: 'HTML / CSS Şablonları', en: 'HTML / CSS Templates' }, - ai: { tr: 'Yapay Zeka Promptları', en: 'AI Prompts' }, - minecraft: { tr: 'Minecraft Teknik Notlar', en: 'Minecraft Technical Notes' }, - unix: { tr: 'Unix / Linux Komutları', en: 'Unix / Linux Commands' }, - windows_terminal: { tr: 'Windows Terminal Kodları', en: 'Windows Terminal Snippets' } - }; - - document.getElementById('page-title').innerText = titleMap[category][currentLang]; - renderSnips(); -} - -window.searchSnips = function () { - const query = document.getElementById('search-input').value.toLowerCase(); - document.querySelectorAll('.snip-card').forEach(card => { - const title = card.querySelector('h3').innerText.toLowerCase(); - const code = card.querySelector('code').innerText.toLowerCase(); - - const matchesCategory = (currentCategory === 'all') || - (currentCategory === 'favorites' && card.querySelector('.fav-btn').classList.contains('fav-active')) || - (card.getAttribute('data-category') === currentCategory); - - if (matchesCategory && (title.includes(query) || code.includes(query))) { - card.style.display = 'block'; - } else { - card.style.display = 'none'; - } - }); -} - -function updateBadges(allSnips) { - const categories = ['all', 'favorites', 'web', 'ai', 'minecraft', 'unix', 'windows_terminal']; - categories.forEach(cat => { - let count = 0; - if (cat === 'all') count = allSnips.length; - else if (cat === 'favorites') count = allSnips.filter(s => s.isFavorite).length; - else count = allSnips.filter(s => s.category === cat).length; - - if (document.getElementById(`badge-${cat}`)) { - document.getElementById(`badge-${cat}`).innerText = count; - } - }); -} - -let saveTimeout; -window.saveNotes = function () { - const scratchPad = document.getElementById('scratchpad'); - if (!scratchPad) return; - - clearTimeout(saveTimeout); - const saveStatus = document.getElementById("save-status"); - - saveTimeout = setTimeout(() => { - localStorage.setItem('codesnip_notes', scratchPad.value); - if (saveStatus) { - saveStatus.style.opacity = "1"; - setTimeout(() => { saveStatus.style.opacity = "0"; }, 1200); - } - }, 300); -} - -function loadNotes() { - const scratchPad = document.getElementById('scratchpad'); - if (!scratchPad) return; // 💡 BUGFIX: Eğer not alanı ekranda yoksa çökme, geç! - - const n = localStorage.getItem('codesnip_notes'); - if (n) scratchPad.value = n; -} - -window.clearAllData = function () { - const confirmMsg = currentLang === 'tr' ? 'DİKKAT: Kayıtlı bütün kod blokların ve notların kalıcı olarak silinecektir. Emin misiniz?' : 'WARNING: All saved codes and notes will be deleted permanently. Are you sure?'; - if (confirm(confirmMsg)) { - localStorage.clear(); - reloadApp(); - } -} - -// 🧠 Spotlight Canlı Arama Motoru -let seciliIndeks = -1; -let filtrelenmisKartlar = []; - -const spInputEl = document.getElementById('spotlight-input'); -if (spInputEl) { - spInputEl.addEventListener('input', () => { - const girdi = spInputEl.value.trim().toLowerCase(); - const resultsDiv = document.getElementById('spotlight-results'); - if (!resultsDiv) return; - - if (!girdi || girdi.startsWith('+') || girdi.startsWith('import:')) { - resultsDiv.innerHTML = `
${currentLang === 'tr' ? 'Hızlı Ekleme:' : 'Quick Add:'} +dil kod_içeriği
`; - return; - } - - const cards = document.querySelectorAll('.snip-card'); - filtrelenmisKartlar = []; - - cards.forEach(card => { - const titleElement = card.querySelector('h3'); - const codeElement = card.querySelector('code'); - if (!titleElement || !codeElement) return; - - const originalTitle = titleElement.innerText; - const titleLower = originalTitle.toLowerCase(); - const category = card.getAttribute('data-category') || 'kod'; - const code = codeElement.innerText; - - if (titleLower.includes(girdi) || category.includes(girdi)) { - filtrelenmisKartlar.push({ title: originalTitle, category, code, originalCard: card }); - } - }); - - if (filtrelenmisKartlar.length > 0) { - resultsDiv.classList.remove('spotlight-results-hidden'); - seciliIndeks = 0; - - let listeHtml = '
'; - filtrelenmisKartlar.forEach((item, index) => { - const activeClass = index === 0 ? 'active' : ''; - listeHtml += ` -
- ${item.title} - ${item.category.toUpperCase()} -
- `; - }); - listeHtml += '
'; - - listeHtml += ` -
-
-
- `; - - resultsDiv.innerHTML = listeHtml; - } else { - resultsDiv.innerHTML = `
${currentLang === 'tr' ? 'Eşleşen kod bulunamadı.' : 'No matching code found.'}
`; - } - }); -} - -// 🎹 Klavye Dinleyicisi -window.addEventListener('keydown', (e) => { - const spotlightOverlay = document.getElementById('spotlight-overlay'); - const spotlightInput = document.getElementById('spotlight-input'); - const resultsDiv = document.getElementById('spotlight-results'); - - if (!spotlightOverlay || !spotlightInput) return; - - if (e.ctrlKey && e.code === 'Space') { - e.preventDefault(); - e.stopPropagation(); - - spotlightOverlay.classList.toggle('spotlight-hidden'); - - if (!spotlightOverlay.classList.contains('spotlight-hidden')) { - spotlightInput.value = ''; - if (resultsDiv) { - resultsDiv.innerHTML = `
${currentLang === 'tr' ? 'Hızlı Ekleme:' : 'Quick Add:'} +dil kod_içeriği
`; - } - setTimeout(() => { spotlightInput.focus(); }, 50); - } - return; - } - - if (e.key === 'Escape' && !spotlightOverlay.classList.contains('spotlight-hidden')) { - spotlightOverlay.classList.add('spotlight-hidden'); - return; - } - - if (spotlightOverlay.classList.contains('spotlight-hidden')) return; - - const items = document.querySelectorAll('.spotlight-item'); - - if (e.key === 'ArrowDown' && items.length > 0) { - e.preventDefault(); - items[seciliIndeks].classList.remove('active'); - seciliIndeks = (seciliIndeks + 1) % items.length; - items[seciliIndeks].classList.add('active'); - items[seciliIndeks].scrollIntoView({ block: 'nearest' }); - guncelleSpotlightQuickLook(); - } - else if (e.key === 'ArrowUp' && items.length > 0) { - e.preventDefault(); - items[seciliIndeks].classList.remove('active'); - seciliIndeks = (seciliIndeks - 1 + items.length) % items.length; - items[seciliIndeks].classList.add('active'); - items[seciliIndeks].scrollIntoView({ block: 'nearest' }); - guncelleSpotlightQuickLook(); - } - else if (e.code === 'Space' && items.length > 0) { - const girdi = spotlightInput.value.trim(); - if (!girdi.startsWith('+') && !girdi.startsWith('import:')) { - e.preventDefault(); - const qlPanel = document.getElementById('spotlight-ql'); - if (qlPanel) { - if (qlPanel.style.display === 'flex') { - qlPanel.style.display = 'none'; - } else { - qlPanel.style.display = 'flex'; - guncelleSpotlightQuickLook(); - } - } - } - } - else if (e.key === 'Enter') { - const girdi = spotlightInput.value.trim(); - if (!girdi) return; - - if (girdi.startsWith('+')) { - e.preventDefault(); - const ilkBosluk = girdi.indexOf(' '); - if (ilkBosluk !== -1) { - const kategori = girdi.substring(1, ilkBosluk).toLowerCase(); - const kodIcerigi = girdi.substring(ilkBosluk + 1); - const varsayilanBaslik = `Quick Snippet (${kategori.toUpperCase()})`; - - hariciKartEkle(varsayilanBaslik, kodIcerigi, kategori); - - spotlightInput.value = ''; - spotlightOverlay.classList.add('spotlight-hidden'); - alert(currentLang === 'tr' ? `Başarıyla ${kategori.toUpperCase()} kategorisine eklendi!` : `Successfully added to ${kategori.toUpperCase()}!`); - } else { - alert(currentLang === 'tr' ? "Lütfen formata uygun yazın: +kategori kod" : "Format: +category code"); - } - return; - } - - if (girdi.startsWith('import:')) { - e.preventDefault(); - try { - const sifreliKisim = girdi.replace('import:', ''); - const cozulmusMetin = decodeURIComponent(atob(sifreliKisim).split('').map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }).join('')); - - const gelenKart = JSON.parse(cozulmusMetin); - hariciKartEkle(`${gelenKart.title} (Gelen)`, gelenKart.code, gelenKart.category); - - spotlightInput.value = ''; - spotlightOverlay.classList.add('spotlight-hidden'); - alert(currentLang === 'tr' ? `"${gelenKart.title}" başarıyla listene eklendi!` : `"${gelenKart.title}" successfully imported!`); - } catch (hata) { - alert(currentLang === 'tr' ? "Geçersiz paylaşım kodu!" : "Invalid import code!"); - console.error(hata); - } - return; - } - - e.preventDefault(); - const anaAramaCubugu = document.getElementById('search-input'); - if (anaAramaCubugu) { - if (filtrelenmisKartlar[seciliIndeks]) { - anaAramaCubugu.value = filtrelenmisKartlar[seciliIndeks].title; - } else { - anaAramaCubugu.value = girdi; - } - if (typeof searchSnips === 'function') searchSnips(); - } - - spotlightInput.value = ''; - if (resultsDiv) resultsDiv.classList.add('spotlight-results-hidden'); - spotlightOverlay.classList.add('spotlight-hidden'); - } -}); - -// 🖱️ Dışarı Tıklayınca Kapanma -window.addEventListener('click', (e) => { - const spotlightOverlay = document.getElementById('spotlight-overlay'); - const spotlightWindow = document.querySelector('.spotlight-window'); - - if (spotlightOverlay && !spotlightOverlay.classList.contains('spotlight-hidden')) { - if (spotlightWindow && !spotlightWindow.contains(e.target)) { - spotlightOverlay.classList.add('spotlight-hidden'); - } - } -}); - -function guncelleSpotlightQuickLook() { - const qlPanel = document.getElementById('spotlight-ql'); - const qlCode = document.getElementById('spotlight-ql-code'); - - if (qlPanel && qlPanel.style.display === 'flex' && filtrelenmisKartlar[seciliIndeks]) { - qlCode.innerText = filtrelenmisKartlar[seciliIndeks].code; - if (typeof Prism !== 'undefined') { - Prism.highlightElement(qlCode); - } - } -} - -// Global kısayol dinleyicisi -ipcRenderer.on('global-spotlight-trigger', () => { - const spotlightOverlay = document.getElementById('spotlight-overlay'); - const spotlightInput = document.getElementById('spotlight-input'); - if (spotlightOverlay && spotlightInput) { - spotlightOverlay.classList.remove('spotlight-hidden'); - spotlightInput.value = ''; - spotlightInput.focus(); - } -}); - -// 💾 JSON Dışa Aktarma (Export) -async function exportCodeSnipData() { - try { - const localData = localStorage.getItem('all_snippets_data'); - if (!localData || localData === '[]') { - alert(currentLang === 'tr' ? 'Yedeklenecek herhangi bir kod veya prompt bulunamadı!' : 'No snippets found to backup!'); - return; - } - const result = await ipcRenderer.invoke('export-data', localData); - if (result.success) alert(result.message); - } catch (error) { - alert('Yedekleme başlatılamadı.'); - } -} - -// 📂 JSON İçe Aktarma (Import) -async function importCodeSnipData() { - const onay = confirm(currentLang === 'tr' ? "Mevcut verilerinizin üzerine yazılacak. Emin misiniz?" : "This will overwrite your existing data. Are you sure?"); - if (!onay) return; - - try { - const result = await ipcRenderer.invoke('import-data'); - if (result.success) { - localStorage.setItem('all_snippets_data', result.data); - alert(currentLang === 'tr' ? 'Verileriniz başarıyla geri yüklendi! Uygulama yenilenecektir.' : 'Data successfully restored! App will reload.'); - window.location.reload(); - } else { - alert(result.message); - } - } catch (error) { - alert('İçe aktarma sırasında bir hata oluştu.'); - } +const { ipcRenderer } = require('electron'); + +let currentCategory = 'all'; +let currentLang = 'tr'; + +const defaultInitialSnips = [ + { id: 'snip-1', title: 'HTML Koyu Mod Temeli', category: 'web', code: '\n\n\n

Hello, World!

\n\n', isFavorite: false }, + { id: 'snip-2', title: 'CSS Flexbox Ortalaması', category: 'web', code: '.ortala {\n display: flex;\n justify-content: center;\n align-items: center;\n}', isFavorite: false }, + { id: 'snip-3', title: 'CSS Cam Efekti (Liquid Glass)', category: 'web', code: '.liquid_glass {\n background: rgba(255, 255, 255, 0.05);\n backdrop-filter: blur(10px);\n border-radius: 12px;\n border: 1px solid rgba(255, 255, 255, 0.1);\n}', isFavorite: false }, + { id: 'snip-4', title: 'AI Kod Düzenleyici Promptu', category: 'ai', code: '"Sen uzman bir yazılımcısın. Sana vereceğim kod bloklarındaki hataları bul, optimize et ve en temiz haliyle bana sadece kod olarak ver."', isFavorite: false }, + { id: 'snip-5', title: 'Karakter Simülasyon Promptu', category: 'ai', code: '"Seninle bir rol yapacağız. Sen tamamen bir işletim sistemi (örneğin bilge bir Linux Terminali) gibi davranacaksın."', isFavorite: false }, + { id: 'snip-6', title: 'Otomatik Eritici Malzemeleri', category: 'minecraft', code: '- 2x Sandık (Chest)\n- 2x Huni (Hopper)\n- 1x Fırın (Furnace)', isFavorite: false }, + { id: 'snip-7', title: 'Köylü Zombiyi İyileştirme', category: 'minecraft', code: '1. Zombi köylüye "Halsizlik İksiri" fırlat.\n2. "Büyülü Altın Elma" ile sağ tıkla.', isFavorite: false }, + { id: 'snip-8', title: 'Hızlı Sistem Özeti (Fastfetch)', category: 'unix', code: 'sudo apt install fastfetch && fastfetch', isFavorite: false }, + { id: 'snip-9', title: 'Paket Güncelleme Komutu', category: 'unix', code: 'sudo apt update && sudo apt upgrade', isFavorite: false }, + { id: 'snip-10', title: 'Windows Terminal List Comprehension', category: 'windows_terminal', code: 'numbers = [1, 2, 3, 4, 5]\nsquares = [x**2 for x in numbers]\nprint(squares)', isFavorite: false } +]; + +// Tek bir merkezi DOMContentLoaded yönetimi +document.addEventListener("DOMContentLoaded", () => { + if (!localStorage.getItem('all_snippets_data')) { + localStorage.setItem('all_snippets_data', JSON.stringify(defaultInitialSnips)); + } + + if (!localStorage.getItem('codesnip_categories')) { + const defaultCategories = [ + { id: 'web', name: { tr: 'HTML / CSS', en: 'HTML / CSS' }, icon: 'bi-globe' }, + { id: 'ai', name: { tr: 'AI Promptları', en: 'AI Prompts' }, icon: 'bi-robot' }, + { id: 'minecraft', name: { tr: 'Minecraft', en: 'Minecraft' }, icon: 'bi-box' }, + { id: 'unix', name: { tr: 'Unix', en: 'Unix' }, icon: 'bi-terminal' }, + { id: 'windows_terminal', name: { tr: 'Windows Terminal', en: 'Windows Terminal' }, icon: 'bi-pc-display' } + ]; + localStorage.setItem('codesnip_categories', JSON.stringify(defaultCategories)); + } + + loadSettings(); + renderCategories(); + renderSnips(); + loadNotes(); + + // Pencere Kontrolleri + const minBtn = document.getElementById('min-btn'); + const maxBtn = document.getElementById('max-btn'); + const closeBtn = document.getElementById('close-btn'); + + if (minBtn) minBtn.addEventListener('click', () => ipcRenderer.send('window-minimize')); + if (maxBtn) maxBtn.addEventListener('click', () => ipcRenderer.send('window-maximize')); + if (closeBtn) closeBtn.addEventListener('click', () => ipcRenderer.send('window-close')); + + const allCodesBtn = document.querySelector('.sidebar-menu li:first-child'); + if (allCodesBtn) allCodesBtn.classList.add('active'); + + // ⚡ IPC Dinleyici Bellek Temizliği (Global Spotlight) + ipcRenderer.removeAllListeners('global-spotlight-trigger'); + ipcRenderer.on('global-spotlight-trigger', () => { + const spotlightOverlay = document.getElementById('spotlight-overlay'); + const spotlightInput = document.getElementById('spotlight-input'); + if (spotlightOverlay && spotlightInput) { + spotlightOverlay.classList.remove('spotlight-hidden'); + spotlightInput.value = ''; + spotlightInput.focus(); + } + }); + + // ⚡ Slider Dinleyicileri (Tek seferlik ve bellek dostu yükleme) + document.querySelectorAll('input[type="range"]').forEach(slider => { + const update = () => { + const percent = ((slider.value - slider.min) / (slider.max - slider.min)) * 100; + slider.style.setProperty('--slider-progress', percent + '%'); + }; + update(); + slider.addEventListener('input', update); + }); + + const blurSlider = document.getElementById("setting-glass-blur"); + const blurValue = document.getElementById("blur-value"); + if (blurSlider && blurValue) { + blurSlider.addEventListener("input", () => { + blurValue.textContent = blurSlider.value; + }); + } +}); + +function renderSnips() { + const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + const container = document.getElementById('snip-list-container'); + if (!container) return; + container.innerHTML = ''; + + const settingGlass = document.getElementById('setting-glass'); + const settingFontSize = document.getElementById('setting-font-size'); + const settingWrap = document.getElementById('setting-wrap'); + + const glassEnabled = settingGlass ? settingGlass.checked : true; + const fontSize = settingFontSize ? settingFontSize.value : '14px'; + const wrapEnabled = settingWrap ? settingWrap.checked : false; + const glassClass = glassEnabled ? 'liquid_glass' : 'no-glass'; + + const fragment = document.createDocumentFragment(); + + allSnips.forEach(snip => { + if (currentCategory === 'favorites' && !snip.isFavorite) return; + if (currentCategory !== 'all' && currentCategory !== 'favorites' && snip.category !== currentCategory) return; + + const card = document.createElement('div'); + card.className = `snip-card ${glassClass} fade-in`; + card.setAttribute('data-category', snip.category); + + const safeCode = snip.code.replace(/&/g, '&').replace(//g, '>'); + const copyBtnText = currentLang === 'tr' ? 'Kopyala' : 'Copy'; + const deleteBtnText = currentLang === 'tr' ? 'Sil' : 'Delete'; + const editBtnText = currentLang === 'tr' ? 'Düzenle' : 'Edit'; + const shareBtnText = currentLang === 'tr' ? 'Paylaş' : 'Share'; + + const favIcon = snip.isFavorite ? '★' : '☆'; + const favClass = snip.isFavorite ? 'fav-active' : ''; + + const lineCount = snip.code.split('\n').length; + const charCount = snip.code.length; + const linesTxt = currentLang === 'tr' ? 'satır' : 'lines'; + const charsTxt = currentLang === 'tr' ? 'karakter' : 'characters'; + + let langClass = 'language-none'; + if (snip.category === 'web') { + langClass = snip.code.trim().startsWith('<') ? 'language-html' : 'language-css'; + } else if (snip.category === 'unix' || snip.category === 'windows_terminal') { + langClass = 'language-bash'; + } else if (snip.category === 'ai') { + langClass = 'language-javascript'; + } + + card.innerHTML = ` +
+

${snip.title}

+
+ + + + + +
+
+
${safeCode}
+
+ ${lineCount} ${linesTxt}${charCount} ${charsTxt} +
+ `; + fragment.appendChild(card); + }); + + container.appendChild(fragment); + updateBadges(allSnips); + + if (typeof Prism !== 'undefined') { + Prism.highlightAll(); + } +} + +function renderCategories() { + const categories = JSON.parse(localStorage.getItem('codesnip_categories')) || []; + const container = document.getElementById('dynamic-categories'); + const selectCategory = document.getElementById('new-category'); + + if (!container || !selectCategory) return; + + container.innerHTML = ''; + selectCategory.innerHTML = ''; + + const fragment = document.createDocumentFragment(); + + categories.forEach(cat => { + const catName = cat.name[currentLang] || cat.name.tr; + + const btn = document.createElement('button'); + btn.className = `nav-item ${currentCategory === cat.id ? 'active' : ''}`; + btn.id = `nav-${cat.id}`; + btn.onclick = function () { filterCategory(cat.id, this); }; + + btn.innerHTML = ` + ${catName} + 0 + `; + + const deleteBtn = document.createElement('i'); + deleteBtn.className = 'bi bi-trash'; + deleteBtn.style.marginLeft = 'auto'; + deleteBtn.style.cursor = 'pointer'; + deleteBtn.style.paddingLeft = '10px'; + deleteBtn.onclick = function (e) { deleteCategory(e, cat.id); }; + + btn.appendChild(deleteBtn); + fragment.appendChild(btn); + + const option = document.createElement('option'); + option.value = cat.id; + option.innerText = catName; + selectCategory.appendChild(option); + }); + + container.appendChild(fragment); + const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + updateBadges(allSnips); +} + +function kartiKopruyeDonustur(id) { + const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + const snip = allSnips.find(s => s.id === id); + + if (!snip) return; + + const kartVerisi = { title: snip.title, code: snip.code, category: snip.category }; + + try { + const jsonMetni = JSON.stringify(kartVerisi); + const sifreliKopru = btoa(encodeURIComponent(jsonMetni).replace(/%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode('0x' + p1))); + const tamPaylasimMetni = `import:${sifreliKopru}`; + + navigator.clipboard.writeText(tamPaylasimMetni).then(() => { + alert(currentLang === 'tr' ? "Kod paylaşım köprüsü panoya kopyalandı! Arkadaşına gönderebilirsin." : "Code share bridge copied to clipboard!"); + }); + } catch (err) { + console.error("Paylaşım kodu oluşturulamadı:", err); + } +} + +function hariciKartEkle(title, code, category) { + let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + const newId = 'snip-' + Date.now(); + allSnips.push({ id: newId, title, category, code, isFavorite: false }); + localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); + renderSnips(); +} + +window.toggleFavorite = function (id) { + let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + const snip = allSnips.find(s => s.id === id); + if (snip) { + snip.isFavorite = !snip.isFavorite; + localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); + renderSnips(); + } +}; + +window.deleteSnip = function (id) { + const confirmMsg = currentLang === 'tr' ? 'Bu kod kartını silmek istediğinize emin misiniz?' : 'Are you sure you want to delete this snippet?'; + if (confirm(confirmMsg)) { + let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + allSnips = allSnips.filter(snip => snip.id !== id); + localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); + renderSnips(); + } +}; + +window.editCard = function (cardId) { + const allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + const snip = allSnips.find(s => s.id === cardId); + + if (snip) { + document.getElementById('edit-snip-id').value = snip.id; + document.getElementById('new-title').value = snip.title; + document.getElementById('new-category').value = snip.category; + document.getElementById('new-code').value = snip.code; + + document.getElementById('panel-form-title').innerText = currentLang === 'tr' ? 'Kod Kartını Düzenle' : 'Edit Snippet Card'; + document.getElementById('form-save-btn').innerText = currentLang === 'tr' ? 'Güncelle' : 'Update'; + + document.getElementById('add-form-panel').style.display = 'block'; + document.getElementById('new-title').focus(); + } +}; + +window.saveSnipAction = function () { + const editId = document.getElementById('edit-snip-id').value; + const title = document.getElementById('new-title').value.trim(); + const category = document.getElementById('new-category').value; + const code = document.getElementById('new-code').value.trim(); + + if (!title || !code) return; + + let allSnips = JSON.parse(localStorage.getItem('all_snippets_data')) || []; + + if (editId) { + allSnips = allSnips.map(snip => snip.id === editId ? { ...snip, title, category, code } : snip); + } else { + const newId = 'snip-' + Date.now(); + allSnips.push({ id: newId, title, category, code, isFavorite: false }); + } + + localStorage.setItem('all_snippets_data', JSON.stringify(allSnips)); + closeFormPanel(); + renderSnips(); +}; + +window.toggleAddForm = function () { + document.getElementById('edit-snip-id').value = ''; + document.getElementById('new-title').value = ''; + document.getElementById('new-code').value = ''; + document.getElementById('panel-form-title').innerText = currentLang === 'tr' ? 'Yeni Kod Kartı Oluştur' : 'Create New Snippet Card'; + document.getElementById('form-save-btn').innerText = currentLang === 'tr' ? 'Kaydet' : 'Save'; + + const panel = document.getElementById('add-form-panel'); + panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; +}; + +window.closeFormPanel = function () { + document.getElementById('add-form-panel').style.display = 'none'; +}; + +window.toggleSettingsModal = function () { + const modal = document.getElementById('settings-modal'); + modal.style.display = modal.style.display === 'none' ? 'flex' : 'none'; +}; + +window.reloadApp = function () { + window.location.reload(); +}; + +function applySettings() { + const settingTheme = document.getElementById('setting-theme'); + const settingGlass = document.getElementById('setting-glass'); + const settingFontSize = document.getElementById('setting-font-size'); + const settingLang = document.getElementById('setting-lang'); + const settingToast = document.getElementById('setting-toast'); + const settingWrap = document.getElementById('setting-wrap'); + + const settingGlassBlur = document.getElementById('setting-glass-blur'); + const settingGlassOpacity = document.getElementById('setting-glass-opacity'); + const settingThemeColor = document.getElementById('setting-theme-color'); + const settingBgType = document.getElementById('setting-bg-type'); + const settingBgColor = document.getElementById('setting-bg-color'); + const settingBgImage = document.getElementById('setting-bg-image'); + + const theme = settingTheme ? settingTheme.value : 'dark'; + const glass = settingGlass ? settingGlass.checked : true; + const fontSize = settingFontSize ? settingFontSize.value : '14px'; + const lang = settingLang ? settingLang.value : 'tr'; + const toastEnabled = settingToast ? settingToast.checked : true; + const wrapEnabled = settingWrap ? settingWrap.checked : false; + + const glassBlur = settingGlassBlur ? settingGlassBlur.value : '16'; + const glassOpacity = settingGlassOpacity ? settingGlassOpacity.value : '5'; + const themeColor = settingThemeColor ? settingThemeColor.value : '#007acc'; + const bgType = settingBgType ? settingBgType.value : 'color'; + const bgColor = settingBgColor ? settingBgColor.value : '#1e1e1e'; + const bgImage = (settingBgImage && settingBgImage.value.trim() !== '') ? settingBgImage.value : 'abstract_beta.png'; + + document.body.className = theme === 'dark' ? 'dark-theme' : 'light-theme'; + const root = document.documentElement; + root.style.setProperty('--theme-color', themeColor); + root.style.setProperty('--glow-color', `${themeColor}33`); + + const bgColorContainer = document.getElementById('bg-color-container'); + const bgImageContainer = document.getElementById('bg-image-container'); + + if (bgType === 'image') { + if (bgColorContainer) bgColorContainer.style.display = 'none'; + if (bgImageContainer) bgImageContainer.style.display = 'flex'; + + if (bgImage.trim() !== '') { + document.body.style.backgroundImage = `url('${bgImage}')`; + document.body.style.backgroundSize = 'cover'; + document.body.style.backgroundPosition = 'center'; + document.body.style.backgroundAttachment = 'fixed'; + } else { + document.body.style.backgroundImage = 'none'; + document.body.style.backgroundColor = '#1e1e1e'; + } + } else { + if (bgColorContainer) bgColorContainer.style.display = 'flex'; + if (bgImageContainer) bgImageContainer.style.display = 'none'; + + document.body.style.backgroundImage = 'none'; + document.body.style.backgroundColor = bgColor; + } + + const sidebar = document.querySelector('.sidebar'); + const addPanel = document.getElementById('add-form-panel'); + const modalContent = document.querySelector('.modal-content'); + + if (sidebar) sidebar.classList.toggle('liquid_glass', glass); + if (addPanel) addPanel.classList.toggle('liquid_glass', glass); + if (modalContent) modalContent.classList.toggle('liquid_glass', glass); + + if (glass) { + document.body.classList.add('liquid-glass'); + root.style.setProperty('--glass-blur', `${glassBlur}px`); + root.style.setProperty('--glass-opacity', (glassOpacity / 100)); + } else { + document.body.classList.remove('liquid-glass'); + root.style.setProperty('--glass-blur', '0px'); + root.style.setProperty('--glass-opacity', '0'); + } + + currentLang = lang; + document.querySelectorAll('.lang-txt').forEach(el => { + el.innerText = el.getAttribute(`data-${lang}`) || el.innerText; + }); + + const searchInput = document.getElementById('search-input'); + if (searchInput) searchInput.placeholder = lang === 'tr' ? 'Kod veya prompt ara...' : 'Search code or prompt...'; + + localStorage.setItem('app_settings', JSON.stringify({ + theme, glass, fontSize, lang, toastEnabled, wrapEnabled, + glassBlur, glassOpacity, themeColor, bgType, bgColor, bgImage + })); + + renderSnips(); + + const bValEl = document.getElementById("blur-value"); + const oValEl = document.getElementById("opacity-value"); + if (bValEl) bValEl.textContent = glassBlur; + if (oValEl) oValEl.textContent = glassOpacity; +} + +function loadSettings() { + const defaultBackgroundImage = 'abstract_beta.png'; + let saved = JSON.parse(localStorage.getItem('app_settings')); + + if (!saved) { + saved = { + theme: 'dark', glass: true, fontSize: '14px', lang: 'tr', + toastEnabled: true, wrapEnabled: false, glassBlur: '16', + glassOpacity: '5', themeColor: '#007acc', bgType: 'image', + bgColor: '#1e1e1e', bgImage: defaultBackgroundImage + }; + localStorage.setItem('app_settings', JSON.stringify(saved)); + } + + if (saved.theme && document.getElementById('setting-theme')) document.getElementById('setting-theme').value = saved.theme; + if (saved.glass !== undefined && document.getElementById('setting-glass')) document.getElementById('setting-glass').checked = saved.glass; + if (saved.fontSize && document.getElementById('setting-font-size')) document.getElementById('setting-font-size').value = saved.fontSize; + if (saved.lang && document.getElementById('setting-lang')) document.getElementById('setting-lang').value = saved.lang; + if (saved.toastEnabled !== undefined && document.getElementById('setting-toast')) document.getElementById('setting-toast').checked = saved.toastEnabled; + if (saved.wrapEnabled !== undefined && document.getElementById('setting-wrap')) document.getElementById('setting-wrap').checked = saved.wrapEnabled; + + if (saved.glassBlur && document.getElementById('setting-glass-blur')) document.getElementById('setting-glass-blur').value = saved.glassBlur; + if (saved.glassOpacity && document.getElementById('setting-glass-opacity')) document.getElementById('setting-glass-opacity').value = saved.glassOpacity; + if (saved.themeColor && document.getElementById('setting-theme-color')) document.getElementById('setting-theme-color').value = saved.themeColor; + + if (saved.bgType && document.getElementById('setting-bg-type')) document.getElementById('setting-bg-type').value = saved.bgType; + if (saved.bgColor && document.getElementById('setting-bg-color')) document.getElementById('setting-bg-color').value = saved.bgColor; + if (document.getElementById('setting-bg-image')) { + document.getElementById('setting-bg-image').value = saved.bgImage || defaultBackgroundImage; + } + + applySettings(); + renderCategories(); +} + +window.copyCode = function (id, event) { + const codeElem = document.getElementById(id); + if (!codeElem) return; + + navigator.clipboard.writeText(codeElem.innerText); + + const btn = event.target; + btn.innerText = currentLang === 'tr' ? "Kopyalandı!" : "Copied!"; + + const settingToast = document.getElementById('setting-toast'); + const toastEnabled = settingToast ? settingToast.checked : true; + if (toastEnabled) { + const toast = document.getElementById('toast-notification'); + if (toast) { + toast.innerText = currentLang === 'tr' ? "Kod panoya kopyalandı!" : "Code copied to clipboard!"; + toast.classList.add('show'); + setTimeout(() => toast.classList.remove('show'), 2000); + } + } + + setTimeout(() => { + btn.innerText = currentLang === 'tr' ? "Kopyala" : "Copy"; + }, 1500); +}; + +window.filterCategory = function (category, element) { + currentCategory = category; + const searchInput = document.getElementById('search-input'); + if (searchInput) searchInput.value = ''; + + document.querySelectorAll('.nav-item').forEach(btn => btn.classList.remove('active')); + if (element) element.classList.add('active'); + + const titleMap = { + all: { tr: 'Tüm Kodlar', en: 'All Snippets' }, + favorites: { tr: 'Favori Kodlarım', en: 'Favorite Snippets' } + }; + + const pageTitle = document.getElementById('page-title'); + if (pageTitle) { + if (category === 'all' || category === 'favorites') { + pageTitle.innerText = titleMap[category][currentLang]; + } else { + const categories = JSON.parse(localStorage.getItem('codesnip_categories')) || []; + const cat = categories.find(c => c.id === category); + if (cat) pageTitle.innerText = cat.name[currentLang] || cat.name.tr; + } + } + renderSnips(); +}; + +window.searchSnips = function () { + const query = document.getElementById('search-input').value.toLowerCase(); + document.querySelectorAll('.snip-card').forEach(card => { + const title = card.querySelector('h3').innerText.toLowerCase(); + const code = card.querySelector('code').innerText.toLowerCase(); + + const matchesCategory = (currentCategory === 'all') || + (currentCategory === 'favorites' && card.querySelector('.fav-btn').classList.contains('fav-active')) || + (card.getAttribute('data-category') === currentCategory); + + card.style.display = (matchesCategory && (title.includes(query) || code.includes(query))) ? 'block' : 'none'; + }); +}; + +function updateBadges(allSnips) { + const badgeAll = document.getElementById(`badge-all`); + const badgeFav = document.getElementById(`badge-favorites`); + + if (badgeAll) badgeAll.innerText = allSnips.length; + if (badgeFav) badgeFav.innerText = allSnips.filter(s => s.isFavorite).length; + + const categories = JSON.parse(localStorage.getItem('codesnip_categories')) || []; + categories.forEach(cat => { + const count = allSnips.filter(s => s.category === cat.id).length; + const bEl = document.getElementById(`badge-${cat.id}`); + if (bEl) bEl.innerText = count; + }); +} + +let saveTimeout; +window.saveNotes = function () { + const scratchPad = document.getElementById('scratchpad'); + if (!scratchPad) return; + + clearTimeout(saveTimeout); + const saveStatus = document.getElementById("save-status"); + + saveTimeout = setTimeout(() => { + localStorage.setItem('codesnip_notes', scratchPad.value); + if (saveStatus) { + saveStatus.style.opacity = "1"; + setTimeout(() => { saveStatus.style.opacity = "0"; }, 1200); + } + }, 300); +}; + +function loadNotes() { + const scratchPad = document.getElementById('scratchpad'); + if (!scratchPad) return; + const n = localStorage.getItem('codesnip_notes'); + if (n) scratchPad.value = n; +} + +window.clearAllData = function () { + const confirmMsg = currentLang === 'tr' ? 'DİKKAT: Kayıtlı bütün kod blokların ve notların kalıcı olarak silinecektir. Emin misiniz?' : 'WARNING: All saved codes and notes will be deleted permanently. Are you sure?'; + if (confirm(confirmMsg)) { + localStorage.clear(); + reloadApp(); + } +}; + +// 🧠 Spotlight Canlı Arama Motoru +let seciliIndeks = -1; +let filtrelenmisKartlar = []; + +const spInputEl = document.getElementById('spotlight-input'); +if (spInputEl) { + spInputEl.addEventListener('input', () => { + const girdi = spInputEl.value.trim().toLowerCase(); + const resultsDiv = document.getElementById('spotlight-results'); + if (!resultsDiv) return; + + if (!girdi || girdi.startsWith('+') || girdi.startsWith('import:')) { + resultsDiv.innerHTML = `
${currentLang === 'tr' ? 'Hızlı Ekleme:' : 'Quick Add:'} +dil kod_içeriği
`; + return; + } + + const cards = document.querySelectorAll('.snip-card'); + filtrelenmisKartlar = []; + + cards.forEach(card => { + const titleElement = card.querySelector('h3'); + const codeElement = card.querySelector('code'); + if (!titleElement || !codeElement) return; + + const originalTitle = titleElement.innerText; + const titleLower = originalTitle.toLowerCase(); + const category = card.getAttribute('data-category') || 'kod'; + const code = codeElement.innerText; + + if (titleLower.includes(girdi) || category.includes(girdi)) { + filtrelenmisKartlar.push({ title: originalTitle, category, code, originalCard: card }); + } + }); + + if (filtrelenmisKartlar.length > 0) { + resultsDiv.classList.remove('spotlight-results-hidden'); + seciliIndeks = 0; + + let listeHtml = '
'; + filtrelenmisKartlar.forEach((item, index) => { + const activeClass = index === 0 ? 'active' : ''; + listeHtml += ` +
+ ${item.title} + ${item.category.toUpperCase()} +
+ `; + }); + listeHtml += '
'; + + resultsDiv.innerHTML = listeHtml; + } else { + resultsDiv.innerHTML = `
${currentLang === 'tr' ? 'Eşleşen kod bulunamadı.' : 'No matching code found.'}
`; + } + }); +} + +// 🎹 Klavye Dinleyicisi +window.addEventListener('keydown', (e) => { + const spotlightOverlay = document.getElementById('spotlight-overlay'); + const spotlightInput = document.getElementById('spotlight-input'); + const resultsDiv = document.getElementById('spotlight-results'); + + if (!spotlightOverlay || !spotlightInput) return; + + if (e.ctrlKey && e.code === 'Space') { + e.preventDefault(); + e.stopPropagation(); + + spotlightOverlay.classList.toggle('spotlight-hidden'); + + if (!spotlightOverlay.classList.contains('spotlight-hidden')) { + spotlightInput.value = ''; + if (resultsDiv) { + resultsDiv.innerHTML = `
${currentLang === 'tr' ? 'Hızlı Ekleme:' : 'Quick Add:'} +dil kod_içeriği
`; + } + setTimeout(() => { spotlightInput.focus(); }, 50); + } + return; + } + + if (e.key === 'Escape' && !spotlightOverlay.classList.contains('spotlight-hidden')) { + spotlightOverlay.classList.add('spotlight-hidden'); + return; + } + + if (spotlightOverlay.classList.contains('spotlight-hidden')) return; + + const items = document.querySelectorAll('.spotlight-item'); + + if (e.key === 'ArrowDown' && items.length > 0) { + e.preventDefault(); + items[seciliIndeks].classList.remove('active'); + seciliIndeks = (seciliIndeks + 1) % items.length; + items[seciliIndeks].classList.add('active'); + items[seciliIndeks].scrollIntoView({ block: 'nearest' }); + guncelleSpotlightQuickLook(); + } + else if (e.key === 'ArrowUp' && items.length > 0) { + e.preventDefault(); + items[seciliIndeks].classList.remove('active'); + seciliIndeks = (seciliIndeks - 1 + items.length) % items.length; + items[seciliIndeks].classList.add('active'); + items[seciliIndeks].scrollIntoView({ block: 'nearest' }); + guncelleSpotlightQuickLook(); + } + else if (e.code === 'Space' && items.length > 0) { + const girdi = spotlightInput.value.trim(); + if (!girdi.startsWith('+') && !girdi.startsWith('import:')) { + e.preventDefault(); + const qlPanel = document.getElementById('spotlight-ql'); + if (qlPanel) { + qlPanel.style.display = qlPanel.style.display === 'flex' ? 'none' : 'flex'; + guncelleSpotlightQuickLook(); + } + } + } + else if (e.key === 'Enter') { + const girdi = spotlightInput.value.trim(); + if (!girdi) return; + + if (girdi.startsWith('+')) { + e.preventDefault(); + const ilkBosluk = girdi.indexOf(' '); + if (ilkBosluk !== -1) { + const kategori = girdi.substring(1, ilkBosluk).toLowerCase(); + const kodIcerigi = girdi.substring(ilkBosluk + 1); + const varsayilanBaslik = `Quick Snippet (${kategori.toUpperCase()})`; + + hariciKartEkle(varsayilanBaslik, kodIcerigi, kategori); + + spotlightInput.value = ''; + spotlightOverlay.classList.add('spotlight-hidden'); + alert(currentLang === 'tr' ? `Başarıyla ${kategori.toUpperCase()} kategorisine eklendi!` : `Successfully added to ${kategori.toUpperCase()}!`); + } else { + alert(currentLang === 'tr' ? "Lütfen formata uygun yazın: +kategori kod" : "Format: +category code"); + } + return; + } + + if (girdi.startsWith('import:')) { + e.preventDefault(); + try { + const sifreliKisim = girdi.replace('import:', ''); + const cozulmusMetin = decodeURIComponent(atob(sifreliKisim).split('').map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join('')); + + const gelenKart = JSON.parse(cozulmusMetin); + hariciKartEkle(`${gelenKart.title} (Gelen)`, gelenKart.code, gelenKart.category); + + spotlightInput.value = ''; + spotlightOverlay.classList.add('spotlight-hidden'); + alert(currentLang === 'tr' ? `"${gelenKart.title}" başarıyla listene eklendi!` : `"${gelenKart.title}" successfully imported!`); + } catch (hata) { + alert(currentLang === 'tr' ? "Geçersiz paylaşım kodu!" : "Invalid import code!"); + console.error(hata); + } + return; + } + + e.preventDefault(); + const anaAramaCubugu = document.getElementById('search-input'); + if (anaAramaCubugu) { + anaAramaCubugu.value = filtrelenmisKartlar[seciliIndeks] ? filtrelenmisKartlar[seciliIndeks].title : girdi; + if (typeof searchSnips === 'function') searchSnips(); + } + + spotlightInput.value = ''; + if (resultsDiv) resultsDiv.classList.add('spotlight-results-hidden'); + spotlightOverlay.classList.add('spotlight-hidden'); + } +}); + +// 🖱️ Dışarı Tıklayınca Kapanma +window.addEventListener('click', (e) => { + const spotlightOverlay = document.getElementById('spotlight-overlay'); + const spotlightWindow = document.querySelector('.spotlight-window'); + + if (spotlightOverlay && !spotlightOverlay.classList.contains('spotlight-hidden')) { + if (spotlightWindow && !spotlightWindow.contains(e.target)) { + spotlightOverlay.classList.add('spotlight-hidden'); + } + } +}); + +function guncelleSpotlightQuickLook() { + const qlPanel = document.getElementById('spotlight-ql'); + const qlCode = document.getElementById('spotlight-ql-code'); + + if (qlPanel && qlPanel.style.display === 'flex' && filtrelenmisKartlar[seciliIndeks]) { + qlCode.innerText = filtrelenmisKartlar[seciliIndeks].code; + if (typeof Prism !== 'undefined') { + Prism.highlightElement(qlCode); + } + } +} + +// 💾 JSON Dışa Aktarma (Export) - Çift tıklama korumalı +window.exportCodeSnipData = async function () { + try { + const localData = localStorage.getItem('all_snippets_data'); + if (!localData || localData === '[]') { + alert(currentLang === 'tr' ? 'Yedeklenecek herhangi bir kod veya prompt bulunamadı!' : 'No snippets found to backup!'); + return; + } + const result = await ipcRenderer.invoke('export-data', localData); + if (result && result.success) alert(result.message); + } catch (error) { + console.error("Export hatası:", error); + } +}; + +// 📂 JSON İçe Aktarma (Import) - Çift pencere çakışması engellendi +window.importCodeSnipData = async function () { + const onay = confirm(currentLang === 'tr' ? "Mevcut verilerinizin üzerine yazılacak. Emin misiniz?" : "This will overwrite your existing data. Are you sure?"); + if (!onay) return; + + try { + const result = await ipcRenderer.invoke('import-data'); + if (result && result.success) { + localStorage.setItem('all_snippets_data', result.data); + alert(currentLang === 'tr' ? 'Verileriniz başarıyla geri yüklendi! Uygulama yenilenecektir.' : 'Data successfully restored! App will reload.'); + window.location.reload(); + } else if (result && result.message) { + alert(result.message); + } + } catch (error) { + console.error("Import hatası:", error); + alert('İçe aktarma sırasında bir hata oluştu.'); + } +}; + +function addCategoryProcess() { + const nameTr = document.getElementById('cat-name-tr').value; + const icon = document.getElementById('cat-icon-select').value; + + if (!nameTr) return; + + let categories = JSON.parse(localStorage.getItem('codesnip_categories')) || []; + + categories.push({ + id: nameTr.toLowerCase().replace(/\s+/g, '-'), + name: { tr: nameTr, en: nameTr }, + icon: icon + }); + + localStorage.setItem('codesnip_categories', JSON.stringify(categories)); + document.getElementById('category-modal').style.display = 'none'; + renderCategories(); +} + +function deleteCategory(event, categoryId) { + event.stopPropagation(); + + if (!confirm("Bu kategoriyi silmek istediğine emin misin?")) return; + + let categories = JSON.parse(localStorage.getItem('codesnip_categories')) || []; + const updatedCategories = categories.filter(c => c.id !== categoryId); + + localStorage.setItem('codesnip_categories', JSON.stringify(updatedCategories)); + renderCategories(); +} + +function toggleAboutModal() { + const modal = document.getElementById('about-modal'); + if (!modal) return; + modal.style.display = (modal.style.display === 'none' || modal.style.display === '') ? 'flex' : 'none'; } \ No newline at end of file diff --git a/style.css b/style.css index 6ad2f71..8c1a321 100644 --- a/style.css +++ b/style.css @@ -1,1230 +1,1985 @@ -* { - box-sizing: border-box; -} - -* { - box-sizing: border-box; -} - -body { - background-color: #0f141c; - color: #f5f6f9; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; - margin: 0; - height: 100vh; - overflow: hidden; - transition: background-color 0.3s, color 0.3s; - - /* Body üzerinde ekstra padding veya position bırakmıyoruz, tertemiz */ - display: flex; - flex-direction: column; -} - -/* GÜNCELLENEN ÜST BAR TASARIMI */ -.electron-titlebar { - width: 100%; - height: 45px; - background-color: #0a0d14; - /* Sol menünün rengiyle bütünlük sağlandı */ - display: flex; - align-items: center; - justify-content: space-between; - - /* padding-right değerini 0 yaparak butonları sağ köşeye tamamen sıfırlıyoruz: */ - padding: 0 0 0 20px; - - user-select: none; - z-index: 9999; -} - -/* Pencereyi sürüklenebilir yapan alan */ -.titlebar-drag-zone { - flex: 1; - height: 100%; - display: flex; - align-items: center; - font-size: 12px; - color: #8e8e93; - font-weight: 500; - /* İşte sürükleme sihrimiz: */ - -webkit-app-region: drag; -} - -/* Sağ üstteki Windows butonlarının altına gelen boşluk alan. - Burada sürüklemeyi kapatıyoruz ki butonlar kilitlenmesin! */ -.window-controls-spacer { - width: 140px; - /* Windows buton genişliği */ - height: 100%; - -webkit-app-region: no-drag; -} - -/* ANA İÇERİK KONTEYNERI */ -.app-container { - display: flex; - flex: 1; - /* Ekranın kalan tüm alt kısmını doldurmasını sağlar */ - height: calc(100vh - 45px); -} - -/* ================= SIDEBAR (SOL MENÜ) TASARIMI ================= */ -.sidebar { - width: 250px; - /* Yeni bileşenler için genişliği biraz rahatlattık */ - background-color: #0a0d14; - /* Arka plandan bir tık daha koyu asil sol menü */ - border-right: 1px solid rgba(255, 255, 255, 0.04); - padding: 20px; - display: flex; - flex-direction: column; - transition: all 0.3s; -} - -/* YENİ LOGO VE ICO GÖRÜNÜMÜ */ -.logo-container { - display: flex; - align-items: center; - gap: 12px; - margin-bottom: 30px; - padding-left: 5px; -} - -.logo-img { - width: 26px; - height: 26px; - object-fit: contain; -} - -.logo-text { - font-size: 20px; - color: #ffffff; - font-weight: 700; - letter-spacing: -0.5px; -} - -nav { - display: flex; - flex-direction: column; - gap: 8px; -} - -.nav-item { - background: transparent; - color: #8e8e93; - border: none; - padding: 12px; - text-align: left; - border-radius: 8px; - font-size: 14px; - cursor: pointer; - transition: all 0.2s; - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; -} - -.nav-item:hover, -.nav-item.active { - background-color: rgba(255, 255, 255, 0.06); - color: #ffffff; -} - -/* ================= SAĞ İÇERİK ALANI ================= */ -.main-content { - flex: 1; - padding: 30px; - overflow-y: auto; - background-color: #0f141c; - /* Mat ve derin koyu tema tabanı */ - transition: background-color 0.3s; -} - -header h2 { - margin-top: 0; - font-size: 24px; - font-weight: 600; - color: #ffffff; -} - -.snip-list { - display: flex; - flex-direction: column; - gap: 20px; -} - -/* Kod Kartları Genel Yapısı */ -.snip-card { - border-radius: 12px; - padding: 20px; - transition: transform 0.2s, box-shadow 0.2s, background-color 0.3s, border-color 0.3s; -} - -.snip-card:hover { - transform: translateY(-2px); - box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5); -} - -.snip-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 12px; -} - -.snip-header h3 { - margin: 0; - font-size: 16px; - font-weight: 500; - color: #e4e6eb; -} - -/* Butonlar */ -.copy-btn { - background-color: rgba(255, 255, 255, 0.07); - color: #e4e6eb; - border: 1px solid rgba(255, 255, 255, 0.05); - padding: 6px 14px; - border-radius: 6px; - font-size: 13px; - cursor: pointer; - transition: all 0.2s; -} - -.copy-btn:hover { - background-color: #007aff; - color: white; - border-color: #007aff; -} - -.card-actions { - display: flex; - gap: 8px; -} - -.delete-btn { - background-color: rgba(255, 61, 48, 0.15); - color: #ff453a; - border: 1px solid rgba(255, 61, 48, 0.2); - padding: 6px 12px; - border-radius: 6px; - font-size: 12px; - cursor: pointer; - transition: all 0.2s; -} - -.delete-btn:hover { - background-color: #ff453a; - color: white; -} - -/* Kod Editörü / Blokları Görünümü */ -pre { - background-color: #080b11; - /* Kodların içi tam bir terminal gibi simsiyah ve net */ - padding: 15px; - border-radius: 8px; - margin: 0; - overflow-x: auto; - border: 1px solid rgba(255, 255, 255, 0.03); - transition: background-color 0.3s, border-color 0.3s; -} - -code { - font-family: 'SFMono-Regular', Consolas, "Liberation Mono", Menlo, monospace; - color: #e0e0e0; - font-size: 14px; -} - -/* ================= MODERN SIVI CAM (LIQUID GLASS) EFEKTİ ================= */ -.liquid_glass { - background: rgba(255, 255, 255, 0.03) !important; - backdrop-filter: blur(16px) !important; - -webkit-backdrop-filter: blur(16px) !important; - border: 1px solid rgba(255, 255, 255, 0.06) !important; -} - -/* ================= MAT GÖRÜNÜM (CAM EFEKTİ KAPALIYKEN) ================= */ -.no-glass { - background-color: #161e2b !important; - /* Cam kapanınca asil grafit/lacivert mat ton */ - backdrop-filter: none !important; - -webkit-backdrop-filter: none !important; - border: 1px solid rgba(255, 255, 255, 0.05) !important; -} - -.no-glass-sidebar { - background-color: #0a0d14 !important; - backdrop-filter: none !important; - -webkit-backdrop-filter: none !important; - border-right: 1px solid rgba(255, 255, 255, 0.05) !important; -} - -/* ================= BİLEŞENLER VE TASARIM ÖGELERİ ================= */ - -/* Arama Çubuğu */ -.search-container { - margin: 20px 0; - width: 100%; -} - -#search-input { - width: 100%; - padding: 12px 20px; - background: rgba(255, 255, 255, 0.04); - border: 1px solid rgba(255, 255, 255, 0.06); - border-radius: 8px; - color: white; - font-size: 15px; - outline: none; - transition: all 0.2s; -} - -#search-input:focus { - border-color: #007aff; - background: rgba(255, 255, 255, 0.07); - box-shadow: 0 0 12px rgba(0, 122, 255, 0.25); -} - -#search-input::placeholder { - color: #545456; -} - -/* Sayı Rozetleri (Badge) */ -.badge { - background-color: rgba(255, 255, 255, 0.06); - color: #007aff; - font-size: 11px; - font-weight: bold; - padding: 2px 8px; - border-radius: 10px; -} - -.nav-item.active .badge { - background-color: #007aff; - color: white; -} - -/* YENİ GELİŞMİŞ KALICI NOTLAR ALANI */ -.scratchpad-area { - margin-top: auto; - /* Sol menünün en altına itilmesini sağlar */ - border-top: 1px solid rgba(255, 255, 255, 0.05); - padding-top: 20px; -} - -.scratchpad-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; -} - -.scratchpad-area h3 { - font-size: 12px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.5px; - margin: 0; - color: #8e8e93; -} - -#save-status { - font-size: 11px; - color: #30d158; - opacity: 0; - transition: opacity 0.3s; -} - -#scratchpad { - width: 100%; - height: 130px; - background: rgba(0, 0, 0, 0.2); - border: 1px solid rgba(255, 255, 255, 0.04); - border-radius: 8px; - color: #ffffff; - padding: 12px; - font-family: inherit; - font-size: 13px; - resize: none; - /* Düzgün durması için manuel büyütmeyi kapattık */ - outline: none; - transition: border-color 0.2s; -} - -#scratchpad:focus { - border-color: #007aff; -} - -/* Header ve Ekleme Paneli */ -.header-actions { - display: flex; - justify-content: space-between; - align-items: center; - gap: 20px; - margin: 20px 0; -} - -.header-actions .search-container { - margin: 0; - flex: 1; -} - -.add-toggle-btn { - background-color: #007aff; - color: white; - border: none; - padding: 12px 20px; - border-radius: 8px; - font-size: 14px; - font-weight: 500; - cursor: pointer; - white-space: nowrap; - transition: background 0.2s; -} - -.add-toggle-btn:hover { - background-color: #0056b3; -} - -.add-panel { - border-radius: 12px; - padding: 25px; - margin-bottom: 25px; - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.6); - background-color: #161e2b; - border: 1px solid rgba(255, 255, 255, 0.05); -} - -.add-panel h3 { - margin-top: 0; - margin-bottom: 20px; - font-size: 18px; - font-weight: 600; -} - -.form-group { - display: flex; - gap: 15px; - margin-bottom: 15px; -} - -.form-group input, -.form-group select, -.form-group textarea { - background: rgba(0, 0, 0, 0.25); - border: 1px solid rgba(255, 255, 255, 0.06); - border-radius: 6px; - color: white; - padding: 10px 15px; - font-size: 14px; - outline: none; -} - -.form-group input { - flex: 2; -} - -.form-group select { - flex: 1; - background-color: #080b11; -} - -.form-group textarea { - width: 100%; - height: 120px; - resize: vertical; -} - -.form-buttons { - display: flex; - gap: 10px; - justify-content: flex-end; -} - -.save-btn { - background-color: #30d158; - color: white; - border: none; - padding: 10px 20px; - border-radius: 6px; - cursor: pointer; - font-weight: 500; -} - -.cancel-btn { - background-color: #3a3a3c; - color: white; - border: none; - padding: 10px 20px; - border-radius: 6px; - cursor: pointer; -} - -/* Sol Menü Footer (Ayarlar Butonu) */ -.sidebar-footer { - padding-top: 15px; - margin-top: 15px; -} - -.settings-toggle-btn { - width: 100%; - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.05); - color: #8e8e93; - padding: 10px; - border-radius: 8px; - cursor: pointer; - font-size: 14px; - transition: all 0.2s; -} - -.settings-toggle-btn:hover { - background: rgba(255, 255, 255, 0.08); - color: white; -} - -/* ================= YENİ GELİŞMİŞ AYARLAR PENCERESİ ================= */ -.modal-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.75); - display: flex; - justify-content: center; - align-items: center; - z-index: 9999; -} - -.modal-content { - width: 540px; - max-height: 85vh; - overflow-y: auto; - padding: 30px; - border-radius: 16px; - background-color: #161e2b; - border: 1px solid rgba(255, 255, 255, 0.06); - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.7); -} - -.modal-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 25px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); - padding-bottom: 15px; -} - -.modal-header h2 { - margin: 0; - font-size: 20px; - font-weight: 600; -} - -.settings-section { - margin-bottom: 25px; -} - -.settings-section h4 { - color: #007aff; - margin: 0 0 12px 0; - font-size: 12px; - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.setting-item { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 14px; - background: rgba(255, 255, 255, 0.01); - padding: 12px; - border-radius: 8px; - border: 1px solid rgba(255, 255, 255, 0.02); -} - -.setting-text h5 { - margin: 0; - font-size: 14px; - font-weight: 500; - color: #ffffff; -} - -.setting-item p { - font-size: 12px; - color: #8e8e93; - margin: 4px 0 0 0; -} - -.setting-item select { - background: #080b11; - color: white; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 6px 12px; - border-radius: 6px; - outline: none; -} - -/* Yenileme ve Tehlike Butonları */ -.reload-btn { - background-color: #ff9500; - color: white; - border: none; - padding: 8px 16px; - border-radius: 6px; - cursor: pointer; - font-size: 13px; - font-weight: 500; - transition: background 0.2s; -} - -.reload-btn:hover { - background-color: #e08200; -} - -.danger-btn { - background-color: rgba(255, 59, 48, 0.15); - color: #ff453a; - border: 1px solid rgba(255, 59, 48, 0.2); - padding: 8px 16px; - border-radius: 6px; - cursor: pointer; - font-size: 13px; - transition: all 0.2s; -} - -.danger-btn:hover { - background-color: #ff3b30; - color: white; -} - -/* Toggle Switch */ -.switch { - position: relative; - display: inline-block; - width: 46px; - height: 24px; -} - -.switch input { - opacity: 0; - width: 0; - height: 0; -} - -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #3a3a3c; - transition: .3s; - border-radius: 24px; -} - -.slider:before { - position: absolute; - content: ""; - height: 18px; - width: 18px; - left: 3px; - bottom: 3px; - background-color: white; - transition: .3s; - border-radius: 50%; -} - -input:checked+.slider { - background-color: #30d158; -} - -input:checked+.slider:before { - transform: translateX(22px); -} - -/* AKILLI TOAST BİLDİRİM SİSTEMİ */ -.toast { - position: fixed; - bottom: 25px; - right: 25px; - background-color: #30d158; - color: white; - padding: 12px 24px; - border-radius: 8px; - font-size: 14px; - font-weight: 500; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4); - opacity: 0; - transform: translateY(20px); - transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); - pointer-events: none; - z-index: 10000; -} - -.toast.show { - opacity: 1; - transform: translateY(0); -} - -/* ================= JİLET GİBİ AÇIK TEMA DÜZENİ ================= */ -.light-theme { - background-color: #c3faf9 !important; - color: #000000 !important; -} - -.light-theme .main-content { - background-color: #c3faf9 !important; -} - -.light-theme .sidebar { - background-color: rgba(232, 230, 230, 0.8) !important; - border-right: 1px solid rgba(0, 0, 0, 0.1); -} - -.light-theme .no-glass-sidebar { - background-color: #e8e6e6 !important; - border-right: 1px solid rgba(0, 0, 0, 0.15) !important; -} - -.light-theme .snip-card.liquid_glass { - background: rgba(232, 230, 230, 0.6) !important; - border: 1px solid rgba(0, 0, 0, 0.1) !important; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); -} - -.light-theme .snip-card.no-glass { - background-color: #e8e6e6 !important; - border: 1px solid rgba(0, 0, 0, 0.15) !important; -} - -.light-theme h2, -.light-theme h3, -.light-theme strong, -.light-theme .nav-item, -.light-theme .sidebar-footer button, -.light-theme .scratchpad-area h3, -.light-theme .add-panel h3, -.light-theme .logo-text, -.light-theme .modal-content h2, -.light-theme .settings-section h5 { - color: #000000 !important; -} - -.light-theme .nav-item:hover, -.light-theme .nav-item.active { - background-color: rgba(0, 0, 0, 0.08); - color: #000000 !important; -} - -.light-theme .snip-card pre { - background-color: #ffffff !important; - border: 1px solid rgba(0, 0, 0, 0.1) !important; -} - -.light-theme .snip-card pre code { - color: #000000 !important; -} - -.light-theme #search-input, -.light-theme .form-group input, -.light-theme .form-group textarea, -.light-theme .scratchpad-area textarea { - background: #ffffff !important; - color: #000000 !important; - border: 1px solid rgba(0, 0, 0, 0.15) !important; -} - -.light-theme #search-input::placeholder { - color: #555555 !important; -} - -.light-theme .form-group select, -.light-theme .setting-item select { - background: #ffffff !important; - color: #000000 !important; - border: 1px solid rgba(0, 0, 0, 0.15) !important; -} - -.light-theme .modal-content { - background-color: #e8e6e6 !important; - border: 1px solid rgba(0, 0, 0, 0.15) !important; -} - -.light-theme .setting-item p { - color: #444444 !important; -} - -.light-theme .copy-btn { - background-color: #007aff !important; - color: #ffffff !important; -} - -/* ================= ANIMASYONLAR ================= */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(8px); - } - - to { - opacity: 1; - transform: translateY(0); - } -} - -.fade-in { - animation: fadeIn 0.3s ease forwards; -} - -/* Favori Buton Tasarımı */ -.fav-btn { - background: transparent; - border: none; - font-size: 18px; - color: #666; - cursor: pointer; - transition: color 0.2s, transform 0.1s; -} - -.fav-btn:hover { - transform: scale(1.2); - color: #ffcc00; -} - -.fav-btn.fav-active { - color: #ffcc00; - /* Aktifken altın sarısı parlasın */ -} - -/* Düzenle Buton Tasarımı */ -.edit-btn { - background-color: #ffcc00; - color: #ffffff; - border: none; - padding: 4px 10px; - border-radius: 4px; - cursor: pointer; - font-size: 12px; - transition: background 0.2s; -} - -.edit-btn:hover { - background-color: #ffde5b; -} - -/* Butonların Kapsayıcısı */ -.window-controls { - display: flex; - height: 100%; - align-items: center; - /* ⚠️ Sürükleme alanının butonları kilitlemesini engellemek için kesinlikle no-drag: */ - -webkit-app-region: no-drag !important; - position: relative; - z-index: 10000; - /* Sürükleme alanının tamamen üstüne çıkmasını sağlıyoruz */ -} - -/* Ortak Buton Özellikleri */ -.control-btn { - background: transparent; - border: none; - height: 45px; - /* Üst barın yüksekliği olan 45px ile tam eşit olmalı (CSS'te yukarısı 45px yapılmış) */ - width: 46px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - -webkit-app-region: no-drag !important; - /* Butonların kendisinde de tıklamayı garantiye alıyoruz */ - transition: background-color 0.15s ease; -} - -/* Minimize ve Maximize Hover Efekti (Hafif beyazımsı par things) */ -.minimize-btn:hover, -.maximize-btn:hover { - background-color: rgba(255, 255, 255, 0.1); -} - -/* Kapatma Butonu Hover Efekti (Klasik Windows Kırmızısı) */ -.close-btn:hover { - background-color: #e81123 !important; -} - -/* SVG İkonlarının Boyutu */ -.control-btn svg { - transition: fill 0.15s ease; -} - -.titlebar-logo { - width: 20px; - height: 20px; - margin-right: 8px; -} - -/* Tüm ekranı kaplayan karartma ve bulanıklaştırma katmanı */ -#spotlight-overlay { - position: fixed; - top: 45px; - /* Başlık çubuğunun tam bittiği yer */ - left: 0; - width: 100vw; - height: calc(100vh - 45px); - /* 45px ile eşitlendi, taşma yapmaz */ - background: rgba(0, 0, 0, 0.4); - /* Camı öne çıkarmak için arka planı biraz hafiflettik */ - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - z-index: 9998; - display: flex; - justify-content: center; - align-items: flex-start; - padding-top: 15vh; - transition: opacity 0.2s ease; -} - -/* Gizliyken görünmez yap */ -.spotlight-hidden { - opacity: 0; - pointer-events: none; -} - -/* 🧪 Ortada yüzen LIQUID GLASS (Cam Efektli) Ana Pencere */ -.spotlight-window { - width: 650px; - - /* Cam Efekti Ayarları */ - background: rgba(25, 25, 25, 0.45); - /* Şeffaflığı artırarak arkadaki kodların buğulu görünmesini sağladık */ - backdrop-filter: blur(20px) saturate(160%); - /* İçerideki camın kendi bulanıklığı ve renk canlılığı */ - -webkit-backdrop-filter: blur(20px) saturate(160%); - - /* İnce Parlayan Cam Çerçevesi (Üst ve sol kenarlar ışık alır) */ - border: 1px solid rgba(255, 255, 255, 0.08); - border-top: 1px solid rgba(255, 255, 255, 0.18); - border-left: 1px solid rgba(255, 255, 255, 0.15); - - border-radius: 14px; - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.6), - inset 0 1px 0 0 rgba(255, 255, 255, 0.1); - /* İç tarafa hafif parlama çizgisi */ - overflow: hidden; - font-family: sans-serif; -} - -/* Arama çubuğunun kapsayıcısı */ -.spotlight-search-wrapper { - display: flex; - align-items: center; - padding: 16px 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.06); - background: rgba(255, 255, 255, 0.02); - /* Üst alan için çok hafif bir kontrast */ -} - -/* Arama ikonu */ -.spotlight-icon { - color: rgba(255, 255, 255, 0.5); - /* İkon rengini cam temasına uydurduk */ - font-size: 18px; - margin-right: 14px; -} - -/* Input'un kendisi */ -#spotlight-input { - width: 100%; - background: transparent; - border: none; - outline: none; - color: #fff; - font-size: 18px; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); - /* Yazının cam üzerinde parlamasını ve net okunmasını sağlar */ -} - -#spotlight-input::placeholder { - color: rgba(255, 255, 255, 0.35); - /* Placeholder rengini biraz daha yumuşattık */ -} - -/* Alt sonuçlar ve ipuçları alanı */ -#spotlight-results { - padding: 12px; - max-height: 300px; - overflow-y: auto; - background: rgba(0, 0, 0, 0.2); - /* Sonuçlar alt panelde hafifçe ayrılsın */ - border-top: 1px solid rgba(255, 255, 255, 0.03); -} - -/* v26Q2.5 — Spotlight Boş Durum / İpucu Alanı Düzenlemesi */ -.spotlight-hint { - width: 100%; - padding: 10px !important; - /* Yazının etrafına nefes aldıracak boşluk */ - color: rgba(255, 255, 255, 0.4); - font-size: 13px; -} - -.spotlight-hint span { - color: #00adb5; - /* Projenin canlı neon mavisini buraya da taşıdık */ - font-weight: 500; -} - -/* --- Paylaş Butonu ve Kart Aksiyonları Düzenlemesi --- */ -.card-actions { - display: flex; - gap: 6px; - /* Butonların arasındaki boşluk */ - align-items: center; -} - -/* Paylaş Butonunun Genel Tasarımı */ -.share-btn { - background: rgba(255, 193, 7, 0.15); - /* Hafif şeffaf sarı/turuncu tonu */ - border: 1px solid rgba(255, 193, 7, 0.3); - color: #ffc107; - padding: 4px 10px; - border-radius: 6px; - font-size: 12px; - cursor: pointer; - font-family: inherit; - transition: all 0.2s ease; - display: flex; - align-items: center; - gap: 4px; - /* İkon ve metin arası boşluk */ -} - -/* Paylaş Butonuna Hover (Fareyle üzerine gelince) Efekti */ -.share-btn:hover { - background: #ffc107; - color: #111; - /* Koyu temada yazı net okunsun diye */ - box-shadow: 0 0 8px rgba(255, 193, 7, 0.4); -} - -/* Eğer butonların genel bir stili varsa (edit-btn, copy-btn gibi) uyum sağlaması için */ -.card-actions button { - outline: none; - font-weight: 500; -} - -/* --- Spotlight İçindeki Geri Bildirimler İçin Küçük İpucu Tasarımı (Opsiyonel) --- */ -#spotlight-input::placeholder { - color: rgba(255, 255, 255, 0.4); -} - -/* Animasyonlu Yeni Kart Geçişi (fade-in sınıfı için) */ -.fade-in { - animation: fadeInAnim 0.3s ease-out forwards; -} - -@keyframes fadeInAnim { - from { - opacity: 0; - transform: translateY(10px); - } - - to { - opacity: 1; - transform: translateY(0); - } -} - -.version-26Q2-5 { - margin-top: 20px; - padding: 15px; - background: rgba(255, 255, 255, 0.02); - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 10px; -} - -.backup-buttons { - display: flex; - gap: 10px; - margin-top: 10px; -} - -.backup-buttons .glass-btn { - flex: 1; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - color: #fff; - padding: 10px; - border-radius: 6px; - cursor: pointer; - font-family: 'Segoe UI', sans-serif; - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - transition: all 0.3s ease; -} - -/* v26Q2.5 Özel Parlama Efektleri */ -#exportBtn:hover { - background: rgba(0, 173, 181, 0.15); - border-color: #00adb5; - box-shadow: 0 0 10px rgba(0, 173, 181, 0.3); -} - -#importBtn:hover { - background: rgba(255, 87, 34, 0.15); - border-color: #ff5722; - box-shadow: 0 0 10px rgba(255, 87, 34, 0.3); -} - -/* ========================================================================== - 🔍 26Q2.5 — macOS Spotlight Alt Panel ve Quick Look (Önizleme) CSS Eklemeleri - ========================================================================== */ - -/* Sonuç alanı devreye girdiğinde alt paneli yan yana yerleşime hazırlar */ -#spotlight-results { - padding: 0 !important; - /* Eski padding'i ezerek sıfırlıyoruz */ - max-height: 400px !important; - /* Listenin rahatça sığması için yükselttik */ - background: rgba(0, 0, 0, 0.25) !important; - border-top: 1px solid rgba(255, 255, 255, 0.06) !important; - display: flex; - /* Sol tarafta liste, sağ tarafta önizleme olmasını sağlar */ - overflow: hidden !important; -} - -/* Sol taraftaki kod başlıkları listesi */ -.spotlight-list { - flex: 1; - max-height: 380px; - overflow-y: auto; - padding: 8px 0; - border-right: 1px solid rgba(255, 255, 255, 0.06); -} - -/* Listelenen her bir arama sonucu satırı */ -.spotlight-item { - padding: 10px 18px; - display: flex; - justify-content: space-between; - align-items: center; - cursor: pointer; - color: rgba(255, 255, 255, 0.7); - font-size: 13px; - transition: background 0.15s ease, color 0.15s ease; -} - -/* Klavyeden Aşağı/Yukarı ok tuşlarıyla seçilen veya mouse ile üzerine gelinen satır */ -.spotlight-item:hover, -.spotlight-item.active { - background: rgba(255, 255, 255, 0.08); - color: #ffffff; -} - -/* Satırların sağındaki dil/kategori etiketleri */ -.item-category { - font-size: 10px; - font-weight: 600; - background: rgba(255, 255, 255, 0.1); - padding: 2px 6px; - border-radius: 4px; - color: rgba(255, 255, 255, 0.5); - letter-spacing: 0.5px; -} - -.spotlight-item.active .item-category { - background: #00adb5; - /* Seçili satırdaki kategori senin neon mavisi rengini alır */ - color: #fff; -} - -/* 📑 SAĞ TARAFTAKİ MINI QUICK LOOK (ÖNİZLEME) PANELİ */ -.spotlight-quick-preview { - flex: 1.3; - /* Kod içeriği rahat okunsun diye sağ tarafı bir tık daha geniş yaptık */ - padding: 15px; - background: rgba(0, 0, 0, 0.2); - display: none; - /* JavaScript'ten Space tuşuna basılana kadar gizli kalır */ - flex-direction: column; - max-height: 380px; - border-left: 1px solid rgba(0, 0, 0, 0.2); -} - -/* Önizleme panelinin içindeki kod alanı */ -.spotlight-quick-preview pre { - margin: 0 !important; - padding: 10px !important; - background: transparent !important; - /* Çift arka plan olmasın diye temizledik */ - border: none !important; - width: 100%; - height: 100%; - overflow: auto; -} - -.spotlight-quick-preview pre code { - font-size: 12px !important; - line-height: 1.5; - white-space: pre-wrap; - /* Kodların taşmasını engeller, alt satıra katlar */ -} - -/* İsteğe bağlı: Listenin scrollbar'ını şıklaştırmak için */ -.spotlight-list::-webkit-scrollbar, -.spotlight-quick-preview pre::-webkit-scrollbar { - width: 6px; - height: 6px; -} - -.spotlight-list::-webkit-scrollbar-thumb, -.spotlight-quick-preview pre::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.1); - border-radius: 3px; -} - -/* ================= v26Q2.5 — MODERN VE İNCE SCROLLBAR TASARIMI ================= */ - -/* 1. Kod Blokları (pre) ve Tüm Uygulama İçin Genel Scrollbar Genişliği/Yüksekliği */ -::-webkit-scrollbar { - width: 8px; - /* Dikey kaydırma çubuğu kalınlığı */ - height: 8px; - /* Yatay kaydırma çubuğu kalınlığı (O beyaz çubukları inceltir) */ -} - -/* 2. Kaydırma Çubuğunun Arkasındaki Yol (Track) */ -::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0.2); - /* Hafif şeffaf siyah, arka planla bütünleşir */ - border-radius: 10px; -} - -/* 3. Kaydırılan Tutamaç Çubuğu (Thumb) */ -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.12); - /* Beyaz yerine çok hafif, şık bir gri ton */ - border-radius: 10px; - border: 2px solid transparent; - /* İçeride biraz daha estetik durması için */ - transition: background-color 0.2s ease; -} - -/* 4. Fareyle Çubuğun Üzerine Gelindiğinde Parlama Efekti (Hover) */ -::-webkit-scrollbar-thumb:hover { - background: rgba(0, 173, 181, 0.4); - /* Üzerine gelince projenin imza neon mavisine/turkuazına göz kırpar */ -} - -/* 5. Köşe Birleşim Noktaları (Corner) */ -::-webkit-scrollbar-corner { - background: transparent; -} +* { + box-sizing: border-box; +} + +* { + box-sizing: border-box; +} + +body { + /* Eski rengi yedek olarak tuttuk, hemen arkasına resmi bağlıyoruz */ + background: #0f141c url('abstract.png') no-repeat center center fixed; + background-size: cover; + /* Resmi ekrana tam yayar, boşluk bırakmaz */ + + color: #f5f6f9; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + margin: 0; + height: 100vh; + overflow: hidden; + transition: background-color 0.3s, color 0.3s; + + display: flex; + flex-direction: column; +} + +/* Liquid Glass aktifken arka plana pürüzsüzlük katacak katman */ +body.liquid-glass::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: inherit; + filter: blur(2px); + /* Arka plan görselini hafifçe yumuşatmak için */ + z-index: -1; +} + +.border-highlight { + border-color: var(--theme-color) !important; +} + +/* GÜNCELLENEN ÜST BAR TASARIMI */ +.electron-titlebar { + width: 100%; + height: 45px; + background-color: #0a0d14; + /* Sol menünün rengiyle bütünlük sağlandı */ + display: flex; + align-items: center; + justify-content: space-between; + + /* padding-right değerini 0 yaparak butonları sağ köşeye tamamen sıfırlıyoruz: */ + padding: 0 0 0 20px; + + user-select: none; + z-index: 9999; +} + +/* Pencereyi sürüklenebilir yapan alan */ +.titlebar-drag-zone { + flex: 1; + height: 100%; + display: flex; + align-items: center; + font-size: 12px; + color: #8e8e93; + font-weight: 500; + /* İşte sürükleme sihrimiz: */ + -webkit-app-region: drag; +} + +/* Sağ üstteki Windows butonlarının altına gelen boşluk alan. + Burada sürüklemeyi kapatıyoruz ki butonlar kilitlenmesin! */ +.window-controls-spacer { + width: 140px; + /* Windows buton genişliği */ + height: 100%; + -webkit-app-region: no-drag; +} + +/* ANA İÇERİK KONTEYNERI */ +.app-container { + display: flex; + flex: 1; + /* Ekranın kalan tüm alt kısmını doldurmasını sağlar */ + height: calc(100vh - 45px); +} + +/* ================= SIDEBAR (SOL MENÜ) TASARIMI ================= */ +.sidebar { + width: 250px; + /* Yeni bileşenler için genişliği biraz rahatlattık */ + background-color: #0a0d14; + /* Arka plandan bir tık daha koyu asil sol menü */ + border-right: 1px solid rgba(255, 255, 255, 0.04); + padding: 20px; + display: flex; + flex-direction: column; + transition: all 0.3s; +} + +/* YENİ LOGO VE ICO GÖRÜNÜMÜ */ +.logo-container { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 30px; + padding-left: 5px; +} + +.logo-img { + width: 26px; + height: 26px; + object-fit: contain; +} + +.logo-text { + font-size: 20px; + color: #ffffff; + font-weight: 700; + letter-spacing: -0.5px; +} + +nav { + display: flex; + flex-direction: column; + gap: 8px; +} + +.nav-item { + background: transparent; + color: #8e8e93; + border: none; + padding: 12px; + text-align: left; + border-radius: 8px; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} + +.nav-item:hover, +.nav-item.active { + background-color: rgba(255, 255, 255, 0.06); + color: #ffffff; +} + +/* ================= SAĞ İÇERİK ALANI ================= */ +.main-content { + flex: 1; + padding: 30px; + overflow-y: auto; + + /* DÜZELTME: Mat renk yerine %45 saydamlık ve cam bulanıklığı ekledik */ + background-color: rgba(15, 20, 28, 0.45) !important; + backdrop-filter: blur(20px); + + transition: background-color 0.3s; +} + +header h2 { + margin-top: 0; + font-size: 24px; + font-weight: 600; + color: #ffffff; +} + +.snip-list { + display: flex; + flex-direction: column; + gap: 20px; +} + +/* Kod Kartları Genel Yapısı (Liquid Glass Güncellemesi) */ +.snip-card { + border-radius: 12px; + padding: 20px; + + /* DÜZELTME: Kart zeminini yarı saydam yapıp arkasını bulandırdık */ + background-color: rgba(30, 35, 45, 0.5) !important; + backdrop-filter: blur(12px); + + /* İnce cam yansıması kenarlık */ + border: 1px solid rgba(255, 255, 255, 0.06); + + transition: transform 0.2s, box-shadow 0.2s, background-color 0.3s, border-color 0.3s; +} + +/* Karta Yaklaştığında (Hover) Cam Parlaması Efekti */ +.snip-card:hover { + transform: translateY(-2px); + + /* Üzerine gelince cam biraz daha aydınlanıp parlasın */ + background-color: rgba(40, 45, 60, 0.6) !important; + border-color: rgba(255, 255, 255, 0.15); + + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4); +} + +.snip-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} + +.snip-header h3 { + margin: 0; + font-size: 16px; + font-weight: 500; + color: #e4e6eb; +} + +/* Butonlar */ + +.copy-btn:hover { + background-color: #007aff; + color: white; + border-color: #007aff; +} + +.card-actions { + display: flex; + gap: 8px; +} + + +/* ========================================================================== + KART BUTONLARI (MİLİMETRİK EŞİTLEME GÜNCELLEMESİ) + ========================================================================== */ + +.copy-btn, +.delete-btn, +.share-btn, +.edit-btn { + /* Hepsine sabit yükseklik vererek tarayıcı farklılıklarını sıfırlıyoruz */ + height: 32px; + + /* İçerikleri (metin ve ikonları) dikeyde tam ortalıyoruz */ + display: inline-flex; + align-items: center; + justify-content: center; + + /* Yatay boşluklar ve fontlar tamamen aynı */ + padding: 0 14px; + font-size: 13px; + border-radius: 6px; + cursor: pointer; + font-family: inherit; + box-sizing: border-box; + /* Border'ların yüksekliğe dahil olmasını sağlar */ + transition: all 0.2s ease; +} + +/* Kopyala Butonu Özel Renkleri */ +.copy-btn { + background-color: rgba(255, 255, 255, 0.07); + color: #e4e6eb; + border: 1px solid rgba(255, 255, 255, 0.05); +} + +/* Sil Butonu Özel Renkleri */ +.delete-btn { + background-color: rgba(255, 61, 48, 0.15); + color: #ff453a; + border: 1px solid rgba(255, 61, 48, 0.2); +} + +/* Paylaş Butonu Özel Renkleri */ +.share-btn { + background: rgba(85, 255, 7, 0.15); + color: #7fff07; + border: 1px solid rgba(139, 255, 7, 0.3); + gap: 4px; + /* İkon ile yazı arasındaki boşluk */ +} + +.share-btn:hover { + background: #a8ff07; + color: #111; + /* Koyu temada yazı net okunsun diye */ + box-shadow: 0 0 8px rgba(181, 255, 7, 0.4); +} + +/* Düzenle Butonu Özel Renkleri */ +.edit-btn { + background: rgba(255, 193, 7, 0.15); + color: #ffc107; + border: 1px solid rgba(255, 193, 7, 0.3); + gap: 4px; +} + +.edit-btn:hover { + background: #ffc107; + color: #111; + /* Koyu temada yazı net okunsun diye */ + box-shadow: 0 0 8px rgba(255, 193, 7, 0.4); +} + +.delete-btn:hover { + background-color: #ff453a; + color: white; +} + +/* Kod Editörü / Blokları Görünümü */ +/* Kod Editörü / Blokları Görünümü (Liquid Glass Güncellemesi) */ +pre { + /* DÜZELTME: Sabit koyu renk yerine yarı saydam bir ton verdik */ + background-color: rgba(10, 13, 20, 0.4) !important; + + /* Kodların arkasında da cam akıcılığı devam etsin */ + backdrop-filter: blur(6px); + -webkit-backdrop-filter: blur(6px); + + padding: 15px; + border-radius: 8px; + margin: 0; + overflow-x: auto; + + /* Hafif parlayan şık bir iç kenarlık */ + border: 1px solid rgba(255, 255, 255, 0.05); + transition: background-color 0.3s, border-color 0.3s; +} + +/* Fareyle kod bloğunun üzerine gelindiğinde hafif bir parlamayla canlansın */ +pre:hover { + background-color: rgba(15, 20, 30, 0.55) !important; + border-color: rgba(255, 255, 255, 0.12); +} + +code { + font-family: 'SFMono-Regular', Consolas, "Liberation Mono", Menlo, monospace; + color: #e0e0e0; + font-size: 14px; +} + +/* ================= MODERN SIVI CAM (LIQUID GLASS) EFEKTİ ================= */ +/* style.css içindeki mevcut tanımı dinamik değişkenlerle güncelleyelim */ +.liquid_glass { + background: rgba(255, 255, 255, var(--glass-opacity, 0.03)) !important; + backdrop-filter: blur(var(--glass-blur, 16px)) !important; + -webkit-backdrop-filter: blur(var(--glass-blur, 16px)) !important; + border: 1px solid rgba(255, 255, 255, 0.06) !important; + box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.05), var(--glow-color, rgba(0, 0, 0, 0)); + transition: all 0.3s ease; +} + +/* ================= MAT GÖRÜNÜM (CAM EFEKTİ KAPALIYKEN) ================= */ +.no-glass { + background-color: #161e2b !important; + /* Cam kapanınca asil grafit/lacivert mat ton */ + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + border: 1px solid rgba(255, 255, 255, 0.05) !important; +} + +.no-glass-sidebar { + background-color: #0a0d14 !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + border-right: 1px solid rgba(255, 255, 255, 0.05) !important; +} + +/* ================= BİLEŞENLER VE TASARIM ÖGELERİ ================= */ + +/* Arama Çubuğu */ +.search-container { + margin: 20px 0; + width: 100%; +} + +#search-input { + width: 100%; + padding: 12px 20px; + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 8px; + color: white; + font-size: 15px; + outline: none; + transition: all 0.2s; +} + +#search-input:focus { + border-color: #007aff; + background: rgba(255, 255, 255, 0.07); + box-shadow: 0 0 12px rgba(0, 122, 255, 0.25); +} + +#search-input::placeholder { + color: #545456; +} + +/* Sayı Rozetleri (Badge) */ +.badge { + background-color: rgba(255, 255, 255, 0.06); + color: #007aff; + font-size: 11px; + font-weight: bold; + padding: 2px 8px; + border-radius: 10px; +} + +.nav-item.active .badge { + background-color: #007aff; + color: white; +} + +/* YENİ GELİŞMİŞ KALICI NOTLAR ALANI */ +.scratchpad-area { + margin-top: auto; + /* Sol menünün en altına itilmesini sağlar */ + border-top: 1px solid rgba(255, 255, 255, 0.05); + padding-top: 20px; +} + +.scratchpad-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; +} + +.scratchpad-area h3 { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + margin: 0; + color: #8e8e93; +} + +#save-status { + font-size: 11px; + color: #30d158; + opacity: 0; + transition: opacity 0.3s; +} + +#scratchpad:focus { + border-color: #007aff; +} + +/* Header ve Ekleme Paneli */ +.header-actions { + display: flex; + justify-content: space-between; + align-items: center; + gap: 20px; + margin: 20px 0; +} + +.header-actions .search-container { + margin: 0; + flex: 1; +} + +.add-toggle-btn { + background-color: #007aff; + color: white; + border: none; + padding: 12px 20px; + border-radius: 8px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + white-space: nowrap; + transition: background 0.2s; +} + +.add-toggle-btn:hover { + background-color: #0056b3; +} + +.add-panel { + border-radius: 12px; + padding: 25px; + margin-bottom: 25px; + box-shadow: 0 15px 35px rgba(0, 0, 0, 0.6); + background-color: #161e2b; + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.add-panel h3 { + margin-top: 0; + margin-bottom: 20px; + font-size: 18px; + font-weight: 600; +} + +.form-group { + display: flex; + gap: 15px; + margin-bottom: 15px; +} + +.form-group input, +.form-group select, +.form-group textarea { + background: rgba(0, 0, 0, 0.25); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 6px; + color: white; + padding: 10px 15px; + font-size: 14px; + outline: none; +} + +.form-group input { + flex: 2; +} + +.form-group select { + /* Temel tasarım */ + background: #080b11; + color: white; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 6px; + padding: 15px 17px; + /* Biraz daha iç boşluk verdik */ + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; + width: 100%; + /* Kutunun genişliği tam sığması için */ + + /* 🌟 Sihirli dokunuş: Varsayılan tarayıcı stilini tamamen kapat */ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + + /* Kendi özel ok simgemizi ekliyoruz (çünkü appearance: none ok'u yok eder) */ + background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3e%3cpath d='M7 10l5 5 5-5z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 10px center; + background-size: 16px; + padding-right: 30px; + /* Okun yazının üstüne binmemesi için */ +} + +/* Üzerine gelince belirginleşsin */ +.form-group select:hover { + border-color: rgba(255, 255, 255, 0.25); + background-color: #111622; +} + +.form-group textarea { + width: 100%; + height: 150px; + resize: vertical; +} + +.form-buttons { + display: flex; + gap: 10px; + justify-content: flex-end; +} + +.save-btn { + background: rgba(85, 255, 7, 0.15); + color: #7fff07; + border: 1px solid rgba(139, 255, 7, 0.3); + border-radius: 6px; +} + +.save-btn:hover { + background: #a8ff07; + color: #111; + /* Koyu temada yazı net okunsun diye */ + box-shadow: 0 0 8px rgba(181, 255, 7, 0.4); + border-radius: 6px; +} + +.cancel-btn { + background-color: #3a3a3c; + color: white; + border: none; + padding: 10px 20px; + border-radius: 6px; + cursor: pointer; +} + +/* Sol Menü Footer (Ayarlar Butonu) */ +.sidebar-footer { + margin-top: auto; + /* Üstteki elemanlardan tamamen bağımsız en alta itilmesi için garanti */ + padding-top: 15px; + border-top: 1px solid rgba(255, 255, 255, 0.1); + /* İsteğe bağlı: Üstüne şık ince bir çizgi */ + align-items: center; +} + +/* Footer içindeki ayarlar butonunun tasarımı (gerekirse genişlik ayarı) */ +.sidebar-footer button { + width: 100%; + text-align: left; + display: flex; + align-items: center; + gap: 10px; +} + +.settings-toggle-btn { + width: 100%; + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.05); + color: #8e8e93; + padding: 10px; + border-radius: 8px; + cursor: pointer; + font-size: 14px; + transition: all 0.2s; +} + +.settings-toggle-btn:hover { + background: rgba(255, 255, 255, 0.08); + color: white; +} + +/* ================= YENİ GELİŞMİŞ AYARLAR PENCERESİ ================= */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.75); + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; +} + +/* ========================================================================== + 🔍 AYARLAR PENCERESİ - CHROMIUM BUG ARINDIRILMIŞ KESİN ÇÖZÜM + ========================================================================== */ + +/* Modalı taşıyan ve tüm ekranı kaplayan karartma katmanı */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + /* Arka planı biraz daha koyulaştırarak alttaki blur çakışmasını nötrlüyoruz */ + background: rgba(5, 7, 12, 0.85) !important; + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; +} + +/* Ayarlar Penceresinin Ana Kutusu */ +.modal-content { + width: 540px; + max-height: 85vh; + overflow-y: auto; + padding: 0 30px 30px 30px; + border-radius: 16px; + position: relative; + + /* ⚠️ CHROMIUM BLUR BUG ÇÖZÜMÜ: + Üst üste binen filtreler patlamaya sebep olduğu için buradaki blur'u sıfırladık. + Arkayı tamamen kapatan, asil ve opak bir gece laciverti verdik: */ + background-color: #111622 !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + + /* Şık ve ince çerçeve çizgisi */ + border: 1px solid rgba(255, 255, 255, 0.08) !important; + box-shadow: 0 25px 60px rgba(0, 0, 0, 0.85) !important; + + transition: background-color 0.3s ease, border-color 0.3s ease; +} + +/* Üst Sabit Başlık Alanı (Aşağı kaydırırken yazılar arkaya gizlenir) */ +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + position: sticky; + top: 0; + padding: 25px 0 15px 0; + margin-bottom: 25px; + z-index: 10; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); + /* İçerik kutusuyla birebir aynı, opak renk olmak zorunda: */ + background-color: #111622 !important; +} + +/* ☀️ Jilet Gibi Açık Tema (Light Theme) Aktifken Ayarlar Görünümü */ +.light-theme .modal-content { + background-color: #e8e6e6 !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; + box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15) !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; +} + +.light-theme .modal-header { + background-color: #e8e6e6 !important; + border-bottom: 1px solid rgba(0, 0, 0, 0.08); +} + +/* -------------------------------------------------------------------------- + A) LIQUID GLASS AKTİFKEN (body elementinde .liquid-glass sınıfı VARKEN) + -------------------------------------------------------------------------- */ +body.liquid-glass .modal-content { + background-color: transparent !important; + border: none !important; + box-shadow: none !important; +} + +body.liquid-glass .modal-header { + /* Yazılar arkadan kayarken hafifçe süzülmesi için yarı saydam cam efekti */ + background-color: rgba(22, 30, 43, 0.6) !important; + backdrop-filter: blur(12px) !important; + -webkit-backdrop-filter: blur(12px) !important; + + /* Sağdan soldan taşma yapmaması için iç boşluk dengeleyici */ + padding: 25px 15px 15px 15px; + margin: 0 -15px 25px -15px; +} + + +/* -------------------------------------------------------------------------- + B) LIQUID GLASS KAPALIYKEN (body elementinde .liquid-glass sınıfı YOKKEN) + -------------------------------------------------------------------------- */ +body:not(.liquid-glass) .modal-content { + /* Orijinal asil koyu lacivert mat görünüm */ + background-color: #161e2b !important; + border: 1px solid rgba(255, 255, 255, 0.06) !important; + box-shadow: 0 25px 50px rgba(0, 0, 0, 0.7) !important; +} + +body:not(.liquid-glass) .modal-header { + /* Arkadan kayan yazılar üste binmesin diye tamamen opak mat arka plan */ + background-color: #161e2b !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + + /* Düz temada ekstra margin taşmalarına gerek yok, sıfırlıyoruz */ + padding: 25px 0 15px 0; + margin: 0 0 25px 0; +} + + +/* -------------------------------------------------------------------------- + C) MODERN KAPATMA BUTONU + -------------------------------------------------------------------------- */ +.modal-header button, +.close-modal-btn { + background: rgba(255, 255, 255, 0.05); + color: #a0a5b5; + border: 1px solid rgba(255, 255, 255, 0.08); + width: 28px; + height: 28px; + border-radius: 6px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + transition: all 0.2s ease; +} + +.modal-header button:hover, +.close-modal-btn:hover { + background-color: rgba(255, 255, 255, 0.12) !important; + color: #ffffff !important; + border-color: rgba(255, 255, 255, 0.2) !important; +} + +.modal-header h2 { + margin: 0; + font-size: 20px; + font-weight: 600; +} + +.settings-section { + margin-bottom: 25px; +} + +.settings-section h4 { + color: #007aff; + margin: 0 0 12px 0; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.setting-item { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 14px; + background: rgba(255, 255, 255, 0.01); + padding: 12px; + border-radius: 8px; + border: 1px solid rgba(255, 255, 255, 0.02); +} + +.setting-text h5 { + margin: 0; + font-size: 14px; + font-weight: 500; + color: #ffffff; +} + +.setting-item p { + font-size: 12px; + color: #8e8e93; + margin: 4px 0 0 0; +} + +.setting-item select { + background: #080b11; + color: white; + border: 1px solid rgba(255, 255, 255, 0.1); + padding: 6px 12px; + border-radius: 6px; + outline: none; +} + +/* Yenileme ve Tehlike Butonları */ +.reload-btn { + background-color: #ff9500; + color: white; + border: none; + padding: 8px 16px; + border-radius: 6px; + cursor: pointer; + font-size: 13px; + font-weight: 500; + transition: background 0.2s; +} + +.reload-btn:hover { + background-color: #e08200; +} + +.danger-btn { + background-color: rgba(255, 59, 48, 0.15); + color: #ff453a; + border: 1px solid rgba(255, 59, 48, 0.2); + padding: 8px 16px; + border-radius: 6px; + cursor: pointer; + font-size: 13px; + transition: all 0.2s; +} + +.danger-btn:hover { + background-color: #ff3b30; + color: white; +} + +/* ========================================================================== + 🔮 HAREKET ANINDA VE BASILI TUTULDUĞUNDA CAMLAŞAN TOGGLE SWITCH + ========================================================================== */ + +.switch { + position: relative; + display: inline-block; + width: 51px; + height: 31px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +/* Gövde */ +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #39393d; + border: 1.5px solid rgba(255, 255, 255, 0.1); + border-radius: 31px; + transition: background-color 0.25s ease; +} + +/* İçteki Yuvarlak (Normal dururken ve hareket bittiğinde HER ZAMAN mat beyaz) */ +.slider:before { + position: absolute; + content: ""; + height: 25px; + width: 25px; + left: 2px; + bottom: 2px; + background-color: #ffffff; + border-radius: 50%; + transform-origin: left center; + + /* 🌟 Sihir burada: Cam efektinin açılıp kapanma hızını da transition'a bağlıyoruz */ + transition: transform 0.25s cubic-bezier(0.25, 1, 0.5, 1), + width 0.25s cubic-bezier(0.25, 1, 0.5, 1), + background-color 0.2s ease, + backdrop-filter 0.2s ease, + border 0.2s ease, + box-shadow 0.2s ease; + + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + border: 1px solid transparent; +} + +/* 🟢 SWITCH AKTİF OLDUĞUNDA (SAĞA KAYIŞ) */ +input:checked+.slider { + background-color: #34c759; +} + +input:checked+.slider:before { + transform: translateX(20px); +} + +/* 🧪 ⚡ BASILI TUTULDUĞU AN (ACTIVE) TETİKLENEN DETAYLAR */ +/* Sen parmağını fare düğmesinden çekene kadar buton bu cam formunda donar: */ +.switch input:active+.slider:before { + width: 32px; + /* Videodaki esneme payı */ + + /* Liquid Glass Kodları */ + background-color: rgba(255, 255, 255, 0.25) !important; + backdrop-filter: blur(6px) !important; + -webkit-backdrop-filter: blur(6px) !important; + + /* Kristal kenarlık parlaması ve gölgesi */ + border: 1px solid rgba(255, 255, 255, 0.45) !important; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15); +} + +/* AKILLI TOAST BİLDİRİM SİSTEMİ */ +.toast { + position: fixed; + bottom: 25px; + right: 25px; + background-color: #30d158; + color: white; + padding: 12px 24px; + border-radius: 8px; + font-size: 14px; + font-weight: 500; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4); + opacity: 0; + transform: translateY(20px); + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + pointer-events: none; + z-index: 10000; +} + +.toast.show { + opacity: 1; + transform: translateY(0); +} + +/* ================= JİLET GİBİ AÇIK TEMA DÜZENİ ================= */ +.light-theme { + background-color: #c3faf9 !important; + color: #000000 !important; +} + +.light-theme .main-content { + /* Açık tema için de istersen hafif saydam bir cam yapabilirsin */ + background-color: rgba(195, 250, 249, 0.7) !important; + backdrop-filter: blur(20px); +} + +.light-theme .sidebar { + background-color: rgba(232, 230, 230, 0.8) !important; + border-right: 1px solid rgba(0, 0, 0, 0.1); +} + +.light-theme .no-glass-sidebar { + background-color: #e8e6e6 !important; + border-right: 1px solid rgba(0, 0, 0, 0.15) !important; +} + +.light-theme .snip-card.liquid_glass { + background: rgba(232, 230, 230, 0.6) !important; + border: 1px solid rgba(0, 0, 0, 0.1) !important; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); +} + +.light-theme .snip-card.no-glass { + background-color: #e8e6e6 !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; +} + +.light-theme h2, +.light-theme h3, +.light-theme strong, +.light-theme .nav-item, +.light-theme .sidebar-footer button, +.light-theme .scratchpad-area h3, +.light-theme .add-panel h3, +.light-theme .logo-text, +.light-theme .modal-content h2, +.light-theme .settings-section h5 { + color: #000000 !important; +} + +.light-theme .nav-item:hover, +.light-theme .nav-item.active { + background-color: rgba(0, 0, 0, 0.08); + color: #000000 !important; +} + +.light-theme .snip-card pre { + background-color: #ffffff !important; + backdrop-filter: none !important; + border: 1px solid rgba(0, 0, 0, 0.1) !important; +} + +.light-theme .snip-card pre code { + color: #000000 !important; +} + +.light-theme #search-input, +.light-theme .form-group input, +.light-theme .form-group textarea, +.light-theme .scratchpad-area textarea { + background: #ffffff !important; + color: #000000 !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; +} + +.light-theme #search-input::placeholder { + color: #555555 !important; +} + +.light-theme .form-group select, +.light-theme .setting-item select { + background: #ffffff !important; + color: #000000 !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; +} + +.light-theme .modal-content { + background-color: #e8e6e6 !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; +} + +.light-theme .setting-item p { + color: #444444 !important; +} + +.light-theme .copy-btn { + background-color: #007aff !important; + color: #ffffff !important; +} + +/* ================= ANIMASYONLAR ================= */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(8px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.fade-in { + animation: fadeIn 0.3s ease forwards; +} + +/* Favori Buton Tasarımı */ +.fav-btn { + background: transparent; + border: none; + font-size: 18px; + color: #666; + cursor: pointer; + transition: color 0.2s, transform 0.1s; +} + +.fav-btn:hover { + transform: scale(1.2); + color: #ffcc00; +} + +.fav-btn.fav-active { + color: #ffcc00; + /* Aktifken altın sarısı parlasın */ +} + + + +/* Butonların Kapsayıcısı */ +.window-controls { + display: flex; + height: 100%; + align-items: center; + /* ⚠️ Sürükleme alanının butonları kilitlemesini engellemek için kesinlikle no-drag: */ + -webkit-app-region: no-drag !important; + position: relative; + z-index: 10000; + /* Sürükleme alanının tamamen üstüne çıkmasını sağlıyoruz */ +} + +/* Ortak Buton Özellikleri */ +.control-btn { + background: transparent; + border: none; + height: 45px; + /* Üst barın yüksekliği olan 45px ile tam eşit olmalı (CSS'te yukarısı 45px yapılmış) */ + width: 46px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + -webkit-app-region: no-drag !important; + /* Butonların kendisinde de tıklamayı garantiye alıyoruz */ + transition: background-color 0.15s ease; +} + +/* Minimize ve Maximize Hover Efekti (Hafif beyazımsı par things) */ +.minimize-btn:hover, +.maximize-btn:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +/* Kapatma Butonu Hover Efekti (Klasik Windows Kırmızısı) */ +.close-btn:hover { + background-color: #e81123 !important; +} + +/* SVG İkonlarının Boyutu */ +.control-btn svg { + transition: fill 0.15s ease; +} + +.titlebar-logo { + width: 20px; + height: 20px; + margin-right: 8px; +} + +/* Tüm ekranı kaplayan karartma ve bulanıklaştırma katmanı */ +#spotlight-overlay { + position: fixed; + top: 45px; + /* Başlık çubuğunun tam bittiği yer */ + left: 0; + width: 100vw; + height: calc(100vh - 45px); + /* 45px ile eşitlendi, taşma yapmaz */ + background: rgba(0, 0, 0, 0.4); + /* Camı öne çıkarmak için arka planı biraz hafiflettik */ + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + z-index: 9998; + display: flex; + justify-content: center; + align-items: flex-start; + padding-top: 15vh; + transition: opacity 0.2s ease; +} + +/* Gizliyken görünmez yap */ +.spotlight-hidden { + opacity: 0; + pointer-events: none; +} + +/* 🧪 Ortada yüzen LIQUID GLASS (Cam Efektli) Ana Pencere */ +.spotlight-window { + width: 650px; + + /* Cam Efekti Ayarları */ + background: rgba(25, 25, 25, 0.45); + /* Şeffaflığı artırarak arkadaki kodların buğulu görünmesini sağladık */ + backdrop-filter: blur(20px) saturate(160%); + /* İçerideki camın kendi bulanıklığı ve renk canlılığı */ + -webkit-backdrop-filter: blur(20px) saturate(160%); + + /* İnce Parlayan Cam Çerçevesi (Üst ve sol kenarlar ışık alır) */ + border: 1px solid rgba(255, 255, 255, 0.08); + border-top: 1px solid rgba(255, 255, 255, 0.18); + border-left: 1px solid rgba(255, 255, 255, 0.15); + + border-radius: 14px; + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.6), + inset 0 1px 0 0 rgba(255, 255, 255, 0.1); + /* İç tarafa hafif parlama çizgisi */ + overflow: hidden; + font-family: sans-serif; +} + +/* Arama çubuğunun kapsayıcısı */ +.spotlight-search-wrapper { + display: flex; + align-items: center; + padding: 16px 20px; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); + background: rgba(255, 255, 255, 0.02); + /* Üst alan için çok hafif bir kontrast */ +} + +/* Arama ikonu */ +.spotlight-icon { + color: rgba(255, 255, 255, 0.5); + /* İkon rengini cam temasına uydurduk */ + font-size: 18px; + margin-right: 14px; +} + +/* Input'un kendisi */ +#spotlight-input { + width: 100%; + background: transparent; + border: none; + outline: none; + color: #fff; + font-size: 18px; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); + /* Yazının cam üzerinde parlamasını ve net okunmasını sağlar */ +} + +#spotlight-input::placeholder { + color: rgba(255, 255, 255, 0.35); + /* Placeholder rengini biraz daha yumuşattık */ +} + +/* Alt sonuçlar ve ipuçları alanı */ +#spotlight-results { + padding: 12px; + max-height: 300px; + overflow-y: auto; + background: rgba(0, 0, 0, 0.2); + /* Sonuçlar alt panelde hafifçe ayrılsın */ + border-top: 1px solid rgba(255, 255, 255, 0.03); +} + +/* v26Q2.5 — Spotlight Boş Durum / İpucu Alanı Düzenlemesi */ +.spotlight-hint { + width: 100%; + padding: 10px !important; + /* Yazının etrafına nefes aldıracak boşluk */ + color: rgba(255, 255, 255, 0.4); + font-size: 13px; +} + +.spotlight-hint span { + color: #00adb5; + /* Projenin canlı neon mavisini buraya da taşıdık */ + font-weight: 500; +} + +/* --- Paylaş Butonu ve Kart Aksiyonları Düzenlemesi --- */ +.card-actions { + display: flex; + gap: 6px; + /* Butonların arasındaki boşluk */ + align-items: center; +} + +/* Eğer butonların genel bir stili varsa (edit-btn, copy-btn gibi) uyum sağlaması için */ +.card-actions button { + outline: none; + font-weight: 500; +} + +/* --- Spotlight İçindeki Geri Bildirimler İçin Küçük İpucu Tasarımı (Opsiyonel) --- */ +#spotlight-input::placeholder { + color: rgba(255, 255, 255, 0.4); +} + +/* Animasyonlu Yeni Kart Geçişi (fade-in sınıfı için) */ +.fade-in { + animation: fadeInAnim 0.3s ease-out forwards; +} + +@keyframes fadeInAnim { + from { + opacity: 0; + transform: translateY(10px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.version-26Q2-5 { + margin-top: 20px; + padding: 15px; + background: rgba(255, 255, 255, 0.02); + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: 10px; +} + +.backup-buttons { + display: flex; + gap: 10px; + margin-top: 10px; +} + +.backup-buttons .glass-btn { + flex: 1; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + color: #fff; + padding: 10px; + border-radius: 6px; + cursor: pointer; + font-family: 'Segoe UI', sans-serif; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + transition: all 0.3s ease; +} + +/* v26Q2.5 Özel Parlama Efektleri */ +#exportBtn:hover { + background: rgba(0, 173, 181, 0.15); + border-color: #00adb5; + box-shadow: 0 0 10px rgba(0, 173, 181, 0.3); +} + +#importBtn:hover { + background: rgba(255, 87, 34, 0.15); + border-color: #ff5722; + box-shadow: 0 0 10px rgba(255, 87, 34, 0.3); +} + +/* ========================================================================== + 🔍 26Q2.5 — macOS Spotlight Alt Panel ve Quick Look (Önizleme) CSS Eklemeleri + ========================================================================== */ + +/* Sonuç alanı devreye girdiğinde alt paneli yan yana yerleşime hazırlar */ +#spotlight-results { + padding: 0 !important; + /* Eski padding'i ezerek sıfırlıyoruz */ + max-height: 400px !important; + /* Listenin rahatça sığması için yükselttik */ + background: rgba(0, 0, 0, 0.25) !important; + border-top: 1px solid rgba(255, 255, 255, 0.06) !important; + display: flex; + /* Sol tarafta liste, sağ tarafta önizleme olmasını sağlar */ + overflow: hidden !important; +} + +/* Sol taraftaki kod başlıkları listesi */ +.spotlight-list { + flex: 1; + max-height: 380px; + overflow-y: auto; + padding: 8px 0; + border-right: 1px solid rgba(255, 255, 255, 0.06); +} + +/* Listelenen her bir arama sonucu satırı */ +.spotlight-item { + padding: 10px 18px; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + color: rgba(255, 255, 255, 0.7); + font-size: 13px; + transition: background 0.15s ease, color 0.15s ease; +} + +/* Klavyeden Aşağı/Yukarı ok tuşlarıyla seçilen veya mouse ile üzerine gelinen satır */ +.spotlight-item:hover, +.spotlight-item.active { + background: rgba(255, 255, 255, 0.08); + color: #ffffff; +} + +/* Satırların sağındaki dil/kategori etiketleri */ +.item-category { + font-size: 10px; + font-weight: 600; + background: rgba(255, 255, 255, 0.1); + padding: 2px 6px; + border-radius: 4px; + color: rgba(255, 255, 255, 0.5); + letter-spacing: 0.5px; +} + +.spotlight-item.active .item-category { + background: #00adb5; + /* Seçili satırdaki kategori senin neon mavisi rengini alır */ + color: #ff008c; +} + +/* 📑 SAĞ TARAFTAKİ MINI QUICK LOOK (ÖNİZLEME) PANELİ */ +.spotlight-quick-preview { + flex: 1.3; + /* Kod içeriği rahat okunsun diye sağ tarafı bir tık daha geniş yaptık */ + padding: 15px; + background: rgba(0, 0, 0, 0.2); + display: none; + /* JavaScript'ten Space tuşuna basılana kadar gizli kalır */ + flex-direction: column; + max-height: 380px; + border-left: 1px solid rgba(0, 0, 0, 0.2); +} + +/* Önizleme panelinin içindeki kod alanı */ +.spotlight-quick-preview pre { + margin: 0 !important; + padding: 10px !important; + background: transparent !important; + /* Çift arka plan olmasın diye temizledik */ + border: none !important; + width: 100%; + height: 100%; + overflow: auto; +} + +.spotlight-quick-preview pre code { + font-size: 12px !important; + line-height: 1.5; + white-space: pre-wrap; + /* Kodların taşmasını engeller, alt satıra katlar */ +} + +/* İsteğe bağlı: Listenin scrollbar'ını şıklaştırmak için */ +.spotlight-list::-webkit-scrollbar, +.spotlight-quick-preview pre::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +.spotlight-list::-webkit-scrollbar-thumb, +.spotlight-quick-preview pre::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + border-radius: 3px; +} + +/* ================= v26Q2.5 — MODERN VE İNCE SCROLLBAR TASARIMI ================= */ + +/* 1. Kod Blokları (pre) ve Tüm Uygulama İçin Genel Scrollbar Genişliği/Yüksekliği */ +::-webkit-scrollbar { + width: 8px; + /* Dikey kaydırma çubuğu kalınlığı */ + height: 8px; + /* Yatay kaydırma çubuğu kalınlığı (O beyaz çubukları inceltir) */ +} + +/* 2. Kaydırma Çubuğunun Arkasındaki Yol (Track) */ +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.2); + /* Hafif şeffaf siyah, arka planla bütünleşir */ + border-radius: 10px; +} + +/* 3. Kaydırılan Tutamaç Çubuğu (Thumb) */ +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.12); + /* Beyaz yerine çok hafif, şık bir gri ton */ + border-radius: 10px; + border: 2px solid transparent; + /* İçeride biraz daha estetik durması için */ + transition: background-color 0.2s ease; +} + +/* 4. Fareyle Çubuğun Üzerine Gelindiğinde Parlama Efekti (Hover) */ +::-webkit-scrollbar-thumb:hover { + background: rgba(0, 173, 181, 0.4); + /* Üzerine gelince projenin imza neon mavisine/turkuazına göz kırpar */ +} + +/* 5. Köşe Birleşim Noktaları (Corner) */ +::-webkit-scrollbar-corner { + background: transparent; +} + +/* ========================================================================== + 🎬 CODESNIP MEGA ANIMATION PACK v26Q3-beta1 — COMPLETE 20 ANIMATIONS + ========================================================================== */ + +/* ========================================== + Section 1: Global Keyframes (01 - 06) + ========================================== */ + +/* 01. Aşağıdan Yukarı Süzülme Girişi */ +@keyframes csFadeInUp { + 0% { + opacity: 0; + transform: translateY(16px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +/* 02. Soldan Sağa Akıcı Giriş */ +@keyframes csFadeInLeft { + 0% { + opacity: 0; + transform: translateX(-20px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +/* 03. macOS Tarzı Esnek Büyüme */ +@keyframes csScalePop { + 0% { + opacity: 0; + transform: scale(0.94); + } + + 100% { + opacity: 1; + transform: scale(1); + } +} + +/* 04. Kopyalama Başarı Sıçraması */ +@keyframes csSuccessBounce { + 0% { + transform: scale(1); + } + + 30% { + transform: scale(1.15); + background-color: #34c759 !important; + border-color: transparent; + } + + 50% { + transform: scale(0.95); + } + + 100% { + transform: scale(1); + } +} + +/* 05. Bildirim Kutusu Sallanma Efekti */ +@keyframes csAlertShake { + + 0%, + 100% { + transform: translateX(0); + } + + 20%, + 60% { + transform: translateX(-4px); + } + + 40%, + 80% { + transform: translateX(4px); + } +} + +/* 06. Arka Plan Shimmer (Yükleniyor) Dalgası */ +@keyframes csShimmerWave { + 0% { + background-position: -200% 0; + } + + 100% { + background-position: 200% 0; + } +} + + +/* ========================================== + Section 2: Uygulama İçi Bileşenler (07 - 20) + ========================================== */ + +/* 07. Kod Kartları İlk Giriş Efekti (.snip-card) */ +.snip-card { + animation: csFadeInUp 0.45s cubic-bezier(0.25, 1, 0.5, 1) both; +} + +/* 08. Kod Kartları Üzerine Gelince Yükselme (Hover) */ +.snip-card { + transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), + box-shadow 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), + border-color 0.3s ease; +} + +.snip-card:hover { + transform: translateY(-5px); + box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35) !important; + border-color: rgba(255, 255, 255, 0.18) !important; +} + +/* 09. Sol Menü Elemanları Esnek Sağa Kayma (.nav-item) */ +.nav-item { + transition: background-color 0.2s ease, + transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), + padding-left 0.25s ease, + color 0.2s ease !important; +} + +.nav-item:hover { + background-color: rgba(255, 255, 255, 0.08) !important; + padding-left: 26px !important; + transform: scale(1.02); + color: #ffffff !important; +} + +/* 10. Sol Menü Elemanları Tıklama İçe Çökme (Active) */ +.nav-item:active { + transform: scale(0.97); +} + +/* 11. Arama Çubuğu Genişleme ve Parlama (Focus) */ +.search-bar-container input, +input[type="text"] { + transition: box-shadow 0.3s ease, border-color 0.3s ease, background-color 0.3s ease; +} + +/* 12. İşlem Butonları Yumuşak Parlama (Hover) */ +.btn-copy, +.btn-edit, +.btn-share, +.main-button { + transition: filter 0.2s ease, transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); +} + +.btn-copy:hover, +.btn-edit:hover, +.btn-share:hover, +.main-button:hover { + filter: brightness(1.2); + transform: translateY(-1.5px); +} + +/* 13. İşlem Butonları Tıklama Tepkisi */ +.btn-copy:active, +.btn-edit:active, +.btn-share:active, +.main-button:active { + transform: translateY(1px) scale(0.95); +} + +/* 14. Kopyala Butonu Başarı Zıplaması (.copied sınıfı tetiklendiğinde) */ +.btn-copy.copied { + animation: csSuccessBounce 0.4s ease-in-out; +} + +/* 15. "+ Yeni Kod Ekle" Butonu Neon Glow Efekti */ +.add-btn { + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.add-btn:hover { + transform: scale(1.04); + box-shadow: 0 0 18px rgba(52, 152, 219, 0.5) !important; +} + +/* 16. Ayarlar / Kod Ekleme Penceresi Pop-up Açılışı (.modal-content) */ +.modal-content { + animation: csScalePop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both; +} + +/* 17. Modal Kapatma Butonu (X) Kendi Etrafında Dönüşü */ +.modal-close-btn { + transition: transform 0.25s cubic-bezier(0.25, 1, 0.5, 1); +} + +.modal-close-btn:hover { + transform: rotate(90deg) scale(1.15); +} + +/* 18. Dil Seçim Dropdown Menü Yumuşak Aşağı Açılışı (.dropdown-menu) */ +.dropdown-menu { + display: block !important; + /* Görünürlüğü opacity ile yöneteceğiz */ + opacity: 0; + transform: translateY(-8px); + pointer-events: none; + transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.25, 1, 0.5, 1); +} + +.dropdown-container:hover .dropdown-menu, +.dropdown-menu.show { + opacity: 1; + transform: translateY(0); + pointer-events: auto; +} + +/* 19. Logo / Başlık Üzerine Gelindiğinde Hafif Sallanma Efekti */ +.app-logo, +.brand-title { + transition: transform 0.3s ease; +} + +.app-logo:hover, +.brand-title:hover { + transform: rotate(-3deg) scale(1.05); +} + +/* 20. Kod Blokları Satır Numaraları Sol Şerit Girişi (.line-numbers) */ +.line-numbers { + animation: csFadeInLeft 0.5s cubic-bezier(0.25, 1, 0.5, 1) both; +} + +/* Açık temada sol menüdeki tüm sayı rozetlerinin kesin rengi */ +.light-theme .sidebar .badge { + background-color: #007aff !important; + color: #ffffff !important; + opacity: 1 !important; +} + +/* Aktif olan menü elemanının sayısının tam beyaz kalması için */ +.light-theme .nav-item.active .badge { + background-color: #0056b3 !important; + color: #ffffff !important; +} + +/* Eski .add-code-panel kodunu sil, doğrusunu yazıyoruz: */ +.add-panel { + overflow: visible !important; + /* Listenin dışarı taşarak düzgün açılması için */ +} + +/* Modal Arka Plan */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(10px); + /* O beklediğimiz cam efekti */ + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; +} + +/* Modal İçerik Kutusu - Ana Temayı Giyiyor */ +.modal-content.glass-panel { + background: rgba(30, 30, 45, 0.8) !important; + /* Koyu tema glass */ + padding: 25px; + border-radius: 15px; + border: 1px solid rgba(255, 255, 255, 0.1); + width: 320px; + color: rgb(255, 255, 255); +} + +/* Input ve Select stilleri */ +.modal-input { + width: 100%; + padding: 10px; + margin: 10px 0; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.2); + color: rgb(54, 54, 54); + border-radius: 6px; + box-sizing: border-box; +} + +/* Butonlar */ +.modal-actions { + display: flex; + gap: 10px; + margin-top: 15px; +} + +.btn-primary { + flex: 1; + padding: 10px; + border-radius: 6px; + border: none; + background: #3498db; + color: white; + cursor: pointer; +} + +.btn-secondary { + flex: 1; + padding: 10px; + border-radius: 6px; + border: none; + background: #444; + color: white; + cursor: pointer; +} + +/* 4. Kategori Ekle Butonu */ +.add-cat-btn { + background: transparent; + border: 1px dashed rgba(255, 255, 255, 0.3); + color: var(--accent-blue); + padding: 10px; + margin-top: 10px; + cursor: pointer; + transition: 0.3s; +} + +.add-cat-btn:hover { + background: rgba(255, 255, 255, 0.05); + border-color: var(--accent-blue); +} + +/* Favori butonu rengi */ +.nav-favorites { + color: #ffcc00; +} + +/* Kategori container düzeni */ +.cat-container { + display: flex; + flex-direction: column; + gap: 8px; +} + +/* Modallar için başlangıç gizleme */ +.hidden-initially { + display: none; +} + +.beta-watermark { + position: fixed; + bottom: 20px; + right: 20px; + opacity: 0.7; + /* Hafif silik görünmesi için */ + font-size: 20px; + font-family: 'Segoe UI', sans-serif; + letter-spacing: 1px; + pointer-events: none; + /* Tıklamaları uygulamaya geçirir, yazıya tıklanmaz */ + user-select: none; + /* Metnin seçilmesini engeller */ + z-index: 9999; + /* En üstte kalmasını sağlar */ + cursor: pointer; + /* Fare imlecini el işareti yap */ + pointer-events: auto; + /* Tıklanabilirliği aç */ + transition: color 0.3s; + /* Tatlı bir geçiş */ +} + +.beta-subtitle { + font-size: 15px; + /* Birinci satırdan daha küçük */ + opacity: 0.7; + /* Biraz daha silik */ + display: block; + /* Alt satıra geçmesini sağlar */ + margin-top: 2px; + /* Satırlar arası boşluk */ + letter-spacing: 0.5px; +} + +.beta-watermark:hover { + color: rgba(255, 255, 255, 0.4); + /* Üzerine gelince biraz belirginleşsin */ +} + +#about-modal { + display: none; + /* Başlangıçta gizli */ +} + +#about-modal.active { + display: flex; + /* Açıkken flex yap */ +} + +/* =======================================================================AI=== + SLIDER METİN HİZALAMASI VE BOZULMA FİXİ + ========================================================================== */ + +/* Kaydırıcıların bulunduğu ayar kutularını özel olarak hizala */ +/* =========================== + Modern Glass Slider + =========================== */ +/* ======================= + Glass Slider +======================= */ + +.glass-slider { + display: flex; + align-items: center; + gap: 12px; + min-width: 220px; +} + +.glass-slider span { + min-width: 42px; + text-align: center; + padding: 5px 8px; + + border-radius: 10px; + + background: rgba(255, 255, 255, .06); + border: 1px solid rgba(255, 255, 255, .08); + + backdrop-filter: blur(10px); + + font-size: 12px; + font-weight: 600; + + color: #fff; +} + +.glass-slider input[type=range] { + -webkit-appearance: none; + appearance: none; + + width: 180px; + height: 5px; + + border-radius: 999px; + + background: rgba(255, 255, 255, .12); + + cursor: pointer; + + transition: .25s; +} + +.glass-slider input[type=range]:hover { + background: rgba(255, 255, 255, .18); +} + +.glass-slider input[type=range]::-webkit-slider-runnable-track { + height: 5px; + border-radius: 999px; +} + +.glass-slider input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + + margin-top: -6px; + + width: 17px; + height: 17px; + + border-radius: 50%; + + background: #fcfbfb; + + border: 3px solid var(--theme-color); + + box-shadow: + 0 0 0 3px rgba(255, 255, 255, .08), + 0 4px 12px rgba(0, 0, 0, .35); + + transition: .2s; +} + +.glass-slider input[type=range]::-webkit-slider-thumb:hover { + transform: scale(1.15); + box-shadow: + 0 0 12px var(--theme-color), + 0 6px 18px rgba(0, 0, 0, .45); +} + +/* Alt açıklama metinlerinin ("Arka planın bulanıklık seviyesi..." vb.) hizası */ +.setting-item:has(input[type="range"]) .setting-description { + font-size: 12px; + color: #a0a5b1; + margin-top: -8px; + /* Başlığa biraz daha yaklaştırıp bütünlük sağlar */ + margin-bottom: 5px; +} \ No newline at end of file