@font-face { font-family: "Homemade Apple"; src: url("assets/homemade-apple.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "SN Pro"; src: url("assets/sn-pro.woff2") format("woff2"); font-style: normal; font-weight: 100 900; font-display: swap; }
:root {
  color-scheme: light;
  --ink: #09090b;
  --body: #71717a;
  --line: #e4e4e7;
  --surface: #fafaf9;
  --paper: #ffffff;
  --button: #27272a;
  --button-ink: #ffffff;
  --button-hover: #3f3f46;
  --paper-rgb: 255 255 255;
  --dialog-paper: #ffffff;
  --dialog-shadow: 0 12px 32px rgb(9 9 11 / .18), 0 2px 8px rgb(9 9 11 / .06);
  --marker: #ffd43b;
  --marker-ink: #09090b;
  --sans: "SN Pro", -apple-system, BlinkMacSystemFont, "PingFang SC", "Segoe UI", Helvetica, Arial, sans-serif;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --marker-ink: #18181b;
  --ink: #f4f4f5;
  --body: #b0b0b9;
  --line: #343438;
  --surface: #242427;
  --paper: #151517;
  --button: #ededf0;
  --button-ink: #18181b;
  --button-hover: #ffffff;
  --paper-rgb: 21 21 23;
  --dialog-paper: #1b1b1e;
  --dialog-shadow: 0 12px 40px rgb(0 0 0 / .45), 0 2px 8px rgb(0 0 0 / .24);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 24px; scrollbar-gutter: stable; }
body { margin: 0; background: var(--paper); color: var(--body); font-family: var(--sans); font-size: 15px; line-height: 28px; -webkit-font-smoothing: antialiased; }
button, input { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
button { color: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
h1, h2, p, figure { margin: 0; }
h1, h2 { color: var(--ink); font: 500 15px/28px var(--sans); }
strong { color: var(--ink); font-weight: 500; }
button:focus-visible, a:focus-visible, input:focus-visible { outline: 2px solid var(--body); outline-offset: 4px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; top: -60px; left: 24px; z-index: 100; padding: 8px 12px; color: var(--paper); background: var(--ink); }
.skip-link:focus { top: 12px; }
.page-sheet { width: 100%; max-width: 598px; margin-inline: auto; padding: 80px 24px 180px; }
.site-header { position: relative; display: flex; align-items: center; gap: 16px; min-height: 40px; width: 100%; }
.brand { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-size: 16px; font-weight: 500; white-space: nowrap; }
/* Pull the logo and toggle outward by their built-in padding so the visible marks line up with the column edges. */
.brand-logo { width: 40px; height: 40px; margin-left: -8px; flex-shrink: 0; object-fit: contain; filter: grayscale(1) brightness(1.02); }
:root[data-theme="dark"] .brand-logo { filter: grayscale(1) contrast(1.1) invert(1) brightness(1.6); mix-blend-mode: screen; }
.brand-avatar { width: 24px; height: 24px; margin-right: 2px; flex-shrink: 0; border-radius: 50%; object-fit: cover; }
.theme-toggle { position: absolute; right: -13.5px; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 2px; color: var(--body); background: transparent; }
.theme-toggle svg { position: absolute; width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: opacity 140ms ease; }
.theme-sun { opacity: 0; }
:root[data-theme="dark"] .theme-moon { opacity: 0; }
:root[data-theme="dark"] .theme-sun { opacity: 1; }
.theme-toggle:active { background: var(--surface); }
@media (hover: hover) and (pointer: fine) {
  .theme-toggle:hover { color: var(--ink); background: var(--surface); }
}
.button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 40px; padding: 6px 16px; color: var(--button-ink); background: var(--button); border: 0; border-radius: 2px; font-size: 15px; line-height: 28px; white-space: nowrap; transition: background .15s, transform .15s; }
.button:hover { background: var(--button-hover); }
.button:active { transform: translateY(1px); }
.theme-changing .button { transition-property: transform; }
.button-arrow { display: block; width: 14px; height: 14px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
main { display: flex; flex-direction: column; gap: 40px; padding-top: 48px; }
main > section { display: flex; flex-direction: column; gap: 24px; width: 100%; }
.flow { width: 100%; }
.flow > .prose { margin-top: 24px; }
.hero-copy, .author-copy { display: flex; flex-direction: column; gap: 24px; }
.prose { display: flex; flex-direction: column; gap: 16px; }
:where(p):has(> .marker) { isolation: isolate; }
.marker { position: relative; transition: color 700ms ease-out; }
.marker.is-drawn { color: var(--marker-ink); }
.marker-svg { position: absolute; z-index: -1; top: 0; left: 0; width: 1px; height: 1px; overflow: visible; pointer-events: none; }
.marker-svg path { fill: none; stroke: var(--marker); }
.inline-link { color: inherit; text-decoration: underline; text-decoration-color: var(--line); text-decoration-thickness: 1px; text-underline-offset: 4px; transition: color .15s, text-decoration-color .15s; }
.inline-link:hover { color: var(--ink); text-decoration-color: currentColor; }
.inline-link::after {
  content: ""; display: inline-block; width: 10px; height: 10px; margin-left: 2px; vertical-align: 1px;
  background: var(--body); transition: transform .15s, background-color .15s;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6'%3E%3Cpath d='M4 12 12 4M5 4h7v7'/%3E%3C/svg%3E") center / contain no-repeat;
}
.inline-link:hover::after { transform: translate(1px, -1px); background: var(--ink); }
.small-copy { color: var(--body); font-size: 13px; line-height: 20px; }
.media-frame { width: 100%; aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface); }
.media-frame > img { width: 100%; height: 100%; object-fit: contain; }
.media-frame--bordered { position: relative; }
.media-frame--bordered::after { content: ""; position: absolute; inset: 0; border: 1px solid rgb(0 0 0 / 4%); pointer-events: none; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .media-frame > img { transition: transform 600ms cubic-bezier(.25, .1, .25, 1); transform-origin: center; }
  .media-frame:hover > img { transform: scale(1.09); }
}

.final-section { align-items: flex-start; }
.final-section > .flow { display: flex; flex-direction: column; }
.final-section .prose { margin-top: 24px; margin-bottom: 24px; }
.final-section .prose:last-child { margin-bottom: 0; }

.site-footer {
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  margin-top: 64px; padding-top: 64px; border-top: 1px dashed var(--line);
  color: var(--body); font-size: 14px; line-height: 24px; text-align: center;
}
.footer-sign { display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--body); transition: color .15s; }
.footer-sign:hover { color: var(--ink); }
.footer-pen { width: 56px; height: 56px; filter: contrast(1.4); mix-blend-mode: multiply; transform-origin: 30% 90%; transition: transform .3s cubic-bezier(.16, 1, .3, 1); }
.footer-sign:hover .footer-pen { transform: rotate(-6deg); }
:root[data-theme="dark"] .footer-pen { filter: contrast(1.4) invert(1) brightness(1.6); mix-blend-mode: screen; }
.footer-name { font-family: "Homemade Apple", cursive; font-size: 18px; line-height: 36px; }

.footer-progressive-blur {
  position: fixed;
  z-index: 20;
  right: 0;
  bottom: 0;
  left: 0;
  height: 160px;
  pointer-events: none;
  transition: opacity 180ms ease, visibility 180ms ease;
}
.footer-progressive-blur span {
  position: absolute;
  z-index: var(--blur-layer);
  inset: 0;
  -webkit-backdrop-filter: blur(var(--blur-radius));
  backdrop-filter: blur(var(--blur-radius));
  -webkit-mask-image: var(--blur-mask);
  mask-image: var(--blur-mask);
}
.footer-progressive-blur span:nth-child(1) { --blur-layer: 1; --blur-radius: .1875px; --blur-mask: linear-gradient(transparent 0%, #000 12.5%, #000 25%, transparent 37.5%); }
.footer-progressive-blur span:nth-child(2) { --blur-layer: 2; --blur-radius: .375px; --blur-mask: linear-gradient(transparent 12.5%, #000 25%, #000 37.5%, transparent 50%); }
.footer-progressive-blur span:nth-child(3) { --blur-layer: 3; --blur-radius: .75px; --blur-mask: linear-gradient(transparent 25%, #000 37.5%, #000 50%, transparent 62.5%); }
.footer-progressive-blur span:nth-child(4) { --blur-layer: 4; --blur-radius: 1.5px; --blur-mask: linear-gradient(transparent 37.5%, #000 50%, #000 62.5%, transparent 75%); }
.footer-progressive-blur span:nth-child(5) { --blur-layer: 5; --blur-radius: 3px; --blur-mask: linear-gradient(transparent 50%, #000 62.5%, #000 75%, transparent 87.5%); }
.footer-progressive-blur span:nth-child(6) { --blur-layer: 6; --blur-radius: 6px; --blur-mask: linear-gradient(transparent 62.5%, #000 75%, #000 87.5%, transparent 100%); }
.footer-progressive-blur span:nth-child(7) { --blur-layer: 7; --blur-radius: 12px; --blur-mask: linear-gradient(transparent 75%, #000 87.5%, #000 100%); }
.footer-progressive-blur span:nth-child(8) { --blur-layer: 8; --blur-radius: 24px; --blur-mask: linear-gradient(transparent 87.5%, #000 100%); }
.footer-progressive-blur::after {
  position: absolute;
  z-index: 9;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgb(var(--paper-rgb) / 0) 0%,
    rgb(var(--paper-rgb) / .3) 40%,
    rgb(var(--paper-rgb) / .8) 75%,
    rgb(var(--paper-rgb) / .98) 100%
  );
  content: "";
}

.floating-join-wrap {
  position: fixed;
  z-index: 30;
  bottom: 48px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  pointer-events: none;
  transition: transform 500ms cubic-bezier(.76, 0, .24, 1), opacity 220ms ease, visibility 220ms ease;
}
.floating-join {
  pointer-events: auto;
  min-height: 44px;
  padding: 0 24px;
  font-size: 15px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18), 0 2px 6px rgba(0, 0, 0, .08);
}
.has-join-dialog .floating-join-wrap,
.has-join-dialog .footer-progressive-blur { visibility: hidden; opacity: 0; pointer-events: none; }
.has-join-dialog .floating-join-wrap { transform: translateY(10px); }
.join-dialog { position: fixed; inset: auto 0 48px; width: min(360px, calc(100% - 32px)); max-height: calc(100dvh - 96px); margin: 0 auto; padding: 24px; border: 0; border-radius: 0; background: var(--dialog-paper); box-shadow: var(--dialog-shadow); color: var(--body); overflow-y: auto; overscroll-behavior: contain; transform-origin: bottom center; }
.join-dialog:focus { outline: none; }
.join-dialog::backdrop { background: rgb(var(--paper-rgb) / .25); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); animation: join-backdrop-in 180ms ease; }
.join-dialog.is-closing::backdrop { animation: join-backdrop-out 180ms ease forwards; }
@keyframes join-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes join-backdrop-out { from { opacity: 1; } to { opacity: 0; } }
.dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.dialog-close { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; background: none; border: 0; color: var(--body); }
.dialog-close:hover { color: var(--ink); background: var(--surface); }
.dialog-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.contact-methods { display: flex; gap: 8px; min-width: 0; padding: 0; border: 0; border-radius: 0; margin: 16px 0; }
.contact-methods label { position: relative; flex: 1; font-size: 13px; cursor: pointer; text-align: center; }
.contact-methods input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.contact-methods span { display: grid; place-items: center; min-height: 38px; padding: 5px 8px; }
.contact-methods label:hover span { background: var(--surface); }
.contact-methods input:checked + span { background: var(--surface); color: var(--ink); }
.contact-methods input:focus-visible + span { outline: 2px solid var(--body); outline-offset: -3px; }
/* The QR image carries a white margin of its own (7 of its 400px) that light mode blends away; a negative margin pulls it back so gaps are measured from the code itself. */
.qr-sheet { --qr-size: 200px; --qr-quiet: calc(var(--qr-size) * 7 / 400); position: relative; padding: 20px; background: var(--surface); text-align: center; }
.qr-sheet img { width: var(--qr-size); height: var(--qr-size); object-fit: contain; margin: calc(-1 * var(--qr-quiet)) auto; mix-blend-mode: multiply; }
/* Dark mode shows the code as issued, on a white tile: an inverted or blended code is risky to scan, and scanners need a light margin around it.
   The tile edge is what the eye sees there, so the margin pull-back is dropped. */
:root[data-theme="dark"] .qr-sheet img { margin-block: 0; padding: 10px; background: #fff; mix-blend-mode: normal; }
/* Both channels share one grid cell, so switching tabs keeps the panel the same height. */
.contact-channels { display: grid; }
.contact-channels > .qr-sheet { grid-area: 1 / 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding-bottom: 24px; }
.contact-channels > :not(.is-active) { visibility: hidden; }
/* The email panel has no QR margin to make up for, so it pads evenly and its content stays centred. */
/* Email content stands on the panel itself, with no tiles; the address sits closer to the icon than to the button. */
.contact-channels > [data-contact-channel="email"] { padding-top: 24px; gap: 16px; }
[data-contact-channel="email"] .button { margin-top: 8px; }
/* The panel top, the code, the ID and the panel bottom sit the same 24px apart by eye.
   The ID's letters start 6px below the top of its 22px line and end 3px above its bottom, so those come off the gap and the bottom padding. */
.contact-channels > [data-contact-channel="wechat"] { --qr-gap: 24px; padding-top: var(--qr-gap); padding-bottom: calc(var(--qr-gap) - 3px); gap: calc(var(--qr-gap) - 6px); }
/* The ID and address are what people copy, so they read at the same size as the product chips. */
.qr-sheet .copy-id { gap: 6px; font-size: 14px; line-height: 22px; }
.qr-sheet .copy-id svg { width: 14px; height: 14px; }
.contact-mail-icon { display: block; color: var(--ink); }
.contact-mail-icon svg { display: block; width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.contact-note { margin-top: 16px; text-align: center; font-size: 13px; line-height: 22px; }
.copy-id { display: inline-flex; align-items: center; gap: 5px; padding: 1px 7px; border: 0; border-radius: 0; background: var(--surface); color: var(--ink); font-size: 12px; line-height: 20px; vertical-align: baseline; }
.copy-id svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.copy-id.is-copied svg { display: none; }
.copy-id.is-copied::after { content: "✓"; color: var(--body); }
.copy-status:not(.sr-only) { margin-top: 12px; }
.dialog-foot { margin-top: 16px; padding-top: 16px; border-top: 1px dashed var(--line); color: var(--body); font-size: 12px; line-height: 20px; text-align: center; }
@media (max-width: 639px) {
  .page-sheet { padding-top: 64px; padding-bottom: calc(180px + env(safe-area-inset-bottom, 0px)); }
  .site-header { gap: 12px; }
  .qr-sheet { --qr-size: 176px; padding-inline: 16px; }
  .join-dialog { bottom: calc(24px + env(safe-area-inset-bottom, 0px)); max-height: calc(100dvh - 48px - env(safe-area-inset-bottom, 0px)); }
  .payment-sheet { --qr-top: 14px; --qr-size: 176px; padding-inline: 16px; }
  .payment-sheet p { margin-top: 5px; }
}
@media (max-width: 359px) {
  .site-header { gap: 8px; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .001ms !important; animation-duration: .001ms !important; }
}
@media print {
  .site-header, .floating-join-wrap, .footer-progressive-blur, .join-dialog, .skip-link { display: none; }
  .page-sheet { padding-block: 0; }
  main { padding-top: 0; }
}

/* 作品保留原比例，沿用产品模板的悬停放大。 */
.case-link { align-self: flex-start; }
.case-cover { display: block; }
.case-cover > img { cursor: pointer; }
.qr-sheet .button { min-height: 32px; padding: 2px 12px; gap: 6px; font-size: 14px; }
.qr-sheet .button-arrow { width: 12px; height: 12px; }
