/* Page, fixed 1440×900 stage, WPS window chrome and transport.
   No CSS animations or transitions anywhere: every moving value is written by render(t). */
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:#f3f4f6;color:#262626;font-family:-apple-system,'PingFang SC','Microsoft YaHei','Helvetica Neue',sans-serif;overflow-x:hidden}
.page{min-height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:16px}
body.embed .page{padding:0;gap:0;background:transparent}
body.embed{background:transparent}
body.embed .transport{display:none}
body.embed .stage-fit{box-shadow:none}

.stage-fit{position:relative;flex:none;overflow:hidden;border-radius:14px;box-shadow:0 1px 2px #0000000f,0 12px 40px #0000001a}
.stage{position:absolute;left:0;top:0;width:1440px;height:900px;transform-origin:0 0;background:#fff;overflow:hidden;display:flex;flex-direction:column}

/* Title bar with traffic lights and file tabs */
.win-top{height:44px;flex:none;display:flex;align-items:flex-end;gap:14px;padding:0 16px;background:#eceef1;font-size:12px;color:#5b6168}
.traffic{display:flex;gap:7px;align-self:center}
.traffic i{width:11px;height:11px;border-radius:50%;background:#ff5f57}
.traffic i:nth-child(2){background:#febc2e}.traffic i:nth-child(3){background:#28c840}
.wps-label{align-self:center;font-weight:500;margin-right:6px}
.tabs{display:flex;align-items:flex-end;height:36px;gap:2px}
.tab{--tab-color:#208259;--tab-tint:#edf7f1;position:relative;height:34px;width:200px;display:flex;align-items:center;gap:8px;padding:0 14px;border:0;border-radius:7px 10px 0 0;background:#e3e6ea;color:#56606e;font:inherit;font-size:12px;white-space:nowrap;overflow:hidden;cursor:pointer;transform-origin:50% 100%}
.tab[data-kind="word"]{--tab-color:#3978d4;--tab-tint:#edf3ff}
.tab[data-kind="ppt"]{--tab-color:#ce7149;--tab-tint:#fff2eb}
.tab.active{background:var(--tab-tint);color:var(--tab-color);font-weight:600}
.tab:hover{background:var(--tab-tint);color:var(--tab-color)}
.tab:focus-visible{outline:2px solid var(--tab-color);outline-offset:-3px}
/* Chapter progress along the tab's foot, as in the old player. */
.tab::after{content:'';position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--tab-color);transform:scaleX(var(--file-progress,0));transform-origin:left center}
.tab .tile{width:16px;height:16px;flex:none}
.tab-name{min-width:0;overflow:hidden;text-overflow:ellipsis}
.ribbon{height:40px;flex:none;display:flex;align-items:center;gap:30px;padding:0 20px;font-size:12px;color:#5b6168;border-bottom:1px solid #e8eaed;background:#fff}
.rb-div{width:1px;height:14px;background:#dcdfe3}
.rb-blocks{display:flex;gap:6px}.rb-blocks b{width:14px;height:14px;border-radius:50%;background:#eceef1}
.rb-kimi{color:#1783ff;font-weight:500}

/* Workspace: the camera zooms .cam inside this fixed clip. */
.workspace{position:relative;height:816px;flex:none;overflow:hidden;background:#f7f8fa}
.cam{position:absolute;inset:0;transform-origin:0 0}
.doc{position:absolute;left:16px;top:12px;width:944px;height:792px;display:flex;flex-direction:column;background:#fff;border:1px solid #e6e8eb;border-radius:10px;overflow:hidden}
.sidebar{position:absolute;left:972px;top:12px;width:452px;height:792px}

.format-bar{height:40px;flex:none;display:flex;align-items:center;gap:18px;padding:0 18px;font-size:12px;color:#5b6168;border-bottom:1px solid #eceef1;background:#fafbfc}
.format-bar i{width:1px;height:14px;background:#dcdfe3}
.format-bar .fb-font{min-width:64px;padding:3px 8px;border:1px solid #e3e5e8;border-radius:4px;background:#fff}
.format-bar .fb-end{margin-left:auto;font-size:10px;color:#9aa0a6}
.panes{position:relative;flex:1;min-height:0}
.pane{position:absolute;inset:0;overflow:hidden}
.doc-status{height:26px;flex:none;display:flex;justify-content:space-between;align-items:center;padding:0 14px;font-size:10px;color:#80868b;border-top:1px solid #eceef1;background:#fafbfc}

/* Transport (outside the stage, not scaled) */
.transport{display:flex;align-items:center;gap:10px;width:min(100%,960px);padding:8px 12px;border-radius:12px;background:#fff;box-shadow:0 1px 3px #0000001a;font-size:12px;color:#444}
.transport button{flex:none;min-width:34px;height:30px;padding:0 10px;border:1px solid #e3e5e8;border-radius:8px;background:#fff;color:#333;font:inherit;cursor:pointer}
.transport button.on{background:#eef5ff;border-color:#b9d6ff;color:#1766c7}
.scrub{position:relative;flex:1;min-width:60px}
.scrub input{width:100%;margin:0;accent-color:#1783ff}
.marks{position:absolute;left:0;right:0;top:-14px;height:12px;font-size:10px;color:#8a9097;pointer-events:none}
.marks span{position:absolute;transform:translateX(-2px);white-space:nowrap;pointer-events:auto;cursor:pointer}
#timecode{flex:none;font-variant-numeric:tabular-nums;min-width:82px;text-align:right}
#chapter-label{flex:none;min-width:84px;color:#262626;font-weight:500}
@media(max-width:700px){.transport{flex-wrap:wrap;gap:6px}.scrub{order:-1;flex-basis:100%;margin-top:12px}.transport button{padding:0 8px}}
/* User pointer (pointer.js) and chapter covers (cover.js). */
.pointer{position:absolute;left:0;top:0;z-index:30;width:20px;height:24px;pointer-events:none;transform-origin:2px 1.5px;filter:drop-shadow(0 1px 1.5px #00000040)}
.pointer svg{display:block;width:20px;height:24px}
/* Cover ground, the same for the opening overview and every chapter card. From Figma QSlqzTnh5hiC4mWnLEYdgM
   node 12938-590211: a flat pastel with the `ascii-2x` halftone laid over it at SOFT_LIGHT. cover-grain.png IS that
   asset, cropped to the stage's 16:10, halved, then MIRROR-tiled 2x2 back up to 1440x900 so it sits 1:1 on the
   canvas (at the asset's own scale the glyphs read as ASCII art rather than grain). The opening is Kimi's own blue,
   not the Excel chapter's green; it is slightly warmer/deeper than the Word ground so the two never read alike. */
.cover{position:absolute;inset:0;z-index:40;background:var(--cv-ground,#f1f0ea);pointer-events:none}
.cover[data-kind=intro]{--cv-ground:#d7e4ff}
.cover[data-kind=excel]{--cv-ground:#d4f4cf}
.cover[data-kind=word]{--cv-ground:#d3eeff}
.cover[data-kind=ppt]{--cv-ground:#ffe1cc}
.cover[data-mode=card]{background:none}
.cover[data-mode=card]:after{display:none}
.cover:after{content:'';position:absolute;inset:0;background:url(../assets/cover-grain.png) center/cover no-repeat;mix-blend-mode:soft-light;pointer-events:none}
.cv-group{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:92px}
.cv-icons{position:relative;width:132px;height:132px}
.cv-icon{position:absolute;left:0;top:0;width:132px;height:132px;opacity:0}
.cv-icon .tile{display:block;width:132px;height:132px}
.cv-line{font:600 56px/78px -apple-system,'SF Pro Display','PingFang SC','Microsoft YaHei','Helvetica Neue',sans-serif;color:#1f2329;letter-spacing:1px;white-space:nowrap;opacity:0}
/* Chapter card, after 歸藏's CodePilot film: its opening lockup (mark + bold wordmark, a line of grey copy
   beneath) on the film's pastel ground. One sans family throughout, the page's own
   stack. */
.cv-card{position:absolute;inset:0;z-index:1;overflow:hidden;font-family:-apple-system,'SF Pro Display','PingFang SC','Microsoft YaHei','Helvetica Neue',sans-serif;color:#1f2329}
.cv-lock{position:absolute;left:84px;top:262px;display:flex;flex-direction:column;align-items:flex-start;gap:26px}
.cv-mark{width:96px;height:96px;flex:none;transform-origin:0 50%}
.cv-tile .tile{display:block;width:96px;height:96px}
.cv-word{position:relative;display:flex;height:112px;align-items:center;margin-left:-6px;opacity:0}
.cv-word span{font-weight:600;font-size:104px;line-height:1;letter-spacing:-2px;white-space:nowrap;padding-bottom:6px}
.cv-sub{position:absolute;left:84px;top:528px;text-align:left;font-size:32px;line-height:46px;font-weight:400;letter-spacing:2px;
  color:rgba(31,35,41,.62);opacity:0;--wipe:0%;
  -webkit-mask-image:linear-gradient(90deg,#000 calc(var(--wipe) - 15%),transparent var(--wipe));mask-image:linear-gradient(90deg,#000 calc(var(--wipe) - 15%),transparent var(--wipe))}
/* Chapter cards, window half (lift.js): the chapter's ground and grain under the WPS window, which is lifted
   off the stage while cover.js's lockup sits on the left. Same ground as the covers. */
.win{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;background:#fff;overflow:hidden;transform-origin:0 50%}
.lift{position:absolute;inset:0;background:var(--cv-ground);pointer-events:none}
.lift[data-kind=excel]{--cv-ground:#d4f4cf}
.lift[data-kind=word]{--cv-ground:#d3eeff}
.lift[data-kind=ppt]{--cv-ground:#ffe1cc}
.lift:after{content:'';position:absolute;inset:0;background:url(../assets/cover-grain.png) center/cover no-repeat;mix-blend-mode:soft-light}
