diff --git a/app/assets/scss/markdown/green.scss b/app/assets/scss/markdown/green.scss index a08ba4f..871f046 100644 --- a/app/assets/scss/markdown/green.scss +++ b/app/assets/scss/markdown/green.scss @@ -1,364 +1,356 @@ @mixin chinese() { - &.chinese { - text-indent: 1.5em; - font-weight: 300; - h1, - h2, - h3, - h4, - h5, - h6, - ol, - ul, - blockquote, - details, - summary, - pre, - .tabs { - text-indent: 0; - } + &.chinese { + text-indent: 1.5em; + font-weight: 300; + + h1, + h2, + h3, + h4, + h5, + h6, + ol, + ul, + blockquote, + details, + summary, + pre, + .tabs { + text-indent: 0; } + } } + .markdown-body { - --color-base: #ef4444; - --markdown-bg: transparent; - --color-bg: #ff47479c; - --color-light: #ef44441a; - --color-extra: rgba(239, 68, 68, 0.3); - --color-more: rgba(239, 68, 68, 0.4); + --color-base: var(--color-accent-fg); + --color-soft-bg: color-mix(in srgb, var(--color-base) 8%, transparent); + --color-softer-bg: color-mix(in srgb, var(--color-base) 4%, transparent); + --markdown-bg: color-mix(in srgb, var(--color-canvas-default) 92%, transparent); + --markdown-shadow: 0 2px 8px rgba(15, 23, 42, 0.08); + --markdown-radius: 10px; + --markdown-padding: 1.6em; +} + +.dark .markdown-body { + --color-fg-default: #e5e7eb; + --color-fg-muted: #c0c7d1; + --color-fg-subtle: #9ca3af; + --color-canvas-default: #111827; + --color-canvas-subtle: #1f2937; + --color-border-default: #374151; + --color-border-muted: #2c3646; + --color-neutral-muted: rgba(148, 163, 184, 0.25); + --color-accent-fg: #60a5fa; + --markdown-bg: color-mix(in srgb, var(--color-canvas-default) 86%, transparent); + --markdown-shadow: 0 10px 28px rgba(2, 6, 23, 0.28); + --code-bg: #0f172a; + --code-head-bg: #172133; + --code-border: #334155; + --code-shadow: rgba(2, 6, 23, 0.45); } .markdown-body.green { - background-color: var(--markdown-bg); - box-shadow: 0 2px 8px rgba(0,0,0,0.1); - border-radius: 10px; - padding: 1.6em; - @media screen and (max-width: 768px) { - padding: 0; - box-shadow: none; - } + background-color: var(--markdown-bg); + border-radius: var(--markdown-radius); + padding: var(--markdown-padding); + box-shadow: var(--markdown-shadow); + border: 1px solid color-mix(in srgb, var(--color-border-default) 72%, transparent); + color: var(--color-fg-default); + font-size: 1rem; + line-height: 1.9; + letter-spacing: 0.01em; - strong { - &::before{ - content: "『"; - } - &::after{ - content: "』"; - } - // color: #ff4d20; - } + @media screen and (max-width: 768px) { + background: transparent; + border: 0; + box-shadow: none; + border-radius: 0; + padding: 0; + font-size: 0.98rem; + line-height: 1.85; + } - /* 块/段落引用 */ - // blockquote { - // position: relative; - // // color: #555; - // font-weight: 400; - // border-left: 6px solid var(--color-base); - // padding-left: 1em; - // margin-left: 0; - // padding: 1em; - // background-color: var(--color-light); - // } - - blockquote { - position: relative; - z-index: 600; - padding: 20px 20px 15px 20px; - line-height: 1.4 !important; - background-color: rgba(239, 68, 68, 0.06); - border-radius: .4em; - > * { - position: relative; - &:first-child:before { - content: '\201C'; - color: var(--color-light); - font-size: 6.5em; - font-weight: 700; - transform: rotate(15deg) translateX(-10px); - opacity: 1; - position: absolute; - top: -.4em; - left: -.2em; - text-shadow: none; - z-index: -10; - } - } - } + p { + color: var(--color-fg-default); + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin-top: 1.35em; + margin-bottom: 0.65em; + line-height: 1.35; + color: var(--color-fg-default); + scroll-margin-top: 5rem; + } + + h1 { + font-size: 2em; + } + + h2 { + font-size: 1.65em; + padding-bottom: 0.25em; + border-bottom: 1px solid var(--color-border-muted); + } + + h3 { + font-size: 1.35em; + } - .tabs{ - margin-top: 0; - margin-bottom: 1em; + h4 { + font-size: 1.15em; + } + + a { + color: var(--color-base); + text-decoration: underline; + text-decoration-thickness: 1px; + text-decoration-color: color-mix(in srgb, var(--color-base) 45%, transparent); + text-underline-offset: 0.18em; + transition: color 0.2s ease, text-decoration-color 0.2s ease; + + &:hover { + color: color-mix(in srgb, var(--color-base) 78%, var(--color-fg-default)); + text-decoration-color: currentColor; } + } - /* 让链接在 hover 状态下显示下划线 */ - // a { - // color: var(--color-base); - // text-decoration: none; - // &:hover { - // text-decoration: underline; - // } - // } - a { - position: relative; - z-index: 10; - transition: color 0.3s linear; + blockquote { + margin-left: 0; + padding: 0.95em 1.05em; + border-left: 4px solid var(--color-base); + border-radius: 0.55rem; + background: var(--color-softer-bg); + color: var(--color-fg-muted); + } + + hr { + height: 1px; + margin: 1.6rem 0; + background: var(--color-border-muted); + } + + img { + border-radius: 0.8rem; + border: 1px solid var(--color-border-default); + box-shadow: 0 6px 20px rgba(15, 23, 42, 0.08); + } + + figure { + margin: 1.4em auto; + } + + figcaption { + margin-top: 0.55rem; + font-size: 0.82em; + color: var(--color-fg-subtle); + text-align: center; + } + + :not(pre) > code { + padding: 0.12em 0.48em; + margin: 0 0.12em; + border-radius: 0.4rem; + background: var(--color-soft-bg); + border: 1px solid color-mix(in srgb, var(--color-base) 26%, var(--color-border-default)); + color: color-mix(in srgb, var(--color-base) 72%, var(--color-fg-default)); + font-size: 0.92em; + } + + pre, + pre code { + font-family: "JetBrains Mono", "Fira Code", Consolas, monospace; + } + + .code-block-wrapper { + margin: 1rem 0 1.25rem; + border: 1px solid var(--color-border-default); + border-radius: 0.8rem; + overflow: hidden; + background: var(--color-canvas-subtle); + color: var(--color-fg-default); + box-shadow: 0 4px 14px rgba(15, 23, 42, 0.07); + + .code-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + padding: 0.55rem 0.85rem; + border-bottom: 1px solid var(--color-border-default); + background: color-mix(in srgb, var(--color-base) 7%, var(--color-canvas-subtle)); + + .code-lang { + font-size: 0.76rem; + font-weight: 600; + letter-spacing: 0.05em; + color: var(--color-fg-subtle); + text-transform: uppercase; + } + + .copy-btn { + border: 1px solid var(--color-border-default); + background: var(--color-canvas-default); + color: var(--color-fg-muted); + border-radius: 0.45rem; + padding: 0.2rem 0.58rem; + font-size: 0.74rem; + line-height: 1.35; cursor: pointer; - font-weight: bolder; - // text-decoration: underline #c7254e; - text-decoration: none; - color: var(--color-base); - border-bottom: 1px solid currentColor; - padding: 0 4px; - &[data-footnote-backref], - &[data-footnote-ref] { - // text-decoration: none; - border: none; - &:hover { - background: none; - animation: none; - } - } + transition: all 0.18s ease; + &:hover { - content: ''; - // text-decoration: none; - border: none; - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 4'%3E%3Cpath fill='none' stroke='%23ff4d20' d='M0 3.5c5 0 5-3 10-3s5 3 10 3 5-3 10-3 5 3 10 3'/%3E%3C/svg%3E") - repeat-x 0 100%; - background-size: 20px auto; - animation: waveMove 1s infinite linear; + border-color: var(--color-base); + color: var(--color-base); } - @keyframes waveMove { - 0% { - background-position: 0 100%; - } - 100% { - background-position: -20px 100%; - } + + &.is-copied { + border-color: #22c55e; + color: #16a34a; + background: color-mix(in srgb, #22c55e 12%, var(--color-canvas-default)); } + } } pre { - background: #f7f7f7; - font-size: 0.95em; - // /* border: 1px solid #ddd; */ - // padding: 1em 1.5em; - display: block; - -webkit-overflow-scrolling: touch; + margin: 0; + padding: 1.05rem 1.1rem; + overflow-x: auto; + background: transparent; + box-shadow: none; } + } - pre, - pre code { - font-family: "JetBrains Mono", "Fira Code", Consolas, monospace; + table { + width: max-content; + min-width: 0; + display: block; + max-width: 100%; + overflow-x: auto; + margin: 1.2rem 0; + border: 1px solid color-mix(in srgb, var(--color-border-default) 88%, transparent); + border-radius: 0.8rem; + border-collapse: separate; + border-spacing: 0; + background: color-mix(in srgb, var(--color-canvas-default) 94%, transparent); + box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08); + + caption { + padding: 0.62em 0.95em; + text-align: left; + color: var(--color-fg-subtle); + border-bottom: 1px solid color-mix(in srgb, var(--color-border-default) 84%, transparent); + background: color-mix(in srgb, var(--color-canvas-subtle) 80%, transparent); } - // /* 底部印刷体、版本等标记 */ - small, - /* 图片说明 */ - figcaption { - font-size: 0.75em; - color: #888; + thead th { + font-weight: 600; + color: var(--color-fg-default); + background: color-mix(in srgb, var(--color-base) 12%, var(--color-canvas-default)); + border-bottom: 1px solid color-mix(in srgb, var(--color-border-default) 86%, transparent); } - // .markdown-body { - legend { - color: #000; - font-weight: inherit; + + th, + td { + padding: 0.62em 0.95em; + white-space: nowrap; + border-right: 1px solid color-mix(in srgb, var(--color-border-default) 82%, transparent); + border-bottom: 1px solid color-mix(in srgb, var(--color-border-default) 82%, transparent); } - caption { - color: #000; - font-weight: inherit; + + th:last-child, + td:last-child { + border-right: 0; } - del { - text-decoration: line-through var(--color-base) 2px; + + tbody tr:last-child td { + border-bottom: 0; } - /* 行内代码:仅匹配非代码块场景,避免和 pre/code 嵌套互相覆盖 */ - :not(pre) > code { - color: #d73a49; - background-color: rgba(160, 174, 192, 0.25); - font-family: inherit; - font-size: 1em; - border-radius: 4px; - padding: 1px 6px; - margin: 0 2px; - vertical-align: bottom; + + tbody tr:nth-child(even) td { + background: color-mix(in srgb, var(--color-canvas-subtle) 52%, transparent); } - /* MarkdownIt highlight 输出的代码块容器 */ - .code-block-wrapper { - margin: 1rem 0; - border-radius: 10px; - overflow: hidden; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); - background: #f7f7f7; - color: #333; - font-family: "JetBrains Mono", "Fira Code", Consolas, monospace; - font-size: 0.95em; - line-height: 1.5; - - .code-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 0.6rem 1rem; - background: #efefef; - - .code-lang { - font-size: 0.78rem; - font-weight: 600; - letter-spacing: 0.02em; - color: #64748b; - text-transform: uppercase; - } - - .copy-btn { - border: 1px solid #d0d7de; - background: #fff; - color: #475569; - border-radius: 6px; - padding: 0.2rem 0.6rem; - font-size: 0.75rem; - line-height: 1.3; - cursor: pointer; - transition: all 0.18s ease; - - &:hover { - background: #f8fafc; - border-color: #b8c2cc; - color: #334155; - } - - &.is-copied { - background: #dcfce7; - border-color: #86efac; - color: #166534; - } - } - } + tbody tr:hover td { + background: color-mix(in srgb, var(--color-base) 10%, var(--color-canvas-subtle)); + } + } - pre { - margin: 0; - padding: 1.2rem; - overflow-x: auto; - background: transparent; - box-shadow: none; - - code { - display: block; - padding: 0; - margin: 0; - color: inherit; - background: transparent; - border-radius: 0; - white-space: pre; - } + ul.toc li { + list-style-type: none; - } + a { + border: 0; + text-decoration: none; } - table { - width: fit-content; - display: block; - max-width: 100%; - overflow-x: auto; - border: 1px solid var(--color-light); - border-radius: 8px; - border-collapse: separate; - border-spacing: 0; - margin: 1rem 0; - background: #fff; - - caption { - padding: 0.6em 1em; - text-align: left; - color: var(--color-fg-subtle); - border-bottom: 1px solid var(--color-light); - background: #fff; - } + } - thead th { - background: var(--color-extra); - border-bottom: 1px solid var(--color-light); - font-weight: 600; - } + @include chinese; +} - th, - td { - padding: 0.55em 1em; - white-space: nowrap; - border-right: 1px solid var(--color-light); - border-bottom: 1px solid var(--color-light); - } +.dark .markdown-body.green { + .code-block-wrapper { + border-color: var(--code-border); + background: var(--code-bg); + box-shadow: 0 10px 26px var(--code-shadow); - th:last-child, - td:last-child { - border-right: 0; - } + .code-header { + border-bottom-color: var(--code-border); + background: var(--code-head-bg); - tbody tr:last-child td { - border-bottom: 0; + .code-lang { + color: #bfdbfe; + } + + .copy-btn { + border-color: #475569; + background: #1e293b; + color: #cbd5e1; + + &:hover { + border-color: #60a5fa; + background: #0f172a; + color: #93c5fd; } - tbody tr:hover td { - background: var(--color-light); + &.is-copied { + border-color: #22c55e; + color: #86efac; + background: #052e16; } + } } - h1, - h2, - h3, - h4, - h5, - h6 { - margin-top: 1.2em; - margin-bottom: 0.6em; - line-height: 1.35; - position: relative; - } - h1 { - font-size: 1.8em; - } - h2 { - font-size: 1.6em; - } - h3 { - font-size: 1.4em; - } - h4 { - font-size: 1.2em; - } - h5 { - font-size: 1em; + + pre { + background: transparent; } - h6 { - font-size: 1em; + } + + table { + border-color: color-mix(in srgb, var(--color-border-default) 92%, transparent); + background: color-mix(in srgb, var(--color-canvas-default) 90%, transparent); + box-shadow: 0 10px 24px rgba(2, 6, 23, 0.26); + + caption { + background: color-mix(in srgb, var(--color-canvas-subtle) 90%, transparent); + border-bottom-color: color-mix(in srgb, var(--color-border-default) 90%, transparent); } - - ::-webkit-calendar-picker-indicator { - filter: invert(50%); + + thead th { + background: color-mix(in srgb, var(--color-base) 18%, var(--color-canvas-subtle)); } - em { - // color: #000; - font-weight: inherit; - position: relative; - &:after { - position: absolute; - top: 0.65em; - left: 0; - width: 100%; - overflow: hidden; - white-space: nowrap; - pointer-events: none; - color: var(--color-base); - content: '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・'; - } + + tbody tr:nth-child(even) td { + background: color-mix(in srgb, var(--color-canvas-subtle) 70%, transparent); } - ul.toc { - li { - list-style-type: none; - a { - text-decoration: none; - border: 0; - list-style-type: none; - } - } + + tbody tr:hover td { + background: color-mix(in srgb, var(--color-base) 16%, var(--color-canvas-subtle)); } - @include chinese; + } } diff --git a/app/assets/scss/markdown/highlight.scss b/app/assets/scss/markdown/highlight.scss index 7e5a278..8b4081b 100644 --- a/app/assets/scss/markdown/highlight.scss +++ b/app/assets/scss/markdown/highlight.scss @@ -51,3 +51,57 @@ } } } + +.dark .markdown-body { + .code-block-wrapper { + pre { + code.hljs { + color: #e5e7eb; + } + + .hljs-comment, + .hljs-quote { + color: #94a3b8; + font-style: italic; + } + + .hljs-keyword, + .hljs-selector-tag, + .hljs-literal, + .hljs-section, + .hljs-link { + color: #c084fc; + } + + .hljs-string, + .hljs-title, + .hljs-name, + .hljs-type, + .hljs-attribute, + .hljs-symbol, + .hljs-bullet, + .hljs-addition { + color: #5eead4; + } + + .hljs-number, + .hljs-variable, + .hljs-template-variable, + .hljs-regexp, + .hljs-meta .hljs-string { + color: #fbbf24; + } + + .hljs-built_in, + .hljs-function, + .hljs-class .hljs-title { + color: #60a5fa; + } + + .hljs-deletion, + .hljs-subst { + color: #f87171; + } + } + } +} diff --git a/app/pages/@[publicSlug]/posts/[postSlug].vue b/app/pages/@[publicSlug]/posts/[postSlug].vue index c8fbbac..d6a32bf 100644 --- a/app/pages/@[publicSlug]/posts/[postSlug].vue +++ b/app/pages/@[publicSlug]/posts/[postSlug].vue @@ -116,7 +116,7 @@ const editPostHref = computed(() => {{ leadSummary }}
+ 请先识别图片字符再输入,不区分大小写。 +
+ 请先识别图片字符再输入,不区分大小写。 +