neiki-editor 2.9.3 → 2.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -21
- package/README.md +11 -9
- package/dist/neiki-editor.css +104 -2
- package/dist/neiki-editor.js +319 -36
- package/dist/neiki-editor.min.css +1 -1
- package/dist/neiki-editor.min.js +1 -1
- package/package.json +2 -2
package/dist/neiki-editor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NeikiEditor - A Modern WYSIWYG Editor
|
|
3
|
-
* Version: 2.9.
|
|
3
|
+
* Version: 2.9.5
|
|
4
4
|
*
|
|
5
5
|
* A lightweight, feature-rich text editor with support for:
|
|
6
6
|
* - Rich text formatting (bold, italic, underline, etc.)
|
|
@@ -1138,7 +1138,8 @@
|
|
|
1138
1138
|
onBlur: null,
|
|
1139
1139
|
onReady: null,
|
|
1140
1140
|
showHelp: true,
|
|
1141
|
-
imageUploadHandler: null
|
|
1141
|
+
imageUploadHandler: null,
|
|
1142
|
+
custom_class: null
|
|
1142
1143
|
};
|
|
1143
1144
|
|
|
1144
1145
|
const TOOLBAR_ITEMS = {
|
|
@@ -1344,37 +1345,237 @@
|
|
|
1344
1345
|
},
|
|
1345
1346
|
|
|
1346
1347
|
sanitizeHTML(html) {
|
|
1347
|
-
const
|
|
1348
|
-
const
|
|
1348
|
+
const input = String(html || '');
|
|
1349
|
+
const lowerInput = input.toLowerCase();
|
|
1350
|
+
const root = document.createDocumentFragment();
|
|
1351
|
+
const stack = [root];
|
|
1349
1352
|
const blockedTags = new Set(['script', 'style', 'iframe', 'object', 'embed', 'link', 'meta', 'base']);
|
|
1353
|
+
const allowedTags = new Set([
|
|
1354
|
+
'a', 'b', 'blockquote', 'br', 'caption', 'code', 'col', 'colgroup', 'div', 'em',
|
|
1355
|
+
'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol',
|
|
1356
|
+
'p', 'pre', 's', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody',
|
|
1357
|
+
'td', 'tfoot', 'th', 'thead', 'tr', 'u', 'ul'
|
|
1358
|
+
]);
|
|
1359
|
+
const voidTags = new Set(['br', 'col', 'hr', 'img']);
|
|
1350
1360
|
const urlAttrs = new Set(['href', 'src', 'xlink:href', 'poster']);
|
|
1361
|
+
let index = 0;
|
|
1351
1362
|
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1363
|
+
const currentParent = () => stack[stack.length - 1];
|
|
1364
|
+
|
|
1365
|
+
while (index < input.length) {
|
|
1366
|
+
const tagStart = input.indexOf('<', index);
|
|
1367
|
+
|
|
1368
|
+
if (tagStart === -1) {
|
|
1369
|
+
currentParent().appendChild(document.createTextNode(input.slice(index)));
|
|
1370
|
+
break;
|
|
1356
1371
|
}
|
|
1357
1372
|
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1373
|
+
if (tagStart > index) {
|
|
1374
|
+
currentParent().appendChild(document.createTextNode(input.slice(index, tagStart)));
|
|
1375
|
+
}
|
|
1361
1376
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1377
|
+
if (input.slice(tagStart, tagStart + 4) === '<!--') {
|
|
1378
|
+
const commentEnd = input.indexOf('-->', tagStart + 4);
|
|
1379
|
+
index = commentEnd === -1 ? input.length : commentEnd + 3;
|
|
1380
|
+
continue;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
const tagEnd = Utils.findTagEnd(input, tagStart + 1);
|
|
1384
|
+
if (tagEnd === -1) {
|
|
1385
|
+
currentParent().appendChild(document.createTextNode(input.slice(tagStart)));
|
|
1386
|
+
break;
|
|
1387
|
+
}
|
|
1366
1388
|
|
|
1367
|
-
|
|
1368
|
-
|
|
1389
|
+
const rawTag = input.slice(tagStart + 1, tagEnd).trim();
|
|
1390
|
+
if (!rawTag || rawTag[0] === '!' || rawTag[0] === '?') {
|
|
1391
|
+
index = tagEnd + 1;
|
|
1392
|
+
continue;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
if (rawTag[0] === '/') {
|
|
1396
|
+
const closingName = Utils.readHTMLName(rawTag, 1).name.toLowerCase();
|
|
1397
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
1398
|
+
if (stack[i].nodeType === Node.ELEMENT_NODE && stack[i].tagName.toLowerCase() === closingName) {
|
|
1399
|
+
stack.length = i;
|
|
1400
|
+
break;
|
|
1401
|
+
}
|
|
1369
1402
|
}
|
|
1403
|
+
index = tagEnd + 1;
|
|
1404
|
+
continue;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
const tagInfo = Utils.readHTMLName(rawTag, 0);
|
|
1408
|
+
const tagName = tagInfo.name.toLowerCase();
|
|
1409
|
+
const selfClosing = Utils.isSelfClosingTag(rawTag);
|
|
1410
|
+
|
|
1411
|
+
if (blockedTags.has(tagName)) {
|
|
1412
|
+
const closeTag = '</' + tagName;
|
|
1413
|
+
const closeStart = lowerInput.indexOf(closeTag, tagEnd + 1);
|
|
1414
|
+
const closeEnd = closeStart === -1 ? -1 : input.indexOf('>', closeStart + closeTag.length);
|
|
1415
|
+
index = closeEnd === -1 ? tagEnd + 1 : closeEnd + 1;
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
if (!allowedTags.has(tagName)) {
|
|
1420
|
+
index = tagEnd + 1;
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
const el = document.createElement(tagName);
|
|
1425
|
+
Utils.parseHTMLAttributes(rawTag, tagInfo.end).forEach(attr => {
|
|
1426
|
+
const attrName = attr.name.toLowerCase();
|
|
1427
|
+
const attrValue = attr.value.trim();
|
|
1428
|
+
|
|
1429
|
+
if (!Utils.isSafeHTMLAttribute(attrName)) return;
|
|
1430
|
+
if (urlAttrs.has(attrName) && !Utils.isSafeUrl(attrValue, tagName === 'img')) return;
|
|
1431
|
+
if (attrName === 'style' && !Utils.isSafeStyleValue(attrValue)) return;
|
|
1432
|
+
|
|
1433
|
+
el.setAttribute(attr.name, attr.value);
|
|
1370
1434
|
});
|
|
1371
1435
|
|
|
1372
|
-
if (
|
|
1436
|
+
if (tagName === 'a' && el.getAttribute('target') === '_blank') {
|
|
1373
1437
|
el.setAttribute('rel', 'noopener noreferrer');
|
|
1374
1438
|
}
|
|
1439
|
+
|
|
1440
|
+
currentParent().appendChild(el);
|
|
1441
|
+
if (!selfClosing && !voidTags.has(tagName)) {
|
|
1442
|
+
stack.push(el);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
index = tagEnd + 1;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
return Utils.serializeHTML(root);
|
|
1449
|
+
},
|
|
1450
|
+
|
|
1451
|
+
findTagEnd(input, start) {
|
|
1452
|
+
let quote = null;
|
|
1453
|
+
|
|
1454
|
+
for (let i = start; i < input.length; i++) {
|
|
1455
|
+
const char = input[i];
|
|
1456
|
+
if (quote) {
|
|
1457
|
+
if (char === quote) quote = null;
|
|
1458
|
+
} else if (char === '"' || char === "'") {
|
|
1459
|
+
quote = char;
|
|
1460
|
+
} else if (char === '>') {
|
|
1461
|
+
return i;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
return -1;
|
|
1466
|
+
},
|
|
1467
|
+
|
|
1468
|
+
readHTMLName(input, start) {
|
|
1469
|
+
let i = start;
|
|
1470
|
+
let name = '';
|
|
1471
|
+
|
|
1472
|
+
while (i < input.length && Utils.isHTMLNameChar(input[i])) {
|
|
1473
|
+
name += input[i];
|
|
1474
|
+
i++;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
return { name, end: i };
|
|
1478
|
+
},
|
|
1479
|
+
|
|
1480
|
+
isHTMLNameChar(char) {
|
|
1481
|
+
return (char >= 'a' && char <= 'z') ||
|
|
1482
|
+
(char >= 'A' && char <= 'Z') ||
|
|
1483
|
+
(char >= '0' && char <= '9') ||
|
|
1484
|
+
char === '-' ||
|
|
1485
|
+
char === '_' ||
|
|
1486
|
+
char === ':';
|
|
1487
|
+
},
|
|
1488
|
+
|
|
1489
|
+
isSelfClosingTag(rawTag) {
|
|
1490
|
+
for (let i = rawTag.length - 1; i >= 0; i--) {
|
|
1491
|
+
const char = rawTag[i];
|
|
1492
|
+
if (char === ' ' || char === '\t' || char === '\n' || char === '\r') continue;
|
|
1493
|
+
return char === '/';
|
|
1494
|
+
}
|
|
1495
|
+
return false;
|
|
1496
|
+
},
|
|
1497
|
+
|
|
1498
|
+
parseHTMLAttributes(rawTag, start) {
|
|
1499
|
+
const attrs = [];
|
|
1500
|
+
let i = start;
|
|
1501
|
+
|
|
1502
|
+
while (i < rawTag.length) {
|
|
1503
|
+
while (i < rawTag.length && /\s/.test(rawTag[i])) i++;
|
|
1504
|
+
if (i >= rawTag.length || rawTag[i] === '/') break;
|
|
1505
|
+
|
|
1506
|
+
const attrInfo = Utils.readHTMLName(rawTag, i);
|
|
1507
|
+
if (!attrInfo.name) {
|
|
1508
|
+
i++;
|
|
1509
|
+
continue;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
i = attrInfo.end;
|
|
1513
|
+
while (i < rawTag.length && /\s/.test(rawTag[i])) i++;
|
|
1514
|
+
|
|
1515
|
+
let value = '';
|
|
1516
|
+
if (rawTag[i] === '=') {
|
|
1517
|
+
i++;
|
|
1518
|
+
while (i < rawTag.length && /\s/.test(rawTag[i])) i++;
|
|
1519
|
+
|
|
1520
|
+
if (rawTag[i] === '"' || rawTag[i] === "'") {
|
|
1521
|
+
const quote = rawTag[i];
|
|
1522
|
+
i++;
|
|
1523
|
+
const valueStart = i;
|
|
1524
|
+
while (i < rawTag.length && rawTag[i] !== quote) i++;
|
|
1525
|
+
value = rawTag.slice(valueStart, i);
|
|
1526
|
+
if (rawTag[i] === quote) i++;
|
|
1527
|
+
} else {
|
|
1528
|
+
const valueStart = i;
|
|
1529
|
+
while (i < rawTag.length && !/\s/.test(rawTag[i]) && rawTag[i] !== '/') i++;
|
|
1530
|
+
value = rawTag.slice(valueStart, i);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
attrs.push({ name: attrInfo.name, value });
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
return attrs;
|
|
1538
|
+
},
|
|
1539
|
+
|
|
1540
|
+
isSafeHTMLAttribute(name) {
|
|
1541
|
+
if (!name || name.startsWith('on') || name === 'srcdoc') return false;
|
|
1542
|
+
if (!Utils.isSafeObjectKey(name)) return false;
|
|
1543
|
+
return /^[a-z0-9_:-]+$/.test(name);
|
|
1544
|
+
},
|
|
1545
|
+
|
|
1546
|
+
isSafeStyleValue(value) {
|
|
1547
|
+
const lower = String(value || '').toLowerCase();
|
|
1548
|
+
return lower.indexOf('expression') === -1 &&
|
|
1549
|
+
lower.indexOf('javascript:') === -1 &&
|
|
1550
|
+
lower.indexOf('vbscript:') === -1 &&
|
|
1551
|
+
lower.indexOf('data:') === -1;
|
|
1552
|
+
},
|
|
1553
|
+
|
|
1554
|
+
serializeHTML(node) {
|
|
1555
|
+
let html = '';
|
|
1556
|
+
|
|
1557
|
+
node.childNodes.forEach(child => {
|
|
1558
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
1559
|
+
html += Utils.escapeHTML(child.textContent);
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
if (child.nodeType !== Node.ELEMENT_NODE) return;
|
|
1564
|
+
|
|
1565
|
+
const tagName = child.tagName.toLowerCase();
|
|
1566
|
+
html += '<' + tagName;
|
|
1567
|
+
Array.from(child.attributes).forEach(attr => {
|
|
1568
|
+
html += ' ' + attr.name + '="' + Utils.escapeHTML(attr.value) + '"';
|
|
1569
|
+
});
|
|
1570
|
+
|
|
1571
|
+
if (new Set(['br', 'col', 'hr', 'img']).has(tagName)) {
|
|
1572
|
+
html += '>';
|
|
1573
|
+
} else {
|
|
1574
|
+
html += '>' + Utils.serializeHTML(child) + '</' + tagName + '>';
|
|
1575
|
+
}
|
|
1375
1576
|
});
|
|
1376
1577
|
|
|
1377
|
-
return
|
|
1578
|
+
return html;
|
|
1378
1579
|
},
|
|
1379
1580
|
|
|
1380
1581
|
isSafeUrl(value, allowImageData = false) {
|
|
@@ -1744,7 +1945,7 @@
|
|
|
1744
1945
|
this.overlay.appendChild(modal);
|
|
1745
1946
|
this.overlay.classList.add('active');
|
|
1746
1947
|
|
|
1747
|
-
const firstInput = modal.querySelector('input');
|
|
1948
|
+
const firstInput = modal.querySelector('input:not([type="file"]), textarea, select, button');
|
|
1748
1949
|
if (firstInput) firstInput.focus();
|
|
1749
1950
|
}
|
|
1750
1951
|
|
|
@@ -1853,8 +2054,13 @@
|
|
|
1853
2054
|
<div class="neiki-modal-body">
|
|
1854
2055
|
<div class="neiki-form-group">
|
|
1855
2056
|
<label>${Utils.escapeHTML(t('modal.uploadImage'))}</label>
|
|
1856
|
-
<
|
|
1857
|
-
|
|
2057
|
+
<div class="neiki-image-upload-zone" role="button" tabindex="0">
|
|
2058
|
+
<input type="file" class="neiki-image-upload-input" name="upload" accept="image/*" multiple>
|
|
2059
|
+
<div class="neiki-image-upload-icon">${Icons.image}</div>
|
|
2060
|
+
<div class="neiki-image-upload-title">${Utils.escapeHTML(t('modal.uploadImage'))}</div>
|
|
2061
|
+
<div class="neiki-image-upload-hint">${Utils.escapeHTML(uploadHint)}</div>
|
|
2062
|
+
<div class="neiki-image-upload-files" aria-live="polite"></div>
|
|
2063
|
+
</div>
|
|
1858
2064
|
</div>
|
|
1859
2065
|
<div class="neiki-form-divider">
|
|
1860
2066
|
<span>${Utils.escapeHTML(t('modal.or'))}</span>
|
|
@@ -1879,19 +2085,27 @@
|
|
|
1879
2085
|
`;
|
|
1880
2086
|
|
|
1881
2087
|
const uploadInput = modal.querySelector('[name="upload"]');
|
|
2088
|
+
const uploadZone = modal.querySelector('.neiki-image-upload-zone');
|
|
2089
|
+
const uploadFiles = modal.querySelector('.neiki-image-upload-files');
|
|
1882
2090
|
const urlInput = modal.querySelector('[name="url"]');
|
|
1883
2091
|
const insertBtn = modal.querySelector('[data-action="insert"]');
|
|
1884
2092
|
let pendingFiles = [];
|
|
2093
|
+
let uploadDragCounter = 0;
|
|
1885
2094
|
|
|
1886
2095
|
urlInput.value = data.url || '';
|
|
1887
2096
|
modal.querySelector('[name="alt"]').placeholder = t('modal.describeImage');
|
|
1888
2097
|
modal.querySelector('[name="alt"]').value = data.alt || '';
|
|
1889
2098
|
modal.querySelector('[name="width"]').value = data.width || '';
|
|
1890
2099
|
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
2100
|
+
const updateUploadFeedback = (files) => {
|
|
2101
|
+
uploadZone.classList.toggle('has-files', files.length > 0);
|
|
2102
|
+
uploadFiles.textContent = files.map(file => file.name).join(', ');
|
|
2103
|
+
};
|
|
2104
|
+
|
|
2105
|
+
const handleSelectedFiles = (fileList) => {
|
|
2106
|
+
const selectedFiles = Array.from(fileList || []);
|
|
2107
|
+
const files = selectedFiles.filter(f => f.type.startsWith('image/'));
|
|
2108
|
+
const invalid = selectedFiles.filter(f => !f.type.startsWith('image/'));
|
|
1895
2109
|
|
|
1896
2110
|
if (invalid.length > 0) {
|
|
1897
2111
|
alert(t('modal.invalidImageFile'));
|
|
@@ -1899,13 +2113,15 @@
|
|
|
1899
2113
|
|
|
1900
2114
|
if (files.length === 0) {
|
|
1901
2115
|
pendingFiles = [];
|
|
2116
|
+
updateUploadFeedback([]);
|
|
2117
|
+
urlInput.disabled = false;
|
|
1902
2118
|
return;
|
|
1903
2119
|
}
|
|
1904
2120
|
|
|
1905
2121
|
pendingFiles = files;
|
|
2122
|
+
updateUploadFeedback(files);
|
|
1906
2123
|
|
|
1907
2124
|
if (files.length === 1 && !hasUploadHandler) {
|
|
1908
|
-
// Single file without handler — preview as base64 in URL field
|
|
1909
2125
|
const reader = new FileReader();
|
|
1910
2126
|
reader.onload = (ev) => {
|
|
1911
2127
|
urlInput.value = ev.target.result;
|
|
@@ -1913,10 +2129,51 @@
|
|
|
1913
2129
|
};
|
|
1914
2130
|
reader.readAsDataURL(files[0]);
|
|
1915
2131
|
} else {
|
|
1916
|
-
// Multiple files or handler present — disable URL field
|
|
1917
2132
|
urlInput.value = '';
|
|
1918
2133
|
urlInput.disabled = true;
|
|
1919
2134
|
}
|
|
2135
|
+
};
|
|
2136
|
+
|
|
2137
|
+
// Handle file upload (supports multiple files)
|
|
2138
|
+
uploadInput.addEventListener('change', (e) => {
|
|
2139
|
+
handleSelectedFiles(e.target.files);
|
|
2140
|
+
});
|
|
2141
|
+
|
|
2142
|
+
uploadZone.addEventListener('click', (e) => {
|
|
2143
|
+
if (e.target !== uploadInput) uploadInput.click();
|
|
2144
|
+
});
|
|
2145
|
+
|
|
2146
|
+
uploadZone.addEventListener('keydown', (e) => {
|
|
2147
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
2148
|
+
e.preventDefault();
|
|
2149
|
+
uploadInput.click();
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
|
|
2153
|
+
uploadZone.addEventListener('dragenter', (e) => {
|
|
2154
|
+
e.preventDefault();
|
|
2155
|
+
uploadDragCounter++;
|
|
2156
|
+
uploadZone.classList.add('drag-over');
|
|
2157
|
+
});
|
|
2158
|
+
|
|
2159
|
+
uploadZone.addEventListener('dragover', (e) => {
|
|
2160
|
+
e.preventDefault();
|
|
2161
|
+
});
|
|
2162
|
+
|
|
2163
|
+
uploadZone.addEventListener('dragleave', (e) => {
|
|
2164
|
+
e.preventDefault();
|
|
2165
|
+
uploadDragCounter--;
|
|
2166
|
+
if (uploadDragCounter <= 0) {
|
|
2167
|
+
uploadDragCounter = 0;
|
|
2168
|
+
uploadZone.classList.remove('drag-over');
|
|
2169
|
+
}
|
|
2170
|
+
});
|
|
2171
|
+
|
|
2172
|
+
uploadZone.addEventListener('drop', (e) => {
|
|
2173
|
+
e.preventDefault();
|
|
2174
|
+
uploadDragCounter = 0;
|
|
2175
|
+
uploadZone.classList.remove('drag-over');
|
|
2176
|
+
handleSelectedFiles(e.dataTransfer.files);
|
|
1920
2177
|
});
|
|
1921
2178
|
|
|
1922
2179
|
// Clear URL when upload is cleared
|
|
@@ -1925,6 +2182,7 @@
|
|
|
1925
2182
|
urlInput.disabled = false;
|
|
1926
2183
|
uploadInput.value = '';
|
|
1927
2184
|
pendingFiles = [];
|
|
2185
|
+
updateUploadFeedback([]);
|
|
1928
2186
|
}
|
|
1929
2187
|
});
|
|
1930
2188
|
|
|
@@ -2254,7 +2512,7 @@
|
|
|
2254
2512
|
<img src="https://github.com/neikiri/neiki-editor/raw/main/logo.png" alt="Neiki's Editor" style="width: 120px; height: auto; margin: 0 auto 16px; display: block;">
|
|
2255
2513
|
<div style="font-size: 14px; line-height: 2; color: var(--neiki-text-primary);">
|
|
2256
2514
|
<div><strong>${Utils.escapeHTML(t('help.author'))}:</strong> neikiri (Jindřich Stoklasa)</div>
|
|
2257
|
-
<div><strong>${Utils.escapeHTML(t('help.version'))}:</strong> 2.9.
|
|
2515
|
+
<div><strong>${Utils.escapeHTML(t('help.version'))}:</strong> 2.9.5</div>
|
|
2258
2516
|
<div><strong>${Utils.escapeHTML(t('help.github'))}:</strong> <a href="https://github.com/neikiri/neiki-editor" target="_blank" rel="noopener noreferrer" style="color: var(--neiki-accent);">github.com/neikiri/neiki-editor</a></div>
|
|
2259
2517
|
<div><strong>${Utils.escapeHTML(t('help.documentation'))}:</strong> <a href="https://github.com/neikiri/neiki-editor/wiki" target="_blank" rel="noopener noreferrer" style="color: var(--neiki-accent);">Wiki</a></div>
|
|
2260
2518
|
</div>
|
|
@@ -2876,8 +3134,8 @@
|
|
|
2876
3134
|
if (range && !range.collapsed) {
|
|
2877
3135
|
this.exec('createLink', url);
|
|
2878
3136
|
if (newTab) {
|
|
2879
|
-
const
|
|
2880
|
-
|
|
3137
|
+
const links = Array.from(this.editor.contentArea.querySelectorAll('a'))
|
|
3138
|
+
.filter(link => link.getAttribute('href') === url);
|
|
2881
3139
|
links.forEach(link => {
|
|
2882
3140
|
link.setAttribute('target', '_blank');
|
|
2883
3141
|
link.setAttribute('rel', 'noopener noreferrer');
|
|
@@ -3109,10 +3367,31 @@
|
|
|
3109
3367
|
}
|
|
3110
3368
|
|
|
3111
3369
|
normalizeStorageKey(value) {
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3370
|
+
const input = String(value).trim();
|
|
3371
|
+
let output = '';
|
|
3372
|
+
let lastWasSeparator = false;
|
|
3373
|
+
|
|
3374
|
+
for (let i = 0; i < input.length; i++) {
|
|
3375
|
+
const char = input[i];
|
|
3376
|
+
const isSafe = (char >= 'a' && char <= 'z') ||
|
|
3377
|
+
(char >= 'A' && char <= 'Z') ||
|
|
3378
|
+
(char >= '0' && char <= '9') ||
|
|
3379
|
+
char === '-' ||
|
|
3380
|
+
char === '_';
|
|
3381
|
+
|
|
3382
|
+
if (isSafe) {
|
|
3383
|
+
output += char;
|
|
3384
|
+
lastWasSeparator = false;
|
|
3385
|
+
} else if (!lastWasSeparator) {
|
|
3386
|
+
output += '_';
|
|
3387
|
+
lastWasSeparator = true;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
|
|
3391
|
+
while (output[0] === '_') output = output.slice(1);
|
|
3392
|
+
while (output[output.length - 1] === '_') output = output.slice(0, -1);
|
|
3393
|
+
|
|
3394
|
+
return output || 'editor';
|
|
3116
3395
|
}
|
|
3117
3396
|
|
|
3118
3397
|
hashString(value) {
|
|
@@ -3536,8 +3815,12 @@
|
|
|
3536
3815
|
createContentArea() {
|
|
3537
3816
|
this.contentWrapper = Utils.createElement('div', { className: 'neiki-content-wrapper' });
|
|
3538
3817
|
|
|
3818
|
+
const contentClasses = this.config.custom_class
|
|
3819
|
+
? `neiki-content ${this.config.custom_class}`
|
|
3820
|
+
: 'neiki-content';
|
|
3821
|
+
|
|
3539
3822
|
this.contentArea = Utils.createElement('div', {
|
|
3540
|
-
className:
|
|
3823
|
+
className: contentClasses,
|
|
3541
3824
|
contentEditable: !this.config.readonly,
|
|
3542
3825
|
spellcheck: this.config.spellcheck,
|
|
3543
3826
|
'data-placeholder': t('placeholder')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.neiki-checkbox,.neiki-find-replace-option input{accent-color:var(--neiki-accent-color)}.neiki-modal,.neiki-modal-overlay.show .neiki-modal{animation:.2s neiki-modal-in}:root{--neiki-bg-primary:#ffffff;--neiki-bg-secondary:#f8f9fa;--neiki-bg-tertiary:#e9ecef;--neiki-bg-hover:#dee2e6;--neiki-bg-active:#ced4da;--neiki-border-color:#dee2e6;--neiki-border-color-dark:#adb5bd;--neiki-text-primary:#212529;--neiki-text-secondary:#495057;--neiki-text-muted:#6c757d;--neiki-accent-color:#0d6efd;--neiki-accent-hover:#0b5ed7;--neiki-danger-color:#dc3545;--neiki-success-color:#198754;--neiki-shadow-sm:0 1px 2px rgba(0, 0, 0, 0.05);--neiki-shadow-md:0 4px 6px rgba(0, 0, 0, 0.1);--neiki-shadow-lg:0 10px 15px rgba(0, 0, 0, 0.1);--neiki-editor-bg:#ffffff;--neiki-toolbar-bg:#f8f9fa;--neiki-statusbar-bg:#f8f9fa;--neiki-modal-overlay:rgba(0, 0, 0, 0.5);--neiki-scrollbar-thumb:#ced4da;--neiki-scrollbar-track:#f8f9fa;--neiki-selection-bg:#b3d7ff;--neiki-highlight-color:#fff3cd;--neiki-table-border:#dee2e6}.neiki-editor.neiki-dark{--neiki-bg-primary:#1e1e1e;--neiki-bg-secondary:#252526;--neiki-bg-tertiary:#2d2d30;--neiki-bg-hover:#3e3e42;--neiki-bg-active:#505050;--neiki-border-color:#3e3e42;--neiki-border-color-dark:#505050;--neiki-text-primary:#d4d4d4;--neiki-text-secondary:#a0a0a0;--neiki-text-muted:#808080;--neiki-accent-color:#4fc3f7;--neiki-accent-hover:#29b6f6;--neiki-danger-color:#f44336;--neiki-success-color:#4caf50;--neiki-shadow-sm:0 1px 2px rgba(0, 0, 0, 0.2);--neiki-shadow-md:0 4px 6px rgba(0, 0, 0, 0.3);--neiki-shadow-lg:0 10px 15px rgba(0, 0, 0, 0.4);--neiki-editor-bg:#1e1e1e;--neiki-toolbar-bg:#252526;--neiki-statusbar-bg:#252526;--neiki-modal-overlay:rgba(0, 0, 0, 0.7);--neiki-scrollbar-thumb:#505050;--neiki-scrollbar-track:#2d2d30;--neiki-selection-bg:#264f78;--neiki-highlight-color:#5c4d00;--neiki-table-border:#3e3e42}.neiki-editor{display:flex;flex-direction:column;width:100%;height:100%;min-height:400px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:8px;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:14px;color:var(--neiki-text-primary);box-shadow:var(--neiki-shadow-md)}.neiki-editor *{box-sizing:border-box}.neiki-editor.neiki-fullscreen{position:fixed!important;top:0!important;left:0!important;right:0!important;bottom:0!important;width:100vw!important;height:100vh!important;z-index:999999!important;border-radius:0!important;border:none!important}.neiki-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:var(--neiki-toolbar-bg);border-bottom:1px solid var(--neiki-border-color);min-height:44px}.neiki-editor.neiki-sticky-toolbar{overflow:visible}.neiki-editor.neiki-sticky-toolbar .neiki-toolbar{position:sticky;top:0;z-index:100;border-radius:8px 8px 0 0}.neiki-toolbar-group{display:inline-flex;align-items:center;gap:2px;padding:0 4px;flex-wrap:nowrap}.neiki-toolbar-group:not(:last-child){border-right:1px solid var(--neiki-border-color);padding-right:8px;margin-right:4px}.neiki-toolbar-divider{width:1px;height:24px;background:var(--neiki-border-color);margin:0 4px}.neiki-btn,.neiki-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:0 0;border:1px solid transparent;border-radius:4px;cursor:pointer;color:var(--neiki-text-secondary);transition:.15s;position:relative}.neiki-btn:hover,.neiki-fontsize-btn:hover,.neiki-modal-close:hover,.neiki-preview-close:hover,.neiki-toolbar-btn:hover{background:var(--neiki-bg-hover);color:var(--neiki-text-primary)}.neiki-btn:active,.neiki-floating-btn:active,.neiki-toolbar-btn:active{background:var(--neiki-bg-active)}.neiki-btn.active,.neiki-toolbar-btn.active{background:var(--neiki-bg-active);color:var(--neiki-accent-color);border-color:var(--neiki-accent-color)}.neiki-btn:disabled,.neiki-toolbar-btn:disabled{opacity:.4;cursor:not-allowed}.neiki-btn svg,.neiki-toolbar-btn svg{width:18px;height:18px;fill:currentColor;pointer-events:none}.neiki-select{height:32px;padding:0 28px 0 10px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:4px;color:var(--neiki-text-primary);font-size:13px;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;min-width:100px}.neiki-select:hover{border-color:var(--neiki-border-color-dark)}.neiki-select:focus{outline:0;border-color:var(--neiki-accent-color);box-shadow:0 0 0 2px rgba(13,110,253,.15)}.neiki-color-custom,.neiki-statusbar{border-top:1px solid var(--neiki-border-color)}.neiki-color-btn{position:relative;width:36px}.neiki-color-btn .neiki-color-indicator{position:absolute;bottom:4px;left:50%;transform:translateX(-50%);width:16px;height:3px;border-radius:1px;background:currentColor}.neiki-checkbox-wrapper{display:flex;align-items:center;gap:6px;padding:0 8px;height:32px;font-size:12px;color:var(--neiki-text-secondary);cursor:pointer;user-select:none}.neiki-checkbox{width:16px;height:16px;cursor:pointer}.neiki-content-wrapper,.neiki-editor-wrapper{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.neiki-content{flex:1;padding:20px 24px;background:var(--neiki-editor-bg);overflow-y:auto;outline:0;line-height:1.6;color:var(--neiki-text-primary);min-height:200px}.neiki-code-view-textarea:focus,.neiki-content:focus{outline:0}.neiki-content:empty::before{content:attr(data-placeholder);color:var(--neiki-text-muted);font-style:italic;pointer-events:none}.neiki-content.neiki-drag-over{border:2px dashed var(--neiki-accent-color);background:rgba(13,110,253,.05)}.neiki-content.neiki-drag-over::after{content:'Drop images here';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--neiki-accent-color);font-weight:600;font-size:16px;pointer-events:none;z-index:10}.neiki-editor.neiki-disabled{opacity:.6;pointer-events:none}.neiki-content::-webkit-scrollbar{width:10px}.neiki-content::-webkit-scrollbar-track{background:var(--neiki-scrollbar-track)}.neiki-content::-webkit-scrollbar-thumb{background:var(--neiki-scrollbar-thumb);border-radius:5px}.neiki-content::-webkit-scrollbar-thumb:hover{background:var(--neiki-border-color-dark)}.neiki-content p{margin:0 0 1em}.neiki-content h1{font-size:2em;font-weight:700;margin:0 0 .5em}.neiki-content h2{font-size:1.5em;font-weight:600;margin:0 0 .5em}.neiki-content h3{font-size:1.25em;font-weight:600;margin:0 0 .5em}.neiki-content h4{font-size:1.1em;font-weight:600;margin:0 0 .5em}.neiki-content h5{font-size:1em;font-weight:600;margin:0 0 .5em}.neiki-content h6{font-size:.9em;font-weight:600;margin:0 0 .5em}.neiki-content ol,.neiki-content ul{margin:0 0 1em;padding-left:2em}.neiki-content li{margin-bottom:.25em}.neiki-content blockquote{margin:0 0 1em;padding:10px 20px;border-left:4px solid var(--neiki-accent-color);background:var(--neiki-bg-secondary);font-style:italic}.neiki-content code,.neiki-content pre{background:var(--neiki-bg-tertiary);font-family:Consolas,Monaco,monospace}.neiki-content pre{margin:0 0 1em;padding:16px;border-radius:4px;overflow-x:auto;font-size:13px}.neiki-content code{padding:2px 6px;border-radius:3px;font-size:.9em}.neiki-content a{color:var(--neiki-accent-color);text-decoration:underline}.neiki-content a:hover{color:var(--neiki-accent-hover)}.neiki-content img{max-width:100%;height:auto;border-radius:4px;cursor:pointer}.neiki-content img.neiki-selected{outline:2px solid var(--neiki-accent-color);outline-offset:2px}.neiki-highlight{background:var(--neiki-highlight-color);padding:1px 0}.neiki-content table,.neiki-table{width:100%;border-collapse:collapse;margin:1em 0;table-layout:fixed}.neiki-content table td,.neiki-content table th{border:1px solid var(--neiki-table-border);padding:8px 12px;min-width:50px;vertical-align:top;position:relative}.neiki-content table th{background:var(--neiki-bg-secondary);font-weight:600}.neiki-btn-secondary:hover,.neiki-button-secondary:hover,.neiki-content table td:hover,.neiki-content table th:hover,.neiki-context-item:hover,.neiki-context-menu-item:hover,.neiki-dropdown-item:hover,.neiki-fontsize-dropdown-item:hover,.neiki-special-char-item:hover{background:var(--neiki-bg-hover)}.neiki-content table td.neiki-cell-selected,.neiki-content table th.neiki-cell-selected{background:var(--neiki-selection-bg)}.neiki-table-resize-handle{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:10}.neiki-table-resize-handle:hover{background:var(--neiki-accent-color)}.neiki-statusbar{display:flex;justify-content:space-between;align-items:center;padding:6px 12px;background:var(--neiki-statusbar-bg);font-size:12px;color:var(--neiki-text-muted)}.neiki-statusbar-left,.neiki-statusbar-right{display:flex;align-items:center;gap:16px}.neiki-statusbar-item{display:flex;align-items:center;gap:4px}.neiki-statusbar-block{font-family:Consolas,Monaco,monospace;font-size:11px;padding:2px 6px;background:var(--neiki-bg-tertiary);border-radius:3px;color:var(--neiki-accent-color);font-weight:600;border:1px solid var(--neiki-border-color)}.neiki-color-picker,.neiki-dropdown{position:absolute;top:100%;left:0;z-index:1000;border:1px solid var(--neiki-border-color);box-shadow:var(--neiki-shadow-lg)}.neiki-dropdown{min-width:180px;background:var(--neiki-bg-primary);border-radius:6px;padding:4px;margin-top:4px}.neiki-dropdown-item{display:flex;align-items:center;gap:6px;padding:7px 10px;border-radius:4px;cursor:pointer;color:var(--neiki-text-primary);font-size:13px;transition:background .1s}.neiki-dropdown-item.active{background:var(--neiki-bg-active);color:var(--neiki-accent-color)}.neiki-context-divider,.neiki-context-menu-divider,.neiki-dropdown-divider{height:1px;background:var(--neiki-border-color);margin:4px 0}.neiki-color-picker{background:var(--neiki-bg-primary);border-radius:8px;padding:8px;margin-top:4px;display:flex;flex-direction:column;gap:6px}.neiki-color-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:2px}.neiki-color-custom{display:flex;align-items:center;gap:6px}.neiki-color-custom-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:28px;height:28px;border:1px solid var(--neiki-border-color);border-radius:4px;padding:2px;cursor:pointer;background:0 0}.neiki-color-custom-input::-webkit-color-swatch-wrapper{padding:0}.neiki-color-custom-input::-webkit-color-swatch{border:none;border-radius:2px}.neiki-color-custom-input::-moz-color-swatch{border:none;border-radius:2px}.neiki-color-hex-input{flex:1;height:28px;padding:0 8px;border:1px solid var(--neiki-border-color);border-radius:4px;font-size:12px;font-family:monospace;background:var(--neiki-bg-secondary);color:var(--neiki-text-primary);outline:0}.neiki-color-hex-input:focus{border-color:var(--neiki-accent-color);box-shadow:0 0 0 2px rgba(13,110,253,.15)}.neiki-color-apply-btn{height:28px;padding:0 10px;border:none;border-radius:4px;font-size:12px;font-weight:500;background:var(--neiki-accent-color);color:#fff;cursor:pointer;transition:background .15s}.neiki-emoji-picker,.neiki-special-picker{max-width:calc(100vw - 16px);overflow-y:auto;background:var(--neiki-bg-primary);padding:8px;margin-top:4px;position:absolute;top:100%;z-index:1000;box-shadow:var(--neiki-shadow-lg);left:0}.neiki-btn-primary:hover,.neiki-button-primary:hover,.neiki-color-apply-btn:hover{background:var(--neiki-accent-hover)}.neiki-color-swatch{width:22px;height:22px;border-radius:3px;cursor:pointer;border:1px solid var(--neiki-border-color);transition:transform .1s}.neiki-color-swatch:hover{transform:scale(1.2);z-index:1}.neiki-color-swatch.neiki-color-reset{background:#fff;position:relative;overflow:hidden;border:1px solid #ccc}.neiki-color-preset.active,.neiki-special-item:hover{border-color:var(--neiki-accent-color)}.neiki-color-swatch.neiki-color-reset::after{content:'';position:absolute;top:50%;left:-2px;right:-2px;height:2px;background:#e53935;transform:rotate(-45deg);transform-origin:center;pointer-events:none}.neiki-color-picker-label{font-size:11px;font-weight:600;color:var(--neiki-text-muted);text-transform:uppercase;margin-bottom:8px}.neiki-emoji-item,.neiki-special-item{align-items:center;font-size:18px;cursor:pointer}.neiki-emoji-picker{width:280px;max-height:250px;border:1px solid var(--neiki-border-color);border-radius:8px;display:grid;grid-template-columns:repeat(10,1fr);gap:2px}.neiki-emoji-item{display:flex;justify-content:center;width:24px;height:24px;border-radius:4px;transition:background .15s,transform .1s}.neiki-emoji-item:hover{background:var(--neiki-bg-hover);transform:scale(1.2)}.neiki-special-picker{width:320px;max-height:280px;border:1px solid var(--neiki-border-color);border-radius:8px;display:grid;grid-template-columns:repeat(8,1fr);gap:4px}.neiki-special-item{display:flex;justify-content:center;width:32px;height:32px;border-radius:4px;border:1px solid var(--neiki-border-color);background:var(--neiki-bg-secondary);transition:.15s}.neiki-special-item:hover{background:var(--neiki-accent-color);color:#fff;transform:scale(1.1)}.neiki-highlight-find{background:#ffeb3b;padding:1px 0;border-radius:2px}.neiki-highlight-current{background:#ff9800;outline:#e65100 solid 2px}.neiki-color-presets{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-bottom:12px}.neiki-color-preset{width:32px;height:32px;border-radius:4px;border:2px solid transparent;cursor:pointer;transition:transform .1s,border-color .1s}.neiki-color-preset:hover{transform:scale(1.1)}.neiki-color-preset.neiki-color-reset{background:linear-gradient(45deg,#fff 45%,red 45%,red 55%,#fff 55%);border:1px solid var(--neiki-border-color)}.neiki-color-custom{display:flex;align-items:center;gap:8px;padding-top:8px;border-top:1px solid var(--neiki-border-color)}.neiki-color-custom input[type=color]{width:40px;height:32px;padding:0;border:1px solid var(--neiki-border-color);border-radius:4px;cursor:pointer}.neiki-color-custom input[type=text]{flex:1;height:32px;padding:0 8px;border:1px solid var(--neiki-border-color);border-radius:4px;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-size:12px;font-family:monospace}.neiki-table-picker,.neiki-table-picker-cell{border:1px solid var(--neiki-border-color);background:var(--neiki-bg-primary)}.neiki-table-picker{position:absolute;top:100%;left:0;z-index:1000;border-radius:8px;box-shadow:var(--neiki-shadow-lg);padding:12px;display:none}.neiki-context-menu.show,.neiki-find-replace.show,.neiki-fontsize-dropdown.show,.neiki-table-picker.show{display:block}.neiki-table-picker-label{font-size:12px;color:var(--neiki-text-secondary);margin-bottom:8px;text-align:center}.neiki-dark .neiki-modal h3,.neiki-dark .neiki-modal-header h3,.neiki-modal-title{color:var(--neiki-text-primary)}.neiki-table-picker-grid{display:grid;grid-template-columns:repeat(10,20px);gap:2px}.neiki-table-picker-cell{width:20px;height:20px;border-radius:2px;cursor:pointer;transition:background .1s}.neiki-table-picker-cell.active,.neiki-table-picker-cell:hover{background:var(--neiki-accent-color);border-color:var(--neiki-accent-color)}.neiki-special-chars{position:absolute;top:100%;left:0;z-index:1000;width:280px;max-height:300px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:8px;box-shadow:var(--neiki-shadow-lg);display:none;overflow:hidden}.neiki-special-chars.show{display:flex;flex-direction:column}.neiki-special-chars-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:2px;padding:8px;overflow-y:auto}.neiki-special-char-item{display:flex;align-items:center;justify-content:center;width:24px;height:24px;font-size:16px;border-radius:4px;cursor:pointer;transition:background .1s}.neiki-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--neiki-modal-overlay);z-index:10000;display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:opacity .2s,visibility .2s}.neiki-modal-overlay.active,[data-tooltip]:hover::after{opacity:1;visibility:visible}.neiki-modal{background:var(--neiki-bg-primary);border-radius:12px;box-shadow:var(--neiki-shadow-lg);width:100%;max-width:440px;max-height:90vh;overflow:hidden}.neiki-modal-wide{max-width:520px}.neiki-modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--neiki-border-color)}.neiki-modal-title{font-size:16px;font-weight:600;margin:0}.neiki-modal-close,.neiki-preview-close{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background:0 0;border:none;border-radius:4px;cursor:pointer;color:var(--neiki-text-muted);transition:background .15s}.neiki-modal-body{padding:20px;overflow-y:auto}.neiki-modal h3,.neiki-modal-header h3{color:#000;margin:0}.neiki-modal-footer{display:flex;justify-content:flex-end;gap:10px;padding:16px 20px;border-top:1px solid var(--neiki-border-color)}.neiki-modal-footer .neiki-btn{width:auto;height:38px;padding:0 16px;font-size:14px;font-weight:500;border-radius:6px}.neiki-form-divider::after,.neiki-form-divider::before{content:'';height:1px;background:var(--neiki-border-color)}.neiki-form-group{margin-bottom:16px}.neiki-find-replace-row:last-child,.neiki-form-group:last-child{margin-bottom:0}.neiki-form-group label,.neiki-form-label{display:block;margin-bottom:6px;font-size:13px;font-weight:500;color:var(--neiki-text-secondary)}.neiki-form-input,.neiki-form-textarea,.neiki-input{width:100%;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-size:14px;transition:border-color .15s}.neiki-form-input,.neiki-input{height:40px;padding:0 12px;border:1px solid var(--neiki-border-color);border-radius:6px}.neiki-form-input:focus,.neiki-form-textarea:focus,.neiki-input:focus{outline:0;border-color:var(--neiki-accent-color);box-shadow:0 0 0 3px rgba(13,110,253,.15)}.neiki-form-input::placeholder,.neiki-input::placeholder{color:var(--neiki-text-muted)}.neiki-input[type=file]{display:flex;align-items:center;padding:0;cursor:pointer}.neiki-input[type=file]::file-selector-button{height:100%;padding:0 14px;margin-right:12px;border:none;border-right:1px solid var(--neiki-border-color);background:var(--neiki-bg-tertiary,var(--neiki-bg-hover));color:var(--neiki-text-primary);font-size:13px;font-weight:500;cursor:pointer;border-radius:5px 0 0 5px}.neiki-find-replace,.neiki-form-textarea{border:1px solid var(--neiki-border-color)}.neiki-form-row{display:flex;gap:16px}.neiki-form-divider{display:flex;align-items:center;margin:16px 0;text-align:center;position:relative}.neiki-form-divider::before{flex:1;margin-right:12px}.neiki-form-divider::after{flex:1;margin-left:12px}.neiki-form-divider span{color:var(--neiki-text-muted);font-size:12px;font-weight:500;text-transform:uppercase}.neiki-form-textarea{min-height:120px;padding:12px;border-radius:6px;font-family:inherit;resize:vertical}.neiki-btn-primary,.neiki-btn-secondary,.neiki-button{display:inline-flex;align-items:center;height:38px;padding:0 16px;font-size:14px;transition:.15s;font-weight:500;cursor:pointer}.neiki-button{justify-content:center;gap:6px;border:1px solid transparent;border-radius:6px}.neiki-btn-primary,.neiki-button-primary{background:var(--neiki-accent-color);color:#fff}.neiki-btn-secondary,.neiki-button-secondary{background:var(--neiki-bg-secondary);color:var(--neiki-text-primary);border-color:var(--neiki-border-color)}.neiki-btn-primary,.neiki-btn-secondary{justify-content:center;border:1px solid transparent;border-radius:6px}.neiki-btn-secondary{border-color:var(--neiki-border-color)}.neiki-button-danger{background:var(--neiki-danger-color);color:#fff}.neiki-code-view,.neiki-find-replace,.neiki-find-replace-input{background:var(--neiki-bg-primary)}.neiki-button-danger:hover{opacity:.9}.neiki-find-replace{position:absolute;top:0;right:0;z-index:100;width:360px;border-radius:0 0 0 8px;box-shadow:var(--neiki-shadow-lg);display:none}.neiki-find-replace-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--neiki-border-color)}.neiki-code-view-title,.neiki-find-replace-title{font-size:13px;font-weight:600;color:var(--neiki-text-primary)}.neiki-find-replace-body{padding:12px}.neiki-find-replace-row{display:flex;gap:8px;margin-bottom:10px}.neiki-find-replace-input{flex:1;height:32px;padding:0 10px;border:1px solid var(--neiki-border-color);border-radius:4px;color:var(--neiki-text-primary);font-size:13px}.neiki-find-replace-input:focus{outline:0;border-color:var(--neiki-accent-color)}.neiki-find-replace-options{display:flex;align-items:center;gap:12px;margin-bottom:10px}.neiki-find-replace-option{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--neiki-text-secondary);cursor:pointer}.neiki-find-replace-actions{display:flex;gap:6px;flex-wrap:wrap}.neiki-find-replace-btn{height:28px;padding:0 10px;font-size:12px;border-radius:4px}.neiki-find-replace-count{font-size:12px;color:var(--neiki-text-muted);margin-left:auto}.neiki-code-view{position:absolute;top:0;left:0;right:0;bottom:0;z-index:50;display:none;flex-direction:column}.neiki-code-view.show,.neiki-drop-overlay.show{display:flex}.neiki-code-view-header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px;background:var(--neiki-bg-secondary);border-bottom:1px solid var(--neiki-border-color);flex-shrink:0}.neiki-code-view-textarea{flex:1;width:100%;padding:16px;border:none;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-family:Consolas,Monaco,'Courier New',monospace;font-size:13px;line-height:1.5;resize:none}.neiki-code-view-apply{width:auto!important;padding:0 12px!important;display:inline-flex;align-items:center;gap:4px;height:30px;font-size:12px;background:var(--neiki-accent-color)!important;color:#fff!important;border-radius:5px}.neiki-context-menu,.neiki-floating-btn,.neiki-floating-toolbar{background:var(--neiki-bg-primary)}.neiki-code-view-apply:hover{background:var(--neiki-accent-hover)!important;color:#fff!important}.neiki-code-view-apply svg{width:14px!important;height:14px!important}.neiki-context-menu{position:fixed;z-index:10001;min-width:180px;border:1px solid var(--neiki-border-color);border-radius:8px;box-shadow:var(--neiki-shadow-lg);padding:4px;display:none}.neiki-context-item,.neiki-context-menu-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:4px;cursor:pointer;color:var(--neiki-text-primary);font-size:13px;transition:background .1s}.neiki-context-item.neiki-context-danger,.neiki-context-menu-item.danger{color:var(--neiki-danger-color)}.neiki-context-item svg,.neiki-context-menu-item svg,.neiki-dropdown-item-icon svg,.neiki-floating-btn svg,.neiki-img-toolbar-btn svg{width:16px;height:16px;fill:currentColor}.neiki-floating-toolbar{position:absolute;z-index:1000;display:none;border:1px solid var(--neiki-border-color);border-radius:8px;box-shadow:var(--neiki-shadow-lg);padding:4px}.neiki-floating-toolbar.show{display:flex;align-items:center;gap:2px}.neiki-floating-btn{width:32px;height:32px;border:none;color:var(--neiki-text-primary);border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.15s}.neiki-floating-btn:hover,.neiki-img-toolbar-btn:hover{background:var(--neiki-bg-hover);color:var(--neiki-accent-color)}.neiki-floating-toolbar .neiki-btn{width:28px;height:28px}.neiki-chevron svg,.neiki-floating-toolbar .neiki-btn svg{width:14px;height:14px}.neiki-floating-divider,.neiki-img-toolbar-separator{width:1px;height:20px;background:var(--neiki-border-color);margin:0 2px}.neiki-floating-move-btn svg{width:16px;height:16px}.neiki-more-btn,[data-tooltip]{position:relative}[data-tooltip]::after{content:attr(data-tooltip);position:absolute;bottom:100%;left:50%;transform:translateX(-50%);padding:6px 10px;background:var(--neiki-text-primary);color:var(--neiki-bg-primary);font-size:11px;font-weight:500;white-space:nowrap;border-radius:4px;opacity:0;visibility:hidden;transition:opacity .15s,visibility .15s;pointer-events:none;z-index:10002;margin-bottom:6px}.neiki-drop-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(13,110,253,.1);border:3px dashed var(--neiki-accent-color);border-radius:8px;display:none;align-items:center;justify-content:center;z-index:100;pointer-events:none}.neiki-img-size-label,.neiki-img-toolbar{left:50%;transform:translateX(-50%);white-space:nowrap}.neiki-drop-overlay-text{font-size:18px;font-weight:600;color:var(--neiki-accent-color)}.neiki-img-resizable{display:inline-block;position:relative;outline:2px solid var(--neiki-accent-color);outline-offset:2px;border-radius:4px;line-height:0}.neiki-img-resizable img{display:block;max-width:100%}.neiki-img-resize-handle{position:absolute;width:12px;height:12px;background:var(--neiki-accent-color);border:2px solid #fff;border-radius:2px;z-index:10;box-shadow:0 1px 3px rgba(0,0,0,.3)}.neiki-img-resize-handle.nw{top:-6px;left:-6px;cursor:nw-resize}.neiki-img-resize-handle.ne{top:-6px;right:-6px;cursor:ne-resize}.neiki-img-resize-handle.sw{bottom:-6px;left:-6px;cursor:sw-resize}.neiki-img-resize-handle.se{bottom:-6px;right:-6px;cursor:se-resize}.neiki-img-size-label{position:absolute;bottom:-32px;background:var(--neiki-text-primary);color:var(--neiki-bg-primary);font-size:13px;line-height:1.4;font-weight:600;padding:4px 12px;border-radius:6px;pointer-events:none;z-index:10;opacity:.9}@media (pointer:coarse){.neiki-img-resize-handle{width:20px;height:20px}.neiki-img-resize-handle.nw{top:-10px;left:-10px}.neiki-img-resize-handle.ne{top:-10px;right:-10px}.neiki-img-resize-handle.sw{bottom:-10px;left:-10px}.neiki-img-resize-handle.se{bottom:-10px;right:-10px}}.neiki-img-toolbar{position:absolute;display:flex;align-items:center;gap:2px;padding:4px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:6px;box-shadow:var(--neiki-shadow-md);z-index:20}.neiki-img-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:4px;background:0 0;color:var(--neiki-text-secondary);cursor:pointer;transition:.15s}.neiki-img-toolbar-btn-danger:hover{background:#fee2e2;color:#dc2626}.neiki-editor.neiki-dark .neiki-img-toolbar-btn-danger:hover{background:#451a1a;color:#f87171}.neiki-img-drag-handle{cursor:grab}.neiki-block-grip:active,.neiki-img-drag-handle:active{cursor:grabbing}.neiki-table-col-resize-handle{position:absolute;width:6px;cursor:col-resize;z-index:10;background:0 0;transition:background .1s}.neiki-table-col-resize-handle:active,.neiki-table-col-resize-handle:hover{background:var(--neiki-accent-color);opacity:.6;border-radius:3px}.neiki-block-grip{position:absolute;width:22px;height:22px;display:flex;align-items:center;justify-content:center;cursor:grab;color:var(--neiki-text-muted);opacity:0;transition:opacity .15s,color .15s;border-radius:4px;z-index:5;user-select:none}.neiki-content:hover .neiki-block-grip{opacity:.5}.neiki-block-grip:hover{opacity:1!important;color:var(--neiki-text-primary);background:var(--neiki-bg-hover)}.neiki-block-grip svg{width:14px;height:14px;fill:currentColor;pointer-events:none}.neiki-block-ghost{position:fixed;z-index:100000;pointer-events:none;opacity:.7;background:var(--neiki-bg-primary);border:2px solid var(--neiki-accent-color);border-radius:6px;padding:8px 12px;box-shadow:var(--neiki-shadow-lg);max-height:120px;overflow:hidden}.neiki-block-placeholder{border:2px dashed var(--neiki-accent-color);border-radius:6px;background:rgba(13,110,253,.05);margin:2px 0;transition:height .15s}@media print{.neiki-content,.neiki-editor-wrapper{overflow:visible!important}.neiki-editor{border:none!important;box-shadow:none!important}.neiki-block-grip,.neiki-code-view-header,.neiki-find-replace,.neiki-floating-toolbar,.neiki-img-resize-handle,.neiki-img-size-label,.neiki-img-toolbar,.neiki-statusbar,.neiki-table-col-resize-handle,.neiki-toolbar{display:none!important}.neiki-content{padding:0!important}}@media (max-width:768px){.neiki-toolbar{padding:4px;gap:1px}.neiki-toolbar-group{padding:0 2px}.neiki-toolbar-group:not(:last-child){padding-right:4px;margin-right:2px}.neiki-btn{width:28px;height:28px}.neiki-btn svg{width:16px;height:16px}.neiki-select{height:28px;min-width:80px;font-size:12px;padding:0 24px 0 8px}.neiki-content,.neiki-modal-footer,.neiki-modal-header{padding:12px 16px}.neiki-statusbar{padding:4px 8px;font-size:11px}.neiki-modal{width:calc(100% - 20px);max-width:none;margin:10px;max-height:calc(100vh - 40px);border-radius:10px}.neiki-modal-overlay{padding:10px}.neiki-modal-body{padding:16px;max-height:calc(100vh - 160px);overflow-y:auto;-webkit-overflow-scrolling:touch}.neiki-modal-footer .neiki-btn{height:36px;padding:0 14px;font-size:13px}.neiki-form-row{flex-direction:column;gap:12px}.neiki-form-input,.neiki-input{height:38px;font-size:16px}.neiki-find-replace{width:100%;border-radius:0}.neiki-checkbox-wrapper{padding:0 4px;font-size:11px}.neiki-color-picker{left:auto;right:0}}@media (max-width:480px){.neiki-toolbar-group:not(:last-child){border-right:none;padding-right:2px;margin-right:0}.neiki-select{min-width:60px}.neiki-statusbar-left,.neiki-statusbar-right{gap:8px}.neiki-img-toolbar{padding:3px;gap:1px;border-radius:5px;left:0;transform:none;max-width:calc(100vw - 20px)}.neiki-img-toolbar-btn{width:26px;height:26px}.neiki-img-toolbar-btn svg{width:14px;height:14px}.neiki-img-toolbar-separator{height:16px;margin:0 1px}}@keyframes neiki-fade-in{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.neiki-color-picker.show,.neiki-dropdown.show,.neiki-emoji-picker.show,.neiki-special-chars.show,.neiki-table-picker.show{animation:.15s neiki-fade-in}@keyframes neiki-modal-in{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.neiki-fontsize-widget{display:inline-flex;align-items:center;position:relative;height:32px;border:1px solid var(--neiki-border-color);border-radius:4px;overflow:visible;background:var(--neiki-bg-primary)}.neiki-fontsize-btn{display:flex;align-items:center;justify-content:center;width:26px;height:30px;background:0 0;border:none;cursor:pointer;color:var(--neiki-text-secondary);transition:background .15s,color .15s;padding:0}.neiki-fontsize-dropdown-item,.neiki-fontsize-input{color:var(--neiki-text-primary);text-align:center;font-size:13px}.neiki-fontsize-input{width:38px;height:30px;border:none;border-left:1px solid var(--neiki-border-color);border-right:1px solid var(--neiki-border-color);background:var(--neiki-bg-primary);outline:0;-moz-appearance:textfield;appearance:textfield;padding:0}.neiki-fontsize-dropdown,.neiki-insert-dropdown{left:0;border:1px solid var(--neiki-border-color)}.neiki-fontsize-input::-webkit-inner-spin-button,.neiki-fontsize-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.neiki-fontsize-dropdown{display:none;position:absolute;top:100%;z-index:1000;min-width:70px;max-height:240px;overflow-y:auto;background:var(--neiki-bg-primary);border-radius:6px;box-shadow:var(--neiki-shadow-lg);padding:4px;margin-top:4px}.neiki-fontsize-dropdown-item{padding:6px 12px;cursor:pointer;border-radius:4px;transition:background .1s}.neiki-insert-dropdown-btn{width:auto!important;padding:0 8px!important;gap:4px;font-size:13px;font-weight:500}.neiki-insert-label{font-size:13px;pointer-events:none}.neiki-chevron{display:inline-flex;pointer-events:none}.neiki-insert-dropdown,.neiki-more-dropdown{display:none;position:absolute;top:100%;z-index:1000;background:var(--neiki-bg-primary);box-shadow:var(--neiki-shadow-lg);padding:4px;margin-top:4px}.neiki-insert-dropdown{min-width:160px;max-width:calc(100vw - 16px);border-radius:6px}.neiki-insert-dropdown.show,.neiki-more-dropdown.show{display:block;animation:.15s neiki-fade-in}.neiki-more-dropdown{right:0;min-width:140px;max-width:170px;border:1px solid var(--neiki-border-color);border-radius:6px}.neiki-lang-cs .neiki-more-dropdown{min-width:165px}.neiki-dropdown-item-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.neiki-dropdown-item-danger{color:var(--neiki-danger-color)!important}.neiki-dropdown-item-danger:hover{background:rgba(220,53,69,.1)}.neiki-autosave-badge{font-size:12px;font-weight:600;color:var(--neiki-text-muted);padding:0 4px}.neiki-autosave-badge.active{color:var(--neiki-success-color)}.neiki-preview-overlay{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:100000;display:flex;align-items:center;justify-content:center;padding:30px;animation:.2s neiki-fade-in}.neiki-preview-modal{background:var(--neiki-bg-primary);border-radius:12px;width:100%;max-width:900px;max-height:90vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 25px 60px rgba(0,0,0,.3);animation:.2s neiki-modal-in}.neiki-preview-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;background:var(--neiki-bg-secondary);border-bottom:1px solid var(--neiki-border-color);font-weight:600;font-size:14px;color:var(--neiki-text-primary)}.neiki-preview-close svg{width:18px;height:18px;fill:currentColor}.neiki-preview-body{flex:1;overflow:auto;padding:30px;color:var(--neiki-text-primary);font-size:15px;line-height:1.7}.neiki-preview-body img{max-width:100%}.neiki-preview-body table{border-collapse:collapse;width:100%}.neiki-preview-body table td,.neiki-preview-body table th{border:1px solid var(--neiki-border-color);padding:8px 12px}.neiki-statusbar-autosave{font-style:italic;color:var(--neiki-success-color);font-size:11px}
|
|
1
|
+
.neiki-checkbox,.neiki-find-replace-option input{accent-color:var(--neiki-accent-color)}.neiki-modal,.neiki-modal-overlay.show .neiki-modal{animation:.2s neiki-modal-in}:root{--neiki-bg-primary:#ffffff;--neiki-bg-secondary:#f8f9fa;--neiki-bg-tertiary:#e9ecef;--neiki-bg-hover:#dee2e6;--neiki-bg-active:#ced4da;--neiki-border-color:#dee2e6;--neiki-border-color-dark:#adb5bd;--neiki-text-primary:#212529;--neiki-text-secondary:#495057;--neiki-text-muted:#6c757d;--neiki-accent-color:#0d6efd;--neiki-accent-hover:#0b5ed7;--neiki-danger-color:#dc3545;--neiki-success-color:#198754;--neiki-shadow-sm:0 1px 2px rgba(0, 0, 0, 0.05);--neiki-shadow-md:0 4px 6px rgba(0, 0, 0, 0.1);--neiki-shadow-lg:0 10px 15px rgba(0, 0, 0, 0.1);--neiki-editor-bg:#ffffff;--neiki-toolbar-bg:#f8f9fa;--neiki-statusbar-bg:#f8f9fa;--neiki-modal-overlay:rgba(0, 0, 0, 0.5);--neiki-scrollbar-thumb:#ced4da;--neiki-scrollbar-track:#f8f9fa;--neiki-selection-bg:#b3d7ff;--neiki-highlight-color:#fff3cd;--neiki-table-border:#dee2e6}.neiki-editor.neiki-dark{--neiki-bg-primary:#1e1e1e;--neiki-bg-secondary:#252526;--neiki-bg-tertiary:#2d2d30;--neiki-bg-hover:#3e3e42;--neiki-bg-active:#505050;--neiki-border-color:#3e3e42;--neiki-border-color-dark:#505050;--neiki-text-primary:#d4d4d4;--neiki-text-secondary:#a0a0a0;--neiki-text-muted:#808080;--neiki-accent-color:#4fc3f7;--neiki-accent-hover:#29b6f6;--neiki-danger-color:#f44336;--neiki-success-color:#4caf50;--neiki-shadow-sm:0 1px 2px rgba(0, 0, 0, 0.2);--neiki-shadow-md:0 4px 6px rgba(0, 0, 0, 0.3);--neiki-shadow-lg:0 10px 15px rgba(0, 0, 0, 0.4);--neiki-editor-bg:#1e1e1e;--neiki-toolbar-bg:#252526;--neiki-statusbar-bg:#252526;--neiki-modal-overlay:rgba(0, 0, 0, 0.7);--neiki-scrollbar-thumb:#505050;--neiki-scrollbar-track:#2d2d30;--neiki-selection-bg:#264f78;--neiki-highlight-color:#5c4d00;--neiki-table-border:#3e3e42}.neiki-editor{display:flex;flex-direction:column;width:100%;height:100%;min-height:400px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:8px;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:14px;color:var(--neiki-text-primary);box-shadow:var(--neiki-shadow-md)}.neiki-editor *{box-sizing:border-box}.neiki-editor.neiki-fullscreen{position:fixed!important;top:0!important;left:0!important;right:0!important;bottom:0!important;width:100vw!important;height:100vh!important;z-index:999999!important;border-radius:0!important;border:none!important}.neiki-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:var(--neiki-toolbar-bg);border-bottom:1px solid var(--neiki-border-color);min-height:44px}.neiki-editor.neiki-sticky-toolbar{overflow:visible}.neiki-editor.neiki-sticky-toolbar .neiki-toolbar{position:sticky;top:0;z-index:100;border-radius:8px 8px 0 0}.neiki-toolbar-group{display:inline-flex;align-items:center;gap:2px;padding:0 4px;flex-wrap:nowrap}.neiki-toolbar-group:not(:last-child){border-right:1px solid var(--neiki-border-color);padding-right:8px;margin-right:4px}.neiki-toolbar-divider{width:1px;height:24px;background:var(--neiki-border-color);margin:0 4px}.neiki-btn,.neiki-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:0 0;border:1px solid transparent;border-radius:4px;cursor:pointer;color:var(--neiki-text-secondary);transition:.15s;position:relative}.neiki-btn:hover,.neiki-fontsize-btn:hover,.neiki-modal-close:hover,.neiki-preview-close:hover,.neiki-toolbar-btn:hover{background:var(--neiki-bg-hover);color:var(--neiki-text-primary)}.neiki-btn:active,.neiki-floating-btn:active,.neiki-toolbar-btn:active{background:var(--neiki-bg-active)}.neiki-btn.active,.neiki-toolbar-btn.active{background:var(--neiki-bg-active);color:var(--neiki-accent-color);border-color:var(--neiki-accent-color)}.neiki-btn:disabled,.neiki-toolbar-btn:disabled{opacity:.4;cursor:not-allowed}.neiki-btn svg,.neiki-toolbar-btn svg{width:18px;height:18px;fill:currentColor;pointer-events:none}.neiki-select{height:32px;padding:0 28px 0 10px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:4px;color:var(--neiki-text-primary);font-size:13px;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;min-width:100px}.neiki-select:hover{border-color:var(--neiki-border-color-dark)}.neiki-select:focus{outline:0;border-color:var(--neiki-accent-color);box-shadow:0 0 0 2px rgba(13,110,253,.15)}.neiki-color-custom,.neiki-statusbar{border-top:1px solid var(--neiki-border-color)}.neiki-color-btn{position:relative;width:36px}.neiki-color-btn .neiki-color-indicator{position:absolute;bottom:4px;left:50%;transform:translateX(-50%);width:16px;height:3px;border-radius:1px;background:currentColor}.neiki-checkbox-wrapper{display:flex;align-items:center;gap:6px;padding:0 8px;height:32px;font-size:12px;color:var(--neiki-text-secondary);cursor:pointer;user-select:none}.neiki-checkbox{width:16px;height:16px;cursor:pointer}.neiki-content-wrapper,.neiki-editor-wrapper{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.neiki-content{flex:1;padding:20px 24px;background:var(--neiki-editor-bg);overflow-y:auto;outline:0;line-height:1.6;color:var(--neiki-text-primary);min-height:200px}.neiki-code-view-textarea:focus,.neiki-content:focus{outline:0}.neiki-content:empty::before{content:attr(data-placeholder);color:var(--neiki-text-muted);font-style:italic;pointer-events:none}.neiki-content.neiki-drag-over{border:2px dashed var(--neiki-accent-color);background:rgba(13,110,253,.05)}.neiki-content.neiki-drag-over::after{content:'Drop images here';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--neiki-accent-color);font-weight:600;font-size:16px;pointer-events:none;z-index:10}.neiki-editor.neiki-disabled{opacity:.6;pointer-events:none}.neiki-content::-webkit-scrollbar{width:10px}.neiki-content::-webkit-scrollbar-track{background:var(--neiki-scrollbar-track)}.neiki-content::-webkit-scrollbar-thumb{background:var(--neiki-scrollbar-thumb);border-radius:5px}.neiki-content::-webkit-scrollbar-thumb:hover{background:var(--neiki-border-color-dark)}.neiki-content p{margin:0 0 1em}.neiki-content h1{font-size:2em;font-weight:700;margin:0 0 .5em}.neiki-content h2{font-size:1.5em;font-weight:600;margin:0 0 .5em}.neiki-content h3{font-size:1.25em;font-weight:600;margin:0 0 .5em}.neiki-content h4{font-size:1.1em;font-weight:600;margin:0 0 .5em}.neiki-content h5{font-size:1em;font-weight:600;margin:0 0 .5em}.neiki-content h6{font-size:.9em;font-weight:600;margin:0 0 .5em}.neiki-content ol,.neiki-content ul{margin:0 0 1em;padding-left:2em}.neiki-content li{margin-bottom:.25em}.neiki-content blockquote{margin:0 0 1em;padding:10px 20px;border-left:4px solid var(--neiki-accent-color);background:var(--neiki-bg-secondary);font-style:italic}.neiki-content code,.neiki-content pre{background:var(--neiki-bg-tertiary);font-family:Consolas,Monaco,monospace}.neiki-content pre{margin:0 0 1em;padding:16px;border-radius:4px;overflow-x:auto;font-size:13px}.neiki-content code{padding:2px 6px;border-radius:3px;font-size:.9em}.neiki-content a{color:var(--neiki-accent-color);text-decoration:underline}.neiki-content a:hover{color:var(--neiki-accent-hover)}.neiki-content img{display:inline-block;max-width:100%;height:auto;border-radius:4px;cursor:pointer}.neiki-content img.neiki-selected{outline:2px solid var(--neiki-accent-color);outline-offset:2px}.neiki-highlight{background:var(--neiki-highlight-color);padding:1px 0}.neiki-content table,.neiki-table{width:100%;border-collapse:collapse;margin:1em 0;table-layout:fixed}.neiki-content table td,.neiki-content table th{border:1px solid var(--neiki-table-border);padding:8px 12px;min-width:50px;vertical-align:top;position:relative}.neiki-content table th{background:var(--neiki-bg-secondary);font-weight:600}.neiki-btn-secondary:hover,.neiki-button-secondary:hover,.neiki-content table td:hover,.neiki-content table th:hover,.neiki-context-item:hover,.neiki-context-menu-item:hover,.neiki-dropdown-item:hover,.neiki-fontsize-dropdown-item:hover,.neiki-special-char-item:hover{background:var(--neiki-bg-hover)}.neiki-content table td.neiki-cell-selected,.neiki-content table th.neiki-cell-selected{background:var(--neiki-selection-bg)}.neiki-table-resize-handle{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:10}.neiki-table-resize-handle:hover{background:var(--neiki-accent-color)}.neiki-statusbar{display:flex;justify-content:space-between;align-items:center;padding:6px 12px;background:var(--neiki-statusbar-bg);font-size:12px;color:var(--neiki-text-muted)}.neiki-statusbar-left,.neiki-statusbar-right{display:flex;align-items:center;gap:16px}.neiki-statusbar-item{display:flex;align-items:center;gap:4px}.neiki-statusbar-block{font-family:Consolas,Monaco,monospace;font-size:11px;padding:2px 6px;background:var(--neiki-bg-tertiary);border-radius:3px;color:var(--neiki-accent-color);font-weight:600;border:1px solid var(--neiki-border-color)}.neiki-color-picker,.neiki-dropdown{position:absolute;top:100%;left:0;z-index:1000;border:1px solid var(--neiki-border-color);box-shadow:var(--neiki-shadow-lg)}.neiki-dropdown{min-width:180px;background:var(--neiki-bg-primary);border-radius:6px;padding:4px;margin-top:4px}.neiki-dropdown-item{display:flex;align-items:center;gap:6px;padding:7px 10px;border-radius:4px;cursor:pointer;color:var(--neiki-text-primary);font-size:13px;transition:background .1s}.neiki-dropdown-item.active{background:var(--neiki-bg-active);color:var(--neiki-accent-color)}.neiki-context-divider,.neiki-context-menu-divider,.neiki-dropdown-divider{height:1px;background:var(--neiki-border-color);margin:4px 0}.neiki-color-picker{background:var(--neiki-bg-primary);border-radius:8px;padding:8px;margin-top:4px;display:flex;flex-direction:column;gap:6px}.neiki-color-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:2px}.neiki-color-custom{display:flex;align-items:center;gap:6px}.neiki-color-custom-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:28px;height:28px;border:1px solid var(--neiki-border-color);border-radius:4px;padding:2px;cursor:pointer;background:0 0}.neiki-color-custom-input::-webkit-color-swatch-wrapper{padding:0}.neiki-color-custom-input::-webkit-color-swatch{border:none;border-radius:2px}.neiki-color-custom-input::-moz-color-swatch{border:none;border-radius:2px}.neiki-color-hex-input{flex:1;height:28px;padding:0 8px;border:1px solid var(--neiki-border-color);border-radius:4px;font-size:12px;font-family:monospace;background:var(--neiki-bg-secondary);color:var(--neiki-text-primary);outline:0}.neiki-color-hex-input:focus{border-color:var(--neiki-accent-color);box-shadow:0 0 0 2px rgba(13,110,253,.15)}.neiki-color-apply-btn{height:28px;padding:0 10px;border:none;border-radius:4px;font-size:12px;font-weight:500;background:var(--neiki-accent-color);color:#fff;cursor:pointer;transition:background .15s}.neiki-emoji-picker,.neiki-special-picker{max-width:calc(100vw - 16px);overflow-y:auto;background:var(--neiki-bg-primary);padding:8px;margin-top:4px;position:absolute;top:100%;z-index:1000;box-shadow:var(--neiki-shadow-lg);left:0}.neiki-btn-primary:hover,.neiki-button-primary:hover,.neiki-color-apply-btn:hover{background:var(--neiki-accent-hover)}.neiki-color-swatch{width:22px;height:22px;border-radius:3px;cursor:pointer;border:1px solid var(--neiki-border-color);transition:transform .1s}.neiki-color-swatch:hover{transform:scale(1.2);z-index:1}.neiki-color-swatch.neiki-color-reset{background:#fff;position:relative;overflow:hidden;border:1px solid #ccc}.neiki-color-preset.active,.neiki-special-item:hover{border-color:var(--neiki-accent-color)}.neiki-color-swatch.neiki-color-reset::after{content:'';position:absolute;top:50%;left:-2px;right:-2px;height:2px;background:#e53935;transform:rotate(-45deg);transform-origin:center;pointer-events:none}.neiki-color-picker-label{font-size:11px;font-weight:600;color:var(--neiki-text-muted);text-transform:uppercase;margin-bottom:8px}.neiki-emoji-item,.neiki-special-item{align-items:center;font-size:18px;cursor:pointer}.neiki-emoji-picker{width:280px;max-height:250px;border:1px solid var(--neiki-border-color);border-radius:8px;display:grid;grid-template-columns:repeat(10,1fr);gap:2px}.neiki-emoji-item{display:flex;justify-content:center;width:24px;height:24px;border-radius:4px;transition:background .15s,transform .1s}.neiki-emoji-item:hover{background:var(--neiki-bg-hover);transform:scale(1.2)}.neiki-special-picker{width:320px;max-height:280px;border:1px solid var(--neiki-border-color);border-radius:8px;display:grid;grid-template-columns:repeat(8,1fr);gap:4px}.neiki-special-item{display:flex;justify-content:center;width:32px;height:32px;border-radius:4px;border:1px solid var(--neiki-border-color);background:var(--neiki-bg-secondary);transition:.15s}.neiki-special-item:hover{background:var(--neiki-accent-color);color:#fff;transform:scale(1.1)}.neiki-highlight-find{background:#ffeb3b;padding:1px 0;border-radius:2px}.neiki-highlight-current{background:#ff9800;outline:#e65100 solid 2px}.neiki-color-presets{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-bottom:12px}.neiki-color-preset{width:32px;height:32px;border-radius:4px;border:2px solid transparent;cursor:pointer;transition:transform .1s,border-color .1s}.neiki-color-preset:hover{transform:scale(1.1)}.neiki-color-preset.neiki-color-reset{background:linear-gradient(45deg,#fff 45%,red 45%,red 55%,#fff 55%);border:1px solid var(--neiki-border-color)}.neiki-color-custom{display:flex;align-items:center;gap:8px;padding-top:8px;border-top:1px solid var(--neiki-border-color)}.neiki-color-custom input[type=color]{width:40px;height:32px;padding:0;border:1px solid var(--neiki-border-color);border-radius:4px;cursor:pointer}.neiki-color-custom input[type=text]{flex:1;height:32px;padding:0 8px;border:1px solid var(--neiki-border-color);border-radius:4px;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-size:12px;font-family:monospace}.neiki-table-picker,.neiki-table-picker-cell{border:1px solid var(--neiki-border-color);background:var(--neiki-bg-primary)}.neiki-table-picker{position:absolute;top:100%;left:0;z-index:1000;border-radius:8px;box-shadow:var(--neiki-shadow-lg);padding:12px;display:none}.neiki-context-menu.show,.neiki-find-replace.show,.neiki-fontsize-dropdown.show,.neiki-table-picker.show{display:block}.neiki-table-picker-label{font-size:12px;color:var(--neiki-text-secondary);margin-bottom:8px;text-align:center}.neiki-dark .neiki-modal h3,.neiki-dark .neiki-modal-header h3,.neiki-modal-title{color:var(--neiki-text-primary)}.neiki-table-picker-grid{display:grid;grid-template-columns:repeat(10,20px);gap:2px}.neiki-table-picker-cell{width:20px;height:20px;border-radius:2px;cursor:pointer;transition:background .1s}.neiki-table-picker-cell.active,.neiki-table-picker-cell:hover{background:var(--neiki-accent-color);border-color:var(--neiki-accent-color)}.neiki-special-chars{position:absolute;top:100%;left:0;z-index:1000;width:280px;max-height:300px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:8px;box-shadow:var(--neiki-shadow-lg);display:none;overflow:hidden}.neiki-special-chars.show{display:flex;flex-direction:column}.neiki-special-chars-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:2px;padding:8px;overflow-y:auto}.neiki-special-char-item{display:flex;align-items:center;justify-content:center;width:24px;height:24px;font-size:16px;border-radius:4px;cursor:pointer;transition:background .1s}.neiki-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--neiki-modal-overlay);z-index:10000;display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:opacity .2s,visibility .2s}.neiki-modal-overlay.active,[data-tooltip]:hover::after{opacity:1;visibility:visible}.neiki-modal{background:var(--neiki-bg-primary);border-radius:12px;box-shadow:var(--neiki-shadow-lg);width:100%;max-width:440px;max-height:90vh;overflow:hidden}.neiki-modal-wide{max-width:520px}.neiki-modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--neiki-border-color)}.neiki-modal-title{font-size:16px;font-weight:600;margin:0}.neiki-modal-close,.neiki-preview-close{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background:0 0;border:none;border-radius:4px;cursor:pointer;color:var(--neiki-text-muted);transition:background .15s}.neiki-modal-body{padding:20px;overflow-y:auto}.neiki-modal h3,.neiki-modal-header h3{color:#000;margin:0}.neiki-modal-footer{display:flex;justify-content:flex-end;gap:10px;padding:16px 20px;border-top:1px solid var(--neiki-border-color)}.neiki-modal-footer .neiki-btn{width:auto;height:38px;padding:0 16px;font-size:14px;font-weight:500;border-radius:6px}.neiki-form-group{margin-bottom:16px}.neiki-find-replace-row:last-child,.neiki-form-group:last-child{margin-bottom:0}.neiki-form-group label,.neiki-form-label{display:block;margin-bottom:6px;font-size:13px;font-weight:500;color:var(--neiki-text-secondary)}.neiki-form-input,.neiki-input{width:100%;height:40px;padding:0 12px;border:1px solid var(--neiki-border-color);border-radius:6px;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-size:14px;transition:border-color .15s}.neiki-form-input:focus,.neiki-form-textarea:focus,.neiki-input:focus{outline:0;border-color:var(--neiki-accent-color);box-shadow:0 0 0 3px rgba(13,110,253,.15)}.neiki-form-input::placeholder,.neiki-input::placeholder{color:var(--neiki-text-muted)}.neiki-input[type=file]{display:flex;align-items:center;padding:0;cursor:pointer}.neiki-input[type=file]::file-selector-button{height:100%;padding:0 14px;margin-right:12px;border:none;border-right:1px solid var(--neiki-border-color);background:var(--neiki-bg-tertiary,var(--neiki-bg-hover));color:var(--neiki-text-primary);font-size:13px;font-weight:500;cursor:pointer;border-radius:5px 0 0 5px}.neiki-image-upload-zone{position:relative;display:grid;justify-items:center;gap:7px;padding:24px 18px;border:2px dashed var(--neiki-border-color);border-radius:8px;background:var(--neiki-bg-secondary);color:var(--neiki-text-secondary);text-align:center;cursor:pointer;transition:border-color .15s,background .15s,box-shadow .15s}.neiki-find-replace,.neiki-form-textarea{border:1px solid var(--neiki-border-color)}.neiki-image-upload-zone:focus-visible,.neiki-image-upload-zone:hover{border-color:var(--neiki-accent-color);background:var(--neiki-bg-primary);box-shadow:0 0 0 3px rgba(13,110,253,.12);outline:0}.neiki-image-upload-zone.drag-over{border-color:var(--neiki-accent-color);background:rgba(13,110,253,.08)}.neiki-form-divider::after,.neiki-form-divider::before{content:'';height:1px;background:var(--neiki-border-color)}.neiki-image-upload-zone.has-files{border-style:solid;border-color:var(--neiki-accent-color)}.neiki-image-upload-input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.neiki-image-upload-icon{width:38px;height:38px;color:var(--neiki-accent-color)}.neiki-image-upload-icon svg{width:100%;height:100%;fill:currentColor}.neiki-image-upload-title{color:var(--neiki-text-primary);font-size:14px;font-weight:600}.neiki-image-upload-files,.neiki-image-upload-hint{max-width:100%;color:var(--neiki-text-muted);font-size:12px;line-height:1.4}.neiki-image-upload-files{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.neiki-image-upload-zone.has-files .neiki-image-upload-files{color:var(--neiki-accent-color);font-weight:500}.neiki-form-row{display:flex;gap:16px}.neiki-form-divider{display:flex;align-items:center;margin:16px 0;text-align:center;position:relative}.neiki-form-divider::before{flex:1;margin-right:12px}.neiki-form-divider::after{flex:1;margin-left:12px}.neiki-form-divider span{color:var(--neiki-text-muted);font-size:12px;font-weight:500;text-transform:uppercase}.neiki-form-textarea{width:100%;min-height:120px;padding:12px;border-radius:6px;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-size:14px;font-family:inherit;resize:vertical;transition:border-color .15s}.neiki-btn-primary,.neiki-btn-secondary,.neiki-button{display:inline-flex;align-items:center;height:38px;padding:0 16px;font-size:14px;transition:.15s;font-weight:500;cursor:pointer}.neiki-button{justify-content:center;gap:6px;border:1px solid transparent;border-radius:6px}.neiki-btn-primary,.neiki-button-primary{background:var(--neiki-accent-color);color:#fff}.neiki-btn-secondary,.neiki-button-secondary{background:var(--neiki-bg-secondary);color:var(--neiki-text-primary);border-color:var(--neiki-border-color)}.neiki-btn-primary,.neiki-btn-secondary{justify-content:center;border:1px solid transparent;border-radius:6px}.neiki-btn-secondary{border-color:var(--neiki-border-color)}.neiki-button-danger{background:var(--neiki-danger-color);color:#fff}.neiki-code-view,.neiki-find-replace,.neiki-find-replace-input{background:var(--neiki-bg-primary)}.neiki-button-danger:hover{opacity:.9}.neiki-find-replace{position:absolute;top:0;right:0;z-index:100;width:360px;border-radius:0 0 0 8px;box-shadow:var(--neiki-shadow-lg);display:none}.neiki-find-replace-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--neiki-border-color)}.neiki-code-view-title,.neiki-find-replace-title{font-size:13px;font-weight:600;color:var(--neiki-text-primary)}.neiki-find-replace-body{padding:12px}.neiki-find-replace-row{display:flex;gap:8px;margin-bottom:10px}.neiki-find-replace-input{flex:1;height:32px;padding:0 10px;border:1px solid var(--neiki-border-color);border-radius:4px;color:var(--neiki-text-primary);font-size:13px}.neiki-find-replace-input:focus{outline:0;border-color:var(--neiki-accent-color)}.neiki-find-replace-options{display:flex;align-items:center;gap:12px;margin-bottom:10px}.neiki-find-replace-option{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--neiki-text-secondary);cursor:pointer}.neiki-find-replace-actions{display:flex;gap:6px;flex-wrap:wrap}.neiki-find-replace-btn{height:28px;padding:0 10px;font-size:12px;border-radius:4px}.neiki-find-replace-count{font-size:12px;color:var(--neiki-text-muted);margin-left:auto}.neiki-code-view{position:absolute;top:0;left:0;right:0;bottom:0;z-index:50;display:none;flex-direction:column}.neiki-context-menu,.neiki-floating-toolbar{position:fixed;box-shadow:var(--neiki-shadow-lg)}.neiki-code-view.show,.neiki-drop-overlay.show{display:flex}.neiki-code-view-header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px;background:var(--neiki-bg-secondary);border-bottom:1px solid var(--neiki-border-color);flex-shrink:0}.neiki-code-view-textarea{flex:1;width:100%;padding:16px;border:none;background:var(--neiki-bg-primary);color:var(--neiki-text-primary);font-family:Consolas,Monaco,'Courier New',monospace;font-size:13px;line-height:1.5;resize:none}.neiki-code-view-apply{width:auto!important;padding:0 12px!important;display:inline-flex;align-items:center;gap:4px;height:30px;font-size:12px;background:var(--neiki-accent-color)!important;color:#fff!important;border-radius:5px}.neiki-context-menu,.neiki-floating-btn,.neiki-floating-toolbar{background:var(--neiki-bg-primary)}.neiki-code-view-apply:hover{background:var(--neiki-accent-hover)!important;color:#fff!important}.neiki-code-view-apply svg{width:14px!important;height:14px!important}.neiki-context-menu{z-index:10001;min-width:180px;border:1px solid var(--neiki-border-color);border-radius:8px;padding:4px;display:none}.neiki-context-item,.neiki-context-menu-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:4px;cursor:pointer;color:var(--neiki-text-primary);font-size:13px;transition:background .1s}.neiki-context-item.neiki-context-danger,.neiki-context-menu-item.danger{color:var(--neiki-danger-color)}.neiki-context-item svg,.neiki-context-menu-item svg,.neiki-dropdown-item-icon svg,.neiki-floating-btn svg,.neiki-img-toolbar-btn svg{width:16px;height:16px;fill:currentColor}.neiki-floating-toolbar{z-index:1000;display:none;border:1px solid var(--neiki-border-color);border-radius:8px;padding:4px}.neiki-floating-toolbar.show{display:flex;align-items:center;gap:2px}.neiki-floating-btn{width:32px;height:32px;border:none;color:var(--neiki-text-primary);border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.15s}.neiki-floating-btn:hover,.neiki-img-toolbar-btn:hover{background:var(--neiki-bg-hover);color:var(--neiki-accent-color)}.neiki-floating-toolbar .neiki-btn{width:28px;height:28px}.neiki-chevron svg,.neiki-floating-toolbar .neiki-btn svg{width:14px;height:14px}.neiki-floating-divider,.neiki-img-toolbar-separator{width:1px;height:20px;background:var(--neiki-border-color);margin:0 2px}.neiki-floating-move-btn svg{width:16px;height:16px}.neiki-more-btn,[data-tooltip]{position:relative}[data-tooltip]::after{content:attr(data-tooltip);position:absolute;bottom:100%;left:50%;transform:translateX(-50%);padding:6px 10px;background:var(--neiki-text-primary);color:var(--neiki-bg-primary);font-size:11px;font-weight:500;white-space:nowrap;border-radius:4px;opacity:0;visibility:hidden;transition:opacity .15s,visibility .15s;pointer-events:none;z-index:10002;margin-bottom:6px}.neiki-drop-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(13,110,253,.1);border:3px dashed var(--neiki-accent-color);border-radius:8px;display:none;align-items:center;justify-content:center;z-index:100;pointer-events:none}.neiki-img-size-label,.neiki-img-toolbar{left:50%;transform:translateX(-50%);white-space:nowrap}.neiki-drop-overlay-text{font-size:18px;font-weight:600;color:var(--neiki-accent-color)}.neiki-img-resizable{display:inline-block;position:relative;outline:2px solid var(--neiki-accent-color);outline-offset:2px;border-radius:4px;line-height:0}.neiki-img-resizable img{display:block;max-width:100%}.neiki-img-resize-handle{position:absolute;width:12px;height:12px;background:var(--neiki-accent-color);border:2px solid #fff;border-radius:2px;z-index:10;box-shadow:0 1px 3px rgba(0,0,0,.3)}.neiki-img-resize-handle.nw{top:-6px;left:-6px;cursor:nw-resize}.neiki-img-resize-handle.ne{top:-6px;right:-6px;cursor:ne-resize}.neiki-img-resize-handle.sw{bottom:-6px;left:-6px;cursor:sw-resize}.neiki-img-resize-handle.se{bottom:-6px;right:-6px;cursor:se-resize}.neiki-img-size-label{position:absolute;bottom:-32px;background:var(--neiki-text-primary);color:var(--neiki-bg-primary);font-size:13px;line-height:1.4;font-weight:600;padding:4px 12px;border-radius:6px;pointer-events:none;z-index:10;opacity:.9}@media (pointer:coarse){.neiki-img-resize-handle{width:20px;height:20px}.neiki-img-resize-handle.nw{top:-10px;left:-10px}.neiki-img-resize-handle.ne{top:-10px;right:-10px}.neiki-img-resize-handle.sw{bottom:-10px;left:-10px}.neiki-img-resize-handle.se{bottom:-10px;right:-10px}}.neiki-img-toolbar{position:absolute;display:flex;align-items:center;gap:2px;padding:4px;background:var(--neiki-bg-primary);border:1px solid var(--neiki-border-color);border-radius:6px;box-shadow:var(--neiki-shadow-md);z-index:20}.neiki-img-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:4px;background:0 0;color:var(--neiki-text-secondary);cursor:pointer;transition:.15s}.neiki-img-toolbar-btn-danger:hover{background:#fee2e2;color:#dc2626}.neiki-editor.neiki-dark .neiki-img-toolbar-btn-danger:hover{background:#451a1a;color:#f87171}.neiki-img-drag-handle{cursor:grab}.neiki-block-grip:active,.neiki-img-drag-handle:active{cursor:grabbing}.neiki-table-col-resize-handle{position:absolute;width:6px;cursor:col-resize;z-index:10;background:0 0;transition:background .1s}.neiki-table-col-resize-handle:active,.neiki-table-col-resize-handle:hover{background:var(--neiki-accent-color);opacity:.6;border-radius:3px}.neiki-block-grip{position:absolute;width:22px;height:22px;display:flex;align-items:center;justify-content:center;cursor:grab;color:var(--neiki-text-muted);opacity:0;transition:opacity .15s,color .15s;border-radius:4px;z-index:5;user-select:none}.neiki-content:hover .neiki-block-grip{opacity:.5}.neiki-block-grip:hover{opacity:1!important;color:var(--neiki-text-primary);background:var(--neiki-bg-hover)}.neiki-block-grip svg{width:14px;height:14px;fill:currentColor;pointer-events:none}.neiki-block-ghost{position:fixed;z-index:100000;pointer-events:none;opacity:.7;background:var(--neiki-bg-primary);border:2px solid var(--neiki-accent-color);border-radius:6px;padding:8px 12px;box-shadow:var(--neiki-shadow-lg);max-height:120px;overflow:hidden}.neiki-block-placeholder{border:2px dashed var(--neiki-accent-color);border-radius:6px;background:rgba(13,110,253,.05);margin:2px 0;transition:height .15s}@media print{.neiki-content,.neiki-editor-wrapper{overflow:visible!important}.neiki-editor{border:none!important;box-shadow:none!important}.neiki-block-grip,.neiki-code-view-header,.neiki-find-replace,.neiki-floating-toolbar,.neiki-img-resize-handle,.neiki-img-size-label,.neiki-img-toolbar,.neiki-statusbar,.neiki-table-col-resize-handle,.neiki-toolbar{display:none!important}.neiki-content{padding:0!important}}@media (max-width:768px){.neiki-toolbar{padding:4px;gap:1px}.neiki-toolbar-group{padding:0 2px}.neiki-toolbar-group:not(:last-child){padding-right:4px;margin-right:2px}.neiki-btn{width:28px;height:28px}.neiki-btn svg{width:16px;height:16px}.neiki-select{height:28px;min-width:80px;font-size:12px;padding:0 24px 0 8px}.neiki-content,.neiki-modal-footer,.neiki-modal-header{padding:12px 16px}.neiki-statusbar{padding:4px 8px;font-size:11px}.neiki-modal{width:calc(100% - 20px);max-width:none;margin:10px;max-height:calc(100vh - 40px);border-radius:10px}.neiki-modal-overlay{padding:10px}.neiki-modal-body{padding:16px;max-height:calc(100vh - 160px);overflow-y:auto;-webkit-overflow-scrolling:touch}.neiki-modal-footer .neiki-btn{height:36px;padding:0 14px;font-size:13px}.neiki-form-row{flex-direction:column;gap:12px}.neiki-form-input,.neiki-input{height:38px;font-size:16px}.neiki-image-upload-zone{grid-template-columns:32px 1fr;justify-items:start;gap:4px 10px;padding:14px;text-align:left}.neiki-image-upload-icon{grid-row:span 3;width:30px;height:30px}.neiki-image-upload-title{font-size:13px}.neiki-image-upload-files,.neiki-image-upload-hint{font-size:11px}.neiki-find-replace{width:100%;border-radius:0}.neiki-checkbox-wrapper{padding:0 4px;font-size:11px}.neiki-color-picker{left:auto;right:0}}@media (max-width:480px){.neiki-toolbar-group:not(:last-child){border-right:none;padding-right:2px;margin-right:0}.neiki-select{min-width:60px}.neiki-statusbar-left,.neiki-statusbar-right{gap:8px}.neiki-img-toolbar{padding:3px;gap:1px;border-radius:5px;left:0;transform:none;max-width:calc(100vw - 20px)}.neiki-img-toolbar-btn{width:26px;height:26px}.neiki-img-toolbar-btn svg{width:14px;height:14px}.neiki-img-toolbar-separator{height:16px;margin:0 1px}}@keyframes neiki-fade-in{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.neiki-color-picker.show,.neiki-dropdown.show,.neiki-emoji-picker.show,.neiki-special-chars.show,.neiki-table-picker.show{animation:.15s neiki-fade-in}@keyframes neiki-modal-in{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.neiki-fontsize-widget{display:inline-flex;align-items:center;position:relative;height:32px;border:1px solid var(--neiki-border-color);border-radius:4px;overflow:visible;background:var(--neiki-bg-primary)}.neiki-fontsize-btn{display:flex;align-items:center;justify-content:center;width:26px;height:30px;background:0 0;border:none;cursor:pointer;color:var(--neiki-text-secondary);transition:background .15s,color .15s;padding:0}.neiki-fontsize-dropdown-item,.neiki-fontsize-input{color:var(--neiki-text-primary);text-align:center;font-size:13px}.neiki-fontsize-input{width:38px;height:30px;border:none;border-left:1px solid var(--neiki-border-color);border-right:1px solid var(--neiki-border-color);background:var(--neiki-bg-primary);outline:0;-moz-appearance:textfield;appearance:textfield;padding:0}.neiki-fontsize-dropdown,.neiki-insert-dropdown{left:0;border:1px solid var(--neiki-border-color)}.neiki-fontsize-input::-webkit-inner-spin-button,.neiki-fontsize-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.neiki-fontsize-dropdown{display:none;position:absolute;top:100%;z-index:1000;min-width:70px;max-height:240px;overflow-y:auto;background:var(--neiki-bg-primary);border-radius:6px;box-shadow:var(--neiki-shadow-lg);padding:4px;margin-top:4px}.neiki-fontsize-dropdown-item{padding:6px 12px;cursor:pointer;border-radius:4px;transition:background .1s}.neiki-insert-dropdown-btn{width:auto!important;padding:0 8px!important;gap:4px;font-size:13px;font-weight:500}.neiki-insert-label{font-size:13px;pointer-events:none}.neiki-chevron{display:inline-flex;pointer-events:none}.neiki-insert-dropdown,.neiki-more-dropdown{display:none;position:absolute;top:100%;z-index:1000;background:var(--neiki-bg-primary);box-shadow:var(--neiki-shadow-lg);padding:4px;margin-top:4px}.neiki-insert-dropdown{min-width:160px;max-width:calc(100vw - 16px);border-radius:6px}.neiki-insert-dropdown.show,.neiki-more-dropdown.show{display:block;animation:.15s neiki-fade-in}.neiki-more-dropdown{right:0;min-width:140px;max-width:170px;border:1px solid var(--neiki-border-color);border-radius:6px}.neiki-lang-cs .neiki-more-dropdown{min-width:165px}.neiki-dropdown-item-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.neiki-dropdown-item-danger{color:var(--neiki-danger-color)!important}.neiki-dropdown-item-danger:hover{background:rgba(220,53,69,.1)}.neiki-autosave-badge{font-size:12px;font-weight:600;color:var(--neiki-text-muted);padding:0 4px}.neiki-autosave-badge.active{color:var(--neiki-success-color)}.neiki-preview-overlay{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:100000;display:flex;align-items:center;justify-content:center;padding:30px;animation:.2s neiki-fade-in}.neiki-preview-modal{background:var(--neiki-bg-primary);border-radius:12px;width:100%;max-width:900px;max-height:90vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 25px 60px rgba(0,0,0,.3);animation:.2s neiki-modal-in}.neiki-preview-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;background:var(--neiki-bg-secondary);border-bottom:1px solid var(--neiki-border-color);font-weight:600;font-size:14px;color:var(--neiki-text-primary)}.neiki-preview-close svg{width:18px;height:18px;fill:currentColor}.neiki-preview-body{flex:1;overflow:auto;padding:30px;color:var(--neiki-text-primary);font-size:15px;line-height:1.7}.neiki-preview-body img{max-width:100%}.neiki-preview-body table{border-collapse:collapse;width:100%}.neiki-preview-body table td,.neiki-preview-body table th{border:1px solid var(--neiki-border-color);padding:8px 12px}.neiki-statusbar-autosave{font-style:italic;color:var(--neiki-success-color);font-size:11px}
|