@charset "UTF-8";
/* ==========================================================================
   Suggesco ─ スクロール連動 棒人間（紙芝居）  2026-08-11
   --------------------------------------------------------------------------
   記事の「読書進捗」そのものを1本のタイムラインにして、棒人間が一日を演じる。
   記事の冒頭では眠っていて、読み終わるころにまた眠る。
   ピン留めも全画面占有もしない＝読書を止めない。

   ■ 器と中身を分けてある
     .sgk*      … 舞台（位置・状態遷移・開閉）。中に何を出すかを知らない
     .sgk-fig*  … 中身（棒人間の振り付け）。ここだけ差し替えれば別の絵になる
     受け渡しは進捗 --sgkp（0→1）ひとつだけ。

   ■ クラス名は全部 sgk- 接頭辞。SWELL・テーマ側との衝突を避けるため。
   ■ 色はトークンのみ（--ink / --paper / --line …）。16進を直書きしない
     ＝ダークモードで壊れないため（docs/design-system.md「色の鉄則」）。
   ========================================================================== */

/* 進捗を「補間できる数値」として登録する。これが無いと custom property は
   ただの文字列なのでアニメーションできない。 */
@property --sgkp{syntax:"<number>";inherits:true;initial-value:0}
@keyframes sgkRead{from{--sgkp:0} to{--sgkp:1}}

/* 本文＝読書進捗の実体。名前をページ全体から見えるようにする。
   --sgk-gap は目次ダイヤル .sg-dial の画面端からの距離と同じ値。
   ダイヤルの真上に積むので、ここがズレると縦位置が合わなくなる。
   （.sg-dial 側を変えたら、ここも合わせること） */
:root{timeline-scope:--sgkread;--sgk-gap:clamp(16px,2.6vw,34px)}
.sgk-on .prose{view-timeline-name:--sgkread;view-timeline-axis:block}

/* contain 0%→100% は「本文の上端が画面上端に来てから、下端が画面下端に来るまで」。
   ＝読んでいる区間そのもの。だから最後の一文を読み終えた瞬間が進捗1.0になる。
   （著者box・関連記事・購読CTAは .prose の外なので巻き込まれない） */
body.sgk-on{
  animation:sgkRead 1s linear both;
  animation-timeline:--sgkread;
  animation-range:contain 0% contain 100%;
}

/* ==========================================================================
   舞台
   ========================================================================== */
/* 隠している間は visibility:hidden も掛ける。opacity:0 だけだと中の「閉じる」が
   キーボードのタブ移動で拾えてしまうため。フェードアウトを待ってから効かせる。 */
.sgk{
  position:fixed;z-index:59;
  background:var(--paper);border:1px solid var(--line);
  opacity:0;pointer-events:none;visibility:hidden;
  transition:opacity .38s ease,translate .42s cubic-bezier(.4,0,.2,1),visibility 0s linear .42s;
}
body.sgk-l .sgk--l{visibility:visible;transition-delay:0s}
.sgk svg{width:100%;height:auto;display:block;overflow:hidden}

/* 閉じ方が一目で分かるように、記号ではなく言葉で書く（odaira 2026-08-11） */
.sgk__bar{
  display:flex;align-items:center;justify-content:space-between;gap:6px;
  padding:5px 5px 5px 10px;border-bottom:1px solid var(--line);
}
.sgk__ttl{font-family:var(--font-mono);font-size:9px;letter-spacing:.18em;
  color:var(--ink-3);text-transform:uppercase;white-space:nowrap}
.sgk__btns{display:flex;flex:0 0 auto}
.sgk__btn{
  border:0;background:none;padding:5px 7px;cursor:pointer;
  font-family:var(--font-sans);font-size:10.5px;letter-spacing:.06em;line-height:1.4;
  color:var(--ink-2);white-space:nowrap;
}
.sgk__btn:hover,.sgk__btn:focus-visible{color:var(--ink);text-decoration:underline}

/* 紙芝居：狭い画面では栞から呼び出して右下に立ち上がる。
   背景を敷かないと本文の文字が透過してぶつかる（SPで顕著）。

   2026-08-15：狭い画面にあった「小さい常駐（.sgk--s）」は廃止した。
   読みながら小さい絵が視界にいるより、「見たくなったら栞から呼ぶ」ほうが
   読書を邪魔しないというodaira判断。気づいてもらうのは下の peek が担う。 */
.sgk--l{
  right:var(--sgk-gap);bottom:calc(var(--sgk-gap) + 72px + 6px);
  width:min(430px,calc(100vw - var(--gutter) * 2));
  translate:0 14px;
}
body.sgk-l .sgk--l{opacity:1;pointer-events:auto;translate:0 0}

/* 栞：しまってある間だけ、画面の端から覗く */
.sgk-tab{
  position:fixed;z-index:59;
  right:0;bottom:calc(var(--sgk-gap) + 72px + 6px);
  writing-mode:vertical-rl;
  margin:0;padding:14px 7px;
  border:1px solid var(--line);border-right:0;
  background:var(--paper);color:var(--ink-2);
  font-family:var(--font-sans);font-size:11.5px;letter-spacing:.2em;line-height:1;
  cursor:pointer;
  translate:100% 0;opacity:0;pointer-events:none;visibility:hidden;
  transition:translate .42s cubic-bezier(.4,0,.2,1),opacity .3s ease,visibility 0s linear .42s;
}
body.sgk-stow .sgk-tab{translate:0 0;opacity:1;pointer-events:auto;visibility:visible;transition-delay:0s}
.sgk-tab:hover,.sgk-tab:focus-visible{color:var(--ink)}

/* --------------------------------------------------------------------------
   PC（1320px〜）：紙芝居を画面の左に、読んでいる間ずっと出しておく。
   本文カラムの外＝もともと何も無い余白なので、大きくても邪魔にならない。

   幅は必ず「余白の実寸」から出す。固定値にすると本文に食い込む。
   .prose は 754px 固定（max-width:calc(42em + 40px) / font-size 17px）なので
   文字の左端 = 50vw − 357px。左端24px＋余白28pxを引いて 50vw − 409px。
   1320px未満では250pxを切って絵が潰れるので、そこで小さい常駐に落とす。
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   栞のプルプル（2026-08-16 odaira指定）
   「そのページにきて、ちょっとスクロールしたら一回だけプルプル」。
   タップすると紙芝居が出てくることに気づいてもらうための合図。

   ⚠️ 以前は「紙芝居が64px覗いて引っ込む（peek）」だったが、出す条件を
      「localStorage に状態が無いこと」にしていたため、初回ロードの保存で
      条件が潰れ、**ブラウザごとに一生に1回しか出なかった**。
      いまは stickman.js 側で「ページを開くたび1回」に直してある。
   -------------------------------------------------------------------------- */
.sgk-tab{will-change:transform}
body.sgk-wiggle .sgk-tab{animation:sgkWiggle 1.15s cubic-bezier(.36,.07,.19,.97) both}
@keyframes sgkWiggle{
   0%  {translate:0 0}
   8%  {translate:-7px 0}
  18%  {translate:4px 0}
  28%  {translate:-5px 0}
  38%  {translate:3px 0}
  48%  {translate:-2px 0}
  58%  {translate:1px 0}
  70%,100%{translate:0 0}
}
/* 広い画面では栞が左端に出るので、揺れる向きを反転させる */
@media (min-width:1320px){
  @keyframes sgkWiggle{
     0%  {translate:0 0}
     8%  {translate:7px 0}
    18%  {translate:-4px 0}
    28%  {translate:5px 0}
    38%  {translate:-3px 0}
    48%  {translate:2px 0}
    58%  {translate:-1px 0}
    70%,100%{translate:0 0}
  }
}

@media (min-width:1320px){
  .sgk--l{
    left:24px;right:auto;
    top:50%;bottom:auto;transform:translateY(-50%);
    width:min(430px,calc(50vw - 409px));
    translate:-14px 0;
  }
  body.sgk-l .sgk--l{opacity:1;pointer-events:auto;translate:0 0;visibility:visible;transition-delay:0s}

  .sgk-tab{
    left:0;right:auto;top:50%;bottom:auto;transform:translateY(-50%);
    border:1px solid var(--line);border-left:0;
    translate:-100% 0;
  }
  body.sgk-stow .sgk-tab{translate:0 0}
}

/* 動きを減らす設定の人には出さない（静止画にする意味がないため） */
@media (prefers-reduced-motion:reduce){
  body.sgk-on{animation:none}
  .sgk,.sgk-tab{display:none !important}
  body.sgk-peek .sgk--l{animation:none;visibility:hidden}
}
@media print{.sgk,.sgk-tab{display:none}}

/* ==========================================================================
   中身（棒人間）── ここだけ差し替えれば別の絵に変わる
   ========================================================================== */
.sgk-ln{fill:none;stroke:var(--ink);stroke-width:3.6;stroke-linecap:round;stroke-linejoin:round}
.sgk-ln3{fill:none;stroke:var(--ink-3);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.sgk-tx{fill:var(--ink-3);stroke:none;font-family:var(--font-mono);font-size:9px;letter-spacing:.1em}
.sgk-fl{fill:var(--ink);stroke:none}

/* 回転の基準点。関節（肩・腰）は絵の座標で、拡縮は図形自身の中心で。 */
.sgk-pv{transform-box:view-box;transform-origin:60px 66px}
.sgk-pvs{transform-box:view-box;transform-origin:60px 46px}
.sgk-kv{transform-box:view-box;transform-origin:150px 92px}
.sgk-kvs{transform-box:view-box;transform-origin:150px 72px}
.sgk-own{transform-box:fill-box;transform-origin:50% 50%}

/* --------------------------------------------------------------------------
   一日ぶんの振り付け（--sgkp 0→1 が記事の頭から終わりに対応）
     0.00 眠っている → 0.13 起き上がる → 0.23 立つ → 0.32 のびをする
     0.36-0.64 歩く（日中）→ 0.66 スマホ → 0.78 手放す
     0.84 頭を冷やす → 0.88-1.00 横になって眠る
   小さい絵と紙芝居は、この振り付けを共有している（違うのは絵の情報量だけ）。
   -------------------------------------------------------------------------- */
.sgk-fig{
  --wake:clamp(0,(var(--sgkp) - .13) / .12,1);
  --sleep:clamp(0,(var(--sgkp) - .87) / .08,1);
  translate:0 calc((1 - var(--wake) + var(--sleep)) * var(--lie,20px));
}
/* 起きるときは 胴→脚 の順、横になるときは 脚→胴 の順。
   逆にすると「棒が倒れた」だけに見えて、人が寝転ぶ動きにならない。 */
.sgk-fig-body{
  --up:clamp(0,(var(--sgkp) - .02) / .11,1);
  --dn:clamp(0,(var(--sgkp) - .88) / .08,1);
  rotate:calc(-82deg + (var(--up) - var(--dn)) * 82deg);
}
.sgk-fig-legs{
  --up:clamp(0,(var(--sgkp) - .13) / .10,1);
  --dn:clamp(0,(var(--sgkp) - .86) / .08,1);
  rotate:calc(-82deg + (var(--up) - var(--dn)) * 82deg);
}

/* 歩行サイクル。sin() でスクロール量から合成する＝連番画像が要らない。
   窓の外では位相が 0 か 1440deg（sin 0）で止まるので、歩き始めと歩き終わりが
   自然に直立へ戻る。 */
.sgk-fig{--ph:calc(clamp(0,(var(--sgkp) - .36) / .28,1) * 1440deg)}
.sgk-fig-leg-a{rotate:calc(sin(var(--ph)) * 25deg)}
.sgk-fig-leg-b{rotate:calc(sin(calc(var(--ph) + 180deg)) * 25deg)}

/* 腕は「のび」＋「歩行」＋「スマホ」の3つを足し込む。
   左腕は時計回り・右腕は反時計回りで“ひらく”。符号を逆にすると胴に畳まれる。 */
.sgk-fig-arm{
  --st:calc(clamp(0,(var(--sgkp) - .24) / .08,1) - clamp(0,(var(--sgkp) - .32) / .06,1));
  --hold:calc(clamp(0,(var(--sgkp) - .60) / .06,1) - clamp(0,(var(--sgkp) - .74) / .06,1));
}
.sgk-fig-arm-l{rotate:calc(var(--st) * 62deg + sin(calc(var(--ph) + 180deg)) * 20deg)}
.sgk-fig-arm-r{rotate:calc(var(--st) * -62deg + sin(var(--ph)) * 20deg + var(--hold) * -38deg)}

.sgk-fig-phone{
  --t:calc(clamp(0,(var(--sgkp) - .60) / .06,1) - clamp(0,(var(--sgkp) - .74) / .05,1));
  --fall:clamp(0,(var(--sgkp) - .74) / .05,1);
  opacity:var(--t);
  translate:0 calc(var(--fall) * 30px);
  rotate:calc(var(--fall) * 40deg);
}
.sgk-fig-heat{
  --t:calc(clamp(0,(var(--sgkp) - .62) / .07,1) - clamp(0,(var(--sgkp) - .78) / .07,1));
  opacity:var(--t);scale:calc(.55 + var(--t) * .45);
}
.sgk-fig-cap{
  --t:clamp(0,(var(--sgkp) - .80) / .07,1);
  opacity:var(--t);translate:0 calc(-26px + var(--t) * 26px);
}
.sgk-fig-z{
  --t:clamp(0,(var(--sgkp) - var(--d)) / .06,1);
  opacity:calc(var(--t) * .85);
  translate:calc(var(--t) * 7px) calc(var(--t) * -10px);
}
.sgk-fig-sun{
  --t:calc(clamp(0,(var(--sgkp) - .22) / .10,1) - clamp(0,(var(--sgkp) - .60) / .08,1));
  opacity:calc(var(--t) * .9);
}
.sgk-fig-moon{--t:clamp(0,(var(--sgkp) - .62) / .08,1);opacity:calc(var(--t) * .9)}

/* 紙芝居（大）にだけ出るもの */
.sgk-k-scenery{translate:calc(clamp(0,(var(--sgkp) - .30) / .40,1) * -1160px) 0}
.sgk-k-futon{--t:clamp(0,(var(--sgkp) - .16) / .10,1);opacity:calc(1 - var(--t))}
.sgk-k-bed{--t:clamp(0,(var(--sgkp) - .82) / .08,1);opacity:var(--t)}
.sgk-k-dot{--t:clamp(0,(var(--sgkp) - var(--d)) / .035,1);opacity:var(--t);scale:var(--t)}
.sgk-k-savers{--t:calc(clamp(0,(var(--sgkp) - .20) / .05,1) - clamp(0,(var(--sgkp) - .40) / .06,1));opacity:var(--t)}
.sgk-k-time{--t:calc(clamp(0,(var(--sgkp) - var(--a)) / .04,1) - clamp(0,(var(--sgkp) - var(--b)) / .04,1));opacity:calc(var(--t) * .9)}

/* ==========================================================================
   中身その2 ── ホワイトボード紙芝居（epicurus-life）  2026-08-15
   --------------------------------------------------------------------------
   本解説系YouTubeの型を分解すると3つしかない。
     ① 上に章バー（いま何章か）
     ② 真ん中で線画が「描かれていく」
     ③ 描き終わってから短い一文が出る
   ①③はHTML、②はSVGの stroke-dashoffset。動画ファイルは使わない。

   全パスに pathLength="1" を振ってあるので、線の実長に関係なく
   stroke-dashoffset を 1→0 にすれば描画になる。長さを測る必要がない。
   ========================================================================== */

/* --- ① 章バー ------------------------------------------------------------ */
/* 高さは詰める。紙芝居が縦に伸びるほど本文の読める面積が減るので、
   全体で棒人間（約200px）と同じくらいに収める（odaira 2026-08-15）。 */
.wb__chap{
  position:relative;border-bottom:1px solid var(--line);
  background:var(--paper-2);
  height:1.6em;overflow:hidden;
}
.wb__chap b{
  position:absolute;inset:0;
  display:flex;align-items:center;gap:.5em;
  padding:0 10px;
  font-size:10.5px;line-height:1.3;font-weight:500;letter-spacing:.01em;
  color:var(--ink);white-space:nowrap;
  opacity:calc(var(--in) - var(--out));
}
.wb__chap i{
  flex:0 0 auto;font-style:normal;
  font-family:var(--font-mono);font-size:9.5px;color:var(--ink-3);
}

/* --- ② 舞台（SVG） ------------------------------------------------------- */
.wb__stage{background:var(--paper)}
.wb-sc{opacity:calc(var(--in) - var(--out))}

/* 章の出入り。--a=章の開始、--sp=章の長さ（どちらもインラインで持たせる）
   --t は章の中での進捗 0→1。子はこれを見て自分の窓を切る。

   ⚠️ 章バー・キャプション・マーカーは .wb-sc の「子」ではなく別の要素なので、
      この3行をそこにも配らないと --in / --out が未定義になる。
      未定義の custom property は 0 扱いではなく **その宣言ごと捨てられる** ので、
      opacity が既定の1に落ちて全章が同時に表示される（2026-08-15 に踏んだ）。 */
.wb-sc,.wb__chap b,.wb__cap span,.wb-pen{
  --t:clamp(0,(var(--sgkp) - var(--a)) / var(--sp),1);
  --in:clamp(0,(var(--sgkp) - var(--a) + .014) / .028,1);
  --out:clamp(0,(var(--sgkp) - var(--a) - var(--sp) + .014) / .028,1);
}

.wb-l,.wb-l2,.wb-l3{fill:none;stroke-linecap:round;stroke-linejoin:round}
.wb-l {stroke:var(--ink);  stroke-width:2.4}
.wb-l2{stroke:var(--ink-2);stroke-width:1.7}
.wb-l3{stroke:var(--ink-3);stroke-width:1.2}
.wb-dash{stroke-dasharray:.012 .012 !important;stroke-dashoffset:0 !important}

/* 描画の窓。--s（章内の開始）と --e（終わり）をずらして並べると、
   順番に描かれていくように見える。 */
.wb-d{
  --d:clamp(0,(var(--t) - var(--s)) / (var(--e) - var(--s)),1);
  stroke-dasharray:1;
  stroke-dashoffset:calc(1 - var(--d));
}
.wb-fade{--f:clamp(0,(var(--t) - var(--fs)) / .14,1);opacity:calc(1 - var(--f) * .88)}
.wb-late{--f:clamp(0,(var(--t) - var(--fs)) / .12,1);opacity:var(--f)}

/* マーカー。描いている線と同じパスを offset-path に持たせているので、
   線の先端を実際になぞる。--d は .wb-d の中で定義しているが、マーカーは
   線ではない（stroke-dasharray が要らない）ので、ここで別に立てる。 */
.wb-pen{
  --d:clamp(0,(var(--t) - var(--s)) / (var(--e) - var(--s)),1);
  offset-rotate:0deg;offset-distance:calc(var(--d) * 100%);
  opacity:calc(
    (clamp(0,var(--d) / .05,1) - clamp(0,(var(--d) - .90) / .10,1))
    * (var(--in) - var(--out))
  );
}
.wb-pen path{fill:var(--ink);stroke:none}
.wb-pen rect{fill:var(--paper);stroke:var(--ink);stroke-width:1.6}

.wb-tx{fill:var(--ink-2);stroke:none;font-family:var(--font-sans);font-size:9px}
.wb-tx-s{fill:var(--ink-3);stroke:none;font-family:var(--font-mono);font-size:7.5px;letter-spacing:.08em}

/* --- ③ キャプション ------------------------------------------------------ */
.wb__cap{
  position:relative;border-top:1px solid var(--line);
  height:1.8em;overflow:hidden;
}
.wb__cap span{
  position:absolute;inset:0;
  display:flex;align-items:center;
  padding:0 11px;
  font-size:11px;line-height:1.45;color:var(--ink-2);white-space:nowrap;
  /* 絵を描き終わってから出す。先に文字が出ると絵を見る意味がなくなる */
  opacity:calc(clamp(0,(var(--t) - .62) / .12,1) * (var(--in) - var(--out)));
}
