/* ============================================================
 * library.css — レシピ提案 page styles.
 *
 * 設計方針:
 * - nav.css の design tokens (--accent / --panel / --radius-* / --shadow-* /
 *   --duration-* / --ease-* / --btn-h-*) を流用.
 * - mobile (<768px): 1 列 grid, 右袖カート非表示 (sticky bottom 合計 bar のみ).
 * - iPad 横 / desktop (≥768px): 2 列 grid + 右袖カート 280px 常駐.
 * - 全タップ target ≥48px (a11y / 手指タップ).
 * - safe-area-inset-bottom を sticky totals に加味して primary CTA に被らない.
 * ============================================================ */

/* ----------------------------------------------------------------
 * 検索 / mode / chip 行
 * ---------------------------------------------------------------- */
.lib-controls{
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 10px;
  position: sticky; top: 60px; z-index: 5; /* page header (--z-sticky: 10) の下に. */
}

.lib-search-row{
  display: flex; gap: 6px; align-items: center;
}
.lib-search-row input[type="search"]{
  flex: 1; padding: 12px 14px; font-size: 16px;
  background: var(--panel2); color: var(--fg);
  border: 1px solid var(--line); border-radius: var(--radius-md);
  min-height: 48px;
  transition: border-color var(--duration-fast) var(--ease-standard);
}
.lib-search-row input[type="search"]:focus{ border-color: var(--accent); }
.lib-search-row button{ min-height: 48px; min-width: 48px; padding: 0 14px; }

/* segmented mode (お任せ / 自分で / 作りたいから) */
.lib-mode-segmented{
  display: flex; gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 3px;
  background: var(--panel2);
  flex-wrap: wrap;
}
.lib-mode-segmented .seg-btn{
  flex: 1 1 0; min-width: 100px;
  background: transparent; color: var(--fg2);
  border: none; border-radius: var(--radius-pill);
  padding: 10px 14px; font-size: 14px; font-weight: 600;
  min-height: 44px; cursor: pointer;
  transition: background var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}
.lib-mode-segmented .seg-btn:hover{
  color: var(--fg); background: var(--bg-elevated);
}
.lib-mode-segmented .seg-btn[aria-pressed="true"]{
  background: var(--accent); color: #0b1120;
}
.lib-mode-segmented .seg-btn:focus-visible{
  outline: 3px solid var(--accent); outline-offset: 2px;
}

/* Round 5: desire chip 列 (作りたいから mode) は削除済 */

/* Round 5: お任せ mode ランディング案内 panel (auto mode で grid 代わりに表示) */
.lib-auto-panel{
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 32px 20px;
  margin: 12px 0;
  text-align: center;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
/* Round 5 + 15 fix: hidden 属性が display:flex / grid に上書きされる bug 修正.
   [hidden] selector で display:none を強制. おまかせ mode で全部消すために必要.
   Round 18 Phase 1.5-A: ndish view も同様に hidden で display:none. */
.lib-auto-panel[hidden],
.lib-search-row[hidden],
.lib-cart-pane[hidden],
.lib-sticky-totals[hidden],
.lib-filter-chips[hidden],
.lib-ndish-view[hidden]{
  display: none !important;
}
.lib-auto-panel .auto-panel-emoji{
  font-size: 56px;
  line-height: 1;
  margin-bottom: 4px;
  animation: auto-panel-bob 2.4s var(--ease-standard) infinite;
}
@keyframes auto-panel-bob{
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}
.lib-auto-panel .auto-panel-title{
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--fg);
}
.lib-auto-panel .auto-panel-desc{
  margin: 4px 0;
  font-size: 14px;
  color: var(--fg2);
  line-height: 1.5;
  max-width: 360px;
}
.lib-auto-panel .auto-panel-stats{
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 6px;
}
.lib-auto-panel .auto-panel-stat{
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
  font-size: 13px;
  color: var(--fg2);
}
.lib-auto-panel .auto-panel-stat b{
  color: var(--fg);
  font-weight: 700;
}
.lib-auto-panel .auto-panel-hint{
  margin-top: 14px;
  font-size: 13px;
  color: var(--accent);
  font-weight: 600;
}
.lib-auto-panel .auto-panel-fab-icon{
  display: inline-block;
  margin: 0 2px;
  transform: translateY(1px);
}
/* Round 15: 中央「おまかせ献立開始」 button (= 旧 右下 FAB の代替). 案内 panel 内に大型配置. */
.lib-auto-panel .auto-panel-cta{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  min-height: 56px;
  padding: 0 28px;
  background: var(--accent);
  color: #0b1120;
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  font-family: inherit;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 120ms var(--ease-standard), background-color 120ms var(--ease-standard);
}
.lib-auto-panel .auto-panel-cta:hover{ background: var(--accent-hover, var(--accent)); transform: scale(1.03); }
.lib-auto-panel .auto-panel-cta:active{ transform: scale(0.97); }
.lib-auto-panel .auto-panel-cta:focus-visible{
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}
.lib-auto-panel .auto-panel-cta span:first-child{
  font-size: 22px;
  line-height: 1;
}
@media (prefers-reduced-motion: reduce){
  .lib-auto-panel .auto-panel-emoji { animation: none; }
  .lib-auto-panel .auto-panel-cta:hover { transform: none; }
}

/* 絞り chip (在庫 match / 時間 / 出自) */
.lib-filter-chips{
  display: flex; flex-wrap: wrap; gap: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.lib-filter-chips .filter-chip{
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--panel2); color: var(--fg2);
  font-size: 12px; font-weight: 500; cursor: pointer;
  white-space: nowrap; min-height: 32px; user-select: none;
  transition: background var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.lib-filter-chips .filter-chip:hover{
  background: var(--bg-elevated); color: var(--fg);
}
.lib-filter-chips .filter-chip[aria-pressed="true"]{
  background: var(--accent); color: #0b1120; border-color: var(--accent);
  font-weight: 600;
}
.lib-filter-chips .chip-sep{
  width: 1px; align-self: stretch; background: var(--line);
  margin: 2px 4px;
}

/* ---------------------------------------------------------------- *
 * Round 17: 主 + 副 カテゴリ chip 行 (= 自分で選択 mode のみ表示).
 *   既存 .lib-filter-chips と同 spec で統一. label 「主:」「副:」 を行頭に置く.
 *   axis 内は OR (= 複数 active), axis 間は AND (= filterDishes で実装).
 * ---------------------------------------------------------------- */
.lib-main-category-chips,
.lib-sub-category-chips{
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; padding: 4px 0;
}
.lib-cat-chips-label{
  font-size: 12px; font-weight: 600; color: var(--fg2);
  flex-shrink: 0; min-width: 24px;
}
.lib-cat-chips-list{
  display: flex; gap: 6px; flex-wrap: wrap; flex: 1 1 auto;
}
.lib-cat-chip{
  display: inline-flex; align-items: center;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--panel2); color: var(--fg2);
  font-size: 12px; font-weight: 500; cursor: pointer;
  white-space: nowrap; min-height: 32px; user-select: none;
  transition: background var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.lib-cat-chip:hover{
  background: var(--bg-elevated); color: var(--fg);
}
.lib-cat-chip[aria-pressed="true"]{
  background: var(--accent); color: #0b1120; border-color: var(--accent);
  font-weight: 600;
}
/* おまかせ mode では chip 行を非表示 (= 既存 .lib-filter-chips と同パターン).
   library.js が html.lib-mode-auto を toggle するので CSS で連動.
   Round 18 Phase 1.5-A: ndish mode でも同様に chip 行を隠す (= 専用 UI 集中). */
html.lib-mode-auto .lib-main-category-chips,
html.lib-mode-auto .lib-sub-category-chips,
html.lib-mode-ndish .lib-main-category-chips,
html.lib-mode-ndish .lib-sub-category-chips{
  display: none;
}
/* mobile (≤519px) では label を hide (= 場所節約). chip は wrap で 2 段以上に. */
@media (max-width: 519px){
  .lib-cat-chips-label { display: none; }
}

/* ----------------------------------------------------------------
 * 2-column layout: grid pane + 右袖 cart pane
 * ---------------------------------------------------------------- */
.lib-layout{
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  /* sticky totals bar の高さ ≈ 88px + safe-area を考慮し下に空ける */
  padding-bottom: calc(112px + env(safe-area-inset-bottom));
}
@media (min-width: 768px){
  .lib-layout {
    grid-template-columns: 1fr 300px;
  }
}
/* Round 15-hotfix2: おまかせ mode は cart pane を hide するため右袖 300px が空白で残る.
   html.lib-mode-auto class が付いている時は 1 列 layout に上書き (= 中央 panel が全幅). */
html.lib-mode-auto .lib-layout{
  grid-template-columns: 1fr !important;
}

.lib-grid-pane{
  min-width: 0; /* grid item overflow 防止 */
}

/* --lib-card-min は card 最小幅. 小さくすると 1 行に多く並ぶ. */
/* auto-fill + minmax で 画面幅に応じて 1/2/3/4 列が自動切替. */
:root{
  --lib-card-min: 220px;
}
.lib-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--lib-card-min), 1fr));
  gap: 10px;
}
/* 4 列固定 hint: viewport >= 1100px で 4 列確保 (240px × 4 + gap 30px ≈ 990px + sidebar) */
@media (min-width: 1100px){
  :root { --lib-card-min: 230px; }
}
/* iPad 横 (1024px) 用 3 列 */
@media (min-width: 880px) and (max-width: 1099.98px){
  :root { --lib-card-min: 240px; }
}
/* mobile 1 列 (狭い時) */
@media (max-width: 519px){
  :root { --lib-card-min: 100%; }
}

.lib-empty,
.lib-loading{
  padding: 32px; text-align: center; color: var(--fg2);
  background: var(--panel); border: 1px dashed var(--line);
  border-radius: var(--radius-md);
}
.spinner{
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%; animation: spin 0.7s linear infinite;
  vertical-align: middle; margin-right: 6px;
}
@keyframes spin{ to { transform: rotate(360deg); } }

/* ----------------------------------------------------------------
 * Dish Card
 * ---------------------------------------------------------------- */
.dish-card{
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 8px;
  /* dish 名は top, kcal/PFC + buttons は bottom 寄せ. 中段 spacer で stick 化. */
  min-height: 200px;
  transition: border-color var(--duration-fast) var(--ease-standard),
              box-shadow var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}
/* head 以外の最初の子 = spacer 役で auto-margin で押下. */
.dish-card > .dish-pfc-mini{ margin-top: auto; }
.dish-card:hover{
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
}
.dish-card.in-cart{
  border-color: var(--accent);
  background: rgba(110, 168, 255, 0.06);
}

/* core 欠損 (味噌が無い 等) — 灰色 + role=alert 警告帯 */
.dish-card.missing-core{
  opacity: 0.85;
  background: var(--panel);
  border-color: var(--line);
}
.dish-card.missing-core .dish-name{
  color: var(--fg2);
}
.dish-missing-banner{
  background: rgba(255, 110, 110, 0.12);
  color: var(--danger);
  border: 1px solid rgba(255, 110, 110, 0.35);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: 12px;
  display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap;
}
.dish-missing-banner button{
  background: transparent; color: var(--danger);
  border: 1px solid var(--danger);
  padding: 4px 8px; font-size: 12px;
  min-height: 32px; min-width: 32px;
  font-weight: 600;
}
.dish-missing-banner button:hover{
  background: var(--danger); color: #1a0808;
}

.dish-card-head{
  display: flex; gap: 8px; align-items: flex-start;
  /* 2 行分の高さを reserve することで card 間で PFC bar の縦位置が揃う. */
  min-height: calc(16px * 1.3 * 2);
}
.dish-name{
  flex: 1; font-size: 16px; font-weight: 700;
  line-height: 1.3; min-width: 0;
  word-break: break-word;
  /* 3 行以上の超長名は省略. 2 行までは折り返し. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 主材料 chip 行 */
.dish-ing-row{
  display: flex; flex-wrap: wrap; gap: 4px;
}
.ing-chip{
  display: inline-flex; align-items: center;
  padding: 3px 8px;
  background: var(--panel); color: var(--fg2);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  font-size: 11px;
}
.ing-chip.missing{
  background: var(--line); color: var(--fg2);
  text-decoration: line-through;
  text-decoration-color: var(--danger);
  text-decoration-thickness: 1.5px;
  opacity: 0.7;
}
.ing-chip.missing::before{ content: "⚠ "; opacity: 0.7; }

/* 在庫 match bar (0-100%) — color + percent text dual encoding */
.match-bar-row{
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; color: var(--fg2);
}
.match-bar{
  flex: 1; height: 6px;
  background: var(--line); border-radius: var(--radius-pill);
  overflow: hidden;
  position: relative;
}
.match-bar-fill{
  height: 100%; border-radius: var(--radius-pill);
  background: var(--ok);
  transition: width var(--duration-normal) var(--ease-standard);
}
.match-bar-fill.mid{ background: var(--warn); }
.match-bar-fill.low{ background: var(--danger); }
.match-pct{
  min-width: 38px; text-align: right; font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* PFC 数値 行 — kcal 大字 + P/F/C chip */
.dish-pfc-mini{
  display: flex; gap: 6px; align-items: baseline;
  color: var(--fg2);
  flex-wrap: wrap;
}
.dish-pfc-mini b{ color: var(--fg); font-weight: 700; }
.dish-pfc-mini .pfc-kcal{
  color: var(--accent); font-weight: 800;
  font-size: 18px; font-variant-numeric: tabular-nums;
  margin-right: 4px;
}
/* P/F/C chip: 色 + テキスト (色覚多様性 — 数値併記必須) */
.dish-pfc-mini .pfc-chip{
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px; border-radius: var(--radius-pill);
  font-size: 11px; font-weight: 500;
  border: 1px solid transparent;
  font-variant-numeric: tabular-nums;
}
.dish-pfc-mini .pfc-chip b{
  font-size: 11px; letter-spacing: 0.02em;
}
.dish-pfc-mini .pfc-chip-p{
  background: rgba(255, 110, 110, 0.14);
  color: #ff9c9c;
  border-color: rgba(255, 110, 110, 0.35);
}
.dish-pfc-mini .pfc-chip-f{
  background: rgba(255, 180, 84, 0.14);
  color: var(--warn);
  border-color: rgba(255, 180, 84, 0.35);
}
.dish-pfc-mini .pfc-chip-c{
  background: rgba(110, 168, 255, 0.14);
  color: var(--accent);
  border-color: rgba(110, 168, 255, 0.35);
}

/* PFC 比率 stacked bar (P×4 + F×9 + C×4 → kcal 比率) — 横 bar に 3 色積み上げ
 * 色弱配慮で下に P/F/C % 数値も併記する.
 * 色: P=赤 / F=黄 / C=青 (task 仕様).
 */
.dish-pfc-ratio{
  display: flex; flex-direction: column; gap: 4px;
}
.pfc-ratio-bar{
  display: flex; height: 10px;
  background: var(--line);
  border-radius: var(--radius-pill);
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.04);
}
.pfc-ratio-bar > span{
  display: inline-block; height: 100%;
  transition: width var(--duration-normal) var(--ease-standard);
}
.pfc-ratio-p{ background: #ff6e6e; }      /* P = 赤 (タンパク質) */
.pfc-ratio-f{ background: #ffb454; }      /* F = 黄 (脂質) */
.pfc-ratio-c{ background: #6ea8ff; }      /* C = 青 (炭水化物) */
.pfc-ratio-nums{
  display: flex; gap: 8px; flex-wrap: wrap;
  font-size: 10px; font-variant-numeric: tabular-nums;
  color: var(--fg2);
}
.pfc-ratio-num{
  display: inline-flex; align-items: center; gap: 3px;
  font-weight: 600;
}
.pfc-ratio-num::before{
  content: ""; display: inline-block;
  width: 8px; height: 8px; border-radius: 50%;
  margin-right: 2px;
}
.pfc-ratio-num-p{ color: #ff9c9c; }
.pfc-ratio-num-p::before{ background: #ff6e6e; }
.pfc-ratio-num-f{ color: var(--warn); }
.pfc-ratio-num-f::before{ background: #ffb454; }
.pfc-ratio-num-c{ color: var(--accent); }
.pfc-ratio-num-c::before{ background: #6ea8ff; }

/* PFC 0 = backend data 欠落時 */
.pfc-ratio-missing{
  display: flex; align-items: center;
}
.pfc-ratio-missing-msg{
  font-size: 10px; color: var(--fg2);
  font-style: italic;
  padding: 2px 0;
}

/* 料理時間 chip */
.dish-time-chip{
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px;
  background: var(--panel); color: var(--fg2);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  font-size: 11px;
  margin-left: auto;
}

/* Round 18 Phase 1.6-A: 採用 (= from_library) dish マーカー chip.
   AI が新規生成せず library 既存 dish を再利用したことを user に明示. */
.from-library-chip{
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px;
  background: var(--accent-soft, rgba(110, 168, 255, 0.15));
  color: var(--accent, #6ea8ff);
  border: 1px solid var(--accent, #6ea8ff);
  border-radius: var(--radius-pill, 999px);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-left: 6px;
}

/* Round 18 Phase 1.7: dish card 役割 chip (= 主食 / 主菜 / 副菜 / 汁物).
   server 側 menu-composition.applyRoleMappingAndWarn が dish.categories[0] を server 指定
   role に overwrite している. 色分けは role ごとに hue を変えて 視覚的に識別容易に. */
.ndish-role-chip{
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border: 1px solid;
  border-radius: var(--radius-pill, 999px);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-left: 6px;
}
.ndish-role-staple{
  background: rgba(255, 200, 120, 0.18);
  color: #d68a2a;
  border-color: #d68a2a;
}
.ndish-role-main{
  background: rgba(255, 120, 130, 0.18);
  color: #d6477a;
  border-color: #d6477a;
}
.ndish-role-side{
  background: rgba(140, 220, 130, 0.18);
  color: #4ea34a;
  border-color: #4ea34a;
}
.ndish-role-soup{
  background: rgba(120, 190, 220, 0.18);
  color: #2e8ab5;
  border-color: #2e8ab5;
}
.ndish-role-other{
  background: var(--panel, rgba(140, 140, 140, 0.15));
  color: var(--fg2, #888);
  border-color: var(--line, #aaa);
}

/* Round 18 Phase 1.7: 主菜 oneshot 警告 banner + 「献立構成 redo」 button.
   server 側 needsRedo=true (= 主菜 が 2 件以上) の時 dish grid 上部に表示. */
.ndish-composition-warning{
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  margin: 8px 0 12px 0;
  background: rgba(255, 200, 80, 0.12);
  border: 1px solid var(--warn, #d6a429);
  border-radius: var(--radius-md, 8px);
  font-size: 13px;
  color: var(--fg, inherit);
  flex-wrap: wrap;
}
.ndish-composition-warning-icon{
  font-size: 18px; flex-shrink: 0;
}
.ndish-composition-warning-text{
  flex: 1 1 200px;
  line-height: 1.45;
}
.ndish-composition-redo-btn{
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 14px;
  background: var(--warn, #d6a429);
  color: #fff;
  border: 1px solid var(--warn, #d6a429);
  border-radius: var(--radius-pill, 999px);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  transition: filter var(--duration-fast, 120ms) var(--ease-standard, ease);
}
.ndish-composition-redo-btn:hover{ filter: brightness(1.08); }
.ndish-composition-redo-btn:focus-visible{
  outline: 3px solid var(--warn, #d6a429);
  outline-offset: 2px;
}
.ndish-composition-redo-btn:active{ transform: scale(0.97); }

/* Round 5: dish card 非表示 button (archived_at soft-delete trigger) */
.dish-delete-btn{
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  margin-left: 4px;
  background: transparent; color: var(--fg2);
  border: 1px solid transparent; border-radius: var(--radius-md);
  font-size: 15px; cursor: pointer;
  opacity: 0.55;
  transition: opacity var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              background var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.dish-delete-btn:hover{
  opacity: 1;
  color: var(--danger, #ff6e6e);
  background: rgba(255, 110, 110, 0.1);
  border-color: var(--danger, #ff6e6e);
}
.dish-delete-btn:focus-visible{
  opacity: 1;
  outline: 3px solid var(--danger, #ff6e6e);
  outline-offset: 2px;
}
.dish-delete-btn:active{
  transform: scale(0.94);
}

.dish-card-actions{
  display: flex; gap: 6px; margin-top: auto;
}
.dish-card-actions .primary{
  flex: 1; min-height: 48px;
}
.dish-card-actions .secondary{
  background: transparent; color: var(--accent);
  border: 1px solid var(--accent);
  min-height: 48px; min-width: 48px; padding: 0 12px;
  font-size: 13px;
}
.dish-card-actions .secondary:hover{
  background: rgba(110, 168, 255, 0.12);
}

/* 代替候補 section header (core 欠損時に grid 内に挿入) */
.alt-section-header{
  grid-column: 1 / -1;
  color: var(--fg2); font-size: 12px;
  padding: 10px 4px 4px;
  border-top: 1px dashed var(--line);
  font-weight: 600; letter-spacing: 0.05em;
}

/* ----------------------------------------------------------------
 * 右袖 Cart Pane (iPad 横 / desktop)
 * ---------------------------------------------------------------- */
.lib-cart-pane{
  display: none;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px;
  box-shadow: var(--shadow-sm);
  position: sticky;
  /* header (約 60px) + controls (sticky 自身) を考慮した top */
  top: calc(60px + 220px);
  align-self: flex-start;
  /* dvh = dynamic viewport (= iOS Safari の address bar 表示時/非表示時の差を吸収).
   * 100vh だと iOS で sticky cart pane の底が address bar 裏に隠れる事故が起きる. */
  max-height: calc(100dvh - 280px - env(safe-area-inset-bottom));
  overflow-y: auto;
}
@media (min-width: 768px){
  .lib-cart-pane { display: flex; flex-direction: column; gap: 10px; }
}

.lib-cart-head{
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.lib-cart-head h2{
  font-size: 13px; margin: 0; color: var(--fg2);
  text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: 600;
  flex: 1;
}
.cart-count-badge{
  background: var(--accent); color: #0b1120;
  border-radius: var(--radius-pill);
  min-width: 26px; height: 22px;
  padding: 0 8px;
  font-size: 12px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}

.lib-cart-empty{
  font-size: 12px; color: var(--fg2);
  padding: 12px 4px;
  text-align: center;
}

.lib-cart-list{
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.cart-item{
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  display: flex; align-items: center; gap: 6px;
  font-size: 13px;
}
.cart-item-name{
  flex: 1; min-width: 0; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cart-variant-btn{
  background: transparent; color: var(--fg2);
  border: 1px solid var(--line);
  padding: 4px 8px; font-size: 11px;
  min-height: 32px; min-width: 44px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.cart-variant-btn:hover{ color: var(--fg); border-color: var(--accent); }
.cart-remove-btn{
  background: transparent; color: var(--fg2);
  border: 1px solid var(--line);
  padding: 4px 8px; font-size: 12px;
  min-height: 32px; min-width: 32px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.cart-remove-btn:hover{ color: var(--danger); border-color: var(--danger); }

/* variant dropdown menu (cart 内 ▾ 押下時) */
.variant-menu{
  position: absolute;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  min-width: 180px;
  padding: 4px;
  z-index: var(--z-sticky-panel, 50);
  display: flex; flex-direction: column;
}
.variant-menu button{
  background: transparent; border: 0; color: var(--fg);
  padding: 10px 12px; text-align: left;
  min-height: 44px; font-size: 14px;
  border-radius: var(--radius-sm);
  font-weight: 500; cursor: pointer;
}
.variant-menu button:hover{ background: var(--panel2); }

.lib-cart-foot{
  display: flex; gap: 6px; margin-top: 4px;
  padding-top: 8px; border-top: 1px solid var(--line);
}
.lib-cart-foot .primary{ flex: 1; min-height: 44px; }

/* compose-mtg CTA: primary button (48px+, accent 色, icon + text 横並び).
 * disabled (cart 空) 時はくすませて pointer 不可.
 * is-loading 時は spinner + "MTG 作成中…" を表示し再押下を防止.
 */
.cart-cta-primary{
  flex: 1;
  min-height: 48px;
  font-size: 15px;
  font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  transition: background var(--duration-fast) var(--ease-standard),
              opacity var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}
.cart-cta-primary .cta-icon{ font-size: 18px; line-height: 1; }
.cart-cta-primary .cta-text{ white-space: nowrap; }
.cart-cta-primary:active:not(:disabled){ transform: scale(0.98); }
.cart-cta-primary:disabled,
.cart-cta-primary[aria-disabled="true"]{
  opacity: 0.45;
  cursor: not-allowed;
  background: var(--panel2);
  color: var(--fg2);
  border: 1px solid var(--line);
}
.cart-cta-primary.is-loading{
  opacity: 0.85;
  cursor: progress;
}
.cart-cta-primary.is-loading .spinner{
  /* primary 背景上での視認性のため border 色を反転 */
  border-color: rgba(11, 17, 32, 0.25);
  border-top-color: #0b1120;
}

/* compose-mtg inline error 領域. role=alert で aria-live=assertive. */
.cart-compose-error{
  background: rgba(255, 110, 110, 0.10);
  color: var(--danger);
  border: 1px solid rgba(255, 110, 110, 0.45);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: 12px;
  line-height: 1.4;
  word-break: break-word;
}
.cart-compose-error[hidden]{ display: none; }

/* ----------------------------------------------------------------
 * mobile (<768px) — cart pane を flow 内に表示 (sticky ではなく通常).
 * 「調理 MTG を作成」 button をモバイルでも常に到達可能にする.
 * ---------------------------------------------------------------- */
@media (max-width: 767.98px){
  .lib-cart-pane {
    display: flex; flex-direction: column; gap: 10px;
    position: static;          /* sticky 解除 (grid pane の下に普通に出す) */
    max-height: none;
    overflow-y: visible;
    margin-top: 8px;
  }
  .cart-cta-primary {
    min-height: 52px;          /* 親指操作向けに更に大きく */
    font-size: 16px;
  }
}

/* ----------------------------------------------------------------
 * お任せ FAB (auto mode)
 * ---------------------------------------------------------------- */
.auto-fab{
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  /* sticky totals bar 上に出す: bottom = totals 高さ (約 88px) + 16px + safe-area */
  bottom: calc(112px + env(safe-area-inset-bottom));
  background: var(--accent); color: #0b1120;
  border: none; border-radius: var(--radius-pill);
  padding: 14px 22px;
  min-height: 56px;
  font-size: 16px; font-weight: 700;
  box-shadow: var(--shadow-lg);
  z-index: var(--z-fab, 80); cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}
.auto-fab:hover{ background: var(--accent-hover); transform: scale(1.04); }
.auto-fab:active{ transform: scale(0.96); }
.auto-fab:focus-visible{
  outline: 3px solid #fff; outline-offset: 3px;
}
/* manual / desire mode 時は非表示 (JS で hidden 切替) */
.auto-fab[hidden]{ display: none; }

/* ----------------------------------------------------------------
 * 下部 sticky 合計 bar
 * ---------------------------------------------------------------- */
.lib-sticky-totals{
  position: fixed;
  left: 0; right: 0;
  bottom: 0;
  background: var(--panel);
  border-top: 1px solid var(--line);
  padding: 10px 12px;
  /* safe-area-inset-bottom を加味し iOS Home Bar に被らない */
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
  z-index: 70; /* fab (--z-fab: 80) の下, page sticky 上 */
  display: flex; align-items: center; gap: 14px;
  box-shadow: 0 -2px 12px rgba(0,0,0,0.35);
}
/* sidebar open 時は (≥768px) body が padding-left:280px されるので
 * fixed bar も同じ offset を踏襲 */
@media (min-width: 768px){
  html.nav-sidebar-open .lib-sticky-totals {
    left: 280px;
  }
}

.totals-kcal{
  display: inline-flex; align-items: baseline; gap: 4px;
  font-size: 12px; color: var(--fg2);
  min-width: 90px;
}
.totals-kcal strong{
  font-size: 22px; color: var(--accent); font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.totals-kcal .totals-unit{ font-size: 11px; }
.totals-kcal .totals-label{
  display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  width: 100%;
}

.totals-pfc{
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.pfc-bar{
  display: flex; height: 8px;
  background: var(--line); border-radius: var(--radius-pill);
  overflow: hidden;
}
/* PFC 色 — protein/fat/carb は色覚多様性に配慮した順序 (青→黄→緑) + テキスト併記 */
.pfc-p{ background: var(--accent); }
.pfc-f{ background: var(--warn); }
.pfc-c{ background: var(--ok); }
.pfc-bar > span{
  transition: width var(--duration-normal) var(--ease-standard);
  display: inline-block;
}
.pfc-nums{
  font-size: 11px; color: var(--fg2);
  display: flex; gap: 4px; flex-wrap: wrap;
}
.pfc-nums b{ color: var(--fg); font-weight: 600; font-variant-numeric: tabular-nums; }

.totals-ring{
  position: relative; width: 44px; height: 44px;
  flex: 0 0 44px;
  display: flex; align-items: center; justify-content: center;
}
.totals-ring svg{ position: absolute; inset: 0; }
.ring-pct{
  font-size: 10px; font-weight: 700; color: var(--fg);
  position: relative; z-index: 1;
  font-variant-numeric: tabular-nums;
}

/* ----------------------------------------------------------------
 * admin link
 * ---------------------------------------------------------------- */
.lib-admin-link{
  text-align: center; padding: 16px 4px;
  font-size: 12px; color: var(--fg2);
}
.lib-admin-link a{
  color: var(--accent); text-decoration: none;
}
.lib-admin-link a:hover{ text-decoration: underline; }

/* ----------------------------------------------------------------
 * Omakase 4-axis selector (Step 0 modal)
 * recipe-builder.html の .strategy-btn を流用. 各軸 3-way radio.
 * ---------------------------------------------------------------- */
.omakase-axes-backdrop{
  position: fixed; inset: 0; background: rgba(0,0,0,0.7);
  z-index: var(--z-modal-backdrop, 1100); display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.omakase-axes-modal{
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; max-width: 460px; width: 100%;
  padding: 18px; color: var(--fg); box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  max-height: 90dvh; overflow-y: auto;
}
.omakase-axes-modal h2{
  margin: 0 0 4px; font-size: 18px; font-weight: 700;
  display: flex; align-items: center; gap: 8px;
}
.omakase-axes-modal .axes-sub{
  margin: 0 0 12px; color: var(--fg2); font-size: 13px;
}
.omakase-axes-row{
  display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap; margin: 8px 0;
}
.omakase-axes-row > .axis-label{
  min-width: 52px; color: var(--fg2); font-size: 13px; font-weight: 600;
}
.strategy-btn{
  background: var(--panel2); color: var(--fg2);
  border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: 8px 12px; font-size: 13px; font-weight: 600; min-height: 44px;
  cursor: pointer; font-family: inherit; flex: 1 1 0; min-width: 70px;
  transition: background var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.strategy-btn:hover{
  color: var(--fg); border-color: var(--accent); background: var(--bg-elevated);
}
.strategy-btn.active{
  background: var(--accent); color: #0b1120;
  border-color: var(--accent); font-weight: 700;
}
.strategy-btn.active:hover{
  background: var(--accent-hover); border-color: var(--accent-hover);
}
.strategy-btn:focus-visible{
  outline: 3px solid var(--accent); outline-offset: 2px;
}
.omakase-axes-footer{
  display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap;
}
.omakase-axes-footer button{
  min-height: 44px; padding: 0 14px; border-radius: 8px;
  cursor: pointer; font-family: inherit; font-weight: 600;
}
.omakase-axes-footer .axes-reset{
  background: var(--panel2); color: var(--fg2);
  border: 1px solid var(--line); flex: 1 1 80px;
}
.omakase-axes-footer .axes-next{
  background: var(--accent); color: #0b1120;
  border: 1px solid var(--accent); flex: 2 1 160px; font-weight: 700;
}
.omakase-axes-footer .axes-cancel{
  background: transparent; color: var(--fg2);
  border: 1px solid var(--line); min-width: 56px;
}

/* ----------------------------------------------------------------
 * Round 18 c15-E5a: N dish AI 生成 — landing CTA 横並び + modal skeleton
 * Round 18 c15-E5b: 4 軸 strategy chip styling (= .ndish-chip + .selected)
 *
 * c15-E5a で form skeleton + state machine + open/close logic.
 * c15-E5b で 4 軸 chip (.ndish-axes / .ndish-axis / .ndish-chip) を追加.
 * submit / mt_graph render / backend 配線 は c15-E5c/d/e 担当.
 * ---------------------------------------------------------------- */

/* CTA 横並び row (= おまかせ + 献立 AI 生成) */
.lib-auto-panel .auto-panel-cta-row{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 14px;
}
.lib-auto-panel .auto-panel-cta-row .auto-panel-cta{
  margin-top: 0;
}
.lib-auto-panel .auto-panel-cta-secondary{
  background: var(--panel2);
  color: var(--fg);
  border: 1px solid var(--accent);
  font-weight: 600;
}
.lib-auto-panel .auto-panel-cta-secondary:hover{
  background: var(--bg-elevated, var(--panel2));
  border-color: var(--accent-hover, var(--accent));
}

/* ----------------------------------------------------------------
 * Round 18 Phase 1.5-A: N dish inline view styling.
 *   旧 modal pattern (.ndish-modal / .ndish-backdrop / .ndish-section /
 *   .ndish-footer 等) は撤去し, library grid と同領域に inline 配置する
 *   .lib-ndish-view 系のみで構成. base rule は本ファイル末尾の
 *   "N dish inline view base" block で定義.
 * ---------------------------------------------------------------- */
.ndish-section-label{
  display: block;
  color: var(--fg2);
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 6px;
}
.lib-ndish-view .ndish-desire-input{
  width: 100%;
  background: var(--panel2); color: var(--fg);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px 12px; font-size: 15px; font-family: inherit;
  min-height: 44px;
}
.lib-ndish-view .ndish-desire-input:focus{
  border-color: var(--accent);
  /* keyboard 利用者向けに focus ring 復活. mouse focus でも border 色変化と二重で示し,
   * a11y test (axe / WCAG 2.4.7) で fail しない. */
  outline: 2px solid var(--accent, #6ea8ff);
  outline-offset: 1px;
}
.lib-ndish-view .ndish-desire-input::placeholder{
  color: var(--fg2); opacity: 0.7;
}
.lib-ndish-view .ndish-count-select{
  background: var(--panel2); color: var(--fg);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 8px 12px; font-size: 15px; font-family: inherit;
  min-height: 44px; min-width: 120px;
}
.lib-ndish-view .ndish-count-select:focus{
  border-color: var(--accent);
  /* keyboard 利用者向けに focus ring 復活 (WCAG 2.4.7). */
  outline: 2px solid var(--accent, #6ea8ff);
  outline-offset: 1px;
}
/* ----------------------------------------------------------------
 * Round 18 c15-E5b: 4 軸 strategy chip (= cost/time/health/stock × 3 段階).
 *   ARIA radiogroup × 4 + role="radio" chip × 12. roving tabindex pattern.
 *   styling は既存 .strategy-btn (omakase 軸 modal) と同 base. 選択時 .selected で
 *   accent 背景 + 黒 text (= 既存 .tag.dish.selected 系の配色を踏襲).
 * ---------------------------------------------------------------- */
.lib-ndish-view .ndish-axes{
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lib-ndish-view .ndish-axis{
  /* fieldset default styling reset. legend は内部で float-left して inline 風に. */
  display: block;
  margin: 0;
  padding: 0;
  border: none;
  min-width: 0;
  /* fieldset の inline-size 制約を回避 (= flex 内子 chip が縮みすぎない) */
}
.lib-ndish-view .ndish-axis-legend{
  /* fieldset legend: 軸名 (= 「コスト」 等). chip 行の左 inline 並びにする. */
  display: inline-block;
  min-width: 52px;
  color: var(--fg2);
  font-size: 13px;
  font-weight: 600;
  padding: 0;
  float: left;
  line-height: 44px; /* chip min-height と中央揃え */
  margin-right: 8px;
}
.lib-ndish-view .ndish-axis-chips{
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  /* legend を float-left しているので overflow: hidden で chip group 領域を確保. */
  overflow: hidden;
}
.lib-ndish-view .ndish-chip{
  background: var(--panel2);
  color: var(--fg2);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  min-height: 44px;
  cursor: pointer;
  font-family: inherit;
  flex: 1 1 0;
  min-width: 64px;
  transition: background var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.lib-ndish-view .ndish-chip:hover{
  color: var(--fg);
  border-color: var(--accent);
  background: var(--bg-elevated, var(--panel2));
}
.lib-ndish-view .ndish-chip.selected,
.lib-ndish-view .ndish-chip[aria-checked="true"]{
  background: var(--accent);
  color: #0b1120;
  border-color: var(--accent);
  font-weight: 700;
}
.lib-ndish-view .ndish-chip.selected:hover,
.lib-ndish-view .ndish-chip[aria-checked="true"]:hover{
  background: var(--accent-hover, var(--accent));
  border-color: var(--accent-hover, var(--accent));
}
.lib-ndish-view .ndish-chip:focus-visible{
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
/* 結果プレビュー placeholder (= 生成前 or empty) */
.lib-ndish-view .ndish-preview-placeholder{
  background: var(--panel2);
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  padding: 16px;
  color: var(--fg2);
  font-size: 13px;
  text-align: center;
  min-height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Round 18 c15-E5d: 生成中 spinner state (= submitNDish path で aria-busy=true).
 *   placeholder 同 box 内に spinner + 「生成中…」 label. submit button 内の小型
 *   spinner と異なり, preview 内では 中央配置 + やや大きい text で目立たせる. */
.lib-ndish-view .ndish-preview-spinner{
  background: var(--panel2);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 16px;
  color: var(--fg);
  font-size: 14px;
  text-align: center;
  min-height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.lib-ndish-view .ndish-preview-spinner .spinner{
  width: 18px; height: 18px; border-width: 3px;
}
.lib-ndish-view .ndish-spinner-text{
  font-weight: 600;
  color: var(--accent);
}
/* Round 18 c15-E5d: error fallback (= window.Toast 不在時のみ preview 内に
 *   error message を inject する fallback path 用). 通常は Toast で通知. */
.lib-ndish-view .ndish-preview-error{
  background: rgba(255, 110, 110, 0.10);
  border: 1px solid rgba(255, 110, 110, 0.45);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  color: var(--danger);
  font-size: 13px;
  text-align: left;
  min-height: 60px;
  line-height: 1.4;
  word-break: break-word;
}
/* 生成失敗 リトライ fix: error UI (= message + hint + 「もう一度生成する」/「キャンセル」).
 *   選択を失わせない導線. spinner / result と同じ modal 幅内に収める. */
.lib-ndish-view .ndish-error-icon{
  font-size: 20px;
  line-height: 1;
  margin-bottom: 4px;
}
.lib-ndish-view .ndish-error-msg{
  font-weight: 600;
  margin-bottom: 4px;
}
.lib-ndish-view .ndish-error-hint{
  color: var(--fg2);
  font-size: 12px;
  margin-bottom: 10px;
  line-height: 1.4;
}
.lib-ndish-view .ndish-error-actions{
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lib-ndish-view .ndish-retry-btn{
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 600;
  background: var(--accent);
  color: #fff;
  border: 1px solid var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.lib-ndish-view .ndish-retry-btn:hover{
  filter: brightness(1.08);
}
.lib-ndish-view .ndish-retry-btn:disabled{
  cursor: not-allowed;
  opacity: 0.5;
}
.lib-ndish-view .ndish-error-cancel-btn{
  width: 100%;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  background: transparent;
  color: var(--fg2);
  border: 1px solid var(--line);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.lib-ndish-view .ndish-error-cancel-btn:hover{
  background: var(--panel2);
  color: var(--fg);
}
/* ----------------------------------------------------------------
 * Round 18 c15-E5c: 結果プレビュー render (dish list + mt_graph + makespan)
 *
 *   - .ndish-preview-result: placeholder と差し替わる root container.
 *     modal 幅 480px 内. 縦は max 400px + overflow auto.
 *   - dish list: 上段 (= 主食材 + pfc).
 *   - mt_graph: 下段 (= text DAG list. 解凍 MT は青 background + ❄).
 *   - makespan summary: 末尾. 並列 / 解凍 / 計 を breakdown.
 * ---------------------------------------------------------------- */
.lib-ndish-view .ndish-preview-result{
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px;
  color: var(--fg);
  font-size: 13px;
  max-height: 400px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.lib-ndish-view .ndish-result-h3{
  margin: 0 0 6px 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--fg2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* dish list (上段) */
.lib-ndish-view .ndish-dish-list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lib-ndish-view .ndish-dish-item{
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  padding: 8px 10px;
}
.lib-ndish-view .ndish-dish-name{
  font-weight: 700;
  font-size: 14px;
  color: var(--fg);
  display: flex;
  gap: 6px;
  align-items: baseline;
}
.lib-ndish-view .ndish-dish-idx{
  color: var(--fg2);
  font-weight: 600;
  font-size: 12px;
}
.lib-ndish-view .ndish-dish-ings{
  color: var(--fg2);
  font-size: 12px;
  margin-top: 2px;
}
.lib-ndish-view .ndish-dish-pfc{
  display: flex;
  gap: 8px;
  margin-top: 4px;
  font-size: 11px;
  color: var(--fg2);
}
.lib-ndish-view .ndish-dish-pfc span{
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  font-weight: 600;
}
/* mt_graph (下段) text DAG list */
.lib-ndish-view .ndish-mt-list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.lib-ndish-view .ndish-mt-step{
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  font-size: 12px;
  flex-wrap: wrap;
}
.lib-ndish-view .ndish-mt-num{
  font-weight: 700;
  color: var(--accent);
  font-size: 11px;
  min-width: 28px;
}
.lib-ndish-view .ndish-mt-label{
  flex: 1 1 auto;
  color: var(--fg);
}
.lib-ndish-view .ndish-mt-dur{
  color: var(--fg2);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.lib-ndish-view .ndish-mt-deps{
  color: var(--fg2);
  font-size: 10px;
  flex-basis: 100%;
  padding-left: 36px;
}
/* 解凍 MT 強調 (= 青 background + ❄ icon) */
.lib-ndish-view .ndish-mt-thaw{
  background: rgba(110, 168, 255, 0.12);
  border-color: var(--accent);
}
.lib-ndish-view .ndish-mt-thaw .ndish-mt-num,
.lib-ndish-view .ndish-mt-thaw .ndish-mt-label{
  color: var(--accent);
}
.lib-ndish-view .ndish-mt-icon{
  color: var(--accent);
  font-size: 13px;
}
/* makespan summary (末尾) */
.lib-ndish-view .ndish-result-summary{
  border-top: 1px solid var(--line);
  padding-top: 10px;
  margin-top: 2px;
}
.lib-ndish-view .ndish-summary-main{
  font-size: 13px;
  color: var(--fg);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.lib-ndish-view .ndish-summary-main strong{
  color: var(--accent);
  font-size: 15px;
  font-weight: 700;
}
.lib-ndish-view .ndish-summary-icon{
  color: var(--fg2);
}
.lib-ndish-view .ndish-summary-note{
  font-size: 11px;
  color: var(--fg2);
  margin-top: 4px;
}
/* Round 18 c15-E5e: 「cart に追加」 button. renderNDishResult 末尾に表示し
 *   全 dish を一括 cart push する CTA. accent 色 + 全幅で目立たせる. */
.lib-ndish-view .ndish-result-actions{
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.lib-ndish-view .ndish-add-cart-btn{
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 700;
  background: var(--accent);
  color: #0b1120;
  border: 1px solid var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.lib-ndish-view .ndish-add-cart-btn:hover{
  filter: brightness(0.95);
}
.lib-ndish-view .ndish-add-cart-btn:disabled{
  background: var(--panel2);
  color: var(--fg2);
  border-color: var(--line);
  cursor: not-allowed;
  opacity: 0.7;
}
/* Round 18 Phase 1.5-C: 「これにする」/「やり直す」/「破棄」 の 3 button group container.
 *   inline view の result area 末尾に表示. dry_run preview から save-from-preview
 *   への確定 flow を提供 (= AI 失敗作で library が散らかる不安を解消).
 *   column 配置で「これにする」 を最上段 primary, 残り 2 つを secondary に. */
.lib-ndish-view .ndish-result-confirm-actions{
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Round 18 Phase 1.5-C: 「これにする」 primary button.
 *   AI 失敗作 library 散らかし不安を解消する確定 CTA. accent 色 + 全幅 + 強調.
 *   click → /api/dishes/save-from-preview (= preview dish object 直接 INSERT, AI 再呼出なし). */
.lib-ndish-view .ndish-confirm-btn{
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 700;
  background: var(--accent);
  color: #0b1120;
  border: 1px solid var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.lib-ndish-view .ndish-confirm-btn:hover{
  filter: brightness(0.95);
}
.lib-ndish-view .ndish-confirm-btn:disabled{
  background: var(--panel2);
  color: var(--fg2);
  border-color: var(--line);
  cursor: not-allowed;
  opacity: 0.6;
}

/* Round 18 Phase 1.5-C: 「やり直す」 secondary button. 同じ要望 + 4 軸で AI 再生成.
 *   別 batch_id で別 dish 出力. cost 倍だが UX 向上. neutral background. */
.lib-ndish-view .ndish-regen-btn{
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 600;
  background: var(--panel2);
  color: var(--fg);
  border: 1px solid var(--line);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.lib-ndish-view .ndish-regen-btn:hover{
  background: var(--panel);
}
.lib-ndish-view .ndish-regen-btn:disabled{
  cursor: not-allowed;
  opacity: 0.5;
}

/* Round 18 Phase 1.5-C: 「破棄」 tertiary button. preview を捨てるだけで view は閉じない.
 *   destructive ではないので赤系は避け subdued style に. */
.lib-ndish-view .ndish-discard-btn{
  width: 100%;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  background: transparent;
  color: var(--fg2);
  border: 1px solid var(--line);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.lib-ndish-view .ndish-discard-btn:hover{
  background: var(--panel2);
  color: var(--fg);
}
.lib-ndish-view .ndish-discard-btn:disabled{
  cursor: not-allowed;
  opacity: 0.5;
}

.lib-ndish-view .ndish-divider-label{
  color: var(--fg2);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: -2px;
  margin-bottom: 8px;
}
/* Round 18 c15-E5d: spinner 中の submit button (= disabled かつ is-loading).
 *   accent 背景上では spinner 色を反転して視認性確保. cart-cta-primary.is-loading
 *   と同 pattern. text + spinner を inline 並びにする. */
/* spinner 中の chip は半透明化して input lock 状態を visual に示す. */
.lib-ndish-view .ndish-chip:disabled{
  opacity: 0.55;
  cursor: not-allowed;
}
.lib-ndish-view .ndish-desire-input:disabled,
.lib-ndish-view .ndish-count-select:disabled{
  opacity: 0.55;
  cursor: not-allowed;
}
/* ----------------------------------------------------------------
 * Round 18 c15-E6: storage chip (= dish 詳細 modal の ingredient 行).
 *   inventory JOIN 結果から「冷凍」「冷蔵」「常温」 を視覚化.
 *   配色は inventory.html 内の .tag.freeze / .tag.refrig / .tag.room と
 *   整合的 (青系 = 冷凍, 緑系 = 冷蔵, 灰系 = 常温). library.html には
 *   inventory token (--freeze 等) が無いので固定値で定義.
 *   opt-in 設計 (= localStorage `library.showStorageChips` = "1" で ON).
 * ---------------------------------------------------------------- */
.storage-chip{
  display: inline-block;
  padding: 1px 6px;
  margin-left: 4px;
  font-size: 11px;
  border-radius: var(--radius-pill, 999px);
  font-weight: 600;
  line-height: 1.4;
  vertical-align: baseline;
  border: 1px solid transparent;
}
.storage-chip.storage-chip-freeze{
  background: rgba(59, 130, 246, 0.15);
  color: #93c5fd;
  border-color: rgba(59, 130, 246, 0.35);
}
.storage-chip.storage-chip-refrig{
  background: rgba(110, 231, 167, 0.15);
  color: var(--ok, #6ee7a7);
  border-color: rgba(110, 231, 167, 0.35);
}
.storage-chip.storage-chip-room{
  background: rgba(179, 185, 195, 0.15);
  color: var(--fg2, #b3b9c3);
  border-color: rgba(179, 185, 195, 0.35);
}

/* ----------------------------------------------------------------
 * Round 18 Phase 1.5-A: N dish inline view base.
 *   library grid と同領域に inline 配置する panel. 旧 modal 系の制約
 *   (中央 dialog flex 配置 / max-width 520px / max-height 90dvh / overflow auto)
 *   は持たず, panel として border + 控えめな shadow + 標準 padding のみ.
 *   max-width: none / overflow: visible は明示的に設定 (= 親 container 等で
 *   うっかり制約が付かないように. かつ regression test gate 4 が assert する形式).
 * ---------------------------------------------------------------- */
.lib-ndish-view {
  max-width: none;
  width: auto;
  max-height: none;
  overflow: visible;
  margin: 12px 0;
  padding: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--fg);
  box-shadow: var(--shadow-sm);
}

/* view head: タイトル + sub */
.lib-ndish-view .ndish-view-head {
  margin-bottom: 12px;
}
.lib-ndish-view .ndish-view-title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 8px;
}
.lib-ndish-view .ndish-view-sub {
  margin: 4px 0 0;
  color: var(--fg2);
  font-size: 13px;
}

/* form row layout: 縦並び + 品数/生成 は inline. */
.lib-ndish-view .ndish-view-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.lib-ndish-view .ndish-view-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.lib-ndish-view .ndish-view-row-inline {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}
.lib-ndish-view .ndish-view-row-inline > div {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.lib-ndish-view .ndish-view-row-cta {
  margin-left: auto;
  align-self: flex-end;
}
.lib-ndish-view .ndish-view-row-cta .ndish-submit {
  min-height: 48px;
  padding: 0 18px;
  font-weight: 700;
  border-radius: var(--radius-md);
}
.lib-ndish-view .ndish-view-row-cta .ndish-submit.is-loading {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  opacity: 0.85;
  cursor: progress;
}
.lib-ndish-view .ndish-view-row-cta .ndish-submit.is-loading .spinner {
  border-color: rgba(11, 17, 32, 0.25);
  border-top-color: #0b1120;
}

/* divider-label (= 「戦略軸 (任意)」) を section header 風に. */
.lib-ndish-view .ndish-divider-label {
  color: var(--fg2);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* 結果 area の base. 旧 .ndish-modal .ndish-preview-* を流用しつつ inline 用に幅解放. */
.lib-ndish-view .ndish-view-result {
  margin-top: 16px;
  max-height: none;
  /* placeholder / spinner / error / result 別 class で見た目 切替 */
}
.lib-ndish-view .ndish-view-result.ndish-preview-placeholder {
  background: var(--panel2);
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  padding: 24px;
  color: var(--fg2);
  font-size: 13px;
  text-align: center;
  min-height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lib-ndish-view .ndish-view-result.ndish-preview-spinner {
  background: var(--panel2);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 24px;
  color: var(--fg);
  font-size: 14px;
  text-align: center;
  min-height: 100px;
  /* Round 18 Phase 1.8: 「server 側で生成中…」 sub-label を 縦並びにするため column. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.lib-ndish-view .ndish-view-result.ndish-preview-spinner .spinner {
  width: 18px; height: 18px; border-width: 3px;
}
.lib-ndish-view .ndish-view-result .ndish-spinner-text {
  font-weight: 600;
  color: var(--accent);
}
/* Round 18 Phase 1.8: 「server 側で生成中… reload しても続行されます」 sub-label.
   spinner / main label より控えめ font / muted color (= 補足情報). */
.lib-ndish-view .ndish-view-result .ndish-spinner-sublabel {
  font-size: 12px;
  color: var(--muted, #888);
  opacity: 0.85;
  line-height: 1.4;
  margin-top: 2px;
}
/* Round 18 Phase 4 (= AI latency 真因対策): elapsed counter + cancel button.
   user 不安軽減: 「動いてる」 visibility + 主導 abort 手段. */
.lib-ndish-view .ndish-view-result .ndish-spinner-elapsed {
  font-size: 14px;
  font-weight: 600;
  color: var(--accent, #f59e0b);
  font-variant-numeric: tabular-nums;
  margin-top: 4px;
}
.lib-ndish-view .ndish-view-result .ndish-cancel-btn {
  margin-top: 10px;
  padding: 6px 16px;
  font-size: 13px;
  background: transparent;
  color: var(--muted, #888);
  border: 1px solid var(--muted, #888);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.lib-ndish-view .ndish-view-result .ndish-cancel-btn:hover {
  background: rgba(255, 110, 110, 0.15);
  color: var(--danger, #ff6e6e);
  border-color: var(--danger, #ff6e6e);
}
/* focus-visible は hover と同じ色味 + outline を維持 (= keyboard 利用者に表示). */
.lib-ndish-view .ndish-view-result .ndish-cancel-btn:focus-visible {
  background: rgba(255, 110, 110, 0.15);
  color: var(--danger, #ff6e6e);
  border-color: var(--danger, #ff6e6e);
  outline: 2px solid var(--danger, #ff6e6e);
  outline-offset: 2px;
}
.lib-ndish-view .ndish-view-result.ndish-preview-error {
  background: rgba(255, 110, 110, 0.10);
  border: 1px solid rgba(255, 110, 110, 0.45);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  color: var(--danger);
  font-size: 13px;
  text-align: left;
  line-height: 1.4;
}
.lib-ndish-view .ndish-view-result.ndish-preview-result {
  background: transparent;
  border: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 結果 dish card grid (= library dish-card と同じ視覚言語 + ndish-result-card 追加) */
.lib-ndish-view .ndish-result-dishes {
  margin-top: 4px;
}
.lib-ndish-view .ndish-result-dishes .ndish-result-h3 {
  margin: 0 0 8px 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--fg2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lib-ndish-view .ndish-result-dish-grid {
  /* lib-grid と同 grid-template だが container は ndish-view 内 */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--lib-card-min), 1fr));
  gap: 10px;
}
.lib-ndish-view .ndish-result-card .dish-name {
  font-weight: 700;
  font-size: 14px;
}
.lib-ndish-view .ndish-result-card .ndish-dish-ings {
  color: var(--fg2);
  font-size: 12px;
}
.lib-ndish-view .ndish-result-card .ndish-dish-pfc {
  display: flex;
  gap: 6px;
  margin-top: 2px;
  font-size: 11px;
  color: var(--fg2);
  flex-wrap: wrap;
}
.lib-ndish-view .ndish-result-card .ndish-dish-pfc span {
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  padding: 2px 8px;
  font-weight: 600;
}
.lib-ndish-view .ndish-result-card .ndish-dish-note {
  color: var(--fg2);
  font-size: 12px;
  font-style: italic;
}
.lib-ndish-view .ndish-result-card.in-cart {
  border-color: var(--ok, #6ee7a7);
}

/* Round 18 Phase 1.6-A: 採用 (= from_library) dish card は薄い accent border + tint.
   新規生成 dish と視覚的に区別 (= 「📚 library」 chip と一貫). */
.lib-ndish-view .ndish-result-card.from-library {
  border-color: var(--accent, #6ea8ff);
  background: linear-gradient(
    to bottom,
    var(--accent-soft, rgba(110, 168, 255, 0.07)),
    transparent 60%
  );
}
.lib-ndish-view .ndish-result-card.from-library.in-cart {
  /* in-cart の ok green を優先 (= cart 状態が user 主要情報) */
  border-color: var(--ok, #6ee7a7);
}

/* 結果 mt_graph / summary / 一括 cart 追加 button は modal 用 style を継承.
   ただし .lib-ndish-view 内では padding 余白を inline 領域用に微調整. */
.lib-ndish-view .ndish-result-mts,
.lib-ndish-view .ndish-result-summary,
.lib-ndish-view .ndish-result-actions {
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px;
}
.lib-ndish-view .ndish-result-actions {
  border: none;
  background: transparent;
  padding: 0;
}
.lib-ndish-view .ndish-add-cart-btn {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: inherit;
  font-weight: 700;
  background: var(--accent);
  color: #0b1120;
  border: 1px solid var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.lib-ndish-view .ndish-add-cart-btn:hover {
  filter: brightness(0.95);
}

/* mt_graph step (= 旧 modal style 流用). 一応再宣言で確実に. */
.lib-ndish-view .ndish-mt-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.lib-ndish-view .ndish-mt-step {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-xs, 4px);
  font-size: 12px;
  flex-wrap: wrap;
}
.lib-ndish-view .ndish-mt-num {
  font-weight: 700;
  color: var(--accent);
  font-size: 11px;
  min-width: 28px;
}
.lib-ndish-view .ndish-mt-label {
  flex: 1 1 auto;
  color: var(--fg);
}
.lib-ndish-view .ndish-mt-dur {
  color: var(--fg2);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.lib-ndish-view .ndish-mt-deps {
  color: var(--fg2);
  font-size: 10px;
  flex-basis: 100%;
  padding-left: 36px;
}
.lib-ndish-view .ndish-mt-thaw {
  background: rgba(110, 168, 255, 0.12);
  border-color: var(--accent);
}
.lib-ndish-view .ndish-mt-thaw .ndish-mt-num,
.lib-ndish-view .ndish-mt-thaw .ndish-mt-label {
  color: var(--accent);
}
.lib-ndish-view .ndish-summary-main {
  font-size: 14px;
  color: var(--fg);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.lib-ndish-view .ndish-summary-main strong {
  color: var(--accent);
  font-size: 16px;
  font-weight: 700;
}
.lib-ndish-view .ndish-summary-note {
  font-size: 11px;
  color: var(--fg2);
  margin-top: 4px;
}

/* mode-segmented: ndish 用 active 色 (= optional. 既存 [aria-pressed=true] で十分なので無効). */

/* ----------------------------------------------------------------
 * reduced motion
 * ---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .dish-card, .auto-fab, .pfc-bar > span, .match-bar-fill {
    transition: none;
  }
  .spinner { animation: none; }
  .strategy-btn { transition: none; }
}

/* ================================================================
 * Round 18 Phase 1.5-D (rebased): inline dedup banner.
 *   window.confirm modal-popup の代わりに DOM 内 inline banner で
 *   「これと似た dish が library にあります」 を表示する.
 *   - .ndish-dedup-banner: 標準. result area 内に挿入される箱.
 *   - .ndish-dedup-banner-floating: $container 不在時の body 直下 fallback.
 *     omakase Builder modal 内で出すケースに対応 (= modal の上に重ねる).
 *   - 「保存する」 「やめる」 button group は inline view 既存 button と
 *     同じ視覚言語 (= primary accent + neutral subdued).
 * ================================================================ */
.ndish-dedup-banner{
  margin: 10px 0;
  padding: 12px 14px;
  border: 1px solid var(--warn, #f5b04a);
  background: rgba(245, 176, 74, 0.08);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--fg);
  font-family: inherit;
}
.ndish-dedup-banner-floating{
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: var(--z-modal, 1110);
  min-width: 280px;
  max-width: 480px;
  background: var(--panel);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.ndish-dedup-banner-head{
  margin: 0;
  font-weight: 700;
  color: var(--warn, #f5b04a);
  font-size: 14px;
}
.ndish-dedup-banner-list{
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ndish-dedup-banner-item{
  font-size: 13px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
}
.ndish-dedup-banner-name{
  font-weight: 600;
  color: var(--fg);
}
.ndish-dedup-banner-sim{
  color: var(--fg2);
  font-size: 12px;
}
.ndish-dedup-banner-q{
  margin: 0;
  font-size: 13px;
  color: var(--fg);
}
.ndish-dedup-banner-actions{
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.ndish-dedup-banner-save,
.ndish-dedup-banner-cancel{
  min-height: 38px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 600;
  font-size: 13px;
}
.ndish-dedup-banner-save{
  background: var(--accent);
  color: #0b1120;
  border: 1px solid var(--accent);
}
.ndish-dedup-banner-save:hover{
  filter: brightness(0.95);
}
.ndish-dedup-banner-save:focus-visible{
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ndish-dedup-banner-cancel{
  background: transparent;
  color: var(--fg2);
  border: 1px solid var(--line);
}
.ndish-dedup-banner-cancel:hover{
  background: var(--panel2);
  color: var(--fg);
}
.ndish-dedup-banner-cancel:focus-visible{
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Phase 1.5-D: dedup conflict inline banner */
.ndish-dedup-banner {
  background: rgba(245, 158, 11, 0.12);
  border: 1px solid rgba(245, 158, 11, 0.5);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 12px;
}
.ndish-dedup-title {
  margin: 0 0 8px 0;
  font-weight: 600;
  color: #d97706;
}
.ndish-dedup-list {
  margin: 6px 0;
  padding-left: 20px;
  font-size: 0.92em;
}
.ndish-dedup-pct {
  color: #b45309;
  font-weight: 600;
  margin-left: 6px;
}
.ndish-dedup-q { margin: 8px 0; }
.ndish-dedup-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}
.ndish-dedup-cancel,
.ndish-dedup-confirm {
  min-height: 36px;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
}
.ndish-dedup-cancel {
  background: var(--card-2, #1f2937);
  color: var(--text, #e5e7eb);
  border: 1px solid var(--border, #374151);
}
.ndish-dedup-confirm {
  background: var(--accent, #f59e0b);
  color: #0b1120;
  border: 1px solid var(--accent, #f59e0b);
}
.ndish-dedup-cancel:focus-visible,
.ndish-dedup-confirm:focus-visible {
  outline: 3px solid var(--accent, #f59e0b);
  outline-offset: 2px;
}

/* Round 18 Phase 1.10: SW update banner — 新 version 検出時 表示 → click で reload.
 * Phase 1.11 critical fix: `display: flex` が UA stylesheet の `[hidden] { display: none }`
 *   を class specificity で上書きして banner が常時表示される bug. `display:none` を
 *   default にし, `:not([hidden])` 時のみ flex 化. これで `hidden` attribute が機能する. */
.sw-update-banner {
  position: fixed;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast, 1200);
  background: var(--accent, #f59e0b);
  color: #0b1120;
  padding: 10px 14px;
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  display: none;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  font-size: 14px;
  max-width: 90vw;
}
.sw-update-banner:not([hidden]) {
  display: flex;
}
.sw-update-banner-btn {
  background: #0b1120;
  color: var(--accent, #f59e0b);
  border: none;
  border-radius: 6px;
  padding: 6px 14px;
  cursor: pointer;
  font-weight: 700;
  min-height: 36px;
}
.sw-update-banner-btn:hover { opacity: 0.9; }
.sw-update-banner-close {
  background: transparent;
  border: none;
  color: #0b1120;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
  padding: 4px 6px;
  min-height: 32px;
}
.sw-update-banner-close:focus-visible,
.sw-update-banner-btn:focus-visible {
  outline: 3px solid #0b1120;
  outline-offset: 2px;
}
