@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);
  }

  /* 排除 CodeMirror 编辑器内的 <img>：CM 用 <img class="cm-widgetBuffer">（width:0、
     height:1em 的占位符）对齐折叠 widget 的基线。若被这里的 margin/height 命中，
     会把折叠那行 .cm-line 撑高约 32px（上下各 1rem margin）。用 :where() 把
     .cm-editor 后代的 img 优先级压到 0，确保 CM 内部任何 img 都不受正文图片样式影响。 */
  .md-content img:where(:not(.cm-widgetBuffer)) {
    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)
     （卡片不写 --ar，var(--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}";

/* ========== CodeMirror 代码运行器高度自适应优化 ========== */
.code-runner-editor {
  min-height: 120px;
  max-height: 400px;
  display: flex;
  flex-direction: column;
}
.code-runner-editor .cm-editor {
  flex: 1 1 auto !important;
}
.code-runner-editor .cm-scroller {
  overflow: auto;
}

