@charset "UTF-8";
/* /assets/css/custom.css */
/* @font-face declarations live in font-chunks.css, generated by
   scripts/build-font-chunks.py and linked separately from custom_head.html.
   Declaring the whole face here pulled 8.25 MB on every page. */
body {
  /* 覆蓋字體 */
  --font-primary: 'HuWenMingChaoTi', Verdana, sans-serif;
  /* 新增：覆蓋主要字體大小 (原默認為 1em) */
  /* 可以試試 1.1em, 1.15em, 1.2em 或 17px, 18px 等 */
  --font-size-primary: 1.15em;
  /* 將這行的值調整到你滿意的大小 */ }

/* center any element with .center-image */
.center-image {
  display: block;
  margin: 0 auto; }

img.img-narrow {
  width: 100%;
  max-width: 420px;
  display: block;
  margin: 1.5rem auto; }

.dictation-blank {
  display: inline-block;
  width: var(--dictation-blank-ch, 12ch);
  max-width: 42vw;
  height: 0.95em;
  border-bottom: 0.08em solid currentColor;
  margin: 0 0.08em;
  vertical-align: -0.08em; }

@media (max-width: 480px) {
  .dictation-blank {
    max-width: 34vw; } }

/* 避免日期換行 */
ul.blog-posts li span:first-child {
  white-space: nowrap;
  /* 一行到底 */ }

/* 若仍擠不下，再酌量放寬固定寬度 */
@media (min-width: 640px) {
  ul.blog-posts li span:first-child {
    flex: 0 0 140px; } }

/* ⬇︎手機寬度時，給日期和標題之間加間距 */
@media (max-width: 639px) {
  ul.blog-posts li span:first-child {
    margin-right: 0.5em;
    /* 想大一點就調數值 */ } }

/* 可選：若需調整標題大小，可參考以下示例
   h1 { font-size: 2.2rem; }
   h2 { font-size: 1.8rem; }
*/
/* === Image Lightbox (Click to expand) === */
img:not(.no-zoom) {
  cursor: zoom-in;
  transition: transform 0.2s ease, box-shadow 0.2s ease; }

/* Subtle hover hint (desktop only) */
@media (hover: hover) {
  img:not(.no-zoom):hover {
    transform: scale(1.02);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } }

img.no-zoom {
  cursor: default; }

/* Lightbox overlay */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.9);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
  cursor: zoom-out;
  padding: 20px;
  box-sizing: border-box; }

.lightbox-overlay.active {
  opacity: 1;
  visibility: visible; }

.lightbox-overlay img {
  max-width: 95vw;
  max-height: 95vh;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  transform: scale(0.9);
  transition: transform 0.3s ease;
  cursor: default; }

.lightbox-overlay.active img {
  transform: scale(1); }

/* Close hint */
.lightbox-close {
  position: absolute;
  top: 20px;
  right: 24px;
  color: #fff;
  font-size: 32px;
  font-weight: 300;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s ease;
  line-height: 1; }

.lightbox-close:hover {
  opacity: 1; }

/* === Kawaii Peeking Cat (Back-to-top) === */
.kawaii-cat {
  --cat-body: #6f747c;
  --cat-shadow: #5a5f67;
  --cat-stripe: #3e434b;
  --cat-ear: #f4bcb6;
  --cat-nose: #f2a59a;
  --cat-eye: #30353c;
  --tail-duration: 1.8s;
  position: fixed;
  left: 16px;
  bottom: 14px;
  width: 96px;
  height: 78px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px) scale(0.96);
  transition: opacity 0.24s ease, transform 0.24s ease;
  pointer-events: none;
  z-index: 1000; }

.kawaii-cat.show {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto; }

@media (max-width: 640px) {
  .kawaii-cat {
    left: 10px;
    bottom: 10px;
    width: 88px;
    height: 72px; } }

.kawaii-cat .cat-shell {
  position: relative;
  width: 100%;
  height: 100%;
  font-size: 1px;
  filter: drop-shadow(0 4px 7px rgba(0, 0, 0, 0.18)); }

.kawaii-cat .cat-shell * {
  position: absolute;
  box-sizing: border-box; }

.kawaii-cat .tail {
  right: 10em;
  bottom: 18em;
  width: 18em;
  height: 40em;
  border-radius: 10em 10em 8em 8em;
  border: 1px solid rgba(38, 42, 49, 0.35);
  background: linear-gradient(to bottom, var(--cat-body) 0 7em, var(--cat-stripe) 7em 12em, var(--cat-body) 12em 18em, var(--cat-stripe) 18em 23em, var(--cat-body) 23em 29em, var(--cat-stripe) 29em 34em, var(--cat-body) 34em 100%);
  transform-origin: 50% 94%;
  transform: rotate(10deg);
  box-shadow: inset 0 -2em 0 rgba(0, 0, 0, 0.12);
  animation: tailWag var(--tail-duration) ease-in-out infinite; }

.kawaii-cat .tail::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(to right, rgba(255, 255, 255, 0.12), transparent 48%); }

.kawaii-cat .body {
  left: 50%;
  bottom: 10em;
  width: 66em;
  height: 30em;
  transform: translateX(-50%);
  border-radius: 48% 48% 40% 40% / 75% 75% 35% 35%;
  border: 1px solid rgba(38, 42, 49, 0.35);
  background: linear-gradient(180deg, #7b8089 0%, var(--cat-body) 72%);
  box-shadow: 0 4em 8em rgba(0, 0, 0, 0.16); }

.kawaii-cat .ear {
  top: -7em;
  width: 17em;
  height: 17em;
  border-radius: 48% 48% 20% 20%;
  border: 1px solid rgba(38, 42, 49, 0.35);
  background: var(--cat-body); }

.kawaii-cat .ear::after {
  content: '';
  top: 4em;
  left: 3em;
  width: 10em;
  height: 9em;
  border-radius: 50%;
  background: var(--cat-ear); }

.kawaii-cat .ear-l {
  left: 9em;
  transform: rotate(-10deg); }

.kawaii-cat .ear-r {
  right: 9em;
  transform: rotate(10deg); }

.kawaii-cat .stripe {
  top: 2em;
  width: 4em;
  height: 10em;
  border-radius: 3em;
  background: var(--cat-stripe);
  opacity: 0.88; }

.kawaii-cat .stripe-l {
  left: 25em;
  transform: rotate(-12deg); }

.kawaii-cat .stripe-c {
  left: 31em; }

.kawaii-cat .stripe-r {
  left: 37em;
  transform: rotate(12deg); }

.kawaii-cat .eye {
  top: 14em;
  width: 6.8em;
  height: 6.8em;
  border-radius: 50%;
  background: var(--cat-eye);
  transition: transform 0.14s ease; }

.kawaii-cat .eye::after {
  content: '';
  top: 1.2em;
  left: 1.4em;
  width: 1.8em;
  height: 1.8em;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.7);
  transition: opacity 0.12s ease; }

.kawaii-cat .eye-l {
  left: 19em; }

.kawaii-cat .eye-r {
  right: 19em; }

.kawaii-cat .nose {
  top: 20em;
  left: 50%;
  width: 7em;
  height: 4.5em;
  transform: translateX(-50%);
  border-radius: 50% 50% 65% 65%;
  background: var(--cat-nose); }

.kawaii-cat .paw {
  bottom: -8em;
  width: 22em;
  height: 14em;
  border-radius: 48% 48% 40% 40%;
  border: 1px solid rgba(38, 42, 49, 0.35);
  background: var(--cat-shadow);
  box-shadow: inset 0 -2em 0 rgba(0, 0, 0, 0.12); }

.kawaii-cat .paw::after {
  content: '';
  left: 4.5em;
  right: 4.5em;
  top: 8em;
  height: 1.1em;
  border-radius: 1em;
  background: rgba(47, 52, 60, 0.65); }

.kawaii-cat .paw-l {
  left: 4em; }

.kawaii-cat .paw-r {
  right: 4em; }

.kawaii-cat.is-blink .eye,
.kawaii-cat.is-wink-left .eye-l,
.kawaii-cat.is-wink-right .eye-r {
  transform: scaleY(0.14) translateY(7px); }

.kawaii-cat.is-blink .eye::after,
.kawaii-cat.is-wink-left .eye-l::after,
.kawaii-cat.is-wink-right .eye-r::after {
  opacity: 0; }

.kawaii-cat.is-hop {
  animation: catHop 0.32s ease-out; }

.kawaii-cat:focus-visible {
  outline: 2px solid var(--link-color);
  outline-offset: 4px;
  border-radius: 10px; }

@keyframes tailWag {
  0% {
    transform: rotate(9deg); }
  50% {
    transform: rotate(18deg); }
  100% {
    transform: rotate(9deg); } }

@keyframes catHop {
  0% {
    transform: translateY(0) scale(1); }
  45% {
    transform: translateY(-10px) scale(1.03); }
  100% {
    transform: translateY(0) scale(1); } }

@media (prefers-reduced-motion: reduce) {
  .kawaii-cat,
  .kawaii-cat * {
    animation: none !important;
    transition: none !important; } }

@media print {
  .kawaii-cat {
    display: none !important; } }

/* Hairlines and quiet fills for controls. The theme's --img-border-color is
   #f2f2f2 in light mode, which all but vanishes on the #fcfcfc page. */
:root {
  --ui-line: rgba(0, 0, 0, 0.16);
  --ui-fill: rgba(0, 0, 0, 0.045); }

@media (prefers-color-scheme: dark) {
  :root {
    --ui-line: rgba(255, 255, 255, 0.22);
    --ui-fill: rgba(255, 255, 255, 0.08); } }

/* ===== 分頁（layouts/partials/cursor.html）=====
   Prev | numbers or picker | Next. The 1fr side columns pin Prev and Next to
   the two edges, far apart and in the same place on every page.
   Prev and Next are the same size and shape as the page-number chips (2.1em,
   no outline, a fill on hover): the 40px outlined pills they replaced were the
   largest thing on the page. */
.pager {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  font-size: 0.95em; }

.pager__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25em;
  box-sizing: border-box;
  height: 2.1em;
  margin: 0;
  padding: 0 0.6em;
  border-radius: 999px;
  /* Body text, not link blue: the theme's #3273dc is 4.43:1 on this page,
     just short of 4.5. */
  color: var(--body-text-color);
  text-decoration: none;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent; }

/* The negative margins line the labels up with the column edges; only the
   hover fill reaches past them. */
.pager__prev {
  justify-self: start;
  margin-left: -0.6em; }

.pager__next {
  justify-self: end;
  margin-right: -0.6em; }

a.pager__step:hover,
a.pager__step:active {
  text-decoration: none;
  background: var(--ui-fill); }

/* Grey text says "nothing there" without dropping the label below readable
   contrast. */
.pager__step[aria-disabled="true"] {
  color: var(--caption-text-color); }

.pager__pages {
  display: none; }

.pager__jump {
  position: relative;
  justify-self: center; }

.pager__face {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  box-sizing: border-box;
  height: 2.1em;
  padding: 0 0.85em;
  border-radius: 999px;
  background: var(--ui-fill);
  color: var(--bold-text-color);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; }

.pager__face svg {
  color: var(--caption-text-color); }

/* Invisible but real: taps and keyboard focus land on the native select. */
.pager__jump select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  font-size: 16px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none; }

.pager__jump:focus-within .pager__face {
  outline: 2px solid var(--link-color);
  outline-offset: 2px; }

@media (max-width: 360px) {
  .pager {
    gap: 8px; }
  .pager__step {
    padding: 0 0.45em; }
  .pager__face {
    padding: 0 0.7em; } }

@media (min-width: 601px) {
  .pager__jump {
    display: none; }
  .pager__pages {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 2px; }
  .pager__pages a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 2.1em;
    height: 2.1em;
    margin: 0;
    padding: 0 0.35em;
    border-radius: 999px;
    color: var(--body-text-color);
    font-variant-numeric: tabular-nums;
    text-decoration: none; }
  .pager__pages a:hover {
    background: var(--ui-fill); }
  .pager__pages a[aria-current="page"] {
    background: var(--ui-fill);
    color: var(--bold-text-color);
    font-weight: 700; }
  .pager__dots {
    padding: 0 0.15em;
    color: var(--caption-text-color); } }

/* 让图片永不溢出容器 */
.post-content img,
article img {
  max-width: 100%;
  height: auto; }

/* Tag links are no longer emitted anywhere: taxonomies are disabled in
   hugo.toml, showTags is false, and the list template no longer renders a tag
   cloud. The catch-all rules that used to live here matched
   a[href*="/tags/"] -- a *substring* match, so any article link to an external
   URL containing /tags/ would have been silently hidden, and
   :has(> a[href^="/tags/"]) would have hidden the whole surrounding block. */
/* Font is declared at top of file - removed duplicate declaration */
/* 为 TOC 中的嵌套列表（第二级及更深）添加左侧内边距（实现缩进） */
#TableOfContents ul ul {
  padding-left: 20px;
  /* 你可以调整这个值，比如 1.5em 或 25px */ }

/* 可选：为更深层级添加额外缩进 */
/*
  #TableOfContents ul ul ul {
    padding-left: 20px; /* 再增加 20px 缩进 */
/* } */
/* 可选：调整列表项之间的间距 */
#TableOfContents li {
  margin-bottom: 4px;
  /* 调整垂直间距 */ }

/* === Home Manuscript Prototype === */
/* The .home-kawaii-cat / .home-directory-stage / .manu-token rules that lived
   here were dead: their script (static/js/home-manuscript.js) was referenced
   nowhere and none of those classes appeared in any built page. The .home-shell
   rules below are live -- they style the /posts/ hero. The back-to-top cat is
   .kawaii-cat, further up; do not confuse the two. */
.home-shell {
  position: relative;
  display: grid;
  gap: 30px;
  padding-bottom: 24px; }

/* /posts/ 列表頁：頭像與題詞先呈現，再自動隱藏，騰出文章列表。 */
.home-shell--posts {
  overflow: hidden;
  transform-origin: top center;
  animation: postsHeroReveal 3.2s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  will-change: max-height, opacity; }

@keyframes postsHeroReveal {
  0%,
  60% {
    opacity: 1;
    max-height: 460px;
    padding-bottom: 24px;
    transform: translateY(0); }
  100% {
    opacity: 0;
    max-height: 0;
    padding-bottom: 0;
    transform: translateY(-10px);
    pointer-events: none; } }

/* 偏好減少動態的訪客：直接收起，避免長期阻擋列表。 */
@media (prefers-reduced-motion: reduce) {
  .home-shell--posts {
    animation: none;
    display: none; } }

/* 同一瀏覽工作階段已看過一次、帶著 ?q= 進來、或開始搜尋：不再重播。
   The class is set by the inline script in list.html and by post-search.js. */
.hero-seen .home-shell--posts {
  display: none; }

.home-shell__hero {
  display: grid;
  justify-items: center;
  gap: 18px;
  text-align: center;
  padding: 10px 0 0; }

.home-shell__portrait-wrap {
  width: 24vw;
  min-width: 116px;
  max-width: 168px; }

.home-shell__portrait {
  width: 100%;
  border: 0;
  border-radius: 999px;
  box-shadow: 0 18px 34px rgba(88, 67, 39, 0.14); }

.home-shell__intro {
  display: grid;
  gap: 0.3rem;
  justify-items: center; }

.home-shell__intro-line {
  margin: 0;
  font-size: clamp(1.02rem, 2.05vw, 1.22rem);
  line-height: 1.72;
  letter-spacing: 0.04em; }

.home-shell__intro-line--final {
  font-size: clamp(1.18rem, 2.4vw, 1.5rem);
  letter-spacing: 0.18em; }

@keyframes homeTailWag {
  0% {
    transform: rotate(7deg); }
  50% {
    transform: rotate(18deg); }
  100% {
    transform: rotate(7deg); } }

@keyframes homeCatBoop {
  0% {
    transform: translateY(0) scale(1); }
  36% {
    transform: translateY(-5px) scale(1.045, 0.96); }
  62% {
    transform: translateY(1px) scale(0.982, 1.02); }
  100% {
    transform: translateY(0) scale(1); } }

@keyframes homeCatStretch {
  0% {
    transform: translateY(0) scale(1); }
  35% {
    transform: translateY(1px) scale(1.04, 0.97); }
  68% {
    transform: translateY(0) scale(1.02, 0.985); }
  100% {
    transform: translateY(0) scale(1); } }

@keyframes homeCatRoll {
  0% {
    transform: rotate(0deg) translateY(0) scale(1); }
  28% {
    transform: rotate(-8deg) translateY(1px) scale(1.02, 0.99); }
  62% {
    transform: rotate(-13deg) translateY(2px) scale(1.035, 0.972); }
  100% {
    transform: rotate(0deg) translateY(0) scale(1); } }

@keyframes homeCatPeek {
  0% {
    transform: rotate(0deg) translateY(0) scale(1); }
  40% {
    transform: rotate(5deg) translateY(-1px) scale(1.01); }
  100% {
    transform: rotate(0deg) translateY(0) scale(1); } }

@media (max-width: 760px) {
  .home-shell {
    gap: 20px; }
  .home-shell__portrait-wrap {
    width: 34vw;
    max-width: 148px; }
  .home-shell__intro-line {
    max-width: 18em; }
  .home-shell__intro-line--final {
    letter-spacing: 0.12em; } }

/* ===== 媒體與附件嵌入（render-link hook）===== */
.media-embed {
  margin: 1.4em 0; }

.media-embed__cap {
  margin-top: 0.4em;
  text-align: center;
  font-size: var(--font-size-secondary);
  color: var(--caption-text-color); }

.media-embed__cap a {
  color: inherit; }

.media-audio__player {
  display: block;
  width: 100%; }

.media-video__player {
  display: block;
  width: 100%;
  max-height: 70vh;
  background: #000;
  border-radius: 8px; }

.media-pdf__frame,
.media-text__frame,
.media-doc__frame {
  width: 100%;
  border: 1px solid var(--img-border-color);
  border-radius: 8px;
  background: var(--body-bg-color); }

.media-pdf__frame {
  height: 80vh; }

.media-text__frame {
  height: 360px; }

.media-doc__frame {
  height: 70vh;
  margin-top: 0.6em; }

.media-image__img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
  border: 1px solid var(--img-border-color);
  border-radius: 6px; }

.attachment-card {
  display: flex;
  align-items: center;
  gap: 0.6em;
  margin: 1.4em 0;
  padding: 0.7em 0.9em;
  border: 1px solid var(--img-border-color);
  border-radius: 10px;
  background: var(--code-bg-color); }

.attachment-card__icon {
  font-size: 1.4em;
  line-height: 1; }

.attachment-card__name {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere; }

.attachment-card__ext {
  flex: none;
  padding: 0.15em 0.5em;
  border-radius: 6px;
  font-family: var(--font-secondary);
  font-size: 0.72em;
  background: var(--table-th-bg-color);
  color: var(--bold-text-color); }

.attachment-card__dl {
  flex: none;
  white-space: nowrap;
  font-size: var(--font-size-secondary); }

.media-doc {
  margin: 1.4em 0; }

.media-doc .attachment-card {
  margin: 0; }

.media-doc__preview {
  margin-top: 0.5em; }

.media-doc__preview > summary {
  cursor: pointer;
  user-select: none;
  font-size: var(--font-size-secondary);
  color: var(--link-color); }

/* ===== 本地搜尋（list.html + assets/js/post-search.js）===== */
/* A quiet filled field, the height of one list row and a half, instead of
   the 44px outlined pill that outweighed everything else on the page. */
.gsearch {
  display: flex;
  margin: 12px 0 0; }

.gsearch__box {
  position: relative;
  display: flex;
  flex: 1;
  align-items: center;
  min-width: 0; }

.gsearch__icon {
  position: absolute;
  left: 12px;
  color: var(--caption-text-color);
  pointer-events: none; }

.gsearch #q {
  flex: 1;
  min-width: 0;
  box-sizing: border-box;
  height: 38px;
  /* 16px keeps iOS from zooming the page on focus. */
  font: inherit;
  font-size: 16px;
  line-height: 1.25;
  padding: 0 36px 0 36px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: var(--ui-fill);
  color: var(--body-text-color);
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease, background-color 0.15s ease; }

.gsearch #q::placeholder {
  color: var(--caption-text-color);
  opacity: 1; }

.gsearch #q:hover {
  border-color: var(--ui-line); }

.gsearch #q:focus {
  outline: none;
  border-color: var(--link-color);
  background: var(--body-bg-color); }

.gsearch #q::-webkit-search-cancel-button {
  display: none; }

.gsearch #clearbtn {
  position: absolute;
  right: 4px;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--caption-text-color);
  font-size: 18px;
  line-height: 1;
  cursor: pointer; }

.gsearch #clearbtn:hover {
  color: var(--bold-text-color); }

#search-stats {
  margin: 6px 0;
  min-height: 1.2em;
  font-size: var(--font-size-secondary);
  color: var(--caption-text-color); }

#search-stats:empty {
  margin: 0;
  min-height: 0; }

#clearbtn[hidden],
#default-list[hidden],
#pagination-wrapper[hidden] {
  display: none !important; }

ul.search-posts {
  list-style: none;
  padding: 0;
  margin: 0; }

ul.search-posts:empty {
  display: none; }

ul.search-posts li {
  margin: 0 0 1.1em; }

ul.search-posts .hit-title {
  font-weight: bold; }

ul.search-posts .hit-title:visited {
  color: var(--link-visited-color); }

ul.search-posts .hit-meta {
  font-size: var(--font-size-secondary);
  color: var(--caption-text-color); }

ul.search-posts .excerpt {
  font-size: 0.92em;
  line-height: 1.65; }

ul.search-posts mark {
  padding: 0 0.1em;
  border-radius: 2px;
  background: rgba(255, 213, 74, 0.55);
  color: inherit; }

@media (prefers-color-scheme: dark) {
  ul.search-posts mark {
    background: rgba(255, 196, 0, 0.32); } }

ul.search-posts .search-more button {
  font: inherit;
  font-size: var(--font-size-secondary);
  padding: 0.4em 1em;
  border: 1px solid var(--img-border-color);
  border-radius: 999px;
  background: transparent;
  color: var(--link-color);
  cursor: pointer; }

/* ===== /posts/ 列表頁：一屏放下全部 =====
   頭像收起之後，標題、搜尋、文章列表、分頁與頁腳（含訪客 IP）同在一屏；
   每頁文章列表由 js/posts-fit.js 收緊到窗格放得下，整頁與列表都不捲動；
   只有搜尋結果在窗格裡捲動。
   The pane spans the whole window width so a wheel or swipe beside the 720px
   column still scrolls it; the column itself is re-centred child by child.
   Windows too short for this (landscape phones) keep the ordinary page, and
   so do browsers without :has(). */
@media (min-height: 520px) {
  /* Only the pane scrolls. Without this the page itself could still be
     dragged: while the portrait was open it pushed the column past the
     window, and on iOS the document rubber-banded under any drag that
     started outside the pane. */
  html:has(#posts-pane) {
    height: 100%;
    overflow: hidden;
    overscroll-behavior: none; }
  body:has(#posts-pane) {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    max-width: none;
    height: 100vh;
    height: 100dvh;
    padding: 0;
    overflow: hidden; }
  body:has(#posts-pane) > header,
  body:has(#posts-pane) > footer,
  body:has(#posts-pane) .home-shell--posts,
  .posts-index > :not(#posts-pane),
  #posts-pane > ul.blog-posts,
  #posts-pane > ul.search-posts {
    box-sizing: border-box;
    width: 100%;
    max-width: var(--width-max);
    margin-left: auto;
    margin-right: auto;
    padding-left: 20px;
    padding-right: 20px; }
  body:has(#posts-pane) > header {
    flex: none;
    padding-top: 20px; }
  body:has(#posts-pane) > main {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%; }
  /* On a short phone the portrait gives up height, not the pagination and
     footer below it. */
  body:has(#posts-pane) .home-shell--posts {
    flex: 0 1 auto;
    min-height: 0; }
  .posts-index {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    min-height: 0; }
  .posts-index > * {
    flex: none; }
  #posts-pane {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch; }
  /* js/posts-fit.js closes up the rows (--fit-lh) and then shrinks the type
     (--fit-scale) until the whole page of posts fits the pane; once it does,
     data-fit takes the pane's scroll away. Search results, which can run to
     hundreds, keep the scroll: the list is hidden while they show. The year
     heading's margins are in em so they shrink with the rows. */
  #posts-pane > ul.blog-posts {
    margin-top: 0;
    margin-bottom: 0;
    font-size: calc(var(--fit-scale, 1) * 1em);
    line-height: var(--fit-lh, 1.5); }
  /* The theme sets dates at a fixed 15px, which held every row at 18px
     however small the titles went. */
  #posts-pane > ul.blog-posts time {
    font-size: calc(var(--fit-scale, 1) * 15px); }
  #posts-pane > ul.blog-posts > h3 {
    margin: 0.4em 0 0.35em; }
  #posts-pane > ul.blog-posts > h3:not(:first-child) {
    margin-top: 0.75em; }
  #posts-pane[data-fit]:has(> ul.blog-posts:not([hidden])) {
    overflow: hidden; }
  /* The bottom gap keeps Next clear of the nav.bdfz.net logo that floats
     over the bottom-right corner on phones. */
  #pagination-wrapper {
    padding-top: 10px;
    padding-bottom: 10px;
    border-top: 1px solid var(--ui-line); }
  body:has(#posts-pane) > footer {
    flex: none;
    padding-top: 10px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); } }

/* The footer now stays on screen, and on a phone the site-nav logo (fixed,
   bottom right, from nav.bdfz.net) would sit on top of its last line. */
@media (min-height: 520px) and (max-width: 600px) {
  body:has(#posts-pane) > footer {
    padding-left: 64px;
    padding-right: 64px; } }

/* A laptop-height window (720-860px) left the 20 rows about 420px under a
   135px header and a two-line footer, so they shrank to small type. Here the
   title and the menu share a row, as they do on phones, and the footer is one
   line; that gives the list about 90px back. Phones are not touched: their
   header is already one row and the pager's bottom gap is for the nav logo. */
@media (min-height: 520px) and (max-height: 860px) and (min-width: 601px) {
  body:has(#posts-pane) > header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0 16px;
    padding-top: 12px; }
  body:has(#posts-pane) > header .title h1 {
    margin: 0; }
  body:has(#posts-pane) > header nav a {
    margin: 0 0 0 14px; }
  #pagination-wrapper {
    padding-top: 6px;
    padding-bottom: 6px; }
  body:has(#posts-pane) > footer {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 0 0.9em;
    padding-top: 6px;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); } }

/* ===== 頁腳 ===== */
footer .footer-line {
  margin: 0; }

footer .footer-visitor {
  min-height: 1.5em;
  font-size: 0.85em;
  opacity: 0.65; }

#visitor-ipcity + #visitor-orghost::before {
  content: " · "; }

/* ===== 文章預覽卡（render-link.html / partials/post-embed.html）===== */
.post-embed {
  margin: 1em 0;
  padding: 0.8em 1em 0.7em;
  border: 1px solid var(--img-border-color);
  border-left: 3px solid var(--link-color);
  border-radius: 8px;
  color: var(--body-text-color);
  font-style: normal; }

/* A bare URL line is a paragraph; the card closes it and leaves empty <p>s. */
p:empty:has(+ .post-embed),
.post-embed + p:empty {
  display: none; }

blockquote > .post-embed {
  margin: 0.4em 0; }

/* A quote holding nothing but the card: the card's own border is enough. */
blockquote:has(> .post-embed):not(:has(> p:not(:empty))) {
  border-left: 0;
  padding-left: 0; }

.post-embed__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.2em 1em; }

.post-embed__title {
  font-weight: bold;
  font-size: 1.05em; }

.post-embed__date {
  font-family: var(--font-secondary);
  font-size: var(--font-size-secondary);
  color: var(--caption-text-color);
  white-space: nowrap; }

.post-embed__excerpt {
  margin: 0.45em 0 0;
  font-size: 0.93em;
  line-height: 1.7; }

.post-embed__body {
  margin-top: 0.6em;
  padding-top: 0.2em;
  border-top: 1px dashed var(--img-border-color); }

.post-embed__actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1em;
  margin-top: 0.5em;
  font-size: var(--font-size-secondary); }

.post-embed__toggle {
  font: inherit;
  padding: 0.25em 0.9em;
  border: 1px solid var(--img-border-color);
  border-radius: 999px;
  background: transparent;
  color: var(--link-color);
  cursor: pointer; }

.post-embed__toggle[hidden],
.post-embed__excerpt[hidden],
.post-embed__body[hidden] {
  display: none; }

.post-embed.is-open {
  border-left-color: var(--caption-text-color); }

/* ===== 手機版面 ===== */
/* Embedded players (YouTube's copy-paste code says width="560") and wide
   tables pushed ten posts sideways on a 375px phone. */
content iframe {
  max-width: 100%; }

content iframe[src*="youtube.com/embed"],
content iframe[src*="youtube-nocookie.com/embed"],
content iframe[src*="player.bilibili.com"] {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9; }

@media (max-width: 600px) {
  /* Title and menu share one row: about 50px more for the list and the
     post, on every page. */
  body > header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0 16px; }
  body > header .title h1 {
    margin: 0;
    font-size: 1.75em; }
  body > header nav a {
    display: inline-block;
    margin: 0 0 0 14px;
    padding: 6px 0; }
  body > main > h1 {
    font-size: 1.55em;
    line-height: 1.35;
    margin: 18px 0 8px; }
  ul.blog-posts .date-year {
    display: none; }
  ul.blog-posts li span.grouped {
    flex-basis: auto; }
  /* Wide tables scroll inside their own box; narrow ones are unchanged
     because the box is only as wide as the table needs. */
  content table {
    display: block;
    width: max-content;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch; }
  /* Once a table scrolls anyway, a many-column one need not squeeze its
     row labels to one character per line. */
  content th,
  content td {
    min-width: 3em; } }
