/* ============================================================
   fan-tool — "Quiet Lounge" design system
   Concept: 閉じた濃いコミュニティ / 静かな熱量 / 居場所
   ------------------------------------------------------------
   - Warm paper + ink-night palette (no Bootstrap blue/purple)
   - Display: Noto Sans JP (gothic, Sprint 20-A default; mincho is opt-in via font settings)
   - Body:    Noto Sans JP
   - Lines hairline-thin, generous whitespace, subtle warmth
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600&family=Zen+Old+Mincho:wght@400;500;600;700&family=Noto+Sans+JP:wght@300;400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  /* Ink (night) */
  --ink-900: #15161b;
  --ink-850: #1a1c22;
  --ink-800: #20232b;
  --ink-700: #2a2d36;
  --ink-600: #3a3d47;
  --ink-500: #555864;

  /* Paper (warm) */
  --paper:         #f3eee3;
  --paper-tint:    #ece5d4;
  --paper-card:    #fbf7ee;
  --paper-elev:    #ffffff;

  /* Accents — low chroma, earthy */
  --amber-700: #a5772f;
  --amber-600: #c8924a;
  --amber-300: #e6c891;
  --amber-100: #f5e6c8;

  --moss-600:  #5d7158;
  --moss-100:  #dfe6d6;

  --clay-600:  #b65a4a;
  --clay-100:  #f1d7ce;

  --plum-600:  #6e4f63; /* admin badge subtle */

  /* Text */
  --text:      #25221c;
  --text-dim:  #5a544a;
  --muted:     #8b8473;
  --line:      #e2d9c6;
  --line-strong: #cabfa6;
  --line-dark: #2e2f38;

  /* ---- Sprint 1.7 bridge tokens ----
     Branding presets (Quiet Lounge / Dark Velvet / Cherry Paper)
     overwrite --color-paper / --color-text etc. via the dynamic
     <style data-branding-vars>. The aliases below let Sprint 1's
     CSS read those preset values transparently. When no preset
     is applied (or for the original Quiet Lounge tone) they
     fall back to the warm Quiet Lounge defaults. */
  --color-paper:    var(--paper);
  --color-card:     var(--paper-card);
  --color-text:     var(--text);
  --color-text-dim: var(--text-dim);
  --color-muted:    var(--muted);
  --color-line:     var(--line);
  --color-accent:   var(--amber-600);
}

/* When a branding preset is applied --text becomes the preset's
   text color, but --text-dim stays the Quiet-Lounge brown unless
   we derive it. color-mix lets us stay neutral across presets:
   a softened version of the active text color over the active
   paper color, then blended toward muted for warmth. */
:root {
  --text-dim: color-mix(in oklab, var(--text) 72%, var(--muted) 28%);

  /* Geometry */
  --radius-sm: 4px;
  --radius:    8px;
  --radius-lg: 14px;

  /* Shadow — soft warm */
  --shadow-sm: 0 1px 0 rgba(50, 40, 20, 0.04);
  --shadow:    0 1px 2px rgba(50, 40, 20, 0.04), 0 8px 24px -12px rgba(50, 40, 20, 0.10);
  --shadow-lg: 0 24px 60px -24px rgba(20, 16, 8, 0.35);

  /* Typography */
  --font-sans:    "Noto Sans JP", -apple-system, BlinkMacSystemFont, "Hiragino Sans", "Yu Gothic UI", sans-serif;
  /* Sprint 20-A: 見出し既定を明朝から和文ゴシック（Noto Sans JP）へ。明朝はフォント設定 UI で選択可。 */
  --font-display: "Noto Sans JP", -apple-system, BlinkMacSystemFont, "Hiragino Sans", "Yu Gothic UI", sans-serif;
  --font-latin:   "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans", "Yu Gothic UI", sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* Focus */
  --focus-ring: 0 0 0 2px var(--paper), 0 0 0 4px rgba(200, 146, 74, 0.55);

  /* ---- sprint-5.1: 本人（推し）の "温かい特別感" トークン ----
     view-all（moss 緑）・author（info 青）・運営とは被らない暖色アクセント。
     clay（テラコッタ〜ローズ）はプリセットごとに再調律される（light=#b65a4a /
     dark=#d6786a）ため、本人強調を全プリセットで地続きに保てる。
     けばけばしいマゼンタは使わず、紙に灯がともるような静かな暖色で。 */
  --owner:       var(--clay-600);
  --owner-deep:  color-mix(in oklab, var(--clay-600) 78%, var(--text) 22%);
  --owner-on:    #fff;
  --owner-tint:  color-mix(in oklab, var(--clay-600) 7%, var(--color-card));
  --owner-line:  color-mix(in oklab, var(--clay-600) 42%, var(--color-line));
  --owner-glow:  color-mix(in oklab, var(--clay-600) 24%, transparent);
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body {
  background: var(--paper);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.65;
  letter-spacing: 0.005em;
}

/* Links use a slightly darkened accent so they sit "in" the page on
   any preset (Quiet Lounge brown, Dark Velvet gold, Cherry Paper pink). */
a { color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%); text-decoration: none; transition: color 0.15s ease; }
a:hover { color: var(--color-text); }

/* ::selection follows preset accent so text drag highlight reflects
   the active theme (TAKETIN Brand=スカイブルー、Office Blue=ネイビー等)。 */
::selection {
  background: color-mix(in oklab, var(--color-accent) 35%, var(--color-paper) 65%);
  color: var(--color-text);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--color-text);
}

code, .mono { font-family: var(--font-mono); font-size: 0.88em; }

/* Global focus ring (kills Bootstrap blue) */
:focus { outline: none; }
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: 4px;
}

/* ============================================================
   AUTH (login)
   ============================================================ */
.auth-body {
  /* Sprint 1.x.y: nav_tone 連動。dark なら --auth-bg-* は ink、light なら paper 派生 */
  background:
    radial-gradient(1200px 600px at 20% -10%, var(--auth-bg-1, #2b2937) 0%, transparent 60%),
    radial-gradient(900px 500px at 90% 110%, var(--auth-bg-2, #1c1822) 0%, transparent 60%),
    linear-gradient(180deg, var(--auth-bg-3, #0f0e14) 0%, var(--auth-bg-2, #16131c) 100%);
  min-height: 100vh;
  position: relative;
  /* register など縦長コンテンツも閲覧できるよう、縦方向はスクロール許可。
     横方向のグレイン/罫線の溢れだけ抑える。 */
  overflow-x: hidden;
}
.auth-body::before {
  /* subtle grain */
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    radial-gradient(rgba(255,255,255,0.025) 1px, transparent 1px);
  background-size: 3px 3px;
  mix-blend-mode: overlay;
}
.auth-body::after {
  /* かつて「閉じた空間の象徴」として中央に縦罫線を引いていたが、
     register 等の縦長ページや light トーン時に視認しすぎるため非表示。
     必要なら display: block; を復活させればよい。 */
  display: none;
}

.auth-shell {
  position: relative;
  max-width: 420px;
  margin: 0 auto;
  padding: 88px 24px 48px;
  text-align: center;
}

.auth-brand {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  margin-bottom: 56px;
}
.auth-brand .brand-mark {
  width: 44px; height: 44px;
  /* Sprint 1.x.y: nav_tone 連動。dark なら金、light なら accent。 */
  color: var(--auth-mark, var(--amber-300));
}
.auth-brand .brand-word {
  font-family: var(--font-latin);
  font-size: 22px;
  font-weight: 500;
  color: var(--auth-word, #e6e8ec);
  letter-spacing: 0.32em;
  padding-left: 0.32em; /* visually centre letter-spaced text */
}
.auth-brand .brand-sub {
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--auth-sub, rgba(230, 200, 145, 0.5));
  letter-spacing: 0.5em;
  padding-left: 0.5em;
}

.auth-card {
  position: relative;
  background: var(--paper-card);
  border-radius: 2px;
  padding: 44px 40px 36px;
  text-align: left;
  box-shadow: var(--shadow-lg);
}
.auth-card::before {
  /* hairline frame inside the card */
  content: "";
  position: absolute;
  inset: 8px;
  border: 1px solid rgba(176, 144, 88, 0.18);
  border-radius: 1px;
  pointer-events: none;
}

.auth-card h1 {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 500;
  margin: 0 0 28px;
  text-align: center;
  letter-spacing: 0.2em;
  color: var(--color-text);
}
.auth-card h1::after {
  content: "";
  display: block;
  width: 24px;
  height: 1px;
  /* hairline accent under the title — follows brand accent across presets */
  background: var(--color-accent);
  margin: 14px auto 0;
}

.auth-footer {
  margin-top: 40px;
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.3em;
  color: var(--auth-sub, rgba(230, 200, 145, 0.35));
  text-transform: uppercase;
}

/* ============================================================
   APP SHELL (user side, 3-column)
   ============================================================ */
.app-body { background: var(--paper); }

.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

/* ---- left sidenav ----
   The sidenav is intentionally a constant dark "rail" across all
   branding presets — it frames the main content like the spine of a
   notebook. All --ink-* and --amber-300 references inside .app-sidenav
   are deliberate fixed colors and are NOT theme-linked. */
.app-sidenav {
  /* Sprint 1.x.y: nav_tone 連動。dark 既定だが light で paper 派生も可。 */
  background: var(--nav-bg, var(--ink-900));
  color: var(--nav-text, #cdd0d6);
  padding: 28px 18px 20px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  border-right: 1px solid var(--nav-line, var(--ink-700));
}

.app-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 8px 28px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--nav-line, var(--ink-700));
}
.app-brand .brand-mark {
  width: 26px; height: 26px;
  color: var(--nav-accent, var(--amber-300));
  flex-shrink: 0;
}
.app-brand .brand-word {
  /* admin (.admin-brand .brand-word) と揃える。font-weight 未指定で
   * Latin フォントの細身を活かす。 */
  font-family: var(--font-latin);
  font-size: 15px;
  color: var(--nav-text, #e6e8ec);
  letter-spacing: 0.18em;
  padding-left: 0.18em;
}

.app-sidenav nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-top: 6px;
}

.app-sidenav .nav-link {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--nav-text-dim, #9aa0a8);
  padding: 10px 12px;
  border-radius: 4px;
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 400;
  letter-spacing: 0.04em;
  transition: background 0.18s ease, color 0.18s ease;
  position: relative;
}
.app-sidenav .nav-link svg {
  width: 18px; height: 18px;
  flex-shrink: 0;
  stroke-width: 1.4;
}
.app-sidenav .nav-link:hover:not(.disabled) {
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 8%, transparent);
  color: var(--nav-text, #e6e8ec);
}
.app-sidenav .nav-link.active {
  color: var(--nav-text, #fff);
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 14%, transparent);
}
.app-sidenav .nav-link.active::before {
  content: "";
  position: absolute;
  left: -18px; top: 50%;
  transform: translateY(-50%);
  width: 2px; height: 18px;
  background: var(--nav-text, var(--amber-600));
}
.app-sidenav .nav-link.disabled {
  color: color-mix(in oklab, var(--nav-text-dim, #5a5546) 70%, transparent);
  pointer-events: none;
  opacity: 0.65;
}
.app-sidenav hr {
  border: 0;
  border-top: 1px solid var(--nav-line, var(--ink-700));
  margin: 14px 0;
}
.app-sidenav .nav-admin {
  margin-top: 6px;
  color: var(--nav-accent, var(--amber-300)) !important;
  border: 1px solid color-mix(in oklab, var(--nav-accent, #e6c891) 22%, transparent);
  justify-content: center;
  font-family: var(--font-latin);
  letter-spacing: 0.18em;
  font-size: 12px;
  padding: 9px 12px;
  text-transform: uppercase;
}
.app-sidenav .nav-admin:hover {
  background: color-mix(in oklab, var(--nav-accent, #e6c891) 10%, transparent) !important;
  border-color: color-mix(in oklab, var(--nav-accent, #e6c891) 35%, transparent);
  color: var(--nav-text, #fff) !important;
}

.app-sidenav-footer {
  border-top: 1px solid var(--nav-line, var(--ink-700));
  padding-top: 14px;
  margin-top: 14px;
  font-size: 12.5px;
}

.user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  padding: 4px 6px;
}
.user-chip .avatar,
.user-chip img {
  width: 32px; height: 32px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--ink-700);
  border: 1px solid var(--ink-600);
  flex-shrink: 0;
}
.user-chip-name {
  /* nav トーン連動の主要テキスト色に合わせる（固定 #ddd5c2 だと light テーマで薄すぎて
     読めない）。ブランド名・アクティブなナビリンクと同じ可読色になる。 */
  color: var(--nav-text, #ddd5c2);
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Sprint 9.1: スーパー管理者（全権限保持者）の印。
   8.3 の moss = 権威/特権の意味づけを踏襲しつつ、暗い admin サイドナビ上で
   読めるよう moss を持ち上げた一段だけの静かなタグ（派手な色は足さない）。 */
.superadmin-mark {
  flex-shrink: 0;
  margin-left: auto;
  padding: 2px 7px;
  border-radius: 999px;
  font-family: var(--font-latin, inherit);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1.4;
  color: color-mix(in oklab, var(--moss-600) 30%, #e7ecdf);
  background: color-mix(in oklab, var(--moss-600) 26%, var(--ink-900));
  border: 1px solid color-mix(in oklab, var(--moss-600) 42%, transparent);
}
.avatar-fallback {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--nav-bg-strong, var(--ink-700));
  border: 1px solid color-mix(in oklab, var(--nav-accent, #e6c891) 22%, transparent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--nav-accent, var(--amber-300));
  font-family: var(--font-latin);
  font-size: 13px;
  font-weight: 500;
}
.logout-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--nav-text-dim, #8a8372);
  font-size: 12px;
  padding: 4px 6px;
  letter-spacing: 0.04em;
}
.logout-link:hover { color: var(--nav-accent, var(--amber-300)); }
.logout-link svg { width: 13px; height: 13px; stroke-width: 1.5; }

/* ============================================================
   Sprint 13: Discord 風サイドナビ（カテゴリ別ラウンジ一覧 + 折りたたみ）
   上部固定導線（.sidenav-top）/ スクロールするカテゴリ一覧（.sidenav-lounges）/
   フッター（.app-sidenav-footer）の 3 段構成。色は既存 nav トークン由来で原色ベタ塗りを避ける。
   ------------------------------------------------------------ */
/* 上部固定導線（ホーム/マイページ）は flex:1 を持たない＝固定高。
   既存 `.app-sidenav nav { flex:1 }` を上書きして、伸びるのは下のラウンジ一覧だけにする。 */
.app-sidenav nav.sidenav-top {
  flex: 0 0 auto;
}

/* カテゴリ別ラウンジ一覧＝スクロール領域（ラウンジが多くてもフッターを押し出さない・C-3）。 */
.app-sidenav nav.sidenav-lounges {
  flex: 1 1 auto;
  min-height: 0;            /* flex 子のスクロールを効かせるため必須 */
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 16px;
  padding-top: 16px;
  padding-right: 2px;
  border-top: 1px solid var(--nav-line, var(--ink-700));
  /* スクロールバー: Firefox 向けにも控えめに。 */
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--nav-text-dim, #8a8372) 28%, transparent) transparent;
}
/* 控えめなスクロールバー（暗い nav 上で目立たせない）。 */
.app-sidenav nav.sidenav-lounges::-webkit-scrollbar { width: 8px; }
.app-sidenav nav.sidenav-lounges::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--nav-text-dim, #8a8372) 26%, transparent);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.app-sidenav nav.sidenav-lounges:hover::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--nav-text-dim, #8a8372) 42%, transparent);
  background-clip: padding-box;
}

/* セクションラベル「ラウンジ」。カテゴリ見出しより一段上位の位置づけと分かるよう、
   うっすらと灯した accent 寄りの極小キャップに。下に微かな余白で群と切り離す。 */
.sidenav-lounges-eyebrow {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--nav-accent, #e6c891) 52%, var(--nav-text-dim, #8a8372));
  padding: 0 12px 10px;
}
/* ラベル右に伸びる極細罫＝「棚」の天板を思わせる静かな線。 */
.sidenav-lounges-eyebrow::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--nav-accent, #e6c891) 26%, transparent),
    transparent);
}

.sidenav-lounges-empty {
  color: color-mix(in oklab, var(--nav-text-dim, #8a8372) 80%, transparent);
  font-size: 12px;
  line-height: 1.7;
  padding: 4px 12px 10px;
  margin: 0;
}

/* ---- カテゴリブロック＝「棚」----
   見出しは棚札、配下のラウンジは棚に並ぶ背表紙。配下の左に細い導線（thread）を
   通して「このカテゴリに属する」関係を静かに示す（Discord の重いグレー塊は使わない）。 */
.sidenav-cat { display: flex; flex-direction: column; }

/* カテゴリ見出し（▾/▸ トグル・棚札）。
   非 uppercase + 字游明朝寄りではなく sans のまま、しかしラウンジ項目より
   一段沈めた色とトラッキングで「ラベル」として読ませる。 */
.sidenav-cat-head {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: color-mix(in oklab, var(--nav-text-dim, #9aa0a8) 80%, transparent);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  padding: 6px 12px 6px 10px;
  border-radius: 5px;
  transition: color 0.16s ease, background 0.16s ease;
}
.sidenav-cat-head:hover {
  color: var(--nav-text, #e6e8ec);
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 5%, transparent);
}
.sidenav-cat-head:hover .sidenav-cat-caret { opacity: 1; }
.sidenav-cat-head:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--nav-accent, #e6c891) 60%, transparent);
  outline-offset: 1px;
}
/* 現在地を含むグループの見出しは、ほのかに灯して「いまここにいる棚」と分かる。 */
.sidenav-cat[data-has-active="1"] > .sidenav-cat-head {
  color: color-mix(in oklab, var(--nav-accent, #e6c891) 30%, var(--nav-text, #e6e8ec));
}
.sidenav-cat-caret {
  width: 9px; height: 9px;
  flex-shrink: 0;
  opacity: 0.62;
  transition: transform 0.2s var(--lounge-ease, cubic-bezier(0.22,0.61,0.36,1)), opacity 0.16s ease;
}
/* 折りたたみ時はキャレットを ▸ 方向（右）に倒す（既定 ▾ = open）。 */
.sidenav-cat.is-collapsed .sidenav-cat-caret { transform: rotate(-90deg); }
.sidenav-cat-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* カテゴリ配下のラウンジ群（折りたたみ対象）。
   左に細い導線を引き、ラウンジが棚に「ぶら下がる」関係を可視化する。 */
.sidenav-cat-body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 2px 0 2px 16px;
  padding-left: 8px;
  border-left: 1px solid color-mix(in oklab, var(--nav-line, var(--ink-700)) 72%, transparent);
}
/* 現在地を含むグループの導線は、上から下へ微かに灯る（active 位置までを示唆）。 */
.sidenav-cat[data-has-active="1"] > .sidenav-cat-body {
  border-left-color: color-mix(in oklab, var(--nav-accent, #e6c891) 30%, var(--nav-line, var(--ink-700)));
}
.sidenav-cat.is-collapsed .sidenav-cat-body { display: none; }

/* ラウンジ項目（# + 名前）。active は温色の灯（amber）でフラットグレーを避ける。 */
.sidenav-lounge-link {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--nav-text-dim, #9aa0a8);
  padding: 6px 12px;
  border-radius: 5px;
  text-decoration: none;
  font-size: 13px;
  letter-spacing: 0.02em;
  transition: background 0.16s ease, color 0.16s ease;
  position: relative;
}
.sidenav-lounge-hash {
  color: color-mix(in oklab, var(--nav-text-dim, #8a8372) 58%, transparent);
  font-weight: 500;
  flex-shrink: 0;
  transition: color 0.16s ease;
}
.sidenav-lounge-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sidenav-lounge-link:hover {
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 7%, transparent);
  color: var(--nav-text, #e6e8ec);
}
.sidenav-lounge-link:hover .sidenav-lounge-hash {
  color: color-mix(in oklab, var(--nav-text-dim, #8a8372) 90%, transparent);
}
/* 現在地＝「灯がともる」。フラットなグレー塗りではなく暖色のごく薄いウォッシュ。 */
.sidenav-lounge-link.active {
  color: var(--nav-text, #fff);
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--nav-accent, #e6c891) 16%, transparent),
    color-mix(in oklab, var(--nav-accent, #e6c891) 6%, transparent));
}
.sidenav-lounge-link.active .sidenav-lounge-hash {
  color: var(--nav-accent, var(--amber-300));
  font-weight: 600;
}
/* active の左アクセントバーは導線（border-left）の上に重ねて灯す。 */
.sidenav-lounge-link.active::before {
  content: "";
  position: absolute;
  left: -9px; top: 50%;
  transform: translateY(-50%);
  width: 2px; height: 18px;
  border-radius: 2px;
  background: var(--nav-accent, var(--amber-600));
  box-shadow: 0 0 6px -1px color-mix(in oklab, var(--nav-accent, #e6c891) 60%, transparent);
}

/* admin console をフッターへ移したので、フッター内では上マージンを詰める。 */
.app-sidenav-footer .nav-admin { margin-top: 0; margin-bottom: 12px; }

/* ---- モバイル: ラウンジ一覧のカテゴリ見出し（D 群）----
   サイドナビの「棚札」と同じ言語: 小さな温色のキャップ + 右へ伸びる極細罫。
   均質グレーの下線ではなく、accent をうっすら灯した区切りにする。 */
.lounge-cat-section + .lounge-cat-section { margin-top: 32px; }
.lounge-cat-heading {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-accent) 40%, var(--color-text-dim));
  margin: 0 0 14px;
  padding: 0;
  border-bottom: 0;
}
.lounge-cat-heading::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--color-accent) 28%, var(--color-line)),
    color-mix(in oklab, var(--color-line) 50%, transparent) 60%,
    transparent);
}

/* ---- main ---- */
.app-main {
  padding: 40px 48px 60px;
  max-width: 760px;
  width: 100%;
  /* 右ウィジェット列を撤去したため、本文列（max 760px）を 1fr 内で中央寄せして
     右側に大きな余白が空かないようにする。 */
  margin-inline: auto;
}

/* ---- bottom nav (mobile) ----
 * BrandingService が出力するブランドトークン（--nav-bg / --nav-text /
 * --nav-text-dim / --nav-line / --nav-accent）を使い、上部 .app-mobilebar と
 * 同じ語彙でブランドカラーに追従させる。未ブランド設定時のフォールバックは
 * 従来の paper / line / accent。 */
.app-bottomnav {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: color-mix(in oklab, var(--nav-bg, #fbf7ee) 92%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-top: 1px solid var(--nav-line, var(--line));
  padding: 6px 0 calc(6px + env(safe-area-inset-bottom));
  z-index: 30;
}
.app-bottomnav a {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--nav-text-dim, var(--text-dim));
  text-decoration: none;
  font-size: 10px;
  letter-spacing: 0.06em;
  padding: 6px 0;
  position: relative;
}
.app-bottomnav a svg {
  width: 22px; height: 22px;
  stroke-width: 1.4;
}
.app-bottomnav a.active { color: var(--nav-text, var(--color-text)); }
.app-bottomnav a.active::after {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 18px; height: 2px;
  background: var(--nav-accent, var(--color-accent));
  border-radius: 0 0 2px 2px;
}
.app-bottomnav a.disabled { color: var(--nav-text-dim, var(--muted)); opacity: 0.55; pointer-events: none; }

/* ドロワー関連要素はデスクトップでは非表示（下のモバイル media query で出現）。 */
.app-mobilebar-trigger,
.app-drawer-scrim,
.app-drawer-close { display: none; }

@media (max-width: 1024px) {
  /* html,body の height:100% は body の box を viewport 高に固定するため、
     body 直下の sticky 要素（.app-mobilebar / top:0）が1画面分しか追従できず、
     スクロールすると外れて消える（→ その下に top:54px で貼り付く .forum-head が
     背景の上に浮いて見え、ヘッダーが固定されていないように見える）。
     mobile では height:auto にして body box をコンテンツ高まで伸ばし、sticky を
     全スクロール域で機能させる。フィル用の最低高は .app-shell の min-height:100vh が担保。 */
  html, body { height: auto; min-height: 100vh; }
  .app-shell { grid-template-columns: 1fr; }
  /* モバイル: サイドナビをオフキャンバスのドロワーにする（ハンバーガーで開閉）。
     PC 版のマークアップ（ブランド/ナビ/ラウンジ一覧/フッター）をそのまま再利用する。
     デスクトップでは sticky の縦レール、ここでは左から滑り込むパネルに切り替える。 */
  .app-sidenav {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 290px;
    max-width: 84vw;
    height: 100dvh;
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 0.30s cubic-bezier(.2, .7, .25, 1);
    box-shadow: 24px 0 60px -32px rgba(0, 0, 0, 0.55);
    overflow-y: auto;
    overscroll-behavior: contain;
    will-change: transform;
  }
  body.app-drawer-open .app-sidenav { transform: translateX(0); }
  /* grid アイテムの min-width:auto は中身の min-content で列を押し広げ、横スクロール／
     入力フォーム見切れの原因になる。min-width:0 で列幅を viewport に収める。 */
  .app-main { padding: 24px 20px 90px; max-width: 100%; min-width: 0; }
  .app-bottomnav { display: flex; }

  /* ハンバーガーボタン（mobilebar 左端）。 */
  .app-mobilebar-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px; height: 40px;
    flex: 0 0 auto;
    margin-left: -6px;
    border: none;
    background: transparent;
    color: var(--nav-text, #e6e8ec);
    border-radius: 10px;
    cursor: pointer;
  }
  .app-mobilebar-trigger:hover,
  .app-mobilebar-trigger:focus-visible {
    background: color-mix(in oklab, var(--nav-text, #fff) 12%, transparent);
    outline: none;
  }
  .app-ham {
    position: relative;
    display: block;
    width: 20px; height: 14px;
  }
  .app-ham::before,
  .app-ham::after,
  .app-ham > span {
    content: "";
    position: absolute;
    left: 0;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.24s ease, opacity 0.18s ease, width 0.24s ease;
  }
  .app-ham::before { top: 0;    width: 100%; }
  .app-ham > span  { top: 50%;  width: 72%; transform: translateY(-50%); display: block; }
  .app-ham::after  { bottom: 0; width: 90%; }
  /* 開いている間はハンバーガーを × に変形。 */
  body.app-drawer-open .app-ham::before { top: 50%; transform: translateY(-50%) rotate(45deg); width: 100%; }
  body.app-drawer-open .app-ham > span  { opacity: 0; }
  body.app-drawer-open .app-ham::after  { bottom: 50%; transform: translateY(50%) rotate(-45deg); width: 100%; }

  /* ドロワー背面スクリム。 */
  .app-drawer-scrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(15, 14, 20, 0.5);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.26s ease;
    z-index: 50;
  }
  body.app-drawer-open .app-drawer-scrim { opacity: 1; pointer-events: auto; }
  body.app-drawer-open { overflow: hidden; }

  /* ドロワー内の閉じる × ボタン（右上）。 */
  .app-drawer-close {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 10px; right: 10px;
    width: 34px; height: 34px;
    border: none;
    background: color-mix(in oklab, var(--nav-text, #fff) 8%, transparent);
    color: var(--nav-text, #e6e8ec);
    border-radius: 8px;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
  }
  .app-drawer-close:hover,
  .app-drawer-close:focus-visible {
    background: color-mix(in oklab, var(--nav-text, #fff) 16%, transparent);
    outline: none;
  }
  /* mobilebar に通知ベルがあるので、ドロワー内（サイドナビのブランド帯）のベルは隠して
     閉じる × ボタンと重ならないようにする。 */
  .app-sidenav .app-bell:not(.app-bell-mobile) { display: none; }
  /* iOS Safari は focus した入力欄の font-size が 16px 未満だと、ページ全体を
     自動ズームする（→ viewport より広がり横スクロール／送信ボタン見切れ）。
     アプリ内のどの入力欄でも起きないよう、テキスト入力系コントロール全体に
     16px の下限を保証する（checkbox/radio/range/color/file/button は除外）。
     maximum-scale は制限していないのでユーザーのピンチ拡大は従来どおり可能。 */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="button"]):not([type="submit"]),
  textarea,
  select {
    font-size: 16px;
  }
}

/* Admin mobile drawer — see end of file (must come after admin shell defs). */

/* ============================================================
   HOME (placeholder)
   ============================================================ */
.home-hero {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 36px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
.home-hero .eyebrow {
  font-family: var(--font-latin);
  text-transform: uppercase;
  letter-spacing: 0.4em;
  font-size: 11px;
  color: var(--muted);
}
.home-hero h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 26px;
  margin: 0;
  letter-spacing: 0.02em;
}
.home-hero .home-hero-sub {
  color: var(--text-dim);
  font-size: 13.5px;
  margin: 2px 0 0;
}

.section-title {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 28px 0 14px;
}
.section-title .label {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0.2em;
}
.section-title .rule {
  flex: 1;
  height: 1px;
  background: var(--line);
}
.section-title .latin {
  font-family: var(--font-latin);
  font-size: 11px;
  font-style: italic;
  color: var(--muted);
  letter-spacing: 0.18em;
}

/* Empty timeline placeholder */
.timeline-placeholder {
  text-align: center;
  padding: 56px 20px;
  background:
    linear-gradient(180deg, var(--paper-card) 0%, var(--paper) 100%);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}
.timeline-placeholder .sigil {
  width: 36px; height: 36px;
  color: var(--color-accent);
  margin: 0 auto 16px;
  opacity: 0.7;
}
.timeline-placeholder .lead-line {
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--text);
  margin: 0 0 4px;
  letter-spacing: 0.05em;
}
.timeline-placeholder .meta {
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.28em;
  color: var(--muted);
  text-transform: uppercase;
}

/* Ticket list on home — refined card row */
.ticket-card-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ticket-card-list li {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.ticket-card-list li:hover {
  border-color: var(--line-strong);
}
.ticket-card-list .ticket-glyph {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  /* Soft accent-tinted circle on the paper surface — derived from the
     active preset accent so Cherry Paper goes pink, Dark Velvet stays
     gold, Quiet Lounge keeps its warm amber. */
  background: color-mix(in oklab, var(--color-accent) 22%, var(--color-card) 78%);
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text) 25%);
  border-radius: 50%;
  flex-shrink: 0;
}
.ticket-card-list .ticket-glyph svg { width: 16px; height: 16px; stroke-width: 1.6; }
.ticket-card-list .ticket-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ticket-card-list .ticket-name {
  font-size: 14px;
  color: var(--color-text);
  font-weight: 500;
}
.ticket-card-list .ticket-code {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
}

.empty-line {
  color: var(--muted);
  font-size: 13.5px;
  font-style: italic;
  font-family: var(--font-display);
  padding: 8px 0;
}

/* ============================================================
   ADMIN SHELL
   ============================================================ */
.admin-body {
  background: var(--color-paper);
  color: var(--color-text);
}
.admin-shell {
  display: grid;
  grid-template-columns: 248px 1fr;
  min-height: 100vh;
}

/* Admin sidenav, like the app sidenav, is a permanent dark rail —
   it signals "管理画面 / 裏側" regardless of which brand preset is
   active on the public side. All --ink-* and --amber-300 inside the
   admin-sidenav are intentional fixed colors. */
.admin-sidenav {
  /* Sprint 1.x.y: nav_tone 連動 */
  background: var(--nav-bg-strong, var(--ink-850));
  color: var(--nav-text, #cdd0d6);
  padding: 26px 14px 18px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  border-right: 1px solid var(--nav-line, #0e0f14);
}

.admin-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 10px 22px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--nav-line, var(--ink-700));
}
.admin-brand .brand-mark {
  width: 24px; height: 24px;
  color: var(--nav-accent, var(--amber-300));
  flex-shrink: 0;
}
.admin-brand .brand-word {
  font-family: var(--font-latin);
  font-size: 15px;
  color: var(--nav-text, #e6e8ec);
  letter-spacing: 0.18em;
  padding-left: 0.18em;
}
.admin-brand .brand-tag {
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--nav-accent, var(--amber-300));
  border: 1px solid color-mix(in oklab, var(--nav-accent, #e6c891) 32%, transparent);
  padding: 2px 6px;
  margin-left: auto;
  border-radius: 2px;
}
/* ロゴ部分をクリックでサイトトップへ戻すリンクにした分の見た目調整。
 * カラー反転はせず、hover で brand-word のみほのかに amber に寄せる。 */
.admin-brand-link {
  text-decoration: none;
  color: inherit;
  transition: color 0.15s ease;
}
.admin-brand-link:hover .brand-word,
.admin-brand-link:focus-visible .brand-word {
  color: var(--nav-accent, var(--amber-300));
}
.admin-brand-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--nav-accent, #e6c891) 60%, transparent);
  border-radius: 4px;
}

.admin-menu {
  flex: 1;
  overflow-y: auto;
  padding-top: 14px;
}
.menu-section { margin-bottom: 18px; }
.menu-header {
  font-family: var(--font-latin);
  font-size: 10px;
  color: var(--nav-text-dim, #7a7466);
  text-transform: uppercase;
  letter-spacing: 0.32em;
  padding: 4px 10px 6px;
  margin-bottom: 4px;
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px;
  border-radius: 4px;
  color: var(--nav-text-dim, #9aa0a8);
  text-decoration: none;
  font-size: 13.5px;
  letter-spacing: 0.04em;
  margin-bottom: 1px;
  position: relative;
  transition: background 0.18s ease, color 0.18s ease;
}
.menu-item svg {
  width: 17px; height: 17px;
  stroke-width: 1.4;
  flex-shrink: 0;
}
.menu-item:hover:not(.disabled) {
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 8%, transparent);
  color: var(--nav-text, #e6e8ec);
}
.menu-item.active {
  color: var(--nav-text, #fff);
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 14%, transparent);
}
.menu-item.active::before {
  content: "";
  position: absolute;
  left: -14px; top: 50%;
  transform: translateY(-50%);
  width: 2px; height: 20px;
  background: var(--nav-text, var(--amber-600));
}
.menu-item.disabled {
  color: color-mix(in oklab, var(--nav-text-dim, #54503f) 60%, transparent);
  pointer-events: none;
}
.menu-item.disabled .lock {
  margin-left: auto;
  font-size: 9px;
  font-family: var(--font-latin);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--nav-text-dim, #4a4636) 70%, transparent);
}

.admin-sidenav-footer {
  border-top: 1px solid var(--ink-700);
  padding-top: 12px;
  margin-top: 8px;
  font-size: 12px;
}

/* ---- admin main ---- */
.admin-main {
  padding: 40px 48px 60px;
  max-width: 1000px;
}

.admin-main h1 {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 500;
  margin: 0 0 6px;
  letter-spacing: 0.02em;
  color: var(--color-text);
}
.admin-main .lead {
  color: var(--text-dim);
  font-size: 13.5px;
  margin: 0 0 32px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
  letter-spacing: 0.02em;
}

/* Breadcrumb-ish eyebrow above h1 */
.admin-eyebrow {
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}

/* ---- cards ---- */
.card-panel {
  background: var(--color-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 32px;
  box-shadow: var(--shadow-sm);
  margin-bottom: 20px;
  position: relative;
}
.card-panel h2 {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  margin: 0 0 6px;
  letter-spacing: 0.08em;
  color: var(--color-text);
}
.card-panel h2 + .text-muted,
.card-panel h2 + p {
  margin-top: 0;
  margin-bottom: 18px;
  color: var(--text-dim);
}
.card-panel .panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 4px;
}
.card-panel .panel-divider {
  height: 1px;
  background: var(--line);
  margin: 14px -32px 22px;
}

/* ============================================================
   FORM CONTROLS — Bootstrap-de-noise
   ============================================================ */
.form-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 6px;
  font-family: var(--font-latin);
}
.form-text {
  color: var(--muted);
  font-size: 12.5px;
  margin-top: 6px;
}
.form-control, .form-select {
  border-radius: 4px;
  border: 1px solid #d6dadf;
  /* Inputs are always pure white regardless of preset so saved text
     stays on a high-contrast surface (Dark Velvet 等の暗プリセット
     でも入力欄が確実に読める)。 */
  background: #ffffff;
  color: #25221c;
  font-size: 14px;
  padding: 10px 12px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  font-family: var(--font-sans);
}
.form-control::placeholder { color: #9ca3a8; }
/* hover / focus は preset の accent を使わず、入力欄全体の "input chrome" として
   ニュートラルなグレーの濃淡で示す。Quiet Lounge 時もゴールドが出ないようにする。 */
.form-control:hover, .form-select:hover { border-color: #9aa1a8; }
.form-control:focus, .form-select:focus {
  outline: none;
  border-color: #5a6168;
  background: #fff;
  box-shadow: 0 0 0 3px rgba(90, 97, 104, 0.18);
}

.input-group-text {
  /* warm tint surface — slightly darker than paper, follows the active
     preset so input-group prefixes blend with the page. */
  background: color-mix(in oklab, var(--color-paper) 88%, var(--color-text) 12%);
  border: 1px solid var(--line-strong);
  color: var(--color-text-dim);
  font-family: var(--font-mono);
  font-size: 13px;
}

.form-check-input {
  width: 1.05em; height: 1.05em;
  margin-top: 0.18em;
  border: 1.5px solid var(--line-strong);
  background-color: #fff;
  border-radius: 3px;
}
.form-check-input:checked {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
}
.form-check-input:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 26%, transparent);
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  border-radius: 4px;
  font-size: 13px;
  font-weight: 500;
  padding: 9px 18px;
  letter-spacing: 0.1em;
  font-family: var(--font-sans);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.05s ease, box-shadow 0.15s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.btn:active { transform: translateY(1px); }
/* Full-width buttons need their contents centred (Bootstrap's w-100 makes
   the container span 100% but doesn't change the flex justify). */
.btn.w-100 {
  justify-content: center;
}

/* Primary button uses the active text color as its fill so it always
   has maximum contrast against the active paper:
   - Quiet Lounge & Cherry Paper (light paper) → dark button
   - Dark Velvet (dark paper)                  → light button */
.btn-primary {
  background: var(--color-text);
  border: 1px solid var(--color-text);
  color: var(--color-paper);
}
.btn-primary:hover {
  /* nudge toward the accent so hover has a brand tint regardless of preset */
  background: color-mix(in oklab, var(--color-text) 78%, var(--color-accent) 22%);
  border-color: color-mix(in oklab, var(--color-text) 78%, var(--color-accent) 22%);
  color: var(--color-paper);
}
.btn-primary:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 55%, transparent);
}
.btn-primary:disabled, .btn-primary.disabled {
  background: color-mix(in oklab, var(--color-text) 45%, var(--color-paper) 55%);
  border-color: color-mix(in oklab, var(--color-text) 45%, var(--color-paper) 55%);
  opacity: 0.7;
}

.btn-secondary {
  background: var(--color-accent);
  border: 1px solid var(--color-accent);
  color: #fff;
}
.btn-secondary:hover {
  background: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%);
  border-color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%);
  color: #fff;
}

.btn-outline-secondary {
  background: transparent;
  color: var(--color-text);
  border: 1px solid var(--line-strong);
}
.btn-outline-secondary:hover {
  background: var(--color-text);
  color: var(--color-paper);
  border-color: var(--color-text);
}

.btn-danger {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: #fff;
}
.btn-danger:hover {
  background: color-mix(in oklab, var(--color-danger) 80%, var(--color-text) 20%);
  border-color: color-mix(in oklab, var(--color-danger) 80%, var(--color-text) 20%);
}

.btn .btn-icon {
  width: 14px; height: 14px;
  stroke-width: 1.7;
}

/* ============================================================
   ALERTS
   ============================================================ */
.alert {
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  padding: 12px 16px;
  border-width: 1px;
  border-style: solid;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.alert::before {
  content: "";
  width: 3px;
  align-self: stretch;
  border-radius: 2px;
  flex-shrink: 0;
}
/* Alerts derive surface/border from the semantic color of the active
   preset, mixed into the active paper so they always sit naturally
   on the page. */
.alert-danger {
  background: color-mix(in oklab, var(--color-danger) 14%, var(--color-paper) 86%);
  color: color-mix(in oklab, var(--color-danger) 70%, var(--color-text) 30%);
  border-color: color-mix(in oklab, var(--color-danger) 28%, var(--color-paper) 72%);
}
.alert-danger::before { background: var(--color-danger); }

.alert-success {
  background: color-mix(in oklab, var(--color-success) 16%, var(--color-paper) 84%);
  color: color-mix(in oklab, var(--color-success) 65%, var(--color-text) 35%);
  border-color: color-mix(in oklab, var(--color-success) 30%, var(--color-paper) 70%);
}
.alert-success::before { background: var(--color-success); }

.alert-warning {
  background: color-mix(in oklab, var(--color-accent) 22%, var(--color-paper) 78%);
  color: color-mix(in oklab, var(--color-accent) 50%, var(--color-text) 50%);
  border-color: color-mix(in oklab, var(--color-accent) 40%, var(--color-paper) 60%);
}
.alert-warning::before { background: var(--color-accent); }

.alert-info {
  background: color-mix(in oklab, var(--color-paper) 88%, var(--color-text) 12%);
  color: var(--color-text);
  border-color: var(--color-line);
}
.alert-info::before { background: var(--color-text-dim); }

/* デモ稼働モード時に login 上部に出すアナウンスバナー */
.auth-demo-banner {
  font-size: 13.5px;
  line-height: 1.6;
}
.auth-demo-banner strong {
  font-family: var(--font-latin);
  letter-spacing: 0.06em;
  color: var(--color-accent);
}
.auth-demo-banner code {
  background: color-mix(in oklab, var(--color-accent) 10%, var(--color-paper) 90%);
  padding: 0 4px;
  border-radius: 3px;
  font-size: 12px;
}
/* 新規登録 / パスワード再設定リンクをデモ稼働中に「見えるけど押せない」状態にする */
.auth-aside-disabled {
  color: var(--color-text-dim);
}
.auth-link-disabled {
  text-decoration: line-through;
  text-decoration-color: color-mix(in oklab, var(--color-text-dim) 60%, transparent);
  color: var(--color-text-dim);
  cursor: not-allowed;
  user-select: none;
}
.auth-link-note {
  font-size: 11px;
  color: var(--color-text-dim);
  margin-left: 4px;
}

/* ============================================================
   CONNECTION TEST CHIP
   ============================================================ */
.test-result {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 500;
  font-family: var(--font-sans);
  letter-spacing: 0.04em;
  border: 1px solid;
  animation: chip-in 0.22s ease-out;
}
@keyframes chip-in {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: translateY(0); }
}
.test-result .chip-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}
.test-result.success {
  background: color-mix(in oklab, var(--color-success) 16%, var(--color-paper) 84%);
  color: color-mix(in oklab, var(--color-success) 65%, var(--color-text) 35%);
  border-color: color-mix(in oklab, var(--color-success) 32%, var(--color-paper) 68%);
}
.test-result.success .chip-dot { background: var(--color-success); }

.test-result.failure {
  background: color-mix(in oklab, var(--color-danger) 14%, var(--color-paper) 86%);
  color: color-mix(in oklab, var(--color-danger) 70%, var(--color-text) 30%);
  border-color: color-mix(in oklab, var(--color-danger) 28%, var(--color-paper) 72%);
}
.test-result.failure .chip-dot { background: var(--color-danger); }

.test-result.pending {
  background: color-mix(in oklab, var(--color-paper) 88%, var(--color-text) 12%);
  color: var(--color-text-dim);
  border-color: var(--line-strong);
}
.test-result.pending .chip-dot {
  background: var(--color-text-dim);
  animation: chip-pulse 1s ease-in-out infinite;
}
@keyframes chip-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}

/* Test row layout */
.test-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

/* ============================================================
   TICKET LIST (admin tickets page) — refined cards
   ============================================================ */
.ticket-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ticket-list li {
  padding: 14px 16px 14px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--color-card);
  display: flex;
  align-items: center;
  gap: 14px;
  transition: border-color 0.15s ease, background 0.15s ease;
  position: relative;
}
.ticket-list li:hover {
  border-color: var(--line-strong);
  background: color-mix(in oklab, var(--color-card) 88%, var(--color-accent) 12%);
}
.ticket-list li:has(input:checked) {
  border-color: var(--color-accent);
  /* accent-tinted card across all presets (gold / pink / etc.) */
  background: color-mix(in oklab, var(--color-card) 70%, var(--color-accent) 30%);
  box-shadow: inset 3px 0 0 var(--color-accent);
}
/* selected card pairs the active accent tint with the active text
   color — light text on dark-velvet, dark text on cherry/quiet */
.ticket-list li:has(input:checked) .ticket-name { color: var(--color-text); }
.ticket-list li:has(input:checked) .ticket-code { color: var(--color-text-dim); }

.ticket-list .ticket-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  cursor: pointer;
  margin: 0;
}
.ticket-list .ticket-code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.ticket-list .ticket-name {
  font-size: 14px;
  color: var(--color-text);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.ticket-list .badge-inactive {
  background: color-mix(in oklab, var(--color-paper) 86%, var(--color-text) 14%);
  color: var(--color-text-dim);
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-family: var(--font-latin);
  border: 1px solid var(--line-strong);
}

/* ----------------------------------------------------------------
   Ticket key-line — shared sub-label hierarchy (Sprint 11)
   ----------------------------------------------------------------
   The ticket NAME stays the primary read; below it the key-line
   ranks the two technical registers so an operator never confuses
   the persistent key with the mutable label:

     [ ID n ]  ·  code
      ^ stable     ^ auxiliary / may change centrally

   The ID is set in a faint outlined chip with tabular figures so it
   reads as an addressable key; the code trails as quiet mono text
   after a hairline divider. Used verbatim on /setup step2 and both
   admin screens for a single, recognisable component. */
.ticket-keyline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.ticket-id-key {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  line-height: 1;
  padding: 2.5px 6px;
  border-radius: 4px;
  color: color-mix(in oklab, var(--color-text) 64%, var(--muted) 36%);
  background: color-mix(in oklab, var(--color-text) 7%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-text) 14%, transparent);
  cursor: help;
}
.ticket-code-sub {
  position: relative;
  padding-left: 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--muted);
  cursor: help;
}
.ticket-code-sub::before {
  content: "·";
  position: absolute;
  left: 0;
  color: color-mix(in oklab, var(--muted) 60%, transparent);
}
/* The key-line lives inside .ticket-code, which forced mono/dim on the
   whole run — relax that so the chip + code can carry their own ranks. */
.ticket-list .ticket-code.ticket-keyline {
  font-family: inherit;
  color: inherit;
  letter-spacing: normal;
}
/* On a selected card the stable key brightens with the accent so the
   chosen rows still read their ID clearly against the tinted fill. */
.ticket-list li:has(input:checked) .ticket-id-key {
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text) 45%);
  border-color: color-mix(in oklab, var(--color-accent) 40%, transparent);
  background: color-mix(in oklab, var(--color-accent) 12%, transparent);
}
.ticket-list li:has(input:checked) .ticket-code-sub {
  color: var(--color-text-dim);
}

/* Current required tickets list (admin) */
.required-tickets {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* "IN USE" pills are intentionally a fixed near-black with warm gold
   type — they read as a tactile rubber-stamp on every preset. Do not
   theme-link these. The pill now carries two registers: the human name
   (regular type) and the stable ID key (mono, tabular) divided by a
   hairline so the operator reads "name → backed by ID n" at a glance. */
.required-tickets li {
  display: inline-flex;
  align-items: stretch;
  font-size: 12px;
  background: var(--ink-900);
  color: var(--amber-300);
  border-radius: 5px;
  overflow: hidden;
  line-height: 1;
}
.required-tickets .required-ticket-name {
  padding: 6px 10px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.required-tickets .required-ticket-id {
  display: inline-flex;
  align-items: center;
  padding: 6px 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--amber-300) 78%, transparent);
  background: color-mix(in oklab, var(--amber-300) 12%, transparent);
  border-left: 1px solid color-mix(in oklab, var(--amber-300) 22%, transparent);
}
.required-tickets .required-ticket-id--solo {
  border-left: 0;
}

/* ============================================================
   UTILS
   ============================================================ */
.text-muted { color: var(--muted) !important; }
hr.soft { border: 0; border-top: 1px solid var(--line); margin: 20px 0; }

code {
  background: color-mix(in oklab, var(--color-paper) 86%, var(--color-text) 14%);
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.86em;
  color: var(--color-text);
  border: 1px solid var(--color-line);
}

/* ============================================================
   Sprint 1.7: branding (logo images / community name)
   ============================================================ */
.brand-image {
  max-height: 30px;
  max-width: 180px;
  object-fit: contain;
}
/* width/height 属性なし & viewBox のみの SVG は max-* だけだと
   ブラウザが 0×0 と判定して見えなくなるため、必ず height を明示する。 */
.app-brand .brand-image {
  display: block;
  width: auto;
  height: 32px;
  max-width: 180px;
  object-fit: contain;
}
.admin-brand .brand-image {
  display: block;
  width: auto;
  height: 26px;
  max-width: 160px;
  object-fit: contain;
}
.brand-image-large {
  /* テキストロゴモードの brand-mark (44px) と高さを揃える。
     横長ロゴ画像の場合は最大 240px 幅まで広がる。 */
  display: block;
  width: auto;
  height: 44px;
  max-width: 240px;
  object-fit: contain;
}
.brand-mark-img {
  object-fit: contain;
  background: transparent;
}
.auth-brand .brand-mark-img { width: 44px; height: 44px; }
.app-brand .brand-mark-img { width: 26px; height: 26px; }
.admin-brand .brand-mark-img { width: 24px; height: 24px; }
.brand-community-name {
  margin-top: 18px;
  font-family: var(--font-display);
  font-size: 10px;
  color: var(--auth-sub, rgba(230, 200, 145, 0.55));
  letter-spacing: 0.42em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 9px;
  justify-content: center;
  font-weight: 400;
}
.brand-community-name::before,
.brand-community-name::after {
  content: "";
  height: 1px;
  width: 18px;
  background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--auth-mark, var(--color-accent)) 32%, transparent), transparent);
}
.brand-community-name span {
  padding-left: 0.42em;
  /* tiny diamond accent before community name */
  position: relative;
}
.brand-community-name span::before {
  content: "◇";
  font-size: 7px;
  vertical-align: middle;
  margin-right: 8px;
  color: rgba(216, 177, 90, 0.45);
}

/* ============================================================
   ADMIN MOBILE DRAWER (<= 768px) — Sprint 1.7 polish
   The desk-side rail collapses into a left drawer; a hairline
   hamburger lives at the top-left of the main column.
   Placed at end of file so it overrides .admin-shell / .admin-sidenav
   defined earlier.
   ============================================================ */
.admin-mobile-bar { display: none; }
.admin-drawer-scrim { display: none; }
.admin-drawer-close { display: none; }

@media (max-width: 767.98px) {
  .admin-shell { grid-template-columns: 1fr; }

  /* mobile chrome bar above admin-main */
  .admin-mobile-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    background: var(--paper-card);
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    z-index: 40;
  }
  .admin-mobile-bar .amb-trigger {
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line-strong);
    border-radius: 3px;
    background: var(--paper);
    color: var(--color-text);
    cursor: pointer;
    transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
    position: relative;
    flex-shrink: 0;
  }
  /* keep the trigger visible above the open drawer so its X-state
     can be clicked to close (z above sidenav z:60) */
  body.admin-drawer-open .admin-mobile-bar {
    position: fixed;
    top: 0; left: 0; right: 0;
    background: transparent;
    border-bottom: 0;
    z-index: 70;
    pointer-events: none;
  }
  body.admin-drawer-open .admin-mobile-bar .amb-trigger {
    pointer-events: auto;
    background: color-mix(in oklab, var(--nav-bg, #0f0e14) 55%, transparent);
    border-color: color-mix(in oklab, var(--nav-accent, #e6c891) 32%, transparent);
    color: var(--nav-text, #e6e8ec);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
  }
  body.admin-drawer-open .admin-mobile-bar .amb-mark,
  body.admin-drawer-open .admin-mobile-bar .amb-title { opacity: 0; transition: opacity 0.18s ease; }
  .admin-mobile-bar .amb-trigger:hover,
  .admin-mobile-bar .amb-trigger:focus-visible {
    border-color: var(--color-text);
    background: color-mix(in oklab, var(--color-paper) 86%, var(--color-text) 14%);
    outline: none;
  }
  /* hand-drawn three-line glyph (no stock icon) */
  .admin-mobile-bar .amb-trigger .ham {
    position: relative;
    display: block;
    width: 18px;
    height: 12px;
  }
  .admin-mobile-bar .amb-trigger .ham::before,
  .admin-mobile-bar .amb-trigger .ham::after,
  .admin-mobile-bar .amb-trigger .ham > span {
    content: "";
    position: absolute;
    left: 0;
    height: 1px;
    background: currentColor;
    border-radius: 1px;
    transition: transform 0.28s ease, opacity 0.18s ease, width 0.22s ease;
  }
  .admin-mobile-bar .amb-trigger .ham::before { top: 0;    width: 100%; }
  .admin-mobile-bar .amb-trigger .ham > span  { top: 50%;  width: 70%;  transform: translateY(-50%); display: block; }
  .admin-mobile-bar .amb-trigger .ham::after  { bottom: 0; width: 90%; }
  body.admin-drawer-open .admin-mobile-bar .amb-trigger .ham::before { transform: translateY(5px) rotate(45deg); width: 100%; }
  body.admin-drawer-open .admin-mobile-bar .amb-trigger .ham > span  { opacity: 0; }
  body.admin-drawer-open .admin-mobile-bar .amb-trigger .ham::after  { transform: translateY(-6px) rotate(-45deg); width: 100%; }

  .admin-mobile-bar .amb-title {
    font-family: var(--font-latin);
    font-size: 11.5px;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--color-text);
    padding-left: 0.32em;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .admin-mobile-bar .amb-title em {
    font-style: normal;
    color: var(--muted);
    font-size: 9.5px;
    letter-spacing: 0.42em;
    padding-right: 6px;
    border-right: 1px solid var(--line-strong);
    margin-right: 8px;
  }
  .admin-mobile-bar .amb-mark {
    width: 22px; height: 22px;
    color: var(--color-accent);
    flex-shrink: 0;
  }

  /* sidebar slides in as drawer */
  .admin-sidenav {
    display: flex !important;
    position: fixed !important;
    top: 0;
    left: 0;
    bottom: 0;
    width: 280px;
    max-width: 84vw;
    height: 100vh;
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 0.32s cubic-bezier(.2, .7, .25, 1);
    box-shadow: 24px 0 60px -32px rgba(0, 0, 0, 0.6);
    padding-top: 18px;
  }
  body.admin-drawer-open .admin-sidenav {
    transform: translateX(0);
  }

  .admin-drawer-scrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(15, 14, 20, 0.5);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.28s ease;
    z-index: 50;
  }
  body.admin-drawer-open .admin-drawer-scrim {
    opacity: 1;
    pointer-events: auto;
  }
  body.admin-drawer-open { overflow: hidden; }

  /* close affordance: keep the hamburger glyph in the top bar as
     the toggle (it morphs to an X via the .admin-drawer-open state).
     The dedicated close button inside the drawer is hidden on mobile;
     the scrim and ESC are the alternate dismissals. */
  .admin-drawer-close { display: none; }

  .admin-main { padding: 22px 18px 60px; max-width: 100%; }
}

/* ============================================================
   REGISTER — Sprint 2
   "the registry book" — 来場者が静かに名前を書きこむ儀式。
   - 仮登録フォーム: ledger 風セクション
   - パスコード入力: 蝋封 (wax-seal) を解く儀式
   - 完了: 席が確保された静かな歓迎
   全要素 --color-* ブリッジトークン経由でプリセット連動。
   ============================================================ */

/* ---- common helpers shared by login + register ---- */
.auth-lede {
  font-family: var(--font-sans);
  font-size: 13.5px;
  color: var(--color-text-dim);
  line-height: 1.85;
  text-align: center;
  margin: -8px 0 30px;
}
.auth-lede strong {
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.02em;
}
.auth-lede .lede-mail {
  /* メールアドレスを長くても折り返さず、字面の存在感を保つ */
  font-family: var(--font-latin);
  font-size: 13px;
  letter-spacing: 0.01em;
  color: var(--color-text);
  display: inline-block;
  padding: 1px 6px;
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 60%, transparent);
  word-break: break-all;
}
.auth-aside {
  margin: 22px 0 0;
  text-align: center;
  font-size: 12.5px;
  color: var(--color-text-dim);
  letter-spacing: 0.02em;
}
.auth-aside a {
  color: color-mix(in oklab, var(--color-accent) 72%, var(--color-text) 28%);
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 50%, transparent);
  padding-bottom: 1px;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.auth-aside a:hover {
  color: var(--color-text);
  border-bottom-color: var(--color-text);
}
.form-text-muted {
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.02em;
}

/* Register layout wants a touch more breathing room than /login */
.auth-shell:has(.auth-card form input[name="name_sei"]),
.auth-shell:has(.auth-card form .passcode-grid),
.auth-shell:has(.auth-card .register-complete) {
  max-width: 480px;
}

/* Password-reset completion wants the same calm, slightly-wider stage
   as register-complete so the envelope seal can breathe. */
.auth-shell:has(.auth-card .password-reset-sent) {
  max-width: 452px;
}

/* ---- ledger sections (register form) ---- */
.ledger-section {
  position: relative;
  padding: 4px 0 6px;
  margin: 0 0 26px;
}
.ledger-section + .ledger-section {
  margin-top: 30px;
  padding-top: 26px;
  border-top: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
}
.ledger-section-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 16px;
  color: var(--color-text);
}
.ledger-section-head .sigil {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%);
  padding: 2px 7px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 35%, transparent);
  border-radius: 2px;
  flex-shrink: 0;
  line-height: 1.1;
}
.ledger-section-head .title {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.18em;
  color: var(--color-text);
}
.ledger-section-head .hint {
  margin-left: auto;
  font-family: var(--font-latin);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.28em;
  color: var(--muted);
}

/* Register form: tighter mb on stacked rows, optional-label color */
.register-form .form-label .optional {
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 400;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
  margin-left: 8px;
  padding: 1px 6px;
  border: 1px solid color-mix(in oklab, var(--muted) 40%, transparent);
  border-radius: 999px;
  vertical-align: 1px;
}
.register-form .field { margin-bottom: 14px; }
.register-form .field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 14px;
}
.register-form .field:last-child { margin-bottom: 0; }

/* Password strength meter — three quiet ticks */
.pass-strength {
  margin-top: 8px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr auto;
  align-items: center;
  gap: 6px;
}
.pass-strength .tick {
  height: 3px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--color-line) 100%, transparent);
  transition: background 0.25s ease;
}
.pass-strength[data-level="1"] .tick:nth-child(1),
.pass-strength[data-level="2"] .tick:nth-child(-n+2),
.pass-strength[data-level="3"] .tick:nth-child(-n+3) {
  background: var(--color-accent);
}
.pass-strength[data-level="3"] .tick {
  background: color-mix(in oklab, var(--color-success) 80%, var(--color-accent) 20%);
}
.pass-strength .label {
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
  padding-left: 4px;
}
.pass-strength[data-level="1"] .label,
.pass-strength[data-level="2"] .label { color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%); }
.pass-strength[data-level="3"] .label { color: color-mix(in oklab, var(--color-success) 65%, var(--color-text) 35%); }

.pass-hint {
  font-size: 12px;
  color: var(--muted);
  margin-top: 8px;
  line-height: 1.6;
  letter-spacing: 0.02em;
}

/* Submit row sits below all ledger sections */
.register-submit {
  margin-top: 28px;
}

/* ============================================================
   PASSCODE / VERIFY
   ============================================================ */

/* "envelope" — small wax-seal motif at the top of the verify card */
.verify-envelope {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  margin: -4px 0 16px;
  color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%);
}
.verify-envelope svg {
  width: 46px;
  height: 46px;
  stroke-width: 1;
  opacity: 0.92;
  animation: envelopeIn 0.55s ease-out both;
}
.verify-envelope .verify-eyebrow {
  font-family: var(--font-latin);
  font-size: 10px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--muted);
  padding-left: 0.42em;
}
@keyframes envelopeIn {
  from { opacity: 0; transform: translateY(-6px) scale(0.92); }
  to   { opacity: 0.92; transform: translateY(0) scale(1); }
}

/* Passcode label centred above grid like a stamp */
.passcode-label {
  display: block;
  text-align: center;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0 0 14px;
  padding-left: 0.42em;
}

.passcode-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 9px;
  margin: 0 0 4px;
}
.passcode-cell {
  width: 100%;
  height: 60px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 500;
  color: var(--color-text);
  background: var(--paper-elev);
  border: 1px solid var(--color-line);
  border-radius: 3px;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease,
              background-color 0.18s ease, transform 0.18s ease;
  caret-color: var(--color-accent);
  letter-spacing: 0;
  /* faint inset shadow to feel "stamped" */
  box-shadow: inset 0 -1px 0 color-mix(in oklab, var(--color-line) 70%, transparent);
  animation: passcodeCellIn 0.45s ease-out both;
  animation-delay: calc(var(--cell-index, 0) * 60ms);
}
.passcode-cell::-webkit-outer-spin-button,
.passcode-cell::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.passcode-cell:hover {
  border-color: color-mix(in oklab, var(--color-accent) 60%, var(--color-line) 40%);
}
/* Focus ring derives from the active preset accent — works on Soft Pastel
   mint, Cherry Paper pink, Dark Velvet gold, etc. without overpowering. */
.passcode-cell:focus {
  border-color: var(--color-accent);
  background: var(--paper-elev);
  box-shadow:
    inset 0 -2px 0 var(--color-accent),
    0 0 0 3px color-mix(in oklab, var(--color-accent) 22%, transparent);
  transform: translateY(-1px);
}
.passcode-cell.is-filled,
.passcode-cell:not(:placeholder-shown) {
  background: color-mix(in oklab, var(--color-card) 70%, var(--color-accent) 8%);
  border-color: color-mix(in oklab, var(--color-accent) 35%, var(--color-line) 65%);
}
@keyframes passcodeCellIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 460px) {
  .passcode-grid { gap: 6px; }
  .passcode-cell { height: 52px; font-size: 22px; }
}

.passcode-actions {
  display: flex;
  flex-direction: column;
  margin-top: 22px;
}

/* Resend block — quiet but findable. Replaces the timid dashed border. */
.passcode-resend {
  margin-top: 22px;
  padding-top: 20px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  border-top: 0;
}
.passcode-resend::before {
  /* hairline rule + center diamond — looks like a deckle-cut paper edge */
  content: "";
  position: absolute;
  top: 0;
  left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--color-line) 100%, transparent) 18%,
    color-mix(in oklab, var(--color-line) 100%, transparent) 82%,
    transparent 100%);
}
.passcode-resend::after {
  content: "◇";
  position: absolute;
  top: -8px; left: 50%;
  transform: translateX(-50%);
  font-size: 9px;
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  background: var(--color-card);
  padding: 0 8px;
  line-height: 16px;
}
.passcode-resend .form-text-muted { margin: 0; }
.passcode-resend form { margin: 0; }

.btn-ghost {
  background: transparent;
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text) 25%);
  border: 1px solid color-mix(in oklab, var(--color-accent) 45%, var(--color-line) 55%);
  border-radius: 3px;
  padding: 8px 16px;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  font-family: var(--font-sans);
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.btn-ghost:hover {
  background: color-mix(in oklab, var(--color-accent) 10%, transparent);
  border-color: var(--color-accent);
  color: var(--color-text);
}
.btn-ghost:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 28%, transparent);
  border-color: var(--color-accent);
}
.btn-ghost.btn-sm { padding: 6px 14px; font-size: 12px; }
.btn-ghost .btn-icon {
  width: 12px; height: 12px;
  stroke-width: 1.7;
}

/* ============================================================
   REGISTER COMPLETE — wax-seal welcome
   ============================================================ */
.register-complete {
  text-align: center;
  padding: 12px 0 0;
}

/* The whole stage is centred; the seal is the hero */
.register-complete-seal {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 112px;
  height: 112px;
  margin: 8px auto 28px;
}
.register-complete-seal svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--color-accent);
}
.register-complete-seal .ring {
  stroke-dasharray: 188;
  stroke-dashoffset: 188;
  animation: sealRingDraw 0.7s cubic-bezier(.45,.05,.25,1) 0.05s forwards;
}
.register-complete-seal .ring-inner {
  opacity: 0;
  animation: sealInnerFade 0.5s ease-out 0.55s forwards;
}
.register-complete-seal .check {
  stroke-dasharray: 38;
  stroke-dashoffset: 38;
  animation: sealCheckDraw 0.55s cubic-bezier(.55,.1,.3,1) 0.75s forwards;
}
.register-complete-seal .spark {
  opacity: 0;
  transform-origin: center;
  animation: sealSpark 1.2s ease-out 1.1s forwards;
}
@keyframes sealRingDraw {
  to { stroke-dashoffset: 0; }
}
@keyframes sealInnerFade {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 0.55; transform: scale(1); }
}
@keyframes sealCheckDraw {
  to { stroke-dashoffset: 0; }
}
@keyframes sealSpark {
  0%   { opacity: 0; transform: scale(0.7); }
  40%  { opacity: 0.6; transform: scale(1.05); }
  100% { opacity: 0; transform: scale(1.2); }
}

.register-complete .complete-eyebrow {
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  color: var(--muted);
  padding-left: 0.5em;
  margin: 0 0 6px;
  animation: completeFadeUp 0.6s ease-out 0.95s both;
}
.register-complete h1 {
  text-align: center;
  letter-spacing: 0.22em;
  margin: 0 0 14px;
  animation: completeFadeUp 0.6s ease-out 1.05s both;
}
.register-complete .complete-body {
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--color-text);
  line-height: 1.85;
  margin: 0 auto 8px;
  max-width: 320px;
  text-wrap: balance;
  word-break: auto-phrase;
  animation: completeFadeUp 0.6s ease-out 1.15s both;
}
.register-complete .complete-sub {
  font-size: 12.5px;
  color: var(--color-text-dim);
  letter-spacing: 0.02em;
  line-height: 1.75;
  margin: 0 auto 0;
  max-width: 320px;
  text-wrap: pretty;
  word-break: auto-phrase;
  animation: completeFadeUp 0.6s ease-out 1.25s both;
}
.register-complete .complete-divider {
  display: block;
  width: 28px;
  height: 1px;
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  margin: 20px auto 22px;
  animation: completeFadeUp 0.6s ease-out 1.18s both;
}
.register-complete-actions {
  margin-top: 28px;
  animation: completeFadeUp 0.6s ease-out 1.35s both;
}
@keyframes completeFadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* When the complete view is rendered, suppress the redundant flash
   message ("登録が完了しました。") — the seal IS the message. */
.auth-card:has(.register-complete) .alert-success {
  display: none;
}

/* "新規登録はこちら" on /login — make the link itself feel like a
   discreet wax-seal pill rather than a Bootstrap blue underline. */
.auth-aside[data-test="register-link"] a {
  border-bottom: 0;
  padding: 4px 12px 5px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 38%, var(--color-line) 62%);
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.08em;
  margin-left: 6px;
  display: inline-block;
  background: color-mix(in oklab, var(--color-accent) 6%, transparent);
}
.auth-aside[data-test="register-link"] a:hover {
  background: color-mix(in oklab, var(--color-accent) 14%, transparent);
  border-color: var(--color-accent);
  color: var(--color-text);
}

/* ============================================================
   Sprint 7 — Password reset (誘導): 焦りを鎮める静かな入口
   login / register と地続き。蝋封の高揚は持ち込まず、手紙を
   そっと託す落ち着きで。
   ============================================================ */

/* ---- Form (/password/reset) ---- */
.auth-pw-reset {
  /* a whisper of entrance — the card already settled, the content
     arrives a beat after, so a forgetful arrival feels welcomed. */
  animation: pwResetEnter 0.5s ease-out both;
}
@keyframes pwResetEnter {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}
.auth-pw-reset .auth-lede {
  /* reassuring copy — keep it airy and balanced, not cramped */
  line-height: 1.95;
  margin: -6px auto 28px;
  /* 20-B: 17em は和文の平易文だと「再設定／用」のような語中改行を招くため、
     測幅を僅かに広げ、auto-phrase で文節境界改行に寄せる。 */
  max-width: 19em;
  text-wrap: balance;
  word-break: auto-phrase;
}
.auth-pw-reset .auth-lede .pw-lede-lead {
  /* the reassurance leads, on its own line, a touch warmer */
  display: block;
  color: var(--color-text);
  font-weight: 500;
  letter-spacing: 0.01em;
  margin-bottom: 4px;
}
.auth-pw-reset-form .form-label {
  /* match the quiet field labels elsewhere in auth */
  letter-spacing: 0.04em;
}
.auth-pw-note {
  margin: 16px 0 0;
  padding: 11px 14px 11px 32px;
  position: relative;
  font-size: 12px;
  line-height: 1.7;
  color: var(--color-text-dim);
  letter-spacing: 0.01em;
  background: color-mix(in oklab, var(--color-accent) 5%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%);
  border-radius: 2px;
}
.auth-pw-note::before {
  /* a small key-glyph marker — "the lock is on the other side" */
  content: "";
  position: absolute;
  left: 13px;
  top: 13px;
  width: 9px;
  height: 9px;
  border: 1.4px solid color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%);
  border-radius: 999px;
  box-shadow: 0 7px 0 -3.5px color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%);
}

/* ---- Completion (/password/reset/sent) ---- */
.password-reset-sent {
  text-align: center;
  padding: 12px 0 0;
}
.password-reset-sent .pw-sent-seal {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 104px;
  height: 104px;
  margin: 6px auto 24px;
}
.password-reset-sent .pw-sent-seal svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--color-accent);
}
/* soft outer aura settles in first */
.password-reset-sent .pw-sent-seal .ring {
  opacity: 0;
  stroke-dasharray: 214;
  stroke-dashoffset: 214;
  animation: pwSealRing 0.8s cubic-bezier(.45,.05,.25,1) 0.1s forwards;
}
/* envelope body fades up */
.password-reset-sent .pw-sent-seal .env-body {
  opacity: 0;
  animation: pwSealFade 0.5s ease-out 0.5s forwards;
}
/* flap draws closed last — the letter is sealed and sent */
.password-reset-sent .pw-sent-seal .env-flap {
  stroke-dasharray: 50;
  stroke-dashoffset: 50;
  animation: pwSealFlap 0.55s cubic-bezier(.55,.1,.3,1) 0.7s forwards;
}
/* a faint line of flight underneath, drawn after */
.password-reset-sent .pw-sent-seal .env-trace {
  stroke-dasharray: 70;
  stroke-dashoffset: 70;
  animation: pwSealTrace 0.9s ease-out 0.95s forwards;
}
@keyframes pwSealRing {
  from { opacity: 0; stroke-dashoffset: 214; }
  to   { opacity: 0.55; stroke-dashoffset: 0; }
}
@keyframes pwSealFade {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 0.95; transform: translateY(0); }
}
@keyframes pwSealFlap {
  to { stroke-dashoffset: 0; }
}
@keyframes pwSealTrace {
  0%   { stroke-dashoffset: 70; opacity: 0; }
  60%  { opacity: 0.5; }
  100% { stroke-dashoffset: 0; opacity: 0.45; }
}

/* Reuse the register-complete typographic rhythm, but namespaced to
   the reset view so the eyebrow/body/sub actually centre + stagger. */
.password-reset-sent .complete-eyebrow {
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  color: var(--muted);
  padding-left: 0.5em;
  margin: 0 0 6px;
  animation: completeFadeUp 0.6s ease-out 0.9s both;
}
.password-reset-sent h1 {
  text-align: center;
  letter-spacing: 0.22em;
  margin: 0 0 14px;
  animation: completeFadeUp 0.6s ease-out 1s both;
}
.password-reset-sent .complete-body {
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--color-text);
  line-height: 1.9;
  margin: 0 auto 4px;
  max-width: 330px;
  text-wrap: balance;
  word-break: auto-phrase;
  animation: completeFadeUp 0.6s ease-out 1.1s both;
}
.password-reset-sent .complete-divider {
  display: block;
  width: 28px;
  height: 1px;
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  margin: 18px auto 18px;
  animation: completeFadeUp 0.6s ease-out 1.15s both;
}
.password-reset-sent .complete-sub {
  font-size: 12.5px;
  color: var(--color-text-dim);
  letter-spacing: 0.02em;
  line-height: 1.8;
  margin: 0 auto;
  max-width: 330px;
  text-wrap: pretty;
  word-break: auto-phrase;
  animation: completeFadeUp 0.6s ease-out 1.2s both;
}
.password-reset-sent .register-complete-actions {
  margin-top: 30px;
  animation: completeFadeUp 0.6s ease-out 1.3s both;
}

/* Honour reduced-motion: keep everything visible, drop the drawing-in. */
@media (prefers-reduced-motion: reduce) {
  .auth-pw-reset,
  .password-reset-sent .pw-sent-seal .ring,
  .password-reset-sent .pw-sent-seal .env-body,
  .password-reset-sent .pw-sent-seal .env-flap,
  .password-reset-sent .pw-sent-seal .env-trace,
  .password-reset-sent .complete-eyebrow,
  .password-reset-sent h1,
  .password-reset-sent .complete-body,
  .password-reset-sent .complete-divider,
  .password-reset-sent .complete-sub,
  .password-reset-sent .register-complete-actions {
    animation: none;
    opacity: 1;
    stroke-dashoffset: 0;
    transform: none;
  }
}


/* ============================================================
   Sprint 1.5 — Mypage / Passkey UI  ("the key ring")
   ------------------------------------------------------------
   World: 「鍵 = 預けるもの」「席 = 自分の居場所」
   - hairline-thin frames, paper warmth, brass accents
   - display font for titles, latin small-caps as sub
   - SOON badge mirrors the admin sidenav vocabulary
   - all colors via --color-* bridge tokens (preset-aware)
   ============================================================ */

.mypage-shell {
  max-width: 900px;
  margin: 0 auto;
  padding: 30px 24px 96px;
}

/* ---- header ---- */
.mypage-header {
  margin: 0 0 28px;
  padding-bottom: 18px;
  position: relative;
}
.mypage-header::after {
  /* hairline rule with a center diamond — echoes the passcode-resend deckle edge */
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--color-line) 90%, transparent) 12%,
    color-mix(in oklab, var(--color-line) 90%, transparent) 88%,
    transparent 100%);
}
.mypage-eyebrow {
  display: inline-block;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-left: 0.42em;
  margin-bottom: 8px;
}
.mypage-title {
  font-family: var(--font-display);
  font-size: 30px;
  /* 20-A: ゴシックは明朝より細く見えるため weight を一段上げ、字間を締めて
     ページ見出しとしての存在感を回復する。 */
  font-weight: 600;
  letter-spacing: 0.01em;
  margin: 0 0 6px;
  color: var(--color-text);
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.mypage-title-sub {
  font-family: var(--font-latin);
  font-size: 11px;
  font-weight: 500;
  font-style: italic;
  letter-spacing: 0.32em;
  text-transform: lowercase;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-muted) 30%);
}
.mypage-lead {
  margin: 0;
  color: var(--color-text-dim);
  font-size: 13.5px;
  max-width: 540px;
  line-height: 1.7;
}

.mypage-layout {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}
@media (max-width: 760px) {
  .mypage-layout { grid-template-columns: 1fr; gap: 18px; }
}

/* ---- subnav (left rail) ----
   Mirrors the admin sidenav active-bar + SOON badge vocabulary but on the
   paper side: hairline rules, brass accent, mincho labels with latin subs. */
.mypage-subnav {
  display: flex;
  flex-direction: column;
  gap: 1px;
  position: sticky;
  top: 24px;
  padding: 6px 0 10px;
  /* paper-side rail uses a left hairline only — quieter than a full card */
  border: 0;
  border-left: 1px solid var(--color-line);
  background: transparent;
  border-radius: 0;
}
.mypage-subnav-header {
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding: 6px 0 14px 18px;
}
@media (max-width: 760px) {
  .mypage-subnav {
    flex-direction: row; flex-wrap: wrap; position: static;
    border-left: 0;
    border-top: 1px solid var(--color-line);
    border-bottom: 1px solid var(--color-line);
    padding: 8px 0;
    gap: 4px;
  }
  .mypage-subnav-header { display: none; }
}
.mypage-subnav-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 16px 10px 18px;
  font-size: 14px;
  color: var(--color-text-dim);
  text-decoration: none;
  position: relative;
  transition: color 0.18s ease, padding-left 0.2s ease;
}
.mypage-subnav-link:hover:not(.disabled) {
  color: var(--color-text);
  padding-left: 22px;
}
.mypage-subnav-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  flex: 1;
}
.mypage-subnav-label {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0.04em;
  line-height: 1.3;
  white-space: nowrap;
}
.mypage-subnav-sub {
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.28em;
  text-transform: lowercase;
  color: var(--color-muted);
  padding-left: 0.28em;
}
.mypage-subnav-link.active {
  color: var(--color-text);
}
.mypage-subnav-link.active::before {
  /* brass active-rail — same pattern as admin sidenav .menu-item.active */
  content: "";
  position: absolute;
  left: -1px; top: 12px; bottom: 12px;
  width: 2px;
  background: var(--color-accent);
  border-radius: 0 1px 1px 0;
}
.mypage-subnav-link.active .mypage-subnav-label {
  font-weight: 600;
}
.mypage-subnav-link.active .mypage-subnav-sub {
  color: color-mix(in oklab, var(--color-accent) 65%, var(--color-muted) 35%);
}
.mypage-subnav-link.disabled {
  color: color-mix(in oklab, var(--color-text-dim) 45%, var(--color-paper) 55%);
  pointer-events: none;
}
.mypage-subnav-link.disabled .mypage-subnav-label {
  font-weight: 400;
}
.mypage-subnav-soon {
  font-family: var(--font-latin);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-text-dim) 50%, var(--color-muted) 50%);
  border: 1px solid color-mix(in oklab, var(--color-line) 70%, var(--color-muted) 30%);
  padding: 1px 6px 2px;
  border-radius: 2px;
  flex-shrink: 0;
  align-self: center;
}
@media (max-width: 760px) {
  .mypage-subnav-link.active::before {
    left: 50%; top: auto; bottom: -1px;
    transform: translateX(-50%);
    width: 14px; height: 2px;
    border-radius: 1px 1px 0 0;
  }
}

/* ---- card ---- */
.mypage-main { min-width: 0; }
.mypage-card {
  background: var(--color-card);
  border: 1px solid var(--color-line);
  border-radius: 4px;
  padding: 26px 26px 22px;
  box-shadow: var(--shadow-sm);
  position: relative;
}
.mypage-card::before {
  /* inset hairline frame — echoes auth-card */
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 14%, transparent);
  pointer-events: none;
  border-radius: 1px;
}
.mypage-card > * { position: relative; }
.mypage-card + .mypage-card { margin-top: 18px; }
.mypage-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
}
.mypage-card-title-wrap {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.mypage-card-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  /* 20-A: ゴシック化に伴い字間を締める。明朝前提の 0.14em は和文ゴシックでは
     字面が間延びして見えるため、見出しとしての密度を取り戻す。 */
  letter-spacing: 0.02em;
  margin: 0;
  color: var(--color-text);
}
.mypage-card-subtitle {
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.36em;
  text-transform: lowercase;
  color: var(--color-muted);
  padding-left: 0.36em;
}
.mypage-card-hint {
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px dashed color-mix(in oklab, var(--color-line) 80%, transparent);
  color: var(--color-muted);
  font-size: 12.5px;
  line-height: 1.7;
}
.mypage-card-hint .disabled-link {
  color: var(--color-muted);
  text-decoration: line-through;
  text-decoration-color: color-mix(in oklab, var(--color-muted) 50%, transparent);
  cursor: not-allowed;
}
.mypage-card-hint .mypage-account-link {
  color: var(--color-accent, var(--nav-text, currentColor));
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, currentColor 40%, transparent);
  text-underline-offset: 2px;
  font-weight: 600;
  white-space: nowrap;
}
.mypage-card-hint .mypage-account-link:hover {
  text-decoration-color: currentColor;
}
.mypage-card-hint .mypage-extlink-ico {
  vertical-align: -2px;
  margin-left: 3px;
  opacity: 0.85;
}
/* デモ稼働中: 中央アカウント設定は見た目そのままで非機能化（<span>）＋無効の注記。 */
.mypage-card-hint .mypage-account-link[aria-disabled="true"] {
  cursor: default;
}
.mypage-card-hint .mypage-account-link[aria-disabled="true"]:hover {
  text-decoration-color: color-mix(in oklab, currentColor 40%, transparent);
}
.mypage-card-hint .mypage-account-note {
  margin-left: 4px;
  color: color-mix(in oklab, var(--color-muted) 85%, transparent);
  font-size: 11.5px;
  white-space: nowrap;
}

/* ---- profile dl/dd ----
   Old layout broke (160px column squeezed the value column on mobile and
   chips wrapped vertically). Switch to a "stamped ledger" two-column with
   the label as a small-caps display tag underlined by a tiny hairline. */
.mypage-prop {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  gap: 16px 20px;
  margin: 0;
  align-items: start;
}
@media (max-width: 640px) {
  .mypage-prop { grid-template-columns: 1fr; gap: 4px 0; }
  .mypage-prop dd { margin-bottom: 8px; }
}
.mypage-prop dt {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 12.5px;
  letter-spacing: 0.16em;
  color: var(--color-text-dim);
  padding-top: 4px;
  position: relative;
  padding-left: 12px;
}
.mypage-prop dt::before {
  /* tiny brass tick — a "ledger entry" mark */
  content: "";
  position: absolute;
  left: 0; top: 11px;
  width: 6px; height: 1px;
  background: color-mix(in oklab, var(--color-accent) 70%, var(--color-line) 30%);
}
.mypage-prop dd {
  margin: 0;
  color: var(--color-text);
  font-size: 14.5px;
  line-height: 1.6;
  min-width: 0;
}
.mypage-prop-name { font-family: var(--font-display); font-size: 17px; letter-spacing: 0.02em; }
.mypage-prop-id {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--color-text-dim);
  background: color-mix(in oklab, var(--color-paper) 85%, var(--color-text) 5%);
  padding: 5px 9px;
  border: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
  border-radius: 2px;
  display: inline-block;
  max-width: 100%;
  word-break: break-all;
  /* hairline ledger underline */
  box-shadow: inset 0 -1px 0 color-mix(in oklab, var(--color-line) 70%, transparent);
}
.mypage-prop-time { font-family: var(--font-latin); font-size: 13px; letter-spacing: 0.04em; color: var(--color-text-dim); }
.mypage-prop-empty { color: var(--color-muted); font-size: 13px; font-style: italic; }
.mypage-prop dd.mono, .mypage-prop .mono {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  word-break: break-all;
}

/* ---- ticket chips ----
   Tickets become small "印章" pills (wax-seal vocab):
   a tiny circle-in-circle stamp + name + monospaced code. */
.mypage-ticket-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 8px;
}
.mypage-ticket-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 13px 7px 10px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%);
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-paper) 95%);
  border-radius: 999px;
  font-size: 13px;
  line-height: 1.3;
  width: fit-content;
  max-width: 100%;
  min-width: 0;
}
.mypage-ticket-mark {
  width: 15px; height: 15px;
  display: inline-flex; align-items: center; justify-content: center;
  color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%);
  flex-shrink: 0;
}
.mypage-ticket-mark svg { width: 100%; height: 100%; }
.mypage-ticket-name {
  font-weight: 500;
  color: var(--color-text);
  white-space: nowrap;
}
.mypage-ticket-code {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--color-accent) 65%, var(--color-text) 35%);
  background: transparent;
  border: 0;
  padding: 0 0 0 8px;
  margin-left: 2px;
  border-left: 1px solid color-mix(in oklab, var(--color-accent) 28%, var(--color-line) 72%);
  text-transform: lowercase;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================
   Passkey list — "鍵束" (key ring)
   ============================================================ */

.passkey-card-shell {
  /* the card that holds the key ring */
}

/* Add-key button — quiet ceremony */
.btn-add-key {
  display: inline-flex !important;
  align-items: center;
  gap: 10px;
  padding: 9px 16px 9px 13px !important;
  font-size: 13px;
  letter-spacing: 0.06em;
}
.btn-key-glyph {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  color: currentColor;
  /* tiny rotation so the key tilts on hover */
  transition: transform 0.35s cubic-bezier(.5,.05,.25,1);
}
.btn-key-glyph svg { width: 20px; height: 20px; }
.btn-add-key:hover .btn-key-glyph { transform: rotate(-12deg); }
.btn-add-key:active .btn-key-glyph { transform: rotate(8deg); }

/* Passkey list */
.passkey-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  border-top: 1px solid color-mix(in oklab, var(--color-line) 75%, transparent);
}
.passkey-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 4px;
  border: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--color-line) 75%, transparent);
  background: transparent;
  border-radius: 0;
  position: relative;
  transition: background 0.2s ease;
}
.passkey-card::before {
  /* hairline left-rail accent that fades in on hover — "this key is being looked at" */
  content: "";
  position: absolute;
  left: -10px; top: 18px; bottom: 18px;
  width: 2px;
  background: var(--color-accent);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.passkey-card:hover {
  background: color-mix(in oklab, var(--color-accent) 4%, transparent);
}
.passkey-card:hover::before { opacity: 0.7; }
.passkey-card:hover .passkey-icon svg { transform: rotate(-8deg); }

.passkey-card-main {
  display: flex; align-items: center; gap: 16px; min-width: 0; flex: 1;
}

/* The key icon — antique, hangs on a tiny "tag" string */
.passkey-icon {
  position: relative;
  width: 48px; height: 48px;
  border-radius: 2px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 10%, var(--color-card) 90%) 0%,
      color-mix(in oklab, var(--color-accent) 4%, var(--color-card) 96%) 100%);
  border: 1px solid color-mix(in oklab, var(--color-accent) 28%, var(--color-line) 72%);
  display: flex; align-items: center; justify-content: center;
  color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%);
  flex-shrink: 0;
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--color-paper) 90%, transparent),
    inset 0 -1px 0 color-mix(in oklab, var(--color-accent) 10%, transparent);
}
.passkey-icon::before {
  /* tag-string at the top — a tiny vertical thread */
  content: "";
  position: absolute;
  top: -8px; left: 50%;
  width: 1px; height: 8px;
  background: color-mix(in oklab, var(--color-accent) 35%, var(--color-line) 65%);
}
.passkey-icon::after {
  /* hook ring above the string */
  content: "";
  position: absolute;
  top: -13px; left: 50%;
  transform: translateX(-50%);
  width: 7px; height: 7px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 45%, var(--color-line) 55%);
  border-radius: 50%;
  background: var(--color-card);
}
.passkey-icon svg {
  width: 26px; height: 26px;
  transition: transform 0.35s cubic-bezier(.5,.05,.25,1);
}
.passkey-icon-tag { display: none; }

.passkey-meta { min-width: 0; flex: 1; }
.passkey-label {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--color-text);
  font-size: 16px;
  letter-spacing: 0.03em;
  margin-bottom: 4px;
  word-break: break-word;
  line-height: 1.3;
}
.passkey-stamps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  font-size: 11.5px;
  color: var(--color-muted);
}
.passkey-stamp {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
.passkey-stamp-key {
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-muted) 70%, var(--color-text-dim) 30%);
}
.passkey-stamp-val {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.01em;
  color: var(--color-text-dim);
}
.passkey-stamp-val--muted {
  /* 20-A: 擬似イタリックの和文ゴシックは傾きが不自然なので正立に。
     未使用状態は色を落として控えめに示す。 */
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--color-muted);
}
.passkey-stamp-sep {
  color: color-mix(in oklab, var(--color-muted) 55%, transparent);
  font-size: 10px;
}

/* Release (delete) key button — quiet, not red-loud */
.btn-release-key {
  flex-shrink: 0;
  /* 20-A: ラベルが汎用日本語「削除」になったため、Latin 専用フォント＋広い字間＋
     lowercase（和文に無効）を外し、和文ゴシックで素直に組む。 */
  font-family: var(--font-sans);
  font-size: 12px !important;
  letter-spacing: 0.04em;
  padding: 6px 14px !important;
  border-radius: 2px !important;
}

.btn-outline-danger {
  border: 1px solid color-mix(in oklab, var(--color-danger) 45%, var(--color-line) 55%);
  color: color-mix(in oklab, var(--color-danger) 80%, var(--color-text) 20%);
  background: transparent;
}
.btn-outline-danger:hover {
  background: color-mix(in oklab, var(--color-danger) 10%, transparent);
  color: var(--color-danger);
  border-color: var(--color-danger);
}
.btn-outline-secondary {
  border: 1px solid var(--color-line);
  color: var(--color-text);
  background: transparent;
}
.btn-outline-secondary:hover {
  background: color-mix(in oklab, var(--color-text) 5%, transparent);
  border-color: color-mix(in oklab, var(--color-text) 25%, var(--color-line) 75%);
  color: var(--color-text);
}
.btn-outline-secondary[disabled],
.btn-outline-secondary.disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Empty state — an empty hook on the rail */
.passkey-empty {
  text-align: center;
  /* 20-A: 汎用コピーで一行が短くなったので、空状態の縦の間延びを締める。 */
  padding: 38px 20px 30px;
  border-top: 1px dashed color-mix(in oklab, var(--color-line) 70%, transparent);
  border-bottom: 1px dashed color-mix(in oklab, var(--color-line) 70%, transparent);
  margin: 6px 0 4px;
  background:
    radial-gradient(220px 80px at 50% 0%,
      color-mix(in oklab, var(--color-accent) 6%, transparent) 0%,
      transparent 70%);
}
.passkey-empty-hook {
  width: 54px; height: 54px;
  color: color-mix(in oklab, var(--color-accent) 58%, var(--color-text-dim) 42%);
  margin: 0 auto 16px;
  opacity: 0.8;
}
.passkey-empty-line {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
  /* ゴシック化に合わせ字間を締める */
  letter-spacing: 0;
  margin: 0 0 6px;
  /* 句点だけが孤立して折り返すのを避け、自然な位置で 1〜2 行に均等割りする。
     max-width で意味のまとまり（〜は / 登録されていません。）で割れるよう促す。 */
  word-break: keep-all;
  overflow-wrap: anywhere;
  text-wrap: balance;
  max-width: 17ch;
  margin-left: auto;
  margin-right: auto;
}
.passkey-empty-sub {
  font-size: 12.5px;
  color: var(--color-muted);
  margin: 0 auto;
  max-width: 360px;
  line-height: 1.7;
}

/* ============================================================
   Passkey dialog — "this key needs a name"
   ============================================================ */
.passkey-dialog {
  border: 1px solid var(--color-line);
  border-radius: 4px;
  background: var(--color-card);
  color: var(--color-text);
  padding: 36px 38px 28px;
  max-width: 460px;
  width: calc(100% - 32px);
  box-shadow: var(--shadow-lg);
  position: relative;
}
.passkey-dialog::before {
  content: "";
  position: absolute;
  inset: 8px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 16%, transparent);
  pointer-events: none;
}
.passkey-dialog::backdrop {
  /* backdrop は preset の text 色（暗成分）から派生 */
  background: radial-gradient(800px 400px at 50% 30%,
    color-mix(in oklab, var(--color-text) 55%, transparent) 0%,
    color-mix(in oklab, var(--color-text) 78%, transparent) 100%);
  backdrop-filter: blur(3px);
}
.passkey-dialog form {
  position: relative;
  text-align: center;
}
.passkey-dialog-glyph {
  width: 42px; height: 42px;
  margin: 0 auto 14px;
  color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text) 20%);
  animation: keyDialogIn 0.5s cubic-bezier(.45,.05,.25,1) both;
}
.passkey-dialog-glyph svg { width: 100%; height: 100%; }
@keyframes keyDialogIn {
  from { opacity: 0; transform: translateY(-6px) rotate(-15deg); }
  to   { opacity: 1; transform: translateY(0) rotate(0); }
}
.passkey-dialog-eyebrow {
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-left: 0.5em;
  margin: 0 0 6px;
}
.passkey-dialog h3 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: 0.12em;
  margin: 0 0 16px;
  color: var(--color-text);
}
.passkey-dialog h3::after {
  content: "";
  display: block;
  width: 22px; height: 1px;
  background: var(--color-accent);
  margin: 12px auto 0;
}
.passkey-dialog-desc {
  font-size: 12.5px;
  color: var(--color-text-dim);
  line-height: 1.85;
  margin: 0 0 22px;
}
.passkey-dialog-label {
  display: block;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-align: left;
  margin: 0 0 6px;
  padding-left: 2px;
}
.passkey-dialog input[type="text"] {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--color-line);
  border-radius: 3px;
  background: var(--color-paper);
  color: var(--color-text);
  font-family: var(--font-display);
  font-size: 16px;
  letter-spacing: 0.02em;
  margin: 0;
  text-align: left;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
  box-shadow: inset 0 -1px 0 color-mix(in oklab, var(--color-line) 70%, transparent);
}
.passkey-dialog input[type="text"]:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow:
    inset 0 -2px 0 var(--color-accent),
    0 0 0 3px color-mix(in oklab, var(--color-accent) 22%, transparent);
}
.passkey-dialog-actions {
  margin-top: 24px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* ============================================================
   Auth — "または" divider (wax-seal-style hairline + diamond)
   ============================================================ */
.auth-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 24px 0 18px;
  height: 14px;
}
.auth-divider .auth-divider-rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--color-line) 95%, transparent) 20%,
    color-mix(in oklab, var(--color-line) 95%, transparent) 80%,
    transparent 100%);
}
.auth-divider .auth-divider-glyph {
  font-size: 10px;
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-line) 40%);
  letter-spacing: 0;
  line-height: 1;
}

/* ============================================================
   Login passkey button — secondary but ceremonial.
   Two-line label: 預けた鍵で入る / passkey · this device
   ============================================================ */
.btn-passkey {
  display: flex !important;
  align-items: center;
  gap: 14px;
  padding: 14px 18px 14px 16px !important;
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--color-accent) 32%, var(--color-line) 68%);
  color: var(--color-text);
  text-align: left;
  border-radius: 3px !important;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
  position: relative;
  overflow: hidden;
}
.btn-passkey:hover:not([disabled]):not(.disabled) {
  background: color-mix(in oklab, var(--color-accent) 8%, transparent);
  border-color: var(--color-accent);
  color: var(--color-text);
}
.btn-passkey:hover:not([disabled]):not(.disabled) .passkey-key-icon { transform: rotate(-10deg); }
.btn-passkey:active:not([disabled]):not(.disabled) .passkey-key-icon { transform: rotate(6deg); }
.btn-passkey[disabled],
.btn-passkey.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn-passkey .passkey-key-icon {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text) 25%);
  flex-shrink: 0;
  transition: transform 0.35s cubic-bezier(.5,.05,.25,1);
}
.btn-passkey .passkey-key-icon svg { width: 26px; height: 26px; }
.btn-passkey .passkey-btn-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.2;
  flex: 1;
}
.btn-passkey .passkey-btn-line1 {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--color-text);
}
.btn-passkey .passkey-btn-line2 {
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: lowercase;
  color: var(--color-muted);
  padding-left: 0.32em;
}
#passkey-login-btn { margin-top: 2px; }

/* Re-usable empty hint */
.empty-mini {
  color: var(--color-muted);
  font-size: 13px;
  margin: 14px 0 0;
}

/* ============================================================
   Re-auth (step-up) — Sprint 1.5.1
   "Welcome back / もう一度、本人確認をさせてください"
   ------------------------------------------------------------
   Lives inside .auth-card. The card itself already paints the
   warm paper + hairline frame; this stylesheet handles only the
   contents: a brass key-plate glyph, a 2-step indicator that
   softens the abrupt redirect, and a quiet ticking footer.

   All paint pulls from --color-* bridge tokens so the screen
   stays coherent across the 6 branding presets (Sprint 1.7.1).
   ============================================================ */
.reauth-section {
  /* sits inside .auth-card, which provides padding + inner frame.
     We pull the title block tighter and let the glyph breathe. */
  max-width: 380px;
  margin: 0 auto;
  position: relative;
}

/* ---- step indicator ----
   A 2-bullet rail at the very top of the card. Helps the user
   understand "this is a brief detour, not a new screen". The
   active bullet glows; the next bullet is hollow, with a hairline
   rail between them. */
.reauth-steps {
  list-style: none;
  margin: -4px 0 22px;
  padding: 0;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  font-family: var(--font-latin);
}
.reauth-step {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.reauth-step--next { justify-self: end; }
.reauth-step-bullet {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  flex-shrink: 0;
  position: relative;
}
.reauth-step--active .reauth-step-bullet {
  background: var(--color-accent);
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 22%, transparent);
}
.reauth-step--active .reauth-step-bullet::after {
  /* gentle pulse — "you are here, holding still" */
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--color-accent) 65%, transparent);
  animation: reauthPulse 2.4s ease-in-out infinite;
  opacity: 0;
}
@keyframes reauthPulse {
  0%   { transform: scale(1);    opacity: 0.55; }
  70%  { transform: scale(1.55); opacity: 0;    }
  100% { transform: scale(1.55); opacity: 0;    }
}
.reauth-step-label {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-muted);
  white-space: nowrap;
  min-width: 0;
}
.reauth-step--active .reauth-step-label { color: var(--color-text); }
.reauth-step-num {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%);
}
.reauth-step--next .reauth-step-num {
  color: color-mix(in oklab, var(--color-muted) 80%, var(--color-line) 20%);
}
.reauth-step-name {
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: lowercase;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reauth-step-rail {
  list-style: none;
  height: 1px;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--color-accent) 45%, transparent) 0%,
    color-mix(in oklab, var(--color-line) 90%, transparent) 35%,
    color-mix(in oklab, var(--color-line) 70%, transparent) 100%);
  position: relative;
}
.reauth-step-rail::before,
.reauth-step-rail::after {
  /* tiny tick caps at both ends — feels engraved */
  content: "";
  position: absolute;
  top: -2px;
  width: 1px; height: 5px;
  background: color-mix(in oklab, var(--color-line) 80%, transparent);
}
.reauth-step-rail::before { left: 0; background: color-mix(in oklab, var(--color-accent) 60%, transparent); }
.reauth-step-rail::after  { right: 0; }

/* ---- header (glyph + title + lead) ---- */
.reauth-header {
  text-align: center;
  margin-bottom: 22px;
}

/* Brass key-plate glyph — antique attendant motif.
   The plate is paper-tinted, the key sits inside it like a
   stamp on a desk. A soft halo lifts it from the card. */
.reauth-glyph {
  width: 64px; height: 64px;
  margin: 0 auto 18px;
  position: relative;
  color: color-mix(in oklab, var(--color-accent) 78%, var(--color-text) 22%);
  display: flex; align-items: center; justify-content: center;
}
.reauth-glyph::before {
  /* soft halo — warmth radiating from under the plate */
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in oklab, var(--color-accent) 14%, transparent) 0%,
    transparent 75%);
  pointer-events: none;
  z-index: 0;
}
.reauth-glyph svg {
  position: relative;
  z-index: 1;
  width: 100%; height: 100%;
}
.reauth-glyph-key {
  transform-origin: 24px 28px;
  animation: reauthKeyIn 0.7s cubic-bezier(.4,.05,.2,1) both;
}
@keyframes reauthKeyIn {
  0%   { opacity: 0; transform: rotate(-22deg) translateX(-3px); }
  60%  { opacity: 1; transform: rotate(6deg)   translateX(0);    }
  100% { opacity: 1; transform: rotate(0)      translateX(0);    }
}

.reauth-eyebrow {
  margin: 0 0 8px;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.46em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-left: 0.46em; /* optical center of letter-spaced text */
}
.reauth-title {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0.08em;
  line-height: 1.55;
  /* 20-B: 汎用化で本文が和文ゴシックの平易文になったため、句読点・文節境界で
     折り返す。balance で行長を均し、auto-phrase で「お願いし／ます」のような
     語中改行を避ける（非対応ブラウザは無害にフォールバック）。 */
  text-wrap: balance;
  word-break: auto-phrase;
}
.reauth-title::after {
  /* hairline accent under the title — same vocab as .auth-card h1::after */
  content: "";
  display: block;
  width: 22px; height: 1px;
  background: var(--color-accent);
  margin: 14px auto 0;
}
.reauth-lead {
  margin: 0;
  font-size: 13px;
  line-height: 1.95;
  color: var(--color-text-dim);
  /* 中央寄せの平易文を文節境界で折り返す（語中改行の回避） */
  text-wrap: pretty;
  word-break: auto-phrase;
}

/* "signed in as ___" — quietly affirms identity */
.reauth-user {
  margin: 16px 0 0;
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 5px 12px 6px;
  background: color-mix(in oklab, var(--color-accent) 5%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%);
  border-radius: 2px;
}
.reauth-user-label {
  font-family: var(--font-latin);
  font-size: 9px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.32em;
  color: var(--color-muted);
  padding-left: 0.32em;
}
.reauth-user-name {
  font-family: var(--font-display);
  font-size: 13.5px;
  color: var(--color-text);
  letter-spacing: 0.04em;
}

/* ---- alert ----
   Override the generic .alert-danger to feel "noticed, not scolded".
   A horizontal layout with a tiny mark + soft amber-tinted band,
   not the loud red the framework defaults to. */
.reauth-alert {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 11px 14px 11px 12px !important;
  border-radius: 2px !important;
  font-size: 12.5px;
  line-height: 1.55;
  margin: 0 0 18px;
  /* Keep the framework's color cues but soften: derive from danger
     mixed deep into paper so the band breathes with the preset. */
  background: color-mix(in oklab, var(--color-danger) 9%, var(--color-card) 91%) !important;
  border: 1px solid color-mix(in oklab, var(--color-danger) 28%, var(--color-line) 72%) !important;
  color: color-mix(in oklab, var(--color-danger) 60%, var(--color-text) 40%) !important;
  animation: reauthAlertIn 0.45s cubic-bezier(.4,.05,.2,1) both;
}
.reauth-alert::before { display: none !important; } /* drop the framework's left bar */
.reauth-alert-mark {
  flex-shrink: 0;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1px solid currentColor;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 500;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
  margin-top: 1px;
  opacity: 0.85;
}
.reauth-alert-text { flex: 1; min-width: 0; }
@keyframes reauthAlertIn {
  0%   { opacity: 0; transform: translateY(-4px); }
  100% { opacity: 1; transform: translateY(0);    }
}
/* Gentle shake on error — once, not insistent */
.reauth-section--errored .reauth-glyph {
  animation: reauthShake 0.55s cubic-bezier(.36,.07,.19,.97) both;
}
@keyframes reauthShake {
  0%,100% { transform: translateX(0); }
  20%     { transform: translateX(-3px); }
  40%     { transform: translateX(3px);  }
  60%     { transform: translateX(-2px); }
  80%     { transform: translateX(2px);  }
}

/* ---- form ---- */
.reauth-form { margin-top: 4px; }
.reauth-field { margin-bottom: 18px; }
.reauth-label {
  display: block;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 7px;
  padding-left: 0.36em;
}

/* Input — bottom-line "engraving" style.
   We keep a real border for accessibility / form-control compat,
   but the focus state lights an under-stroke in accent, echoing
   the passkey dialog's bottom-line treatment. */
.reauth-input {
  width: 100%;
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: 16px; /* 16+ avoids iOS zoom on focus */
  letter-spacing: 0.18em;
  border: 1px solid var(--color-line);
  background: var(--color-paper);
  color: var(--color-text);
  border-radius: 2px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
  box-shadow: inset 0 -1px 0 color-mix(in oklab, var(--color-line) 70%, transparent);
}
.reauth-input::placeholder {
  font-family: var(--font-mono);
  letter-spacing: 0.4em;
  color: color-mix(in oklab, var(--color-muted) 55%, transparent);
}
.reauth-input:hover {
  border-color: color-mix(in oklab, var(--color-accent) 35%, var(--color-line) 65%);
}
.reauth-input:focus {
  outline: none;
  border-color: var(--color-accent);
  background: var(--color-card);
  box-shadow:
    inset 0 -2px 0 var(--color-accent),
    0 0 0 3px color-mix(in oklab, var(--color-accent) 18%, transparent);
}

/* ---- actions ---- */
.reauth-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 4px;
}
.btn-reauth-submit {
  flex: 1;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 11px 18px !important;
  font-size: 13px;
  letter-spacing: 0.12em;
  border-radius: 2px !important;
  position: relative;
  overflow: hidden;
}
.btn-reauth-submit::after {
  /* subtle inner hairline — matches auth-card frame language */
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid color-mix(in oklab, var(--color-paper) 26%, transparent);
  pointer-events: none;
  border-radius: 1px;
}
.reauth-submit-key {
  width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 0.4s cubic-bezier(.5,.05,.25,1);
}
.reauth-submit-key svg { width: 18px; height: 18px; }
.btn-reauth-submit:hover .reauth-submit-key { transform: translateX(2px) rotate(-6deg); }
.btn-reauth-submit:active .reauth-submit-key { transform: translateX(0) rotate(4deg); }
.reauth-submit-text { display: inline-block; }

.reauth-cancel {
  font-family: var(--font-latin);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-decoration: none;
  padding: 4px 2px;
  border-bottom: 1px solid transparent;
  transition: color 0.18s ease, border-color 0.18s ease;
  white-space: nowrap;
}
.reauth-cancel:hover {
  color: var(--color-text);
  border-bottom-color: color-mix(in oklab, var(--color-text) 30%, transparent);
}

/* ---- foot: "約 10 分有効" with a soft pulsing tick ---- */
.reauth-foot {
  margin: 26px 0 0;
  text-align: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-muted);
  width: 100%;
  padding-top: 18px;
  border-top: 1px solid color-mix(in oklab, var(--color-line) 65%, transparent);
}
.reauth-foot-tick {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 75%, transparent);
  position: relative;
  animation: reauthTick 1.6s ease-in-out infinite;
}
.reauth-foot-tick::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--color-accent) 55%, transparent);
  opacity: 0.5;
  animation: reauthTickRing 1.6s ease-out infinite;
}
@keyframes reauthTick {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1;    }
}
@keyframes reauthTickRing {
  0%   { transform: scale(0.6); opacity: 0.55; }
  100% { transform: scale(1.6); opacity: 0;    }
}
.reauth-foot-text strong {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0.08em;
  padding: 0 2px;
}

/* ---- responsive ---- */
@media (max-width: 420px) {
  .reauth-section { max-width: none; }
  .reauth-title { font-size: 17px; letter-spacing: 0.06em; }
  .reauth-steps { margin-bottom: 18px; gap: 8px; }
  .reauth-step-name { display: none; } /* keep only 01/02 + bullets on tight widths */
  .reauth-user { flex-wrap: wrap; gap: 4px 8px; }
  .reauth-actions { flex-direction: column-reverse; align-items: stretch; gap: 10px; }
  .reauth-cancel { text-align: center; }
}

/* ============================================================
   Passkey step-up redirect overlay — Sprint 1.5.1
   Replaces the abrupt `alert + 800ms jump` on the passkeys page
   with a small ceremonial pause: a brass key-plate fades in and
   the user understands "I'm being asked to confirm at the door".
   ============================================================ */
.reauth-redirect-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: color-mix(in oklab, var(--color-paper) 88%, var(--color-text) 12%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease;
}
.reauth-redirect-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}
.reauth-redirect-card {
  position: relative;
  max-width: 360px;
  width: 100%;
  background: var(--color-card);
  border: 1px solid var(--color-line);
  border-radius: 3px;
  padding: 34px 30px 28px;
  text-align: center;
  box-shadow: var(--shadow-lg);
  transform: translateY(8px) scale(0.985);
  transition: transform 0.4s cubic-bezier(.4,.05,.2,1);
}
.reauth-redirect-overlay.is-open .reauth-redirect-card { transform: translateY(0) scale(1); }
.reauth-redirect-card::before {
  /* hairline inner frame — matches auth-card vocabulary */
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 18%, transparent);
  pointer-events: none;
}
.reauth-redirect-glyph {
  width: 56px; height: 56px;
  margin: 0 auto 14px;
  position: relative;
  color: color-mix(in oklab, var(--color-accent) 78%, var(--color-text) 22%);
}
.reauth-redirect-glyph::before {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in oklab, var(--color-accent) 14%, transparent) 0%,
    transparent 75%);
}
.reauth-redirect-glyph svg {
  position: relative;
  width: 100%; height: 100%;
  animation: reauthRedirectKey 1.6s cubic-bezier(.4,.05,.2,1) infinite;
  transform-origin: 50% 60%;
}
@keyframes reauthRedirectKey {
  0%, 100% { transform: rotate(-6deg); }
  50%      { transform: rotate(6deg);  }
}
.reauth-redirect-eyebrow {
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 6px;
  padding-left: 0.5em;
}
.reauth-redirect-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--color-text);
  margin: 0 0 10px;
}
.reauth-redirect-desc {
  font-size: 12.5px;
  color: var(--color-text-dim);
  line-height: 1.8;
  margin: 0 0 16px;
}
.reauth-redirect-dots {
  display: inline-flex;
  gap: 6px;
  align-items: center;
}
.reauth-redirect-dots span {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  animation: reauthRedirectDot 1.2s ease-in-out infinite;
}
.reauth-redirect-dots span:nth-child(2) { animation-delay: 0.15s; }
.reauth-redirect-dots span:nth-child(3) { animation-delay: 0.30s; }
@keyframes reauthRedirectDot {
  0%, 100% { opacity: 0.35; transform: translateY(0);    }
  50%      { opacity: 1;    transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
  .reauth-glyph-key,
  .reauth-step--active .reauth-step-bullet::after,
  .reauth-foot-tick,
  .reauth-foot-tick::after,
  .reauth-redirect-glyph svg,
  .reauth-redirect-dots span {
    animation: none;
  }
}

/* ============================================================
   Sprint 1.5.2 — Dormant verify  ("the sleeping key wakes")
   ------------------------------------------------------------
   久しぶりのログイン = 「鍵が眠っていた」メタファ。
   Sprint 2 (wax-seal envelope) と Sprint 1.5.1 (brass key plate)
   の中間トーン:
     - Sprint 2 verify    → 封蝋を解く (新規入会の儀式)
     - Sprint 1.5.2 (ここ) → 眠っていた鍵を取り出す (久しぶりの来訪)

   Vocabulary:
     .dormant-section / .dormant-glyph / .dormant-days-plate /
     .dormant-eyebrow / .dormant-title / .dormant-lead /
     .dormant-reassure
   All paint via --color-* bridge tokens (preset-aware).
   ============================================================ */

/* Loosen .auth-shell for this screen so the days-plate has air */
.auth-shell:has(.dormant-section) { max-width: 460px; }

.dormant-section {
  position: relative;
  text-align: center;
  max-width: 380px;
  margin: 0 auto;
}

/* ---- the sleeping-key glyph ----
   An antique key resting half-out of a low envelope, with two faint
   Z marks drifting above. Echoes Sprint 1.5.1 brass key + Sprint 2
   envelope, but the staging (slumped envelope, exposed bow) is unique
   to "dormant". The key softly turns toward upright on load. */
.dormant-glyph {
  position: relative;
  width: 124px;
  height: 96px;
  margin: -6px auto 12px;
  color: color-mix(in oklab, var(--color-accent) 78%, var(--color-text) 22%);
}
.dormant-glyph-halo {
  /* warm halo radiating from the bow — like the key has just lit up.
     Centred over the key bow in the 120-wide viewBox. */
  position: absolute;
  inset: -2px 26px 22px 26px;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in oklab, var(--color-accent) 22%, transparent) 0%,
    color-mix(in oklab, var(--color-accent) 9%, transparent) 45%,
    transparent 82%);
  pointer-events: none;
  z-index: 0;
  animation: dormantHaloBreathe 4.8s ease-in-out 0.8s infinite;
}
.dormant-glyph-svg {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
}

/* envelope: settle in from below — a quiet ledger drawer opening */
.dormant-glyph-envelope {
  transform-origin: 60px 86px;
  animation: dormantEnvIn 0.7s cubic-bezier(.4,.05,.2,1) both;
}
@keyframes dormantEnvIn {
  from { opacity: 0; transform: translateY(6px) scale(0.96); }
  to   { opacity: 0.78; transform: translateY(0) scale(1); }
}

/* key: gently lift + rotate to vertical, as if waking up */
.dormant-glyph-key {
  transform-origin: 60px 34px;
  animation: dormantKeyWake 1.1s cubic-bezier(.45,.05,.2,1) 0.25s both;
}
@keyframes dormantKeyWake {
  0%   { opacity: 0; transform: rotate(-14deg) translateY(3px); }
  55%  { opacity: 1; transform: rotate(3deg)   translateY(0);   }
  100% { opacity: 1; transform: rotate(0)      translateY(0);   }
}

/* Z marks: drift up, fade — "the key was just sleeping" */
.dormant-glyph-zs {
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-muted) 45%);
  opacity: 0;
  animation: dormantZsDrift 3.2s ease-out 0.6s both;
}
@keyframes dormantZsDrift {
  0%   { opacity: 0; transform: translateY(4px); }
  20%  { opacity: 0.7; }
  85%  { opacity: 0.7; transform: translateY(-6px); }
  100% { opacity: 0;   transform: translateY(-10px); }
}

@keyframes dormantHaloBreathe {
  0%, 100% { opacity: 0.75; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.06); }
}

/* ---- eyebrow + title ---- */
.dormant-eyebrow {
  margin: 0 0 10px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.46em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-left: 0.46em;
  animation: dormantFadeUp 0.6s ease-out 0.7s both;
}
.dormant-title {
  /* Override .auth-card h1's tight tracking — おかえりなさい wants warmth.
     Keep display font but with a touch more weight and a longer stroke. */
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 500;
  margin: 0 0 24px;
  letter-spacing: 0.18em;
  color: var(--color-text);
  text-align: center;
  animation: dormantFadeUp 0.6s ease-out 0.78s both;
}
.dormant-title::after {
  /* hairline accent — same vocab as .auth-card h1 but a touch wider */
  content: "";
  display: block;
  width: 32px; height: 1px;
  background: var(--color-accent);
  margin: 12px auto 0;
  opacity: 0.8;
}

/* ---- the engraved metal "days since" plate ----
   This is the visual hero. A small ledger-card with a serif numeral
   that says "you've been gone N days" without being accusatory.
   Composition: latin small-caps cap on top, big serif number, then
   a quiet japanese sub. Brass-tinted hairline frame + paper inset. */
.dormant-days-plate {
  position: relative;
  display: inline-block;
  margin: 0 0 22px;
  padding: 14px 32px 12px;
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-card) 95%);
  border: 1px solid color-mix(in oklab, var(--color-accent) 25%, var(--color-line) 75%);
  border-radius: 3px;
  /* faint inner glow at top + soft hairline shadow below — feels stamped */
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--color-card) 100%, transparent),
    inset 0 -1px 0 color-mix(in oklab, var(--color-accent) 12%, transparent),
    0 1px 0 color-mix(in oklab, var(--color-line) 60%, transparent);
  animation: dormantPlateIn 0.7s cubic-bezier(.4,.05,.2,1) 0.85s both;
  text-align: center;
}
.dormant-days-plate::before,
.dormant-days-plate::after {
  /* tiny "rivets" at the top corners — like a brass nameplate */
  content: "";
  position: absolute;
  top: 5px;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 60%, var(--color-line) 40%);
  opacity: 0.55;
}
.dormant-days-plate::before { left: 7px; }
.dormant-days-plate::after  { right: 7px; }

.dormant-days-plate-cap {
  display: block;
  font-family: var(--font-latin);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-left: 0.42em;
  margin-bottom: 6px;
  white-space: nowrap;
}
.dormant-days-plate-num {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  margin: 0 0 4px;
  color: var(--color-text);
}
.dormant-days-plate-num .dormant-days {
  font-family: var(--font-display);
  font-size: 44px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--color-accent) 35%, var(--color-text) 65%);
  /* gentle vertical optical alignment with the 日 character */
  position: relative;
}
.dormant-days-plate-num .dormant-days-unit {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0.04em;
}
.dormant-days-plate-sub {
  display: block;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--color-text-dim);
  margin-top: 2px;
}

@keyframes dormantPlateIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- lead paragraph ---- */
.dormant-lead {
  margin: 0 0 26px;
  font-size: 13px;
  line-height: 1.95;
  color: var(--color-text-dim);
  animation: dormantFadeUp 0.6s ease-out 0.95s both;
}
.dormant-lead .lede-mail {
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.01em;
  color: var(--color-text);
  display: inline-block;
  padding: 1px 6px;
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 55%, transparent);
  word-break: break-all;
}

/* ---- reassurance line below the form ---- */
.dormant-reassure {
  margin: 22px 0 0;
  font-family: var(--font-display);
  font-size: 12px;
  font-style: normal;
  line-height: 1.8;
  text-align: center;
  color: color-mix(in oklab, var(--color-text-dim) 80%, var(--color-accent) 20%);
  letter-spacing: 0.06em;
  padding: 10px 14px;
  position: relative;
}
.dormant-reassure::before,
.dormant-reassure::after {
  /* tiny serif corner brackets — like a printed editorial quote */
  position: absolute;
  font-family: var(--font-display);
  font-size: 16px;
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  line-height: 1;
}
.dormant-reassure::before { content: "「"; top: 6px; left: 2px; }
.dormant-reassure::after  { content: "」"; bottom: 6px; right: 2px; }

@keyframes dormantFadeUp {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* error state — quiet, no scolding (reuses Sprint 1.5.1 vocabulary) */
.dormant-section .reauth-alert {
  margin: 0 0 18px;
  text-align: left;
}

@media (max-width: 460px) {
  .dormant-days-plate { padding: 12px 22px 10px; }
  .dormant-days-plate-num .dormant-days { font-size: 38px; }
  .dormant-days-plate-cap { font-size: 8.5px; letter-spacing: 0.34em; }
  .dormant-title { font-size: 19px; letter-spacing: 0.14em; }
}

@media (prefers-reduced-motion: reduce) {
  .dormant-glyph-key,
  .dormant-glyph-envelope,
  .dormant-glyph-zs,
  .dormant-glyph-halo,
  .dormant-days-plate,
  .dormant-title,
  .dormant-eyebrow,
  .dormant-lead {
    animation: none;
  }
}

/* ---- Admin settings: dormant threshold panel polish ----
   The "0 で無効化" mention is the key concept; pull it into a quiet
   inline pill so admins read it as a real switch, not body text. */
.card-panel[data-test="dormant-settings-panel"] .text-muted strong {
  display: inline-block;
  font-weight: 500;
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 2px 8px 3px;
  margin: 0 2px;
  background: color-mix(in oklab, var(--color-accent) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-accent) 32%, var(--color-line) 68%);
  border-radius: 2px;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%);
  vertical-align: 1px;
}
.card-panel[data-test="dormant-settings-panel"] .form-text code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 1px 6px;
  background: color-mix(in oklab, var(--color-accent) 6%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%);
  border-radius: 2px;
  color: var(--color-text);
}

/* ============================================================
   Sprint 3 — 投稿 / タイムライン / コメント / リアクション
   ------------------------------------------------------------
   Tone: 「居場所」「静かな熱量」「ROM専に優しい」
   - 余白を広く、情報密度を低く（Discord型の詰め込みを避ける）
   - 投稿は "流れて消える" のではなく "積み上がる" 縦の連なり
   - リアクションは ROM 専でも気軽に押せる温かい一拍
   - すべて --color-* トークン経由でブランディングプリセットに追従
   ------------------------------------------------------------
   token aliases — keep the palette intent local & brand-agnostic */
:root {
  --post-hair:   color-mix(in oklab, var(--color-line) 64%, transparent);
  --post-quiet:  color-mix(in oklab, var(--color-text) 6%, var(--color-card));
  --post-warm:   color-mix(in oklab, var(--color-accent) 16%, var(--color-card));
  --post-on-acc: color-mix(in oklab, var(--color-accent) 90%, #ffffff 10%);
  --post-ease:   cubic-bezier(0.22, 0.61, 0.36, 1);
}

.timeline-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 22px;
}
.timeline-title {
  font-family: var(--font-display);
  font-size: 23px;
  font-weight: 600;
  /* 20-A: ゴシック化に合わせ字間を締める */
  letter-spacing: 0.01em;
  margin: 0;
}
.timeline-sub {
  color: var(--color-muted);
  /* 20-A: 既定見出しが Noto Sans（ゴシック）化したため、display の擬似イタリックは
     和文で不自然に傾く。リード文は本文系・正立・軽量に寄せて素直な注記にする。 */
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 12.5px;
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.6;
  margin: 0;
  max-width: 30ch;
  text-align: right;
}
.back-link {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: color .15s ease, gap .2s var(--post-ease);
}
.back-link:hover { color: var(--color-text); gap: 8px; }

/* ---- 投稿フォーム（タイムライン上部の "ひとこと置き場"） ---- */
.composer {
  background: var(--color-card);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 16px 18px 14px;
  margin-bottom: 30px;
  box-shadow: var(--shadow-sm);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.composer:focus-within {
  border-color: color-mix(in oklab, var(--color-accent) 55%, var(--color-line));
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-accent) 10%, transparent);
}
.composer-standalone { margin-top: 8px; }
.composer-textarea {
  width: 100%;
  resize: vertical;
  min-height: 64px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--color-text);
  padding: 4px 2px;
  font: inherit;
  line-height: 1.7;
}
.composer-textarea::placeholder {
  color: var(--color-muted);
  font-family: var(--font-display);
  font-style: italic;
}
.composer-textarea:focus { outline: none; }
.composer-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--post-hair);
}
/* Sprint 18-A: foot 内の縦並びの意図を order で明示化（attach → submit → previews）。
   previews が独立行に押し出されるため、attach と submit が同じ行に綺麗に並ぶ。 */
.composer-foot > .composer-attach { order: 1; }
.composer-foot > .composer-submit { order: 1; }
.composer-attach {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-latin);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--color-muted);
  cursor: pointer;
  padding: 5px 10px 5px 8px;
  border-radius: 999px;
  transition: color .15s ease, background .15s ease;
}
.composer-attach:hover {
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text));
  background: var(--post-warm);
}
.composer-attach svg { width: 17px; height: 17px; flex: 0 0 auto; }
.composer-attach input[type="file"] { display: none; }
/* Sprint 18-A: previews は foot 内で「独立行」に押し出して、プレビュー・警告が
   横に潰されず素直に並ぶようにする。中身ゼロのときは余白を作らない。 */
.composer-previews {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  width: 100%;
  order: 2;
}
.composer-previews:empty { display: none; }
.composer-preview {
  width: 60px; height: 60px; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--color-line);
  box-shadow: var(--shadow-sm);
  animation: composer-pop .28s var(--post-ease) both;
}
@keyframes composer-pop {
  from { opacity: 0; transform: scale(.86); }
  to   { opacity: 1; transform: scale(1); }
}
/* Sprint 18-A: ドラッグ&ドロップ受け入れ中の視覚フィードバック。
   コンセプト: 「紙にそっと添える」— 縁取りに amber の灯がふわっと射し、
   中央にうっすら温度の輪が浮かぶ。Dropbox 的な原色青の dropzone は避ける。
   ------------------------------------------------------------------ */
.composer {
  /* drop position hint（is-dragover で目立つ）の中心。通常時は不可視。 */
  position: relative;
  isolation: isolate;
}
.composer::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  /* 中央から外側へ薄く広がる accent の温度の輪 */
  background:
    radial-gradient(
      120% 90% at 50% 45%,
      color-mix(in oklab, var(--color-accent) 10%, transparent) 0%,
      color-mix(in oklab, var(--color-accent) 3%, transparent) 38%,
      transparent 72%
    );
  opacity: 0;
  transition: opacity .28s var(--post-ease);
  z-index: 0;
}
/* リズムのある破線（紙の縁取り風）— mask で SVG を切り抜き、accent 色で塗る。
   こうすることでブランドプリセット（amber/blue/moss 等）に追従する。 */
.composer::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: calc(var(--radius-lg) - 4px);
  pointer-events: none;
  background: color-mix(in oklab, var(--color-accent) 70%, var(--color-text-dim));
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'><rect x='1' y='1' width='calc(100%25 - 2px)' height='calc(100%25 - 2px)' rx='12' ry='12' fill='none' stroke='black' stroke-width='1.4' stroke-dasharray='10 7 3 7' stroke-linecap='round'/></svg>") no-repeat center / 100% 100%;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'><rect x='1' y='1' width='calc(100%25 - 2px)' height='calc(100%25 - 2px)' rx='12' ry='12' fill='none' stroke='black' stroke-width='1.4' stroke-dasharray='10 7 3 7' stroke-linecap='round'/></svg>") no-repeat center / 100% 100%;
  opacity: 0;
  transform: scale(.992);
  transition: opacity .26s var(--post-ease), transform .32s var(--post-ease);
  z-index: 0;
}
.composer > * { position: relative; z-index: 1; }

.composer.is-dragover {
  /* 基底 border は通常の太さを保ったまま色だけ accent 寄りに（破線は ::after で描く）。
     これでレイアウトが 1px もずれず、紙の縁取りに灯がともる体験を作れる。 */
  border-color: color-mix(in oklab, var(--color-accent) 35%, var(--color-line));
  background-color: color-mix(in oklab, var(--color-accent) 4%, var(--color-card));
  /* :focus-within の amber ring と重ねず、より柔らかな広がり */
  box-shadow:
    0 0 0 5px color-mix(in oklab, var(--color-accent) 7%, transparent),
    0 18px 38px -28px color-mix(in oklab, var(--color-accent) 55%, transparent);
  transform: translateY(-1px);
  transition:
    background-color .22s var(--post-ease),
    box-shadow .22s var(--post-ease),
    transform .22s var(--post-ease),
    border-color .22s var(--post-ease);
}
.composer.is-dragover::before { opacity: 1; }
.composer.is-dragover::after { opacity: .65; transform: scale(1); }
.composer.is-dragover .composer-textarea { background: transparent; }
.composer.is-dragover .composer-textarea::placeholder {
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-muted));
}
/* focus-within と is-dragover の同時発火時は dragover の描線を優先 */
.composer:focus-within.is-dragover {
  box-shadow:
    0 0 0 6px color-mix(in oklab, var(--color-accent) 8%, transparent),
    0 18px 38px -28px color-mix(in oklab, var(--color-accent) 60%, transparent);
}

/* --- ドラッグ&ドロップのヒント（アイコン + 文言） --- */
.composer-attach-hint {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--color-muted);
  opacity: 0.78;
  margin-left: 6px;
  padding-left: 8px;
  border-left: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
  transition: opacity .2s ease, color .2s ease, transform .2s var(--post-ease);
}
.composer-attach-hint-icon {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  transform: translateY(0);
  transition: transform .25s var(--post-ease), color .2s ease;
}
/* composer に hover/focus が当たったとき、ヒントがほのかに灯る */
.composer:hover .composer-attach-hint,
.composer:focus-within .composer-attach-hint {
  opacity: 1;
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text-dim));
}
.composer:hover .composer-attach-hint-icon,
.composer:focus-within .composer-attach-hint-icon {
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text-dim));
  animation: composer-hint-drop 2.4s var(--post-ease) infinite;
}
.composer.is-dragover .composer-attach-hint {
  opacity: 1;
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text));
  border-left-color: color-mix(in oklab, var(--color-accent) 50%, transparent);
}
.composer.is-dragover .composer-attach-hint-icon {
  color: color-mix(in oklab, var(--color-accent) 90%, var(--color-text));
  animation: composer-hint-drop 1.2s var(--post-ease) infinite;
}
@keyframes composer-hint-drop {
  0%, 100% { transform: translateY(0); }
  45%      { transform: translateY(2px); }
  55%      { transform: translateY(2px); }
}
/* アップロード中インジケーター（JS が data-uploading を立てる） */
.composer.is-uploading .composer-submit {
  pointer-events: none;
  opacity: .7;
}
.composer.is-uploading .composer-submit::after {
  content: "";
  width: 13px; height: 13px;
  margin-left: 8px;
  border: 2px solid color-mix(in oklab, #ffffff 70%, transparent);
  border-top-color: transparent;
  border-radius: 50%;
  display: inline-block;
  vertical-align: -2px;
  animation: composer-spin .7s linear infinite;
}
@keyframes composer-spin { to { transform: rotate(360deg); } }
.composer-warn, .composer-error {
  color: var(--color-danger);
  font-size: 12px;
  width: 100%;
  display: flex; align-items: center; gap: 6px;
  padding: 7px 10px;
  background: color-mix(in oklab, var(--color-danger) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-danger) 28%, transparent);
  border-radius: 8px;
}
.composer-error { margin-top: 8px; }
/* CakePHP FormHelper の既定エラー（.error-message）を投稿/コメント文脈で整える */
.composer .error-message,
.comment-form .error-message {
  color: var(--color-danger);
  font-size: 12px;
  margin: 8px 0 0;
  padding: 7px 10px;
  background: color-mix(in oklab, var(--color-danger) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-danger) 28%, transparent);
  border-radius: 8px;
}
.composer .is-error .composer-textarea,
.composer textarea.is-invalid {
  border-color: color-mix(in oklab, var(--color-danger) 50%, var(--color-line)) !important;
}
.composer-submit {
  margin-left: auto;
  background: var(--color-accent);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 9px 22px;
  font: inherit;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  box-shadow: 0 6px 16px -8px color-mix(in oklab, var(--color-accent) 70%, transparent);
  transition: transform .12s var(--post-ease), box-shadow .2s ease, filter .15s ease;
}
.composer-submit:hover { filter: brightness(1.05); transform: translateY(-1px); }
.composer-submit:active { transform: translateY(0) scale(.98); }

/* ---- 投稿リスト・カード（"積み上がる" 縦の連なり） ---- */
.post-list { display: flex; flex-direction: column; gap: 18px; }
.post-card, .post-detail {
  background: var(--color-card);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 20px 22px;
  box-shadow: var(--shadow-sm);
  transition: border-color .2s ease, box-shadow .25s ease, transform .25s var(--post-ease);
}
.post-card { position: relative; }
.post-card:hover {
  border-color: color-mix(in oklab, var(--color-accent) 32%, var(--color-line));
  box-shadow: var(--shadow);
}
.post-detail { padding: 24px 26px; }
.post-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}
.post-author { display: flex; align-items: center; gap: 12px; }
.post-avatar, .comment-avatar {
  width: 42px; height: 42px; border-radius: 50%;
  object-fit: cover; flex: 0 0 auto;
  box-shadow: 0 0 0 1px var(--post-hair);
}
.post-avatar-fallback, .comment-avatar-fallback {
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(140deg,
      color-mix(in oklab, var(--color-accent) 30%, var(--color-card)),
      color-mix(in oklab, var(--color-accent) 14%, var(--color-card)));
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
}
.comment-avatar { width: 34px; height: 34px; }
.comment-avatar-fallback { font-size: 14px; }
.post-author-meta { display: flex; flex-direction: column; gap: 1px; }
.post-author-name {
  font-weight: 600; font-size: 14.5px; line-height: 1.3;
  display: inline-flex; align-items: center; gap: 6px;
}
.author-badge-slot:empty { display: none; }

/* ============================================================
   sprint-5.1: 本人（推し）の視覚強調
   ------------------------------------------------------------
   世界観: 「ここに推しがいる」温かい特別感を、静かな暖色で。
   - 色は clay（テラコッタ〜ローズ）= view-all 緑/author 青と非衝突
   - マゼンタの原色・点滅・けばけばしいグラデは使わない
   - 紙に灯がともるような淡い暖色のにじみ＋細い金線で "特別" を示す
   ============================================================ */

/* 本人バッジ — 名前の右に灯る小さな印。塗りだが彩度は抑え、
   微かな暖色グローで "温度" を持たせる。点ハートで推しの親密さを一点だけ。 */
.owner-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1.5px 9px 1.5px 7px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 0.08em;
  color: var(--owner-on);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--owner) 88%, #fff 12%),
      var(--owner));
  border: 1px solid color-mix(in oklab, var(--owner-deep) 55%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, #fff 30%, transparent),
    0 1px 6px var(--owner-glow);
  white-space: nowrap;
}
.owner-badge::before {
  content: "";
  width: 9px;
  height: 9px;
  flex: 0 0 auto;
  background: currentColor;
  /* tiny heart glyph — "推し" のぬくもりを一点だけ */
  -webkit-mask: var(--owner-heart) center / contain no-repeat;
          mask: var(--owner-heart) center / contain no-repeat;
  opacity: 0.92;
}
:root {
  --owner-heart: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21s-7.5-4.6-10-9.1C.4 8.9 1.7 5.5 5 5.5c2 0 3.2 1.2 4 2.4.8-1.2 2-2.4 4-2.4 3.3 0 4.6 3.4 3 6.4C19.5 16.4 12 21 12 21z'/%3E%3C/svg%3E");
}

/* 本人投稿カード — 左の細い金線＋ごく淡い暖色のにじみ。
   バッジと併用しても "賑やか" にならない静かな格上げ。 */
.post-card-owner,
.post-detail.post-card-owner {
  position: relative;
  border-color: var(--owner-line);
  background:
    linear-gradient(90deg,
      color-mix(in oklab, var(--owner) 10%, var(--color-card)) 0%,
      var(--color-card) 38%);
}
.post-card-owner::before,
.post-detail.post-card-owner::before {
  content: "";
  position: absolute;
  /* カードの角丸（--radius-lg）の分だけ上下を内側に逃がし、直線が丸角からはみ出さない
     “浮いたアクセントバー”にする。カードに overflow:hidden は使わない（リアクションの
     ピッカーが上に開くため切れてしまう）。 */
  left: 0; top: var(--radius-lg); bottom: var(--radius-lg);
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg,
      var(--owner),
      color-mix(in oklab, var(--owner) 55%, transparent));
}
.post-card-owner:hover {
  border-color: color-mix(in oklab, var(--owner) 60%, var(--color-line));
}

/* ホーム上部「本人からの最新投稿」固定枠 — 通常タイムラインから
   一段引き上げた "舞台"。額縁の上辺に金線、内側に淡い暖色の灯り。 */
.owner-pin {
  position: relative;
  margin: 0 0 26px;
  padding: 16px 16px 4px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--owner-line);
  background:
    radial-gradient(120% 90% at 0% 0%,
      color-mix(in oklab, var(--owner) 9%, transparent) 0%,
      transparent 55%),
    var(--color-card);
  box-shadow: var(--shadow);
}
.owner-pin::before {
  content: "";
  position: absolute;
  /* 角丸（--radius-lg）の分だけ左右を内側に逃がし、直線の上端アクセントが丸角から
     はみ出さないようにする（全幅 inset:0 だと角の外へ線が飛び出す）。 */
  top: 0;
  left: var(--radius-lg);
  right: var(--radius-lg);
  height: 2px;
  border-radius: 0 0 2px 2px;
  background: linear-gradient(90deg,
      var(--owner) 0%,
      color-mix(in oklab, var(--owner) 35%, transparent) 70%,
      transparent 100%);
}
.owner-pin-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 13px;
  color: var(--owner-deep);
}
.owner-pin-icon {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  fill: var(--owner);
  stroke: var(--owner);
}
.owner-pin-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.06em;
  line-height: 1;
}
/* 固定枠内のカードは "額の中" として枠線・余計な影を落とし、
   背景のにじみに溶け込ませる（二重の枠を避ける）。 */
.owner-pin .post-card {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  margin: 0;
  padding-left: 0;
  padding-right: 0;
}
.owner-pin .post-card::before { display: none; }
.owner-pin .post-card:hover { border-color: transparent; }
/* 固定枠ではカード左右 padding が 0（owner-pin 側の 16px padding で内容を寄せている）。
   インラインコメントトレイの負マージン/内側 padding を owner-pin の 16px に合わせ、
   枠の角丸からはみ出さないようにする（通常カードは 22px だが固定枠だけ上書き）。 */
.owner-pin .post-comments {
  margin-left: -16px;
  margin-right: -16px;
  padding-left: 16px;
  padding-right: 16px;
}
.post-time, .comment-time {
  font-family: var(--font-latin);
  font-size: 11.5px;
  letter-spacing: 0.03em;
  color: var(--color-muted);
}
/* sprint-6: 削除コントロールの実体は末尾の「静かな手当て」ブロックを参照 */
.post-body-link, .post-images-link { text-decoration: none; color: inherit; display: block; }
.post-body, .post-detail-body {
  font-size: 15px; line-height: 1.85; margin: 0 0 14px; white-space: normal;
  color: color-mix(in oklab, var(--color-text) 92%, var(--color-muted));
  letter-spacing: 0.01em;
  overflow-wrap: anywhere; word-break: break-word;
}
.post-detail-body { font-size: 15.5px; margin-bottom: 4px; }
.post-more {
  color: var(--color-accent);
  font-family: var(--font-latin);
  margin-left: 5px; font-size: 12.5px; white-space: nowrap;
  transition: color .15s ease;
}
.post-body-link:hover .post-more { color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text)); }

/* ---- 画像（添付の "並び" に意図を持たせる） ---- */
.post-images { display: block; }
.post-images-grid {
  display: grid; gap: 4px; margin-bottom: 14px;
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--post-hair);
  grid-template-columns: 1fr;
}
.post-images-count-2,
.post-images-count-4 { grid-template-columns: 1fr 1fr; }
/* 3枚は "1枚大きく + 2枚積む" 雑誌的レイアウト。行高を固定してタイル高さを確定させる。 */
.post-images-count-3 {
  grid-template-columns: 1.5fr 1fr;
  grid-template-rows: 152px 152px;
}
.post-images-count-3 .post-image-tile:nth-child(1) { grid-row: 1 / span 2; }

/* タイル = クリック領域（ボタン）。グリッドセルを埋め、中の画像が cover で満たす。 */
.post-image-tile {
  position: relative; display: block; overflow: hidden;
  width: 100%; padding: 0; margin: 0; border: 0;
  background: color-mix(in oklab, var(--color-text) 6%, transparent);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
/* 複数枚は正方形タイルで均一化（どの枚数でも縦積みにならない）。 */
.post-images-count-2 .post-image-tile,
.post-images-count-4 .post-image-tile { aspect-ratio: 1 / 1; }
/* 1枚は自然な縦横比で最大 460px。 */
.post-images-count-1 .post-image-tile { max-height: 460px; }
.post-image {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform .4s var(--post-ease), filter .2s ease;
}
.post-images-count-1 .post-image { height: auto; max-height: 460px; }
.post-image-tile:hover .post-image { filter: brightness(.93); transform: scale(1.015); }
.post-image-tile:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 3px color-mix(in oklab, var(--color-accent) 55%, transparent);
}
/* +N オーバーレイ（5枚以上のとき4枚目に残数を重ねる） */
.post-image-tile.is-more .post-image { filter: brightness(.45); }
.post-image-more {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-family: var(--font-latin); font-weight: 600;
  font-size: 26px; letter-spacing: .02em; pointer-events: none;
}

/* タイムライン画像ライトボックス（画面遷移せず拡大表示） */
.tl-lightbox {
  position: fixed; inset: 0; z-index: 1000;
  display: none; align-items: center; justify-content: center;
}
.tl-lightbox.is-open { display: flex; }
.tl-lightbox-backdrop {
  position: absolute; inset: 0;
  background: rgba(12, 11, 16, 0.9);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.tl-lightbox-fig { position: relative; margin: 0; max-width: 94vw; max-height: 90vh; z-index: 1; }
.tl-lightbox-img {
  display: block; max-width: 94vw; max-height: 90vh;
  object-fit: contain; border-radius: 8px;
  box-shadow: 0 24px 80px -20px rgba(0,0,0,.7);
}
.tl-lightbox-btn {
  position: absolute; display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 0; border-radius: 999px;
  background: rgba(20,18,26,.55); color: #fff; cursor: pointer; z-index: 2;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: background .15s ease, transform .1s ease;
}
.tl-lightbox-btn:hover { background: rgba(20,18,26,.85); }
.tl-lightbox-close { top: -54px; right: 0; }
.tl-lightbox-prev { left: 8px; top: 50%; transform: translateY(-50%); }
.tl-lightbox-next { right: 8px; top: 50%; transform: translateY(-50%); }
/* 押下フィードバックはボタンごとに用意する。prev/next は translateY(-50%) を保ったまま
   ごく僅かに縮めるだけにする（汎用の :active{scale} だと translateY が消えて下に落ちる）。 */
.tl-lightbox-close:active { transform: scale(.96); }
.tl-lightbox-prev:active { transform: translateY(-50%) scale(.97); }
.tl-lightbox-next:active { transform: translateY(-50%) scale(.97); }
.tl-lightbox-count {
  position: absolute; bottom: -38px; left: 50%; transform: translateX(-50%);
  color: rgba(255,255,255,.85); font-family: var(--font-latin);
  font-variant-numeric: tabular-nums; font-size: 13px; letter-spacing: .04em;
}
.tl-lightbox[data-single="1"] .tl-lightbox-prev,
.tl-lightbox[data-single="1"] .tl-lightbox-next,
.tl-lightbox[data-single="1"] .tl-lightbox-count { display: none; }
@media (max-width: 768px) {
  .tl-lightbox-close { top: -48px; }
  .tl-lightbox-prev { left: 4px; }
  .tl-lightbox-next { right: 4px; }
}
@media (prefers-reduced-motion: reduce) {
  .post-image-tile:hover .post-image { transform: none; }
}
.post-detail-images { display: flex; flex-direction: column; gap: 12px; margin: 18px 0 6px; }
.post-detail-image {
  width: 100%; max-height: 72vh; object-fit: contain;
  border-radius: var(--radius);
  border: 1px solid var(--post-hair);
  background: var(--post-quiet);
  display: block;
}

/* ---- カードフッター ---- */
.post-card-foot, .post-detail-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-top: 4px; flex-wrap: wrap;
}
.post-detail-foot {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--post-hair);
}
.comment-count-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--color-muted); text-decoration: none;
  font-family: var(--font-latin); font-size: 13px;
  padding: 4px 6px; border-radius: 8px;
  transition: color .15s ease, background .15s ease;
}
.comment-count-link:hover { color: var(--color-text); background: var(--post-quiet); }
.comment-count-link svg { width: 17px; height: 17px; }
.comment-count-link .comment-count { font-variant-numeric: tabular-nums; }

/* sprint-21-A: 件数を「詳細リンク」から「インライン開閉トグル」へ。見た目は従来のリンクと地続き。 */
.comment-count-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--color-muted); background: transparent;
  border: none; cursor: pointer;
  font-family: var(--font-latin); font-size: 13px;
  padding: 4px 8px; border-radius: 8px;
  transition: color .15s ease, background .15s ease;
}
.comment-count-toggle:hover { color: var(--color-text); background: var(--post-quiet); }
.comment-count-toggle:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--color-accent) 55%, transparent);
  outline-offset: 2px;
}
.comment-count-toggle svg {
  width: 17px; height: 17px;
  transition: transform .15s var(--post-ease, ease);
}
.comment-count-toggle[aria-expanded="true"] {
  color: color-mix(in oklab, var(--color-accent) 50%, var(--color-text));
  background: color-mix(in oklab, var(--color-accent) 9%, var(--post-quiet));
}
.comment-count-toggle[aria-expanded="true"] svg {
  transform: translateY(-1px);
  fill: color-mix(in oklab, var(--color-accent) 14%, transparent);
}
.comment-count-toggle .comment-count { font-variant-numeric: tabular-nums; }

/* sprint-21-A: カード直下のインラインコメント領域。
   「カードから引き出した会話トレイ」として、本文より一段沈んだ recessed 面に置く。
   詳細ページのトーン（.comment-list / .comment-item）を流用しつつ、上端の細い仕切り＋
   トレイ内側に落ちる淡い影で “引き出しが開いた” 階層を作る。開閉でレイアウトは飛ばない。 */
.post-comments {
  /* カード左右パディング分（22px）だけ外側へ広げ、トレイをカードの縁まで届かせる。
     カード下端は radius-lg なので、トレイ下角もそれに合わせて丸める。 */
  margin: 16px -22px -20px;
  padding: 16px 22px 18px;
  border-top: 1px solid var(--post-hair);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-text) 4%, var(--color-card)),
      color-mix(in oklab, var(--color-text) 2.5%, var(--color-card)) 120px);
  box-shadow: inset 0 7px 10px -10px color-mix(in oklab, var(--color-text) 22%, transparent);
  border-radius: 0 0 var(--radius-lg, var(--radius)) var(--radius-lg, var(--radius));
}
/* オーナー投稿カードのトレイは温かみのトーンに寄せる（左ライン世界観と地続き） */
.post-card-owner .post-comments {
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--owner-tint) 70%, var(--color-card)),
      var(--color-card) 120px);
  border-top-color: var(--owner-line);
}
.post-comments[hidden] { display: none; }
/* 初回展開時のなめらかな立ち上がり（JS は hidden を外すだけ。CSS で受ける）。 */
.post-comments:not([hidden]) {
  animation: post-comments-reveal .26s var(--post-ease, cubic-bezier(.22,.61,.36,1)) both;
}
@keyframes post-comments-reveal {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.post-comments .post-comments-list { margin: 0 0 14px; }
.post-comments .post-comments-list:empty { margin-bottom: 0; }
/* トレイ内ではアバターのリングをトレイ面に馴染ませ、会話の背骨を主役にする */
.post-comments .comment-avatar { box-shadow: 0 0 0 3px var(--color-card); }
.post-comments-status {
  color: var(--color-muted);
  font-family: var(--font-display); font-style: italic;
  font-size: 13px;
  padding: 2px 2px 12px;
}
.post-comments-status[hidden] { display: none; }
.post-comments-error {
  margin: 8px 2px 0;
  color: var(--color-danger, #c0392b);
  font-size: 12.5px; line-height: 1.5;
  font-weight: 500;
}
.post-comments-error[hidden] { display: none; }
.post-comments .comment-submit:disabled { opacity: .55; cursor: default; transform: none; }

/* sprint-21-A: トレイ内 composer。recessed なトレイ面の上で “書く場所” が一段持ち上がって
   見えるよう card 面＋淡い影で浮かせ、リスト末尾と一定の間隔を保つ。 */
.post-comments .comment-form {
  margin-top: 2px;
  box-shadow: 0 1px 2px color-mix(in oklab, var(--color-text) 6%, transparent);
}
.post-comments .post-comments-list:empty + .comment-form { margin-top: 2px; }
.post-comments .comment-textarea { min-height: 34px; line-height: 1.55; }

/* sprint-21-B: 「もっと見る」（古い方向ページング）。コメント列の上端に控えめに置く。
   会話の背骨と同じ中心線へ寄せ、押下後の prepend でスクロールが大きく飛ばないよう小さく保つ。 */
.post-comments-more {
  display: flex; justify-content: center;
  margin: 0 0 10px;
}
.post-comments-more[hidden] { display: none; }
.comments-more-btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--color-card);
  border: 1px solid var(--post-hair);
  border-radius: 999px;
  padding: 5px 16px;
  font: inherit; font-size: 12.5px; letter-spacing: .01em;
  color: var(--color-text-dim);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s var(--post-ease), border-color .18s ease,
              color .18s ease, box-shadow .18s ease;
}
.comments-more-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  border-color: color-mix(in oklab, var(--color-accent) 40%, var(--post-hair));
  color: var(--color-text);
  box-shadow: 0 3px 10px -7px color-mix(in oklab, var(--color-text) 40%, transparent);
}
.comments-more-btn:active:not(:disabled) { transform: scale(.97); }
.comments-more-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 28%, transparent);
}
.comments-more-btn:disabled { opacity: .6; cursor: default; }
.comments-more-spinner { display: none; width: 13px; height: 13px; }
.comments-more-btn.is-loading .comments-more-label { opacity: .55; }
.comments-more-btn.is-loading .comments-more-spinner {
  display: inline-block;
  border: 2px solid color-mix(in oklab, var(--color-text) 18%, transparent);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: comments-spin .7s linear infinite;
}
@keyframes comments-spin { to { transform: rotate(360deg); } }

/* sprint-21-B: 行内アクション（削除 / 通報）。
   会話の流れを乱さないよう、平常時はほぼ気配だけ（薄い・小さく沈める）。
   行 hover / フォーカスで初めて立ち上がり、意図が伝わる。head ベースラインに揃え、
   bubble 上端に浮かないようにする。既存 delete_control / report_button のトーンを踏襲。 */
.comment-actions {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 1px;
  flex: 0 0 auto;
  margin-right: -2px;      /* bubble 右パディングへ少し寄せて行内に収める */
  margin-top: -6px; margin-bottom: -6px; /* 26px のタップ域で head 行を広げない */
}
.comment-actions .comment-delete-btn,
.comment-actions .comment-report-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  font: inherit; line-height: 1;
  color: color-mix(in oklab, var(--color-muted) 70%, transparent);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  opacity: .28;
  transform: scale(.92);
  transition: opacity .18s ease, color .16s ease, background .16s ease,
              border-color .16s ease, transform .18s var(--post-ease, ease);
}
/* 行に触れた / 行内のどこかにフォーカスが入ったときだけ、アクションが立ち上がる。 */
.comment-item:hover .comment-actions .comment-delete-btn,
.comment-item:hover .comment-actions .comment-report-btn,
.comment-item:focus-within .comment-actions .comment-delete-btn,
.comment-item:focus-within .comment-actions .comment-report-btn {
  opacity: .85;
  transform: scale(1);
}
.comment-actions .comment-delete-btn .del-ic,
.comment-actions .comment-report-btn .report-ic { width: 15px; height: 15px; }
.comment-actions .comment-delete-btn .del-label,
.comment-actions .comment-report-btn .report-label {
  /* ラベルは視覚的には隠し、アイコンで意図を伝える（aria-label が読み上げを担う）。 */
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.comment-actions .comment-delete-btn:hover,
.comment-actions .comment-delete-btn:focus-visible {
  opacity: 1;
  color: var(--color-danger, #c0392b);
  background: color-mix(in oklab, var(--color-danger, #c0392b) 11%, transparent);
}
.comment-actions .comment-report-btn:hover,
.comment-actions .comment-report-btn:focus-visible {
  opacity: 1;
  color: color-mix(in oklab, var(--color-text) 78%, var(--color-muted));
  background: color-mix(in oklab, var(--color-text) 8%, transparent);
}
/* キーボードで直接ターゲットした行内アクションは最前面（full opacity）＋アクセントリング。
   focus-within の .85 を上書きできるよう .comment-item を前置して優先度を上げる。 */
.comment-item .comment-actions .comment-delete-btn:focus-visible,
.comment-item .comment-actions .comment-report-btn:focus-visible {
  outline: none;
  opacity: 1;
  transform: scale(1);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 24%, transparent);
}
.comment-actions .comment-delete-btn:disabled { opacity: .35; cursor: default; transform: scale(.92); }
/* タッチ端末（hover が効かない）では hover で立ち上げられないため、常時しっかり見せて
   確実にタップできるようにする（ただし会話を圧迫しない控えめなグレー）。 */
@media (hover: none) {
  .comment-actions .comment-delete-btn,
  .comment-actions .comment-report-btn {
    opacity: 1; transform: scale(1);
    color: color-mix(in oklab, var(--color-muted) 92%, transparent);
  }
  .comment-actions .comment-delete-btn:active {
    color: var(--color-danger, #c0392b);
    background: color-mix(in oklab, var(--color-danger, #c0392b) 12%, transparent);
  }
  .comment-actions .comment-report-btn:active {
    background: color-mix(in oklab, var(--color-text) 8%, transparent);
  }
}
/* 削除進行中はその行を静かに沈める。 */
.comment-item.is-deleting { opacity: .5; pointer-events: none; transition: opacity .18s ease; }
.comment-count-label {
  color: var(--color-muted);
  font-family: var(--font-latin); font-size: 12.5px; letter-spacing: 0.02em;
}
.comment-count-label .comment-count {
  color: var(--color-text); font-weight: 600; font-variant-numeric: tabular-nums;
}

/* ---- リアクション（ワンタップで気持ちよく押せる一拍） ---- */
.reaction-bar { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }
.reaction-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--post-quiet);
  border: 1px solid var(--post-hair);
  border-radius: 999px;
  padding: 6px 13px 6px 11px;
  min-height: 34px;
  font: inherit; font-size: 13px;
  color: var(--color-text-dim);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s var(--post-ease), background .18s ease,
              border-color .18s ease, color .18s ease, box-shadow .18s ease;
}
.reaction-btn:hover:not([disabled]) {
  transform: translateY(-1.5px);
  border-color: color-mix(in oklab, var(--color-accent) 45%, var(--post-hair));
  color: var(--color-text);
}
.reaction-btn:active:not([disabled]) { transform: scale(.93); }
.reaction-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 30%, transparent);
}
.reaction-btn[disabled] { opacity: .5; cursor: not-allowed; }
.reaction-btn.is-active {
  background: var(--post-warm);
  border-color: color-mix(in oklab, var(--color-accent) 60%, transparent);
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text));
  font-weight: 600;
  box-shadow: 0 4px 12px -6px color-mix(in oklab, var(--color-accent) 60%, transparent);
}
.reaction-btn.is-active .reaction-emoji { animation: reaction-pop .34s var(--post-ease); }
@keyframes reaction-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.42) rotate(-8deg); }
  70%  { transform: scale(.92); }
  100% { transform: scale(1); }
}
.reaction-emoji { font-size: 16px; line-height: 1; display: inline-block; }
.reaction-count {
  font-family: var(--font-latin);
  font-variant-numeric: tabular-nums;
  font-size: 12.5px;
  min-width: 9px; text-align: center;
}
.reaction-btn { position: relative; }
.reaction-fx {
  position: absolute;
  left: 13px; top: 4px;
  font-size: 16px;
  pointer-events: none;
  animation: reaction-float .65s var(--post-ease) forwards;
}
@keyframes reaction-float {
  0%   { opacity: 0; transform: translateY(0) scale(.8); }
  25%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-26px) scale(1.15); }
}

/* ---- 集約コンパクト版（sprint-20）: 0 件の絵文字は隠し、「追加」ボタンから付ける ---- */
.reaction-bar--compact { gap: 6px; }
/* 追加ボタン（笑顔＋） */
.reaction-add-wrap { position: relative; display: inline-flex; }
.reaction-add {
  display: inline-flex; align-items: center; justify-content: center; gap: 1px;
  height: 34px; padding: 0 9px 0 8px;
  background: var(--post-quiet);
  border: 1px solid var(--post-hair);
  border-radius: 999px;
  color: var(--color-text-dim);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s var(--post-ease), background .18s ease, border-color .18s ease, color .18s ease;
}
.reaction-add svg { width: 19px; height: 19px; }
.reaction-add-plus { font-size: 13px; font-weight: 700; line-height: 1; margin-bottom: 1px; }
.reaction-add:hover {
  transform: translateY(-1.5px);
  border-color: color-mix(in oklab, var(--color-accent) 45%, var(--post-hair));
  color: var(--color-text);
}
.reaction-add:active { transform: scale(.93); }
.reaction-add:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 30%, transparent);
}
.reaction-add[aria-expanded="true"] {
  background: var(--post-warm);
  border-color: color-mix(in oklab, var(--color-accent) 55%, transparent);
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text));
}
/* ピッカー（小さなポップオーバー） */
.reaction-picker {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  display: flex;
  gap: 2px;
  padding: 5px;
  background: var(--paper-elev, #fff);
  border: 1px solid var(--post-hair);
  border-radius: 999px;
  box-shadow: 0 10px 30px -10px color-mix(in oklab, var(--color-text) 30%, transparent);
  z-index: 30;
  animation: reaction-picker-in .14s var(--post-ease);
}
.reaction-picker[hidden] { display: none; }
@keyframes reaction-picker-in {
  from { opacity: 0; transform: translateY(4px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.reaction-pick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border: none; background: transparent;
  border-radius: 999px;
  font-size: 19px; line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s var(--post-ease), background .15s ease;
}
.reaction-pick:hover { background: var(--post-quiet); transform: scale(1.12); }
.reaction-pick:active { transform: scale(.92); }
.reaction-pick:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 30%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .reaction-picker { animation: none; }
  .reaction-pick:hover { transform: none; }
}
/* スマホ: チップ・追加ボタンを一回り小さくして 1 行に収める */
@media (max-width: 768px) {
  .reaction-bar--compact { gap: 5px; }
  .reaction-bar--compact .reaction-btn {
    min-height: 30px;
    padding: 4px 10px 4px 9px;
    gap: 4px;
    font-size: 12.5px;
  }
  .reaction-bar--compact .reaction-emoji { font-size: 15px; }
  .reaction-add { height: 30px; padding: 0 8px; }
  .reaction-add svg { width: 18px; height: 18px; }
}

/* ---- 空状態（冷たくない "余白に置かれた招き"） ---- */
.timeline-empty {
  text-align: center;
  color: var(--color-muted);
  padding: 56px 22px 60px;
  border: 1px dashed color-mix(in oklab, var(--color-line) 78%, var(--color-accent) 22%);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 90% at 50% -10%,
      var(--post-warm) 0%, transparent 60%),
    var(--color-card);
}
.timeline-empty .sigil {
  width: 44px; height: 44px;
  color: var(--color-accent);
  opacity: .55; margin-bottom: 16px;
  animation: empty-breathe 5.5s ease-in-out infinite;
}
@keyframes empty-breathe {
  0%, 100% { opacity: .42; transform: scale(1); }
  50%      { opacity: .62; transform: scale(1.05); }
}
.timeline-empty .lead-line {
  font-family: var(--font-display);
  font-size: 17px; letter-spacing: 0.06em;
  color: var(--color-text); margin: 0 0 6px;
}
.timeline-empty .meta {
  font-family: var(--font-display); font-style: italic;
  font-size: 13px; margin: 0; color: var(--color-muted);
}

/* ---- もっと見る ---- */
.timeline-more { text-align: center; margin: 26px 0 6px; }
.more-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--color-line);
  border-radius: 999px;
  padding: 9px 26px;
  color: var(--color-text-dim);
  font-family: var(--font-latin);
  text-decoration: none;
  font-size: 12.5px; letter-spacing: 0.04em;
  background: var(--color-card);
  transition: border-color .18s ease, color .18s ease, background .18s ease;
}
.more-btn:hover {
  border-color: color-mix(in oklab, var(--color-accent) 50%, var(--color-line));
  color: var(--color-text);
  background: var(--post-warm);
}
/* SPA 風ページネーション: 取得中はボタンを無効化しつつスピナーを出す。 */
.more-btn.is-loading {
  pointer-events: none;
  opacity: 0.7;
}
.more-btn.is-loading::after {
  content: "";
  width: 13px; height: 13px;
  border: 2px solid color-mix(in oklab, var(--color-text-dim) 45%, transparent);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: more-spin .7s linear infinite;
}
@keyframes more-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .more-btn.is-loading::after { animation: none; }
}
.timeline-more-error {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--color-danger);
}

/* ---- コメント（スレッド型の片鱗 / 会話の積み上がり） ---- */
.comments { margin-top: 30px; }
.comment-list {
  list-style: none; padding: 0; margin: 0 0 22px;
  display: flex; flex-direction: column; gap: 2px;
  position: relative;
}
/* 縦の "会話の背骨"：アバター中心を貫く細い線 */
.comment-list::before {
  content: "";
  position: absolute;
  left: 17px; top: 18px; bottom: 18px;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--post-hair) 12%, var(--post-hair) 88%, transparent);
}
.comment-item {
  display: flex; gap: 12px;
  padding: 8px 0;
  position: relative;
}
.comment-avatar {
  position: relative; z-index: 1;
  box-shadow: 0 0 0 3px var(--color-card);
}
.comment-bubble {
  background: var(--post-quiet);
  border: 1px solid var(--post-hair);
  border-radius: 4px 14px 14px 14px;
  padding: 10px 14px 11px;
  flex: 1;
  min-width: 0;
}
.comment-head { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.comment-name { font-weight: 600; font-size: 13px; }
.comment-head .comment-time { margin-top: 1px; }
.comment-head .comment-delete-btn { margin-left: auto; }
.comment-body {
  margin: 0; font-size: 14px; line-height: 1.7;
  color: color-mix(in oklab, var(--color-text) 92%, var(--color-muted));
  word-break: break-word;
}
.empty-line {
  font-family: var(--font-display); font-style: italic;
  color: var(--color-muted); font-size: 13.5px;
  padding: 10px 2px 18px;
}
.comment-form {
  display: flex; gap: 10px; align-items: flex-end;
  background: var(--color-card);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 10px 12px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.comment-form:focus-within {
  border-color: color-mix(in oklab, var(--color-accent) 55%, var(--color-line));
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-accent) 10%, transparent);
}
.comment-textarea {
  flex: 1; resize: vertical; min-height: 38px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--color-text);
  padding: 4px 4px; font: inherit; line-height: 1.6;
}
.comment-textarea:focus { outline: none; }
.comment-textarea::placeholder {
  color: var(--color-muted);
  font-family: var(--font-display); font-style: italic;
}
.comment-submit {
  background: var(--color-accent); color: #fff; border: none;
  border-radius: 999px; padding: 8px 20px; font: inherit;
  font-weight: 600; font-size: 13.5px; cursor: pointer;
  flex: 0 0 auto;
  box-shadow: 0 6px 16px -8px color-mix(in oklab, var(--color-accent) 70%, transparent);
  transition: transform .12s var(--post-ease), filter .15s ease;
}
.comment-submit:hover { filter: brightness(1.05); transform: translateY(-1px); }
.comment-submit:active { transform: translateY(0) scale(.98); }

@media (max-width: 640px) {
  .timeline-head { flex-direction: column; align-items: stretch; gap: 6px; }
  .timeline-title { font-size: 21px; }
  .timeline-sub { text-align: left; max-width: none; }
  .post-card { padding: 16px 16px; }
  .post-detail { padding: 18px 16px; }
  /* sprint-20: ギャラリーはタイル(aspect-ratio / 固定行)で高さが決まるため、
     旧 .post-image の min-height 上書きは不要（むしろ aspect 比率と競合するので撤去）。
     3枚レイアウトの行高だけ狭い画面向けに少し詰める。 */
  .post-images-count-3 { grid-template-rows: 124px 124px; }
  .comment-form { flex-wrap: wrap; }
  .comment-textarea { flex: 1 1 100%; }
  .comment-submit { margin-left: auto; }
  /* sprint-21-A: 狭い画面のカードは padding 16px。トレイの食い込み量を合わせる。 */
  .post-comments { margin: 14px -16px -16px; padding: 14px 16px 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .post-comments:not([hidden]) { animation: none; }
  .timeline-empty .sigil { animation: none; }
  .reaction-btn.is-active .reaction-emoji { animation: none; }
  .composer-preview { animation: none; }
  /* Sprint 18-A: ドラッグ&ドロップ周りの動きを抑制 */
  .composer,
  .composer::before,
  .composer.is-dragover,
  .composer-attach-hint,
  .composer-attach-hint-icon { transition: none !important; }
  .composer.is-dragover { transform: none; }
  .composer:hover .composer-attach-hint-icon,
  .composer:focus-within .composer-attach-hint-icon,
  .composer.is-dragover .composer-attach-hint-icon { animation: none; }
}

/* モバイルでの D&D ヒント調整（実機 D&D は OS が支援しないが、表示の破綻だけは防ぐ） */
@media (max-width: 560px) {
  .composer-attach { flex-wrap: wrap; row-gap: 4px; }
  .composer-attach-hint {
    margin-left: 0;
    padding-left: 0;
    border-left: none;
    width: 100%;
  }
  .composer.is-dragover {
    /* モバイル幅では radius を僅かに緩めて破線 SVG の角が綺麗に出るように */
    background-size: 100% 100%;
  }
}

/* ============================================================
   Sprint 8.2 — 投稿権限のない状態（composer-locked）
   ------------------------------------------------------------
   Tone: タイムライン限定公開を撤去し、投稿可否はロールで決まる。
   投稿できないユーザーには空白でも赤いエラーでもなく、
   「いまは灯りを置く側ではない／でも在席はしている」という
   静かな在り方を示す。空状態（.timeline-empty）の語彙を継ぎ、
   権威ではなく moss の落ち着きで "閉じた席" を表す。
   既存の蝋封/印章と同じ琥珀ではなく、moss 寄りにして
   「自分の不足」ではなく「役割の違い」として読ませる。
   ------------------------------------------------------------ */
.composer-locked {
  /* .composer の枠は活かしつつ、入力可能な席ではないと分かる地に変える */
  padding: 30px 26px 32px;
  text-align: center;
  border-style: dashed;
  border-color: color-mix(in oklab, var(--color-line) 74%, var(--moss-600) 26%);
  background:
    radial-gradient(125% 96% at 50% -12%,
      color-mix(in oklab, var(--moss-600) 7%, transparent) 0%, transparent 62%),
    var(--color-card);
}
.composer-locked:focus-within {
  /* 入力欄が無いので focus リング（琥珀）を継がせない */
  border-color: color-mix(in oklab, var(--color-line) 74%, var(--moss-600) 26%);
  box-shadow: var(--shadow-sm);
}
.composer-locked-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  max-width: 46ch;
  margin: 0 auto;
}
/* 鍵 = 拒絶の警報ではなく、静かに閉じた席の印章。moss の輪に納める */
.composer-locked-body > svg {
  width: 26px; height: 26px;
  flex: 0 0 auto;
  margin-bottom: 13px;
  padding: 11px;
  box-sizing: content-box;
  border-radius: 50%;
  color: color-mix(in oklab, var(--moss-600) 72%, var(--color-text));
  background: color-mix(in oklab, var(--moss-600) 9%, var(--color-card));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--moss-600) 26%, var(--color-line));
  animation: composer-locked-breathe 6s ease-in-out infinite;
}
@keyframes composer-locked-breathe {
  0%, 100% { opacity: .82; }
  50%      { opacity: 1; }
}
.composer-locked-title {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  /* 20-A: ゴシック化に合わせ字間を締める */
  letter-spacing: 0.02em;
  color: var(--color-text);
  margin: 0 0 4px;
}
.composer-locked-hint {
  font-size: 13px;
  line-height: 1.8;
  color: var(--color-muted);
  margin: 0;
  text-wrap: pretty;
}
/* 「壊れている」ではなく「役割の違い」と伝えるため、
   使える機能（フォーラム / コメント・リアクション）を moss の小さなチップで添える。
   席を取り上げられたのではなく、別の場所では声を出せると分かる。 */
.composer-locked-can {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 7px;
  margin: 15px 0 0;
  padding: 0;
  list-style: none;
}
.composer-locked-can li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px 5px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: color-mix(in oklab, var(--moss-600) 40%, var(--color-text));
  background: color-mix(in oklab, var(--moss-600) 8%, var(--color-card));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--moss-600) 24%, var(--color-line));
}
.composer-locked-can svg {
  width: 14px; height: 14px;
  flex: 0 0 auto;
  color: color-mix(in oklab, var(--moss-600) 62%, var(--color-text));
}
@media (prefers-reduced-motion: reduce) {
  .composer-locked-body > svg { animation: none; }
}

/* ------------------------------------------------------------
   マイページ — 付与ロールのチップ
   既存チケットチップ（印章ピル）と地続きに。特権は moss で差をつける。
   ------------------------------------------------------------ */
.mypage-role-list {
  list-style: none;
  padding: 0; margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* 1 ロール = [pill] + 「チケット由来」。dd 幅が足りなければ内部で折り返し、
   pill 自体は 1 行を保ったまま「チケット由来」だけが次行へ回る（はみ出し防止）。 */
.mypage-role-item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: 100%;
  flex-wrap: wrap;
}
.mypage-role-chip {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 13px 6px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%);
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-paper) 95%);
  line-height: 1.3;
  max-width: 100%;
}
/* 特権ロール（全投稿閲覧）は moss 寄りに：運営の落ち着いた権威 */
.mypage-role-chip:has(.mypage-role-badge) {
  border-color: color-mix(in oklab, var(--moss-600) 34%, var(--color-line));
  background: color-mix(in oklab, var(--moss-600) 8%, var(--color-paper));
}
.mypage-role-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
  white-space: nowrap;
}
.mypage-role-badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 9px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--moss-600) 50%, var(--color-text));
  background: color-mix(in oklab, var(--moss-600) 16%, transparent);
  border: 1px solid color-mix(in oklab, var(--moss-600) 32%, transparent);
  white-space: nowrap;
}
.mypage-role-source {
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--color-muted);
  padding-left: 9px;
  margin-left: 1px;
  border-left: 1px solid color-mix(in oklab, var(--color-accent) 24%, var(--color-line) 76%);
  white-space: nowrap;
}

/* ============================================================
   Sprint 4 — 管理画面: ロール一覧テーブルの脱 Bootstrap
   業務系・白基調を保ちつつ、原色バッジ・重い罫線を排除する。
   ============================================================ */
.card-panel table.table {
  --bs-table-bg: transparent;
  margin: 0;
  border-collapse: collapse;
  font-size: 13.5px;
  color: var(--color-text);
}
.card-panel table.table > thead > tr > th {
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  border: 0;
  border-bottom: 1px solid var(--line-strong);
  padding: 0 14px 11px;
  background: transparent;
  white-space: nowrap;
}
.card-panel table.table > tbody > tr {
  border: 0;
  transition: background .15s ease;
}
.card-panel table.table > tbody > tr + tr > td {
  border-top: 1px solid color-mix(in oklab, var(--line) 70%, transparent);
}
.card-panel table.table > tbody > tr:hover {
  background: color-mix(in oklab, var(--color-accent) 4%, transparent);
}
.card-panel table.table > tbody > tr > td {
  border: 0;
  padding: 15px 14px;
  vertical-align: middle;
  background: transparent;
  box-shadow: none;
}
.card-panel table.table td.text-muted {
  color: var(--text-dim);
  font-size: 13px;
}
/* slug は dark ピルではなく、地に馴染む薄い印字に */
.card-panel table.table td code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--text-dim);
  background: color-mix(in oklab, var(--color-text) 5%, var(--color-paper));
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 2px 8px;
}
.role-name {
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* 「初期」バッジ — Bootstrap グレーを地の色のタグに置換 */
.card-panel .badge.text-bg-secondary {
  display: inline-flex;
  align-items: center;
  margin-left: 7px;
  padding: 2px 8px;
  border-radius: 5px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--muted) !important;
  background: color-mix(in oklab, var(--color-text) 6%, var(--color-paper)) !important;
  border: 1px solid var(--line);
}
/* 「全投稿閲覧」特権バッジ — 原色シアンを moss の落ち着いた権威に置換 */
.card-panel .badge.text-bg-info,
.badge[data-view-all-badge] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: color-mix(in oklab, var(--moss-600) 46%, var(--text)) !important;
  background: color-mix(in oklab, var(--moss-600) 14%, var(--color-paper)) !important;
  border: 1px solid color-mix(in oklab, var(--moss-600) 32%, transparent);
}
.badge[data-view-all-badge]::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--moss-600);
  flex: 0 0 auto;
}

/* ---- Sprint 13: カテゴリ管理テーブルの細部 ----
   カテゴリ名は本文よりわずかに格を上げ、ラウンジ数は 0 を静かに沈める
   （0 か 1+ かが一目で分かる）。原色は使わず既存トークン由来で。 */
.card-panel table.table td .category-name {
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--text);
}
.card-panel table.table td .category-lounge-count {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  color: var(--text-dim);
  font-size: 13px;
}
.card-panel table.table td .category-lounge-count b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.card-panel table.table td .category-lounge-count.is-empty {
  color: color-mix(in oklab, var(--muted) 78%, transparent);
}
.card-panel table.table td .category-lounge-count.is-empty b {
  color: var(--muted);
  font-weight: 500;
}

/* 操作セル — 3 つの outline ボタンを "静かなテキストリンク" 群に */
.card-panel table.table td.text-end {
  white-space: nowrap;
  text-align: right;
}
.card-panel table.table td.text-end .btn {
  --bs-btn-padding-y: 0;
  --bs-btn-padding-x: 0;
  display: inline-flex;
  align-items: center;
  margin-left: 14px;
  padding: 4px 2px;
  border: 0;
  background: none;
  box-shadow: none;
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.01em;
  color: var(--text-dim);
  border-radius: 0;
  transition: color .15s ease;
}
.card-panel table.table td.text-end .btn:first-child { margin-left: 0; }
.card-panel table.table td.text-end .btn:hover {
  background: none;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.card-panel table.table td.text-end .btn-outline-danger:hover {
  color: var(--color-danger);
}
/* 初期ロールの削除不可ボタンは、無効ボタンではなく南京錠の小印に */
.card-panel table.table td.text-end .btn[disabled] {
  color: color-mix(in oklab, var(--muted) 80%, transparent);
  cursor: not-allowed;
}
.card-panel table.table td.text-end .btn[disabled]:hover {
  text-decoration: none;
  color: color-mix(in oklab, var(--muted) 80%, transparent);
}

@media (max-width: 640px) {
  .composer-locked { padding: 26px 18px 28px; }
  .composer-locked-title { font-size: 16px; }
  .card-panel table.table td.text-end .btn { margin-left: 10px; }
}


/* ============================================================
   Sprint 5: サイト内通知（ベル + 通知一覧 + お知らせトグル）
   「しずかなラウンジ」のトーンに地続き。通知＝届く「便り」として、
   赤い警報ではなく "静かな灯り" に寄せる。すべて --color-* /
   --nav-* トークン経由でブランディングプリセットに追従。
   ------------------------------------------------------------ */
:root {
  /* 種別ごとの "印"（封蝋）色。プリセット非依存の落ち着いた色味 */
  --notif-comment: var(--moss-600);
  --notif-announce: var(--amber-700);
  --notif-owner: var(--clay-600);
  --notif-unread-rail: var(--color-accent);
}

/* --- ベル（app-brand 右端に常設） --- */
.app-brand { position: relative; }
.app-bell {
  position: relative;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 12px;
  color: var(--nav-text-dim, #9aa0a8);
  flex: 0 0 auto;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .18s ease, color .18s ease, transform .12s var(--post-ease, ease);
}
.app-bell:hover {
  background: color-mix(in oklab, var(--nav-text, #e6e8ec) 9%, transparent);
  color: var(--nav-text, #fff);
}
.app-bell:active { transform: scale(.92); }
.app-bell:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--nav-bg, #14161a), 0 0 0 4px color-mix(in oklab, var(--color-accent) 60%, transparent);
}
.app-bell svg {
  width: 21px; height: 21px;
  transition: transform .35s var(--post-ease, ease);
}
/* 未読があるとき、ベルだけほのかに灯す */
.app-bell.has-unread { color: var(--nav-text, #e6e8ec); }
.app-bell.has-unread:hover svg { animation: bell-swing .6s var(--post-ease, ease); }
@keyframes bell-swing {
  0%, 100% { transform: rotate(0); }
  20% { transform: rotate(11deg); }
  45% { transform: rotate(-8deg); }
  70% { transform: rotate(4deg); }
}
.app-bell-badge {
  position: absolute;
  top: 4px; right: 4px;
  min-width: 17px; height: 17px;
  padding: 0 4.5px;
  border-radius: 999px;
  background: var(--clay-600, #b65a4a);
  color: #fff;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 17px;
  text-align: center;
  letter-spacing: -0.02em;
  box-shadow: 0 0 0 2px var(--nav-bg, #14161a),
              0 1px 3px rgba(0,0,0,.35);
  animation: badge-arrive .42s var(--post-ease, ease) both;
}
@keyframes badge-arrive {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.18); }
  100% { transform: scale(1); opacity: 1; }
}

/* --- スマホ用ヘッダー帯（ベル到達性の確保） ---
   PC ではサイドナビにベルがあるので非表示。スマホでサイドナビが
   display:none になる帯域でだけ、固定ヘッダーとして出してベルを常設。 */
.app-mobilebar { display: none; }
@media (max-width: 1024px) {
  .app-mobilebar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    position: sticky;
    top: 0;
    z-index: 40;
    height: 54px;
    padding: 0 14px 0 16px;
    background: color-mix(in oklab, var(--nav-bg, var(--ink-900)) 92%, transparent);
    -webkit-backdrop-filter: saturate(140%) blur(10px);
    backdrop-filter: saturate(140%) blur(10px);
    border-bottom: 1px solid var(--nav-line, var(--ink-700));
    color: var(--nav-text, #e6e8ec);
  }
  .app-mobilebar-brand {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--nav-text, #e6e8ec);
    font-family: var(--font-display);
    font-size: 16px;
    letter-spacing: 0.06em;
    min-width: 0;
  }
  .app-mobilebar-brand:hover { color: var(--nav-text, #fff); }
  .app-mobilebar-brand svg,
  .app-mobilebar-brand img { width: 24px; height: 24px; flex: 0 0 auto; }
  .app-mobilebar-brand img:not(.brand-mark-img) { width: auto; max-height: 26px; }
  .app-mobilebar-brand span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* スマホのベルは少し小ぶりにして帯に馴染ませる */
  .app-bell-mobile { width: 42px; height: 42px; color: var(--nav-text, #e6e8ec); }
  .app-bell-mobile .app-bell-badge { box-shadow: 0 0 0 2px var(--nav-bg, var(--ink-900)), 0 1px 3px rgba(0,0,0,.4); }
}

/* --- 通知一覧（/notifications）— 静かな "便り" 棚 --- */
.notif-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--post-hair, var(--color-line));
}
.notif-head-main { display: flex; align-items: baseline; gap: 13px; flex-wrap: wrap; }
.notif-title {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 500;
  letter-spacing: 0.03em;
  margin: 0;
  line-height: 1;
}
.notif-unread-count {
  font-family: var(--font-latin);
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--color-text);
  background: color-mix(in oklab, var(--color-accent) 16%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-accent) 30%, transparent);
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.notif-read-all {
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--color-text-dim);
  background: none;
  border: 1px solid var(--post-hair, var(--color-line));
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  padding: 6px 13px;
  white-space: nowrap;
  flex: 0 0 auto;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.notif-read-all:hover {
  color: var(--color-text);
  border-color: var(--line-strong, var(--color-line));
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-card));
}

.notif-empty {
  text-align: center;
  padding: 72px 20px 76px;
  color: var(--color-muted);
}
.notif-empty svg {
  width: 46px; height: 46px;
  opacity: .42;
  margin-bottom: 16px;
  color: var(--color-accent);
}
.notif-empty p {
  margin: 4px 0;
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--color-text-dim);
  letter-spacing: 0.02em;
}
/* 「通知はありません」は契約上の正準文言。温かい見出しの裏に
   スクリーンリーダー向けに残す（視覚上は "今は、しずかです。" を主役に）。 */
.notif-empty-canonical {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.notif-empty-sub {
  font-family: var(--font-sans) !important;
  font-size: 13px !important;
  color: var(--color-muted) !important;
  line-height: 1.7;
  max-width: 26em;
  margin-left: auto;
  margin-right: auto;
  text-wrap: balance;
  word-break: auto-phrase;
}

.notif-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.notif-item {
  border-radius: 12px;
  animation: notif-in .4s var(--post-ease, ease) both;
}
.notif-item:nth-child(1) { animation-delay: .02s; }
.notif-item:nth-child(2) { animation-delay: .05s; }
.notif-item:nth-child(3) { animation-delay: .08s; }
.notif-item:nth-child(4) { animation-delay: .11s; }
.notif-item:nth-child(5) { animation-delay: .14s; }
@keyframes notif-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.notif-row {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 13px;
  width: 100%;
  padding: 14px 16px 14px 15px;
  text-align: left;
  background: var(--color-card);
  border: 1px solid var(--post-hair, var(--color-line));
  border-radius: 12px;
  cursor: pointer;
  color: inherit;
  font: inherit;
  transition: border-color .18s ease, background .18s ease,
              transform .12s var(--post-ease, ease), box-shadow .2s ease;
}
.notif-row:hover {
  border-color: var(--line-strong, var(--color-line));
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.notif-row:active { transform: translateY(0) scale(.995); }
.notif-row.notif-row-notarget { cursor: default; }
.notif-row.notif-row-notarget:hover { transform: none; box-shadow: none; }

/* 未読: 左に "栞" の帯 + ほのかな温かみ */
.notif-item.is-unread .notif-row {
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-card));
  border-color: color-mix(in oklab, var(--color-accent) 26%, var(--post-hair));
  padding-left: 18px;
}
.notif-item.is-unread .notif-row::before {
  content: "";
  position: absolute;
  left: 0; top: 12px; bottom: 12px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--notif-unread-rail);
}
/* 既読: トーンを落として静かに */
.notif-item.is-read .notif-row { background: transparent; }
.notif-item.is-read .notif-summary { color: var(--color-text-dim); }
.notif-item.is-read .notif-icon { opacity: .68; }

.notif-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 11px;
  flex: 0 0 auto;
  margin-top: 1px;
  background: color-mix(in oklab, var(--color-text) 5%, var(--color-card));
  color: var(--color-text-dim);
  border: 1px solid var(--post-hair, var(--color-line));
}
.notif-icon svg { width: 19px; height: 19px; }
.notif-icon-announcement {
  color: var(--notif-announce);
  background: color-mix(in oklab, var(--notif-announce) 14%, var(--color-card));
  border-color: color-mix(in oklab, var(--notif-announce) 30%, transparent);
}
.notif-icon-comment_received {
  color: var(--notif-comment);
  background: color-mix(in oklab, var(--notif-comment) 14%, var(--color-card));
  border-color: color-mix(in oklab, var(--notif-comment) 30%, transparent);
}
.notif-icon-owner_post {
  color: var(--notif-owner);
  background: color-mix(in oklab, var(--notif-owner) 14%, var(--color-card));
  border-color: color-mix(in oklab, var(--notif-owner) 30%, transparent);
}
.notif-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.notif-type-label {
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--color-muted);
  letter-spacing: 0.08em;
}
.notif-item.is-unread .notif-type-label { color: var(--notif-unread-rail); }
.notif-summary {
  font-size: 14px;
  line-height: 1.55;
  color: var(--color-text);
  word-break: break-word;
}
.notif-time {
  font-family: var(--font-latin);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--color-muted);
  margin-top: 1px;
}
.notif-dot {
  align-self: center;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--notif-unread-rail);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--notif-unread-rail) 18%, transparent);
  flex: 0 0 auto;
  margin-left: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .notif-item, .app-bell-badge { animation: none; }
  .app-bell.has-unread:hover svg { animation: none; }
  .notif-row:hover { transform: none; }
}

/* --- 投稿フォーム: お知らせトグル（運営のみ表示・スイッチ UI） --- */
.composer-announce {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 14px;
  margin-top: 10px;
  border: 1px solid color-mix(in oklab, var(--notif-announce, var(--amber-700)) 28%, var(--post-hair));
  border-radius: 12px;
  background: color-mix(in oklab, var(--notif-announce, var(--amber-700)) 4%, var(--color-card));
  font-size: 13px;
  color: var(--color-text-dim);
  cursor: pointer;
  user-select: none;
  transition: border-color .2s ease, background .2s ease;
}
/* 実チェックボックスは隠し、ラベル内のスイッチで表現 */
.composer-announce input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  margin: -1px;
  pointer-events: none;
}
.composer-announce > svg {
  width: 18px; height: 18px;
  color: var(--notif-announce, var(--amber-700));
  flex: 0 0 auto;
  transition: transform .3s var(--post-ease, ease);
}
.composer-announce span { flex: 1; min-width: 0; line-height: 1.4; }
/* トグルスイッチ（::before/::after を input の次の svg ではなくラベル末尾に） */
.composer-announce::after {
  content: "";
  flex: 0 0 auto;
  width: 38px; height: 22px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--color-text) 16%, var(--color-card));
  border: 1px solid var(--post-hair, var(--color-line));
  background-image: radial-gradient(circle 8px at 12px center,
                    var(--color-card) 98%, transparent);
  transition: background-color .22s var(--post-ease, ease),
              background-position .22s var(--post-ease, ease);
  background-repeat: no-repeat;
}
/* ON 状態：枠と地色を温め、ノブを右へ */
.composer-announce:has(input:checked) {
  border-color: color-mix(in oklab, var(--notif-announce, var(--amber-700)) 55%, transparent);
  background: color-mix(in oklab, var(--notif-announce, var(--amber-700)) 9%, var(--color-card));
  color: var(--color-text);
}
.composer-announce:has(input:checked) > svg { transform: rotate(-12deg) scale(1.06); }
.composer-announce:has(input:checked)::after {
  background-color: var(--notif-announce, var(--amber-700));
  background-position: 16px 0;
}
.composer-announce:hover {
  border-color: color-mix(in oklab, var(--notif-announce, var(--amber-700)) 42%, transparent);
}
.composer-announce:focus-within {
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--notif-announce, var(--amber-700)) 22%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .composer-announce::after, .composer-announce > svg { transition: none; }
}

/* ============================================================
   Sprint 5.2 — ラウンジ（掲示板スレッド）
   ------------------------------------------------------------
   Tone: 「居場所」「静かな熱量」「ストック型でじっくり積み上がる掲示板」
   - Discord的な高速チャットの逆。読みに来た ROM 専にも優しい "静かな賑わい"。
   - ラウンジ = カテゴリ。本棚の背表紙のように、左に温色の "背" を立てて
     「機能の一覧」ではなく「居場所の一覧」として見せる。
   - スレッド一覧は掲示板リスト。直近動いたものが上に来る "動き" を一点だけ示す。
   - スレッド詳細は会話が下に積み上がる縦の連なり。
   - すべて --color-* / --post-* トークン経由でプリセットに追従。
     ダーク「しずかなラウンジ」でも明プリセットでも破綻しない。
   ------------------------------------------------------------
   local aliases */
:root {
  --lounge-hair:  color-mix(in oklab, var(--color-line) 64%, transparent);
  --lounge-quiet: color-mix(in oklab, var(--color-text) 6%, var(--color-card));
  --lounge-spine: var(--color-accent);
  --lounge-ease:  cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---- 共通ヘッダ（ラウンジ名・サブ） ---- */
.lounge-head {
  margin: 2px 0 22px;
}
.lounge-title {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1.2;
  margin: 0;
  color: var(--color-text);
}
.lounge-sub {
  margin: 7px 0 0;
  font-size: 14px;
  line-height: 1.7;
  color: var(--color-text-dim);
  max-width: 54ch;
}

/* ---- パンくず ---- */
.lounge-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  margin: 0 0 12px;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--color-muted);
}
.lounge-breadcrumb a {
  color: var(--color-text-dim);
  border-bottom: 1px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.lounge-breadcrumb a:hover {
  color: var(--color-text);
  border-bottom-color: color-mix(in oklab, var(--color-accent) 55%, transparent);
}
.lounge-breadcrumb .sep { color: color-mix(in oklab, var(--color-muted) 70%, transparent); }
.lounge-breadcrumb .current {
  color: var(--color-text);
  font-family: var(--font-display);
  letter-spacing: 0.02em;
}

/* ============================================================
   B. ラウンジ一覧 — 「居場所」カードの本棚
   ============================================================ */
.lounge-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

/* 本棚の背表紙を思わせる：左に温色の "背"、紙のカード。 */
.lounge-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 132px;
  padding: 18px 20px 16px 24px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 4%, var(--color-card)) 0%,
      var(--color-card) 64%);
  border: 1px solid var(--lounge-hair);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  color: var(--color-text);
  transition:
    transform .26s var(--lounge-ease),
    border-color .2s ease,
    box-shadow .26s ease;
}
/* 左の背表紙 */
.lounge-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--lounge-spine) 78%, transparent),
    color-mix(in oklab, var(--lounge-spine) 32%, transparent));
  transition: width .26s var(--lounge-ease);
}
.lounge-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in oklab, var(--color-accent) 34%, var(--lounge-hair));
  box-shadow: var(--shadow);
  color: var(--color-text);
}
.lounge-card:hover::before { width: 6px; }
.lounge-card:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.lounge-card-body { flex: 1 1 auto; min-width: 0; }
.lounge-card-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.35;
  margin: 0 0 6px;
  color: var(--color-text);
}
.lounge-card-desc {
  margin: 0;
  font-size: 13px;
  line-height: 1.65;
  color: var(--color-text-dim);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.lounge-card-desc.text-muted { color: var(--color-muted); font-style: italic; }

/* カード下部：賑わい指標（スレッド数）と CTA */
.lounge-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--lounge-hair);
}
.lounge-card-stat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--color-text-dim);
}
/* 賑わいの灯：スレッドがあると温色で点く小さな丸 */
.lounge-card-stat .pulse {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 80%, transparent);
  box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 40%, transparent);
  flex: 0 0 auto;
}
.lounge-card-stat.is-quiet .pulse {
  background: color-mix(in oklab, var(--color-muted) 60%, transparent);
}
.lounge-card:hover .lounge-card-stat:not(.is-quiet) .pulse {
  animation: lounge-pulse 1.8s var(--lounge-ease) infinite;
}
@keyframes lounge-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 38%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in oklab, var(--color-accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 0%, transparent); }
}
.lounge-card-stat b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
.lounge-card-cta {
  font-size: 12px;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--color-accent) 72%, var(--color-text));
  white-space: nowrap;
  transition: color .15s ease, transform .2s var(--lounge-ease);
}
.lounge-card:hover .lounge-card-cta {
  color: var(--color-text);
  transform: translateX(2px);
}

/* ---- 空状態（冷たくない） ---- */
.lounge-empty {
  text-align: center;
  padding: 52px 24px;
  background:
    radial-gradient(120% 80% at 50% -10%,
      color-mix(in oklab, var(--color-accent) 7%, transparent) 0%, transparent 70%),
    var(--lounge-quiet);
  border: 1px dashed color-mix(in oklab, var(--color-line) 80%, var(--color-text) 8%);
  border-radius: var(--radius-lg);
}
.lounge-empty .sigil {
  width: 38px; height: 38px;
  color: color-mix(in oklab, var(--color-accent) 78%, var(--color-text));
  margin: 0 auto 14px;
  opacity: 0.8;
}
.lounge-empty .lead-line {
  font-family: var(--font-display);
  font-size: 17px;
  letter-spacing: 0.04em;
  color: var(--color-text);
  margin: 0 0 6px;
}
.lounge-empty .meta {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--color-text-dim);
  margin: 0;
  max-width: 40ch;
  margin-inline: auto;
}

/* ============================================================
   C. スレッド一覧 — 掲示板リスト（直近動いたものが上）
   ============================================================ */
.thread-composer.card-panel {
  padding: 22px 24px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 4%, var(--color-card)) 0%,
      var(--color-card) 70%);
}
.thread-composer .composer-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.05em;
  margin: 0 0 16px;
  color: var(--color-text);
  display: flex;
  align-items: center;
  gap: 9px;
}
.thread-composer .composer-title::before {
  content: "";
  width: 16px; height: 1.5px;
  background: var(--color-accent);
  border-radius: 2px;
}

/* セクション見出し（プレーンな h2.section-title を一語見出しとして整える） */
.thread-list-section .section-title,
.comment-section .section-title {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 26px 0 14px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--color-text);
}
.thread-list-section .section-title::after {
  content: "";
  flex: 1;
  height: 1px;
  align-self: center;
  background: linear-gradient(90deg, var(--lounge-hair), transparent);
}

.thread-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--lounge-hair);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-card);
}
.thread-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0;
  position: relative;
}
.thread-row + .thread-row { border-top: 1px solid var(--lounge-hair); }

.thread-row-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 16px 4px 16px 22px;
  color: var(--color-text);
  position: relative;
  transition: background .18s ease;
}
.thread-row-main::before {
  /* 左の "動いてる" 印：直近スレッドだけ温色、それ以外は静かなグレー */
  content: "";
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 0;
  border-radius: 2px;
  background: var(--color-accent);
  transition: height .22s var(--lounge-ease);
}
.thread-row:hover .thread-row-main { background: var(--lounge-quiet); }
.thread-row:hover .thread-row-main::before { height: 60%; }
.thread-row-main:focus-visible {
  outline: none;
  background: var(--lounge-quiet);
  box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--color-accent) 45%, transparent);
}

/* 先頭行（直近に動いた）は背に常時 灯をともす */
.thread-row:first-child .thread-row-main::before { height: 60%; }
.thread-row:first-child .thread-row-title { color: var(--color-text); }

.thread-row-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1.4;
  color: var(--color-text);
  word-break: break-word;
  transition: color .15s ease;
}
.thread-row:hover .thread-row-title {
  color: color-mix(in oklab, var(--color-accent) 30%, var(--color-text));
}
.thread-row-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  font-size: 12px;
  color: var(--color-muted);
}
.thread-row-meta .thread-author {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--color-text-dim);
  font-weight: 500;
}
.thread-row-meta .thread-author::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line));
}
.thread-row-meta .thread-updated { font-variant-numeric: tabular-nums; }

/* コメント数：賑わいのカウンタ。0件は静かに、1件以上は温色で。 */
.thread-count {
  flex: 0 0 auto;
  align-self: center;
  margin-right: 18px;
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--lounge-quiet);
  border: 1px solid var(--lounge-hair);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--color-text-dim);
  white-space: nowrap;
}
.thread-count b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
.thread-count.is-active {
  background: color-mix(in oklab, var(--color-accent) 12%, var(--color-card));
  border-color: color-mix(in oklab, var(--color-accent) 38%, transparent);
  color: color-mix(in oklab, var(--color-accent) 50%, var(--color-text));
}
.thread-count.is-active b { color: color-mix(in oklab, var(--color-accent) 40%, var(--color-text)); }

/* ============================================================
   sprint-12. ピン留め / 注目スレッド
   固定群が上部にまとまって見えるよう、行に控えめな灯をともす。
   原色バッジは避け、トークン由来のアンバーで「静かな熱量」を保つ。
   ============================================================ */
/* 固定行：左の灯を常時ともし、背に淡いアンバーを敷いてピン群を一目で束ねる */
.thread-row.is-pinned .thread-row-main::before {
  height: 60%;
  background: color-mix(in oklab, var(--color-accent) 70%, var(--color-line));
}
.thread-row.is-pinned .thread-row-main {
  background: color-mix(in oklab, var(--color-accent) 6%, var(--color-card));
}
.thread-row.is-pinned:hover .thread-row-main {
  background: color-mix(in oklab, var(--color-accent) 10%, var(--color-card));
}

/* 固定目印（全員に見える）。タイトル先頭の小さなピン＋「固定」ラベル */
.thread-pin-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-right: 7px;
  padding: 2px 7px 2px 5px;
  border-radius: 999px;
  vertical-align: 1px;
  background: color-mix(in oklab, var(--color-accent) 12%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-accent) 32%, transparent);
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text));
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1;
}
.thread-pin-badge .pin-badge-ic {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  display: block;
}
.thread-pin-badge-label {
  white-space: nowrap;
}

/* ピン留めトグルボタン — 削除ボタン(thread-delete-btn)と同じ寸法・挙動。
   普段はアイコンのみ、hover/フォーカスでラベルがそっと開く。色はアンバー。 */
.thread-pin-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 5px 7px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.02em;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.5;
  -webkit-appearance: none;
  appearance: none;
  transition:
    color .18s ease,
    border-color .18s ease,
    background-color .18s ease,
    opacity .18s ease;
}
.thread-pin-btn .pin-ic {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  display: block;
  transition: transform .2s var(--lounge-ease, ease);
}
.thread-pin-btn .pin-label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-weight: 500;
  transition: max-width .26s var(--lounge-ease, ease), opacity .18s ease, margin .26s ease;
}
.thread-pin-btn:hover,
.thread-pin-btn:focus-visible {
  opacity: 1;
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-text));
  border-color: color-mix(in oklab, var(--color-accent) 36%, transparent);
  background: color-mix(in oklab, var(--color-accent) 9%, var(--color-card));
  outline: none;
}
.thread-pin-btn:hover .pin-label,
.thread-pin-btn:focus-visible .pin-label {
  max-width: 12rem;
  opacity: 1;
}
.thread-pin-btn:hover .pin-ic {
  transform: translateY(-0.5px);
}
.thread-pin-btn:focus-visible {
  box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px color-mix(in oklab, var(--color-accent) 38%, transparent);
}
.thread-pin-btn:active {
  transform: translateY(0.5px);
}
/* 固定中は常時うっすら灯し、「いま固定されている」ことを示す（解除アクション） */
.thread-pin-btn.is-pinned {
  opacity: 0.66;
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-muted));
  border-color: color-mix(in oklab, var(--color-accent) 26%, transparent);
}
.thread-pin-btn.is-pinned .pin-ic {
  fill: color-mix(in oklab, var(--color-accent) 14%, transparent);
}
.thread-pin-btn.is-pinned:hover,
.thread-pin-btn.is-pinned:focus-visible {
  opacity: 1;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  border-color: color-mix(in oklab, var(--color-accent) 40%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .thread-pin-btn,
  .thread-pin-btn .pin-ic,
  .thread-pin-btn .pin-label { transition: none; }
}

/* ============================================================
   D. スレッド詳細 — 冒頭本文を大きく、会話が下に積み上がる
   ============================================================ */
.thread-detail.card-panel {
  padding: 26px 28px 24px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 5%, var(--color-card)) 0%,
      var(--color-card) 58%);
  border-color: color-mix(in oklab, var(--color-accent) 16%, var(--lounge-hair));
}
.thread-detail-title {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.32;
  margin: 0 0 12px;
  color: var(--color-text);
  word-break: break-word;
}
.thread-detail-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  font-size: 12.5px;
  color: var(--color-muted);
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--lounge-hair);
}
.thread-detail-meta .thread-author {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-weight: 600;
  color: var(--color-text-dim);
}
.thread-detail-meta .thread-author::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 60%, var(--color-line));
}
.thread-detail-meta .thread-created { font-variant-numeric: tabular-nums; }
.thread-detail-body {
  font-size: 15.5px;
  line-height: 1.85;
  color: color-mix(in oklab, var(--color-text) 94%, var(--color-muted));
  word-break: break-word;
}

/* ---- コメント節：Sprint3 の .comment-* と衝突しないよう .comment-section で局所上書き ---- */
.comment-section .section-title .comment-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--color-accent) 14%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-accent) 34%, transparent);
  color: color-mix(in oklab, var(--color-accent) 46%, var(--color-text));
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.comment-section .comment-list {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
}
/* 会話の背骨：アバター中心を貫く細い縦線（積み上がる連なり） */
.comment-section .comment-list::before {
  content: "";
  position: absolute;
  left: 18px; top: 26px; bottom: 26px;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--lounge-hair) 10%, var(--lounge-hair) 90%, transparent);
}
.comment-section .comment-item {
  display: flex;
  gap: 14px;
  padding: 14px 0;
  position: relative;
  align-items: flex-start;
}
.comment-section .comment-item + .comment-item {
  border-top: 1px solid color-mix(in oklab, var(--lounge-hair) 60%, transparent);
}
.comment-section .comment-avatar {
  width: 36px; height: 36px;
  flex: 0 0 36px;
  border-radius: 50%;
  overflow: hidden;
  position: relative;
  z-index: 1;
  background: var(--color-card);
  box-shadow: 0 0 0 3px var(--color-card), 0 0 0 4px var(--lounge-hair);
}
.comment-section .comment-avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.comment-section .comment-avatar .avatar-fallback {
  width: 100%; height: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(140deg,
    color-mix(in oklab, var(--color-accent) 30%, var(--color-card)),
    color-mix(in oklab, var(--color-accent) 13%, var(--color-card)));
  color: color-mix(in oklab, var(--color-accent) 68%, var(--color-text));
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
}
.comment-section .comment-body-wrap {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 1px;
}
.comment-section .comment-meta {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 4px;
}
.comment-section .comment-author {
  font-weight: 600;
  font-size: 13.5px;
  color: var(--color-text);
}
.comment-section .comment-created {
  font-size: 11.5px;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.comment-section .comment-body {
  margin: 0;
  font-size: 14px;
  line-height: 1.75;
  color: color-mix(in oklab, var(--color-text) 92%, var(--color-muted));
  word-break: break-word;
}

/* コメント投稿欄 — 末尾に自然配置 */
.comment-composer.card-panel {
  padding: 20px 22px;
  margin-top: 4px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 4%, var(--color-card)) 0%,
      var(--color-card) 72%);
}

/* ============================================================
   レスポンシブ
   ============================================================ */
@media (max-width: 720px) {
  .lounge-grid { grid-template-columns: 1fr; gap: 12px; }
  .lounge-title { font-size: 25px; }
  .thread-detail-title { font-size: 21px; }
  .thread-composer.card-panel,
  .thread-detail.card-panel { padding: 20px 18px; }
  .thread-row { flex-wrap: wrap; }
  .thread-row-main { padding: 14px 16px 6px 18px; }
  .thread-count {
    margin: 0 16px 14px 18px;
    align-self: flex-start;
  }
  .comment-section .comment-list::before { left: 16px; }
  .comment-section .comment-avatar { width: 32px; height: 32px; flex-basis: 32px; }
}

@media (prefers-reduced-motion: reduce) {
  .lounge-card,
  .lounge-card::before,
  .lounge-card-cta,
  .thread-row-main,
  .thread-row-main::before { transition: none; }
  .lounge-card:hover .lounge-card-stat .pulse { animation: none; }
}

/* ============================================================
   Sprint 5.3 — ラウンジのリアクション / 返信通知の磨き込み
   ------------------------------------------------------------
   Tone: 「静かな相槌（あいづち）」。ROM 専が "見るだけでも参加" できる、
   そっと置くスタンプ。Sprint3 投稿カードの .reaction-btn を流用しつつ、
   ラウンジ＝掲示板の文脈に合わせて：
   - 反応のないスタンプは退いて（recede）、押された／自分の反応だけが灯る
   - スレッド本文の反応は "返信のとなりに置く相槌" として一拍の余白を持つ
   - コメント行の反応は会話の背骨を侵さないコンパクトな相槌列にする
   既存 .reaction-bar（投稿カード）には一切触れない＝ .lounge-reaction-bar /
   .comment-section スコープに閉じる（Sprint3 / 5.2 回帰なし）。
   すべて --color-* / --post-* / --lounge-* トークン経由でプリセット追従。
   ============================================================ */

/* ---- スレッド本文の相槌列：本文と投稿欄の "あいだ" にそっと置く ---- */
.thread-detail .lounge-reaction-bar {
  margin-top: 20px;
  padding-top: 16px;
  gap: 8px;
  position: relative;
}
/* 本文との境に引く、消えゆくヘアライン（区切りすぎない一筋） */
.thread-detail .lounge-reaction-bar::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--color-accent) 22%, transparent),
    var(--lounge-hair) 38%,
    transparent 82%);
}

/* ---- 反応のないスタンプは退かせる（ROM 専に圧をかけない） ---- */
/* 0 件のカウントは灯さない。押された数だけが浮かび上がる。 */
.lounge-reaction-bar .reaction-btn .reaction-count {
  color: var(--color-muted);
  opacity: .62;
  transition: color .2s ease, opacity .2s ease;
}
.lounge-reaction-bar .reaction-btn:hover:not([disabled]) .reaction-count {
  opacity: 1;
}

/* 自分の反応（is-active）の灯りを、ラウンジ文脈で少し澄ませる。
   base の温色グローはそのままに、カウント数を確実に読ませる。 */
.lounge-reaction-bar .reaction-btn.is-active .reaction-count {
  color: color-mix(in oklab, var(--color-accent) 62%, var(--color-text));
  opacity: 1;
  font-weight: 600;
}

/* ---- コメント行の相槌：会話の背骨を侵さないコンパクト列 ---- */
/* 各コメント本文の直下に、ひとまわり小さく・静かに。賑わいは "自分が押したとき" だけ灯る。 */
.comment-section .comment-body-wrap .lounge-reaction-bar {
  margin-top: 9px;
  gap: 5px;
}
.comment-section .lounge-reaction-bar .reaction-btn {
  min-height: 28px;
  padding: 4px 9px 4px 8px;
  gap: 4px;
  font-size: 12px;
  /* 退いた静けさ：背景をさらに薄く、線を細く。読みの邪魔をしない。 */
  background: color-mix(in oklab, var(--color-text) 3.5%, var(--color-card));
  border-color: color-mix(in oklab, var(--lounge-hair) 78%, transparent);
  color: var(--color-muted);
}
.comment-section .lounge-reaction-bar .reaction-emoji {
  font-size: 14px;
  /* 反応0のスタンプは少しだけ色を抜いて "置いてあるだけ" に。押すと戻る。 */
  filter: saturate(.72) opacity(.78);
  transition: filter .22s var(--lounge-ease, ease), transform .12s var(--post-ease, ease);
}
.comment-section .lounge-reaction-bar .reaction-btn:hover:not([disabled]) .reaction-emoji,
.comment-section .lounge-reaction-bar .reaction-btn.is-active .reaction-emoji {
  filter: none;
}
.comment-section .lounge-reaction-bar .reaction-count {
  font-size: 11.5px;
  min-width: 7px;
}
.comment-section .lounge-reaction-bar .reaction-btn:hover:not([disabled]) {
  background: var(--lounge-quiet);
  border-color: color-mix(in oklab, var(--color-accent) 40%, var(--lounge-hair));
  color: var(--color-text-dim);
}
/* 自分が押したコメント反応：本文より目立たせず、でも確かに灯す（小さな相槌） */
.comment-section .lounge-reaction-bar .reaction-btn.is-active {
  background: color-mix(in oklab, var(--color-accent) 13%, var(--color-card));
  border-color: color-mix(in oklab, var(--color-accent) 50%, transparent);
  color: color-mix(in oklab, var(--color-accent) 52%, var(--color-text));
  box-shadow: 0 3px 9px -6px color-mix(in oklab, var(--color-accent) 55%, transparent);
}

/* ---- 返信通知（lounge_reply）：コメント系（緑）と分けて "ラウンジの灯" に ---- */
:root { --notif-lounge: var(--color-accent); }
.notif-icon-lounge_reply {
  color: var(--notif-lounge);
  background: color-mix(in oklab, var(--notif-lounge) 14%, var(--color-card));
  border-color: color-mix(in oklab, var(--notif-lounge) 32%, transparent);
}

/* ---- Sprint 15-D: 新フォーラム通知（lounge_message_reply / lounge_message_thread_reply） ----
   既存のベルアイコン語彙（neutral 矩形 + amber 細罫）と統一しつつ、
   Reply は「親密な細い灯」、Thread は「専有の少し濃い灯」で対比させる。
   既存 lounge_reply とは色相を少しずらして識別性を確保（Reply は ink 寄り、
   Thread は amber を一段濃く）。
*/
.notif-icon-lounge_message_reply {
  /* 普通の返信 = 親密で静か。amber より少し ink 寄りに振って、コメント系（緑）
     とも lounge_reply（純 amber）とも違う「落ち着いた手紙」のトーンに。 */
  color: color-mix(in oklab, var(--notif-lounge) 60%, var(--color-text-dim));
  background: color-mix(in oklab, var(--notif-lounge) 8%, var(--color-card));
  border-color: color-mix(in oklab, var(--notif-lounge) 22%, var(--post-hair, var(--color-line)));
}
.notif-icon-lounge_message_thread_reply {
  /* スレッド = 専有空間。amber を一段濃く灯し、"付箋を貼る" の語彙と整合させる。 */
  color: color-mix(in oklab, var(--notif-lounge) 88%, var(--color-text));
  background: color-mix(in oklab, var(--notif-lounge) 18%, var(--color-card));
  border-color: color-mix(in oklab, var(--notif-lounge) 45%, transparent);
}

@media (max-width: 720px) {
  .comment-section .comment-body-wrap .lounge-reaction-bar {
    /* スマホでは 5 つが折り返すので、行間を詰めて相槌の "ひとまとまり" 感を保つ */
    gap: 5px 5px;
  }
  .thread-detail .lounge-reaction-bar { margin-top: 16px; padding-top: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .comment-section .lounge-reaction-bar .reaction-emoji { transition: none; }
}

/* ============================================================
   Sprint 6 — モデレーション削除「静かな手当て」
   ------------------------------------------------------------
   Tone: 削除は破壊的だが、コミュニティを治安維持で守る "そっとした
   片付け／介入"。けばけばしい赤で威圧しない。普段は紙に溶けるほど
   控えめ、hover とモデレーター文脈でだけ意図が灯る。

   - 本人削除（.is-self）  = 自分の投稿の "片付け"。ゴミ箱。
                             普段は気配だけ、hover で静かな clay。
   - モデレーター削除（.is-mod）= 他人への "介入"。盾アイコンで
                             役割を示す。本人削除より一段 "重い" 質感
                             （色ではなく "格"）。アンバー寄りの警告で、
                             血のような赤にはしない。

   配色: --color-danger は既定で clay(#b65a4a)=暖かいテラコッタ。
   owner アクセントと同系のため、モデレーター削除は
   amber-700 寄りの "戒め色" を併せて owner と被らせない。
   ============================================================ */

/* 共通トークン */
:root {
  --del-self:      color-mix(in oklab, var(--color-danger) 88%, var(--color-text) 12%);
  --del-self-soft: color-mix(in oklab, var(--color-danger) 9%, transparent);
  /* モデレーターの戒め色: danger を ink で締めた "深い炭テラコッタ"。
     威圧の純赤ではなく、責任の重さを帯びた落ち着いた色。 */
  --del-mod:       color-mix(in oklab, var(--color-danger) 72%, var(--ink-800, #20232b) 28%);
  --del-mod-edge:  color-mix(in oklab, var(--color-danger) 50%, var(--color-line));
  --del-mod-soft:  color-mix(in oklab, var(--color-danger) 11%, transparent);
}

/* ---- 基底: アイコン主役の控えめゴースト ---- */
.post-delete-btn,
.comment-delete-btn,
.thread-delete-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 5px 7px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.02em;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.5;
  -webkit-appearance: none;
  appearance: none;
  transition:
    color .18s ease,
    border-color .18s ease,
    background-color .18s ease,
    opacity .18s ease;
}

.post-delete-btn .del-ic,
.comment-delete-btn .del-ic,
.thread-delete-btn .del-ic {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  display: block;
  transition: transform .2s var(--lounge-ease, ease);
}

/* ラベルは普段たたんでアイコンだけ。hover/フォーカスでそっと開く。
   = タイムラインを賑やかにせず、必要なときだけ意図が読める。 */
.post-delete-btn .del-label,
.comment-delete-btn .del-label,
.thread-delete-btn .del-label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-weight: 500;
  transition: max-width .26s var(--lounge-ease, ease), opacity .18s ease, margin .26s ease;
}

/* ---- hover / focus: そっと灯す ---- */
.post-delete-btn:hover,
.comment-delete-btn:hover,
.thread-delete-btn:hover,
.post-delete-btn:focus-visible,
.comment-delete-btn:focus-visible,
.thread-delete-btn:focus-visible {
  opacity: 1;
  color: var(--del-self);
  border-color: color-mix(in oklab, var(--color-danger) 32%, transparent);
  background: var(--del-self-soft);
  outline: none;
}
.post-delete-btn:hover .del-label,
.comment-delete-btn:hover .del-label,
.thread-delete-btn:hover .del-label,
.post-delete-btn:focus-visible .del-label,
.comment-delete-btn:focus-visible .del-label,
.thread-delete-btn:focus-visible .del-label {
  max-width: 12rem;
  opacity: 1;
}
.post-delete-btn:hover .del-ic,
.comment-delete-btn:hover .del-ic,
.thread-delete-btn:hover .del-ic {
  transform: translateY(-0.5px);
}
.post-delete-btn:focus-visible,
.comment-delete-btn:focus-visible,
.thread-delete-btn:focus-visible {
  box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px color-mix(in oklab, var(--color-danger) 38%, transparent);
}
.post-delete-btn:active,
.comment-delete-btn:active,
.thread-delete-btn:active {
  transform: translateY(0.5px);
}

/* ============================================================
   モデレーター削除（.is-mod）— "介入" の一段重い質感
   本人削除より輪郭が立ち、盾アイコンで役割を示す。色は戒めの
   炭テラコッタ。普段でも本人削除よりわずかに存在感を持たせ、
   "他人の投稿に手を入れている" 緊張を静かに伝える。
   ============================================================ */
.post-delete-btn.is-mod,
.comment-delete-btn.is-mod,
.thread-delete-btn.is-mod {
  opacity: 0.62;
  color: color-mix(in oklab, var(--del-mod) 70%, var(--color-muted));
  border-color: color-mix(in oklab, var(--del-mod-edge) 34%, transparent);
}
.post-delete-btn.is-mod .del-ic,
.comment-delete-btn.is-mod .del-ic,
.thread-delete-btn.is-mod .del-ic {
  /* 盾は塗り気配を一点だけ持たせ、ゴミ箱(線のみ)と質感を変える */
  fill: color-mix(in oklab, var(--del-mod) 14%, transparent);
}
.post-delete-btn.is-mod:hover,
.comment-delete-btn.is-mod:hover,
.thread-delete-btn.is-mod:hover,
.post-delete-btn.is-mod:focus-visible,
.comment-delete-btn.is-mod:focus-visible,
.thread-delete-btn.is-mod:focus-visible {
  opacity: 1;
  color: var(--del-mod);
  border-color: var(--del-mod-edge);
  background: var(--del-mod-soft);
}
.post-delete-btn.is-mod .del-ic,
.comment-delete-btn.is-mod .del-ic,
.thread-delete-btn.is-mod .del-ic {
  fill: color-mix(in oklab, var(--del-mod) 14%, transparent);
}
.post-delete-btn.is-mod:hover .del-ic,
.comment-delete-btn.is-mod:hover .del-ic,
.thread-delete-btn.is-mod:hover .del-ic {
  fill: color-mix(in oklab, var(--del-mod) 24%, transparent);
}
.post-delete-btn.is-mod:focus-visible,
.comment-delete-btn.is-mod:focus-visible,
.thread-delete-btn.is-mod:focus-visible {
  box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px color-mix(in oklab, var(--del-mod) 40%, transparent);
}
/* モデレーター削除はラベルが長い。スマホ等で潰れないよう、フォーカス時は確実に開く */
.post-delete-btn.is-mod:hover .del-label,
.comment-delete-btn.is-mod:hover .del-label,
.thread-delete-btn.is-mod:hover .del-label,
.post-delete-btn.is-mod:focus-visible .del-label,
.comment-delete-btn.is-mod:focus-visible .del-label,
.thread-delete-btn.is-mod:focus-visible .del-label {
  max-width: 14rem;
}

/* ============================================================
   配置の微調整（既存レイアウトを壊さない範囲で）
   ============================================================ */

/* 投稿カード/詳細: ヘッダ右上。アバター行と中心を揃える */
.post-card-head .post-delete-btn {
  align-self: center;
  margin: -2px -2px 0 0;
}

/* 投稿詳細コメント行: 既存 .comment-head .comment-delete-btn { margin-left:auto } を継承し右端へ */
.comment-head .comment-delete-btn { margin-top: -1px; }

/* ラウンジ スレッド行末尾: コメント数バッジの右に、行に溶ける小さな印 */
.thread-row .thread-delete-btn {
  align-self: center;
  margin-right: 14px;
}

/* ラウンジ スレッド詳細見出し: タイトルと横並び、上端を揃える */
.thread-detail-headline {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.thread-detail-headline .thread-detail-title { margin-bottom: 0; }
.thread-detail-headline .thread-delete-btn {
  flex: 0 0 auto;
  margin-top: 4px;
}

/* ラウンジ コメント行: メタ行の末尾へ寄せる */
.comment-section .comment-meta { position: relative; }
.comment-section .comment-meta .comment-delete-btn { margin-left: auto; }

/* ============================================================
   レスポンシブ — スマホでは "押せる面積" を確保しつつ控えめさは維持
   ============================================================ */
@media (max-width: 720px) {
  /* タッチ端末ではラベルを常時たたんだままだと意図が伝わりにくいので、
     モデレーター削除のラベルだけは小さく常時表示（役割を明示）。
     本人削除はアイコンのみで十分（自分の片付けは自明）。 */
  .post-delete-btn,
  .comment-delete-btn,
  .thread-delete-btn {
    padding: 7px 8px;
    opacity: 0.62;
  }
  .post-delete-btn.is-mod .del-label,
  .comment-delete-btn.is-mod .del-label,
  .thread-delete-btn.is-mod .del-label {
    max-width: 14rem;
    opacity: 1;
    margin-left: 1px;
    font-size: 10.5px;
  }
  .post-delete-btn.is-mod,
  .comment-delete-btn.is-mod,
  .thread-delete-btn.is-mod {
    opacity: 0.78;
  }
  /* スレッド詳細見出しでタイトルとボタンが詰まらないよう改行余地 */
  .thread-detail-headline { flex-wrap: wrap; }
}

/* タッチ主体デバイス（hover 不可）ではラベルを常に開く＝意図を必ず伝える */
@media (hover: none) {
  .post-delete-btn .del-label,
  .comment-delete-btn .del-label,
  .thread-delete-btn .del-label {
    max-width: 14rem;
    opacity: 1;
    margin-left: 1px;
  }
  .post-delete-btn,
  .comment-delete-btn,
  .thread-delete-btn { opacity: 0.7; }
}

@media (prefers-reduced-motion: reduce) {
  .post-delete-btn,
  .comment-delete-btn,
  .thread-delete-btn,
  .post-delete-btn .del-ic,
  .comment-delete-btn .del-ic,
  .thread-delete-btn .del-ic,
  .post-delete-btn .del-label,
  .comment-delete-btn .del-label,
  .thread-delete-btn .del-label { transition: none; }
}

/* ============================================================
   sprint-6.1 — 通報（report）
   ------------------------------------------------------------
   設計の精神（Sprint 6 削除と地続き）:
   通報は "治安維持の静かな手当て"。削除が "自分で片付ける／介入する"
   破壊的操作なのに対し、通報は "そっと運営に知らせる" もっと軽い行為。
   だから旗ボタンは削除ボタンよりさらに控えめに。色も削除の暖かい
   clay（テラコッタ）とは別系統の "冷たいスレート" にして、隣り合っても
   役割が混ざらないようにする（赤＝消す／青みグレー＝知らせる）。

   3 つのパート:
     1. 通報ボタン（旗・控えめゴースト）   … ユーザー側・しずかなラウンジ
     2. 通報モーダル（静かな中央ダイアログ）… ユーザー側・しずかなラウンジ
     3. モデレーション一覧（白基調・業務）  … 管理側・白い worktool パネル
   ============================================================ */

:root {
  /* 通報＝冷たいスレート（知らせる印）。delete の clay と被らない。
     プリセットに依らず安定するよう ink を地に色相だけ寄せる。 */
  --report-ink:   #4a5560;
  --report-soft:  color-mix(in oklab, var(--report-ink) 9%, transparent);
  --report-edge:  color-mix(in oklab, var(--report-ink) 30%, transparent);
}

/* ---- 1. 通報ボタン（旗）------------------------------------
   delete_control と同じ "アイコン主役・ラベルは hover で開く" 文法に
   合わせる。タイムラインに旗が並んで賑やかにならないよう、普段は紙に
   溶ける。削除ボタンの隣に置いても、色（スレート）と気配で別物と分かる。 */
.report-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 5px 7px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.02em;
  line-height: 1;
  cursor: pointer;
  opacity: 0.46;
  -webkit-appearance: none;
  appearance: none;
  transition:
    color .18s ease,
    border-color .18s ease,
    background-color .18s ease,
    opacity .18s ease;
}
.report-btn .report-ic {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  display: block;
  transition: transform .2s var(--lounge-ease, ease);
}
.report-btn .report-label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-weight: 500;
  transition: max-width .26s var(--lounge-ease, ease), opacity .18s ease, margin .26s ease;
}
.report-btn:hover,
.report-btn:focus-visible {
  opacity: 1;
  color: var(--report-ink);
  border-color: var(--report-edge);
  background: var(--report-soft);
  outline: none;
}
.report-btn:hover .report-label,
.report-btn:focus-visible .report-label {
  max-width: 8rem;
  opacity: 1;
  margin-left: 1px;
}
/* 旗がそっと立つ。手当てのジェスチャー。 */
.report-btn:hover .report-ic,
.report-btn:focus-visible .report-ic {
  transform: translateY(-0.5px) rotate(-3deg);
}
.report-btn:focus-visible {
  box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px var(--report-edge);
}
.report-btn:active { transform: translateY(0.5px); }

/* 通報＋削除が同居するコントロール群は 1 行に揃える（投稿カード／スレッド見出し）。
   旗 → 片付け の順。詰まりすぎないよう小さな間。 */
.post-card-controls,
.thread-detail-controls {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
}
.thread-detail-controls { margin-top: 4px; }
.thread-detail-headline .thread-detail-controls .thread-delete-btn { margin-top: 0; }

/* コメント文脈: メタ行末尾へ寄せる（削除ボタンと同じ作法）。
   両方出る場合は通報→削除の順で並ぶ。 */
.comment-head .comment-report-btn { margin-left: auto; }
.comment-head .comment-report-btn + .comment-delete-btn { margin-left: 0; }
.comment-section .comment-meta .comment-report-btn { margin-left: auto; }
.comment-section .comment-meta .comment-report-btn + .comment-delete-btn { margin-left: 0; }

/* タッチ端末: hover が無いので旗を少しだけ立たせる（押せると分かる程度）。
   ラベルは出さず旗のみ＝控えめさは保つ。 */
@media (hover: none) {
  .report-btn { opacity: 0.6; }
}
@media (prefers-reduced-motion: reduce) {
  .report-btn,
  .report-btn .report-ic,
  .report-btn .report-label { transition: none; }
}

/* ---- 2. 通報モーダル（静かな中央ダイアログ）----------------
   しずかなラウンジのトーン。バックドロップで奥を沈め、紙のダイアログを
   そっと前へ。威圧しない＝赤や警告色を散らさず、紙とインクで構成。 */
.report-modal {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.report-modal[hidden] { display: none; }

.report-modal-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--ink-900) 58%, transparent);
  -webkit-backdrop-filter: blur(3px) saturate(0.9);
  backdrop-filter: blur(3px) saturate(0.9);
  opacity: 0;
  transition: opacity .22s ease;
}
.report-modal.is-open .report-modal-backdrop { opacity: 1; }

.report-modal-dialog {
  position: relative;
  width: 100%;
  max-width: 440px;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  background: var(--color-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 26px 26px 22px;
  /* 開く時にそっと持ち上がる */
  opacity: 0;
  transform: translateY(8px) scale(0.985);
  transition: opacity .22s ease, transform .26s var(--lounge-ease, cubic-bezier(.22,.8,.3,1));
}
.report-modal.is-open .report-modal-dialog {
  opacity: 1;
  transform: translateY(0) scale(1);
}
/* 上辺に細い印 — 旗と同じスレートで "通報" の文脈をそっと示す */
.report-modal-dialog::before {
  content: "";
  position: absolute;
  top: 0;
  left: 26px;
  right: 26px;
  height: 2px;
  border-radius: 0 0 2px 2px;
  background: linear-gradient(90deg,
    var(--report-ink),
    color-mix(in oklab, var(--report-ink) 30%, transparent));
  opacity: 0.5;
}

.report-modal-x {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.report-modal-x:hover { color: var(--color-text); background: color-mix(in oklab, var(--color-text) 7%, transparent); }
.report-modal-x:focus-visible { outline: none; box-shadow: var(--focus-ring); }

.report-modal-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-text);
  margin: 0 30px 5px 0;
}
.report-modal-lead {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim);
  margin: 0 0 18px;
}

.report-reasons {
  border: 0;
  margin: 0 0 4px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.report-reasons-legend {
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 9px;
  padding: 0;
}
/* 理由は "押せる行" として。ラジオは隠さず小さく残し、行全体が当たり判定。 */
.report-reason-option {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--color-paper) 55%, var(--color-card));
  font-size: 14px;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.report-reason-option:hover {
  border-color: var(--line-strong);
  background: var(--color-card);
}
.report-reason-option input[type="radio"] {
  width: 1.05em;
  height: 1.05em;
  margin: 0;
  flex: 0 0 auto;
  accent-color: var(--report-ink);
  cursor: pointer;
}
.report-reason-option:has(input:checked) {
  border-color: var(--report-edge);
  background: var(--report-soft);
  box-shadow: inset 2px 0 0 var(--report-ink);
}
.report-reason-option:has(input:focus-visible) {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--report-ink) 22%, transparent);
}
.report-reason-option span { line-height: 1.3; }

/* 「その他」自由記述 — そっと現れる */
.report-detail-field {
  margin-top: 12px;
  animation: report-detail-in .24s var(--lounge-ease, ease);
}
.report-detail-field[hidden] { display: none; }
@keyframes report-detail-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.report-detail-label {
  display: block;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.report-detail-input {
  width: 100%;
  border: 1px solid #d6dadf;
  border-radius: var(--radius-sm);
  background: #fff;
  color: #25221c;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.6;
  padding: 10px 12px;
  resize: vertical;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.report-detail-input::placeholder { color: #9ca3a8; }
.report-detail-input:focus {
  outline: none;
  border-color: #5a6168;
  box-shadow: 0 0 0 3px rgba(90, 97, 104, 0.18);
}

/* フィードバック行（ok / warn / error） */
.report-feedback {
  margin: 14px 0 0;
  padding: 10px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 13px;
  line-height: 1.5;
}
.report-feedback[hidden] { display: none; }
.report-feedback.is-ok {
  background: color-mix(in oklab, var(--color-success) 13%, var(--color-card));
  color: color-mix(in oklab, var(--color-success) 60%, var(--color-text));
  border-color: color-mix(in oklab, var(--color-success) 30%, var(--line));
}
.report-feedback.is-warn {
  background: color-mix(in oklab, var(--amber-600) 14%, var(--color-card));
  color: color-mix(in oklab, var(--amber-700) 70%, var(--color-text));
  border-color: color-mix(in oklab, var(--amber-600) 34%, var(--line));
}
.report-feedback.is-error {
  background: color-mix(in oklab, var(--color-danger) 13%, var(--color-card));
  color: color-mix(in oklab, var(--color-danger) 64%, var(--color-text));
  border-color: color-mix(in oklab, var(--color-danger) 30%, var(--line));
}

.report-modal-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid color-mix(in oklab, var(--line) 70%, transparent);
}
.report-cancel {
  border: 0;
  background: none;
  color: var(--text-dim);
  font-family: var(--font-sans);
  font-size: 13px;
  padding: 9px 14px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.report-cancel:hover { color: var(--color-text); background: color-mix(in oklab, var(--color-text) 6%, transparent); }
.report-cancel:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* 送信＝スレートインクの実ボタン（控えめだが押せると分かる存在感） */
.report-submit {
  border: 1px solid var(--report-ink);
  background: var(--report-ink);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  padding: 9px 20px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .12s ease, opacity .15s ease;
}
.report-submit:hover {
  background: color-mix(in oklab, var(--report-ink) 84%, #000 16%);
  border-color: color-mix(in oklab, var(--report-ink) 84%, #000 16%);
}
.report-submit:active { transform: translateY(0.5px); }
.report-submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--report-ink) 40%, transparent);
}
.report-submit:disabled { opacity: 0.55; cursor: default; }

@media (max-width: 560px) {
  .report-modal { padding: 0; align-items: flex-end; }
  .report-modal-dialog {
    max-width: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    max-height: 92vh;
    padding: 22px 18px 18px;
    /* スマホはボトムシート風に下から */
    transform: translateY(14px);
  }
  .report-modal.is-open .report-modal-dialog { transform: translateY(0); }
  .report-modal-dialog::before { left: 18px; right: 18px; }
  .report-modal-actions { flex-direction: column-reverse; align-items: stretch; }
  .report-cancel, .report-submit { width: 100%; text-align: center; }
}
@media (prefers-reduced-motion: reduce) {
  .report-modal-backdrop,
  .report-modal-dialog,
  .report-detail-field { transition: none; animation: none; }
}

/* ---- 3. モデレーション一覧（白基調・業務 worktool）---------
   ユーザー側のしずかなラウンジ（紙＋暖色）から切り離し、管理画面と
   地続きの "白い業務パネル" を default レイアウト内に自前で立てる。
   wireframe の運営業務トーン: クールニュートラルの白、罫線テーブル、
   小さく色分けされたバッジ。プリセット（暖色）の影響を受けないよう
   ローカルなニュートラル変数で固める。 */
/* モデレーションは業務 worktool。本体に広めの幅を渡す（右レールは全体で撤去済み）。
   :has() で当該画面だけに限定＝他画面のレイアウトは一切変えない。 */
.app-shell:has(.moderation-page) .app-main { max-width: 1080px; }

.moderation-page {
  --m-bg:      #ffffff;
  --m-tint:    #f6f7f9;
  --m-line:    #e6e9ed;
  --m-line-2:  #d6dbe1;
  --m-ink:     #1f2933;
  --m-ink-2:   #4a5560;
  --m-muted:   #8a929c;

  background: var(--m-bg);
  border: 1px solid var(--m-line);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(20, 28, 40, 0.04), 0 18px 44px -28px rgba(20, 28, 40, 0.22);
  overflow: hidden;
  color: var(--m-ink);
}

.moderation-head {
  padding: 22px 26px 18px;
  border-bottom: 1px solid var(--m-line);
  background:
    linear-gradient(180deg, var(--m-tint), var(--m-bg));
}
.moderation-title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--m-ink);
  margin: 0 0 5px;
}
.moderation-title::before {
  /* 盾の小印 — 業務 = モデレーション の標識 */
  content: "";
  width: 16px;
  height: 18px;
  flex: 0 0 auto;
  background: var(--m-ink-2);
  -webkit-mask: no-repeat center / contain url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 3 5 5.4v5c0 4.3 2.9 7.4 7 8.6 4.1-1.2 7-4.3 7-8.6v-5z" fill="black"/></svg>');
  mask: no-repeat center / contain url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 3 5 5.4v5c0 4.3 2.9 7.4 7 8.6 4.1-1.2 7-4.3 7-8.6v-5z" fill="black"/></svg>');
  opacity: 0.85;
}
.moderation-sub {
  font-size: 13px;
  line-height: 1.6;
  color: var(--m-ink-2);
  margin: 0;
  max-width: 60ch;
}

/* 空状態 */
.moderation-empty {
  padding: 56px 26px 64px;
  text-align: center;
}
.moderation-empty .lead-line {
  font-size: 15px;
  font-weight: 600;
  color: var(--m-ink);
  margin: 0 0 6px;
}
.moderation-empty .meta {
  font-size: 13px;
  color: var(--m-muted);
  margin: 0;
}

/* テーブル */
.moderation-table-wrap { overflow-x: auto; }
.moderation-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
.moderation-table thead th {
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--m-muted);
  text-align: left;
  padding: 12px 16px;
  background: var(--m-tint);
  border-bottom: 1px solid var(--m-line-2);
  white-space: nowrap;
}
.moderation-table tbody td {
  padding: 16px 16px;
  border-bottom: 1px solid var(--m-line);
  vertical-align: top;
  color: var(--m-ink);
}
.moderation-row { transition: background .14s ease; }
.moderation-row:hover { background: var(--m-tint); }
.moderation-table tbody tr:last-child td { border-bottom: 0; }

.moderation-table .col-type    { width: 1%; white-space: nowrap; }
.moderation-table .col-reporter{ width: 1%; white-space: nowrap; color: var(--m-ink-2); }
.moderation-table .col-reason  { width: 1%; white-space: nowrap; }
.moderation-table .col-date    { width: 1%; white-space: nowrap; color: var(--m-muted); font-family: var(--font-latin); font-size: 12px; }
.moderation-table .col-actions { width: 1%; white-space: nowrap; text-align: right; }
.moderation-table .col-excerpt { min-width: 220px; }

/* 種別バッジ — 4 種を低彩度で色分け（業務的に判別できる程度）。 */
.type-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.4;
  border: 1px solid transparent;
  white-space: nowrap;
}
.type-badge::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
  opacity: 0.85;
}
.type-badge.type-post {
  color: #2f5d8a;
  background: #eaf1f8;
  border-color: #cfe0f0;
}
.type-badge.type-comment {
  color: #3d6b4f;
  background: #e9f2ec;
  border-color: #cfe3d6;
}
.type-badge.type-lounge_thread {
  color: #7a5a2e;
  background: #f6efe2;
  border-color: #e8dcc4;
}
.type-badge.type-lounge_thread_comment {
  color: #6b4f6e;
  background: #f1ebf2;
  border-color: #e0d3e2;
}

/* 対象抜粋 */
.moderation-table .excerpt {
  margin: 0;
  line-height: 1.55;
  color: var(--m-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 52ch;
}
.moderation-table .excerpt-empty {
  color: var(--m-muted);
  font-style: italic;
}
.moderation-table .report-detail {
  margin: 6px 0 0;
  padding: 7px 10px;
  border-left: 2px solid var(--m-line-2);
  background: var(--m-tint);
  border-radius: 0 5px 5px 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--m-ink-2);
  max-width: 52ch;
}

/* 理由タグ — 4 理由を抑えた色で */
.reason-tag {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  white-space: nowrap;
}
.reason-tag.reason-spam {
  color: #8a6d2f;
  background: #f7f0dd;
  border-color: #e7d8b2;
}
.reason-tag.reason-harassment {
  color: #a4453a;
  background: #f8e9e6;
  border-color: #eccdc7;
}
.reason-tag.reason-inappropriate {
  color: #8a4a6e;
  background: #f6e9f0;
  border-color: #e6cbdc;
}
.reason-tag.reason-other {
  color: #566069;
  background: #eef0f3;
  border-color: #dadfe5;
}

/* 操作 — "対象を見る"（静かなリンク）／"削除して処理済み"（戒めの実行） */
.mod-action {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.01em;
  border-radius: 6px;
  cursor: pointer;
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.mod-action-view {
  color: var(--m-ink-2);
  padding: 6px 10px;
  border: 1px solid var(--m-line-2);
  background: var(--m-bg);
  margin-right: 8px;
  text-decoration: none;
}
.mod-action-view:hover {
  color: var(--m-ink);
  border-color: #9aa3ad;
  background: var(--m-tint);
}
.mod-action-resolve {
  color: #fff;
  padding: 6px 12px;
  border: 1px solid #a4453a;
  background: #a4453a;
  text-decoration: none;
}
.mod-action-resolve:hover {
  color: #fff;
  background: #8f3a30;
  border-color: #8f3a30;
}
.mod-action:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(90, 97, 104, 0.28);
}
.mod-action-resolve:focus-visible {
  box-shadow: 0 0 0 3px rgba(164, 69, 58, 0.32);
}

/* スマホ: テーブルを縦カードに崩す（横スクロール地獄を避ける） */
@media (max-width: 760px) {
  .moderation-head { padding: 18px 18px 15px; }
  .moderation-table thead { display: none; }
  .moderation-table,
  .moderation-table tbody,
  .moderation-table tr,
  .moderation-table td { display: block; width: 100%; }
  .moderation-table tbody tr {
    padding: 14px 16px;
    border-bottom: 1px solid var(--m-line);
  }
  .moderation-table tbody tr:last-child { border-bottom: 0; }
  .moderation-table tbody td {
    padding: 0 0 8px;
    border: 0;
  }
  .moderation-table tbody td:last-child { padding-bottom: 0; }
  .moderation-table .col-type { margin-bottom: 4px; }
  /* メタ（通報者・理由・日時）にラベルを補う */
  .moderation-table .col-reporter::before { content: "通報者: "; color: var(--m-muted); font-size: 12px; }
  .moderation-table .col-date::before { content: "日時: "; color: var(--m-muted); }
  .moderation-table .col-reason,
  .moderation-table .col-reporter,
  .moderation-table .col-date { display: inline-block; width: auto; margin-right: 14px; }
  .moderation-table .col-actions {
    text-align: left;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--m-line);
    white-space: normal;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .mod-action {
    justify-content: center;
    white-space: nowrap;
    flex: 1 1 auto;
    padding: 9px 12px;
  }
  .mod-action-view { margin-right: 0; margin-bottom: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .moderation-row,
  .mod-action,
  .type-badge,
  .reason-tag { transition: none; }
}

/* ============================================================
   Sprint 6.2 — ラウンジ補助チャット「静かな熱量・フロー型」
   ------------------------------------------------------------
   Tone: ラウンジ（掲示板＝ストック型）の "対の場所"。こちらはフロー型
   だが、Discord 的な高速・賑やかさの逆を行く「いまちょっと雑談」する
   静かな縁側。世界観は Sprint 5.2 ラウンジと地続き — 温かい紙、髪の毛
   ほどの罫、ごく淡い暖色のにじみ。原色の赤・ビビッドな吹き出しは使わない。

   設計の勘所:
   - 会話の "背骨"：左に細い縦線を一本通し、メッセージが下に積み上がる
     連なりを示す（5.2 コメント節と同じ語彙）。賑やかな箱の羅列にしない。
   - 自分の発言は右へ寄せるが、吹き出しは "灯る紙"。相手は静かな紙。
     本人（推し）の発言だけ clay の灯をともす（5.1 と同トーン）。
   - 新着は "そっと着地" する（フェード＋わずかな浮上）。流れる速さを
     演出しない＝静かな熱量。上を読んでいる時は追わず "新着" ピルで知らせる。
   - 削除/通報は 6 / 6.1 と同じアイコン体系（ゴミ箱・盾・旗）、ホバーで開く。
   - すべて --color-* / 5.x トークン経由でプリセット・ダークに追従。
   ------------------------------------------------------------ */
:root {
  --chat-hair:  color-mix(in oklab, var(--color-line) 64%, transparent);
  --chat-quiet: color-mix(in oklab, var(--color-text) 5%, var(--color-card));
  --chat-ease:  cubic-bezier(0.22, 0.61, 0.36, 1);
  /* 相手の吹き出し＝静かな紙。自分＝紙に灯がともる淡い暖色。 */
  --chat-bubble:      color-mix(in oklab, var(--color-paper) 42%, var(--color-card));
  --chat-bubble-mine: color-mix(in oklab, var(--color-accent) 12%, var(--color-card));
  --chat-bubble-edge: color-mix(in oklab, var(--color-line) 78%, transparent);
}

/* ---- ラウンジ詳細 / チャットの 2 タブ（スレッド ⇔ チャット）----
   生のアンダーラインではなく、紙の上の "薄い帯" を切り替えるトーンに。
   ラウンジ＝積み上がる場所 / チャット＝流れる場所、を一本の罫の上で並べる。 */
.lounge-tabs,
.chat-tabs {
  display: inline-flex;
  gap: 4px;
  margin: 14px 0 20px;
  padding: 4px;
  background: var(--chat-quiet);
  border: 1px solid var(--chat-hair);
  border-radius: 999px;
}
.lounge-tab,
.chat-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 18px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.05em;
  color: var(--color-text-dim);
  text-decoration: none;
  transition: color .18s ease, background .2s var(--chat-ease), box-shadow .2s ease;
}
.lounge-tab::before,
.chat-tab::before {
  /* 場所を示す小さな印：流れ（チャット）/ 積み上げ（スレッド）の気配だけ */
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-muted) 55%, transparent);
  transition: background .18s ease, box-shadow .2s ease;
}
.lounge-tab:hover,
.chat-tab:hover {
  color: var(--color-text);
}
.lounge-tab.is-active,
.chat-tab.is-active {
  color: var(--color-text);
  background: var(--color-card);
  box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--chat-hair);
}
.lounge-tab.is-active::before,
.chat-tab.is-active::before {
  background: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 18%, transparent);
}

/* ============================================================
   チャット画面 — アプリシェル内に "縁側" として収める
   ============================================================ */
.chat-page {
  position: relative;
  display: flex;
  flex-direction: column;
  /* 入力欄を下に固定し、リストだけ内側でスクロールする縦の器 */
  height: calc(100vh - 132px);
  min-height: 420px;
}

/* ---- ヘッダ（パンくず・見出し・タブ）---- */
.chat-head { flex: 0 0 auto; }
.chat-breadcrumb {
  margin: 0 0 8px;
  font-size: 12px;
  letter-spacing: 0.04em;
}
.chat-breadcrumb a {
  color: var(--color-text-dim);
  border-bottom: 1px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.chat-breadcrumb a:hover {
  color: var(--color-text);
  border-bottom-color: color-mix(in oklab, var(--color-accent) 55%, transparent);
}
.chat-title {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 500;
  letter-spacing: 0.035em;
  line-height: 1.2;
  margin: 0;
  color: var(--color-text);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
}
.chat-title-lounge {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--color-muted);
}
.chat-title-lounge::before {
  content: "in ";
  font-family: var(--font-latin);
  font-style: italic;
  opacity: 0.7;
}

/* ---- スクロールするメッセージの器 ---- */
.chat-scroll {
  position: relative;
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  padding: 18px 20px 8px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 4%, var(--color-card)) 0%,
      var(--color-card) 22%);
  border: 1px solid var(--chat-hair);
  border-radius: var(--radius-lg);
  /* 上端で内容がフェードして "上にまだ続く" 気配を出す */
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--color-line-strong, var(--color-line)) 70%, transparent) transparent;
}
.chat-scroll::-webkit-scrollbar { width: 9px; }
.chat-scroll::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--color-line-strong, var(--color-line)) 60%, transparent);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: padding-box;
}

.chat-loadmore {
  text-align: center;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 4px 0 12px;
}
.chat-loadmore[hidden] { display: none; }

/* ---- 空状態（冷たくしない・縁側で待つトーン）---- */
.chat-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
  margin: 0;
  padding: 48px 24px;
  color: var(--color-text-dim);
}
.chat-empty-sigil {
  display: inline-flex;
  width: 34px; height: 34px;
  margin-bottom: 8px;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  opacity: 0.82;
}
.chat-empty-sigil svg { width: 100%; height: 100%; }
.chat-empty-lead {
  font-family: var(--font-display);
  font-size: 17px;
  letter-spacing: 0.04em;
  color: var(--color-text);
}
.chat-empty-sub {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--color-text-dim);
  max-width: 34ch;
}

/* ---- メッセージリスト — 会話の "背骨" を一本通す ---- */
.chat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}
/* 左にアバター中心を貫く細い縦線（積み上がる連なり・5.2 と同語彙）。
   自分の発言は右寄せなので線からは離れる＝"自分は対岸" の感覚。 */
.chat-list::before {
  content: "";
  position: absolute;
  left: 17px; top: 20px; bottom: 14px;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--chat-hair) 8%, var(--chat-hair) 92%, transparent);
  pointer-events: none;
}

.chat-msg {
  display: flex;
  gap: 12px;
  padding: 9px 2px;
  align-items: flex-start;
  position: relative;
}
.chat-msg.is-mine {
  flex-direction: row-reverse;
}

/* アバター — 紙で縁取り、背骨の上に乗る丸 */
.chat-avatar {
  flex: 0 0 36px;
  width: 36px; height: 36px;
  border-radius: 50%;
  overflow: hidden;
  position: relative;
  z-index: 1;
  background: var(--color-card);
  box-shadow: 0 0 0 3px var(--color-card), 0 0 0 4px var(--chat-hair);
}
.chat-avatar img,
.chat-avatar-fallback {
  width: 100%; height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  object-fit: cover;
}
.chat-avatar-fallback {
  background: linear-gradient(140deg,
    color-mix(in oklab, var(--color-accent) 28%, var(--color-card)),
    color-mix(in oklab, var(--color-accent) 12%, var(--color-card)));
  color: color-mix(in oklab, var(--color-accent) 68%, var(--color-text));
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
}
/* 本人（推し）のアバターは clay の輪で灯す */
.chat-msg.is-owner .chat-avatar {
  box-shadow: 0 0 0 3px var(--color-card), 0 0 0 4px var(--owner-line);
}

.chat-body {
  max-width: min(72%, 560px);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 1px;
}
.chat-msg.is-mine .chat-body { align-items: flex-end; }

.chat-meta {
  display: flex;
  align-items: baseline;
  gap: 4px 9px;
  font-size: 11.5px;
  color: var(--color-muted);
}
.chat-msg.is-mine .chat-meta { flex-direction: row-reverse; }
.chat-author {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 13px;
  color: var(--color-text);
}
.chat-time {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--color-muted);
}

/* ---- 本人バッジ — 5.1 の .owner-badge と同トーン（heart つき）---- */
.chat-owner-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px 1px 6px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 0.06em;
  color: var(--owner-on);
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--owner) 88%, #fff 12%),
    var(--owner));
  border: 1px solid color-mix(in oklab, var(--owner-deep) 55%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in oklab, #fff 30%, transparent), 0 1px 6px var(--owner-glow);
  white-space: nowrap;
}
.chat-owner-badge[hidden] { display: none; }
.chat-owner-badge::before {
  content: "";
  width: 8px; height: 8px;
  flex: 0 0 auto;
  background: currentColor;
  -webkit-mask: var(--owner-heart) center / contain no-repeat;
          mask: var(--owner-heart) center / contain no-repeat;
  opacity: 0.92;
}

/* ---- 吹き出し本文 ---- */
.chat-text {
  display: inline-block;
  max-width: 100%;
  padding: 9px 13px;
  border-radius: 4px 14px 14px 14px;
  background: var(--chat-bubble);
  border: 1px solid var(--chat-bubble-edge);
  color: color-mix(in oklab, var(--color-text) 94%, var(--color-muted));
  font-size: 14px;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
  text-align: left;
  box-shadow: var(--shadow-sm);
}
/* 自分の発言＝紙に灯がともる暖色。角は反転して "自分側" を示す。 */
.chat-msg.is-mine .chat-text {
  border-radius: 14px 4px 14px 14px;
  background: var(--chat-bubble-mine);
  border-color: color-mix(in oklab, var(--color-accent) 26%, var(--chat-bubble-edge));
  color: var(--color-text);
}
/* 本人（推し）の発言＝clay の灯。左に細い縁、淡い暖色のにじみ。 */
.chat-msg.is-owner .chat-text {
  background: color-mix(in oklab, var(--owner) 9%, var(--color-card));
  border-color: var(--owner-line);
}
.chat-msg.is-owner:not(.is-mine) .chat-text {
  box-shadow: var(--shadow-sm), inset 2px 0 0 color-mix(in oklab, var(--owner) 60%, transparent);
}

/* 新着の "そっと着地" — フェード＋わずかな浮上。一度だけ。 */
.chat-msg.is-arriving {
  animation: chat-arrive .42s var(--chat-ease) both;
}
@keyframes chat-arrive {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- メタ行のアクション（削除・通報）---- */
.chat-actions {
  display: flex;
  align-items: center;
  gap: 1px;
  margin-top: 1px;
  /* 普段は気配だけ。行 hover でそっと開く＝賑やかにしない。 */
  opacity: 0;
  transition: opacity .18s ease;
}
.chat-msg.is-mine .chat-actions { justify-content: flex-end; }
.chat-msg:hover .chat-actions,
.chat-msg:focus-within .chat-actions { opacity: 1; }

/* 削除/通報ボタンは 6 / 6.1 の .post-delete-btn / .report-btn 文法を継承。
   ここではチャットの行に馴染むよう、サイズだけ一段小さく揃える。 */
.chat-delete-btn,
.chat-report-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  padding: 4px 6px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  line-height: 1;
  cursor: pointer;
  opacity: 0.85;
  -webkit-appearance: none;
  appearance: none;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease, opacity .18s ease;
}
.chat-delete-btn .del-ic,
.chat-report-btn .report-ic {
  width: 14px; height: 14px;
  flex: 0 0 auto;
  display: block;
  transition: transform .2s var(--chat-ease);
}
.chat-delete-btn .del-label,
.chat-report-btn .report-label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-weight: 500;
  transition: max-width .26s var(--chat-ease), opacity .18s ease, margin .26s ease;
}
/* 通報（旗・スレート）= 知らせる */
.chat-report-btn:hover,
.chat-report-btn:focus-visible {
  opacity: 1;
  color: var(--report-ink);
  border-color: var(--report-edge);
  background: var(--report-soft);
  outline: none;
}
.chat-report-btn:hover .report-label,
.chat-report-btn:focus-visible .report-label { max-width: 6rem; opacity: 1; margin-left: 1px; }
.chat-report-btn:hover .report-ic,
.chat-report-btn:focus-visible .report-ic { transform: translateY(-0.5px) rotate(-3deg); }
.chat-report-btn:focus-visible { box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px var(--report-edge); }

/* 削除（本人＝ゴミ箱 / clay） */
.chat-delete-btn.is-self:hover,
.chat-delete-btn.is-self:focus-visible {
  opacity: 1;
  color: var(--del-self);
  border-color: color-mix(in oklab, var(--color-danger) 32%, transparent);
  background: var(--del-self-soft);
  outline: none;
}
/* 削除（モデレーター＝盾 / 戒めの炭テラコッタ） */
.chat-delete-btn.is-mod {
  color: color-mix(in oklab, var(--del-mod) 70%, var(--color-muted));
}
.chat-delete-btn.is-mod .del-ic { fill: color-mix(in oklab, var(--del-mod) 14%, transparent); }
.chat-delete-btn.is-mod:hover,
.chat-delete-btn.is-mod:focus-visible {
  opacity: 1;
  color: var(--del-mod);
  border-color: var(--del-mod-edge);
  background: var(--del-mod-soft);
  outline: none;
}
.chat-delete-btn.is-mod:hover .del-ic,
.chat-delete-btn.is-mod:focus-visible .del-ic { fill: color-mix(in oklab, var(--del-mod) 24%, transparent); }
.chat-delete-btn:hover .del-label,
.chat-delete-btn:focus-visible .del-label { max-width: 14rem; opacity: 1; margin-left: 1px; }
.chat-delete-btn:hover .del-ic,
.chat-delete-btn:focus-visible .del-ic { transform: translateY(-0.5px); }
.chat-delete-btn.is-self:focus-visible {
  box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px color-mix(in oklab, var(--color-danger) 38%, transparent);
}
.chat-delete-btn.is-mod:focus-visible {
  box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px color-mix(in oklab, var(--del-mod) 40%, transparent);
}
.chat-delete-btn:active,
.chat-report-btn:active { transform: translateY(0.5px); }

/* ============================================================
   "新着" ピル — 上を読んでいる時に下から来た新着をそっと知らせる
   （最下部にいる時は出ない。追従しすぎない配慮の視覚フィードバック）
   ============================================================ */
.chat-jump {
  position: absolute;
  left: 50%;
  /* composer（高さ + 上マージン）の少し上に浮かせる */
  bottom: 92px;
  transform: translate(-50%, 8px);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px 7px 12px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 34%, var(--chat-hair));
  border-radius: 999px;
  background: color-mix(in oklab, var(--color-accent) 9%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 46%, var(--color-text));
  font-family: var(--font-display);
  font-size: 12.5px;
  letter-spacing: 0.05em;
  cursor: pointer;
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  z-index: 4;
  transition: opacity .22s ease, transform .26s var(--chat-ease), background .15s ease, color .15s ease;
}
.chat-jump[hidden] { display: none; }
.chat-jump.is-shown {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.chat-jump:hover {
  background: color-mix(in oklab, var(--color-accent) 16%, var(--color-card));
  color: var(--color-text);
}
.chat-jump:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.chat-jump-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 45%, transparent);
  animation: chat-jump-pulse 1.8s var(--chat-ease) infinite;
}
@keyframes chat-jump-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 42%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in oklab, var(--color-accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 0%, transparent); }
}
.chat-jump-ic { width: 14px; height: 14px; }

/* ============================================================
   下部固定の入力欄（composer）
   ============================================================ */
.chat-composer {
  flex: 0 0 auto;
  display: flex;
  gap: 10px;
  margin-top: 14px;
  align-items: flex-end;
  padding: 10px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 4%, var(--color-card)) 0%,
      var(--color-card) 70%);
  border: 1px solid var(--chat-hair);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.chat-composer:focus-within {
  border-color: color-mix(in oklab, var(--color-accent) 40%, var(--chat-hair));
  box-shadow: var(--shadow-sm), 0 0 0 3px color-mix(in oklab, var(--color-accent) 14%, transparent);
}
.chat-input {
  flex: 1 1 auto;
  min-width: 0;
  resize: none;
  border: 0;
  background: none;
  padding: 7px 6px 7px 8px;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.6;
  max-height: 140px;
}
.chat-input:focus { outline: none; }
.chat-input::placeholder { color: var(--color-muted); }

.chat-send {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--color-accent) 92%, #fff 8%),
    var(--color-accent));
  color: #fff;
  border: 1px solid color-mix(in oklab, var(--color-accent) 70%, var(--color-text) 30%);
  border-radius: 999px;
  padding: 9px 20px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.08em;
  cursor: pointer;
  box-shadow: inset 0 1px 0 color-mix(in oklab, #fff 26%, transparent), var(--shadow-sm);
  transition: transform .16s var(--chat-ease), box-shadow .18s ease, filter .18s ease;
}
.chat-send:hover {
  filter: brightness(1.04);
  box-shadow: inset 0 1px 0 color-mix(in oklab, #fff 30%, transparent), var(--shadow);
}
.chat-send:active { transform: translateY(1px); }
.chat-send:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.chat-send:disabled { opacity: 0.5; cursor: default; filter: none; box-shadow: none; }

/* 未ログイン時の誘導 — 突き放さない静かな招待 */
.chat-login-prompt {
  flex: 0 0 auto;
  margin-top: 14px;
  padding: 16px 18px;
  text-align: center;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--color-text-dim);
  background: var(--chat-quiet);
  border: 1px dashed color-mix(in oklab, var(--color-line) 82%, var(--color-text) 8%);
  border-radius: var(--radius-lg);
}
.chat-login-prompt a {
  font-weight: 600;
  color: color-mix(in oklab, var(--color-accent) 72%, var(--color-text));
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 45%, transparent);
}
.chat-login-prompt a:hover { color: var(--color-text); }

/* ============================================================
   レスポンシブ — スマホ中心（bottom nav と干渉しない高さに）
   ============================================================ */
@media (max-width: 720px) {
  .chat-page {
    /* スマホは bottom nav 分を差し引く（余裕を持たせる） */
    height: calc(100vh - 168px);
    min-height: 360px;
  }
  .chat-title { font-size: 22px; }
  .chat-scroll { padding: 14px 13px 6px; }
  .chat-list::before { left: 15px; }
  .chat-avatar { flex-basis: 32px; width: 32px; height: 32px; }
  .chat-body { max-width: 80%; }
  .chat-msg { gap: 10px; }
  .chat-send { padding: 9px 16px; }
  /* タッチ端末ではアクションを常時ほのかに出す（hover が無いため） */
  .lounge-tabs, .chat-tabs { display: flex; }
}

/* タッチ主体（hover 不可）: アクションは常時うっすら見せて押せると伝える */
@media (hover: none) {
  .chat-actions { opacity: 0.7; }
}

@media (prefers-reduced-motion: reduce) {
  .chat-msg.is-arriving { animation: none; }
  .chat-jump,
  .chat-jump-dot,
  .chat-actions,
  .chat-delete-btn,
  .chat-report-btn,
  .chat-delete-btn .del-ic,
  .chat-report-btn .report-ic,
  .chat-delete-btn .del-label,
  .chat-report-btn .report-label,
  .chat-send,
  .lounge-tab,
  .chat-tab { transition: none; animation: none; }
  .chat-scroll { scroll-behavior: auto; }
}

/* ============================================================
   残課題片付け: /admin/roles 説明列の折返し改善
   説明セルが極端に狭まり1文字ずつ縦折返しになるのを防ぐ。
   [data-roles-table] でロール一覧テーブルのみにスコープ限定。
   ============================================================ */
[data-roles-table] .role-desc-cell {
  min-width: 8rem;
  max-width: 15rem;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}
/* この一覧はカラム数が多いので、セル左右パディングと操作リンク間隔を詰める */
[data-roles-table] > tbody > tr > td,
[data-roles-table] > thead > tr > th { padding-left: 11px; padding-right: 11px; }
[data-roles-table] td.text-end .btn { margin-left: 11px; }

/* ============================================================
   Sprint 8.3 — ロール管理 UI 磨き込み
   ・rank / 権限フラグ / 並び替えボタンの脱 Bootstrap 原色
   ・9 列テーブルの収まり（ロール名折返し防止・列幅配分）
   ・編集フォームの権限フラグを "能力カード" に
   既存 Quiet Lounge トーン（paper / amber / moss / clay）に地続き。
   ============================================================ */

/* --- 一覧テーブルの列幅配分（窮屈さの解消） --- */
[data-roles-table] { table-layout: auto; width: 100%; }
[data-roles-table] th.col-num,
[data-roles-table] td.col-num {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}
[data-roles-table] td.col-num .cell-count {
  font-family: var(--font-latin);
  font-weight: 600;
  color: var(--text);
  margin-right: 1px;
}
[data-roles-table] th.col-reorder,
[data-roles-table] td.col-reorder { width: 1%; white-space: nowrap; }

/* ロール一覧のスクロールラッパ。広幅では overflow を切らず、紐付け popover を
   セルの外へはみ出して表示できるようにする。狭幅のみ横スクロールに切り替える
   （Bootstrap .table-responsive の overflow-x:auto は popover を縦横ともクリップするため使わない）。 */
.roles-table-scroll,
.lounges-table-scroll { overflow: visible; }
@media (max-width: 720px) {
  .roles-table-scroll,
  .lounges-table-scroll { overflow-x: auto; }
}

/* --- 紐付けチケットのホバー popover（CSS のみ・Bootstrap JS 非依存） --- */
.mapping-pop {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  cursor: default;
  border-radius: 5px;
  outline: none;
}
.mapping-pop[data-mapping-pop] {
  text-decoration: underline dotted color-mix(in oklab, var(--color-text) 28%, transparent);
  text-underline-offset: 3px;
}
.mapping-pop:focus-visible {
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-accent, var(--color-text)) 45%, transparent);
}
.mapping-pop-card {
  position: absolute;
  top: calc(100% + 7px);
  right: 0;
  z-index: 40;
  min-width: 200px;
  max-width: 320px;
  padding: 11px 13px;
  text-align: left;
  white-space: normal;
  background: var(--color-card);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  box-shadow: var(--shadow-md, 0 10px 30px rgba(0, 0, 0, 0.18));
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.mapping-pop-card::before {
  content: "";
  position: absolute;
  top: -5px;
  right: 14px;
  width: 9px;
  height: 9px;
  background: var(--color-card);
  border-left: 1px solid var(--line-strong);
  border-top: 1px solid var(--line-strong);
  transform: rotate(45deg);
}
.mapping-pop:hover .mapping-pop-card,
.mapping-pop:focus .mapping-pop-card,
.mapping-pop:focus-within .mapping-pop-card {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.mapping-pop-head {
  display: block;
  margin-bottom: 7px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.mapping-pop-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.mapping-pop-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.35;
}
.mapping-pop-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.mapping-pop-meta {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--font-latin);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}
.mapping-pop-code {
  color: color-mix(in oklab, var(--color-text) 45%, transparent);
  word-break: break-all;
}

/* ロール名 + slug を 2 段に。slug 列を畳んで横幅を確保する。 */
[data-roles-table] td.role-cell { white-space: nowrap; }
[data-roles-table] .role-cell-name {
  display: flex;
  align-items: center;
  gap: 7px;
}
[data-roles-table] .role-name { white-space: nowrap; }
[data-roles-table] .role-cell .badge.text-bg-secondary { margin-left: 0; }
[data-roles-table] code.role-slug {
  display: inline-block;
  margin-top: 4px;
  font-size: 11px;
  padding: 1px 7px;
}

/* --- card-panel 内の注意バッジ：原色 amber → clay の控えめな警告 --- */
.card-panel .badge.text-bg-warning {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--clay-600) 60%, var(--text)) !important;
  background: color-mix(in oklab, var(--clay-600) 12%, var(--color-paper)) !important;
  border: 1px solid color-mix(in oklab, var(--clay-600) 34%, transparent);
}

/* --- 権限バッジ群（5 列目=権限）：縦積みで揃えて並べる ---
   バッジが 4 種まで増えたので、面ごとに 1 行の縦スタックにして
   どの能力が立っているかを上から順に読めるようにする。
   （generator は :nth-child(6)=並び替え列を誤指定していたため 5 列目へ修正） */
[data-roles-table] td:nth-child(5) {
  white-space: normal;
  min-width: 8.5rem;
}
[data-roles-table] td:nth-child(5) .badge {
  display: flex;
  width: fit-content;
  margin: 0 0 5px;
}
[data-roles-table] td:nth-child(5) .badge:last-child {
  margin-bottom: 0;
}

/* モデレーションバッジ：原色青 → clay（owner 系の権威色と差別化した
   "対応者" の落ち着いた赤茶）。view-all（moss）と並べて調和させる。 */
.card-panel .badge.text-bg-primary,
.badge[data-moderation-badge] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: color-mix(in oklab, var(--clay-600) 52%, var(--text)) !important;
  background: color-mix(in oklab, var(--clay-600) 12%, var(--color-paper)) !important;
  border: 1px solid color-mix(in oklab, var(--clay-600) 30%, transparent);
}
.badge[data-moderation-badge]::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--clay-600);
  flex: 0 0 auto;
}

/* 投稿可バッジ：原色緑 → amber（"発言できる" 灯りのトーン）。
   全 3 種が paper の上で別々の落ち着いた色相に分かれて読み分けられる。 */
.card-panel .badge.text-bg-success,
.badge[data-can-post-badge] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: color-mix(in oklab, var(--amber-700) 78%, var(--text)) !important;
  background: color-mix(in oklab, var(--amber-600) 13%, var(--color-paper)) !important;
  border: 1px solid color-mix(in oklab, var(--amber-600) 36%, transparent);
}
.badge[data-can-post-badge]::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--amber-600);
  flex: 0 0 auto;
}

/* タイムライン投稿可バッジ（sprint-19）：フォーラム投稿可（amber）と対になる
   発信面の色＝plum。モデレーション（clay）とも全投稿閲覧（moss）とも色相が分かれ、
   能力バッジ 4 種が paper の上で互いに読み分けられる。
   generator が付けた text-bg-warning（clay）の一般指定を data 属性で上書きする。 */
.card-panel .badge.text-bg-warning[data-can-post-timeline-badge],
.badge[data-can-post-timeline-badge] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 0;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: color-mix(in oklab, var(--plum-600) 58%, var(--text)) !important;
  background: color-mix(in oklab, var(--plum-600) 13%, var(--color-paper)) !important;
  border: 1px solid color-mix(in oklab, var(--plum-600) 32%, transparent);
}
.badge[data-can-post-timeline-badge]::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--plum-600);
  flex: 0 0 auto;
}

/* --- 並び替え：上下の小さな三角ボタンを縦に積む --- */
.reorder-group {
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  overflow: hidden;
  background: var(--color-paper);
}
.reorder-group .reorder-btn,
.reorder-group form { margin: 0; }
.reorder-group form { display: block; }
.reorder-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 100%;
  padding: 4px 9px;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-latin);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background .14s ease, color .14s ease;
}
.reorder-group .reorder-btn + .reorder-btn,
.reorder-group form + form .reorder-btn,
.reorder-group .reorder-btn + form .reorder-btn {
  border-top: 1px solid var(--line);
}
/* postLink は <form><a> 構造なので、隣接する form 間に区切り線を引く */
.reorder-group > form + form .reorder-btn,
.reorder-group > .reorder-btn + form .reorder-btn,
.reorder-group > form + .reorder-btn { border-top: 1px solid var(--line); }
.reorder-btn svg { width: 11px; height: 11px; flex: 0 0 auto; }
.reorder-btn:hover {
  background: color-mix(in oklab, var(--color-accent) 12%, var(--color-paper));
  color: color-mix(in oklab, var(--color-accent) 55%, var(--text));
  text-decoration: none;
}
.reorder-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.reorder-btn[disabled] {
  color: color-mix(in oklab, var(--muted) 55%, transparent);
  cursor: not-allowed;
  background: color-mix(in oklab, var(--color-text) 3%, var(--color-paper));
}
.reorder-btn[disabled]:hover {
  background: color-mix(in oklab, var(--color-text) 3%, var(--color-paper));
  color: color-mix(in oklab, var(--muted) 55%, transparent);
}

/* --- 並び順の凡例：本文ではなく "覚え書き" の小さな注記に --- */
[data-roles-rank-legend] {
  margin: 2px 0 20px;
  padding: 11px 14px;
  border-left: 2px solid color-mix(in oklab, var(--color-accent) 55%, var(--line-strong));
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-paper));
  border-radius: 0 7px 7px 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-dim);
}
[data-roles-rank-legend] strong { color: var(--text); font-weight: 600; }

@media (max-width: 720px) {
  .reorder-btn .reorder-label { display: none; }
  .reorder-btn { padding: 6px 8px; }
}

/* ============================================================
   Sprint 8.3 — ロール編集フォーム：権限フラグを能力カードに
   3 つのフラグを枠付きの行に分け、各能力の意味を読みやすく。
   ============================================================ */
.role-form-flags {
  margin: 0 0 22px;
  padding: 0;
  border: 0;
}
.role-form-flags > legend.form-label {
  float: none;
  width: auto;
  margin-bottom: 10px;
  font-size: 12px;
}
.role-flag {
  display: grid;
  grid-template-columns: auto auto 1fr;
  column-gap: 12px;
  row-gap: 2px;
  align-items: start;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--color-paper);
  transition: border-color .15s ease, background .15s ease;
}
.role-flag + .role-flag { margin-top: 10px; }
.role-flag:hover { border-color: var(--line-strong); }
.role-flag:has(.form-check-input:checked) {
  border-color: color-mix(in oklab, var(--color-accent) 38%, var(--line-strong));
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-paper));
}
.role-flag .form-check-input {
  grid-row: 1 / span 2;
  align-self: center;
  margin: 0;
  width: 1.15em; height: 1.15em;
}
/* Bootstrap の青チェックを Quiet Lounge の amber に統一（原色排除） */
.role-flag .form-check-input:checked {
  background-color: var(--color-accent) !important;
  border-color: var(--color-accent) !important;
}
/* 各能力のアイコン章標。未チェックは静かに沈め、チェックで色相が灯る。 */
.role-flag-mark {
  grid-row: 1 / span 2;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: 8px;
  color: var(--muted);
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-paper));
  box-shadow: inset 0 0 0 1px var(--line);
  transition: color .18s ease, background .18s ease, box-shadow .18s ease;
}
.role-flag-mark svg { width: 17px; height: 17px; }
.role-flag .form-check-label {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}
.role-flag .form-text {
  grid-column: 3;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
}

/* 章標の色相は能力ごとに分ける（バッジの色相と対応）。
   閲覧=moss / モデレーション=clay / フォーラム投稿=amber / タイムライン投稿=plum。
   チェック時のみ点灯し、4 つの能力が地続きだが別物として読める。 */
.role-flag[data-flag="view-all"]:has(.form-check-input:checked)   { border-color: color-mix(in oklab, var(--moss-600) 34%, var(--line-strong)); background: color-mix(in oklab, var(--moss-600) 5%, var(--color-paper)); }
.role-flag[data-flag="moderation"]:has(.form-check-input:checked) { border-color: color-mix(in oklab, var(--clay-600) 32%, var(--line-strong)); background: color-mix(in oklab, var(--clay-600) 5%, var(--color-paper)); }
.role-flag[data-flag="forum"]:has(.form-check-input:checked)      { border-color: color-mix(in oklab, var(--amber-600) 40%, var(--line-strong)); background: color-mix(in oklab, var(--amber-600) 6%, var(--color-paper)); }
.role-flag[data-flag="timeline"]:has(.form-check-input:checked)   { border-color: color-mix(in oklab, var(--plum-600) 38%, var(--line-strong)); background: color-mix(in oklab, var(--plum-600) 6%, var(--color-paper)); }

.role-flag[data-flag="view-all"]:has(.form-check-input:checked) .role-flag-mark   { color: color-mix(in oklab, var(--moss-600) 64%, var(--text)); background: color-mix(in oklab, var(--moss-600) 13%, var(--color-paper)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--moss-600) 30%, transparent); }
.role-flag[data-flag="moderation"]:has(.form-check-input:checked) .role-flag-mark { color: color-mix(in oklab, var(--clay-600) 60%, var(--text)); background: color-mix(in oklab, var(--clay-600) 13%, var(--color-paper)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--clay-600) 28%, transparent); }
.role-flag[data-flag="forum"]:has(.form-check-input:checked) .role-flag-mark      { color: color-mix(in oklab, var(--amber-700) 78%, var(--text)); background: color-mix(in oklab, var(--amber-600) 15%, var(--color-paper)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--amber-600) 34%, transparent); }
.role-flag[data-flag="timeline"]:has(.form-check-input:checked) .role-flag-mark   { color: color-mix(in oklab, var(--plum-600) 70%, var(--text)); background: color-mix(in oklab, var(--plum-600) 14%, var(--color-paper)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--plum-600) 32%, transparent); }

/* チェック時はチェックボックス自身も能力色に合わせる（amber 一律をやめる） */
.role-flag[data-flag="view-all"]:has(.form-check-input:checked) .form-check-input   { background-color: var(--moss-600) !important; border-color: var(--moss-600) !important; }
.role-flag[data-flag="moderation"]:has(.form-check-input:checked) .form-check-input { background-color: var(--clay-600) !important; border-color: var(--clay-600) !important; }
.role-flag[data-flag="timeline"]:has(.form-check-input:checked) .form-check-input   { background-color: var(--plum-600) !important; border-color: var(--plum-600) !important; }

/* どこに書ける投稿かを示す小さな面ラベル（ラウンジ / ホーム） */
.role-flag-where {
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 1px 7px;
  border-radius: 999px;
  color: var(--muted);
  background: color-mix(in oklab, var(--color-text) 5%, var(--color-paper));
  box-shadow: inset 0 0 0 1px var(--line);
}
.role-flag[data-flag="forum"]:has(.form-check-input:checked) .role-flag-where {
  color: color-mix(in oklab, var(--amber-700) 72%, var(--text));
  background: color-mix(in oklab, var(--amber-600) 14%, var(--color-paper));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--amber-600) 32%, transparent);
}
.role-flag[data-flag="timeline"]:has(.form-check-input:checked) .role-flag-where {
  color: color-mix(in oklab, var(--plum-600) 66%, var(--text));
  background: color-mix(in oklab, var(--plum-600) 13%, var(--color-paper));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--plum-600) 30%, transparent);
}

/* 2 つの投稿系カードを「投稿できる面」サブグループとして括る。
   左に静かな縦の界線を引き、フォーラム / タイムラインが同種だが別面と読ませる。 */
.role-flag-group {
  margin-top: 10px;
  padding-left: 14px;
  border-left: 2px solid color-mix(in oklab, var(--line-strong) 70%, transparent);
}
.role-flag-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 2px 0 9px;
}
.role-flag-group-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: none;
  color: var(--text-dim);
}
.role-flag-group-note {
  font-size: 11.5px;
  color: var(--muted);
}
.role-flag-group .role-flag:first-of-type { margin-top: 0; }

/* 編集不可フィールド（システムロールの slug）の "ロック" 表現 */
.role-form .form-control:disabled,
.role-form input.form-control[disabled] {
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-paper));
  color: var(--text-dim);
  border-style: dashed;
  cursor: not-allowed;
}
.role-locked-note {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
}
.role-locked-note svg { width: 13px; height: 13px; flex: 0 0 auto; }

/* ============================================================
   Sprint 8.4 — 管理ラウンジ編集：参加できるロール設定
   8.3 のロール権限カード（.role-flag）と体裁を統一。
   各ロールを枠付きカードにし、選択状態を amber で示す（原色青を排除）。
   ============================================================ */
.lounge-roles {
  margin: 0 0 22px;
  padding: 0;
  border: 0;
}
.lounge-roles > legend.form-label {
  float: none;
  width: auto;
  margin-bottom: 10px;
  font-size: 12px;
}

/* 説明＋現在の公開範囲の導入ブロック */
.lounge-roles-intro {
  margin-bottom: 14px;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: color-mix(in oklab, var(--color-text) 2.5%, var(--color-paper));
}
.lounge-roles-lead {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim);
}
.lounge-roles-lead strong { color: var(--text); font-weight: 600; }

/* 現在の公開範囲：ラベル＋バッジ＋補足を 1 行のステータスバーに */
.lounge-visibility-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 9px;
}
.lounge-visibility-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-transform: uppercase;
  font-family: var(--font-latin);
}
.lounge-visibility-status .badge { margin-left: 0; }
.lounge-visibility-hint {
  flex: 1 1 100%;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}

/* ロールカードのグリッド（賑わいすぎないよう最大 2 列） */
.role-checkbox-group {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

/* 各ロール：8.3 の .role-flag を踏襲（チェック＋見出し＋説明の入れ子グリッド） */
.lounge-role {
  display: grid;
  grid-template-columns: auto 1fr auto;
  column-gap: 11px;
  row-gap: 3px;
  align-items: center;
  margin: 0;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--color-paper);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.lounge-role:hover { border-color: var(--line-strong); }
.lounge-role:has(.form-check-input:checked) {
  border-color: color-mix(in oklab, var(--color-accent) 38%, var(--line-strong));
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-paper));
}
.lounge-role .form-check-input {
  grid-row: 1 / span 2;
  align-self: center;
  margin: 0;
  width: 1.15em; height: 1.15em;
  cursor: pointer;
}
.lounge-role .form-check-input:checked {
  background-color: var(--color-accent) !important;
  border-color: var(--color-accent) !important;
}
.lounge-role-name {
  grid-column: 2;
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 7px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.lounge-role-slug {
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--muted);
}
.lounge-role-desc {
  grid-column: 2;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* 全ラウンジ参加可（grants_view_all）ロール：moss トーンの常時バッジ。
   設定不能であることを淡く示し、チェックが任意なことを伝える。 */
.lounge-role-always.badge {
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  margin-left: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  color: color-mix(in oklab, var(--moss-600) 70%, var(--text)) !important;
  background: color-mix(in oklab, var(--moss-600) 12%, var(--color-paper)) !important;
  border: 1px solid color-mix(in oklab, var(--moss-600) 32%, transparent);
}
.lounge-role.is-always-on {
  background: color-mix(in oklab, var(--moss-600) 3%, var(--color-paper));
}
.lounge-role.is-always-on:has(.form-check-input:checked) {
  border-color: color-mix(in oklab, var(--color-accent) 38%, var(--line-strong));
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-paper));
}

.lounge-roles-note {
  margin: 12px 0 0;
  padding-left: 1px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
}

@media (max-width: 720px) {
  .role-checkbox-group { grid-template-columns: 1fr; }
}

/* 管理ラウンジ一覧：公開範囲バッジ列（restricted/public を一目で） */
.lounge-visibility-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.lounge-visibility-pill::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.lounge-visibility-pill[data-vis="restricted"] {
  color: color-mix(in oklab, var(--clay-600) 56%, var(--text));
  background: color-mix(in oklab, var(--clay-600) 12%, var(--color-paper));
  border: 1px solid color-mix(in oklab, var(--clay-600) 32%, transparent);
}
.lounge-visibility-pill[data-vis="restricted"]::before { background: var(--clay-600); }
.lounge-visibility-pill[data-vis="public"] {
  color: color-mix(in oklab, var(--moss-600) 64%, var(--text));
  background: color-mix(in oklab, var(--moss-600) 11%, var(--color-paper));
  border: 1px solid color-mix(in oklab, var(--moss-600) 30%, transparent);
}
.lounge-visibility-pill[data-vis="public"]::before { background: var(--moss-600); }

/* ============================================================
   Sprint 9.2: 初回セットアップウィザード（/setup・auth レイアウト）
   "Quiet Lounge" の editorial トーンに合わせた一気通貫ウィザード。
   ステッパー＝連続した道筋 / 各 step ＝ serif 見出し + hairline 節 /
   接続テスト＝admin の test-result chip と同語彙 / Step3 ＝ role←tickets。
   既存トークン（paper・ink・amber・moss・clay・font-display 等）のみ使用。
   ============================================================ */
/* 情報量が多いので auth-shell を広めに取る（generator が 560 に拡張済）*/
.auth-shell:has(.setup-wizard) {
  /* セットアップは PC 操作前提なので広めに。チケット一覧やフォームに余裕を持たせる。 */
  max-width: 760px;
}
/* チケット一覧は中央チケットが多くても扱えるよう検索＋スクロールに。 */
.setup-ticket-search {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 6px 0 12px;
}
.setup-ticket-search .form-control { flex: 1; }
.setup-ticket-count { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.setup-ticket-scroll {
  max-height: 44vh;
  overflow-y: auto;
  border: 1px solid var(--color-line);
  border-radius: 12px;
  padding: 6px;
}
.setup-ticket-scroll .setup-ticket-list { margin: 0; }

/* ---- ウェルカム導入（serif の歓迎・eyebrow は admin と同語彙）---- */
.setup-header {
  margin: 0 0 26px;
  text-align: center;
}
.setup-eyebrow {
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
}
.setup-title {
  font-family: var(--font-display);
  font-size: 1.42rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1.45;
  color: var(--color-text);
  margin: 0 0 14px;
}
.setup-lead {
  font-size: 0.86rem;
  color: var(--text-dim);
  margin: 0 auto;
  max-width: 38em;
  line-height: 1.75;
}
.setup-lead-em {
  font-weight: 600;
  color: var(--color-text);
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 55%, transparent);
  padding-bottom: 1px;
}

/* ---- ステップインジケーター：連なった道筋 ---- */
.setup-steps {
  --rail: color-mix(in oklab, var(--color-text) 14%, transparent);
  --rail-done: color-mix(in oklab, var(--moss-600) 60%, transparent);
  list-style: none;
  padding: 0;
  margin: 0 0 30px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.setup-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  text-align: center;
  padding: 2px 4px 0;
}
/* 連結レール（マーカー中心の高さに引く） */
.setup-step::before,
.setup-step::after {
  content: "";
  position: absolute;
  top: 15px;
  height: 1.5px;
  background: var(--rail);
  z-index: 0;
}
.setup-step::before { left: 0;   right: 50%; }
.setup-step::after  { left: 50%; right: 0;   }
.setup-step:first-child::before { display: none; }
.setup-step:last-child::after   { display: none; }
/* done より手前のレールは moss で「通ってきた道」に */
.setup-step--done::before,
.setup-step--done::after,
.setup-step--current::before {
  background: var(--rail-done);
}

.setup-step-marker {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-card);
  border: 1.5px solid var(--rail);
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.setup-step-num {
  font-family: var(--font-latin);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--color-text) 55%, transparent);
}
.setup-step-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.setup-step-kicker {
  font-family: var(--font-latin);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.setup-step-label {
  font-size: 0.74rem;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--color-text) 58%, transparent);
}

/* current = ink 充填 + amber halo（"いまここ"を強く） */
.setup-step--current .setup-step-marker {
  background: var(--color-text);
  border-color: var(--color-text);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-accent) 22%, transparent);
}
.setup-step--current .setup-step-num { color: var(--color-paper); }
.setup-step--current .setup-step-kicker { color: var(--color-accent); }
.setup-step--current .setup-step-label {
  color: var(--color-text);
  font-weight: 600;
}
/* done = moss 充填 + チェック */
.setup-step--done .setup-step-marker {
  background: var(--moss-600);
  border-color: var(--moss-600);
}
.setup-step--done .setup-step-num { color: #fff; }
.setup-step--done .setup-step-kicker { color: color-mix(in oklab, var(--moss-600) 80%, var(--color-text)); }
.setup-step--done .setup-step-label { color: var(--text-dim); }

/* ---- step 本文（serif 見出し + eyebrow）---- */
.setup-pane { animation: setup-pane-in 0.32s ease-out both; }
@keyframes setup-pane-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.setup-pane-eyebrow {
  font-family: var(--font-latin);
  font-size: 10px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0 0 8px;
}
.setup-pane-title {
  font-family: var(--font-display);
  font-size: 1.12rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  line-height: 1.5;
  color: var(--color-text);
  margin: 0 0 12px;
}
.setup-pane-desc {
  font-size: 0.84rem;
  line-height: 1.72;
  color: var(--text-dim);
  margin: 0 0 16px;
}

/* スーパー管理者の確定＝ceremonial な注記 */
.setup-note {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  font-size: 0.82rem;
  line-height: 1.65;
  color: var(--text-dim);
  margin: 0 0 22px;
  padding: 13px 15px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--color-accent) 7%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-accent) 24%, transparent);
  border-left: 2px solid var(--color-accent);
}
.setup-note strong { color: var(--color-text); font-weight: 600; }
.setup-note-glyph {
  flex-shrink: 0;
  font-size: 11px;
  line-height: 1.6;
  color: color-mix(in oklab, var(--color-accent) 80%, var(--color-text));
}

/* ---- hairline 節（fieldset）---- */
.setup-fieldset {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 18px 16px;
  margin: 0 0 18px;
  background: color-mix(in oklab, var(--color-card) 80%, var(--color-paper));
}
.setup-fieldset legend {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-display);
  font-size: 0.86rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  width: auto;
  padding: 0 9px;
  color: var(--color-text);
}
.setup-legend-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0;
  background: color-mix(in oklab, var(--color-accent) 18%, var(--color-paper));
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--color-accent) 35%, transparent);
}
.setup-fieldhint {
  font-size: 12px;
  color: var(--muted);
  margin: 4px 0 0;
  line-height: 1.6;
}
.setup-fieldhint--standalone { margin: -6px 0 16px; }

/* 接続テスト行（chip は admin/settings/api と同じ test-result 語彙）*/
.setup-test-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 6px 0 2px;
}
.setup-test-result.test-result { letter-spacing: 0.02em; }

/* 確定済みバナー */
.setup-confirmed {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 0.83rem;
  font-weight: 600;
  color: color-mix(in oklab, var(--moss-600) 70%, var(--color-text) 30%);
  margin: 2px 0 14px;
  padding: 11px 14px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--moss-600) 12%, var(--color-paper));
  border: 1px solid color-mix(in oklab, var(--moss-600) 32%, transparent);
}
.setup-confirmed-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px; height: 19px;
  border-radius: 50%;
  background: var(--moss-600);
  color: #fff;
  font-size: 11px;
  flex-shrink: 0;
}

/* ---- チケット選択リスト ---- */
.setup-ticket-list {
  list-style: none;
  padding: 0;
  margin: 0 0 6px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.setup-ticket-label {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--color-card);
  cursor: pointer;
  transition: border-color 0.16s ease, background 0.16s ease, box-shadow 0.16s ease;
}
/* 実際の checkbox は label の外（兄弟）に置き視覚的に隠す。
   label[for] が唯一のクリック面となるため、ネスト由来の二重トグルが起きない。*/
.setup-ticket-input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  margin: 0;
  pointer-events: none;
}
.setup-ticket-check {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 6px;
  border: 1.5px solid var(--line-strong);
  background: #fff;
  color: #fff;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
}
.setup-ticket-check svg {
  width: 13px; height: 13px;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.16s ease, transform 0.16s ease;
}
.setup-ticket-body {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
}
.setup-ticket-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--color-text);
}
.setup-ticket-code {
  margin-left: auto;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  font-family: var(--font-mono, monospace);
  color: var(--muted);
  white-space: nowrap;
}
/* Setup-context key-line: same ID-chip → code ranking as the admin
   screens, sized for the tighter wizard card and right-aligned. */
.setup-ticket-code.ticket-keyline {
  font-family: inherit;
  letter-spacing: normal;
  gap: 7px;
}
.setup-ticket-code .ticket-id-key {
  font-size: 9.5px;
  padding: 2px 5.5px;
}
.setup-ticket-code .ticket-code-sub {
  font-size: 0.68rem;
}
/* On the moss-tinted selected card, lift the ID chip toward the accent. */
.setup-ticket-input:checked + .setup-ticket-label .ticket-id-key {
  color: color-mix(in oklab, var(--moss-600) 62%, var(--color-text) 38%);
  border-color: color-mix(in oklab, var(--moss-600) 42%, transparent);
  background: color-mix(in oklab, var(--moss-600) 12%, transparent);
}
.setup-ticket-input:checked + .setup-ticket-label .ticket-code-sub {
  color: var(--color-text-dim);
}
.setup-ticket-label:hover .ticket-id-key {
  border-color: color-mix(in oklab, var(--moss-600) 30%, var(--color-text) 14%);
}
.setup-ticket-label:hover {
  border-color: color-mix(in oklab, var(--moss-600) 40%, var(--line));
  box-shadow: var(--shadow-sm);
}
.setup-ticket-label:hover .setup-ticket-check {
  border-color: color-mix(in oklab, var(--moss-600) 55%, var(--line-strong));
}
.setup-ticket-input:focus-visible + .setup-ticket-label .setup-ticket-check {
  border-color: var(--moss-600);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--moss-600) 24%, transparent);
}
.setup-ticket-input:checked + .setup-ticket-label {
  border-color: color-mix(in oklab, var(--moss-600) 55%, transparent);
  background: color-mix(in oklab, var(--moss-600) 8%, var(--color-card));
}
.setup-ticket-input:checked + .setup-ticket-label .setup-ticket-check {
  background: var(--moss-600);
  border-color: var(--moss-600);
}
.setup-ticket-input:checked + .setup-ticket-label .setup-ticket-check svg {
  opacity: 1;
  transform: scale(1);
}

.setup-empty {
  font-size: 0.83rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0;
  padding: 12px 0;
}

/* ---- Step3：role ← tickets の対応カード ---- */
.setup-mapping-caption {
  font-family: var(--font-latin);
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 10px;
}
.setup-mapping {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: 18px;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--moss-600) 5%, var(--color-card)) 0%,
      var(--color-card) 100%);
  box-shadow: var(--shadow-sm);
  margin: 0 0 22px;
}
.setup-mapping--empty {
  grid-template-columns: auto auto 1fr;
}
.setup-mapping-role {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 104px;
  padding-right: 4px;
}
.setup-mapping-role-badge {
  align-self: flex-start;
  font-family: var(--font-latin);
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-paper);
  background: var(--moss-600);
  padding: 2px 7px;
  border-radius: 999px;
  margin-bottom: 4px;
}
.setup-mapping-role-name {
  font-family: var(--font-mono, monospace);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.02em;
  color: var(--color-text);
}
.setup-mapping-role-sub {
  font-size: 0.72rem;
  color: var(--muted);
}
.setup-mapping-arrow {
  display: inline-flex;
  align-items: center;
  color: color-mix(in oklab, var(--moss-600) 60%, var(--color-text) 40%);
}
.setup-mapping-arrow svg { width: 46px; height: 20px; }
.setup-mapping-tickets { min-width: 0; }
.setup-mapping-ticket-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.setup-mapping-ticket {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: 9px;
  row-gap: 1px;
  font-size: 0.85rem;
}
.setup-mapping-ticket-dot {
  grid-row: 1;
  flex-shrink: 0;
  align-self: center;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--moss-600);
}
.setup-mapping-ticket .setup-ticket-name { grid-column: 2; line-height: 1.45; }
/* code は名前の下段へ（横並びで名前を潰さない）*/
.setup-mapping-ticket .setup-ticket-code {
  grid-column: 2;
  margin-left: 0;
}
.setup-mapping--empty .setup-empty { padding: 0; }

/* ---- 前進ボタンの矢印マイクロインタラクション ---- */
.setup-advance { margin-top: 4px; }
.setup-advance-arrow { transition: transform 0.18s ease; }
.setup-advance:hover .setup-advance-arrow:not([disabled]) { transform: translateX(3px); }
.setup-finish { margin-top: 6px; }
.setup-finish-note {
  text-align: center;
  font-size: 11.5px;
  color: var(--muted);
  letter-spacing: 0.02em;
  margin: 14px 0 0;
}

/* ---- 狭い画面（auth-shell の外側パディングで既に余裕がある） ---- */
@media (max-width: 480px) {
  .setup-step-kicker { display: none; }
  .setup-step-label { font-size: 0.68rem; }
  .setup-mapping {
    grid-template-columns: 1fr;
    gap: 12px;
    text-align: left;
  }
  .setup-mapping-arrow { transform: rotate(90deg); justify-self: start; }
  .setup-mapping-arrow svg { width: 30px; }
}

/* ============================================================
   Sprint 9.3: スーパー管理者 譲渡画面
   ------------------------------------------------------------
   Concept — "受け渡す（the handover, weighed）"
   全権限を手放す不可逆操作。Quiet Lounge の暖色トークンを保ちつつ、
   危険色（clay）を "緊張の糸" として段階的に強める。原色の赤は使わず、
   紙に灯る重さで「気軽に押せない / しかし安心して託せる」トーンを作る。
   ローカル token alias（このブロック内だけで使う）。 */
.transfer-select,
.transfer-confirm,
.transfer-notice {
  --tf-danger:      var(--color-danger, #b65a4a);
  --tf-danger-deep: color-mix(in oklab, var(--color-danger, #b65a4a) 72%, var(--color-text) 28%);
  --tf-danger-tint: color-mix(in oklab, var(--color-danger, #b65a4a) 8%, var(--color-card) 92%);
  --tf-danger-line: color-mix(in oklab, var(--color-danger, #b65a4a) 36%, var(--color-line) 64%);
}

/* ---- lead: 失う側であることを一言で締める ---- */
.transfer-lead strong {
  color: color-mix(in oklab, var(--color-danger, #b65a4a) 64%, var(--color-text) 36%);
  font-weight: 600;
  border-bottom: 1.5px solid color-mix(in oklab, var(--color-danger, #b65a4a) 40%, transparent);
  padding-bottom: 1px;
}

/* ============================================================
   候補一覧 — 選べる "台帳の行"
   ============================================================ */
.transfer-candidates {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.transfer-candidate-label {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px 13px 18px;
  background: var(--color-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
  transition: border-color .18s ease, background .18s ease, box-shadow .18s ease, transform .05s ease;
}
/* 左に細い "選択リール"。未選択は透明、ホバー/選択でゴールド→クレイへ */
.transfer-candidate-label::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: transparent;
  transition: background .18s ease;
}
.transfer-candidate-label:hover {
  border-color: var(--line-strong);
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-card) 95%);
}
.transfer-candidate-label:hover::before {
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line));
}

/* ネイティブ radio は隠し、avatar の枠を擬似ラジオとして使う */
.transfer-candidate-radio {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  pointer-events: none;
}

/* イニシャル・アバター（兼・選択インジケータ） */
.transfer-candidate-avatar {
  flex-shrink: 0;
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  color: var(--text-dim);
  background: color-mix(in oklab, var(--color-paper) 60%, var(--color-card) 40%);
  border: 1px solid var(--line-strong);
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}

.transfer-candidate-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.transfer-candidate-name {
  font-size: 14.5px;
  color: var(--color-text);
  letter-spacing: 0.01em;
  transition: font-weight .05s ease;
}
.transfer-candidate-login {
  font-family: var(--font-latin);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--muted);
}
/* 候補のロール名（最上位ロール）を少し濃く示す */
.transfer-candidate-role {
  color: var(--color-text);
  font-weight: 600;
}

/* 一般設定 最下部の控えめな譲渡リンク（サイドナビには出さない・本人のみ） */
.settings-transfer-link {
  margin-top: 1.5rem;
  text-align: right;
  font-size: 12.5px;
}
.settings-transfer-link a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.settings-transfer-link a:hover {
  color: var(--color-danger, var(--color-text));
}

/* 選択チェック（既定は非表示、選択時にフェードイン） */
.transfer-candidate-check {
  flex-shrink: 0;
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  color: var(--color-paper);
  background: var(--tf-danger);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity .18s ease, transform .22s cubic-bezier(.34,1.56,.64,1);
}
.transfer-candidate-check svg { width: 13px; height: 13px; }

/* --- 選択状態：行全体がクレイの "確定行" に --- */
.transfer-candidate-radio:checked ~ .transfer-candidate-check {
  opacity: 1;
  transform: scale(1);
}
.transfer-candidate-radio:checked + .transfer-candidate-avatar {
  background: var(--tf-danger);
  border-color: var(--tf-danger);
  color: var(--color-paper);
}
/* checked の行 = label。:has で行全体を着色（対応ブラウザ）。
   非対応でも avatar/check の変化で選択は十分伝わる。 */
.transfer-candidate-label:has(.transfer-candidate-radio:checked) {
  border-color: var(--tf-danger-line);
  background: var(--tf-danger-tint);
}
.transfer-candidate-label:has(.transfer-candidate-radio:checked)::before {
  background: var(--tf-danger);
}
.transfer-candidate-label:has(.transfer-candidate-radio:checked) .transfer-candidate-name {
  font-weight: 600;
}

/* キーボードフォーカス（radio が隠れているので label に可視リングを出す） */
.transfer-candidate-label:focus-within {
  border-color: var(--tf-danger-line);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-danger, #b65a4a) 22%, transparent);
}

/* 「確認へ進む」ボタン：disabled 時は "まだ選んでいない" と分かる静けさ */
#transfer-select-btn { margin-top: 2px; }
#transfer-select-btn:not(:disabled) {
  background: var(--color-text);
  border-color: var(--color-text);
}

/* ============================================================
   確認ステップ — 受け渡しの "証文"
   ============================================================ */
.transfer-confirm {
  /* 全体に重みを足す：紙より一段濃いクレイの縁取り＋わずかな影 */
  border-color: var(--tf-danger-line);
  box-shadow:
    var(--shadow-sm),
    0 18px 40px -28px color-mix(in oklab, var(--color-danger, #b65a4a) 55%, transparent);
  padding-left: 34px;
}
/* 左端の太いクレイ・レール（card 全高） */
.transfer-confirm-rail {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  border-radius: var(--radius) 0 0 var(--radius);
  background: linear-gradient(180deg,
    var(--tf-danger) 0%,
    var(--tf-danger-deep) 100%);
}
.transfer-confirm .panel-header { align-items: baseline; }
/* "取り消せません" タグ：声高でなく、刻印のような小さな札 */
.transfer-irreversible-tag {
  flex-shrink: 0;
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--tf-danger-deep);
  background: var(--tf-danger-tint);
  border: 1px solid var(--tf-danger-line);
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

/* --- from → to バトン --- */
.transfer-summary {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: 0;
  margin: 20px 0 22px;
}
.transfer-party {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 18px;
  background: color-mix(in oklab, var(--color-paper) 45%, var(--color-card) 55%);
  border: 1px solid var(--line);
}
.transfer-party--from { border-radius: var(--radius) 0 0 var(--radius); border-right: none; }
.transfer-party--to {
  border-radius: 0 var(--radius) var(--radius) 0;
  border-left: none;
  background: var(--tf-danger-tint);
  border-color: var(--tf-danger-line);
}
.transfer-summary dt {
  font-family: var(--font-latin);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.transfer-summary dd {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.transfer-party-avatar {
  flex-shrink: 0;
  width: 40px; height: 40px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  color: var(--text-dim);
  background: var(--color-card);
  border: 1px solid var(--line-strong);
}
.transfer-party-avatar--to {
  color: var(--color-paper);
  background: var(--tf-danger);
  border-color: var(--tf-danger);
}
.transfer-party-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.transfer-party-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.transfer-party-role {
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--muted);
}
.transfer-party--from .transfer-party-role {
  color: var(--tf-danger-deep);
}
.confirm-to-login { font-family: var(--font-latin); }

/* バトンの矢印（中央の引き渡し動作） */
.transfer-baton-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  color: var(--tf-danger);
  background: var(--color-card);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.transfer-baton-arrow svg { width: 36px; height: 22px; }

/* --- 失うものの明示（alert-danger を "証文の注記" に整える） --- */
.transfer-consequence {
  align-items: flex-start;
  line-height: 1.7;
  background: var(--tf-danger-tint);
  border-color: var(--tf-danger-line);
}
/* テキストを 1 つのブロックに閉じ込め、flex 子の min-content 化による
   "1 文字ずつ折返し" を防ぐ（alert の ::before バーは保持）。 */
.transfer-consequence-text {
  flex: 1 1 auto;
  min-width: 0;
}
.transfer-consequence strong {
  color: var(--tf-danger-deep);
}

/* --- 実行アクション：重い赤、キャンセルが穏やかな既定 --- */
.transfer-confirm-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.transfer-confirm-actions #transfer-execute-btn {
  padding: 11px 22px;
  font-weight: 600;
  box-shadow: 0 10px 24px -14px color-mix(in oklab, var(--color-danger, #b65a4a) 80%, transparent);
}
.transfer-confirm-actions #transfer-execute-btn:hover {
  box-shadow: 0 12px 26px -12px color-mix(in oklab, var(--color-danger, #b65a4a) 85%, transparent);
}

/* ============================================================
   空 / 未確定 状態 — エラーではなく "静かな案内"
   ============================================================ */
.transfer-notice {
  display: flex;
  gap: 18px;
  align-items: flex-start;
}
.transfer-notice-mark {
  flex-shrink: 0;
  width: 40px; height: 40px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim);
  background: color-mix(in oklab, var(--color-paper) 55%, var(--color-card) 45%);
  border: 1px solid var(--line-strong);
  margin-top: 2px;
}
.transfer-notice-mark svg { width: 20px; height: 20px; }
.transfer-notice-body { flex: 1; min-width: 0; }
.transfer-notice-body .panel-header { margin-bottom: 4px; }
.transfer-notice-body p { margin-bottom: 0; }

/* ============================================================
   レスポンシブ（<= 560px）：バトンを縦積みに
   ============================================================ */
@media (max-width: 560px) {
  .transfer-summary {
    grid-template-columns: 1fr;
  }
  .transfer-party--from {
    border-radius: var(--radius) var(--radius) 0 0;
    border-right: 1px solid var(--line);
    border-bottom: none;
  }
  .transfer-party--to {
    border-radius: 0 0 var(--radius) var(--radius);
    border-left: 1px solid var(--tf-danger-line);
    border-top: none;
  }
  .transfer-baton-arrow {
    border-top: none;
    border-bottom: none;
    border-left: 1px solid var(--line);
    border-right: 1px solid var(--line);
    padding: 6px 0;
  }
  .transfer-baton-arrow svg { transform: rotate(90deg); }
  .transfer-confirm-actions { flex-direction: column; align-items: stretch; }
  .transfer-confirm-actions .btn { justify-content: center; width: 100%; }
  .transfer-confirm-actions form { width: 100%; }
  .transfer-confirm-actions form .btn { width: 100%; }
}

/* 動きを抑える設定の尊重 */
@media (prefers-reduced-motion: reduce) {
  .transfer-candidate-label,
  .transfer-candidate-check,
  .transfer-candidate-avatar { transition: none; }
}

/* ============================================================
   MEMBERS ADMIN (sprint-14 会員管理: 一覧 / 詳細 / BAN)
   既存トークン（--color-*）由来の色のみ使い、原色ベタ塗りは避ける。
   BAN 中の状態色は本人強調と被らない控えめな赤系（clay-600）で。
   ============================================================ */

/* 個人情報制約などの注意ボックス（運営向け・「責めない・先回りの案内」トーン）。
   警告ではなく "そういう仕組みです" と静かに伝える便箋のような佇まいに。 */
.info-note {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin: 0 0 22px;
  padding: 13px 16px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 20%, var(--color-line));
  border-left: 3px solid color-mix(in oklab, var(--color-accent) 46%, var(--color-line));
  border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-card));
  color: var(--color-text-dim);
  font-size: 13px;
  line-height: 1.68;
}
.info-note-icon {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 2px;
  color: color-mix(in oklab, var(--color-accent) 78%, var(--color-text));
}

/* 検索 / ロールフィルタのバー — 入力欄は本文の "input chrome"（4px・白地）に揃える */
.members-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  margin-bottom: 22px;
}
.members-filter-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.members-filter-field .form-control,
.members-filter-field .form-select {
  min-width: 220px;
  border-radius: var(--radius-sm);
}
.members-filter-label {
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
}
.members-filter-actions {
  display: flex;
  gap: 8px;
}

.members-table-scroll { overflow-x: auto; }

/* 会員行の本人セル（avatar + 表示名） */
.member-identity {
  display: flex;
  align-items: center;
  gap: 11px;
}
.member-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  background: color-mix(in oklab, var(--color-text) 6%, var(--color-card));
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-text) 10%, transparent);
}
.member-avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 落ち着いた墨色のグラデで "顔のない人" を上品に。原色は使わない。 */
  background: linear-gradient(150deg,
    color-mix(in oklab, var(--color-text) 36%, var(--color-card)),
    color-mix(in oklab, var(--color-text) 22%, var(--color-card)));
  color: var(--color-card);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.02em;
  box-shadow: none;
}
.member-name {
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
}
.member-name:hover { color: var(--color-accent); }

/* 最終ログイン列は等幅数字で縦に揃える（日時が読みやすい） */
.member-lastlogin {
  font-family: var(--font-latin);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* ロール / チケットのチップ（閲覧専用に見える静的表示・折り返さない） */
.role-pill {
  display: inline-block;
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  background: color-mix(in oklab, var(--color-accent) 13%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 72%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--color-accent) 26%, var(--color-line));
}
.role-pill.is-none {
  background: var(--color-card);
  color: var(--color-muted);
  border-color: var(--color-line);
  font-weight: 500;
}
.ticket-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 5px;
  max-width: 280px;
}
.ticket-chip {
  display: inline-block;
  padding: 2px 9px;
  border-radius: var(--radius-sm);
  font-size: 11.5px;
  background: color-mix(in oklab, var(--color-text) 5%, var(--color-card));
  color: var(--color-text-dim);
  border: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
}

/* 状態バッジ（通常 / BAN 中）。一目で分かるが、原色の警報色にはしない。
   通常 = 地に沈む小さな印 / BAN = ドット付きの控えめな clay。 */
.state-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.state-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
}
.state-active {
  background: color-mix(in oklab, var(--moss-600) 8%, var(--color-card));
  color: color-mix(in oklab, var(--moss-600) 52%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--moss-600) 26%, var(--color-line));
}
.state-active::before { background: var(--moss-600); }
.state-banned {
  background: color-mix(in oklab, var(--clay-600) 14%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 80%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--clay-600) 42%, var(--color-line));
}
.state-banned::before { background: var(--clay-600); }

/* BAN 中の会員行は地でも区別する。本人強調(owner)とは別物の "停止" として、
   左に clay の細い帯を立て、名前はわずかに沈ませる（賑やかにしない）。 */
tr.is-banned > td {
  background: color-mix(in oklab, var(--clay-600) 5%, var(--color-card));
}
tr.is-banned > td:first-child {
  box-shadow: inset 3px 0 0 color-mix(in oklab, var(--clay-600) 55%, transparent);
}
tr.is-banned .member-name {
  color: var(--color-text-dim);
}
tr.is-banned .member-avatar {
  filter: grayscale(0.5);
  opacity: 0.85;
}

/* ページャ — 既存 .pagination は他画面で整っているので余白だけ家風に */
.members-pager {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
}
.members-pager .pagination {
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 8px;
}
.members-pager-counter {
  font-family: var(--font-latin);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  margin: 0;
}

/* 操作セル（詳細リンク）— 既存ロール表と同じ "静かなテキストリンク" に揃える */
[data-members-table] td.text-end .btn {
  --bs-btn-padding-y: 0;
  --bs-btn-padding-x: 0;
  display: inline-flex;
  align-items: center;
  padding: 4px 2px;
  border: 0;
  background: none;
  box-shadow: none;
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.01em;
  color: var(--color-text-dim);
  border-radius: 0;
  transition: color .15s ease;
}
[data-members-table] td.text-end .btn:hover {
  background: none;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- 会員詳細 ---- */
.member-detail-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 16px;
}
.member-detail-head h1 { margin: 0; }
/* 共有の .back-link（gap ホバー演出付き）をそのまま使い、
   詳細ヘッダ内での回り込みだけ調整する（グローバル定義は上書きしない）。 */
.member-detail-head .back-link { flex-basis: 100%; }

.member-detail-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 20px;
  margin-bottom: 20px;
}
@media (max-width: 860px) {
  .member-detail-grid { grid-template-columns: 1fr; }
}

.member-profile {
  display: flex;
  gap: 18px;
  align-items: flex-start;
}
.member-profile-avatar {
  width: 66px;
  height: 66px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-text) 10%, transparent),
              0 6px 16px -10px rgba(20, 16, 8, 0.4);
}
.member-profile-avatar.member-avatar-fallback {
  font-size: 27px;
  box-shadow: 0 6px 16px -10px rgba(20, 16, 8, 0.4);
}
.member-fields {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 18px;
  margin: 0;
  flex: 1;
}
.member-fields dt {
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
  padding: 9px 0;
  align-self: center;
}
.member-fields dd {
  margin: 0;
  padding: 9px 0;
  font-size: 13.5px;
  color: var(--color-text);
}
.member-fields dt + dd { align-self: center; }
.member-fields dt:not(:first-of-type),
.member-fields dt:not(:first-of-type) + dd {
  border-top: 1px solid color-mix(in oklab, var(--color-line) 60%, transparent);
}
.field-readonly-hint {
  font-size: 11px;
  color: var(--color-muted);
  margin-left: 8px;
}

/* BAN 操作パネル — 「重い操作」として、パネル全体に静かな緊張感を持たせる。 */
.member-ban-panel .panel-header h2 {
  position: relative;
  padding-left: 14px;
}
.member-ban-panel .panel-header h2::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 14px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--clay-600) 70%, transparent);
}
.ban-status {
  padding: 13px 15px;
  border-radius: var(--radius-sm);
  margin-bottom: 16px;
}
.ban-status p { margin: 0 0 5px; }
.ban-status p:last-child { margin-bottom: 0; }
.ban-status-active {
  background: color-mix(in oklab, var(--clay-600) 9%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--clay-600) 36%, var(--color-line));
  border-left: 3px solid var(--clay-600);
}
.ban-status-line strong { color: color-mix(in oklab, var(--clay-600) 78%, var(--color-text)); }
.ban-status-blocked {
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-card));
  border: 1px solid var(--color-line);
  color: var(--color-text-dim);
  font-size: 13.5px;
}
.ban-status-blocked p { margin: 0; }
.ban-status-meta,
.ban-status-reason { font-size: 12.5px; color: var(--color-text-dim); }

.ban-form { margin-bottom: 14px; }
/* BAN 理由テキストエリアは "メモ帳" の佇まいで気軽すぎず */
.ban-form textarea.form-control { line-height: 1.6; }
/* BAN ボタン = 軽い色面のボタンではなく "枠線＋塗り" の決断ボタンに。
   ホバーで初めてベタ塗りになり、押す手前で一拍置く感覚を作る。 */
.member-ban-panel .btn-danger {
  background: color-mix(in oklab, var(--color-danger) 12%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-danger) 55%, var(--color-line));
  color: color-mix(in oklab, var(--color-danger) 82%, var(--color-text));
  font-weight: 600;
  letter-spacing: 0.02em;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.member-ban-panel .btn-danger:hover:not([disabled]) {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: #fff;
}
.member-ban-panel .btn-danger[disabled] {
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-card));
  border-color: var(--color-line);
  color: var(--color-muted);
  opacity: 1;
}

.ban-caution {
  margin-top: 18px;
  padding: 13px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
  background: color-mix(in oklab, var(--color-text) 3%, var(--color-card));
}
.ban-caution-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 8px;
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--color-muted);
}
.ban-caution-head::before {
  content: "";
  width: 13px;
  height: 13px;
  flex: none;
  background: currentColor;
  -webkit-mask: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
  mask: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
}
.ban-caution-list {
  margin: 0;
  padding-left: 18px;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--color-text-dim);
}
.ban-caution-list li { margin-bottom: 5px; }
.ban-caution-list li:last-child { margin-bottom: 0; }
.ban-caution-list strong { color: color-mix(in oklab, var(--color-text) 88%, var(--clay-600)); }

/* 投稿・コメント履歴 — 中央に細い仕切りを立てた "対の台帳" として */
.history-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 32px;
}
.history-grid .history-col:first-child {
  padding-right: 32px;
  border-right: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
}
.history-grid .history-col:first-child + .history-col { margin-left: -32px; }
@media (max-width: 720px) {
  .history-grid { grid-template-columns: 1fr; gap: 8px; }
  .history-grid .history-col:first-child {
    padding-right: 0;
    padding-bottom: 18px;
    margin-bottom: 18px;
    border-right: 0;
    border-bottom: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
  }
  .history-grid .history-col:first-child + .history-col { margin-left: 0; }
}
.history-head {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  margin: 0 0 12px;
  color: var(--color-text);
}
.history-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 20px;
  padding: 0 7px;
  border-radius: 999px;
  font-family: var(--font-latin);
  font-size: 11.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: color-mix(in oklab, var(--color-accent) 13%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line));
}
.history-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.history-item {
  padding: 9px 0;
  border-bottom: 1px solid color-mix(in oklab, var(--color-line) 65%, transparent);
}
.history-item:last-child { border-bottom: none; }
.history-link { display: block; }
.history-body {
  display: block;
  color: var(--color-text);
  font-size: 13px;
  line-height: 1.55;
  transition: color .15s ease;
}
.history-link:hover .history-body { color: var(--color-accent); }
.history-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
  font-size: 11px;
  color: var(--color-muted);
}
.history-meta time {
  font-family: var(--font-latin);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.history-stat { font-variant-numeric: tabular-nums; }

/* =========================================================
   Sprint 16-A: 管理ダッシュボード — "観測卓 / Observation Desk"
   ---------------------------------------------------------
   コンセプト: 静かな研究室の観測卓。事業者が朝、机に向かって
   「今日のコミュニティの呼吸」を確認する場。数値は紙の上の
   インデックス、グラフは温度計、通報カードは小さな警鐘。
   ---------------------------------------------------------
   - paper / ink / amber / clay (Quiet Lounge) のトークンで構成
   - 通報強調は原色赤ではなく clay（テラコッタ）— モデレーション
     画面と地続きのトーン
   - 数値は display 体（Zen Old Mincho）で書物の組版のように
   - グラフは amber グラデと "今日" の pin マーカー（Sprint 12
     thread-pin-badge と語彙統一）
   ========================================================= */

/* リード文（h1 + p.lead の下）— 一段落の余白を取り、観測卓の
   "見出し" として静かに区切る */
.admin-dashboard-lede {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin: 8px 0 6px;
  color: var(--color-text-dim);
  font-size: 12.5px;
  letter-spacing: 0.02em;
}
.admin-dashboard-lede::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 1px;
  background: color-mix(in oklab, var(--color-accent) 45%, var(--color-line));
  flex: 0 0 auto;
  transform: translateY(-3px);
}
.admin-dashboard-lede .lede-now {
  font-family: var(--font-latin);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--color-text);
}

/* ====== A. サマリ統計カード ====== */
.dashboard-stats {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
  margin: 18px 0 28px;
}
@media (max-width: 1180px) {
  .dashboard-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .dashboard-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
}
@media (max-width: 420px) {
  .dashboard-stats { grid-template-columns: 1fr; }
}
.stat-card {
  position: relative;
  background: var(--color-card);
  border: 1px solid var(--color-line);
  border-radius: 10px;
  padding: 16px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  overflow: hidden;
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.stat-card:hover { border-color: var(--line-strong); }

/* 上部に走る極細のインジケーター線（観測卓の "ガラス天板の縁"） */
.stat-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--color-accent) 30%, transparent) 0%,
    color-mix(in oklab, var(--color-accent) 18%, transparent) 60%,
    transparent 100%);
  opacity: 0.85;
}

.stat-label {
  font-size: 11.5px;
  font-family: var(--font-latin);
  font-weight: 500;
  color: var(--color-text-dim);
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  gap: 8px;
  text-transform: uppercase;
}
.stat-label .stat-label-jp {
  font-family: var(--font-sans);
  text-transform: none;
  letter-spacing: 0.02em;
  font-weight: 500;
  color: var(--color-text);
  font-size: 12.5px;
}
.stat-label .stat-label-en {
  font-size: 10.5px;
  color: var(--color-muted);
  letter-spacing: 0.18em;
}

.stat-value {
  font-family: var(--font-display);
  font-size: 38px;
  font-weight: 500;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.stat-value .stat-unit {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 400;
  color: var(--color-muted);
  letter-spacing: 0.04em;
}
.stat-sub {
  font-size: 11.5px;
  color: var(--color-text-dim);
  line-height: 1.5;
  letter-spacing: 0.01em;
  margin-top: auto;
}

/* 通報カード（最後尾・観測卓の「警鐘」位置） */
.stat-card-reports {
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-card) 96%, var(--color-paper) 4%) 0%,
      var(--color-card) 100%);
}

/* 1 件以上 — clay（テラコッタ）のアラート。原色赤を避け
   モデレーション画面のトーンと地続きに */
.stat-card-reports.is-alert {
  border-color: color-mix(in oklab, var(--clay-600) 50%, var(--color-line));
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--clay-600) 9%, var(--color-card)) 0%,
      color-mix(in oklab, var(--clay-600) 4%, var(--color-card)) 100%);
}
.stat-card-reports.is-alert::before {
  background: linear-gradient(90deg,
    var(--clay-600) 0%,
    color-mix(in oklab, var(--clay-600) 60%, transparent) 70%,
    transparent 100%);
  opacity: 1;
  height: 2px;
}
.stat-card-reports.is-alert .stat-value {
  color: color-mix(in oklab, var(--clay-600) 72%, var(--color-text));
  font-weight: 600;
}
.stat-card-reports.is-alert .stat-sub {
  color: color-mix(in oklab, var(--clay-600) 68%, var(--color-text-dim));
  font-weight: 500;
}

/* 警鐘のドット（脈打つ呼吸）— サイレンではなく心拍 */
.stat-pulse {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--clay-600);
  margin-left: auto;
}
.stat-pulse-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--clay-600);
  box-shadow: 0 0 0 0 color-mix(in oklab, var(--clay-600) 60%, transparent);
  animation: stat-pulse 2.4s ease-out infinite;
}
@keyframes stat-pulse {
  0%   { box-shadow: 0 0 0 0   color-mix(in oklab, var(--clay-600) 55%, transparent); }
  70%  { box-shadow: 0 0 0 8px color-mix(in oklab, var(--clay-600) 0%,  transparent); }
  100% { box-shadow: 0 0 0 0   color-mix(in oklab, var(--clay-600) 0%,  transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .stat-pulse-dot { animation: none; }
}

/* 0 件 — 静かな moss（苔）。緑だが落ち着いた色 */
.stat-card-reports.is-calm {
  border-color: color-mix(in oklab, var(--moss-600) 28%, var(--color-line));
}
.stat-card-reports.is-calm::before {
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--moss-600) 40%, transparent) 0%,
    transparent 100%);
}
.stat-card-reports.is-calm .stat-value {
  color: color-mix(in oklab, var(--moss-600) 28%, var(--color-text));
}
.stat-card-reports.is-calm .stat-sub {
  color: color-mix(in oklab, var(--moss-600) 60%, var(--color-text-dim));
}
.stat-calm-mark {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--moss-600) 75%, var(--color-text-dim));
  margin-left: auto;
}
.stat-calm-mark::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: transparent;
  border: 1.5px solid color-mix(in oklab, var(--moss-600) 65%, var(--color-line));
}

/* ====== B. グラフ panel — "30 日の温度計" ====== */
.dashboard-chart-panel {
  margin-bottom: 22px;
  padding: 26px 30px 22px;
}
.dashboard-chart-panel .panel-header {
  align-items: baseline;
}
.dashboard-chart-panel .panel-header h2::after {
  content: "30d · forum messages";
  display: inline-block;
  margin-left: 12px;
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.dashboard-chart-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  flex-shrink: 0;
  white-space: nowrap;
}
.dashboard-chart-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.dashboard-chart-meta-item::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line));
}
.dashboard-chart-meta-item.is-today::before {
  background: var(--color-accent);
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--color-accent) 35%, transparent);
}
.dashboard-chart-wrap {
  position: relative;
  padding: 10px 0 0;
}
.dashboard-chart {
  width: 100%;
  height: 220px;
  display: block;
  overflow: visible;
}
.dashboard-chart-bar rect {
  fill: url(#dashboardChartFill);
  transition: fill 0.18s ease, opacity 0.18s ease;
  opacity: 0.86;
}
.dashboard-chart-bar:hover rect,
.dashboard-chart-bar:focus rect {
  opacity: 1;
  fill: color-mix(in oklab, var(--color-accent) 90%, var(--color-text) 8%);
}
.dashboard-chart-bar.is-today rect {
  fill: var(--color-accent);
  opacity: 1;
  filter: drop-shadow(0 1px 2px color-mix(in oklab, var(--color-accent) 35%, transparent));
}
/* 今日マーカー（バーの直上に小さな pin + 上から伸びる計測線） */
.dashboard-chart-today-mark {
  fill: var(--color-accent);
  stroke: var(--color-card);
  stroke-width: 1.5;
}
.dashboard-chart-today-axis {
  stroke: color-mix(in oklab, var(--color-accent) 45%, transparent);
  stroke-width: 1;
  stroke-dasharray: 1.5 2.5;
}
.dashboard-chart-grid {
  stroke: color-mix(in oklab, var(--color-line) 70%, transparent);
  stroke-width: 1;
  stroke-dasharray: 2 4;
}
.dashboard-chart-axis {
  stroke: color-mix(in oklab, var(--color-line-strong, var(--line-strong)) 80%, transparent);
  stroke-width: 1;
}
.dashboard-chart-xtick,
.dashboard-chart-ytick {
  fill: var(--color-muted);
  font-size: 10px;
  font-family: var(--font-latin, inherit);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.dashboard-chart-ytick { font-size: 9.5px; }
.dashboard-chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--color-card);
  color: var(--color-text);
  padding: 6px 10px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 25%, var(--line-strong));
  border-radius: 6px;
  font-family: var(--font-latin);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
  white-space: nowrap;
  transform: translate(-50%, -100%);
  box-shadow:
    0 1px 2px rgba(50, 40, 20, 0.06),
    0 8px 22px -8px rgba(50, 40, 20, 0.18);
  z-index: 5;
}
.dashboard-chart-tooltip::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -5px;
  transform: translateX(-50%) rotate(45deg);
  width: 8px;
  height: 8px;
  background: var(--color-card);
  border-right: 1px solid color-mix(in oklab, var(--color-accent) 25%, var(--line-strong));
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 25%, var(--line-strong));
}
.dashboard-chart-tooltip .tt-date {
  color: var(--color-text);
  font-weight: 500;
}
.dashboard-chart-tooltip .tt-count {
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  font-weight: 600;
  margin-left: 6px;
}

/* ====== C. 2 カラム grid（通報 / 新規会員） ====== */
.dashboard-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-bottom: 22px;
}
@media (max-width: 900px) {
  .dashboard-grid { grid-template-columns: 1fr; gap: 14px; }
}

.dashboard-list-panel { padding: 24px 26px; }
.dashboard-list-panel .panel-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.dashboard-list-panel .panel-divider {
  margin: 12px -26px 8px;
}

/* h2 横の通し番号（観測卓のラベル）。観測項目を 01〜04 で番号付け */
.dashboard-list-panel .panel-header h2,
.dashboard-chart-panel .panel-header h2,
.dashboard-messages-panel .panel-header h2 {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.dashboard-section-no {
  font-family: var(--font-latin);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--color-muted);
  text-transform: uppercase;
}
.dashboard-section-no::after {
  content: "";
  display: inline-block;
  width: 14px;
  height: 1px;
  background: color-mix(in oklab, var(--color-accent) 35%, var(--color-line));
  margin-left: 8px;
  vertical-align: 4px;
}

.panel-action {
  font-family: var(--font-latin);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text));
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: color 0.15s ease, gap 0.18s ease;
}
.panel-action::after {
  content: "→";
  font-family: var(--font-latin);
  font-size: 11px;
}
.panel-action:hover {
  color: var(--color-text);
  gap: 7px;
}

/* リスト共通 */
.dashboard-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.dashboard-list-item + .dashboard-list-item {
  border-top: 1px solid color-mix(in oklab, var(--color-line) 75%, transparent);
}
.dashboard-list-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 12px 13px 16px;
  color: var(--color-text);
  transition: background 0.14s ease, padding-left 0.18s ease;
  min-width: 0;
  border-radius: 6px;
}
.dashboard-list-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  height: 0;
  width: 2px;
  background: var(--color-accent);
  border-radius: 0 2px 2px 0;
  transition: height 0.18s ease, top 0.18s ease;
}
.dashboard-list-link:hover {
  background: color-mix(in oklab, var(--color-accent) 5%, transparent);
  color: var(--color-text);
  padding-left: 18px;
}
.dashboard-list-link:hover::before {
  height: 60%;
  top: 20%;
}
.dashboard-list-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1;
}
.dashboard-list-meta {
  font-family: var(--font-latin);
  font-size: 11px;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  letter-spacing: 0.02em;
}

/* 空状態 — 「静かさ」を担保 */
.dashboard-list-panel .empty-line,
.dashboard-messages-panel .empty-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 22px 4px 6px;
  color: var(--color-muted);
  font-size: 13px;
  letter-spacing: 0.01em;
}
.dashboard-list-panel .empty-line::before,
.dashboard-messages-panel .empty-line::before {
  content: "";
  display: inline-block;
  width: 18px;
  height: 1px;
  background: color-mix(in oklab, var(--color-accent) 40%, var(--color-line));
  flex: 0 0 auto;
}

/* === 通報リスト === */
.dashboard-reports .dashboard-list-link {
  justify-content: space-between;
  gap: 10px;
}
.dashboard-reports .dashboard-list-main {
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.dashboard-reports .report-type {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border-radius: 4px;
  background: color-mix(in oklab, var(--clay-600) 9%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 70%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--clay-600) 22%, transparent);
  white-space: nowrap;
}
.dashboard-reports .report-type::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
}
.dashboard-reports .report-reason {
  font-weight: 500;
  color: var(--color-text);
  font-size: 13.5px;
}
.dashboard-reports .report-target {
  font-family: var(--font-mono);
  color: var(--color-muted);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* === 会員リスト === */
.dashboard-members .dashboard-list-link { gap: 14px; }
.dashboard-member-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: color-mix(in oklab, var(--color-accent) 15%, var(--color-paper));
  border: 1px solid color-mix(in oklab, var(--color-accent) 18%, var(--color-line));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  flex-shrink: 0;
}
.dashboard-member-avatar-fallback { line-height: 1; }
.dashboard-member-name {
  font-weight: 600;
  color: var(--color-text);
  font-size: 13.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: 0.01em;
}
.dashboard-member-meta {
  font-family: var(--font-latin);
  font-size: 11px;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.dashboard-member-meta time { color: var(--color-text-dim); }

/* === 投稿リスト === */
.dashboard-messages-panel { padding: 24px 26px; margin-bottom: 22px; }
.dashboard-messages-panel .panel-divider { margin: 12px -26px 8px; }
.dashboard-messages .dashboard-list-link {
  align-items: flex-start;
  gap: 14px;
  padding: 14px 12px 14px 16px;
}
.dashboard-messages .dashboard-list-link:hover { padding-left: 18px; }
.dashboard-message-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: color-mix(in oklab, var(--color-accent) 15%, var(--color-paper));
  border: 1px solid color-mix(in oklab, var(--color-accent) 18%, var(--color-line));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  flex-shrink: 0;
  margin-top: 1px;
}
.dashboard-message-avatar-fallback { line-height: 1; }
.dashboard-message-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12.5px;
  margin-bottom: 3px;
}
.dashboard-message-author {
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
}
.dashboard-message-lounge {
  color: var(--color-text-dim);
  font-size: 12px;
}
.dashboard-message-lounge::before {
  content: "·";
  margin-right: 6px;
  color: var(--color-muted);
}
.dashboard-message-lounge-name {
  color: var(--color-text-dim);
}
/* Sprint 15 系のスレッド意匠（amber tint）と語彙統一 */
.dashboard-message-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--color-accent) 10%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--color-accent) 28%, transparent);
  line-height: 1;
}
.dashboard-message-tag::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-left: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg) translateY(-1px);
  opacity: 0.7;
}
.dashboard-message-time {
  margin-left: auto;
  color: var(--color-muted);
  font-family: var(--font-latin);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  letter-spacing: 0.02em;
}
.dashboard-message-excerpt {
  color: var(--color-text);
  font-size: 13.5px;
  line-height: 1.6;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  letter-spacing: 0.005em;
}

/* モバイルでの密度調整 */
@media (max-width: 720px) {
  .dashboard-chart-panel,
  .dashboard-list-panel,
  .dashboard-messages-panel { padding: 20px 18px; }
  .dashboard-list-panel .panel-divider,
  .dashboard-messages-panel .panel-divider { margin-left: -18px; margin-right: -18px; }
  .stat-value { font-size: 32px; }
  .dashboard-chart-panel .panel-header h2::after { display: none; }
}
@media (max-width: 420px) {
  .stat-card { padding: 14px 14px 16px; }
  .stat-value { font-size: 28px; }
  .dashboard-chart { height: 180px; }
}


/* ============================================================================
 * Sprint 16-B — 投稿管理（/admin/posts）— "観測卓 / Posts"
 *
 * Sprint 16-A ダッシュボードの「観測卓 / Observation Desk」コンセプトを
 * admin console の 2 つ目の引き出しとして継続。
 *
 * 言語語彙:
 *  - 数値は Zen Old Mincho（紙の組版）
 *  - ラベルは Latin smallcaps（11px / .1em letter-spacing）
 *  - セクション通し番号 01 / 02 / 03 / 04 / 05（観測の段取り）
 *  - clay 警鐘（削除済み / 通報未対応）／moss 平穏（公開中 / ピン留め）
 *  - 行 hover で左 accent ストライプが立ち上がる（ダッシュボードのリスト hover と語彙統一）
 *  - 「絞り込みパネル」は paper-tint で一段沈め、観測卓の作業卓面として表現
 * ========================================================================== */

/* ---------- 観測卓 lede（一覧 / 詳細共通） ---------- */
.admin-posts-lede {
  align-items: baseline;
  flex-wrap: wrap;
}
.admin-posts-lede-count {
  margin-left: auto;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-latin);
  letter-spacing: 0.06em;
  color: var(--color-text-dim);
}
.admin-posts-lede-count-num {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.admin-posts-lede-count-label {
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* ---------- 一覧パネル ---------- */
.admin-posts-panel {
  padding-top: 22px;
}
.admin-posts-panel-meta {
  margin-left: auto;
  font-family: var(--font-latin);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-muted);
  white-space: nowrap;
}
.admin-posts-panel-meta--reports {
  color: color-mix(in oklab, var(--moss-600) 60%, var(--color-muted));
}

/* ---------- フィルタ UI（観測卓の作業卓面） ---------- */
.posts-filter {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 24px;
  padding: 18px 20px 18px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-paper) 70%, var(--color-card)) 0%,
      color-mix(in oklab, var(--color-paper) 40%, var(--color-card)) 100%);
  border: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
  border-radius: 8px;
  position: relative;
}
/* 観測卓の縁の極細インジケータ（dashboard stat-card と語彙統一） */
.posts-filter::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--color-accent) 25%, transparent) 0%,
    color-mix(in oklab, var(--color-accent) 8%, transparent) 50%,
    transparent 100%);
  border-radius: 8px 8px 0 0;
}
.posts-filter.is-active {
  border-color: color-mix(in oklab, var(--color-accent) 22%, var(--color-line));
}
.posts-filter.is-active::before {
  background: linear-gradient(90deg,
    var(--color-accent) 0%,
    color-mix(in oklab, var(--color-accent) 50%, transparent) 55%,
    transparent 100%);
  opacity: 0.75;
}

.posts-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px;
}
.posts-filter-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.posts-filter-label {
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
  line-height: 1.2;
}
.posts-filter-field .form-control,
.posts-filter-field .form-select {
  border-radius: var(--radius-sm);
  background: var(--color-card);
  border: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
  font-size: 13.5px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.posts-filter-field .form-control:focus,
.posts-filter-field .form-select:focus {
  border-color: color-mix(in oklab, var(--color-accent) 50%, var(--color-line));
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 12%, transparent);
}

/* 各フィールドの幅は内容に応じてゆとりを持たせる */
.posts-filter-field--lounge .form-select { min-width: 200px; max-width: 260px; }
.posts-filter-field--state .form-select  { min-width: 180px; }
.posts-filter-field--scope .form-select  { min-width: 210px; }
.posts-filter-field--author .form-control { min-width: 180px; }
.posts-filter-field--grow { flex: 1 1 260px; min-width: 220px; }
.posts-filter-field--grow .form-control { width: 100%; }

/* 期間（合体表現） */
.posts-filter-field--range { flex: 0 1 auto; }
.posts-filter-range {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.posts-filter-range .form-control {
  min-width: 0;
  width: 150px;
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--color-text);
}
.posts-filter-range-sep {
  font-family: var(--font-latin);
  font-size: 13px;
  color: var(--color-muted);
  letter-spacing: 0.06em;
  user-select: none;
}

.posts-filter-actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
  align-items: center;
}
.posts-filter-submit {
  letter-spacing: 0.06em;
  padding-left: 18px;
  padding-right: 18px;
}
.posts-filter-clear {
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.05em;
}

@media (max-width: 980px) {
  .posts-filter-field--range { flex: 1 1 100%; }
  .posts-filter-range .form-control { width: calc(50% - 18px); }
}
@media (max-width: 720px) {
  .posts-filter { padding: 16px 14px; }
  .posts-filter-row { flex-direction: column; align-items: stretch; }
  .posts-filter-actions { margin-left: 0; flex-wrap: wrap; }
  .posts-filter-field .form-control,
  .posts-filter-field .form-select { min-width: 0; width: 100%; }
  .posts-filter-range { width: 100%; }
  .posts-filter-range .form-control { width: calc(50% - 12px); flex: 1; }
}

/* ---------- 結果見出し（観測ログ） ---------- */
.admin-posts-result-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 6px 0 10px;
  padding: 0 2px;
}
.admin-posts-result-head-no {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 17px;
  color: color-mix(in oklab, var(--color-accent) 35%, var(--color-text-dim));
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.admin-posts-result-head-no::after {
  content: "·";
  margin-left: 8px;
  color: var(--color-muted);
}
.admin-posts-result-head-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.04em;
}
.admin-posts-result-head-meta {
  margin-left: auto;
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* ---------- テーブル ---------- */
.posts-table-scroll { overflow-x: auto; }

.admin-posts-table thead th {
  font-family: var(--font-latin) !important;
  font-size: 10.5px !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  color: var(--color-muted) !important;
  font-weight: 600 !important;
  padding-top: 10px !important;
  padding-bottom: 10px !important;
  border-bottom: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent) !important;
  background: transparent !important;
  white-space: nowrap;
}
.admin-posts-table .col-when    { width: 110px; }
.admin-posts-table .col-lounge  { width: 150px; }
.admin-posts-table .col-author  { width: 200px; }
.admin-posts-table .col-state   { width: 150px; }
.admin-posts-table .col-action  { width: 130px; }

/* 行 hover：左から極細の accent ストライプが立ち上がる（ダッシュボードの list hover と語彙統一） */
.admin-posts-table > tbody > tr {
  position: relative;
  transition: background-color .15s ease;
}
.admin-posts-table > tbody > tr > td:first-child {
  position: relative;
}
.admin-posts-table > tbody > tr > td:first-child::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: var(--color-accent);
  opacity: 0;
  transform: scaleY(0.4);
  transform-origin: top;
  transition: opacity .15s ease, transform .2s ease;
  border-radius: 1px;
}
.admin-posts-table > tbody > tr:hover > td:first-child::before {
  opacity: 0.7;
  transform: scaleY(1);
}

/* 投稿日時セル：date を Latin smallcaps の上、time を Zen Old Mincho の下、視覚密度低減 */
[data-posts-table] .post-created {
  font-family: var(--font-latin);
  white-space: nowrap;
  line-height: 1.3;
  padding-top: 14px !important;
  padding-bottom: 14px !important;
}
[data-posts-table] .post-created-date {
  display: block;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--color-text);
}
[data-posts-table] .post-created-time {
  display: block;
  font-family: var(--font-display);
  font-size: 13px;
  color: var(--color-text-dim);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  margin-top: 1px;
}

/* ラウンジ chip：amber 寄りで「観測対象のチャネル」を示す */
.post-lounge-cell { max-width: 160px; }
[data-posts-table] .lounge-chip {
  display: inline-block;
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: color-mix(in oklab, var(--color-accent) 8%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--color-accent) 20%, var(--color-line));
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 投稿者セル（avatar + display_name） */
.post-author {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.post-author-link {
  text-decoration: none;
  color: inherit;
}
.post-author-link:hover .post-author-name {
  color: var(--color-accent);
}
.post-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  background: color-mix(in oklab, var(--color-text) 6%, var(--color-card));
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-text) 10%, transparent);
}
.post-avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(150deg,
    color-mix(in oklab, var(--color-text) 36%, var(--color-card)),
    color-mix(in oklab, var(--color-text) 22%, var(--color-card)));
  color: var(--color-card);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.02em;
  box-shadow: none;
}
.post-author-name {
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color .15s ease;
}

/* 本文抜粋セル */
.post-body-cell { max-width: 460px; }
.post-body-link {
  color: var(--color-text);
  text-decoration: none;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-bottom: 1px dashed transparent;
  transition: color .15s ease, border-color .15s ease;
}
.post-body-link:hover {
  color: var(--color-accent);
  border-bottom-color: color-mix(in oklab, var(--color-accent) 40%, transparent);
}

/* 状態セル：state を上、scope を下に 2 段スタック（横の視覚密度低減） */
.post-state-cell {
  white-space: nowrap;
  padding-top: 12px !important;
  padding-bottom: 12px !important;
}
.post-state-stack {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.post-scope-row {
  display: inline-flex;
  gap: 4px;
  flex-wrap: wrap;
}
.post-state-cell .state-badge,
.post-state-cell .scope-badge {
  margin: 0;
}

/* 状態バッジ：削除済み（控えめな clay） */
.state-deleted {
  background: color-mix(in oklab, var(--clay-600) 12%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 78%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--clay-600) 38%, var(--color-line));
}
.state-deleted::before { background: var(--clay-600); }

/* 通報状態：未対応（控えめな clay） */
.state-open {
  background: color-mix(in oklab, var(--clay-600) 10%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 70%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--clay-600) 30%, var(--color-line));
}
.state-open::before { background: var(--clay-600); }

/* スコープバッジ：直下 / スレッド配下 / ピン留め — 状態より一段静か */
.scope-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-card));
  color: var(--color-text-dim);
  border: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
}
.scope-thread {
  background: color-mix(in oklab, var(--color-accent) 6%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-text));
  border-color: color-mix(in oklab, var(--color-accent) 18%, var(--color-line));
}
.scope-pinned {
  background: color-mix(in oklab, var(--moss-600) 8%, var(--color-card));
  color: color-mix(in oklab, var(--moss-600) 60%, var(--color-text));
  border-color: color-mix(in oklab, var(--moss-600) 22%, var(--color-line));
}

/* 削除済み行：薄い clay の地 + 左の clay ストライプ + 本文は静かに沈める（忘れられた観測記録の雰囲気） */
tr.is-deleted {
  position: relative;
}
tr.is-deleted > td {
  background: color-mix(in oklab, var(--clay-600) 3%, var(--color-card));
}
tr.is-deleted > td:first-child {
  box-shadow: inset 3px 0 0 color-mix(in oklab, var(--clay-600) 42%, transparent);
}
tr.is-deleted .post-body-link {
  color: color-mix(in oklab, var(--clay-600) 30%, var(--color-text-dim));
  text-decoration: line-through;
  text-decoration-color: color-mix(in oklab, var(--clay-600) 45%, transparent);
  text-decoration-thickness: 1px;
}
tr.is-deleted .post-author-name { color: var(--color-text-dim); font-weight: 500; }
tr.is-deleted .post-avatar { opacity: 0.7; }
tr.is-deleted .lounge-chip { opacity: 0.75; }
tr.is-deleted .post-created-date,
tr.is-deleted .post-created-time { color: var(--color-text-dim); }
/* hover 時のストライプは clay ではなく accent のままにせず、削除済み行は clay 強調を維持 */
.admin-posts-table > tbody > tr.is-deleted:hover > td:first-child::before {
  background: var(--clay-600);
  opacity: 0.6;
}

/* 操作セル：詳細リンク（矢印つき・観測卓らしい矢印 motion） */
.post-action-cell {
  padding-top: 12px !important;
  padding-bottom: 12px !important;
}
.post-action-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-latin);
  font-size: 12.5px;
  letter-spacing: 0.05em;
  color: var(--color-text-dim);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  transition: color .15s ease, border-color .15s ease;
}
.post-action-link:hover {
  color: var(--color-accent);
  border-bottom-color: color-mix(in oklab, var(--color-accent) 35%, transparent);
}
.post-action-link-arrow {
  width: 14px;
  height: 14px;
  transition: transform .2s ease;
}
.post-action-link:hover .post-action-link-arrow { transform: translateX(3px); }

/* 空表示（観測卓トーン） */
.admin-posts-empty {
  text-align: center;
  padding: 48px 16px;
  border: 1px dashed color-mix(in oklab, var(--color-line) 90%, transparent);
  border-radius: 8px;
  background: color-mix(in oklab, var(--color-paper) 50%, var(--color-card));
  margin: 8px 0 12px;
}
.admin-posts-empty-mark {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 28px;
  color: color-mix(in oklab, var(--color-accent) 35%, var(--color-text-dim));
  letter-spacing: 0.2em;
}
.admin-posts-empty-jp {
  margin: 6px 0 2px;
  color: var(--color-text-dim);
  font-size: 13.5px;
}
.admin-posts-empty-en {
  margin: 0;
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* ページャ */
.posts-pager {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
}
.posts-pager .pagination {
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 8px;
}
.posts-pager-counter {
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0;
}

/* info-note 内のリンク */
.info-note-link {
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.info-note-link:hover { color: var(--color-accent); }

/* ========== 詳細画面 ========== */
.post-detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}
.post-detail-head h1 {
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}
.post-detail-id {
  font-family: var(--font-latin);
  font-weight: 500;
  font-size: 0.6em;
  color: var(--color-muted);
  letter-spacing: 0.06em;
  margin-left: 4px;
  font-variant-numeric: tabular-nums;
}
.post-detail-head-badges {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
}

.admin-posts-detail-lede {
  margin-top: 2px;
  margin-bottom: 14px;
}

/* 詳細グリッド 1 : 1 — 投稿者 / 投稿情報の重みを揃える */
.post-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-bottom: 18px;
}
@media (max-width: 960px) {
  .post-detail-grid { grid-template-columns: 1fr; }
}

.post-detail-author-panel,
.post-detail-meta-panel {
  display: flex;
  flex-direction: column;
}

.post-author-block {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 6px 2px 8px;
}
.post-author-block .post-author-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-text) 10%, transparent),
              0 0 0 6px color-mix(in oklab, var(--color-paper) 60%, var(--color-card));
}
.post-author-block .post-author-avatar.post-avatar-fallback {
  font-size: 26px;
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-text) 10%, transparent),
              0 0 0 6px color-mix(in oklab, var(--color-paper) 60%, var(--color-card));
}

.post-author-fields,
.post-meta-fields {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 18px;
  row-gap: 9px;
  margin: 0;
  align-items: baseline;
  flex: 1;
}
.post-author-fields dt,
.post-meta-fields dt {
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
}
.post-author-fields dd,
.post-meta-fields dd {
  margin: 0;
  color: var(--color-text);
  min-width: 0;
  word-break: break-word;
}
.post-author-name-large {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--color-text);
  line-height: 1.2;
}
.post-hash {
  font-family: var(--font-latin);
  font-size: 11.5px;
  color: var(--color-text-dim);
  letter-spacing: 0.02em;
  word-break: break-all;
  display: inline-block;
  padding: 2px 8px;
  background: color-mix(in oklab, var(--color-text) 3%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
  border-radius: 3px;
}
.post-author-foot-note {
  margin: 14px 0 0;
  padding-top: 10px;
  border-top: 1px dashed color-mix(in oklab, var(--color-line) 80%, transparent);
  font-size: 11.5px;
  color: var(--color-text-dim);
  line-height: 1.6;
  letter-spacing: 0.01em;
}

.post-meta-link {
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in oklab, var(--color-accent) 28%, var(--color-line));
  transition: color .15s ease, border-color .15s ease;
}
.post-meta-link:hover {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}
.post-meta-place-tag {
  display: inline-block;
  padding: 2px 9px;
  margin-right: 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: color-mix(in oklab, var(--color-accent) 6%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-text));
  border: 1px solid color-mix(in oklab, var(--color-accent) 18%, var(--color-line));
}
.post-meta-place-tag--root {
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-card));
  color: var(--color-text-dim);
  border-color: color-mix(in oklab, var(--color-line) 80%, transparent);
}
.post-meta-time {
  font-family: var(--font-latin);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  font-size: 13px;
  color: var(--color-text-dim);
}
.post-meta-time--clay {
  color: color-mix(in oklab, var(--clay-600) 65%, var(--color-text-dim));
}
.post-meta-stat {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 18px;
  color: var(--color-text);
  letter-spacing: 0;
  margin: 0 2px;
  font-variant-numeric: tabular-nums;
}
.post-meta-dim {
  color: var(--color-text-dim);
  font-size: 12px;
}

/* 元のラウンジへジャンプ：amber 寄り「観測対象から実フィールドへ降りる」 */
.post-detail-jump {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px dashed color-mix(in oklab, var(--color-line) 80%, transparent);
}
.post-jump-link {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--color-text);
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--color-accent) 7%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-accent) 25%, var(--color-line));
  transition: background-color .15s ease, border-color .15s ease, transform .2s ease;
}
.post-jump-link:hover {
  background: color-mix(in oklab, var(--color-accent) 14%, var(--color-card));
  border-color: color-mix(in oklab, var(--color-accent) 45%, var(--color-line));
}
.post-jump-link-pre {
  font-family: var(--font-latin);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-muted));
  font-weight: 600;
  padding-right: 12px;
  border-right: 1px solid color-mix(in oklab, var(--color-accent) 30%, var(--color-line));
}
.post-jump-link-body {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--color-accent) 50%, var(--color-text));
}
.post-jump-link-icon {
  width: 16px;
  height: 16px;
  transition: transform .2s ease;
}
.post-jump-link:hover .post-jump-link-icon { transform: translate(2px, -2px); }

/* 本文カード */
.post-body-panel { margin-bottom: 18px; }
.post-body {
  font-size: 15px;
  line-height: 1.85;
  color: var(--color-text);
  white-space: pre-wrap;
  word-break: break-word;
  padding: 4px 2px;
  border-left: 2px solid color-mix(in oklab, var(--color-accent) 25%, var(--color-line));
  padding-left: 18px;
  margin-left: 2px;
}
.post-body--deleted {
  color: var(--color-text-dim);
  border-left-color: color-mix(in oklab, var(--clay-600) 45%, var(--color-line));
  font-style: italic;
}

/* 削除 / 復元 アクション */
.post-action-panel { margin-bottom: 18px; }
.post-action-status {
  position: relative;
  padding: 14px 16px 14px 20px;
  border-radius: var(--radius-sm);
  margin-bottom: 16px;
  border: 1px solid var(--color-line);
  background: color-mix(in oklab, var(--color-text) 3%, var(--color-card));
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.post-action-status p {
  margin: 0;
  color: var(--color-text-dim);
  font-size: 13.5px;
  line-height: 1.7;
}
.post-action-status p strong {
  color: var(--color-text);
  font-weight: 600;
}
.post-action-status-mark {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-top: 8px;
  flex: none;
}
.post-action-status--deleted {
  background: color-mix(in oklab, var(--clay-600) 5%, var(--color-card));
  border-color: color-mix(in oklab, var(--clay-600) 28%, var(--color-line));
}
.post-action-status--deleted .post-action-status-mark {
  background: var(--clay-600);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--clay-600) 20%, transparent);
}
.post-action-status--deleted p strong {
  color: color-mix(in oklab, var(--clay-600) 65%, var(--color-text));
}
.post-action-status--active {
  background: color-mix(in oklab, var(--moss-600) 4%, var(--color-card));
  border-color: color-mix(in oklab, var(--moss-600) 22%, var(--color-line));
}
.post-action-status--active .post-action-status-mark {
  background: var(--moss-600);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--moss-600) 18%, transparent);
}
.post-action-status--active p strong {
  color: color-mix(in oklab, var(--moss-600) 55%, var(--color-text));
}

.post-action-btn {
  letter-spacing: 0.04em;
  padding: 8px 18px;
}
.post-action-btn--delete {
  background: color-mix(in oklab, var(--clay-600) 88%, var(--color-text) 12%);
  border-color: color-mix(in oklab, var(--clay-600) 88%, var(--color-text) 12%);
}
.post-action-btn--delete:hover {
  background: var(--clay-600);
  border-color: var(--clay-600);
}
.post-action-btn--restore {
  border-color: color-mix(in oklab, var(--moss-600) 35%, var(--color-line));
  color: color-mix(in oklab, var(--moss-600) 60%, var(--color-text));
}
.post-action-btn--restore:hover {
  background: color-mix(in oklab, var(--moss-600) 8%, var(--color-card));
  border-color: color-mix(in oklab, var(--moss-600) 55%, var(--color-line));
  color: color-mix(in oklab, var(--moss-600) 70%, var(--color-text));
}

.post-action-caution {
  margin-top: 18px;
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-paper) 70%, var(--color-card)) 0%,
      color-mix(in oklab, var(--color-paper) 40%, var(--color-card)) 100%);
  border: 1px dashed color-mix(in oklab, var(--color-line) 90%, transparent);
}
.post-action-caution-head {
  font-family: var(--font-latin);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
  margin: 0 0 8px;
}
.post-action-caution-list {
  margin: 0;
  padding-left: 18px;
  color: var(--color-text-dim);
  font-size: 12.5px;
  line-height: 1.75;
}
.post-action-caution-list code {
  font-family: var(--font-latin);
  font-size: 11.5px;
  padding: 1px 5px;
  background: color-mix(in oklab, var(--color-text) 4%, var(--color-card));
  border: 1px solid color-mix(in oklab, var(--color-line) 70%, transparent);
  border-radius: 3px;
  color: var(--color-text-dim);
}

/* 通報歴セクション */
.post-reports-panel .panel-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.post-reports-action {
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: color-mix(in oklab, var(--color-accent) 60%, var(--color-text-dim));
  text-decoration: none;
  border-bottom: 1px solid transparent;
  margin-left: 12px;
}
.post-reports-action:hover {
  color: var(--color-accent);
  border-bottom-color: color-mix(in oklab, var(--color-accent) 40%, transparent);
}
.post-reports-note {
  font-size: 12.5px;
  color: var(--color-text-dim);
  margin: 8px 0 14px;
  line-height: 1.7;
}
.post-reports-note-link {
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text));
  font-weight: 500;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.post-reports-note-link:hover { color: var(--color-accent); }

.post-reports-table-scroll { overflow-x: auto; }

.post-reports-table thead th {
  font-family: var(--font-latin) !important;
  font-size: 10.5px !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  color: var(--color-muted) !important;
  font-weight: 600 !important;
  background: transparent !important;
}
.post-reports-table .col-when     { width: 130px; }
.post-reports-table .col-reason   { width: 130px; }
.post-reports-table .col-state    { width: 120px; }
.post-reports-table .col-resolved { width: 130px; }

.post-report-when {
  font-family: var(--font-latin);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--color-text-dim);
  white-space: nowrap;
}

/* 通報理由 chip：reason ごとに hue 差別化 — spam=clay 寄り、harassment=濃 clay、inappropriate=clay 中、other=neutral */
.report-reason-chip {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: color-mix(in oklab, var(--color-text) 5%, var(--color-card));
  color: var(--color-text-dim);
  border: 1px solid color-mix(in oklab, var(--color-line) 80%, transparent);
}
.report-reason-chip--spam {
  background: color-mix(in oklab, var(--clay-600) 9%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 70%, var(--color-text));
  border-color: color-mix(in oklab, var(--clay-600) 28%, var(--color-line));
}
.report-reason-chip--harassment {
  background: color-mix(in oklab, var(--clay-600) 18%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 88%, var(--color-text));
  border-color: color-mix(in oklab, var(--clay-600) 48%, var(--color-line));
  font-weight: 700;
}
.report-reason-chip--inappropriate {
  background: color-mix(in oklab, var(--clay-600) 13%, var(--color-card));
  color: color-mix(in oklab, var(--clay-600) 78%, var(--color-text));
  border-color: color-mix(in oklab, var(--clay-600) 36%, var(--color-line));
}
.report-reason-chip--other {
  background: color-mix(in oklab, var(--color-text) 5%, var(--color-card));
  color: var(--color-text-dim);
  border-color: color-mix(in oklab, var(--color-line) 80%, transparent);
}

.report-detail-cell {
  max-width: 360px;
  color: var(--color-text-dim);
  font-size: 13px;
  line-height: 1.6;
}
.post-report-empty-cell { color: var(--color-muted); }

/* 通報歴空表示（観測卓トーン） */
.post-reports-empty {
  text-align: center;
  padding: 36px 16px;
  border: 1px dashed color-mix(in oklab, var(--moss-600) 25%, var(--color-line));
  border-radius: 8px;
  background: color-mix(in oklab, var(--moss-600) 3%, var(--color-card));
  margin: 4px 0 0;
}
.post-reports-empty-mark {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in oklab, var(--moss-600) 65%, var(--color-line));
  margin-bottom: 8px;
}
.post-reports-empty-jp {
  margin: 0 0 4px;
  color: color-mix(in oklab, var(--moss-600) 55%, var(--color-text-dim));
  font-size: 13.5px;
  font-weight: 500;
}
.post-reports-empty-en {
  margin: 0;
  font-family: var(--font-latin);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--moss-600) 55%, var(--color-muted));
}

/* 戻りリンク */
.post-detail-head .back-link {
  font-family: var(--font-latin);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-decoration: none;
  width: 100%;
  display: block;
  margin-bottom: -2px;
  transition: color .15s ease;
}
.post-detail-head .back-link:hover { color: var(--color-accent); }

/* ---------- モバイル ---------- */
@media (max-width: 720px) {
  .admin-posts-lede-count { width: 100%; margin-left: 0; margin-top: 4px; }
  .admin-posts-result-head-meta { display: none; }
  .post-detail-head h1 { font-size: 22px; }
  .post-author-block { flex-direction: column; align-items: flex-start; gap: 12px; }
  .post-author-block .post-author-avatar { width: 60px; height: 60px; }
  .post-author-name-large { font-size: 19px; }
  .post-jump-link { width: 100%; justify-content: flex-start; }
  .post-jump-link-pre { padding-right: 10px; }
  .post-body { padding-left: 14px; }
  .admin-posts-table .col-state,
  .admin-posts-table .col-author,
  .admin-posts-table .col-lounge { width: auto; }
}

/* ============================================================
   Sprint 17-B: マイページ通知設定 — 「届け先のしるべ」
   メタファー: 通知 = 便り。各種別は小さな手紙、チェックは「届く / 封をする」。
   - パスキー画面と同じシェル（.mypage-card）の上に乗る。
   - 4 グループ × 各 1〜3 行。グループには番号入りの小さな「消印」を打つ。
   - チェックボックスは「届く」スタンプ風（amber）と「封をする」（hairline）に切り替わる。
   - すべて .notif-prefs-* プレフィックスで局所化。他画面に影響しない。
   ============================================================ */
.notif-prefs-card { padding-bottom: 28px; position: relative; overflow: hidden; }
.notif-prefs-card::after {
  /* 右下にうっすら浮かぶ "letter rail" — 便箋の罫線が消えていくような余韻 */
  content: "";
  position: absolute;
  right: -18px;
  bottom: 18px;
  width: 180px;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%) 60%,
    transparent);
  opacity: 0.55;
  pointer-events: none;
}

/* ---- ヘッダー右上に置く "消印" — カードに格式を 1 段足す装飾 ---- */
.notif-prefs-postmark {
  flex-shrink: 0;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 64px; height: 64px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--color-accent) 6%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 70%, var(--color-text-dim) 30%);
  position: relative;
  margin-left: auto;
}
.notif-prefs-postmark svg { width: 52px; height: 52px; }
.notif-prefs-postmark-tag {
  position: absolute;
  bottom: 8px; left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-latin);
  font-size: 8px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text-dim) 45%);
}

/* ---- 「メール通知はありません」の控えめな帯 — 封筒グリフ付き ---- */
.notif-prefs-note {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 4px 0 22px;
  padding: 13px 16px 14px;
  border: 1px solid color-mix(in oklab, var(--color-line) 65%, transparent);
  border-left: 2px solid color-mix(in oklab, var(--color-accent) 35%, var(--color-line) 65%);
  border-radius: 2px;
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 3%, var(--color-card)) 0%,
      var(--color-card) 100%);
}
.notif-prefs-note-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  color: color-mix(in oklab, var(--color-accent) 55%, var(--color-text-dim) 45%);
  flex-shrink: 0;
  margin-top: 1px;
  position: relative;
}
.notif-prefs-note-glyph svg { width: 26px; height: 26px; }
.notif-prefs-note-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.notif-prefs-note-line {
  font-family: var(--font-display);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-text);
}
.notif-prefs-note-sub {
  font-size: 12px;
  line-height: 1.7;
  color: var(--color-muted);
}

/* ---- フォーム ---- */
.notif-prefs-form { display: block; margin: 0; }

/* ---- グループ（4 ブロック）---- */
.notif-prefs-group {
  border: 0;
  margin: 0 0 22px;
  padding: 0;
}
.notif-prefs-group + .notif-prefs-group {
  margin-top: 0;
  padding-top: 22px;
  border-top: 1px dashed color-mix(in oklab, var(--color-line) 70%, transparent);
}
.notif-prefs-group:last-of-type { margin-bottom: 4px; }

.notif-prefs-group-legend {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 0 4px;
  margin: 0;
  width: 100%;
}
/* 番号入りの小さな「消印」 — グループに序列と"区切り"の手応えを与える */
.notif-prefs-group-seal {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--color-accent) 40%, var(--color-line) 60%);
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-card));
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text) 25%);
  flex-shrink: 0;
}
.notif-prefs-group-seal::before {
  /* 内側の薄い破線リング — 消印スタイル */
  content: "";
  position: absolute;
  inset: 2px;
  border: 1px dashed color-mix(in oklab, var(--color-accent) 35%, var(--color-line) 65%);
  border-radius: 50%;
  opacity: 0.6;
  pointer-events: none;
}
.notif-prefs-group-seal-num {
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.05em;
  font-weight: 600;
}
.notif-prefs-group-titles {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  min-width: 0;
}
.notif-prefs-group-label {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 600;
  /* 20-A: ゴシック化に合わせ字間を締める（明朝前提の 0.14em は間延びする） */
  letter-spacing: 0.03em;
  color: var(--color-text);
}
.notif-prefs-group-sub {
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.34em;
  text-transform: lowercase;
  color: var(--color-muted);
}
.notif-prefs-group-caption {
  margin: 4px 0 10px;
  padding-left: 38px; /* seal の幅 + gap に合わせて caption をぶら下げる */
  font-size: 12px;
  line-height: 1.65;
  color: color-mix(in oklab, var(--color-muted) 80%, var(--color-text-dim) 20%);
  /* 20-A: 擬似イタリック和文を正立に */
  font-style: normal;
  letter-spacing: 0.01em;
}

/* ---- 8 項目のリスト ---- */
.notif-prefs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.notif-prefs-item { margin: 0; }

/* 各行は「便り 1 通」のプレート — アイコン + 本文 + 届く/封スタンプ */
.notif-prefs-row {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border: 1px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  transition:
    background-color .18s ease,
    border-color .18s ease,
    transform .18s ease;
  position: relative;
}
.notif-prefs-row::before {
  /* 左端に細い "送り票" ライン — ホバーで amber に灯る */
  content: "";
  position: absolute;
  left: 0; top: 14px; bottom: 14px;
  width: 1px;
  background: color-mix(in oklab, var(--color-line) 80%, transparent);
  transition: background-color .18s ease, width .18s ease;
}
.notif-prefs-row:hover {
  background: color-mix(in oklab, var(--color-accent) 4%, transparent);
  border-color: color-mix(in oklab, var(--color-line) 70%, transparent);
}
.notif-prefs-row:hover::before {
  background: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
  width: 2px;
}
.notif-prefs-item.is-off .notif-prefs-row {
  /* 封がされた便り — 全体をひと段階沈ませる */
  background: color-mix(in oklab, var(--color-line) 12%, transparent);
}
.notif-prefs-item.is-off .notif-prefs-icon,
.notif-prefs-item.is-off .notif-prefs-label,
.notif-prefs-item.is-off .notif-prefs-desc {
  color: color-mix(in oklab, var(--color-text-dim) 75%, var(--color-muted) 25%);
}
.notif-prefs-item.is-off .notif-prefs-icon {
  background: var(--color-card);
  border-style: dashed;
}

/* ---- 種別アイコン（typeMeta SVG）を載せる小さな"切手プレート" ---- */
.notif-prefs-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 2px;
  border: 1px solid color-mix(in oklab, var(--color-accent) 22%, var(--color-line) 78%);
  background:
    linear-gradient(180deg,
      color-mix(in oklab, var(--color-accent) 7%, var(--color-card)) 0%,
      color-mix(in oklab, var(--color-accent) 3%, var(--color-card)) 100%);
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text) 25%);
  position: relative;
  flex-shrink: 0;
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--color-paper) 90%, transparent),
    inset 0 -1px 0 color-mix(in oklab, var(--color-accent) 8%, transparent);
  transition: transform .25s cubic-bezier(.4,.05,.2,1), color .18s ease;
}
.notif-prefs-icon::after {
  /* 切手の四隅にうっすらドット — "perforation" の暗示 */
  content: "";
  position: absolute;
  inset: 2px;
  border: 1px dashed color-mix(in oklab, var(--color-accent) 14%, transparent);
  border-radius: 1px;
  pointer-events: none;
}
.notif-prefs-icon svg { width: 22px; height: 22px; position: relative; z-index: 1; }
.notif-prefs-row:hover .notif-prefs-icon {
  transform: rotate(-3deg);
}

/* ---- 本文（ラベル + lowercase + desc）---- */
.notif-prefs-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.notif-prefs-label {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  font-family: var(--font-display);
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--color-text);
  line-height: 1.3;
  /* 日本語のラベルが短いマス目で 1 文字ごとに改行されないよう、可能なら全体で粘る */
  word-break: keep-all;
  overflow-wrap: anywhere;
}
.notif-prefs-sub {
  font-family: var(--font-latin);
  font-size: 9px;
  letter-spacing: 0.32em;
  text-transform: lowercase;
  color: var(--color-muted);
}
.notif-prefs-desc {
  color: var(--color-muted);
  font-size: 12.5px;
  line-height: 1.65;
}

/* ---- 「届く / 封をする」スタンプ（右側）---- */
.notif-prefs-check {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  padding-left: 6px;
}
.notif-prefs-check input[type="checkbox"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 2;
}
/* スタンプ本体 — 26px の角丸スクエア */
.notif-prefs-check-box {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border: 1px solid color-mix(in oklab, var(--color-line) 90%, transparent);
  border-radius: 3px;
  background: var(--color-card);
  color: transparent;
  transition:
    background-color .15s ease,
    border-color .15s ease,
    color .15s ease,
    transform .15s ease;
  overflow: hidden;
}
.notif-prefs-check-mark,
.notif-prefs-check-seal {
  position: absolute;
  width: 16px; height: 16px;
  transition: opacity .15s ease, transform .25s cubic-bezier(.4,.05,.2,1);
}
.notif-prefs-check-mark { opacity: 0; transform: scale(0.7); }
/* 封 (folded letter) glyph — OFF 状態のとき微かに表示 */
.notif-prefs-check-seal {
  width: 13px; height: 13px;
  color: color-mix(in oklab, var(--color-text-dim) 55%, transparent);
  opacity: 0.55;
}
.notif-prefs-check input[type="checkbox"]:checked + .notif-prefs-check-box {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-card);
}
.notif-prefs-check input[type="checkbox"]:checked + .notif-prefs-check-box .notif-prefs-check-mark {
  opacity: 1;
  transform: scale(1);
}
.notif-prefs-check input[type="checkbox"]:checked + .notif-prefs-check-box .notif-prefs-check-seal {
  opacity: 0;
}
.notif-prefs-check input[type="checkbox"]:focus-visible + .notif-prefs-check-box {
  outline: 2px solid color-mix(in oklab, var(--color-accent) 65%, transparent);
  outline-offset: 2px;
}
/* hover で微かな"押される前"の余韻 */
.notif-prefs-row:hover .notif-prefs-check-box {
  border-color: color-mix(in oklab, var(--color-accent) 55%, var(--color-line) 45%);
}
.notif-prefs-row:active .notif-prefs-check-box {
  transform: scale(0.94);
}

/* スタンプ下の "届く / 封をする" ラベル */
.notif-prefs-state {
  font-family: var(--font-display);
  font-size: 10.5px;
  /* 20-A: 汎用ラベル「受け取る/オフにする」になり字数が増えたので字間を締めて収める */
  letter-spacing: 0.04em;
  color: var(--color-text-dim);
  min-width: 52px;
  text-align: center;
  user-select: none;
  white-space: nowrap;
}
.notif-prefs-state-on,
.notif-prefs-state-off { display: none; }
.notif-prefs-item.is-on .notif-prefs-state-on {
  display: inline;
  color: color-mix(in oklab, var(--color-accent) 75%, var(--color-text) 25%);
  font-weight: 500;
}
.notif-prefs-item.is-off .notif-prefs-state-off {
  display: inline;
  color: var(--color-muted);
}

/* ---- 保存アクション ---- */
.notif-prefs-actions {
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid color-mix(in oklab, var(--color-line) 65%, transparent);
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.notif-prefs-save {
  min-width: 160px;
  letter-spacing: 0.1em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.notif-prefs-save::before {
  /* 送り出すモチーフ — 小さな飛行する矢印 */
  content: "";
  display: inline-block;
  width: 14px; height: 14px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fffbf2' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.6'><path d='M2 8 L13 3 L11 13 L7.5 9 Z'/></svg>");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  transition: transform .25s cubic-bezier(.4,.05,.2,1);
}
.notif-prefs-save:hover::before { transform: translateX(2px) rotate(-6deg); }

.notif-prefs-hint {
  margin: 0;
  color: var(--color-muted);
  font-size: 12px;
  line-height: 1.65;
  flex: 1 1 240px;
  min-width: 0;
}

/* ---- カード下の小さなフッター行 ---- */
.notif-prefs-foot {
  margin: 18px 0 4px;
  text-align: center;
  font-family: var(--font-display);
  font-size: 12.5px;
  letter-spacing: 0.08em;
  color: var(--color-text-dim);
}
.notif-prefs-foot-sub {
  display: block;
  margin-top: 2px;
  font-family: var(--font-latin);
  font-size: 9.5px;
  letter-spacing: 0.32em;
  text-transform: lowercase;
  color: var(--color-muted);
}

/* ---- レスポンシブ ---- */
@media (max-width: 720px) {
  .notif-prefs-postmark { width: 52px; height: 52px; }
  .notif-prefs-postmark svg { width: 42px; height: 42px; }
}
@media (max-width: 640px) {
  .notif-prefs-card { padding: 22px 16px 26px; }
  .notif-prefs-note { padding: 12px 14px; }
  .notif-prefs-row {
    grid-template-columns: 34px 1fr auto;
    gap: 11px;
    padding: 12px 8px;
  }
  .notif-prefs-icon { width: 34px; height: 34px; }
  .notif-prefs-icon svg { width: 18px; height: 18px; }
  .notif-prefs-label { font-size: 14px; gap: 6px; }
  .notif-prefs-sub { font-size: 8.5px; letter-spacing: 0.28em; }
  .notif-prefs-desc { font-size: 12px; }
  .notif-prefs-state { display: none; } /* モバイルは省略・スタンプだけで意味伝達 */
  .notif-prefs-check-box { width: 28px; height: 28px; }
  .notif-prefs-group-caption { padding-left: 0; }
  .notif-prefs-actions {
    flex-direction: column;
    align-items: stretch;
    margin-bottom: 10px;
  }
  .notif-prefs-save { width: 100%; }
  .notif-prefs-hint { flex: 1 1 auto; text-align: left; }
  .notif-prefs-card { margin-bottom: 24px; }
  /* Bottom Navigation の上に被らないように、フッターに息継ぎ余白を確保 */
  .notif-prefs-foot { margin-bottom: 88px; }
}
@media (max-width: 420px) {
  .notif-prefs-postmark { display: none; }
  .notif-prefs-group-titles { gap: 6px; }
}

/* ============================================================
 * sprint-18-B (designer): 管理画面 templates/Admin/Posts/view.php
 *   「04 添付ファイル」セクション
 *
 *   「観測卓 / Posts · 引き出し」のトーンと統一感を持つ "台帳" 表現。
 *   - 上下に薄い罫線・各行は dashed の境界（dashboard セクションのリズム）。
 *   - 行頭に 01 / 02 ... の通し番号（16-A の dashboard-section-no と同語彙）。
 *   - 画像はサムネを左に小さく添える（72×56・運営調査用なので過大表示しない）。
 *   - 非画像はファイル種を示す折り紙アイコン（forum.css と同じ dog-ear 形状の svg）。
 *   - 右端に "open ↗" / "dl ↓" の小印を eyebrow と同じ大文字 latin で添える。
 *
 *   admin ページは forum.css を読み込まないため、admin 系の .post-attachments-*
 *   はここ（style.css）に集約する。
 * ============================================================ */
.post-attachments-panel { margin-top: 18px; }
.post-attachments-empty { padding: 14px 0; color: #8a7d6a; }
.post-attachments-empty-jp { margin: 0; }
.post-attachments-empty-en {
  margin: 4px 0 0;
  font-size: 11.5px;
  opacity: 0.65;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-family: var(--font-latin, "Inter", sans-serif);
}

/* 台帳: list-style なし・上下に薄い罫線。 */
.post-attachments-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: block;
  border-top: 1px solid #e8e3d7;
  border-bottom: 1px solid #e8e3d7;
  counter-reset: post-att;
}
.post-attachment-item {
  display: grid;
  grid-template-columns: 32px 80px 1fr 64px;
  align-items: center;
  gap: 14px;
  padding: 10px 6px;
  background: transparent;
  border: none;
  border-radius: 0;
  border-bottom: 1px dashed color-mix(in oklab, #c8924a 18%, #e8e3d7);
  position: relative;
  transition: background-color 0.15s ease;
  list-style: none;
  counter-increment: post-att;
}
.post-attachment-item::marker { content: ""; }
.post-attachment-item:last-child { border-bottom: none; }
.post-attachment-item:hover {
  background: color-mix(in oklab, #c8924a 3.5%, transparent);
}

/* 行頭の通し番号バッジ（16-A ダッシュボード語彙） */
.post-attachment-item::before {
  content: counter(post-att, decimal-leading-zero);
  font-family: var(--font-latin, "Inter", sans-serif);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: color-mix(in oklab, #c8924a 75%, #6b6353);
  grid-column: 1;
  justify-self: start;
  align-self: center;
  padding-left: 2px;
}

/* 第 2 列: サムネ / アイコン枠（72×56 固定） */
.post-attachment-item--image .post-attachment-thumb {
  width: 72px;
  height: 56px;
  border-radius: 4px;
  overflow: hidden;
  display: block;
  background: color-mix(in oklab, #2b2418 5%, #fdfaf3);
  border: 1px solid color-mix(in oklab, #c8924a 16%, #e2d9c6);
  grid-column: 2;
  justify-self: start;
  align-self: center;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.post-attachment-item--image .post-attachment-thumb:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(80, 50, 10, 0.10);
  border-color: color-mix(in oklab, #c8924a 35%, #e2d9c6);
}
.post-attachment-item--image .post-attachment-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.post-attachment-chip-icon {
  color: color-mix(in oklab, #6b4a1f 60%, #8a7d6a);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 56px;
  border-radius: 4px;
  background: color-mix(in oklab, #c8924a 5%, #fdfaf3);
  border: 1px solid color-mix(in oklab, #c8924a 16%, #e2d9c6);
  grid-column: 2;
  justify-self: start;
  align-self: center;
  padding: 0;
}

/* 第 3 列: メタ（名前 + サイズ + MIME） */
.post-attachment-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  grid-column: 3;
  align-self: center;
}
.post-attachment-name {
  font-size: 13.5px;
  color: #2b2418;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
  letter-spacing: 0.005em;
}
.post-attachment-item .post-attachment-name[href]:hover {
  color: color-mix(in oklab, #c8924a 70%, #2b2418);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, #c8924a 55%, transparent);
  text-underline-offset: 3px;
}
.post-attachment-sub {
  font-size: 11px;
  color: #8a7d6a;
  font-family: var(--font-latin, "Inter", sans-serif);
  letter-spacing: 0.04em;
}

/* 第 4 列: 動作の小印（画像 / ファイル）。
 *  generic な「open」と「dl」を eyebrow と同じ大文字 latin で。 */
.post-attachment-item::after {
  grid-column: 4;
  justify-self: end;
  align-self: center;
  font-family: var(--font-latin, "Inter", sans-serif);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: color-mix(in oklab, #c8924a 75%, #8a7d6a);
  padding-right: 4px;
  opacity: 0.7;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.post-attachment-item--image::after { content: "open ↗"; }
.post-attachment-item--file::after  { content: "dl ↓"; }
.post-attachment-item:hover::after { opacity: 1; transform: translateY(-1px); }

.post-attachments-note {
  margin: 14px 0 0;
  font-size: 12.5px;
  color: #8a7d6a;
  line-height: 1.7;
  padding: 4px 12px;
  border-left: 2px solid color-mix(in oklab, #c8924a 35%, #e2d9c6);
}

@media (max-width: 640px) {
  .post-attachment-item {
    grid-template-columns: 30px 60px 1fr;
    grid-template-rows: auto auto;
    gap: 10px;
  }
  .post-attachment-item--image .post-attachment-thumb,
  .post-attachment-chip-icon {
    width: 60px;
    height: 48px;
  }
  .post-attachment-item::after {
    display: none;
  }
}

