/* ゆめのとしょかん。色のトークンと質感は .claude/rules/yume-no-toshokan/design/shitsukan.md(夜だけ) */
:root{
  --night-0:#12162a; --night-1:#1c2236; --night-2:#262d45; --forest:#1f3a33;
  --wood:#6b4a33; --wood-dark:#3f2a1c; --wood-light:#8a6446;
  --lamp:#f2c98a;
  --paper:#d8c9ad; --paper-card:#988b73; --ink:#2a211c; --text-night:#e6d9bf; --text-dim:#a79c86;
  --pc-rose:#c98a8a; --pc-sky:#8aa6c9; --pc-leaf:#8fae8a; --pc-gold:#d8b870; --pc-lav:#a99bc4;
  /* 彩度を落とした差し色(2択の「本棚へ」の絵。2枚を同格に見せる ← saigo.md 3) */
  --pc-rose-m:color-mix(in srgb,var(--pc-rose) 50%,var(--text-dim)); --pc-sky-m:color-mix(in srgb,var(--pc-sky) 50%,var(--text-dim));
  --pc-leaf-m:color-mix(in srgb,var(--pc-leaf) 50%,var(--text-dim)); --pc-gold-m:color-mix(in srgb,var(--pc-gold) 50%,var(--text-dim));
  --pc-lav-m:color-mix(in srgb,var(--pc-lav) 50%,var(--text-dim));
  --focus:#d8b870;
  --moon-dim:#6b6384;
  /* 舞台の幕(butai.md 3.3。幕と上の飾り幕だけ。ほかの面に使わない) */
  --curtain:#5a3140; --curtain-fold:#44242f; --curtain-hi:#6e4050;
  --font-book:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --font-ui:ui-rounded,"Hiragino Maru Gothic ProN","Segoe UI",system-ui,sans-serif;
  /* 紙のざらつき(1枚のタイル。画面全体に filter を掛けない) */
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 0.95 0 0 0 0 0.88 0 0 0 0 0.75 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");
  --grain-wall:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 0.95 0 0 0 0 0.88 0 0 0 0 0.75 0 0 0 0.10 0'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");
  --grain-ink:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 0.23 0 0 0 0 0.18 0 0 0 0 0.15 0 0 0 0.10 0'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");
}
*{box-sizing:border-box}
html,body{margin:0;height:100%;overflow:hidden;background:var(--night-1);color:var(--text-night);font-family:var(--font-ui);
  -webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;overscroll-behavior:none}
#app{position:fixed;inset:0}
.screen{position:absolute;inset:0;overflow:hidden}
.screen[hidden]{display:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;margin:0;cursor:pointer;touch-action:manipulation}
button:focus{outline:none}
button:focus-visible .face{outline:3px solid var(--focus);outline-offset:3px}
img{-webkit-user-drag:none}

/* ---- 押せる物の文法: 丸 + 縁 + 影 2px(押せない物に付けない) ---- */
.round{width:88px;height:88px;display:grid;place-items:center;flex:0 0 auto}
.round[hidden]{display:none}
.round .face{position:relative;width:56px;height:56px;border-radius:50%;background:var(--night-2);border:2px solid var(--text-dim);
  box-shadow:0 2px 0 var(--wood-dark);display:grid;place-items:center;transition:transform .1s}
.round.big{width:96px;height:96px}
.round.big .face{width:72px;height:72px}
.round.back .face{width:64px;height:64px;background:var(--wood-dark)}
.round.is-down .face{transform:scale(.94)}
.ico{width:62%;height:62%;display:block}
.round.back .ico{width:74%;height:74%}
/* 長押しの輪(1000ms で時計回りに満ちる。離したら 200ms で縮んで消える) */
.hold-ring{position:absolute;inset:-8px;width:calc(100% + 16px);height:calc(100% + 16px);pointer-events:none;transform:rotate(-90deg)}
.hold-ring circle{fill:none;stroke:var(--pc-gold);stroke-width:4;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:100}
.is-holding .hold-ring circle{animation:hold-fill var(--hold-ms,1000ms) linear forwards}
.is-letgo .hold-ring{transform:rotate(-90deg) scale(.6);transition:transform .2s}
@keyframes hold-fill{to{stroke-dashoffset:0}}

/* 色鉛筆の輪(押せない所の一次応答) */
.ripple{position:absolute;width:48px;height:48px;pointer-events:none;overflow:visible;z-index:50}
.ripple circle{fill:none;stroke:var(--text-dim);stroke-width:2;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:100;animation:ripple-draw .25s linear forwards}
.veil .ripple circle{stroke:#3a3f5a}
@keyframes ripple-draw{to{stroke-dashoffset:0}}

/* ================= 図書館(本棚) ================= */
/* 部屋: 上は夜の壁、下へ行くほど木とランプの色が薄く差す。奥の壁に低い明るさの本棚のシルエット、
   棚の下に床(板が宙に浮かない)。壁・床・シルエットは .lib の中の z-index:-1(.lib が重なりの箱)。 */
.lib{position:absolute;inset:0;isolation:isolate;display:grid;grid-template-rows:56px minmax(0,auto) minmax(0,1fr);
  background:var(--grain-wall),
    linear-gradient(180deg,var(--night-1) 0 42%,color-mix(in srgb,var(--wood) 16%,var(--night-1)) 78%,color-mix(in srgb,var(--lamp) 7%,color-mix(in srgb,var(--wood) 18%,var(--night-1))) 100%);
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  --wall-shelf:color-mix(in srgb,var(--night-1) 90%,var(--wood-dark));
  --wall-spine:color-mix(in srgb,var(--night-1) 89%,var(--text-dim));
  --wall-board:color-mix(in srgb,var(--night-1) 78%,var(--wood-dark));
  /* 部屋の絵の色(トークンを混ぜただけ。新しい色の値を持ち込まない ← shitsukan.md 3) */
  --win-sky-low:color-mix(in srgb,var(--night-2) 82%,var(--pc-lav)); --hill:color-mix(in srgb,var(--forest) 55%,var(--night-2));
  --brass:color-mix(in srgb,var(--pc-gold) 60%,var(--wood)); --brass-dark:color-mix(in srgb,var(--pc-gold) 30%,var(--wood-dark));
  --owl-face:color-mix(in srgb,var(--wood-light) 60%,var(--paper)); --owl-belly:color-mix(in srgb,var(--wood-light) 45%,var(--paper));
  --glass:color-mix(in srgb,var(--night-2) 80%,var(--pc-sky)); --lantern-glass:color-mix(in srgb,var(--lamp) 45%,var(--wood));
  --leaf-dark:color-mix(in srgb,var(--pc-leaf) 60%,var(--forest)); --pot-rim:color-mix(in srgb,var(--pc-rose) 70%,var(--wood-light));
  --cat:color-mix(in srgb,var(--paper) 72%,var(--wood-light)); --cat-patch:color-mix(in srgb,var(--wood-light) 70%,var(--pc-gold));
  --cat-patch-dark:color-mix(in srgb,var(--wood-dark) 80%,var(--ink));
  --cushion:color-mix(in srgb,var(--pc-rose) 60%,var(--night-2)); --cushion-dark:color-mix(in srgb,var(--pc-rose) 35%,var(--night-1));
  --cab:26px}
.lib-title{margin:0;align-self:end;justify-self:center;font-size:24px;font-weight:600;color:var(--text-night);letter-spacing:.02em;white-space:nowrap;pointer-events:none}
.lib-window{position:relative;justify-self:center;align-self:center;width:min(190px,24vh);aspect-ratio:1;margin-top:8px;pointer-events:none}
.lib-window .win{width:100%;height:100%;display:block}
/* 窓の下の出窓の板(飾りが宙に浮かない。押せない = 影なし)。縦は左にふくろう、右に鉢植えと小瓶 */
.lib-window::after{content:"";position:absolute;left:-64px;right:-86px;bottom:-7px;height:7px;border-radius:2px;
  background:linear-gradient(180deg,var(--wood-light) 0 2px,var(--wood) 2px 5px,var(--wood-dark) 5px)}
@media (orientation:landscape){ .lib-window::after{left:8%;right:-46px} }
.sill{position:absolute;bottom:0;display:flex;align-items:flex-end;gap:2px}
.sill-l{right:100%;margin-right:8px}
.sill-r{left:100%;margin-left:6px}
.sill .owl{width:46px;height:56px}
.sill .plant{width:40px;height:48px}
.sill .jar{width:32px;height:46px}
@media (orientation:portrait){ .only-l{display:none!important} }
@media (orientation:landscape){ .only-p{display:none!important} }
/* 天井から下がるランタン(縦だけ。題名の左・窓より上で止まる) */
.lantern-wrap{position:absolute;z-index:1;left:calc(env(safe-area-inset-left) + 12px);top:0;width:48px;height:136px;pointer-events:none}
.lantern-wrap .lantern{display:block;width:100%;height:100%;transform-origin:50% 0}
.lantern-wrap::before,.lantern-wrap::after{content:"";position:absolute;left:50%;top:64%;width:170px;height:170px;transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(closest-side,color-mix(in srgb,var(--lamp) 30%,transparent),color-mix(in srgb,var(--lamp) 8%,transparent) 60%,transparent)}
.lantern-wrap::after{opacity:0}
.shelf-area{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:0;padding-bottom:12px;
  --bw:140px;--bh:187px}
/* ランプの光だまり(芯 38% → 外周で地に溶ける。揺らがない) */
.lamp-glow{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(closest-side at 50% 50%,color-mix(in srgb,var(--lamp) 38%,transparent),color-mix(in srgb,var(--lamp) 12%,transparent) 55%,transparent 100%)}
.lamp-glow::after{content:"";position:absolute;inset:0;opacity:0;
  background:radial-gradient(closest-side at 50% 50%,color-mix(in srgb,var(--lamp) 20%,transparent),transparent)}
.shelf-view{position:relative;width:100%;overflow:hidden}
.shelf-track{display:flex}
/* 回る棚(3冊以上 ← toshokan.md 3.3)。奥行きは .shelf-track の perspective、輪は preserve-3d(角度は toshokan.js place) */
.lib[data-count=ring] .shelf-track{display:block;position:relative;height:calc(var(--bh) + 46px);perspective:1000px;perspective-origin:50% 40%}
.shelf-ring{position:absolute;left:50%;top:12px;width:0;height:100%;transform-style:preserve-3d;transition:transform .5s ease-in-out;will-change:transform}
.shelf-ring .book-slot{position:absolute;left:calc(var(--bw) / -2);top:0;width:var(--bw);backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:opacity .5s ease-in-out}
.shelf-ring.live .book-slot{transition:none}
/* 横の指の動きは自分で読む(ブラウザに横へのパンとして取られると pointercancel が来て回らない)。縦のスクロールは要らないが残してよい */
.lib[data-count=ring] .shelf-view{touch-action:pan-y}
.shelf-page{flex:0 0 100%;display:grid;grid-template-columns:repeat(2,var(--bw));justify-content:center;gap:24px 28px;padding:12px 0 0}
.lib[data-count=one] .shelf-page{display:flex;flex-direction:column;align-items:center;gap:0}
.lib[data-count=one] .shelf-area{--bw:180px;--bh:240px}
.lectern{width:calc(var(--bw) + 48px);height:30px;display:block;margin-top:-2px}
.plank{position:relative;width:min(92%,560px);height:18px;border-radius:3px;border-bottom:3px solid var(--wood-dark);
  background:repeating-linear-gradient(90deg,transparent 0 46px,color-mix(in srgb,var(--wood-dark) 35%,transparent) 46px 47px,transparent 47px 83px),
    linear-gradient(180deg,var(--wood-light) 0 3px,var(--wood) 3px 72%,color-mix(in srgb,var(--wood) 70%,var(--wood-dark)) 72%)}
/* 棚の胴(板の下)→ 床。床は画面の端から端まで */
.cabinet{position:absolute;left:3%;right:3%;top:calc(100% + 3px);height:var(--cab);pointer-events:none;
  background:radial-gradient(circle at calc(50% - 10px) 50%,var(--wood) 0 2px,transparent 2.6px),
    radial-gradient(circle at calc(50% + 10px) 50%,var(--wood) 0 2px,transparent 2.6px),
    linear-gradient(90deg,transparent 0 calc(50% - 1px),color-mix(in srgb,var(--wood-dark) 60%,#000) calc(50% - 1px) calc(50% + 1px),transparent calc(50% + 1px)),
    linear-gradient(180deg,color-mix(in srgb,var(--wood-dark) 70%,var(--wood)),color-mix(in srgb,var(--wood-dark) 92%,#000))}
/* 扉 2 枚の鏡板(細い溝だけ)。つまみは木の色で目立たせない(押せそうに見せない) */
.cabinet::before,.cabinet::after{content:"";position:absolute;top:5px;bottom:5px;border:1px solid color-mix(in srgb,var(--wood) 60%,transparent);border-radius:2px}
.cabinet::before{left:8px;right:calc(50% + 18px)}
.cabinet::after{right:8px;left:calc(50% + 18px)}
/* 床の座ぶとんのねこ(棚の左下) */
.cat-wrap{position:absolute;left:2%;top:calc(100% + 3px + var(--cab) + 12px);width:96px;height:56px}
.cat-wrap .cat{display:block;width:100%;height:100%}
/* 縦の回る棚は胴の下に ◀ 数 ▶ が来るので、ねこはその下の床へ(低い縦は床が足りないので置かない) */
@media (orientation:portrait){ .lib[data-count=ring] .cat-wrap{top:calc(100% + 3px + var(--cab) + 104px)} }
@media (orientation:portrait) and (max-height:740px){ .lib[data-count=ring] .cat-wrap{display:none} }
@media (orientation:landscape) and (max-height:340px){ .lib[data-count=ring] .cat-wrap{left:-2%;width:60px;height:35px} }
.floor{position:absolute;z-index:-1;left:-100vw;right:-100vw;top:calc(100% + 3px + var(--cab));height:100vh;pointer-events:none;
  border-top:3px solid color-mix(in srgb,var(--wood-dark) 70%,#000);
  background:repeating-linear-gradient(180deg,transparent 0 18px,color-mix(in srgb,var(--wood-dark) 55%,#000) 18px 20px),
    linear-gradient(180deg,color-mix(in srgb,var(--wood-dark) 78%,var(--night-1)),color-mix(in srgb,var(--wood-dark) 45%,var(--night-0)) 70%)}
.wall{position:absolute;z-index:-1;left:-100vw;right:-100vw;bottom:calc(-3px - var(--cab));height:220px;pointer-events:none}
.wall-shelves{display:block;width:100%;height:100%}
.deco-l,.deco-r{position:absolute;bottom:100%;pointer-events:none;display:flex;align-items:flex-end;gap:4px}
.deco-l{left:4%}.deco-r{right:3%}
/* 横は板を広げ、飾りを端へ寄せる(本の縁との間を 8px 以上 ← 押し間違い) */
@media (orientation:landscape){ .plank{width:min(99%,600px)} .deco-l{left:0}.deco-r{right:0} }
.deco{display:block;width:52px;height:60px}
.deco.lamp{width:44px;height:78px}
.lamp-wrap{position:relative;display:block}
.lamp-wrap::after{content:"";position:absolute;left:50%;top:32%;width:190px;height:190px;transform:translate(-50%,-50%);pointer-events:none;opacity:0;
  background:radial-gradient(closest-side,color-mix(in srgb,var(--lamp) 34%,transparent),transparent)}
/* ランプの傘のまわりの小さな光(芯) */
.lamp-wrap::before{content:"";position:absolute;left:50%;top:32%;width:150px;height:150px;transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(closest-side,color-mix(in srgb,var(--lamp) 36%,transparent),color-mix(in srgb,var(--lamp) 10%,transparent) 60%,transparent)}
.lamp-wrap .lamp{position:relative}
/* 回る棚の操作: ◀ 3 / 10 ▶(棚の胴の下。本に重ならない)。数は「いま前の本 / 全部」で見通しを付ける */
.shelf-ctrl{position:relative;z-index:3;display:flex;align-items:center;justify-content:center;gap:2px;margin-top:calc(var(--cab) + 6px)}
.shelf-ctrl[hidden]{display:none}
.shelf-count{min-width:84px;text-align:center;font-size:20px;font-weight:600;color:var(--text-night);letter-spacing:.04em;font-variant-numeric:tabular-nums;white-space:nowrap}
.nav .face{background:var(--wood)}

/* ---- 飾りを押したときの小さな応え(toshokan.md 5)。1 回きり・ゆっくり・明滅しない。動くのは箱の transform と不透明度だけ ---- */
.poke{pointer-events:auto;cursor:pointer;will-change:transform}
.jar,.cat{overflow:visible}
@keyframes sway{0%,100%{transform:none}14%{transform:rotate(-6deg)}34%{transform:rotate(4.5deg)}54%{transform:rotate(-2.6deg)}74%{transform:rotate(1.2deg)}}
@keyframes nod{0%,100%{transform:none}25%{transform:rotate(-3deg)}55%{transform:rotate(2deg)}80%{transform:rotate(-.8deg)}}
@keyframes swing{0%,100%{transform:none}12%{transform:rotate(7deg)}32%{transform:rotate(-5.5deg)}52%{transform:rotate(3.6deg)}72%{transform:rotate(-2deg)}88%{transform:rotate(.8deg)}}
@keyframes owl-tilt{0%,100%{transform:none}22%,62%{transform:rotate(-9deg)}80%{transform:rotate(2deg)}}
@keyframes eyes-open{0%,16%{opacity:0}26%,64%{opacity:1}76%,100%{opacity:0}}
@keyframes eyes-shut{0%,16%{opacity:1}26%,64%{opacity:0}76%,100%{opacity:1}}
@keyframes glow-once{0%{opacity:0}30%,55%{opacity:1}100%{opacity:0}}
@keyframes room-glow{0%{opacity:0}30%,55%{opacity:1}100%{opacity:0}}
@keyframes float-up{0%{opacity:0;transform:none}20%{opacity:1}100%{opacity:0;transform:translateY(-34px)}}
@keyframes tail{0%,100%{transform:none}22%{transform:rotate(-16deg)}48%{transform:rotate(6deg)}72%{transform:rotate(-9deg)}}
@keyframes z-up{0%{opacity:0;transform:none}25%{opacity:1}100%{opacity:0;transform:translate(10px,-24px)}}
@keyframes shoot{0%{opacity:0;transform:translate(116px,28px)}14%,70%{opacity:1}100%{opacity:0;transform:translate(34px,70px)}}
.plant,.owl,.jar,.lamp{transform-origin:50% 100%}
.plant.poked{animation:sway 1.6s ease-in-out}
.owl.poked{animation:owl-tilt 2.4s ease-in-out}
.owl .owl-open{opacity:0}
.owl.poked .owl-open{animation:eyes-open 2.4s ease-in-out}
.owl.poked .owl-shut{animation:eyes-shut 2.4s ease-in-out}
.jar.poked{animation:nod 1.2s ease-in-out}
.jar .jar-glow,.jar .jar-float{opacity:0}
.jar.poked .jar-glow{animation:glow-once 3s ease-in-out}
.jar.poked .jar-float{animation:float-up 2.4s ease-out .3s backwards}
.lamp.poked{animation:nod 1.2s ease-in-out}
.lantern.poked{animation:swing 3.2s ease-in-out}
.lib.glow .lamp-glow::after,.lib.glow .lamp-wrap::after,.lib.glow .lantern-wrap::after{animation:room-glow 3.2s ease-in-out}
.cat .cat-tail{transform-origin:41px 50px}
.cat .cat-z{opacity:0}
.cat.poked .cat-tail{animation:tail 1.8s ease-in-out}
.cat.poked .cat-z{animation:z-up 2.6s ease-out .2s backwards}
/* 飾りひも(縦だけ。窓と棚のあいだの壁)。押せるのは旗だけ(ひもの箱の空いた所は壁のまま) */
.garland-wrap{position:absolute;left:0;right:0;top:10px;pointer-events:none}
.garland{display:block;width:100%;height:auto}
.garland.poke{pointer-events:none}
.garland .flag{pointer-events:auto}
@keyframes flag{0%,100%{transform:none}20%{transform:rotate(12deg)}45%{transform:rotate(-8deg)}70%{transform:rotate(3deg)}}
.garland.poked .flag{animation:flag 1.6s ease-in-out var(--d,0ms) backwards}
.win .shoot{opacity:0}
.win.poked .shoot{animation:shoot 1.5s ease-in-out}

.book-slot{display:flex;justify-content:center}
.book{display:block;width:var(--bw)}
.book .face{display:flex;flex-direction:column;align-items:center;transition:transform .12s ease-out;will-change:transform;position:relative}
.book .cover{position:relative;display:block;width:var(--bw);height:var(--bh);border:2px solid var(--text-dim);border-radius:3px 7px 7px 3px;overflow:hidden;
  box-shadow:0 4px 0 var(--wood-dark);background:var(--tint)}
.book .cover img{display:block;width:100%;height:100%;object-fit:cover}
/* 背の側の厚み(固い表紙の綴じ目)。光らせない・押せる物の縁と影はそのまま */
.book .cover::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,color-mix(in srgb,var(--wood-dark) 45%,transparent) 0 3px,color-mix(in srgb,var(--paper) 14%,transparent) 3px 5px,transparent 10px)}
/* 開くときの写し(棚の箱の外。縦の画面で棚に切られないように ← toshokan.js openBook) */
.book-fly{position:fixed;z-index:40;margin:0;pointer-events:none}
.book-fly .book-title{transition:opacity .25s}
.book-fly.opening .book-title{opacity:0}   /* 大きくなった題名が隣の本の題名に重ならない */
.book .cover.plain{display:grid;place-items:center;color:var(--ink);font-family:var(--font-book);font-size:20px;padding:12px;text-align:center}
.book-title{display:block;max-width:100%;margin-top:10px;font-size:16px;color:var(--text-night);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.book.is-down .face{transform:translateY(-6px) scale(1.04)}
.book.opening .face{transition:transform .7s ease-in-out;z-index:20}
.book.closing .face{animation:book-close .7s ease-in-out}
@keyframes book-close{from{transform:translateY(-60px) scale(1.5)}to{transform:none}}

@media (orientation:landscape){
  .lib{grid-template-columns:minmax(0,36%) minmax(0,1fr);grid-template-rows:52px minmax(0,1fr)}
  .lib-title{grid-column:1;grid-row:1;justify-self:center}
  .lib-window{grid-column:1;grid-row:2;width:min(180px,40vh,30vw);align-self:center}
  .shelf-area{grid-column:2;grid-row:1 / span 2;--bw:120px;--bh:160px}
  .shelf-page{grid-template-columns:repeat(var(--cols,4),var(--bw))}
  .lib[data-count=one] .shelf-area{--bw:150px;--bh:200px}
  /* 回る棚の日は棚の上の飾りを置かない(両どなりの本に重なる ← toshokan.md 3.3) */
  .lib[data-count=ring] .deco-l,.lib[data-count=ring] .deco-r{display:none!important}
}
@media (orientation:landscape) and (max-height:340px){
  .lib-title{font-size:20px}
  .lib{--cab:14px}
  .shelf-area{--bw:96px;--bh:128px}
  .lib[data-count=one] .shelf-area{--bw:120px;--bh:160px}
  .deco{width:42px;height:48px}
  .deco.lamp{width:34px;height:60px}
  .cat-wrap{width:72px;height:42px;top:calc(100% + 3px + var(--cab) + 6px)}
  .shelf-ctrl{margin-top:calc(var(--cab) + 2px)}
  .shelf-ctrl .round{width:64px;height:64px}
  .shelf-ctrl .round .face{width:46px;height:46px}
  .shelf-count{min-width:68px;font-size:17px}
  /* 低い横は棚の右に鉢植えまで並べると題名に掛かる。ランプだけ */
  .shelf-plant{display:none}
}

/* ことば(本棚の右上。長押し 1 秒で一覧 ← design/toshokan.md 3.4)。絵本・2択・おやすみには置かない */
.lang-btn{position:absolute;z-index:4;top:calc(env(safe-area-inset-top) + 2px);right:calc(env(safe-area-inset-right) + 2px);width:52px;height:52px}
.lang-btn .face{width:38px;height:38px;background:color-mix(in srgb,var(--night-2) 70%,transparent)}
.lang-btn .ico{width:76%;height:76%}
/* 入口ページへ戻る口(本棚の右下の隅 ← .claude/rules/site-home.md・toshokan.md 3.4)。ことばと同じ控えめな丸(光らない・動かない) */
.site-home{position:absolute;z-index:4;right:calc(env(safe-area-inset-right) + 2px);bottom:calc(env(safe-area-inset-bottom) + 2px);width:52px;height:52px}
.site-home .face{width:38px;height:38px;background:color-mix(in srgb,var(--night-2) 70%,transparent)}
.site-home .ico{width:72%;height:72%}
/* 細い縦(320・360 幅)では右下だと ▶ の当たりの箱(88px)に届く(320x568 で隙間 0)。右上の ことば の下(窓の右の壁の空き)へ移す。
   ▶◀ の箱は詰めない(1歳の指の的)。ことば(長押し)と縦に並ぶので、絵(地球と家)で見分ける */
@media (orientation:portrait) and (max-width:370px){ .site-home{top:calc(env(safe-area-inset-top) + 62px);bottom:auto} }
/* 一覧: 本棚の上に重ねる(開いている間だけ DOM にある)。下地を押しても閉じる。札は割れない1語でも枠から出ない(minmax(0,1fr) + anywhere)
   2026-10-02 に14言語(+ とじる で15枚)。段の高さは中身なり(grid-auto-rows:minmax(62px,auto)。下限は名前 + 添え名の高さより少し上 = 普通の段はどれも同じ高さ。1fr だと Bahasa Indonesia の2行に全段が揃って
   360x640 でも入らない)。入らない画面(320x480・横向き)は safe center + overflow-y:auto で送れば とじる まで届く(実測 2026-10-02) */
.lang-menu{position:absolute;inset:0;z-index:30;display:grid;place-items:safe center;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;
  padding:calc(env(safe-area-inset-top) + 16px) calc(env(safe-area-inset-right) + 16px) calc(env(safe-area-inset-bottom) + 16px) calc(env(safe-area-inset-left) + 16px);
  background:color-mix(in srgb,var(--night-0) 90%,transparent)}
.lang-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(62px,auto);gap:12px;width:min(100%,380px)}
.lang-item,.lang-close{position:relative;display:flex;align-items:center;min-width:0;min-height:60px;padding:8px 34px 8px 14px;border-radius:12px;
  background:var(--night-2);border:2px solid var(--text-dim);box-shadow:0 2px 0 var(--wood-dark);color:var(--text-night);font-size:18px;line-height:1.25;text-align:left;overflow-wrap:anywhere;transition:transform .1s}
.lang-item.is-down,.lang-close.is-down{transform:scale(.96)}
.lang-item:focus-visible,.lang-close:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.lang-item{flex-direction:column;align-items:flex-start;justify-content:center}
.lang-name{min-width:0;max-width:100%}
.lang-sub{min-width:0;max-width:100%;margin-top:2px;font-size:13px;line-height:1.2;color:var(--text-dim)}
.lang-item.on{border-color:var(--pc-gold);box-shadow:inset 0 0 0 2px var(--pc-gold),0 2px 0 var(--wood-dark)}
.lang-check{position:absolute;right:8px;top:50%;width:22px;height:22px;margin-top:-11px;display:none}
.lang-check path{fill:none;stroke:var(--pc-gold);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.lang-item.on .lang-check{display:block}
.lang-close{justify-content:center;padding:8px 14px;background:var(--wood-dark);border-color:var(--wood-light)}
@media (orientation:landscape){ .lang-list{grid-template-columns:repeat(3,minmax(0,1fr));width:min(100%,560px)} }
@media (orientation:landscape) and (max-height:340px){
  .lang-menu{padding-top:calc(env(safe-area-inset-top) + 10px);padding-bottom:calc(env(safe-area-inset-bottom) + 10px)}
  .lang-list{gap:8px;grid-auto-rows:minmax(58px,auto)}
  .lang-item,.lang-close{min-height:52px;font-size:16px}
}

/* ================= 絵本 ================= */
/* 2026-09-30 利用者: スマホの縦が主。舞台を画面いっぱいに使い、操作は左上の「…」にたたむ(ehon.md 3)。
   縦 = 上に舞台(幅いっぱい・窓は 3:4〜4:3)、下に文の札。横 = 左に舞台(高さいっぱい)、右に文の札。
   --vw / --vh = safe-area を除いた画面。--pil / --val / --apr = 柱・上の飾り幕・床の縁。窓の外寸に足して舞台の箱にする */
.ehon{position:absolute;inset:0;display:grid;background:var(--grain),var(--night-2);
  grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);justify-items:center;
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  --vw:calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right));
  --vh:calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  --pil:8px;--val:18px;--apr:10px;--frame-w:calc(2 * var(--pil));--frame-h:calc(var(--val) + var(--apr));
  --textroom:236px;   /* 縦で文の札に残す高さ(24px・行間 1.5 の 5 行 + 余白) */
  --text:24px}
@supports (height:100dvh){ .ehon{--vh:calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom))} }
/* 縦: 幅いっぱい。高さは 窓 3:4(いちばん縦長)まで伸ばし、文の札の分は残す(窓が 4:3 より横長にはならない) */
.stage{grid-row:1;grid-column:1;position:relative;width:var(--vw);aspect-ratio:4/3}
.stage.is-stage{aspect-ratio:auto;width:var(--vw);
  height:max(calc((var(--vw) - var(--frame-w)) * .75 + var(--frame-h)),
    min(calc((var(--vw) - var(--frame-w)) * 4 / 3 + var(--frame-h)), calc(var(--vh) - var(--textroom))))}
.page{position:absolute;inset:0;background:var(--paper);border:6px solid var(--paper);border-radius:4px;box-shadow:0 3px 0 var(--wood-dark);overflow:hidden}
.page img{display:block;width:100%;height:100%;object-fit:cover;filter:brightness(.78) sepia(.1)}
.page.is-cover{background:var(--night-1)}
.page.is-cover img{object-fit:contain}
.page.outgoing{z-index:2;pointer-events:none;transform-origin:0 100%;transition:transform .9s ease-in-out;will-change:transform}
.page.outgoing.go{transform:translateX(-112%) rotate(-3deg)}
/* ---- 舞台(butai.md 3.3)。枠と幕は静止した SVG、窓の中は canvas 1枚 ---- */
.st-win{position:absolute;left:var(--pil);right:var(--pil);top:var(--val);bottom:var(--apr);overflow:hidden;background:var(--night-0)}
.stage-canvas{display:block;width:100%;height:100%;image-rendering:auto}
.st-cur{position:absolute;top:0;bottom:0;width:calc(50% + 1px);will-change:transform;
  transition:transform var(--cur-ms,1100ms) var(--cur-ease,ease-out)}
.st-cur svg{display:block;width:100%;height:100%}
.st-cur.l{left:0;transform:translateX(-90%)}
.st-cur.r{right:0;transform:translateX(90%)}
.st-win.closed .st-cur{transform:none}
.st-pil,.st-val,.st-apr{position:absolute;display:block;pointer-events:none}
.st-pil{top:0;bottom:0;width:var(--pil);height:100%}
.st-pil.l{left:0}
.st-pil.r{right:0}
.st-val{left:0;top:0;width:100%;height:calc(var(--val) + 6px)}
.st-apr{left:0;bottom:0;width:100%;height:var(--apr)}
.text-card{grid-row:2;grid-column:1;align-self:center;width:calc(100% - 24px);max-height:calc(100% - 24px);margin:12px 0;overflow:hidden;
  background:var(--grain-ink),var(--paper-card);color:var(--ink);border-radius:4px;padding:12px 18px;box-shadow:0 2px 0 var(--wood-dark)}
.text{margin:0;font-family:var(--font-book);font-size:var(--text);line-height:1.5;overflow-wrap:anywhere}
/* ja(分かち書き)と ko は語の切れ目で行を折る(文節の途中で折らない) */
.text:lang(ja),.text:lang(ko){word-break:keep-all}
.origin{margin:6px 0 0;font-size:13px;color:var(--ink)}
.origin:empty{display:none}

/* ---- たたんだ操作: 左上の「…」の丸 → 押すと帯が開く(舞台の上に重ねる。舞台の大きさは変えない) ---- */
.hud{position:absolute;z-index:6;left:calc(env(safe-area-inset-left) + 2px);top:calc(env(safe-area-inset-top) + 2px);
  display:flex;align-items:flex-start;gap:2px}
.round.mini{width:52px;height:52px}
.round.mini .face{width:38px;height:38px;background:color-mix(in srgb,var(--night-2) 70%,transparent)}
.hud:not(.open) .menu .face{opacity:.7}
.tray{display:flex;flex-direction:column;align-items:center;padding:0 6px 6px;border-radius:0 0 16px 16px;
  background:color-mix(in srgb,var(--night-0) 86%,transparent);box-shadow:0 2px 0 var(--wood-dark)}
.tray[hidden]{display:none}
.controls{display:flex;align-items:center;gap:0}
.controls .round{width:64px;height:64px}
.controls .round .face{width:50px;height:50px}
.controls .round.back .face{width:52px;height:52px}
.controls .pause .face{width:56px;height:56px;border-color:var(--text-night)}
.pause .i-play{display:none}
.pause.is-paused .i-play{display:block}
.pause.is-paused .i-pause{display:none}
.pause .i-play,.pause .i-pause{width:62%;height:62%}
.pause .i-play .ico,.pause .i-pause .ico{width:100%;height:100%}
/* ---- 横向き(全画面)の札: 舞台の右上にいつも出す。絵(縦 → 横に回る端末)+ 短い字で「横で見る」と分かるように
   (2026-09-30 利用者: 帯の中の 4 隅のかぎの絵は分かりにくかった)。押せる物の文法(縁 + 影)は守る ---- */
.rotate{position:absolute;z-index:6;top:calc(var(--val) + 6px);right:calc(var(--pil) + 6px);min-height:52px;display:grid;place-items:center}
.rotate[hidden]{display:none}
@media (orientation:portrait){ .rotate.under-tray{visibility:hidden} }   /* 縦だけ帯が札へ重なる */
.rotate .face{display:flex;align-items:center;gap:4px;height:40px;padding:0 12px 0 6px;border-radius:20px;
  background:color-mix(in srgb,var(--night-2) 78%,transparent);border:2px solid var(--text-dim);box-shadow:0 2px 0 var(--wood-dark);transition:transform .1s}
.rotate.is-down .face{transform:scale(.94)}
.rotate .i-full,.rotate .i-exit{width:30px;height:30px;display:block}
.rotate .ico{width:100%;height:100%}
.rot-label{font-size:14px;line-height:1;color:var(--text-night);white-space:nowrap}
.rotate .i-exit{display:none}
.rotate.is-full .i-exit{display:block}
.rotate.is-full .i-full,.rotate.is-full .rot-label{display:none}
.rotate.is-full .face{padding:0 4px}
/* 端では矢印を出さないが、場所は残す(一時停止がずれない)。全画面の無い端末は場所ごと消す */
.controls .round[hidden]{display:grid;visibility:hidden}
.dots{display:flex;gap:8px;padding:2px 0 2px}
.dots i{width:8px;height:8px;border-radius:50%;border:1.5px solid var(--text-dim)}
.dots i.read{background:var(--text-dim)}
.dots i.now{background:var(--pc-gold);border-color:var(--pc-gold)}

/* 横: 左に舞台(高さいっぱい)、右に細い文の列。横にするのは舞台を大きく見るため(2026-09-30 利用者)なので、
   文は小さく細い列に寄せ、残りを全部舞台へ回す。窓は 16:9 まで横長になれて、4:3 より横長の分は上の空を切って拡大する(stage.js) */
@media (orientation:landscape){
  .ehon{grid-template-columns:auto minmax(0,1fr);grid-template-rows:minmax(0,1fr);justify-items:stretch;align-items:center;
    --text:17px;--textcol:clamp(170px,22vw,240px)}
  .stage{grid-column:1;grid-row:1;width:auto;height:var(--vh)}
  .stage.is-stage{height:var(--vh);
    width:min(calc((var(--vh) - var(--frame-h)) * 16 / 9 + var(--frame-w)), calc(var(--vw) - var(--textcol)))}
  .text-card{grid-column:2;grid-row:1;width:auto;max-width:320px;max-height:calc(100% - 16px);margin:8px 8px 8px 10px;padding:10px 12px;align-self:center}
}
@media (orientation:landscape) and (max-height:340px){
  .ehon{--pil:6px;--val:12px;--apr:8px;--text:15px}
  .text-card{padding:8px 10px}
  .controls .round{width:56px;height:56px}
  .controls .round .face,.controls .round.back .face{width:44px;height:44px}
  .controls .pause .face{width:48px;height:48px}
}

/* ================= 最後の2択 ================= */
.saigo{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:28px;
  background:var(--grain),var(--night-2);--cw:min(160px,calc((100vw - 48px) / 2));--ch:180px;--art-w:min(351px,calc(100vw - 24px))}
/* 縦のカード幅は画面幅から決める(2枚 + 間 24 + 両端 12。160 固定だと 320 幅で左が -12 に出た ← #1573) */
.last-art{width:calc(var(--art-w) * .6);aspect-ratio:4/3;background:var(--paper);border:4px solid var(--paper);border-radius:4px;overflow:hidden;box-shadow:0 3px 0 var(--wood-dark)}
.last-art img{display:block;width:100%;height:100%;object-fit:cover;filter:brightness(.78) sepia(.1)}
.saigo.in .last-art{animation:shrink-up 1.5s ease-in-out}
.last-art.is-stage{aspect-ratio:auto;width:auto;background:none;border:0;border-radius:0;box-shadow:none;overflow:visible}
.last-art .stage{position:relative;--sw:calc(var(--art-w) * .6);--pil:6px;--val:12px;--apr:8px;
  aspect-ratio:auto;width:var(--sw);height:calc((var(--sw) - 2 * var(--pil)) * .75 + var(--val) + var(--apr))}
@keyframes shrink-up{from{transform:translateY(20%) scale(1.66)}to{transform:none}}
.cards{display:flex;gap:24px}
.saigo.in .cards{animation:rise .6s ease-out}
@keyframes rise{from{transform:translateY(16px)}to{transform:none}}
.card{width:var(--cw);height:var(--ch)}
.card .face{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;width:100%;height:100%;border-radius:14px;
  box-shadow:0 3px 0 rgba(0,0,0,.4);transition:transform .1s}
.card[data-choice=oyasumi] .face{background:var(--night-0);border:3px solid var(--pc-lav)}
.card[data-choice=shelf] .face{background:var(--wood-dark);border:3px solid var(--wood-light)}
.card.is-down .face{transform:scale(.95)}
/* 絵は縮んでよい(低い横でラベルが2行になると、縮まない絵が上下へ 2px 押し出した ← #1578) */
.card-art{width:72%;height:52%;display:grid;place-items:center;min-height:0;min-width:0}
.card-art .ico,.card-art svg{width:100%;height:100%;min-height:0;min-width:0}
/* 2枚を同格に: 本棚カードの差し色は彩度を落とす(filter を使わず、トークンを灰みの色に差し替える) */
.card[data-choice=shelf] .card-art{--pc-rose:var(--pc-rose-m);--pc-sky:var(--pc-sky-m);--pc-leaf:var(--pc-leaf-m);--pc-gold:var(--pc-gold-m);--pc-lav:var(--pc-lav-m)}
.card .label{font-size:16px;color:var(--text-night);text-align:center;padding:0 8px;line-height:1.2}
/* ja は空白で折る(320 幅で「ねむりの おん / がく」と語の途中で折れた ← #1573) */
.card .label:lang(ja){word-break:keep-all}
/* ねむりの おんがく の何分で止まるか(2026-10-02 利用者「30分を数字で明記」) */
/* 本棚のカードにも見えない同じ高さの行を置き、2枚のラベルの高さをそろえる(同格) */
.card .sublabel{display:block;margin-top:-6px;font-size:14px;color:var(--text-dim);text-align:center;padding:0 8px;line-height:1.2}
.card .sublabel.spacer{visibility:hidden}
@media (orientation:landscape){
  .saigo{flex-direction:row;gap:32px;--cw:180px;--ch:160px;--art-w:min(400px,48vw)}
  .cards{gap:32px}
}
@media (orientation:landscape) and (max-height:340px){
  .saigo{--cw:140px;--ch:130px;gap:24px}
  .cards{gap:24px}
}
/* もう1冊の読みきかせの本への口(saigo.md 3.1)。右下の隅に小さく静か(2択より暗い縁・光らない・動かない・出てくる動きも無い)。
   箱は高さ 52px(本棚の ことば・入口への口と同じ大人の口の大きさ)、見えるのは 38px の丸い札 */
.other-book{position:absolute;z-index:4;right:calc(env(safe-area-inset-right) + 2px);bottom:calc(env(safe-area-inset-bottom) + 2px);
  height:52px;max-width:calc(100vw - 16px);padding:0 7px;display:flex;align-items:center;color:var(--text-dim);text-decoration:none;touch-action:manipulation}
.other-book:focus{outline:none}
.other-book:focus-visible .face{outline:3px solid var(--focus);outline-offset:3px}
.other-book .face{display:flex;align-items:center;gap:4px;min-width:0;height:38px;padding:0 12px 0 6px;border-radius:19px;
  background:color-mix(in srgb,var(--night-2) 70%,transparent);border:2px solid color-mix(in srgb,var(--text-dim) 70%,transparent);transition:transform .1s}
.other-book.is-down .face{transform:scale(.94)}
.other-book .ico{width:28px;height:28px;flex:0 0 auto}
.other-label{font-size:14px;line-height:1.1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ================= おやすみ ================= */
.veil{position:absolute;inset:0;background:var(--night-0);transform:translateY(-100%);display:grid;place-items:center}
.veil.down{animation:veil-down 2s linear forwards}
.veil.up{animation:veil-up .6s linear forwards}
@keyframes veil-down{from{transform:translateY(-100%)}to{transform:none}}
@keyframes veil-up{from{transform:none}to{transform:translateY(-100%)}}
.veil .back{position:absolute;left:calc(4px + env(safe-area-inset-left));top:calc(4px + env(safe-area-inset-top))}
.veil .back .face{background:var(--night-0);border-color:#2c3048;box-shadow:none;opacity:.35;transition:opacity 2s linear}
.veil .back.lit .face{opacity:.7;transition:opacity .2s}
.moon-wrap{width:150px;height:150px;pointer-events:none}
/* 月の上に、何分で音が止まるかを1行(数えない・動かない。暗いまま読める --moon-dim) */
.sleep-time{position:absolute;left:16px;right:16px;top:calc(50% - 75px - 44px);margin:0;font-size:16px;line-height:1.3;color:var(--moon-dim);text-align:center;pointer-events:none}
.moon{width:100%;height:100%;display:block}
.moon .crescent{fill:#20243a;stroke:var(--moon-dim);stroke-width:2}
.moon .arc-bg{fill:none;stroke:#1a1e33;stroke-width:3}
.moon .arc{fill:none;stroke:var(--moon-dim);stroke-width:3;stroke-linecap:round;stroke-dasharray:1000;stroke-dashoffset:0}
.veil .resume{position:absolute;left:50%;top:calc(50% + 100px);transform:translateX(-50%)}
.veil .resume .face{background:var(--night-0);border-color:var(--text-dim)}
@media (orientation:landscape){ .moon-wrap{width:112px;height:112px} .veil .resume{top:calc(50% + 72px)} .sleep-time{top:calc(50% - 56px - 40px);left:96px;right:96px} }

/* ---- 動きを減らす: 置き換わるだけ ---- */
@media (prefers-reduced-motion:reduce){
  .page.outgoing{display:none}
  .st-cur{transition:none}
  .veil.down{animation:none;transform:none}
  .veil.up{animation:none;transform:translateY(-100%)}
  .saigo.in .last-art,.saigo.in .cards,.book.closing .face{animation:none}
  .shelf-ring,.shelf-ring .book-slot,.book .face,.book.opening .face{transition:none}
  /* 飾りの応えは動かさず、灯りと目だけ(不透明度) */
  .plant.poked,.owl.poked,.jar.poked,.lamp.poked,.lantern.poked,.jar.poked .jar-float,.cat.poked .cat-tail,.cat.poked .cat-z,.win.poked .shoot,.garland.poked .flag{animation:none}
}
/* ---- テストの早送り(?fast=1) ---- */
html.fast *,html.fast *::before,html.fast *::after{transition-duration:1ms!important;animation-duration:1ms!important}
/* 早送りの上の行は transition-property の既定 all にも 1ms を与えるので、字の大きさまで遷移して測った値が一瞬前の値になる
   (本の字の大きさを測る ehon.js の bookFontSize が 24px のまま決めてしまった。製品の速さでは duration 0 なので起きない)。文の札は遷移させない */
html.fast .text-card,html.fast .text-card *{transition:none!important}
