        /* ============================================================
           ▼ 反復 #16-D (v0.8.59, 2026-05-03): z-index 階層 (ADR 0034)
           ============================================================
           17 段以上に散らかっていた z-index 値を 8 段の名前付き layer に整理。
           Tailwind の任意値構文 `z-[var(--z-xxx)]` で参照可能。
           CSS 内では `z-index: var(--z-xxx)` で参照。

           階層 (大きい値ほど前面):
              - canvas        :  0     キャンバス本体・背景
              - canvas-overlay:  7     ミニマップ / zoom slider
              - sticky        : 40     sticky toolbar / mobile bar
              - dd-hint       : 45     D&D ヒントアニメ (sticky パネルより前・popover より後)
              - popover       : 50     検索 popover / help tip
              - panel         : 170    side panel (home / validation)
              - modal         : 180    一般 modal (cheat / spec / sample / toast history)
              - confirm       : 680    確認ダイアログ (上書き等)
              - urgent        : 900    緊急 (decline / share URL)
              - tutorial      : 1000   チュートリアル (画面全 cover)
              - tour          : 2000   機能ツアー (最上位)
              - tooltip-float : 10005  cursor 追従 tooltip (常に最前面)
           ============================================================ */
        :root {
            --z-decoration: -1;
            --z-canvas: 0;
            --z-canvas-overlay: 7;
            --z-sticky: 40;
            --z-dd-hint: 45;
            --z-popover: 50;
            --z-modal-wizard: 100;
            --z-modal-editor: 150;
            --z-panel: 170;
            --z-modal-settings: 175;
            --z-modal-history-viewer: 178;
            --z-modal: 180;
            --z-modal-release-notes: 185;
            --z-modal-alert: 200;
            --z-floating-action: 450;
            --z-toast: 500;
            --z-node-menu: 550;
            --z-file-drop: 600;
            --z-slot-panel: 650;
            --z-confirm-side: 670;
            --z-confirm: 680;
            --z-resume: 700;
            --z-legal-agreement: 800;
            --z-urgent: 900;
            --z-tutorial: 1000;
            --z-tour: 2000;
            --z-tooltip-float: 10005;
        }

        /* ▼ 反復 #5 末尾追補 (2026-04-30 ユーザー指示):
              「タイムラインのＴＩＰＳを既存のもののＵＩと統一してください」
           radial menu の `.ccrl-radial-tooltip` と同じスタイルを共通化。
           ホバー時にダーク半透明 + 白文字 + 角丸 + drop-shadow で表示。 */
        /* ▼ 反復 #26-A (v0.8.70): canvas UI (家系図のアイコンカード) と同じ「rounded-2xl + 重ね影 + 1px 強調枠」
           の雰囲気に統一。tooltip もキャンバス上の card と同じ "浮いたミニカード" として読める。 */
        .ccrl-shared-tip {
            position: fixed;
            background: rgba(30, 41, 59, 0.97);   /* slate-800 ベース */
            color: #f1f5f9;                         /* slate-100 */
            padding: 10px 16px;
            border-radius: 12px;                    /* canvas card と同じ rounded-xl 系 */
            font-size: 12px;
            font-weight: 500;
            font-family: system-ui, sans-serif;
            line-height: 1.55;
            white-space: normal;
            word-break: break-word;
            max-width: 320px;
            min-width: 120px;
            pointer-events: none;
            border: 1px solid rgba(148, 163, 184, 0.35); /* slate-400/35 — canvas icon の border 感 */
            box-shadow: 0 12px 28px -8px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.06);
            z-index: var(--z-tooltip-float);
            opacity: 0;
            transition: opacity 0.14s ease-out;
        }
        .ccrl-shared-tip.visible { opacity: 1; }

        /* ▼ 反復 #5 末尾追補 (2026-04-30 ユーザー指示):
              「タイムライン実行時は、キャンバスの背景に、未来に向かっている感じのアニメーション」
           初期実装: 4色グラデーション流れ → 控えめすぎて気付きにくいとの FB
              「時計モチーフを上部奥の中心点に向かって集める Star Wars 円バージョン」を採用。
           SVG 時計を 8 個、画面 4 隅から中心 (上部 1/3 地点) に向かってフェード+縮小+回転で集約。
           6 秒で 1 サイクル、stagger で連続感、透過度 8-15% でポップさを抑制。 */
        .ccrl-canvas-frame.ccrl-timeline-active::before {
            content: '';
            position: absolute;
            inset: 0;
            border-radius: 1rem;
            pointer-events: none;
            /* 微妙なグラデーションを背景に維持 (Layer 1) */
            background: radial-gradient(ellipse at 50% 35%,
                rgba(251,191,36,0.05) 0%,
                rgba(99,102,241,0.04) 40%,
                rgba(15,23,42,0) 75%);
            background-size: 250% 250%;
            animation: ccrl-timeline-flow 16s linear infinite;
            z-index: 1;
            overflow: hidden;
        }
        /* 時計モチーフ overlay (Layer 2): SVG を background に repeat
           ▼ 反復 #5 末尾追補 (2026-04-30 v2 ユーザー指示):
              「時計の出現場所と大きさはランダムにしてください。
               あともう少し濃くてもいいかもしれません。」
           4 隅固定 → 8 個の半ランダム位置 + サイズ変動に拡張、opacity 16% → 28%。 */
        .ccrl-canvas-frame.ccrl-timeline-active::after {
            content: '';
            position: absolute;
            inset: 0;
            border-radius: 1rem;
            pointer-events: none;
            z-index: 2;
            /* 8 個の時計マーク (色違い + サイズ違い) で擬似ランダム配置 */
            background-image:
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%23818cf8' stroke-width='1.6'/><line x1='16' y1='16' x2='16' y2='6' stroke='%23818cf8' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='22' y2='16' stroke='%23818cf8' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%23818cf8'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%23fbbf24' stroke-width='1.6'/><line x1='16' y1='16' x2='16' y2='8' stroke='%23fbbf24' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='20' y2='20' stroke='%23fbbf24' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%23fbbf24'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%2334d399' stroke-width='1.6'/><line x1='16' y1='16' x2='10' y2='10' stroke='%2334d399' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='22' y2='14' stroke='%2334d399' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%2334d399'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%2306b6d4' stroke-width='1.6'/><line x1='16' y1='16' x2='22' y2='10' stroke='%2306b6d4' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='14' y2='22' stroke='%2306b6d4' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%2306b6d4'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%23ec4899' stroke-width='1.6'/><line x1='16' y1='16' x2='12' y2='8' stroke='%23ec4899' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='22' y2='12' stroke='%23ec4899' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%23ec4899'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%23a855f7' stroke-width='1.6'/><line x1='16' y1='16' x2='20' y2='8' stroke='%23a855f7' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='22' y2='18' stroke='%23a855f7' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%23a855f7'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%23f97316' stroke-width='1.6'/><line x1='16' y1='16' x2='12' y2='6' stroke='%23f97316' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='10' y2='18' stroke='%23f97316' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%23f97316'/></svg>"),
                url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><circle cx='16' cy='16' r='13' fill='none' stroke='%2310b981' stroke-width='1.6'/><line x1='16' y1='16' x2='14' y2='8' stroke='%2310b981' stroke-width='1.8' stroke-linecap='round'/><line x1='16' y1='16' x2='8' y2='14' stroke='%2310b981' stroke-width='1.6' stroke-linecap='round'/><circle cx='16' cy='16' r='1.6' fill='%2310b981'/></svg>");
            background-repeat: no-repeat;
            /* 8 個それぞれ異なる初期サイズ (28-44px 幅で variation) */
            background-size: 38px 38px, 32px 32px, 44px 44px, 30px 30px,
                             40px 40px, 28px 28px, 36px 36px, 34px 34px;
            /* 非対称な初期位置 (ランダム感を演出する 8 個の散在) */
            background-position:
                7% 14%,   18% 78%,
                88% 21%,  72% 88%,
                33% 8%,   62% 12%,
                12% 47%,  91% 56%;
            animation: ccrl-clock-warp 7s ease-in infinite;
            opacity: 0.28;
            mix-blend-mode: multiply;
        }
        /* dark mode は overlay を screen に + 濃度アップ */
        .dark .ccrl-canvas-frame.ccrl-timeline-active::after {
            mix-blend-mode: screen;
            opacity: 0.40;
        }
        @keyframes ccrl-timeline-flow {
            0%   { background-position: 50% 50%; }
            50%  { background-position: 50% 30%; }
            100% { background-position: 50% 50%; }
        }
        @keyframes ccrl-clock-warp {
            /* 8 個の時計が散在位置から中心 (50%, 35%) へ集まる + 縮小 + 透過変化 */
            0% {
                background-position:
                    7% 14%,   18% 78%,
                    88% 21%,  72% 88%,
                    33% 8%,   62% 12%,
                    12% 47%,  91% 56%;
                background-size: 38px 38px, 32px 32px, 44px 44px, 30px 30px,
                                 40px 40px, 28px 28px, 36px 36px, 34px 34px;
                opacity: 0;
            }
            10% { opacity: 0.32; }
            70% { opacity: 0.20; }
            100% {
                background-position:
                    50% 35%, 50% 35%, 50% 35%, 50% 35%,
                    50% 35%, 50% 35%, 50% 35%, 50% 35%;
                background-size: 5px 5px, 4px 4px, 6px 6px, 4px 4px,
                                 5px 5px, 3px 3px, 5px 5px, 4px 4px;
                opacity: 0;
            }
        }

        /* ▼ 反復 #44 (2026-05-25): 旧「横向き推奨」ヒントバナー (.ccrl-landscape-hint) の
           CSS 規則を撤去 (user 指示「ヒントは消しましょうか」)。HTML 側も削除済み。 */

        .half-blood-node { border-style: dashed !important; border-color: #fb923c !important; }
        .dead-same-badge { background: #6366f1 !important; }
        [x-cloak] { display: none !important; }
        /* mirror はシンメトリー保険として DOM 上に残すが、描画ピクセルはゼロ化する。
           recalcDecedentBarWidth が JS 実測で被相続人ノード中心を計算しており、
           mirror の寸法に依存するコードは存在しない。
           canvas-inner 内の右側余白を完全に消すため width:0 + overflow:hidden を適用。 */
        [data-mirror] { width: 0 !important; overflow: hidden !important; }
        /* mirror をゼロ幅化したことで decedent_tc の幾何中心と decedent ノード中心が一致しなくなるため、
           ::before の縦線位置も --decedent-bar-w (=decedent 中心の % 位置) に揃える。
           ::after バーと縦線が同じ変数を使うことで完全整列する。 */
        .tree-child[data-decedent-tc]::before { left: var(--decedent-bar-w, 50%); }
        /* ▼ 砂時計ツリー: 直系尊属 (親・祖父母・曾祖父母) 用の「上下反転」レイアウト ▼
           子孫側の .tree-children / .tree-child と鏡映関係にあるクラス。
           - flex コンテナを align-items:flex-end (底揃え) に
           - 各 tree-parent の ::before は「底部から上へ伸びる縦線」(padding-bottom 24px 内で描画)
           - 各 tree-parent の ::after は「底部の兄弟姉妹バー」(親同士を下辺で束ねる横線)
           - first-of-type/last-of-type/middle のロジックは子孫側と同じで位置だけ bottom:0 に切替え
           これにより複数の親・祖父母・曾祖父母が「コ/エ」の字型に束ねられて 1 本の縦線で被相続人につながる。 */
        .tree-parents { display: flex; justify-content: center; align-items: flex-end; position: relative; }
        .tree-parent { display: flex; flex-direction: column; align-items: center; position: relative; padding: 0 10px 24px 10px; }
        .tree-parent::before { content: ''; position: absolute; bottom: 0; left: 50%; width: var(--tree-line-width); height: 24px; background: var(--tree-line-color); transform: translateX(-50%); }
        .tree-parent:not(:only-of-type)::after { content: ''; position: absolute; bottom: 0; height: var(--tree-line-width); background: var(--tree-line-color); }
        .tree-parent:first-of-type:not(:only-of-type)::after { left: 50%; width: 50%; }
        .tree-parent:last-of-type:not(:only-of-type)::after { left: 0; width: 50%; }
        .tree-parent:not(:first-of-type):not(:last-of-type)::after { left: 0; width: 100%; }
        /* ▼ ゴースト表示中の線: 通常の tree-line-color ではなく emerald 系の半透明で、
           他のゴーストノード (border-emerald-400 / opacity-50) と視覚的に揃える。
           - .tree-parent.ghost-parent: 単独ゴースト行の per-parent vline (::before) と横バー (::after)
           - .tree-vline-down.ghost-vline: ゴースト行と隣接行を繋ぐ縦線 */
        .tree-parent.ghost-parent::before { background: #34d399 !important; opacity: 0.5 !important; }
        .tree-parent.ghost-parent::after { background: #34d399 !important; opacity: 0.5 !important; }
        .tree-vline-down.ghost-vline { background: #34d399 !important; opacity: 0.5 !important; }
        :root { --tree-line-color: #94a3b8; --tree-line-width: 2px; }
        .dark { --tree-line-color: #475569; }
        .tree-children { display: flex; justify-content: center; align-items: flex-start; position: relative; }
        .tree-child { display: flex; flex-direction: column; align-items: center; position: relative; padding: 24px 10px 0 10px; --spouse-bridge-w: 0px; }
        /* ハイブリッド配偶者レイアウト（通常ノード専用 spouse-bridge 方式）:
           - 通常ノード: 配偶者は absolute な "spouse-sidecar"。本人カードは flow 中央に残す。
             .tree-child.spouse-bridge に margin-right: var(--spouse-bridge-w) を付けて
             隣ノードと干渉しないようにし、::after の横線を calc() で延長する。
             幅は固定ではなく DOM 実測で recalcSpouseBridgeLayout() が設定する。
           - 被相続人ユニット: 既存の左右対称ミラー方式を維持（spouse-bridge は付けない）。 */
        .tree-child::before { content: ''; position: absolute; top: 0; left: 50%; width: var(--tree-line-width); height: 24px; background: var(--tree-line-color); transform: translateX(-50%); }
        .tree-child:not(:only-of-type)::after { content: ''; position: absolute; top: 0; height: var(--tree-line-width); background: var(--tree-line-color); }
        .tree-child:first-of-type:not(:only-of-type)::after { left: 50%; width: 50%; }
        .tree-child:last-of-type:not(:only-of-type)::after { left: 0; width: 50%; }
        /* 被相続人 tc は ex-spouses が左にあると非対称になり 50% (= tc 中心) では bar が decedent ノードに届かない。
           JS の recalcDecedentBarWidth() が decedent ノードの実位置を測って --decedent-bar-w を設定する。 */
        .tree-child[data-decedent-tc]:last-of-type:not(:only-of-type)::after { width: var(--decedent-bar-w, 50%); }
        .tree-child:not(:first-of-type):not(:last-of-type)::after { left: 0; width: 100%; }
        /* spouse-bridge: 実測 width 分だけマージンを取り、横線も延長する */
        /* 完全シンメトリー・ユニット用の左ダミースペーサ。配偶者あり時に本人カードの左に置くことで、
           [spacer(88)][node(64)][connector(24)][spouse(64)] = 240px のユニットが左右対称になり、
           本人カードが必ずユニット中心に来る（parent vline が本人を串刺しにする保証）。
           ジェミニ提案の「Flexbox に逆らわない最小構造」に全面移行（spouse-bridge / spouse-sidecar は撤廃）。 */
        .dummy-spacer { width: 88px; flex-shrink: 0; pointer-events: none; }
        .tree-vline-down { width: var(--tree-line-width); height: 24px; background: var(--tree-line-color); margin: 0 auto; }
        .couple-connector { display: flex; align-items: center; }
        /* 二重線がコネクタ幅いっぱいに延びて、配偶者アイコン同士を視覚的に繋ぐ。
           コネクタ自身の横幅（w-[42px] など）がそのまま線の長さになる。 */
        .couple-connector::before { content: ''; display: block; width: 100%; height: 8px; flex-shrink: 0; border-top: 2px solid var(--tree-line-color); border-bottom: 2px solid var(--tree-line-color); }
        /* 離婚（元配偶者）を示す二重点線コネクタ。couple-connector と同じ二重線構造で、線種だけ dashed に。
           コネクタ自体の横幅は 32px（アイコン同士がくっつかないよう breathing を確保）。
           ::before（点線）は中央寄せで 20px、左右に 6px ずつの視覚的余白を持つ。 */
        .ex-spouse-connector { display: flex; align-items: center; justify-content: center; width: 32px; }
        .ex-spouse-connector::before { content: ''; display: block; width: 20px; height: 8px; flex-shrink: 0; border-top: 2px dashed var(--tree-line-color); border-bottom: 2px dashed var(--tree-line-color); }
        .canvas-print-mode .ex-spouse-connector::before { border-color: #000 !important; }
        /* 認知子の生母プレースホルダの左側スペーサ。
           元配偶者の二重点線 (ex-spouse-connector) と同幅 (32px) を確保し、被相続人からの距離を揃える。
           線そのものは描画しない (ユーザー要望: 線なし)。
           → 空の 32px ブロックとして動作する。width のみ残す。 */
        .recognized-mother-connector { display: flex; align-items: center; justify-content: center; width: 32px; }
        /* 共通相続線（全ての子を横に繋げる）: 複数系統がある時に利用する視覚的補助 */
        .common-inherit-bar { height: var(--tree-line-width); background: var(--tree-line-color); width: 100%; }
        /* データ整合性エラーのリング（赤＝エラー、橙＝警告）。アイコンに付与する。 */
        .validation-error { box-shadow: 0 0 0 3px rgba(239,68,68,0.75), 0 0 0 6px rgba(239,68,68,0.25) !important; border-color: #ef4444 !important; }
        .validation-warning { box-shadow: 0 0 0 3px rgba(245,158,11,0.7), 0 0 0 6px rgba(245,158,11,0.2) !important; border-color: #f59e0b !important; }
        @keyframes vpulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }
        .validation-error .validation-icon,.validation-warning .validation-icon { animation: vpulse 1.3s ease-in-out infinite; }
        /* スマホでのD&Dブラウザ介入を遮断 (Pull-to-Refresh / 縦スクロール / ピンチズームの暴発対策)。
           touch-action:none を付けることで、ブラウザのデフォルトタッチ挙動を完全に無効化し、
           DragDropTouch.js (or HTML5 Drag) のみがタッチ入力を取り扱うようにする。 */
        .draggable-item { cursor: grab; touch-action: none; } .draggable-item:active { cursor: grabbing; }
        /* ▼ 反復 #35 (2026-05-08、Mobile UX audit): 36px 高さは tap target 不足 (<40px) */
        @media (pointer: coarse) {
            .draggable-item { min-height: 44px; }
        }
        .node-container[draggable="true"] { touch-action: none; }
        /* ドラッグオーバー中のハイライトは「ユーザーが今操作中」の最優先 UI ステート。
           validation-error の box-shadow (!important 付き) と CSS カスケーディング上で衝突しても
           必ず勝つよう、!important を付与する。さもないと赤エラー枠が緑ハイライトを上書きして、
           ユーザーは「エラーノードにはドロップできないのか?」とパニックになる。 */
        .drop-highlight { box-shadow: 0 0 0 4px rgba(52,211,153,0.7) !important; background-color: rgba(236,253,245,0.9) !important; opacity: 0.8; transition: all 0.2s ease; }
        /* ▼ 反復 #5 末尾追補 (2026-04-29 ユーザー要望):
             「上下のスクロールバー削除 (左右は削除済み想定)」 + zoom 調整バー設置のため、
             overflow: auto → hidden に変更。canvas は cy の zoom + pan で navigation。 */
        .canvas-viewport { overflow: hidden; position: relative; min-height: 300px; display: flex; justify-content: safe center; align-items: safe flex-start; }
        /* ▼ canvas 左上の zoom 調整バー (反復 #5)
             ▼ 反復 #5 末尾追補 (2026-04-29 ユーザー指摘 累積):
                「拡大すると戻ってくることが不可能」 → cytoscape canvas が拡大時に
                slider を覆い隠して操作不能になっていた。
                「戻る進むの下に配置してください」 → toolbar (~40-48px) の下に位置を下ろす。
             修正:
                - z-index 50 → 99999 (cytoscape の内部 canvas より確実に上)
                - pointer-events: auto を明示 (parent の pointer 制御に巻き込まれない)
                - top 8px → 56px → 100px → 130px (canvas-viewport 内側、フレーム境界と被らない)
                - スライダー手前に半透明 backdrop で常時識別可能 */
        /* ▼ 反復 #5 末尾追補 (2026-04-29 ユーザー指摘):
              「スライダーがミニマップと違う表層にあります」
           ミニマップは canvas frame 直下に z-index:6, 暗背景 (rgba(15,23,42,0.92)) で float。
           スライダーは旧 z-index:99999 + 白背景 → 「別世界に浮いている」印象。
           ミニマップと同じ表層に揃えるため:
             - z-index: 99999 → 7 (= ミニマップ +1, 同じ階層内で適切な前後)
             - 背景色をミニマップと同じダーク半透明に統一
             - shadow / border もミニマップと同系統に
           これで両者が「同じ階層に float している UI」として視覚的に整合する。 */
        /* ▼ 反復 #35 (2026-05-10、UX-COVERED-CONTROL 対策で再 sibling 化):
           slider は canvas-viewport の sibling (canvas-frame 直下)。
           canvas-frame 起点で position: absolute、top は heading + toolbar 高 (~80px) を offset。
           cy stacking context と分離されるため確実に operable。
           toolbar が wrap して 2-3 行になる場合は top 値を bump 必要 — 通常は 1-2 行内。
           ▼ 反復 #36 (2026-05-11、内蔵 audit UI-CONTROL-OVERLAP / UX-BUTTON-OVERLAP):
           旧 left:24px だと canvas-pan-pad の pan-up (top:12 left:50%) と bbox 重複 (96×20)。
           right:24px (top-right corner) に移動 — pan-up center は中央なので X 軸で分離される。
           pan-right (right:12 top:50%) とは Y で分離 (slider top:130 vs pan-right center)。 */
        /* ▼ 反復 #38 末尾追補 v45 (2026-05-15 user 指示「スライダーの厚さを常に上下左右ボタンと
           同じ厚さとしてください」):
           上下左右 pan-btn の厚さ = 24px (PC、 line 442) / 22px (mobile, line 471) と統一。
           padding を 0 にして高さ固定、 内部 flex align-items: center で center 配置。
           インナー (visibility-btn / step-btn / input range / label) も 24/22 内に収まるよう調整。 */
        .canvas-zoom-slider {
            position: absolute;
            top: 130px;
            right: 24px;
            bottom: auto;
            left: auto;
            transform: none;
            z-index: 100;
            pointer-events: auto;
            display: inline-flex;
            flex-wrap: nowrap;
            align-items: center;
            gap: 6px;
            background: rgba(15, 23, 42, 0.85);
            color: #f1f5f9;
            padding: 0 8px;
            border: 1px solid rgba(148, 163, 184, 0.3);
            border-radius: 9999px;
            box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
            font-size: 10px;
            font-family: system-ui, sans-serif;
            backdrop-filter: blur(6px);
            -webkit-backdrop-filter: blur(6px);
            width: auto;
            min-width: 0;
            max-width: calc(100% - 32px);
            height: 24px;  /* pan-btn と統一 (PC 24px) */
            box-sizing: border-box;
        }
        /* slider input は flex 縮小可、btn は flex-shrink: 0 で潰さない */
        .canvas-zoom-slider input[type="range"] {
            flex: 1 1 auto;
            min-width: 90px;
            max-width: 180px;
        }
        .canvas-zoom-slider .zoom-step-btn,
        .canvas-zoom-slider .zoom-label {
            flex-shrink: 0;
        }
        /* ▼ 反復 #38 末尾追補 v46 (2026-05-15 user 指示「スライダーの位置は自由に変えられるように」):
           drag handle (⋮⋮)。 slider の左端に配置、 cursor: move でドラッグ可能を視覚的に示す。
           clicked 領域は handle のみ (zoom button や input range は通常操作)。
           font-family を monospace 系にして bullets が等幅で安定。 */
        .canvas-zoom-slider .zoom-drag-handle {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 14px;
            height: 20px;
            font-size: 14px;
            font-family: 'SF Mono', 'Cascadia Mono', 'Consolas', monospace;
            color: rgba(241, 245, 249, 0.7);
            cursor: move;
            user-select: none;
            -webkit-user-select: none;
            flex-shrink: 0;
            line-height: 1;
            letter-spacing: -2px;
            transition: color 0.15s;
        }
        .canvas-zoom-slider .zoom-drag-handle:hover {
            color: #ffffff;
        }
        .canvas-zoom-slider.canvas-zoom-dragging {
            cursor: move;
            transition: none !important;  /* drag 中の transition 抑止 */
        }
        @media (max-width: 768px), (pointer: coarse) {
            .canvas-zoom-slider .zoom-drag-handle {
                width: 12px;
                height: 18px;
                font-size: 12px;
            }
        }

        /* ▼ 反復 #35 (2026-05-10、user 指示「スライダー左端に表示/非表示ボタン」):
           常時 visible な toggle button (eye icon) で slider 本体を即時 on/off。
           ▼ v45 (2026-05-15): slider 厚さ 24px に統一に伴い 26→20px に縮小 (24px 内に余白付き)。 */
        .canvas-zoom-slider .zoom-visibility-btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 20px;
            height: 20px;
            padding: 0;
            border: 1px solid rgba(148, 163, 184, 0.45);
            border-radius: 50%;
            background: rgba(51, 65, 85, 0.65);
            color: #f1f5f9;
            cursor: pointer;
            flex-shrink: 0;
            transition: background 0.15s, color 0.15s;
        }
        .canvas-zoom-slider .zoom-visibility-btn:hover {
            background: rgba(56, 189, 248, 0.75);  /* sky-400 */
            color: #ffffff;
        }
        .canvas-zoom-slider .zoom-visibility-btn:focus-visible {
            outline: 2px solid #38bdf8;
            outline-offset: 2px;
        }
        /* collapsed 状態: drag handle (⋮⋮) + visibility-btn (🔍) のみ表示。
           ▼ v48 (2026-05-15 user 指摘「眼鏡みたいなマークも枠内に収めてください」):
           旧 max-width: 28px は visibility-btn (20px) のみ想定で drag handle 追加後は overflow。
           新: handle 14 + gap 6 + btn 20 + padding 16 = 56px 確保。 width: auto + max-width: none
               で内容に応じてフィット、 確実に枠 (border-radius: 9999px の pill) 内に収める。 */
        .canvas-zoom-slider.canvas-zoom-collapsed {
            padding: 0 8px;
            width: auto;
            min-width: 56px;
            max-width: 80px;
        }

        /* ▼ 反復 #34 hotfix #12+#13b (2026-05-07): canvas-viewport 4 方向 pan button (ゲーム風)
           半透明 + ホバーで濃くなる。canvas-viewport は position:relative + overflow:hidden の
           static layout context のため、その中に置く absolute 子は scroll に追従しない。
           buttons は viewport 各端に張り付く。 */
        /* ▼ 反復 #35 (2026-05-10、UI 工学分析 #1): pan arrows を hover/focus 限定表示に
           常時表示は Tufte chart-junk 過多 → canvas hover or focus-within で fade-in。
           タッチデバイスは coarse pointer なので常時可視化 (touch には hover 概念なし)。 */
        .canvas-pan-pad {
            position: absolute;
            inset: 0;
            pointer-events: none;
            z-index: var(--z-canvas-overlay);
            opacity: 0;
            transition: opacity 0.2s ease;
        }
        .ccrl-canvas-frame:hover .canvas-pan-pad,
        .ccrl-canvas-frame:focus-within .canvas-pan-pad {
            opacity: 1;
        }
        @media (pointer: coarse) {
            /* touch device は常時 visible */
            .canvas-pan-pad { opacity: 1 !important; }
        }
        .canvas-pan-btn {
            position: absolute;
            pointer-events: auto;
            display: flex; align-items: center; justify-content: center;
            /* ▼ 反復 #34 hotfix #17 (2026-05-07、user 指示「半透明ボタンを長方形に」):
               旧 44×44 (正方形) → 上下: 横長 (88×32)、左右: 縦長 (32×88) に変更。
               ゲームコントローラの d-pad 風の方向性が直感的に伝わる形状。 */
            background: rgba(15, 23, 42, 0.35);
            color: rgba(255, 255, 255, 0.75);
            border: 1px solid rgba(148, 163, 184, 0.3);
            border-radius: 8px;
            backdrop-filter: blur(2px);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
            cursor: pointer;
            transition: background 0.12s ease, color 0.12s ease, transform 0.06s ease;
            user-select: none;
        }
        /* 反復 #34 hotfix #21 (2026-05-07、user 「もっと長方形に」): aspect ratio を強調。
           上下 button: 横長矩形 (120×24)、左右 button: 縦長矩形 (24×120) */
        .canvas-pan-btn.pan-up,
        .canvas-pan-btn.pan-down { width: 120px; height: 24px; }
        .canvas-pan-btn.pan-left,
        .canvas-pan-btn.pan-right { width: 24px; height: 120px; }
        .canvas-pan-btn:hover {
            background: rgba(15, 23, 42, 0.65);
            color: rgba(255, 255, 255, 1);
        }
        .canvas-pan-btn:active {
            transform: scale(0.92);
        }
        .canvas-pan-btn svg {
            width: 22px; height: 22px;
        }
        /* 4 方向の位置指定 (.canvas-pan-pad 内に absolute、各端に張り付き) */
        .canvas-pan-btn.pan-up    { top: 12px;    left: 50%; transform: translateX(-50%); }
        .canvas-pan-btn.pan-down  { bottom: 12px; left: 50%; transform: translateX(-50%); }
        .canvas-pan-btn.pan-left  { left: 12px;   top: 50%;  transform: translateY(-50%); }
        .canvas-pan-btn.pan-right { right: 12px;  top: 50%;  transform: translateY(-50%); }
        /* :active 時の transform 上書き対策 (translate を保持しつつ scale を加える) */
        .canvas-pan-btn.pan-up:active    { transform: translateX(-50%) scale(0.92); }
        .canvas-pan-btn.pan-down:active  { transform: translateX(-50%) scale(0.92); }
        .canvas-pan-btn.pan-left:active  { transform: translateY(-50%) scale(0.92); }
        .canvas-pan-btn.pan-right:active { transform: translateY(-50%) scale(0.92); }
        /* ダーク mode: border のみ強める */
        .dark .canvas-pan-btn { border-color: rgba(148, 163, 184, 0.45); }
        /* モバイル: 矩形比率を維持しつつサイズ調整 + 視認性確保 */
        @media (max-width: 768px), (pointer: coarse) {
            .canvas-pan-btn { background: rgba(15, 23, 42, 0.45); }
            .canvas-pan-btn.pan-up,
            .canvas-pan-btn.pan-down { width: 96px; height: 22px; }
            .canvas-pan-btn.pan-left,
            .canvas-pan-btn.pan-right { width: 22px; height: 96px; }
            .canvas-pan-btn svg { width: 16px; height: 16px; }
        }
        /* ▼ v45 (2026-05-15): slider 本体 24px に合わせて input range は 16px、 thumb 14px に。 */
        .canvas-zoom-slider input[type="range"] {
            width: 110px; cursor: pointer; pointer-events: auto;
            height: 16px; margin: 0; padding: 0;
        }
        .canvas-zoom-slider input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none; appearance: none;
            width: 14px; height: 14px; border-radius: 50%;
            background: #f1f5f9; cursor: pointer; border: 1px solid #94a3b8;
        }
        .canvas-zoom-slider input[type="range"]::-moz-range-thumb {
            width: 14px; height: 14px; border-radius: 50%;
            background: #f1f5f9; cursor: pointer; border: 1px solid #94a3b8;
        }
        .canvas-zoom-slider .zoom-label { font-weight: 700; color: #cbd5e1; min-width: 32px; text-align: right; font-size: 10px; }
        /* ▼ 反復 #6 後追補 v12 (2026-05-01): zoom step button (+/-) */
        /* ▼ 反復 #32 (2026-05-06、C 社 HIRI-2026-002 指摘): WCAG 2.5.5 準拠で
           モバイル touch target を 44×44 px 以上に拡張。PC では既存の visual size を
           保持するため、min-h/min-w で確保しつつ display: inline-flex で center 配置。 */
        .canvas-zoom-slider .zoom-step-btn {
            /* ▼ 反復 #35 (2026-05-10、user 指摘「操作場所がわかりにくい」): 14→16px に戻す
               ▼ 反復 #36 末尾追補 (2026-05-11、内蔵 audit UX-TINY-TARGET): 16→24px (WCAG 2.5.5 24px floor)
               ▼ v45 (2026-05-15 user 指示「スライダーの厚さを pan-btn と統一」): 24→20px に縮小
                 (slider 本体 24px 内に収めるため)。 PC ホバー操作前提なので a11y 影響は限定的。
                 touch device (mobile/coarse pointer) では下の @media で 44×44 に上書きされる。 */
            min-width: 20px; min-height: 20px;
            width: 20px; height: 20px;
            display: flex; align-items: center; justify-content: center;
            /* ▼ 反復 #35 (2026-05-08、health check A11Y-LOW-CONTRAST 1.1:1 対策):
               旧: rgba(255,255,255,0.08) 背景は親 (dark overlay) との重ね合わせで
               実効 contrast が極端に低くなっていた。明確な背景色 + 強いコントラストへ。 */
            background: rgba(255,255,255,0.18);
            color: #ffffff;
            border: 1px solid #94a3b8;
            border-radius: 3px;
            font-size: 11px; font-weight: 700;
            line-height: 1;
            cursor: pointer; pointer-events: auto;
            user-select: none;
            transition: background 0.12s ease, transform 0.06s ease;
            /* WCAG 2.5.5 (反復 #32 C 社指摘): touch device で 44×44 px 確保 */
            touch-action: manipulation;
        }
        /* ▼ v45 (2026-05-15 user 指示「スライダーの厚さを常に上下左右ボタンと同じ厚さ」):
           タッチデバイスでは pan-btn 厚さも 22px (line 471) なので、 zoom-step-btn を 44 に拡大すると
           slider はみ出し → 統一感を維持できない。
           タッチ操作はジェスチャ (ピンチ zoom) が主、 slider は補助 UI のため step-btn は 20×20 維持で
           font-size のみ拡大。 slider 全体高は @media で 22px に揃える。 */
        @media (max-width: 768px), (pointer: coarse) {
            .canvas-zoom-slider {
                height: 22px;  /* mobile / coarse pointer 時の pan-btn 厚さと統一 */
            }
            .canvas-zoom-slider .zoom-step-btn {
                font-size: 12px;
            }
            .canvas-zoom-slider .zoom-visibility-btn {
                width: 18px;
                height: 18px;
            }
            .canvas-zoom-slider input[type="range"] {
                height: 14px;
            }
        }
        .canvas-zoom-slider .zoom-step-btn:hover { background: rgba(255,255,255,0.18); }
        .canvas-zoom-slider .zoom-step-btn:active { transform: scale(0.92); }
        .dark .canvas-zoom-slider { background: rgba(15,23,42,0.92); border-color: #475569; color: #f1f5f9; }
        .dark .canvas-zoom-slider .zoom-label { color: #cbd5e1; }
        .canvas-scale-frame { position: relative; flex-shrink: 0; flex-grow: 0; flex-basis: auto; min-width: 0 !important; min-height: 0 !important; max-width: none !important; }
        .canvas-inner { position: absolute; top: 0; left: 0; transform-origin: top left; }
        .canvas-idle { position: absolute; inset: 0; pointer-events: none; z-index: var(--z-canvas); }
        .canvas-idle canvas { display: block; width: 100%; height: 100%; }
        /* ▼ 反復 #35 (2026-05-10、empty-state CTA onboarding):
           cy canvas (decedent dot) より前面に配置。z-canvas-overlay (= 7) と
           同層 (canvas-pan-pad / zoom slider と並ぶ層)。modal layer (>= 100) より下。 */
        .ccrl-empty-cta { z-index: var(--z-canvas-overlay); }
        /* ▼ 反復 #38 末尾追補 v72 (2026-05-19 user 指示「最初の操作が終わるまで、
           D&D ができることがわかるアニメーション」): D&D ヒント (ゴーストドラッグデモ)。
           #ccrl-dd-hint は position:fixed の 0×0 アンカー点 (left/top は app.js
           positionDdHint() が「人物を追加」グリッド中心に設定)。子要素は absolute 配置。
           ghost が「つかむ→canvas 方向 (--dd-dx/--dd-dy) へドラッグ→離す」をループ再生。
           pointer-events:none で操作を一切妨げない。z は sticky パネルより前・modal より後。 */
        #ccrl-dd-hint {
            position: fixed;
            left: 0; top: 0;
            width: 0; height: 0;
            z-index: var(--z-dd-hint);
            pointer-events: none;
        }
        .ccrl-dd-ghost {
            position: absolute;
            left: 0; top: 0;
            width: 46px; height: 46px;
            border-radius: 9999px;
            display: flex; align-items: center; justify-content: center;
            color: #fff;
            background: linear-gradient(135deg, #10b981, #0d9488);
            box-shadow: 0 8px 18px rgba(13,148,136,.45), 0 0 0 5px rgba(16,185,129,.18);
            will-change: transform, opacity;
            /* v72: 2.8s → 3.4s。user 指示で clamp 撤廃し canvas 内まで travel するため、
               移動距離が伸びた分 duration を延ばしドラッグを読み取りやすい速度に保つ。 */
            animation: ccrl-dd-drag 3.4s ease-in-out infinite;
        }
        .ccrl-dd-ghost svg { width: 26px; height: 26px; }
        .ccrl-dd-caption {
            position: absolute;
            left: 0; top: 0;
            transform: translate(-50%, calc(-50% - 56px));
            display: flex; align-items: center; gap: 4px;
            white-space: nowrap;
            padding: 5px 11px;
            border-radius: 9999px;
            background: #059669;
            color: #fff;
            font-size: 11px;
            font-weight: 700;
            letter-spacing: .02em;
            box-shadow: 0 4px 12px rgba(0,0,0,.24);
            animation: ccrl-dd-caption-pulse 3.4s ease-in-out infinite;
        }
        .ccrl-dd-caption svg { width: 13px; height: 13px; flex-shrink: 0; }
        /* ghost が「人物を追加」グリッド (起点) で出現→つかむ→canvas 中心 (--dd-dx/--dd-dy)
           まで drag→drop pop→fade、を 3.4s でループ。drag 区間 (14%→64% = 1.7s) を長めに
           取り、 canvas まで届く長距離移動でも読み取れる速度を確保。 */
        @keyframes ccrl-dd-drag {
            0%   { transform: translate(-50%,-50%) scale(.6);  opacity: 0; }
            6%   { transform: translate(-50%,-50%) scale(1);   opacity: 1; }
            14%  { transform: translate(-50%,-50%) scale(.84); opacity: 1; }
            62%  { transform: translate(calc(-50% + var(--dd-dx,-120px)), calc(-50% + var(--dd-dy,28px))) scale(.84); opacity: 1; }
            70%  { transform: translate(calc(-50% + var(--dd-dx,-120px)), calc(-50% + var(--dd-dy,28px))) scale(1.14); opacity: 1; }
            77%  { transform: translate(calc(-50% + var(--dd-dx,-120px)), calc(-50% + var(--dd-dy,28px))) scale(.97); opacity: 1; }
            89%  { transform: translate(calc(-50% + var(--dd-dx,-120px)), calc(-50% + var(--dd-dy,28px))) scale(1);   opacity: 1; }
            95%  { transform: translate(calc(-50% + var(--dd-dx,-120px)), calc(-50% + var(--dd-dy,28px))) scale(.9);  opacity: 0; }
            100% { transform: translate(-50%,-50%) scale(.6); opacity: 0; }
        }
        @keyframes ccrl-dd-caption-pulse {
            0%, 100% { opacity: .45; }
            8%, 72%  { opacity: 1; }
        }
        /* prefers-reduced-motion: ループ animation を停止し ghost を起点 (ボタン上) に静止表示。
           caption (← ドラッグして家族を追加) と合わせ「ここからドラッグ可」を動きなしで伝える。 */
        @media (prefers-reduced-motion: reduce) {
            .ccrl-dd-ghost {
                animation: none;
                transform: translate(-50%,-50%) scale(.96);
                opacity: .95;
            }
            .ccrl-dd-caption { animation: none; opacity: 1; }
        }
        /* ▼ 反復 #35 末尾追補 (2026-05-10、user 指摘「横スクロール解消」):
           help-tip 自体は relative + inline-block。tooltip (absolute child) の
           scrollWidth 影響を最小化するため contain で layout を isolate。 */
        .help-tip { position: relative; display: inline-block; cursor: help; margin-left: 4px; color: #94a3b8; contain: layout; }
        .help-tip:hover { color: #0ea5e9; }
        /* ▼ 反復 #26-A (v0.8.70): .help-tip-text も canvas card 風スタイルに統一 */
        .help-tip-text {
            visibility: hidden;
            width: 220px;
            background: rgba(30, 41, 59, 0.97);
            color: #f1f5f9;
            text-align: left;
            border-radius: 12px;
            padding: 10px 16px;
            position: absolute;
            z-index: var(--z-popover);
            bottom: 125%;
            left: 50%;
            transform: translateX(-50%);
            opacity: 0;
            transition: opacity 0.14s ease-out;
            font-size: 12px;
            font-weight: 500;
            font-family: system-ui, sans-serif;
            line-height: 1.55;
            border: 1px solid rgba(148, 163, 184, 0.35);
            box-shadow: 0 12px 28px -8px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.06);
        }
        .help-tip-text::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: rgba(30, 41, 59, 0.97) transparent transparent transparent; }
        /* ▼ 反復 #35 末尾追補 (2026-05-10): 右端付近の help-tip 用に right-anchored variant。
           「現在の相続状況」 badge の (直系卑属) tooltip 等、viewport 右端でクロップしないように。 */
        .help-tip.help-tip-anchor-right .help-tip-text { left: auto; right: 0; transform: none; }
        .help-tip.help-tip-anchor-right .help-tip-text::after { left: auto; right: 12px; margin-left: 0; }

        /* ============================================================
           ▼ 反復 #26-E (v0.8.70): ダイアログ UI 統一規約 (ADR 0040)
           ============================================================
           17 modal を共通スタイルに揃え、新規 modal も同パターンで作る.
           以下のクラスを使えば、bg / padding / border / shadow が自動で揃う:

           - .ccrl-dialog-overlay : overlay (fixed inset-0 + bg + backdrop-blur)
           - .ccrl-dialog-card    : modal 本体 (rounded-2xl + shadow + border + theme)
           - .ccrl-dialog-header  : title bar (gradient bg + flex layout)
           - .ccrl-dialog-body    : 中身 (scroll 領域、padding)
           - .ccrl-dialog-footer  : action button 行 (border-t + bg)

           Tailwind class との併用前提 (header gradient 色は per-modal で変えて OK)。
           ============================================================ */
        .ccrl-dialog-overlay {
            position: fixed;
            inset: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 1rem;
            background: rgba(15, 23, 42, 0.6);
            backdrop-filter: blur(4px);
        }
        .ccrl-dialog-card {
            border-radius: 1rem;       /* rounded-2xl */
            box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
            width: 100%;
            max-width: 32rem;          /* max-w-lg を default、個別 modal で上書き可 */
            overflow: hidden;
            display: flex;
            flex-direction: column;
            border: 1px solid rgba(226, 232, 240, 1);  /* slate-200 */
            background: #ffffff;
            max-height: 90vh;
        }
        .dark .ccrl-dialog-card,
        body.dark .ccrl-dialog-card {
            background: rgb(30, 41, 59);  /* slate-800 */
            border-color: rgb(51, 65, 85);  /* slate-700 */
        }
        .ccrl-dialog-header {
            padding: 1rem;
            color: #ffffff;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-weight: bold;
        }
        .ccrl-dialog-header h3 {
            font-size: 1rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
            margin: 0;
        }
        .ccrl-dialog-body {
            padding: 1.25rem;
            overflow-y: auto;
            color: rgb(51, 65, 85);  /* slate-700 */
            flex: 1;
        }
        .dark .ccrl-dialog-body,
        body.dark .ccrl-dialog-body {
            color: rgb(226, 232, 240);  /* slate-200 */
        }
        .ccrl-dialog-footer {
            padding: 0.75rem 1.25rem;
            display: flex;
            gap: 0.5rem;
            justify-content: flex-end;
            border-top: 1px solid rgb(226, 232, 240);
            background: rgb(248, 250, 252);  /* slate-50 */
        }
        .dark .ccrl-dialog-footer,
        body.dark .ccrl-dialog-footer {
            border-top-color: rgb(51, 65, 85);
            background: rgba(30, 41, 59, 0.5);
        }
        .help-tip:hover .help-tip-text { visibility: visible; opacity: 1; }

        /* ▼ 提出用（白黒）モード専用スタイル ▼ */
        .canvas-print-mode {
            --tree-line-color: #000 !important;
            background-color: #fff !important;
        }
        .canvas-print-mode * { border-color: #000 !important; color: #000 !important; box-shadow: none !important; }
        .canvas-print-mode [class*="bg-"]:not(.canvas-print-mode-show) { background-color: #fff !important; }
        .canvas-print-mode .rounded-2xl, .canvas-print-mode .rounded-xl { border-radius: 0 !important; border-width: 1px !important; }
        .canvas-print-mode .hide-in-print, .canvas-print-mode button, .canvas-print-mode svg, .canvas-print-mode .help-tip { display: none !important; }
        .canvas-print-mode-show { display: none; }
        .canvas-print-mode .canvas-print-mode-show { display: block !important; }
        .canvas-print-mode .print-name { border: none !important; font-size: 12px !important; font-weight: bold !important; text-decoration: none !important; }
        .canvas-print-mode .node-container { padding: 12px 16px !important; min-width: 90px !important; }
        .canvas-print-mode .couple-connector::before { border-color: #000 !important; }
        .canvas-print-mode .pointer-events-none.opacity-50 { display: none !important; }
        /* 公文書出力時は max-width / truncate を解除して、長い氏名・住所を省略せず全文表示する。
           PDF / 法務局提出書類で「長男 田中…」のような省略表示は法的に無効になりかねない。 */
        .canvas-print-mode .node-container { max-width: none !important; }
        .canvas-print-mode .truncate { overflow: visible !important; white-space: normal !important; text-overflow: clip !important; word-break: break-all !important; }
        /* 印刷モードでは .node-container の padding が増えてアイコン縦寸が大きくなる。
           固定値の mt-[18px] では connector が脱臼して中心からズレるため、印刷時は 26px に補正。 */
        .canvas-print-mode .ex-spouse-connector,
        .canvas-print-mode .recognized-mother-connector { margin-top: 26px !important; }

        /* ▼ ホバーで現れるアクションUI（PC時のみ） ▼ */
        .node-action { opacity: 0; transition: opacity 0.15s ease; pointer-events: auto; }
        .node-container:hover .node-action, .node-container:focus-within .node-action { opacity: 1; }
        @media (hover: none) { .node-action { opacity: 1 !important; } }

        /* ▼ トースト通知 ▼ */
        /* ▼ 反復 #35 (2026-05-10、user 指摘「右下のノーティスは注とかぶる」):
           toast は default 右下 (bottom:20 right:20) で sidebar の 注 footer (右下に位置) と重なる。
           bottom-center に再配置 → sidebar / canvas どちらにも干渉せず、視認性も向上。 */
        .toast-container {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%) translateZ(0);
            z-index: var(--z-toast);
            display: flex;
            flex-direction: column-reverse;
            gap: 10px;
            pointer-events: none;
            max-width: min(480px, calc(100vw - 40px));
            will-change: transform;
            align-items: center;
        }
        @media (max-width: 640px) {
            .toast-container { bottom: 90px; left: 16px; right: 16px; transform: none; max-width: none; }
        }

        /* ▼ ノードアクションメニュー ▼ */
        /* ▼ 反復 #6 v28 (妥当な指摘 #10-1 60fps 最適化):
             position: fixed の要素を GPU layer に昇格し、scroll/zoom 中の repaint を抑制。
             will-change は対象を絞らないと memory 圧迫するため、transformed 要素のみに付与。 */
        .node-menu { position: fixed; z-index: var(--z-node-menu); min-width: 160px; border-radius: 12px; overflow: hidden; box-shadow: 0 20px 35px -10px rgba(0,0,0,0.25); will-change: transform; transform: translateZ(0); }
        .node-menu button { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 12px; font-size: 12px; font-weight: bold; text-align: left; transition: background-color 0.1s; }

        /* ▼ 反復 #2 (3回目 v3): 待合室アイコンの脈動アニメ
           cytoscape-integration.js animateMoveNodeToHome / animateRestoreFromHome が
           class を追加 / 削除して、視覚的な「受け入れ」「送り出し」を演出する。 */
        @keyframes ccrlHomePulse {
            0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.6); }
            50% { transform: scale(1.22); box-shadow: 0 0 0 12px rgba(245, 158, 11, 0.45); }
            100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
        }
        /* ▼ 反復 #2 (3回目 v3): ユーザー指摘で 0.5s → 0.8s に */
        .ccrl-home-pulsing { animation: ccrlHomePulse 0.8s ease-in-out !important; }

        /* ▼ 反復 #35 (2026-05-10、user 指摘「右下の出力ボタンはいらない」): FAB CSS を撤去。
           sidebar tools panel の出力 button で代替。 */

        /* ▼ 反復 #35 (2026-05-10、Mobile UX 監査 #1): touch device で w-6 h-6 (24px) 以下の button が
           HID minimum 44px を下回る問題への対策。pointer:coarse のみ適用 → desktop mouse では現状維持。 */
        @media (pointer: coarse) {
            button.w-4.h-4.rounded-full {
                min-width: 32px !important;
                min-height: 32px !important;
            }
            button.w-5.h-5.rounded-full {
                min-width: 28px !important;
                min-height: 28px !important;
            }
            button.w-6.h-6.rounded-full {
                min-width: 32px !important;
                min-height: 32px !important;
            }
            /* ▼ 反復 #38 末尾追補 v92.6 (2026-05-21 user 指摘「タブレット横表示でスライダーの +−が
               飛び出ている。 大きさをスライダー(の高さ)に依存させたい」):
               旧: coarse pointer で zoom-step-btn を min 32px に拡大していたが、 slider 本体は
               v45 で 22px の薄ピル化されており (下記 @media(max-width:768px),(pointer:coarse))、
               32px のボタンが pill から上下に約 10px はみ出していた (タブレット=coarse pointer で発生)。
               v45 の設計判断 (step-btn は 20×20 維持・ ピンチzoom が主操作・ slider は補助 UI) に従い、
               coarse での 32px 強制を撤去。 ボタンは slider の高さ内に収まる 20px を維持する。
               (タッチターゲットの実効領域は touch-action: manipulation + 周辺 padding で確保) */
        }

        /* ▼ 反復 #35 (2026-05-10、A11y 監査 #2): text-slate-500 (4.54:1 borderline) / text-slate-400 (3.15:1 fail)
           を WCAG AA 4.5:1 通過する slate-600 / slate-700 に bump (light mode のみ、dark mode は適切)。
           ターゲット: bg-white / bg-slate-50 (薄背景) 上の slate-400/500 テキスト。 */
        body:not(.dark) .text-slate-400 {
            color: rgb(75, 85, 99) !important;  /* slate-600: 7.0:1 contrast */
        }
        body:not(.dark) .text-slate-500 {
            color: rgb(51, 65, 85) !important;  /* slate-700: 9.8:1 contrast */
        }
        /* ただし dark bg 上では薄い slate を維持 (反転で見やすくなるため) */
        body:not(.dark) .bg-slate-700 .text-slate-400,
        body:not(.dark) .bg-slate-800 .text-slate-400,
        body:not(.dark) .bg-slate-900 .text-slate-400 {
            color: rgb(148, 163, 184) !important;  /* original slate-400 */
        }
        body:not(.dark) .bg-slate-700 .text-slate-500,
        body:not(.dark) .bg-slate-800 .text-slate-500,
        body:not(.dark) .bg-slate-900 .text-slate-500 {
            color: rgb(100, 116, 139) !important;  /* original slate-500 */
        }

/* ▼ 反復 #35 (2026-05-10、user 指摘「rose だと差別化できない、別案を」):
             旧 rose-300 (button と同系色 → コントラスト不足) → sky-cyan ring + scale。
             button bg: rose、ring: sky-300 で WCAG コントラスト確保 + 即視認可能。
             scale 1 → 1.03 の微弱 zoom と組合わせ、目を惹くが攻撃的でない 「呼吸」リズム。
             prefers-reduced-motion: アニメ無効化、静的 ring のみ残す。 */
        @keyframes ccrl-close-pulse {
            0%, 100% {
                transform: scale(1);
                box-shadow: 0 0 0 0 rgba(125, 211, 252, 0.0),
                            0 1px 2px rgba(0, 0, 0, 0.04);
            }
            50% {
                transform: scale(1.025);
                box-shadow: 0 0 0 5px rgba(125, 211, 252, 0.45),  /* sky-300 outer ring */
                            0 4px 14px rgba(56, 189, 248, 0.25);   /* sky-400 soft glow */
            }
        }
        .ccrl-close-pulse {
            animation: ccrl-close-pulse 2.6s ease-in-out infinite;
        }
        /* dark mode 用は sky-400 ring + 強めの glow */
        .dark .ccrl-close-pulse {
            animation-name: ccrl-close-pulse-dark;
        }
        @keyframes ccrl-close-pulse-dark {
            0%, 100% {
                transform: scale(1);
                box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.0),
                            0 1px 2px rgba(0, 0, 0, 0.18);
            }
            50% {
                transform: scale(1.025);
                box-shadow: 0 0 0 5px rgba(56, 189, 248, 0.40),
                            0 4px 14px rgba(14, 165, 233, 0.30);
            }
        }
        @media (prefers-reduced-motion: reduce) {
            .ccrl-close-pulse,
            .dark .ccrl-close-pulse {
                animation: none !important;
                /* 静的 sky ring (薄め) + 弱い glow で位置を伝える */
                box-shadow: 0 0 0 2px rgba(125, 211, 252, 0.5) !important;
                transform: none !important;
            }
        }

        /* ▼ 反復 #35 (2026-05-10、user 指摘「戻る/進む は 家系図キャンバス の右横」):
             floating top-left bar から canvas heading inline 配置に変更。
             コンテキスト直近 = canvas 編集と直結。 inline 表示 (h2 の右横) で発見性 + 操作直感性を改善。 */
        /* ▼ 反復 #36 末尾追補 part 2 (2026-05-11、内蔵 audit UX-TINY-TARGET 残対応):
           ccrl-canvas-toolbar 内の button (表示 / 全体表示 / 待合室 / 対象外を退避 等) は
           py-1.5 を class で指定しても flex 内で height 21px に collapse する。
           直接 min-height: 24px を強制して WCAG 2.5.5 24px floor を達成。 */
        .ccrl-canvas-toolbar button {
            min-height: 24px;
        }
        /* ▼ 反復 #36 末尾追補 (2026-05-11、内蔵 audit UX-TINY-TARGET):
           padding 2px → 4px で 21px → 24px floor (WCAG 2.5.5 推奨最低タップ target) */
        .ccrl-history-btn-inline {
            display: inline-flex;
            align-items: center;
            gap: 3px;
            padding: 4px 6px;
            min-height: 24px;
            font-size: 10px;
            font-weight: bold;
            border-radius: 6px;
            border: 1px solid;
            transition: background-color 0.15s, color 0.15s, border-color 0.15s;
            cursor: pointer;
            background: transparent;
        }
        .ccrl-history-btn-inline-light {
            color: #475569;
            border-color: #e2e8f0;
            background: #f8fafc;
        }
        .ccrl-history-btn-inline-light:hover:not(:disabled) {
            background: #f1f5f9;
            color: #0f172a;
            border-color: #cbd5e1;
        }
        .ccrl-history-btn-inline-dark {
            color: #cbd5e1;
            border-color: #475569;
            background: rgba(15, 23, 42, 0.6);
        }
        .ccrl-history-btn-inline-dark:hover:not(:disabled) {
            background: rgba(51, 65, 85, 0.85);
            color: #f1f5f9;
            border-color: #64748b;
        }
        .ccrl-history-btn-inline:disabled {
            opacity: 0.3;
            cursor: not-allowed;
        }
        .ccrl-history-btn-inline svg {
            flex-shrink: 0;
        }
        @media print {
            .ccrl-history-inline-bar { display: none !important; }
        }

        /* ▼ プレゼンモード: ツールバー・各種 × ボタン・＋枠などを非表示にして、D&D も無効化 ▼
           反復 #2 (3回目) 強化: 「キャンバスのみで操作可能」状態を実現するため:
             - .hide-in-present 要素の非表示
             - キャンバスを PC / タブレット 画面いっぱいに拡張 (横幅・高さ・余白除去)
             - 編集ボタン (×・✎・△) は隠すが、キャンバス自体の操作 (zoom / pan / クリック /
               radial menu) はそのまま生きる。
        */
        .present-mode .hide-in-present { display: none !important; }
        .present-mode .node-action { display: none !important; }
        .present-mode .draggable-item { pointer-events: none !important; opacity: 0.4; }
        .present-mode [draggable="true"] { -webkit-user-drag: none; user-drag: none; }
        /* ▼ ページの余白・親要素の幅制約を解除 (画面端まで使い切る) */
        html.present-mode, .present-mode body {
            padding: 0 !important; margin: 0 !important;
            width: 100vw !important; min-height: 100vh !important;
            overflow: hidden !important;
        }
        .present-mode main,
        .present-mode .max-w-7xl,
        .present-mode .container,
        .present-mode .mx-auto {
            max-width: 100vw !important;
            width: 100vw !important;
            padding: 0 !important;
            margin: 0 !important;
        }
        /* ▼ 反復 #35 (2026-05-10、user 指示「全画面モードでも広告掲載は維持」+
             「スライダーとマップの配置を美しく」):
             旧版は canvas を 100vw で占有させていたが、それだと広告枠 (左右 160px) と重なる。
             新方針: ad-layout-wrapper の flex で 広告 + canvas が並ぶ自然 layout を維持し、
             canvas は flex:1 で「広告以外の領域」を取る。
             canvas-frame は position:fixed ではなく flex 子として配置することで広告を覆わない。 */
        .present-mode .ad-layout-wrapper {
            height: 100vh !important;
            width: 100vw !important;
            max-width: 100vw !important;
            align-items: center !important;
            justify-content: center !important;
            gap: 8px !important;          /* ad と canvas の間に最小ギャップ */
            padding: 0 !important;
            margin: 0 !important;
        }
        .present-mode #main-content {
            flex: 1 1 auto !important;
            display: block !important;
            grid-template-columns: none !important;
            grid-template-rows: none !important;
            grid-template-areas: none !important;
            height: 100vh !important;
            max-height: 100vh !important;
            padding: 0 !important;
            margin: 0 !important;
            overflow: hidden !important;
            min-width: 0 !important;       /* flex 子で縮小可能 */
        }
        .present-mode .ccrl-canvas-frame {
            height: 100vh !important;
            width: 100% !important;        /* #main-content (flex:1) の幅をフル占有 */
            max-width: none !important;
            min-height: 100vh !important;
            border-radius: 0 !important;
            border: none !important;        /* 枠線も消す */
            padding: 0 !important;          /* canvas を画面いっぱいに */
            box-shadow: none !important;
            margin: 0 !important;
            position: relative !important;  /* zoom slider / minimap の absolute pin の起点 */
        }
        /* ▼ キャンバスの内側 ccrl-cy-chart-container を flex で全領域占有 */
        .present-mode #ccrl-cy-chart-container,
        .present-mode #ccrl-cy-chart-container > div {
            min-height: 100% !important;
            height: 100% !important;
            width: 100% !important;
            flex: 1 1 auto !important;
        }
        /* ▼ <main> 親 grid / Subject / 詳細パネル系の bottom margin を削除 */
        .present-mode .mb-6 { margin-bottom: 0 !important; }
        .present-mode .mb-3 { margin-bottom: 0 !important; }
        .present-mode .mb-4 { margin-bottom: 0 !important; }

        /* ▼ 反復 #35 (2026-05-10、user 指摘「全画面で巨大ピル化バグ」修正):
             旧 CSS は親 .canvas-zoom-slider が `flex-wrap: wrap` + max-width: calc(100% - 48px)
             を持つため、`position: fixed; left: 50%; transform: translateX(-50%)` の context で
             子要素が縦に折返し → 縦長ピルになっていた。
             修正: width auto + nowrap + 明示的 max-width 上限 + flex 子要素の幅固定。 */
        .present-mode .canvas-zoom-slider {
            position: fixed !important;
            bottom: 16px !important;
            left: 50% !important;
            transform: translateX(-50%) !important;
            z-index: 8 !important;
            background: rgba(15, 23, 42, 0.85) !important;
            backdrop-filter: blur(8px) !important;
            -webkit-backdrop-filter: blur(8px) !important;
            border: 1px solid rgba(148, 163, 184, 0.3) !important;
            border-radius: 9999px !important;
            padding: 6px 14px !important;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
            color: #e2e8f0 !important;
            /* ▼ flex-wrap を強制 nowrap、width を auto (内容で fit) + max-width 制限 */
            display: inline-flex !important;
            flex-wrap: nowrap !important;
            width: auto !important;
            max-width: min(420px, calc(100vw - 32px)) !important;
            min-width: 0 !important;
            height: auto !important;
            top: auto !important;
            right: auto !important;
            gap: 8px !important;
            align-items: center !important;
        }
        /* slider input は flex 縮小を許可、btn 群は flex-shrink: 0 で潰さない */
        .present-mode .canvas-zoom-slider input[type="range"] {
            flex: 1 1 auto !important;
            width: auto !important;
            min-width: 100px !important;
            max-width: 200px !important;
        }
        .present-mode .canvas-zoom-slider .zoom-step-btn,
        .present-mode .canvas-zoom-slider .zoom-label {
            flex-shrink: 0 !important;
        }
        .present-mode .canvas-zoom-slider .zoom-label {
            color: #cbd5e1 !important;
            font-weight: bold !important;
        }
        .present-mode .canvas-zoom-slider .zoom-step-btn {
            background: rgba(51, 65, 85, 0.85) !important;
            color: #f1f5f9 !important;
            border-color: rgba(148, 163, 184, 0.4) !important;
        }
        .present-mode .canvas-zoom-slider .zoom-step-btn:hover {
            background: rgba(71, 85, 105, 0.95) !important;
        }
        /* minimap (#ccrl-minimap) は inline style で position:absolute right:12px bottom:72px。
           全画面では bottom を上げてズームスライダー (bottom:16px + ~40px 高) と縦に重ならないよう調整 */
        .present-mode #ccrl-minimap {
            bottom: 80px !important;
            right: 16px !important;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4) !important;
            border: 1px solid rgba(148, 163, 184, 0.4) !important;
        }

        /* ▼ ファイルD&Dインポート: ハイライト ▼ */
        .file-drop-active { box-shadow: 0 0 0 3px rgba(16,185,129,0.7) !important; border-color: #10b981 !important; }
        .file-drop-overlay { position: fixed; inset: 0; background: rgba(16,185,129,0.08); border: 3px dashed #10b981; z-index: var(--z-file-drop); pointer-events: none; display: flex; align-items: center; justify-content: center; }
        .file-drop-overlay .msg { background: #fff; padding: 16px 24px; border-radius: 12px; font-weight: bold; color: #059669; box-shadow: 0 10px 30px rgba(0,0,0,0.2); }

        /* （旧フローティングメニュー CSS は右側サイドバーに統合したため削除。プレゼン中のみ表示する
           「プレゼン終了」ボタンだけインライン fixed で残してある） */

        /* ▼ 反復 #35 (2026-05-08、user 指摘「プレゼンモードは破綻しています」):
           旧 .present-mode は canvas frame の高さを 100vh に拡張するだけで、内部の
           toolbar / 凡例 / pan button / 広告枠 を隠す指定が漏れていた。
           hide-in-present class の追加 + 補強 CSS で完全な「キャンバスのみ」状態を実現。 */
        .present-mode .ccrl-canvas-frame {
            padding: 0 !important;            /* 余白完全除去 (キャンバスを画面いっぱいに) */
        }
        /* canvas frame の中身 (cy + viewport) を画面いっぱい */
        .present-mode .ccrl-canvas-frame > .canvas-viewport,
        .present-mode .canvas-viewport {
            width: 100% !important;
            height: 100% !important;
        }
        /* canvas-frame 内の zoom slider はプレゼン用にも便利なので残す。 */
        /* 凡例 (生存/先に死亡 等) はインライン span のため hide-in-present 親 div で消える */

        /* スマホ画面 (<= 640px) でのツールチップ大はみ出し対策。
           デフォルトの left:50% + transform:translateX(-50%) は、画面右端の「？」アイコン上で
           吹き出し (200px) が画面外に突き抜けて文字が切れる/横スクロールバー出現の原因になる。
           モバイルでは左右の絶対 px 制約に変更し、必ず viewport 内に収まるようにする。 */
        @media (max-width: 640px) {
            .help-tip-text {
                left: auto !important;
                right: -10px !important;
                transform: none !important;
            }
            .help-tip-text::after {
                left: auto !important;
                right: 15px !important;
                margin-left: 0 !important;
            }
        }

        /* =========================================================
         * ゲームフィール風のマイクロインタラクション
         *   1. success-pulse  : ドロップ成功時の緑の輪 (0.6s, 1 回)
         *   2. error-shake    : 保存バリデーション失敗時の横振動 (0.35s, 1 回)
         * 共に prefers-reduced-motion を尊重して動きを無効化。
         * ========================================================= */
        @keyframes success-pulse {
            0%   { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.55); }
            70%  { box-shadow: 0 0 0 14px rgba(16, 185, 129, 0); }
            100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
        }
        .success-pulse {
            animation: success-pulse 0.6s ease-out 1;
        }
        @keyframes error-shake {
            0%, 100% { transform: translateX(0); }
            15%      { transform: translateX(-4px); }
            30%      { transform: translateX(4px); }
            45%      { transform: translateX(-3px); }
            60%      { transform: translateX(3px); }
            75%      { transform: translateX(-2px); }
            90%      { transform: translateX(2px); }
        }
        .error-shake {
            animation: error-shake 0.35s cubic-bezier(0.36, 0.07, 0.19, 0.97) 1;
        }
        @media (prefers-reduced-motion: reduce) {
            .success-pulse, .error-shake { animation: none !important; }

            /* ▼ 反復 #32 (v0.9.0): a11y 強化 — prefers-reduced-motion 全面対応
             *   WCAG 2.3.3 (Animation from Interactions) + a11y 反復 #30-D の延長。
             *   OS / Browser で「動きを減らす」設定を ON にしているユーザー向け:
             *     - めまい/前庭障害のある利用者
             *     - 司法書士事務所等で長時間使う利用者の視覚疲労軽減
             *   全 transition / animation を停止 (highlight 等の機能性は残す)。
             */
            *,
            *::before,
            *::after {
                animation-duration: 0.01ms !important;
                animation-iteration-count: 1 !important;
                transition-duration: 0.01ms !important;
                scroll-behavior: auto !important;
            }
            /* Toast の slide-in 等を瞬時に */
            .toast-container > * {
                transition: none !important;
            }
            /* Cytoscape は JS 駆動なので CSS では制御不可だが、
             *   layoutAnimation を無効化する hint として data 属性付け
             *   (将来 cy 側で読む可能性のため preserve) */
            #cy[data-reduced-motion="1"] { /* placeholder for future JS use */ }
        }

        /* =========================================================
         * D&D 兄弟ゴースト結界: ゴースト挿入時の線の暴走と幅計算汚染を防ぐ
         *
         * 問題:
         *   dragAction==='add_sibling' 時に <div class="tree-child ghost-slot">
         *   がトップレベル .tree-children の最初に挿入される。これにより:
         *   (1) :first-of-type はタグ名ベースでマッチするためゴーストが奪取。
         *       結果、本来の先頭兄弟が「中央の兄弟」扱いになり ::after が
         *       left:0 width:100% で描かれ、黒い横線がゴースト側へ暴走する。
         *   (2) :last-of-type は奪われない (decedent-tc が常に最後) が、
         *       ゴースト自身の ::after は first-of-type 規則で描画され、
         *       ゴースト↔隣接 sibling の接続が視覚的に重複する。
         *
         * 対策: ゴーストを挿入しても、
         *   - 本来の先頭 sibling (= ゴースト直後) を first-of-type として描画
         *   - ゴースト自身の線は緑半透明に変更 (黒線の上書き)
         *   - recalcAnchorLayout 側で .ghost-slot を width 計算から除外 (JS 側)
         * ========================================================= */
        /* (1) ゴースト直後の real sibling を first-of-type と同じ描画に矯正 */
        .tree-child.ghost-slot + .tree-child:not(:last-of-type)::after {
            left: 50% !important;
            width: 50% !important;
        }
        /* (1-b) ゴースト + 1 人の real sibling (= decedent-tc) のみの場合
         *      → 本来は兄弟が 1 人だけなので横線は不要。decedent-tc の ::after を消す。
         *      ※ decedent-tc は :last-of-type マッチのため、:not(:last-of-type) では拾えない */
        .tree-child.ghost-slot:first-child + .tree-child[data-decedent-tc]:last-of-type::after {
            display: none !important;
        }
        /* (2) ゴースト自身の線 (::before 縦線・::after 横線) を緑半透明に。
         *     opacity は親 div の opacity-0 / opacity-60 によって継承される (inherit)。
         *     ゴースト非表示時は親の opacity で全て透明化される。 */
        .tree-child.ghost-slot::before,
        .tree-child.ghost-slot::after {
            background: #34d399 !important;
        }

        /* =========================================================
         * Phase 6: モバイル UX — WCAG 2.5.5 (Target Size) 準拠のタップ領域拡張
         *
         * 設計方針:
         *   - 可視サイズは据え置き (w-5 h-5 = 20×20px のまま) で見た目を崩さない
         *   - タッチデバイス (@media (pointer: coarse)) 限定でタップ領域を
         *     44×44px に拡張する (WCAG AAA でも推奨の 44×44)
         *   - ::before 擬似要素で透明なヒット領域を重ねる方式を採用
         *     → ボタン本体の visual style (丸型・枠線) は変わらず、
         *       タップ判定だけ約 2 倍の面積で取れる
         *   - touch-action: manipulation でダブルタップズームを抑制
         *     (連打・スワイプ操作で意図しない拡大が入るのを防止)
         *
         * 対象: .node-action 共通クラスを付けた全ノード操作ボタン
         *   (⋯メニュー / ×削除 / ✏️編集 / 配偶者編集 / 配偶者削除)
         * ========================================================= */
        @media (pointer: coarse) {
            .node-action {
                position: relative;
                touch-action: manipulation;
            }
            .node-action::before {
                content: '';
                position: absolute;
                inset: -12px; /* 20 + 12*2 = 44px hit area */
                z-index: -1;
                /* 透明: 視覚的には見えない。ヒット領域だけ確保 */
            }
            /* validation-icon (! バッジ) も小さい (10px) ので拡張 */
            .validation-icon {
                position: relative;
                touch-action: manipulation;
            }
            .validation-icon::after {
                content: '';
                position: absolute;
                inset: -16px; /* 10 + 16*2 ≈ 42px (44 相当) */
                z-index: -1;
            }
        }

        /* =========================================================
         * Phase 6: タッチ操作共通 — ダブルタップズーム抑制
         *
         * モバイル Safari / Chrome は 300ms 以内の 2 回タップをダブルタップ
         * (ズーム操作) と解釈する。法律文書編集ツールでは意図しないズームが
         * 入るとカードが突然拡大して操作不能になる地雷源なので、
         * インタラクティブ要素には一律 touch-action: manipulation を推奨。
         * ========================================================= */
        button, a, [role="button"], [role="group"][tabindex="0"], [role="dialog"] button,
        .toast-container > * {
            touch-action: manipulation;
        }
        /* ただし D&D 対象は touch-action: none (既存) を優先する必要があるため、
           .draggable-item / [draggable="true"] には上記を適用しない。
           CSS 詳細度: [draggable="true"] の既存ルール (L85) が勝つ。 */

        /* =========================================================
         * Phase 6: タブレット (768px+) / PC (1024px+) 向けブレークポイント
         *
         * 現状は 640px (max-width) 以下と以上の 2 段階しか考慮されていないため、
         * タブレット (iPad 768px) で「モバイル UI のまま拡大」された窮屈な
         * 表示になっていた。以下で中間層を追加:
         *
         *   - 768px+: トースト最大幅を広げる / 操作メニュー min-width 拡大
         *   - 1024px+: (将来拡張用プレースホルダ)
         * ========================================================= */
        @media (min-width: 768px) {
            .toast-container {
                max-width: min(480px, calc(100vw - 40px));
            }
            .node-menu {
                min-width: 200px;
            }
        }
        /* =========================================================
         * Phase 1 テーマ切替 (反復 #5 末尾追補 2026-04-30)
         *
         * ユーザー指示: 「今のものとＡＢＣを選択できるようにできますか？
         *                  操作性は絶対に変更しないでください。」
         *
         * 設計原則 (絶対遵守):
         *   - position / size / display / cursor / pointer-events / z-index は不変
         *   - クリック領域・バッジサイズ・メニュー構造には一切触れない
         *   - 触っていいプロパティ: font-family / color / background / border-color /
         *     box-shadow / letter-spacing / filter (saturate のみ)
         *
         * 3 テーマ (bauhaus は 2026-04-30 撤去 — 死亡者グレーアウトと重複):
         *   .theme-default — 現状維持 (no-op、本ファイル他箇所の Tailwind 配色がそのまま生きる)
         *   .theme-wa      — 和風モダン (明朝 + 生成 #f5f3ec / 蘇芳 #9b1c2c アクセント)
         *   .theme-scroll  — 巻物伝統 (明朝 + 牛乳色 #faf6e8 / 金茶 #b8a565 アクセント)
         *
         * 適用範囲は Phase 1 で「body 周辺の雰囲気」のみ。Cytoscape 内部 stylesheet や
         * 個別の Tailwind colored class は触らない (Phase 2 以降)。
         * ========================================================= */

        /* ---- A. 和風モダン (theme-wa) ---- */
        body.theme-wa {
            font-family: 'Noto Serif JP', 'Yu Mincho', '游明朝', 'Hiragino Mincho ProN', '游明朝体', serif;
            letter-spacing: 0.01em;
        }
        body.theme-wa:not(.dark) {
            background-color: #f5f3ec !important;  /* 生成 (washi cream) */
            color: #1f2937;                         /* 墨 (deep charcoal) */
        }
        body.theme-wa.dark {
            background-color: #1a1814 !important;  /* 墨夜 */
            color: #e7e3d6;                         /* 月白 */
        }
        /* 和風: ヘッダー title を蘇芳 (suou red) アクセント */
        body.theme-wa h1 {
            color: #9b1c2c !important;
            font-weight: 700;
            letter-spacing: 0.05em;
        }
        body.theme-wa.dark h1 { color: #d97583 !important; }
        /* 和風: キャンバスフレームに極薄の和紙テクスチャ風グラデ */
        body.theme-wa .ccrl-canvas-frame {
            background-image: linear-gradient(135deg, rgba(155, 28, 44, 0.015), rgba(31, 41, 55, 0.012));
        }

        /* ---- (削除) B. 設計図 / Tufte (theme-bauhaus) ----
           2026-04-30 撤去: filter:saturate(0.45) で全体白黒化していたが、
           ユーザー指示「白黒はやめましょう。グレーアウトで亡くなったことを表現する機能と
           まるっきりかぶっています。」に従い、テーマごと削除。
           bauhaus を持っていた旧 state は app.js loadStateString で 'default' に migrate。 */

        /* ---- C. 巻物伝統 (theme-scroll) ---- */
        body.theme-scroll {
            font-family: 'Noto Serif JP', 'Yu Mincho', '游明朝', serif;
            letter-spacing: 0.02em;
        }
        body.theme-scroll:not(.dark) {
            background-color: #faf6e8 !important;  /* 牛乳色 / scroll cream */
            color: #2c1810;                         /* 茶墨 */
        }
        body.theme-scroll.dark {
            background-color: #1c160c !important;
            color: #e8d9b4;
        }
        /* 巻物: タイトルを金茶 + 朱の組み合わせで装飾感を強調 */
        body.theme-scroll h1 {
            color: #b54028 !important;             /* 朱 (vermillion) */
            font-weight: 700;
            text-shadow: 0 1px 0 rgba(184, 165, 101, 0.3);  /* 金茶のうっすら影 */
            letter-spacing: 0.08em;
        }
        body.theme-scroll.dark h1 {
            color: #e89070 !important;
            text-shadow: 0 1px 0 rgba(184, 165, 101, 0.2);
        }
        /* 巻物: キャンバスフレームに金茶の細い枠 */
        body.theme-scroll .ccrl-canvas-frame {
            box-shadow: inset 0 0 0 1px rgba(184, 165, 101, 0.45),
                        0 4px 12px rgba(184, 165, 101, 0.08);
        }
        body.theme-scroll.dark .ccrl-canvas-frame {
            box-shadow: inset 0 0 0 1px rgba(184, 165, 101, 0.55),
                        0 4px 12px rgba(0, 0, 0, 0.35);
        }

        /* =========================================================
         * キャンバス表現方式 (反復 #5 末尾追補 → 反復 #35 拡張)
         *
         * 現在の有効モード (反復 #35 以降):
         *   .canvas-mode-default   — cytoscape による標準家系図表示 (no-op)
         *   .canvas-mode-sankey    — 取り分の帯グラフ (cy 非表示 + 別描画)
         *   .canvas-mode-treemap   — 取り分の面積比 (cy 非表示 + 別描画、反復 #35)
         *   .canvas-mode-dashboard — KPI ダッシュボード (cy 非表示 + 別描画、反復 #35)
         *
         * 廃止された旧モード (loadStateString で 'default' に migrate):
         *   .canvas-mode-iso       — 反復 #16-A: 世代軸崩壊で撤廃
         *   .canvas-mode-ambient   — 反復 #33 hotfix #9: 「個性も機能性もない」で削除
         *   .canvas-mode-legal-doc — 反復 #34 Phase 1 hotfix B-1: 撤廃 (isPrintMode toggle で代替)
         *
         * 設計原則:
         *   - 既存機能は完全維持 (グレーアウトでの死亡表現、cy 操作、レイアウト)
         *   - 各モードは theme と直交
         * ========================================================= */

        /* ---- Phase 2-C: Sankey 相続フロービュー (.canvas-mode-sankey) ---- */
        /* canvasMode='sankey' のとき #cy を完全非表示にして #ccrl-sankey-container を表示。
           cytoscape のレンダリングは継続 (内部 cy インスタンスは生きてる) ため、
           sankey モードから「標準」に戻したとき即座に元の家系図が再表示される。 */
        .canvas-mode-sankey #cy {
            display: none !important;
        }
        .canvas-mode-default #ccrl-sankey-container {
            display: none !important;
        }
        /* sankey 表示時はキャンバス枠の transform / vignette を抑制 (純粋な平面グラフ) */
        .canvas-mode-sankey .ccrl-canvas-frame {
            transform: none !important;
            box-shadow: none !important;
        }
        .canvas-mode-sankey .ccrl-canvas-frame::before,
        .canvas-mode-sankey .ccrl-canvas-frame::after {
            opacity: 0 !important;
        }
        /* sankey container の内部 SVG はテーマ色を text 色として継承 */
        #ccrl-sankey-container svg {
            color: inherit;
        }

        /* ---- 反復 #35 Phase 1 (2026-05-07): 追加 view モード (treemap / dashboard) ----
           ▼ 反復 #35 (2026-05-08、user 指摘「印刷用をキャンバス表示させる意義は薄い」):
           print-onepager は canvasMode から除外。CSS rule も削除。
           モード組合せ (4 種):
             default → cy のみ表示、その他 3 container 非表示
             sankey  → ccrl-sankey-container 表示、cy + 他 2 container 非表示
             treemap → ccrl-treemap-container 表示、cy + 他 2 container 非表示
             dashboard → ccrl-dashboard-container 表示、cy + 他 2 container 非表示
        */
        /* default モード: cy のみ表示 → 他 view container を全部非表示 */
        .canvas-mode-default #ccrl-treemap-container,
        .canvas-mode-default #ccrl-dashboard-container {
            display: none !important;
        }
        /* sankey モード: cy + 他 view container を全部非表示 */
        .canvas-mode-sankey #ccrl-treemap-container,
        .canvas-mode-sankey #ccrl-dashboard-container {
            display: none !important;
        }
        /* treemap モード: cy + sankey + dashboard 非表示 */
        .canvas-mode-treemap #cy,
        .canvas-mode-treemap #ccrl-sankey-container,
        .canvas-mode-treemap #ccrl-dashboard-container {
            display: none !important;
        }
        /* dashboard モード */
        .canvas-mode-dashboard #cy,
        .canvas-mode-dashboard #ccrl-sankey-container,
        .canvas-mode-dashboard #ccrl-treemap-container {
            display: none !important;
        }
        /* 全 view 共通: 透明 / 影 / vignette を抑制 (純平面 SVG) */
        .canvas-mode-treemap .ccrl-canvas-frame,
        .canvas-mode-dashboard .ccrl-canvas-frame {
            transform: none !important;
            box-shadow: none !important;
        }
        .canvas-mode-treemap .ccrl-canvas-frame::before,
        .canvas-mode-treemap .ccrl-canvas-frame::after,
        .canvas-mode-dashboard .ccrl-canvas-frame::before,
        .canvas-mode-dashboard .ccrl-canvas-frame::after {
            opacity: 0 !important;
        }
        #ccrl-treemap-container svg,
        #ccrl-dashboard-container svg { color: inherit; }

        /* =========================================================
         * 広告枠 (反復 #5 末尾追補 2026-04-30)
         * ユーザー指示: 「将来埋め込む予定としてください。スペースだけ開けておいてください」
         * 反復 #5 末尾追補 v2 (2026-04-30 ユーザー指示「いまの私のＰＣサイズだと
         *   確認できません」): threshold を 1952px → 1100px に下げて、
         *   一般的なノート PC (1280-1440px) でも視認できるように調整。
         *   - 1100px 未満 (タブレット縦・スマホ): 非表示
         *   - 1100px 以上 (一般ノート PC ~ ワイドモニター): 表示
         *   - 1100px のとき: main = 1100 - 160*2 - 16*2 = 748px (max-w-[1600px] は max のみ
         *     なので問題なし、content は available width に収まる)
         * ========================================================= */
        /* ▼ 反復 #38 末尾追補 v92.8 (2026-05-21 user 指摘「PC 画面の広告枠が残存している」):
           旧 CSS は display:flex !important で広告 aside を ≥1100px で強制表示しており、
           Alpine の x-show="enableThirdPartyAds && showAds" が立てる inline display:none を
           !important が上書きしてしまい、 広告 OFF でも aside が消えなかった (これが残存の原因)。
           !important を除去し、 x-show の inline display:none が効くようにする。
           表示制御 (≥1100px で表示) は media query の通常 cascade で維持される
           (style.css は tailwind.css より後に load されるため .hidden に勝つ)。 */
        .ad-visible-3xl\:flex {
            display: none;
        }
        @media (min-width: 1100px) {
            .ad-visible-3xl\:flex {
                display: flex;
            }
        }
        /* ▼ 反復 #35 (2026-05-09、user 指示「一画面モードはもはやふようですよね」):
             pc-onepane-mode 関連 CSS は完全削除。サイドバー default 化により不要。 */
        /* ▼ 反復 #35 (2026-05-09、user 指示
             「一画面モードはいろいろと表示や配置を動かしていい」+「上のDDも右側に集約」+
             「ノーマルモードもこの配置の方がいい」+「既存ユーザーはいまいません。デプロイ前です」):
             サイドバー配置を default に昇格。一画面モードは 100vh strict modifier に変更。
             ┌── header (full width) ───────────┐
             ├── canvas (large, left) ─┬ actions ┤  ← 6 つの追加 button
             │                         ├ status ─┤  ← 現在の相続状況
             │                         ├ tools ──┤  ← ツール・出力
             └─────────────────────────┴─────────┘
             ▼ 歴史的経緯 (= 原点回帰):
                - 元 (2026-04-27 以前): サイドバー集約。index.html:176/:590/:1004 のコメントに化石。
                - 2026-04-27 user 要望: 横長フラット展開 (PC 横幅 + ad 枠活用)。
                - 2026-05-09 反復 #35: 一画面モードでサイドバー復活 → 「むしろこっちの方がいい」 →
                  デフォルトに昇格 (デプロイ前なので過去 user 互換不要)。
             ▼ Mode 区別:
                - PC default (≥768px): sidebar grid layout (page scroll 可)
                - mobile (<768px): grid 解除して縦並びに revert
                - @media print: 縦並び (印刷用紙では sidebar が読みにくい)
        */
        @media (min-width: 768px) {
            /* ▼ 反復 #35 (2026-05-09、user 指示「全体の縦スクロールいらないと思います」):
                 PC default で page scroll を完全廃止。すべて 100vh 内に収め、各 sidebar section が
                 必要に応じて内部スクロールする model に移行。 */
            body {
                overflow: hidden;
                height: 100vh;
            }
            #main-content {
                display: grid;
                /* ▼ 反復 #35 (2026-05-10、user 指示「キャンバスとツールバーの幅を自分で調整」):
                   CSS 変数 --sidebar-width で user-adjustable に。
                   default 300px、ドラッグ resize で 240-500px。 localStorage で永続化。
                   resize handle (5px) を canvas と sidebar の間に配置。 */
                grid-template-columns: minmax(0, 1fr) 5px var(--sidebar-width, 300px);
                /* ▼ 反復 #38 末尾追補 v58 (2026-05-15 user 指示「突き抜けないでください。 ライセンス表示の
                   下のラインを最大にしてください」):
                   v57 の min-height: 340px は viewport を突き抜ける regression を起こした。
                   新: grid を 5 行構成にし、 row 5 は PC footer (ライセンス表示) の行。
                       canvas は rows 2-4 を span (従来通り)、 tools は rows 4-5 を span して
                       footer の下端ライン (= row 5 の下端) まで伸びる。 突き抜けは grid が
                       100vh 内に収めるため発生しない。 */
                grid-template-rows: auto auto auto minmax(0, 1fr) auto;
                /* ▼ 反復 #35 (2026-05-09、user 指示「+/- 入力は DD 枠内に配置 (DOM 統合)」):
                     edit grid area 廃止。+/- パネルは action panel (DD 枠) 内に DOM 統合済。
                     順序: status (結果) → actions+edit統合 → tools (出力 + 注意書き)
                   ▼ v58: row 5 に footer (canvas 列) と tools 継続 (sidebar 列)。 */
                grid-template-areas:
                    "header   header  header"
                    "canvas   resize  status"
                    "canvas   resize  actions"
                    "canvas   resize  tools"
                    "footer   footer  tools";
                gap: 0.5rem;
                column-gap: 1rem;
                /* ▼ 反復 #35 (2026-05-10、user 指摘「キャンパス下部が画面の描画範囲からはみ出ています」):
                     旧 align-items: start (sticky canvas 対応の名残) は canvas wrapper を content
                     サイズで自然成長させていた。stretch (default) に戻し、grid cell に正確に clamp する。 */
                align-items: stretch;
                /* 反復 #35: 100vh 固定 + overflow:hidden で page scroll 廃止 */
                height: 100vh;
                max-height: 100vh;
                overflow: hidden;
                /* 反復 #35 (2026-05-10): canvas を右にずらすため左 padding を 0.75 → 1.5rem に増 */
                padding: 0.5rem 0.75rem 0.5rem 1.5rem;
            }
            /* ▼ 反復 #35 (2026-05-09): header — page scroll 廃止により sticky 解除 (grid 配置だけで OK)
               ▼ 反復 #35 (2026-05-10、user 指摘「設定ボタンとかが被ってます」):
                 padding を圧縮しすぎると、絶対配置の 3 icons (top-4 right-0/12/24) が
                 header 下に overflow する。pt-4 (Tailwind: 1rem=16px) を維持して
                 button の 36px 領域 (top-4 + p-2 + svg w-5 = 16+8+20 = 44px) を内包する。 */
            #main-content > header.hide-in-present {
                grid-area: header;
                margin-bottom: 0.25rem !important;
                /* padding-top は Tailwind pt-4 を維持 (override しない) */
                padding-bottom: 0.5rem !important;  /* 下も btn 終端を内包する余裕 */
            }
            /* action 行 (line 188 の sticky な p-4 panel — 6 つの追加 button) → 右上
               ▼ 反復 #35 (2026-05-10、user 指示「一画面ですべて確認」): padding/gap/font 圧縮 */
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky {
                grid-area: actions;
                margin: 0;
                padding: 0.375rem 0.625rem;  /* 0.5/0.75 → 0.375/0.625 */
                position: static !important;
                min-height: 0;
                overflow-y: auto;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky > p,
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky .text-center {
                font-size: 10px !important;
                margin-bottom: 0.25rem !important;
                line-height: 1.25;
            }
            /* 6 つの button (土台作成/サンプル) + draggable-item を 2 カラム × 3 行に再配置 */
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky > .flex.flex-wrap {
                display: grid !important;
                grid-template-columns: repeat(2, 1fr) !important;
                gap: 0.25rem !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky > .flex.flex-wrap > button {
                padding: 0.25rem 0.5rem !important;  /* 0.375 → 0.25 */
                font-size: 11px !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky > .flex.flex-wrap > button svg,
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky .draggable-item svg {
                width: 1rem !important;
                height: 1rem !important;
                margin-right: 0.25rem !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky > .flex.flex-wrap > button span,
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky .draggable-item span {
                font-size: 11px !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky .draggable-item {
                padding: 0.375rem 0.5rem !important;
                justify-content: flex-start;
            }
            /* ▼ 反復 #35 (2026-05-10、user 指示「ツールバーちょっと小さく」+「キャンバスをもう少し右にずらす」):
               canvas toolbar 内の button を 圧縮 (padding / font / icon size 縮小) +
               sidebar を 340→320 に narrowing して canvas 幅を確保 */
            .ccrl-canvas-toolbar button {
                padding-top: 0.125rem !important;
                padding-bottom: 0.125rem !important;
                padding-left: 0.5rem !important;
                padding-right: 0.5rem !important;
                font-size: 10px !important;
            }
            .ccrl-canvas-toolbar svg {
                width: 0.75rem !important;
                height: 0.75rem !important;
            }
            .ccrl-canvas-toolbar .w-px {
                margin-left: 0.125rem;
                margin-right: 0.125rem;
            }
            /* canvas wrapper → 左メイン (rows 2-4 を span)
               ▼ 反復 #35 (2026-05-09、user 指示「全体の縦スクロールいらない」):
                  page scroll 廃止により sticky 解除。grid cell として配置、内部 height は flex で auto。
               ▼ 反復 #35 (2026-05-10、user MD audit「laptop 1280x800 で cy が viewport を 55px 超過」):
                  Tailwind h-[650px] / md:h-[720px] / xl:h-[800px] が grid 内で過剰になる場合があるため
                  canvas-frame の height を grid stretch で自動調整。
               ▼ 反復 #35 (2026-05-10 追補): cy / canvas-viewport の min-height: 0 で flex chain が
                  0 高さに崩壊する bug を修正。flex-grow を信頼するが minimum 200px を保証。 */
            #main-content > .mb-6:has(.ccrl-canvas-frame) {
                grid-area: canvas;
                margin: 0;
                min-height: 0;
                min-width: 0;
                overflow: hidden;
                display: flex;
                flex-direction: column;
            }
            /* ▼ 反復 #38 末尾追補 v58 (2026-05-15): PC footer (canvas 直下の compact ライセンス表示)
               を grid-area: footer に明示配置 (row 5 cols 1-2)。 旧 implicit row auto-place を廃し、
               tools が rows 4-5 span で footer 下端まで伸びる構成にする。 */
            #main-content > footer.hidden.md\:block[aria-label="ライセンス情報"] {
                grid-area: footer;
                margin: 0;
                align-self: end;
            }
            /* canvas-frame の固定 height を grid stretch に上書き */
            #main-content > .mb-6:has(.ccrl-canvas-frame) > .ccrl-canvas-frame {
                height: auto !important;
                flex: 1 1 auto;
                min-height: 200px;  /* min-height: 0 だと flex chain が 0 に崩壊 */
            }
            /* ccrl-edit-panel (+/-) は DD 枠内に DOM 統合済。
               展開時は ccrl-edit-form-scroll で内部スクロール (max-height + overflow-y)
               → ページ全体は伸びない、「小さな画面」を作るイメージ
               (反復 #35 user 指示「展開中は そのなかに小さな画面を作るイメージで」) */
            .ccrl-edit-form-scroll {
                max-height: 50vh;  /* viewport 半分まで、それ超過は内部 scroll */
                overflow-y: auto;
                overflow-x: hidden;
                font-size: 12px;
                /* 内部スクロールバー styling (薄め) */
                scrollbar-width: thin;
            }
            /* ▼ 反復 #35 (2026-05-10、user 指摘「無理やり押し込んでる感」改善):
               +/- counter 行の breathing room 拡張 + label と counter の責任領域明確化
               ▼ 反復 #36 (2026-05-11、user 指示「２段にしましょう」):
               counter 行を「ラベル (1段目 / full width) + カウンタ (2段目 / 右寄せ)」 の
               縦 2 段 stack に再編。ラベルが row 幅を全部使えるため、深いネスト行でも
               2-3 行で読める状態に。
               ▼ 反復 #36 R3 (2026-05-11): 2-段 stack を「深いネスト行 (.relative 配下)」 のみに限定。
               shallow row (元配偶者の人数、生存している子、兄弟姉妹 等の top-level) は inline 維持で
               +20px/行 の縦伸びを回避。 */
            /* default: top-level rows は inline (短ラベル前提) */
            .ccrl-edit-form-scroll .flex.items-center.justify-between {
                flex-direction: row;
                align-items: center;
                gap: 0.5rem;
            }
            /* nested row (.relative 配下 = 代襲/数次の深いネスト): 2-段 stack */
            .ccrl-edit-form-scroll .relative .flex.items-center.justify-between {
                flex-direction: column;
                align-items: stretch;
                gap: 0.375rem;
            }
            /* nested 2-段 stack 時の counter wrapper を右寄せ */
            .ccrl-edit-form-scroll .relative .flex.items-center.justify-between > .flex.items-center {
                align-self: flex-end;
                flex-shrink: 0;
            }
            /* counter 内部の button 間隔 (gap-2 / space-x-3 両方に対応) */
            .ccrl-edit-form-scroll .flex.items-center.space-x-3 {
                gap: 0.5rem !important;  /* 12px → 8px (適度に compact) */
            }
            .ccrl-edit-form-scroll .flex.items-center.space-x-3 > * + * {
                margin-left: 0 !important;  /* gap で代替 */
            }
            /* label は 1 段目 full width。line-height は折返し時にタイト */
            .ccrl-edit-form-scroll .flex.items-center.justify-between > span:first-child {
                line-height: 1.35;
            }
            /* ▼ 反復 #36 R1 (2026-05-11): block header (代襲世代名 + 親チェーン) の 縦書き化 fix。
               深いネスト (depth 4+) で flex 内 CJK span が 1 文字/行 wrap になる問題を line-clamp で抑制。
               2 行を超える場合は末尾に「…」 で truncate、full text は title attribute (tooltip) で取得可能。 */
            .ccrl-line-clamp-2 {
                display: -webkit-box;
                -webkit-line-clamp: 2;
                -webkit-box-orient: vertical;
                overflow: hidden;
                word-break: break-word;
            }
            /* 数字表示は tabular-nums で桁揃え */
            .ccrl-edit-form-scroll .text-sm.font-black {
                font-variant-numeric: tabular-nums;
            }
            /* counter button の hover で背景強調 (現状クリック対象が分かりにくい) */
            .ccrl-edit-form-scroll button.w-6.h-6.rounded-full,
            .ccrl-edit-form-scroll button.w-5.h-5.rounded-full {
                transition: background-color 0.15s, border-color 0.15s, transform 0.1s;
            }
            .ccrl-edit-form-scroll button.w-6.h-6.rounded-full:hover,
            .ccrl-edit-form-scroll button.w-5.h-5.rounded-full:hover {
                background: rgba(56, 189, 248, 0.15);  /* sky-400 light */
                border-color: rgba(56, 189, 248, 0.5);
            }
            .ccrl-edit-form-scroll button.w-6.h-6.rounded-full:active,
            .ccrl-edit-form-scroll button.w-5.h-5.rounded-full:active {
                transform: scale(0.92);
            }
            .ccrl-edit-form-scroll::-webkit-scrollbar {
                width: 6px;
            }
            .ccrl-edit-form-scroll::-webkit-scrollbar-thumb {
                background: rgba(100, 116, 139, 0.4);
                border-radius: 3px;
            }
            .ccrl-edit-form-scroll::-webkit-scrollbar-track {
                background: transparent;
            }
            /* ▼ 反復 #35 (2026-05-10、user 指示「キャンバスとツールバーの幅を自分で調整」):
               canvas と sidebar の間の drag-resize handle。
               cursor: ew-resize、hover で sky-cyan ハイライト、active 時は強調。
               5px 幅 (mouse target は ::before で ±4px 拡張 → 13px hit area)。
               double-click で default (300px) にリセット。 */
            #ccrl-sidebar-resize-handle {
                grid-area: resize;
                cursor: ew-resize;
                background: transparent;
                position: relative;
                z-index: 2;
                transition: background 0.15s;
                user-select: none;
                -webkit-user-select: none;
            }
            #ccrl-sidebar-resize-handle::before {
                content: '';
                position: absolute;
                top: 0; bottom: 0;
                left: -4px; right: -4px;  /* hit area 拡張 ±4px */
                background: transparent;
            }
            #ccrl-sidebar-resize-handle::after {
                /* ▼ 反復 #35 (2026-05-10、UI 工学分析 #6): 永続 micro-label (⇔)。
                   旧: hover まで 2px grip → 発見性低 (Affordance 不可視)
                   新: default 4px sky-300 grip + hover で sky-400 に強調 — 常時 visible */
                content: '⇔';
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 14px;
                height: 36px;
                line-height: 36px;
                text-align: center;
                font-size: 11px;
                font-weight: bold;
                color: rgba(125, 211, 252, 0.8);  /* sky-300 半透明 */
                background: rgba(125, 211, 252, 0.12);
                border-radius: 7px;
                transition: background 0.15s, color 0.15s, height 0.15s;
            }
            #ccrl-sidebar-resize-handle:hover::after {
                background: rgba(56, 189, 248, 0.85);  /* sky-400 */
                height: 56px;
            }
            #ccrl-sidebar-resize-handle.dragging::after {
                background: rgba(14, 165, 233, 0.95);  /* sky-500 */
                height: 80px;
            }
            .dark #ccrl-sidebar-resize-handle::after {
                background: rgba(71, 85, 105, 0.6);
            }
            .dark #ccrl-sidebar-resize-handle:hover::after {
                background: rgba(56, 189, 248, 0.9);
            }
            /* drag 中は body cursor + select 抑制 (JS 側で class 切替) */
            body.ccrl-sidebar-resizing {
                cursor: ew-resize !important;
                user-select: none !important;
                -webkit-user-select: none !important;
            }
            body.ccrl-sidebar-resizing * {
                pointer-events: none !important;
            }
            body.ccrl-sidebar-resizing #ccrl-sidebar-resize-handle {
                pointer-events: auto !important;
            }

            /* status panel (現在の相続状況、グリーンのカード) → 右中段
               ▼ 反復 #35 (2026-05-10、300px 化に伴い更に圧縮): padding/gap/font 圧縮 */
            #main-content > .p-6.rounded-2xl.shadow-xl {
                grid-area: status;
                margin: 0;
                padding: 0.375rem 0.625rem;
                /* ▼ 反復 #38 末尾追補 v69 (2026-05-18 user 指摘「直系卑属の TIPS ツールチップが
                   見切れる」): status 行は grid-template-rows の auto 行 = content-sized のため
                   実質スクロール不要。旧 overflow-y:auto は help-tip ツールチップ (panel 外へ
                   pop する絶対配置要素) を上端/左端でクリップしていた。overflow:visible で解消。 */
                overflow: visible;
                min-height: 0;
                font-size: 0.75rem;  /* 12px */
            }
            #main-content > .p-6.rounded-2xl.shadow-xl > h2 {
                margin-bottom: 0.5rem !important;  /* h2 mb-4 → mb-2 */
                padding-bottom: 0.25rem !important;
            }
            #main-content > .p-6.rounded-2xl.shadow-xl > div.grid {
                grid-template-columns: 1fr !important;
                gap: 0.375rem !important;
            }
            #main-content > .p-6.rounded-2xl.shadow-xl .md\:col-span-2 {
                grid-column: span 1 !important;
            }
            /* 統合カード内の padding 圧縮 */
            #main-content > .p-6.rounded-2xl.shadow-xl .bg-white\/10.rounded-xl {
                padding: 0.375rem 0.5rem !important;
            }
            /* 計算モード toggle の縦余白圧縮 */
            #main-content > .p-6.rounded-2xl.shadow-xl .space-y-2 > * + * {
                margin-top: 0.25rem !important;
            }
            /* breakdown 行 (配偶者 / カテゴリ名) の padding 圧縮 — 300px 幅で収まる */
            #main-content > .p-6.rounded-2xl.shadow-xl .grid.grid-cols-1.sm\:grid-cols-2 > div {
                padding: 0.25rem 0.5rem !important;
            }
            /* 免責文の line-height/margin 圧縮 */
            #main-content > .p-6.rounded-2xl.shadow-xl .border-t.border-white\/20 {
                margin-top: 0.375rem !important;
                padding-top: 0.25rem !important;
                line-height: 1.35 !important;
            }
            /* tools panel (line 592、:not(.sticky) で action 行と区別) → 右下段
               ▼ 反復 #35 (2026-05-10、user 指示「一画面ですべて確認」): padding/font 圧縮
               ▼ 反復 #38 末尾追補 v58 (2026-05-15 user 指示「突き抜けないで、 ライセンス表示の下の
                 ラインを最大に」):
                 v57 の min-height: 340px (突き抜け regression) を撤去。 grid-area: tools は
                 rows 4-5 を span するようになった (grid-template-areas で "tools" が 2 行に出現)
                 ため、 tools card は footer 下端ライン (row 5 下端) まで自然に伸びる。 */
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) {
                grid-area: tools;
                margin: 0;
                padding: 0.375rem 0.625rem;
                overflow-y: auto;
                min-height: 0;
                align-self: stretch;
            }
            /* tools panel の section header (ツール・出力・データ管理) を非表示
               (button 自体に label があるため redundant) */
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) > .text-\[10px\].font-bold.mb-3 {
                display: none !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) > div.grid {
                grid-template-columns: repeat(2, 1fr) !important;
                gap: 0.25rem !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) > div.grid > button {
                padding: 0.25rem 0.5rem !important;
                font-size: 10px !important;
            }
            /* ▼ 反復 #35 (2026-05-09): 「📤 出力」 button を 2 col span (= 横幅一杯) で大きく目立たせる */
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) > div.grid > button.col-span-2 {
                grid-column: span 2 / span 2 !important;
                font-size: 11px !important;
                padding: 0.375rem 0.625rem !important;
            }
            /* tools panel 下部の注意書き text-[9px] を更にコンパクト */
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) > .mt-3 {
                margin-top: 0.375rem !important;
                padding-top: 0.375rem !important;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) > .mt-3 > p {
                font-size: 9px !important;
                line-height: 1.4 !important;
            }

            /* ▼ 反復 #35 (2026-05-09、user 指示「+/- 開いたら右側を全部占有する開き方で」):
                 showInputPanel = true のとき右サイドバーの status / tools を hide し、
                 action panel が rows 2-4 を span して右サイドバー全体を占有する。
                 user が +/- 編集に集中できる「全画面エディタ」風 UX。 */
            /* ▼ 反復 #38 末尾追補 v94 (2026-05-21 user 指摘「人数で入力するとき、 キャンバスを縮める
               意味があるか。 場所は移動させなくていい」):
               旧 expanded grid は 4 行しか定義せず footer 行 (row5) を欠いていたため、 footer が
               implicit grid に押し出され canvas の行スパンがずれて canvas が縮小・移動して見えた
               (cytoscape も refit して 23% 等に zoom out)。
               canvas (rows 2-4) と footer (row5・canvas列) を base grid と完全一致させ、 actions だけを
               rows 2-5 に span させる。 これで input panel 開閉時に canvas の位置・サイズが一切動かない。 */
            body.input-panel-expanded #main-content {
                grid-template-areas:
                    "header   header  header"
                    "canvas   resize  actions"
                    "canvas   resize  actions"
                    "canvas   resize  actions"
                    "footer   footer  actions" !important;
            }
            body.input-panel-expanded #main-content > .p-6.rounded-2xl.shadow-xl,
            body.input-panel-expanded #main-content > .p-4.rounded-2xl.shadow-sm:not(.sticky) {
                display: none !important;
            }
            body.input-panel-expanded #main-content > .p-4.rounded-2xl.shadow-sm.sticky {
                /* action panel が右サイドバー全高 を占有 + 内部スクロール */
                align-self: stretch;
                max-height: calc(100vh - 5rem);
                overflow-y: auto;
            }
            /* +/- form 自身の max-height は親 (action panel) が scroll するので解除 */
            body.input-panel-expanded .ccrl-edit-form-scroll {
                max-height: none !important;
                overflow-y: visible !important;
            }
            /* ▼ 反復 #35 (2026-05-10、user 指摘「+/- 展開時の 閉じる button が見失いやすい」):
                 .ccrl-edit-panel 内の toggle button を sticky にして、スクロールしても常に top に
                 visible に。z-index で他要素より前面、shadow で浮遊感、bg は theme-aware で背景色維持。 */
            body.input-panel-expanded #main-content > .p-4.rounded-2xl.shadow-sm.sticky .ccrl-edit-panel > button {
                position: sticky;
                top: 0;
                z-index: 5;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
            }
            .dark body.input-panel-expanded #main-content > .p-4.rounded-2xl.shadow-sm.sticky .ccrl-edit-panel > button {
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
            }
        }

        /* モバイル (< 768px): grid 解除して縦並びに revert (ad 枠は別 CSS で hidden)
           ▼ 反復 #38 末尾追補 (2026-05-12 user 指示「家系図はシンプルに人型アイコンと名前くらいで、
              こじんまりさせる必要がありそうですね。スマホでマップは絶対に不要」):
              旧: height: 650px !important (キャンバスが画面の大半を占有)
              新: height: 420px !important + padding: 0.75rem (badge 全 hide + 縦サイズ縮小で
                  「アイコンと名前のみのこじんまり表示」を実現) */
        @media (max-width: 767px) {
            #main-content {
                display: block;
                height: auto;
                max-height: none;
                overflow: visible;
            }
            body {
                overflow: auto;
            }
            #main-content > .mb-6:has(.ccrl-canvas-frame) {
                display: block;
            }
            #main-content > .p-4.rounded-2xl.shadow-sm.sticky {
                position: sticky !important;
                top: 0.5rem;
            }
            /* ▼ 反復 #38 末尾追補 (2026-05-12 user 指示「むしろ、キャンパスをフロートで表示」):
               キャンバスを mobile 用に sticky フロート化 + 表示順を変更。
               旧: ad banner → list editor → canvas (canvas は scroll しないと見えない)
               新: ad banner → canvas (sticky) → list editor (canvas を見ながら scroll 編集可能)
               flex order で DOM 順を変えずに視覚順序のみ変更 (PC layout は影響なし)。 */
            #main-content > .mb-6:has(.ccrl-canvas-frame) {
                display: flex;
                flex-direction: column;
            }
            .ccrl-canvas-frame {
                /* 旧: height 420px 静的、order 4 (DOM 順)
                   新: height 320px、order 2 (ad の直後)、sticky 化
                   ▼ v89 (2026-05-21 user 指示「モバイルの家系図キャンバスは、 手動で上下の幅を
                   調整できるようにしてください」): 静的 320px を CSS 変数 --mobile-canvas-height
                   に変更。 default 320px、 mobile-canvas-resizer.js が drag で動的に更新。 */
                height: var(--mobile-canvas-height, 320px) !important;
                padding: 0.5rem !important;
                order: 2;
                position: sticky !important;
                top: 0;
                z-index: 30;
                /* sticky な canvas を視覚的に強調 (浮いている感を出す影) */
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
                /* ▼ 反復 #38 末尾追補 (2026-05-12 user 指摘「モバイルのキャンパスの範囲バグってます」):
                   cytoscape node (decedent icon 等) が canvas-frame の境界を越えて下方に
                   bleed out していたため overflow: hidden で clip。 */
                overflow: hidden !important;
                /* ▼ 反復 #38 末尾追補 v92.6 (2026-05-21): アコーディオン廃止に伴い height transition を撤去。
                   旧 transition: height 0.28s はアコーディオン開閉用だったが、 v89 の drag-resize では
                   height が連続更新されるため transition が drag をラグらせていた。 height を除外し
                   box-shadow のみ残す (drag が即時追従)。 */
                transition: box-shadow 0.28s ease;
            }
            .dark .ccrl-canvas-frame {
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
            }
            /* ▼ 反復 #38 末尾追補 v92.6 (2026-05-21 user 指示「v89 で指でサイズ調整できるようにしたので
               アコーディオンの閉じるボタンは廃棄していい」): .canvas-collapsed-mobile 関連の全ルール
               (44px 薄バー化 / 内部要素 hide / header overlay relative 化 / toggle 位置調整 / 凡例 hide)
               を撤去。 canvas frame は常時展開、 高さ調整は下記 v89 の drag handle が担う。 */
            /* ▼ v89 (2026-05-21 user 指示「モバイルの家系図キャンバスは、 手動で上下の幅を
               調整できるようにしてください」): canvas frame の直下に drag handle (横長薄バー)。
               flex order 2.5 相当 (canvas:2 の直後、 list editor:3 の前) を実現するため
               flex order: 2 + DOM 順序で canvas-frame の直後に配置 (handle は canvas の sibling)。
               14px tall + 4px margin-top = 18px 総高、 center にグリップ表示 (3 lines)。
               cursor: row-resize で drag 方向を視覚化、 touch-action:none で iOS scroll を抑止。 */
            .ccrl-mobile-canvas-resize-handle {
                order: 2;  /* canvas-frame と同 order、 DOM 順で canvas の直後 */
                margin-top: 6px;
                margin-bottom: 2px;
                height: 18px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: row-resize;
                touch-action: none;
                user-select: none;
                -webkit-user-select: none;
                border-radius: 9999px;
                transition: background-color 0.15s ease;
                /* ▼ 反復 #38 末尾追補 v92.8 (2026-05-21 user 指摘「拡縮バーをキャンバスの裏に
                   隠しちゃダメ」): canvas-frame は position:sticky + z-index:30 で stacking context を
                   作るため、 z-index 未指定の本ハンドルが canvas の背面に潜り込んで見えなくなっていた。
                   z-index:31 で canvas より前面に出し、 常に視認・操作可能にする。
                   高さも 14→18px に拡大し、 margin で canvas との隙間を確保してタップしやすくする。
                   ▼ 反復 #45 (2026-05-25 user 指摘「キャンバスバーのバグ」): 旧 position:relative では
                   sticky な canvas (top:0) を下スクロールで追い越せず、 ハンドルのグリップ (灰色バー) だけが
                   canvas の途中に浮いて見えるバグがあった。 ハンドル自身も position:sticky にして
                   top: --mobile-canvas-height で canvas 下端にピン留めし、 常に canvas 直下へ追従させる
                   (canvas 高さを drag で変えても同じ CSS 変数を参照するので追従)。 */
                position: sticky;
                top: var(--mobile-canvas-height, 320px);
                z-index: 31;
                background-color: rgba(100, 116, 139, 0.08);
            }
            .ccrl-mobile-canvas-resize-handle:hover,
            .ccrl-mobile-canvas-resize-handle:focus-visible {
                background-color: rgba(100, 116, 139, 0.12);  /* slate-500 hint */
                outline: none;
            }
            .ccrl-mobile-canvas-resize-handle.dragging {
                background-color: rgba(100, 116, 139, 0.22);
            }
            .ccrl-mobile-canvas-resize-grip {
                display: block;
                width: 44px;
                height: 4px;
                border-radius: 2px;
                background-color: rgba(100, 116, 139, 0.55);
                transition: background-color 0.15s ease, height 0.15s ease;
            }
            .ccrl-mobile-canvas-resize-handle:hover .ccrl-mobile-canvas-resize-grip,
            .ccrl-mobile-canvas-resize-handle:focus-visible .ccrl-mobile-canvas-resize-grip,
            .ccrl-mobile-canvas-resize-handle.dragging .ccrl-mobile-canvas-resize-grip {
                background-color: rgba(71, 85, 105, 0.85);  /* slate-600 */
            }
            /* dark mode: 視認性のため grip を明色に */
            .dark .ccrl-mobile-canvas-resize-grip {
                background-color: rgba(148, 163, 184, 0.55);  /* slate-400 */
            }
            .dark .ccrl-mobile-canvas-resize-handle:hover .ccrl-mobile-canvas-resize-grip,
            .dark .ccrl-mobile-canvas-resize-handle:focus-visible .ccrl-mobile-canvas-resize-grip,
            .dark .ccrl-mobile-canvas-resize-handle.dragging .ccrl-mobile-canvas-resize-grip {
                background-color: rgba(203, 213, 225, 0.95);  /* slate-300 */
            }
            /* drag 中は body 全体に row-resize cursor を当て、 text 選択を抑止 */
            body.ccrl-mobile-canvas-resizing,
            body.ccrl-mobile-canvas-resizing * {
                cursor: row-resize !important;
                user-select: none !important;
                -webkit-user-select: none !important;
            }
            /* 広告枠 は canvas の上 (order: 1 = ad banner) */
            #main-content > .mb-6:has(.ccrl-canvas-frame) > aside {
                order: 1;
            }
            /* Mobile List Editor は canvas の下 (order: 3) */
            #main-content > .mb-6:has(.ccrl-canvas-frame) > .md\:hidden.mb-2 {
                order: 3;
            }
            /* 反復 #38 末尾追補: モバイル時はミニマップ要素自体を非表示 */
            #ccrl-minimap {
                display: none !important;
            }
            /* ▼ 反復 #38 末尾追補 (2026-05-12 user 指示「スマホ画面で、十字キーや拡縮しライダーは
               不要です。手で十分操作できます」):
               タッチデバイスでは pinch / pan ジェスチャで充分なため、十字 pan ボタン群と
               zoom slider を完全非表示。 */
            .canvas-pan-pad,
            .canvas-zoom-slider {
                display: none !important;
            }
            /* ▼ 反復 #38 末尾追補 (2026-05-12 user 指摘「モバイルのアイコン表示がバグってます」):
               canvas-idle (空 canvas 用 idle 動画、人型 SVG が canvas 上を動き回る装飾) を
               モバイルで完全非表示。狭い canvas 領域 (320px) では装飾が雑然となり、また
               sticky 配置との互換性問題で他コンテンツ領域に icon が leak することがある。 */
            .canvas-idle {
                display: none !important;
            }
            /* ▼ 反復 #38 末尾追補 (2026-05-12 user 指示「キャンバスの挙動をスマホ二本指で操作できる
               ようにしてください。拡大縮小も一般的な指の操作でできるように」):
               canvas-viewport および内部 cytoscape canvas 要素に touch-action: none を付与し、
               ブラウザによるデフォルト touch ジェスチャ (page zoom / scroll の捕捉) を抑制。
               これにより cytoscape が pinch-zoom + 2-finger pan を直接処理可能になる。
               注意: canvas 領域内では page scroll が無効化される (user は canvas 外を touch して
                     page を scroll する設計)。canvas は 320px と狭く、上下に scroll 用の領域が
                     十分にあるため UX 上問題なし。 */
            .canvas-viewport,
            .canvas-viewport canvas {
                touch-action: none !important;
            }
            /* ▼ 反復 #38 末尾追補 (2026-05-12 user 指示「現在の相続状況は、下部に表示されているので、
               本体には表示不要 / 下部の現在の相続状況の下に、常にライセンス表示」):
               #main-content を flex column 化し、order で「現在の相続状況」と license footer を
               最下部に押し出す (DOM 順を変えずに mobile のみ視覚順を変更)。 */
            #main-content {
                display: flex;
                flex-direction: column;
            }
            /* ▼ 反復 #37 refactor (2026-05-14): mobile floating bar (.ccrl-mobile-bottom-bar) 関連を集約。
               旧: order rule (line ~1997, 2001) と独立した @media block (line ~2011) で hide rule が
                   分散していた。 新: 同じ media query 内に統合 (CSS cascade 探索性向上)。
               反復 #38 末尾追補 (2026-05-12): mobile floating result bar (.ccrl-mobile-bottom-bar) を
                   導入したことで、 body 内の 現在の相続状況 card + license footer は重複となり hide。
                   floating bar の高さ ~160px に合わせて body padding-bottom 確保。
               order は display:none と矛盾しないため両方残置 (将来 hide を外すときに有効化)。 */
            #main-content > .p-6.rounded-2xl.shadow-xl.text-white {
                order: 90;
                display: none !important;  /* 現在の相続状況 card 重複 hide (.ccrl-mobile-bottom-bar に統合済) */
            }
            /* ▼ 反復 #38 末尾追補 v42 (2026-05-15 user 指示「モバイルのプライバシーポリシーとか利用規約は、
               本文の一番下、ただしちゃんと見える位置に配置してください」):
               旧: .ccrl-license-footer は floating bar 内 3 リンクに統合済として display:none
               新: 3 リンクを floating bar から分離して footer に戻したため、 visible に変更。
                   order: 91 で 現在の相続状況 (hide) の直下に配置 → body scroll の最下部に visible。
               ▼ v86 (2026-05-21): v85 で一度撤去したが user 指示でロールバック。 同 rule を復元。 */
            #main-content > .ccrl-license-footer {
                order: 91;
                /* display:none を撤去 — 3 リンクが本文最下部に見えるようになる */
            }
            /* ▼ v88 (2026-05-21): floating bar に 320×50 ad slot を配置すると bar 全高 ~125px。
               ▼ v92 (2026-05-21): 広告フィーチャートグルで bar 下部が ad / license に分岐するため、
                 body の marker class (ccrl-ads-on / ccrl-ads-off) で padding-bottom を出し分け:
                 - ccrl-ads-on  : 320×50 ad slot 分 → 130px
                 - ccrl-ads-off : license (version + copyright 2 行) 分 → 96px
                 デフォルト (class 未付与時) は安全側の 130px。 */
            body {
                padding-bottom: 130px !important;
            }
            body.ccrl-ads-off {
                padding-bottom: 96px !important;
            }
            body.ccrl-ads-on {
                padding-bottom: 130px !important;
            }
        }

        /* ▼ 反復 #38 末尾追補 v92.8 (2026-05-21 user 指示「タブレットの縦表示はやはり PC に準拠させて」):
           v90 では tablet (768-1023px) で mobile floating bar を優先し PC の現在の相続状況カードを
           hide していたが、 方針転換。 floating bar を md:hidden (＜768px のみ) に変更したことで
           tablet では floating bar が出ず、 PC カードが表示される (= PC レイアウト準拠)。
           よって旧 v90 の tablet 用 PC カード hide + padding-bottom 上書きルールは撤去した
           (tablet は通常の PC body padding を使う)。 */

        /* @media print: 印刷時は grid 解除して縦並びに (印刷用紙では sidebar が読みにくい) */
        @media print {
            #main-content {
                display: block !important;
                height: auto !important;
                max-height: none !important;
                overflow: visible !important;
            }
        }
        /* ============================================================
         * ▼ 反復 #30-D (v0.9.0): a11y 強化
         * ============================================================
         *   - skip-link: スクリーンリーダー / Tab ユーザー向けに main へ jump
         *   - focus-visible outline: Tab navigation 時のみ見やすい outline を表示
         *     (mouse click では outline が出ないので UI が汚れない)
         *   - 高コントラスト: WCAG AA 4.5:1 を満たす outline 色を採用
         * ============================================================ */
        .ccrl-skip-link {
            position: absolute;
            left: -9999px;
            top: 0;
            z-index: 9999;
            padding: 0.5rem 1rem;
            background: #1e293b;
            color: #ffffff;
            font-weight: bold;
            border-radius: 0.5rem;
            text-decoration: none;
            border: 2px solid #ffffff;
        }
        .ccrl-skip-link:focus {
            left: 0.5rem;
            top: 0.5rem;
        }
        /* focus-visible: pointer click では出ず、keyboard navigation でのみ outline 表示 */
        :focus-visible {
            outline: 2px solid #06b6d4;  /* cyan-500: ライト/ダーク両でコントラスト確保 */
            outline-offset: 2px;
            border-radius: 4px;
        }
        .dark :focus-visible {
            outline-color: #67e8f9;  /* cyan-300 (ダークでより視認性確保) */
        }
        /* button / [role="button"] 系は内側に少し inset させて押せる感を保つ */
        button:focus-visible,
        [role="button"]:focus-visible {
            outline-offset: 2px;
        }
        /* 印刷時 (PDF/PNG export) は ad 枠を非表示 (印刷物に「広告枠」プレースホルダが
           出ると不格好なため) */
        /* ▼ 反復 #30-C (v0.9.0): 印刷モード強化
           直接ブラウザ印刷時 (Ctrl+P) でも余分な UI を非表示にする。
           本ツールの主流は jsPDF 経由だが、ブラウザ印刷も sub-route として扱う。 */
        @media print {
            /* 広告 / toolbar / sidebar / toast を非表示 */
            .ad-side-left,
            .ad-side-right,
            .toast-container,
            .ccrl-shared-tip,
            .help-tip-text {
                display: none !important;
            }
            /* 開いているモーダルは印刷対象から除外 */
            .ccrl-dialog-overlay,
            [role="dialog"]:not([data-print-include]),
            [role="alertdialog"] {
                display: none !important;
            }
            /* 日本の民事訴訟規則第2条1項: A4 縦の余白 */
            @page {
                margin: 35mm 30mm 27mm 30mm;
            }
            /* ヘッダ・フッタの余分な UI も非表示 */
            .ccrl-toolbar,
            .canvas-controls,
            button[aria-label*="設定"],
            button[aria-label*="チートシート"] {
                display: none !important;
            }
            /* キャンバスは紙面いっぱいに */
            #cy {
                width: 100% !important;
                height: auto !important;
                page-break-inside: avoid;
            }
            /* page-break-inside: avoid を主要要素に適用 */
            section, article, .ccrl-dialog-card, .canvas-card {
                page-break-inside: avoid;
            }
            /* 暗色背景は紙では白に */
            body, .dark body, body.oled-mode {
                background: #ffffff !important;
                color: #000000 !important;
            }
        }
        body.canvas-print-active .ad-side-left,
        body.canvas-print-active .ad-side-right {
            display: none !important;
        }

        /* =========================================================
         * 60fps 最適化 (反復 #6 v28、妥当な指摘 #10-1):
         *   高頻度で transform/opacity が変わる要素を GPU layer に昇格して、
         *   scroll / zoom / 円環アニメ中の repaint コストを削減する。
         *   will-change は memory cost があるため、対象は厳選 (toast / radial / overlay).
         * ========================================================= */
        #cy {
            contain: layout paint;  /* レイアウト・ペイントを内部にスコープ化、外部 reflow から隔離 */
        }
        .ccrl-radial-menu, .radial-menu, .ccrl-radial-svg {
            will-change: transform, opacity;
            transform: translateZ(0);  /* GPU layer 強制 */
        }
        .ccrl-node-overlay, .node-overlay {
            will-change: transform;
            transform: translateZ(0);
        }
        /* 円環アニメ (open/close) の transform は scaleX 変化が頻繁なので backface-visibility を抑制 */
        .ccrl-radial-menu {
            backface-visibility: hidden;
            -webkit-backface-visibility: hidden;
        }

        /* =========================================================
         * OLED true black variant (反復 #6 v28、妥当な指摘 #10-3):
         *   ゲーマーペルソナ #10 「`bg-slate-800` (#1e293b) は普通の暗い灰色で、
         *   有機 EL モニターのバックライト消灯メリットを潰してる。OLED モード追加要求」
         *   isOledMode=true && isDarkMode=true で body に `oled-mode` class が付与され、
         *   主要 dark variant slate 色を pure black (#000) に override する。
         *   OLED 画面ではバックライトが完全消灯し、true black 体験 + 焼き付き軽減が得られる。
         * ========================================================= */
        body.oled-mode {
            background-color: #000 !important;
        }
        body.oled-mode .bg-slate-800,
        body.oled-mode .bg-slate-900 {
            background-color: #000 !important;
        }
        body.oled-mode .bg-slate-700 {
            background-color: #0a0a0a !important;
        }
        body.oled-mode .bg-slate-900\/95,
        body.oled-mode .bg-slate-900\/80,
        body.oled-mode .bg-slate-900\/60,
        body.oled-mode .bg-slate-900\/40 {
            background-color: rgba(0, 0, 0, 0.95) !important;
        }
        body.oled-mode .border-slate-700,
        body.oled-mode .border-slate-600 {
            border-color: #1a1a1a !important;
        }

        /* 印刷時は screen media query の影響を受けない (print media query が別途優先) */
