/* MOOSSin 部落格 — MOOSSin 殼 + 閱讀優先正文 (2026-09-20)
 *
 * The shell (hero band, cards, buttons, footer) follows the www homepage
 * redesign so the sites read as one place: a deep-space band with CSS star
 * points, moss-green links and buttons, white cards with a 1rem radius and a
 * shadow, and a four-column deep-space footer. Every page opens with the
 * one-row MOOSSin bar shared by all five sections (owner decision
 * 2026-10-05), embedded verbatim at the end of this file. Reading stays the
 * blog's own: the 68ch measure, the reader-adjustable size and line height,
 * the sticky contents column and the code, table and quote treatment are
 * unchanged.
 *
 * Still hand-written, project-original, no framework and no external
 * request: the site sends `style-src 'self'`, so this file has no import
 * rule, no webfont and no external resource reference of any kind. The stars
 * are radial-gradient dots and the planets are gradient circles. Mobile
 * first; every width below is a min-width step up unless a max-width rule
 * says otherwise.
 */

/* moossin-tokens v1 (www portal.css, 2026-09-20)
 *
 * Copied from www `static/portal.css` (ADR-0015). Every site keeps its own
 * copy; when the tokens change, all three sites bump the version together.
 * Measured WCAG contrast on the near-white page: ink 15.75:1, muted 7.67:1,
 * moss 6.19:1, moss-strong 8.67:1, line 3.54:1 (the non-text 3:1 minimum for
 * a card border). On the dark bands white sits only on space-deep (17.80:1)
 * through teal-mid (4.88:1); teal-light is a highlight and never carries
 * text; mint on space-deep 13.91:1; star on space-deep 14.81:1; moss-strong
 * on mint 6.97:1; moss on the light band 5.74:1.
 */
:root {
  color-scheme: light;

  --moossin-page: #fbfcfa;
  --moossin-surface: #f1f4ef;
  --moossin-ink: #1c221d;
  --moossin-muted: #4a544b;
  --moossin-moss: #2f6b3f;
  --moossin-moss-strong: #24532f;
  --moossin-line: #7c8a78;

  --moossin-band: #eef4f6;
  --moossin-space-deep: #0b1730;
  --moossin-space: #12264a;
  --moossin-teal-deep: #1b4d4a;
  --moossin-teal: #23665f;
  --moossin-teal-mid: #2e7d74;
  --moossin-teal-light: #3f9a8b;
  --moossin-mint: #cfe9e2;
  --moossin-star: #ffe9a8;
  --moossin-line-soft: #d5dfe3;

  --moossin-space-1: 0.25rem;
  --moossin-space-2: 0.5rem;
  --moossin-space-3: 1rem;
  --moossin-space-4: 1.5rem;
  --moossin-space-5: 2.5rem;

  --moossin-measure: 38rem;
  --moossin-radius: 0.5rem;
  --moossin-radius-card: 1rem;
  --moossin-shadow: 0 8px 28px rgba(11, 23, 48, 0.12);
  --moossin-gutter: max(var(--moossin-space-3), calc((100% - 64rem) / 2));
  --moossin-stars:
    radial-gradient(1.6px 1.6px at 8% 22%, rgba(255, 255, 255, 0.95) 50%, transparent 52%),
    radial-gradient(1.2px 1.2px at 19% 71%, rgba(255, 255, 255, 0.75) 50%, transparent 52%),
    radial-gradient(2px 2px at 27% 38%, rgba(255, 233, 168, 0.95) 50%, transparent 52%),
    radial-gradient(1px 1px at 36% 12%, rgba(255, 255, 255, 0.8) 50%, transparent 52%),
    radial-gradient(1.4px 1.4px at 44% 64%, rgba(255, 255, 255, 0.7) 50%, transparent 52%),
    radial-gradient(1px 1px at 52% 28%, rgba(255, 255, 255, 0.85) 50%, transparent 52%),
    radial-gradient(2px 2px at 61% 80%, rgba(207, 233, 226, 0.9) 50%, transparent 52%),
    radial-gradient(1.2px 1.2px at 68% 18%, rgba(255, 255, 255, 0.8) 50%, transparent 52%),
    radial-gradient(1.6px 1.6px at 77% 52%, rgba(255, 233, 168, 0.9) 50%, transparent 52%),
    radial-gradient(1px 1px at 84% 30%, rgba(255, 255, 255, 0.75) 50%, transparent 52%),
    radial-gradient(1.4px 1.4px at 91% 70%, rgba(255, 255, 255, 0.85) 50%, transparent 52%),
    radial-gradient(1px 1px at 96% 10%, rgba(255, 255, 255, 0.7) 50%, transparent 52%),
    radial-gradient(1px 1px at 13% 90%, rgba(255, 255, 255, 0.6) 50%, transparent 52%),
    radial-gradient(1.2px 1.2px at 58% 6%, rgba(255, 255, 255, 0.7) 50%, transparent 52%);

  /* Blog aliases (plan §3.3): the older token names point at the shared
   * tokens so long-tail rules keep working without a rename. */
  --paper: var(--moossin-page);
  --surface: #ffffff;
  --surface-sunk: var(--moossin-surface);
  --ink: var(--moossin-ink);
  --ink-soft: var(--moossin-muted);
  --ink-faint: var(--moossin-muted);
  --line: var(--moossin-line-soft);
  --line-strong: var(--moossin-line);
  --accent: var(--moossin-moss);
  --accent-dark: var(--moossin-moss-strong);
  --accent-wash: var(--moossin-mint);
  --highlight: var(--moossin-star);
  /* Blog-only: comment form notices that did not go through; 7.5:1 on white. */
  --alert: #8a3028;

  /* Interface font is the system sans stack shared with the portal; article
   * headings keep the serif stack. No font file is embedded. */
  --sans: system-ui, -apple-system, "Segoe UI", "Noto Sans TC", "Microsoft JhengHei", sans-serif;
  --serif: "Noto Serif TC", "Songti TC", "PMingLiU", serif;
  --mono: ui-monospace, "Cascadia Mono", "Consolas", "Noto Sans Mono CJK TC", monospace;

  /* Reader-adjustable; public.js writes these to the root element. */
  --reader-font-size: 17px;
  --reader-line-height: 1.85;

  --shell: 64rem;
  --measure: 68ch;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Flex column so a short page still pushes the footer to the bottom
   instead of leaving it stranded mid-viewport. */
body {
  display: flex;
  min-height: 100vh;
  min-width: 320px;
  flex-direction: column;
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.7;
  -webkit-text-size-adjust: 100%;
}

body > main {
  flex: 1 0 auto;
}

.site-footer {
  flex-shrink: 0;
}

h1,
h2,
h3 {
  margin: 0;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.35;
}

a {
  color: var(--moossin-moss);
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--moossin-moss-strong);
}

/* One focus rule for everything focusable: moss, never the line colour. */
:focus-visible {
  outline: 3px solid var(--moossin-moss);
  outline-offset: 2px;
}

img {
  max-width: 100%;
  height: auto;
}

mark {
  padding: 0 2px;
  border-radius: 2px;
  background: var(--highlight);
  color: inherit;
}

.site-shell {
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 1rem;
}

/* Above the MOOSSin bar (z-index 40), so the link shows when it has focus. */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 50;
  padding: 10px 16px;
  background: var(--moossin-moss);
  color: #fff;
  text-decoration: none;
}

.skip-link:focus {
  left: 16px;
  top: 16px;
}

/* ---------------------------------------------------------------- header */

/* The page header is the one-row MOOSSin bar shared by all five sections
   (owner decision 2026-10-05, plan A). Its rules sit verbatim at the end of
   this file, last, so they win any tie with the rules above; they are never
   edited here, only in every section at once. */

/* ------------------------------------------------------- deep-space bands */

/* The hero band, the shorter page bands and the footer share one ground:
   star points over the space-deep to teal gradient. White text sits only on
   the space-deep to teal range. */
.home-hero,
.page-band,
.site-footer {
  position: relative;
  overflow: hidden;
  color: #fff;
  background-image:
    var(--moossin-stars),
    linear-gradient(160deg, var(--moossin-space-deep) 0%, var(--moossin-space) 40%, var(--moossin-teal-deep) 78%, var(--moossin-teal) 100%);
}

.home-hero > *,
.page-band > *,
.site-footer > * {
  position: relative;
  z-index: 1;
}

/* Full hero band (home and the posts list): an orbit ring and a planet arc
   in the lower right. */
.home-hero,
.page-band--hero {
  padding: 3.5rem 0 5rem;
  border-radius: 0 0 2.5rem 2.5rem;
}

.home-hero::before,
.page-band--hero::before {
  content: "";
  position: absolute;
  right: -16rem;
  bottom: -9rem;
  width: 46rem;
  height: 18rem;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
  transform: rotate(-10deg);
  pointer-events: none;
}

.home-hero::after,
.page-band--hero::after {
  content: "";
  position: absolute;
  right: -9rem;
  bottom: -17rem;
  width: 30rem;
  height: 30rem;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, var(--moossin-teal-light), var(--moossin-teal) 42%, var(--moossin-teal-deep) 72%, var(--moossin-space) 100%);
  box-shadow: 0 0 60px rgba(63, 154, 139, 0.35);
  pointer-events: none;
}

.home-hero {
  text-align: center;
}

.home-hero .eyebrow,
.page-band .eyebrow {
  color: var(--moossin-star);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: none;
}

.page-band .eyebrow a {
  color: var(--moossin-mint);
  text-decoration-color: rgba(255, 255, 255, 0.5);
}

.page-band .eyebrow a:hover,
.page-band .eyebrow a:focus-visible {
  color: #fff;
}

.home-hero h1 {
  max-width: 24ch;
  margin: 0.75rem auto 1rem;
  font-size: clamp(1.9rem, 1.3rem + 2.6vw, 3rem);
  font-weight: 800;
}

.home-hero__lead {
  max-width: 40ch;
  margin: 0 auto 1.5rem;
  color: rgba(255, 255, 255, 0.92);
  font-size: 1.05rem;
}

.home-hero__actions {
  justify-content: center;
  margin: 0 0 1.5rem;
}

/* Quick destinations under the hero copy: the categories as white pills. */
.quick {
  max-width: 46rem;
  margin: 0 auto;
  padding: 0.5rem 1rem 1rem;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 1.5rem;
  background: rgba(11, 23, 48, 0.35);
  text-align: center;
}

.quick__label {
  margin: 0;
  color: var(--moossin-mint);
  font-size: 0.9rem;
  letter-spacing: 0.06em;
}

.quick ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}

.quick a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.9rem;
  border-radius: 999px;
  background: #fff;
  color: var(--moossin-space-deep);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}

.quick a:hover,
.quick a:focus-visible {
  background: var(--moossin-mint);
  color: var(--moossin-space-deep);
}

/* Shorter page band without the planet (categories, tags, series, search
   and their English counterparts). */
.page-band {
  padding: 2.25rem 0 2.5rem;
  border-radius: 0 0 1.5rem 1.5rem;
}

.page-band--hero {
  padding: 3.25rem 0 4.5rem;
  border-radius: 0 0 2.5rem 2.5rem;
}

.page-band h1 {
  margin: 0.35rem 0 0;
  font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem);
  font-weight: 800;
  overflow-wrap: anywhere;
}

/* -------------------------------------------------------- buttons, links */

.eyebrow {
  margin: 0;
  color: var(--moossin-muted);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.eyebrow--accent {
  color: var(--moossin-moss);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

/* Pill buttons: moss on the page, white or ghost on a dark band. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 1.4rem;
  border: 2px solid var(--moossin-moss);
  border-radius: 999px;
  background: var(--moossin-moss);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
}

.button:hover {
  border-color: var(--moossin-moss-strong);
  background: var(--moossin-moss-strong);
  color: #fff;
}

.button--light {
  border-color: #fff;
  background: #fff;
  color: var(--moossin-space-deep);
}

.button--light:hover {
  border-color: var(--moossin-mint);
  background: var(--moossin-mint);
  color: var(--moossin-space-deep);
}

.button--ghost {
  border-color: rgba(255, 255, 255, 0.85);
  background: transparent;
  color: #fff;
}

.button--ghost:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}

.button--dark {
  border-color: var(--moossin-moss);
  background: var(--moossin-moss);
  color: #fff;
}

.button--dark:hover {
  border-color: var(--moossin-moss-strong);
  background: var(--moossin-moss-strong);
  color: #fff;
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 44px;
  color: var(--moossin-moss);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
}

.text-link:hover,
.text-link:focus-visible {
  color: var(--moossin-moss-strong);
  text-decoration: underline;
}

/* --------------------------------------------------------------- sections */

.home-section,
.page-section {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}

.page-band + .page-section {
  padding-top: 2rem;
}

.section-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 1.25rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--moossin-line-soft);
}

.section-heading h1,
.section-heading h2 {
  margin: 4px 0 0;
  font-size: clamp(1.35rem, 3.4vw, 1.7rem);
}

.section-heading p {
  margin: 0;
  color: var(--moossin-muted);
  font-size: 0.9rem;
}

.page-intro {
  max-width: var(--measure);
  margin: 0 0 1.75rem;
  color: var(--moossin-muted);
}

/* A white card around a home section's prose. */
.home-panel {
  padding: 1.5rem;
  background: #fff;
  border: 1px solid var(--moossin-line);
  border-radius: var(--moossin-radius-card);
  box-shadow: var(--moossin-shadow);
}

.home-panel h2 {
  margin-bottom: 0.5rem;
  font-size: 1.35rem;
}

.home-panel p {
  margin: 0 0 0.8em;
}

.browse-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-bottom: 1.25rem;
}

.browse-grid > div {
  min-width: 0;
  padding: 1.25rem;
  background: #fff;
  border: 1px solid var(--moossin-line);
  border-radius: var(--moossin-radius-card);
  box-shadow: var(--moossin-shadow);
}

.browse-grid h3 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
}

/* ------------------------------------------------------------ post cards */

.post-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.post-card {
  min-width: 0;
  padding: 1.25rem;
  background: #fff;
  border: 1px solid var(--moossin-line);
  border-radius: var(--moossin-radius-card);
  box-shadow: var(--moossin-shadow);
}

.post-card__link {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 16px;
  color: inherit;
  text-decoration: none;
}

.post-card__link:has(.post-card__body:only-child) {
  grid-template-columns: minmax(0, 1fr);
}

.post-card__cover img {
  width: 100%;
  border: 1px solid var(--moossin-line-soft);
  border-radius: 0.75rem;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.post-card__body {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 6px;
}

.post-card__meta {
  color: var(--moossin-muted);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.post-card__title {
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.post-card__link:hover .post-card__title,
.post-card__link:focus-visible .post-card__title {
  color: var(--moossin-moss);
  text-decoration: underline;
}

.post-card__excerpt {
  display: -webkit-box;
  overflow: hidden;
  color: var(--moossin-muted);
  font-size: 0.95rem;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

/* ---------------------------------------------------------------- chips */

.tag-row,
.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 0;
}

.tag-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.9rem;
  border: 1px solid var(--moossin-line);
  border-radius: 999px;
  background: #fff;
  color: var(--moossin-moss-strong);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

.tag-chip:hover,
.tag-chip:focus-visible {
  border-color: var(--moossin-moss);
  background: var(--moossin-mint);
  color: var(--moossin-moss-strong);
}

.tag-chip span:last-child {
  margin-left: 6px;
  color: var(--moossin-muted);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------- index list */

.index-list,
.series-list {
  margin: 0;
  padding: 0 1.25rem;
  list-style: none;
  background: #fff;
  border: 1px solid var(--moossin-line);
  border-radius: var(--moossin-radius-card);
  box-shadow: var(--moossin-shadow);
}

.index-list li + li,
.series-list li + li {
  border-top: 1px solid var(--moossin-line-soft);
}

.index-list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  padding: 14px 0;
  color: inherit;
  text-decoration: none;
}

.index-list a:hover strong,
.index-list a:focus-visible strong {
  color: var(--moossin-moss);
  text-decoration: underline;
}

.index-list strong {
  font-size: 1.05rem;
}

.index-list span {
  color: var(--moossin-muted);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.series-list {
  counter-reset: series;
}

.series-list li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 14px;
  padding: 16px 0;
}

.series-list__index {
  color: var(--moossin-moss);
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.series-list a {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  min-height: 44px;
  color: inherit;
  text-decoration: none;
}

.series-list strong {
  font-size: 1.05rem;
}

.series-list a:hover strong,
.series-list a:focus-visible strong {
  color: var(--moossin-moss);
  text-decoration: underline;
}

.series-list a span {
  color: var(--moossin-muted);
  font-size: 0.9rem;
}

/* -------------------------------------------------------------- pagination */

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--moossin-line-soft);
  font-size: 0.92rem;
}

.pagination__status {
  color: var(--moossin-muted);
  font-variant-numeric: tabular-nums;
}

.pagination__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1.1rem;
  border: 1px solid var(--moossin-line);
  border-radius: 999px;
  background: #fff;
  color: var(--moossin-moss-strong);
  font-weight: 600;
  text-decoration: none;
}

.pagination__link:hover,
.pagination__link:focus-visible {
  border-color: var(--moossin-moss);
  background: var(--moossin-mint);
}

/* ------------------------------------------------------------------ search */

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 8px;
}

.search-form__field {
  display: flex;
  min-width: 240px;
  flex: 1 1 320px;
  flex-direction: column;
  gap: 6px;
}

.search-form__field span {
  color: var(--moossin-muted);
  font-size: 0.85rem;
  font-weight: 600;
}

.search-form input {
  width: 100%;
  min-height: 44px;
  padding: 0 1rem;
  border: 1px solid var(--moossin-line);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font-family: inherit;
  font-size: 1rem;
}

.search-form input:focus-visible {
  border-color: var(--moossin-moss);
}

.search-form button {
  font-family: inherit;
}

.search-summary {
  margin: 20px 0 4px;
  color: var(--moossin-muted);
  font-size: 0.9rem;
}

/* -------------------------------------------------------------- post page */

/* Reading is unchanged: the measure, the reader-adjustable size and line
   height, the sticky contents column. Only colours moved onto the tokens. */
.post {
  padding-top: 2.75rem;
  padding-bottom: 4.5rem;
}

.post__header {
  max-width: var(--measure);
  margin-bottom: 28px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--moossin-line-soft);
}

.post__breadcrumb,
.post__meta {
  margin: 0;
  color: var(--moossin-muted);
  font-size: 0.88rem;
}

.post__breadcrumb a {
  color: var(--moossin-moss);
}

.post__header h1 {
  margin: 12px 0;
  font-family: var(--serif);
  font-size: clamp(1.6rem, 5vw, 2.3rem);
}

.post__cover {
  max-width: var(--measure);
  margin: 0 0 28px;
}

.post__cover img {
  width: 100%;
  border: 1px solid var(--moossin-line-soft);
  border-radius: 0.75rem;
}

.post__summary {
  max-width: var(--measure);
  margin-bottom: 28px;
  padding-left: 16px;
  border-left: 3px solid var(--moossin-moss);
  color: var(--moossin-muted);
}

.post__summary p {
  margin: 0 0 0.6em;
}

.post__layout {
  display: grid;
  gap: 28px;
}

.post__body {
  max-width: var(--measure);
  min-width: 0;
  font-size: var(--reader-font-size);
  line-height: var(--reader-line-height);
  overflow-wrap: anywhere;
}

/* A jump to a heading leaves a little room above it. The header scrolls away
   with the page (the one-row MOOSSin bar is not sticky, 2026-10-05), so there
   is no header height to clear. */
.post__body h1,
.post__body h2,
.post__body h3 {
  margin: 1.9em 0 0.55em;
  font-family: var(--serif);
  scroll-margin-top: 24px;
}

.post__body h1 {
  font-size: 1.5em;
}

.post__body h2 {
  padding-bottom: 0.25em;
  border-bottom: 1px solid var(--moossin-line-soft);
  font-size: 1.28em;
}

.post__body h3 {
  font-size: 1.1em;
}

.post__body p {
  margin: 0 0 1.15em;
}

.post__body ul,
.post__body ol {
  padding-inline-start: 1.5em;
}

.post__body li {
  margin-block: 0.6em;
}

.post__body a {
  color: var(--moossin-moss);
  text-decoration: underline;
}

.post__body a:hover {
  color: var(--moossin-moss-strong);
}

.post__body code {
  padding: 2px 6px;
  border: 1px solid var(--moossin-line-soft);
  border-radius: 4px;
  background: var(--moossin-surface);
  font-family: var(--mono);
  font-size: 0.88em;
  word-break: break-word;
}

/* Code blocks scroll rather than truncate; long-form notes stay contained on
   narrow screens by wrapping long lines. */
.post__body pre {
  overflow-x: auto;
  max-width: 100%;
  margin: 1.4em 0;
  padding: 1em;
  border: 1px solid var(--moossin-line-soft);
  border-radius: 0.75rem;
  background: var(--moossin-surface);
  font-family: var(--mono);
  font-size: 0.86em;
  line-height: 1.65;
  tab-size: 2;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.post__body pre code {
  padding: 0;
  border: none;
  background: none;
  font-size: inherit;
  white-space: inherit;
  word-break: normal;
}

.post__body blockquote {
  margin: 1.5em 0;
  padding: 0.5em 1.2em;
  border-inline-start: 3px solid var(--moossin-moss);
  border-radius: 0 0.75rem 0.75rem 0;
  background: var(--moossin-surface);
  color: var(--moossin-muted);
}

.post__body figure {
  margin: 1.6em 0;
}

.post__body figcaption {
  margin-top: 8px;
  color: var(--moossin-muted);
  font-size: 0.84rem;
  text-align: center;
}

.table-scroll {
  max-width: 100%;
  overflow-x: auto;
  margin-block: 1.5em;
}

.table-scroll table {
  border-collapse: collapse;
  width: 100%;
}

.table-scroll th,
.table-scroll td {
  padding: 0.7em;
  border: 1px solid var(--moossin-line-soft);
  text-align: start;
  min-width: 8em;
}

.table-scroll th {
  background: var(--moossin-band);
}

.post__body--pending {
  margin-block: 2rem;
}

.related-reading {
  margin-block: 2rem;
  padding-block-start: 1.5rem;
  border-block-start: 1px solid var(--moossin-line-soft);
}

.related-reading h2 {
  font-size: 1.25rem;
}

.related-reading ul {
  margin: 0.5rem 0 0;
  padding-inline-start: 1.25rem;
}

.related-reading li a,
.related-reading > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* --------------------------------------------------------------- contents */

.contents {
  font-size: 0.88rem;
}

.contents__disclosure {
  padding: 12px 16px;
  border: 1px solid var(--moossin-line-soft);
  border-radius: 0.75rem;
  background: #fff;
}

.contents__disclosure > summary {
  color: var(--moossin-muted);
  cursor: pointer;
  font-weight: 700;
  letter-spacing: 0.06em;
  /* WCAG 2.2 AA target size (2.5.8): the row is the target, so it gets the height. */
  padding-block: 5px;
}

.contents__list {
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.contents__item {
  margin-bottom: 6px;
  line-height: 1.5;
}

.contents__item a {
  color: var(--moossin-muted);
  text-decoration: none;
  /* Each link is alone in its list item, so it is a target in its own right. */
  display: inline-block;
  padding-block: 4px;
}

.contents__item a:hover,
.contents__item a:focus-visible {
  color: var(--moossin-moss);
  text-decoration: underline;
}

.contents__item--level-2 {
  padding-left: 12px;
}

.contents__item--level-3 {
  padding-left: 24px;
  font-size: 0.94em;
}

/* -------------------------------------------------------- reader controls */

.reader-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: var(--measure);
  margin-top: 40px;
  padding-top: 20px;
  border-top: 1px solid var(--moossin-line-soft);
}

.reader-controls__label {
  margin-right: 4px;
  color: var(--moossin-muted);
  font-size: 0.85rem;
}

.reader-controls button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--moossin-line);
  border-radius: 999px;
  background: #fff;
  color: var(--moossin-moss-strong);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.reader-controls button:hover {
  border-color: var(--moossin-moss);
  background: var(--moossin-mint);
  color: var(--moossin-moss-strong);
}

.post-nav {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: var(--measure);
  margin-top: 36px;
  padding-top: 20px;
  border-top: 1px solid var(--moossin-line-soft);
  font-size: 0.92rem;
}

.post-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration: none;
}

.post-nav a:hover,
.post-nav a:focus-visible {
  text-decoration: underline;
}

/* --------------------------------------------------------------- comments */

/* Reader comments close the article (2026-10-04): the same 68ch column and
   thin rule as the post navigation above, plain text throughout. A comment
   keeps the writer's line breaks (pre-line); long words wrap. When
   `#comments` is the fragment the section lands a little below the top edge,
   the same room as a heading (no sticky header to clear since 2026-10-05). */
.comments {
  max-width: var(--measure);
  margin-top: 36px;
  padding-top: 20px;
  border-top: 1px solid var(--moossin-line-soft);
  scroll-margin-top: 24px;
}

.comments h2 {
  margin: 0 0 16px;
  font-size: 1.25rem;
}

/* Ink on mint 12.7:1; the error and rate-limit notices use --alert on white. */
.comments__notice {
  margin: 0 0 20px;
  padding: 10px 14px;
  border-left: 3px solid var(--moossin-moss);
  border-radius: var(--moossin-radius);
  background: var(--moossin-mint);
  color: var(--moossin-ink);
}

.comments__notice--error,
.comments__notice--slow {
  border-left-color: var(--alert);
  background: #fff;
  color: var(--alert);
}

.comments__empty {
  margin: 0 0 24px;
  color: var(--moossin-muted);
}

.comments__list {
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
}

.comment {
  padding: 14px 0;
  border-bottom: 1px solid var(--moossin-line-soft);
}

.comment:first-child {
  padding-top: 0;
}

.comment__meta {
  margin: 0 0 6px;
  color: var(--moossin-muted);
  font-size: 0.88rem;
}

.comment__author {
  color: var(--moossin-ink);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.comment__body {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.comment-form {
  display: grid;
  gap: 14px;
}

.comment-form__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.comment-form__field label {
  color: var(--moossin-muted);
  font-size: 0.85rem;
  font-weight: 600;
}

.comment-form__field input,
.comment-form__field textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--moossin-line);
  border-radius: var(--moossin-radius);
  background: #fff;
  color: var(--ink);
  font-family: inherit;
  font-size: 1rem;
}

.comment-form__field textarea {
  min-height: 8rem;
  line-height: 1.6;
  resize: vertical;
}

.comment-form__field input:focus-visible,
.comment-form__field textarea:focus-visible {
  border-color: var(--moossin-moss);
}

.comment-form__note {
  margin: 0;
  color: var(--moossin-muted);
  font-size: 0.85rem;
}

.comment-form .button {
  justify-self: start;
  font-family: inherit;
}

/* The honeypot: off-screen rather than display:none, which simple bots read
   as "skip this field"; aria-hidden and tabindex keep it from people. */
.comment-form__trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ------------------------------------------------------------ empty/error */

.empty-state {
  margin: 0;
  padding: 2rem 1.25rem;
  border: 1px dashed var(--moossin-line);
  border-radius: var(--moossin-radius-card);
  color: var(--moossin-muted);
  text-align: center;
}

.status-page {
  display: flex;
  min-height: 55vh;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 56px 20px 72px;
  text-align: center;
}

.status-page__code {
  margin: 0 0 4px;
  color: var(--moossin-muted);
  font-family: var(--mono);
  font-size: 2.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1;
}

.status-page h1 {
  margin: 0 0 12px;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 5vw, 2rem);
}

.status-page p {
  max-width: 44ch;
  margin: 0 0 24px;
  color: var(--moossin-muted);
}

/* ----------------------------------------------- machine-translated pages */

/* Translated English pages end with the notice, the original link, Google's
   attribution badge and the disclaimer (owner decision 2026-10-03). Google
   asks that the badge sit next to the translation, unmodified and fully
   visible, and links to translate.google.com; it sets no position, so the
   block closes the content rather than opening it. A quiet end of page: one
   thin rule, no fill and no frame, on the page background. The side margins
   repeat the shell's gutter so the rule spans the content column, never the
   viewport; the font size stays the page's own so `--measure` (in ch)
   matches the article column above. */
.machine-translation {
  margin: 3rem max(1rem, calc((100% - var(--shell)) / 2 + 1rem)) 0;
  padding-top: 1rem;
  border-top: 1px solid var(--moossin-line-soft);
  overflow-wrap: anywhere;
}

/* Under an article or a legal page: the 68ch reading column. */
.post + .machine-translation {
  max-width: var(--measure);
}

/* The block brings its own 3rem, so the article or section above it drops
   its bottom padding and the gap is the same on every page. */
.post:has(+ .machine-translation),
.home-section:has(+ .machine-translation),
.page-section:has(+ .machine-translation) {
  padding-bottom: 0;
}

/* Muted on the near-white page: 7.67:1; the moss link 6.19:1. */
.machine-translation > p {
  margin: 0;
  color: var(--moossin-muted);
  font-size: 0.875rem;
  line-height: 1.6;
}

.machine-translation > p + p {
  margin-top: 0.75rem;
}

.machine-translation > .machine-translation__disclaimer {
  font-size: 0.75rem;
  line-height: 1.5;
}

/* A 24px-tall link target around the 16px badge. No side margin: the
   space before it separates it inline, and when it wraps at narrow widths
   it starts on the same edge as the text and the rule. */
.machine-translation__badge {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  vertical-align: middle;
}

/* The official file is 352x32 (@2x); shown at its 1x size and never
   smaller. The narrowest column (320px less both gutters) is 288px. */
.machine-translation__badge img {
  width: 176px;
  max-width: none;
  height: 16px;
}

/* ---------------------------------------------------------------- footer */

/* Four columns on deep space with a planet horizon: the site name, the
   shared MOOSSin section navigation, this site's own links, and the
   language column. */
.site-footer {
  margin-top: 3rem;
  padding: 2.5rem 0 4rem;
  color: rgba(255, 255, 255, 0.85);
  background-image:
    var(--moossin-stars),
    linear-gradient(180deg, var(--moossin-space-deep), var(--moossin-space));
}

.site-footer::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -30rem;
  width: 90rem;
  height: 34rem;
  border-radius: 50%;
  transform: translateX(-50%);
  opacity: 0.9;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 0%, var(--moossin-teal-light), var(--moossin-teal) 30%, var(--moossin-teal-deep) 60%);
}

.site-footer__inner {
  font-size: 0.92rem;
}

.site-footer p {
  margin: 0;
}

.site-footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 0.8fr;
  gap: 1.5rem;
}

.site-footer__col {
  min-width: 0;
}

.site-footer__brand {
  margin: 0 0 0.25rem;
  color: #fff;
  font-size: 1.25rem;
  font-weight: 700;
}

.site-footer__links {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  min-width: 0;
}

.site-footer__links-label,
.site-footer__sections-label {
  display: block;
  margin: 0 0 0.35rem;
  color: #fff;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.site-footer a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--moossin-mint);
  text-decoration-thickness: 1px;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: #fff;
}

.site-footer a[aria-current="page"] {
  color: #fff;
  font-weight: 700;
  text-decoration-thickness: 2px;
}

.site-footer__current {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: #fff;
  font-weight: 700;
}

.site-footer__note {
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.25);
  color: rgba(255, 255, 255, 0.75);
  font-size: 0.85rem;
}

@media (max-width: 52rem) {
  .site-footer__grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 30rem) {
  .site-footer__grid {
    grid-template-columns: 1fr;
  }
}

/* -------------------------------------------------------------- 768px up */

@media (min-width: 768px) {
  body {
    font-size: 17px;
  }

  /* Only the sides: the home and list sections and the article keep their own top and bottom
     padding at every width. Until 2026-10-06 this was `padding: 0 2rem`, which zeroed them from
     768px up and left headings against the bands and articles against the header. */
  .site-shell {
    padding-inline: 2rem;
  }

  /* The notice follows the shell's wider gutter. */
  .machine-translation {
    margin-inline: max(2rem, calc((100% - var(--shell)) / 2 + 2rem));
  }

  .post-card__link {
    grid-template-columns: 132px minmax(0, 1fr);
    gap: 22px;
  }

  .post-nav {
    flex-direction: row;
    justify-content: space-between;
  }
}

/* ------------------------------------------------------------- 1024px up */

@media (min-width: 1024px) {
  /* The contents column only appears when there is room beside the text. */
  .post__layout {
    display: grid;
    grid-template-columns: minmax(0, var(--measure)) 220px;
    gap: 48px;
    align-items: start;
  }

  /* Sticks a little below the viewport's top edge with the same room left
     below it; the header scrolls away (not sticky since 2026-10-05), so
     there is no header height to clear. */
  .contents {
    position: sticky;
    top: 24px;
    order: 2;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
  }

  .contents__disclosure {
    border: none;
    border-left: 2px solid var(--moossin-line-soft);
    border-radius: 0;
    background: none;
    padding: 0 0 0 16px;
  }

  .contents__disclosure > summary {
    font-size: 0.76rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
  }
}

/* The one-row MOOSSin bar (owner decision 2026-10-05, plan A), byte for byte
   the stylesheet all five sections share; it replaced the UX E section strip
   and the blog's own header. Keep it last and never edit it here:
   tests/test_mooss_bar.py checks its SHA-256. */
/* mooss-hero:begin */
/* MOOSSin home hero carousel (owner, 2026-10-06: the novel and blog homes rotate their own content
 * in the deep-space band, as the portal home has since 2026-10-03). This block is byte-identical in
 * the blog and the novel between the mooss-hero markers, and both test suites compare its SHA-256.
 * The band, the planet and every carousel measure copy the portal's `.home .hero-band` rules
 * (www `static/portal.css`), so the three homes look alike.
 *
 * CSS only: the page needs no script. All slides share one grid cell, so the band is as tall as the
 * tallest slide and nothing jumps; the one on show sits on top and takes the clicks. A hidden radio
 * group is the control: "auto" (checked on load) rotates, seven seconds a slide, and choosing a dot
 * shows that slide and stops the rotation (WCAG 2.2.2). The list item switches which slide is on
 * show in one step and its body fades inside that window, so a pause never freezes a half-faded
 * slide. A resting mouse or keyboard focus on a dot pauses every layer; focus on a link inside a
 * slide shows that slide. Only opacity changes. The rotation runs for every visitor, reduced motion
 * included (the owner's decision for the portal, 2026-10-03; see the end of this block).
 *
 * Two to five slides: `mooss-hero--N` on the carousel picks the cycle and the keyframes. A slide's
 * delay counts back from the end of the list, so it needs no rule per count (the first slide's
 * delay is one whole cycle, which is the same as none). One slide carries no radios or dots. */
.mooss-hero { position: relative; overflow: hidden; padding: 1.75rem max(1rem, calc((100% - 64rem) / 2)) 1.5rem; border-radius: 0 0 2rem 2rem; color: #fff; text-align: center; background-image: var(--moossin-stars), linear-gradient(160deg, var(--moossin-space-deep) 0%, var(--moossin-space) 40%, var(--moossin-teal-deep) 78%, var(--moossin-teal) 100%); }
.mooss-hero::before { content: ""; position: absolute; right: -13rem; bottom: -7rem; width: 36rem; height: 14rem; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.28); transform: rotate(-10deg); pointer-events: none; }
.mooss-hero::after { content: ""; position: absolute; right: -7rem; bottom: -14rem; width: 22rem; height: 22rem; border-radius: 50%; background: radial-gradient(circle at 32% 30%, var(--moossin-teal-light), var(--moossin-teal) 42%, var(--moossin-teal-deep) 72%, var(--moossin-space) 100%); box-shadow: 0 0 60px rgba(63, 154, 139, 0.35); pointer-events: none; }
.mooss-hero > * { position: relative; z-index: 1; }
.mooss-hero .mooss-hero__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.mooss-hero .mooss-hero__carousel { position: relative; }
/* The radios sit by the dot row: a browser scrolls a focused control into view, and one parked at
 * the top of the carousel would make the page jump there whenever a dot is pressed. */
.mooss-hero .mooss-hero__pick { position: absolute; left: 50%; bottom: 22px; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.mooss-hero .mooss-hero__slides { display: grid; margin: 0; padding: 0; list-style: none; }
.mooss-hero .mooss-hero__slide { grid-area: 1 / 1; display: grid; min-width: 0; opacity: 0; z-index: 0; }
.mooss-hero .mooss-hero__slide:first-child { opacity: 1; z-index: 1; }
.mooss-hero .mooss-hero__body { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 0; }
.mooss-hero .mooss-hero__kind { margin: 0 0 var(--moossin-space-1); color: var(--moossin-star); font-weight: 600; font-size: 0.85rem; letter-spacing: 0.04em; }
.mooss-hero .mooss-hero__slide h2 { max-width: 34em; margin: 0 0 var(--moossin-space-2); font-size: clamp(1.2rem, 1rem + 1vw, 1.65rem); font-weight: 800; line-height: 1.35; letter-spacing: normal; text-wrap: balance; overflow-wrap: anywhere; }
.mooss-hero .mooss-hero__slide h2 a { color: #fff; text-decoration: none; }
.mooss-hero .mooss-hero__slide h2 a:hover { color: #fff; text-decoration: underline; }
/* A title with natural pauses breaks at its punctuation and spaces instead of splitting a Chinese
 * word at the line end; the page adds the class only when every phrase fits a phone line. */
.mooss-hero .mooss-hero__slide h2.mooss-hero__phrases { word-break: keep-all; overflow-wrap: anywhere; }
.mooss-hero .mooss-hero__summary { max-width: var(--moossin-measure); margin: 0 0 var(--moossin-space-3); color: rgba(255, 255, 255, 0.92); line-height: 1.6; text-wrap: balance; }
.mooss-hero .mooss-hero__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--moossin-space-2) var(--moossin-space-3); margin: 0; }
.mooss-hero .mooss-hero__button { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--moossin-space-4); border-radius: 999px; font-weight: 700; text-decoration: none; }
.mooss-hero .mooss-hero__button--light { background: #fff; color: var(--moossin-space-deep); }
.mooss-hero .mooss-hero__button--light:hover { background: var(--moossin-mint); color: var(--moossin-space-deep); }
.mooss-hero .mooss-hero__button--ghost { border: 2px solid rgba(255, 255, 255, 0.85); color: #fff; }
.mooss-hero .mooss-hero__button--ghost:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
/* The moss focus ring measures 2.79:1 on space-deep; white keeps it visible. */
.mooss-hero a:focus-visible { outline-color: #fff; }
.mooss-hero--2 { --mooss-hero-cycle: 14s; --mooss-hero-rotate: mooss-hero-rotate-2; --mooss-hero-fade: mooss-hero-fade-2; --mooss-hero-dot: mooss-hero-dot-2; }
.mooss-hero--3 { --mooss-hero-cycle: 21s; --mooss-hero-rotate: mooss-hero-rotate-3; --mooss-hero-fade: mooss-hero-fade-3; --mooss-hero-dot: mooss-hero-dot-3; }
.mooss-hero--4 { --mooss-hero-cycle: 28s; --mooss-hero-rotate: mooss-hero-rotate-4; --mooss-hero-fade: mooss-hero-fade-4; --mooss-hero-dot: mooss-hero-dot-4; }
.mooss-hero--5 { --mooss-hero-cycle: 35s; --mooss-hero-rotate: mooss-hero-rotate-5; --mooss-hero-fade: mooss-hero-fade-5; --mooss-hero-dot: mooss-hero-dot-5; }
/* Each slide and its dot start one seven-second window after the one before. */
.mooss-hero .mooss-hero__slide:nth-last-child(1), .mooss-hero .mooss-hero__dots label:nth-last-child(1) { --mooss-hero-delay: -7s; }
.mooss-hero .mooss-hero__slide:nth-last-child(2), .mooss-hero .mooss-hero__dots label:nth-last-child(2) { --mooss-hero-delay: -14s; }
.mooss-hero .mooss-hero__slide:nth-last-child(3), .mooss-hero .mooss-hero__dots label:nth-last-child(3) { --mooss-hero-delay: -21s; }
.mooss-hero .mooss-hero__slide:nth-last-child(4), .mooss-hero .mooss-hero__dots label:nth-last-child(4) { --mooss-hero-delay: -28s; }
.mooss-hero .mooss-hero__slide:nth-last-child(5), .mooss-hero .mooss-hero__dots label:nth-last-child(5) { --mooss-hero-delay: -35s; }
.mooss-hero__pick--auto:checked ~ .mooss-hero__slides .mooss-hero__slide { animation: var(--mooss-hero-rotate) var(--mooss-hero-cycle) step-end var(--mooss-hero-delay, 0s) infinite; }
.mooss-hero__pick--auto:checked ~ .mooss-hero__slides .mooss-hero__body { animation: var(--mooss-hero-fade) var(--mooss-hero-cycle) var(--mooss-hero-delay, 0s) infinite; }
@keyframes mooss-hero-rotate-2 { 0% { opacity: 1; z-index: 2; } 50%, 100% { opacity: 0; z-index: 0; } }
@keyframes mooss-hero-rotate-3 { 0% { opacity: 1; z-index: 2; } 33.333%, 100% { opacity: 0; z-index: 0; } }
@keyframes mooss-hero-rotate-4 { 0% { opacity: 1; z-index: 2; } 25%, 100% { opacity: 0; z-index: 0; } }
@keyframes mooss-hero-rotate-5 { 0% { opacity: 1; z-index: 2; } 20%, 100% { opacity: 0; z-index: 0; } }
/* The body fades in and out over 0.525 s at each end of its window, as on the portal. */
@keyframes mooss-hero-fade-2 { 0% { opacity: 0; } 3.75%, 46.25% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes mooss-hero-fade-3 { 0% { opacity: 0; } 2.5%, 30.833% { opacity: 1; } 33.333%, 100% { opacity: 0; } }
@keyframes mooss-hero-fade-4 { 0% { opacity: 0; } 1.875%, 23.125% { opacity: 1; } 25%, 100% { opacity: 0; } }
@keyframes mooss-hero-fade-5 { 0% { opacity: 0; } 1.5%, 18.5% { opacity: 1; } 20%, 100% { opacity: 0; } }
.mooss-hero__pick:not(.mooss-hero__pick--auto):checked ~ .mooss-hero__slides .mooss-hero__slide { opacity: 0; z-index: 0; }
.mooss-hero__pick--1:checked ~ .mooss-hero__slides .mooss-hero__slide:nth-child(1),
.mooss-hero__pick--2:checked ~ .mooss-hero__slides .mooss-hero__slide:nth-child(2),
.mooss-hero__pick--3:checked ~ .mooss-hero__slides .mooss-hero__slide:nth-child(3),
.mooss-hero__pick--4:checked ~ .mooss-hero__slides .mooss-hero__slide:nth-child(4),
.mooss-hero__pick--5:checked ~ .mooss-hero__slides .mooss-hero__slide:nth-child(5) { opacity: 1; z-index: 2; }
@media (hover: hover) {
  .mooss-hero .mooss-hero__carousel:hover .mooss-hero__slides .mooss-hero__slide,
  .mooss-hero .mooss-hero__carousel:hover .mooss-hero__slides .mooss-hero__body,
  .mooss-hero .mooss-hero__carousel:hover .mooss-hero__dots .mooss-hero__dot { animation-play-state: paused; }
  .mooss-hero .mooss-hero__carousel:hover .mooss-hero__body { opacity: 1 !important; }
}
.mooss-hero .mooss-hero__pick:focus-visible ~ .mooss-hero__slides .mooss-hero__slide,
.mooss-hero .mooss-hero__pick:focus-visible ~ .mooss-hero__slides .mooss-hero__body,
.mooss-hero .mooss-hero__pick:focus-visible ~ .mooss-hero__dots .mooss-hero__dot { animation-play-state: paused; }
.mooss-hero .mooss-hero__pick:focus-visible ~ .mooss-hero__slides .mooss-hero__body { opacity: 1 !important; }
/* Focus on a link inside a slide: every layer drops its animation in the same rule set, so none of
 * them can restart on its own clock afterwards. */
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:focus-within .mooss-hero__slide:nth-child(n) { animation: none; opacity: 0; z-index: 0; }
.mooss-hero .mooss-hero__carousel .mooss-hero__slides .mooss-hero__slide:nth-child(n):focus-within { opacity: 1; z-index: 3; }
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:focus-within .mooss-hero__body { animation: none; opacity: 1; }
.mooss-hero .mooss-hero__dots { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; width: fit-content; margin: var(--moossin-space-1) auto 0; }
.mooss-hero .mooss-hero__dots label { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; min-height: 44px; border-radius: 999px; cursor: pointer; }
/* The dot of the slide on show is a filled disc and the others are rings, so the state is a shape
 * and not only a colour. */
.mooss-hero .mooss-hero__dot { width: 0.7rem; height: 0.7rem; border: 2px solid rgba(255, 255, 255, 0.85); border-radius: 50%; }
.mooss-hero__pick--auto:checked ~ .mooss-hero__dots label:nth-child(1) .mooss-hero__dot { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); }
.mooss-hero__pick--auto:checked ~ .mooss-hero__dots .mooss-hero__dot { animation: var(--mooss-hero-dot) var(--mooss-hero-cycle) step-end var(--mooss-hero-delay, 0s) infinite; }
@keyframes mooss-hero-dot-2 { 0% { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); } 50%, 100% { border-color: rgba(255, 255, 255, 0.85); border-width: 2px; background: transparent; } }
@keyframes mooss-hero-dot-3 { 0% { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); } 33.333%, 100% { border-color: rgba(255, 255, 255, 0.85); border-width: 2px; background: transparent; } }
@keyframes mooss-hero-dot-4 { 0% { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); } 25%, 100% { border-color: rgba(255, 255, 255, 0.85); border-width: 2px; background: transparent; } }
@keyframes mooss-hero-dot-5 { 0% { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); } 20%, 100% { border-color: rgba(255, 255, 255, 0.85); border-width: 2px; background: transparent; } }
.mooss-hero__pick--1:checked ~ .mooss-hero__dots label:nth-child(1) .mooss-hero__dot,
.mooss-hero__pick--2:checked ~ .mooss-hero__dots label:nth-child(2) .mooss-hero__dot,
.mooss-hero__pick--3:checked ~ .mooss-hero__dots label:nth-child(3) .mooss-hero__dot,
.mooss-hero__pick--4:checked ~ .mooss-hero__dots label:nth-child(4) .mooss-hero__dot,
.mooss-hero__pick--5:checked ~ .mooss-hero__dots label:nth-child(5) .mooss-hero__dot { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); }
/* While a link inside a slide has focus, no dot runs on a timer: they all go back to rings, and the
 * dot of the slide that holds the focus is the filled one (that rule needs `:has()`). */
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:focus-within ~ .mooss-hero__dots label .mooss-hero__dot { animation: none; border-color: rgba(255, 255, 255, 0.85); border-width: 2px; background: transparent; }
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:has(.mooss-hero__slide:nth-child(1):focus-within) ~ .mooss-hero__dots label:nth-child(1) .mooss-hero__dot,
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:has(.mooss-hero__slide:nth-child(2):focus-within) ~ .mooss-hero__dots label:nth-child(2) .mooss-hero__dot,
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:has(.mooss-hero__slide:nth-child(3):focus-within) ~ .mooss-hero__dots label:nth-child(3) .mooss-hero__dot,
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:has(.mooss-hero__slide:nth-child(4):focus-within) ~ .mooss-hero__dots label:nth-child(4) .mooss-hero__dot,
.mooss-hero .mooss-hero__carousel .mooss-hero__slides:has(.mooss-hero__slide:nth-child(5):focus-within) ~ .mooss-hero__dots label:nth-child(5) .mooss-hero__dot { border-color: var(--moossin-star); border-width: 0.35rem; background: var(--moossin-star); }
/* The radios are invisible, so the dot they belong to shows their focus; the auto radio has no
 * visible label, so while it has keyboard focus the whole dot row shows it. */
.mooss-hero__pick--1:focus-visible ~ .mooss-hero__dots label:nth-child(1),
.mooss-hero__pick--2:focus-visible ~ .mooss-hero__dots label:nth-child(2),
.mooss-hero__pick--3:focus-visible ~ .mooss-hero__dots label:nth-child(3),
.mooss-hero__pick--4:focus-visible ~ .mooss-hero__dots label:nth-child(4),
.mooss-hero__pick--5:focus-visible ~ .mooss-hero__dots label:nth-child(5) { outline: 3px solid #fff; outline-offset: -4px; }
.mooss-hero__pick--auto:focus-visible ~ .mooss-hero__dots { outline: 3px solid #fff; outline-offset: 2px; border-radius: 999px; }
/* The rotation runs when a visitor asks for reduced motion: each site's own rule shortens every
 * animation to nothing with `!important`, and these selectors outrank its `*`. Only opacity
 * changes, and a dot still stops it while a resting mouse or keyboard focus pauses it. */
@media (prefers-reduced-motion: reduce) {
  .mooss-hero .mooss-hero__slide,
  .mooss-hero .mooss-hero__body,
  .mooss-hero .mooss-hero__dot { animation-duration: var(--mooss-hero-cycle) !important; animation-iteration-count: infinite !important; }
}
@media (max-width: 64rem) {
  .mooss-hero { padding-block: 1.5rem 2.75rem; border-radius: 0 0 1.5rem 1.5rem; }
  .mooss-hero::before { right: -12rem; bottom: -7rem; width: 28rem; height: 10.5rem; }
  .mooss-hero::after { right: -6rem; bottom: -15.5rem; width: 18rem; height: 18rem; }
}
/* mooss-hero:end */

/* mooss-bar:begin */
/* MOOSSin one-row header (owner decision 2026-10-05, plan A): the brand, the five sections with the
 * current section's own menu behind a chevron, and a few tools, in one row; one "選單" drawer below
 * 960px. Shared verbatim by all five sections; every rule is scoped to .mooss-bar and resets what a
 * section stylesheet could leak in. Colours are the portal's palette (ink 14.6:1, muted 7.7:1 and
 * moss 6.1:1 on the bar). Change it in every section at once, never in one. */
.mooss-bar {
  position: relative;
  z-index: 40;
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-bottom: 1px solid #dfe5dc;
  background: #fbfcfa;
  color: #1c221d;
  font-family: system-ui, -apple-system, "Segoe UI", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: normal;
  text-align: left;
}

.mooss-bar *,
.mooss-bar *::before,
.mooss-bar *::after {
  box-sizing: border-box;
}

.mooss-bar a {
  color: inherit;
  text-decoration: none;
}

.mooss-bar ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.mooss-bar li {
  margin: 0;
  padding: 0;
}

.mooss-bar summary {
  list-style: none;
  cursor: pointer;
}

.mooss-bar summary::-webkit-details-marker {
  display: none;
}

.mooss-bar__inner {
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: 1180px;
  min-height: 56px;
  margin: 0 auto;
  padding: 0 20px;
}

.mooss-bar__brand {
  flex: none;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.mooss-bar__here {
  display: none;
}

.mooss-bar__sections {
  flex: 1 1 auto;
  min-width: 0;
}

.mooss-bar__list {
  display: flex;
  align-items: center;
  gap: 2px;
}

.mooss-bar__list > li {
  position: relative;
  display: flex;
  align-items: center;
}

.mooss-bar__list a,
.mooss-bar__tools a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 10px;
  border-radius: 6px;
  color: #4a544b;
  white-space: nowrap;
}

.mooss-bar__list a:hover,
.mooss-bar__tools a:hover {
  background: #f1f4ef;
  color: #1c221d;
}

.mooss-bar__list > li > a[aria-current="page"] {
  border-radius: 6px 6px 0 0;
  box-shadow: inset 0 -2px 0 #2f6b3f;
  color: #1c221d;
  font-weight: 700;
}

.mooss-bar__more > summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 40px;
  margin-left: -4px;
  border-radius: 6px;
  color: #4a544b;
}

.mooss-bar__more > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}

.mooss-bar__more[open] > summary::after {
  transform: translateY(2px) rotate(-135deg);
}

.mooss-bar__more > summary:hover {
  background: #f1f4ef;
  color: #1c221d;
}

.mooss-bar__sub {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 200px;
  padding: 6px;
  border: 1px solid #dfe5dc;
  border-radius: 10px;
  background: #ffffff;
  box-shadow: 0 10px 28px rgba(28, 34, 29, 0.12);
}

.mooss-bar__sub a {
  display: flex;
  width: 100%;
  border-radius: 6px;
  color: #1c221d;
}

.mooss-bar__tools {
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
}

.mooss-bar__drawer {
  display: none;
}

.mooss-bar a:focus-visible,
.mooss-bar summary:focus-visible {
  outline: 2px solid #2f6b3f;
  outline-offset: -2px;
}

@media (max-width: 959px) {
  .mooss-bar__sections,
  .mooss-bar__tools {
    display: none;
  }

  .mooss-bar__inner {
    gap: 8px;
    padding: 0 16px;
  }

  .mooss-bar__here {
    display: block;
    min-width: 0;
    overflow: hidden;
    color: #4a544b;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .mooss-bar__drawer {
    display: block;
    flex: none;
    margin-left: auto;
  }

  .mooss-bar__drawer > summary {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid #c9d2c5;
    border-radius: 8px;
    color: #1c221d;
  }

  .mooss-bar__drawer[open] > summary {
    background: #f1f4ef;
  }

  .mooss-bar__panel {
    position: absolute;
    top: 100%;
    right: 0;
    left: 0;
    max-height: calc(100vh - 56px);
    overflow-y: auto;
    padding: 8px 16px 16px;
    border-bottom: 1px solid #dfe5dc;
    background: #fbfcfa;
    box-shadow: 0 12px 24px rgba(28, 34, 29, 0.1);
  }

  .mooss-bar__panel a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 10px;
    border-radius: 6px;
    color: #1c221d;
  }

  .mooss-bar__panel a:hover {
    background: #f1f4ef;
  }

  .mooss-bar__panel > ul > li > a[aria-current="page"] {
    box-shadow: inset 3px 0 0 #2f6b3f;
    font-weight: 700;
  }

  .mooss-bar__panel .mooss-bar__sub-m a {
    padding-left: 26px;
    color: #4a544b;
  }

  .mooss-bar__panel-tools {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #dfe5dc;
  }
}
/* mooss-bar:end */
