/* =========================================================================
   pengsilindejiantao.com — 检讨书
   影青 (qingbai glaze) ground · 青花 cobalt · 锔钉 copper
   ========================================================================= */

/* ---- Faces: subsetted static instances, self-hosted -------------------- */
@font-face{font-family:"JT Song";src:url("/fonts/song-400.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"JT Song Light";src:url("/fonts/song-200.woff2") format("woff2");
  font-weight:200;font-style:normal;font-display:swap}
@font-face{font-family:"JT News";src:url("/fonts/news-400.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"JT News";src:url("/fonts/news-400i.woff2") format("woff2");
  font-weight:400;font-style:italic;font-display:swap}

/* ---- Tokens ------------------------------------------------------------ */
:root{
  color-scheme:light dark;

  /* 影青 — the cool, faintly celadon white of Jingdezhen qingbai porcelain */
  --ground:#edf0ee;
  --ink:#161a19;
  --ink-soft:#333b39;
  --muted:#5f6765;
  --rule:#d2d8d4;
  --hair:#c3cac6;
  --cobalt:#26418f;   /* 青花 — the break   */
  --copper:#97703f;   /* 锔钉 — the mend    */
  --select:#dfe4f2;
  --hl1:rgba(38,65,143,.10);
  --hl2:rgba(38,65,143,.17);
  --hl3:rgba(38,65,143,.24);
  --hl4:rgba(38,65,143,.32);

  /* Latin first so ASCII resolves to Newsreader and CJK falls through to Song */
  --ff-body:"JT News","JT Song","Songti SC","Noto Serif CJK SC","Source Han Serif SC",
            "SimSun",serif;
  --ff-display:"JT Song Light","JT Song","Songti SC","Noto Serif CJK SC",serif;
  --ff-news:"JT News",Georgia,"Times New Roman",serif;

  /* Every fluid value is anchored in rem so browser zoom and a raised default
     font size scale it; vw only interpolates between the two rem endpoints.  */
  --fs-micro:clamp(.6875rem,.665rem + .11vw,.75rem);
  --fs-small:clamp(.8125rem,.785rem + .14vw,.875rem);
  --fs-body:clamp(1.0625rem,1.01rem + .26vw,1.1875rem);
  --fs-lede:clamp(1.1875rem,1.09rem + .45vw,1.4375rem);
  --fs-feat:clamp(1.3125rem,1.13rem + .90vw,1.9375rem);
  --fs-sign:clamp(2rem,1.53rem + 2.3vw,3.25rem);
  --fs-title:clamp(3rem,2.05rem + 6.2vw,9rem);

  --space-xs:clamp(.5rem,.44rem + .3vw,.75rem);
  --space-s:clamp(1rem,.82rem + .9vw,1.75rem);
  --space-m:clamp(2rem,1.5rem + 2.5vw,4rem);
  --space-l:clamp(3.75rem,2.6rem + 5.7vw,8rem);
  --space-xl:clamp(6rem,3.9rem + 10.5vw,14rem);

  --pad:clamp(1.25rem,5vw,4rem);
  --measure:38rem;

  /* One track list, reused by every grid on the page, so the cover's spread
     and the body's reading column land on exactly the same vertical lines. */
  --cols:
    [full-start] minmax(var(--pad),1fr)
    [text-start] min(var(--measure),100% - var(--pad) * 2) [text-end]
    minmax(var(--pad),1fr) [full-end];

  --ease:cubic-bezier(.16,1,.3,1);
  --ease-soft:cubic-bezier(.22,.61,.36,1);
}

@media (prefers-color-scheme:dark){
  :root{
    --ground:#101312;
    --ink:#e6eae7;
    --ink-soft:#c3cac6;
    --muted:#8d9793;
    --rule:#262b29;
    --hair:#323836;
    --cobalt:#8aa6e8;
    --copper:#c79a63;
    --select:#22304f;
    --hl1:rgba(138,166,232,.14);
    --hl2:rgba(138,166,232,.22);
    --hl3:rgba(138,166,232,.30);
    --hl4:rgba(138,166,232,.40);
  }
}

/* ---- Reset ------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}

html{
  /* clip, not hidden: no scroll container is created, so position:sticky and
     scroll anchoring keep working while stray overflow is still contained.   */
  overflow-x:clip;
  /* reserve the scrollbar track: the page never jumps sideways when the
     document grows past one viewport.                                       */
  scrollbar-gutter:stable;
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--ground);
  color:var(--ink-soft);
  font-family:var(--ff-body);
  font-weight:400;
  font-size:var(--fs-body);
  line-height:2.05;
  /* only weights 400/200 are shipped — never let the UA fake one */
  font-synthesis:none;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}

h1,p{margin:0}
::selection{background:var(--select);color:var(--ink)}

a{color:inherit;text-decoration:none;border-bottom:1px solid var(--hair);
  transition:border-color .3s var(--ease-soft),color .3s var(--ease-soft)}
a:hover{color:var(--cobalt);border-bottom-color:var(--cobalt)}
:focus-visible{outline:2px solid var(--cobalt);outline-offset:4px;border-radius:2px}

/* =========================================================================
   Sheet — one grid governs every horizontal position on the page.
   The centre track can never exceed the viewport minus its gutters, so
   horizontal overflow is impossible by construction (no clamping hacks).
   ========================================================================= */
.sheet{display:grid;grid-template-columns:var(--cols)}
.sheet > *{grid-column:text}

/* =========================================================================
   开片 — the crack rail (wide viewports only)
   Fixed overlay: entirely out of flow, so it can never shift the text.
   ========================================================================= */
.rail{display:none}

@media (min-width:1024px){
  .rail:not([hidden]){
    display:block;
    position:fixed;
    top:0;bottom:0;
    left:max(1rem,calc(50% - var(--measure) / 2 - 3.9rem));
    width:40px;
    z-index:1;
    pointer-events:none;
    opacity:0;
    transition:opacity .7s var(--ease-soft);
  }
  .rail.is-on{opacity:1}
}

.rail__svg{display:block;width:100%;height:100%;overflow:visible}
.rail__bed{fill:none;stroke:var(--hair);stroke-width:1;stroke-linejoin:miter;opacity:.7}
.rail__cut{
  fill:none;stroke:var(--cobalt);stroke-width:1.1;stroke-linejoin:miter;
  opacity:.9;
  stroke-dasharray:1;
  stroke-dashoffset:calc(1 - var(--p,0));
}

.rail__staples{position:absolute;inset:0}

.staple{
  position:absolute;
  width:28px;height:14px;
  margin:-7px 0 0 -14px;   /* centre on its point */
  opacity:0;
  transform:scale(.6);
  transform-origin:50% 50%;
  transition:opacity .55s var(--ease),transform .55s var(--ease);
}
.staple.is-set{opacity:1;transform:scale(1)}
.staple svg{display:block;width:100%;height:100%;overflow:visible}
.staple path{fill:none;stroke:var(--copper);stroke-width:1.6;stroke-linecap:square}

/* =========================================================================
   Masthead — a running head, not a nav bar.
   ========================================================================= */
.masthead{display:none}

@media (min-width:640px){
  .masthead{
    display:flex;
    justify-content:space-between;
    align-items:baseline;
    gap:var(--space-s);
    position:fixed;
    inset:0 0 auto 0;
    z-index:3;
    padding:.9rem var(--pad);
    background:var(--ground);
    border-bottom:1px solid transparent;
    font-size:var(--fs-micro);
    letter-spacing:.16em;
    line-height:1;
    color:var(--muted);
    pointer-events:none;
    opacity:0;
    transform:translate3d(0,-101%,0);
    transition:opacity .45s var(--ease-soft),transform .55s var(--ease),
               border-color .45s var(--ease-soft);
  }
  .masthead.is-on{opacity:1;transform:translate3d(0,0,0);border-bottom-color:var(--rule)}
}

.masthead__r{font-variant-numeric:tabular-nums}

/* =========================================================================
   Cover
   ========================================================================= */
/* The cover is a spread: its four corners sit on the page margins while the
   title block stays on the same left axis as the body text below it.       */
.cover{
  grid-column:full;
  min-height:100vh;
  min-height:100svh;
  display:grid;
  grid-template-columns:var(--cols);
  grid-template-rows:auto 1fr auto;
  row-gap:var(--space-m);
  padding-block:clamp(1.5rem,3.5vw,3rem);
}

.cover__top,
.cover__bot{
  grid-column:full;
  padding-inline:var(--pad);
  display:flex;
  justify-content:space-between;
  align-items:baseline;
  gap:var(--space-s);
  font-size:var(--fs-small);
  letter-spacing:.14em;
  line-height:1.6;
  color:var(--muted);
}

.cover__no{font-variant-numeric:tabular-nums;text-align:right}

.cover__mid{
  grid-column:text;
  display:grid;
  align-content:center;
  justify-items:start;
  padding-bottom:clamp(0rem,2vw,1.5rem);
}

.cover__title{
  font-family:var(--ff-display);
  font-weight:200;
  font-size:var(--fs-title);
  line-height:1.04;
  letter-spacing:.17em;
  margin-right:-.17em;      /* absorb the trailing track so the block stays optically flush */
  color:var(--ink);
  text-wrap:balance;
}

.cover__bot{align-items:flex-end}

/* Below ~480px the two dateline items would crowd each other on one line. */
@media (max-width:479px){
  .cover__top{flex-direction:column;align-items:flex-start;gap:.3rem}
  .cover__no{text-align:left}
}

.cover__by{display:grid;gap:.35rem;line-height:1.4}
.cover__by-cn{font-size:var(--fs-small);letter-spacing:.22em;color:var(--ink-soft)}
.cover__by-en{
  font-family:var(--ff-news);
  font-size:var(--fs-micro);
  letter-spacing:.3em;
  text-transform:uppercase;
  color:var(--muted);
}

.cover__cue{
  display:grid;
  justify-items:end;
  gap:.85rem;
  font-size:var(--fs-micro);
  letter-spacing:.2em;
  color:var(--muted);
}
.cover__tick{
  position:relative;
  display:block;
  width:1px;
  height:2.75rem;
  background:var(--rule);
  overflow:hidden;
}
.cover__tick i{
  position:absolute;
  inset:0 auto auto 0;
  width:1px;height:38%;
  background:var(--cobalt);
  animation:tick 2.6s var(--ease-soft) infinite;
}
@keyframes tick{
  0%   {transform:translateY(-110%);opacity:0}
  22%  {opacity:1}
  72%  {opacity:1}
  100% {transform:translateY(280%);opacity:0}
}

/* =========================================================================
   Letter — one left axis, a three-step descent in size, nothing else.
   All rules are namespaced under .letter so the size and spacing tiers can
   never be out-specified by the base `.letter p` rule.
   ========================================================================= */
.letter{padding-block:var(--space-xl) 0}

.letter p{
  font-size:var(--fs-body);
  line-height:2.05;
  letter-spacing:.02em;
  color:var(--ink-soft);
  text-align:justify;
  text-justify:inter-ideograph;
  hanging-punctuation:allow-end;
  text-spacing-trim:space-first;
  line-break:strict;
  overflow-wrap:break-word;
}
/* .para wraps each <p> plus its annotation block, so adjacency lives here */
.letter .para + .para{margin-top:1.8em}
.letter .para--lede + .para--rest{margin-top:1.35em}
.letter .para--feature{margin-top:var(--space-m)}
.letter .para--feature + .para{margin-top:var(--space-m)}

.letter .lede{
  font-size:var(--fs-feat);
  line-height:1.72;
  letter-spacing:.015em;
  color:var(--ink);
  text-align:start;
}
.letter .lede-rest{
  font-size:var(--fs-lede);
  line-height:1.92;
  color:var(--ink-soft);
}
.letter .feature{
  font-size:var(--fs-feat);
  line-height:1.72;
  letter-spacing:.015em;
  color:var(--ink);
  text-align:start;
}

.signoff{
  margin-top:var(--space-l);
  text-align:right;
  font-family:var(--ff-news);
  font-style:italic;
  color:var(--ink);
}
.signoff__word{
  display:block;
  font-size:clamp(1.0625rem,1rem + .3vw,1.25rem);
  letter-spacing:.015em;
  color:var(--muted);
}
.signoff__name{
  display:block;
  font-size:var(--fs-sign);
  line-height:1.12;
  margin-top:.1em;
}

/* =========================================================================
   Colophon — the mended spoon, then the facts about the page.
   ========================================================================= */
.colophon{
  padding-block:var(--space-m) var(--space-l);
  text-align:center;
}

.spoon{
  width:clamp(11.5rem,32vw,19rem);
  /* the rem floor grows with the reader's font size; an illustration must not.
     The column is the hard ceiling. */
  max-width:100%;
  margin-inline:auto;
  padding-block:var(--space-l);
}
.spoon svg{display:block;width:100%;height:auto}  /* viewBox holds the box: no CLS */

.spoon__body{
  stroke:var(--muted);stroke-width:1.25;stroke-linejoin:round;
  stroke-dasharray:1;stroke-dashoffset:1;
}
.spoon__well{
  stroke:var(--hair);stroke-width:1;
  stroke-dasharray:1;stroke-dashoffset:1;
}
.spoon__hole{fill:none;stroke:var(--muted);stroke-width:1.1;opacity:0}
.spoon__break{
  stroke:var(--cobalt);stroke-width:1.4;stroke-linejoin:miter;
  stroke-dasharray:1;stroke-dashoffset:1;
}
.spoon__pin{stroke:var(--copper);stroke-width:1.7;stroke-linecap:square;
  opacity:0;transform:scale(.72);transform-origin:50% 50%;transform-box:fill-box}

.reveal-spoon.is-drawn .spoon__body{stroke-dashoffset:0;transition:stroke-dashoffset 1.7s var(--ease) .15s}
.reveal-spoon.is-drawn .spoon__well{stroke-dashoffset:0;transition:stroke-dashoffset 1.1s var(--ease) .85s}
.reveal-spoon.is-drawn .spoon__hole{opacity:1;transition:opacity .5s var(--ease-soft) 1.5s}
.reveal-spoon.is-drawn .spoon__break{stroke-dashoffset:0;transition:stroke-dashoffset .7s var(--ease-soft) 1.85s}
.reveal-spoon.is-drawn .spoon__pin{opacity:1;transform:scale(1);
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.reveal-spoon.is-drawn .spoon__pin:nth-child(1){transition-delay:2.45s}
.reveal-spoon.is-drawn .spoon__pin:nth-child(2){transition-delay:2.62s}

.colophon__line{
  font-size:var(--fs-small);
  letter-spacing:.18em;
  color:var(--ink-soft);
}
.colophon__meta{
  margin-top:.55rem;
  font-size:var(--fs-micro);
  letter-spacing:.16em;
  line-height:2;
  color:var(--muted);
}
.colophon__meta:first-of-type{margin-top:clamp(1.5rem,3.5vw,2.5rem)}

/* =========================================================================
   The annotation layer — highlights, notes, messages.
   What a reader adds is set in the same two faces and the same scale as the
   letter. Nothing here is a card, a bubble or a badge.
   ========================================================================= */

/* 划线 — background only. No padding, no border, no font change, so wrapping
   the letter's own text in <mark> cannot move a single line.               */
mark.hl{
  background:var(--hl1);
  color:inherit;
  padding:0;
  border-radius:0;
}
mark.hl[data-n="2"]{background:var(--hl2)}
mark.hl[data-n="3"]{background:var(--hl3)}
mark.hl[data-n="4"]{background:var(--hl4)}
mark.hl[data-note]{box-shadow:inset 0 -1px 0 var(--cobalt)}  /* box-shadow costs no layout */

.anno[hidden]{display:none}
.anno__toggle{
  appearance:none;background:none;border:0;padding:.7rem 0 0;
  font-family:var(--ff-body);font-size:var(--fs-micro);letter-spacing:.18em;
  color:var(--muted);cursor:pointer;
  transition:color .3s var(--ease-soft);
}
.anno__toggle::before{content:"\2014\2014\00a0"}
.anno__toggle:hover{color:var(--cobalt)}
.anno__toggle.is-open{color:var(--ink-soft)}

.anno__list{
  list-style:none;margin:.9rem 0 0;padding:0 0 0 1.15rem;
  border-left:1px solid var(--rule);
}
.anno__item{margin-bottom:1.3rem}
.anno__item:last-child{margin-bottom:0}
.anno__quote{
  display:block;font-size:var(--fs-small);line-height:1.9;
  color:var(--muted);letter-spacing:.02em;
}
.anno__quote::before{content:"\300c"}
.anno__quote::after{content:"\300d"}
.anno__text{
  display:block;font-size:var(--fs-small);line-height:1.95;
  color:var(--ink-soft);letter-spacing:.02em;margin-top:.25rem;
}
.anno__who{
  display:block;font-size:var(--fs-micro);letter-spacing:.14em;
  color:var(--muted);margin-top:.4rem;
}

/* =========================================================================
   Messages
   ========================================================================= */
.forum{padding-block:var(--space-l) 0}
.forum__title{
  font-size:clamp(1.375rem,1.2rem + .8vw,1.875rem);
  font-weight:400;letter-spacing:.24em;line-height:1.4;
  color:var(--ink);margin:0;
}
.forum__count{
  font-size:var(--fs-micro);letter-spacing:.16em;
  color:var(--muted);margin-top:.9rem;
}

.thread{
  list-style:none;margin:clamp(2rem,5vw,3.5rem) 0 0;padding:0;
  min-height:2rem;            /* a little reserved room so first paint barely moves */
}
.msg{padding-block:clamp(1.25rem,3vw,1.9rem);border-top:1px solid var(--rule)}
.msg:first-child{border-top:0;padding-top:0}
.msg__head{
  display:flex;gap:.9rem;align-items:baseline;
  font-size:var(--fs-micro);letter-spacing:.16em;color:var(--muted);
}
.msg__who{color:var(--ink-soft)}
.msg__body{
  margin-top:.6rem;
  font-size:var(--fs-body);line-height:1.95;letter-spacing:.02em;
  color:var(--ink-soft);
  white-space:pre-wrap;overflow-wrap:break-word;
}

/* =========================================================================
   Fields — a rule under the text, not a box around it.
   ========================================================================= */
.compose{
  margin-top:clamp(2.5rem,6vw,4rem);
  border-top:1px solid var(--rule);
  padding-top:clamp(1.5rem,4vw,2.5rem);
}
.compose__row{display:block;margin-bottom:1.4rem}
.compose__label{
  display:block;font-size:var(--fs-micro);letter-spacing:.2em;
  color:var(--muted);margin-bottom:.55rem;
}
.compose__name,.compose__text{
  display:block;width:100%;box-sizing:border-box;
  appearance:none;background:transparent;border:0;
  border-bottom:1px solid var(--rule);border-radius:0;
  padding:.45rem 0;
  font-family:var(--ff-body);font-size:var(--fs-small);line-height:1.9;
  letter-spacing:.02em;color:var(--ink);
  transition:border-color .3s var(--ease-soft);
}
.compose__text{resize:vertical;min-height:5.4rem}
.compose__name:focus,.compose__text:focus{outline:none;border-bottom-color:var(--cobalt)}
.compose__name::placeholder,.compose__text::placeholder{color:var(--hair)}
.compose__foot{display:flex;justify-content:space-between;align-items:center;gap:1rem}
.compose__hint{font-size:var(--fs-micro);letter-spacing:.14em;color:var(--muted)}

.btn{
  appearance:none;background:transparent;cursor:pointer;
  border:1px solid var(--ink-soft);border-radius:0;
  padding:.62rem 1.5rem;
  font-family:var(--ff-body);font-size:var(--fs-micro);
  letter-spacing:.22em;color:var(--ink);
  transition:background-color .3s var(--ease-soft),color .3s var(--ease-soft),
             border-color .3s var(--ease-soft);
}
.btn:hover{background:var(--ink);color:var(--ground);border-color:var(--ink)}
.btn:disabled{opacity:.4;cursor:default}
.btn--quiet{border-color:var(--rule);color:var(--muted)}
.btn--quiet:hover{background:transparent;color:var(--ink);border-color:var(--ink-soft)}

/* =========================================================================
   Selection toolbar and note sheet — fixed overlays, never in the flow.
   ========================================================================= */
.tools{
  position:fixed;top:0;left:0;z-index:40;
  display:flex;align-items:stretch;
  background:var(--ground);
  border:1px solid var(--rule);
  box-shadow:0 2px 14px rgba(0,0,0,.09);
  will-change:transform;
}
.tools[hidden]{display:none}
.tools__btn{
  appearance:none;background:none;border:0;cursor:pointer;
  padding:.6rem 1.05rem;
  font-family:var(--ff-body);font-size:var(--fs-micro);
  letter-spacing:.18em;color:var(--ink-soft);white-space:nowrap;
}
.tools__btn:hover{color:var(--cobalt)}
.tools__sep{width:1px;background:var(--rule);margin-block:.5rem}

.sheetbox{
  position:fixed;inset:0;z-index:50;
  display:flex;align-items:center;justify-content:center;
  padding:var(--pad);
  background:rgba(18,22,21,.34);
}
.sheetbox[hidden]{display:none}
.sheetbox__card{
  width:min(30rem,100%);
  background:var(--ground);
  border:1px solid var(--rule);
  padding:clamp(1.5rem,4vw,2.25rem);
  max-height:80vh;overflow-y:auto;
}
.sheetbox__title{
  font-size:var(--fs-micro);letter-spacing:.22em;color:var(--muted);
  margin-bottom:1.1rem;
}
.sheetbox__quote{
  margin:0 0 1.6rem;padding:0 0 0 1rem;
  border-left:1px solid var(--cobalt);
  font-size:var(--fs-small);line-height:1.95;letter-spacing:.02em;
  color:var(--ink-soft);
}
@media (max-width:479px){
  .sheetbox{align-items:flex-end;padding:0}
  .sheetbox__card{width:100%;border-left:0;border-right:0;border-bottom:0;max-height:88vh}
}

/* =========================================================================
   Motion — opacity and transform only, so nothing here can move the layout.
   Without JS the .js class is absent and every element renders at rest.
   ========================================================================= */
.js .reveal{opacity:0;transform:translate3d(0,1.15rem,0)}
.js .reveal.is-in{
  opacity:1;transform:translate3d(0,0,0);
  transition:opacity .95s var(--ease-soft),transform 1.05s var(--ease);
}

.js .cover .r-1,
.js .cover .r-2,
.js .cover .r-5{opacity:0;transform:translate3d(0,1.4rem,0)}

.js.is-ready .cover .r-1,
.js.is-ready .cover .r-2,
.js.is-ready .cover .r-5{
  opacity:1;transform:translate3d(0,0,0);
  transition:opacity 1.1s var(--ease-soft),transform 1.25s var(--ease);
}
.js.is-ready .cover .r-1{transition-delay:.05s}
.js.is-ready .cover .r-2{transition-delay:.16s}
.js.is-ready .cover .r-5{transition-delay:.46s}

.cover__fade{will-change:opacity,transform}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  .js .reveal,
  .js .cover .r-1,.js .cover .r-2,.js .cover .r-5{opacity:1;transform:none}
  .spoon__body,.spoon__break,.spoon__well{stroke-dashoffset:0}
  .spoon__pin,.spoon__hole{opacity:1;transform:none}
  .cover__tick i{display:none}
  .rail__cut{--p:1}
  .staple{opacity:1;transform:scale(1)}
}

/* =========================================================================
   Print — it is a letter, after all.
   ========================================================================= */
@media print{
  .rail,.masthead,.cover__cue,.tools,.sheetbox,.compose,.anno__toggle{display:none !important}
  .anno__list{display:block !important}
  html,body{background:#fff;color:#000}
  .cover{min-height:0;page-break-after:always}
  .letter{padding-top:0}
  .letter p,.signoff,.colophon > *{opacity:1 !important;transform:none !important}
  .spoon__body,.spoon__break,.spoon__well{stroke-dashoffset:0}
  .spoon__pin,.spoon__hole{opacity:1;transform:none}
}
