/* ============================================================================
   abi-ui.css — Abi Signature UI（部品ライブラリはこれ1つ）
   ABI-SIG-001（ABI_MOTION_GRAMMAR.md）の実装。色は ABI-SIG-002（abi-look.css）の階調から採る。

   2026-09-01、abi-buttons.css をここへ取り込んで1本にした。
   ボタン20種と、円弧の選択盤・進捗の縁・状態の球・送り出しの4つ、あわせて24部品。
   重複していたもの（素のボタン／数量／切り替え／択一／送り出し）は1つに畳んである。

   規則1 色は着地の瞬間に乗る … .abi-sat / .abi-b / .abi-bx が saturate() を持ち、動作中だけ抜く
   規則2 物は消えない        … opacity:0 で消す指定をこのファイルは1つも持たない
   規則3 動く前に一度だけ縮む … .is-pre（scale プロパティ。transform と衝突しない）

   進捗・充填に scaleX を使っていないのは、静止時の matrix(0.95〜0.995) が
   「予備動作が残っている」と読めてしまうため。すべて translate かクリップで作る。

   使い方（1行）:
     <link rel="stylesheet" href="abi-ui.css"><script src="abi-ui.js" defer></script>

   案件ごとの色替えは --abi-accent の1行だけで済む。外部リクエスト0件。
   ==========================================================================

   規則1 色は着地の瞬間に乗る … .abi-sat / .is-moving（彩度は .abi-ui.js が切替）
   規則2 物は消えない        … opacity:0 を1箇所も書かない。退場は移動か遮蔽
   規則3 動く前に一度だけ縮む … .abi-pre（scale プロパティ。transform と衝突しない）

   外部リクエスト0件。フォント・画像・CDNを読まない。
   案件ごとの色替えは :root か任意の親で --abi-accent 等を上書きするだけで済む。
   ========================================================================== */

:root {
  /* ---- 色（墨と生成り） ---- */
  --abi-bg-dark:  #0B0B0C;
  --abi-bg:       #F3F0EA;
  --abi-ink:      #16181D;
  --abi-accent:   #26348C;   /* 藍。着地したものにだけ乗る */
  --abi-alert:    #C8443A;   /* 緋。警告と現在地のみ */
  --abi-focus:    var(--abi-accent);

  /* 上の5色から機械的に導く面（彩度の高い色を2つ以上同時に置かない） */
  --abi-surface:  #FFFFFF;
  --abi-sunk:     #E7E3DA;
  --abi-line:     #D8D3C8;
  --abi-line-soft:#E6E2D8;
  --abi-mute:     #7C7970;
  --abi-ink-soft: #4A4A4E;

  /* ---- 尺 ---- */
  --abi-t-state:  170ms;     /* 状態の切替 */
  --abi-t-scene:  320ms;     /* 場面の切替 */
  --abi-t-enter:  620ms;     /* 登場 */
  --abi-in:       cubic-bezier(.16, 1, .3, 1);
  --abi-out:      cubic-bezier(.4, 0, 1, 1);
  --abi-k:        620;       /* ばね定数。ζ=1固定 */
  --abi-step-near: 40ms;
  --abi-step-far: 115ms;

  --abi-pre-t:    60ms;      /* 規則3 */
  --abi-pre-s:    .985;
  --abi-sat-move: .15;       /* 規則1 */

  /* ---- 形 ---- */
  --abi-r-s:  8px;
  --abi-r-m:  14px;
  --abi-r-l:  22px;
  --abi-r-pill: 999px;
  --abi-hair: 1px;

  /* ---- 字 ---- */
  --abi-font: "Hiragino Sans", "Yu Gothic UI", "Yu Gothic", YuGothic, "Noto Sans JP", Meiryo, system-ui, sans-serif;
  --abi-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ==========================================================================
   0. 土台 — 3規則の受け皿。全部品がこの3ブロックを共有する
   ========================================================================== */

.abi-ui, .abi-ui *, .abi-b, .abi-b *, .abi-bx, .abi-bx * { box-sizing: border-box; }

.abi-ui {
  font-family: var(--abi-font);
  color: var(--abi-ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* 見出しは詰める。数値と符牒は等幅 */
.abi-h  { font-weight: 700; letter-spacing: -.01em; margin: 0; }
.abi-num{ font-family: var(--abi-mono); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }

/* --- 規則1 …… 動いている間だけ彩度を抜く ---------------------------------
   抜くのは即座（transitionを使わない）、戻すのは 170ms のアニメーション。
   .abi-sat は「彩度の管理だけ借りたい物」（canvas・見本帳の段など）用の素の口。 */
.abi-sat, .abi-b, .abi-bx { filter: saturate(1); }
.abi-sat.is-moving, .abi-b.is-moving, .abi-bx.is-moving { filter: saturate(var(--abi-sat-move)); }
.abi-sat.is-land, .abi-b.is-land, .abi-bx.is-land,
.abi-sat.abi-land, .abi-b.abi-land, .abi-bx.abi-land { animation: abi-land var(--abi-t-state) var(--abi-in); }
@keyframes abi-land {
  from { filter: saturate(var(--abi-sat-move)); }
  to   { filter: saturate(1); }
}

/* --- 規則3 …… 主役だけが動く前に一度だけ 60ms 縮む ---------------------- */
/* 名前は2つとも受ける。部品側は .is-pre / .is-land、canvas を持つエンジン側
   （abi-points / abi-stage / abi-flock …）は .abi-pre / .abi-land を付けている。
   2026-09-01 に部品集を1本へまとめたとき前者へ寄せたが、後者を使う既存が
   9ファイルあり、片方だけにすると規則1の着地と規則3の予備動作が黙って消える */
.is-pre, .abi-pre { animation: abi-pre var(--abi-pre-t) linear forwards; }
.is-pre.is-land, .abi-pre.abi-land {
  animation: abi-pre var(--abi-pre-t) linear forwards,
             abi-land var(--abi-t-state) var(--abi-in);
}
@keyframes abi-pre {
  from { scale: 1; }
  to   { scale: var(--abi-pre-s); }
}

/* --- 焦点 …… 全部品で同じ1本 ------------------------------------------- */
.abi-ui :focus, .abi-b:focus, .abi-bx :focus { outline: none; }
.abi-ui :focus-visible,
.abi-ui [data-abi] :focus-visible,
.abi-b:focus-visible,
.abi-bx :focus-visible {
  outline: 2px solid var(--abi-focus);
  outline-offset: 3px;
  border-radius: inherit;
}


/* ==========================================================================
   1. 面の上に直接置く素のボタン（JSを付けない飾りのない1つ）
   ========================================================================== */

.abi-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;   /* 44px ちょうどだと中心±22 が縁に乗って隣に当たる（2026-09-04 実測） */
  padding: 0 22px;
  border: var(--abi-hair) solid transparent;
  border-radius: var(--abi-r-m);
  background: var(--abi-accent);
  color: #FFF;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .01em;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition:
    translate var(--abi-t-state) var(--abi-in),
    background-color var(--abi-t-state) var(--abi-in);
}
.abi-btn::after {                      /* 沈み込みの受け皿。影は補助要素なので予備動作を付けない */
  content: "";
  position: absolute;
  inset: auto 2px -3px 2px;
  height: 10px;
  border-radius: inherit;
  background: var(--abi-ink);
  opacity: .18;
  z-index: -1;
  transition: translate var(--abi-t-state) var(--abi-in);
}
.abi-btn.is-down { translate: 0 2px; }
.abi-btn.is-down::after { translate: 0 -2px; }
.abi-btn:hover { background: #2C3BA0; }

.abi-btn--quiet {
  background: var(--abi-surface);
  color: var(--abi-ink);
  border-color: var(--abi-line);
}
.abi-btn--quiet:hover { background: #FBFAF7; }
.abi-btn--quiet::after { opacity: .08; }

.abi-btn--alert { background: var(--abi-alert); }
.abi-btn--alert:hover { background: #D24C42; }

.abi-btn[disabled], .abi-btn[aria-disabled="true"] {
  cursor: default;
  background: var(--abi-sunk);
  color: var(--abi-mute);
  border-color: var(--abi-line-soft);
}
.abi-btn[disabled]::after { opacity: .05; }

/* ==========================================================================
   2. 素のボタン（ボタン20種すべての土台）
   ========================================================================== */

.abi-b {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 48px;   /* 44px ちょうどだと中心±22 が縁に乗って隣に当たる（2026-09-04 実測） */
  padding: 0 20px;
  margin: 0;
  border: 1px solid transparent;
  border-radius: var(--abi-r-m);
  background: var(--abi-accent);
  color: #FFFFFF;
  font-family: var(--abi-font);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -.005em;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--abi-t-state) var(--abi-in),
              border-color var(--abi-t-state) var(--abi-in),
              color var(--abi-t-state) var(--abi-in),
              box-shadow var(--abi-t-state) var(--abi-in);
}
.abi-b.is-down { translate: 0 1px; }
.abi-b:hover { background: #2C3C9E; }

/* 控えめ（生成りの面に置く） */
.abi-b--quiet {
  background: var(--abi-surface);
  color: var(--abi-ink);
  border-color: var(--abi-line);
}
.abi-b--quiet:hover { background: #FBFAF7; border-color: #C7C1B4; }
.abi-b--quiet.is-on { border-color: var(--abi-accent); color: var(--abi-accent); }

/* 警告（緋は警告と現在地のみ。装飾に使わない） */
.abi-b--alert { background: var(--abi-alert); }
.abi-b--alert:hover { background: #D24C42; }

.abi-b[aria-disabled="true"] { cursor: not-allowed; color: var(--abi-mute); background: var(--abi-sunk); border-color: var(--abi-line); }
.abi-b[aria-disabled="true"]:hover { background: var(--abi-sunk); }

.abi-b svg { display: block; width: 17px; height: 17px; }

/* --- 入れ替わる面（規則2：ラベルは消えず、上か下へ送られる） ------------- */
.abi-b-slot { position: relative; display: block; overflow: hidden; }
.abi-b-face { position: relative; display: inline-flex; align-items: center; white-space: nowrap; }
.abi-b-face.is-set { position: absolute; left: 0; top: 0; width: 100%; justify-content: center; }
.abi-b-face.is-warn { color: #FFD9D5; }
.abi-b-slot--left .abi-b-face.is-set { justify-content: flex-start; }

/* --- 走る線・充填（translate で作る。静止時に scale を残さない） --------- */
.abi-b-rail {
  position: absolute; left: 10px; right: 10px; bottom: 6px; height: 3px;
  border-radius: var(--abi-r-pill); overflow: hidden; background: rgba(255,255,255,.28);
  pointer-events: none;
}
.abi-b--quiet .abi-b-rail { background: var(--abi-sunk); }
.abi-b-rail > i { position: absolute; inset: 0; border-radius: inherit; background: #FFFFFF; transform: translateX(-101%); }
.abi-b--quiet .abi-b-rail > i { background: var(--abi-accent); }
.abi-b-rail > i.is-short { right: 62%; }

/* ==========================================================================
   3. 02 長押しで確定 — 縁が満ちる
   ========================================================================== */

.abi-b-ring {
  position: absolute; inset: -3px; border-radius: inherit; padding: 2px; pointer-events: none;
  background: conic-gradient(from -90deg, var(--abi-accent) calc(var(--abi-p, 0) * 1turn), var(--abi-line) 0deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.abi-b--alert .abi-b-ring { background: conic-gradient(from -90deg, var(--abi-alert) calc(var(--abi-p, 0) * 1turn), var(--abi-line) 0deg); }

/* ==========================================================================
   4. 03 引いて実行 — つまみが端で嵌まる
   ========================================================================== */

.abi-drag {
  position: relative; display: inline-flex; align-items: center;
  width: 288px; height: 52px; padding: 4px;
  border-radius: var(--abi-r-pill); background: var(--abi-sunk);
  border: 1px solid var(--abi-line); overflow: hidden;
  font-family: var(--abi-font);
}
.abi-drag-hint {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: var(--abi-mute); pointer-events: none; padding-left: 34px;
}
.abi-drag-socket {
  position: absolute; right: 5px; top: 5px; width: 42px; height: 42px; border-radius: var(--abi-r-pill);
  border: 1px dashed var(--abi-line); pointer-events: none;
}
.abi-drag.is-done .abi-drag-socket { border-color: var(--abi-accent); border-style: solid; }
.abi-drag-knob {
  position: relative; z-index: 2; width: 44px; height: 44px; flex: 0 0 44px;
  border: 0; border-radius: var(--abi-r-pill); background: var(--abi-accent); color: #FFFFFF;
  display: flex; align-items: center; justify-content: center; cursor: grab; touch-action: none;
}
.abi-drag-knob:active { cursor: grabbing; }
.abi-drag.is-done .abi-drag-hint { color: var(--abi-accent); }

/* ==========================================================================
   5. 05 送信して結果を返す / 19 やり直す
   ========================================================================== */

.abi-b.is-ok   { background: var(--abi-accent); }
.abi-b.is-ng   { background: var(--abi-alert); }
.abi-b.is-busy { background: #5A6087; }
.abi-b--quiet.is-ok { background: var(--abi-surface); color: var(--abi-accent); border-color: var(--abi-accent); }
.abi-b--quiet.is-ng { background: var(--abi-surface); color: var(--abi-alert); border-color: var(--abi-alert); }
.abi-b--quiet.is-busy { background: var(--abi-surface); color: var(--abi-mute); border-color: var(--abi-line); }

.abi-b-mark { width: 18px; height: 18px; overflow: visible; }
.abi-b-mark path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

.abi-status {
  display: block; margin-top: 9px; font-family: var(--abi-mono); font-size: 11.5px;
  letter-spacing: .04em; color: var(--abi-mute); min-height: 15px;
}
.abi-status.is-ok { color: var(--abi-accent); }
.abi-status.is-ng { color: var(--abi-alert); }

/* ==========================================================================
   6. 06 切り替え / 16 開始と停止
   ========================================================================== */

.abi-b--toggle { background: var(--abi-surface); color: var(--abi-ink); border-color: var(--abi-line); overflow: hidden; }
.abi-b-plane { position: absolute; inset: 0; background: var(--abi-accent); transform: translateY(101%); }
.abi-b--toggle .abi-b-slot { z-index: 1; }
.abi-b--toggle[aria-pressed="true"] { color: #FFFFFF; border-color: var(--abi-accent); }

.abi-run-dot { width: 9px; height: 9px; border-radius: var(--abi-r-pill); background: var(--abi-line); flex: 0 0 9px; }
.abi-b--run[aria-pressed="true"] .abi-run-dot { background: var(--abi-alert); }  /* 現在地としての緋 */
.abi-b--run[aria-pressed="true"] { border-color: var(--abi-alert); color: var(--abi-alert); }
.abi-run-shape polygon { fill: currentColor; }

/* ==========================================================================
   7. 07 数を増やす — 桁が転がる
   ========================================================================== */

.abi-step {
  display: inline-flex; align-items: stretch; border: 1px solid var(--abi-line);
  border-radius: var(--abi-r-m); background: var(--abi-surface); overflow: hidden;
}
.abi-step .abi-b { min-height: 42px; border-radius: 0; border: 0; padding: 0 16px; background: var(--abi-surface); color: var(--abi-ink); font-size: 18px; }
.abi-step .abi-b:hover { background: #F7F5F0; }
.abi-step-val {
  display: flex; align-items: center; justify-content: center; gap: 1px;
  min-width: 74px; padding: 0 8px; border-left: 1px solid var(--abi-line-soft); border-right: 1px solid var(--abi-line-soft);
  font-family: var(--abi-mono); font-size: 17px; font-weight: 700; color: var(--abi-ink);
  cursor: ns-resize;
}
.abi-digit { position: relative; overflow: hidden; width: .62em; height: 1.5em; transition: width var(--abi-t-state) var(--abi-in); }
.abi-digit > span { position: absolute; left: 0; top: 0; width: 100%; height: 10em; }
.abi-digit i { display: block; height: 1.5em; line-height: 1.5em; text-align: center; font-style: normal; }

/* ==========================================================================
   8. 08 複製・追加 — 増えた物が元から生えて出る
   ========================================================================== */

.abi-bx { position: relative; font-family: var(--abi-font); }
.abi-spawn-list { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 8px; }
.abi-spawn-list li {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  border: 1px solid var(--abi-line-soft); border-radius: var(--abi-r-m); background: var(--abi-surface);
  font-size: 13px; color: var(--abi-ink-soft); will-change: transform;
}
.abi-spawn-list li b { font-family: var(--abi-mono); font-size: 11px; color: var(--abi-accent); }

/* ==========================================================================
   9. 09 取り消せる削除 — 粒に分解 → 数秒だけ戻せる
   ========================================================================== */

.abi-trash { position: relative; min-height: 168px; padding-bottom: 58px; }
.abi-trash-card {
  display: flex; align-items: center; gap: 12px; padding: 16px 18px;
  border: 1px solid var(--abi-line-soft); border-radius: var(--abi-r-m); background: var(--abi-surface);
}
.abi-trash-card b { font-size: 14px; }
.abi-trash-card span { font-size: 12px; color: var(--abi-mute); }
.abi-trash-act { margin-top: 10px; }
.abi-trash canvas { position: absolute; left: 0; top: 0; pointer-events: none; }
.abi-trash-undo {
  position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: var(--abi-r-m); background: var(--abi-ink); color: var(--abi-bg);
  transform: translateY(120%); overflow: hidden;
}
.abi-trash-undo p { margin: 0; font-size: 12.5px; }
.abi-trash-undo .abi-b { margin-left: auto; background: transparent; border-color: #4A4A52; color: var(--abi-bg); min-height: 34px; padding: 0 14px; font-size: 12px; }
.abi-trash-undo .abi-b:hover { background: #23232B; }
.abi-trash-grace { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; overflow: hidden; background: #33333C; }
.abi-trash-grace > i { position: absolute; inset: 0; background: var(--abi-bg); }

/* ==========================================================================
   10. 10 読み込み — 終わりが見えない待ち／見える待ち
   ========================================================================== */

.abi-load-track {
  position: relative; width: 100%; height: 4px; margin-top: 10px; overflow: hidden;
  border-radius: var(--abi-r-pill); background: var(--abi-sunk);
}
.abi-load-track > i { position: absolute; top: 0; bottom: 0; left: 0; right: 0; border-radius: inherit; background: var(--abi-accent); transform: translateX(-101%); }
.abi-load-track > i.is-blip { right: 66%; }

/* ==========================================================================
   11. 11 開いて選ぶ / 18 開閉
   ========================================================================== */

/* .abi-bx の filter が積み重ね文脈を作るので、開いた面が後続の要素に潜らないよう
   ここでだけ層を上げる（子の z-index は文脈の外へ出られないため、親に付ける）*/
.abi-menu { position: relative; display: inline-block; z-index: 40; }
.abi-menu-panel {
  position: absolute; left: 0; top: calc(100% + 8px); z-index: 30; min-width: 210px;
  margin: 0; padding: 6px; list-style: none; overflow: hidden;
  border: 1px solid var(--abi-line); border-radius: var(--abi-r-m); background: var(--abi-surface);
  box-shadow: 0 14px 34px rgba(22,24,29,.14);
}
.abi-menu-panel[hidden] { display: none; }
.abi-menu-panel li { display: block; }
.abi-menu-panel button {
  display: block; width: 100%; text-align: left; border: 0; border-radius: var(--abi-r-s);
  padding: 10px 12px; background: transparent; color: var(--abi-ink);
  font-family: var(--abi-font); font-size: 13px; cursor: pointer;
}
.abi-menu-panel button:hover, .abi-menu-panel button.is-cursor { background: var(--abi-sunk); }

.abi-expand-panel { overflow: hidden; height: 0; }
.abi-expand-inner {
  padding: 14px 16px; margin-top: 10px; border: 1px solid var(--abi-line-soft);
  border-radius: var(--abi-r-m); background: var(--abi-surface);
  font-size: 13px; line-height: 1.9; color: var(--abi-ink-soft);
}
.abi-caret { transition: rotate var(--abi-t-state) var(--abi-in); }
[aria-expanded="true"] > .abi-caret { rotate: 180deg; }

/* ==========================================================================
   12. 13 取り出す / 14 外へ出る — 矢印に行き先を持たせる
   ========================================================================== */

.abi-glyph { position: relative; display: block; width: 18px; height: 18px; overflow: hidden; }
.abi-glyph svg { position: absolute; left: 0; top: 0; }
.abi-tray {
  position: absolute; left: 14px; right: 14px; bottom: 7px; height: 3px; overflow: hidden;
  border-radius: var(--abi-r-pill); background: rgba(255,255,255,.3);
}
.abi-tray > i { position: absolute; inset: 0; background: #FFFFFF; transform: translateX(-101%); }

/* ==========================================================================
   13. 15 送り / 17 択一
   ========================================================================== */

.abi-pager { display: inline-flex; align-items: center; gap: 10px; font-family: var(--abi-font); }
.abi-pager-num {
  position: relative; display: flex; align-items: baseline; gap: 4px; min-width: 74px; justify-content: center;
  font-family: var(--abi-mono); font-size: 15px; font-weight: 700; color: var(--abi-ink);
}
.abi-pager-num .abi-b-slot { width: 22px; }
.abi-pager-num em { font-style: normal; color: var(--abi-mute); font-size: 12px; }
.abi-pager-bar { position: relative; width: 96px; height: 3px; border-radius: var(--abi-r-pill); background: var(--abi-sunk); overflow: hidden; }
.abi-pager-bar > i { position: absolute; top: 0; bottom: 0; left: 0; width: 24px; border-radius: inherit; background: var(--abi-accent); }

.abi-seg {
  position: relative; display: inline-flex; padding: 4px; gap: 2px;
  border: 1px solid var(--abi-line); border-radius: var(--abi-r-m); background: var(--abi-sunk);
}
.abi-seg-ind { position: absolute; top: 4px; bottom: 4px; left: 0; width: 10px; border-radius: 10px; background: var(--abi-surface); box-shadow: 0 2px 6px rgba(22,24,29,.10); }
.abi-seg button {
  position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 7px;
  border: 0; background: transparent; cursor: pointer;
  min-height: 34px; padding: 0 18px; border-radius: 10px;
  font-family: var(--abi-font); font-size: 13px; font-weight: 700; color: var(--abi-mute);
  transition: color var(--abi-t-state) var(--abi-in);
}
.abi-seg button[aria-checked="true"], .abi-seg button[aria-selected="true"] { color: var(--abi-accent); }
.abi-seg button svg { display: block; width: 16px; height: 16px; }
/* data-panels を書いたときだけ現れる面。行と面で1部品 */
.abi-seg-host { display: block; }
.abi-seg-panel {
  margin-top: 12px; padding: 15px 16px;
  border-radius: var(--abi-r-m);
  background: var(--abi-surface);
  border: var(--abi-hair) solid var(--abi-line-soft);
  font-size: 13.5px; line-height: 1.75; color: var(--abi-ink-soft);
  overflow: hidden;
}
.abi-seg-panel strong { color: var(--abi-accent); font-weight: 700; }


/* ==========================================================================
   14. 20 三値の巡回
   ========================================================================== */

.abi-b--cycle .abi-b-slot { width: 68px; }
.abi-cycle-mark { position: relative; width: 14px; height: 18px; overflow: hidden; }
.abi-cycle-mark i {
  position: absolute; left: 0; top: 0; width: 14px; height: 18px; font-style: normal;
  display: flex; align-items: center; justify-content: center; font-size: 11px; color: currentColor;
}


/* ==========================================================================
   15. 円弧の選択盤
   2本の弧が向かい合う。選ぶと反対の弧へ飛んで移る（消えない＝規則2）
   弧から外れた項目は透明化ではなく、遮蔽板の下へ滑り込む
   ========================================================================== */

.abi-arc {
  position: relative;
  display: block;
  height: 336px;
  padding: 0;
  border-radius: var(--abi-r-l);
  background: var(--abi-bg-dark);
  overflow: hidden;
  touch-action: pan-y;
}
.abi-arc__col { position: relative; }
.abi-arc__cap {                      /* 列の見出し */
  position: absolute; top: 12px; left: 0; right: 0;
  text-align: center;
  font-size: 11px; font-weight: 700; letter-spacing: .12em;
  color: #7E7B74;
  z-index: 4;
  pointer-events: none;
}
.abi-arc__item {
  position: absolute;
  top: 50%; left: 50%;
  display: flex; align-items: center; gap: 7px;
  height: 32px;
  max-width: 46%;
  margin: -16px 0 0 0;
  padding: 0 13px;
  border: 0;
  border-radius: var(--abi-r-s);
  background: #191A1E;
  color: #DCD8CF;
  font: inherit; font-size: 13px; font-weight: 700; white-space: nowrap;
  cursor: pointer;
  transform-origin: center;
  translate: calc(var(--abi-ax, 0) * 1px) calc(var(--abi-ay, 0) * 1px);
  rotate: calc(var(--abi-arot, 0) * 1deg);
  scale: var(--abi-asc, 1);
  transition: background-color var(--abi-t-state) var(--abi-in);
}
.abi-arc__item[data-picked="true"] { background: var(--abi-accent); color: #FFF; }
.abi-arc__item > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.abi-arc__item .abi-arc__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
  flex: none;
}
.abi-arc__shade {                    /* 上下の遮蔽板。ここへ滑り込ませて退場させる */
  position: absolute; left: 0; right: 0; height: 78px;
  z-index: 3; pointer-events: none;
}
.abi-arc__shade--t { top: 0;    background: linear-gradient(180deg, var(--abi-bg-dark) 34%, rgba(11,11,12,0)); }
.abi-arc__shade--b { bottom: 0; background: linear-gradient(0deg,   var(--abi-bg-dark) 34%, rgba(11,11,12,0)); }
.abi-arc__mid {                      /* 現在地。緋はここだけ */
  position: absolute; top: 50%; left: 8px; right: 8px;
  height: 38px; margin-top: -19px;
  border-top: var(--abi-hair) solid rgba(200, 68, 58, .26);
  border-bottom: var(--abi-hair) solid rgba(200, 68, 58, .26);
  z-index: 1; pointer-events: none;
}

/* ==========================================================================
   16. 進捗の縁
   ========================================================================== */

.abi-progress { display: block; }
.abi-progress__head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 8px;
  font-size: 13px; font-weight: 700; color: var(--abi-ink-soft);
}
.abi-progress__pct { font-family: var(--abi-mono); font-size: 13px; color: var(--abi-accent); }
.abi-progress__canvas {
  display: block;
  width: 100%;
  height: 26px;
  border-radius: var(--abi-r-s);
  background: var(--abi-sunk);
}

/* ==========================================================================
   17. 状態の球
   ========================================================================== */

.abi-orb {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.abi-orb__canvas {
  display: block;
  width: 132px; height: 132px;
  border-radius: 50%;
  background: var(--abi-bg-dark);
}
.abi-orb__cap {
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
  color: var(--abi-mute);
  transition: color var(--abi-t-state) var(--abi-in);
}
.abi-orb[data-state="done"] .abi-orb__cap { color: var(--abi-accent); }

/* ==========================================================================
   18. 送り出しの順番
   未到着は「まだ空の枠」として残す。opacity:0 にはしない（規則2）
   ========================================================================== */

.abi-reveal {
  display: grid;
  grid-template-columns: repeat(var(--abi-cols, 3), minmax(0, 1fr));
  gap: 10px;
}
.abi-reveal > * {
  opacity: 1;
  translate: 0 0;
  transition:
    opacity var(--abi-t-enter) var(--abi-in),
    translate var(--abi-t-enter) var(--abi-in);
}
.abi-reveal > .is-waiting {
  opacity: .10;                      /* 0 にしない。枠は最初からそこに在る */
  translate: 0 14px;
  transition: none;
}

.abi-card {
  padding: 13px 14px;
  border-radius: var(--abi-r-m);
  background: var(--abi-surface);
  border: var(--abi-hair) solid var(--abi-line-soft);
}
.abi-card__k { display: block; font-size: 11.5px; font-weight: 700; color: var(--abi-mute); letter-spacing: .04em; }
.abi-card__v { display: block; margin-top: 5px; font-family: var(--abi-mono); font-size: 19px; font-weight: 700; color: var(--abi-ink); }

/* ==========================================================================
   19. 動きを外しても意味が通る状態（prefers-reduced-motion）
   3規則を外しても「色は着地に乗る／物は行き先を持つ／面は入れ替わる」は
   結果の状態として残る。消える演出はここでも作らない。
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .abi-ui *, .abi-ui *::before, .abi-ui *::after,
  .abi-b, .abi-b *, .abi-bx, .abi-bx * {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }
  .abi-sat, .abi-b, .abi-bx,
  .abi-sat.is-moving, .abi-b.is-moving, .abi-bx.is-moving { filter: saturate(1) !important; }
  .abi-sat.is-land, .abi-b.is-land, .abi-bx.is-land, .is-pre, .is-pre.is-land,
  .abi-sat.abi-land, .abi-b.abi-land, .abi-bx.abi-land, .abi-pre, .abi-pre.abi-land { animation: none !important; }
  .abi-reveal > .is-waiting { opacity: 1; translate: 0 0; }
  .abi-caret { transition: none; }
}
