Files
ONE/frontend/src/ui/yohaku/article.css
T

218 lines
14 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
html[data-ui='vivid'] .article-layout {max-width:1100px;margin:0 auto;padding:24px 24px 44px;
display:grid;
grid-template-columns:140px minmax(0,1fr) 180px;
gap:24px;align-items:start;}
@media (max-width:960px) {
/* 1fr 的自动最小尺寸是 min-content:正文里出现不可断行的长 token
(长内联代码/链接)时轨道会被顶到 592px+,整页横向溢出。
minmax(0,1fr) 和 classic 的 .layout 同一写法,把最小尺寸钉死为 0。 */
html[data-ui='vivid'] .article-layout {grid-template-columns:minmax(0,1fr);gap:0}
html[data-ui='vivid'] .side-l, html[data-ui='vivid'] .side-r {display:none}
html[data-ui='vivid'] .progress-pct {display:none}
}
/* 宽屏三栏。上限必须和「三栏 + 两个 gap + 左右内边距」正好相等,声明的 gap 才是
渲染出来的 gap —— 否则 justify-content:space-between 会把富余量塞回列间隙里,
数字改小也不动:
180 + 776 + 220 + 24×2(gap) = 1224 内容宽,+ 24×2(内边距) = 1272
中列 776 = 728(正文, --measure) + 24×2(.paper 内边距),正文吃满不留内空。
顶栏不跟着放 —— 顶栏全站一个宽度(1100),从首页点进文章时导航不会跳。 */
@media (min-width:1200px) {
html[data-ui='vivid'] .article-layout {max-width:1272px;
grid-template-columns:180px minmax(0,776px) 220px;
justify-content:space-between;}
}
html[data-ui='vivid'] .side-l {position:sticky;top:80px;padding-top:8px}
html[data-ui='vivid'] .tl {position:relative;padding-left:14px}
html[data-ui='vivid'] .tl::before {content:"";position:absolute;left:3px;top:6px;bottom:6px;width:1.5px;
background:linear-gradient(180deg,var(--accent),transparent);
border-radius:2px;}
html[data-ui='vivid'] .tl-item {position:relative;padding:0 0 18px 0;font-size:12px;color:var(--muted);}
html[data-ui='vivid'] .tl-item::before {content:"";position:absolute;left:-14px;top:5px;
width:7px;height:7px;border-radius:50%;
background:var(--card);border:2px solid var(--accent);}
html[data-ui='vivid'] .tl-item.now::before {background:var(--accent);
box-shadow:0 0 0 4px var(--accent-soft);}
html[data-ui='vivid'] .tl-item b {display:block;color:var(--soft);font-weight:700;font-size:12px}
html[data-ui='vivid'] .tl-item.now b {color:var(--accent)}
/* 纸张不再是卡片:去掉底色 / 边框 / 圆角 / 阴影,正文直接落在页面上(手机和桌面一致)。
横向内边距 24px(原来 48)——它决定了正文列在中列里的位置:776 - 24×2 = 728 = --measure,
正好吃满不剩空。这三个数是一组,改一个另两个要跟着动,否则正文会在列里偏左
(实测:只把内边距改成 24、measure 不动,正文离左栏 83px、离右栏 131px,一边宽一边窄)。
右上角那团强调色渐晕是卡片的角饰,卡片没了也一并去掉。 */
html[data-ui='vivid'] .paper {padding:30px 24px 40px;
animation:paperIn .7s var(--spring) both;}
@keyframes paperIn {
from {opacity:0;transform:translateY(24px) scale(.985)}
to {opacity:1;transform:none}
}
/* 题头居中(参考 innei.in 的文章页:题头整块居中,正文才回到左对齐)。
tabular-nums 让日期/字数这类数字等宽,换行时也不会左右跳。
注意都用 > 直接子元素:.paper h1 会连正文里的 h1(正文本身可能从 `# 标题` 开始)
一起命中,把正文标题也居中。 */
html[data-ui='vivid'] .paper > .meta {display:flex;gap:12px;align-items:center;flex-wrap:wrap;
justify-content:center;
font-size:12.5px;color:var(--muted);font-weight:600;
font-variant-numeric:tabular-nums;
margin-bottom:18px;}
html[data-ui='vivid'] .paper > h1 {margin:0 0 20px;font-size:clamp(28px,4vw,40px);font-weight:800;
letter-spacing:-.03em;line-height:1.25;color:var(--ink);
text-align:center;
/* 居中标题容易折出「最后一行只落一两个字」,balance 让两行长度接近(Chrome/Safari) */
text-wrap:balance;}
html[data-ui='vivid'] .paper > .dek {margin:0 0 32px;font-size:17px;line-height:1.8;color:var(--soft);
padding-left:16px;border-left:3px solid var(--accent);
font-family:var(--serif);}
html[data-ui='vivid'] .prose {font-size:16.5px;line-height:1.95;color:var(--text);max-width:var(--measure);
/* 中英混排自动补一点字距(Chrome 120+ 的 text-autospace)。不支持就退回现在的样子。 */
text-autospace:normal;
/* 长 token(URL/内联代码)超出行宽时在任意字符处断行,别把列撑破 */
overflow-wrap:break-word;}
/* 段距上下各 1.5em(参考 .v10dui0 .rich-paragraph),首末段把外边距吃掉,
否则标题/分隔线上方会多出一段空白 */
html[data-ui='vivid'] .prose p {margin:1.5em 0}
html[data-ui='vivid'] .prose > :first-child {margin-top:0}
html[data-ui='vivid'] .prose > :last-child {margin-bottom:0}
html[data-ui='vivid'] .prose h2 {font-size:21px;font-weight:800;margin:2.2em 0 .8em;
letter-spacing:-.02em;color:var(--ink);
padding-bottom:10px;border-bottom:1px solid var(--line);}
/* 设计稿只写了 h2,h1/h3 不补样式会退回浏览器默认(h1 是 2em + .67em 外边距、
h3 是 1.17em + 自己的行高),在 16.5px/1.95 的正文里很突兀。
正文里出现 h1 是因为有的文章正文本身就是从 `# 标题` 开始的。 */
html[data-ui='vivid'] .prose h1 {margin:2.4em 0 .8em;font-size:1.5em;font-weight:800;
letter-spacing:-.02em;color:var(--ink);}
html[data-ui='vivid'] .prose h3 {margin:1.65em 0 .65em;font-size:1.18em;font-weight:700;
letter-spacing:-.01em;color:var(--ink);}
/* 链接改用 text-decoration:border-bottom 会进盒模型,换行时下划线也跟着断得不对。
参考里是 1px、hover 加粗到 2px。 */
html[data-ui='vivid'] .prose a {color:var(--accent);font-weight:600;
text-decoration:underline;text-decoration-thickness:1px;
text-underline-offset:2px;text-decoration-color:var(--accent-soft);
transition:text-decoration-color .25s,text-decoration-thickness .25s;}
@media (hover: hover) and (pointer: fine) {
html[data-ui='vivid'] .prose a:hover {text-decoration-color:var(--accent);text-decoration-thickness:2px}
}
html[data-ui='vivid'] .prose code {font-family:var(--mono);font-size:.88em;
background:var(--accent-soft);color:var(--accent);
padding:2px 7px;border-radius:6px;}
html[data-ui='vivid'] .prose pre {background:color-mix(in srgb,var(--ink) 92%,var(--accent));
color:#e8e8f0;padding:18px 20px;border-radius:12px;
overflow-x:auto;font-size:13.5px;line-height:1.7;
box-shadow:var(--shadow-lg);}
/* 暗色下「92% ink」混出的是浅底,浅底配浅字没法读;暗端换深底微混强调色 */
html[data-ui='vivid'][data-theme='vivid-dark'] .prose pre {
background:color-mix(in srgb,var(--paper) 86%,var(--accent));
border:1px solid var(--line);box-shadow:none;}
html[data-ui='vivid'] .prose pre code {background:none;padding:0;color:inherit;font-size:inherit}
html[data-ui='vivid'] .prose blockquote {margin:1.8em 0;padding:16px 20px;
background:var(--accent-soft);
border-left:3px solid var(--accent);
border-radius:0 12px 12px 0;
font-family:var(--serif);font-size:1.05em;
color:var(--soft);font-style:italic;}
html[data-ui='vivid'] .prose ul {padding-left:1.3em}
/* 设计稿漏了 ol,默认 40px 缩进和 ul 对不上;序号比圆点宽,给多一点 */
html[data-ui='vivid'] .prose ol {padding-left:1.6em}
html[data-ui='vivid'] .prose li {margin-bottom:.55em}
/* 分隔线收成 60px 居中(参考),比整幅虚线安静 */
html[data-ui='vivid'] .prose hr {border:0;border-top:1px solid var(--line-strong);
width:60px;margin:3.5em auto;}
/* 图:设计稿没写,插图会顶满整列、和上下文字紧贴 */
html[data-ui='vivid'] .prose img {max-width:100%;height:auto;border-radius:var(--radius-sm)}
html[data-ui='vivid'] .prose p > img {margin:2em 0}
html[data-ui='vivid'] .prose figure {margin:2em 0}
html[data-ui='vivid'] .prose figcaption {margin-top:1em;font-size:.875em;line-height:1.5;
color:var(--muted);text-align:center;}
/* 标签用 home.css 里那个共用的 .tg(纯文本 #标签),不加自己的一套。
「标签」二字的小标也去掉了:有 # 就是标签,再来两个字是重复。
这里只补一点纵向内边距 —— 详情页的标签是链接,12.5px 裸文字只有 ~18px 高,
手机上不好点;不画背景不画边框,观感不变。 */
html[data-ui='vivid'] .paper > .end {margin-top:40px;padding-top:24px;border-top:1px dashed var(--line-strong);
display:flex;gap:14px;flex-wrap:wrap;align-items:center;}
html[data-ui='vivid'] .paper > .end .tg {padding:6px 0}
/* 短文配图:Twitter 式网格(快发盒上传,≤4 张;跟 prose 同宽,圆角跟 vivid 走) */
html[data-ui='vivid'] .post-imgs {margin-top: 6px;
border-radius: var(--radius);}
html[data-ui='vivid'] .post-imgs.n1 img {max-height: 520px;}
/* ==========================================================================
把 classic 的 .prose 挡回去
--------------------------------------------------------------------------
styles.css 里那一段 .prose 规则是不带 data-ui 前缀的,vivid 也照样命中。
我们的规则特指度更高,但只覆盖自己声明过的属性 —— 没声明的就漏过来了。
实测漏过来的是这几条(都是量出来的,不是猜的):
· a 的 border-bottom → 和新的 text-decoration 叠成双下划线
· hr 的 height+background → 我们的 60px 细线被垫成 2px、颜色也变成 --line
· h3::after → 每条 h3 下面多一条 28×2px 的强调色横杠
· ul/ol 的 1.1em 下边距 → 和正文 1.5em 的段距对不齐
· blockquote 里末段 p → 下边距没被吃掉,引用块底部多半行空
· pre 的 1px 边框 → 深色代码块外多一圈发丝线
· h4 → 用 classic 的 16.5px(和正文字号一样大,不成层级)
下面逐条认领。tokens.css 里那段防线处理的是 .stat/.toolbar/.chip 那类组件外壳,
正文这一摊放在这里,改正文的人一眼能看到。
========================================================================== */
html[data-ui='vivid'] .prose a {border-bottom:0}
html[data-ui='vivid'] .prose hr {height:0;background:none}
html[data-ui='vivid'] .prose h3::after {content:none}
html[data-ui='vivid'] .prose ul,
html[data-ui='vivid'] .prose ol {margin:1.5em 0}
html[data-ui='vivid'] .prose blockquote p:last-child {margin-bottom:0}
html[data-ui='vivid'] .prose pre {border:0}
html[data-ui='vivid'] .prose h4 {margin:1.4em 0 .5em;font-size:1.05em;font-weight:700;
letter-spacing:-.01em;color:var(--ink);}
/* 首字下沉:设计稿里没有这条,classic 漏过来的是固定 52px。参考站(innei.in 余白模式)
也有首字下沉,那就认领成自己的,按 2.4em 走、跟着正文字号缩放。 */
html[data-ui='vivid'] .prose > p:first-of-type::first-letter {float:left;
font-family:var(--serif);font-size:2.4em;line-height:1;
margin:.06em .18em 0 0;color:var(--accent);}
/* 短文不做首字下沉:正文第一句就是全部,压一个大字进去反而像截断
(classic 也是这么分的,它用 .prose-short 关掉) */
html[data-ui='vivid'] .prose.prose-note > p:first-of-type::first-letter {float:none;
font-family:inherit;font-size:inherit;line-height:inherit;margin:0;color:inherit;}
html[data-ui='vivid'] .back {display:inline-flex;align-items:center;gap:6px;
font-size:13px;font-weight:700;color:var(--accent);
margin-bottom:20px;padding:6px 0;
transition:gap .4s var(--spring);}
@media (hover: hover) and (pointer: fine) {
html[data-ui='vivid'] .back:hover {gap:12px}
}
html[data-ui='vivid'] .side-r {position:sticky;top:80px;padding-top:8px}
html[data-ui='vivid'] .toc h4 {margin:0 0 12px;font-size:11px;font-weight:800;
letter-spacing:.14em;text-transform:uppercase;color:var(--muted);}
html[data-ui='vivid'] .toc ol {list-style:none;margin:0;padding:0;counter-reset:toc}
html[data-ui='vivid'] .toc li {counter-increment:toc;margin-bottom:2px}
html[data-ui='vivid'] .toc a {display:flex;gap:8px;font-size:12.5px;color:var(--soft);
padding:6px 8px;border-radius:8px;line-height:1.4;
transition:background .4s var(--spring),color .4s var(--spring),transform .4s var(--spring);}
html[data-ui='vivid'] .toc a::before {content:counter(toc,decimal-leading-zero);
font-family:var(--mono);font-size:10px;color:var(--muted);
flex:none;padding-top:2px;}
html[data-ui='vivid'] .toc a.on {background:var(--accent-soft);color:var(--accent);transform:translateX(4px);}
@media (hover: hover) and (pointer: fine) {
html[data-ui='vivid'] .toc a:hover {background:var(--accent-soft);color:var(--accent);transform:translateX(4px);}
}
html[data-ui='vivid'] .toc a.on::before {color:var(--accent)}
@media (hover: hover) and (pointer: fine) {
html[data-ui='vivid'] .toc a:hover::before {color:var(--accent)}
}
html[data-ui='vivid'] .read-meter {margin-top:20px;padding-top:16px;border-top:1px solid var(--line);}
html[data-ui='vivid'] .read-meter .bar {height:3px;background:color-mix(in srgb,var(--ink) 8%,transparent);
border-radius:999px;overflow:hidden;}
html[data-ui='vivid'] .read-meter .bar i {display:block;height:100%;width:0%;
background:linear-gradient(90deg,var(--accent),var(--accent-deep));
border-radius:999px;transition:width .15s linear;}
html[data-ui='vivid'] .read-meter .num {display:flex;justify-content:space-between;
font-family:var(--mono);font-size:11px;color:var(--muted);
margin-top:8px;font-weight:600;}
html[data-ui='vivid'] .read-meter .num b {color:var(--accent)}
html[data-ui='vivid'] .sr-only {position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;}
html[data-ui='vivid'] .toc a:active { color: var(--accent); }