/* スマホ1画面。本文の上に、下の一本だけ。 */
#page {
  position: fixed;
  /* 会話の帯のぶんを空ける。重ねると、その下の本文が読めなくなる。
     **キーボードのぶんは引かない。**縦組みは箱の高さで列が決まるので、
     高さを変えると本文がその場で組み直され、字が跳ねる（実機で観測）。
     キーボードが出ている間は、紙の下のほうが隠れるだけにする。 */
  /* **下の一本の高さ（--barh）を使わない。**入力欄が伸びたり、赤やスポンサーの
     答え待ちで中身が入れ替わるたびに箱の高さが変わり、そのたびに縦組みが
     組み直されて改行位置が動く（実機で観測）。開いたときの高さ（--barh0）で
     場所を決め、以後は動かさない。 */
  /* **セーフエリアも足さない。**キーボードが出ると下の余白（ジェスチャーバー）が
     消えて env(safe-area-inset-bottom) が変わり、そのぶん箱の高さが動いて
     本文が組み直される（Chrome の実機で観測。Brave では出なかった）。
     --barh0 は下の一本の実寸で、その余白を padding として既に含んでいる。 */
  /* 12px だと本文のいちばん下の列が吹き出しに掛かって読みにくい。余白を広げる。 */
  inset: 3vh 4vw calc(var(--barh0, 118px) + var(--chat, 190px) + 30px) 4vw;
  /* 書いている先が画面の左端に貼り付くと読みにくい。
     本文の左に余白そのものを足して、書き先を中央寄りに置く。
     （スクロールを手前で止めると、書いている先が画面の外へ出る） */
  padding-left: min(30vw, 150px);
  writing-mode: vertical-rl; text-orientation: upright;
  font-size: clamp(15px, 4.3vw, 20px);
  line-height: 1.9; letter-spacing: 0.04em;
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
#page::-webkit-scrollbar { display: none; }
#page { -webkit-user-select: text; user-select: text; } /* OS の範囲選択を使う */
#page span { cursor: pointer; } /* 字はタップで選べる */
/* **送れないときは掴ませない。**選べてしまうとキーボードだけが立ち上がり、
   打っても送れない画面になる。JS 側の判定は play.html の canAdvise。
   ここで OS の選択ごと殺しておかないと、長押しの選択 UI が出てしまう。 */
body:is(.tut, .asking, .dealing, .busy, .over) #page {
  -webkit-user-select: none; user-select: none;
}
body:is(.tut, .asking, .dealing, .busy, .over) #page span { cursor: default; }
#page span.spotted { background: color-mix(in srgb, var(--red) 18%, transparent); }
#page ::selection { background: color-mix(in srgb, var(--red) 26%, transparent); }
#page span.censored { color: var(--ink); }
/* 改行も1文字ぶんの span で持つ（<br> だと glyphs() に出てこず、
   サーバーの本文とのあいだで位置がずれる）。white-space: pre で改行として効かせる。 */
/* 改行は1文字ぶんの span で持つが、これ自体を選ばせない。
   選択されると縦組みで列いっぱいに塗られて、崩れて見える。 */
#page span.br { white-space: pre; cursor: default; -webkit-user-select: none; user-select: none; }
#page span.br::selection { background: transparent; }

/* 造本の段は、書いている画面には出さない。
   紙の色や判型を落としていたが、読んでいる最中にいきなり色が変わって
   読みづらかった（実機で観測）。突っぱねた結果は、スポンサーが冷たくなって
   最後は降りることと、共有された先の表紙・奥付に残す（three-agents.md）。 */

/* 会話履歴。下が新しく、上へ行くほど溶ける。 */
:root { --chat: min(26vh, 190px); }
#voices {
  position: fixed; left: 4vw; right: 4vw;
  bottom: calc(var(--barh, 118px) + 10px + env(safe-area-inset-bottom));
  height: var(--chat);
  display: flex; flex-direction: column;
  /* justify-content: flex-end だと、はみ出した上側が掴めなくなる（遡れない）。
     先頭に margin-top:auto を入れて下寄せにする。 */
  justify-content: flex-start;
  gap: 5px;
  /* 遡って読み返せるようにする。触れるが、紙のタップは奪わない（帯の外は素通し）。 */
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; pointer-events: auto; z-index: 7;
  transition: opacity 0.3s ease;
  /* 帯の上端で切れる。ぶつ切りに見えないよう、上だけ溶かす。 */
  mask-image: linear-gradient(to bottom, transparent 0, #000 38px);
}
/* 本文を遡って読んでいる間は引っ込む（帯は空けたままなので、字は動かない） */
#voices > :first-child { margin-top: auto; }
#voices::-webkit-scrollbar { display: none; }
/* **遡って読んでいる間も、会話は見せる。**引っ込めていたが、
   三人が何を言っているか分からなくなるほうが困る。筆は止まっているので、
   会話だけが動いて本文が動かない、という見え方になる。 */
/* 本文を選んでいる間は引っ込める。選んだ場所が吹き出しの裏に入ると読めない。 */
body.spotting #voices { opacity: 0; pointer-events: none; }
/* 遡っている間は、薄れたものも読めるように戻す */
body.chatting #voices { background: color-mix(in srgb, var(--paper) 88%, transparent); }

/* ------------------------------------------------ 下の一本 */
#bar {
  position: fixed; left: 0; right: 0; z-index: 9;
  /* キーボードのぶんは持ち上げない。レイアウトごと縮ませているので、
     bottom:0 のままで IME のツールバーの上に出る（play.html の viewport を参照）。 */
  bottom: 0;
  padding: 8px 4vw calc(8px + env(safe-area-inset-bottom));
  background: var(--paper); border-top: 1px solid var(--hair);
  display: flex; flex-direction: column; gap: 7px;
}
/* **帯の下も同じ紙で塞ぐ。**本文の箱は画面の底まで伸びたままなので（組み直さない
   ため）、帯を持ち上げると、その下から本文がのぞく（実機で観測）。
   影ではなく敷物で塞ぐ。box-shadow は箱をずらして描くだけなので塗り潰せない。 */
#bar::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 100vh;
  background: var(--paper); pointer-events: none;
}

#bar .row { display: flex; align-items: flex-end; gap: 7px; }
#bar .row.sub { align-items: center; }
#bar .grow { flex: 1; }
#say {
  flex: 1; min-width: 0; font-family: inherit; font-size: 16px; /* iOS の自動ズーム回避 */
  line-height: 1.5; padding: 10px 14px; border: 1px solid var(--hair); border-radius: 18px;
  background: color-mix(in srgb, var(--paper) 92%, var(--ink)); color: var(--ink);
  resize: none; overflow-y: auto; max-height: 132px;
}
/* 文言が長いとき、枠の中で切れるより外へ省略させる。
   textarea は placeholder を折り返すので、二行目が枠から切れて読めなくなる。 */
#say::placeholder { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
#say:focus { outline: none; border-color: color-mix(in srgb, var(--ink) 40%, transparent); }
/* 押すところは一つだけ。いちばん濃く、いちばん大きい。 */
#go {
  font-family: inherit; font-size: 14px; font-weight: 500;
  padding: 11px 18px; flex: 0 0 auto;
  border: 1px solid var(--ink); border-radius: 22px;
  background: var(--ink); color: var(--paper); cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
#go.quiet { background: none; color: var(--faint); border-color: var(--hair); }
/* 書いている間は押させない。**ただし書き上がったあとは別。**
   仕上げは生成ではなく、その場でひらく紙。ここを busy で塞ぐと、
   ストリームが返り切らないまま turning が戻らなかったときに
   **書き上がっているのに仕上げられなくなる**。 */
body.busy:not(.over) #go { opacity: 0.4; pointer-events: none; }

/* 書き上がったら、注文はもう入らない（サーバーが advance も redline も受け付けない）。
   **打てるのに効かない欄を残さない。**帯は仕上げの一本だけにする。 */
body.over #say { display: none; }
body.over #go { flex: 1; }

/* 校正者への返事と、スポンサーへの返事。
   入力欄と入れ替わりで、同じ場所に大きく出る。押すところは増やさない。 */
#bar #side, #bar #deal { display: none; gap: 8px; }
body.asking #bar #side, body.dealing #bar #deal { display: flex; }
body.asking #bar .row.main, body.dealing #bar .row.main { display: none; }
#deal button {
  flex: 1; font-family: inherit; font-size: 14px; padding: 13px 10px;
  border: 1px solid var(--hair); border-radius: 22px;
  background: var(--paper); color: var(--ink); cursor: pointer;
}
/* 呑む側だけ金の色を持たせる。何が起きるかは書かない（断ってから見せる） */
#deal button.pay { border-color: #8a6a1f; color: #6d5316; background: color-mix(in srgb, #e0b41f 14%, var(--paper)); }
#side button {
  flex: 1; font-family: inherit; font-size: 14px; padding: 13px 10px;
  border: 1px solid var(--hair); border-radius: 22px;
  background: var(--paper); color: var(--ink); cursor: pointer;
}
#side button.red { color: var(--paper); background: var(--red); border-color: var(--red); }

/* ------------------------------------------------ 登場人物 */
/* 表紙。名簿はここでは出さない（誰のことか分からないうちに読ませても頭に入らない） */
/* 表紙。絵を画面いっぱいに敷いて、その上に題を置く。 */
#sheet {
  position: fixed; inset: 0; z-index: 20; display: none;
  align-items: flex-end; justify-content: center;
  background: #14120f center/cover no-repeat url(/illus/cover.jpg);
}
#sheet.on { display: flex; }
/* 題を読ませるための影。絵の上に文字を直に置くと沈む。 */
#sheet::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(12,10,8,0.1) 30%, rgba(12,10,8,0.62) 62%, rgba(12,10,8,0.94) 100%);
}
#sheet .card {
  position: relative; width: min(92vw, 460px); background: none;
  padding: 0 22px calc(34px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 15px; text-align: center;
  color: #f2eee4;
  animation: up 0.6s cubic-bezier(0.2,0.8,0.3,1);
}
@keyframes up { from { transform: translateY(30px); opacity: 0; } to { transform: none; opacity: 1; } }
#sheet .ttl {
  font-size: clamp(28px, 8.5vw, 40px); letter-spacing: 0.16em;
  text-shadow: 0 2px 18px rgba(0,0,0,0.6);
}
#sheet .li { font-size: 12.5px; color: rgba(242,238,228,0.78); line-height: 1.95; }
#sheet button {
  margin-top: 6px; font-family: inherit; font-size: 15px; padding: 15px;
  border: 1px solid #f2eee4; border-radius: 4px; background: #f2eee4; color: #14120f; cursor: pointer;
}
/* 同意の一行。押すところ（はじめる）のすぐ下に置く。 */
#sheet .agree {
  margin-top: -4px; font-size: 11.5px; line-height: 1.9;
  color: rgba(242, 238, 228, 0.66);
}
#sheet .agree a { color: rgba(242, 238, 228, 0.92); text-underline-offset: 3px; }
/* 役ごとの判子の色は style.css にまとめてある（ここに書くと似顔絵の上に字が乗る） */
/* flex の伸長で丸ボタンが楕円になるので、縦を自分で決める */


/* 消しゴムで擦られている字 */
#page span.erasing {
  animation: rub 0.26s ease-in-out infinite;
  color: var(--faint);
}
@keyframes rub {
  0%,100% { transform: translateX(0); opacity: 0.85; }
  50% { transform: translateX(1.5px); opacity: 0.5; }
}
/* hidden 属性は UA の display:none。上の display:flex に負けるので明示する */


/* 会話の吹き出し。積んで、古いものから薄くなって消える。 */
.voice {
  display: flex; align-items: flex-start; gap: 7px; max-width: 92%;
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.8s ease, transform 0.45s cubic-bezier(0.2,0.8,0.3,1);
}
.voice.in { opacity: 1; transform: none; }
/* 要素ごと透明にすると、吹き出しの紙まで透けて本文が裏から見える。
   薄くするのは中身だけにして、紙は不透明のままにする。 */
.voice.in .seal, .voice.in .nm { opacity: var(--o, 1); }
.voice.in .say { color: color-mix(in srgb, var(--ink) calc(var(--o, 1) * 100%), transparent); }
.voice.in.proof .say { color: color-mix(in srgb, var(--red) calc(var(--o, 1) * 100%), transparent); }
.voice.in.censor .say { color: color-mix(in srgb, var(--paper) calc(var(--o, 1) * 100%), transparent); }
.voice.in.editor .say { color: color-mix(in srgb, var(--paper) calc(var(--o, 1) * 100%), transparent); }
.voice .col { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* 顔だけでは誰か分からない。名前を上に添える。
   **名前は吹き出しの外に出るので、素の字で置くと本文と重なって読めない。**
   9.5px の薄墨で紙に直接置いていたころ、縦組みの本文の上に乗って
   誰が喋っているのか分からなかった（実機で観測・2026-08-09）。
   紙を一枚敷き、字を大きく・濃くし、**役の色**を付ける。 */
.voice .nm {
  align-self: flex-start;
  font-size: 11px; font-weight: 600; letter-spacing: 0.1em;
  color: var(--ink); padding: 1px 6px; border-radius: 3px;
  background: var(--paper);
}
/* 名前の色でも役が分かること。顔・名前・吹き出しの三つが揃って初めて、
   通りすがりの一瞥で誰の声か分かる。 */
.voice.proof .nm { color: var(--red); }
.voice.sponsor .nm { color: #6d5316; }
@media (prefers-color-scheme: dark) {
  .voice.sponsor .nm { color: #e8c45c; }
}
.voice .say {
  position: relative; font-size: 12.5px; line-height: 1.6; color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--hair); border-radius: 3px; padding: 6px 9px;
}
.voice .say::before {
  content: ""; position: absolute; left: -5px; top: 10px;
  width: 8px; height: 8px; transform: rotate(45deg);
  background: inherit; border-left: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
}
.voice.proof .say { color: var(--red); border-color: color-mix(in srgb, var(--red) 30%, transparent); }
.voice.censor .say { background: var(--ink); border-color: var(--ink); color: var(--paper); letter-spacing: 0.2em; }
/* スポンサーは金の色。校正者の朱とも、小説家の墨とも見分けがつくこと。 */
/* スポンサーは金の色。**暗い配色では明るい金にする。**
   濃い金（#6d5316）を暗い紙に載せていたので、ほとんど読めなかった（実機で観測）。 */
.voice.sponsor .say { color: #6d5316; border-color: #8a6a1f; background: color-mix(in srgb, #e0b41f 12%, var(--paper)); }
@media (prefers-color-scheme: dark) {
  .voice.sponsor .say { color: #e8c45c; border-color: #8a6a1f; background: color-mix(in srgb, #e0b41f 10%, var(--paper)); }
}
/* 編集者＝あなたの発言は右側に寄せる */
.voice.editor { flex-direction: row-reverse; align-self: flex-end; }
.voice.editor .col { align-items: flex-end; }
.voice.editor .nm { padding: 0 2px 0 0; }
.voice.editor .say {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}
.voice.editor .say::before { left: auto; right: -5px; border: none; background: inherit; }

/* 台本の間は入力させない */
body.tut #bar { opacity: 0; pointer-events: none; }

/* 編集者に権限を渡すところ */
#tut { position: fixed; inset: 0; z-index: 21; display: none; align-items: center; justify-content: center; background: rgba(0,0,0,0.34); }
#tut.on { display: flex; }
#tut .card {
  width: min(88vw, 400px); max-height: 88vh; overflow-y: auto;
  background: var(--paper); border-radius: 14px;
  padding: 26px 24px 22px;
  display: flex; flex-direction: column; gap: 13px;
  animation: up 0.4s cubic-bezier(0.2,0.8,0.3,1);
}
#tut .ttl { font-size: 17px; letter-spacing: 0.06em; }
#tut p { font-size: 13px; line-height: 1.85; color: var(--faint); }
#tut b { color: var(--ink); }
#tut .row2 { display: flex; align-items: flex-start; gap: 12px; font-size: 13px; }
#tut .li { font-size: 11.5px; color: var(--faint); line-height: 1.7; }
#tut .you b { text-decoration: underline; text-underline-offset: 4px; }
#tut ul { margin: 0 0 0 1.1em; font-size: 12.5px; line-height: 2; color: var(--faint); }

/* 3枚を横に送る。指でも払えるし、ボタンでも進む。 */
#tut .track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
#tut .track::-webkit-scrollbar { display: none; }
/* 1枚が必ず1画面に収まること。縦スクロールさせない。 */
#tut .track section {
  flex: 0 0 100%; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 10px;
}
#tut .dots { display: flex; justify-content: center; gap: 7px; }
#tut .dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--faint); opacity: 0.3; }
#tut .dots i.on { opacity: 1; }
#tut button {
  margin-top: 6px; font-family: inherit; font-size: 15px; padding: 14px;
  border: 1px solid var(--ink); border-radius: 4px; background: var(--ink); color: var(--paper); cursor: pointer;
}

/* 本文は読むところ。進めるのは下のボタンだけなので、押せるようには見せない
   （紙全体を「続けて」にしていたころ、読もうとした指が続きを書かせていた）。
   字はタップで選べるので、テキストのカーソルは残す。 */
#page { -webkit-tap-highlight-color: transparent; }

/* 吹き出しの顔は、名前と本文の二段ぶんに見合う大きさに */
.voice .seal.face { width: 30px; height: 30px; flex: 0 0 30px; }

/* 案内の挿絵。文字を読ませる前に、何の話かを絵で見せる。 */
#tut .illus {
  width: 100%; height: min(23vh, 168px); object-fit: cover; object-position: center 42%;
  border-radius: 8px; display: block; flex: 0 0 auto;
}
@media (prefers-color-scheme: dark) { #tut .illus { opacity: 0.86; } }

/* 背の低い端末（iPhone SE 等）では絵と余白を削って、1枚を1画面に収める */
@media (max-height: 720px) {
  #tut .illus { height: 15vh; }
  #tut .card { padding: 18px 20px 16px; gap: 10px; }
  #tut .track section { gap: 8px; }
  #tut .row2 { font-size: 12.5px; }
}

/* ------------------------------------------------ 広い画面
   スマホでは会話が本文の下に重なるが、PC はそれをやる理由がない。
   左をやりとり専用の欄にし、本文は右へ寄せて、重ならないようにする。 */
@media (min-width: 900px) {
  :root { --col: 380px; }
  /* 縦書きは箱の右端から始まる。画面いっぱいに広げると、本文が右の端に取り残されて読みにくい。
     箱の幅を絞って、書き出しが画面の真ん中寄りに来るようにする。 */
  #page {
    inset: 6vh auto 6vh auto;
    left: calc(var(--col) + 7vw);
    width: min(46vw, 680px);
  }
  #voices {
    left: 4vw; right: auto; width: var(--col);
    top: 4vh; bottom: calc(4vh + var(--barh, 118px) + 14px);
    height: auto; max-height: none; justify-content: flex-end;
  }
  /* 左が専用欄になるので、本文を沈めるための紙は要らない */
  #voices::before { display: none; }
  #bar {
    left: 4vw; right: auto; width: var(--col);
    bottom: 4vh; border: 1px solid var(--hair); border-radius: 12px;
    /* 広い画面では帯が浮いた箱になる。下を塞ぐ敷物は要らない（狭い画面だけの手当て） */
    padding: 10px 12px;
  }
  #bar::after { display: none; }
  /* 縦長の絵を横長の画面に敷くと上下が切れる。顔が残る位置まで上げる。 */
  #sheet { background-position: center 20%; }
  .voice { max-width: 100%; }

}

/* 考え中。返事を待つ間だけ出る。 */
.voice.think .say { display: flex; gap: 4px; align-items: center; padding: 9px 11px; }
.voice.think .say i {
  width: 4px; height: 4px; border-radius: 50%; background: var(--faint);
  animation: think 1.25s ease-in-out infinite;
}
.voice.think .say i:nth-child(2) { animation-delay: 0.18s; }
.voice.think .say i:nth-child(3) { animation-delay: 0.36s; }
@keyframes think {
  0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* 仕上げる前の名乗り */
#sign { position: fixed; inset: 0; z-index: 22; display: none; align-items: center; justify-content: center; background: rgba(0,0,0,0.34); }
#sign.on { display: flex; }
#sign .card {
  width: min(88vw, 380px); background: var(--paper); border-radius: 14px;
  padding: 26px 24px 22px; display: flex; flex-direction: column; gap: 13px;
  animation: up 0.35s cubic-bezier(0.2,0.8,0.3,1);
}
#sign .ttl { font-size: 17px; letter-spacing: 0.06em; }
#sign p { font-size: 12.5px; line-height: 1.8; color: var(--faint); }
#sign input {
  font-family: inherit; font-size: 16px; padding: 12px 14px;
  border: 1px solid var(--hair); border-radius: 8px;
  background: color-mix(in srgb, var(--paper) 92%, var(--ink)); color: var(--ink);
}
#sign input:focus { outline: none; border-color: color-mix(in srgb, var(--ink) 40%, transparent); }
#sign button {
  font-family: inherit; font-size: 15px; padding: 14px;
  border: 1px solid var(--ink); border-radius: 4px; background: var(--ink); color: var(--paper); cursor: pointer;
}
#sign button:disabled { opacity: 0.5; }

/* 今日ぶんの紙が尽きたとき */
#dry { position: fixed; inset: 0; z-index: 24; display: none; align-items: center; justify-content: center; background: rgba(0,0,0,0.5); }
#dry.on { display: flex; }
#dry .card {
  width: min(88vw, 380px); background: var(--paper); border-radius: 14px;
  padding: 28px 24px 22px; display: flex; flex-direction: column; gap: 13px; text-align: center;
  animation: up 0.4s cubic-bezier(0.2,0.8,0.3,1);
}
#dry .ttl { font-size: 18px; letter-spacing: 0.06em; }
#dry p { font-size: 13px; line-height: 1.9; color: var(--faint); }
#dry .li { font-size: 11.5px; }
#dry .row { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
#dry button, #dry a {
  font-family: inherit; font-size: 14px; padding: 13px; text-decoration: none;
  border: 1px solid var(--hair); border-radius: 4px; background: none; color: var(--ink); cursor: pointer;
}
#dry button, #dry a.primary { border-color: var(--ink); background: var(--ink); color: var(--paper); }

/* 書いている間は、入力の一本を引っ込める。
   高さは空けたまま（display を切ると本文が跳ねる）。
   墨が乾くように、ゆっくり出て、ゆっくり消える。 */
#bar .row.main {
  transition: opacity 1s cubic-bezier(0.33, 0, 0.2, 1), transform 1s cubic-bezier(0.33, 0, 0.2, 1);
}
/* **書き上がったあと（.over）は引っ込めない。**その一本が仕上げる唯一の口なので、
   turning が戻らないまま busy が残ると、書き上がっているのに仕上げられなくなる
   （editor-actions.md「仕上げる口も、その一本」）。 */
body.busy:not(.over) #bar .row.main {
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
}
/* 引っ込んでいる間は、押せる見た目を残さない */
body.busy:not(.over) #go { opacity: 0; }
