/* =====================================================================
   おばけ算数 － 見た目（2/5）：プレー画面（盤面・v2・枠の問題・足あと道）
   ---------------------------------------------------------------------
   もとは1本の style.css でした。中身は1文字も変えず、行の順番も
   そのままで 5 本に分けただけです。
   ★ CSSは「後に書いたほうが勝つ」ので、index.html の <link> の
     並び順を入れ替えないでください。1→2→3→4→5 の順です。
   ===================================================================== */
:root{ --css-2-loaded:1; }

  /* =====================================================================
     盤面レイアウト（統合版）
     ---------------------------------------------------------------------
     #playArea は常に画面中央に「1つの箱」として配置する（left:50%+
     transform:translateX(-50%)を常にセットで維持し、左右非対称に
     ズラす時も必ずtransformを揃えて書く。これが崩れると中心がズレる）。

     縦持ち：#playArea を縦のFlexboxにして、おばけ→問題文→お皿の順に積む。
     横持ち：#playArea をCSS Gridにして、左列＝おばけ（縦方向に中央寄せで
     2行分を占有）、右列＝問題文とお皿を縦に並べる。おばけをposition:absolute
     で箱の外に逃がす方式は、箱自体もposition:absoluteだと入れ子の基準点が
     狂うため使わない。
     ===================================================================== */
  #playArea{position:absolute;left:50%;top:2%;transform:translateX(-50%);z-index:8;
    width:min(96vw,600px);height:66%;
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:clamp(12px,3vw,24px);pointer-events:none;}
  #promptText{width:100%;text-align:center;
    display:flex;flex-direction:column;align-items:center;gap:3px;pointer-events:none;}
  .pline{font-weight:900;color:var(--ink);line-height:1.35;
    font-size:clamp(19px,5.4vw,26px);
    background:rgba(255,252,246,.93);border-radius:16px;padding:5px 14px;
    box-shadow:0 3px 0 rgba(60,45,110,.13);align-self:center;}
  .pline2{font-size:clamp(20px,5.8vw,28px);}

  /* =====================================================================
     プレー画面 v2（いまは第1章だけ。body.playV2 が付いたときだけ効く）
     ===================================================================== */
  /* ---- B. 問題文は白い2段カードではなく、おばけが話す1つの吹き出し ---- */
  body.playV2 .pbubble{position:relative;font-weight:900;color:var(--ink);
    line-height:1.3;font-size:clamp(20px,5.6vw,27px);
    background:rgba(255,252,246,.95);border-radius:20px;padding:9px 20px;
    box-shadow:0 4px 0 rgba(60,45,110,.14), 0 8px 18px rgba(20,12,40,.22);
    max-width:min(86vw,460px);text-align:center;}
  /* おばけが話しているように見せる短い尻尾。上向き（おばけは吹き出しの上にいる） */
  body.playV2 .pbubble::after{content:"";position:absolute;top:-9px;left:50%;
    transform:translateX(-50%);
    border-left:11px solid transparent;border-right:11px solid transparent;
    border-bottom:11px solid rgba(255,252,246,.95);}
  body.playV2 #promptText{gap:0;}

  /* ---- A. お皿の大きさと影は共通木皿の規格へ一本化した ----
     以前はここで v2 の章だけ約72%へ縮め、旧CSS皿の立体感を弱めていた。
     いまは素材1枚＋承認済み carrierSize（standard／large／giant）だけで決まる。
     章ごとの倍率や影の上書きは持たせない（共通設計 v1.1.2 §12.4A）。 */
  /* おばけと操作対象の距離を近づけ、同じ場面の中にいるように見せる */
  body.playV2 #plateWrap{padding-top:clamp(8px,2vw,14px);}
  body.playV2 #playArea{gap:clamp(6px,1.8vw,14px);}
  /* 操作領域の後ろだけを柔らかく暗くして、りんごを見やすくする */
  body.playV2 #zoneSource::before{content:"";position:absolute;inset:-6% -4%;
    z-index:-1;pointer-events:none;border-radius:44%;
    background:radial-gradient(ellipse at 50% 50%,
      rgba(16,10,34,.42) 0%, rgba(16,10,34,.22) 52%, rgba(16,10,34,0) 78%);}

  /* ---- E. りんごを置くたびの、おばけの小さな反応 ---- */
  /* 置くほど少しだけ明るくなる灯り。画像そのものには触れないので、
     既存の4状態（weak/awake/restored/full）の見た目と競合しない */
  #stepGlow{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);
    width:96%;aspect-ratio:1/1;border-radius:50%;pointer-events:none;z-index:0;
    background:radial-gradient(circle, rgba(255,236,180,.55) 0%, rgba(255,214,120,0) 66%);
    opacity:0;transition:opacity .45s ease;}
  body.playV2 #stepGlow{opacity:calc(var(--stepLit,0) * .85);}
  /* 置いた瞬間の、ごく小さな上下。大声で褒めない */
  @keyframes ghostStep{
    0%{transform:translateY(0)} 42%{transform:translateY(-6px)} 100%{transform:translateY(0)}
  }
  @keyframes ghostWait{   /* 最後の1個の前だけ、少し期待した反応 */
    0%{transform:translateY(0) scale(1)}
    35%{transform:translateY(-9px) scale(1.035)}
    100%{transform:translateY(0) scale(1)}
  }
  body.playV2 #ghostWrap.stepReact{animation:ghostStep .42s ease-out;}
  body.playV2 #ghostWrap.stepReact.lastOne{animation:ghostWait .58s ease-out;}
  @media (prefers-reduced-motion:reduce){
    body.playV2 #ghostWrap.stepReact,
    body.playV2 #ghostWrap.stepReact.lastOne{animation:none;}
  }
  #plateWrap{width:100%;display:flex;gap:min(4vw,26px);
    justify-content:center;align-items:flex-start;
    padding-top:clamp(20px,5vw,26px);
    pointer-events:auto;}
  /* zeroChoice / zeroCustom で hidden にしても、author側のdisplay:flexが勝たないようにする。 */
  #plateWrap[hidden]{display:none!important;}
  /* 深い森の共通木皿（deepForest.shallowWoodPlate）。
     承認済みの透過素材1枚を第1〜10章で共有し、章ごとに表示規格だけを選ぶ。
     縦横比3:2は素材キャンバスの規格。可視外形だけを基準に引き伸ばさない。
     ふちの立ち上がりは素材が持っているので、CSSで木目や枠を描き足さない。
     影は矩形ではなく素材の形に沿わせる（drop-shadow）。 */
  /* 高さは aspect-ratio に頼らず、幅から計算して明示する。
     flexの子で aspect-ratio だけに任せると、実機のSafariで高さが0になり
     お皿が見えなくなった（2026-08-25 実機で発生）。
     幅は --t-plate-w 一つで決め、高さは常にその2/3（素材の3:2）にする。 */
  .plate{position:relative;flex:0 0 auto;
    --t-plate-w:var(--t-carrier, var(--t-carrier-standard));
    width:var(--t-plate-w);
    height:calc(var(--t-plate-w) * 2 / 3);
    min-width:120px;min-height:80px;   /* どんな環境でも消えないための下限 */
    max-width:100%;border-radius:0;
    background:url('assets/deep-forest-common-shallow-wood-plate-v1.png')
      center/100% 100% no-repeat;
    box-shadow:none;
    filter:drop-shadow(0 10px 12px rgba(20,12,4,.45));
    transition:filter .18s;}
  /* 表示規格は章データの carrierSize だけで決まる。
     standard＝第1〜8章／large＝第9章／giant＝第10章（決定D20）。
     キャラクター名や章番号のセレクタは作らない。 */
  body[data-carrier-size="standard"] #stage{--t-carrier:var(--t-carrier-standard);}
  body[data-carrier-size="large"]    #stage{--t-carrier:var(--t-carrier-large);}
  body[data-carrier-size="giant"]    #stage{--t-carrier:var(--t-carrier-giant);}

  /* ======================================================================
     numberFrame（frameFill問題）：5枠・10枠の共通盤面
     plateAはそのまま当たり判定・サイズの土台として使い、上にframeGridを重ねる。
     おぼんの木目は隠し、枠らしい見た目にする（白木の升目・角丸の輪郭）。
     ====================================================================== */
  /* 枠の問題でも、お盆の見た目は通常と同じにする。
     以前は半透明にして「枠」を強調していたが、背景が透けて見づらかった。 */
  /* z-index は お皿(#playArea=8) より上、操作アイテム(.item=10) より下。
     ここを1や2にすると、お皿の裏に隠れて影も点も見えなくなる。 */
  .frameGrid{position:absolute; left:0; top:0; z-index:9; pointer-events:none;}
  /* マス目は「お盆にあいた浅いくぼみ」くらいの弱さで常に見せる。
     点線の枠は出さない。5個ずつ2段に並ぶので、5のまとまりが目で分かる。 */
  .frameCell{position:absolute; box-sizing:border-box;
    border:0; border-radius:26%;
    background:radial-gradient(ellipse at 50% 42%,
      rgba(96,70,38,.26) 0%, rgba(96,70,38,.13) 68%, rgba(96,70,38,0) 100%);
    box-shadow:inset 0 0 0 2px rgba(126,96,54,.22),
               inset 0 2px 3px rgba(60,42,20,.16);}
  /* bare：手がかりを一切出さない状態（第10章＝集大成）。
     くぼみも消して、ただのお盆に見せる。置き場所としては生きている。
     ヒントで手がかりを出す段になると、JS が bare を外して段階的に見せる。 */
  .frameGrid.bare .frameCell{background:none; box-shadow:none;}
  /* 「あといくつ」の印。くぼみの上に重ねるので ::after を使い、
     マス目そのものの見た目（background）は壊さない。 */
  /* 点：抽象的な印。形は見せない */
  .frameCell.cue-dots::after{
    content:''; position:absolute; left:50%; top:50%; width:30%; height:30%;
    transform:translate(-50%,-50%); border-radius:50%;
    background:rgba(255,250,236,.72);
    box-shadow:0 0 8px rgba(255,240,200,.45);}
  /* 影：アイテムの形そのものを、うすい白抜きで見せる */
  .frameCell.cue-shadow::after{
    content:''; position:absolute; inset:14%;
    background-image:var(--item-shadow-img, none);
    background-size:contain; background-repeat:no-repeat; background-position:center;
    opacity:.30;
    filter:grayscale(1) brightness(2.6) contrast(.7)
           drop-shadow(0 0 3px rgba(255,248,228,.5));}
  /* 影の絵が用意できていないキャラでは、点にしておく（何も出ないのを防ぐ） */
  .frameCell.cue-shadow.noShadowImg::after{
    inset:auto; left:50%; top:50%; width:30%; height:30%;
    transform:translate(-50%,-50%); border-radius:50%;
    background-image:none; background-color:rgba(255,250,236,.72); opacity:1;
    filter:none; box-shadow:0 0 8px rgba(255,240,200,.45);}
  /* 影の絵を画像ファイルではなくインラインSVGで持つキャラ（第1章のりんごなど）。
     新しい画像素材は増やさず、同じ絵をうすい白抜きにして数量ヒントへ流用する。 */
  .frameCell.cue-art::after{content:none;}
  .frameCell .cueArt{position:absolute; inset:14%; line-height:0;
    opacity:.34;
    filter:grayscale(1) brightness(2.4) contrast(.75)
           drop-shadow(0 0 3px rgba(255,248,228,.5));}
  .frameCell .cueArt svg, .frameCell .cueArt img{display:block; width:100%; height:100%;}
  .frameNumeral{position:absolute; right:-6px; top:-10px; z-index:9;
    min-width:1.6em; padding:.15em .3em; border-radius:50%;
    background:rgba(40,28,14,.72); color:#FFF6DE; font-weight:900;
    font-size:clamp(16px, 4vw, 22px); text-align:center; line-height:1.3;
    box-shadow:0 3px 8px rgba(0,0,0,.35);}
  /* 見本（第2章Q5専用）：触れない点のまとまり。枠と対になる位置に置く */
  /* 見本（「これと おなじ かずに」の“これ”）。
     位置は JS が子どものお皿の真上へ置く。中身は点ではなく、実物と同じ絵。
     display:flex を書くと hidden 属性が効かなくなるため、必ず打ち消しを添える。 */
  .frameReference{position:absolute; z-index:9; pointer-events:none;
    display:flex; align-items:center; justify-content:center;
    flex-wrap:nowrap; gap:4%;
    padding:2.2% 3%; border-radius:999px;
    border:3px solid rgba(255,248,228,.55);
    background:rgba(40,28,14,.42);
    box-shadow:0 4px 14px rgba(0,0,0,.35);}
  .frameReference[hidden]{display:none;}
  .frameGrid[hidden], .frameNumeral[hidden]{display:none;}
  .frameReference .refItem{flex:0 0 auto; display:block; line-height:0;}
  .frameReference .refItem img, .frameReference .refItem svg{
    display:block; width:100%; height:100%;}

  /* 2枚を横に並べる型は pair 規格。素材・縦横比は1枚のときと同じ。
     幅を1つの値で決めるので、2枚は必ず同寸法になる。
     carrierSize（standard／large／giant）は1枚型のときの規格なので、
     ここでは使わない。第9・10章も2枚になる問題では pair になる。 */
  #stage.lay-two .plate{--t-plate-w:var(--t-carrier-pair);}
  /* 触れる合図・正誤の合図・触れない状態は、矩形の枠ではなく
     素材の形に沿った光と明るさで出す。 */
  .plate.hot{filter:brightness(1.06)
    drop-shadow(0 0 7px rgba(255,238,160,.95))
    drop-shadow(0 10px 12px rgba(20,12,4,.45));}
  .plate.flash{animation:plateFlash .6s ease-in-out 2;}
  @keyframes plateFlash{
    0%,100%{filter:drop-shadow(0 10px 12px rgba(20,12,4,.45))}
    50%    {filter:brightness(1.08) drop-shadow(0 0 11px rgba(255,238,160,.95))
            drop-shadow(0 10px 12px rgba(20,12,4,.45))}}
  /* 触れないお皿は、木の色を沈ませる */
  .plate.locked{filter:saturate(.62) brightness(.9)
    drop-shadow(0 8px 10px rgba(20,12,4,.4));}
  .zlabel{position:absolute;left:50%;top:clamp(-24px,-5vw,-20px);transform:translateX(-50%);
    font-size:clamp(13px,3.6vw,17px);font-weight:900;color:#FFF3D6;
    text-shadow:0 2px 4px rgba(30,20,60,.6);white-space:nowrap;}
  .zcount{position:absolute;left:50%;bottom:-26px;transform:translateX(-50%);
    font-size:clamp(14px,3.8vw,18px);font-weight:900;color:var(--ink);
    background:rgba(255,252,246,.94);border-radius:12px;padding:2px 11px;
    box-shadow:0 2px 0 rgba(60,45,110,.14);white-space:nowrap;}
  #zoneSource{position:absolute;left:3%;right:3%;top:70%;height:22%;z-index:1;}

  /* 第11章「空っぽ」：生成した果物かごを、ブルーベリーの戻し先として見せる。 */
  body.zeroMake #zoneSource::after{
    content:"";position:absolute;inset:0;
    background:url('assets/fruit_basket_w2.webp') center/contain no-repeat;
    filter:drop-shadow(0 9px 10px rgba(4,11,35,.42));
    pointer-events:none;
  }
  body.zeroMake #zoneSource{z-index:2;}
  /* お皿とカゴを横並びにする。zoneSource自体がカゴの当たり判定になる。 */
  body.zeroMake #plateWrap{justify-content:flex-start;padding-left:4%;padding-right:0;}
  body.zeroMake #plateA{flex:0 0 min(44vw,225px);max-width:min(44vw,225px);height:min(22vw,108px);}
  /* お皿と同じ高さに並べる（お皿の中心と、かごの中心をそろえる） */
  /* お皿とかごを、空いている下側へそろえて下げる。
     かごは stage 基準の%、お皿は自分の高さ基準なので、
     画面の高さ（vh）で合わせている。ここだけ触れば上下に動かせる。 */
  body.zeroMake #zoneSource{left:55%;right:3%;top:50%;height:24%;}
  body.zeroMake #plateWrap{transform:translateY(11.5vh);}
  body.zeroMake #zoneSource::before{display:none;}

  /* 直接タップする大きな器（Q1・Q2・Q5・Q6） */
  .zeroQuestBoard{position:absolute;z-index:13;left:50%;top:68%;transform:translate(-50%,-50%);
    width:min(96vw,680px);min-height:30%;display:flex;align-items:center;justify-content:center;
    pointer-events:auto;}
  .zeroVesselRow{width:100%;display:flex;align-items:flex-end;justify-content:center;
    gap:clamp(10px,3vw,28px);padding:12px;}
  .zeroVessel{position:relative;width:clamp(88px,25vw,150px);height:clamp(76px,21vw,124px);
    border:0;border-radius:0;overflow:visible;padding:0;font-family:inherit;
    background:url('assets/blue_light_vessel_w2.webp') center/100% 100% no-repeat;
    filter:drop-shadow(0 9px 9px rgba(1,12,40,.46));touch-action:manipulation;}
  button.zeroVessel:active{transform:translateY(3px) scale(.97);}
  .vesselRim{display:none;}
  .vesselInside{position:absolute;z-index:2;left:13%;right:13%;top:11%;bottom:15%;display:flex;
    align-items:center;justify-content:center;gap:2px;flex-wrap:wrap;align-content:center;}
  .zeroBerry{display:inline-flex;width:clamp(31px,8vw,48px);height:clamp(31px,8vw,48px);
    border:0;background:none;padding:0;align-items:center;justify-content:center;touch-action:manipulation;}
  .zeroBerry svg{display:block;width:100%;height:100%;filter:drop-shadow(0 3px 3px rgba(9,23,76,.35));}
  button.zeroBerry:active{transform:scale(.88);}
  .zeroBadge{position:absolute;z-index:5;left:50%;top:46%;transform:translate(-50%,-50%) scale(.55);
    display:grid;place-items:center;width:clamp(48px,13vw,72px);height:clamp(48px,13vw,72px);
    border-radius:50%;background:rgba(246,253,255,.95);border:4px solid #5CC5FF;color:#1455C6;
    font-size:clamp(30px,8vw,48px);font-weight:900;opacity:0;box-shadow:0 0 22px rgba(88,211,255,.9);}
  /* v71：小正解の表示。行き過ぎを承認済みの上限へそろえた */
  .zeroBadge.reveal{opacity:1;transform:translate(-50%,-50%) scale(1);transition:opacity .25s,transform .38s var(--t-ease-pop-once, cubic-bezier(.22,1.08,.36,1));}
  .zeroVessel.correct{filter:drop-shadow(0 0 7px rgba(155,240,255,.95)) drop-shadow(0 0 20px rgba(72,199,255,.92));}
  .zeroVessel.blueLight{animation:blueVesselLight .7s ease-in-out infinite alternate;}
  @keyframes blueVesselLight{to{filter:brightness(1.20) drop-shadow(0 0 24px rgba(75,207,255,.95));}}
  .zeroVessel.wrong{animation:zeroWrong .36s ease-in-out 2;}
  @keyframes zeroWrong{0%,100%{transform:translateX(0)}50%{transform:translateX(8px)}}
  .zeroQuestBoard.hintPulse .zeroVessel{animation:zeroHint 1.1s ease-in-out 1;}
  @keyframes zeroHint{50%{filter:brightness(1.18) drop-shadow(0 0 15px rgba(183,241,255,.82));}}
  .orderNumber{position:absolute;left:50%;bottom:-38px;transform:translateX(-50%);min-width:1.55em;
    padding:.08em .35em;border-radius:50%;background:rgba(248,253,255,.94);color:#164C9B;
    font-size:clamp(24px,6vw,36px);font-weight:900;box-shadow:0 4px 10px rgba(2,13,45,.35);}
  .zeroFinalWrap{position:relative;width:100%;display:flex;align-items:flex-end;justify-content:center;
    gap:clamp(24px,7vw,70px);padding:10px;}
  /* うつわは drop-shadow を持つため独立した重なりを作る。
     かごより手前に置かないと、運んでいる途中のブルーベリーが
     かごの後ろへ回り込んで見えなくなる。 */
  .zeroFinalWrap{position:relative;}
  .zeroFinalWrap .zeroVessel{z-index:3;}
  .zeroFinalWrap .zeroBasket{z-index:2;}
  .zeroBasket{position:relative;width:clamp(126px,31vw,205px);height:clamp(72px,18vw,112px);
    display:flex;align-items:center;justify-content:center;padding:0;}
  .zeroBasket img{display:block;width:100%;height:100%;object-fit:contain;
    filter:drop-shadow(0 8px 8px rgba(4,11,35,.42));pointer-events:none;}
  .basketBerry{position:absolute;z-index:2;width:clamp(27px,6vw,42px);height:clamp(27px,6vw,42px);
    transform:translate(-50%,-50%);filter:drop-shadow(0 2px 3px rgba(9,23,76,.38));}
  .basketBerry svg{display:block;width:100%;height:100%;}
  .basketBerry.b1{left:40%;top:42%;}.basketBerry.b2{left:57%;top:42%;}.basketBerry.b3{left:49%;top:25%;}
  /* Q6はタップ移動ではなく、指で目的地まで運んで離す。 */
  .zeroBerry.zeroDragging,.zeroLight.zeroDragging{z-index:40;animation:none!important;
    transform:translate(var(--dragX,0),var(--dragY,0)) scale(1.10)!important;
    filter:brightness(1.12) drop-shadow(0 8px 9px rgba(2,13,45,.48));transition:none;}
  .zeroBerry.zeroAccepted,.zeroLight.zeroAccepted{pointer-events:none;z-index:40;animation:none!important;
    transform:translate(var(--dragX,0),var(--dragY,0)) scale(.45)!important;opacity:.72;
    transition:transform .22s cubic-bezier(.2,.75,.3,1),opacity .22s ease;}
  .zeroBerry.zeroReturning,.zeroLight.zeroReturning{z-index:40;animation:none!important;
    transform:translate(var(--dragX,0),var(--dragY,0)) scale(1)!important;
    transition:transform .18s ease-out;}
  .zeroBasket.dropReady{filter:brightness(1.12) drop-shadow(0 0 18px rgba(255,220,120,.92));}
  .zeroVessel.dropReady{filter:brightness(1.15) drop-shadow(0 0 22px rgba(104,227,255,.96));}
  /* stage直下に置き、あおばけちゃんの下で光らせる。 */
  .zeroLight{position:absolute;z-index:18;left:50%;top:42%;translate:-50% -50%;
    width:clamp(64px,15vw,94px);aspect-ratio:1;
    border:0;border-radius:50%;padding:0;background:none;touch-action:none;}
  .zeroLight[hidden]{display:none!important;}
  /* 第20章でも同じ発光球を数量単位として再利用する。形の正はここ1か所。 */
  .aobakeLight{position:relative;display:block;width:100%;aspect-ratio:1;
    border-radius:50%;pointer-events:none;}
  .zeroLight span,.aobakeLight>span{position:absolute;inset:13%;border-radius:50%;
    background:radial-gradient(circle at 38% 32%,#FFFFFF 0 6%,#CFFBFF 9%,#70E6FF 28%,#238DFF 58%,#1647C7 76%,rgba(22,71,199,0) 78%);
    box-shadow:0 0 12px #B8F7FF,0 0 30px rgba(64,203,255,.96),0 0 55px rgba(47,111,255,.72);}
  .zeroLight.ready{animation:zeroLightReady 1.1s ease-in-out infinite alternate;}
  @keyframes zeroLightReady{to{transform:translateY(-7px) scale(1.08);filter:brightness(1.15)}}
  .zeroLight.zeroHintPulse{filter:brightness(1.35);transform:scale(1.16);}
  @media (orientation:landscape) and (min-width:820px){
    .zeroQuestBoard{left:66%;top:71%;width:min(62vw,670px);min-height:34%;}
    .zeroVessel{width:clamp(105px,13vw,155px);height:clamp(88px,10vw,125px);}
    .zeroBerry{width:clamp(34px,4.3vw,49px);height:clamp(34px,4.3vw,49px);}
    body.zeroMake #plateWrap{padding-left:0;}
    body.zeroMake #plateA{flex-basis:min(23vw,235px);max-width:min(23vw,235px);height:min(12vw,115px);}
    body.zeroMake #zoneSource{left:67%;right:6%;top:50%;height:25%;}
    body.zeroMake #plateWrap{transform:translateY(7.4vh);}
    /* 盤面を広げたぶん、運ぶ先（おばけのあたり）も画面基準に置き直す */
    .composeBoard.deliverPhase{--ch13-zoneLeft:13%;--ch13-zoneTop:14%;
      --ch13-zoneW:18%;--ch13-zoneH:52%;}
    .zeroLight{left:28%;top:53%;}
  }
  @media (orientation:landscape) and (max-height:520px){
    .zeroQuestBoard{top:70%;}
    .zeroVessel{width:96px;height:78px;}.zeroBerry{width:30px;height:30px;}
    .orderNumber{bottom:-28px;font-size:22px;}
  }

  /* =====================================================================
     第12章「べとべとさん」：10と残りが見える足あと道
     ---------------------------------------------------------------------
     最初の10個は5個＋5個の二つの水たまりに分け、指を横へ滑らせると
     順番に光る。通常のお皿・アイテムは使わない。
     ===================================================================== */
  .footprintBoard{position:absolute;z-index:15;left:50%;top:70%;transform:translate(-50%,-50%);
    width:min(96vw,760px);min-height:clamp(150px,35vw,225px);padding:36px 10px 12px;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
    pointer-events:auto;touch-action:none;border-radius:28px;
    background:linear-gradient(180deg,rgba(6,30,66,.30),rgba(5,17,47,.54));
    border:1px solid rgba(114,222,255,.22);box-shadow:0 14px 34px rgba(0,9,38,.28);}
  .footGoal{position:absolute;left:50%;top:-24px;transform:translateX(-50%);z-index:5;
    display:flex;align-items:flex-end;gap:5px;color:#EAFBFF;font-weight:900;
    text-shadow:0 3px 8px rgba(0,8,36,.85);pointer-events:none;}
  .footGoalNumber{display:grid;place-items:center;width:clamp(56px,14vw,82px);aspect-ratio:1;
    border-radius:50%;font-size:clamp(31px,8vw,48px);line-height:1;color:#12529E;
    background:rgba(245,253,255,.96);border:4px solid #66D4FF;
    box-shadow:0 0 19px rgba(70,213,255,.72),0 6px 10px rgba(0,10,38,.35);}
  .footGoal small{font-size:clamp(15px,3.8vw,21px);padding-bottom:8px;white-space:nowrap;}
  .footprintTrack{position:relative;width:100%;height:clamp(72px,17vw,116px);
    display:grid;grid-template-columns:1fr 1fr 1fr;gap:clamp(5px,1.5vw,13px);
    align-items:center;padding:8px 10px;isolation:isolate;}
  .footprintTrack::before{content:"";position:absolute;z-index:-2;inset:1% 0 0;
    background:url('assets/betobetosan-footpath-base.webp') center/100% 82% no-repeat;
    opacity:.48;filter:saturate(.85) brightness(.88);transition:opacity .4s,filter .4s;}
  .footFive,.footExtras{position:relative;height:100%;display:grid;grid-template-columns:repeat(5,1fr);
    align-items:center;justify-items:center;gap:1px;padding:4px 3px 16px;border-radius:999px;
    background:rgba(28,94,142,.16);border:2px solid rgba(112,220,255,.12);
    transition:background .35s,border-color .35s,box-shadow .35s;}
  .footExtras{background:rgba(32,105,160,.08);border-color:rgba(112,220,255,.08);}
  .trailFoot{position:relative;z-index:2;width:clamp(22px,5.2vw,45px);height:clamp(36px,8vw,68px);
    display:flex;align-items:center;justify-content:center;border:0;padding:0;background:none;
    opacity:.42;filter:saturate(.60) brightness(.72);transform:translateY(0) scale(.92);
    transition:opacity .22s,filter .22s,transform .24s;touch-action:none;}
  .trailFoot img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none;}
  .trailFoot:nth-child(even){transform:translateY(5px) scale(.92);}
  .trailFoot.lit{opacity:1;filter:saturate(1.13) brightness(1.18)
    drop-shadow(0 0 7px #8AF3FF) drop-shadow(0 0 16px rgba(40,171,255,.94));
    transform:translateY(-2px) scale(1.04);}
  .trailFoot.lit:nth-child(even){transform:translateY(3px) scale(1.04);}
  .trailFoot.hintNext{animation:footHint 1.05s ease-in-out 1;}
  @keyframes footHint{50%{opacity:1;filter:brightness(1.45) drop-shadow(0 0 17px #A8F7FF);transform:scale(1.16)}}
  .trailFoot.demoTrace{animation:footDemo 1s ease-in-out 1;}
  @keyframes footDemo{45%{opacity:.9;filter:brightness(1.35) drop-shadow(0 0 13px #8CEEFF);transform:translateY(-5px) scale(1.10)}}
  .groupMark{position:absolute;z-index:4;left:50%;bottom:-7px;transform:translateX(-50%) scale(.7);
    display:grid;place-items:center;min-width:34px;height:28px;padding:0 7px;border-radius:999px;
    color:#155291;background:rgba(241,253,255,.96);border:2px solid #62CEFA;
    font-size:18px;font-weight:900;opacity:0;box-shadow:0 0 15px rgba(74,211,255,.65);
    transition:opacity .25s,transform .32s var(--t-ease-pop-once, cubic-bezier(.22,1.08,.36,1));}   /* v71 */
  .footprintBoard.firstFiveDone .mark5,
  .footprintBoard.tenDone .mark10{opacity:1;transform:translateX(-50%) scale(1);}
  .footprintBoard.firstFiveDone .footFiveA,
  .footprintBoard.tenDone .footFiveB{background:rgba(49,160,204,.22);border-color:rgba(126,232,255,.55);
    box-shadow:0 0 18px rgba(44,182,255,.25);}
  .footprintBoard.tenDone .footprintTrack::before{opacity:.92;filter:saturate(1.08) brightness(1.12)
    drop-shadow(0 0 11px rgba(61,202,255,.74));}
  .footStructure{display:flex;align-items:center;justify-content:center;gap:7px;min-height:34px;
    color:#EAFBFF;font-weight:900;font-size:clamp(16px,4vw,22px);text-shadow:0 2px 6px rgba(0,8,36,.82);}
  .tenChip,.extraChip{padding:3px 10px;border-radius:999px;background:rgba(236,252,255,.92);
    color:#15559D;box-shadow:0 0 12px rgba(73,205,255,.28);opacity:.45;transition:opacity .35s,transform .35s;}
  .andWord{opacity:.55;}.footNow{font-size:clamp(12px,3vw,16px);opacity:.64;min-width:68px;text-align:left;}
  .footprintBoard.tenDone .tenChip,.footprintBoard.tenDone .extraChip,
  .footprintBoard.tenDone .andWord{opacity:1;transform:scale(1.04);}
  .footprintBoard.trailComplete{border-color:rgba(132,240,255,.62);
    box-shadow:0 0 28px rgba(62,199,255,.42),0 14px 34px rgba(0,9,38,.28);}
  .footprintBoard.bridgeReached::after{content:"";position:absolute;right:-3%;top:43%;width:18%;height:45%;
    background:radial-gradient(ellipse,rgba(255,229,137,.72),rgba(75,205,255,.30) 45%,transparent 72%);
    filter:blur(3px);pointer-events:none;}
  .footprintBoard.showTenGuide .footFive{border-color:rgba(117,226,255,.48);}

  /* 散らばり方が違っても、5＋5のまとまりは同じだと見せる。 */
  .footprintBoard.pattern-scattered .trailFoot:nth-child(2n){transform:translateY(9px) rotate(5deg) scale(.90);}
  .footprintBoard.pattern-scattered .trailFoot:nth-child(3n){transform:translateY(-8px) rotate(-5deg) scale(.90);}
  .footprintBoard.pattern-wide .footFive,.footprintBoard.pattern-wide .footExtras{gap:4px;background:rgba(27,91,139,.08);}
  .footprintBoard.pattern-wide .trailFoot:nth-child(odd){transform:translateY(-7px) scale(.90);}
  .footprintBoard.pattern-wide .trailFoot:nth-child(even){transform:translateY(9px) scale(.90);}
  .footprintBoard.pattern-scattered .trailFoot.lit,
  .footprintBoard.pattern-wide .trailFoot.lit{transform:translateY(-1px) rotate(0) scale(1.04);}

  @media (orientation:landscape) and (min-width:820px){
    .footprintBoard{left:66%;top:73%;width:min(64vw,790px);min-height:188px;padding-top:38px;}
    .footprintTrack{height:102px;}.trailFoot{width:clamp(34px,3.2vw,44px);height:clamp(52px,4.8vw,66px);}
    .footGoal{top:-25px;}
  }
  @media (orientation:landscape) and (max-height:520px){
    .footprintBoard{top:72%;min-height:138px;padding:25px 8px 5px;gap:2px;}
    .footprintTrack{height:72px;padding-top:2px;padding-bottom:2px;}
    .trailFoot{width:30px;height:44px;}.footGoal{top:-17px;}
    .footGoalNumber{width:46px;font-size:27px;border-width:3px;}.footGoal small{font-size:13px;}
    .footStructure{min-height:23px;font-size:14px;}.groupMark{height:22px;font-size:14px;bottom:-3px;}
  }
  @media (max-width:390px) and (orientation:portrait){
    .footprintBoard{top:72%;padding-left:5px;padding-right:5px;}
    .footprintTrack{gap:2px;padding-left:2px;padding-right:2px;}
    .trailFoot{width:22px;height:36px;}.footStructure{gap:4px;}
    .tenChip,.extraChip{padding:2px 7px;}.footNow{min-width:55px;font-size:11px;}
  }
  @media (prefers-reduced-motion:reduce){
    .trailFoot.hintNext,.trailFoot.demoTrace{animation:none;filter:brightness(1.35) drop-shadow(0 0 12px #8CEEFF);}
  }
  #lanterns{position:absolute;top:10px;left:50%;transform:translateX(-50%);z-index:20;display:flex;gap:14px;}
  .lan{width:36px;height:50px;position:relative;}
  #bookBtn{position:absolute;right:4%;top:12px;z-index:76;
    width:clamp(48px,11vw,58px);height:clamp(48px,11vw,58px);border:none;border-radius:50%;
    background:rgba(255,249,239,.92);box-shadow:0 4px 0 rgba(60,45,110,.25);
    display:flex;align-items:center;justify-content:center;padding:0;}
  #ghostWrap{width:var(--ghost-w);max-width:100%;flex:0 0 auto;
    animation:bob 3.4s ease-in-out infinite;}
  #teaser{position:fixed;right:8%;bottom:18%;z-index:95;width:110px;opacity:0;
    transition:opacity 1s, transform 1s;transform:translateY(30px);pointer-events:none;}
  /* 左下の設定ボタンに届かない幅に収める。長い文は折り返す */
  #line{position:absolute;left:56%;bottom:2.5%;transform:translateX(-50%);z-index:65;
    max-width:min(62vw,560px);box-sizing:border-box;
    background:rgba(255,255,255,.92);border-radius:20px;padding:8px 18px;
    font-weight:700;font-size:var(--line-fs);white-space:normal;text-align:center;color:var(--ink);
    box-shadow:0 4px 0 rgba(60,45,110,.12);opacity:0;transition:opacity .3s;pointer-events:none;}
  #line.show{opacity:1;}

  /* ---- タブレット縦：全体を大きく ---- */
  @media (min-width:700px) and (orientation:portrait){
    #lanterns{gap:24px;top:20px;}
    .lan{width:55px;height:77px;}
    #teaser{width:180px;bottom:20%;}
    #bookBtn{width:70px;height:70px;top:22px;}
    #playArea{top:2%;height:62%;gap:22px;width:min(90vw,780px);}
    .pline{font-size:clamp(26px,3.4vw,34px);padding:8px 22px;border-radius:22px;}
    .pline2{font-size:clamp(27px,3.6vw,36px);}
    #plateWrap{gap:36px;padding-top:34px;}
    /* お皿の大きさは共通木皿の規格（carrierSize／pair）だけで決まる。
       ここにあった旧CSS皿むけの max-width／height の上書きは、
       承認済みの幅と3:2の比率を壊すため撤去した。 */
    #zoneSource{left:7%;right:7%;top:68%;height:23%;}
    .zcount{font-size:22px;bottom:-32px;padding:3px 14px;}
    .zlabel{font-size:22px;top:-32px;}
  }

  /* ---- 横向き：CSS Gridで左＝おばけ、右＝問題文とお皿の2列にする ---- */
  @media (orientation:landscape) and (min-width:820px){
    #stage{--apple:82px; --btn-size:112px; --ghost-w:min(24vw,240px);
           --line-fs:clamp(20px,2.4vw,28px); --num-fs:clamp(46px,5vw,64px);}
    #lanterns{left:50%;top:3.4%;gap:20px;}
    .lan{width:50px;height:70px;}
    #tree{height:22%;}
    #treeCrown{width:min(70vw,700px);}
    #line{bottom:2%;}
    #teaser{right:5%;bottom:24%;width:150px;}
    #bookBtn{width:62px;height:62px;right:2.5%;}

    #playArea{
      /* 箱全体は常に画面中央に固定する（left:50%とtransformは崩さない）。
         下の置き場(#zoneSource)と重ならないよう、縦の占有を抑えておく */
      top:6%;height:56%;
      width:min(88vw,760px);
      display:grid;
      grid-template-columns:minmax(150px,32%) 1fr;
      grid-template-rows:1fr auto;
      align-items:center;
      column-gap:clamp(16px,3vw,32px);
      row-gap:10px;
    }
    #ghostWrap{grid-column:1;grid-row:1 / span 2;justify-self:center;align-self:center;}
    #promptText{grid-column:2;grid-row:1;align-self:end;}
    #plateWrap{grid-column:2;grid-row:2;align-self:start;padding-top:20px;}
    .pline{font-size:clamp(20px,2.3vw,28px);}
    /* お皿の大きさは共通木皿の規格（carrierSize／pair）だけで決まる。
       ここにあった旧CSS皿むけの max-width／height の上書きは、
       承認済みの幅と3:2の比率を壊すため撤去した。 */
    /* playAreaの下端(top+height=62%)より確実に下から始める */
    #zoneSource{left:34%;right:4%;top:68%;height:28%;}
  }

  /* ---- 小型スマホ縦：はみ出しを防ぐ ---- */
  @media (max-width:360px){
    #lanterns{gap:10px;}
    .lan{width:31px;height:43px;}
    /* 左下の設定ボタン（幅50px＋余白）に重ならない幅に収める */
    #line{font-size:12px;padding:6px 12px;max-width:62vw;left:56%;}
    .pline{font-size:17px;padding:4px 10px;}
    /* お皿の大きさは共通木皿の規格（carrierSize／pair）だけで決まる。
       ここにあった旧CSS皿むけの max-width／height の上書きは、
       承認済みの幅と3:2の比率を壊すため撤去した。 */
    #zoneSource{top:71%;height:21%;}
  }

  /* ---- 縦が短い画面（アプリ内ブラウザ・小型端末） ---- */
  @media (max-height:820px) and (orientation:portrait){
    #stage{--ghost-w:min(34vw,150px);}
    #playArea{top:1%;height:68%;gap:clamp(8px,2vw,14px);}
    .pline{font-size:clamp(17px,4.8vw,22px);padding:4px 12px;border-radius:14px;}
    .pline2{font-size:clamp(18px,5.0vw,23px);}
    #plateWrap{padding-top:17px;}
    /* お皿の大きさは共通木皿の規格（carrierSize／pair）だけで決まる。
       ここにあった旧CSS皿むけの max-width／height の上書きは、
       承認済みの幅と3:2の比率を壊すため撤去した。 */
    .zcount{bottom:-21px;font-size:14px;padding:2px 9px;}
    .zlabel{top:-18px;font-size:14px;}
  }

  /* ---- 横向きで縦が狭い場合（スマートフォン横持ち） ---- */
  @media (orientation:landscape) and (max-height:520px){
    #stage{--ghost-w:min(20vw,150px); --apple:56px; --btn-size:84px;}
    #playArea{top:4%;height:88%;width:min(92vw,640px);column-gap:14px;row-gap:6px;}
    .pline{font-size:clamp(15px,2vw,20px);padding:3px 10px;}
    .pline2{font-size:clamp(16px,2.1vw,21px);}
    /* お皿の大きさは共通木皿の規格（carrierSize／pair）だけで決まる。
       ここにあった旧CSS皿むけの max-width／height の上書きは、
       承認済みの幅と3:2の比率を壊すため撤去した。 */
    .zcount{bottom:-18px;font-size:12px;}
    .zlabel{top:-16px;font-size:12px;}
    #zoneSource{left:32%;right:4%;top:60%;height:34%;}
  }

  /* ===== v008: 予告・バナー・行・キラキラの基本CSS（メディアクエリより前） ===== */
  
  #teaser.show{opacity:1;transform:translateY(0);animation:teaseBob 2.6s ease-in-out infinite 1s;}
  @keyframes teaseBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
  #teaser svg,#teaser img{width:100%;display:block;filter:drop-shadow(0 0 16px rgba(120,220,255,.6));}
  #teaser img.auto-sil{
    filter:brightness(0) drop-shadow(0 0 14px rgba(140,220,255,.55));
    opacity:.9;
  }
  #teaserQ{position:absolute;top:-26px;left:50%;transform:translateX(-50%);
    font-size:34px;font-weight:900;color:#8FE3FF;text-shadow:0 0 14px rgba(140,230,255,.8);}
  #teaserImg{width:100%;}
  #banner{position:fixed;inset:0;z-index:90;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:22px;
    background:rgba(40,30,80,.5);backdrop-filter:blur(2px);
    opacity:0;pointer-events:none;transition:opacity .45s;}
  #banner.show{opacity:1;pointer-events:auto;}
  #bannerCard{padding:40px 30px 36px;text-align:center;
    display:flex;flex-direction:column;align-items:center;gap:14px;
    max-width:90vw;min-width:min(80vw,300px);
    /* v71：章クリアのバナーはUIに近い。行き過ぎを上限へそろえた */
    transform:scale(.7);transition:transform .45s var(--t-ease-pop-once, cubic-bezier(.22,1.08,.36,1));
    /* --- 古びた木の板（実素材の1枚絵）---------------------------------
       ふちが欠けた形なので、四角い影は付けられない。
       box-shadow ではなく filter:drop-shadow を使うと、絵の形どおりに影が落ちる。
       画像は assets/card-plank.webp（透過webp） */
    /* 下地の色は置かない。置くと、欠けたふちの透過部分まで塗ってしまう */
    background:url('assets/card-plank.webp') no-repeat center/100% 100%;
    border-radius:0;
    box-shadow:none;
    filter:drop-shadow(0 10px 16px rgba(0,0,0,.55));
    min-height:min(28vh,210px);
    justify-content:center;
  }

  #banner.show #bannerCard{transform:scale(1);}
  #bannerIcon{font-size:52px;}
  #bannerTitle{font-size:25px;font-weight:900;color:#3F3218;
    text-shadow:0 1px 0 rgba(255,246,224,.7);}
  #bannerSub{font-size:15px;font-weight:700;color:#6B5637;}
  #line.show{opacity:1;}
  .spark{position:absolute;z-index:55;font-size:26px;pointer-events:none;animation:sparkFly 1.1s ease-out forwards;}
  @keyframes sparkFly{0%{opacity:1;transform:translate(0,0) scale(.6) rotate(0)}
    100%{opacity:0;transform:translate(var(--sx),var(--sy)) scale(1.35) rotate(140deg)}}

  @media (prefers-reduced-motion: reduce){ .gimg{animation:none;} }

  @keyframes flash{0%,100%{transform:scale(1)}50%{transform:scale(1.22)}}

  /* ---------- plate ---------- */

  #tree{position:absolute;left:0;right:0;bottom:0;height:29%;z-index:1;}
  #treeCrown{position:absolute;left:50%;bottom:-10%;transform:translateX(-50%);
    width:min(96vw,450px);height:110%;
    background:radial-gradient(ellipse at 50% 100%,#4F8F45 0%,#63A554 55%,#79B865 100%);
    border-radius:50% 50% 0 0;box-shadow:inset 0 14px 24px rgba(255,255,255,.16);}

  @keyframes applePulse{0%,100%{transform:scale(1)}50%{transform:scale(1.35)}}

  #teaserQ{position:absolute;top:-26px;left:50%;transform:translateX(-50%);
    font-size:34px;font-weight:900;color:#8FE3FF;text-shadow:0 0 14px rgba(140,230,255,.8);}

  .overlay{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;
    visibility:visible;background:rgba(45,35,85,.6);backdrop-filter:blur(3px);transition:opacity .4s;}
  /* opacityだけで隠すと、子要素でpointer-events:autoを指定したボタンが
     透明なまま手前に残り、別画面の操作を遮ることがある。非表示時は画面全体を
     hit-testから外し、深い森・水幻郷・全体マップの切替後も操作を残さない。 */
  .overlay.hidden{opacity:0;visibility:hidden;pointer-events:none!important;}
  .overlay.hidden *{pointer-events:none!important;}
  .card{padding:46px 30px 42px;display:flex;flex-direction:column;
    align-items:center;gap:16px;max-width:92vw;min-width:min(84vw,320px);text-align:center;
    /* --- 古びた木の板（実素材の1枚絵）---------------------------------
       ふちが欠けた形なので、四角い影は付けられない。
       box-shadow ではなく filter:drop-shadow を使うと、絵の形どおりに影が落ちる。
       画像は assets/card-plank.webp（透過webp） */
    /* 下地の色は置かない。置くと、欠けたふちの透過部分まで塗ってしまう */
    background:url('assets/card-plank.webp') no-repeat center/100% 100%;
    border-radius:0;
    box-shadow:none;
    filter:drop-shadow(0 10px 16px rgba(0,0,0,.55));
    min-height:min(34vh,290px);
    justify-content:center;
  }

  .card h1{font-size:26px;font-weight:900;color:#3F3218;
    text-shadow:0 1px 0 rgba(255,246,224,.7);}
  .card p{font-size:15px;font-weight:700;color:#6B5637;line-height:1.7;}
  /* 板の上でも読めるよう、図鑑の番号だけ色を合わせる */
  .card .zno{color:#7A6242;}
  /* 決定の札は共通コンポーネント（style-base.css の .tagPrimary）へ移した。
     板の上に置く札だけ、文字を折り返さない指定をここへ残す */
  .card .tagPrimary{white-space:nowrap;}
  #miniGhost{width:105px;} #endGhost{width:110px;} #endGhost img{width:100%;display:block;} #miniGhost img{width:100%;display:block;filter:brightness(.75) saturate(.85);animation:bobSmall 2.6s ease-in-out infinite;}
  @keyframes bobSmall{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}

  /* =====================================================================
     合成する問題（composeParts）／第13章「いったんもめん」
     ---------------------------------------------------------------------
     部品を置き場所へ運んで目標の数にする盤面。汎用の型なので、
     ここには章名で分岐する指定を書かないこと。
     位置と大きさは下の変数だけを触れば調整できる（実機を見てから詰める用）。
     ===================================================================== */
  :root{
    --stage-bg-7:url('assets/stage_bg_7_suigenkyo_ch13.webp');
    /* 盤面の置き場所（おばけと吹き出しに重ならない範囲） */
    --ch13-left:34%;   --ch13-right:3%;
    --ch13-top:24%;    --ch13-bottom:4%;
    /* 部品の大きさ */
    /* 10の帯2本を横に並べた幅＝20の帯1本の幅、になるようにそろえる */
    --ch13-bandW:min(29vw,290px);
    --ch13-patchW:min(13vw,140px);
    --ch13-longW:min(38vw,420px);   /* 20の帯は二段の絵（縦横比3.50）。横向きは背の高さを優先して控えめに */
    /* 完成した帯を運ぶ先（おばけのあたり）。盤面の左外側に置く */
    --ch13-zoneLeft:-30%; --ch13-zoneTop:14%;
    --ch13-zoneW:27%;     --ch13-zoneH:52%;
  }
  /* 合成の盤面は自前で場所を作るので、既定のお皿と置き場は出さない。
     （後ろに大きなお皿が残って見えてしまうため） */
  body.composePlay #plateWrap,
  body.composePlay #plateA,
  body.composePlay #plateB,
  body.composePlay #zoneSource,
  body.composePlay .plateCount{display:none!important;}
  .composeBoard{position:absolute;z-index:15;
    left:var(--ch13-left);right:var(--ch13-right);
    top:var(--ch13-top);bottom:var(--ch13-bottom);
    display:flex;flex-direction:column;align-items:center;justify-content:space-evenly;
    gap:clamp(4px,1.4vh,14px);pointer-events:none;}
  .composeBoard > *{pointer-events:auto;}

  .composeGoal{display:flex;align-items:baseline;gap:6px;padding:4px 16px;border-radius:16px;
    background:rgba(14,42,72,.72);border:2px solid rgba(150,222,255,.42);
    color:#E9F8FF;font-weight:900;text-shadow:0 2px 5px rgba(0,0,0,.7);}
  .composeGoalNumber{font-size:clamp(22px,5.2vw,40px);color:#FFE9A8;}
  .composeGoal small{font-size:clamp(11px,2.4vw,17px);}

  .composeSlots{display:flex;align-items:center;justify-content:center;
    gap:clamp(6px,1.6vw,20px);width:100%;flex-wrap:nowrap;}
  .composeSlot{position:relative;border:3px dashed rgba(180,226,255,.52);border-radius:16px;
    background:rgba(16,46,78,.30);display:flex;align-items:center;justify-content:center;}
  .composeSlot.kind-band{width:var(--ch13-bandW);aspect-ratio:1100 / 239;}
  .composeSlot.kind-patch{width:var(--ch13-patchW);aspect-ratio:700 / 304;}
  .composeSlot .slotBase{width:96%;height:96%;object-fit:contain;opacity:.34;display:none;}
  .composeSlot.kind-band .slotBase,
  .composeSlot.kind-bandLong .slotBase,
  .composeSlot.kind-patch .slotBase{display:block;}
  .composeSlot.filled{border-style:solid;border-color:rgba(140,236,255,.72);
    background:rgba(30,86,128,.34);}
  .composeSlot .composePart.placed{position:absolute;inset:0;width:100%;}

  .composeSum{display:flex;align-items:center;gap:6px;min-height:1.6em;
    color:#EAF8FF;font-weight:900;font-size:clamp(13px,3vw,22px);
    text-shadow:0 2px 5px rgba(0,0,0,.72);}
  .composeSum .sumChip{padding:1px 10px;border-radius:11px;background:rgba(20,58,92,.74);
    border:1px solid rgba(154,224,255,.42);}
  .composeSum .composeNow{padding:1px 12px;border-radius:12px;background:rgba(255,220,130,.9);
    color:#3A2C10;border:1px solid rgba(255,240,190,.9);}
  .composeSum .composeNow.dim{background:rgba(210,232,248,.32);color:#DDEFFA;}

  .composeTray{display:flex;align-items:flex-end;justify-content:center;
    gap:clamp(8px,2.4vw,26px);width:100%;flex-wrap:nowrap;}
  .composePart{position:relative;border:0;background:none;padding:0;font-family:inherit;
    display:flex;flex-direction:column;align-items:center;gap:2px;
    touch-action:none;cursor:pointer;transition:transform .16s ease,opacity .2s ease;}
  .composePart.kind-band{width:var(--ch13-bandW);}
  .composePart.kind-patch{width:var(--ch13-patchW);}
  .composePart.kind-bandLong{width:var(--ch13-longW);}
  .composePart img{width:100%;height:auto;display:block;
    filter:drop-shadow(0 6px 10px rgba(0,16,44,.5));}
  .composePart .partNo{min-width:2.1em;padding:0 8px;border-radius:11px;
    background:rgba(12,40,70,.82);border:1px solid rgba(160,226,255,.5);
    color:#F2FBFF;font-weight:900;font-size:clamp(13px,3vw,21px);
    text-shadow:0 2px 4px rgba(0,0,0,.7);}
  .composePart.placed .partNo{font-size:clamp(11px,2.4vw,17px);}
  .composePart.dragging{transform:translate(var(--dragX,0),var(--dragY,0)) scale(1.05);
    z-index:30;transition:none;}
  .composePart.used{opacity:0;pointer-events:none;}
  .composePart.reject{animation:composeReject .34s ease;}
  @keyframes composeReject{
    0%,100%{transform:translateX(0)}
    30%{transform:translateX(-7px)}
    65%{transform:translateX(6px)}
  }

  /* ヒント。自動で正解にはせず、見せるだけ */
  .composeBoard.hint1 .composeSlot.kind-band{animation:composeGlow 1.5s ease-in-out infinite;}
  .composeBoard.hint1 .composeGoalNumber{animation:composeGlow 1.5s ease-in-out infinite;}
  .composePart.hintOn img{animation:composeGlow 1.2s ease-in-out infinite;}
  .composePart.hintDemo{animation:composeDemo 1.4s ease-in-out;}
  @keyframes composeGlow{50%{filter:brightness(1.35) drop-shadow(0 0 12px rgba(150,232,255,.9));}}
  @keyframes composeDemo{
    0%,100%{transform:translateY(0)}
    40%{transform:translateY(-38px) scale(1.05)}
    70%{transform:translateY(-38px) scale(1.05)}
  }

  /* 完成した帯を自分で運ぶ段階 */
  .composeDeliverZone{position:absolute;left:var(--ch13-zoneLeft);top:var(--ch13-zoneTop);
    width:var(--ch13-zoneW);height:var(--ch13-zoneH);border-radius:26px;
    border:3px dashed rgba(255,232,160,.6);background:rgba(255,226,150,.12);
    animation:composeGlow 1.8s ease-in-out infinite;pointer-events:none;}
  .composeDeliverZone.received{border-color:rgba(255,244,200,.95);
    background:rgba(255,238,180,.3);animation:none;}
  .composeBoard.deliverPhase .composeSlots{display:none;}
  .composeBoard.deliverPhase .composeSum{display:none;}
  /* 置き場所が消えたぶん、運ぶ帯は空いた場所の下寄りのまん中へ。
     まん中に置くと、おばけの吹き出しと重なるため。 */
  .composeBoard.deliverPhase .composeTray{flex:1;align-items:flex-end;justify-content:center;
    padding-bottom:14%;}
  /* 運ぶ段階は吹き出しが役目を引き継ぐので、目標の札は出さない */
  /* v70：補助文。既定では出さない。タブレット横だけで使う。 */
  .composeSub{display:none;}
  .composeBoard.deliverPhase .composeGoal{display:none;}
  /* 置き場所が消えるので、盤面を画面いっぱいに広げて帯を画面のまん中に置く */
  .composeBoard.deliverPhase{left:3%;right:3%;}
  .composePart.deliverItem{margin-bottom:2px;}
  /* 運び終わり。以前はここで opacity:0 にして消していたため、
     せっかく運んだ帯が目の前から消えてしまっていた。今は枠の上に残して着地させる */
  .composePart.delivered{opacity:1;}
  .composePart.delivered img{animation:ch13Land .36s var(--t-ease-pop-once, cubic-bezier(.22,1.08,.36,1));}   /* v71 */
  @keyframes ch13Land{
    0%{transform:scale(1.07)}
    55%{transform:scale(.965)}
    100%{transform:scale(1)}
  }

  /* 布のおばけは輪郭が柔らかいので、共通の濃い影だと背景から浮いて見える。
     広く・薄く散らして、世界に溶け込ませる（第13章の画面だけ） */
  body.composePlay #ghostImgs{
    filter:drop-shadow(0 14px 26px rgba(10,6,26,.32))
           drop-shadow(0 4px 8px rgba(10,6,26,.20))
           drop-shadow(0 0 4px rgba(255,255,255,.22));}

  /* 縦向きの端末では、おばけの下に広く取る */
  @media (orientation:portrait){
    :root{
      --ch13-left:3%; --ch13-right:3%; --ch13-top:40%; --ch13-bottom:3%;
      --ch13-bandW:min(43vw,210px); --ch13-patchW:min(20vw,104px); --ch13-longW:min(88vw,430px);
      --ch13-zoneLeft:28%; --ch13-zoneTop:-32%; --ch13-zoneW:44%; --ch13-zoneH:28%;
    }
  }
  @media (prefers-reduced-motion:reduce){
    .composeBoard.hint1 .composeSlot.kind-band,
    .composeBoard.hint1 .composeGoalNumber,
    .composePart.hintOn img,.composePart.hintDemo,
    .composeDeliverZone{animation:none;}
  }

  /* =====================================================================
     第13章の縦画面：三領域で組み直す（2026/8/4・設計書 v1.0.1 準拠）
     ---------------------------------------------------------------------
       ものがたり  3つの灯り ＋ 今日つなぐ数の札（画面でいちばん強いもの）
       おばけ      高さ216px。基準は144〜220px かつ 画面高22〜32%
       操作域      下部44%。基準は40〜50%
       下端        実余白 max(セーフエリア,16px)。12%の注意帯は
                   空白予約ではないので、操作域が入ってよい

     数字の札を上へ出したのは、置き先2行＋部品行を操作域へ入れると
     縦画面に収まらないため。「どこへ行くか」は物語側の情報なので、
     灯りの隣へ掲げるほうが役割としても正しい。

     実機で調整するのは下の4つだけ。トークンが未読込でも動くように
     var(…, 既定値) の形にしてある。
     ===================================================================== */
  @media (orientation:portrait){
    body.composePlay #stage{
      /* v55：画面の高さについてくるようにした。
         下限は iPhone14（高さ844px）で実機承認した値そのもの。
         25.6vh × 844 = 216px、7.6vh × 844 = 64px、1.4vh × 844 = 12px。
         iPad縦（1180px）では上限まで伸びる（280 / 88 / 16）。
         px固定のままだと iPad で おばけが画面高の18%になり、
         設計書の「救出対象 iPad 176〜280px かつ縦画面高22〜32%」を
         下回っていた。余った高さが下端の空白として残るのも同じ原因。 */
      --hero-h:clamp(216px, 25.6vh, 280px);  /* おばけの高さ */
      --row-gap:clamp(12px, 1.4vh, 16px);    /* 盤面の行と行 */
      --part-h:clamp(64px, 7.6vh, 88px);     /* 部品と置き先の高さ。56px以上 */
      --play-h:48%;      /* 操作域の高さ。基準40〜50% */
      --goal-h:60px;     /* 数字の札のおよその高さ */

      /* 部品の幅は「高さ×絵の縦横比」で決まる。
         帯 1100/239＝4.60倍、パッチ 700/304＝2.30倍。（v50で荷札つきの絵に合わせて更新） */
      --ch13-bandW:min(84vw, calc(var(--part-h) * 4.60));
      --ch13-patchW:min(38vw, calc(var(--part-h) * 2.30));
      /* 20の帯は10＋10の二段の絵（縦横比 4.23・荷札つき）。
         高さは 幅÷4.23 になるので、幅237px以上で 56px の基準を満たす。 */
      --ch13-longW:min(88vw, 420px);
    }

    /* --- 数字の札は出さない。
       「17に しよう」と「ひかりを 17こに つなごう」は同じ意味で、
       同じことを2か所で言っていた。おばけの声だけ残し、
       その中の数字を強くする（下の .pnum）。 --- */
    body.composePlay .composeGoal,
    body.composePlay .composeSub{display:none;}

    /* --- おばけ：灯りの下から、札の上まで。ここが画面の主役 --- */
    body.composePlay #playArea{
      top:62px;
      bottom:calc(var(--play-h) + 12px);height:auto;
      justify-content:flex-start;gap:var(--t-space-1,4px);}
    /* 収まらない端末では、重なるのではなく おばけが縮む。
       56px は ことば1行分の場所。 */
    body.composePlay #ghostWrap{
      width:auto;height:min(var(--hero-h),calc(100% - 56px));
      aspect-ratio:1/1;max-width:96vw;}
    /* ことばは紙の板ではなく、おばけの声。
       背景と同化して読めなかったので、墨のにじみを回して浮かせる。
       運ぶ段階は文字が #promptText へ直接入るので、親も同じ扱いにする。 */
    body.composePlay #playArea #promptText,
    body.composePlay #playArea .pline,
    body.composePlay #playArea .pbubble{
      background:none;box-shadow:none;border-radius:0;padding:0;
      color:#FFFFFF;opacity:1;font-weight:900;line-height:1.35;
      font-size:clamp(16px,4.2vw,20px);max-width:92%;
      text-shadow:
        0 0 3px rgba(2,7,43,1),0 0 8px rgba(2,7,43,1),
        0 0 18px rgba(2,7,43,.95),0 2px 4px rgba(2,7,43,1);}
    body.composePlay #playArea .pbubble::after{display:none;}
    /* 文中の数字は、世界の中の小さな札として囲む。
       囲むと「いくつにするのか」を探さずに見つけられる。 */
    body.composePlay #playArea .pnum{
      display:inline-block;vertical-align:middle;
      font-size:clamp(34px,8.6vw,44px);line-height:1.05;
      color:var(--t-lantern-700,#9A5B10);
      font-variant-numeric:tabular-nums;
      background:var(--t-paper-050,#FAF5E8);
      border:2px solid var(--t-wood-300,#C9A971);
      border-radius:var(--t-radius-s,12px);
      box-shadow:var(--t-shadow-1,0 4px 10px rgba(23,43,50,.18));
      padding:0 10px 3px;margin:0 5px;text-shadow:none;}
    /* 札が大きいぶん、行と行の間を空けて折り返しても読めるようにする */
    body.composePlay #playArea #promptText,
    body.composePlay #playArea .pline,
    body.composePlay #playArea .pbubble{line-height:1.5;}

    /* --- 操作域：下端から積み上げる --- */
    body.composePlay .composeBoard{
      top:auto;height:var(--play-h);
      bottom:max(env(safe-area-inset-bottom,0px),var(--t-space-4,16px));
      justify-content:flex-start;gap:var(--row-gap);}
    /* 帯とパッチは横に並べると両方を56px以上にできないので、折り返す */
    body.composePlay .composeSlots{
      flex-wrap:wrap;gap:var(--row-gap);}
    body.composePlay .composeSlot{
      border-width:2px;border-color:rgba(250,245,232,.42);
      border-radius:var(--t-radius-s,12px);}
    body.composePlay .composeSlot.filled{
      border-color:var(--t-lantern-300,#FFD77A);
      background:rgba(255,215,122,.14);}
    /* 部品の当たり判定を、見た目より上下へ広げる（72px以上） */
    body.composePlay .composePart{position:relative;}
    body.composePlay .composePart::after{
      content:"";position:absolute;left:50%;top:50%;
      transform:translate(-50%,-50%);
      width:calc(100% + var(--t-space-4,16px));
      height:max(72px,calc(100% + var(--t-space-4,16px)));}
    body.composePlay .composePart.placed::after{display:none;}
    /* 合計の式は出さない。帯の上と下に数字が二重に出ていた。
       いくつ置いたかは、置いた帯そのものに付く数字で分かる。 */
    body.composePlay .composeSum{display:none;}
    /* 数字は絵の中の荷札の上へ乗せる。荷札は「数を書く場所」として
       描いてもらったもの。黄色の札を重ねると荷札が隠れるので、
       背景を外して墨の文字だけにする。
       帯とパッチで荷札の位置が違うので、種類ごとに合わせる。 */
    body.composePlay .composePart .partNo{
      position:absolute;bottom:auto;margin:0;z-index:2;
      transform:translate(-50%,-50%);
      display:flex;align-items:center;justify-content:center;
      min-width:0;padding:0;border:0;border-radius:0;
      background:none;box-shadow:none;line-height:1;
      color:var(--t-ink-900,#1F2D2A);font-weight:900;
      text-shadow:0 1px 0 rgba(255,252,244,.92);}
    /* 帯の荷札：左から11.5%、上下のほぼ中央 */
    body.composePlay .composePart.kind-band .partNo,
    body.composePlay .composePart.kind-bandLong .partNo{
      left:11.5%;top:50%;font-size:clamp(18px,4.4vw,24px);}
    /* パッチの荷札：左から17.5%、上から36%（実測 6/7/8 が中心x17.4%・y35.3%） */
    body.composePlay .composePart.kind-patch .partNo{
      left:17.5%;top:36%;font-size:clamp(15px,3.6vw,20px);}
    /* 設定は左下から右上へ。左下は部品の並ぶ場所と同じ帯なので、
       設計書10.4「戻る・確定を同じ親指帯へ重ねない」に反していた。
       上の帯（灯りの列）は空いていて、地図ボタンと左右で対になる。 */
    body.composePlay #settingsBtn{
      top:max(12px,env(safe-area-inset-top,0px));
      right:max(14px,env(safe-area-inset-right,0px));
      left:auto;bottom:auto;}

    /* 選ぶ帯は縮めない。数字が中に入っているので、
       小さくすると光が数字で隠れてしまう。
       横に入りきらないときは2段へ折り返す。 */
    body.composePlay .composeTray{
      flex-wrap:wrap;justify-content:center;
      gap:var(--row-gap);padding:0 var(--t-space-2,8px);}
    body.composePlay .composeTray .composePart{flex:0 0 auto;}
    /* 案内の白い札は出さない。おばけの声と同じことを言っていて、
       2つの文字が重なって読みにくかった。 */
    body.composePlay #line{display:none;}

    /* 運ぶ段階：20の帯が二段になって背が高くなったぶん、下の余白を詰める */
    body.composePlay .composeBoard.deliverPhase .composeTray{padding-bottom:4%;}
    /* 「いったんもめんへ はこんでね」と言うのだから、
       運ぶ先の枠は おばけを囲んでいないと言葉と合わない。
       盤面の中ではなく、画面の中のおばけの位置へ重ねる。 */
    /* 運ぶ段階は、枠のすぐ下に文字が付きすぎるので少し離す */
    body.composeDeliver #playArea{gap:var(--t-space-8,32px);}
    /* おばけの絵には下側に透明な余白がある。そのぶん詰めて、
       ことばを おばけのすぐ下へ寄せる。 */
    body.composePlay:not(.composeDeliver) #playArea #promptText{
      margin-top:-36px;}
    /* v55：枠の大きさを おばけの高さから決める。
       おばけを囲む枠なので、おばけが大きくなったら枠も大きくならないと
       「囲んでいる」に見えない。1.26倍・1.04倍は iPhone の承認値
       （216px のとき 272×224）をそのまま再現する係数。 */
    body.composePlay .composeDeliverZone{
      position:fixed;top:58px;
      left:50%;margin-left:calc(-1 * min(33vw, calc(var(--hero-h) * .63)));
      width:min(66vw, calc(var(--hero-h) * 1.26));
      height:min(31vh, calc(var(--hero-h) * 1.04));
      border-radius:var(--t-radius-l,24px);}
  }

  /* ============================================================
     第13章 v55：タブレット縦（幅700px以上）
     ・iPhone は部品が2段に折り返して操作域が埋まるが、
       iPad は幅が広いので1段に収まり、余りが全部
       下端の空白として残っていた。
     ・操作域の中で中央に寄せて、余りを上下へ分ける。
       幅700px未満（iPhone）には一切かからないので、
       承認済みの縦画面は変わらない。
     ============================================================ */
  @media (orientation:portrait) and (min-width:700px){
    body.composePlay .composeBoard{justify-content:center;}

    /* v56：おばけを画面のまん中寄りへ。
       上に寄せていたぶん、ことばと部品の間が大きく空いて見えていた。
       運ぶ段階は除く（運ぶ先の枠が画面の上に固定されていて、
       おばけが下がると枠から外れてしまうため）。 */
    body.composePlay:not(.composeDeliver) #playArea{justify-content:center;}

    /* v56：運ぶ段階のトレイは引き伸ばさない。
       flex:1 + align-items:flex-end で盤面いっぱいに伸びてから
       中身を下端へ押し付けていたので、20の帯だけ画面の
       いちばん下に取り残されていた。 */
    body.composePlay .composeBoard.deliverPhase .composeTray{
      flex:0 0 auto;align-items:center;padding-bottom:0;}
  }

  /* ============================================================
     第13章 v57：タブレット横（横向き かつ 高さ600px以上）
     縦画面で決めた考え方をそのまま横へ移した共通テンプレート。
       左＝助けるおばけ ／ 中央上＝主見出し ／ その下＝補助文
       中央＝置き場 ／ その下＝カード ／ 右上＝おとも ／ 上中央＝3灯
     子どもが覚えるのは「上にやること、真ん中に置く場所、
     下に使うカード」という順番。問題が変わっても骨組みは変えない。
     スマホ横は高さ430px以下なのでかからない。
     ============================================================ */
  @media (orientation:landscape) and (min-height:600px){
    body.composePlay #stage{
      --hero-h:clamp(220px, 38vh, 330px);   /* v59：少し大きく。iPad横(820h) → 312px */
      /* 遊び心の小さな星。札と入れる枠のワンポイントに使う */
      --ch13-star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12,2 15,9 22,9.5 16.5,14 18.5,21 12,17 5.5,21 7.5,14 2,9.5 9,9' fill='%23FFE7A6'/%3E%3C/svg%3E");
      --row-gap:clamp(12px, 2.2vh, 18px);
      --part-h:clamp(72px, 11.7vh, 100px);  /* iPad横 → 96px。縦より大きめ */
      /* 部品の幅は「高さ×絵の縦横比」。帯4.60・パッチ2.30 */
      --ch13-bandW:min(38vw, calc(var(--part-h) * 4.60));
      --ch13-patchW:min(19vw, calc(var(--part-h) * 2.30));
      --ch13-longW:min(50vw, 565px);        /* v60：20の帯を約8%大きく（比5.09） */
      /* 盤面はおばけの右。上は補助文の下から */
      /* v64：おばけの位置と大きさを1か所にまとめた。
         運ぶ先の枠はこの3つから計算するので、おばけを動かせば
         枠も一緒に動く（別々に指定しない）。 */
      --ghost-x:9.5%;                        /* 左からの位置 */
      --ghost-y:clamp(72px, 11vh, 110px);    /* 上からの位置 */
      --ghost-size:min(var(--hero-h), 50vh); /* 一辺の長さ */
      --ch13-left:27%;  --ch13-right:3%;
      --ch13-top:38%;   --ch13-bottom:4%;   /* v61：補助文の紙帯の下から */
    }

    /* v62：3灯を少し上へ寄せて、主見出しの札と重ならない場所を作る。
       灯りは進み具合を伝える大事な表示なので、札の下に隠さない。 */
    body.composePlay #lanterns{top:2.6%;}

    /* --- 左：助けるおばけ。
       #playArea を画面いっぱいの横並びにして、おばけを左端へ置く。
       ここが感情の入口なので、最初に目に入る位置にする。 --- */
    body.composePlay #playArea{
      left:0;transform:none;width:100%;top:0;height:100%;
      display:flex;flex-direction:row;align-items:center;
      justify-content:flex-start;gap:0;}
    /* v63〜64：主見出しの真横に立たせる。「20を はこぼう」と並ぶことで、
       おばけが困って頼んでいる場面に見える。
       おばけは transform でふわふわ動いているので、
       transform ではなく余白と align-self でずらす。 */
    body.composePlay #ghostWrap{
      flex:0 0 auto;align-self:flex-start;
      width:auto;height:var(--ghost-size);
      aspect-ratio:1/1;max-width:34vw;
      margin-left:var(--ghost-x);
      margin-top:var(--ghost-y);
      margin-bottom:0;}

    /* --- 中央上：主見出し。3灯の下、その問題のゴールだけを短く強く。
       縦画面では場所が足りず消したが、横は中央上が空いている。
       v58：札の幅を中身ぴったりにした。画面幅いっぱいに広げていたため
       中が空っぽに見え、右上のおともまで札の中に入ってしまっていた。 --- */
    body.composePlay .composeGoal{
      display:flex;position:fixed;z-index:20;
      left:50%;right:auto;transform:translateX(-50%);
      width:max-content;max-width:56vw;top:12.5%;
      justify-content:center;align-items:baseline;
      padding:6px 34px;border-radius:var(--t-radius-l,24px);
      /* v59：札の四隅に小さな星。飾りが主役にならない大きさにする */
      background-color:rgba(14,42,72,.72);
      background-image:var(--ch13-star),var(--ch13-star);
      background-repeat:no-repeat,no-repeat;
      background-position:12px 8px, right 12px bottom 8px;
      background-size:15px 15px, 11px 11px;}
    /* v59：運ぶ段階でも主見出しを出す。
       これまでは長い説明文だけで、ゴールが一目で分からなかった。 */
    body.composePlay .composeBoard.deliverPhase .composeGoal{display:flex;}
    /* v70：補助文。文言は index.html の PROMPT_SET が持ち、
       CSSは見た目だけを受け持つ（旧版はCSSのcontentに直書きしていた）。
       文字の後ろに細い紙の帯を敷き、置き先の輪郭を横切らせない。
       主見出しの札と同じ基準（12.5%）から積む。 */
    body.composePlay .composeSub{
      display:block;position:fixed;z-index:20;
      left:50%;transform:translateX(-50%);
      top:calc(12.5% + 96px);white-space:nowrap;
      padding:5px 22px;border-radius:999px;
      background:rgba(250,245,232,.90);
      border:1px solid rgba(201,169,113,.7);
      box-shadow:0 3px 10px rgba(2,7,43,.35);
      font-size:clamp(16px,1.9vw,22px);font-weight:900;
      color:var(--t-ink-900,#1F2D2A);text-shadow:none;}
    body.composePlay .composeBoard.deliverPhase .composeSub{display:block;}
    /* 主見出しが「おなじに しよう」のように数字を持たない型のとき */
    body.composePlay .composeGoalWord{
      font-size:clamp(26px,3.4vw,44px);font-weight:900;color:#FFE9A8;}
    /* 補助文をDOMへ移したので、おばけの声は横画面では使わない */
    body.composePlay #playArea #promptText{display:none;}
    /* v61：札が大きすぎて、下に添えた補助文が置き先の帯に重なっていた。
       主見出しは「いちばん強い」ままで、高さだけ抑える。 */
    body.composePlay .composeGoalNumber{font-size:clamp(36px,4.7vw,56px);line-height:1.1;}
    body.composePlay .composeGoal small{font-size:clamp(17px,2.1vw,26px);}

    /* --- 主見出しの下：補助文。
       白い板をやめて「おばけの声」にする（縦画面と同じ扱い）。
       主見出しより弱く見せて、順番を作る。 --- */
    /* v58：主見出しと同じことを言っているので、ふだんは出さない。
       「16にしよう」と「ひかりを16こに つなごう」は同じ意味で、
       数字が2回出るぶん、どこを見ればいいか分かりにくくなる。
       運ぶ段階だけは主見出しが出ないので、ここが唯一の案内になる。 */
    body.composePlay #promptText{
      position:absolute;left:27%;right:3%;top:28%;width:auto;}
    body.composePlay #playArea #promptText,
    body.composePlay #playArea .pline,
    body.composePlay #playArea .pbubble{
      background:none;box-shadow:none;border-radius:0;padding:0;
      color:#FFFFFF;opacity:1;font-weight:900;line-height:1.4;
      font-size:clamp(18px,2.2vw,26px);max-width:100%;
      text-shadow:
        0 0 3px rgba(2,7,43,1),0 0 8px rgba(2,7,43,1),
        0 0 18px rgba(2,7,43,.95),0 2px 4px rgba(2,7,43,1);}
    body.composePlay #playArea .pbubble::after{display:none;}
    body.composePlay #playArea .pnum{
      display:inline-block;vertical-align:middle;
      font-size:clamp(26px,3.2vw,38px);line-height:1.05;
      color:var(--t-lantern-700,#9A5B10);
      font-variant-numeric:tabular-nums;
      background:var(--t-paper-050,#FAF5E8);
      border:2px solid var(--t-wood-300,#C9A971);
      border-radius:var(--t-radius-s,12px);
      box-shadow:var(--t-shadow-1,0 4px 10px rgba(23,43,50,.18));
      padding:0 10px 3px;margin:0 5px;text-shadow:none;}
    /* 案内の白い札と合計の式は出さない。
       主見出しと同じことを言っていて、数字が二重になる。 */
    body.composePlay #line{display:none;}
    body.composePlay .composeSum{display:none;}

    /* --- 中央：置き場、その下：カード。
       「ここに、これを入れる」が伝わるよう距離を詰める。 --- */
    body.composePlay .composeBoard{
      justify-content:center;gap:var(--row-gap);}
    body.composePlay .composeSlots,
    body.composePlay .composeTray{
      flex-wrap:wrap;gap:var(--row-gap);}
    body.composePlay .composeSlot{
      border-width:2px;border-color:rgba(250,245,232,.42);
      border-radius:var(--t-radius-s,12px);}
    body.composePlay .composeSlot.filled{
      border-color:var(--t-lantern-300,#FFD77A);
      background:rgba(255,215,122,.14);}
    /* v60：まだ入っていない枠は「明るい紙面＋点線＋四隅の星」。
       常時強く光らせるのはやめ、カードを持ったときだけ明るくする。
       （v59は光りっぱなしで、つかめる物より枠のほうが目立っていた） */
    body.composePlay .composeSlot:not(.filled){
      border-color:rgba(255,240,205,.85);
      background-color:rgba(250,245,232,.20);
      background-image:var(--ch13-star),var(--ch13-star),
                       var(--ch13-star),var(--ch13-star);
      background-repeat:no-repeat;
      background-position:8px 7px, right 8px top 7px,
                          8px calc(100% - 7px), right 8px bottom 7px;
      background-size:11px 11px;
      box-shadow:0 0 0 2px rgba(255,231,166,.12);
      transition:background-color .18s ease, box-shadow .18s ease,
                 border-color .18s ease;}
    body.composePlay .composeSlot:not(.filled) .slotBase{opacity:.55;}
    /* カードをつかんでいる間だけ、入れ先が明るくなる。
       :has() が使えない端末では光らないだけで、動作には影響しない。 */
    body.composePlay:has(.composePart.dragging) .composeSlot:not(.filled){
      border-color:rgba(255,231,166,.98);
      background-color:rgba(255,214,110,.22);
      box-shadow:0 0 0 3px rgba(255,214,110,.22),
                 0 0 26px 8px rgba(255,214,110,.32);}
    /* 当たり判定を見た目より広げる（72px以上） */
    body.composePlay .composePart{position:relative;}
    body.composePlay .composePart::after{
      content:"";position:absolute;left:50%;top:50%;
      transform:translate(-50%,-50%);
      width:calc(100% + var(--t-space-4,16px));
      height:max(72px,calc(100% + var(--t-space-4,16px)));}
    body.composePlay .composePart.placed::after{display:none;}

    /* --- カードの数字を絵の荷札の上へ。
       縦画面で直した内容が横に入っておらず、
       数字が帯の外へ飛び出していた。位置は縦と同じ割合。 --- */
    body.composePlay .composePart .partNo{
      position:absolute;bottom:auto;margin:0;z-index:2;
      transform:translate(-50%,-50%);
      display:flex;align-items:center;justify-content:center;
      min-width:0;padding:0;border:0;border-radius:0;
      background:none;box-shadow:none;line-height:1;
      color:var(--t-ink-900,#1F2D2A);font-weight:900;
      text-shadow:0 1px 0 rgba(255,252,244,.92);}
    body.composePlay .composePart.kind-band .partNo,
    body.composePlay .composePart.kind-bandLong .partNo{
      left:11.5%;top:50%;font-size:clamp(20px,2.4vw,30px);}
    body.composePlay .composePart.kind-patch .partNo{
      left:17.5%;top:36%;font-size:clamp(19px,2.3vw,29px);}
    /* v59：選ぶカードどうしの間を少し広げて、1枚ずつに見えるようにする */
    body.composePlay .composeTray{gap:clamp(20px,3vw,40px);}

    /* --- 運ぶ段階：「いったんもめんへ はこんでね」と言うのだから、
       運ぶ先の枠は左のおばけに重ねる。 --- */
    /* v64：枠はおばけをそのまま囲む。--ghost-x/y/size から計算するので、
       おばけを動かしても枠がついてくる。16pxは絵のまわりの余白。 */
    body.composePlay .composeDeliverZone{
      position:fixed;margin-left:0;transform:none;
      left:calc(var(--ghost-x) - 16px);
      top:calc(var(--ghost-y) - 16px);
      width:calc(var(--ghost-size) + 32px);
      height:calc(var(--ghost-size) + 32px);
      border-radius:var(--t-radius-l,24px);
      border-color:rgba(255,240,205,.82);
      background:rgba(250,245,232,.10);
      box-shadow:0 0 0 2px rgba(255,231,166,.10);
      transition:background .18s ease, box-shadow .18s ease,
                 border-color .18s ease;}
    /* v62：運び終えた帯は入れ先の中へ収まる大きさまで縮める。
       帯（565px）が入れ先（330px）より大きく、入れ先が画面の左端に
       あるため、届けた瞬間に帯の左半分が画面の外へ出ていた。
       縮めることで「おばけに渡した」という意味とも合う。
       ※ img に掛ける。部品本体に transform を掛けると
         ドラッグの位置指定を奪う（v60の不具合と同じ理由）。 */
    body.composePlay .composePart.delivered img{
      animation:ch13LandShrink .38s cubic-bezier(.2,.9,.3,1) both;}

    /* v60：運ぶカードをつかんでいる間だけ、入れ先が淡く光る */
    body.composePlay:has(.composePart.dragging) .composeDeliverZone{
      border-color:rgba(255,231,166,.98);
      background:rgba(255,214,110,.18);
      box-shadow:0 0 26px 8px rgba(255,214,110,.30);}
    /* v60：長いカードを少し大きく、始まりに一度だけふわりと浮かせる。
       いちばん先に見てほしいのは「つかめる物」なので、
       枠より先にこちらへ目がいくようにする。 */
    /* 【重要】アニメは img に掛ける。部品そのものに掛けると、
       アニメの transform が .composePart.dragging の
       transform:translate(var(--dragX),var(--dragY)) を上書きしてしまい、
       指で動かしても部品が動かない＝ドラッグできない状態になる。
       fill-mode も使わない（終わった後まで transform を握り続けるため）。 */
    body.composePlay .composePart.deliverItem img{
      animation:ch13LiftOnce 1.1s cubic-bezier(.22,1.08,.36,1) .25s 1;}
    /* v59：ゴール地点に短い案内。どこへ運ぶのか一目で分かるようにする */
    body.composePlay .composeDeliverZone::before{
      content:"ここに いれてね";
      position:absolute;left:0;right:0;top:calc(100% + 10px);text-align:center;
      font-size:clamp(16px,1.9vw,22px);font-weight:900;color:#FFFFFF;
      text-shadow:
        0 0 3px rgba(2,7,43,1),0 0 8px rgba(2,7,43,1),
        0 0 18px rgba(2,7,43,.95),0 2px 4px rgba(2,7,43,1);}
    body.composePlay .composeBoard.deliverPhase{
      left:var(--ch13-left);right:var(--ch13-right);
      justify-content:center;}
    body.composePlay .composeBoard.deliverPhase .composeTray{
      flex:0 0 auto;align-items:center;padding-bottom:0;}
  }

  /* ============================================================
     第12章 v75：タブレット横（横向き かつ 高さ600px以上）
     第13章で決めた骨組みをそのまま持ち込む。
       左＝助けるおばけ ／ 中央上＝主見出し ／ その下＝補助文
       中央＝なぞる盤面 ／ 右上＝おとも ／ 上中央＝3灯
     主見出しと補助文は第13章と同じ .composeGoal / .composeSub を
     使うので、見た目の指定はここでも同じ値をなぞる。
     スマホ横（高さ430px以下）にはかからない。
     ============================================================ */
  @media (orientation:landscape) and (min-height:600px){
    body.footprintPlay #stage{
      --hero-h:clamp(220px, 38vh, 330px);
      --ghost-x:9.5%;
      --ghost-y:clamp(72px, 11vh, 110px);
      --ghost-size:min(var(--hero-h), 50vh);
      --ch13-star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12,2 15,9 22,9.5 16.5,14 18.5,21 12,17 5.5,21 7.5,14 2,9.5 9,9' fill='%23FFE7A6'/%3E%3C/svg%3E");}

    /* 3灯は主見出しの札と重ならない位置へ */
    body.footprintPlay #lanterns{top:2.6%;}

    /* --- 左：助けるおばけ --- */
    body.footprintPlay #playArea{
      left:0;transform:none;width:100%;top:0;height:100%;
      display:flex;flex-direction:row;align-items:center;
      justify-content:flex-start;gap:0;}
    body.footprintPlay #ghostWrap{
      flex:0 0 auto;align-self:flex-start;
      width:auto;height:var(--ghost-size);
      aspect-ratio:1/1;max-width:34vw;
      margin-left:var(--ghost-x);
      margin-top:var(--ghost-y);
      margin-bottom:0;}
    /* 白い吹き出しと案内の札は使わない（第13章と同じ扱い） */
    body.footprintPlay #playArea #promptText{display:none;}
    body.footprintPlay #line{display:none;}

    /* --- 中央上：主見出し。第13章と同じ札 --- */
    body.footprintPlay .composeGoal{
      display:flex;position:fixed;z-index:20;
      left:50%;right:auto;transform:translateX(-50%);
      width:max-content;max-width:56vw;top:12.5%;
      justify-content:center;align-items:baseline;gap:6px;
      padding:6px 34px;border-radius:var(--t-radius-l,24px);
      background-color:rgba(14,42,72,.72);
      background-image:var(--ch13-star),var(--ch13-star);
      background-repeat:no-repeat,no-repeat;
      background-position:12px 8px, right 12px bottom 8px;
      background-size:15px 15px, 11px 11px;
      color:#FFFFFF;font-weight:900;
      border:1px solid rgba(255,231,166,.28);
      box-shadow:0 6px 18px rgba(2,7,43,.45);}
    body.footprintPlay .composeGoalNumber{
      font-size:clamp(36px,4.7vw,56px);line-height:1.1;color:#FFE9A8;}
    body.footprintPlay .composeGoal small{font-size:clamp(17px,2.1vw,26px);}

    /* --- その下：補助文 --- */
    body.footprintPlay .composeSub{
      display:block;position:fixed;z-index:20;
      left:50%;transform:translateX(-50%);
      top:calc(12.5% + 96px);white-space:nowrap;
      padding:5px 22px;border-radius:999px;
      background:rgba(250,245,232,.90);
      border:1px solid rgba(201,169,113,.7);
      box-shadow:0 3px 10px rgba(2,7,43,.35);
      font-size:clamp(16px,1.9vw,22px);font-weight:900;
      color:var(--t-ink-900,#1F2D2A);text-shadow:none;}

    /* --- 中央：なぞる盤面。おばけの右、補助文の下 ---
       【重要】transform を必ず外す。
       主見出しと補助文は position:fixed で画面の上のほうへ置くが、
       transform の掛かった要素の中では fixed が「画面基準」ではなく
       「その要素基準」になり、盤面の中へ入り込んでしまう。
       第13章の盤面は transform を持っていないので起きなかった。
       ここでは transform をやめ、左右と上を直接指定する。 */
    body.footprintPlay .footprintBoard{
      transform:none;
      left:37%;right:4%;top:39%;bottom:auto;
      width:auto;min-height:190px;
      padding:18px 14px 14px;}
    /* 丸い目標は主見出しと同じことを言っているので横では出さない。
       これが吹き出しと重なっていた原因でもある。 */
    body.footprintPlay .footGoal{display:none;}
    body.footprintPlay .footStructure{margin-top:6px;}
    body.footprintPlay .footNow{min-width:0;opacity:.8;}
  }

  /* ============================================================
     第13章 v48：運ぶ段階の吸着
     ・.dragging が外れると位置指定も消える書き方なので、
       離したあと専用のクラスで位置を保ったまま飛ばす
     ============================================================ */
  /* v62：届けた帯が入れ先の中へ収まるまで縮む */
  @keyframes ch13LandShrink{
    0%{transform:scale(1);}
    62%{transform:scale(.54);}
    100%{transform:scale(.58);}}
  /* v60：運ぶカードが始まりに一度だけふわりと浮く。往復1回・拡大なし */
  @keyframes ch13LiftOnce{
    0%{transform:translateY(0);}
    45%{transform:translateY(-14px);}
    100%{transform:translateY(0);}}
  @media (prefers-reduced-motion:reduce){
    .composePart.deliverItem img{animation:none!important;}
  }
  .composePart.snapNear{filter:drop-shadow(0 10px 18px rgba(0,16,44,.34));}
  .composePart.composeFlying,
  .composePart.composeReturning{
    transform:translate(var(--dragX,0),var(--dragY,0)) scale(1.02)!important;
    z-index:40;pointer-events:none;}
  .composePart.composeFlying{
    transition:transform .24s cubic-bezier(.18,.86,.3,1.03)!important;}
  .composePart.composeReturning{
    transition:transform .22s cubic-bezier(.3,.7,.4,1)!important;}
  /* 近づいたとき、運ぶ先の枠が「ここだよ」と強く光る */
  .composeDeliverZone.near{
    animation:none;
    border-color:rgba(255,244,200,.95);
    background:rgba(255,238,180,.3);
    box-shadow:0 0 26px 10px rgba(255,214,110,.5);}
  @media (prefers-reduced-motion:reduce){
    .composePart.composeFlying,
    .composePart.composeReturning{transition-duration:.01s!important;}
    .composePart.delivered img{animation:none;}
  }

  /* =====================================================================
     第14章「すなばあ」／正式版 Q1〜Q6
     ---------------------------------------------------------------------
     ・数量は絵に焼き込まない。単位の絵（sand_unit）をコードで並べる。
       10は group:5 で 5＋5 に見えるようにしてある。
     ・器の大きさ（縦横比）は素材が来るまで仮の値。実機で見て、
       下の変数と aspect-ratio だけを触れば直せるようにしてある。
     ・ここへ章名で分岐する処理を書かないこと（見た目だけを受け持つ）。
     ===================================================================== */
  :root{
    --stage-bg-8:url('assets/ch14_background_approved.webp');
    /* 【試作】第一問の中立な仮背景。画像を使わず、既存の水幻郷の夜色から作る。
       上の --stage-bg-8 は消していないので、参照先を戻せば元の絵に戻る。 */
    --stage-bg-proto:linear-gradient(180deg,
      var(--t-world-base,#0A1560) 0%,
      var(--t-world-deep,#02072B) 100%);
    /* 盤面の置き場所。おばけと吹き出しに重ならない範囲 */
    --ch14-left:34%;   --ch14-right:3%;
    --ch14-top:20%;    --ch14-bottom:3%;
    /* 器の大きさ */
    --ch14-troughW:min(30vw,300px);   /* 横長の浅い器（10のまとまり） */
    --ch14-bowlW:min(16vw,164px);     /* 浅い丸皿（ばら） */
    /* 器の縦横比。素材の実寸（v1.1）に合わせてある。
       絵を差し替えたときだけ、ここを実寸へ直す。 */
    --ch14-troughRatio:958 / 313;
    --ch14-bowlRatio:860 / 455;
    /* 器の「中身が置ける範囲」。器は斜め上から見た絵なので、
       枠いっぱいに砂を置くと縁からはみ出して見える。
       下の4つは絵から見たおよその値。実機で見てここだけ触る。 */
    --ch14-troughIn-t:4%;  --ch14-troughIn-r:11%;
    --ch14-troughIn-b:51%; --ch14-troughIn-l:11%;
    --ch14-bowlIn-t:3%;    --ch14-bowlIn-r:12%;
    --ch14-bowlIn-b:44%;   --ch14-bowlIn-l:12%;
    /* 砂道の置き場所（正解後だけ出る）。実機で背景に合わせて詰める */
    --ch14-road-left:8%;  --ch14-road-top:58%;  --ch14-road-w:82%;
    /* 道の絵は昼の砂色なので、夜の背景へ寄せる */
    --ch14-road-filter:saturate(.86) brightness(.80) hue-rotate(-6deg);
    /* 砂1個の表示幅。20pxではスマホで数えにくかったため、
       5＋5が器に収まる上限寄りの24pxへ上げる。 */
    --ch14-unitW:24px;
    /* 数字札 */
    --ch14-numSize:clamp(56px,13vw,76px);   /* 56px を下回らせない */
  }

  /* ---- 数字→量：砂の器。composeSlot / composePart の種類ちがい ---- */
  .composeSlot.kind-tenTrough,
  .composePart.kind-tenTrough{width:var(--ch14-troughW);}
  .composeSlot.kind-looseBowl,
  .composePart.kind-looseBowl{width:var(--ch14-bowlW);}
  .composeSlot.kind-tenTrough,
  .composePart.kind-tenTrough{aspect-ratio:var(--ch14-troughRatio);}
  .composeSlot.kind-looseBowl,
  .composePart.kind-looseBowl{aspect-ratio:var(--ch14-bowlRatio);}
  .composeSlot.kind-tenTrough .slotBase,
  .composeSlot.kind-looseBowl .slotBase{display:block;}

  /* 選ぶ側にも器を表示する。器が無いと砂だけが宙に浮き、
     10のまとまりとばらの区別が見た目から消えてしまう。 */
  .composePart.hasUnits{display:block;position:relative;}
  .composePart.hasUnits .unitBase{position:absolute;inset:0;z-index:0;
    width:100%;height:100%;object-fit:contain;display:block;}
  .composeSlot .composePart.placed .unitBase{display:none;}

  /* ---- 単位の絵を並べて量を見せる（10は 5＋5）----
     数えるための並びなので、1つぶんの入れ物（--unit-cell）を先に決め、
     絵はその中に収める。個数が変わっても1つの大きさは変わらない。
     こうしないと「4個のときだけ大きい」ことになり、数の比べ方が崩れる。 */
  .unitStack{display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:clamp(3px,.8vh,7px);width:100%;overflow:visible;
    --unit-cell:var(--ch14-unitW);}
  .unitGroup{display:flex;flex:1 1 0;min-height:0;
    width:100%;align-items:center;justify-content:center;gap:1px;}
  .kind-tenTrough .unitGroup{gap:clamp(3px,1.2vw,10px);}
  /* 絵は入れ物の中に収める（はみ出さず、比率も変えない） */
  /* .composePart img の width:100% より詳細に指定しないと、
     1個ずつの砂が器いっぱいの大きな山になってしまう。 */
  .unitPip{display:block!important;position:relative;width:var(--unit-cell)!important;
    height:calc(var(--unit-cell) * .68)!important;
    min-width:var(--unit-cell)!important;max-width:var(--unit-cell)!important;
    flex:0 0 var(--unit-cell)!important;background-position:center;
    background-size:contain;background-repeat:no-repeat;
    filter:drop-shadow(0 2px 3px rgba(30,16,4,.42));}
  /* sand_unit.webp は「砂1個」ではなく大きな砂山の絵だったため、
     小さく縮めると尖った三角にしか見えなかった。数える単位だけは
     コードで小さな砂だまりとして描き、明暗の粒を重ねてざらつきを出す。 */
  .unitPip.sandPip{
    border-radius:52% 48% 40% 44% / 72% 68% 34% 32%;
    clip-path:polygon(3% 86%,10% 68%,24% 57%,34% 34%,48% 13%,61% 31%,
      74% 46%,90% 70%,98% 87%,90% 100%,9% 100%);
    background-image:
      radial-gradient(circle at 23% 72%,rgba(255,245,199,.98) 0 1.2px,transparent 1.5px),
      radial-gradient(circle at 67% 67%,rgba(116,74,28,.72) 0 1.1px,transparent 1.5px),
      radial-gradient(circle at 48% 36%,rgba(255,231,161,.98) 0 1.3px,transparent 1.7px),
      radial-gradient(circle at 79% 82%,rgba(137,87,31,.70) 0 1px,transparent 1.4px),
      linear-gradient(145deg,#fff0b8 4%,#e2b867 42%,#b77732 76%,#805020 100%)!important;
    background-size:100% 100%;
    box-shadow:inset 1px 2px 2px rgba(255,247,202,.76),
               inset -2px -2px 3px rgba(105,60,20,.58);
    filter:drop-shadow(0 2px 1px rgba(35,17,3,.88))
           drop-shadow(0 0 3px rgba(255,218,118,.52));}
  /* 器の中に置くときは、縁からはみ出さない範囲へ収める */
  .composeSlot.kind-tenTrough .unitStack,
  .sandVessel.kind-tenTrough .unitStack{
    position:absolute;
    top:var(--ch14-troughIn-t);   right:var(--ch14-troughIn-r);
    bottom:var(--ch14-troughIn-b);left:var(--ch14-troughIn-l);
    width:auto;--unit-cell:var(--ch14-unitW);}
  .composeSlot.kind-looseBowl .unitStack,
  .sandVessel.kind-looseBowl .unitStack{
    position:absolute;
    top:var(--ch14-bowlIn-t);   right:var(--ch14-bowlIn-r);
    bottom:var(--ch14-bowlIn-b);left:var(--ch14-bowlIn-l);
    width:auto;--unit-cell:var(--ch14-unitW);}
  /* 器の外（選ぶ札）でも、同じ内側領域へ単位画像を置く */
  .composePart.kind-tenTrough.hasUnits .unitStack{
    position:absolute;z-index:1;
    top:var(--ch14-troughIn-t);right:var(--ch14-troughIn-r);
    bottom:var(--ch14-troughIn-b);left:var(--ch14-troughIn-l);
    width:auto;--unit-cell:var(--ch14-unitW);}
  .composePart.kind-looseBowl.hasUnits .unitStack{
    position:absolute;z-index:1;
    top:var(--ch14-bowlIn-t);right:var(--ch14-bowlIn-r);
    bottom:var(--ch14-bowlIn-b);left:var(--ch14-bowlIn-l);
    width:auto;--unit-cell:var(--ch14-unitW);}

  /* すなばあの章では数を器の下へ文字で重ねない。
     目標の数字と、実際に並んだ砂の量を対応させるため。 */
  body[data-character="sunabaa"].composePlay .composePart .partNo,
  body[data-character="sunabaa"].composePlay .composeSum{display:none;}
  body[data-character="sunabaa"].composePlay .composeBoard{
    left:var(--ch14-left);right:var(--ch14-right);
    top:var(--ch14-top);bottom:var(--ch14-bottom);}

  /* ---- 量→数字：Q2・Q4・Q6の共通盤面 ---- */
  .sandBoard{justify-content:space-between;}
  .sandQty{position:relative;z-index:1;
    display:flex;align-items:center;justify-content:center;
    gap:clamp(6px,1.8vw,20px);width:100%;flex-wrap:nowrap;}
  .sandVessel{position:relative;display:flex;align-items:center;justify-content:center;}
  .sandVessel.kind-tenTrough{width:var(--ch14-troughW);aspect-ratio:var(--ch14-troughRatio);}
  .sandVessel.kind-looseBowl{width:var(--ch14-bowlW);aspect-ratio:var(--ch14-bowlRatio);}
  .sandVessel .slotBase{position:absolute;inset:0;width:100%;height:100%;
    object-fit:contain;opacity:.9;}
  .sandVessel .unitStack{position:relative;z-index:1;}

  /* 空の2桁の戸札。答えの数は書かない */
  .sandPlate{position:relative;z-index:1;
    display:flex;align-items:center;justify-content:center;gap:clamp(8px,2.2vw,20px);}
  .sandDigit{width:var(--ch14-numSize);height:calc(var(--ch14-numSize) * 1.22);
    border:3px dashed rgba(214,196,158,.72);border-radius:14px;
    background:rgba(58,44,72,.52);color:#FFF4DD;
    font-family:inherit;font-weight:900;font-size:calc(var(--ch14-numSize) * .62);
    line-height:1;display:flex;align-items:center;justify-content:center;
    text-shadow:0 2px 5px rgba(0,0,0,.65);cursor:pointer;
    transition:border-color .2s ease,background .2s ease;}
  .sandDigit.filled{border-style:solid;border-color:rgba(226,210,255,.9);
    background:rgba(96,80,128,.62);}
  .sandDigit.want{animation:composeGlow 1.5s ease-in-out infinite;}

  /* 砂のふた。払うと下の戸札が出てくる */
  .sandCover{position:absolute;left:0;right:0;z-index:4;
    /* 量と戸札の両方を覆う。上下は盤面に合わせて実機で詰める */
    top:0;bottom:42%;border-radius:26px;overflow:hidden;
    touch-action:none;cursor:grab;
    box-shadow:inset 0 3px 0 rgba(255,240,194,.48),
               inset 0 -8px 16px rgba(101,64,26,.22),
               0 5px 14px rgba(25,11,4,.30);
    transition:opacity .55s ease;}
  .sandMask{display:block;width:100%;height:100%;}
  .sandBoard.swept .sandCover{opacity:0;pointer-events:none;}
  .sandBoard.sweeping .sandNumPad{opacity:.35;pointer-events:none;}
  .sandBoard.sweeping .sandDigit{pointer-events:none;}
  .sandBoard.hint1 .sandCover{animation:composeGlow 1.6s ease-in-out infinite;}

  /* 0〜9の数字札。スマホは5列×2段、1枚 56px 以上 */
  .sandNumPad{display:grid;grid-template-columns:repeat(5,var(--ch14-numSize));
    gap:clamp(5px,1.4vw,12px);justify-content:center;
    transition:opacity .4s ease;}
  .sandNum{width:var(--ch14-numSize);height:var(--ch14-numSize);
    border:2px solid rgba(226,210,255,.55);border-radius:14px;
    background:linear-gradient(180deg,rgba(238,228,206,.96),rgba(206,192,166,.96));
    color:#3B2E4E;font-family:inherit;font-weight:900;
    font-size:calc(var(--ch14-numSize) * .52);line-height:1;
    display:flex;align-items:center;justify-content:center;
    touch-action:none;cursor:pointer;
    box-shadow:0 4px 8px rgba(24,12,40,.4);
    transition:transform .16s ease,opacity .2s ease;}
  .sandNum.dragging{transform:translate(var(--dragX,0),var(--dragY,0)) scale(1.08);
    z-index:30;transition:none;}
  .sandNum.reject{animation:composeReject .34s ease;}
  .sandNum.hintOn{animation:composeGlow 1.2s ease-in-out infinite;}
  .sandNum.hintDemo{animation:composeDemo 1.4s ease-in-out;}

  /* タブレット横：盤面が広いので器と数字札を少し大きく */
  @media (min-width:820px) and (orientation:landscape){
    :root{
      --ch14-troughW:min(24vw,320px);
      --ch14-bowlW:min(13vw,168px);
      --ch14-numSize:clamp(60px,7vw,84px);
    }
  }

  /* スマホ縦。器の高さを72px前後確保し、Q5の10の器2つは
     無理に横へ縮めず上下へ折り返す。 */
  @media (orientation:portrait){
    :root{
      --ch14-left:3%;--ch14-right:3%;--ch14-top:auto;--ch14-bottom:3%;
      /* 24pxの砂を5個並べても、器の縁へ重ならない内幅を確保する。 */
      --ch14-troughW:min(61vw,244px);
      --ch14-bowlW:min(42vw,164px);
      --ch14-numSize:clamp(56px,14.3vw,68px);
      --ch14-road-left:5%;--ch14-road-top:57%;--ch14-road-w:90%;
    }
    body[data-character="sunabaa"].composePlay .composeBoard{
      /* Safariの下部バーに丸い器が隠れないよう、操作域を約1列ぶん上へ。
         問題文は #playArea 側なので、器だけが「10こに あつめよう」へ近づく。 */
      top:auto;height:48%;
      bottom:max(env(safe-area-inset-bottom,0px),clamp(48px,8vh,68px));
      justify-content:flex-start;gap:clamp(4px,.7vh,7px);}
    body[data-character="sunabaa"].composePlay .composeSlots,
    body[data-character="sunabaa"].composePlay .composeTray{
      /* 器どうしの縦間隔を詰め、大きくした砂と器を下へ押し出さない。 */
      flex-wrap:wrap;gap:clamp(4px,.7vh,7px);}
    body[data-character="sunabaa"].composePlay .sandBoard{
      justify-content:space-between;}
    body[data-character="sunabaa"].composePlay .sandQty{min-height:82px;}
    /* 砂を払う面が0〜9の数字キーへ被らないよう、下端を一段上げる。 */
    body[data-character="sunabaa"].composePlay .sandCover{bottom:42%;}
    /* すなばあの絵は足元まで描かれていて、第13章用の透明余白補正では
       「14」の札に重なる。絵だけを少し上げ、問題文の基準位置は保つ。 */
    body[data-character="sunabaa"].composePlay #ghostWrap{
      margin-top:-12px;margin-bottom:12px;}
  }

  /* iPad横では第13章の三領域テンプレートを使い、中央の操作域だけ
     すなばあ用の器寸法へ差し替える。 */
  @media (orientation:landscape) and (min-height:600px){
    body[data-character="sunabaa"].composePlay .composeBoard{
      left:27%;right:3%;top:38%;bottom:4%;}
    body[data-character="sunabaa"].composePlay .sandBoard{
      display:grid;grid-template-columns:minmax(0,1fr) auto;
      grid-template-rows:auto auto 1fr;column-gap:clamp(16px,2.5vw,30px);
      align-items:center;justify-items:center;}
    body[data-character="sunabaa"].composePlay .sandBoard .composeGoal,
    body[data-character="sunabaa"].composePlay .sandBoard .composeSub{
      grid-column:1 / -1;}
    body[data-character="sunabaa"].composePlay .sandBoard .sandQty{grid-column:1;grid-row:3;}
    body[data-character="sunabaa"].composePlay .sandBoard .sandPlate{grid-column:2;grid-row:3;}
    body[data-character="sunabaa"].composePlay .sandBoard .sandNumPad{grid-column:1 / -1;grid-row:4;}
    body[data-character="sunabaa"].composePlay .sandBoard .sandCover{bottom:30%;}
  }

  /* ---- 正解したあとに戻る砂の道（第14章）---- */
  .roadLayer{position:absolute;z-index:2;pointer-events:none;
    left:var(--ch14-road-left);top:var(--ch14-road-top);
    width:var(--ch14-road-w);bottom:0;}
  .roadImg{position:absolute;
    left:0;top:0;width:var(--roadW,100%);
    height:auto;opacity:0;
    filter:var(--ch14-road-filter);
    transition:opacity .7s ease;}
  .roadImg.on{opacity:1;}
  .roadImg.fading{opacity:0;}
  /* 正解後も画面全体の大きさは変えず、道の画像だけを切り替える。 */
  @media (prefers-reduced-motion:reduce){
    .roadImg{transition-duration:.25s;}
  }

  /* =====================================================================
     第15章「あぶらーん」／スマホ縦 v1.0.4
     ---------------------------------------------------------------------
     ・数字は画像へ焼き込まず、油灯りの和紙面へコードで重ねる。
     ・ドラッグ／吸着は第13・14章の composeAttachDrag を再利用する。
     ・灯りを戻した直後に、同じ画面で水流と水車が一段進む。
     ・iPad横の専用配置は、実機確認時にこのブロックと分けて追加する。
     ===================================================================== */
  :root{
    --stage-bg-9:url('assets/ch15_background_phone.webp');
    --ch15-fixed-lantern:clamp(54px,15.5vw,64px);
    --ch15-fixed-lantern-h:clamp(72px,20.8vw,86px);
    --ch15-fixed-number:clamp(25px,7.1vw,30px);
    --ch15-slot-w:clamp(63px,18vw,74px);
    --ch15-slot-h:clamp(80px,23vw,95px);
    --ch15-choice-lantern:clamp(68px,19vw,78px);
    --ch15-choice-lantern-h:clamp(91px,25.5vw,105px);
    --ch15-choice-number:clamp(31px,8.7vw,36px);
  }

  /* 背景正本は車輪・落水なし。承認画像と同じ中央クロップを使う。 */
  body[data-character="aburaan"] #stageBg{
    background-position:center center!important;
    background-size:cover!important;
  }

  /* ---- 世界の復旧レイヤー：木樋の水流・水車・局所光 ---- */
  .sequenceRescueLayer{position:absolute;inset:0;z-index:3;pointer-events:none;overflow:hidden;
    --water-lead-left:100%;--water-lead-opacity:0;--water-full-opacity:0;
    --houseOpacity:0;--wheel-angle:0deg;--wheel-bright:.66;}
  body:not([data-character="aburaan"]) .sequenceRescueLayer{display:none;}
  /* 背景と同じ1024×1536座標の透過素材をcoverで重ねる。
     Q1〜Q5は木樋部分だけを右から左へ見せ、車輪沿いの水はQ6で初めて出す。 */
  .sequenceWater{position:absolute;inset:0;width:100%;height:100%;display:block;
    object-fit:cover;object-position:center center;pointer-events:none;
    filter:drop-shadow(0 0 5px rgba(137,224,255,.42));}
  .sequenceWaterLead{z-index:3;opacity:var(--water-lead-opacity);
    clip-path:polygon(var(--water-lead-left) 23%,100% 23%,100% 32%,var(--water-lead-left) 32%);
    transition:clip-path .68s ease,opacity .42s ease;}
  .sequenceWaterFull{z-index:4;opacity:var(--water-full-opacity);
    transition:opacity .55s ease;}
  .sequenceHouseGlow{position:absolute;right:2%;top:21%;width:42vw;max-width:180px;aspect-ratio:1;
    border-radius:50%;opacity:var(--houseOpacity);
    background:radial-gradient(circle,rgba(255,218,128,.35) 0%,rgba(255,196,76,.13) 46%,transparent 72%);
    filter:blur(4px);transition:opacity .5s ease;}
  /* 正式な車輪単体画像。背景側の軸受けへ中心を合わせ、画像の50% 50%を回転軸にする。 */
  .sequenceWheel{position:absolute;z-index:2;left:51%;right:auto;top:20.1%;width:min(48.2vw,208px);height:auto;
    display:block;border:0;background:none;
    transform:rotate(var(--wheel-angle));transform-origin:50% 50%;
    filter:brightness(var(--wheel-bright)) saturate(.92) drop-shadow(0 6px 8px rgba(0,0,0,.48));}
  .sequenceWheel.turning{animation:sequenceWheelTurn .72s cubic-bezier(.22,.78,.25,1) both;}
  .sequenceRescueLayer.sequencePulse .sequenceWater{filter:brightness(1.18) drop-shadow(0 0 7px rgba(137,224,255,.56));}
  .sequenceRescueLayer[data-step="6"] .sequenceWheel:not(.turning){animation:sequenceWheelLoop 5.2s linear infinite;}
  .sequenceRescueLayer[data-step="6"] .sequenceHouseGlow{opacity:.82;}
  @keyframes sequenceWheelTurn{
    from{transform:rotate(calc(var(--wheel-angle) - 45deg));}
    to{transform:rotate(var(--wheel-angle));}
  }
  @keyframes sequenceWheelLoop{
    from{transform:rotate(var(--wheel-angle));}
    to{transform:rotate(calc(var(--wheel-angle) + 360deg));}
  }

  /* ---- 数列盤面 ---- */
  body.sequencePlay .sequenceBoard{
    left:2%;right:2%;top:41.5%;bottom:max(env(safe-area-inset-bottom,0px),14px);
    z-index:18;display:flex;flex-direction:column;justify-content:flex-start;
    align-items:center;gap:clamp(6px,1.2vh,11px);pointer-events:none;}
  body.sequencePlay .sequenceBoard .composeGoal,
  body.sequencePlay .sequenceBoard .composeSub{display:none;}
  .sequenceAction{display:flex;align-items:center;justify-content:center;
    min-height:42px;width:min(68vw,270px);padding:5px 18px;
    border:2px solid rgba(222,197,112,.92);border-radius:999px;
    background:rgba(34,27,53,.82);box-shadow:0 5px 14px rgba(5,8,25,.34);
    color:#FFF0B8;text-align:center;font-weight:900;
    font-size:clamp(17px,4.7vw,21px);line-height:1.25;pointer-events:none;}
  .sequenceRow{width:100%;min-height:116px;display:flex;align-items:flex-end;justify-content:center;
    gap:clamp(3px,1.3vw,7px);pointer-events:auto;
    padding:5px 3px 12px;border-radius:28px;
    background:linear-gradient(180deg,rgba(8,31,55,0),rgba(8,31,55,.34));}
  .sequenceTray{width:min(94vw,390px);min-height:126px;display:flex;align-items:flex-end;justify-content:center;
    gap:clamp(24px,6vw,30px);padding:18px 12px max(12px,env(safe-area-inset-bottom,0px));
    margin-top:auto;
    border-radius:28px 28px 18px 18px;pointer-events:auto;
    background:
      repeating-linear-gradient(0deg,rgba(91,64,36,.07) 0 1px,transparent 1px 7px),
      linear-gradient(180deg,rgba(224,205,170,.94),rgba(176,143,100,.95));
    border:2px solid rgba(239,220,181,.72);
    box-shadow:inset 0 2px 0 rgba(255,245,216,.62),0 8px 18px rgba(10,13,30,.45);}
  .sequenceBoard.sequenceComplete{pointer-events:none;}
  .sequenceTray.sequenceCompleteTray{align-items:center;justify-content:center;
    color:#493424;text-align:center;font-weight:900;
    font-size:clamp(19px,5.2vw,23px);line-height:1.4;}

  /* 正式な油灯り画像＋コード描画の数字＋独立した琥珀発光。 */
  .oilLantern{position:relative;display:block;flex:0 0 auto;
    width:var(--ch15-fixed-lantern);height:var(--ch15-fixed-lantern-h);
    padding:0;border:0;background:none;overflow:visible;font-family:inherit;color:#39240F;
    filter:drop-shadow(0 6px 6px rgba(6,13,24,.48));}
  .oilLanternArt{position:absolute!important;z-index:1;inset:0;width:100%!important;height:100%!important;
    display:block;object-fit:contain;filter:none!important;pointer-events:none;}
  .oilLanternGlow{position:absolute!important;z-index:0;left:50%!important;top:49%!important;
    width:174%!important;height:174%!important;max-width:none!important;
    display:block;object-fit:contain;transform:translate(-50%,-50%);filter:none!important;opacity:0;pointer-events:none;}
  .oilNumber{position:absolute;z-index:2;left:17%;right:17%;top:37%;bottom:25%;
    display:flex;align-items:center;justify-content:center;
    font-family:'Zen Maru Gothic',sans-serif;font-weight:900;
    font-size:var(--ch15-fixed-number);line-height:1;
    color:#3C270F;text-shadow:0 1px 0 rgba(255,250,220,.8);font-variant-numeric:tabular-nums;}
  .oilLantern.lit .oilLanternGlow{opacity:.64;}
  .oilLantern.sequencePlaced .oilLanternGlow{opacity:.88;}
  .sequenceFixed{opacity:.94;}
  .sequenceSlot{position:relative;flex:0 0 auto;width:var(--ch15-slot-w);
    height:var(--ch15-slot-h);border-radius:18px;
    border:3px dashed rgba(255,226,145,.78);pointer-events:none;
    background:rgba(21,56,78,.24);
    box-shadow:0 0 0 3px rgba(30,77,102,.24),inset 0 0 18px rgba(124,214,244,.18);}
  .sequenceSlotImg{position:absolute;z-index:1;left:50%;bottom:0;width:116%;height:44%;
    display:block;object-fit:contain;transform:translateX(-50%);pointer-events:none;}
  .sequenceSlot.near,.sequenceSlot.filled{border-style:solid;border-color:rgba(255,235,166,.98);
    box-shadow:0 0 18px 7px rgba(255,204,92,.48),inset 0 0 18px rgba(255,231,154,.25);}
  .sequenceSlot.filled{background:none;border-color:transparent;box-shadow:none;}
  .sequenceSlot.filled .sequenceSlotImg{display:none;}
  .sequenceSlot .sequencePlaced{position:absolute;left:50%;bottom:3%;transform:translateX(-50%);}
  .sequenceQuestion{position:absolute;left:50%;top:12%;transform:translateX(-50%);z-index:2;
    font-family:'Zen Maru Gothic',sans-serif;font-size:clamp(34px,9vw,42px);font-weight:900;
    color:#FFF1B7;text-shadow:0 2px 5px rgba(0,0,0,.75);}
  .sequenceSlot.filled .sequenceQuestion{display:none;}

  .sequenceChoice.composePart{width:var(--ch15-choice-lantern);height:var(--ch15-choice-lantern-h);
    display:block;flex:0 0 var(--ch15-choice-lantern);touch-action:none;cursor:pointer;
    transition:transform .16s ease,opacity .2s ease,filter .2s ease;}
  /* 見た目は小さな灯りのまま、左右へ10pxずつ当たり判定を広げて88pxを確保する。 */
  .sequenceChoice::before{content:"";position:absolute;inset:-8px -10px;z-index:0;}
  .sequenceChoice .oilNumber{font-size:var(--ch15-choice-number);}
  .sequenceChoice .oilLanternGlow{display:none;}
  .sequenceChoice.hintOn img,.sequenceChoice.hintDemo img{animation:none!important;}
  .sequenceChoice.dragging{transform:translate(var(--dragX,0),calc(var(--dragY,0) - 28px)) scale(1.06);
    z-index:32;transition:none;}
  .sequenceChoice.snapNear{filter:drop-shadow(0 0 13px rgba(255,225,130,.92));}
  .sequenceChoice.used{opacity:0;pointer-events:none;}
  .sequenceChoice.hintHidden{opacity:0;pointer-events:none;transform:scale(.84);}
  .sequenceBoard.hint1 .sequenceSlot,
  .sequenceBoard.hint1 .sequenceFixed:nth-child(2),
  .sequenceBoard.hint1 .sequenceFixed:nth-last-child(2){animation:sequenceGlow 1.35s ease-in-out infinite;}
  .sequenceChoice.hintOn{animation:sequenceGlow 1.2s ease-in-out infinite;}
  .sequenceChoice.hintDemo{animation:composeDemo 1.4s ease-in-out;}
  @keyframes sequenceGlow{50%{filter:brightness(1.3) drop-shadow(0 0 13px rgba(255,222,125,.9));}}

  /* ---- スマホ縦：上にあぶらーんと水車、中央に数列、下に候補 ---- */
  @media (orientation:portrait){
    body[data-character="aburaan"].sequencePlay #playArea{
      left:0;right:0;top:52px;bottom:auto;transform:none;width:100%;height:260px;
      display:block;max-width:none;}
    body[data-character="aburaan"].sequencePlay #ghostWrap{
      position:fixed!important;left:1%!important;top:112px!important;
      width:47vw!important;height:auto!important;bottom:auto!important;
      aspect-ratio:1 / 1!important;max-width:190px!important;margin:0!important;}
    body[data-character="aburaan"].sequencePlay #promptText{
      position:fixed!important;left:14%!important;top:96px!important;right:auto!important;
      width:64%!important;max-width:270px;text-align:left;}
    body[data-character="aburaan"].sequencePlay #promptText .pbubble{
      display:block;position:relative;box-sizing:border-box;width:100%;max-width:none;
      padding:0;border:0;border-radius:0;background:none;box-shadow:none;
      color:#FFFFFF;font-size:clamp(17px,4.4vw,20px);font-weight:900;
      line-height:1.42;white-space:pre-line;text-align:left;
      text-shadow:0 0 3px rgba(2,7,43,1),0 0 8px rgba(2,7,43,1),
                  0 0 18px rgba(2,7,43,.95),0 2px 4px rgba(2,7,43,1);}
    body[data-character="aburaan"].sequencePlay #promptText .pbubble::after{
      display:none;}
    body[data-character="aburaan"].sequencePlay #activeCompanion{
      transform:scale(.78);transform-origin:right top;}
  }

  /* 横向きは素材とロジックが見失われない最低限の退避だけ行う。
     iPad専用の大きさ・余白・背景位置は実機確認時に別調整する。 */
  @media (orientation:landscape){
    body.sequencePlay .sequenceBoard{left:28%;right:3%;top:34%;bottom:4%;}
    body.sequencePlay .sequenceRow{min-height:104px;}
    body.sequencePlay .sequenceTray{min-height:108px;padding-top:10px;padding-bottom:8px;}
  }
  @media (prefers-reduced-motion:reduce){
    .sequenceWheel.turning,.sequenceRescueLayer[data-step="6"] .sequenceWheel,
    .sequenceBoard.hint1 .sequenceSlot,.sequenceBoard.hint1 .sequenceFixed,
    .sequenceChoice.hintOn,.sequenceChoice.hintDemo{animation:none!important;}
    .sequenceWater{transition-duration:.25s;}
  }

/* =====================================================================
   共通プレーシェル／算数土台（プレー画面共通設計 v1.1.2 第4・12節）
   ---------------------------------------------------------------------
   一枚の明るい面に、主見出し・Math focus・Action dock をまとめる。
   ・出す条件は body.shellPlay だけ。章番号・キャラクター名では分岐しない。
   ・寸法はデザイントークン v1.0.2 と共通設計 v1.1.2 の割合から決める。
     Safe幅 … 縦は 88〜94%、横は 50〜62%（play.boardWidth*）
   ・safe area は env() から実行時に求める（play.safeAreaInsets）。
     機種名の media query と固定値は使わない。
   ・!important は使わない。既存章へ影響させないため、すべて
     body.shellPlay の下に閉じる。
   ===================================================================== */
  body.shellPlay #playArea,
  body.shellPlay #zoneSource,
  body.shellPlay #tree,
  body.shellPlay #line{display:none;}
  /* 救出対象は Story band として使うため、#playArea の外へ出さずに
     シェル側で位置だけを決める。DOMは動かさない。 */
  body.shellPlay #playArea{display:block;background:none;border:none;box-shadow:none;
    left:50%;top:var(--t-inset-top);transform:translateX(-50%);
    width:min(100vw - var(--t-inset-side) * 2, 780px);height:auto;pointer-events:none;}
  body.shellPlay #playArea > *{display:none;}
  body.shellPlay #ghostWrap{display:block;margin:0 auto;pointer-events:none;}
  /* companionState=selected は救出対象を start へ寄せ、おともと左右に分ける。
     none は中央のまま。数学面の寸法・中心はどちらでも変えない。 */
  body.shellPlay.companionSelected #ghostWrap{margin:0 auto 0 0;}

  #playShell[hidden]{display:none;}
  #playShell{position:absolute;inset:0;z-index:9;display:flex;
    align-items:center;justify-content:center;
    padding:calc(var(--t-inset-top) + var(--ghost-band, 0px)) var(--t-inset-side)
            calc(var(--t-inset-bottom) + var(--t-space-12)) var(--t-inset-side);
    pointer-events:none;}

  /* 算数土台。Math focus と Action dock を分断しない一枚面 */
  #mathSurface{pointer-events:auto;
    width:min(94%, 640px);                    /* Safe幅 88〜94% の上限側 */
    max-height:100%;
    display:flex;flex-direction:column;align-items:center;
    gap:var(--t-space-2);
    padding:var(--t-space-3);
    border-radius:var(--t-radius-l);
    background:var(--t-c-surface, #FAF5E8);
    box-shadow:0 10px 24px rgba(20,12,4,.34), inset 0 0 0 2px rgba(154,116,64,.22);
    transition:opacity .48s var(--t-ease-standard), transform .48s var(--t-ease-standard);}
  /* 章の最後の問いが終わったら、そろった盤面を見せたまま土台ごと静かに引く。
     主見出しだけを画面へ残さない。付くのは foldSurfaceOnClear の型のときだけ。 */
  #playShell.surfaceFold #mathSurface{opacity:0;transform:translateY(10px) scale(.985);}
  @media (prefers-reduced-motion: reduce){
    #mathSurface{transition:opacity .14s linear;}
    #playShell.surfaceFold #mathSurface{transform:none;}
  }

  /* 主見出し。一行・短文。補助文は置かない */
  /* 折り返すときは文節の区切り（半角スペース）だけで折る。
     「なぞろ／う」のように語の途中で切れないようにする。 */
  #mathHeading{margin:0;text-align:center;line-height:1.35;
    font-size:clamp(24px, 6.4vw, 32px);font-weight:900;color:#5A4A2A;
    min-height:calc(1.35em);word-break:keep-all;overflow-wrap:normal;}
  #mathHeading:empty{display:none;}

  #mathFocus{width:100%;display:flex;align-items:center;justify-content:center;
    flex:1 1 auto;min-height:0;}
  #actionDock{width:100%;display:flex;align-items:center;justify-content:center;
    gap:var(--t-gap-control);flex:0 0 auto;}
  #actionDock[hidden]{display:none;}

  /* iPad横：Story band を側面へ回し、算数土台は中央のまま保つ */
  @media (orientation:landscape) and (min-width:768px){
    body.shellPlay #playArea{left:var(--t-inset-side);top:50%;transform:translateY(-50%);
      width:min(26vw,300px);}
    #playShell{padding-top:var(--t-inset-top);}
    #mathSurface{width:min(56%, 720px);}   /* Safe幅 50〜62% */
  }
  /* 短い横画面（スマホを横にした場合）。
     高さが足りないので、桶を高さ基準にして土台からはみ出させない。
     3灯の下から始めて主見出しを隠さない。機種名では分岐しない。 */
  @media (orientation:landscape) and (max-height:560px){
    #playShell{padding-top:clamp(64px, 17vh, 96px);
      padding-bottom:calc(var(--t-inset-bottom) + var(--t-space-4));}
    #mathSurface{width:min(76%, 640px);padding:var(--t-space-2);gap:var(--t-space-1);}
    #mathHeading{font-size:clamp(20px, 5.2vh, 26px);}
  }

/* =====================================================================
   第11章 EX-11 / EMPTY-TAP の桶と共通単位
   ---------------------------------------------------------------------
   ・桶は水幻郷の共通carrier一素材（assets/carrier_shallow_bamboo_tub_w2.webp）。
     サイズ別・章別・キャラクター別の画像は作らない。
   ・器の全体が一つのタッチ対象。子どもの主要操作なので 56px 以上を確保する。
   ・数える単位は章のアイテム（第11章はブルーベリー）。内側だけに置き、縁・外側へ出さない。
   ・キャラクター名のセレクタは使わない。
   ===================================================================== */
  /* 桶どうしの間隔はデザイントークンの play.candidateGap（12px以上）を守る */
  .tubBoard{display:grid;width:100%;justify-items:center;align-items:center;
    gap:var(--t-gap-control);}
  .tubBoard.cols3{grid-template-columns:repeat(3, minmax(0,1fr));}
  .tubBoard.cols4{grid-template-columns:repeat(2, minmax(0,1fr));}

  .tubSlot{position:relative;border:0;background:none;padding:0;
    font-family:inherit;-webkit-tap-highlight-color:transparent;
    container-type:inline-size;            /* 0 と単位の大きさを桶の幅から決める */
    width:100%;max-width:190px;aspect-ratio:3 / 2;
    min-width:var(--t-tap-primary);min-height:var(--t-tap-primary);
    border-radius:var(--t-radius-l);
    transition:transform .16s var(--t-ease-standard), filter .16s;}
  .tubSlot .tubArt{position:absolute;inset:0;
    background:url('assets/carrier_shallow_bamboo_tub_w2.webp') center/100% 100% no-repeat;}
  /* 内容安全楕円の内側だけに単位を置く。素材の内寸に合わせた領域 */
  .tubSlot .tubInside{position:absolute;left:12%;right:12%;top:22%;bottom:20%;
    display:flex;flex-wrap:wrap;align-content:center;justify-content:center;
    gap:4px;pointer-events:none;}
  .tubSlot .tubUnit{width:28cqw;max-width:40px;min-width:17px;aspect-ratio:1;
    display:block;line-height:0;}
  .tubSlot .tubUnit svg{width:100%;height:100%;display:block;}
  .tubSlot:active{transform:scale(.96);}

  /* 3択（1×3）は1行に3個入るぶん1マスが小さくなる。
     素材は幅の約30%が薄いにじみで、実体（不透明部分）は幅70.6%・高さ90.8%しかない。
     マスの大きさ・間隔・タッチ範囲はそのままに、絵と中身だけを拡大して
     実体が読みやすい大きさになるようにする。
     ・押せる範囲（.tubSlot）は変えないので、桶どうしの間隔も詰まらない
     ・はみ出すのは、ほぼ透明なにじみの部分だけ
     ・4択（2×2）は対象外。章名・キャラクター名では分岐しない
     ・横向きは1マスがもともと大きく、拡大すると絵が土台の外へ出るため縦向きだけ
     ・縦向きでも、画面の広さで1マスの大きさが変わるため倍率を2段に分ける */
  @media (orientation:portrait) and (max-width:767px){
    .tubBoard.cols3 .tubArt,
    .tubBoard.cols3 .tubInside{transform:scale(1.21);}
  }
  /* 画面が広い縦向き（タブレット縦）は1マスがもともと大きい。
     同じ倍率だと絵が土台の外へ出るので、収まる範囲までにとどめる。 */
  @media (orientation:portrait) and (min-width:768px){
    .tubBoard.cols3 .tubArt,
    .tubBoard.cols3 .tubInside{transform:scale(1.10);}
  }

  /* 正解。空の内側へ0を出す */
  .tubSlot .tubZero{font-size:clamp(28px, 9cqw, 44px);font-weight:900;color:#5A4A2A;
    line-height:1;opacity:0;transform:scale(.7);
    transition:opacity .26s var(--t-ease-standard), transform .26s var(--t-ease-pop-once);}
  .tubSlot .tubZero.reveal{opacity:1;transform:scale(1);}
  .tubSlot.correct{filter:drop-shadow(0 0 14px rgba(255,214,110,.9));}

  /* 誤答。選んだ桶の外周だけを一度弱く戻す。赤×や罰は使わない */
  @keyframes tubNudge{
    0%{transform:translateY(0)} 34%{transform:translateY(3px)} 100%{transform:translateY(0)}
  }
  .tubSlot.nudge{animation:tubNudge .3s var(--t-ease-standard);}

  /* ヒント。H1 外周／H2 中身を一個ずつ／H3 正解桶の外周 */
  @keyframes tubRim{
    0%,100%{box-shadow:0 0 0 0 rgba(121,183,198,0)}
    50%{box-shadow:0 0 0 6px rgba(121,183,198,.55)}
  }
  .tubSlot.hintRim{border-radius:50%/40%;animation:tubRim 1.1s var(--t-ease-standard);}
  .tubUnit.hintCount{filter:drop-shadow(0 0 8px rgba(255,238,170,.95));transform:scale(1.12);
    transition:transform .18s var(--t-ease-standard);}
  @keyframes tubLift{
    0%,100%{transform:translateY(0)} 45%{transform:translateY(-8px)}
  }
  .tubSlot.hintLift{animation:tubLift .9s var(--t-ease-pop-once);}

  @media (min-width:768px){
    .tubSlot{max-width:220px;}
    .tubSlot .tubUnit{max-width:40px;}
    .tubBoard{gap:var(--t-gap-group);}
  }

  /* 短い横画面での桶の大きさ。
     幅ではなく高さから決めて、縦横比3:2のまま土台へ収める。
     .tubSlot の基本形より後に置く必要があるためここに書く。 */
  @media (orientation:landscape) and (max-height:560px){
    .tubSlot{width:auto;max-width:none;height:min(24vh, 100px);}
    .tubBoard{gap:var(--t-space-1);}
  }

/* =====================================================================
   第12〜15章の共通シェル用の盤面
   ---------------------------------------------------------------------
   ・第13〜15章は「候補札3枚 → activeな置き先ひとつ」の同じ手の文法。
     札の外形は3枚とも同じで、内側の数量か数字だけが違う。
   ・置き先は同時にひとつだけ .isActive にする。
   ・章名・キャラクター名のセレクタと !important は使わない。
   ===================================================================== */
  /* ---- 候補札（Action dock）---- */
  #actionDock.cardRow{gap:var(--t-gap-control);flex-wrap:nowrap;}
  .choiceCard{position:relative;border:0;padding:0;font-family:inherit;
    -webkit-tap-highlight-color:transparent;
    flex:0 0 auto;
    min-width:var(--t-drag-visual);min-height:var(--t-drag-visual);
    width:clamp(64px, 21vw, 96px);aspect-ratio:1;
    border-radius:var(--t-radius-m);
    background:var(--t-c-surface-2, #F2E6CC);
    /* ふちを半透明から実線へ、下の面も実色へ。つまんで運ぶ札なので
       transform には触れず、輪郭のはっきりさだけを上げている */
    box-shadow:inset 0 0 0 2px var(--t-wood-600,#9A7440), 0 4px 0 var(--t-wood-800,#7A5A31);
    display:flex;align-items:center;justify-content:center;
    transform:translate(var(--dragX,0px), var(--dragY,0px));
    transition:box-shadow .16s var(--t-ease-standard);}
  .choiceCard.zeroDragging{z-index:40;transition:none;}
  .choiceCard.zeroReturning{transition:transform .21s var(--t-ease-standard);}
  .choiceCard.zeroAccepted{transition:transform .24s var(--t-ease-standard);}
  .choiceCard.used{opacity:0;pointer-events:none;}
  .choiceCard .cardNum{font-size:clamp(28px, 8vw, 44px);font-weight:900;color:#5A4A2A;line-height:1;}
  .choiceCard .cardDots{display:flex;flex-wrap:wrap;align-content:center;justify-content:center;
    gap:3px;width:78%;}
  .choiceCard.hintGlow,.dropSlot.hintGlow,
  .clothPart.hintGlow,.tenFrame.hintGlow,.onesRow.hintGlow{
    box-shadow:0 0 0 4px rgba(121,183,198,.6), inset 0 0 0 2px rgba(154,116,64,.45);}
  @keyframes cardDemo{0%,100%{transform:translateY(0)} 45%{transform:translateY(-14px)}}
  .choiceCard.hintDemo{animation:cardDemo 1.1s var(--t-ease-pop-once);}

  /* ---- 単位の粒。数量を見て数えられる形にする ---- */
  .uDot,.pDot,.oDot{display:block;border-radius:50%;
    width:clamp(9px, 2.6vw, 14px);aspect-ratio:1;
    background:radial-gradient(circle at 38% 32%, #FFF3C9 0%, #F2B84B 55%, #9A5B10 100%);}
  .pDot{background:radial-gradient(circle at 38% 32%, #FFFFFF 0%, #C9A971 55%, #7A5A31 100%);}
  .oDot{background:radial-gradient(circle at 38% 32%, #FFF3C9 0%, #E0C48A 55%, #9A7440 100%);}

  /* ---- 置き先。activeなものだけが受け取る ---- */
  .dropSlot{border-radius:var(--t-radius-m);
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.35);
    background:rgba(201,169,113,.14);}
  .dropSlot.isActive{box-shadow:inset 0 0 0 3px rgba(242,184,75,.9);
    background:rgba(255,241,197,.55);}
  .dropSlot.dropReady{box-shadow:inset 0 0 0 4px rgba(121,183,198,.95);}
  .dropSlot.filled{background:rgba(201,169,113,.2);box-shadow:inset 0 0 0 2px rgba(154,116,64,.4);}

  /* ---- 第13章：布の全体と部分（PS-E / E-PART） ----
     いっためんは布・帯・パッチが数学表現そのもの。丸ドットへ置き換えない。
     使う素材は既存の正式素材だけ：
       wind_band_empty.webp  … 全体の布（金の札つき）
       wind_patch_empty.webp … 候補の布パッチ（金の札つき）
       wind_light.webp       … かぜのひかり＝数える単位
     大きさは --clothLight ひとつで決め、章名・キャラ名での分岐は持たない。 */
  /* 巻物は主見出し・候補札と同じ左右位置にそろえる。
     ここだけ外へ張り出すと、算数土台の外枠へ重なって見える。 */
  .clothBoard{--clothLight:clamp(20px, 6.4vw, 34px);
    display:flex;flex-direction:column;align-items:center;width:100%;}

  /* かぜのひかり。布の上にのる数える単位 */
  .windLight{display:block;flex:0 0 auto;width:var(--clothLight);aspect-ratio:1;
    background:url('assets/wind_light.webp') center/contain no-repeat;}

  /* 全体の布。金の札に「ぜんぶで いくつ」を出す */
  /* 素材 wind_band_empty.webp（1100×239）は左右の端に巻き軸がある。
     右の軸は幅の約6%を占めるので、内側余白をそれより広く取り、
     空欄や札が軸へ乗って「紙が切れている」ように見えないようにする。 */
  .clothWhole{position:relative;width:100%;min-height:calc(var(--clothLight) * 2.6);
    display:flex;align-items:center;
    padding:calc(var(--clothLight) * .34) 7.5% calc(var(--clothLight) * .34) 21%;
    background:url('assets/wind_band_empty.webp') center/100% 100% no-repeat;
    transition:filter .3s var(--t-ease-standard);}
  /* 数字は布の金の札の上へ置く。単独で離して置かない */
  .clothWhole .clothTag{position:absolute;left:11.5%;top:50%;transform:translate(-50%,-50%);
    font-size:clamp(22px, 6vw, 34px);font-weight:900;color:#5A4A2A;line-height:1;}
  .clothRow{display:flex;align-items:stretch;justify-content:center;gap:0;width:100%;}
  /* 左右の部分は必ず同じ幅にする。幅が答えを漏らさないため */
  .clothPart{flex:1 1 0;min-width:0;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:3px;
    padding:calc(var(--clothLight) * .18) 4px;}
  /* 数の見え方の辞書の1段ぶん。同じ数はどこでも同じ段組みになる */
  .lightRow{display:flex;align-items:center;justify-content:center;gap:3px;}
  /* 布の継ぎ目。ここから先がまだつながっていない */
  .clothSeam{flex:0 0 4px;align-self:stretch;border-radius:2px;
    background:repeating-linear-gradient(to bottom,
      rgba(122,90,49,.70) 0 5px, transparent 5px 10px);
    transition:opacity .3s var(--t-ease-standard);}
  .clothPart.isSlot{border-radius:var(--t-radius-m);}
  .clothWhole.joined .clothSeam{opacity:0;}

  /* 候補の布パッチ。3枚とも同じ外形・同じ大きさ。違うのは中のひかりの数だけ */
  /* 金の札は絵の左端にあるので、ひかりはその右側の布面にだけのせる。
     割合は札そのものを基準にしたいので、padding ではなく絶対配置で決める
     （padding の % は親＝Action dock の幅を基準にしてしまうため） */
  /* 3枚が Action dock の幅を分け合うようにする。固定幅のままだと3枚＋すきまが
     算数土台より広くなり、左右の札が土台の外枠へまたいで見えていた。
     上限はこれまでの幅と同じなので、広い画面での見え方は変わらない。 */
  .choiceCard.kind-cloth{position:relative;
    flex:1 1 0;min-width:0;width:auto;max-width:clamp(88px, 27vw, 150px);
    height:auto;aspect-ratio:1 / 0.88;padding:0;
    background:url('assets/wind_patch_empty.webp') center/100% 100% no-repeat;
    box-shadow:none;}
  .choiceCard.kind-cloth .cardCloth{position:absolute;
    left:26%;right:7%;top:9%;bottom:9%;width:auto;height:auto;
    --clothLight:clamp(12px, 3.8vw, 22px);
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;}
  /* 候補札の金の札に、入っているひかりの数を出す */
  .choiceCard.kind-cloth .clothNum{position:absolute;left:15.5%;top:47%;
    transform:translate(-50%,-50%);
    font-size:clamp(17px, 4.6vw, 26px);font-weight:900;color:#5A4A2A;line-height:1;}

  /* ---- 第14章：十枠と一の列 ---- */
  /* 十枠と受け皿の幅。見えている高さ（svh）でも頭打ちにして、
     背の低い画面でも盤面が算数土台に収まるようにする。
     十枠と受け皿は必ず同じ幅にする（別々に縮めない）。 */
  .tensBoard{display:flex;flex-direction:column;align-items:center;gap:var(--t-space-2);width:100%;
    --ch14W:min(320px, 37svh);}
  .tensNumeral{font-size:min(clamp(34px, 10vw, 56px), 5svh);
    font-weight:900;color:#5A4A2A;line-height:1;}
  /* 十枠は「ここ全体で10のまとまり」に見せる。外枠を中のマス線より
     強くして、10こがバラバラに見えないようにする。
     Q1（10のまとまりを置く問題）では .dropSlot.isActive の黄色い枠が
     優先されるため、この外枠は出ない（従来どおり）。 */
  /* 10のまとまりを囲う外枠だけを残す。内側は1枚の面にして、
     砂10こが「10のまとまり1つ」として読めるようにする。 */
  .tenFrame{display:grid;grid-template-columns:repeat(5,1fr);grid-auto-rows:1fr;
    gap:3px;padding:5px;width:min(100%, var(--ch14W, 320px));aspect-ratio:5 / 2;
    border-radius:var(--t-radius-m);
    background:rgba(201,169,113,.10);
    box-shadow:inset 0 0 0 3px rgba(122,88,44,.78);}
  /* Q1の置き場の合図。共通の黄色い内枠は使わず、10のまとまりの茶色い外枠を
     そのまま残したうえで、まわりへやわらかい灯りを回す。
     合図の出し方を同じ章の受け皿（Q2〜Q6）とそろえる。
     共通の .dropSlot 側は変更しないので、第11〜13章・第15章に影響はない。 */
  .tenFrame.dropSlot.isActive{
    box-shadow:inset 0 0 0 3px rgba(122,88,44,.78);
    background:rgba(201,169,113,.14);
    filter:drop-shadow(0 0 7px rgba(242,184,75,.85));
    transition:filter .22s var(--t-ease-standard);}
  .tenFrame.dropSlot.dropReady{
    filter:drop-shadow(0 0 11px rgba(121,183,198,.95));}
  /* 砂1単位。十枠・一の列・候補札で同じ絵を必要な数だけ並べる。
     数量を絵へ焼き込まないので、1こでも10こでも同じ砂に見える。 */
  .sandUnit{display:block;flex:0 0 auto;width:var(--sandUnit, clamp(22px, 6.2vw, 40px));
    aspect-ratio:512 / 300;
    background:url('assets/sand_unit_v2.webp') center bottom/contain no-repeat;}
  /* 1マスずつの枠線と面は持たない（2026-08-24 の承認済み仕様で、
     箱10個ではなく砂10このまとまりが見える方を採る）。
     マスは砂を等間隔に置くための場所としてだけ残し、線は引かない。
     5列×2行の配置そのものが5＋5＝10を示す。
     Q1の候補札は別クラス（.miniCell）なので、この変更は及ばない。 */
  .tenCell{display:flex;align-items:flex-end;justify-content:center;overflow:hidden;
    padding:2px;box-sizing:border-box;}
  .tenCell.on::after{content:"";display:block;width:86%;aspect-ratio:512 / 300;
    background:url('assets/sand_unit_v2.webp') center bottom/contain no-repeat;}
  .onesRow{display:flex;flex-wrap:wrap;align-content:center;justify-content:center;
    align-items:flex-end;gap:4px;
    width:min(100%, var(--ch14W, 320px));min-height:clamp(40px, 11vw, 62px);padding:5px;}
  .onesRow .sandUnit{--sandUnit:clamp(26px, 7vw, 44px);}

  /* 一の置き先の見た目だけを既存の石の水槽（sand_trough_empty.webp）へ差し替える。
     受け皿はこの1枚だけ。共通 dropSlot の黄色い枠は出さず、
     外側へ別の枠も足さない。判定領域は共通 receiver のまま。 */
  .onesRow.troughSlot{position:relative;
    background:url('assets/sand_trough_empty.webp') center/100% 100% no-repeat;
    box-shadow:none;border-radius:0;
    width:min(100%, var(--ch14W, 320px));aspect-ratio:958 / 313;min-height:0;
    /* 砂は皿の内側の底（手前の縁の内側）へ置く。2段になるときは、
       5この列を上に、残りを下に置く（justify-content:flex-end で
       いちばん下の段の底面が常に同じ高さになる）。
       下余白18%は、手前の縁より内側へ砂が収まる位置。
       align-items:center で上下の段の中心をそろえる（5とあと3が読めるように）。 */
    flex-direction:column;flex-wrap:nowrap;justify-content:flex-end;align-items:center;
    /* 余白は皿自身の幅を基準にする。% は「親の幅」を基準にするため、
       皿だけ細くしたときに余白が過大になり、砂が皿の上へはみ出していた。 */
    padding:0 calc(var(--ch14W, 320px) * .13)
              calc(var(--ch14W, 320px) * .18);gap:1px;
    filter:drop-shadow(0 0 0 rgba(242,184,75,0));
    transition:filter .22s var(--t-ease-standard);}
  /* 皿の内側だけを少し暗く・灰色寄りにして、置いた砂と分離させる。
     皿そのものの存在感は上げない（内側の窪みにだけ効かせる）。 */
  .onesRow.troughSlot::before{content:"";position:absolute;z-index:0;
    left:12%;right:12%;top:16%;height:46%;border-radius:50% / 42%;
    background:radial-gradient(ellipse at 50% 38%,
      rgba(74,66,58,.30) 0%, rgba(74,66,58,.20) 58%, rgba(74,66,58,.06) 100%);
    pointer-events:none;}
  .onesRow.troughSlot .sandRow{position:relative;z-index:1;
    display:flex;align-items:flex-end;justify-content:center;gap:3px;}
  .onesRow.troughSlot.isActive{background:url('assets/sand_trough_empty.webp') center/100% 100% no-repeat;
    box-shadow:none;
    filter:drop-shadow(0 0 7px rgba(242,184,75,.85));}
  .onesRow.troughSlot.dropReady{filter:drop-shadow(0 0 11px rgba(121,183,198,.95));}
  .onesRow.troughSlot.filled{background:url('assets/sand_trough_empty.webp') center/100% 100% no-repeat;
    box-shadow:none;filter:none;}
  /* 置いた砂は候補札の砂より大きく、皿の中で「置いた」と分かる大きさにする。
     下にやわらかい影を付けて、皿の底へ接地して見えるようにする。 */
  .onesRow.troughSlot .sandUnit{
    --sandUnit:min(clamp(34px, 9.7vw, 54px), calc(var(--ch14W, 320px) * .134));
    filter:drop-shadow(0 3px 2px rgba(62,48,32,.45));}
  /* 2段のときも底の位置は同じ。上の段が皿の内側に収まる大きさにする。 */
  .onesRow.troughSlot.twoRow{padding-bottom:calc(var(--ch14W, 320px) * .18);}
  .onesRow.troughSlot.twoRow .sandUnit{
    --sandUnit:min(clamp(25px, 7.2vw, 40px), calc(var(--ch14W, 320px) * .114));}

  /* 候補札。数字と数量構造を同じ札の中で対応させる。
     外形・寸法・材質は3枚とも同じで、中身だけが違う。 */
  .choiceCard.kind-sand,.choiceCard.kind-tenCard{
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    padding:5px;}
  .cardNumSmall{font-size:clamp(19px, 5.2vw, 30px);font-weight:900;color:#5A4A2A;line-height:1;}
  .choiceCard.kind-sand .cardSand{display:flex;flex-wrap:wrap;align-items:flex-end;
    align-content:center;justify-content:center;gap:2px;width:100%;
    --sandUnit:clamp(15px, 4.2vw, 26px);}
  /* Q1の2×5構造（2026-08-24 の承認済み仕様）。
     札が小さいので、枠は1本も引かない。1マスずつの枠も、まとまり全体の外枠も
     持たない。数はカードの数字が言うので、枠で囲って伝える必要がない。
     枠にとられていた余白ぶん、砂そのものを大きくする。
     ただし砂どうしがくっつくと 9・10・11 を数えにくくなるので、あいだはあける。
     列数と「10をこえる1こ」の位置は3枚とも同じままで、
     形や枠の数から答えが漏れないようにする。 */
  .choiceCard.kind-tenCard .miniTen{display:grid;grid-template-columns:repeat(5,1fr);
    gap:3px;width:100%;aspect-ratio:5 / 2;}
  .miniCell.on{background:url('assets/sand_unit_v2.webp') center bottom/98% auto no-repeat;}
  .miniExtra{display:block;width:calc(20% - 2.4px);aspect-ratio:5 / 4;}
  .miniExtra.on{background:url('assets/sand_unit_v2.webp') center bottom/98% auto no-repeat;}

  /* ---- 第15章：数字入りの油灯りで作る数列 ----
     ・数列も候補も oil_lantern_empty.webp ＋ lantern_glow.webp ＋ コード描画の数字。
       数字は画像へ焼き込まない。0〜20すべて同じ外形で出せる。
     ・空所は別の穴や器にしない。同じ灯りが「消えていて数字がない」状態。
     ・高さは svh で頭打ちにして算数土台へ収める（vh は実機Safariで大きすぎる）。
     ・幅は flex が分け、高さの上限から出した max-width で頭打ちにする。
       こうすると灯りの数が5でも6でも、はみ出さずに比率のまま縮む。 */
  /* 上段＝固定された問題の並び。ごく薄い横長の面で「ひとつづきの数列」と分かる
     程度にまとめる。枠は作らない。器にも見せない。 */
  .seqBoard{--seqH:clamp(74px, 14.5svh, 116px);
    width:100%;display:flex;flex-wrap:nowrap;
    align-items:flex-end;justify-content:center;gap:clamp(3px, 1.1vw, 7px);
    padding:var(--t-space-1) var(--t-space-2);
    border-radius:var(--t-radius-l);
    background:rgba(160,124,72,.06);}
  .seqLantern{position:relative;flex:1 1 0;min-width:0;
    max-width:calc(var(--seqH) * 700 / 960);aspect-ratio:700 / 960;
    container-type:size;
    border:0;padding:0;background:none;overflow:visible;}
  .seqLanternArt{position:absolute;z-index:1;inset:0;
    width:100%;height:100%;display:block;object-fit:contain;pointer-events:none;}
  .seqLanternGlow{position:absolute;z-index:0;left:50%;top:49%;
    width:174%;height:174%;max-width:none;display:block;object-fit:contain;
    transform:translate(-50%,-50%);opacity:0;pointer-events:none;
    transition:opacity .3s var(--t-ease-standard);}
  /* 灯りの火屋の中。二桁が一行で読めるよう、幅と高さの小さいほうで決める */
  .seqNumber{position:absolute;z-index:2;left:17%;right:17%;top:37%;bottom:25%;
    display:flex;align-items:center;justify-content:center;
    font-weight:900;font-size:min(37cqh, 50cqw);line-height:1;
    color:#3C270F;text-shadow:0 1px 0 rgba(255,250,220,.8);
    font-variant-numeric:tabular-nums;pointer-events:none;}
  /* 数列の灯りは並びの一部。候補ほど浮かせない */
  .seqBoard .seqLantern{filter:drop-shadow(0 2px 1.5px rgba(20,12,4,.20));}
  .seqLantern.lit .seqLanternGlow{opacity:.62;}
  /* 空所：あかりが消えている。分かるが、強くは光らせない */
  .seqLantern.seqGap .seqLanternArt{opacity:.44;filter:grayscale(.4);}
  .seqLantern.seqGap::after{content:"";position:absolute;z-index:2;
    left:9%;right:9%;top:14%;bottom:6%;border-radius:14px;
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.5);
    background:rgba(201,169,113,.12);
    transition:box-shadow .18s var(--t-ease-standard), background .18s var(--t-ease-standard);}
  /* 運んできた灯りがこの空所の上に来た合図。第14章の置き場と同じ寒色の灯り */
  .seqLantern.seqGap.dropReady::after{
    box-shadow:inset 0 0 0 3px rgba(121,183,198,.85), 0 0 12px 2px rgba(121,183,198,.42);
    background:rgba(121,183,198,.16);}
  .seqLantern.hintGlow{box-shadow:none;}
  .seqLantern.hintGlow::after{
    box-shadow:inset 0 0 0 3px rgba(121,183,198,.7);}
  .seqLantern.seqFixed.hintGlow{filter:drop-shadow(0 0 10px rgba(242,184,75,.85));}

  /* 下段＝ここから持ってくる候補。数列の帯とは別トーンの薄い面を敷き、
     間隔を広めに取る。説明文は足さず、見た目だけで役割を分ける。 */
  #actionDock.cardRow.kind-lantern{
    gap:clamp(12px, 4.6vw, 24px);
    padding:var(--t-space-2) var(--t-space-3);
    border-radius:var(--t-radius-l);
    background:rgba(112,80,38,.17);
    box-shadow:inset 0 1px 0 rgba(255,250,236,.62), inset 0 3px 6px rgba(58,38,14,.10);}
  /* 役目を終えた候補は静かに引く。盤面はそのまま見せておく */
  #actionDock.cardRow.dockSpent{opacity:0;
    transition:opacity .34s var(--t-ease-standard);pointer-events:none;}

  /* 候補の灯り。数列側と同じ素材・同じ形で、少しだけ大きい */
  .choiceCard.kind-lantern{--seqChoiceH:clamp(88px, 16.5svh, 132px);
    flex:1 1 0;min-width:0;min-height:0;width:auto;
    max-width:calc(var(--seqChoiceH) * 700 / 960);aspect-ratio:700 / 960;
    container-type:size;
    border-radius:0;background:none;box-shadow:none;display:block;
    /* 候補は少しだけ浮いて見せる。数列側より強い影にする */
    filter:drop-shadow(0 5px 4px rgba(20,12,4,.38));
    transition:filter .16s var(--t-ease-standard);}
  /* つまむと、さらに少し持ち上がる */
  .choiceCard.kind-lantern.zeroDragging{
    transform:translate(var(--dragX,0px), calc(var(--dragY,0px) - 8px)) scale(1.05);
    filter:drop-shadow(0 13px 10px rgba(20,12,4,.46));}
  /* 見た目は灯りのまま、指の当たり判定だけ左右へ広げる */
  .choiceCard.kind-lantern::before{content:"";position:absolute;z-index:3;inset:-6px -9px;}
  .choiceCard.kind-lantern.hintGlow{box-shadow:none;
    filter:drop-shadow(0 0 12px rgba(121,183,198,.9));}
  /* 高さの低い画面（iPhone SE をSafariで見た場合など）では、灯りを少し詰めて
     算数土台をあぶらーんから離す。候補は指でつまめる大きさを下回らせない。 */
  @media (max-height:600px){
    .seqBoard{--seqH:clamp(62px, 12.3svh, 116px);padding:2px var(--t-space-1);}
    #actionDock.cardRow.kind-lantern{padding:var(--t-space-1) var(--t-space-2);}
    /* 候補の見た目は --t-drag-visual（56px）を下回らせない。
       高さ76.8pxで幅がちょうど56pxになる。 */
    .choiceCard.kind-lantern{--seqChoiceH:clamp(74px, 13.9svh, 132px);}
  }

  /* -------- 第12章 EX-12：10までなぞって、その先へ --------
     旧レイアウト（絶対配置・道の下敷き・小さな一列）を算数土台の中で打ち消す。
     足あとは1〜10こめ（5＋5）と11こめ以降が ひとつづきの道で、順になぞる。
     大きさは --fpStep 一つで決め、章名・キャラ名での座標補正は持たない。 */
  .footprintBoard.inShell{position:static;transform:none;z-index:auto;
    --fpStep:clamp(40px, 12.9vw, 62px);   /* 足あと1こ。10までも10の先も同じ大きさ */
    --fpGap:4px;                          /* 同じ列の足あとの間隔＝道のつなぎ幅 */
    width:100%;max-width:100%;height:auto;min-height:0;
    display:flex;flex-direction:column;align-items:center;gap:var(--t-space-3);
    background:none;border:0;box-shadow:none;border-radius:var(--t-radius-l);
    padding:var(--t-space-2);
    transition:background .28s var(--t-ease-standard), box-shadow .28s var(--t-ease-standard);}

  /* ここまでで10。5こ×2列。10の数字を同じ枠の中へ入れ、群と数字を切り離さない */
  .footprintBoard.inShell .tenBlock{position:relative;display:flex;flex-direction:column;
    align-items:center;gap:var(--fpGap);max-width:100%;
    padding:4px;border-radius:var(--t-radius-l);
    background:rgba(240,229,201,.55);box-shadow:inset 0 0 0 2px rgba(154,116,64,.20);
    transition:background .22s var(--t-ease-standard), box-shadow .22s var(--t-ease-standard);}
  .footprintBoard.inShell .tenChip{order:-1;
    font-size:clamp(20px, 5.2vw, 28px);font-weight:900;color:#5A4A2A;line-height:1;
    padding:4px 14px;border-radius:var(--t-radius-pill);
    background:rgba(255,241,197,.92);box-shadow:inset 0 0 0 3px rgba(242,184,75,.9);
    transition:transform .22s var(--t-ease-standard);}
  /* 10の先へつづく、という向きだけを示す小さな印 */
  .footprintBoard.inShell .tenBlock::after{content:"";position:absolute;
    left:50%;bottom:calc(-1 * var(--t-space-3) + 1px);width:12px;height:12px;
    margin-left:-6px;border-right:3px solid rgba(154,116,64,.42);
    border-bottom:3px solid rgba(154,116,64,.42);transform:rotate(45deg);}

  /* なぞる道。指を置く前から「ここを通る」と分かるように薄い帯を敷く */
  .footprintBoard.inShell .tenRow,
  .footprintBoard.inShell .footprintTrack{position:relative;display:flex;flex-wrap:wrap;
    align-items:center;justify-content:center;gap:var(--fpGap);max-width:100%;
    height:auto;padding:3px;border-radius:var(--t-radius-pill);
    isolation:auto;background:rgba(121,183,198,.10);
    transition:background .2s var(--t-ease-standard);}
  /* 5＋5の列は絶対に折り返さない。狭い画面では足あとが縮んで5こを保つ */
  .footprintBoard.inShell .tenRow{flex-wrap:nowrap;}
  .footprintBoard.inShell .tenRow .trailFoot{flex:0 1 auto;min-width:0;}
  .footprintBoard.inShell .footprintTrack{
    width:auto;max-width:calc(var(--fpStep) * 3 + var(--fpGap) * 2 + 6px);}
  .footprintBoard.inShell.tracing .tenRow,
  .footprintBoard.inShell.tracing .footprintTrack{background:rgba(121,183,198,.20);}
  /* 旧レイアウトの道の下敷き画像と橋の光は共通シェルでは使わない。
     position が変わると画面いっぱいへ広がるため、疑似要素ごと止める。 */
  .footprintBoard.inShell .footprintTrack::before{content:none;}
  .footprintBoard.inShell.bridgeReached::after{content:none;}

  .footprintBoard.inShell .trailFoot{position:relative;border:0;background:none;padding:0;
    flex:0 0 auto;box-sizing:border-box;transform:none;filter:none;
    width:var(--fpStep);height:auto;aspect-ratio:1;opacity:.42;
    transition:opacity .18s var(--t-ease-standard), transform .18s var(--t-ease-standard);}
  .footprintBoard.inShell .trailFoot img{width:100%;height:100%;object-fit:contain;display:block;
    position:relative;z-index:2;}
  /* 通った足あとの間を線でつなぐ。続けて通るほど道が一本になっていく */
  .footprintBoard.inShell .trailFoot::before{content:"";position:absolute;z-index:1;
    top:50%;left:calc(-1 * var(--fpGap) - 2px);right:46%;height:9px;
    transform:translateY(-50%) scaleX(0);transform-origin:left center;
    border-radius:var(--t-radius-pill);background:rgba(108,214,240,.95);
    transition:transform .16s var(--t-ease-standard);}
  .footprintBoard.inShell .trailFoot.lit::before{transform:translateY(-50%) scaleX(1);}
  /* 列の先頭には手前へ伸びる線を出さない（3こ折り返しに合わせる） */
  .footprintBoard.inShell .tenRow .trailFoot:first-child::before,
  .footprintBoard.inShell .footprintTrack .trailFoot:nth-child(3n+1)::before{content:none;}
  /* 通った瞬間に一度だけ水の輪をひろげる。べっとんの足あとらしい手ごたえ */
  .footprintBoard.inShell .trailFoot::after{content:"";position:absolute;z-index:0;
    inset:-6%;border-radius:50%;box-shadow:0 0 0 3px rgba(140,238,255,.55);
    opacity:0;transform:scale(.6);}
  .footprintBoard.inShell .trailFoot.lit::after{animation:footWake .5s ease-out 1;}
  @keyframes footWake{
    0%{opacity:.85;transform:scale(.6);}
    100%{opacity:0;transform:scale(1.45);}}
  .footprintBoard.inShell .trailFoot.lit{opacity:1;transform:scale(1.04);
    filter:drop-shadow(0 0 8px rgba(121,183,198,.85));}
  /* 正しい順で通過した瞬間、足あと自身が一度だけ小さくふくらんで戻る。
     第13章の着地と同じ承認済みの動き（ch13Land）をそのまま再利用する。
     .lit は正しい順の通過でしか付かないので、1足あとにつき1回しか動かない。
     ヒント（hintNext）・動作例（demoTrace）・盤面生成・再入場では動かない。 */
  .footprintBoard.inShell .trailFoot.lit img{
    animation:ch13Land .36s var(--t-ease-pop-once, cubic-bezier(.22,1.08,.36,1));}
  .footprintBoard.inShell .trailFoot.hintNext{opacity:.8;transform:none;
    filter:drop-shadow(0 0 8px rgba(121,183,198,.9));}
  .footprintBoard.inShell .trailFoot.demoTrace{opacity:.9;transform:scale(1.1);filter:none;}

  /* 5こ目・10こ目のまとまり。既存の判定が付けるクラスをそのまま使う */
  .footprintBoard.inShell.firstFiveDone .tenRow:first-of-type{background:rgba(121,183,198,.24);}
  .footprintBoard.inShell.tenDone .tenBlock{background:rgba(255,241,197,.58);
    box-shadow:inset 0 0 0 3px rgba(242,184,75,.9);}
  .footprintBoard.inShell.tenDone .tenChip{transform:scale(1.06);}

  /* H1：10のまとまりを一度だけ強調する */
  .footprintBoard.inShell .tenBlock.hintTen{box-shadow:inset 0 0 0 3px rgba(242,184,75,.85);}
  /* H2：10の起点は固定色、その先の足あと群は弱い囲み。文章は増やさない */
  .footprintBoard.inShell.showTenGuide .tenBlock{box-shadow:inset 0 0 0 3px rgba(242,184,75,.9);}
  .footprintBoard.inShell.showTenGuide .footprintTrack{
    box-shadow:inset 0 0 0 2px rgba(121,183,198,.55);}
  /* 正解：10のまとまりと たどった足あとを一つの群として見せ、結果文と結びつける */
  .footprintBoard.inShell.trailComplete{background:rgba(255,241,197,.42);
    box-shadow:inset 0 0 0 3px rgba(242,184,75,.55);}

  @media (min-width:768px){
    .choiceCard{width:clamp(80px, 12vw, 116px);}
    .seqBoard{--seqH:clamp(96px, 15svh, 150px);}
    .choiceCard.kind-lantern{--seqChoiceH:clamp(110px, 17svh, 168px);}
    .tensBoard{--ch14W:min(420px, 44svh);}
  }

  /* 高さの低いスマホ縦（iPhone SE をSafariで見た場合など）。
     主見出しは2行のまま、足あとの数も問題も変えない。
     盤面の内側の余白・行間・ブロック間だけを詰めて算数土台へ収める。
     足あとは 44px（指で押せる大きさ）を下回らせない。
     .footprintBoard は第12章だけが作るので、他章へは効かない。 */
  @media (orientation:portrait) and (max-height:600px){
    .footprintBoard.inShell{
      --fpStep:clamp(44px, 11.8vw, 52px);
      --fpGap:3px;
      gap:var(--t-space-2);
      padding:2px;}
    .footprintBoard.inShell .tenBlock{padding:2px;gap:2px;}
    .footprintBoard.inShell .tenChip{padding:2px 12px;
      font-size:clamp(17px, 4.6vw, 22px);}
    /* 10の先へ続く印。ブロック間を詰めたぶん、印も同じだけ上へ寄せる */
    .footprintBoard.inShell .tenBlock::after{
      bottom:calc(-1 * var(--t-space-2) + 1px);
      width:10px;height:10px;margin-left:-5px;}
    .footprintBoard.inShell .tenRow,
    .footprintBoard.inShell .footprintTrack{padding:1px;}
  }

  /* 高さの低い画面（スマホ横など、対応外の向きを含む）では、
     足あとを小さくして算数土台に収める。 */
  @media (max-height:480px){
    .footprintBoard.inShell{--fpStep:clamp(30px, 9.6vh, 40px);gap:var(--t-space-2);}
  }

  /* 「動きを減らす」設定では、水の輪と道の伸びをやめて状態だけ変える */
  @media (prefers-reduced-motion:reduce){
    .footprintBoard.inShell .trailFoot::before{transition:none;}
    .footprintBoard.inShell .trailFoot.lit::after{animation:none;}
    .footprintBoard.inShell .trailFoot.lit img{animation:none;}
  }

  /* 第12章は算数土台が縦に長く、スマホ縦でべっとんと近づく。
     土台の上端を固定して、問題の大きさによらず おばけとの間隔を保つ。
     出す条件は盤面が付ける body.tallShellBoard だけで、章番号・キャラクター名では分岐しない。 */
  /* 単位は svh（バーを除いた実際に見えている高さ）を使う。
     vh は Safari ではアドレスバーを含む大きい高さを指すため、
     実機では下げ幅が見えている高さの想定より大きくなり、
     算数土台が縮んで盤面が見出しへ重なっていた。
     さらに、見えている高さが足りないときは下げ幅を自動で戻し、
     土台が縮まないようにする（第2項の calc がその上限）。 */
  @media (orientation:portrait){
    body.tallShellBoard #playShell{align-items:flex-start;
      padding-top:max(calc(var(--t-inset-top) + var(--ghost-band, 0px)), 29.5svh);}
    /* おばけが低い位置に座る画面では、土台をもう少しだけ下へ置く。
       おばけ・背景・3灯の位置は動かさない。 */
    body.tallShellBoard.lowerBoard #playShell{
      padding-top:max(calc(var(--t-inset-top) + var(--ghost-band, 0px)),
                      min(32.5svh, max(30svh, calc(100svh - 470px))));}
  }

/* =====================================================================
   第16章 PS-C：二量の比較（てぐりん）
   ---------------------------------------------------------------------
   ・出す条件は盤面が作るクラスだけ。章番号・キャラクター名では分岐しない。
   ・風鈴・うちわ・太鼓は 1024×1024 の透過素材を1点ずつだけ使う。
     値別・左右別・状態別の合成画像は作らない。
   ・記号（＞＝＜）、完成式、置き場所の点線は、すべてここと DOM で描く。
     素材へ焼き込まない。
   ・素材ごとの「絵が実際に写っている範囲」を測ってから、その範囲が
     箱と一致するように width / left / top をひとつの変数から計算している。
     透明な余白を CSS で隠すのではなく、余白の分だけずらして置いている。
       風鈴 x[.3271,.6719] y[.0889,.8555]
       うちわ x[.2080,.7920] y[.0996,.9004]
       側面太鼓 x[.1006,.9004] y[.2227,.7676]
       中央土台 x[.0967,.9043] y[.2109,.8018]
   ===================================================================== */
  .compareBoard{width:100%;display:flex;flex-direction:column;align-items:center;
    gap:var(--t-space-2);}

  /* ---- 上に空いた帯を救出対象へ使う（body.roomyGhost）----
     算数土台を下げた盤面では、3灯と土台のあいだに帯が余る。
     その分だけ救出対象を大きくし、同時に上へ持ち上げる。
     ・出す条件は盤面が付ける body.roomyGhost だけ。章番号・キャラクター名では分岐しない。
     ・付けていない第11〜15章の見え方は変わらない（--ghost-w も #playArea も既定のまま）。
     ・大きくした分だけ top を戻さないと足もとが下がって土台へ近づくので、
       grow と lift を別々に持ち、伸ばす向きと持ち上げる量を分けて決める。 */
  @media (orientation:portrait){
    body.roomyGhost{--ghost-grow:clamp(10px, 4.2vw, 20px);
      --ghost-lift:clamp(5px, 2vw, 11px);}
    body.roomyGhost #stage{--ghost-w:calc(min(34vw,150px) + var(--ghost-grow));}
    body.roomyGhost #playArea{
      top:calc(var(--t-inset-top) - var(--ghost-grow) - var(--ghost-lift));}
  }

  /* ---- 左右の数量枠。左右は同じ作りで、値だけが違う ---- */
  .compareRow{width:100%;display:flex;align-items:stretch;justify-content:center;
    gap:clamp(8px, 2.6vw, 18px);}
  .qtyFrame{flex:1 1 0;min-width:0;
    display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
    gap:var(--t-space-1);
    padding:var(--t-space-2) var(--t-space-1);
    border-radius:var(--t-radius-m);
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.32);
    background:rgba(255,248,232,.42);}

  /* 風鈴は同じ1素材のくり返し。5こで折り返し、10といくつを読み取りやすくする。
     行の間隔は絵の高さより短くしてあるので、短冊が次の行の下へ少し隠れる。
     これは承認画面と同じ重なり方で、数は必ず1こずつ分かれて見える。 */
  /* 風鈴の大きさは svh（アドレスバーを除いた実際に見えている高さ）で決める。
     vh は Safari でバーを含む大きい値を指すため、実機で盤面が縦に伸びて
     算数土台がてぐりんへかぶる。幅ではなく高さを基準にするのは、
     この盤面の詰まり方を決めているのが行数＝高さだから。 */
  .chimeGrid{--chimeW:clamp(15px, 3.1svh, 28px);
    --chimeGap:clamp(3px, 1.2vw, 7px);
    display:grid;grid-template-columns:repeat(5, var(--chimeW));
    grid-auto-rows:calc(var(--chimeW) * 1.62);
    gap:0 var(--chimeGap);
    justify-content:center;justify-items:start;
    /* 最後の行の短冊が下の数字へかからないよう、絵のはみ出し分だけ空ける */
    padding-bottom:calc(var(--chimeW) * .62);}
  .chimeUnit{position:relative;display:block;
    width:var(--chimeW);height:calc(var(--chimeW) * 1.62);
    pointer-events:none;}
  /* 実体の絵。箱＝風鈴そのものになるように、透明な余白の分だけずらす */
  .chimeArt{position:absolute;
    width:calc(var(--chimeW) * 2.901);height:auto;
    left:calc(var(--chimeW) * -.949);top:calc(var(--chimeW) * -.2579);
    pointer-events:none;}
  /* 枠が空のときも高さを保ち、0のときに枠がつぶれないようにする */
  .chimeGrid:empty{min-height:calc(var(--chimeW) * 1.62);}

  /* 行が増える問題ほど風鈴を小さくして、盤面の高さを一定に近づける。
     数の見え方（5こで折り返し）は変えない。値で決まるので章名では分岐しない。 */
  .compareBoard[data-rows="3"] .chimeGrid{--chimeW:clamp(14px, 2.9svh, 26px);}
  .compareBoard[data-rows="4"] .chimeGrid{--chimeW:clamp(13px, 2.6svh, 24px);}

  /* 風鈴と同じ値の算用数字。かならず枠の中の数と一致させる */
  .qtyNum{margin-top:auto;line-height:1;font-weight:900;
    font-size:clamp(24px, 4.6svh, 46px);color:#5A4A2A;}
  /* 数字を出さない問題では、その分の余白も残さない */
  .qtyFrame.noNumeral .chimeGrid{padding-bottom:calc(var(--chimeW) * .70);}

  /* ---- 1対1の対応づけ（H2と正解のとき）---- */
  .chimeUnit.paired{animation:chimePair .52s var(--t-ease-pop-once);}
  .chimeUnit.extra{animation:chimeExtra 1.05s var(--t-ease-standard) infinite alternate;}
  @keyframes chimePair{0%,100%{transform:translateY(0)} 46%{transform:translateY(-6px)}}
  @keyframes chimeExtra{
    from{filter:none}
    to{filter:drop-shadow(0 0 8px rgba(121,183,198,.95)) brightness(1.12)}}

  /* ---- 正解のあとに出す完成式。DOMの文字で出し、画像にしない ---- */
  .compareEquation{margin:0;
    padding:var(--t-space-1) var(--t-space-3);
    border-radius:var(--t-radius-pill);
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.30);
    background:rgba(255,248,232,.62);
    font-weight:900;line-height:1.2;letter-spacing:.06em;
    font-size:clamp(20px, 5.6vw, 30px);color:#5A4A2A;}
  .compareEquation[hidden]{display:none;}

  /* ---- 答え太鼓。置き先は共通の .dropSlot をそのまま使う ---- */
  .drumRow{width:100%;display:flex;align-items:flex-end;justify-content:center;
    gap:clamp(10px, 3.4vw, 26px);}
  .answerDrum{--drumW:clamp(64px, 20vw, 108px);
    position:relative;flex:0 0 auto;width:var(--drumW);
    transition:transform .16s var(--t-ease-standard), filter .16s var(--t-ease-standard);}
  /* 太鼓は絵そのものが置き先なので、共通の黄色い枠と下地は出さない。
     置ける／触れている／受け取ったの区別は、下の発光と大きさで示す。 */
  .answerDrum.dropSlot,
  .answerDrum.dropSlot.isActive,
  .answerDrum.dropSlot.filled{background:none;box-shadow:none;}
  .answerDrum.kind-side{aspect-ratio:7998 / 5449;--drumFaceY:21.9%;}
  .answerDrum.kind-equal{aspect-ratio:8076 / 5908;--drumFaceY:26.9%;}
  .answerDrum .drumArt{position:absolute;height:auto;pointer-events:none;}
  .answerDrum.kind-side .drumArt{width:calc(var(--drumW) * 1.2503);
    left:calc(var(--drumW) * -.1258);top:calc(var(--drumW) * -.2784);}
  .answerDrum.kind-equal .drumArt{width:calc(var(--drumW) * 1.2382);
    left:calc(var(--drumW) * -.1197);top:calc(var(--drumW) * -.2611);}
  /* 記号は太鼓の面の上へ重ねる。3つとも同じ書体・同じ太さ・同じ色にする */
  .answerDrum .drumSymbol{position:absolute;left:50%;top:var(--drumFaceY);
    transform:translate(-50%,-50%);
    font-size:calc(var(--drumW) * .34);font-weight:900;line-height:1;
    color:#4A3A1E;pointer-events:none;
    text-shadow:0 1px 0 rgba(255,250,236,.55);}
  /* 指が近づいた／受け取った。どちらも同じやさしい金色で、赤は使わない */
  .answerDrum.dropSlot.dropReady{transform:scale(1.05);
    filter:drop-shadow(0 0 10px rgba(242,184,75,.95));}
  .answerDrum.accepted{transform:scale(1.04);
    filter:drop-shadow(0 0 14px rgba(242,184,75,.98));}
  .answerDrum.hintGlow{box-shadow:none;
    filter:drop-shadow(0 0 12px rgba(121,183,198,.9));}

  /* ---- 金の羽根うちわ。画面に出るのは常にこの1枚だけ ---- */
  #actionDock.cardRow.kind-fan{
    padding:var(--t-space-1) var(--t-space-3);
    border-radius:var(--t-radius-l);
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.28);
    background:rgba(255,248,232,.34);
    /* うちわが太鼓の上へ移ったあとも、置き場所として枠だけが残る */
    min-height:calc(var(--t-drag-visual) + var(--t-space-2));}
  .choiceCard.kind-fan{--fanW:clamp(68px, 12svh, 108px);
    width:var(--fanW);aspect-ratio:5840 / 8008;
    min-width:0;min-height:0;
    border-radius:0;background:none;box-shadow:none;
    filter:drop-shadow(0 5px 5px rgba(20,12,4,.36));
    transition:filter .16s var(--t-ease-standard);}
  .choiceCard.kind-fan .fanArt{position:absolute;
    width:calc(var(--fanW) * 1.7123);height:auto;
    left:calc(var(--fanW) * -.3562);top:calc(var(--fanW) * -.1706);
    pointer-events:none;}
  /* 見た目はうちわのまま、指の当たり判定だけ少し広げる */
  .choiceCard.kind-fan::before{content:"";position:absolute;z-index:3;inset:-6px -8px;}
  .choiceCard.kind-fan.zeroDragging{
    transform:translate(var(--dragX,0px), calc(var(--dragY,0px) - 8px)) scale(1.05);
    filter:drop-shadow(0 13px 10px rgba(20,12,4,.46));
    animation:none;}
  /* 受け取ったあとのうちわは、太鼓の面へ立てかけるように少し小さく・下へ置く。
     ここをずらさないと、うちわが記号と完成式を覆ってしまう。
     置き場所（--dragX/--dragY）は共通のドラッグ処理が決めた値をそのまま使う。 */
  .choiceCard.kind-fan.zeroAccepted{
    transform:translate(var(--dragX,0px), var(--dragY,0px)) translate(-2%, 32%) scale(.70);}
  .choiceCard.kind-fan.hintGlow{box-shadow:none;
    filter:drop-shadow(0 0 12px rgba(121,183,198,.9));}
  /* H3：正しい太鼓の方向へ途中まで動いて戻る。最後まで運ばない＝置くのは子ども */
  .choiceCard.kind-fan.hintTrail{animation:fanTrail 1.15s var(--t-ease-standard);}
  @keyframes fanTrail{
    0%{transform:translate(0,0)}
    48%{transform:translate(var(--cueX,0px), var(--cueY,0px))}
    100%{transform:translate(0,0)}}

  /* ---- 置き場所の点線。3本とも同じ太さ・色・明るさで、正解を示さない ---- */
  .dropCueLayer{position:absolute;inset:0;width:100%;height:100%;
    pointer-events:none;z-index:6;overflow:visible;}
  .dropCuePath,.dropCueHead{fill:none;
    stroke:rgba(214,169,92,.92);stroke-width:3;
    stroke-linecap:round;stroke-linejoin:round;}
  .dropCuePath{stroke-dasharray:2 11;animation:cueFlow 1.5s linear infinite;}
  @keyframes cueFlow{to{stroke-dashoffset:-26}}

  /* ---- 動きを減らす設定。意味は変えず、移動だけを短い強調へ置き換える ---- */
  @media (prefers-reduced-motion: reduce){
    .chimeUnit.paired{animation:chimePairSoft .3s linear;}
    .chimeUnit.extra{animation:none;
      filter:drop-shadow(0 0 8px rgba(121,183,198,.95)) brightness(1.12);}
    @keyframes chimePairSoft{0%,100%{filter:none} 50%{filter:brightness(1.22)}}
    .dropCuePath{animation:none;}
    .answerDrum{transition:filter .14s linear;}
    .answerDrum.dropReady,.answerDrum.accepted{transform:none;}
    /* うちわは動かさず、光だけで方向を伝える */
    .choiceCard.kind-fan.hintTrail{animation:fanTrailSoft 1.1s linear;}
    @keyframes fanTrailSoft{0%,100%{filter:drop-shadow(0 5px 5px rgba(20,12,4,.36))}
      50%{filter:drop-shadow(0 0 14px rgba(242,184,75,.98))}}
  }

  /* 高さがとても足りない画面（スマホ横）では、置き場の余白だけをさらに詰める。
     風鈴・太鼓・うちわの大きさは上の svh 基準がそのまま効く。 */
  @media (max-height:560px){
    #actionDock.cardRow.kind-fan{padding:2px var(--t-space-2);}
  }

/* =====================================================================
   PS-E / ADD：二つの具体物を合わせて、結果の数字札を置く盤面
   ---------------------------------------------------------------------
   ・章名やキャラクター名には依存しない。additionResult 型が付けるクラスだけで出す。
   ・具体物は同じ1単位をDOMで反復し、数量を合成画像へ焼き込まない。
   ・Q1は中央の＋を出さず、Q2以降だけ同じ位置へ＋を出す。
   ・正解時は左右の二群を一群へ入れ替え、結果の数字と式を結ぶ。
   ===================================================================== */
  .additionBoard{width:100%;display:flex;flex-direction:column;align-items:center;
    gap:var(--t-space-1);
    /* 数量札が緑枠の上辺を半分またぐぶん、見出しに触れないよう少しだけ余地を作る。
       盤面は #mathFocus の中で上下中央に置かれるため、ここを増やすと
       同じだけ下へも出て、正解後の完成式が数字札の下へ隠れる。増やさないこと。
       緑枠自体の寸法と余白は変えていない。 */
    padding-top:clamp(16px, 4.7vw, 24px);}
  /* 舞台の最低高さは中の群にそろえる。ここに使われない余白があると、
     数量札のぶんだけ盤面が伸びて完成式が数字札の下へ隠れる。 */
  .additionGroupsStage{position:relative;width:100%;
    min-height:clamp(84px, 17svh, 132px);display:flex;align-items:center;justify-content:center;}
  .additionGroups{position:relative;z-index:1;width:100%;
    display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
    align-items:center;justify-items:center;gap:clamp(6px,2vw,14px);
    transition:opacity .32s var(--t-ease-standard), transform .36s var(--t-ease-standard);}
  /* 左右の群の後ろを通る横線は置かない（視覚表現訂正追補v1.0.0 §4-1）。
     実機で枝に見えず、実を串刺しにした棒・目盛り・スライダーに見えたため撤去した。
     代わりの枝、矢印、点線、飾り線も追加しない。二群がつながることは、
     正解後に一群へ入れ替える動きだけで伝える。 */
  .additionGroup{position:relative;box-sizing:border-box;width:100%;min-height:clamp(84px,17svh,132px);
    padding:clamp(6px,1.8vw,10px);
    display:flex;flex-wrap:wrap;align-content:center;justify-content:center;
    gap:clamp(2px,.8vw,5px);
    border-radius:var(--t-radius-l);
    background:rgba(224,237,184,.58);
    box-shadow:inset 0 0 0 2px rgba(94,116,57,.30);
    transition:box-shadow .18s var(--t-ease-standard), opacity .32s var(--t-ease-standard),
      transform .36s var(--t-ease-standard);}
  /* 量と数を結ぶ足場の数量札（視覚表現訂正追補v1.1.0 §4）。
     ・左右の群に1枚ずつ。実1個ごとには付けない。
     ・枠の上辺へ半分出して固定する。実の置き場所を削らないので、
       9個入る問題でも実・枠線・見出し・中央の＋と重ならない。
     ・操作対象に見せない。つまめず、押しても沈まない。
     ・読み上げは群のラベルが持つので、札自体は読ませない。 */
  .additionCountTag{
    /* 内側へ入れるのは枠の内余白のぶんだけ（4px）。ここは実が入らない帯なので、
       9個並んで枠がいっぱいでも最上段の実に触れない。
       全部を枠の外へ出すと盤面が高くなりすぎ、正解後の完成式が
       数字札の下へ隠れるため、この位置で釣り合わせている。 */
    position:absolute;left:50%;top:0;transform:translate(-50%,calc(-100% + 4px));
    z-index:3;pointer-events:none;
    display:grid;place-items:center;
    width:clamp(26px, 6.7vw, 32px);aspect-ratio:1;
    border-radius:50%;
    background:var(--t-paper-050, #FAF5E8);
    box-shadow:inset 0 0 0 2px rgba(94,116,57,.42),
               0 1px 3px rgba(45,60,25,.22);
    font-family:inherit;font-weight:900;line-height:1;
    font-size:clamp(17px, 4.4vw, 21px);
    color:var(--t-c-text-on-paper, #1F2D2A);}
  /* 実は数える対象なので、画面幅の許すかぎり大きく出す。
     390px幅で37px。小さい端末では折り返しが増えて数量札の下へ実が入るため、
     幅に比例させて自動で小さくする。よこ向きで高さが足りない端末は下で別に決める。 */
  .additionFruit{display:block;flex:0 0 auto;
    width:clamp(28px, calc(12.86vw - 13.14px), 40px);aspect-ratio:1;line-height:0;}
  /* 数える単位は章の item をそのまま置く。画像でもインラインSVGでも
     同じ大きさに収まるようにしておく（章では分岐しない）。 */
  .additionFruit svg,.additionFruit img{display:block;width:100%;height:100%;
    object-fit:contain;}
  .additionOperator{position:relative;z-index:2;display:grid;place-items:center;
    width:clamp(30px,8vw,44px);aspect-ratio:1;border-radius:50%;
    font-size:clamp(27px,7vw,40px);font-weight:900;line-height:1;color:#5A4A2A;
    background:rgba(250,245,232,.92);
    box-shadow:0 2px 5px rgba(45,29,11,.24);}
  /* Q1は記号をまだ教えない。中央は「左右が別の群である」空間だけを残し、
     白い円も枝の節も出さない（視覚表現訂正追補v1.0.0 §4-2）。
     幅と aspect-ratio は上の .additionOperator のまま残すので、
     左右の緑枠は接触しない（同 §4-3）。 */
  .additionOperator.isConcrete{background:none;box-shadow:none;}
  .additionGroup.isMerged{position:absolute;z-index:2;left:50%;top:50%;
    width:min(70%,330px);min-height:clamp(84px,17svh,132px);
    transform:translate(-50%,-50%) scale(.82);opacity:0;pointer-events:none;
    background:rgba(238,242,181,.78);}
  .additionBoard.joined .additionGroups{opacity:0;transform:scale(.88);}
  .additionBoard.joined .additionGroup.isMerged{
    opacity:1;transform:translate(-50%,-50%) scale(1);}

  .additionResultRow{display:flex;flex-direction:column;align-items:center;
    gap:2px;min-height:clamp(72px,13svh,96px);}
  .additionJoinMark{display:block;width:18px;height:13px;position:relative;}
  .additionJoinMark::before{content:"";position:absolute;left:50%;top:0;
    width:3px;height:9px;transform:translateX(-50%);border-radius:2px;background:#A87936;}
  .additionJoinMark::after{content:"";position:absolute;left:50%;bottom:0;
    width:8px;height:8px;border-right:3px solid #A87936;border-bottom:3px solid #A87936;
    transform:translateX(-50%) rotate(45deg);}
  .additionResultSlot{width:clamp(64px,18vw,88px);aspect-ratio:1;
    display:flex;align-items:center;justify-content:center;
    transition:box-shadow .18s var(--t-ease-standard), transform .2s var(--t-ease-standard);}
  .additionResultSlot .cardNum{font-size:clamp(30px,8vw,46px);font-weight:900;
    line-height:1;color:#5A4A2A;}
  .additionResultSlot.accepted{transform:scale(1.04);
    box-shadow:inset 0 0 0 3px rgba(242,184,75,.85),0 0 14px rgba(242,184,75,.55);}
  .additionGroup.hintGlow{box-shadow:0 0 0 4px rgba(121,183,198,.6),
    inset 0 0 0 2px rgba(94,116,57,.30);}
  .additionEquation{margin:0;padding:var(--t-space-1) var(--t-space-3);
    border-radius:var(--t-radius-pill);background:rgba(255,248,232,.7);
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.28);
    font-size:clamp(20px,5.5vw,30px);font-weight:900;line-height:1.2;
    letter-spacing:.05em;color:#5A4A2A;}
  .additionEquation[hidden]{display:none;}

  @media (orientation:landscape) and (max-height:560px){
    .additionCountTag{width:28px;font-size:18px;}
    .additionGroupsStage{min-height:86px;}
    .additionGroup,.additionGroup.isMerged{min-height:78px;padding:4px;}
    .additionFruit{width:clamp(23px,6.2vh,34px);}
    .additionResultRow{min-height:62px;}
    .additionResultSlot{width:58px;}
  }
  @media (prefers-reduced-motion:reduce){
    .additionGroups,.additionGroup{transition:opacity .14s linear;}
    .additionBoard.joined .additionGroups{transform:none;}
    .additionGroup.isMerged,
    .additionBoard.joined .additionGroup.isMerged{transform:translate(-50%,-50%);}
    .additionResultSlot.accepted{transform:none;}
  }

/* =====================================================================
   PS-E / E-SUB：一量から取り去り、残りの数字札を置く盤面
   ---------------------------------------------------------------------
   ・第18章の章名やキャラクター名には依存しない。subtractionResult型だけで出す。
   ・一段目の二群と「−」は常に横並び。折り返すのは各しずく群の内側だけ。
   ・二段目は「＝ 結果枠」。候補は共通Action dockの3枚一列を使う。
   ・しずくは既存の1点をDOMで反復し、数量・式・光を画像へ焼き込まない。
   ===================================================================== */
  .subtractionBoard{
    --subDropW:clamp(30px,8vw,44px);
    position:relative;width:100%;
    display:flex;flex-direction:column;align-items:center;
    gap:var(--t-space-1);
  }
  .subtractionTopRow{
    position:relative;width:100%;
    display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
    align-items:stretch;justify-items:center;
    gap:clamp(4px,1.5vw,10px);
  }
  .subtractionGroup{
    position:relative;box-sizing:border-box;width:100%;
    min-height:clamp(106px,22svh,148px);
    padding:clamp(30px,7vw,36px) 4px 6px;
    display:flex;align-items:center;justify-content:center;
    border-radius:var(--t-radius-l);
    background:rgba(208,238,246,.56);
    box-shadow:inset 0 0 0 2px rgba(67,132,151,.30);
    overflow:hidden;
    transition:box-shadow .18s var(--t-ease-standard), background .18s var(--t-ease-standard);
  }
  .subtractionDropGrid{
    position:relative;z-index:2;
    display:grid;grid-template-columns:repeat(4,var(--subDropW));
    grid-auto-rows:var(--subDropW);
    justify-content:center;align-content:center;
    gap:2px;
  }
  .subtractionDrop{
    position:relative;display:block;width:var(--subDropW);height:var(--subDropW);
    line-height:0;pointer-events:none;
    transform:translate(0,0) scale(1);opacity:1;
    transition:transform .42s var(--t-ease-standard),
               opacity .34s linear,filter .22s linear;
  }
  .subtractionDrop img,.subtractionDrop svg{
    display:block;width:100%;height:100%;object-fit:contain;
    filter:drop-shadow(0 0 1.5px rgba(255,255,255,.98))
           drop-shadow(0 2px 3px rgba(7,45,70,.55))
           saturate(1.12) brightness(1.08);
  }
  .subtractionCountTag{
    position:absolute;z-index:5;left:50%;top:5px;transform:translateX(-50%);
    min-width:clamp(28px,7vw,34px);height:clamp(28px,7vw,34px);
    padding:0 7px;border-radius:var(--t-radius-pill);
    display:flex;align-items:center;justify-content:center;gap:3px;
    pointer-events:none;
    background:var(--t-paper-050,#FAF5E8);
    box-shadow:inset 0 0 0 2px rgba(67,132,151,.42),0 1px 3px rgba(25,72,103,.20);
    color:var(--t-c-text-on-paper,#1F2D2A);font-family:inherit;line-height:1;
  }
  .subtractionCountTag strong{font-size:clamp(17px,4.5vw,22px);font-weight:900;}
  .subtractionCountTag small{font-size:clamp(10px,2.7vw,13px);font-weight:900;white-space:nowrap;}
  .subtractionCountTag.isRemove{min-width:clamp(56px,15vw,72px);}
  .subtractionOperator{
    align-self:center;position:relative;z-index:3;
    display:grid;place-items:center;
    width:clamp(30px,8vw,42px);aspect-ratio:1;border-radius:50%;
    font-size:clamp(27px,7vw,39px);font-weight:900;line-height:1;color:#5A4A2A;
    background:rgba(250,245,232,.94);box-shadow:0 2px 5px rgba(45,29,11,.22);
  }

  .subtractionResultRow{
    display:flex;align-items:center;justify-content:center;
    gap:clamp(10px,3vw,18px);
    min-height:clamp(66px,12svh,92px);
  }
  .subtractionEquals{
    display:grid;place-items:center;
    font-size:clamp(27px,7vw,39px);font-weight:900;line-height:1;color:#5A4A2A;
  }
  .subtractionResultSlot{
    width:clamp(64px,18vw,88px);aspect-ratio:1;
    display:flex;align-items:center;justify-content:center;
    transition:box-shadow .18s var(--t-ease-standard),transform .2s var(--t-ease-standard);
  }
  .subtractionResultSlot .cardNum{
    font-size:clamp(30px,8vw,46px);font-weight:900;line-height:1;color:#5A4A2A;
  }
  .subtractionResultSlot.accepted{
    transform:scale(1.04);
    box-shadow:inset 0 0 0 3px rgba(242,184,75,.85),0 0 14px rgba(242,184,75,.55);
  }
  .subtractionEquation{
    margin:0;padding:var(--t-space-1) var(--t-space-3);
    border-radius:var(--t-radius-pill);background:rgba(255,248,232,.72);
    box-shadow:inset 0 0 0 2px rgba(154,116,64,.28);
    font-size:clamp(20px,5.5vw,30px);font-weight:900;line-height:1.2;
    letter-spacing:.05em;color:#5A4A2A;
  }
  .subtractionEquation[hidden]{display:none;}

  /* ひしゃくはH2と正解後だけ現れる。タップ・読み上げ対象にはしない。 */
  .subtractionHishaku{
    position:absolute;z-index:4;left:35%;top:38%;
    width:clamp(104px,30vw,166px);height:auto;
    opacity:0;pointer-events:none;
    transform-origin:64% 74%;
  }
  .subtractionBoard.removalActive .subtractionHishaku{
    animation:subtractionScoop 1.08s var(--t-ease-standard) both;
  }
  @keyframes subtractionScoop{
    0%{opacity:0;transform:translate(-62%,-58%) rotate(-18deg) scale(.76)}
    16%{opacity:1}
    52%{opacity:1;transform:translate(-18%,-8%) rotate(10deg) scale(.92)}
    78%{opacity:.92;transform:translate(22%,32%) rotate(23deg) scale(.88)}
    100%{opacity:0;transform:translate(48%,50%) rotate(26deg) scale(.78)}
  }

  /* start群の末尾からremove個だけを外へ送り、残りだけを水色に光らせる。 */
  .subtractionDrop.isRemoved{
    transition-delay:calc(var(--remove-order,0) * 45ms);
    transform:translate(58%,46%) scale(.56);opacity:0;
    filter:blur(1px) brightness(1.18);
  }
  .subtractionBoard.showRemainder .subtractionDrop.isRemainder{
    animation:subtractionRemainder .72s var(--t-ease-pop-once)
              calc(var(--glow-order,0) * 55ms) 2 alternate;
    filter:drop-shadow(0 0 9px rgba(104,220,255,.95)) brightness(1.18);
  }
  @keyframes subtractionRemainder{
    from{transform:scale(1);filter:drop-shadow(0 0 2px rgba(104,220,255,.20)) brightness(1)}
    to{transform:scale(1.13);filter:drop-shadow(0 0 12px rgba(104,220,255,1)) brightness(1.25)}
  }
  .subtractionEmptyLabel{
    position:absolute;z-index:3;left:50%;top:58%;
    transform:translate(-50%,-50%) scale(.88);
    opacity:0;pointer-events:none;
    font-size:clamp(15px,4vw,20px);font-weight:900;white-space:nowrap;color:#416E7C;
    transition:opacity .2s linear,transform .2s var(--t-ease-pop-once);
  }
  .subtractionBoard.emptyRemainder .sub-startGroup{
    background:rgba(217,243,248,.72);
    box-shadow:inset 0 0 0 3px rgba(104,197,222,.48),0 0 12px rgba(104,220,255,.36);
  }
  .subtractionBoard.emptyRemainder .sub-startGroup .subtractionEmptyLabel{
    opacity:1;transform:translate(-50%,-50%) scale(1);
  }

  /* H3。正解札は結果枠の手前まで進んで戻り、置く判断は子どもへ残す。 */
  .choiceCard.subtractionHintTrail{
    animation:subtractionCardTrail 1.18s var(--t-ease-standard);
  }
  @keyframes subtractionCardTrail{
    0%,100%{transform:translate(0,0)}
    52%{transform:translate(var(--subCueX,0px),var(--subCueY,0px))}
  }

  @media (min-width:600px){
    .subtractionDropGrid{grid-template-columns:repeat(5,var(--subDropW));}
  }
  @media (orientation:landscape) and (max-height:560px){
    .subtractionBoard{--subDropW:clamp(22px,6.4vh,32px);}
    .subtractionGroup{min-height:88px;padding-top:26px;padding-bottom:4px;}
    .subtractionCountTag{top:3px;height:25px;min-width:25px;}
    .subtractionCountTag.isRemove{min-width:54px;}
    .subtractionResultRow{min-height:56px;}
    .subtractionResultSlot{width:56px;}
    .subtractionEquation{font-size:20px;padding:3px var(--t-space-2);}
  }
  @media (orientation:portrait) and (max-height:600px){
    .subtractionBoard{--subDropW:clamp(24px,8.2vw,30px);}
    .subtractionGroup{min-height:98px;padding-top:28px;padding-bottom:4px;}
    .subtractionResultRow{min-height:58px;}
    .subtractionResultSlot{width:58px;}
    .subtractionEquation{font-size:20px;padding:3px var(--t-space-2);}
  }
  @media (prefers-reduced-motion:reduce){
    .subtractionBoard.removalActive .subtractionHishaku{
      animation:subtractionScoopSoft .72s linear both;
    }
    @keyframes subtractionScoopSoft{0%,100%{opacity:0} 30%,70%{opacity:.9}}
    .subtractionDrop.isRemoved{transition:none;transform:none;opacity:.16;filter:grayscale(.3);}
    .subtractionBoard.showRemainder .subtractionDrop.isRemainder{
      animation:none;filter:drop-shadow(0 0 10px rgba(104,220,255,.95)) brightness(1.18);
    }
    .choiceCard.subtractionHintTrail{
      animation:subtractionCardTrailSoft 1s linear;
    }
    @keyframes subtractionCardTrailSoft{
      0%,100%{box-shadow:inset 0 0 0 2px rgba(154,116,64,.45),0 3px 0 rgba(122,90,49,.35)}
      50%{box-shadow:0 0 0 5px rgba(121,183,198,.58),inset 0 0 0 2px rgba(154,116,64,.45)}
    }
    .subtractionResultSlot.accepted{transform:none;}
  }

  /* 第19章は既存の数字＋量・候補札・二部分合成を使う。
     ここは play type の最小レイアウト指定だけで、章・キャラ固有補正は持たない。 */
  .makeTenBoard{width:min(100%,560px);margin-inline:auto;}
  .makeTenTarget{position:relative;min-height:clamp(126px,28vw,176px);}
  .makeTenParts{
    display:grid;
    grid-template-columns:minmax(78px,1fr) auto minmax(78px,1fr) auto auto;
    align-items:center;justify-items:center;
    gap:clamp(3px,1vw,7px);
  }
  .makeTenSlot{
    position:relative;box-sizing:border-box;width:100%;min-width:0;
    min-height:clamp(104px,25vw,142px);
    display:grid;place-items:center;overflow:visible;
  }
  .makeTenSlot.isActive:empty::after{
    content:"?";display:grid;place-items:center;
    width:clamp(32px,9vw,44px);aspect-ratio:1;border-radius:50%;
    font-size:clamp(24px,7vw,36px);font-weight:900;line-height:1;
    color:rgba(90,74,42,.72);background:rgba(250,245,232,.72);
  }
  .makeTenSlot .additionGroup{
    min-width:0;min-height:clamp(104px,25vw,142px);
    padding:clamp(8px,2vw,12px) clamp(4px,1vw,8px);
  }
  .makeTenSlot .makeTenRingUnit{width:min(100%,42px);}
  .makeTenEquals{
    font-size:clamp(24px,6.5vw,38px);font-weight:900;line-height:1;color:#5A4A2A;
  }
  .makeTenGoal{
    min-width:clamp(38px,10vw,52px);padding:.12em .18em;
    border-radius:var(--t-radius-m);
    font-size:clamp(28px,7.6vw,43px);font-weight:900;line-height:1;color:#5A4A2A;
    background:rgba(250,245,232,.92);box-shadow:0 2px 5px rgba(45,29,11,.18);
  }
  .makeTenRingUnit{
    display:block;box-sizing:border-box;width:100%;min-width:0;aspect-ratio:1;
    border:clamp(1px,.35vw,2px) solid rgba(71,211,240,.9);border-radius:50%;
    box-shadow:inset 0 0 3px rgba(230,255,255,.9),0 0 3px rgba(61,205,242,.72);
    background-position:center;background-repeat:no-repeat;background-size:contain;
  }
  .makeTenHintPreview{
    position:absolute;inset:clamp(7px,2vw,11px);z-index:5;pointer-events:none;
    display:grid;align-content:center;align-items:center;justify-items:center;
    gap:clamp(2px,.7vw,4px);
  }
  .makeTenHintPreview .makeTenRingUnit{width:min(100%,34px);}
  .makeTenSlot.filled.makeTenKnownHint{
    box-shadow:inset 0 0 0 3px rgba(121,183,198,.78),0 0 10px rgba(116,224,255,.5);
  }
  #actionDock.cardRow.makeTenChoices{
    display:grid;gap:clamp(7px,2vw,12px);width:min(100%,430px);margin-inline:auto;
  }
  #actionDock.cardRow.makeTenChoices[hidden]{display:none;}
  .choiceCard.kind-waterRing{
    box-sizing:border-box;overflow:hidden;min-width:0;width:100%;
    height:clamp(92px,25vw,108px);aspect-ratio:auto;
    display:grid;grid-template-rows:auto minmax(0,1fr);align-items:center;
    padding:clamp(5px,1.3vw,8px);gap:2px;
  }
  .makeTenCardNumber{
    display:block;text-align:center;font-size:clamp(25px,7vw,36px);
    font-weight:900;line-height:1;color:#5A4A2A;
  }
  .makeTenCardQuantity{
    display:grid;align-self:stretch;width:100%;height:100%;min-width:0;min-height:0;
    align-content:center;align-items:center;justify-content:center;justify-items:center;gap:2px;
  }
  .makeTenCardQuantity .makeTenRingUnit{width:clamp(20px,6vw,28px);}
  .choiceCard.kind-waterRing[data-value="7"] .makeTenRingUnit,
  .choiceCard.kind-waterRing[data-value="8"] .makeTenRingUnit{
    width:clamp(15px,4.3vw,20px);
  }
  .choiceCard.kind-waterRing[data-value="9"] .makeTenRingUnit{
    width:clamp(16px,4.6vw,21px);
  }
  @media (max-width:380px){
    .makeTenParts{grid-template-columns:minmax(70px,1fr) auto minmax(70px,1fr) auto auto;gap:3px;}
    .makeTenGoal{min-width:36px;}
  }

/* =====================================================================
   第20章が再利用する「あおばけちゃんの光」と、10＋残り／10＋10の汎用スキン
   ===================================================================== */
  .additionFruit .aobakeLight,.subtractionDrop .aobakeLight{width:100%;height:100%;}
  .additionFruit .aobakeLight>span,.subtractionDrop .aobakeLight>span{
    box-shadow:0 0 5px #B8F7FF,0 0 12px rgba(64,203,255,.78);}

  .seqLantern.isAobakeLight{aspect-ratio:1;max-width:var(--seqH);align-self:center;}
  .seqLantern.isAobakeLight .aobakeLight{position:absolute;inset:0;width:100%;}
  .seqLantern.isAobakeLight .seqNumber{inset:20%;z-index:4;
    color:#F8FEFF;text-shadow:0 2px 4px rgba(9,46,122,.95),0 0 8px #5FE8FF;
    font-size:min(42cqh,54cqw);}
  .seqLantern.isAobakeLight.seqGap .aobakeLight{opacity:.18;filter:grayscale(.45);}
  .seqLantern.isAobakeLight.seqGap::after{inset:7%;border-radius:50%;
    background:rgba(31,101,188,.12);box-shadow:inset 0 0 0 2px rgba(141,225,255,.52);}
  .choiceCard.kind-lantern.isAobakeLight{aspect-ratio:1;max-width:clamp(68px,19vw,104px);}
  .choiceCard.kind-lantern.isAobakeLight::before{inset:-7px;}

  .makeTenRingUnit.aobakeLightUnit{border:0;box-shadow:none;background:none;overflow:visible;}
  .makeTenRingUnit.aobakeLightUnit .aobakeLight{width:100%;height:100%;}
  .makeTenRingUnit.aobakeLightUnit .aobakeLight>span{
    box-shadow:0 0 4px #B8F7FF,0 0 9px rgba(64,203,255,.72);}
  .additionGroup.hasWaterRipple{overflow:visible;background:rgba(202,241,255,.38);}
  .quantityWaterRipple{position:absolute;z-index:0;left:50%;top:50%;
    width:118%;height:118%;object-fit:contain;transform:translate(-50%,-50%);
    opacity:.48;pointer-events:none;filter:drop-shadow(0 0 7px rgba(105,224,255,.45));}
  .hasWaterRipple .makeTenRingUnit{position:relative;z-index:1;}
  /* 数量札はgridの1マスとして数えない。10個を常に5個×2列で並べる。 */
  .hasWaterRipple .additionCountTag{position:absolute;z-index:2;}

  .tenRestBoard{width:100%;display:flex;flex-direction:column;align-items:center;gap:var(--t-space-1);}
  .tenRestGroups{width:100%;display:grid;grid-template-columns:minmax(0,1.45fr) auto minmax(0,1fr);
    align-items:center;justify-items:center;gap:clamp(6px,2vw,12px);}
  .tenRestGroup{min-height:clamp(100px,21svh,144px);padding:clamp(8px,2vw,12px);}
  .tenRestGroup.hintGlow{box-shadow:0 0 0 4px rgba(109,220,255,.66),0 0 18px rgba(84,195,255,.46);}
  .tenRestJoin{font-size:clamp(18px,5vw,28px);font-weight:900;color:#315E75;}
  .tenRestResultRow{min-height:clamp(64px,11svh,86px);display:grid;place-items:center;}
  .tenRestBoard.solved .tenRestGroups{filter:brightness(1.14);}

  .makeTwentyBoard .makeTenParts{
    grid-template-columns:minmax(86px,1.1fr) auto minmax(72px,.88fr) auto minmax(72px,.88fr) auto auto;
    gap:clamp(2px,.65vw,5px);}
  .makeTwentyBoard .makeTenBase{min-height:clamp(92px,22vw,130px);padding:5px;}
  .makeTwentyBoard .makeTenSlot{min-height:clamp(92px,22vw,130px);}
  .makeTwentyBoard .makeTenGoal{font-size:clamp(25px,6.5vw,38px);}
  .makeTwentyBoard .additionGroup.makeTenRightComplete{
    left:70%;width:min(30%,170px);min-height:clamp(92px,22vw,130px);
    background:rgba(202,241,255,.42);}
  .makeTwentyBoard .makeTenBase{transition:filter .34s ease,transform .34s ease;
    filter:drop-shadow(0 0 10px rgba(96,218,255,.5));}

  /* Q6は7要素の式と候補6枚を持つため、端末の安全幅まで問題面を広げる。 */
  body.wideMakeTwenty #playShell{padding-left:6px;padding-right:6px;}
  body.wideMakeTwenty #mathSurface{width:min(98%,720px);padding-left:7px;padding-right:7px;}

  .altarLightParticle{position:fixed;z-index:210;aspect-ratio:1;pointer-events:none;
    margin:0;transform:translate(-50%,-50%);}

  @media (orientation:landscape) and (max-height:560px){
    .tenRestGroup{min-height:82px;}
    .makeTwentyBoard .makeTenBase,.makeTwentyBoard .makeTenSlot{min-height:78px;}
    .choiceCard.kind-waterRing{height:82px;}
  }
