schema_version: 1

# PLATE 03「相手役・登場人数」の再利用プリセット。
# 全候補は成人年齢を明記する。体格と身だしなみは別軸にして、
# 「大柄だから不潔」等を固定で結び付けない。
profiles:
  faceless_default:
    label: 顔なしの相手役
    note: 顔を画面外にして、女性キャラと衣装を安定させやすい既定
    traits:
      age: adult_30
      build: average
      face: ordinary
      grooming: clean
      hair: short_dark
      clothes: none
      role: none
    face_visibility: hidden

  handsome_25:
    label: 若い成人のイケメン
    note: 25歳前後・清潔感・引き締まった体格
    traits:
      age: adult_25
      build: athletic
      face: handsome
      grooming: clean
      hair: short_dark
      clothes: casual
      role: lover
    face_visibility: visible

  clean_adult:
    label: 清潔感のある成人男性
    note: 30代・標準体型・落ち着いた外見
    traits:
      age: adult_35
      build: average
      face: ordinary
      grooming: clean
      hair: short_dark
      clothes: casual
      role: acquaintance
    face_visibility: partial

  muscular_adult:
    label: 筋肉質な成人男性
    note: 30代・筋肉質・短髪
    traits:
      age: adult_35
      build: muscular
      face: rugged
      grooming: clean
      hair: short_dark
      clothes: none
      role: acquaintance
    face_visibility: partial

  refined_middle:
    label: 渋い中年男性
    note: 48歳前後・整った身だしなみ・白髪混じり
    traits:
      age: adult_48
      build: average
      face: refined
      grooming: clean
      hair: graying
      clothes: suit
      role: boss
    face_visibility: visible

  rugged_heavy_middle:
    label: 大柄で無精な中年男性
    note: 48歳前後・大柄・無精ひげ・くたびれた外見
    traits:
      age: adult_48
      build: heavyset
      face: rugged
      grooming: unkempt
      hair: thinning
      clothes: workwear
      role: neighbor
    face_visibility: visible

  chubby_middle:
    label: 小太りの中年男性
    note: 48歳前後・小太り・普通の顔立ち・無精ひげ
    traits:
      age: adult_48
      build: chubby
      face: ordinary
      grooming: stubble
      hair: short_dark
      clothes: casual
      role: neighbor
    face_visibility: visible

  overweight_middle:
    label: 太った中年男性（親父系）
    note: 50代・太った体格・強面・薄毛
    traits:
      age: adult_58
      build: overweight
      face: rugged
      grooming: stubble
      hair: thinning
      clothes: casual
      role: neighbor
    face_visibility: visible

  obese_unkempt_middle:
    label: 肥満体で無精な中年男性
    note: 50代・肥満体・無精ひげ・くたびれた外見
    traits:
      age: adult_58
      build: obese
      face: rugged
      grooming: unkempt
      hair: thinning
      clothes: workwear
      role: neighbor
    face_visibility: visible

  bald_sweaty_middle:
    label: 汗まみれのハゲ中年男性
    note: 58歳前後・肥満・ハゲ・大量発汗・強い紅潮（隣人NTR系寄り）
    traits:
      age: adult_58
      build: overweight
      face: ordinary
      grooming: stubble
      hair: bald
      clothes: casual
      role: neighbor
      sweat_level: heavy
      blush_level: flushed
    face_visibility: visible

  plump_gentle_middle:
    label: 善良なぽっちゃり中年男性
    note: 45歳前後・小太り・清潔・穏やかな雰囲気（善良系・BBM寄り）
    traits:
      age: adult_48
      build: chubby
      face: ordinary
      grooming: clean
      hair: short_dark
      clothes: casual
      role: acquaintance
      sweat_level: mild
      blush_level: blushing
    face_visibility: visible

face_visibility:
  hidden:
    label: 顔を隠す
    note: 安定・既定
    # ★2026-08-06 修正: 旧 "faceless male, male face out of frame" は**両立しない2つの
    #   描き方**を同時に指示していた。Danbooru の定義では `faceless male`(顔はあるが
    #   目鼻が描かれない・影)は「**頭が完全に枠外の場合には付かない**」。綱引きになる。
    #   → 枚数の多い `faceless male`(50,493枚)一本にする。
    #   ※「頭を枠の外へ出す」は別の描き方(`head out of frame` 28,725枚)。
    #     必要になったら**別の選択肢として足す**(既存を置き換えない)。
    prompt: faceless male, faceless
  partial:
    label: 一部だけ見せる
    note: 顔の一部を構図外・影・横顔にする
    # ★2026-08-06 タグ化: `head out of frame`(28,725枚)が実在タグ。
    #   旧 "male face partly out of frame" は英文で学習されていない。
    prompt: partially obscured male face, head out of frame
  visible:
    label: 顔を見せる
    note: 同一人物の維持は文章指定だけでは難しい
    prompt: male focus, detailed male face

axes:
  age:
    label: 年代
    options:
      adult_25: {label: 20代後半, prompt: "mature male, 25 years old"}
      adult_30: {label: 30歳前後, prompt: "mature male, 30 years old"}
      adult_35: {label: 30〜40代, prompt: "mature male, 35 years old"}
      adult_48: {label: 40〜50代, prompt: "mature male, 48 years old"}
      adult_58: {label: 50代以上, prompt: "mature male, old man, 58 years old"}

  build:
    label: 体格
    options:
      slim: {label: 細身, prompt: "skinny, slim male build"}
      average: {label: 標準, prompt: "mature male, average male build"}
      athletic: {label: 引き締まった, prompt: "muscular male, athletic male build"}
      # ★2026-08-10(段②): `broad shoulders`(1,942枚)は印が無いので女性へ回る。落とした。
      #   `muscular man` は 0枚 = 存在しない語だった → 実在タグ `muscular male`(137,749)へ。
      #   弱くなるどころか、**印つきのまま桁違いに強くなる**。
      muscular: {label: 筋肉質, prompt: "muscular male"}
      heavyset: {label: 大柄, prompt: "fat man, heavyset man, large male build"}
      # ★2026-08-06 タグ化: Illustrious は Danbooru のタグで学習している。英文で書くと
      #   「にじみ(bleeding)」を起こすか無視される。実在タグと枚数を照合して書き直した
      #   (docs/research/46-danbooru-undress-tag-matrix.md)。
      #   使った実在タグ: fat man 14,345 / fat 19,342 / obese 1,138 / plump 43,302 / big belly 8,185
      #   ★存在しなかった語: chubby(0) / huge belly(0) / pot belly(0) → 使わない
      #   ★`fat man` は1語で「太った男」を指すので、女性側の打ち消しと語がぶつからない。
      # ★★2026-08-10(段②)ここから体格を作り直した。**印の無い語を全部落とした。**
      #   体の形だけは2回目(顔の塗り直し)では直せない(1回目で輪郭が決まる)ので、
      #   1回目に残すしかない。だから**残す語は男性の印つきだけ**にする。
      #   実測(2026-08-10・Danbooru):
      #     印つき(安全) muscular_male 137,749 / fat_man 14,394 / short_male 963 / tall_male 678
      #     印なし(染み出す) plump 43,398 / fat 19,400 / skinny 11,222 / big_belly 8,203 /
      #                      broad_shoulders 1,942 / obese 1,141
      #     ★そもそも存在しない語(0枚) = 書いても効かない:
      #       muscular man / plump man / soft belly / stocky man / heavyset /
      #       large male build / slim male build / athletic male build /
      #       average male build / thick body / chubby / flabby
      #   ★`fat man` 1語だけだった頃は染み出しが出ていなかった(ユーザー証言+実測)。
      #     太さの段は **fat man の重みだけ**で分ける(語を増やさない)。
      #   ★0枚の語(plump man など)も、字としては plump + man に分かれて効くので残す。
      #     「man」が付いているぶん、裸の plump より女性へ回りにくい。
      chubby: {label: 小太り, prompt: "fat man, plump man"}
      overweight: {label: 太った, prompt: "fat man"}
      obese: {label: 肥満体, prompt: "(fat man:1.15), obese man"}
      # ★2026-08-05 追加(ユーザー要望): 肥満体より上を2つ。方向を分けてある。
      #   超肥満 = もっと太い / 巨漢 = 太いだけでなく大きい(背丈と体積)。
      #   どちらも _HEAVY_BUILDS(pipeline/partner_cast.py)に入れて、
      #   女性側への体型の染み出しを打ち消す。足しただけだと主役まで太る。
      # ★2026-08-06 タグ化。旧 "morbidly obese man, extremely fat man, enormous belly, huge gut,
      #   thick rolls of fat" は英文で、しかも後ろ3つが anti_body_bleed と正面衝突していた。
      #   ★力比べは今も不利: muscular male 137,397 枚 vs fat man 14,345 枚 = 約9.6対1。
      #     タグを正しくしても勝ちきれない前提で扱う。最後は §10(男性用LoRA)で解く。
      super_obese: {label: 超肥満, prompt: "(fat man:1.3), obese man"}
      # towering は塔を呼びうるので使わない(2026-08-05・crown と同じ型の用心)。
      # ★2026-08-10(段②): `broad thick frame` `huge body` は印が無いので落とした
      #   (女性まで大きくなる。anti_size_bleed で押さえていたが、書かない方が確実)。
      giant_heavy: {label: 巨漢, prompt: "fat man, giant heavy man, very tall and massive man"}

      # ★2026-08-08 追加(ユーザー判断)。**体型と身長を1つにまとめた選択肢**。
      #   なぜ: 「体格 × 体つき × 身長」を掛け算する作りにしたら、
      #     ・語が7対1のように偏り、**矛盾する組み合わせ**が作れた(超肥満×小さい)
      #     ・男性の語が増えるほど**女性側へ溢れた**(お腹・髪の色)
      #   → 1本にまとめれば矛盾は物理的に作れず、語も減る。体つき・身長の軸は削除した。
      #   ★実測: fat_man 14,394 / plump 43,394 / muscular_male 137,747 / skinny 11,222 /
      #           short_male 963 / tall_male 678 / height_difference 45,922 / big_belly 8,200
      #     ★存在しない語: stocky(0) / thin(0) / slender(0) / lanky(0) / scrawny(0) → 使わない
      #   ★身長の単体タグは千枚未満で弱い。主力は height difference(4.5万枚)。
      #     それでも効きは弱い(実測済み)。**体型のほうが確実に効く**前提で組んである。
      # ★2026-08-10(段②): 印の無い語(obese / big belly / soft belly / thick body /
      #   broad shoulders)を落とした。身長の語は残す = `short male` `tall male` は印つき、
      #   `height difference` と「the man is shorter than the woman」は**2人の関係**を
      #   書いた語なので、片方へ染み出しようがない(むしろ誰が誰かを教える語)。
      short_obese: {label: ずんぐりした小柄な超肥満, prompt: "(fat man:1.3), obese man, short male, height difference, the man is shorter than the woman"}
      short_chubby: {label: ぽっちゃりした小柄な男, prompt: "fat man, plump man, short male, height difference, the man is shorter than the woman"}
      tall_fat: {label: 大柄で太った男, prompt: "fat man, tall male, height difference, the man is taller than the woman"}
      tall_muscular: {label: 大柄で筋肉質な男, prompt: "muscular male, tall male, height difference, the man is taller than the woman"}
      # ★2026-08-11 修正(ユーザー実画像で発見: ガリガリを選んでも男性の腹が出たまま)。
      #   原因: 2語のうち `thin male build` が **0枚 = 存在しない語**で、実質 `skinny` 1語だけ。
      #         それでモデルの既定(中年男性=ずんぐり)に負けていた。
      #   直し方: 効かない語を落とし、**残る実在タグの重みを上げる**(語を増やさない)。
      #   ★`skinny`(11,238枚)には性別の印が無い。理屈では女性へ回るが、
      #     ・これを消すと使える語が1つも無くなる(skinny_male / thin_male / scrawny / gaunt は全部0枚)
      #     ・主役の女性はもともと `very slender` なので、痩せ方向の染み出しは害が小さい
      #     → 残す。実画像で「女性が痩せすぎる」が出たら重みを下げる。
      #   ★これでも足りなければ、太った男と同じ結論 = 言葉では解けない → 男性用LoRA。
      short_skinny: {label: ガリガリで小柄な男, prompt: "(skinny:1.3), short male, height difference, the man is shorter than the woman"}
      tall_skinny: {label: ガリガリで大柄な男, prompt: "(skinny:1.3), tall male, height difference, the man is taller than the woman"}

  # ★2026-08-08 新設(ユーザー要望「男性の肌の色も女性と同じように選びたい」)。
  #   実測: dark_skin 399,799 / dark-skinned_male 131,754 / pale_skin 72,354 / tan 77,888
  #         ★存在しない語: tanned(0) / light_skin(0) / sun_tanned_skin(0) → 使わない
  #   ★★ここが今日いちばん危ない軸。dark_skin(40万枚)は**誰の肌か**を書いていないので、
  #     そのまま置くと**女性の肌まで褐色になる**(髪の色で同じ事故を起こしている)。
  #     → 男性の印が付く `dark-skinned male` を主力にし、女性側への打ち消しも足す
  #       (_partner_negative で自動)。`pale skin` にも男性の言い回しを添える。
  skin:
    label: 肌の色
    # ★2026-08-10(段①): 1回目には出さない。**表面の語**なので染み出しの本体。
    #   dark_skin は 399,799枚で「誰の肌か」を書いていない。打ち消しで押さえるより、
    #   1回目に書かない方が確実(打ち消しは綱引きの一票にすぎない)。
    #   値は保持され、2回目(顔の塗り直し)へ渡る。
    #   ★注意: 顔の塗り直しは**顔まわりしか変えない**ので、段③④が入るまでは
    #     肌の色は絵に出ない(男性は既定の肌になる)。段④の後も体は既定のままで、
    #     顔だけ色が付く可能性がある。実画像で見て、ちぐはぐなら
    #     この `pass1: false` を消せば元に戻る(コードは触らなくてよい)。
    pass1: false
    options:
      none: {label: 指定なし, prompt: ""}
      pale: {label: 色白,   prompt: "pale skin"}
      normal: {label: 標準, prompt: ""}
      # ★2026-08-08 修正(ユーザー実測「日焼けしていない」)。`tanned` は Danbooru で **0枚**
      #   だった(存在しない語を書いていた)。実在するのは dark-skinned male 131,754 枚。
      #   日焼けと褐色は**重みで分ける**(どちらも男性の印つき)。
      tan:  {label: 日焼け, prompt: "tan, (dark-skinned male:1.2)"}
      dark: {label: 褐色,   prompt: "dark skin, (dark-skinned male:1.5)"}

  face:
    label: 顔立ち
    # ★2026-08-10(段①): 1回目には出さない。顔は2回目(顔の塗り直し)の担当。
    #   ★★戻すときの目印: 2026-08-07 に顔立ちの語を1回目から落としたところ、
    #     **女性に男性器が生えた(ふたなり化 26%)**。「顔の語を全部落とすと男性が
    #     体だけの何かになり、主役の女性へ吸い寄せられる」と見立てた経緯がある。
    #     今回また落とすので、**刷ったらまず ふたなり化 が出ていないか見る**。
    #     当時と違い、いまは男性が出る場面すべてに anti_futanari が入っている
    #     (genital_axis.futanari_negative・2026-08-07 深夜に追加)。
    #     それでも出るなら、この `pass1: false` を消せば元に戻る。
    pass1: false
    options:
      handsome: {label: イケメン, prompt: "bishounen, handsome man, attractive male face"}
      ordinary: {label: 普通, prompt: "mature male, ordinary-looking adult man"}
      rugged: {label: 強面, prompt: "rugged adult male face"}
      refined: {label: 上品, prompt: "refined mature male face"}
      # ★2026-08-05 追加(ユーザー要望)。NTR・格差ものの定番なので選べるようにする。
      #   打ち消し(anti_ikemen)に handsome が入っているので、むしろ追い風になる。
      #   ※ anti_unclean(ugly を含む)は定義されているだけで**どこからも使われていない**ため衝突しない。
      # ★2026-08-06 修正: `ugly man` は Danbooru で **0枚** = 学習されていない語だった
      #   (書いてあるのに絵に効いていなかった)。実在するのは `ugly bastard` 3,493枚で、
      #   これがこのジャンルの「親父」を指す本来のタグ。先頭に置き、旧い英文は保険で残す。
      #   ★注意: `ugly bastard` は顔だけでなく「太った・薄毛・年配」まで含む型なので、
      #     体格・髪の選択と引っ張り合うことがある。A/B で見ること。
      ugly: {label: ブサイク, prompt: "ugly bastard, unattractive adult male face"}

  grooming:
    label: 身だしなみ
    # ★2026-08-10(段①): 1回目には出さない。ひげ・清潔感はすべて顔まわりの話で、
    #   2回目(顔の塗り直し)で描ける。`unkempt appearance`(くたびれた外見)は
    #   「誰の」が付いていないので、1回目に置くと女性側へ回る。
    pass1: false
    options:
      clean: {label: 清潔, prompt: "male focus, clean-shaven, well-groomed"}
      stubble: {label: 無精ひげ, prompt: "stubble"}
      unkempt: {label: くたびれた外見, prompt: "stubble, facial hair, unkempt appearance"}

  hair:
    label: 髪
    options:
      short_dark: {label: 短い黒髪, prompt: "short dark male hair"}
      medium_dark: {label: 長めの黒髪, prompt: "medium-length dark male hair"}
      graying: {label: 白髪混じり, prompt: "short graying male hair"}
      # ★2026-08-18 実測: `thinning male hair` は male を挟んでタグが壊れている(0枚)。
      #   balding(1,835枚)が「薄い」を表す唯一の実在タグなので、これを土台に説明文を足す。
      thinning: {label: 薄毛, prompt: "balding, thinning hair"}
      # ★2026-08-18 実測で置換: receding_hairline は **367枚**で絵に出ない。
      #   balding(1,835枚)も弱いが「部分脱毛」の意味を持つ唯一の語なので、bald と一緒に置く。
      balding: {label: 部分脱毛, prompt: "bald, balding"}
      # ★2026-08-18 実測で置換: bald_head と no_hair は **どちらも0枚**だった。bald は 23,148枚。
      bald: {label: ハゲ, prompt: "bald"}
      # ★2026-08-05 追加(ユーザー要望)。既存6つはそのまま残す。
      # ★2026-08-18 実測: comb-over は 191枚 / receding_hairline は 367枚。どちらもタグとしては効かない。
      #   土台に bald(23,148枚)を置いて、髪の描写は説明文で足す。
      barcode: {label: バーコード頭, prompt: "bald, few thin strands of hair combed across a balding scalp"}
      # ★2026-08-05 修正(ユーザーが実画像で発見): 最初 "bald crown with white hair..." と書いた。
      #   英語の crown は「頭のてっぺん」の意味だが、**絵のAIは王冠として描く**。
      #   実測: 主役の女性の頭に金の王冠が乗った(相手役の語なのに女性側へ出た=染み出し)。
      #   絵のAIに渡す語は「英語として正しいか」ではなく「物として何を呼ぶか」で選ぶ。
      # ★2026-08-18 実測で置換: white_hair_fringe は 0枚 / bald_head も 0枚。
      #   実在の組み合わせ bald×white_hair は 1,774枚。
      bald_white: {label: 白髪のハゲ, prompt: "bald, white hair, white hair on the sides of the head"}
      # ★2026-08-05 修正: 最初 "full head of white hair" と書いたが、相手役の共通の打ち消し
      #   (anti_ikemen)に **"full head of hair"** が入っており正面衝突していた。
      # ★2026-08-18 実測で置換: `gray hair`(米綴り)は **0枚**。Danbooru は `grey_hair`(1,012,935枚)。
      #   `short white male hair` は male を挟んでタグが壊れている(実在は white_hair 1,027,522)。
      white: {label: 白髪, prompt: "white hair, grey hair, short hair"}
      # ★2026-08-07 深夜 追加(ユーザー提案「禿げ方をもう少しはっきりさせる」)。
      #   顔の塗り直しを止めたので、**言葉だけで髪型をそろえる**必要がある。
      #   実在タグと枚数(実測): bald 22,962 / shaved_head 803 / buzz_cut 4,443 /
      #                        very_short_hair 36,768 / balding 1,815 / undercut 22,378
      #   ★`receding hairline` は 366枚 = 少なすぎて絵に出ない。単独では使わない。
      #   ★既存の6段は1つも変えない(いま気に入っている出方を動かさないため)。
      # ★2026-08-18 実測で置換: completely_bald / smooth_scalp は 0枚、shaved_head は 808枚。
      #   残るのは bald(23,148枚)だけ。「no hair at all」は説明文として残す(強調のため)。
      skinhead:   {label: スキンヘッド, prompt: "bald, no hair at all", no_color: true}   # 髪が無いので色は捨てる
      # ★★2026-08-18 修正(ユーザー報告「男性の頭がかなりブレる」)。実測で原因が判明:
      #   旧: bald, balding, hair only on the sides of the head, bald on top, very short hair on the sides
      #   `very short hair` は `short_hair`(**3,091,125枚**)として効き、`bald`(23,148枚)と
      #   **133倍の綱引き**になっていた。さらに `balding`(1,835枚)は
      #   `bald`との同時出現が **93枚**＝事実上あり得ない組み合わせで、何もせず他の語を薄めるだけだった。
      #   → `balding` を外し、実在する組み合わせ **bald×short_hair(6,394枚)** に寄せる。
      #     `short hair` は重みを下げて bald が勝つようにする(3M 対 2.3万 のため)。
      #   ★これは実画像で未確認。刷って見比べること([[prompt-is-a-tug-of-war]])。
      bald_sides: {label: 側頭部だけ髪,
                   prompt: "bald, bald on top, (short hair on the sides of the head:0.7)",
                   # ★2026-08-08(ユーザー実測「白髪混じりが出ない」)。
                   #   髪型の語が5つ・色が1つで、しかも髪の面積が小さいため色が乗らなかった。
                   #   → 色を選んだときは、**髪型の文の中へ色を織り込む**。
                   with_color: "bald, bald on top, ({color} short hair on the sides of the head:0.7), {color} hair"}
      # ★2026-08-18 実測: shaved_sides は 0枚。buzz_cut 4,460 / very_short_hair 37,334 は生きている。
      buzz:       {label: 丸刈り, prompt: "buzz cut, very short hair",
                   with_color: "{color} buzz cut, very short {color} hair, {color} hair"}

  # ★2026-08-07 深夜 新設(ユーザー提案)。顔の塗り直しを止めたぶん、
  #   髪の「色」も言葉で決められるようにして、1枚ごとのブレを減らす。
  #   実在タグ(実測): black_hair 2,155,620 / grey_hair 1,006,311 /
  #                   white_hair 1,020,334 / brown_hair 2,051,402
  #   ★`salt and pepper hair` は **0枚** = 使わない(白髪混じりは grey_hair で表す)。
  #   ★既定は「指定なし」= 何も足さない。選ばなければ今までの出方は1文字も変わらない。
  #   ★スキンヘッドを選んだときは、髪の色を選んでも意味が無い(髪が無いので)。
  hair_color:
    label: 髪の色
    # ★2026-08-10(段①): 1回目には出さない。**今日いちばん実害が出た軸**。
    #   `black hair` は 2,155,620枚。しかも髪型の文へ織り込むと1回目に3回入り、
    #   女性の `blonde hair` 1回に勝って**女性の髪が黒くなっていた**(HANDOFF §2)。
    #   打ち消し(woman with black hair)で押さえようとしたが、2,155,620枚 対 打ち消し1つでは
    #   綱引きに勝てない。→ **1回目に書かない**のが唯一の確実な直し方。
    #   髪は顔まわりなので、2回目(顔の塗り直し)で描ける。
    #   ★1回目に出さないので、女性側への打ち消しも自動で消える(pipeline/partner_cast.py が
    #     「1回目に実際に書いた語」から鏡写しを作るため)。片方だけ残る事故を防いである。
    pass1: false
    options:
      # ★2026-08-07 深夜 修正(ユーザーが30枚で発見: 女性の髪の色が何枚か変わった)。
      #   最初 `grey hair` のように**性別の印を付けずに**書いてしまった。
      #   grey_hair は 1,006,311枚 / black_hair 2,155,620枚 の巨大タグで、
      #   「誰の髪か」を書いていないので**女性側にも掛かる**。
      #   anti_body_bleed で今日学んだこと(性別の付いていない語を置かない)をそのまま踏んだ。
      #   → 既存の髪の軸と同じ書き方(`short dark male hair`)に合わせ、**male を必ず入れる**。
      #     さらに、女性側へ回らないよう打ち消しも足す(_partner_negative)。
      # ★2026-08-08 再修正(ユーザー実測「髪の色が効いていない」)。
      #   昨夜「女性の髪が変わる」を直すとき `grey male hair` のように male を挟んだが、
      #   **それでタグを壊していた**。実在するのは `grey_hair`(1,006,311枚)で、
      #   `grey male hair` という語は存在しない。**弱いのではなく、無い語にしていた**。
      #   → 実在タグに戻し、女性側は**打ち消しで守る**(服で成功しているやり方と同じ)。
      none:  {label: 指定なし, prompt: ""}
      black: {label: 黒,       prompt: "black hair", word: black}
      grey:  {label: 白髪混じり, prompt: "grey hair", word: grey}
      white: {label: 白,       prompt: "white hair", word: white}
      brown: {label: 茶,       prompt: "brown hair", word: brown}

  clothes:
    label: 服装
    options:
      # ★2026-08-06 作り直し(ユーザー実測「男性が女性と同じ白T+グレー短パンになる」)。
      #   旧 `adult men's casual clothes` は**何色の何かを一言も書いていない**。
      #   一方で女性は `white t-shirt, gray shorts` と具体的。同じ1文の中で具体的な方が
      #   両方に塗られる = 染み出し。Civitai の解説どおり「2人の差が小さいほど混ざる」。
      #   → 男性側にも**具体的な衣類タグ + 色**を持たせ、女性の白・グレーと必ずずらす。
      #   使った実在タグ: shirt 148,733+ / suit 104,999 / necktie 649,031 / overalls 32,111 /
      #                   pants 689,333 / track suit 14,242 / male underwear 22,035
      #   ★存在しなかった語: work uniform(0) / khaki pants(0) → 使わない
      #   ★色は**女性の衣装が使っていない色**から選ぶ。実測(2026-08-06)で女性側6衣装が
      #     使っているのは white / cream / navy / red / blue の5色だったので、
      #     男性は olive / brown / black / gray から選ぶ。同じ服+同じ色が最悪の組み合わせ。
      #     (最初 navy polo shirt にしたら、制服ブレザーの navy blazer と衝突して検査に落ちた)
      # ★★2026-08-10(段①): 1回目は **pass1_prompt(色を抜いた文)** を使う。
      #   なぜ軸まるごと(pass1: false)にしないか:
      #     服は**顔まわりの外**。2回目(顔の塗り直し)はマスクの内側しか変えないので、
      #     1回目で服を書かないと**二度と戻せない**(男性が既定の服・裸になる)。
      #     一方、実害が出たのは**色**だった(女性が緑ポロ+茶ズボンになった。HANDOFF §3-4)。
      #     → 服の形は1回目に残し、**色だけ**を2回目へ回す。
      #   ★色なし語の枚数は実測(2026-08-10): polo shirt 3,806 / pants 691,304 /
      #     business suit 7,947 / necktie 650,439 / overalls 32,194 / track suit 14,272 /
      #     male underwear 22,080 / briefs 3,356
      #     ★存在しない語: work clothes(0) / tracksuit(0) → 1回目の文からは外した
      #       (色つきの文の方には元のまま残してある。既存の出方を勝手に変えないため)
      #   ★女性側への鏡写しの打ち消しも、この pass1_prompt から自動で作られる
      #     (`(woman in polo shirt:1.3)` のように、必ず「女性」と明記した語になる)。
      none: {label: 指定なし, prompt: ""}
      casual: {label: 私服, prompt: "polo shirt, brown pants, olive polo shirt",
               pass1_prompt: "polo shirt, pants"}
      suit: {label: スーツ, prompt: "black suit, necktie, business suit",
             pass1_prompt: "business suit, necktie"}
      workwear: {label: 作業着, prompt: "overalls, olive overalls, brown work clothes",
                 pass1_prompt: "overalls"}
      # ★2026-08-06 追加(選択肢は減らさず足すだけ)。既存3つの出方は1文字も変えない。
      jersey: {label: ジャージ, prompt: "track suit, grey track suit",
               pass1_prompt: "track suit"}
      # ★★2026-08-11 二度目の修正(ユーザーが350枚で発見: ぽっちゃりが反映されない)。
      #   午前に「上半身が空欄でシャツを着てしまう」を直すため `topless male` を足したが、
      #   **これが体格を打ち消していた**。実測(Danbooru):
      #       topless_male 57,178枚 のうち muscular 47.9% / muscular male 43.8% /
      #       pectorals 42.1% / abs 38.6% / bara 31.2% ── 対して **fat man はわずか 1.4%**
      #   つまり「上半身裸」ではなく**筋肉質な男の絵を呼ぶ語**で、fat man(14,416枚)と
      #   真っ向からぶつかり、しかも枚数で4倍。ぽっちゃりが勝てるはずがなかった。
      #   ★直し方: 上半身のことは**positive に書かず、男性側の打ち消しで表す**。
      #     「シャツを着せない」を男性と明記して打ち消せば、女性の白Tシャツは消えない
      #     (指輪・服で成功している型)。→ negative_defaults.anti_male_shirt
      #   ★教訓: 空欄を埋めるために語を足すときも、その語が**他に何を連れてくるか**を測る。
      underwear: {label: 下着, prompt: "briefs, grey briefs",
                  pass1_prompt: "male underwear, briefs",
                  counter: anti_male_shirt}

  role:
    label: 役柄
    options:
      none: {label: 指定なし, prompt: ""}
      husband: {label: 夫, prompt: "husband"}
      lover: {label: 恋人, prompt: "adult boyfriend"}
      neighbor: {label: 隣人, prompt: "adult male neighbor"}
      boss: {label: 上司, prompt: "adult male boss"}
      acquaintance: {label: 知人, prompt: "adult male acquaintance"}

  sweat_level:
    label: 発汗
    # ★★2026-08-11 作り直し(ユーザーの実画像で「全身びしょ濡れ」を確認 → 原因を実測)。
    #   原因: `sweat` は **756,147枚**。この文章の中で桁が2つ大きい巨大タグで、
    #         しかも**性別の印が無い**。相手役が出る場面 100枚中 79枚に入っていたので、
    #         男性だけでなく**絵ぜんぶ(主役の女性も背景も)が濡れていた**。
    #         2026-08-07 に `hetero`(785,370枚)を保険で入れて画風を壊したのと同じ桁。
    #   ★実測(2026-08-11・過去8run): 明るさ 181〜189 / ほぼ真っ白な画素 17.5〜21.9%。
    #     ずっとこの値なので「最近悪化した」のではなく**最初からこうだった**。
    #   直し方(語を増やさない):
    #     ・軽度 … `sweat` の重みを下げて桁の暴力をやわらげる。0枚の言い回しは捨てる
    #     ・大量 … `sweaty`(★0枚=存在しない語)を捨て、実在タグに置き換える
    #   ★実測: sweat 756,147 / sweatdrop 322,562 / flying_sweatdrops 125,828
    #     ★存在しない語: sweaty(0) / male_sweat(0) / sweaty_forehead(0) /
    #       forehead_sweat(0) / dripping_sweat(268=少なすぎ) → 使わない
    #   ★「なし」を選べば1文字も出ない(今までどおり)。濡れが嫌なら「なし」が確実。
    options:
      none: {label: なし, prompt: ""}
      mild: {label: 軽度, prompt: "(sweat:0.75)"}
      heavy: {label: 大量, prompt: "sweat, flying sweatdrops"}

  blush_level:
    label: 紅潮
    options:
      none: {label: なし, prompt: ""}
      blushing: {label: 頬・鼻筋が赤, prompt: "blush, nose blush"}
      flushed: {label: 顔全体が赤, prompt: "full-face blush, blush, heavy breathing"}

  # ── 股間まわり(2026-08-07 追加・ユーザー要望)────────────────────────────
  #   ★他の軸と決定的に違う点: **場面によって出してはいけない**。
  #     男性が出るカード40枚のうち4枚(肩に手/背後から抱擁/引き寄せられる/翌朝・寄り添い)は
  #     股間が画面に無い。そこへ大きさの語を足すと、着衣の抱擁に男性器が描かれる。
  #     → `scope: genital` を付けた軸は resolve_partner の共通promptには入れず、
  #       pipeline/partner_cast.py が**カードごとに**出し分ける。
  #   ★枚数は Danbooru の tags API で実測(2026-08-07)。推測では書かない。
  #     方法は docs/research/46-danbooru-undress-tag-matrix.md と同じ。
  genital_size:
    label: 大きさ
    scope: genital
    # 実測枚数: small_penis 6,670 / (無指定=penis 584,100) / large_penis 45,262 /
    #           huge_penis 16,491 / gigantic_penis 2,059
    # ★小さい方向は不利。small 6,670 に対し large+huge+gigantic = 63,812 で **約1:9.6**。
    #   これは「太った男」で勝ちきれなかった時の比率(muscular_male 137,397 : fat_man 14,345
    #   = 9.6:1)とほぼ同じ。→ 小さい2段には打ち消し(anti_large_penis)を付けるが、
    #   **打ち消しは綱引きの一票**であって命令ではない。実画像で確かめること。
    options:
      # ★2026-08-07 夜 いったん重みを 1.5 へ上げたが、**同じ日のうちに元へ戻した**。
      #   理由: ユーザーの言葉「小さいで指定した今までのものが、私としては理想の大きさ。
      #   それより小さくしろという話ではない」。**今の出方が正解**なので動かしてはいけない。
      #   ★ここを触ると、ユーザーが気に入っている絵の大きさが変わる。将来もし
      #     「もっと小さく」と言われたときだけ、重みを上げるか counter: anti_large_penis を足す。
      #     (anti_large_penis の定義は残してあるが、いまはどこからも使っていない)
      # ★2026-08-10 追加: counter を付けた(prompt は1文字も変えていない = 大きさは今のまま)。
      #   `small penis` が呼び込む「男の娘」の絵を打ち消す(理由は anti_small_penis_genre)。
      very_small: {label: かなり小さい, prompt: "(small penis:1.3)", counter: anti_small_penis_genre}
      small:      {label: 小さい,       prompt: "small penis",       counter: anti_small_penis_genre}
      average:    {label: 標準,         prompt: ""}
      large:      {label: 大きい,       prompt: "large penis"}
      # さらに上が要るときは gigantic_penis(2,059)を**足す**(この段を置き換えない)。
      very_large: {label: かなり大きい, prompt: "huge penis"}

  erection:
    label: 勃起
    scope: genital
    # 実測枚数: flaccid 7,721 / half-erect 1,304 / erection 147,593 /
    #           erection_under_clothes 15,093(着衣の場面用)
    # ★half-erect は 1,304 枚 = 実用の下限(1,000)ぎりぎり。効きが弱い可能性がある。
    options:
      # ★挿入・射精の場面では「していない」は矛盾する(勃っていないのに挿入している絵)。
      #   当たったら fallback の段へ自動で戻す = 正面衝突を作らない。
      #   phase だけでは足りない: 「二人に交互フェラ」「フェラ+手コキ」は foreplay だが
      #   カード本文に erect penis と書いてある。→ not_when_card_says で本文も見る。
      # ★2026-08-07 夕 追加(ユーザーが実画像で発見): `erect` だけでは穴があった。
      #   「口淫」の本文は `fellatio, oral` で erect の字が無いため、
      #   「していない」がそのまま通り、**勃っていないのに口淫している**指定になっていた
      #   (実画像では勃起して描かれた = モデルが矛盾を勝手に片づけていた)。
      #   男性器を刺激している場面の語を足す: fellatio(口淫・二人に交互フェラ・フェラ+手コキ)
      #   / handjob(手淫) / paizuri(パイズリ)。
      #   ★足してはいけない語:
      #     `oral`    → クンニ(cunnilingus, oral)まで拾う。女性側への口なので矛盾しない
      #     `sucking` → 「乳首を吸う」(sucking her nipple)まで拾う。同じく矛盾しない
      # ★2026-08-07 夜 作り直し(ユーザーが実画像で発見: フェラで男性器が2本)。
      #   実測(口淫の画像72枚を検出器で数えた):
      #       erection なし 70枚中 2枚が2本以上 (3%)
      #       erection あり  2枚中 2枚が2本以上 (100%)
      #   ★原因: Danbooru の `erection` は状態の形容ではなく **それ自体が「勃ったモノ」を
      #     指す名詞**(147,598枚)。`(small penis:1.3)` と並べると**男性器を指す名詞が2つ**になり、
      #     さらに口淫の絵は「口元」と「股間」の2か所に置き場所があるため、2本描かれる。
      #   ★直し方: 行為そのものが勃起を含意している場面では **勃起の語を1つも出さない**。
      #     口淫・手淫・パイズリ・挿入・射精は、書かなくても勃っている絵になる。
      #     (昼に入れた `fallback: erect` は、矛盾を消すつもりで**名詞を1つ増やしていた**)
      #   ★3段すべてに同じ条件を書く = どの段を選んでも、これらの場面では言葉を足さない。
      #     着衣のカット(approach)は条件に当たらないので `erection under clothes` は今までどおり。
      flaccid: {label: あまりしていない, prompt: "flaccid",
                not_in_phases: [main, climax], not_when_card_says: [erect, fellatio, handjob, paizuri]}
      half:    {label: 半分,             prompt: "half-erect", clothed_prompt: "erection under clothes",
                not_in_phases: [main, climax], not_when_card_says: [erect, fellatio, handjob, paizuri]}
      erect:   {label: している,         prompt: "erection",   clothed_prompt: "erection under clothes",
                not_in_phases: [main, climax], not_when_card_says: [erect, fellatio, handjob, paizuri]}

# recipe 側 negative との接続は別タスク。ここでは骨のみ。
# 相手役側で「男性が若返る／イケメン化する」ことを防ぐための共通ネガトークン。
negative_defaults:
  anti_ikemen:
    label: イケメン化防止
    note: mature_male を指定してもモデルによっては若く・端整に寄る事故を防ぐ
    prompt: "bishounen, ikemen, handsome, young man, boy, teenage, slim, muscular, abs, six pack, athletic, glossy skin, smooth skin, long hair, full head of hair"
  anti_unclean:
    label: 汚さ強調の抑制
    note: 善良系プリセットで ugly/unclean 方向へ振れることを防ぐ
    prompt: "ugly, unclean, dirty, filthy"

  anti_body_bleed:
    label: 相手役の体型が女性へ移るのを防ぐ
    note: |
      ★2026-08-05 実測(ユーザー): 相手役に「肥満体で無精な中年男性」を選んだら、
      主役の女性まで**お腹が出て**描かれた。同じ1つの文に
      `obese man, very fat man, very large belly` と `very slender`(女性)が並ぶため、
      AIが「誰の腹か」を区別しきれず、太さが女性側へ染み出す。
      2026-08-01 に「1人指定なのに2人性が混ざる」を数指定の除外で抑えたのと同じ型の事故。
      ★相手役が太い体型のときだけ足す。細身の相手役では何も足さない
      (不要な打ち消しを常時入れると、別方向の綱引きになるため)。
      ★打ち消しは綱引きの一票であって命令ではない。効かない場合は LoRA 側の可能性を疑う。
      ★2026-08-05 追記: 対象を _HEAVY_BUILDS(pipeline/partner_cast.py)で持つ。
        新設の 超肥満・巨漢 を足すと同時に、**取りこぼしていた「太った」も対象に入れた**
        (prompt に `fat man, large belly` があり、肥満体と同じ染み出しが起きる)。
        「小太り」は soft belly だけなので入れない(弱い語に強い打ち消しを当てない)。
      ★2026-08-05 実画像で力負けを確認(ユーザー): 超肥満で刷ったら**主役の女性が大きく太った**。
        配線は正しく打ち消しは入っていたが、綱引きで負けていた。同じ絵に太い方向が3つある:
          ① 相手役の語が5つ(morbidly obese / extremely fat / enormous belly / huge gut / rolls of fat)
          ② 女性側は `very slender` 系だけで弱く、`(slender legs:0.9)` はむしろ下げている
          ③ **LoRA(rinko_v1)自体がむちむち体型を焼き込んでいる**(2026-08-05 午前に判明)
        対して打ち消しは1つ。重みを上げ、相手役側に実際に出ている語を鏡写しにした。
        ★それでも打ち消しは一票。**超肥満は今の LoRA では勝ち切れない前提**で扱うこと。
    # ★2026-08-06 修正(実データで原因判明): この打ち消しが**相手役の腹まで消していた**。
    #   打ち消し文は「誰の腹か」を区別できない(絵全体にかかる)。ところが旧版には
    #     (belly:1.3) (big belly:1.3) (huge gut:1.3) (thick rolls of fat:1.3) (plump:1.3) (thick waist:1.2)
    #   と**性別の付いていない語**が6つ入っており、相手役の positive
    #     enormous belly, huge gut, thick rolls of fat  (重み1.0)
    #   を 1.3倍の強さで打ち消していた。腹を失った男性はモデルの既定(=筋肉質)へ戻る。
    #   ユーザー実測「超肥満にしているのに筋肉隆々になる」の正体がこれ。
    #   → **女性と明記した語だけ**にする。性別の付いていない語は1つも置かない。
    # ★(chubby girl) も外した: Danbooru で `chubby` は **0枚** = 学習されていない語だった。
    # ★弱くなる方向なので、女性が太る方へ戻らないか **同じ乱数で必ず A/B を見る**。
    #   戻るようなら、打ち消しではなく §10(男性だけを描き直す)側で解く。
    prompt: "(fat woman:1.4), (obese woman:1.4), (morbidly obese woman:1.4), (fat girl:1.3), (plump woman:1.3)"

  anti_size_bleed:
    label: 相手役の大きさが女性へ移るのを防ぐ
    note: |
      ★2026-08-05 新設。「巨漢」は太さだけでなく**大きさ**(背丈・体積)を足す語なので、
      anti_body_bleed(腹まわりの打ち消し)では届かない。同じ文に
      `very tall and massive man` と女性が並ぶと、女性まで大きく・いかつく寄りうる。
      ★巨漢を選んだときだけ足す。既存の体格(肥満体など)の出方は1文字も変えない
      (途中まで刷った作品の見た目を後から動かさないため)。
    prompt: "giant woman, huge woman, tall muscular woman, broad-shouldered woman, large female body"

  anti_male_ring:
    label: 男性の手に結婚指輪が出るのを防ぐ
    note: |
      ★2026-08-08 新設(ユーザー指摘「男性側に結婚指輪の指定などしていない」)。
      そのとおりで、**相手役のプロンプトに指輪の語は1つも無い**。出どころは女性側の
      キャラ定義にある `wedding ring`(21,285枚)で、**「誰の」が付いていない**ため
      男性の手にも回っていた。今日ずっと追いかけてきた染み出し(服・髪・肌・腹)と同じ形。
      ★キャラ定義(characters/rina.yaml)は作品の土台なので**触らない**。
        相手役が出る場面だけ、男性の手の指輪を打ち消す。
      ★実測: wedding_ring 21,285 / ring 127,546 / multiple_rings 21,390
        ★存在しない語: left_hand(0) / ring_finger(0) → 使わない。
          「左手の薬指だけ」は**言葉では指定できない**(タグが無い)。
          いま出来るのは「男性の手には出さない」「余計な指輪を増やさない」まで。
      ★`ring`(127,546) や `jewelry`(1,568,935) を裸で打ち消すと、**女性の結婚指輪まで
        消える**(女性の指輪は作品の要)。男性と明記した語だけにする。
    prompt: "(wedding ring on the man:1.3), (ring on male hand:1.3), (male hand with ring:1.2), multiple rings"
  anti_futanari:
    label: 女性側に男性器が生えるのを防ぐ
    note: |
      ★2026-08-07 新設。wildcards/nsfw/partner.txt に元々あった警告がここでも効く:
        「faceless male, penis, hetero が無いと、モデルが**女性側に**ペニスを生やして
          ふたなり化し、絵が破綻する」。
      今回はじめて男性器を**名指しで**プロンプトに書くので、この事故の確率が上がる。
      実測: futanari は 50,242 枚 = 十分に学習されている = 放っておくと出る。
      ★newhalf / dickgirl は Danbooru で **0枚** = 学習されていない語なので使わない。
      ★打ち消しだけでは足りないので、positive 側にも土台(genital_axis.anchor_prompt =
        hetero 785,361枚)を置く。negative は必要条件であって十分条件ではない。
      ★股間の軸を使ったときだけ足す。使っていない既存作品の出方は1文字も変わらない。
    prompt: "futanari, futanari with male, penis on female, penis on woman"

  anti_large_penis:
    label: 小さい方向が大きい方向に負けるのを防ぐ（★いまは未使用）
    # ★2026-08-07 夜: **どこからも使っていない**。大きさの選択肢から counter を外したため。
    #   理由 = ユーザーが「今の大きさが理想」と明言。小さくする必要が無い。
    #   将来「もっと小さく」と言われたときだけ、genital_size の段へ
    #   `counter: anti_large_penis` を書き戻す。定義は消さずに残しておく。
    note: |
      ★2026-08-07 新設。大きさの「かなり小さい」「小さい」を選んだときだけ足す。
      ★anti_body_bleed(体型)と違い、**誰の物か迷う語が無い**のがこの打ち消しの利点。
        腹や太さは女性にもあるので打ち消しが女性側へ回ってしまったが、
        男性器の語は男性にしか掛からないため、女性側を巻き込む心配がない。
      ★それでも綱引きの一票。1:9.6 の不利を覆せるとは限らないので、
        必ず同じ乱数で「大きい」との A/B を見ること。
    # ★2026-08-07 夜 作り直し(実測で「効いていない」と確定したため)。
    #   検出器で口淫の画像を測ったところ、男性器が画面に占める割合は
    #       指定なし 45枚: 平均 4.84% / 中央 4.54%
    #       かなり小さい 3枚: 平均 6.66% / 中央 6.30%  ← **小さくなるどころか大きい**
    #   3枚とも指定なしの中央値を超えていた。旧版(1.3/1.3/1.2 + 太さ・血管)は無力だった。
    #   ★直し方2つ:
    #     ① **大きさと無関係な語を外す**。`girthy`(太さ) `veiny`(血管)は大きさではないので、
    #        打ち消しても小さくならない。的が外れていた。
    #     ② **重みを上げる**。small_penis 6,673 に対し large+huge+gigantic は 63,812 で
    #        約1:9.6。1.2〜1.3 では足りない。
    #   ★これでも勝てない可能性は高い。使える語は `small_penis` 1つしか無い
    #     (tiny penis / micropenis / short penis は Danbooru に**存在しない**と確認済み)。
    #     負けたら、太った男と同じ結論 = **言葉では解けない → LoRA 側**になる。
    prompt: "(large penis:1.5), (huge penis:1.5), (gigantic penis:1.4)"

  anti_male_shirt:
    label: 下着なのに男性がシャツを着るのを防ぐ
    note: |
      ★2026-08-11 新設。相手役の服に「下着」を選ぶと**上半身が空欄**になり、
      絵のAIがそこを勝手に埋めてシャツを着せていた(しかも主役の女性が白Tなので同じ色になる)。
      ★最初 positive に `topless male` を足したが、これは失敗だった。実測で
        topless_male 57,178枚のうち muscular 47.9% / pectorals 42.1% / bara 31.2% で、
        **fat man は 1.4%**。上半身裸ではなく「筋肉質な男」を呼ぶ語で、体格を打ち消していた。
      → positive に語を足すのをやめ、**男性と明記した打ち消し**で「シャツを着せない」を表す。
        こうすれば主役の女性の白いTシャツは1枚も消えない(指輪・服で成功している型)。
      ★「下着」を選んだときだけ足す。他の服の出方は1文字も変わらない。
    prompt: "(shirt on the man:1.3), (man wearing a shirt:1.3), (male upper body clothing:1.2)"

  anti_small_penis_genre:
    label: 「小さい」の指定が男の娘・非勃起の絵を呼び込むのを防ぐ
    note: |
      ★2026-08-10 新設(ユーザーが実画像で発見 → Danbooru で実測して原因を確定)。
      症状: 「かなり小さい」にすると、**挿入の場面なのに男性器が外に描き出される**。
            100枚に1枚は女性の体に生えた(ふたなり)。
      原因: `small_penis`(6,688枚)は「小さい」だけの語ではない。同居している語の実測:
              男の娘(trap)   31.4%  ← いちばん強い同居相手。打ち消しに**1つも無かった**
              yaoi           26.5%
              ふたなり        14.5%  (penis 全体 7.2% の**2倍**)
              勃起していない   12.4%  (penis 全体 1.3% の**9.5倍**)
              挿入している     5.1%  ← ほとんど無い
            つまり「女性的な体に小さいものが付いている・勃っていない・挿入していない」絵を
            まとめて呼び込む語だった。
      実測(100枚 × 2本): 男性器が出た絵 39枚(標準は13枚)。**小さくする語ではなく
            「男性器を描かせる語」**として効き、隠れるはずの挿入場面でも外に出ていた。
      ★実在タグと枚数(2026-08-10 実測): trap 75,946 / yaoi 112,852 / futanari 50,389
        ★存在しない語: femboy(0) / otoko_no_ko(0) → 使わない(正式なタグ名は trap)
      ★入れる語を `trap` 1つに絞った理由:
        ・実測でいちばん強い同居相手であり、症状(女性的な体に小さいもの)と直結する
        ・`yaoi`(112,852枚)は絵柄そのものを動かしかねない大きな語なので入れない
          (2026-08-07 に `hetero` 785,370枚 を保険で入れて画風を壊した反省)
        ・`flaccid` は入れない。勃起の軸で「あまりしていない」を選ぶと**同じ語が
          positive にも出る**場面があり、自分で自分を消す(anti_ikemen × 筋肉質と同じ型)
      ★大きさの「かなり小さい」「小さい」を選んだときだけ足す。
        選ばない作品の出方は1文字も変わらない。
    prompt: "trap"

  anti_extra_penis:
    label: 男性1人の場面で男性器が2本描かれるのを防ぐ
    note: |
      ★2026-08-07 夜 新設(ユーザーが実画像で発見: フェラで2本出た)。
      ★これは今回の機能で始まった事故ではない。検出器で口淫の画像71枚を数えたところ、
        **股間の設定を入れる前から70枚中2枚(約3%)で2本以上**が出ていた(8/5 に2枚)。
        33枚に1枚は、売り物のCG集としては見過ごせない。
      ★使った実在タグと枚数:
          disembodied penis      9,276  (体につながっていない男性器 = まさに今回の絵)
          surrounded by penises 25,423  (複数本に囲まれる)
          double penetration    14,305  (2本で挿入)
      ★存在しなかった語: multiple penises(0) / two penises(0) / extra penis(0) → 使わない。
      ★**男性1人の場面にだけ**足す。3P(男性2人)では2本が正しいので足してはいけない
        (既にある `2boys` の除外と同じ考え方)。
      ★股間が画面にある場面にだけ足す。着衣の抱擁カットには不要。
    prompt: "disembodied penis, surrounded by penises, double penetration"

# ── 股間まわりの軸だけに効く規則(2026-08-07 追加)──────────────────────────
#   ここを空にすれば機能ごと止まる(既存の出方に戻る)。
genital_axis:
  # ★★2026-08-07 夜 全面的に作り直した(ユーザーが100枚を刷って発見: 女性に男性器が生えた)。
  #
  #   ★私の読み違い: `expected_zones` を「股間が画面にある」印として使っていたが、
  #     これは **モザイクを掛ける対象の一覧**であって「男性器が出る」印ではない。
  #     クンニ・乳首を吸う・乳を揉む・指 にも genitals が入っているが、
  #     そこに写るのは **女性側の股間**。そこへ `(small penis:1.3)` を入れていたので、
  #     絵の中で唯一の「股間」である女性側に男性器が付いた。
  #
  #   ★実測(男性器が出るはずのないカードで、男性器が検出された率):
  #       07-22〜08-04  125枚中 0枚  (0%)
  #       08-05          20枚中 1枚  (5%)
  #       08-06          19枚中 0枚  (0%)
  #       08-07(今日)    19枚中 5枚  (**26%**)  ← この機能を入れた日
  #
  #   ★直し方: **カード本文が「男性器を使う行為」を書いている場合だけ**出す。
  #     入れ忘れても既定の大きさになるだけだが、入れすぎるとふたなり化する。
  #     **危険が釣り合っていないので、迷ったら入れない**方に倒してある。
  male_genital_when_card_says:
    - penis          # 手淫 / パイズリ / 二人に交互フェラ（旧 `penis grab` `breasts on penis` は実体ゼロ）
    - fellatio
    - irrumatio      # 深口
    - deepthroat
    - handjob
    - paizuri
    - vaginal        # 挿入10種
    - intercourse
    - sex from behind
    - penetrat       # penetration / penetrating
    - cum in pussy   # 体内（旧 `creampie` は Danbooru に実体ゼロだったので差し替え）
    - spitroast
    - sandwiched     # 挟み込み（旧 `double team` は実体ゼロ）
    - bukkake        # 多量
    - facial         # 顔射
  # ここに当たらないカードのうち、**何も露出していない**もの(expected_zones が空)は
  #   服の上からの言い換え(erection under clothes)を使う。
  #   どちらでもないカード(女性側だけ露出 = クンニ・乳首・指)は **何も出さない**。
  # 段どうしの矛盾避け(not_in_phases / not_when_card_says / fallback)は
  #   選択肢1つずつに書いてある。ここには置かない。

  # ── 保険の3つ。★2026-08-07 夕に既定を off にした ────────────────────────
  #   ★なぜ止めたか(ユーザー指摘 → 実測):
  #     「何十枚生成してもこんなに暗くなったことはない」と指摘され、過去50run・1,015枚を
  #     測り直した。**今回だけが異常値**だった。
  #        過去(8/5〜8/6・約200枚)の男性あり : 明るさ 170〜191 / 赤−青 19〜27
  #        同じ日の 15:18 までの4回          : 明るさ 166〜171 / 赤−青 26〜29
  #        16:12(この機能を入れた後)         : 明るさ **143.3** / 赤−青 **58.7**
  #     15:18 と 16:12 の文章の差は14語だけで、**うち12語がこの機能の追加分**。
  #     画質・キャラ・共通の打ち消し・生成設定は1文字も違わない。
  #   ★一番の容疑者は `hetero` = **785,370枚**。この文章の中で桁が2つ違う。
  #     「男女の性行為の絵ぜんぶ」を指す語なので、絵全体をその平均(肌色が多く暖色)へ引く。
  #     観測された「赤みが約2倍」と方向が一致する。
  #   ★この3つは**利用者が頼んだ機能ではなく、こちらが足した保険**なので先に止める。
  #     頼まれた機能(大きさ・勃起状態)そのものは止めない。
  #   ★消さずに残してあるのは、ふたなり化が実際に出たときに戻せるようにするため。
  #     戻すときは true にして、**必ず同じ設定で6枚テストを刷って色を測ること**。
  #   ★anti_large_penis も一緒に止める理由: 16:12 のテストは
  #     「かなり小さい」+ この打ち消し5語が**両方効いた状態で、大きく勃起して描かれた**。
  #     効いていない打ち消しのために、重み1.2〜1.3の語を5つ置く価値はない。
  safety_extras: false
  anchor_prompt: hetero            # safety_extras: true のときだけ positive へ足す
  always_negative: anti_futanari   # 同上

  # ★2026-08-07 深夜 追加: ふたなり化の**打ち消しだけ**は、男性が出る場面に常時入れる。
  #   ★`hetero`(785,370枚・positive)とは切り離す。色を暖色へ引いたのはそちらで、
  #     こちらは負の4語なので色への影響は桁違いに小さいはず(要実測)。
  #   ★8/6(ふたなり0枚)にも入っていなかったので、これ単体が決め手とは言えない。
  #     顔立ちの語を戻したことと合わせて、二重の備えとして入れる。
  #   男性が出る場面すべてに入れる(股間が写るかは問わない。ふたなり化は
  #   「乳を揉む」のような場面でこそ起きていたため)。
  futanari_negative: anti_futanari

  # ── ここから下は safety_extras とは別。止めない ──────────────────────────
  #   ★2026-08-07 夜 分離した。上の2つは「こちらが勝手に足した保険」なので止めたが、
  #     下の2つは**利用者が頼んだ機能そのもの**なので同じ扱いにしてはいけない。
  #       ・大きさの打ち消し(counter) = 「小さい」を効かせるための本体
  #       ・1本にする打ち消し         = ユーザーが実画像で見つけた事故への対処(承認済み)
  # 男性1人 × 股間が画面にある場面にだけ足す。3P では足さない(2本が正しいため)。
  one_penis_negative: anti_extra_penis

# ── 相手役だけに当てる LoRA(2026-08-07 追加)────────────────────────────────
#   ★なぜ要るか: タグを正しく直しても「太った男」に勝ちきれない。実測(Danbooru の枚数)で
#       muscular male 137,397 枚 : fat man 14,345 枚 = 約 9.6 : 1
#     モデルにとって成人男性の既定は圧倒的に筋肉質で、言葉だけでは押し切れない。
#     実画像のA/B(2026-08-07)でも、腹は半分しか戻らなかった。
#   ★全体には当てない。当てると**主役の女性まで引きずられる**(いま打ち消しで戦っているのと同じ事故)。
#     当てるのは「男性の顔まわりを塗り直す工程」だけ(pipeline/face_fix.py)。
#   ★ライセンス: Civitai の allowCommercialUse = ["Sell"]。
#     ユーザーが作者ページを目視確認して使用可と判断(2026-08-07)。
male_lora:
  # ★2026-08-07 導入済み。**入れ方は S3(ネットワークボリューム)へ直接置く**のが正解。
  #   遠回りした記録(同じ失敗を繰り返さないため):
  #     ✗ Manager save_path=loras   … 200 が返るが現れない
  #     ✗ Manager save_path=default … 現れる。**が、ポッドを止めたら消えた**
  #        (default は容器側 /ComfyUI/models/loras。ポッドと一緒に消える)
  #     ✗ Jupyter から curl         … このポッドに JUPYTER_LAB_PASSWORD が無く接続できない
  #     ○ S3 で直接                 … tool/podlogs.py の client で
  #        bucket=ボリュームID / key=comfyui/models/loras/<file> へ put。
  #        **ポッドを起動しないので費用ゼロ**。29秒で完了(228MB)。
  # ★true でもファイルがポッドに無ければ、塗り直し工程が自動で男性側を飛ばす
  #   (pipeline/face_fix.py が生成の直前に在庫を確認する)。存在しないLoRAで生成は落ちない。
  # ★2026-08-07 深夜 OFF にした(ユーザー判断)。
  #   理由1: **時間**。100枚中60枚を塗り直して23分。画像生成(17分)より長い。
  #          ユーザーの言葉「男性の顔をきれいにするのに1ミリも時間をかけたくない。
  #          同じ髪型・同じ禿げ方であればいい」。
  #   理由2: **ふたなり化の容疑者2つのうち1つ**。8/6(ふたなり0枚)には塗り直しが無く、
  #          8/7(発生)には60枚あった。止めれば切り分けにもなる。
  #   ★止めても絵は落ちない(male_pass が None を返し、塗り直し工程を飛ばす)。
  #   ★戻すときは true。ただし**時間が23分戻る**ことを承知のうえで。
  enabled: false
  name: uglyBastardIL_baseV1.safetensors
  strength: 0.75          # 強すぎると相手役が「別のキャラ」になる。実画像で調整すること
  trigger: "UBV1, ugly bastard"
  source: https://civitai.com/models/1865181
  license: "allowCommercialUse=Sell (2026-08-07 ユーザー確認済み)"
  note: |
    顔を隠す作品には FacelessBastardV1IL(呼び言葉 UBV1F)という別の版がある。
    必要になったら **足す**(この版を置き換えない)。
