feat: 浅色/暗色主题并支持跟随系统

顶栏循环切换,localStorage 记忆;head 内联脚本避免首屏闪烁。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 04:54:15 +08:00
parent 1f777eebb1
commit 4a21d362d0
9 changed files with 353 additions and 56 deletions

View File

@@ -12,7 +12,7 @@
## A. 浏览与布局
- [x] 三栏布局:左导航 / 中 Feed / 右栏小组件 — SSR桌面≤900px 隐藏右栏)
- [ ] 浅色 / 暗色主题;跟随系统偏好并本地记忆
- [x] 浅色 / 暗色主题;跟随系统偏好并本地记忆`data-theme` + `localStorage``j13-theme`);顶栏循环:跟随系统 / 浅色 / 暗色
- [ ] 响应式:平板/手机收起侧栏
- [ ] 长列表虚拟滚动或等价流畅方案
- [x] Feed 排序:`latest`(最新发帖)/ `reply`(最新回复)/ `hot`(热门)

View File

@@ -105,7 +105,10 @@
### 2.5 主题
- 浅色 / 暗色;`localStorage` 记忆;可跟随系统
- 浅色 / 暗色;默认 **跟随系统**`localStorage` `j13-theme``system` | `light` | `dark`
- `<html data-theme="light|dark" data-theme-pref="…">``<head>` 内联脚本防首屏闪烁
- 顶栏按钮循环切换;系统偏好变化时在 `system` 模式下即时更新
- 兼容旧 SPA 仅存 `light`/`dark` 的值
---

View File

@@ -10,15 +10,15 @@
| 项 | 值 |
|----|-----|
| **上一刀** | Markdown 编辑器(工具栏 + 预览,共用 md_editor |
| **下一刀** | 需点名OIDC / S3 / Gitea / 主题 / 表格表情…) |
| **上一刀** | 浅色/暗色主题(跟随系统 + localStorage |
| **下一刀** | 需点名OIDC / S3 / Gitea / 表格表情…) |
| **工作区** | 应干净 |
---
## 一句话状态
核心论坛、Admin、Limits/伪静态、嵌套评论、**Markdown 编辑器**已齐。TipTap / 表格 / 表情贴纸仍后置
核心论坛、Admin、Limits/伪静态、嵌套评论、Markdown 编辑器、**主题**已齐。余量多为后置与体验打磨
---
@@ -30,12 +30,13 @@
| Limits / 伪静态 / 品牌图 | 已迁 |
| 评论嵌套树 UI | 已迁 |
| Markdown 工具栏 + preview | 已迁 |
| 浅色 / 暗色 / 跟随系统 | 已迁 |
---
## 未完成
- P3主题、TipTip、游客评论、修订 diff
- P3TipTip、游客评论、修订 diff、响应式侧栏抽屉
- 编辑器后置TipTap、表格、图片组、表情贴纸
- 后置OIDC、S3 热切换、Gitea `/projects`

View File

@@ -1,13 +1,66 @@
/* 姜十三论坛 SSR 骨架样式web_src → public/assets */
:root {
color-scheme: light;
--j13-bg: #f6f4ef;
--j13-surface: #fffdf8;
--j13-text: #1c1917;
--j13-muted: #78716c;
--j13-accent: #0f766e;
--j13-on-accent: #fff;
--j13-border: #e7e5e4;
--j13-radius: 8px;
--j13-font: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
--j13-danger: #b91c1c;
--j13-ok-bg: #ecfdf5;
--j13-ok-fg: #065f46;
--j13-warn-bg: #fff7ed;
--j13-warn-fg: #9a3412;
--j13-warn-border: #fed7aa;
--j13-err-bg: #fef2f2;
--j13-err-fg: #991b1b;
--j13-err-border: #fecaca;
--j13-pin-bg: #fef3c7;
--j13-pin-fg: #92400e;
--j13-feat-bg: #ede9fe;
--j13-feat-fg: #5b21b6;
--j13-neutral-bg: #f8fafc;
--j13-neutral-fg: #475569;
--j13-self-bg: #eff6ff;
--j13-self-border: #bfdbfe;
--j13-delta-pos: #15803d;
--j13-delta-neg: #b91c1c;
--j13-overlay: rgba(255, 255, 255, 0.85);
}
html[data-theme="dark"] {
color-scheme: dark;
--j13-bg: #1c1917;
--j13-surface: #292524;
--j13-text: #f5f5f4;
--j13-muted: #a8a29e;
--j13-accent: #2dd4bf;
--j13-on-accent: #134e4a;
--j13-border: #44403c;
--j13-danger: #f87171;
--j13-ok-bg: #064e3b;
--j13-ok-fg: #a7f3d0;
--j13-warn-bg: #7c2d12;
--j13-warn-fg: #fed7aa;
--j13-warn-border: #9a3412;
--j13-err-bg: #7f1d1d;
--j13-err-fg: #fecaca;
--j13-err-border: #991b1b;
--j13-pin-bg: #78350f;
--j13-pin-fg: #fde68a;
--j13-feat-bg: #4c1d95;
--j13-feat-fg: #ddd6fe;
--j13-neutral-bg: #334155;
--j13-neutral-fg: #e2e8f0;
--j13-self-bg: #1e3a5f;
--j13-self-border: #1d4ed8;
--j13-delta-pos: #4ade80;
--j13-delta-neg: #f87171;
--j13-overlay: rgba(28, 25, 23, 0.85);
}
* { box-sizing: border-box; }
@@ -62,9 +115,25 @@ body.j13-body {
.j13-brand__text { display: flex; flex-direction: column; }
.j13-brand__text strong { font-size: 1rem; }
.j13-brand__slogan { font-size: 0.75rem; color: var(--j13-muted); }
.j13-nav { display: flex; gap: 0.85rem; flex-wrap: wrap; }
.j13-nav { display: flex; gap: 0.85rem; flex-wrap: wrap; align-items: center; }
.j13-nav a { color: var(--j13-accent); text-decoration: none; font-size: 0.9rem; }
.j13-nav a:hover { text-decoration: underline; }
.j13-theme-toggle {
appearance: none;
border: 1px solid var(--j13-border);
background: var(--j13-surface);
color: var(--j13-muted);
border-radius: var(--j13-radius);
padding: 0.2rem 0.55rem;
font: inherit;
font-size: 0.8rem;
cursor: pointer;
line-height: 1.3;
}
.j13-theme-toggle:hover {
color: var(--j13-accent);
border-color: var(--j13-accent);
}
.j13-layout {
max-width: 1200px;
@@ -270,7 +339,7 @@ body.j13-body {
}
.j13-search__err {
margin: 0.5rem 0 0;
color: #b91c1c;
color: var(--j13-danger);
font-size: 0.875rem;
}
@@ -297,15 +366,15 @@ body.j13-body {
align-items: center;
}
.j13-tag {
background: #ecfdf5;
background: var(--j13-ok-bg);
color: var(--j13-accent);
padding: 0.1rem 0.4rem;
border-radius: 4px;
font-size: 0.75rem;
}
.j13-tag--pin { background: #fef3c7; color: #92400e; }
.j13-tag--pending { background: #fff7ed; color: #9a3412; }
.j13-tag--rejected { background: #fef2f2; color: #991b1b; }
.j13-tag--pin { background: var(--j13-pin-bg); color: var(--j13-pin-fg); }
.j13-tag--pending { background: var(--j13-warn-bg); color: var(--j13-warn-fg); }
.j13-tag--rejected { background: var(--j13-err-bg); color: var(--j13-err-fg); }
.j13-mod-banner {
margin: 0.5rem 0 0.75rem;
padding: 0.65rem 0.85rem;
@@ -314,18 +383,18 @@ body.j13-body {
line-height: 1.4;
}
.j13-mod-banner--pending {
background: #fff7ed;
color: #9a3412;
border: 1px solid #fed7aa;
background: var(--j13-warn-bg);
color: var(--j13-warn-fg);
border: 1px solid var(--j13-warn-border);
}
.j13-mod-banner--rejected {
background: #fef2f2;
color: #991b1b;
border: 1px solid #fecaca;
background: var(--j13-err-bg);
color: var(--j13-err-fg);
border: 1px solid var(--j13-err-border);
}
.j13-tag--feat { background: #ede9fe; color: #5b21b6; }
.j13-tag--resolved { background: #ecfdf5; color: #065f46; }
.j13-tag--unresolved { background: #f8fafc; color: #475569; }
.j13-tag--feat { background: var(--j13-feat-bg); color: var(--j13-feat-fg); }
.j13-tag--resolved { background: var(--j13-ok-bg); color: var(--j13-ok-fg); }
.j13-tag--unresolved { background: var(--j13-neutral-bg); color: var(--j13-neutral-fg); }
.j13-empty { color: var(--j13-muted); }
.j13-pager {
@@ -351,8 +420,8 @@ body.j13-body {
padding: 0.65rem 1rem;
border-radius: var(--j13-radius);
}
.j13-flash { background: #ecfdf5; color: #065f46; }
.j13-alert--error { background: #fef2f2; color: #991b1b; }
.j13-flash { background: var(--j13-ok-bg); color: var(--j13-ok-fg); }
.j13-alert--error { background: var(--j13-err-bg); color: var(--j13-err-fg); }
.j13-main--solo {
max-width: 480px;
@@ -372,6 +441,8 @@ body.j13-body {
border: 1px solid var(--j13-border);
border-radius: var(--j13-radius);
font: inherit;
background: var(--j13-surface);
color: var(--j13-text);
}
.j13-form button, .j13-post__actions button, .j13-comment-form button {
margin-top: 0.5rem;
@@ -379,7 +450,7 @@ body.j13-body {
border: 0;
border-radius: var(--j13-radius);
background: var(--j13-accent);
color: #fff;
color: var(--j13-on-accent);
cursor: pointer;
font: inherit;
}
@@ -478,7 +549,8 @@ body.j13-body {
border: 1px solid var(--j13-border);
border-radius: var(--j13-radius);
font: inherit;
background: #fff;
background: var(--j13-surface);
color: var(--j13-text);
}
.j13-form__row {
display: flex;
@@ -770,8 +842,8 @@ body.j13-body {
vertical-align: top;
}
.j13-profile__ledger th { color: var(--j13-muted); font-weight: 600; }
.j13-delta--pos { color: #15803d; }
.j13-delta--neg { color: #b91c1c; }
.j13-delta--pos { color: var(--j13-delta-pos); }
.j13-delta--neg { color: var(--j13-delta-neg); }
.j13-btn {
display: inline-block;
padding: 0.35rem 0.85rem;
@@ -862,8 +934,8 @@ body.j13-body {
}
.j13-msg-bubble.is-self {
align-self: flex-end;
background: #eff6ff;
border-color: #bfdbfe;
background: var(--j13-self-bg);
border-color: var(--j13-self-border);
}
.j13-msg-bubble.is-system { max-width: 100%; }
.j13-msg-bubble__subj { font-weight: 600; margin-bottom: 0.25rem; }
@@ -980,7 +1052,7 @@ points-only[data-locked="false"] {
height: 48px;
object-fit: contain;
border-radius: 6px;
background: #fff;
background: var(--j13-surface);
}
.j13-links__logo--sm {
width: 24px;
@@ -1211,7 +1283,7 @@ points-only[data-locked="false"] {
top: 0.4rem;
left: 0.4rem;
z-index: 1;
background: rgba(255,255,255,0.85);
background: var(--j13-overlay);
border-radius: 3px;
padding: 0.1rem 0.2rem;
}

View File

@@ -1,6 +1,73 @@
// 姜十三论坛 SSR 渐进增强
document.documentElement.dataset.j13Ssr = "1";
(function themeToggle() {
var KEY = "j13-theme";
var LABELS = { system: "跟随系统", light: "浅色", dark: "暗色" };
var ORDER = ["system", "light", "dark"];
function normalizePref(raw) {
if (raw === "light" || raw === "dark" || raw === "system") return raw;
return "system";
}
function resolve(pref) {
if (pref === "dark") return "dark";
if (pref === "light") return "light";
try {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
} catch (e) {
return "light";
}
}
function apply(pref) {
pref = normalizePref(pref);
var resolved = resolve(pref);
document.documentElement.setAttribute("data-theme", resolved);
document.documentElement.setAttribute("data-theme-pref", pref);
document.documentElement.style.colorScheme = resolved;
try {
localStorage.setItem(KEY, pref);
} catch (e) {}
var btn = document.getElementById("j13-theme-toggle");
if (btn) {
btn.textContent = LABELS[pref] || LABELS.system;
btn.setAttribute("aria-label", "主题:" + (LABELS[pref] || ""));
btn.title = "当前:" + (LABELS[pref] || "") + "(点击切换)";
}
}
function currentPref() {
try {
return normalizePref(localStorage.getItem(KEY) || document.documentElement.getAttribute("data-theme-pref") || "system");
} catch (e) {
return "system";
}
}
apply(currentPref());
var btn = document.getElementById("j13-theme-toggle");
if (btn) {
btn.addEventListener("click", function () {
var cur = currentPref();
var idx = ORDER.indexOf(cur);
var next = ORDER[(idx + 1) % ORDER.length];
apply(next);
});
}
try {
var mq = window.matchMedia("(prefers-color-scheme: dark)");
var onChange = function () {
if (currentPref() === "system") apply("system");
};
if (mq.addEventListener) mq.addEventListener("change", onChange);
else if (mq.addListener) mq.addListener(onChange);
} catch (e) {}
})();
(function mdEditors() {
function insertAtCursor(textarea, text) {
const start = textarea.selectionStart || 0;

View File

@@ -10,6 +10,20 @@
<meta property="og:title" content="{{.Title}}"/>
{{if .Description}}<meta property="og:description" content="{{.Description}}"/>{{end}}
{{if .OGImageURL}}<meta property="og:image" content="{{.OGImageURL}}"/>{{end}}
<script>
(function () {
try {
var key = "j13-theme";
var pref = localStorage.getItem(key) || "system";
if (pref !== "light" && pref !== "dark" && pref !== "system") pref = "system";
var dark = pref === "dark" || (pref === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches);
var resolved = dark ? "dark" : "light";
document.documentElement.setAttribute("data-theme", resolved);
document.documentElement.setAttribute("data-theme-pref", pref);
document.documentElement.style.colorScheme = resolved;
} catch (e) {}
})();
</script>
<link rel="stylesheet" href="/ssr-assets/site.css"/>
</head>
<body class="j13-body">

View File

@@ -13,6 +13,7 @@
</span>
</a>
<nav class="j13-nav">
<button type="button" class="j13-theme-toggle" id="j13-theme-toggle" aria-label="切换主题" title="切换主题">主题</button>
<a href="/#search">搜索</a>
<a href="/boards">板块</a>
{{if .ShowFriendLinksNav}}<a href="/links">友链</a>{{end}}

View File

@@ -1,13 +1,66 @@
/* 姜十三论坛 SSR 骨架样式web_src → public/assets */
:root {
color-scheme: light;
--j13-bg: #f6f4ef;
--j13-surface: #fffdf8;
--j13-text: #1c1917;
--j13-muted: #78716c;
--j13-accent: #0f766e;
--j13-on-accent: #fff;
--j13-border: #e7e5e4;
--j13-radius: 8px;
--j13-font: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
--j13-danger: #b91c1c;
--j13-ok-bg: #ecfdf5;
--j13-ok-fg: #065f46;
--j13-warn-bg: #fff7ed;
--j13-warn-fg: #9a3412;
--j13-warn-border: #fed7aa;
--j13-err-bg: #fef2f2;
--j13-err-fg: #991b1b;
--j13-err-border: #fecaca;
--j13-pin-bg: #fef3c7;
--j13-pin-fg: #92400e;
--j13-feat-bg: #ede9fe;
--j13-feat-fg: #5b21b6;
--j13-neutral-bg: #f8fafc;
--j13-neutral-fg: #475569;
--j13-self-bg: #eff6ff;
--j13-self-border: #bfdbfe;
--j13-delta-pos: #15803d;
--j13-delta-neg: #b91c1c;
--j13-overlay: rgba(255, 255, 255, 0.85);
}
html[data-theme="dark"] {
color-scheme: dark;
--j13-bg: #1c1917;
--j13-surface: #292524;
--j13-text: #f5f5f4;
--j13-muted: #a8a29e;
--j13-accent: #2dd4bf;
--j13-on-accent: #134e4a;
--j13-border: #44403c;
--j13-danger: #f87171;
--j13-ok-bg: #064e3b;
--j13-ok-fg: #a7f3d0;
--j13-warn-bg: #7c2d12;
--j13-warn-fg: #fed7aa;
--j13-warn-border: #9a3412;
--j13-err-bg: #7f1d1d;
--j13-err-fg: #fecaca;
--j13-err-border: #991b1b;
--j13-pin-bg: #78350f;
--j13-pin-fg: #fde68a;
--j13-feat-bg: #4c1d95;
--j13-feat-fg: #ddd6fe;
--j13-neutral-bg: #334155;
--j13-neutral-fg: #e2e8f0;
--j13-self-bg: #1e3a5f;
--j13-self-border: #1d4ed8;
--j13-delta-pos: #4ade80;
--j13-delta-neg: #f87171;
--j13-overlay: rgba(28, 25, 23, 0.85);
}
* { box-sizing: border-box; }
@@ -62,9 +115,25 @@ body.j13-body {
.j13-brand__text { display: flex; flex-direction: column; }
.j13-brand__text strong { font-size: 1rem; }
.j13-brand__slogan { font-size: 0.75rem; color: var(--j13-muted); }
.j13-nav { display: flex; gap: 0.85rem; flex-wrap: wrap; }
.j13-nav { display: flex; gap: 0.85rem; flex-wrap: wrap; align-items: center; }
.j13-nav a { color: var(--j13-accent); text-decoration: none; font-size: 0.9rem; }
.j13-nav a:hover { text-decoration: underline; }
.j13-theme-toggle {
appearance: none;
border: 1px solid var(--j13-border);
background: var(--j13-surface);
color: var(--j13-muted);
border-radius: var(--j13-radius);
padding: 0.2rem 0.55rem;
font: inherit;
font-size: 0.8rem;
cursor: pointer;
line-height: 1.3;
}
.j13-theme-toggle:hover {
color: var(--j13-accent);
border-color: var(--j13-accent);
}
.j13-layout {
max-width: 1200px;
@@ -270,7 +339,7 @@ body.j13-body {
}
.j13-search__err {
margin: 0.5rem 0 0;
color: #b91c1c;
color: var(--j13-danger);
font-size: 0.875rem;
}
@@ -297,15 +366,15 @@ body.j13-body {
align-items: center;
}
.j13-tag {
background: #ecfdf5;
background: var(--j13-ok-bg);
color: var(--j13-accent);
padding: 0.1rem 0.4rem;
border-radius: 4px;
font-size: 0.75rem;
}
.j13-tag--pin { background: #fef3c7; color: #92400e; }
.j13-tag--pending { background: #fff7ed; color: #9a3412; }
.j13-tag--rejected { background: #fef2f2; color: #991b1b; }
.j13-tag--pin { background: var(--j13-pin-bg); color: var(--j13-pin-fg); }
.j13-tag--pending { background: var(--j13-warn-bg); color: var(--j13-warn-fg); }
.j13-tag--rejected { background: var(--j13-err-bg); color: var(--j13-err-fg); }
.j13-mod-banner {
margin: 0.5rem 0 0.75rem;
padding: 0.65rem 0.85rem;
@@ -314,18 +383,18 @@ body.j13-body {
line-height: 1.4;
}
.j13-mod-banner--pending {
background: #fff7ed;
color: #9a3412;
border: 1px solid #fed7aa;
background: var(--j13-warn-bg);
color: var(--j13-warn-fg);
border: 1px solid var(--j13-warn-border);
}
.j13-mod-banner--rejected {
background: #fef2f2;
color: #991b1b;
border: 1px solid #fecaca;
background: var(--j13-err-bg);
color: var(--j13-err-fg);
border: 1px solid var(--j13-err-border);
}
.j13-tag--feat { background: #ede9fe; color: #5b21b6; }
.j13-tag--resolved { background: #ecfdf5; color: #065f46; }
.j13-tag--unresolved { background: #f8fafc; color: #475569; }
.j13-tag--feat { background: var(--j13-feat-bg); color: var(--j13-feat-fg); }
.j13-tag--resolved { background: var(--j13-ok-bg); color: var(--j13-ok-fg); }
.j13-tag--unresolved { background: var(--j13-neutral-bg); color: var(--j13-neutral-fg); }
.j13-empty { color: var(--j13-muted); }
.j13-pager {
@@ -351,8 +420,8 @@ body.j13-body {
padding: 0.65rem 1rem;
border-radius: var(--j13-radius);
}
.j13-flash { background: #ecfdf5; color: #065f46; }
.j13-alert--error { background: #fef2f2; color: #991b1b; }
.j13-flash { background: var(--j13-ok-bg); color: var(--j13-ok-fg); }
.j13-alert--error { background: var(--j13-err-bg); color: var(--j13-err-fg); }
.j13-main--solo {
max-width: 480px;
@@ -372,6 +441,8 @@ body.j13-body {
border: 1px solid var(--j13-border);
border-radius: var(--j13-radius);
font: inherit;
background: var(--j13-surface);
color: var(--j13-text);
}
.j13-form button, .j13-post__actions button, .j13-comment-form button {
margin-top: 0.5rem;
@@ -379,7 +450,7 @@ body.j13-body {
border: 0;
border-radius: var(--j13-radius);
background: var(--j13-accent);
color: #fff;
color: var(--j13-on-accent);
cursor: pointer;
font: inherit;
}
@@ -478,7 +549,8 @@ body.j13-body {
border: 1px solid var(--j13-border);
border-radius: var(--j13-radius);
font: inherit;
background: #fff;
background: var(--j13-surface);
color: var(--j13-text);
}
.j13-form__row {
display: flex;
@@ -770,8 +842,8 @@ body.j13-body {
vertical-align: top;
}
.j13-profile__ledger th { color: var(--j13-muted); font-weight: 600; }
.j13-delta--pos { color: #15803d; }
.j13-delta--neg { color: #b91c1c; }
.j13-delta--pos { color: var(--j13-delta-pos); }
.j13-delta--neg { color: var(--j13-delta-neg); }
.j13-btn {
display: inline-block;
padding: 0.35rem 0.85rem;
@@ -862,8 +934,8 @@ body.j13-body {
}
.j13-msg-bubble.is-self {
align-self: flex-end;
background: #eff6ff;
border-color: #bfdbfe;
background: var(--j13-self-bg);
border-color: var(--j13-self-border);
}
.j13-msg-bubble.is-system { max-width: 100%; }
.j13-msg-bubble__subj { font-weight: 600; margin-bottom: 0.25rem; }
@@ -980,7 +1052,7 @@ points-only[data-locked="false"] {
height: 48px;
object-fit: contain;
border-radius: 6px;
background: #fff;
background: var(--j13-surface);
}
.j13-links__logo--sm {
width: 24px;
@@ -1211,7 +1283,7 @@ points-only[data-locked="false"] {
top: 0.4rem;
left: 0.4rem;
z-index: 1;
background: rgba(255,255,255,0.85);
background: var(--j13-overlay);
border-radius: 3px;
padding: 0.1rem 0.2rem;
}

View File

@@ -1,6 +1,73 @@
// 姜十三论坛 SSR 渐进增强
document.documentElement.dataset.j13Ssr = "1";
(function themeToggle() {
var KEY = "j13-theme";
var LABELS = { system: "跟随系统", light: "浅色", dark: "暗色" };
var ORDER = ["system", "light", "dark"];
function normalizePref(raw) {
if (raw === "light" || raw === "dark" || raw === "system") return raw;
return "system";
}
function resolve(pref) {
if (pref === "dark") return "dark";
if (pref === "light") return "light";
try {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
} catch (e) {
return "light";
}
}
function apply(pref) {
pref = normalizePref(pref);
var resolved = resolve(pref);
document.documentElement.setAttribute("data-theme", resolved);
document.documentElement.setAttribute("data-theme-pref", pref);
document.documentElement.style.colorScheme = resolved;
try {
localStorage.setItem(KEY, pref);
} catch (e) {}
var btn = document.getElementById("j13-theme-toggle");
if (btn) {
btn.textContent = LABELS[pref] || LABELS.system;
btn.setAttribute("aria-label", "主题:" + (LABELS[pref] || ""));
btn.title = "当前:" + (LABELS[pref] || "") + "(点击切换)";
}
}
function currentPref() {
try {
return normalizePref(localStorage.getItem(KEY) || document.documentElement.getAttribute("data-theme-pref") || "system");
} catch (e) {
return "system";
}
}
apply(currentPref());
var btn = document.getElementById("j13-theme-toggle");
if (btn) {
btn.addEventListener("click", function () {
var cur = currentPref();
var idx = ORDER.indexOf(cur);
var next = ORDER[(idx + 1) % ORDER.length];
apply(next);
});
}
try {
var mq = window.matchMedia("(prefers-color-scheme: dark)");
var onChange = function () {
if (currentPref() === "system") apply("system");
};
if (mq.addEventListener) mq.addEventListener("change", onChange);
else if (mq.addListener) mq.addListener(onChange);
} catch (e) {}
})();
(function mdEditors() {
function insertAtCursor(textarea, text) {
const start = textarea.selectionStart || 0;