/* 鱼の琴 · keepsake.css — 信笺 (the vertical envelope and the 八行笺 letter) and 墨迹 (the ink calendar in 曲库).
   Tokens come from app.css. Motion animates transform and opacity only; prefers-reduced-motion fades only.
   The sheet geometry (760×600, eight 82 px columns, 473 px text height) matches SHEET in keepsake.js. */

/* ---------- Layer: above the drawer (60) and dialogs (80), below the love note (95) and toasts ---------- */
.ksLayer{position:fixed;inset:0;z-index:90;outline:none;font-family:var(--font);color:var(--ink);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.ksScrim{position:absolute;inset:0;background:rgba(43,34,22,.38);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:ksFadeIn .32s ease-out both}
.ksLayer:is([data-stage=leaving],[data-stage=closing]) .ksScrim{animation:ksFadeOut .3s ease-in both}
.ksLayer[data-stage=stowing] .ksScrim{animation:ksFadeOut .52s ease-in both}
.ksStageEnv,.ksStageLetter{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}
.ksStageEnv>*,.ksStageLetter>*{pointer-events:auto}
.ksLayer:is([data-stage=envelope],[data-stage=leaving]) .ksStageLetter{display:none}
.ksLayer:not([data-stage=envelope]):not([data-stage=leaving]):not([data-stage=opening]) .ksStageEnv{display:none}

/* ---------- The envelope: 300×470, a double cinnabar window, the 缄 seal on the flap ---------- */
.ksStageEnv{gap:30px}
.ksEnvelopeWrap{width:300px;height:470px;transform:rotate(-2deg);animation:ksDrop .6s cubic-bezier(.2,.8,.2,1) both}
.ksEnvelope{position:relative;display:block;width:300px;height:470px;padding:0;border-radius:4px;cursor:pointer;transform:scale(var(--ke,1));transform-origin:50% 50%;font:inherit;color:inherit}
.ksEnvelope:focus-visible{outline:2px solid #FBF8F1;outline-offset:6px}
.ksEnvelope>span{position:absolute;display:block}
.ksEnvFront{inset:0;border-radius:4px;background:#F7F0E2 var(--fibre);box-shadow:0 30px 60px rgba(29,26,22,.30),0 2px 6px rgba(29,26,22,.12),inset 0 0 0 1px rgba(120,96,60,.12),inset 0 1px 0 rgba(255,255,255,.55)}
.ksFlap,.ksFlapIn{left:0;right:0;top:0;height:124px;transform-origin:50% 0;pointer-events:none}
.ksFlap{filter:drop-shadow(0 1px 0 rgba(120,96,60,.20)) drop-shadow(0 4px 5px rgba(29,26,22,.07))}
.ksFlap::before,.ksFlapIn::before{content:'';position:absolute;inset:0;clip-path:polygon(0 0,100% 0,100% 58%,50% 100%,0 58%)}
.ksFlap::before{background:linear-gradient(180deg,#EDE2CC,#F3EADA 78%,#F1E7D5)}
.ksFlapIn{opacity:0;transform:perspective(800px) rotateX(90deg)}
.ksFlapIn::before{background:#E6D9C0 var(--fibre)}
/* The folded letter waits inside; its frame and 朱丝栏 peek out when it slides up. */
.ksInner{left:20px;right:20px;top:10px;height:300px;border-radius:2px;background:#FFFBF2 var(--fibre);box-shadow:0 0 0 1px rgba(120,96,60,.10),0 1px 3px rgba(29,26,22,.10)}
.ksInner i{position:absolute;left:16px;right:16px;top:18px;height:150px;border:1px solid rgba(178,58,41,.55);border-bottom:0;background:repeating-linear-gradient(to left,transparent 0 28px,rgba(178,58,41,.34) 28px 29px)}
.ksWindow{position:absolute;left:104px;top:162px;width:92px;height:240px;border:1.5px solid var(--cinnabar);outline:1px solid rgba(178,58,41,.42);outline-offset:4px}
.ksWindow b{position:absolute;left:50%;top:46px;transform:translateX(-50%);writing-mode:vertical-rl;font:500 31px/1 var(--font);letter-spacing:.34em;color:var(--ink)}
.ksWindow small{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);writing-mode:vertical-rl;font:500 15px/1 var(--font);letter-spacing:.32em;color:var(--cinnabar-ink)}
.ksFrom{position:absolute;left:24px;bottom:24px;display:flex;flex-direction:column;align-items:center;gap:12px}
.ksPairBox{display:block;width:24px;height:24px;opacity:.82}
.ksPair{display:block;width:100%;height:100%}
.ksFromText{writing-mode:vertical-rl;font:400 13px/1 var(--font);letter-spacing:.3em;color:var(--ink-3)}
.ksJian{left:121px;top:94px;width:58px;height:58px;mix-blend-mode:multiply;pointer-events:none}
.ksJianArt{display:block;width:100%;height:100%}
.ksJianArt text{font-family:var(--font)}
.ksHint{font:400 15px/1 var(--font);letter-spacing:.26em;text-indent:.26em;color:#FBF8F1;text-shadow:0 1px 8px rgba(29,26,22,.45);animation:ksFadeIn .5s .45s ease-out both,ksBreathe 3.2s 1.2s ease-in-out 6}

/* Opening: the seal presses and fades, the flap opens, the letter slides out, the envelope leaves. */
/* The hint breathes six times (about 20 s, like the 15 s ambient quiet window) while the envelope waits,
   then rests at full opacity; with 小鱼动效 off (body.ambient-off) it stays still. */
.ambient-off .ksHint{animation:ksFadeIn .5s .45s ease-out both}
.ksLayer[data-stage=opening] .ksJian{animation:ksPress .12s ease-out both,ksFadeOut .16s .12s ease-in both}
.ksLayer[data-stage=opening] .ksFlap{animation:ksFlapUp .13s .12s cubic-bezier(.5,0,1,1) both}
.ksLayer[data-stage=opening] .ksFlapIn{animation:ksFlapOver .15s .25s cubic-bezier(0,0,.4,1) both}
.ksLayer[data-stage=opening] .ksInner{animation:ksSlideOut .32s .38s cubic-bezier(.2,.8,.2,1) both}
.ksLayer[data-stage=opening] .ksHint{animation:ksFadeOut .16s ease-in both}
.ksLayer[data-stage=opening] .ksEnvelopeWrap{animation:ksAway .3s .66s ease-in both}
.ksLayer[data-stage=leaving] .ksEnvelopeWrap{animation:ksAway .28s ease-in both}
.ksLayer[data-stage=leaving] .ksHint{animation:ksFadeOut .16s ease-in both}
/* While the envelope is on screen the letter stage overlaps it, so it sits on top only once it unfolds. */
.ksLayer[data-stage=opening] .ksStageLetter{z-index:1}

/* ---------- The letter: 八行笺, ivory paper, a double cinnabar frame and eight 朱丝栏 columns ---------- */
.ksStageLetter{gap:22px}
.ksSheetsBox{position:relative;flex:none;width:calc(760px * var(--k,1));height:calc(600px * var(--k,1))}
.ksSheets{position:absolute;left:0;top:0;width:760px;height:600px;transform:scale(var(--k,1));transform-origin:0 0}
.ksSheets.paged::before{content:'';position:absolute;inset:0;border-radius:3px;background:#F8F1E3 var(--fibre);box-shadow:0 22px 50px rgba(29,26,22,.22),0 0 0 1px rgba(120,96,60,.08);transform:translate(-10px,8px) rotate(-1.3deg)}
.ksSheet{position:absolute;inset:0;border-radius:3px;background:#FFFBF2 var(--fibre);box-shadow:0 30px 70px rgba(29,26,22,.32),0 2px 6px rgba(29,26,22,.12),inset 0 0 0 1px rgba(120,96,60,.06)}
.ksFrame{position:absolute;left:50.5px;top:44px;width:659px;height:512px;border:1.5px solid rgba(178,58,41,.62);outline:1px solid rgba(178,58,41,.32);outline-offset:5px;background:repeating-linear-gradient(to left,transparent 0 81px,rgba(178,58,41,.42) 81px 82px) right top/574px 100% no-repeat}
.ksCol{position:absolute;top:17px;width:82px;height:473px;margin:0;overflow:visible;writing-mode:vertical-rl;white-space:nowrap;font:400 23px/82px var(--font);letter-spacing:.2em;color:#24201B;-webkit-user-select:text;user-select:text}
.ksCol.ksLead{font-weight:600;color:var(--ink)}
.ksClosing{position:absolute;left:0;top:17px;bottom:8px;width:82px;display:flex;flex-direction:row-reverse;justify-content:center;align-items:flex-end;gap:5px;padding-bottom:58px}
.ksSig{writing-mode:vertical-rl;font:500 17px/1 var(--font);letter-spacing:.34em;color:var(--ink-2)}
.ksDate{writing-mode:vertical-rl;font:400 14px/1 var(--font);letter-spacing:.3em;color:var(--ink-3)}
.ksMarkBox{position:absolute;left:50%;bottom:6px;width:40px;height:40px;margin-left:-20px;transform:rotate(-6deg);mix-blend-mode:multiply;opacity:.94}
.ksMark{display:block;width:100%;height:100%;color:var(--cinnabar,#B23A29)}
.ksCrease{position:absolute;left:0;right:0;top:50%;height:1px;background:linear-gradient(90deg,transparent,rgba(120,96,60,.15) 7%,rgba(120,96,60,.15) 93%,transparent);pointer-events:none}
.ksShade{position:absolute;inset:0;border-radius:3px;background:linear-gradient(180deg,rgba(29,26,22,0) 26%,rgba(29,26,22,.13) 49.5%,rgba(255,255,255,.18) 50.5%,rgba(29,26,22,0) 74%);opacity:0;pointer-events:none}
.ksPage{position:absolute;bottom:0;height:44px;padding:0 14px;display:inline-flex;align-items:center;gap:2px;font:500 13px/44px var(--font);letter-spacing:.16em;color:var(--cinnabar-ink);border-radius:10px}
.ksPage .ic{width:15px;height:15px}
.ksPage.ksNext{left:30px}
.ksPage.ksPrev{right:30px}
.ksPage:active{opacity:.6}
.ksActions{display:flex;gap:12px;flex:none}
.ksBtn{height:44px;min-width:132px;padding:0 24px;border-radius:12px;background:var(--paper-raised);box-shadow:inset 0 0 0 1px var(--rule-2),0 8px 22px rgba(29,26,22,.16);font:500 15px/44px var(--font);letter-spacing:.08em;color:var(--ink)}
.ksBtn.primary{background:var(--ink);color:#FBF8F1;box-shadow:0 8px 22px rgba(29,26,22,.24)}
.ksBtn:active{background:#ECE5D7}
.ksBtn.primary:active{background:#3A342D}
.ksBtn:focus-visible,.ksPage:focus-visible{outline:2px solid #FBF8F1;outline-offset:3px}

/* Unfolding (after the envelope, or straight away when she opens it again) */
.ksLayer[data-stage=opening] .ksSheet:not([hidden]){animation:ksUnfold .36s .62s cubic-bezier(.2,.8,.2,1) both}
.ksLayer[data-stage=opening] .ksShade{animation:ksCrease .36s .62s ease-out both}
.ksLayer[data-stage=opening] .ksActions,.ksLayer[data-stage=opening] .ksSheets.paged::before{animation:ksFadeIn .26s .9s ease-out both}
.ksLayer[data-stage=unfolding] .ksSheet:not([hidden]){animation:ksUnfold .36s cubic-bezier(.2,.8,.2,1) both}
.ksLayer[data-stage=unfolding] .ksShade{animation:ksCrease .36s ease-out both}
.ksLayer[data-stage=unfolding] .ksActions,.ksLayer[data-stage=unfolding] .ksSheets.paged::before{animation:ksFadeIn .26s .24s ease-out both}
/* Folding away (去弹琴, a piano key, Escape) and turning a sheet */
.ksLayer[data-stage=closing] .ksSheet:not([hidden]){animation:ksFold .3s cubic-bezier(.4,0,1,1) both}
.ksLayer[data-stage=closing] .ksActions,.ksLayer[data-stage=stowing] .ksActions,.ksLayer:is([data-stage=closing],[data-stage=stowing]) .ksSheets.paged::before{animation:ksFadeOut .18s ease-in both}
.ksSheet.ksOut{animation:ksTurnOut .22s cubic-bezier(.4,0,1,1) both}
.ksSheet.ksIn{animation:ksTurnIn .26s cubic-bezier(.2,.8,.2,1) both}

@keyframes ksFadeIn{from{opacity:0}to{opacity:1}}
@keyframes ksFadeOut{from{opacity:1}to{opacity:0}}
@keyframes ksDrop{0%{opacity:0;transform:translateY(-46px) rotate(-7deg)}45%{opacity:1}100%{opacity:1;transform:rotate(-2deg)}}
@keyframes ksBreathe{0%,100%{opacity:1}50%{opacity:.58}}
@keyframes ksPress{from{transform:scale(1)}to{transform:scale(.94)}}
@keyframes ksFlapUp{from{transform:perspective(800px) rotateX(0deg)}to{transform:perspective(800px) rotateX(90deg)}}
@keyframes ksFlapOver{from{opacity:1;transform:perspective(800px) rotateX(90deg)}to{opacity:1;transform:perspective(800px) rotateX(180deg)}}
@keyframes ksSlideOut{from{transform:translateY(0)}to{transform:translateY(-120px)}}
@keyframes ksAway{from{opacity:1;transform:rotate(-2deg)}to{opacity:0;transform:translateY(40px) rotate(-4deg)}}
@keyframes ksUnfold{0%{opacity:0;transform:translateY(-26px) scaleY(.5)}28%{opacity:1}100%{opacity:1;transform:none}}
@keyframes ksCrease{from{opacity:1}to{opacity:0}}
@keyframes ksFold{from{opacity:1;transform:none}to{opacity:0;transform:translateY(20px) scaleY(.5)}}
@keyframes ksTurnOut{from{opacity:1;transform:none}to{opacity:0;transform:translateX(26px)}}
@keyframes ksTurnIn{from{opacity:0;transform:translateX(-12px)}to{opacity:1;transform:none}}

/* ---------- 曲库: the envelope icon after the title (only when a letter exists) ---------- */
.ksLetterButton{position:relative;color:var(--cinnabar-ink)}
.ksLetterButton .ksDot{position:absolute;top:9px;right:9px;width:8px;height:8px;border-radius:50%;background:var(--cinnabar);box-shadow:0 0 0 2px var(--paper-raised);display:none}
.ksLetterButton.unread .ksDot{display:block}

/* ---------- 墨迹: the ink-drop calendar after the practice stats ---------- */
.ksInk{margin-top:12px;max-width:320px}
.ksInkHead{display:flex;align-items:center;height:44px;margin:0 -10px 0 0}
.ksInkHead .ksInkTitle{flex:1 1 auto;min-width:0;margin:0}
.ksInkHead .btn.icon{color:var(--ink-3)}
.ksInkHead .btn.icon:disabled{color:var(--ink-4);opacity:.45}
.ksInkGrid svg{display:block;width:100%;height:auto;overflow:visible}
.ksInkGrid .ksDow{font:500 9.5px var(--font);fill:var(--ink-4);letter-spacing:.06em}
.ksInkGrid .ksNum{font:400 10.5px var(--font);fill:var(--ink-3)}
.ksInkGrid .ksNum.ksFuture{fill:var(--ink-4);opacity:.55}
.ksInkGrid .ksNum.ksTodayNum{fill:var(--cinnabar-ink);font-weight:600;opacity:1}
.ksInkGrid .ksNum.ksOnInk{fill:var(--ink);font-weight:600}
.ksInkGrid .ksNum.ksOnInk.ksTodayNum{fill:var(--cinnabar-ink)}
.ksInkSum{margin-top:8px;font:400 12px/1.65 var(--font);color:var(--ink-2)}
.ksInkSum b{font-weight:600;color:var(--ink)}
.ksInkSum{overflow:hidden}
.ksInkSum .ksSumIn{display:block;margin-left:-1.4em}
.ksInkSum .ksPhrase{display:inline-block;margin-left:1.4em;white-space:nowrap}
.ksInkSum .ksPhrase+.ksPhrase::before{content:"·";display:inline-block;width:1.4em;margin-left:-1.4em;text-align:center;color:var(--ink-4)}

/* ---------- prefers-reduced-motion: nothing moves, the letter simply fades in ---------- */
@media (prefers-reduced-motion:reduce){
  .ksEnvelopeWrap{transform:rotate(-2deg);animation:ksFadeIn .24s ease-out both}
  .ksHint{animation:ksFadeIn .24s ease-out both}
  .ksLayer[data-stage=opening] :is(.ksJian,.ksFlap,.ksFlapIn,.ksInner,.ksShade){animation:none}
  .ksLayer:is([data-stage=opening],[data-stage=leaving]) .ksEnvelopeWrap,.ksLayer:is([data-stage=opening],[data-stage=leaving]) .ksHint{animation:ksFadeOut .2s ease-in both}
  .ksLayer:is([data-stage=opening],[data-stage=unfolding]) .ksSheet:not([hidden]),.ksLayer:is([data-stage=opening],[data-stage=unfolding]) .ksActions,.ksLayer:is([data-stage=opening],[data-stage=unfolding]) .ksSheets.paged::before{animation:ksFadeIn .22s ease-out both}
  .ksLayer[data-stage=unfolding] .ksShade{animation:none}
  .ksLayer[data-stage=closing] .ksSheet:not([hidden]){animation:ksFadeOut .2s ease-in both}
  .ksLayer[data-stage=stowing] .ksSheet:not([hidden]){animation:ksFadeOut .2s ease-in both}
  .ksLayer[data-stage=stowing] .ksScrim{animation:ksFadeOut .2s ease-in both}
  .ksSheet.ksOut{animation:ksFadeOut .16s ease-in both}
  .ksSheet.ksIn{animation:ksFadeIn .16s ease-out both}
}
