/* uplift.css — 2026-10-13 completeness uplift (demo-design.md §10 · §11-3 · §11-5).
   Loaded after renewal.css and the #app-motion block. Spacing/radius/weights come from the tokens;
   durations from motion-kit tokens. Reduced motion and body.capture-mode stop every animation here through
   the token floor (animation/transition: none !important) — nothing below is hidden by default. */

/* hero:begin - generated by build/build.mjs from build/img-src/reading-hero.jpg (sharp 0.34.4). Do not edit by hand.
   Layer 1 = responsive AVIF/WebP/JPEG, layer 2 = 24px LQIP shown until it decodes, colour = measured dominant. */
.classic-feature-art,.classic-feature-art.mk-par::before{background-color:#080808;background-image:url("./assets/reading-hero-1344.jpg?v=98fb81bf8f"),url("data:image/webp;base64,UklGRooAAABXRUJQVlA4IH4AAACwAwCdASoYABAAPu1iqk2ppaQiMAgBMB2JYwCdACGmHG4oxrZKUAD7G7vgJ7vPrEWHyaDQTeMzqexbHhtCSd/JCRQPy99P8b3xniDdqqVosw7hhIgjCoaJlME5S1CAXWXDR2yx9YD006LGy4022dieHhmN3Iu6vqqgX454AAA=");background-image:image-set(url("./assets/reading-hero-1344.avif?v=a08e82ccd4") type("image/avif"),url("./assets/reading-hero-1344.webp?v=cd69fa2a81") type("image/webp"),url("./assets/reading-hero-1344.jpg?v=98fb81bf8f") type("image/jpeg")),url("data:image/webp;base64,UklGRooAAABXRUJQVlA4IH4AAACwAwCdASoYABAAPu1iqk2ppaQiMAgBMB2JYwCdACGmHG4oxrZKUAD7G7vgJ7vPrEWHyaDQTeMzqexbHhtCSd/JCRQPy99P8b3xniDdqqVosw7hhIgjCoaJlME5S1CAXWXDR2yx9YD006LGy4022dieHhmN3Iu6vqqgX454AAA=")}
@media(max-width:600px){.classic-feature-art,.classic-feature-art.mk-par::before{background-image:url("./assets/reading-hero-768.jpg?v=e5cb864012"),url("data:image/webp;base64,UklGRooAAABXRUJQVlA4IH4AAACwAwCdASoYABAAPu1iqk2ppaQiMAgBMB2JYwCdACGmHG4oxrZKUAD7G7vgJ7vPrEWHyaDQTeMzqexbHhtCSd/JCRQPy99P8b3xniDdqqVosw7hhIgjCoaJlME5S1CAXWXDR2yx9YD006LGy4022dieHhmN3Iu6vqqgX454AAA=");background-image:image-set(url("./assets/reading-hero-768.avif?v=4b1cdce37c") type("image/avif"),url("./assets/reading-hero-768.webp?v=7ab4d33366") type("image/webp"),url("./assets/reading-hero-768.jpg?v=e5cb864012") type("image/jpeg")),url("data:image/webp;base64,UklGRooAAABXRUJQVlA4IH4AAACwAwCdASoYABAAPu1iqk2ppaQiMAgBMB2JYwCdACGmHG4oxrZKUAD7G7vgJ7vPrEWHyaDQTeMzqexbHhtCSd/JCRQPy99P8b3xniDdqqVosw7hhIgjCoaJlME5S1CAXWXDR2yx9YD006LGy4022dieHhmN3Iu6vqqgX454AAA=")}}
/* hero:end */

/* ── icons (one Lucide set, stroke 1.5, two sizes) ───────────────────────── */
.icon-sprite { position:absolute; width:0; height:0; overflow:hidden; }
.ico { width:20px; height:20px; flex:0 0 auto; display:inline-block; vertical-align:middle;
       fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; }
.ico.s16 { width:16px; height:16px; }
.vh { position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
      clip-path:inset(50%); white-space:nowrap; border:0; }
.btn .ico { margin-inline-start:calc(var(--sp-1) * -0.5); }
.icon-btn { padding:0 !important; width:44px; min-width:44px; justify-content:center; }

/* banner: guide + theme */
.banner-acts .btn { gap:var(--sp-1); }
#themeToggle .i-moon { display:none; }
#themeToggle[aria-pressed="true"] .i-sun { display:none; }
#themeToggle[aria-pressed="true"] .i-moon { display:inline-block; }

/* ── finish details (§10-4) ─────────────────────────────────────────────── */
::selection { background:var(--accent); color:var(--accent-ink); }
/* Korean wraps at word (eojeol) boundaries like the card typesetter; a word longer than its box still breaks */
body { word-break:keep-all; overflow-wrap:break-word; }
html { scrollbar-color:var(--line-strong) transparent; }
.classic-discover article .disc-ico .ico { width:20px; height:20px; }
.classic-start .ico { color:var(--accent); }
.tab-no, .section-number, .t-metric, .reflection-quote > span { font-family:var(--font-literary); }

/* 360: tab bar = icon + label (≥601 keeps the numbered editorial tabs) */
.tab .tab-ico { display:none; }
@media (max-width:600px) {
  .tab .tab-ico { display:block; width:20px; height:20px; }
  .tab .tab-no { display:none; }
  .tab { min-height:60px; gap:2px; }
  body { padding-bottom:calc(68px + env(safe-area-inset-bottom)); }
}

/* screen 1 narrative: arrow keys + swipe */
#s1narr { touch-action:pan-y; cursor:default; }
#s1narr:focus-visible { outline:2px solid var(--accent); outline-offset:var(--sp-1); }
.narr-hint { color:var(--text-2); }

/* ── screen 2: the state machine as a drawing ───────────────────────────── */
#s2machine.is-map { position:relative; grid-template-columns:repeat(3, minmax(0, 1fr));
                    grid-auto-rows:minmax(56px, auto); gap:calc(var(--sp-6) + var(--sp-2)) var(--sp-7); }
@media (max-width:600px) { #s2machine.is-map { gap:var(--sp-6) var(--sp-5); } }
#s2machine.is-map .node { position:relative; z-index:1; background:var(--surface); }
#s2machine.is-map .node.on { background:var(--accent); }
#s2machine.is-map .node.past { background:var(--surface); }
.machine-edges { position:absolute; left:0; top:0; width:100%; height:100%; overflow:visible;
                 pointer-events:none; z-index:0; }
.machine-edges .edge { fill:none; stroke:var(--line-strong); stroke-width:1.5; marker-end:url(#s2arrow);
                       transition:stroke var(--dur-2) var(--ease-out), stroke-width var(--dur-2) var(--ease-out); }
.machine-edges .edge.out { stroke:var(--accent); stroke-width:2; stroke-dasharray:6 5; marker-end:url(#s2arrowOn);
                           animation:edge-flow 1.1s linear infinite; }
.machine-edges .edge.hot { stroke:var(--accent); stroke-width:3; stroke-dasharray:none; marker-end:url(#s2arrowOn); }
.machine-edges .hit { fill:none; stroke:transparent; stroke-width:14; pointer-events:stroke; cursor:pointer; }
.machine-edges .ah { fill:var(--line-strong); }
.machine-edges .ah.on { fill:var(--accent); }
@keyframes edge-flow { to { stroke-dashoffset:-22; } }
#s2edges .btn.is-hot { border-color:var(--accent); background:var(--accent-bg); color:var(--accent); }
.mk-travel.on-path { left:0; top:0; position:absolute; offset-rotate:0deg; z-index:3; }

/* signature timeline: second ticks */
#s2tl { height:98px; }
.tl .ticks { position:absolute; left:0; right:0; bottom:0; height:24px; border-top:1px solid var(--line); }
.tl .tick { position:absolute; top:0; width:1px; height:5px; background:var(--line-strong); }
.tl .tick b { position:absolute; top:6px; left:0; transform:translateX(-50%); font-size:var(--fs-1);
              font-weight:var(--fw-normal); color:var(--text-2); white-space:nowrap;
              font-variant-numeric:tabular-nums; line-height:1.2; }
.tl .tick:first-child b { transform:none; }
.tl .tick.end b { transform:translateX(-100%); }

/* ── screen 3: enlarge + save states ───────────────────────────────────── */
.shot .shot-zoom { position:absolute; top:var(--sp-2); right:var(--sp-2); z-index:2; width:44px; min-height:44px;
                   padding:0; color:var(--ink-fg); border-color:color-mix(in srgb, var(--ink-fg) 30%, transparent);
                   background:color-mix(in srgb, var(--ink-bg) 70%, transparent); backdrop-filter:blur(4px); }
.shot .shot-zoom:hover { background:var(--ink-bg); color:var(--ink-fg); border-color:var(--ink-fg); }
.btn[aria-busy="true"] { cursor:progress; opacity:.72; }

/* PhotoSwipe re-theme to the demo tokens (div.pswp beats the library's .pswp) */
div.pswp { --pswp-bg:var(--ink-bg); --pswp-placeholder-bg:var(--ink-bg); --pswp-icon-color:var(--ink-fg);
           --pswp-icon-color-secondary:var(--ink-bg); --pswp-icon-stroke-color:var(--ink-bg);
           --pswp-error-text-color:var(--ink-fg); --pswp-root-z-index:120; font-family:var(--font-ui); }
div.pswp .pswp__button:focus-visible { outline:2px solid var(--accent); outline-offset:-4px; }
div.pswp .pswp-ico { position:absolute; top:50%; left:50%; width:24px; height:24px; transform:translate(-50%, -50%);
                     fill:none; stroke:var(--ink-fg); pointer-events:none; }
div.pswp .pswp__button--arrow .pswp-ico { width:32px; height:32px; }
.pswp-cap { position:absolute; left:0; right:0; bottom:0; display:flex; flex-wrap:wrap; gap:var(--sp-2) var(--sp-4);
            align-items:center; justify-content:space-between;
            padding:var(--sp-4) var(--sp-4) calc(var(--sp-4) + env(safe-area-inset-bottom));
            color:var(--ink-fg); background:linear-gradient(transparent, color-mix(in srgb, var(--ink-bg) 92%, transparent) 38%); }
.pswp-cap p { font-size:var(--fs-2); line-height:var(--lh-2); }
.pswp-cap small { display:block; font-size:var(--fs-1); opacity:.75; }
.pswp-cap .btn { background:transparent; color:var(--ink-fg); border-color:color-mix(in srgb, var(--ink-fg) 45%, transparent); }
.pswp-cap .btn:hover { background:var(--ink-fg); color:var(--ink-bg); }

/* ── screen 4: reading rhythm (ECharts) ─────────────────────────────────── */
#s4 .library-rhythm { grid-column:1; grid-row:3; }
#s4 .library-shelves { grid-row:4; }
#s4 .library-export { grid-row:2 / 5; }
.library-rhythm { background:transparent; border:0; padding:0 0 var(--sp-6); border-bottom:1px solid var(--line); }
.rhythm-head { display:flex; justify-content:space-between; align-items:flex-end; gap:var(--sp-3); flex-wrap:wrap; }
.rhythm-head .t-group { font-family:var(--font-literary); font-size:var(--fs-4); font-weight:var(--fw-normal); }
.rhythm-grid { display:grid; grid-template-columns:minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); gap:var(--sp-5);
               align-items:start; }
.rh-card { display:grid; gap:var(--sp-2); align-content:start; }
.rh-card > .t-meta:first-child { color:var(--text); font-weight:var(--fw-mid); }
.rh-box { position:relative; width:100%; }
.rh-cal .rh-box { aspect-ratio:10 / 9; }
.rh-pie .rh-box { aspect-ratio:1 / 1; max-height:300px; }
.rh-bar .rh-box { aspect-ratio:1 / 1; max-height:300px; }
.rh-box.is-loading { background:linear-gradient(90deg, var(--surface-2) 25%, var(--surface) 50%, var(--surface-2) 75%) 0 0 / 220% 100%;
                     animation:rh-sheen 1.3s linear infinite; }
@keyframes rh-sheen { to { background-position:-220% 0; } }
.rh-center { position:absolute; inset:0; display:grid; place-content:center; text-align:center; pointer-events:none; }
.rh-center b { font-family:var(--font-literary); font-size:var(--fs-6); line-height:1; font-weight:var(--fw-normal);
               font-variant-numeric:tabular-nums; }
.rh-center span { font-size:var(--fs-1); color:var(--text-2); margin-top:var(--sp-1); }
.rh-legend { display:flex; flex-wrap:wrap; gap:var(--sp-1) var(--sp-3); font-size:var(--fs-1); color:var(--text-2); }
.rh-legend i { display:inline-block; width:10px; height:10px; margin-right:var(--sp-1); vertical-align:-1px;
               border:1px solid var(--line); }
.rh-legend .is-off { opacity:.45; }
.rh-err { padding:var(--sp-4); background:var(--surface-2); color:var(--text-2); }
@media (max-width:1100px) {
  .rhythm-grid { grid-template-columns:minmax(0, 1.2fr) minmax(0, 1fr); }
  .rh-bar { grid-column:1 / -1; }
  .rh-bar .rh-box { aspect-ratio:2 / 1; max-height:none; }
}
@media (max-width:850px) {
  #s4 .library-rhythm { grid-column:1 / -1; grid-row:3; }
  #s4 .library-shelves { grid-column:1; grid-row:4; }
  #s4 .library-export { grid-column:2; grid-row:4; }
}
@media (max-width:600px) {
  #s4 .library-rhythm { grid-column:1; grid-row:3; }
  #s4 .library-shelves { grid-column:1; grid-row:4; }
  #s4 .library-export { grid-column:1; grid-row:5; }
  .rhythm-grid { grid-template-columns:minmax(0, 1fr); }
  .rh-bar { grid-column:auto; }
  .rh-bar .rh-box { aspect-ratio:3 / 2; }
}

/* shelf: flat / 3D, picked book */
.shelf-head { display:flex; justify-content:space-between; align-items:center; gap:var(--sp-3); flex-wrap:wrap; }
.shelf-head .seg > button { display:inline-flex; align-items:center; gap:var(--sp-1); }
.spine { cursor:pointer; }
.spine:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.spine[aria-pressed="true"] { outline:2px solid var(--accent); outline-offset:3px; }
.shelf-pick { min-height:44px; padding:var(--sp-2) var(--sp-3); border-left:2px solid var(--accent);
              background:var(--surface-2); }
.shelf3d { position:relative; width:100%; aspect-ratio:16 / 10; background:var(--shelf-bg); overflow:hidden; }
.shelf3d.is-loading { background:linear-gradient(90deg, var(--shelf-bg) 25%, var(--surface) 50%, var(--shelf-bg) 75%) 0 0 / 220% 100%;
                      animation:rh-sheen 1.3s linear infinite; }
.shelf3d canvas { display:block; width:100%; height:100%; touch-action:none; cursor:grab; }
.shelf3d canvas:active { cursor:grabbing; }
.shelf3d .s3d-tools { position:absolute; right:var(--sp-2); top:var(--sp-2); display:flex; gap:var(--sp-2); }
.shelf3d .s3d-tools .btn { background:var(--surface); }
.shelf3d .s3d-msg { position:absolute; inset:0; display:grid; place-content:center; gap:var(--sp-2); text-align:center;
                    padding:var(--sp-5); color:var(--text-2); }
.shelf3d .s3d-hint { position:absolute; left:var(--sp-3); bottom:var(--sp-2); font-size:var(--fs-1); color:var(--text-2);
                     pointer-events:none; }
@media (max-width:600px) { .shelf3d { aspect-ratio:1 / 1; } }
/* 3D 모드: 평면 서가는 같은 책을 고르는 제목 목록으로 줄인다(장면과 양방향 선택은 그대로) */
.shelf-glnote { padding:var(--sp-2) var(--sp-3); border-left:2px solid var(--text-2); background:var(--surface-2); }
.library-shelves.is-3d .shelf { padding:var(--sp-3); gap:var(--sp-2); background:var(--surface-2); box-shadow:none; }
.library-shelves.is-3d .deck { min-height:0; border-bottom:0; box-shadow:none; flex-wrap:wrap; align-items:center;
                               gap:var(--sp-1); padding:0; }
.library-shelves.is-3d .spine { writing-mode:horizontal-tb; text-orientation:mixed; width:auto !important; height:auto !important;
                                min-height:32px; align-items:center; padding:var(--sp-1) var(--sp-2); border-radius:var(--r-sm);
                                border-right:0; box-shadow:none; }

/* ── screen 6: search · sort · export ──────────────────────────────────── */
.s6-search { position:relative; display:block; }
.s6-search > .ico { position:absolute; left:var(--sp-3); top:50%; transform:translateY(-50%); color:var(--text-2);
                    pointer-events:none; }
.s6-search input { padding-left:calc(var(--sp-3) * 2 + 16px); padding-right:48px; }
.s6-search .q-clear { position:absolute; right:0; top:0; height:100%; width:44px; min-height:44px; padding:0;
                      border:0; background:transparent; color:var(--text-2); }
.s6-search .q-clear:hover { color:var(--accent); background:transparent; }
.s6-qcount { font-size:var(--fs-1); color:var(--text-2); }
@media (min-width:601px) { #s6>.toolbar label.fld.s6-q { flex:1 1 260px; } }
.led th .sort-ico { opacity:.45; }
.led th[aria-sort] .sort-ico { opacity:1; }
.led th .th-sort { appearance:none; background:none; border:0; padding:0; margin:0; font:inherit; color:inherit;
                   letter-spacing:inherit; display:inline-flex; align-items:center; gap:var(--sp-1); cursor:pointer; }
.led th .th-sort:hover { color:var(--accent); }
.led th[aria-sort="ascending"] .th-sort, .led th[aria-sort="descending"] .th-sort { color:var(--accent); }
.led th .th-plain { display:none; }
.led mark { background:color-mix(in srgb, var(--accent) 24%, transparent); color:inherit; padding:0 1px; }
label.fld.s6-sortsel { display:none; }   /* beats the inline label.fld { display:grid } */
#s6>.toolbar .s6-export { align-self:end; }
@media (max-width:600px) {
  .led th .th-sort { display:none; }
  .led th .th-plain { display:inline; }
  label.fld.s6-sortsel { display:grid; flex:1 1 100%; }
  #s6>.toolbar .s6-export { flex:1 1 100%; }
}

/* screen 5: keyboard hint only where a keyboard is likely */
@media (max-width:600px), (hover:none) { .kbd-hint { display:none; } }

/* ── screen 1 video stage: poster still (Hugh Thomson 1894, public domain) + state overlay ─────────────
   The poster is drawn once; the overlay (.stage-ov) and data-kind change with the state.
   wait = dimmed still · lock = blurred, desaturated still under the lock · play = clear still, player chrome.
   The corner tag and the "no video source" sentence stay: the demo has no video file. */
.stagebox { position:relative; display:grid; place-items:stretch; padding:0; min-height:0; aspect-ratio:16 / 9; overflow:hidden;
            background:var(--ink-bg); isolation:isolate; text-align:center; }
.stage-poster-slot, .stage-poster, .stage-poster img { position:absolute; inset:0; width:100%; height:100%; display:block; }
.stage-poster img { object-fit:cover; object-position:50% 46%; background:var(--ink-bg);
                    transition:filter var(--dur-4, .4s) ease, transform var(--dur-4, .4s) ease; }
.stage-ov { grid-area:1 / 1; position:relative; z-index:1; display:grid; place-content:center; justify-items:center;
            gap:var(--sp-3); padding:var(--sp-6) var(--sp-5); text-align:center;
            background:linear-gradient(180deg, color-mix(in srgb, var(--ink-bg) 55%, transparent),
                                               color-mix(in srgb, var(--ink-bg) 82%, transparent)); }
.stagebox[data-kind="wait"] .stage-poster img { filter:saturate(.85) brightness(.92); }
.stagebox[data-kind="lock"] .stage-poster img { filter:blur(5px) grayscale(.55) brightness(.7); transform:scale(1.06); }
.stagebox[data-kind="lock"] .stage-ov { background:color-mix(in srgb, var(--ink-bg) 74%, transparent); }
.stagebox[data-kind="play"] .stage-ov { place-content:end stretch; justify-items:stretch; text-align:left; gap:var(--sp-2);
            padding:var(--sp-5); background:linear-gradient(180deg, transparent 30%,
                                               color-mix(in srgb, var(--ink-bg) 92%, transparent) 88%); }
.stage-bar { display:grid; gap:var(--sp-2); }
.stage-play { position:absolute; left:50%; top:42%; transform:translate(-50%, -50%); width:68px; height:68px;
              display:grid; place-items:center; border-radius:var(--r-full);
              background:color-mix(in srgb, var(--ink-bg) 55%, transparent); border:1px solid color-mix(in srgb, var(--ink-fg) 55%, transparent);
              color:var(--ink-fg); backdrop-filter:blur(2px); }
.stage-play .ico { width:28px; height:28px; margin-left:3px; }
.stage-tag { position:absolute; z-index:2; left:var(--sp-3); top:var(--sp-3); padding:2px var(--sp-2);
             font-size:var(--fs-1); line-height:1.6; letter-spacing:.02em; color:var(--ink-fg);
             background:color-mix(in srgb, var(--ink-bg) 78%, transparent); border:1px solid color-mix(in srgb, var(--ink-fg) 30%, transparent); }
.stage-cap { font-size:var(--fs-1); color:var(--text-2); }
@media (max-width:600px) {
  .stagebox { aspect-ratio:4 / 3; }
  .stage-ov { padding:var(--sp-6) var(--sp-4) var(--sp-4); }
  .stagebox[data-kind="play"] .stage-ov { padding:var(--sp-4);
    background:linear-gradient(180deg, transparent 0%, color-mix(in srgb, var(--ink-bg) 90%, transparent) 52%); }
  .stage-play { width:44px; height:44px; left:auto; right:var(--sp-3); top:var(--sp-3); transform:none; }
  .stage-play .ico { width:20px; height:20px; }
}

/* ── screen 4 flat shelf: cloth-bound spines on a wood board (ambientCG CC0 textures) ──────────────────
   Height / width / colour of each spine stay the data encoding (inline style); the cloth weave is multiplied
   over the category colour, two foil bands sit at 6% / 94% like the 3D shelf's spine, a soft gradient rounds the
   spine. The images load only when screen 4 renders a spine (hidden screens fetch nothing). */
.shelf .spine { position:relative;
  background-image:
    linear-gradient(180deg, transparent 5.2%, #d9b97acc 5.2%, #f3dfaecc 6%, #b8924fcc 6.8%, transparent 6.8%,
                            transparent 93.2%, #b8924fcc 93.2%, #f3dfaecc 94%, #d9b97acc 94.8%, transparent 94.8%),
    linear-gradient(90deg, #00000038 0, #ffffff1f 22%, #ffffff0a 45%, #00000014 70%, #00000047 100%),
    url("./assets/tex-cloth.webp?v=a7ac41687a");
  background-size:100% 100%, 100% 100%, 160px 160px;
  background-blend-mode:normal, normal, multiply;
  border-right:0; box-shadow:inset 0 1px 0 #ffffff26, 0 -1px 0 #0000001a, 2px 0 3px -1px #00000033; }
.deck { position:relative; border-bottom:0; padding-bottom:14px;
        background:url("./assets/tex-wood-strip.webp?v=9eabd7ecaa") left bottom / auto 14px repeat-x; box-shadow:none; }
.deck::after { content:''; position:absolute; left:0; right:0; bottom:-8px; height:8px; pointer-events:none;
               background:linear-gradient(180deg, #2a1d1059, transparent); }
.deck::before { content:''; position:absolute; left:0; right:0; bottom:13px; height:1px; background:#ffffff40; pointer-events:none; }
.shelf { background-image:linear-gradient(180deg, #0000000a, transparent 30%); }
.library-shelves.is-3d .deck { background:none; padding-bottom:0; }
.library-shelves.is-3d .deck::before, .library-shelves.is-3d .deck::after { display:none; }
.library-shelves.is-3d .shelf .spine { background-image:none; }
