yggdrasil/input.css

851 lines
19 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.

@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--font-serif: 'Source Serif 4', 'Noto Serif SC', 'Source Han Serif SC', 'Songti SC', Georgia, serif;
/* Catppuccin Latte亮色。语义 token → 调色板角色:
theme=base entry=mantle primary=text secondary=subtext1
tertiary=overlay0 content=subtext0 code-block=crust code-bg=surface0
border=surface1 accent=green accent-2=teal主/次强调色) */
--color-paper-theme: #eff1f5;
--color-paper-entry: #e6e9ef;
--color-paper-primary: #4c4f69;
--color-paper-secondary: #5c5f77;
--color-paper-tertiary: #9ca0b0;
--color-paper-content: #6c6f85;
--color-paper-code-block: #dce0e8;
--color-paper-code-bg: #ccd0da;
--color-paper-border: #bcc0cc;
--color-paper-accent: #40a02b;
--color-paper-accent-soft: #ccd0da;
--color-paper-accent-2: #179299;
--color-paper-accent-2-soft: #ccd0da;
--radius-paper: 8px;
--gap-paper: 24px;
--content-gap-paper: 20px;
--nav-width-paper: 1024px;
--main-width-paper: 720px;
}
@layer base {
html {
scroll-behavior: smooth;
background-color: var(--color-paper-theme);
}
body {
background-color: var(--color-paper-theme);
color: var(--color-paper-primary);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@keyframes page-enter {
0% {
opacity: 0;
transform: translateY(16px) scale(0.995);
}
100% {
opacity: 1;
transform: none;
}
}
.animate-page-enter {
animation: page-enter 400ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
/* Minimalist custom scrollbars */
* {
scrollbar-width: thin;
scrollbar-color: var(--color-paper-border) transparent;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: var(--color-paper-border);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--color-paper-tertiary);
}
.dark {
/* Catppuccin Mocha暗色。accent-soft 带绿调、accent-2-soft 带 teal 调,
在 surface0 暗底上透出微弱主/次强调色。 */
--color-paper-theme: #1e1e2e;
--color-paper-entry: #181825;
--color-paper-primary: #cdd6f4;
--color-paper-secondary: #bac2de;
--color-paper-tertiary: #6c7086;
--color-paper-content: #a6adc8;
--color-paper-code-block: #313244;
--color-paper-code-bg: #313244;
--color-paper-border: #45475a;
--color-paper-accent: #a6e3a1;
--color-paper-accent-soft: #1e2e22;
--color-paper-accent-2: #94e2d5;
--color-paper-accent-2-soft: #1e2a28;
}
}
@layer components {
.post-single {
margin: 0 auto;
}
.post-header {
margin: 48px auto 48px auto;
display: flex;
flex-direction: column;
gap: 16px;
}
.post-title {
font-size: clamp(2.5rem, 6vw, 4.5rem);
font-weight: 800;
line-height: 1.1;
color: var(--color-paper-primary);
word-break: break-word;
letter-spacing: -0.04em;
margin: 0;
}
.post-description {
color: var(--color-paper-secondary);
font-size: 1.125rem;
font-weight: 500;
line-height: 1.7;
margin: 0;
}
.post-meta {
margin-top: 8px;
color: var(--color-paper-tertiary);
font-size: 15px;
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
font-weight: 500;
}
.post-meta a {
color: var(--color-paper-secondary);
text-decoration-style: dotted;
text-underline-offset: 0.3rem;
text-decoration: underline;
}
.post-meta a:hover {
color: var(--color-paper-primary);
}
.breadcrumbs {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.2rem;
color: var(--color-paper-secondary);
font-size: 14px;
margin-bottom: 10px;
}
.breadcrumbs a {
font-size: 16px;
color: var(--color-paper-primary);
}
.breadcrumbs a:hover {
text-decoration: underline;
text-underline-offset: 0.2rem;
}
.entry-hint {
display: inline-flex;
margin-left: 0.5rem;
color: var(--color-paper-secondary);
}
details.toc {
margin-bottom: var(--content-gap-paper);
background: var(--color-paper-code-bg);
border-radius: var(--radius-paper);
border: 1px solid var(--color-paper-border);
}
details.toc summary {
padding: 0.3rem 1.2rem;
border-radius: var(--radius-paper);
cursor: pointer;
display: list-item;
width: 100%;
user-select: none;
color: var(--color-paper-primary);
}
details.toc .title {
display: inline;
font-weight: 500;
margin-inline-start: 0.2rem;
}
details.toc .inner {
margin: 0 2.4rem;
padding-bottom: 0.6rem;
}
details.toc ul {
list-style: none;
padding: 0;
margin: 0;
}
details.toc li {
margin: 0.3rem 0;
}
details.toc a {
color: var(--color-paper-secondary);
text-decoration: none;
font-size: 14px;
}
details.toc a:hover {
color: var(--color-paper-primary);
text-decoration: underline;
text-underline-offset: 0.3rem;
}
details.toc li ul {
margin-inline-start: var(--gap-paper);
}
details {
interpolate-size: allow-keywords;
}
details::details-content {
height: 0;
opacity: 0;
overflow: clip;
transition: height 150ms ease, opacity 150ms ease, content-visibility 150ms allow-discrete;
}
details[open]::details-content {
height: auto;
opacity: 1;
}
.entry-cover {
margin-bottom: var(--content-gap-paper);
}
/* 封面用 blur-img 结构:去 margin、保持圆角内层 img cover 填充 */
.entry-cover .blur-img {
margin: 0;
border-radius: 2rem;
overflow: hidden;
}
.entry-cover img {
width: 100%;
height: 100%;
object-fit: cover;
}
.post-content {
color: var(--color-paper-content);
margin: 30px 0;
}
.md-content h1 {
margin: 40px auto 32px;
font-size: 40px;
color: var(--color-paper-primary);
letter-spacing: -0.01em;
}
.md-content h2 {
margin: 32px auto 24px;
font-size: 32px;
color: var(--color-paper-primary);
letter-spacing: -0.01em;
}
.md-content h3 {
margin: 24px 0 16px;
font-size: 24px;
color: var(--color-paper-primary);
}
.md-content h4 {
margin: 24px 0 16px;
font-size: 16px;
color: var(--color-paper-primary);
}
.md-content h5 {
margin: 24px 0 16px;
font-size: 14px;
color: var(--color-paper-primary);
}
.md-content h6 {
margin: 24px 0 16px;
font-size: 12px;
color: var(--color-paper-primary);
}
.md-content a:not(.anchor) {
text-underline-offset: 0.3rem;
text-decoration: underline;
color: var(--color-paper-accent);
}
.md-content a:not(.anchor):hover {
color: var(--color-paper-accent-2);
}
.md-content p {
margin-bottom: var(--content-gap-paper);
line-height: 1.85;
}
.md-content p:last-child {
margin-bottom: 0;
}
.md-content blockquote {
margin: 1rem 0;
padding-inline-start: 1rem;
border-inline-start: 0.3rem solid var(--color-paper-content);
color: var(--color-paper-secondary);
}
.md-content blockquote p:last-child {
margin-bottom: 0;
}
.md-content ol,
.md-content ul {
padding-inline-start: 1.25rem;
margin-bottom: var(--content-gap-paper);
}
/* Tailwind Preflight 把 list-style 清成 none,这里恢复被清掉的 marker。
* 任务列表项(含 checkbox 的 li另有规则覆盖为 none不受影响。 */
.md-content ul {
list-style-type: disc;
}
.md-content ol {
list-style-type: decimal;
}
.md-content li {
margin-top: 0.3rem;
}
.md-content li p {
margin-bottom: 0;
}
/* 任务列表pulldown-cmark 把 - [ ] / - [x] 渲染成裸 <li><input type="checkbox">…
* (无 <label> 包裹,也无 data-type 标记)。用 :has() 识别含 checkbox 的 li
* 布局成 flex 让复选框与文本对齐;不支持 :has() 的浏览器降级为普通列表,仍可读。 */
.md-content li:has(> input[type="checkbox"]) {
list-style: none;
margin-left: -1.25rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.md-content li > input[type="checkbox"] {
flex-shrink: 0;
width: 1rem;
height: 1rem;
margin: 0;
accent-color: var(--color-paper-accent);
cursor: default;
}
.md-content hr {
margin: 30px 0;
height: 2px;
background: var(--color-paper-tertiary);
border: 0;
}
.md-content table {
margin-bottom: var(--content-gap-paper);
width: 100%;
border-collapse: separate;
border-spacing: 0;
border-radius: 16px;
box-shadow: 0 0 0 1px var(--color-paper-border);
}
.md-content table thead th {
background: var(--color-paper-code-block);
font-weight: 600;
color: var(--color-paper-primary);
padding: 16px 24px;
text-align: left;
border-bottom: 1px solid var(--color-paper-border);
white-space: nowrap;
}
.md-content table thead th:first-child {
border-top-left-radius: 16px;
}
.md-content table thead th:last-child {
border-top-right-radius: 16px;
}
.md-content table tbody tr:last-child td:first-child {
border-bottom-left-radius: 16px;
}
.md-content table tbody tr:last-child td:last-child {
border-bottom-right-radius: 16px;
}
.md-content table tbody td {
padding: 16px 24px;
line-height: 1.6;
border-bottom: 1px solid var(--color-paper-border);
color: var(--color-paper-secondary);
}
.md-content table tbody tr:last-child td {
border-bottom: none;
}
.md-content table tbody tr {
transition: background-color 0.2s ease;
}
.md-content table tbody tr:hover {
background: var(--color-paper-entry);
}
.md-content img {
border-radius: var(--radius-paper);
margin: 1rem 0;
max-width: 100%;
height: auto;
}
.dark .md-content img:not(.blur-img-placeholder):not(.blur-img-full),
.dark .md-content .blur-img,
.dark .lightbox-img {
filter: brightness(0.9);
}
.md-content-img-zoomable {
cursor: zoom-in;
transition: opacity 0.2s ease-out;
}
.md-content-img-zoomable:hover {
opacity: 0.9;
}
.md-content iframe {
max-width: 100%;
border-radius: var(--radius-paper);
}
.md-content code {
padding: 0.2rem 0.3rem;
font-size: 0.85em;
line-height: 1.5;
background: var(--color-paper-code-bg);
border-radius: 0.2rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
.md-content pre {
position: relative;
margin-bottom: var(--content-gap-paper);
background: var(--color-paper-code-block);
border-radius: var(--radius-paper);
overflow-x: auto;
}
.md-content pre code {
display: block;
padding: 16px;
background: transparent;
border-radius: 0;
overflow-x: auto;
white-space: pre;
font-size: 0.85em;
line-height: 1.6;
}
.md-content pre code span {
display: inline !important;
}
.copy-code {
display: none;
position: absolute;
top: 8px;
right: 8px;
color: var(--color-paper-theme);
background: var(--color-paper-tertiary);
border-radius: var(--radius-paper);
padding: 4px 8px;
font-size: 12px;
user-select: none;
cursor: pointer;
border: none;
font-family: inherit;
transition: background 0.2s ease-out;
}
.copy-code:hover {
background: var(--color-paper-accent);
}
pre:hover .copy-code,
.highlight:hover .copy-code {
display: block;
}
.anchor {
display: none;
text-decoration: none;
color: var(--color-paper-secondary);
}
.md-content h1:hover .anchor,
.md-content h2:hover .anchor,
.md-content h3:hover .anchor,
.md-content h4:hover .anchor,
.md-content h5:hover .anchor,
.md-content h6:hover .anchor {
display: inline-flex;
margin-inline-start: 0.5em;
font-weight: 500;
user-select: none;
text-decoration: none;
color: var(--color-paper-secondary);
}
.anchor:hover {
color: var(--color-paper-primary) !important;
}
.post-footer {
margin-top: var(--content-gap-paper);
}
.post-tags {
display: flex;
flex-wrap: wrap;
gap: 10px;
list-style: none;
padding: 0;
margin: 0 0 var(--content-gap-paper) 0;
}
.post-tags li {
display: inline-block;
}
.post-tags a {
display: block;
padding: 0 14px;
color: var(--color-paper-secondary);
font-size: 14px;
line-height: 34px;
background: var(--color-paper-code-bg);
border-radius: var(--radius-paper);
border: 1px solid var(--color-paper-border);
text-decoration: none;
transition: all 0.2s ease-out;
}
.post-tags a:hover {
background: var(--color-paper-accent-soft);
border-color: var(--color-paper-accent);
color: var(--color-paper-accent);
}
.paginav {
display: flex;
border-radius: var(--radius-paper);
background: var(--color-paper-code-bg);
border: 1px solid var(--color-paper-border);
overflow: hidden;
}
.paginav a {
width: 50%;
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.8rem;
text-decoration: none;
color: var(--color-paper-primary);
transition: background 0.2s ease-out;
}
.paginav a:hover {
background: var(--color-paper-border);
}
.paginav .next {
margin-inline-start: auto;
text-align: right;
}
.paginav .title {
letter-spacing: 1px;
font-size: 0.8rem;
color: var(--color-paper-secondary);
}
.paginav .post-title-nav {
font-size: 16px;
font-weight: 500;
}
.back-to-home {
margin-top: calc(var(--content-gap-paper) * 1.5);
padding-top: var(--content-gap-paper);
border-top: 1px solid var(--color-paper-border);
}
.back-to-home a,
.back-to-home button {
color: var(--color-paper-secondary);
font-size: 14px;
text-decoration: none;
background: none;
border: none;
cursor: pointer;
padding: 0;
font-family: inherit;
}
.back-to-home a:hover,
.back-to-home button:hover {
color: var(--color-paper-primary);
text-decoration: underline;
text-underline-offset: 0.3rem;
}
/* 卡片封面blur-img 结构,固定 21:9 比例hover 缩放。
双类选择器提升特异性,可靠覆盖 .blur-img 的 aspect-ratio: var(--ar)
(卡片不写 --arvar(--ar) 解析为空会导致高度塌陷)。
21:9 与后台编辑器封面区统一比例,宽屏横幅式。 */
.blur-img.post-card-cover-blur {
margin: 0;
aspect-ratio: 21 / 9;
}
.post-card-cover-blur img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease-out;
}
.group:hover .post-card-cover-blur img {
transform: scale(1.05);
}
a.accent-link {
color: var(--color-paper-accent);
text-decoration: none;
transition: color 0.2s ease-out;
}
a.accent-link:hover {
color: var(--color-paper-primary);
}
.post-card-accent {
position: relative;
}
.post-card-accent::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: var(--color-paper-accent);
transition: width 0.3s ease-out;
}
.post-card-accent:hover::after {
width: 100%;
}
/* ========== Blur-up 渐进图片加载 ==========
放在 @layer components 内,与 .blur-img.post-card-cover-blur 同层,
这样特异性能正常生效layer 外规则会无条件覆盖 layer 内规则,
导致卡片的 aspect-ratio:4/3 败给全局 var(--ar))。 */
.blur-img {
position: relative;
display: block;
overflow: hidden;
aspect-ratio: var(--ar);
/* 加载中灰底(占位图未加载完时) */
background: var(--color-paper-code-bg);
border-radius: 6px;
margin: 1em 0;
}
.blur-img-placeholder {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
/* 重置 .md-content img 的 margin/max-width/height避免把 absolute 图层推偏 */
margin: 0;
max-width: none;
/* 20px 占位图放大后模糊scale 遮边缘 */
filter: blur(20px) saturate(1.2);
transform: scale(1.1);
transition: opacity 0.4s ease;
}
.blur-img-full {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
/* 重置 .md-content img 的 margin/max-width/height避免把 absolute 图层推偏 */
margin: 0;
max-width: none;
opacity: 0;
z-index: 1;
}
/* full 加载完成后由 JS 直接设 opacity:1不依赖 CSS transition
避免合成层重绘时机导致 opacity 卡在 0。 */
.blur-img-full.is-loaded,
.blur-img.is-loaded .blur-img-full {
opacity: 1;
}
/* 容器标记 loaded 后:显式隐藏占位图 + 去掉灰底,避免重绘时机导致残留/灰边 */
.blur-img.is-loaded .blur-img-placeholder {
opacity: 0;
}
.blur-img.is-loaded {
background: transparent;
}
/* ========== 主题切换图标进入动画 ==========
点击切换主题时 theme.set 立即换 SVG配合 RSX 的 key 强制重挂载),
该动画为新挂载的图标播放一次缩放+淡入,给用户即时反馈。
仅作用于 .theme-toggle 内的 svg不影响页面其它 svg。 */
.theme-toggle svg {
animation: theme-icon-enter 0.3s ease-out;
}
@keyframes theme-icon-enter {
from {
opacity: 0;
transform: scale(0.5) rotate(-60deg);
}
to {
opacity: 1;
transform: scale(1) rotate(0deg);
}
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@media screen and (max-width: 768px) {
.post-title {
font-size: 32px;
}
.md-content h1 {
font-size: 32px;
}
.md-content h2 {
font-size: 26px;
}
.md-content h3 {
font-size: 20px;
}
.paginav {
flex-direction: column;
}
.paginav a {
width: 100%;
}
.paginav .next {
margin-inline-start: 0;
text-align: left;
border-top: 1px solid var(--color-paper-border);
}
details.toc .inner {
margin: 0 1rem;
}
}
@keyframes pageEnter {
from {
opacity: 0;
transform: translateY(6px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.page-enter {
animation: pageEnter 0.15s ease-out;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
details::details-content {
transition: none;
}
.page-enter {
animation: none;
}
.theme-toggle svg {
animation: none;
}
}
/* ========== Blur-up 渐进图片加载(已移入 @layer components ========== */
@source "./src/**/*.{rs,html}";