mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
feat: 微信读书式阅读体验 — 主题/字体/字号/行距调节 + 阅读进度条
- Aa 阅读工具栏:5 种字体(系统/宋体/黑体/楷体/等宽)、字号 13-24px、三档行距、4 种主题(明亮/纸感/护眼绿/夜间),localStorage 持久化 - 正文阅读宽度收敛至 46rem(~736px),行高 1.85,符合长文阅读最佳实践 - 顶部阅读进度条 + 返回顶部按钮 - markdown.css 全量 CSS 变量化:表格/代码/引用/标题随主题联动,夜间模式自动适配 - 主题切换平滑过渡 + 面板弹出动画 + 页面淡入 - 移动端右下角 Aa FAB(与 TOC 按钮错开),面板全宽适配 390px
This commit is contained in:
@@ -27,6 +27,103 @@
|
|||||||
--apple-radius-sm: 14px;
|
--apple-radius-sm: 14px;
|
||||||
--apple-shadow-card: 0 4px 24px rgba(0, 0, 0, 0.05);
|
--apple-shadow-card: 0 4px 24px rgba(0, 0, 0, 0.05);
|
||||||
--apple-shadow-lift: 0 18px 44px rgba(0, 0, 0, 0.10);
|
--apple-shadow-lift: 0 18px 44px rgba(0, 0, 0, 0.10);
|
||||||
|
|
||||||
|
/* Reader surface (cards) — follows theme */
|
||||||
|
--reader-surface: #ffffff;
|
||||||
|
--reader-surface-2: #fafafa;
|
||||||
|
--reader-control: #f5f5f7;
|
||||||
|
--reader-hover: rgba(0, 0, 0, 0.05);
|
||||||
|
--reader-progress: linear-gradient(90deg, #0071e3 0%, #7c3aed 100%);
|
||||||
|
--reader-font-size: 17px;
|
||||||
|
--reader-line-height: 1.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
Reader themes (微信读书-style): light / paper / green / night
|
||||||
|
Overrides the --apple-* + --md-* design tokens so the whole
|
||||||
|
page (cards, TOC, tables, code, quotes) re-skins together.
|
||||||
|
============================================================ */
|
||||||
|
body.reader-paper {
|
||||||
|
--apple-bg: #ece5d5;
|
||||||
|
--apple-text: #40392e;
|
||||||
|
--apple-gray: #8a8272;
|
||||||
|
--apple-separator: rgba(64, 57, 46, 0.10);
|
||||||
|
--reader-surface: #faf6ec;
|
||||||
|
--reader-surface-2: #f3ede0;
|
||||||
|
--reader-control: #efe8d8;
|
||||||
|
--reader-hover: rgba(64, 57, 46, 0.07);
|
||||||
|
--reader-progress: linear-gradient(90deg, #b8860b 0%, #8a6d1f 100%);
|
||||||
|
--md-text: #40392e;
|
||||||
|
--md-muted: #8a8272;
|
||||||
|
--md-heading: #332d23;
|
||||||
|
--md-border: #ddd4c0;
|
||||||
|
--md-accent: #9a6b1f;
|
||||||
|
--md-accent-soft: rgba(154, 107, 31, 0.12);
|
||||||
|
--md-table-head-bg: #efe8d8;
|
||||||
|
--md-table-zebra: rgba(154, 130, 60, 0.05);
|
||||||
|
--md-code-bg: #f0e9da;
|
||||||
|
--md-code-text: #4a4234;
|
||||||
|
--md-pre-bg: #3d362a;
|
||||||
|
--md-pre-text: #e8e0cd;
|
||||||
|
--md-quote-bg: rgba(154, 130, 60, 0.07);
|
||||||
|
--md-hr: #ddd4c0;
|
||||||
|
}
|
||||||
|
body.reader-green {
|
||||||
|
--apple-bg: #dde8da;
|
||||||
|
--apple-text: #26342a;
|
||||||
|
--apple-gray: #5f7163;
|
||||||
|
--apple-separator: rgba(38, 52, 42, 0.10);
|
||||||
|
--reader-surface: #eef5ec;
|
||||||
|
--reader-surface-2: #e3eee0;
|
||||||
|
--reader-control: #dde8da;
|
||||||
|
--reader-hover: rgba(38, 52, 42, 0.06);
|
||||||
|
--reader-progress: linear-gradient(90deg, #2e8b57 0%, #1e6b3c 100%);
|
||||||
|
--md-text: #26342a;
|
||||||
|
--md-muted: #5f7163;
|
||||||
|
--md-heading: #1d2a20;
|
||||||
|
--md-border: #c9dac4;
|
||||||
|
--md-accent: #1e7b34;
|
||||||
|
--md-accent-soft: rgba(30, 123, 52, 0.10);
|
||||||
|
--md-table-head-bg: #e3eee0;
|
||||||
|
--md-table-zebra: rgba(46, 139, 87, 0.05);
|
||||||
|
--md-code-bg: #e3eee0;
|
||||||
|
--md-code-text: #2c3a30;
|
||||||
|
--md-pre-bg: #22301f;
|
||||||
|
--md-pre-text: #dce8d9;
|
||||||
|
--md-quote-bg: rgba(46, 139, 87, 0.06);
|
||||||
|
--md-hr: #c9dac4;
|
||||||
|
}
|
||||||
|
body.reader-night {
|
||||||
|
--apple-bg: #131316;
|
||||||
|
--apple-text: #d4d4dc;
|
||||||
|
--apple-gray: #8b8b96;
|
||||||
|
--apple-blue: #4d9fff;
|
||||||
|
--apple-blue-hover: #66aeff;
|
||||||
|
--apple-green: #4caf7d;
|
||||||
|
--apple-purple: #c58af9;
|
||||||
|
--apple-red: #ff6b61;
|
||||||
|
--apple-separator: rgba(255, 255, 255, 0.10);
|
||||||
|
--reader-surface: #1c1c22;
|
||||||
|
--reader-surface-2: #232329;
|
||||||
|
--reader-control: #26262e;
|
||||||
|
--reader-hover: rgba(255, 255, 255, 0.07);
|
||||||
|
--reader-progress: linear-gradient(90deg, #4d9fff 0%, #c58af9 100%);
|
||||||
|
--apple-shadow-card: 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||||
|
--apple-shadow-lift: 0 18px 44px rgba(0, 0, 0, 0.55);
|
||||||
|
--md-text: #c4c4cf;
|
||||||
|
--md-muted: #8b8b96;
|
||||||
|
--md-heading: #ececf2;
|
||||||
|
--md-border: #33333c;
|
||||||
|
--md-accent: #7db4ff;
|
||||||
|
--md-accent-soft: rgba(77, 159, 255, 0.14);
|
||||||
|
--md-table-head-bg: #26262e;
|
||||||
|
--md-table-zebra: rgba(255, 255, 255, 0.03);
|
||||||
|
--md-code-bg: #2a2a33;
|
||||||
|
--md-code-text: #e0e0e8;
|
||||||
|
--md-pre-bg: #0d0d10;
|
||||||
|
--md-pre-text: #c8c8d4;
|
||||||
|
--md-quote-bg: rgba(255, 255, 255, 0.04);
|
||||||
|
--md-hr: #2c2c34;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -36,10 +133,11 @@
|
|||||||
color: var(--apple-text);
|
color: var(--apple-text);
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
|
transition: background-color 0.4s var(--apple-ease), color 0.4s var(--apple-ease);
|
||||||
}
|
}
|
||||||
|
|
||||||
.apple-card {
|
.apple-card {
|
||||||
background: #fff;
|
background: var(--reader-surface);
|
||||||
border-radius: var(--apple-radius-lg);
|
border-radius: var(--apple-radius-lg);
|
||||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||||
box-shadow: var(--apple-shadow-card);
|
box-shadow: var(--apple-shadow-card);
|
||||||
@@ -108,7 +206,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.modal-content {
|
.modal-content {
|
||||||
background: #fff;
|
background: var(--reader-surface);
|
||||||
border-radius: var(--apple-radius-md);
|
border-radius: var(--apple-radius-md);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 26rem;
|
max-width: 26rem;
|
||||||
@@ -404,11 +502,12 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.main-content {
|
.main-content {
|
||||||
background: #fff;
|
background: var(--reader-surface);
|
||||||
border-radius: var(--apple-radius-lg);
|
border-radius: var(--apple-radius-lg);
|
||||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||||
box-shadow: var(--apple-shadow-card);
|
box-shadow: var(--apple-shadow-card);
|
||||||
padding: clamp(1.25rem, 4vw, 2.5rem);
|
padding: clamp(1.25rem, 4vw, 2.5rem);
|
||||||
|
transition: background-color 0.4s var(--apple-ease), border-color 0.4s var(--apple-ease);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== Table of Contents Layout ===== */
|
/* ===== Table of Contents Layout ===== */
|
||||||
@@ -422,7 +521,7 @@
|
|||||||
.post-actions { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; flex-wrap: wrap; max-width: 100%; }
|
.post-actions { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; flex-wrap: wrap; max-width: 100%; }
|
||||||
.post-meta { display: flex; flex-direction: column; gap: 0.85rem; margin-bottom: 1.25rem; }
|
.post-meta { display: flex; flex-direction: column; gap: 0.85rem; margin-bottom: 1.25rem; }
|
||||||
.post-summary { position: relative; padding-left: 1rem; border-left: 3px solid rgba(0, 113, 227, 0.35); }
|
.post-summary { position: relative; padding-left: 1rem; border-left: 3px solid rgba(0, 113, 227, 0.35); }
|
||||||
.post-summary p { font-size: 1.08rem; color: var(--apple-gray); font-style: italic; margin: 0; }
|
.post-summary p { font-size: 1.02rem; color: var(--apple-gray); font-style: normal; margin: 0; line-height: 1.7; }
|
||||||
.post-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
.post-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||||
.post-timestamps { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; font-size: 0.85rem; color: var(--apple-gray); background: var(--apple-bg); border-radius: 980px; padding: 0.6rem 1.1rem; }
|
.post-timestamps { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; font-size: 0.85rem; color: var(--apple-gray); background: var(--apple-bg); border-radius: 980px; padding: 0.6rem 1.1rem; }
|
||||||
.post-timestamps .timestamp-item { display: flex; align-items: center; }
|
.post-timestamps .timestamp-item { display: flex; align-items: center; }
|
||||||
@@ -474,11 +573,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#toc-sidebar-inner > div {
|
#toc-sidebar-inner > div {
|
||||||
background: #fff;
|
background: var(--reader-surface);
|
||||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||||
border-radius: var(--apple-radius-md);
|
border-radius: var(--apple-radius-md);
|
||||||
box-shadow: var(--apple-shadow-card);
|
box-shadow: var(--apple-shadow-card);
|
||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
|
transition: background-color 0.4s var(--apple-ease), border-color 0.4s var(--apple-ease);
|
||||||
}
|
}
|
||||||
.toc-card-label {
|
.toc-card-label {
|
||||||
font-size: 0.7rem; font-weight: 600; color: var(--apple-gray);
|
font-size: 0.7rem; font-weight: 600; color: var(--apple-gray);
|
||||||
@@ -570,10 +670,257 @@
|
|||||||
}
|
}
|
||||||
#toc-nav-mobile .toc-link:hover { color: var(--apple-blue); background-color: rgba(0, 113, 227, 0.08); }
|
#toc-nav-mobile .toc-link:hover { color: var(--apple-blue); background-color: rgba(0, 113, 227, 0.08); }
|
||||||
#toc-nav-mobile .toc-link.toc-active { color: var(--apple-blue); border-left-color: var(--apple-blue); font-weight: 500; }
|
#toc-nav-mobile .toc-link.toc-active { color: var(--apple-blue); border-left-color: var(--apple-blue); font-weight: 500; }
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
Reader typography — 微信读书-style reading experience
|
||||||
|
============================================================ */
|
||||||
|
/* Comfortable measure: ~68-75 chars per line */
|
||||||
|
.post-article {
|
||||||
|
font-size: var(--reader-font-size, 17px);
|
||||||
|
line-height: var(--reader-line-height, 1.85);
|
||||||
|
max-width: 46rem;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
transition: font-size 0.25s var(--apple-ease), line-height 0.25s var(--apple-ease);
|
||||||
|
}
|
||||||
|
.post-article * { font-family: var(--reader-font-family, inherit); }
|
||||||
|
.post-article code, .post-article pre, .post-article code * {
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Menlo', 'Cascadia Code', 'JetBrains Mono', Consolas, monospace !important;
|
||||||
|
}
|
||||||
|
.post-article h1, .post-article h2, .post-article h3, .post-article h4 {
|
||||||
|
font-family: var(--reader-font-family, inherit);
|
||||||
|
scroll-margin-top: 5.5rem;
|
||||||
|
}
|
||||||
|
.post-article table { font-size: 0.92em; }
|
||||||
|
|
||||||
|
/* Font families */
|
||||||
|
.reader-font-system { --reader-font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "Noto Sans SC", "Microsoft YaHei", "Segoe UI", sans-serif; }
|
||||||
|
.reader-font-serif { --reader-font-family: "Songti SC", "Noto Serif SC", "Source Han Serif SC", "STSong", "SimSun", Georgia, "Times New Roman", serif; }
|
||||||
|
.reader-font-hei { --reader-font-family: "PingFang SC", "Noto Sans SC", "Source Han Sans SC", "Microsoft YaHei", "Heiti SC", "SimHei", sans-serif; }
|
||||||
|
.reader-font-kai { --reader-font-family: "Kaiti SC", "KaiTi", "STKaiti", "Noto Serif SC", "Songti SC", serif; }
|
||||||
|
.reader-font-mono { --reader-font-family: "SF Mono", "Menlo", "Monaco", "Cascadia Code", "JetBrains Mono", Consolas, monospace; }
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
Reading progress bar (top of viewport, below navbar)
|
||||||
|
============================================================ */
|
||||||
|
#reading-progress {
|
||||||
|
position: fixed;
|
||||||
|
top: 0; left: 0;
|
||||||
|
height: 3px;
|
||||||
|
width: 0%;
|
||||||
|
background: var(--reader-progress);
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
|
||||||
|
transition: width 0.12s linear;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
Aa reading toolbar
|
||||||
|
============================================================ */
|
||||||
|
.reader-toolbar-btn {
|
||||||
|
display: inline-flex; align-items: center; justify-content: center;
|
||||||
|
width: 36px; height: 36px; border-radius: 50%;
|
||||||
|
border: none; cursor: pointer;
|
||||||
|
background: var(--reader-control);
|
||||||
|
color: var(--apple-text);
|
||||||
|
font-size: 0.95rem; font-weight: 700; letter-spacing: 0.02em;
|
||||||
|
transition: background 0.25s ease, transform 0.2s var(--apple-ease), box-shadow 0.25s ease;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
.reader-toolbar-btn:hover { background: var(--reader-hover); transform: translateY(-1px); }
|
||||||
|
.reader-toolbar-btn:active { transform: scale(0.94); }
|
||||||
|
.reader-toolbar-btn.active { background: var(--apple-blue); color: #fff; }
|
||||||
|
|
||||||
|
#reader-panel {
|
||||||
|
position: fixed;
|
||||||
|
right: 1.25rem;
|
||||||
|
bottom: 5.75rem;
|
||||||
|
z-index: 90;
|
||||||
|
width: min(21rem, calc(100vw - 2rem));
|
||||||
|
background: var(--reader-surface);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.07);
|
||||||
|
border-radius: var(--apple-radius-md);
|
||||||
|
box-shadow: var(--apple-shadow-lift);
|
||||||
|
padding: 1.1rem 1.2rem 1.2rem;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(12px) scale(0.98);
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.28s var(--apple-ease), transform 0.28s var(--apple-ease);
|
||||||
|
}
|
||||||
|
#reader-panel.open {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.rp-section { margin-bottom: 1rem; }
|
||||||
|
.rp-section:last-child { margin-bottom: 0; }
|
||||||
|
.rp-label {
|
||||||
|
font-size: 0.68rem; font-weight: 700; color: var(--apple-gray);
|
||||||
|
text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
/* Theme swatches */
|
||||||
|
.rp-themes { display: flex; gap: 0.75rem; }
|
||||||
|
.rp-swatch {
|
||||||
|
width: 34px; height: 34px; border-radius: 50%;
|
||||||
|
border: 2px solid transparent; cursor: pointer;
|
||||||
|
position: relative; transition: transform 0.2s var(--apple-ease), border-color 0.2s ease;
|
||||||
|
}
|
||||||
|
.rp-swatch:hover { transform: scale(1.1); }
|
||||||
|
.rp-swatch.active { border-color: var(--apple-blue); box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.18); }
|
||||||
|
.rp-swatch svg { position: absolute; inset: 0; margin: auto; width: 14px; height: 14px; color: #fff; opacity: 0; transition: opacity 0.2s; }
|
||||||
|
.rp-swatch.active svg { opacity: 1; }
|
||||||
|
.rp-swatch-light { background: #ffffff; border-color: #d1d1d6; }
|
||||||
|
.rp-swatch-paper { background: #faf6ec; border-color: #ddd4c0; }
|
||||||
|
.rp-swatch-green { background: #eef5ec; border-color: #c9dac4; }
|
||||||
|
.rp-swatch-night { background: #1c1c22; border-color: #44444e; }
|
||||||
|
/* Font chips */
|
||||||
|
.rp-fonts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.45rem; }
|
||||||
|
.rp-font-chip {
|
||||||
|
padding: 0.45rem 0.3rem; border-radius: var(--apple-radius-sm);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.08); background: var(--reader-surface-2);
|
||||||
|
cursor: pointer; text-align: center; color: var(--apple-text);
|
||||||
|
transition: border-color 0.2s, background 0.2s;
|
||||||
|
}
|
||||||
|
.rp-font-chip:hover { background: var(--reader-hover); }
|
||||||
|
.rp-font-chip.active { border-color: var(--apple-blue); background: rgba(0, 113, 227, 0.08); }
|
||||||
|
.rp-font-chip .rp-font-name { display: block; font-size: 1rem; line-height: 1.3; }
|
||||||
|
.rp-font-chip .rp-font-meta { display: block; font-size: 0.62rem; color: var(--apple-gray); margin-top: 0.15rem; }
|
||||||
|
.rp-font-chip[data-font="system"] .rp-font-name { font-family: -apple-system, "PingFang SC", sans-serif; }
|
||||||
|
.rp-font-chip[data-font="serif"] .rp-font-name { font-family: "Songti SC", "Noto Serif SC", serif; }
|
||||||
|
.rp-font-chip[data-font="hei"] .rp-font-name { font-family: "PingFang SC", "Heiti SC", "Microsoft YaHei", sans-serif; }
|
||||||
|
.rp-font-chip[data-font="kai"] .rp-font-name { font-family: "Kaiti SC", "KaiTi", "STKaiti", serif; }
|
||||||
|
.rp-font-chip[data-font="mono"] .rp-font-name { font-family: "SF Mono", Menlo, Consolas, monospace; }
|
||||||
|
/* Size & spacing */
|
||||||
|
.rp-row { display: flex; align-items: center; gap: 0.6rem; }
|
||||||
|
.rp-size-btn {
|
||||||
|
width: 38px; height: 38px; border-radius: 50%;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1); background: var(--reader-surface-2);
|
||||||
|
color: var(--apple-text); font-weight: 700; cursor: pointer;
|
||||||
|
display: inline-flex; align-items: center; justify-content: center;
|
||||||
|
transition: background 0.2s, transform 0.15s var(--apple-ease);
|
||||||
|
}
|
||||||
|
.rp-size-btn:hover { background: var(--reader-hover); }
|
||||||
|
.rp-size-btn:active { transform: scale(0.92); }
|
||||||
|
.rp-size-btn[data-action="dec"] { font-size: 0.85rem; }
|
||||||
|
.rp-size-btn[data-action="inc"] { font-size: 1.15rem; }
|
||||||
|
.rp-size-val { flex: 1; text-align: center; font-size: 0.85rem; color: var(--apple-gray); font-variant-numeric: tabular-nums; }
|
||||||
|
.rp-spacing { display: flex; gap: 0.45rem; }
|
||||||
|
.rp-spacing-btn {
|
||||||
|
flex: 1; padding: 0.45rem 0; border-radius: var(--apple-radius-sm);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.08); background: var(--reader-surface-2);
|
||||||
|
color: var(--apple-text); font-size: 0.75rem; cursor: pointer; text-align: center;
|
||||||
|
transition: border-color 0.2s, background 0.2s;
|
||||||
|
}
|
||||||
|
.rp-spacing-btn:hover { background: var(--reader-hover); }
|
||||||
|
.rp-spacing-btn.active { border-color: var(--apple-blue); background: rgba(0, 113, 227, 0.08); }
|
||||||
|
.rp-reset {
|
||||||
|
width: 100%; margin-top: 0.9rem; padding: 0.5rem;
|
||||||
|
border-radius: var(--apple-radius-sm); border: 1px dashed rgba(0, 0, 0, 0.15);
|
||||||
|
background: transparent; color: var(--apple-gray); font-size: 0.75rem; cursor: pointer;
|
||||||
|
transition: color 0.2s, border-color 0.2s;
|
||||||
|
}
|
||||||
|
.rp-reset:hover { color: var(--apple-text); border-color: var(--apple-blue); }
|
||||||
|
/* Backdrop for closing panel on outside click (invisible) */
|
||||||
|
#reader-panel-backdrop {
|
||||||
|
position: fixed; inset: 0; z-index: 85; display: none;
|
||||||
|
}
|
||||||
|
#reader-panel.open ~ #reader-panel-backdrop { display: block; }
|
||||||
|
|
||||||
|
/* Aa button placement: inline in actions row (desktop) + floating (mobile) */
|
||||||
|
.reader-toolbar-wrap { display: inline-flex; align-items: center; }
|
||||||
|
#reader-fab {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 5.75rem; right: 1.5rem;
|
||||||
|
z-index: 41;
|
||||||
|
width: 3rem; height: 3rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: var(--apple-blue); color: #fff;
|
||||||
|
border: none; cursor: pointer;
|
||||||
|
font-size: 1.1rem; font-weight: 800;
|
||||||
|
box-shadow: 0 12px 28px rgba(0, 113, 227, 0.32);
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
transition: background-color 0.2s ease, transform 0.2s var(--apple-ease);
|
||||||
|
}
|
||||||
|
#reader-fab:hover { transform: translateY(-1px); }
|
||||||
|
@media (max-width: 1023px) {
|
||||||
|
#reader-fab { display: flex; }
|
||||||
|
#reader-panel {
|
||||||
|
bottom: 9.25rem;
|
||||||
|
right: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
#reader-panel {
|
||||||
|
left: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
width: auto;
|
||||||
|
bottom: 9.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Scroll-to-top mini button */
|
||||||
|
#back-to-top {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 1.5rem; left: 1.5rem;
|
||||||
|
z-index: 41;
|
||||||
|
width: 2.75rem; height: 2.75rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||||
|
background: var(--reader-surface);
|
||||||
|
color: var(--apple-gray);
|
||||||
|
box-shadow: var(--apple-shadow-card);
|
||||||
|
cursor: pointer;
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
transition: opacity 0.3s ease, transform 0.2s var(--apple-ease), color 0.2s;
|
||||||
|
}
|
||||||
|
#back-to-top:hover { color: var(--apple-blue); transform: translateY(-1px); }
|
||||||
|
#back-to-top.visible { display: flex; }
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
#back-to-top { display: none !important; }
|
||||||
|
}
|
||||||
|
/* Night theme tweaks for controls */
|
||||||
|
body.reader-night .rp-size-btn,
|
||||||
|
body.reader-night .rp-spacing-btn,
|
||||||
|
body.reader-night .rp-font-chip {
|
||||||
|
background: var(--reader-control);
|
||||||
|
}
|
||||||
|
body.reader-night .action-btn-secondary { background: var(--reader-control); }
|
||||||
|
body.reader-night .apple-btn-secondary { background: var(--reader-control); color: var(--apple-text); }
|
||||||
|
body.reader-night .post-timestamps { background: var(--reader-control); }
|
||||||
|
body.reader-night .post-summary { border-left-color: rgba(77, 159, 255, 0.4); }
|
||||||
|
body.reader-night .think-header { background: var(--reader-control); }
|
||||||
|
body.reader-night .think-header:hover { background: var(--reader-hover); }
|
||||||
|
body.reader-night .think-panel { background: var(--reader-surface); }
|
||||||
|
body.reader-night .append-textarea { background: var(--reader-control); color: var(--apple-text); }
|
||||||
|
body.reader-night .append-textarea:focus { background: var(--reader-surface-2); }
|
||||||
|
body.reader-night .audio-player { background: var(--reader-surface-2); }
|
||||||
|
body.reader-night .voice-controls { background: var(--reader-surface-2); }
|
||||||
|
body.reader-night .voice-select-compact,
|
||||||
|
body.reader-night .custom-voice-input { background: var(--reader-control); color: var(--apple-text); }
|
||||||
|
body.reader-night .toc-mobile-btn-back { background: var(--reader-control); }
|
||||||
|
body.reader-night #toc-sidebar .toc-h3,
|
||||||
|
body.reader-night #toc-sidebar .toc-h4,
|
||||||
|
body.reader-night #toc-nav-mobile .toc-h3,
|
||||||
|
body.reader-night #toc-nav-mobile .toc-h4 { color: #a5a5b0; }
|
||||||
|
body.reader-night .post-summary p { color: #a5a5b0; }
|
||||||
|
body.reader-night .prose blockquote { color: #a9a9b4; }
|
||||||
|
/* Reveal animation on load */
|
||||||
|
@keyframes readerFadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
.main-content { animation: readerFadeIn 0.5s var(--apple-ease) both; }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<!-- Reading progress bar -->
|
||||||
|
<div id="reading-progress" aria-hidden="true"></div>
|
||||||
|
|
||||||
<!-- Delete Confirmation Modal -->
|
<!-- Delete Confirmation Modal -->
|
||||||
<div id="deleteModal" class="modal" aria-labelledby="modal-title" role="dialog" aria-modal="true">
|
<div id="deleteModal" class="modal" aria-labelledby="modal-title" role="dialog" aria-modal="true">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -624,6 +971,10 @@
|
|||||||
|
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<div class="post-actions">
|
<div class="post-actions">
|
||||||
|
<div class="reader-toolbar-wrap">
|
||||||
|
<button id="reader-toolbar-btn" onclick="toggleReaderPanel()" class="reader-toolbar-btn"
|
||||||
|
title="{% trans 'Reading settings' %}" aria-label="{% trans 'Reading settings' %}">Aa</button>
|
||||||
|
</div>
|
||||||
<button onclick="toggleTTS()" class="action-btn action-btn-purple">
|
<button onclick="toggleTTS()" class="action-btn action-btn-purple">
|
||||||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
@@ -815,7 +1166,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content Section -->
|
<!-- Content Section -->
|
||||||
<article class="prose max-w-none prose-lg post-article">
|
<article id="post-article" class="prose max-w-none prose-lg post-article">
|
||||||
{% markdown_with_tasks post.content post.task_states %}
|
{% markdown_with_tasks post.content post.task_states %}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
@@ -841,6 +1192,79 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Mobile Aa floating button -->
|
||||||
|
<button id="reader-fab" onclick="toggleReaderPanel()" title="{% trans 'Reading settings' %}" aria-label="{% trans 'Reading settings' %}">Aa</button>
|
||||||
|
|
||||||
|
<!-- Reader settings panel -->
|
||||||
|
<div id="reader-panel" role="dialog" aria-label="{% trans 'Reading settings' %}">
|
||||||
|
<div class="rp-section">
|
||||||
|
<p class="rp-label">{% trans "Theme" %}</p>
|
||||||
|
<div class="rp-themes">
|
||||||
|
<button class="rp-swatch rp-swatch-light" data-theme="light" onclick="setReaderTheme('light')" title="{% trans 'Light' %}">
|
||||||
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
|
||||||
|
</button>
|
||||||
|
<button class="rp-swatch rp-swatch-paper" data-theme="paper" onclick="setReaderTheme('paper')" title="{% trans 'Paper' %}">
|
||||||
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
|
||||||
|
</button>
|
||||||
|
<button class="rp-swatch rp-swatch-green" data-theme="green" onclick="setReaderTheme('green')" title="{% trans 'Green' %}">
|
||||||
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
|
||||||
|
</button>
|
||||||
|
<button class="rp-swatch rp-swatch-night" data-theme="night" onclick="setReaderTheme('night')" title="{% trans 'Night' %}">
|
||||||
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rp-section">
|
||||||
|
<p class="rp-label">{% trans "Font" %}</p>
|
||||||
|
<div class="rp-fonts">
|
||||||
|
<button class="rp-font-chip" data-font="system" onclick="setReaderFont('system')">
|
||||||
|
<span class="rp-font-name">系统</span><span class="rp-font-meta">System</span>
|
||||||
|
</button>
|
||||||
|
<button class="rp-font-chip" data-font="serif" onclick="setReaderFont('serif')">
|
||||||
|
<span class="rp-font-name">宋体</span><span class="rp-font-meta">Serif</span>
|
||||||
|
</button>
|
||||||
|
<button class="rp-font-chip" data-font="hei" onclick="setReaderFont('hei')">
|
||||||
|
<span class="rp-font-name">黑体</span><span class="rp-font-meta">Sans</span>
|
||||||
|
</button>
|
||||||
|
<button class="rp-font-chip" data-font="kai" onclick="setReaderFont('kai')">
|
||||||
|
<span class="rp-font-name">楷体</span><span class="rp-font-meta">Kai</span>
|
||||||
|
</button>
|
||||||
|
<button class="rp-font-chip" data-font="mono" onclick="setReaderFont('mono')">
|
||||||
|
<span class="rp-font-name">等宽</span><span class="rp-font-meta">Mono</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rp-section">
|
||||||
|
<p class="rp-label">{% trans "Size" %}</p>
|
||||||
|
<div class="rp-row">
|
||||||
|
<button class="rp-size-btn" data-action="dec" onclick="changeReaderSize(-1)" aria-label="{% trans 'Smaller' %}">A−</button>
|
||||||
|
<span class="rp-size-val" id="rp-size-val">17px</span>
|
||||||
|
<button class="rp-size-btn" data-action="inc" onclick="changeReaderSize(1)" aria-label="{% trans 'Larger' %}">A+</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rp-section">
|
||||||
|
<p class="rp-label">{% trans "Spacing" %}</p>
|
||||||
|
<div class="rp-spacing">
|
||||||
|
<button class="rp-spacing-btn" data-spacing="1.6" onclick="setReaderSpacing(1.6)">{% trans "Compact" %}</button>
|
||||||
|
<button class="rp-spacing-btn" data-spacing="1.85" onclick="setReaderSpacing(1.85)">{% trans "Cozy" %}</button>
|
||||||
|
<button class="rp-spacing-btn" data-spacing="2.15" onclick="setReaderSpacing(2.15)">{% trans "Relaxed" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="rp-reset" onclick="resetReaderPrefs()">↺ {% trans "Reset to defaults" %}</button>
|
||||||
|
</div>
|
||||||
|
<div id="reader-panel-backdrop" onclick="closeReaderPanel()"></div>
|
||||||
|
|
||||||
|
<!-- Back to top -->
|
||||||
|
<button id="back-to-top" onclick="window.scrollTo({top: 0, behavior: 'smooth'})" aria-label="{% trans 'Back to top' %}">
|
||||||
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 15l7-7 7 7"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Mobile TOC backdrop -->
|
<!-- Mobile TOC backdrop -->
|
||||||
<div id="toc-mobile-backdrop" aria-hidden="true"></div>
|
<div id="toc-mobile-backdrop" aria-hidden="true"></div>
|
||||||
|
|
||||||
@@ -1437,5 +1861,118 @@ function regenerateWithVoice() {
|
|||||||
if (backdrop) backdrop.addEventListener('click', closeMobileDrawer);
|
if (backdrop) backdrop.addEventListener('click', closeMobileDrawer);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Reader preferences — 微信读书-style reading experience
|
||||||
|
// ============================================================
|
||||||
|
(function() {
|
||||||
|
var STORAGE_KEY = 'links-reader-prefs-v1';
|
||||||
|
var DEFAULTS = { theme: 'light', font: 'system', size: 17, spacing: 1.85 };
|
||||||
|
|
||||||
|
var prefs = Object.assign({}, DEFAULTS);
|
||||||
|
try {
|
||||||
|
var saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
|
||||||
|
Object.assign(prefs, saved);
|
||||||
|
} catch (e) { /* ignore corrupt prefs */ }
|
||||||
|
|
||||||
|
function clampSize(v) { return Math.min(24, Math.max(13, v)); }
|
||||||
|
function clampSpacing(v) { return Math.min(2.3, Math.max(1.4, v)); }
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs)); } catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply() {
|
||||||
|
var body = document.body;
|
||||||
|
// Theme
|
||||||
|
['light', 'paper', 'green', 'night'].forEach(function(t) {
|
||||||
|
body.classList.toggle('reader-' + t, t === prefs.theme);
|
||||||
|
});
|
||||||
|
// Font
|
||||||
|
['system', 'serif', 'hei', 'kai', 'mono'].forEach(function(f) {
|
||||||
|
body.classList.toggle('reader-font-' + f, f === prefs.font);
|
||||||
|
});
|
||||||
|
// Size + spacing on the article
|
||||||
|
var article = document.getElementById('post-article');
|
||||||
|
if (article) {
|
||||||
|
article.style.setProperty('--reader-font-size', prefs.size + 'px');
|
||||||
|
article.style.setProperty('--reader-line-height', prefs.spacing);
|
||||||
|
}
|
||||||
|
// Panel UI state
|
||||||
|
document.querySelectorAll('.rp-swatch').forEach(function(el) {
|
||||||
|
el.classList.toggle('active', el.getAttribute('data-theme') === prefs.theme);
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.rp-font-chip').forEach(function(el) {
|
||||||
|
el.classList.toggle('active', el.getAttribute('data-font') === prefs.font);
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.rp-spacing-btn').forEach(function(el) {
|
||||||
|
el.classList.toggle('active', parseFloat(el.getAttribute('data-spacing')) === prefs.spacing);
|
||||||
|
});
|
||||||
|
var sizeVal = document.getElementById('rp-size-val');
|
||||||
|
if (sizeVal) sizeVal.textContent = prefs.size + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reading progress bar + back-to-top visibility
|
||||||
|
var progressBar = document.getElementById('reading-progress');
|
||||||
|
var backToTop = document.getElementById('back-to-top');
|
||||||
|
var scrollTicking = false;
|
||||||
|
function onScroll() {
|
||||||
|
if (scrollTicking) return;
|
||||||
|
scrollTicking = true;
|
||||||
|
requestAnimationFrame(function() {
|
||||||
|
scrollTicking = false;
|
||||||
|
var doc = document.documentElement;
|
||||||
|
var total = doc.scrollHeight - window.innerHeight;
|
||||||
|
var pct = total > 0 ? (window.scrollY / total) * 100 : 0;
|
||||||
|
if (progressBar) progressBar.style.width = pct + '%';
|
||||||
|
if (backToTop) backToTop.classList.toggle('visible', window.scrollY > 600);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
onScroll();
|
||||||
|
|
||||||
|
// Expose panel controls globally (used by inline onclick)
|
||||||
|
window.toggleReaderPanel = function() {
|
||||||
|
var panel = document.getElementById('reader-panel');
|
||||||
|
if (!panel) return;
|
||||||
|
var open = panel.classList.toggle('open');
|
||||||
|
syncReaderTriggers(open);
|
||||||
|
};
|
||||||
|
window.closeReaderPanel = function() {
|
||||||
|
var panel = document.getElementById('reader-panel');
|
||||||
|
if (panel) panel.classList.remove('open');
|
||||||
|
syncReaderTriggers(false);
|
||||||
|
};
|
||||||
|
function syncReaderTriggers(open) {
|
||||||
|
['reader-toolbar-btn', 'reader-fab'].forEach(function(id) {
|
||||||
|
var el = document.getElementById(id);
|
||||||
|
if (el) el.classList.toggle('active', open);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.setReaderTheme = function(t) {
|
||||||
|
prefs.theme = t; save(); apply();
|
||||||
|
};
|
||||||
|
window.setReaderFont = function(f) {
|
||||||
|
prefs.font = f; save(); apply();
|
||||||
|
};
|
||||||
|
window.changeReaderSize = function(delta) {
|
||||||
|
prefs.size = clampSize(prefs.size + delta); save(); apply();
|
||||||
|
};
|
||||||
|
window.setReaderSpacing = function(s) {
|
||||||
|
prefs.spacing = clampSpacing(s); save(); apply();
|
||||||
|
};
|
||||||
|
window.resetReaderPrefs = function() {
|
||||||
|
prefs = Object.assign({}, DEFAULTS); save(); apply();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close panel on Escape
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (e.key === 'Escape') closeReaderPanel();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
apply();
|
||||||
|
});
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
+122
-40
@@ -1,103 +1,185 @@
|
|||||||
|
/* ============================================================
|
||||||
|
Markdown prose styling — theme-variable driven.
|
||||||
|
Defaults keep existing light appearance; the post detail
|
||||||
|
reader overrides --md-* variables per theme (paper/green/night).
|
||||||
|
============================================================ */
|
||||||
|
:root {
|
||||||
|
--md-bg: #ffffff; /* content background */
|
||||||
|
--md-text: #374151; /* body text */
|
||||||
|
--md-muted: #6b7280; /* secondary text */
|
||||||
|
--md-heading: #111827; /* headings */
|
||||||
|
--md-border: #e5e7eb; /* table / block borders */
|
||||||
|
--md-accent: #2563eb; /* links */
|
||||||
|
--md-accent-soft: rgba(37, 99, 235, 0.08);
|
||||||
|
--md-table-head-bg: #f3f4f6;
|
||||||
|
--md-table-zebra: rgba(0, 0, 0, 0.02);
|
||||||
|
--md-code-bg: #f3f4f6;
|
||||||
|
--md-code-text: #111827;
|
||||||
|
--md-pre-bg: #1f2937;
|
||||||
|
--md-pre-text: #e5e7eb;
|
||||||
|
--md-quote-bg: rgba(0, 0, 0, 0.02);
|
||||||
|
--md-hr: #e5e7eb;
|
||||||
|
--md-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.prose {
|
.prose {
|
||||||
color: #374151;
|
color: var(--md-text);
|
||||||
max-width: none;
|
max-width: none;
|
||||||
|
line-height: 1.85;
|
||||||
}
|
}
|
||||||
.prose p {
|
.prose p {
|
||||||
margin-top: 1.25em;
|
margin-top: 1.3em;
|
||||||
margin-bottom: 1.25em;
|
margin-bottom: 1.3em;
|
||||||
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
.prose a {
|
.prose a {
|
||||||
color: #2563eb;
|
color: var(--md-accent);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 2px;
|
||||||
|
text-decoration-thickness: 1px;
|
||||||
|
}
|
||||||
|
.prose a:hover {
|
||||||
|
text-decoration-thickness: 2px;
|
||||||
}
|
}
|
||||||
.prose strong {
|
.prose strong {
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
|
color: var(--md-heading);
|
||||||
}
|
}
|
||||||
.prose ul {
|
.prose ul {
|
||||||
margin-top: 1.25em;
|
margin-top: 1.1em;
|
||||||
margin-bottom: 1.25em;
|
margin-bottom: 1.1em;
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
padding-left: 1.625em;
|
padding-left: 1.625em;
|
||||||
}
|
}
|
||||||
.prose ol {
|
.prose ol {
|
||||||
margin-top: 1.25em;
|
margin-top: 1.1em;
|
||||||
margin-bottom: 1.25em;
|
margin-bottom: 1.1em;
|
||||||
list-style-type: decimal;
|
list-style-type: decimal;
|
||||||
padding-left: 1.625em;
|
padding-left: 1.625em;
|
||||||
}
|
}
|
||||||
|
.prose li {
|
||||||
|
margin-top: 0.35em;
|
||||||
|
margin-bottom: 0.35em;
|
||||||
|
}
|
||||||
|
.prose li > ul,
|
||||||
|
.prose li > ol {
|
||||||
|
margin-top: 0.3em;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
.prose h1 {
|
.prose h1 {
|
||||||
font-size: 2.25em;
|
font-size: 2.1em;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0.8888889em;
|
margin-bottom: 0.8em;
|
||||||
line-height: 1.1111111;
|
line-height: 1.25;
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
|
color: var(--md-heading);
|
||||||
|
letter-spacing: -0.015em;
|
||||||
}
|
}
|
||||||
.prose h2 {
|
.prose h2 {
|
||||||
font-size: 1.5em;
|
font-size: 1.55em;
|
||||||
margin-top: 2em;
|
margin-top: 2.2em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 0.7em;
|
||||||
line-height: 1.3333333;
|
line-height: 1.35;
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
|
color: var(--md-heading);
|
||||||
|
letter-spacing: -0.01em;
|
||||||
}
|
}
|
||||||
.prose h3 {
|
.prose h3 {
|
||||||
font-size: 1.25em;
|
font-size: 1.22em;
|
||||||
|
margin-top: 1.8em;
|
||||||
|
margin-bottom: 0.55em;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 650;
|
||||||
|
color: var(--md-heading);
|
||||||
|
}
|
||||||
|
.prose h4 {
|
||||||
|
font-size: 1.05em;
|
||||||
margin-top: 1.6em;
|
margin-top: 1.6em;
|
||||||
margin-bottom: 0.6em;
|
margin-bottom: 0.5em;
|
||||||
line-height: 1.6;
|
line-height: 1.5;
|
||||||
font-weight: 600;
|
font-weight: 650;
|
||||||
|
color: var(--md-heading);
|
||||||
}
|
}
|
||||||
.prose img {
|
.prose img {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
|
border-radius: var(--md-radius);
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
||||||
.prose code {
|
.prose code {
|
||||||
color: #111827;
|
color: var(--md-code-text);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
background-color: #f3f4f6;
|
background-color: var(--md-code-bg);
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.45em;
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Menlo', 'Cascadia Code', Consolas, monospace;
|
||||||
}
|
}
|
||||||
.prose pre {
|
.prose pre {
|
||||||
color: #e5e7eb;
|
color: var(--md-pre-text);
|
||||||
background-color: #1f2937;
|
background-color: var(--md-pre-bg);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
line-height: 1.7142857;
|
line-height: 1.7142857;
|
||||||
margin-top: 1.7142857em;
|
margin-top: 1.7142857em;
|
||||||
margin-bottom: 1.7142857em;
|
margin-bottom: 1.7142857em;
|
||||||
border-radius: 0.375rem;
|
border-radius: var(--md-radius);
|
||||||
padding: 1em;
|
padding: 1.1em 1.25em;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
.prose pre code {
|
.prose pre code {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
font-weight: 450;
|
||||||
}
|
}
|
||||||
.prose blockquote {
|
.prose blockquote {
|
||||||
font-style: italic;
|
font-style: normal;
|
||||||
border-left: 4px solid #e5e7eb;
|
border-left: 3px solid var(--md-border);
|
||||||
padding-left: 1em;
|
background: var(--md-quote-bg);
|
||||||
margin: 1.25em 0;
|
padding: 0.9em 1.2em;
|
||||||
|
margin: 1.4em 0;
|
||||||
|
border-radius: 0 var(--md-radius) var(--md-radius) 0;
|
||||||
|
color: var(--md-text);
|
||||||
|
}
|
||||||
|
.prose blockquote p {
|
||||||
|
margin: 0.4em 0;
|
||||||
|
}
|
||||||
|
.prose blockquote strong {
|
||||||
|
color: var(--md-heading);
|
||||||
|
}
|
||||||
|
.prose hr {
|
||||||
|
border: 0;
|
||||||
|
height: 1px;
|
||||||
|
background: var(--md-hr);
|
||||||
|
margin: 2.4em 0;
|
||||||
}
|
}
|
||||||
.prose table {
|
.prose table {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin: 2em 0;
|
margin: 1.8em 0;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
|
border-radius: var(--md-radius);
|
||||||
|
font-size: 0.93em;
|
||||||
}
|
}
|
||||||
.prose table th {
|
.prose table th {
|
||||||
background-color: #f3f4f6;
|
background-color: var(--md-table-head-bg);
|
||||||
font-weight: 600;
|
font-weight: 650;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0.5em;
|
padding: 0.6em 0.8em;
|
||||||
border: 1px solid #e5e7eb;
|
border: 1px solid var(--md-border);
|
||||||
|
color: var(--md-heading);
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.prose table td {
|
.prose table td {
|
||||||
padding: 0.5em;
|
padding: 0.6em 0.8em;
|
||||||
border: 1px solid #e5e7eb;
|
border: 1px solid var(--md-border);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.prose table tr:nth-child(even) td {
|
||||||
|
background-color: var(--md-table-zebra);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user