DevCSS — Live CSS Editor (TR/EN)

Bilingual live CSS editor with floating button and right-click element picker. / İki dilli canlı CSS editörü.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

Advertisement:

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

Advertisement:

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         DevCSS — Live CSS Editor (TR/EN)
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Bilingual live CSS editor with floating button and right-click element picker. / İki dilli canlı CSS editörü.
// @author       Mustafa Hakan
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

(function () {
  'use strict';

  /* =====================================================
     LANGUAGE & DICTIONARY
  ===================================================== */
  var LANG = GM_getValue('devcss_lang',
    (navigator.language || '').startsWith('tr') ? 'tr' : 'en'
  );

  var T = {
    tr: {
      fabTitle: 'DevCSS (Alt+C)',
      panelTitle: 'DevCSS',
      tabEditor: 'Editör',
      tabComputed: 'Hesaplanan',
      tabHistory: 'Geçmiş',
      tabSnippets: 'Parçacıklar',
      pickBtn: 'Element Seç',
      pickBtnCancel: 'İptal',
      applyBtn: 'Uygula',
      formatBtn: 'Biçimlendir',
      clearBtn: 'Temizle',
      copyBtn: 'Kopyala',
      resetBtn: 'Sıfırla',
      undoBtn: 'Geri Al',
      saveSnippetBtn: 'Parçacık Kaydet',
      statusReady: 'Hazır',
      statusApplied: 'Uygulandı',
      statusError: 'Hata',
      statusSelected: 'Seçildi',
      statusFormatted: 'Biçimlendirildi',
      editorCleared: 'Editör temizlendi',
      snippetSaved: 'Parçacık kaydedildi',
      snippetLoaded: 'Parçacık yüklendi',
      snippetDeleted: 'Parçacık silindi',
      noSnippet: 'Kayıtlı parçacık yok',
      noHistory: 'Henüz değişiklik yok',
      noComputed: 'Element seçin',
      computedSearchPlaceholder: 'Özellik ara…',
      snippetNamePlaceholder: 'Parçacık adı…',
      editorPlaceholder: 'CSS kuralları yaz veya element seç…',
      quickHeading: 'Hızlı Ekle',
      quickBtnLabels: {
        hide: 'Gizle',
        visible: 'Görünür',
        flex: 'Flex',
        grid: 'Grid',
        fullscreen: 'Tam Ekran',
        circle: 'Yuvarla',
        opacity0: 'Opaklık 0',
        blur: 'Blur',
        shadow: 'Gölge',
        animation: 'Animasyon',
        gradient: 'Gradyan',
        glass: 'Cam Efekti'
      },
      ctxOpen: 'DevCSS Aç',
      ctxPick: 'Elementi Seç',
      ctxInspect: 'Hesaplanan Stiller',
      ctxHide: 'Gizle',
      ctxHighlight: 'Vurgu Ekle',
      ctxOutline: 'Çerçeve Göster',
      ctxRemove: 'Kaldır',
      langBtn: 'EN'
    },
    en: {
      fabTitle: 'DevCSS (Alt+C)',
      panelTitle: 'DevCSS',
      tabEditor: 'Editor',
      tabComputed: 'Computed',
      tabHistory: 'History',
      tabSnippets: 'Snippets',
      pickBtn: 'Select Element',
      pickBtnCancel: 'Cancel',
      applyBtn: 'Apply',
      formatBtn: 'Format',
      clearBtn: 'Clear',
      copyBtn: 'Copy',
      resetBtn: 'Reset',
      undoBtn: 'Undo',
      saveSnippetBtn: 'Save Snippet',
      statusReady: 'Ready',
      statusApplied: 'Applied',
      statusError: 'Error',
      statusSelected: 'Selected',
      statusFormatted: 'Formatted',
      editorCleared: 'Editor cleared',
      snippetSaved: 'Snippet saved',
      snippetLoaded: 'Snippet loaded',
      snippetDeleted: 'Snippet deleted',
      noSnippet: 'No snippets yet',
      noHistory: 'No changes yet',
      noComputed: 'Select an element',
      computedSearchPlaceholder: 'Search property…',
      snippetNamePlaceholder: 'Snippet name…',
      editorPlaceholder: 'Write CSS rules or select an element…',
      quickHeading: 'Quick Insert',
      quickBtnLabels: {
        hide: 'Hide',
        visible: 'Visible',
        flex: 'Flex',
        grid: 'Grid',
        fullscreen: 'Fullscreen',
        circle: 'Circle',
        opacity0: 'Opacity 0',
        blur: 'Blur',
        shadow: 'Shadow',
        animation: 'Animation',
        gradient: 'Gradient',
        glass: 'Glass Effect'
      },
      ctxOpen: 'Open DevCSS',
      ctxPick: 'Select Element',
      ctxInspect: 'Computed Styles',
      ctxHide: 'Hide',
      ctxHighlight: 'Add Highlight',
      ctxOutline: 'Show Outline',
      ctxRemove: 'Remove',
      langBtn: 'TR'
    }
  };

  function t(key) {
    return (T[LANG] && T[LANG][key]) || key;
  }

  function switchLang(newLang) {
    if (newLang !== 'tr' && newLang !== 'en') return;
    LANG = newLang;
    GM_setValue('devcss_lang', LANG);
    // Reload panel to reflect new strings
    var oldPanel = document.getElementById('devcss-panel');
    var oldFab = document.getElementById('devcss-fab');
    var oldRoot = document.getElementById('devcss-root');
    if (oldRoot) oldRoot.remove();
    buildHTML();
    initEvents();
    renderSnippets();
    if (isOpen) togglePanel(true);
    if (selectedEl) {
      selectElement(selectedEl);
    }
  }

  /* =====================================================
     STATE
  ===================================================== */
  var isOpen       = false;
  var isPickMode   = false;
  var hoveredEl    = null;
  var selectedEl   = null;
  var savedSnippets = JSON.parse(GM_getValue('devcss_snippets', '[]'));
  var customStyle  = null; // <style> tag
  var history      = [];   // undo history
  var histIdx      = -1;
  var activeTab    = 'editor';

  /* =====================================================
     CSS INJECTION
  ===================================================== */
  GM_addStyle([
    '@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap");',
    '#devcss-root *{box-sizing:border-box;font-family:Inter,sans-serif;}',
    '#devcss-fab{position:fixed;bottom:24px;right:24px;z-index:2147483640;',
    'width:48px;height:48px;border-radius:14px;border:none;cursor:pointer;',
    'background:linear-gradient(135deg,#1e1e2e,#2a2a3e);',
    'box-shadow:0 4px 20px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.06);',
    'display:flex;align-items:center;justify-content:center;',
    'transition:transform .2s,box-shadow .2s;}',
    '#devcss-fab:hover{transform:scale(1.08);box-shadow:0 6px 28px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.1);}',
    '#devcss-fab.active{background:linear-gradient(135deg,#7c3aed,#4f46e5);}',
    '#devcss-fab svg{pointer-events:none;}',
    '#devcss-panel{position:fixed;bottom:86px;right:24px;z-index:2147483641;',
    'width:440px;max-height:calc(100vh - 120px);',
    'background:#13131f;border:1px solid rgba(255,255,255,.08);border-radius:16px;',
    'box-shadow:0 24px 60px rgba(0,0,0,.7);display:flex;flex-direction:column;',
    'opacity:0;transform:translateY(10px) scale(.97);pointer-events:none;',
    'transition:opacity .2s,transform .2s;}',
    '#devcss-panel.open{opacity:1;transform:translateY(0) scale(1);pointer-events:all;}',
    '#dp-hdr{display:flex;align-items:center;justify-content:space-between;',
    'padding:12px 16px;border-bottom:1px solid rgba(255,255,255,.06);flex-shrink:0;}',
    '#dp-title{font-size:13px;font-weight:600;color:rgba(255,255,255,.8);letter-spacing:-.2px;}',
    '#dp-title span{color:#7c3aed;margin-right:4px;}',
    '#dp-hdr-r{display:flex;gap:6px;align-items:center;}',
    '.dp-icon-btn{background:none;border:1px solid rgba(255,255,255,.07);',
    'color:rgba(255,255,255,.35);padding:4px 8px;border-radius:7px;cursor:pointer;',
    'font-size:11px;line-height:1;transition:all .15s;display:flex;align-items:center;gap:4px;}',
    '.dp-icon-btn:hover{background:rgba(255,255,255,.07);color:rgba(255,255,255,.8);}',
    '.dp-icon-btn.danger:hover{background:rgba(239,68,68,.1);border-color:rgba(239,68,68,.3);color:#ef4444;}',
    '.dp-icon-btn.active{background:rgba(124,58,237,.15);border-color:rgba(124,58,237,.35);color:#a78bfa;}',
    '#dp-tabs{display:flex;gap:2px;padding:8px 10px;border-bottom:1px solid rgba(255,255,255,.05);flex-shrink:0;}',
    '.dp-tab{background:none;border:none;color:rgba(255,255,255,.3);padding:5px 10px;',
    'border-radius:7px;cursor:pointer;font-size:11.5px;font-family:Inter,sans-serif;',
    'transition:all .15s;font-weight:500;}',
    '.dp-tab:hover{color:rgba(255,255,255,.6);background:rgba(255,255,255,.05);}',
    '.dp-tab.active{color:#c4b5fd;background:rgba(124,58,237,.12);}',
    '#dp-selector-bar{padding:8px 12px;border-bottom:1px solid rgba(255,255,255,.05);',
    'flex-shrink:0;display:flex;align-items:center;gap:8px;}',
    '#dp-el-tag{font-family:"JetBrains Mono",monospace;font-size:11px;',
    'color:#7dd3fc;background:rgba(125,211,252,.08);border:1px solid rgba(125,211,252,.15);',
    'padding:3px 8px;border-radius:5px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}',
    '#dp-pick-btn{background:rgba(124,58,237,.1);border:1px solid rgba(124,58,237,.25);',
    'color:#a78bfa;padding:4px 10px;border-radius:7px;cursor:pointer;font-size:11px;',
    'font-family:Inter,sans-serif;transition:all .15s;white-space:nowrap;}',
    '#dp-pick-btn:hover{background:rgba(124,58,237,.2);}',
    '#dp-pick-btn.picking{background:rgba(239,68,68,.1);border-color:rgba(239,68,68,.3);color:#f87171;}',
    '#dp-body{flex:1;overflow-y:auto;min-height:0;}',
    '#dp-body::-webkit-scrollbar{width:3px;}',
    '#dp-body::-webkit-scrollbar-thumb{background:rgba(124,58,237,.25);border-radius:2px;}',
    '#dp-editor-wrap{padding:10px;}',
    '#dp-css-input{width:100%;background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.07);',
    'border-radius:10px;padding:12px;font-family:"JetBrains Mono",monospace;font-size:12px;',
    'color:#e2d9f3;line-height:1.7;resize:none;outline:none;min-height:180px;',
    'transition:border-color .2s;}',
    '#dp-css-input:focus{border-color:rgba(124,58,237,.4);}',
    '#dp-css-input::placeholder{color:rgba(255,255,255,.15);}',
    '#dp-editor-actions{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap;}',
    '.dp-act-btn{border:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.04);',
    'color:rgba(255,255,255,.5);padding:5px 12px;border-radius:7px;cursor:pointer;',
    'font-size:11.5px;font-family:Inter,sans-serif;transition:all .15s;}',
    '.dp-act-btn:hover{background:rgba(255,255,255,.08);color:rgba(255,255,255,.85);}',
    '.dp-act-btn.primary{background:linear-gradient(135deg,rgba(124,58,237,.4),rgba(79,70,229,.4));',
    'border-color:rgba(124,58,237,.4);color:#c4b5fd;}',
    '.dp-act-btn.primary:hover{background:linear-gradient(135deg,rgba(124,58,237,.6),rgba(79,70,229,.6));}',
    '.dp-act-btn.green{border-color:rgba(74,222,128,.25);color:#4ade80;}',
    '.dp-act-btn.green:hover{background:rgba(74,222,128,.08);}',
    '.dp-act-btn.red{border-color:rgba(239,68,68,.25);color:#f87171;}',
    '.dp-act-btn.red:hover{background:rgba(239,68,68,.08);}',
    '#dp-quick-wrap{padding:0 10px 10px;}',
    '#dp-quick-wrap h5{font-size:9.5px;color:rgba(255,255,255,.2);letter-spacing:1.5px;',
    'text-transform:uppercase;margin:8px 0 6px;font-weight:600;}',
    '#dp-quick-btns{display:flex;flex-wrap:wrap;gap:5px;}',
    '.dp-quick{border:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.03);',
    'color:rgba(255,255,255,.4);padding:4px 9px;border-radius:6px;cursor:pointer;',
    'font-size:11px;font-family:Inter,sans-serif;transition:all .15s;}',
    '.dp-quick:hover{background:rgba(124,58,237,.1);border-color:rgba(124,58,237,.25);color:#c4b5fd;}',
    '#dp-computed-wrap{padding:10px;}',
    '#dp-computed-search{width:100%;background:rgba(0,0,0,.3);border:1px solid rgba(255,255,255,.07);',
    'border-radius:8px;padding:7px 10px;font-size:12px;color:rgba(255,255,255,.8);',
    'outline:none;margin-bottom:8px;font-family:"JetBrains Mono",monospace;transition:border-color .2s;}',
    '#dp-computed-search:focus{border-color:rgba(124,58,237,.35);}',
    '#dp-computed-search::placeholder{color:rgba(255,255,255,.2);}',
    '#dp-computed-list{display:flex;flex-direction:column;gap:1px;}',
    '.dp-prop-row{display:flex;align-items:center;padding:4px 6px;border-radius:5px;',
    'transition:background .1s;cursor:pointer;gap:8px;}',
    '.dp-prop-row:hover{background:rgba(255,255,255,.04);}',
    '.dp-prop-name{font-family:"JetBrains Mono",monospace;font-size:11px;color:#7dd3fc;',
    'flex:0 0 160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}',
    '.dp-prop-val{font-family:"JetBrains Mono",monospace;font-size:11px;color:#d4c5b0;',
    'flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}',
    '.dp-color-dot{width:12px;height:12px;border-radius:3px;flex-shrink:0;',
    'border:1px solid rgba(255,255,255,.12);}',
    '#dp-history-wrap{padding:10px;display:flex;flex-direction:column;gap:6px;}',
    '.dp-hist-item{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.06);',
    'border-radius:8px;padding:8px 10px;cursor:pointer;transition:all .15s;}',
    '.dp-hist-item:hover{background:rgba(124,58,237,.08);border-color:rgba(124,58,237,.2);}',
    '.dp-hist-time{font-size:10px;color:rgba(255,255,255,.25);margin-bottom:3px;font-family:"JetBrains Mono",monospace;}',
    '.dp-hist-preview{font-family:"JetBrains Mono",monospace;font-size:11px;color:#d4c5b0;',
    'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}',
    '.dp-empty{font-size:12px;color:rgba(255,255,255,.2);text-align:center;padding:24px;}',
    '#dp-snippets-wrap{padding:10px;display:flex;flex-direction:column;gap:6px;}',
    '#dp-snippet-name{width:100%;background:rgba(0,0,0,.3);border:1px solid rgba(255,255,255,.07);',
    'border-radius:8px;padding:7px 10px;font-size:12px;color:rgba(255,255,255,.8);',
    'outline:none;margin-bottom:6px;font-family:Inter,sans-serif;transition:border-color .2s;}',
    '#dp-snippet-name:focus{border-color:rgba(74,222,128,.35);}',
    '#dp-snippet-name::placeholder{color:rgba(255,255,255,.2);}',
    '.dp-snippet-card{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.06);',
    'border-radius:8px;padding:9px 11px;display:flex;justify-content:space-between;align-items:flex-start;gap:8px;}',
    '.dp-snippet-info{flex:1;min-width:0;}',
    '.dp-snippet-title{font-size:12px;font-weight:500;color:rgba(255,255,255,.7);margin-bottom:3px;}',
    '.dp-snippet-preview{font-family:"JetBrains Mono",monospace;font-size:10.5px;color:rgba(255,255,255,.3);',
    'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}',
    '.dp-snippet-btns{display:flex;gap:5px;flex-shrink:0;}',
    '.dp-snip-btn{border:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.03);',
    'color:rgba(255,255,255,.35);padding:3px 8px;border-radius:5px;cursor:pointer;',
    'font-size:10.5px;font-family:Inter,sans-serif;transition:all .15s;}',
    '.dp-snip-btn:hover{background:rgba(255,255,255,.07);color:rgba(255,255,255,.7);}',
    '.dp-snip-btn.load:hover{background:rgba(74,222,128,.08);border-color:rgba(74,222,128,.25);color:#4ade80;}',
    '.dp-snip-btn.del:hover{background:rgba(239,68,68,.08);border-color:rgba(239,68,68,.25);color:#f87171;}',
    '#dp-status{padding:7px 12px;border-top:1px solid rgba(255,255,255,.05);',
    'display:flex;align-items:center;justify-content:space-between;flex-shrink:0;}',
    '#dp-status-msg{font-size:10.5px;color:rgba(255,255,255,.25);font-family:"JetBrains Mono",monospace;}',
    '#dp-status-msg.ok{color:#4ade80;}',
    '#dp-status-msg.err{color:#f87171;}',
    '#dp-rule-count{font-size:10px;color:rgba(255,255,255,.15);font-family:"JetBrains Mono",monospace;}',
    '#devcss-highlight{position:fixed;pointer-events:none;z-index:2147483639;',
    'border:2px solid #7c3aed;background:rgba(124,58,237,.08);border-radius:2px;',
    'transition:all .08s ease;}',
    '#devcss-highlight-label{position:fixed;z-index:2147483639;pointer-events:none;',
    'background:#7c3aed;color:#fff;font-size:10px;font-family:"JetBrains Mono",monospace;',
    'padding:2px 7px;border-radius:4px;white-space:nowrap;}',
    '#devcss-selected-highlight{position:fixed;pointer-events:none;z-index:2147483638;',
    'border:2px dashed rgba(124,58,237,.5);background:rgba(124,58,237,.04);border-radius:2px;}',
    '#devcss-ctx{position:fixed;z-index:2147483645;background:#1a1a2e;',
    'border:1px solid rgba(255,255,255,.08);border-radius:10px;',
    'box-shadow:0 12px 40px rgba(0,0,0,.6);min-width:180px;padding:5px;',
    'animation:ctxIn .12s ease;}',
    '@keyframes ctxIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}',
    '.ctx-item{display:flex;align-items:center;gap:9px;padding:7px 11px;border-radius:7px;',
    'cursor:pointer;font-size:12.5px;color:rgba(255,255,255,.6);transition:all .1s;}',
    '.ctx-item:hover{background:rgba(124,58,237,.15);color:#c4b5fd;}',
    '.ctx-sep{height:1px;background:rgba(255,255,255,.06);margin:4px 0;}',
    '.ctx-item.danger:hover{background:rgba(239,68,68,.1);color:#f87171;}',
    '#devcss-pick-overlay{position:fixed;inset:0;z-index:2147483636;cursor:crosshair;}',
    '#devcss-toast{position:fixed;bottom:90px;right:24px;z-index:2147483650;',
    'background:#1e1e2e;border:1px solid rgba(255,255,255,.1);',
    'color:rgba(255,255,255,.8);padding:9px 14px;border-radius:10px;',
    'font-size:12px;font-family:Inter,sans-serif;',
    'box-shadow:0 8px 24px rgba(0,0,0,.5);',
    'opacity:0;transform:translateY(5px);',
    'transition:opacity .2s,transform .2s;pointer-events:none;}',
    '#devcss-toast.show{opacity:1;transform:translateY(0);}',
    /* language toggle button */
    '#dp-lang-btn{border:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.03);',
    'color:rgba(255,255,255,.4);font-size:10px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;',
    'transition:all .15s;font-family:Inter,sans-serif;}',
    '#dp-lang-btn:hover{background:rgba(124,58,237,.1);border-color:rgba(124,58,237,.25);color:#c4b5fd;}'
  ].join(''));

  /* =====================================================
     BUILD HTML
  ===================================================== */
  function buildHTML() {
    var root = document.createElement('div');
    root.id = 'devcss-root';

    // Floating button
    var fab = document.createElement('button');
    fab.id = 'devcss-fab';
    fab.title = t('fabTitle');
    fab.innerHTML = '<svg width="20" height="20" fill="none" stroke="rgba(167,139,250,.9)" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>';
    root.appendChild(fab);

    // Panel
    var panel = document.createElement('div');
    panel.id = 'devcss-panel';

    // Header
    var header = document.createElement('div');
    header.id = 'dp-hdr';
    header.innerHTML = '<div id="dp-title"><span>&#x2B21;</span>' + t('panelTitle') + '</div>';
    var hdrRight = document.createElement('div');
    hdrRight.id = 'dp-hdr-r';
    hdrRight.innerHTML = [
      '<button class="dp-icon-btn" id="dp-undo-btn" title="' + t('undoBtn') + '">&larr; ' + t('undoBtn') + '</button>',
      '<button class="dp-icon-btn" id="dp-copy-btn" title="' + t('copyBtn') + '">&#x2913; ' + t('copyBtn') + '</button>',
      '<button class="dp-icon-btn danger" id="dp-reset-btn" title="' + t('resetBtn') + '">&times; ' + t('resetBtn') + '</button>',
      '<button id="dp-lang-btn" title="' + (LANG === 'tr' ? 'Switch to English' : 'Türkçe\'ye geç') + '">' + t('langBtn') + '</button>'
    ].join('');
    header.appendChild(hdrRight);
    panel.appendChild(header);

    // Tabs
    var tabs = document.createElement('div');
    tabs.id = 'dp-tabs';
    tabs.innerHTML = [
      '<button class="dp-tab active" data-tab="editor">' + t('tabEditor') + '</button>',
      '<button class="dp-tab" data-tab="computed">' + t('tabComputed') + '</button>',
      '<button class="dp-tab" data-tab="history">' + t('tabHistory') + '</button>',
      '<button class="dp-tab" data-tab="snippets">' + t('tabSnippets') + '</button>'
    ].join('');
    panel.appendChild(tabs);

    // Selector bar
    var selBar = document.createElement('div');
    selBar.id = 'dp-selector-bar';
    selBar.innerHTML = '<div id="dp-el-tag">' + t('noComputed') + '</div><button id="dp-pick-btn">' + t('pickBtn') + '</button>';
    panel.appendChild(selBar);

    // Body
    var body = document.createElement('div');
    body.id = 'dp-body';

    // Editor tab
    var editorWrap = document.createElement('div');
    editorWrap.id = 'dp-editor-wrap';
    editorWrap.innerHTML = [
      '<textarea id="dp-css-input" spellcheck="false" placeholder="' + t('editorPlaceholder') + '"></textarea>',
      '<div id="dp-editor-actions">',
        '<button class="dp-act-btn primary" id="dp-apply-btn">&#x25B6; ' + t('applyBtn') + '</button>',
        '<button class="dp-act-btn green" id="dp-save-snippet-wrap">&#x1F4BE; ' + t('saveSnippetBtn') + '</button>',
        '<button class="dp-act-btn" id="dp-format-btn">&#x21BB; ' + t('formatBtn') + '</button>',
        '<button class="dp-act-btn red" id="dp-clear-btn">&times; ' + t('clearBtn') + '</button>',
      '</div>',
      '<div id="dp-quick-wrap"><h5>' + t('quickHeading') + '</h5><div id="dp-quick-btns"></div></div>'
    ].join('');

    // Quick buttons will be filled dynamically
    var quickBtnsContainer = editorWrap.querySelector('#dp-quick-btns');
    var quickMap = {
      hide: 'display: none;',
      visible: 'visibility: visible;',
      flex: 'display: flex;\nalign-items: center;\njustify-content: center;',
      grid: 'display: grid;\ngrid-template-columns: repeat(2, 1fr);\ngap: 16px;',
      fullscreen: 'position: fixed;\ninset: 0;\nz-index: 9999;',
      circle: 'border-radius: 50%;',
      opacity0: 'opacity: 0;',
      blur: 'filter: blur(4px);',
      shadow: 'box-shadow: 0 8px 24px rgba(0,0,0,.3);',
      animation: '@keyframes spin {\n  to { transform: rotate(360deg); }\n}\nanimation: spin 1s linear infinite;',
      gradient: 'background: linear-gradient(135deg, #667eea, #764ba2);',
      glass: 'background: rgba(255,255,255,.08);\nbackdrop-filter: blur(10px);\nborder: 1px solid rgba(255,255,255,.1);'
    };
    var labels = t('quickBtnLabels');
    for (var key in quickMap) {
      var btn = document.createElement('button');
      btn.className = 'dp-quick';
      btn.setAttribute('data-css', quickMap[key]);
      btn.textContent = labels[key] || key;
      quickBtnsContainer.appendChild(btn);
    }

    body.appendChild(editorWrap);

    // Computed tab
    var computedWrap = document.createElement('div');
    computedWrap.id = 'dp-computed-wrap';
    computedWrap.style.display = 'none';
    computedWrap.innerHTML = '<input id="dp-computed-search" placeholder="' + t('computedSearchPlaceholder') + '"><div id="dp-computed-list"><div class="dp-empty">' + t('noComputed') + '</div></div>';
    body.appendChild(computedWrap);

    // History tab
    var historyWrap = document.createElement('div');
    historyWrap.id = 'dp-history-wrap';
    historyWrap.style.display = 'none';
    historyWrap.innerHTML = '<div class="dp-empty">' + t('noHistory') + '</div>';
    body.appendChild(historyWrap);

    // Snippets tab
    var snippetsWrap = document.createElement('div');
    snippetsWrap.id = 'dp-snippets-wrap';
    snippetsWrap.style.display = 'none';
    snippetsWrap.innerHTML = '<input id="dp-snippet-name" placeholder="' + t('snippetNamePlaceholder') + '"><div id="dp-snippets-list"></div>';
    body.appendChild(snippetsWrap);

    panel.appendChild(body);

    // Status bar
    var statusBar = document.createElement('div');
    statusBar.id = 'dp-status';
    statusBar.innerHTML = '<div id="dp-status-msg">' + t('statusReady') + '</div><div id="dp-rule-count">0 kural</div>';
    panel.appendChild(statusBar);

    root.appendChild(panel);

    // Highlight elements
    var highlight = document.createElement('div');
    highlight.id = 'devcss-highlight';
    highlight.style.display = 'none';
    root.appendChild(highlight);

    var highlightLabel = document.createElement('div');
    highlightLabel.id = 'devcss-highlight-label';
    highlightLabel.style.display = 'none';
    root.appendChild(highlightLabel);

    var selectedHighlight = document.createElement('div');
    selectedHighlight.id = 'devcss-selected-highlight';
    selectedHighlight.style.display = 'none';
    root.appendChild(selectedHighlight);

    var toast = document.createElement('div');
    toast.id = 'devcss-toast';
    root.appendChild(toast);

    document.body.appendChild(root);
  }

  /* =====================================================
     PANEL TOGGLE
  ===================================================== */
  function togglePanel(force) {
    isOpen = force !== undefined ? force : !isOpen;
    var panel = document.getElementById('devcss-panel');
    var fab   = document.getElementById('devcss-fab');
    if (!panel || !fab) return;
    if (isOpen) {
      panel.classList.add('open');
      fab.classList.add('active');
    } else {
      panel.classList.remove('open');
      fab.classList.remove('active');
      stopPicker();
    }
  }

  /* =====================================================
     TAB SWITCH
  ===================================================== */
  function switchTab(tab) {
    activeTab = tab;
    var tabs = document.querySelectorAll('.dp-tab');
    for (var i = 0; i < tabs.length; i++) {
      tabs[i].classList.toggle('active', tabs[i].getAttribute('data-tab') === tab);
    }
    document.getElementById('dp-editor-wrap').style.display = tab === 'editor' ? '' : 'none';
    document.getElementById('dp-computed-wrap').style.display = tab === 'computed' ? '' : 'none';
    document.getElementById('dp-history-wrap').style.display = tab === 'history' ? '' : 'none';
    document.getElementById('dp-snippets-wrap').style.display = tab === 'snippets' ? '' : 'none';
    if (tab === 'computed') renderComputed();
    if (tab === 'history')  renderHistory();
    if (tab === 'snippets') renderSnippets();
  }

  /* =====================================================
     APPLY CSS
  ===================================================== */
  function applyCss(cssText) {
    if (!customStyle) {
      customStyle = document.createElement('style');
      customStyle.id = 'devcss-injected';
      document.head.appendChild(customStyle);
    }
    try {
      customStyle.textContent = cssText;
      var ts = new Date().toLocaleTimeString();
      history.unshift({ time: ts, css: cssText });
      if (history.length > 30) history.pop();
      histIdx = -1;
      updateRuleCount();
      setStatus(t('statusApplied'), 'ok');
      if (activeTab === 'history') renderHistory();
    } catch (e) {
      setStatus(t('statusError') + ': ' + e.message, 'err');
    }
  }

  function updateRuleCount() {
    var el = document.getElementById('dp-rule-count');
    if (!el || !customStyle) return;
    try {
      var rules = customStyle.sheet ? customStyle.sheet.cssRules.length : 0;
      el.textContent = rules + ' kural';
    } catch (e) {}
  }

  function setStatus(msg, cls) {
    var el = document.getElementById('dp-status-msg');
    if (!el) return;
    el.textContent = msg;
    el.className = cls || '';
    setTimeout(function() {
      if (el.textContent === msg) {
        el.textContent = t('statusReady');
        el.className = '';
      }
    }, 2500);
  }

  /* =====================================================
     CSS FORMATTER
  ===================================================== */
  function formatCss(raw) {
    var s = raw.replace(/\s*\{\s*/g, ' {\n  ')
               .replace(/;\s*/g, ';\n  ')
               .replace(/\s*\}\s*/g, '\n}\n')
               .replace(/  \n\}/g, '\n}')
               .replace(/\n{3,}/g, '\n\n')
               .trim();
    return s;
  }

  /* =====================================================
     ELEMENT PICKER
  ===================================================== */
  function startPicker() {
    isPickMode = true;
    var overlay = document.createElement('div');
    overlay.id = 'devcss-pick-overlay';
    document.body.appendChild(overlay);

    var btn = document.getElementById('dp-pick-btn');
    if (btn) { btn.textContent = t('pickBtnCancel'); btn.classList.add('picking'); }

    setStatus('Element seçmek için tıkla...', '');
    overlay.addEventListener('mousemove', onPickMove);
    overlay.addEventListener('click', onPickClick);
  }

  function stopPicker() {
    isPickMode = false;
    var overlay = document.getElementById('devcss-pick-overlay');
    if (overlay) overlay.parentNode.removeChild(overlay);

    var btn = document.getElementById('dp-pick-btn');
    if (btn) { btn.textContent = t('pickBtn'); btn.classList.remove('picking'); }

    var hl = document.getElementById('devcss-highlight');
    var lbl = document.getElementById('devcss-highlight-label');
    if (hl) hl.style.display = 'none';
    if (lbl) lbl.style.display = 'none';
  }

  function onPickMove(e) {
    var overlay = document.getElementById('devcss-pick-overlay');
    if (overlay) overlay.style.display = 'none';
    var el = document.elementFromPoint(e.clientX, e.clientY);
    if (overlay) overlay.style.display = '';
    if (!el || el.id === 'devcss-root' || el.closest('#devcss-root')) return;

    hoveredEl = el;
    var rect = el.getBoundingClientRect();
    var hl = document.getElementById('devcss-highlight');
    var lbl = document.getElementById('devcss-highlight-label');

    if (hl) {
      hl.style.display = '';
      hl.style.top    = rect.top  + 'px';
      hl.style.left   = rect.left + 'px';
      hl.style.width  = rect.width  + 'px';
      hl.style.height = rect.height + 'px';
    }
    if (lbl) {
      lbl.style.display = '';
      lbl.style.top  = Math.max(0, rect.top - 22) + 'px';
      lbl.style.left = rect.left + 'px';
      lbl.textContent = getSelector(el);
    }
  }

  function onPickClick(e) {
    e.preventDefault();
    var overlay = document.getElementById('devcss-pick-overlay');
    if (overlay) overlay.style.display = 'none';
    var el = document.elementFromPoint(e.clientX, e.clientY);
    if (overlay) overlay.style.display = '';
    if (!el || el.id === 'devcss-root' || el.closest('#devcss-root')) return;

    selectElement(el);
    stopPicker();
  }

  function selectElement(el) {
    selectedEl = el;
    var selector = getSelector(el);

    var tagEl = document.getElementById('dp-el-tag');
    if (tagEl) tagEl.textContent = selector;

    var input = document.getElementById('dp-css-input');
    if (input) {
      var existing = input.value.trim();
      if (!existing) {
        input.value = selector + ' {\n  \n}';
      } else {
        input.value = existing + '\n\n' + selector + ' {\n  \n}';
      }
    }

    var rect = el.getBoundingClientRect();
    var shl = document.getElementById('devcss-selected-highlight');
    if (shl) {
      shl.style.display = '';
      shl.style.top    = rect.top  + window.scrollY + 'px';
      shl.style.left   = rect.left + window.scrollX + 'px';
      shl.style.width  = rect.width  + 'px';
      shl.style.height = rect.height + 'px';
    }

    setStatus(t('statusSelected') + ': ' + selector, 'ok');
    if (activeTab === 'computed') renderComputed();
    toast(t('statusSelected') + ': ' + selector);
  }

  function getSelector(el) {
    if (el.id) return '#' + el.id;
    var cls = Array.prototype.slice.call(el.classList)
                .filter(function(c){ return c.indexOf('devcss') === -1; })
                .slice(0, 2)
                .map(function(c){ return '.' + c; })
                .join('');
    return el.tagName.toLowerCase() + (cls || '');
  }

  /* =====================================================
     COMPUTED STYLES
  ===================================================== */
  function renderComputed() {
    var list = document.getElementById('dp-computed-list');
    if (!list) return;
    if (!selectedEl) {
      list.innerHTML = '<div class="dp-empty">' + t('noComputed') + '</div>';
      return;
    }
    var computed = window.getComputedStyle(selectedEl);
    var search = (document.getElementById('dp-computed-search') || {}).value || '';
    var html = '';
    var important = [
      'display','position','width','height','margin','padding',
      'color','background-color','font-size','font-weight',
      'border','border-radius','opacity','z-index','overflow',
      'flex','grid','transform','transition','box-shadow',
      'text-align','line-height','letter-spacing'
    ];
    var props = search ? [] : important;
    if (search) {
      for (var i = 0; i < computed.length; i++) {
        if (computed[i].indexOf(search) !== -1) props.push(computed[i]);
      }
    }
    for (var j = 0; j < props.length; j++) {
      var prop = props[j];
      var val = computed.getPropertyValue(prop);
      if (!val) continue;
      var colorDot = '';
      if (val.indexOf('rgb') !== -1 || val.match(/^#[0-9a-f]{3,6}$/i)) {
        colorDot = '<div class="dp-color-dot" style="background:' + val + '"></div>';
      }
      html += '<div class="dp-prop-row" data-prop="' + esc(prop) + '" data-val="' + esc(val) + '">' +
              colorDot +
              '<div class="dp-prop-name">' + esc(prop) + '</div>' +
              '<div class="dp-prop-val">' + esc(val) + '</div>' +
              '</div>';
    }
    list.innerHTML = html || '<div class="dp-empty">' + t('noComputed') + '</div>';

    var rows = list.querySelectorAll('.dp-prop-row');
    for (var k = 0; k < rows.length; k++) {
      (function(row){
        row.onclick = function() {
          var p = row.getAttribute('data-prop');
          var v = row.getAttribute('data-val');
          var inp = document.getElementById('dp-css-input');
          if (inp) inp.value += '\n' + p + ': ' + v + ';';
          toast('Editöre eklendi: ' + p);
        };
      })(rows[k]);
    }
  }

  /* =====================================================
     HISTORY
  ===================================================== */
  function renderHistory() {
    var wrap = document.getElementById('dp-history-wrap');
    if (!wrap) return;
    if (!history.length) {
      wrap.innerHTML = '<div class="dp-empty">' + t('noHistory') + '</div>';
      return;
    }
    var html = '';
    for (var i = 0; i < history.length; i++) {
      var item = history[i];
      html += '<div class="dp-hist-item" data-i="' + i + '">' +
              '<div class="dp-hist-time">' + item.time + '</div>' +
              '<div class="dp-hist-preview">' + esc(item.css.slice(0, 80)) + (item.css.length > 80 ? '…' : '') + '</div>' +
              '</div>';
    }
    wrap.innerHTML = html;
    var items = wrap.querySelectorAll('.dp-hist-item');
    for (var j = 0; j < items.length; j++) {
      (function(item) {
        item.onclick = function() {
          var idx = parseInt(item.getAttribute('data-i'), 10);
          var inp = document.getElementById('dp-css-input');
          if (inp) inp.value = history[idx].css;
          switchTab('editor');
          toast(t('snippetLoaded'));
        };
      })(items[j]);
    }
  }

  /* =====================================================
     SNIPPETS
  ===================================================== */
  function saveSnippet() {
    var nameEl = document.getElementById('dp-snippet-name');
    var inp    = document.getElementById('dp-css-input');
    if (!nameEl || !inp) return;
    var name = nameEl.value.trim();
    var css  = inp.value.trim();
    if (!name) { toast('⚠ Snippet adı girin'); return; }
    if (!css)  { toast('⚠ CSS içeriği boş');  return; }
    savedSnippets.unshift({ name: name, css: css, time: new Date().toLocaleString() });
    GM_setValue('devcss_snippets', JSON.stringify(savedSnippets));
    nameEl.value = '';
    toast(t('snippetSaved'));
    if (activeTab === 'snippets') renderSnippets();
  }

  function renderSnippets() {
    var list = document.getElementById('dp-snippets-list');
    if (!list) return;
    if (!savedSnippets.length) {
      list.innerHTML = '<div class="dp-empty">' + t('noSnippet') + '</div>';
      return;
    }
    var html = '';
    for (var i = 0; i < savedSnippets.length; i++) {
      var s = savedSnippets[i];
      html += '<div class="dp-snippet-card">' +
              '<div class="dp-snippet-info">' +
                '<div class="dp-snippet-title">' + esc(s.name) + '</div>' +
                '<div class="dp-snippet-preview">' + esc(s.css.slice(0, 60)) + '</div>' +
              '</div>' +
              '<div class="dp-snippet-btns">' +
                '<button class="dp-snip-btn load" data-i="' + i + '">' + t('snippetLoaded') + '</button>' +
                '<button class="dp-snip-btn del" data-i="' + i + '">' + t('snippetDeleted') + '</button>' +
              '</div>' +
              '</div>';
    }
    list.innerHTML = html;

    var loadBtns = list.querySelectorAll('.dp-snip-btn.load');
    for (var j = 0; j < loadBtns.length; j++) {
      (function(btn) {
        btn.onclick = function() {
          var idx = parseInt(btn.getAttribute('data-i'), 10);
          var inp = document.getElementById('dp-css-input');
          if (inp) inp.value = savedSnippets[idx].css;
          switchTab('editor');
          toast(t('snippetLoaded') + ': ' + savedSnippets[idx].name);
        };
      })(loadBtns[j]);
    }

    var delBtns = list.querySelectorAll('.dp-snip-btn.del');
    for (var k = 0; k < delBtns.length; k++) {
      (function(btn) {
        btn.onclick = function() {
          var idx = parseInt(btn.getAttribute('data-i'), 10);
          savedSnippets.splice(idx, 1);
          GM_setValue('devcss_snippets', JSON.stringify(savedSnippets));
          renderSnippets();
          toast(t('snippetDeleted'));
        };
      })(delBtns[k]);
    }
  }

  /* =====================================================
     CONTEXT MENU (no emojis)
  ===================================================== */
  function showCtxMenu(x, y, target) {
    removeCtx();
    var menu = document.createElement('div');
    menu.id = 'devcss-ctx';
    menu.style.top  = y + 'px';
    menu.style.left = x + 'px';

    menu.innerHTML = [
      '<div class="ctx-item" id="ctx-open">' + t('ctxOpen') + '</div>',
      '<div class="ctx-item" id="ctx-pick">' + t('ctxPick') + '</div>',
      '<div class="ctx-item" id="ctx-inspect">' + t('ctxInspect') + '</div>',
      '<div class="ctx-sep"></div>',
      '<div class="ctx-item" id="ctx-hide">' + t('ctxHide') + '</div>',
      '<div class="ctx-item" id="ctx-highlight-el">' + t('ctxHighlight') + '</div>',
      '<div class="ctx-item" id="ctx-outline">' + t('ctxOutline') + '</div>',
      '<div class="ctx-sep"></div>',
      '<div class="ctx-item danger" id="ctx-remove">' + t('ctxRemove') + '</div>'
    ].join('');

    document.body.appendChild(menu);

    var mw = menu.offsetWidth || 180;
    var mh = menu.offsetHeight || 200;
    if (x + mw > window.innerWidth)  menu.style.left = (x - mw) + 'px';
    if (y + mh > window.innerHeight) menu.style.top  = (y - mh) + 'px';

    bindCtx('ctx-open', function() { togglePanel(true); });
    bindCtx('ctx-pick', function() { selectElement(target); togglePanel(true); });
    bindCtx('ctx-inspect', function() { selectElement(target); togglePanel(true); switchTab('computed'); });
    bindCtx('ctx-hide', function() { injectQuick(selector, 'display: none;'); });
    bindCtx('ctx-highlight-el', function() { injectQuick(selector, 'outline: 3px solid #7c3aed !important;\noutline-offset: 2px;'); });
    bindCtx('ctx-outline', function() { injectQuick(selector, 'outline: 2px dashed rgba(124,58,237,.6) !important;'); });
    bindCtx('ctx-remove', function() { if (target && target.parentNode) target.parentNode.removeChild(target); });

    function bindCtx(id, fn) {
      var el = document.getElementById(id);
      if (el) el.onclick = function() { fn(); removeCtx(); };
    }
  }

  function removeCtx() {
    var old = document.getElementById('devcss-ctx');
    if (old) old.parentNode.removeChild(old);
  }

  function injectQuick(selector, css) {
    var inp = document.getElementById('dp-css-input');
    var newRule = selector + ' {\n  ' + css.replace(/\n/g, '\n  ') + '\n}';
    var current = customStyle ? customStyle.textContent : '';
    var next = current + '\n' + newRule;
    if (inp) inp.value = next;
    applyCss(next);
    toast('Uygulandı: ' + selector);
  }

  /* =====================================================
     TOAST
  ===================================================== */
  var toastTimer = null;
  function toast(msg) {
    var el = document.getElementById('devcss-toast');
    if (!el) return;
    el.textContent = msg;
    el.classList.add('show');
    if (toastTimer) clearTimeout(toastTimer);
    toastTimer = setTimeout(function() {
      el.classList.remove('show');
    }, 2000);
  }

  /* =====================================================
     EVENTS
  ===================================================== */
  function initEvents() {
    // Floating button
    var fab = document.getElementById('devcss-fab');
    if (fab) fab.onclick = function() { togglePanel(); };

    // Tabs
    var tabs = document.querySelectorAll('.dp-tab');
    for (var i = 0; i < tabs.length; i++) {
      (function(tab) {
        tab.onclick = function() { switchTab(tab.getAttribute('data-tab')); };
      })(tabs[i]);
    }

    // Pick button
    var pickBtn = document.getElementById('dp-pick-btn');
    if (pickBtn) {
      pickBtn.onclick = function() {
        if (isPickMode) stopPicker();
        else startPicker();
      };
    }

    // Apply
    var applyBtn = document.getElementById('dp-apply-btn');
    if (applyBtn) applyBtn.onclick = function() {
      var inp = document.getElementById('dp-css-input');
      if (inp) applyCss(inp.value);
    };

    // Format
    var fmtBtn = document.getElementById('dp-format-btn');
    if (fmtBtn) fmtBtn.onclick = function() {
      var inp = document.getElementById('dp-css-input');
      if (inp) { inp.value = formatCss(inp.value); toast(t('statusFormatted')); }
    };

    // Clear
    var clrBtn = document.getElementById('dp-clear-btn');
    if (clrBtn) clrBtn.onclick = function() {
      var inp = document.getElementById('dp-css-input');
      if (inp) inp.value = '';
      toast(t('editorCleared'));
    };

    // Copy
    var cpyBtn = document.getElementById('dp-copy-btn');
    if (cpyBtn) cpyBtn.onclick = function() {
      var inp = document.getElementById('dp-css-input');
      if (inp && inp.value) {
        navigator.clipboard.writeText(inp.value);
        toast('Panoya kopyalandı');
      }
    };

    // Reset
    var rstBtn = document.getElementById('dp-reset-btn');
    if (rstBtn) rstBtn.onclick = function() {
      if (customStyle) customStyle.textContent = '';
      var inp = document.getElementById('dp-css-input');
      if (inp) inp.value = '';
      var shl = document.getElementById('devcss-selected-highlight');
      if (shl) shl.style.display = 'none';
      selectedEl = null;
      var tagEl = document.getElementById('dp-el-tag');
      if (tagEl) tagEl.textContent = t('noComputed');
      updateRuleCount();
      toast('Değişiklikler sıfırlandı');
    };

    // Undo
    var undoBtn = document.getElementById('dp-undo-btn');
    if (undoBtn) undoBtn.onclick = function() {
      if (history.length > 1) {
        history.shift();
        var prev = history[0];
        if (customStyle) customStyle.textContent = prev.css;
        var inp = document.getElementById('dp-css-input');
        if (inp) inp.value = prev.css;
        toast(t('undoBtn'));
      } else if (history.length === 1) {
        history = [];
        if (customStyle) customStyle.textContent = '';
        var inp2 = document.getElementById('dp-css-input');
        if (inp2) inp2.value = '';
        toast('Tüm değişiklikler geri alındı');
      }
      updateRuleCount();
    };

    // Save snippet button
    var savSnpBtn = document.getElementById('dp-save-snippet-wrap');
    if (savSnpBtn) savSnpBtn.onclick = function() {
      switchTab('snippets');
      setTimeout(function() {
        var nameEl = document.getElementById('dp-snippet-name');
        if (nameEl) nameEl.focus();
      }, 100);
    };

    // Quick insert buttons
    var quickBtns = document.querySelectorAll('.dp-quick');
    for (var q = 0; q < quickBtns.length; q++) {
      (function(btn) {
        btn.onclick = function() {
          var css = btn.getAttribute('data-css');
          var inp = document.getElementById('dp-css-input');
          if (!inp) return;
          var current = inp.value.trim();
          if (!current) {
            inp.value = css;
          } else {
            var lastBrace = current.lastIndexOf('{');
            var lastClose = current.lastIndexOf('}');
            if (lastBrace > lastClose) {
              inp.value = current + '\n  ' + css.replace(/\n/g, '\n  ');
            } else {
              inp.value = current + '\n\n' + css;
            }
          }
          toast('Eklendi: ' + btn.textContent);
        };
      })(quickBtns[q]);
    }

    // Computed search
    var csearch = document.getElementById('dp-computed-search');
    if (csearch) csearch.addEventListener('input', function() { renderComputed(); });

    // Snippet name enter
    var snpName = document.getElementById('dp-snippet-name');
    if (snpName) snpName.addEventListener('keydown', function(e) {
      if (e.keyCode === 13) saveSnippet();
    });

    // CSS input Ctrl+Enter and Tab
    var cssInput = document.getElementById('dp-css-input');
    if (cssInput) {
      cssInput.addEventListener('keydown', function(e) {
        if (e.ctrlKey && e.keyCode === 13) applyCss(cssInput.value);
        if (e.keyCode === 9) {
          e.preventDefault();
          var start = cssInput.selectionStart;
          var end   = cssInput.selectionEnd;
          cssInput.value = cssInput.value.slice(0,start) + '  ' + cssInput.value.slice(end);
          cssInput.selectionStart = cssInput.selectionEnd = start + 2;
        }
      });
    }

    // Right click context menu
    document.addEventListener('contextmenu', function(e) {
      var target = e.target;
      if (!target || target.closest('#devcss-root')) return;
      removeCtx();
      showCtxMenu(e.clientX, e.clientY, target);
      e.preventDefault();
    });

    // Close context menu
    document.addEventListener('click', function(e) {
      if (!e.target.closest('#devcss-ctx')) removeCtx();
    });
    document.addEventListener('keydown', function(e) {
      if (e.keyCode === 27) { removeCtx(); stopPicker(); }
    });

    // Keyboard shortcuts: Alt+C, Ctrl+Z
    document.addEventListener('keydown', function(e) {
      if (e.altKey && (e.keyCode === 67 || e.key === 'c')) {
        e.preventDefault();
        togglePanel();
      }
      if (e.ctrlKey && e.keyCode === 90 && isOpen) {
        var undoB = document.getElementById('dp-undo-btn');
        if (undoB) undoB.click();
      }
    });

    // Language toggle button
    var langBtn = document.getElementById('dp-lang-btn');
    if (langBtn) {
      langBtn.onclick = function() {
        switchLang(LANG === 'tr' ? 'en' : 'tr');
      };
    }

    // Draggable panel
    makeDraggable(
      document.getElementById('devcss-panel'),
      document.getElementById('dp-hdr')
    );
  }

  /* =====================================================
     DRAGGABLE
  ===================================================== */
  function makeDraggable(panel, handle) {
    if (!panel || !handle) return;
    var startX, startY, origRight, origBottom;
    handle.style.cursor = 'grab';
    handle.addEventListener('mousedown', function(e) {
      if (e.target.tagName === 'BUTTON') return;
      e.preventDefault();
      startX = e.clientX;
      startY = e.clientY;
      var rect = panel.getBoundingClientRect();
      origRight  = window.innerWidth  - rect.right;
      origBottom = window.innerHeight - rect.bottom;
      handle.style.cursor = 'grabbing';

      function onMove(ev) {
        var dx = ev.clientX - startX;
        var dy = ev.clientY - startY;
        panel.style.right  = (origRight  - dx) + 'px';
        panel.style.bottom = (origBottom + dy) + 'px';
        panel.style.left   = 'auto';
        panel.style.top    = 'auto';
      }
      function onUp() {
        handle.style.cursor = 'grab';
        document.removeEventListener('mousemove', onMove);
        document.removeEventListener('mouseup', onUp);
      }
      document.addEventListener('mousemove', onMove);
      document.addEventListener('mouseup', onUp);
    });
  }

  /* =====================================================
     START
  ===================================================== */
  buildHTML();
  initEvents();
  renderSnippets();

  console.log(
    '%c DevCSS yüklendi %c Alt+C veya sağ tık',
    'color:#a78bfa;font-weight:700;font-size:12px;background:#13131f;padding:3px 8px;border-radius:4px',
    'color:rgba(255,255,255,.3);font-size:11px'
  );

})();