/* =============================================================
 * Morioka Portal v2 (kai) — Style (PHP twclone と視覚的互換)
 *
 * 構成 (PHP style-new.css に倣う):
 *   §0  デザイントークン
 *   §1  リセット + ベース
 *   §2  アニメーション
 *   §3  レイアウト (3 カラム + レスポンシブ)
 *   §4  サイドバーナビ (左カラム)
 *   §5  メインカラム (col-main-header / タブ)
 *   §6  モバイルヘッダー + サイドドロワー
 *   §7  ボトムナビ (モバイル)
 *   §8  アバター + バッジ
 *   §9  投稿カード
 *   §10 メディア (画像グリッド / 動画)
 *   §11 OGP カード + 引用カード
 *   §12 アクションバー (X 風)
 *   §13 コンポーザモーダル
 *   §14 共通 (フォーム / リスト / 空状態 / プロフィール)
 *   §15 v2 独自コンポーネント
 *
 * PHP style-new.css のデザイントークン・命名規則と互換。
 * HTML は Go html/template から生成、PHP 流用ではなく v2 ネイティブ実装。
 * ============================================================= */

/* §0  デザイントークン */
:root {
  --bg-primary:    #070916;
  --bg-secondary:  #0d1330;
  --bg-tertiary:   #0b1028;
  --bg-overlay:    rgba(13, 19, 48, 0.95);
  --bg-hover:      rgba(255, 255, 255, 0.04);
  --bg-card:       rgba(13, 19, 48, 0.55);
  --bg-card-hover: rgba(255, 255, 255, 0.025);

  --text-primary:   #e7ecff;
  --text-secondary: #9aa6d6;
  --text-muted:     #6b7aa1;
  --text-accent:    #ffffff;

  --accent-purple: #7c4dff;
  --accent-cyan:   #00e5ff;
  --accent-green:  #00ff9d;
  --accent-pink:   #ff4d6d;
  --accent-gold:   #ffd700;

  --action-reply:    var(--accent-cyan);
  --action-repost:   var(--accent-green);
  --action-like:     var(--accent-pink);
  --action-share:    var(--accent-purple);
  --action-bookmark: var(--accent-gold);
  --action-reply-bg:    rgba(0, 229, 255, 0.10);
  --action-repost-bg:   rgba(0, 255, 157, 0.10);
  --action-like-bg:     rgba(255, 77, 109, 0.10);
  --action-share-bg:    rgba(124, 77, 255, 0.10);
  --action-bookmark-bg: rgba(255, 215, 0, 0.10);

  --gradient-primary:   linear-gradient(135deg, rgba(124, 77, 255, 0.95), rgba(0, 229, 255, 0.85));
  --gradient-secondary: linear-gradient(135deg, rgba(0, 229, 255, 0.20), rgba(124, 77, 255, 0.15));

  --border-primary:   rgba(255, 255, 255, 0.10);
  --border-secondary: rgba(255, 255, 255, 0.06);
  --border-glow:      rgba(0, 229, 255, 0.35);
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.15);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.25);
  --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.35);

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  --radius-sm:   8px;
  --radius-md:   14px;
  --radius-lg:   20px;
  --radius-xl:   28px;
  --radius-full: 9999px;

  --transition-fast:   0.15s ease-out;
  --transition-normal: 0.20s ease-out;

  --sidebar-width:        260px;
  --sidebar-width-narrow: 72px;
  --aside-width:          340px;
  --tl-max-width:         620px;
  --header-mobile-height: 52px;
  --bottom-nav-height:    56px;
}

/* §1  リセット + ベース */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Noto Sans JP", "Helvetica Neue", sans-serif;
  background:
    radial-gradient(ellipse 1400px 700px at 10% -10%, rgba(124, 77, 255, 0.4), transparent 65%),
    radial-gradient(ellipse 1000px 600px at 90%   0%, rgba(0, 229, 255, 0.3), transparent 65%),
    radial-gradient(ellipse 1000px 700px at 70% 110%, rgba(0, 255, 157, 0.2), transparent 60%),
    var(--bg-primary);
  color: var(--text-primary);
  min-height: 100vh;
  line-height: 1.5;
  overflow-x: clip;
}

/* .lightbox-close / .lightbox-nav の見た目は php-style.css §138 で
   Morioka brand 風 (暗ガラス + 紫グラデ glow on hover) に統一済。
   ここでは §109 text-primary 強制を打ち消すための色 !important のみ。 */
.lightbox-nav {
  background: rgba(20, 16, 40, 0.62) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, 0.22) !important;
  -webkit-backdrop-filter: blur(10px) saturate(140%);
          backdrop-filter: blur(10px) saturate(140%);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45) !important;
}
.lightbox-close,
.lightbox-close *,
.lightbox-nav,
.lightbox-nav * { color: #fff !important; }
.lightbox-nav:hover {
  background: linear-gradient(135deg, rgba(124, 77, 255, 0.85), rgba(0, 229, 255, 0.7)) !important;
  border-color: rgba(255, 255, 255, 0.4) !important;
}

/* 認証ページ (login / register / forgot / reset) は PHP と同じ
 * 暗めの linear-gradient + orbs + 花火で statement する。
 * v2.css の body radial-gradient を上書き。 */
body.auth-page {
  background: linear-gradient(135deg, #0a0e2a 0%, #1a0f3a 50%, #070916 100%) !important;
}

/* iOS PWA (standalone) の Dynamic Island / notch にロゴ/ヘッダが被るのを防ぐ。
 * auth (login/register/forgot/reset) と legal (terms/privacy) で
 * 上端に safe-area-inset-top を加算。bottom も home indicator 分を確保。 */
body.auth-page .auth-x-container,
body.auth-page .auth-x-hero,
body.legal-page .legal-wrap {
  padding-top: max(env(safe-area-inset-top), 12px);
  padding-bottom: max(env(safe-area-inset-bottom), 12px);
}
@media (max-width: 768px) {
  body.auth-page .auth-x-hero { padding-top: max(env(safe-area-inset-top), 16px); }
  body.legal-page .legal-header { padding-top: max(env(safe-area-inset-top), 12px); }
}
a { color: inherit; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.08); border-radius: var(--radius-full); }
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.15); }

/* §2  アニメーション */
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes likePop { 0% { transform: scale(1); } 30% { transform: scale(1.4); } 60% { transform: scale(0.9); } 100% { transform: scale(1); } }
@keyframes cm-slide-down { from { transform: translateY(-110%); opacity: 0.4; } to { transform: translateY(0); opacity: 1; } }

/* §3  レイアウト (3 カラム) */
.layout-3col {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, var(--tl-max-width)) var(--aside-width);
  max-width: calc(var(--sidebar-width) + var(--tl-max-width) + var(--aside-width));
  margin: 0 auto;
  min-height: 100vh;
}
.col-nav { position: sticky; top: 0; height: 100dvh;
  border-right: 1px solid var(--border-primary); display: flex; flex-direction: column;
  padding: var(--space-2); z-index: 50; }
.col-main { border-right: 1px solid var(--border-primary); min-width: 0; position: relative; }
.col-aside { position: sticky; top: 0; height: 100dvh; overflow-y: auto;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4); }

@media (max-width: 1279px) {
  .layout-3col {
    grid-template-columns: var(--sidebar-width-narrow) minmax(0, var(--tl-max-width)) var(--aside-width);
    max-width: calc(var(--sidebar-width-narrow) + var(--tl-max-width) + var(--aside-width));
  }
  .nav-item .label, .logo-section .logo-text { display: none; }
  .nav-item { justify-content: center; padding: 12px; }
}
@media (max-width: 1023px) {
  .layout-3col {
    grid-template-columns: var(--sidebar-width-narrow) minmax(0, 1fr);
    max-width: calc(var(--sidebar-width-narrow) + var(--tl-max-width));
  }
  .col-aside { display: none; }
}
@media (max-width: 767px) {
  .layout-3col { grid-template-columns: 1fr; max-width: 100%; }
  .col-nav { display: none; }
  /* PWA standalone モードでは status bar (≈47px) と被るぶん mobile-header が
     視覚的に背伸びするので、col-main の margin-top にも safe-area-inset-top を
     足さないとコンテンツ先頭 (col-main-header の h1) が mobile-header に潜り込む。
     bottom-nav も同様に safe-area-inset-bottom 加算。 */
  .col-main { border-right: none;
    margin-top: calc(var(--header-mobile-height) + env(safe-area-inset-top));
    margin-bottom: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom)); }
}

/* §4  サイドバーナビ */
.logo-section {
  margin-bottom: var(--space-2);
  padding: var(--space-2) var(--space-3);
  display: flex; align-items: center; gap: var(--space-2);
}
.logo-section a { display: flex; align-items: center; gap: var(--space-2);
  text-decoration: none; color: inherit; transition: filter var(--transition-fast); }
.logo-section a:hover { filter: brightness(1.2) drop-shadow(0 0 12px rgba(0, 229, 255, 0.40)); }
.logo-section .logo-text {
  font-weight: 900; font-size: 1.05rem;
  background: linear-gradient(135deg, var(--text-accent), var(--accent-cyan));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.logo-section .logo-emoji { font-size: 1.6rem; }
.logo-section .sidebar-logo-link img {
  width: 56px; height: 56px;
  border-radius: 12px;
  object-fit: cover;
  display: block;
}
@media (max-width: 1279px) {
  .logo-section { padding: var(--space-2); justify-content: center; }
  .logo-section .sidebar-logo-link img { width: 48px; height: 48px; }
}

.nav-menu { display: flex; flex-direction: column; flex: 1; }
.nav-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 10px 14px; border-radius: var(--radius-full);
  color: var(--text-primary); text-decoration: none;
  font-size: 1rem; font-weight: 500;
  transition: background var(--transition-fast);
  position: relative; white-space: nowrap;
}
.nav-item:hover { background: rgba(255, 255, 255, 0.06); }
.nav-item.active { font-weight: 800; }
.nav-item .icon {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.35rem; position: relative; flex-shrink: 0;
}
.nav-item .label { flex: 1; }

.notification-badge {
  position: absolute; top: -4px; right: -8px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--accent-pink); color: #fff;
  font-size: 0.7rem; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
  box-shadow: 0 0 10px rgba(255, 77, 109, 0.50);
}

.sidebar-actions {
  margin-top: auto; padding-top: var(--space-3);
  display: flex; flex-direction: column; gap: var(--space-2);
  border-top: 1px solid var(--border-primary);
}

.btn-post-new {
  width: 100%;
  background: var(--gradient-primary);
  color: #fff; border: none;
  padding: 12px 20px;
  border-radius: var(--radius-full);
  font-size: 1rem; font-weight: 800;
  text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  cursor: pointer;
  transition: all var(--transition-fast);
  box-shadow: 0 0 20px rgba(0, 229, 255, 0.20);
}
.btn-post-new:hover {
  filter: brightness(1.15); transform: translateY(-1px);
  box-shadow: 0 0 30px rgba(0, 229, 255, 0.35), 0 4px 16px rgba(124, 77, 255, 0.25);
}
@media (max-width: 1279px) {
  .btn-post-new { padding: 12px; font-size: 0; }
  .btn-post-new::before { content: '+'; font-size: 1.5rem; font-weight: 800; }
}

.sidebar-account {
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  display: flex; align-items: center; gap: var(--space-2);
  border-radius: var(--radius-full);
  cursor: pointer; text-decoration: none; color: inherit;
  transition: background var(--transition-fast);
}
.sidebar-account:hover { background: rgba(255, 255, 255, 0.06); }
.sidebar-account .account-info { min-width: 0; flex: 1; overflow: hidden; }
.sidebar-account .account-info > div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-account .account-name { font-weight: 700; font-size: 0.92rem; line-height: 1.2; }
.sidebar-account .account-handle { font-size: 0.82rem; color: var(--text-muted); }
@media (max-width: 1279px) {
  .sidebar-account .account-info, .sidebar-account .account-chevron { display: none; }
  .sidebar-account { justify-content: center; }
}

/* §5  メインカラム header / タブ */
.col-main-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(7, 9, 22, 0.85);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border-primary);
  padding: var(--space-3) var(--space-4) 0;
  transition: transform var(--transition-normal);
}
/* sticky 要素を display:none で flow から消すと document 高が縮み、
   ブラウザの scroll 補正 → JS の逆方向検知 → 反対トグルのループで
   コンテンツがガクガクする (ホーム中盤を小刻みスクロールで再現)。
   flow を動かさない transform + opacity (iOS の sticky+transform バグ用の
   視覚フォールバック) + pointer-events:none (クリック透過) で隠す。 */
.col-main-header.hidden {
  /* !important は body.theme-* 等の specificity 0-2-1 オーバーライドからの保険
     (php-style.css 11444 の theme-light GPU ヒントが上書きしていた件)。 */
  transform: translateY(-200%) !important;
  opacity: 0 !important;
  pointer-events: none !important;
}
.col-main-header h1 { font-size: 1.25rem; font-weight: 800; margin: 0 0 var(--space-2); }

/* モバイル時は固定 mobile-header (高さ var(--header-mobile-height) + PWA の
   safe-area-inset-top) が viewport 上端を占めるので、col-main-header の sticky
   top にも同じ計算を入れて「ホーム」見出し / タブが mobile-header に被らない
   ようにする。 */
@media (max-width: 767px) {
  .col-main-header { top: calc(var(--header-mobile-height) + env(safe-area-inset-top)); }
}

.tabs { display: flex; margin-top: var(--space-3); gap: 0; }
.tab {
  flex: 1; min-width: 0; text-align: center;
  padding: var(--space-3) var(--space-2);
  cursor: pointer;
  color: var(--text-muted); text-decoration: none;
  font-weight: 700; font-size: 1rem;
  white-space: nowrap;
  position: relative;
  transition: all var(--transition-fast);
}
.tab:hover { background: var(--bg-card-hover); color: var(--text-primary); }
.tab.active { color: var(--text-primary); }
.tab.active::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 50%;
  max-width: 80px;
  height: 4px;
  background: var(--gradient-primary);
  border-radius: var(--radius-full);
}

/* §6  モバイルヘッダー + ドロワー */
.mobile-header {
  display: none;
  position: fixed; top: 0; left: 0; right: 0;
  /* PWA standalone モードで status bar (~47px) と被るぶん height を増やす。
     padding-top が border-box で 52px を食ってしまうのを防ぐ。これで
     mobile-header の実体は (52 + safe-area) px に拡張され、コンテンツ部は
     常に 52px 確保される。 */
  height: calc(var(--header-mobile-height) + env(safe-area-inset-top));
  padding-top: env(safe-area-inset-top);
  background: rgba(7, 9, 22, 0.85);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border-primary);
  z-index: 100;
}
.mobile-header-content {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--space-3);
  height: var(--header-mobile-height);
}
.mobile-logo .logo-emoji { font-size: 1.6rem; }
.account-icon { width: 32px; height: 32px; cursor: pointer; }
.account-icon img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.account-icon-placeholder {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 0.95rem;
}

.drawer-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 199; opacity: 0;
  transition: opacity var(--transition-normal);
}
.drawer-overlay.open { display: block; opacity: 1; }

.side-drawer {
  position: fixed; top: 0; left: 0;
  width: 280px; height: 100dvh;
  /* 旧 var(--bg-secondary) は半透明値で、スクロール時に裏のページ内容
     (ホーム/検索/+ ボタン等) が透けて重なって読めなくなる事故。
     完全不透明な solid 色で塗って下に何も透けないように。 */
  background: #0a0e1a;
  border-right: 1px solid var(--border-primary);
  transform: translateX(-100%);
  transition: transform var(--transition-normal);
  z-index: 200;
  padding: env(safe-area-inset-top) var(--space-3) var(--space-3);
  overflow-y: auto;
  display: flex; flex-direction: column;
}
/* light テーマでは白寄りに */
body.theme-light .side-drawer {
  background: #ffffff;
}
.side-drawer.open { transform: translateX(0); }
/* iOS Safari の overflow scroll で子要素が描画ズレ (drawer-header と
 * drawer-menu が重なって見える) するのを防ぐため、新しいスタッキング
 * コンテキストを切って慣性スクロールも有効化。 */
.side-drawer {
  isolation: isolate;
  -webkit-overflow-scrolling: touch;
  contain: layout style;
}
/* drawer 内の主要セクションは必ず block + 自身の不透明背景で重ならないよう
 * 明示。PHP では暗黙的に成立してたが iOS PWA で稀に z 順が崩れて被る。 */
.drawer-header,
.drawer-x-header,
.drawer-account-menu,
.drawer-menu,
.drawer-footer,
.drawer-feedback {
  position: relative;
  display: block;
  z-index: 1;
  background: inherit;
}
.drawer-menu { display: flex; flex-direction: column; }
.drawer-header { padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--border-primary); }
.drawer-x-top { display: flex; align-items: center; justify-content: space-between; }
.drawer-x-avatar { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; }
.drawer-x-name { margin-top: var(--space-2); font-weight: 800; font-size: 1.05rem; }
.drawer-x-handle { color: var(--text-muted); font-size: 0.88rem; }
.drawer-x-stats { display: flex; gap: var(--space-4); margin-top: var(--space-2); }
.drawer-x-stat { text-decoration: none; color: inherit; }
.drawer-x-stat-num { font-weight: 800; }
.drawer-x-stat-label { color: var(--text-muted); margin-left: 4px; font-size: 0.85rem; }
.drawer-menu { padding: var(--space-2) 0; flex: 1; }
.drawer-menu-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 12px var(--space-3); border-radius: var(--radius-md);
  color: var(--text-primary); text-decoration: none; font-size: 1rem;
}
.drawer-menu-item:hover { background: var(--bg-hover); }
.drawer-menu-item .icon {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.2rem; position: relative;
}
.drawer-footer { padding: var(--space-3) var(--space-2); border-top: 1px solid var(--border-primary); }
.drawer-logout-btn {
  display: flex; align-items: center; gap: var(--space-2);
  padding: 10px var(--space-3); border-radius: var(--radius-full);
  color: var(--accent-pink); text-decoration: none; font-weight: 700;
}
.drawer-logout-btn:hover { background: var(--action-like-bg); }

@media (max-width: 767px) { .mobile-header { display: block; } }

/* php-style.css L7906-7912 で .drawer-header に
     background: linear-gradient(#0a0e2a, #050714) !important;
   が当たっていて、user-colors を変えても drawer 上部のアカウント枠だけ
   濃紺のままになる。selector specificity 0-2-0 + !important で上書きして
   .side-drawer 本体 (var(--bg-secondary)) と同じ色味に揃える。 */
@media (max-width: 767px) {
  .side-drawer .drawer-header {
    background: transparent !important;
  }
  /* drawer-x-name / handle も PHP は color: white / #7a8aaf 固定なので
     CSS variable に戻してカスタムカラー追従。 */
  .side-drawer .drawer-x-name   { color: var(--text-primary) !important; }
  .side-drawer .drawer-x-handle { color: var(--text-muted) !important; }

  /* php-style.css L8203- が "X 本物互換" として モバイル限定で本文系を
       color: #e7e9ea !important; (白) / #71767b !important; (グレー)
     にハードコード塗りしているせいで、明色テーマ / 桃色などカスタム
     カラー時に読めなくなる (背景白っぽい + 文字も白系)。
     selector 先頭に body を足して specificity 0-1-1 + !important で
     CSS variable 経由に戻す。 */
  body .post-body,
  body .post-detail-body,
  body .post-author-meta .author-name,
  body .quote-card .author-name,
  body .quote-card .quote-body,
  body .ogp-title {
    color: var(--text-primary) !important;
  }
  body .post-author-meta .author-handle,
  body .post-author-meta .post-meta-sep,
  body .post-author-meta .time-toggle,
  body .quote-card .author-handle,
  body .quote-card .quote-time,
  body .ogp-host,
  body .ogp-desc,
  body .post-author-meta .muted.small,
  body .post-pinned-label,
  body .action-btn,
  body .action-btn i,
  body .action-btn .count,
  body .kebab-btn {
    color: var(--text-muted) !important;
  }
  body .quote-card,
  body .ogp-card {
    border-color: var(--border-primary) !important;
  }
}

/* §7  ボトムナビ — スタイル定義は php-style.css の .bottom-nav / .bottom-nav .nav-item
   に完全依存。v2 独自の bottom-nav-inner / bottom-nav-item ルールは bottom_nav.html を
   PHP 互換 (.nav-menu > .nav-item) 構造に書き換えたので不要になり削除した。 */

/* §8  アバター + バッジ */
.avatar { display: inline-block; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.avatar-sm { width: 28px; height: 28px; }
.avatar-md { width: 44px; height: 44px; }
.avatar-lg { width: 80px; height: 80px; }
.avatar-xl { width: 128px; height: 128px; }
.avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center;
}
.avatar-sm.avatar-placeholder { font-size: 0.85rem; }
.avatar-md.avatar-placeholder { font-size: 1.1rem; }
.avatar-lg.avatar-placeholder { font-size: 2.2rem; }
.avatar-xl.avatar-placeholder { font-size: 3.4rem; }

/* 認証バッジ (specialMark / adminMark / secretMark) は php-style.css の実装
   (cyan-purple ✓ 円 / 青 fa-circle-check / cyan fa-lock) に完全に任せる。
   v2.css が独自に gold ★ + ピンク 🛡 でラップしていたが、PHP と見た目が
   食い違う + secretMark を 18x18 のブロック化して FA lock を潰すバグ付きだった。 */

/* プレミアム加入ユーザのバッジ。Plan.BadgeIcon = "fa-solid fa-gem" を Pink-Gold
   グラデのチップに乗せる。.specialMark 等と並んで表示可能。
   タイムライン / プロフィール / drawer など、@handle 横で共通使用。 */
.premiumMark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: linear-gradient(135deg, #ff578b, #ffd700);
  color: #fff;
  font-size: 9px;
  margin-left: 1px;
  vertical-align: middle;
  flex-shrink: 0;
}
.premiumMark i { font-size: 9px; line-height: 1; }

.beta-tag {
  display: inline-block;
  /* ダーク・ライト両モードで完全一致の固定グラデーション (テーマ変数に依存しない)。
     ユーザ要望: light でも dark でも同じ見た目に。 */
  background: linear-gradient(135deg, #7c4dff, #00e5ff) !important;
  color: #fff !important;
  border-radius: var(--radius-full);
  padding: 1px 8px; font-size: 0.65rem; font-weight: 800;
  margin-left: 4px; vertical-align: middle;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
  box-shadow: 0 1px 3px rgba(124, 77, 255, 0.35);
}
.muted { color: var(--text-muted); }
.small { font-size: 0.85rem; }

/* §9  投稿カード */
.post {
  padding: var(--space-3) var(--space-4) var(--space-2);
  border-bottom: 1px solid var(--border-primary);
  transition: background var(--transition-fast);
  position: relative;
  cursor: pointer;
}
.post:last-child { border-bottom: none; }
.post:hover { background: var(--bg-card-hover); }
.post-pinned-label {
  font-size: 0.78rem; color: var(--text-muted);
  margin-bottom: var(--space-2); padding-left: 56px;
}
/* X 風「↻ ◯◯ さんがリポストしました」: アバター列の左にインデントを揃え、
   ミュート色で控えめに表示。post-card 全体をクリック可能なまま個別リンクとして動かす。 */
.post-repost-by {
  display: flex; align-items: center; gap: 6px;
  font-size: 0.78rem; color: var(--text-muted);
  margin-bottom: var(--space-2); padding-left: 56px;
  text-decoration: none;
}
.post-repost-by:hover span { text-decoration: underline; }
.post-repost-by i { color: var(--accent-green); font-size: 0.82rem; flex-shrink: 0; }
.post-grid {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: var(--space-3); min-width: 0;
}
.post-avatar-col { width: 44px; }
.post-main-col { min-width: 0; }
.posthead {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--space-3); margin-bottom: 2px;
}
.post-author-meta {
  /* PHP _post_card.php と同じく flex-wrap: nowrap + flex: 1 で 1 行固定。
     これで名前 / handle / 時刻が長くても折り返さず、posthead 直下の kebab
     (post-meta-right) が常に最右上に居続ける (折り返して "下に潜る" のを防ぐ)。
     名前が長い場合は author-link が overflow: hidden + ellipsis で省略される。 */
  display: flex; align-items: center; gap: 4px 6px;
  flex: 1; min-width: 0; flex-wrap: nowrap;
  font-size: 0.9rem; line-height: 1.3;
}
.post-author-meta .author-link {
  text-decoration: none; color: inherit;
  min-width: 0;     /* 子の ellipsis を有効化 */
  flex: 0 1 auto;
  overflow: hidden;
}
.post-author-meta .author-name-text {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.author-link { text-decoration: none; color: inherit; }
.author-name {
  font-size: 0.95rem; font-weight: 800; color: var(--text-primary);
  display: inline-flex; align-items: center; gap: 4px;
}
.author-name:hover .author-name-text { text-decoration: underline; }
.author-handle { font-size: 0.88rem; color: var(--text-muted); white-space: nowrap; }
.post-meta-sep { color: var(--text-muted); padding: 0 2px; }
.time-toggle {
  background: none; border: none; color: var(--text-muted);
  cursor: pointer; padding: 0; font: inherit; font-size: 0.88rem;
}
.time-toggle:hover { color: var(--accent-cyan); }
.post-meta-right {
  display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0;
}
.reply-to-line { font-size: 0.875rem; color: var(--text-muted); margin-bottom: var(--space-1); }
.post-body {
  word-wrap: break-word; overflow-wrap: break-word;
  white-space: pre-wrap;
  font-size: 0.9375rem; line-height: 1.45;
  color: var(--text-primary); margin-bottom: 4px;
}
.linkified, .mention, .hashtag, .post-body a {
  color: var(--accent-cyan); text-decoration: none;
  transition: color var(--transition-fast);
}
.linkified:hover, .mention:hover, .hashtag:hover, .post-body a:hover { text-decoration: underline; }

/* ケバブ */
.kebab-wrapper { position: relative; display: inline-block; }
.kebab-btn {
  width: 32px; height: 32px; border-radius: var(--radius-full);
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all var(--transition-fast);
}
.kebab-btn:hover { background: var(--action-reply-bg); color: var(--accent-cyan); }
.kebab-menu {
  position: absolute; right: 0; top: calc(100% + 4px);
  min-width: 200px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-md);
  padding: var(--space-1) 0;
  z-index: 9999;
  box-shadow: var(--shadow-lg);
  animation: fadeIn 0.15s ease-out;
}
.kebab-item {
  display: flex; align-items: center; gap: var(--space-2);
  width: 100%; text-align: left;
  background: none; border: none; cursor: pointer;
  padding: 10px 16px;
  color: var(--text-primary); font-size: 0.9rem;
  text-decoration: none; font-family: inherit;
}
.kebab-item:hover { background: var(--bg-hover); }
.kebab-danger { color: var(--accent-pink); }
.kebab-danger:hover { background: var(--action-like-bg); }
.kebab-divider { height: 1px; background: var(--border-primary); margin: var(--space-1) 0; }

/* kebab-menu が次の post の下に隠れるバグ対策。
   .post は position: relative だが z-index 無しなので、:has() で
   メニューが開いてる post だけ持ち上げて新しい stacking context を作る。
   :has() 未対応ブラウザでは元の挙動 (= 潜る) に戻るだけで実害は少ない。 */
.post:has(.kebab-menu:not([hidden])) { z-index: 50; }
/* repost / share メニューを開いている post を最上位に上げる。
 * 後続の .post も position:relative なので、デフォルト z-index:auto では
 * DOM 順で後の方が上に来てしまい menu が隠れる。 */
.post:has(.repost-menu:not([hidden])),
.post:has(.share-menu:not([hidden])) { z-index: 100; }

/* 管理者削除 (admin / special のみ表示)。デフォルト hidden で
   body[data-user-role="admin"] / "special" のときだけ flex 表示。 */
.kebab-admin-only { display: none !important; }
body[data-user-role="admin"]   .kebab-admin-only,
body[data-user-role="special"] .kebab-admin-only { display: flex !important; }
body[data-user-role="admin"]   .kebab-divider.kebab-admin-only,
body[data-user-role="special"] .kebab-divider.kebab-admin-only { display: block !important; }

/* §10  メディア */
.post-media {
  margin-top: var(--space-3); border-radius: var(--radius-md);
  overflow: hidden; border: 1px solid var(--border-primary);
}
.post-media img { display: block; max-width: 100%; height: auto; }
.post-media-grid { display: grid; gap: 2px; }
.post-media-grid.post-media-1 { grid-template-columns: 1fr; }
.post-media-grid.post-media-2 { grid-template-columns: 1fr 1fr; }
.post-media-grid.post-media-3 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.post-media-grid.post-media-3 .post-media-item:nth-child(1) { grid-row: span 2; }
.post-media-grid.post-media-4 { grid-template-columns: 1fr 1fr; }
.post-media-item {
  display: block; position: relative;
  background: var(--bg-secondary); overflow: hidden;
}
.post-media-item img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 1 / 1; }
.post-media-1 .post-media-item img { aspect-ratio: auto; max-height: 540px; }

.post-video {
  margin-top: var(--space-3); position: relative; width: 100%;
  aspect-ratio: 16 / 9; border-radius: var(--radius-md);
  overflow: hidden; cursor: pointer;
  background: #000; border: 1px solid var(--border-primary);
}
.post-video video { width: 100%; height: 100%; object-fit: contain; }

/* §11  OGP + 引用 */
.ogp-card {
  display: block; margin-top: var(--space-3);
  border: 1px solid var(--border-primary); border-radius: 16px;
  overflow: hidden; text-decoration: none; color: inherit;
  background: var(--bg-card);
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.ogp-card:hover { border-color: var(--border-glow); background: var(--bg-card-hover); }
.ogp-image {
  width: 100%; aspect-ratio: 1.91 / 1; object-fit: cover; display: block;
  background: var(--bg-secondary);
}
.ogp-body  { padding: 10px 12px; }
.ogp-title {
  font-weight: 600; margin-bottom: 2px; color: var(--text-primary);
  font-size: 0.9375rem; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ogp-desc {
  font-size: 0.875rem; color: var(--text-secondary); line-height: 1.35; margin-bottom: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ogp-host { font-size: 0.8125rem; color: var(--text-muted); line-height: 1.3; }

.quote-card {
  display: block; margin-top: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-primary); border-radius: var(--radius-md);
  /* 親 post-card との視覚的分離は親色に薄いオーバーレイで作る。
     ハードコード色だとカスタムテーマで「青いブロブ」になるため、
     透過オーバーレイ + 透過 panel の重ねで全テーマに追従させる。 */
  background:
    linear-gradient(rgba(127,127,127,0.06), rgba(127,127,127,0.06)),
    var(--bg-card);
  color: var(--text-primary);
  text-decoration: none;
  transition: border-color var(--transition-fast);
  min-width: 0; max-width: 100%; overflow: hidden;
}
.quote-card:hover { border-color: var(--border-glow); }
.quote-head { display: flex; gap: var(--space-2); margin-bottom: var(--space-2); align-items: center; }
.quote-meta { flex: 1; min-width: 0; }
.quote-author {
  font-weight: 700; font-size: 0.875rem; color: var(--text-primary);
  display: flex; align-items: center; gap: 4px; min-width: 0;
}
.quote-author .author-name-text {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.quote-handle { color: var(--text-muted); }
.quote-time { white-space: nowrap; font-size: 0.825rem; color: var(--text-muted); }
.quote-body {
  font-size: 0.875rem; color: var(--text-primary); line-height: 1.4;
  word-wrap: break-word; overflow-wrap: anywhere; white-space: pre-wrap;
}
.quote-image {
  max-width: 60%; max-height: 200px; object-fit: cover;
  margin-top: var(--space-2); border-radius: var(--radius-sm); display: block;
}

/* §12  アクションバー X 風
   PHP _post_card.php と完全同等: 親 col-main の幅一杯まで space-between で
   広げる (ブックマーク/共有が右端に来る)。前 commit で max-width: 425px に
   絞ったら左寄せでスカスカになり PHP より悪化したので 100% に戻す。 */
.post-actions {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 2px; max-width: 100%; padding-right: var(--space-2);
}
/* スマホ幅: 親幅一杯 + 5 等分配置 (PC と同じく親幅一杯)。
   form ラッパが flex 子なので button に flex:1 が効かない問題対策で
   直系子に flex:1 を当てる。 */
@media (max-width: 767px) {
  .post-actions > * { flex: 1 1 0; min-width: 0; }
  .post-actions > form > .action-btn { width: 100%; justify-content: center; }
  .post-actions > .action-btn         { justify-content: center; }
}
.action-btn {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 0.8125rem;
  display: inline-flex; align-items: center; gap: 2px;
  padding: 0; text-decoration: none;
  font-family: inherit; font-weight: 500;
  transition: color var(--transition-fast);
}
.action-btn i {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--radius-full);
  font-size: 16px; transition: all var(--transition-fast); flex-shrink: 0;
}
.action-btn .count { font-variant-numeric: tabular-nums; min-width: 1ch; }

.action-btn:hover     { color: var(--action-reply); }
.action-btn:hover i   { background: var(--action-reply-bg); color: var(--action-reply); }
.action-btn.like:hover     { color: var(--action-like); }
.action-btn.like:hover i   { background: var(--action-like-bg); color: var(--action-like); }
.action-btn.liked          { color: var(--action-like); }
.action-btn.liked i        { color: var(--action-like); }
.action-btn.liked:active i { animation: likePop 0.4s ease-out; }
.action-btn.repost:hover   { color: var(--action-repost); }
.action-btn.repost:hover i { background: var(--action-repost-bg); color: var(--action-repost); }
.action-btn.reposted       { color: var(--action-repost); }
.action-btn.reposted i     { color: var(--action-repost); }
.action-btn.share:hover    { color: var(--action-share); }
.action-btn.share:hover i  { background: var(--action-share-bg); color: var(--action-share); }
.action-btn.bookmark:hover     { color: var(--action-bookmark); }
.action-btn.bookmark:hover i   { background: var(--action-bookmark-bg); color: var(--action-bookmark); }
.action-btn.bookmarked         { color: var(--action-bookmark); }
.action-btn.bookmarked i       { color: var(--action-bookmark); }

.repost-wrapper, .share-wrapper { position: relative; display: inline-block; }
.repost-menu {
  position: absolute; bottom: calc(100% + 4px); left: 0;
  min-width: 200px; background: var(--bg-secondary);
  border: 1px solid var(--border-primary); border-radius: var(--radius-md);
  padding: var(--space-1) 0; z-index: 100; box-shadow: var(--shadow-lg);
}
.repost-menu.share-menu { left: auto; right: 0; }
.repost-menu-item {
  display: flex; align-items: center; gap: var(--space-2);
  width: 100%; text-align: left; background: none; border: none;
  padding: 10px 16px; color: var(--text-primary);
  font-size: 0.9rem; text-decoration: none; cursor: pointer; font-family: inherit;
}
.repost-menu-item:hover { background: var(--bg-hover); }
.repost-menu-divider { height: 1px; background: var(--border-primary); margin: var(--space-1) 0; }

/* §13  コンポーザ */
.composer-inline {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-primary);
}
.composer-grid { display: grid; grid-template-columns: 44px 1fr; gap: var(--space-3); }
.composer-textarea {
  width: 100%;
  background: transparent;
  border: none; color: var(--text-primary);
  font: inherit; font-size: 1.1rem;
  resize: none; outline: none;
  min-height: 56px; line-height: 1.4;
}
.composer-textarea::placeholder { color: var(--text-muted); }
.composer-actions {
  display: flex; align-items: center;
  margin-top: var(--space-2); gap: var(--space-2);
  border-top: 1px solid var(--border-primary); padding-top: var(--space-2);
}
.composer-action {
  width: 36px; height: 36px; border-radius: 50%;
  border: none; background: transparent;
  color: var(--accent-cyan); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.1rem; transition: background var(--transition-fast);
}
.composer-action:hover { background: var(--action-reply-bg); }
.composer-counter { color: var(--text-muted); margin-left: auto; font-size: 0.85rem; }
.composer-submit {
  background: var(--gradient-primary); color: #fff; border: none;
  padding: 8px 20px; border-radius: var(--radius-full);
  font-weight: 800; font-size: 0.95rem; cursor: pointer;
  transition: filter var(--transition-fast);
}
.composer-submit:hover:not(:disabled) { filter: brightness(1.15); }
.composer-submit:disabled { opacity: 0.5; cursor: not-allowed; }

.composer-modal {
  display: none;
  position: fixed; inset: 0; z-index: 1000;
  align-items: flex-start; justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  padding: var(--space-4);
}
.composer-modal[open] { display: flex; }
.cm-sheet {
  background: var(--bg-secondary);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-xl);
  width: 100%; max-width: 600px; max-height: 90vh;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg);
  margin-top: max(calc(env(safe-area-inset-top, 0px) + 8px), 8px);
}
.cm-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-primary);
}
.cm-close {
  background: none; border: none; color: var(--text-primary);
  width: 36px; height: 36px; border-radius: 50%;
  cursor: pointer; font-size: 1.2rem;
}
.cm-close:hover { background: var(--bg-hover); }
.cm-body { padding: var(--space-3) var(--space-4); flex: 1; overflow-y: auto; }
.cm-preview {
  border: 1px solid var(--border-primary); border-radius: var(--radius-md);
  padding: var(--space-3); margin-bottom: var(--space-3); background: var(--bg-card);
}
.cm-preview-text {
  font-size: 0.88rem; color: var(--text-muted);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.cm-preview-thumb {
  max-width: 160px; max-height: 96px; border-radius: var(--radius-sm);
  margin-top: var(--space-2); object-fit: cover;
}
.cm-image-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 6px; margin-top: var(--space-2);
}
.cm-image-tile { position: relative; border-radius: var(--radius-sm); overflow: hidden; }
.cm-image-tile img { width: 100%; max-height: 140px; object-fit: cover; }
/* 動画プレビュー (1 投稿に 1 本)。サムネがあれば <img>、無ければ noimg。 */
.cm-video-preview { margin-top: var(--space-2); }
.cm-video-tile {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  max-width: 320px;
}
.cm-video-tile img { width: 100%; max-height: 200px; object-fit: cover; display: block; }
.cm-video-tile-noimg {
  display: flex; align-items: center; justify-content: center;
  height: 120px; background: #1a1033; color: #fff; font-size: 1.4rem;
}
.cm-image-remove {
  position: absolute; top: 4px; right: 4px;
  width: 28px; height: 28px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.6); color: #fff;
  border: none; cursor: pointer; font-size: 1rem;
}
.cm-progress {
  position: relative; margin: var(--space-2) 0; height: 6px;
  background: rgba(255, 255, 255, 0.08); border-radius: var(--radius-full); overflow: hidden;
}
.cm-progress-bar { height: 100%; width: 0; background: var(--gradient-primary); transition: width 0.1s; }
.cm-actions-bar {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border-primary);
}
.cm-attach-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--border-primary); color: var(--text-muted);
  cursor: pointer; margin-right: auto; font-size: 1rem; background: transparent;
}
.cm-attach-btn:hover { color: var(--accent-cyan); border-color: var(--accent-cyan); }

/* TL ピン留めトグル (composer 内、attach btn 横)。
 *   - 既定: 線アイコン + 文字 "ピン留め" (グレー)
 *   - active (1h/24h 選択時): gold 色 + ラベル変化、押すたびに cycle */
.cm-promote-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 10px;
  border-radius: 999px; border: 1px solid var(--border-primary);
  background: transparent; color: var(--text-muted);
  cursor: pointer; font-size: 0.78rem; line-height: 1; font-weight: 600;
  white-space: nowrap;
}
.cm-promote-btn i { font-size: 0.78rem; }
.cm-promote-btn:hover { color: var(--accent-gold); border-color: var(--accent-gold); }
.cm-promote-btn.active { color: var(--bg-primary); background: var(--accent-gold); border-color: var(--accent-gold); }
body.theme-light .cm-promote-btn.active { color: #fff; }

@media (max-width: 720px) {
  .composer-modal { padding: 0; align-items: flex-start; }
  .cm-sheet {
    margin-top: calc(8px + env(safe-area-inset-top, 0px));
    max-height: calc(90dvh - env(safe-area-inset-top, 0px));
    border-radius: var(--radius-lg);
    animation: cm-slide-down 0.22s cubic-bezier(0.22, 1, 0.36, 1);
  }
}

/* §14  共通 */
.empty-state { text-align: center; padding: 48px 16px; color: var(--text-muted); }
.empty-state h2 { color: var(--text-primary); margin: 12px 0; font-size: 1.1rem; }
.empty-state .empty-icon { font-size: 2rem; color: var(--accent-cyan); }
.empty-state code {
  background: var(--bg-hover); padding: 1px 6px; border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85em;
}

.v2-error {
  padding: 11px 14px;
  margin: 0 var(--space-4) var(--space-3);
  border: 1px solid var(--accent-pink);
  background: var(--action-like-bg);
  border-radius: var(--radius-md);
  color: var(--accent-pink); font-size: 0.9rem;
}
.v2-success, .settings-success {
  padding: 11px 14px; margin-bottom: var(--space-3);
  background: rgba(0, 255, 157, 0.08);
  border: 1px solid var(--accent-green);
  border-radius: var(--radius-md);
  color: var(--accent-green); font-size: 0.9rem;
}
.v2-breadcrumb {
  padding: var(--space-3) var(--space-4);
  font-size: 0.85rem; color: var(--text-muted);
}
.v2-breadcrumb a { color: var(--text-muted); text-decoration: none; }
.v2-breadcrumb a:hover { color: var(--accent-cyan); }
.v2-breadcrumb-sep { margin: 0 6px; }

/* .btn の基本スタイルは php-style.css L929 (subtle bg + border) を継承。
 * 旧 v2 では全 .btn を gradient 化していたが、PHP 配色に揃えるため撤回。
 * gradient が欲しい primary action は class="btn primary" を使う (php-style L960)。 */
.auth-submit {
  background: var(--gradient-primary); color: #fff; border: none;
  padding: 10px 22px; border-radius: var(--radius-full);
  font-weight: 800; cursor: pointer; font-family: inherit; font-size: 0.95rem;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  text-decoration: none; transition: filter var(--transition-fast);
}
.auth-submit:hover { filter: brightness(1.15); }
.btn.ghost { background: transparent; border: 1px solid var(--border-primary); color: var(--text-primary); }
.btn.ghost:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }

.auth-form-section {
  max-width: 420px; margin: var(--space-8) auto;
  padding: var(--space-6) var(--space-5);
  border: 1px solid var(--border-primary); border-radius: var(--radius-lg);
  background: var(--bg-card);
}
.auth-form-title {
  margin: 0 0 var(--space-4); font-size: 1.4rem; text-align: center;
  background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.auth-form { display: flex; flex-direction: column; gap: var(--space-3); }
.auth-field { display: flex; flex-direction: column; gap: 5px; }
.auth-label { font-size: 0.85rem; color: var(--text-muted); }
.auth-label small { color: var(--text-muted); opacity: 0.7; margin-left: 4px; font-size: 0.78em; }
.auth-form input, .settings-textarea {
  padding: 10px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-primary);
  background: rgba(255, 255, 255, 0.03); color: var(--text-primary); font: inherit;
}
.auth-form input:focus, .settings-textarea:focus { outline: none; border-color: var(--accent-cyan); }
.settings-textarea { resize: vertical; line-height: 1.5; }
.auth-alt { text-align: center; font-size: 0.9rem; color: var(--text-muted); margin: var(--space-4) 0 0; }
.auth-alt a { color: var(--accent-cyan); text-decoration: none; }
.auth-alt a:hover { text-decoration: underline; }

.user-list { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--border-primary); }
.user-list-item { border-bottom: 1px solid var(--border-primary); }
.user-list-link {
  display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-4);
  text-decoration: none; color: inherit;
}
.user-list-link:hover { background: var(--bg-card-hover); }
.user-list-avatar img, .user-list-avatar-placeholder {
  width: 44px; height: 44px; border-radius: 50%; object-fit: cover; display: block;
}
.user-list-avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem;
}
.user-list-meta { min-width: 0; flex: 1; }
.user-list-name { color: var(--text-primary); font-weight: 700; font-size: 0.95rem; }
.user-list-handle { color: var(--text-muted); font-size: 0.85rem; }
.user-list-bio {
  margin-top: 4px; color: var(--text-muted); font-size: 0.85rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Profile */
.profile-header {
  padding: var(--space-5) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border-primary);
}
.profile-identity { display: flex; gap: var(--space-4); align-items: center; }
.profile-avatar {
  width: 96px; height: 96px; border-radius: 50%; object-fit: cover; flex-shrink: 0;
}
.profile-avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800; font-size: 2.4rem;
  display: flex; align-items: center; justify-content: center;
}
.profile-name-block { flex: 1; min-width: 0; }
.profile-name { font-size: 1.4rem; font-weight: 800; }
.profile-handle { color: var(--text-muted); font-size: 0.95rem; }
.profile-bio { margin: var(--space-3) 2px var(--space-2); white-space: pre-wrap; word-break: break-word; }
.profile-meta {
  display: flex; gap: var(--space-4);
  color: var(--text-muted); font-size: 0.88rem; margin-top: var(--space-2);
}
.profile-meta-item strong { color: var(--text-primary); }
.profile-meta-link { text-decoration: none; color: var(--text-muted); }
.profile-meta-link:hover { color: var(--accent-cyan); text-decoration: underline; }

.profile-actions { display: flex; gap: var(--space-2); align-items: center; margin-left: auto; }
.profile-msg-btn {
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--border-primary);
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; color: var(--text-primary); font-size: 1.05rem;
}
.profile-msg-btn:hover { border-color: var(--accent-cyan); background: var(--action-reply-bg); }
.profile-follow-form { margin: 0; }
.profile-follow-btn {
  padding: 8px 22px; border-radius: var(--radius-full);
  font-weight: 800; cursor: pointer;
  border: 1px solid var(--accent-cyan);
  background: var(--gradient-primary); color: #fff; font-size: 0.9rem;
}
.profile-follow-btn:hover { filter: brightness(1.15); }
.profile-follow-btn--on { background: transparent; color: var(--accent-cyan); }
.profile-follow-btn--on:hover {
  background: var(--action-like-bg); border-color: var(--accent-pink); color: var(--accent-pink);
}
.profile-more { position: relative; }
.profile-more[open] .profile-more-menu { display: block; }
.profile-more-btn {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border: 1px solid var(--border-primary); border-radius: 50%;
  font-size: 1.2rem;
}
.profile-more-btn::-webkit-details-marker { display: none; }
.profile-more-btn:hover { border-color: var(--accent-cyan); }
.profile-more-menu {
  display: none; position: absolute; right: 0; top: 46px; z-index: 50;
  min-width: 220px;
  background: var(--bg-secondary); border: 1px solid var(--border-primary);
  border-radius: var(--radius-md); padding: var(--space-1);
  box-shadow: var(--shadow-lg);
}
.profile-more-menu form { margin: 0; }
.profile-more-item {
  display: block; width: 100%; text-align: left;
  background: transparent; border: none; color: var(--text-primary);
  padding: 10px 14px; border-radius: var(--radius-sm);
  cursor: pointer; font: inherit; text-decoration: none;
}
.profile-more-item:hover { background: var(--bg-hover); }
.profile-more-item--danger { color: var(--accent-pink); }
.profile-more-item--danger:hover { background: var(--action-like-bg); }

/* §15  v2 独自コンポーネント */
.timeline {}

.settings-section { padding: var(--space-4); }
.settings-title { margin: 0 0 var(--space-3); font-size: 1.3rem; }
.settings-help { color: var(--text-muted); font-size: 0.88rem; margin: 6px 0 var(--space-3); }
.settings-form { display: flex; flex-direction: column; gap: var(--space-3); max-width: 520px; }
.settings-btn {
  padding: 9px 22px; border: none; border-radius: var(--radius-full);
  font-weight: 800; color: #fff; background: var(--gradient-primary);
  cursor: pointer; font-family: inherit;
}
.settings-btn:hover { filter: brightness(1.15); }
.settings-btn--ghost {
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border-primary);
}
.settings-btn--ghost:hover {
  color: var(--accent-cyan); border-color: var(--accent-cyan); background: var(--action-reply-bg);
}
.settings-avatar-form {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-5); padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border-primary);
}
.settings-avatar-preview img, .settings-avatar-placeholder {
  width: 96px; height: 96px; border-radius: 50%; object-fit: cover; display: block;
}
.settings-avatar-placeholder {
  background: var(--gradient-primary); color: #fff;
  font-weight: 800; font-size: 2rem;
  display: flex; align-items: center; justify-content: center;
}
.settings-avatar-actions { display: flex; flex-direction: column; gap: 6px; }

.notify-title { margin: var(--space-3) var(--space-4); font-size: 1.3rem; }
.notify-list { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--border-primary); }
.notify-item { border-bottom: 1px solid var(--border-primary); }
.notify-item--unread { background: var(--action-reply-bg); }
.notify-link { display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-4); text-decoration: none; color: inherit; }
.notify-link:hover { background: var(--bg-card-hover); }
.notify-avatar img, .notify-avatar-placeholder {
  width: 36px; height: 36px; border-radius: 50%; object-fit: cover; display: block;
}
.notify-avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 0.95rem;
}
.notify-body { flex: 1; min-width: 0; }
.notify-text { color: var(--text-primary); font-size: 0.92rem; line-height: 1.5; }
.notify-handle { color: var(--text-muted); margin-left: 4px; font-size: 0.85em; }
.notify-snippet {
  margin-top: 4px; color: var(--text-muted); font-size: 0.85rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.notify-time { margin-top: 4px; color: var(--text-muted); font-size: 0.75rem; }

.msg-title { margin: var(--space-3) var(--space-4); font-size: 1.3rem; }
.msg-conv-list { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--border-primary); }
.msg-conv-item { border-bottom: 1px solid var(--border-primary); }
.msg-conv-item--unread { background: var(--action-reply-bg); }
.msg-conv-link { display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-4); text-decoration: none; color: inherit; align-items: center; }
.msg-conv-link:hover { background: var(--bg-card-hover); }
.msg-conv-avatar img, .msg-conv-avatar-placeholder {
  width: 44px; height: 44px; border-radius: 50%; object-fit: cover; display: block; flex-shrink: 0;
}
.msg-conv-avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem;
}
.msg-conv-body { flex: 1; min-width: 0; }
.msg-conv-head { display: flex; align-items: baseline; gap: 8px; font-size: 0.9rem; min-width: 0; overflow: hidden; }
.msg-conv-name {
  font-weight: 700;
  flex: 1 1 auto; min-width: 0; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.msg-conv-handle { color: var(--text-muted); font-size: 0.8rem; }
.msg-conv-time {
  color: var(--text-muted); font-size: 0.8rem;
  margin-left: auto;
  flex-shrink: 0;
  white-space: nowrap;
}

/* 時刻表記 (「○分前」「2026年5月17日」等) は絶対に改行させない。
 * post カード / 通知 / DM / 引用 / 全 <time> 要素を一括カバー。 */
time,
.time-toggle,
.notif-time,
.notif-time time,
.quote-time,
.post-time {
  white-space: nowrap !important;
  flex-shrink: 0;
}
.msg-conv-last { margin-top: 2px; color: var(--text-muted); font-size: 0.88rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msg-conv-self { color: var(--text-primary); opacity: 0.85; margin-right: 4px; }
.msg-conv-badge {
  background: var(--accent-pink); color: #fff; font-weight: 700;
  border-radius: var(--radius-full); padding: 2px 8px; font-size: 0.78rem;
}
/* ====================================================================
   DM (Direct Messages) — 全面再設計版
   ====================================================================
   構造:
     <header.dm-head> peer + 通話ボタン
     <section.dm-thread>
       <div.dm-row.is-me|is-peer>
         <button.dm-quote>?     (返信引用)
         <div.dm-bubble> 画像/テキスト
         <div.dm-meta>  時刻 + 返信/リアクション/削除
         <div.dm-reacts>?       (リアクション集計)
     <form.dm-composer>  画像 / textarea / 送信
     <div.dm-call-modal> 通話 UI
     <div.dm-react-modal> リアクションピッカー

   余計な width 計算を一切しない (bubble は max-width: 75% + viewport 上限)
   親 grid item が広がらないよう min-width:0 を明示。
   ==================================================================== */

/* === ヘッダ (sticky で常に最上部に表示) === */
/* === DM shell: 高さ固定 + 内部スクロールのチャットレイアウト ===
   PHP messages.php の .dm-col-main / .dm-chat と同じパターン:
   shell 高さを viewport - chrome に固定し、内部の .dm-thread が
   overflow:auto でスクロール。composer は flex-shrink: 0 で常に底に
   いるので、iOS Safari のキーボード展開時もページ全体の auto-scroll
   で自然に composer がキーボード直上に来る (visualViewport JS 不要)。 */
.dm-shell {
  display: flex; flex-direction: column;
  /* PC: viewport 全部使ってよい。sticky にして col-main 内で
     スクロール時もカラム上端に張り付かせる。 */
  height: 100dvh;
  position: sticky; top: 0;
  min-height: 0;
}
@media (max-width: 767px) {
  .dm-shell {
    position: static;
    /* mobile-header / bottom-nav 分を viewport から引く。
       safe-area-inset も chrome 高さに含めて差し引く必要がある。 */
    height: calc(
      100vh
      - var(--header-mobile-height) - env(safe-area-inset-top)
      - var(--bottom-nav-height)    - env(safe-area-inset-bottom)
    );
  }
  /* 入力フォーカス中は bottom-nav を隠して composer をキーボード直上に。
     PHP と同じパターン (style-new.css L12498 周辺)。 */
  body:has(.dm-input:focus) .bottom-nav { display: none; }
  body:has(.dm-input:focus) .col-main   { margin-bottom: 0; }
  body:has(.dm-input:focus) .dm-shell {
    height: calc(100vh - var(--header-mobile-height) - env(safe-area-inset-top));
  }
}

.dm-head {
  display: flex; align-items: center; gap: 12px;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-primary);
  /* user-colors の header 指定 (= --bg-overlay) に追従するため CSS var を
     使う。フォールバックは元のハードコード値を残す。 */
  background: var(--bg-overlay, rgba(7, 9, 22, 0.92));
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  flex-shrink: 0;
}
.dm-peer { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.dm-peer-avatar {
  width: 40px; height: 40px; border-radius: 50%; object-fit: cover;
  flex-shrink: 0; display: block;
}
.dm-peer-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.dm-peer-name { min-width: 0; line-height: 1.2; overflow: hidden; }
.dm-peer-name strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-call-btn {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--action-reply-bg); color: var(--accent-cyan);
  border: none; cursor: pointer; font-size: 1.1rem;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.dm-call-btn:hover { background: var(--accent-cyan); color: #fff; }

/* === スレッド (= bubble の縦リスト) ===
   shell 内で flex: 1 + overflow-y: auto。内部スクロール領域として動作。
   justify-content: flex-end + 先頭子要素 margin-top: auto で、メッセージが
   少ない時も下端 (composer 直上) に寄せて表示する (PHP 互換)。 */
.dm-thread {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--space-3) var(--space-4);
  overflow-y: auto;
  justify-content: flex-end;
  /* grid item の min-width:auto / fit-content による横はみ出しを完全防止 */
  max-width: 100%; min-width: 0; overflow-x: clip;
  box-sizing: border-box;
}
.dm-thread > :first-child { margin-top: auto; }
.dm-empty {
  text-align: center; color: var(--text-muted);
  padding: 40px 12px; font-size: 0.95rem;
}
.dm-empty i { display: block; font-size: 2rem; margin-bottom: 8px; opacity: 0.6; }

/* === 行 === */
.dm-row {
  display: flex; flex-direction: column;
  /* 75% + viewport 上限の二重防御 */
  max-width: min(75%, calc(100vw - 64px));
  min-width: 0;
}
.dm-row.is-me   { align-self: flex-end;   align-items: flex-end; }
.dm-row.is-peer { align-self: flex-start; align-items: flex-start; }

/* 通話履歴 chip (LINE 風): 中央寄せの小さい pill。発信/着信どちらでも同じ見た目。
   call_signal.go の /end で direct_messages に "📞 通話 M:SS" or "📞 不在着信"
   を insert し、テンプレ側 (hasPrefix .Body "📞 ") で chip にレンダリング。
   別途 call_history テーブル / /calls ページが並列で詳細履歴を持つ (29b7a28)。 */
.dm-row.dm-row--call-event {
  align-self: center;
  align-items: center;
  max-width: 90%;
}
.dm-call-event {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px;
  border-radius: var(--radius-full);
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.2;
}
.dm-call-event i { color: var(--accent-cyan); font-size: 0.78rem; }
.dm-call-event-text { color: var(--text-primary); font-weight: 600; }
.dm-call-event-time { color: var(--text-muted); margin-left: 4px; }
/* 通話イベントの色分け: 応答済み=緑 / つながらなかった系(不在/応答なし/拒否)=赤。
   ネオン色 (--accent-green/--accent-pink) は赤緑が隣接するとチカチカするため、
   彩度を抑えた落ち着いたトーンを使う。inline style は html/template が var() を
   潰すので class で付ける。 */
.dm-row--call-event .ico-phone          { --ico-color: #4cb98c; }
.dm-row--call-event .dm-call-event-text { color: #4cb98c; }
.dm-row--call-event.is-missed .ico-phone          { --ico-color: #d97585; }
.dm-row--call-event.is-missed .dm-call-event-text { color: #d97585; }
/* メッセージ一覧の通話プレビュー (同じく class で色分け) */
.msg-call-ico            { --ico-color: #4cb98c; }
.msg-call-ico.is-missed  { --ico-color: #d97585; }
.msg-call-text           { color: #4cb98c; }
.msg-call-text.is-missed { color: #d97585; }

/* === 引用 (返信元 snippet) === */
.dm-quote {
  display: block; max-width: 100%;
  background: var(--bg-card-hover);
  border-left: 3px solid var(--accent-cyan);
  border-radius: 10px;
  padding: 4px 8px; margin-bottom: 4px;
  font-size: 0.78rem; cursor: pointer;
  border-top: none; border-right: none; border-bottom: none;
  color: var(--text-muted); text-align: left;
  /* inline span の overflow:hidden は効かないので、親 block 側で
     name + text をまとめて 1 行省略する。 */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dm-quote-name { color: var(--accent-cyan); font-weight: 700; margin-right: 6px; }
.dm-quote-text { color: var(--text-secondary); }

/* === bubble === */
.dm-bubble {
  width: fit-content; max-width: 100%;
  box-sizing: border-box;
  padding: 8px 12px; border-radius: 16px;
  font-size: 0.93rem; line-height: 1.45;
  word-break: break-word; overflow-wrap: anywhere;
  /* white-space: pre-wrap は本文 .dm-text にだけ当てる。
     ここに付けるとテンプレのインデント (改行 + 空白) まで文字として
     描画され、本文の上下に不思議な空白行が入る。 */
}
.dm-row.is-me   .dm-bubble {
  background: var(--gradient-primary); color: #fff;
  border-bottom-right-radius: 4px;
}
.dm-row.is-peer .dm-bubble {
  background: rgba(255, 255, 255, 0.06); color: var(--text-primary);
  border-bottom-left-radius: 4px;
}
body.theme-light .dm-row.is-peer .dm-bubble {
  background: #e9edf1; color: #0f1419; border: 1px solid rgba(0, 0, 0, 0.07);
}
/* 送信側 (.is-me) はグラデ維持。php-style.css §109 の text-primary 強制で
   dark に潰されるのを !important + * で全 descendant に白を当てて救済。
   投稿ボタン (.post-btn) と同じ「ネオン背景 = 白文字」思想。
   重要: v2 DM テンプレは .dm-row.is-me を使う (.dm-message-row.sent ではない)。
   php-style.css 側の .dm-message-row.sent ルールは v1/PHP 互換用の死蔵。 */
body.theme-light .dm-row.is-me .dm-bubble,
body.theme-light .dm-row.is-me .dm-bubble *,
body.theme-light .dm-row.is-me .dm-bubble a { color: #ffffff !important; }
.dm-bubble .dm-image {
  display: block; max-width: 100%; height: auto;
  border-radius: 10px; margin-bottom: 4px;
}
.dm-bubble .dm-image:not([src]),
.dm-bubble .dm-image[src=""] { display: none; }

/* 動画メッセージ (画像と同じ吹き出し馴染ませ思想)。
   playsinline + controls + preload=metadata を template 側で付与。 */
.dm-bubble .dm-video {
  display: block;
  max-width: min(360px, 100%);
  width: 100%;
  height: auto;
  max-height: 480px;
  border-radius: 10px;
  margin-bottom: 4px;
  background: #000;
}
.dm-bubble.image-only .dm-video {
  border-radius: 16px;
  margin: 0;
  max-width: min(360px, 100%);
}
.dm-bubble.has-video:not(.image-only) .dm-video {
  margin: -8px -12px 8px;
  width: calc(100% + 24px);
  max-width: calc(100% + 24px);
  border-radius: 0;
}
.dm-row.is-me   .dm-bubble.image-only.has-video,
.dm-row.is-me   .dm-bubble.image-only .dm-video { border-bottom-right-radius: 4px; }
.dm-row.is-peer .dm-bubble.image-only.has-video,
.dm-row.is-peer .dm-bubble.image-only .dm-video { border-bottom-left-radius: 4px; }

/* 動画プレビュー (送信前): 画像プレビューの dm-imgpreview と同じ思想 */
.dm-vidpreview {
  position: relative;
  padding: 8px 12px 0;
}
.dm-vidpreview video {
  display: block;
  max-width: min(280px, 100%);
  max-height: 200px;
  border-radius: 10px;
  background: #000;
}
.dm-vidpreview > button {
  position: absolute;
  top: 4px; right: 4px;
  width: 26px; height: 26px;
  border: none;
  border-radius: 50%;
  background: rgba(0,0,0,.6);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.dm-vidpreview > button:hover { background: rgba(0,0,0,.85); }

/* === 画像メッセージ (LINE/Instagram/X 風) ===
   - 画像のみ:   吹き出し背景・余白を取り去り、画像そのものを吹き出しに。
   - 画像+本文: 画像は吹き出しの端から端まで貼り付け、本文は下に通常 padding で続く。
   いずれもバブルの角丸を画像にも適用して馴染ませる。 */
.dm-bubble.image-only {
  padding: 0 !important;
  background: transparent !important;
  border: none !important;
  overflow: hidden;
  border-radius: 16px;
}
.dm-bubble.image-only .dm-image {
  border-radius: 16px;
  margin: 0;
  width: auto;
  max-width: min(320px, 100%);
}
.dm-row.is-me   .dm-bubble.image-only,
.dm-row.is-me   .dm-bubble.image-only .dm-image { border-bottom-right-radius: 4px; }
.dm-row.is-peer .dm-bubble.image-only,
.dm-row.is-peer .dm-bubble.image-only .dm-image { border-bottom-left-radius: 4px; }

.dm-bubble.has-image:not(.image-only) { overflow: hidden; }
.dm-bubble.has-image:not(.image-only) .dm-image {
  /* 吹き出しの padding (8px 12px) を相殺して画像を端まで貼る */
  margin: -8px -12px 8px;
  width: calc(100% + 24px);
  max-width: calc(100% + 24px);
  border-radius: 12px 12px 0 0;
}
/* 本文だけ pre-wrap で改行保持。bubble 全体に当てるとテンプレのインデントまで
   見える空白行になるので必ず .dm-text のスコープに限定する。 */
.dm-text { white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere; }
.dm-text p { margin: 0; }
.dm-text br + br { display: none; }

/* === メタ (時刻 + アクション) === */
/* LINE 風: 時刻 + 返信/削除/リアクションは既定で隠し、吹き出しタップで出す。
   常時表示だとごちゃついて見にくいので。 */
.dm-meta {
  display: none; align-items: center; gap: 6px;
  margin-top: 3px;
  font-size: 0.72rem; color: var(--text-muted);
}
.dm-row.show-actions .dm-meta { display: inline-flex; }
/* デスクトップ (ホバー可能) ではホバーでも出す。タッチ端末には影響しない。 */
@media (hover: hover) {
  .dm-row:hover .dm-meta { display: inline-flex; }
}
.dm-bubble { cursor: pointer; }
.dm-row.show-actions .dm-bubble { box-shadow: 0 0 0 2px var(--accent-cyan); }
.dm-time { font-size: inherit; }
.dm-act {
  background: none; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 0.9rem; padding: 2px 6px;
  border-radius: 6px; line-height: 1;
}
.dm-act:hover { color: var(--accent-cyan); background: var(--action-reply-bg); }
.dm-meta .inline-form { display: inline; margin: 0; }

/* === リアクション === */
.dm-reacts { display: flex; gap: 4px; margin-top: 3px; flex-wrap: wrap; }
.dm-react {
  background: var(--bg-card-hover); border-radius: 999px;
  padding: 2px 8px; font-size: 0.82rem;
  display: inline-flex; align-items: center; gap: 3px;
}
.dm-react small { color: var(--text-muted); font-size: 0.72rem; }

/* === ハイライト (引用元へジャンプ) === */
.dm-highlight {
  animation: dm-highlight-flash 1.4s ease-out;
}
@keyframes dm-highlight-flash {
  0%   { background: rgba(0, 229, 255, 0.20); }
  100% { background: transparent; }
}

/* === 現況届の発令による投稿バッジ (PHP _layout_header.php L129 互換) ===
   _post_card / view_post / 引用カード / composer で使う共通スタイル。
   PHP では inline CSS だが v2 ではここに移植。 */
.post-genkyo-tag {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 4px 0 8px;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 0.76rem; font-weight: 700; line-height: 1.4;
  text-decoration: none;
  background: rgba(124,77,255,0.05);
  border: 1px solid var(--border-primary);
  color: var(--accent-cyan) !important;
  max-width: 100%;
  transition: background 0.12s, transform 0.12s;
}
body.theme-light .post-genkyo-tag {
  /* 枠は元の控えめな見た目 (薄い背景+ラベンダー枠) を維持。
     本文 (.g-topic) は color:inherit なので、ここの color を変えるだけで
     「お題：〇〇」の 〇〇 部分だけブランドブルー (--accent-cyan = ライト時
     #1d9bf0) になる。アイコンと .g-l「お題：」は別途 --text-secondary を
     強制しているためグレーのまま。 */
  background: rgba(0,131,168,0.06);
  color: var(--accent-cyan) !important;
  border-color: #d9e0ee;
}
a.post-genkyo-tag:hover { transform: translateY(-1px); }
.post-genkyo-tag i { font-size: 0.78rem; flex-shrink: 0; color: var(--text-secondary) !important; }
.post-genkyo-tag .g-l { white-space: nowrap; color: var(--text-secondary) !important; font-weight: 600; }
.post-genkyo-tag .g-topic {
  color: inherit; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; max-width: 260px;
}
/* お題本体は常時表示 (テキスト短縮後はモバイルでも収まる、はみ出しは ellipsis)。 */

/* === Composer ===
   .dm-shell flex column の最下段。flex-shrink: 0 で常にレイアウト下端に居る。
   position:fixed や visualViewport JS は使わない (PHP 互換)。 */
.dm-composer {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border-primary);
  background: var(--bg-primary);
  flex-shrink: 0;
  box-sizing: border-box;
}
.dm-composer-row { display: flex; align-items: flex-end; gap: 8px; }
.dm-input {
  flex: 1; resize: none; min-height: 40px; max-height: 160px;
  padding: 10px 12px; border-radius: var(--radius-md);
  border: 1px solid var(--border-primary);
  background: var(--bg-secondary); color: var(--text-primary);
  font-family: inherit; box-sizing: border-box;
  /* iOS Safari は input/textarea の font-size が 16px 未満だと focus 時に
     画面を自動拡大するので、明示的に 16px を当てて zoom を抑制する。 */
  font-size: 16px;
}
.dm-input:focus { outline: none; border-color: var(--accent-cyan); }
.dm-img-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex-shrink: 0;
  color: var(--accent-cyan); cursor: pointer; font-size: 1.1rem;
  border-radius: 50%; transition: background var(--transition-fast);
}
.dm-img-btn:hover { background: var(--action-reply-bg); }
.dm-send {
  padding: 10px 16px; border: none; border-radius: var(--radius-full);
  background: var(--gradient-primary); color: #fff; cursor: pointer;
  font-size: 1rem; display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.dm-send:hover { filter: brightness(1.15); }
/* ライト: 紙飛行機アイコンが §109 text-primary 強制で dark になるのを
   !important + * で白に固定 (is-me バブルと同じ思想)。 */
body.theme-light .dm-send,
body.theme-light .dm-send *,
body.theme-light .dm-send i { color: #ffffff !important; }

.dm-replyto {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: var(--bg-card-hover); border-radius: var(--radius-md);
  border-left: 3px solid var(--accent-cyan); font-size: 0.85rem;
}
/* 返信中バー: name + text を 1 行に揃えて、長文は ellipsis で省略。
   text のみ span に nowrap を当てても効かない (inline 要素は overflow 不可)
   ので、block 親の dm-replyto-body 側で省略する。 */
.dm-replyto-body { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.dm-replyto-name { color: var(--accent-cyan); font-weight: 700; margin-right: 6px; }
.dm-replyto-text { color: var(--text-muted); }
.dm-replyto button {
  background: none; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 1.2rem; padding: 4px 8px;
}

.dm-imgpreview {
  display: flex; align-items: center; gap: 8px;
  padding: 6px; background: var(--bg-card-hover); border-radius: var(--radius-md);
}
.dm-imgpreview img { max-width: 80px; max-height: 80px; border-radius: 6px; }
.dm-imgpreview button {
  background: rgba(0,0,0,0.4); color: #fff; border: none;
  width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
}

/* === 音声通話モーダル === */
.dm-call-modal {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(0,0,0,0.8);
  display: flex; align-items: center; justify-content: center;
}
.dm-call-card {
  background: var(--bg-secondary); border-radius: var(--radius-xl);
  padding: 32px 24px; min-width: 280px; max-width: 90vw;
  display: flex; flex-direction: column; gap: 20px; align-items: center;
  box-shadow: var(--shadow-lg);
}
.dm-call-peer { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.dm-call-avatar {
  width: 96px; height: 96px; border-radius: 50%; object-fit: cover;
  border: 3px solid var(--accent-cyan);
}
.dm-call-avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center; font-size: 2rem;
}
.dm-call-name strong { font-size: 1.15rem; }
.dm-call-status { margin-top: 4px; }
.dm-call-timer { margin-top: 2px; font-variant-numeric: tabular-nums; }
.dm-call-controls { display: flex; gap: 16px; align-items: center; }
.dm-call-mute,
.dm-call-hangup {
  width: 56px; height: 56px; border-radius: 50%; border: none;
  cursor: pointer; font-size: 1.4rem; color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
}
.dm-call-mute   { background: var(--bg-card); color: var(--text-primary); }
.dm-call-mute.is-muted { background: var(--accent-gold); color: #000; }
.dm-call-hangup { background: var(--accent-pink); }
.dm-call-hangup:hover { filter: brightness(1.15); }
.dm-call-camera {
  width: 56px; height: 56px; border-radius: 50%; border: none;
  cursor: pointer; font-size: 1.4rem;
  background: var(--bg-card); color: var(--text-primary);
  display: inline-flex; align-items: center; justify-content: center;
}
.dm-call-camera.is-off { background: var(--accent-gold); color: #000; }
/* カメラボタンはビデオ通話の時だけ出す */
.dm-call-modal[data-call-video="0"] .dm-call-camera { display: none; }

/* === 最小化ボタン (通話確立中だけ表示) === */
.dm-call-min {
  position: absolute; top: calc(env(safe-area-inset-top, 0px) + 14px); right: 16px; z-index: 2;
  width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255,255,255,0.16); color: #fff; font-size: 1rem;
  display: inline-flex; align-items: center; justify-content: center;
}
.dm-call-min:hover { background: rgba(255,255,255,0.28); }
.dm-call-modal[data-call-state="idle"] .dm-call-min,
.dm-call-modal[data-call-state="incoming"] .dm-call-min { display: none; }

/* === 最小化フローティング通話バー === */
.dm-call-bar {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 64px);
  z-index: 9998; width: min(440px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-radius: 999px; cursor: pointer;
  background: linear-gradient(135deg, #1f8f4e, #15c98e); color: #fff;
  box-shadow: 0 6px 20px rgba(0,0,0,0.35);
}
.dm-call-bar-ic {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: rgba(255,255,255,0.22);
  display: inline-flex; align-items: center; justify-content: center; font-size: 0.95rem;
}
.dm-call-bar-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.dm-call-bar-meta strong { font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-call-bar-sub { font-size: 0.74rem; opacity: 0.9; font-variant-numeric: tabular-nums; }
.dm-call-bar-hangup {
  flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--accent-pink); color: #fff; font-size: 1rem;
  display: inline-flex; align-items: center; justify-content: center;
}
.dm-call-bar-hangup:hover { filter: brightness(1.15); }

/* === ビデオ通話レイアウト (data-call-video="1") ===
   相手の映像を全面、自分の映像を小窓 (PiP)、名前/操作は下部にオーバーレイ。 */
.dm-call-remote-video, .dm-call-local-video { display: none; }
.dm-call-modal[data-call-video="1"] .dm-call-remote-video {
  display: block; position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover; background: #000;
}
.dm-call-modal[data-call-video="1"] .dm-call-local-video {
  display: block; position: absolute; z-index: 2;
  right: 14px; top: calc(14px + env(safe-area-inset-top, 0px));
  width: 28vw; max-width: 130px; aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: 12px; border: 2px solid rgba(255,255,255,0.65);
  background: #111; transform: scaleX(-1); /* 自分の映像は鏡像 */
}
.dm-call-modal[data-call-video="1"] .dm-call-card {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  width: 100%; max-width: none; min-width: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.6), transparent);
  box-shadow: none; border-radius: 0;
  justify-content: flex-end; gap: 16px;
  padding: 24px 16px calc(28px + env(safe-area-inset-bottom, 0px));
}
.dm-call-modal[data-call-video="1"] .dm-call-name strong,
.dm-call-modal[data-call-video="1"] .dm-call-status { color: #fff; }
/* 通話中は映像を主役にするためアバターを隠す (着信/発信中はアバター表示のまま) */
.dm-call-modal[data-call-video="1"][data-call-state="active"] .dm-call-avatar { display: none; }
.dm-call-modal[data-call-video="1"] .dm-call-settings-link { display: none; }

/* 相手のカメラOFF (data-remote-video-off="1") のときは黒い映像の代わりに
   相手アバターを中央に表示する (LINE/Zoom 風)。カードを全面・中央寄せにする。 */
.dm-call-modal[data-call-video="1"][data-call-state="active"][data-remote-video-off="1"] .dm-call-card {
  inset: 0; justify-content: center;
  background: rgba(0,0,0,0.6);
}
.dm-call-modal[data-call-video="1"][data-call-state="active"][data-remote-video-off="1"] .dm-call-avatar {
  display: block;
}

/* === 着信モーダル状態切替 ===
   data-call-state=incoming: 応答 / 拒否ボタンのみ
   data-call-state=calling | active: ミュート / 切断ボタンのみ
   confirm() に頼らず明示ボタンにすることで PWA / iOS でも
   user gesture を保持して getUserMedia を呼べる */
.dm-call-controls-incoming,
.dm-call-controls-active { display: none; }
.dm-call-modal[data-call-state="incoming"] .dm-call-controls-incoming { display: flex; }
.dm-call-modal[data-call-state="calling"]  .dm-call-controls-active   { display: flex; }
.dm-call-modal[data-call-state="active"]   .dm-call-controls-active   { display: flex; }
.dm-call-accept,
.dm-call-decline {
  width: 64px; height: 64px; border-radius: 50%; border: none;
  cursor: pointer; font-size: 1.5rem; color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
}
.dm-call-accept  { background: #2bbf6a; }
.dm-call-accept:hover  { filter: brightness(1.12); }
.dm-call-decline { background: var(--accent-pink); }
.dm-call-decline:hover { filter: brightness(1.12); }
/* 着信中は着信ボタンを軽く呼吸させる */
@keyframes dmCallPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.07); }
}
.dm-call-modal[data-call-state="incoming"] .dm-call-accept {
  animation: dmCallPulse 1.1s ease-in-out infinite;
}
/* 通話モーダル内に置く設定画面への導線リンク (旧 gear popover を /settings/dm に移管) */
.dm-call-settings-link {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 14px;
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 0.82rem;
}
.dm-call-settings-link:hover { color: var(--accent-cyan); }

/* === リアクションピッカー === */
.dm-react-modal {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(0,0,0,0.6);
  display: flex; align-items: center; justify-content: center;
}
.dm-react-card {
  background: var(--bg-secondary); border-radius: var(--radius-lg);
  padding: 20px; min-width: 280px; max-width: 90vw;
  box-shadow: var(--shadow-lg);
}
.dm-react-card h3 { margin: 0 0 12px; font-size: 1rem; }
.dm-react-grid {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px;
}
.dm-react-grid button {
  background: var(--bg-card-hover); border: none; cursor: pointer;
  padding: 10px; border-radius: 8px; font-size: 1.4rem;
}
.dm-react-grid button:hover { background: var(--bg-hover); }

/* 言葉の銀行 */
.kb-header { display: flex; align-items: center; justify-content: space-between;
  margin: var(--space-3) var(--space-4); }
.kb-title { margin: 0; font-size: 1.3rem; }
.kb-lock-btn {
  background: transparent; border: 1px solid var(--border-primary); color: var(--text-muted);
  border-radius: var(--radius-full); padding: 6px 14px; cursor: pointer;
}
.kb-lock-btn:hover { border-color: var(--accent-pink); color: var(--accent-pink); }
.kb-gate { max-width: 360px; margin: 28px auto; padding: 26px; text-align: center;
  border: 1px solid var(--border-primary); border-radius: var(--radius-lg); background: var(--bg-card); }
.kb-gate-ico { font-size: 2.2rem; color: var(--accent-cyan); }
.kb-pin-input {
  width: 170px; text-align: center; letter-spacing: 0.35em;
  font-size: 1.4rem; padding: 9px 8px;
  border-radius: var(--radius-md); border: 1px solid var(--border-primary);
  background: rgba(255, 255, 255, 0.03); color: var(--text-primary);
}
.kb-pin-input:focus { outline: none; border-color: var(--accent-cyan); }
.kb-gate-btn {
  display: block; width: 100%; margin-top: 14px; padding: 11px; border: none;
  border-radius: var(--radius-full); background: var(--gradient-primary);
  color: #fff; font-weight: 800; cursor: pointer;
}
.kb-account {
  padding: 20px; border-radius: var(--radius-lg); margin: var(--space-4); color: #fff;
  background: linear-gradient(135deg, #3a2d7d, #1f6f8b 60%, #149c8e);
  box-shadow: 0 8px 24px rgba(31, 111, 139, 0.25);
}
.kb-account-bal { font-size: 2.2rem; font-weight: 800; }
.kb-account-bal small { font-size: 0.95rem; opacity: 0.9; }
.kb-account-label { font-size: 0.78rem; opacity: 0.85; margin-top: 12px; }
.kb-account-bank { font-size: 0.8rem; opacity: 0.85; letter-spacing: 0.08em; }
.kb-account-holder { margin-top: 10px; font-size: 0.82rem; opacity: 0.9; }
.kb-convert { font-size: 0.72rem; color: var(--text-muted); text-align: center;
  margin: -6px var(--space-4) var(--space-3); }
.kb-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px; margin: 14px var(--space-4) 18px; }
.kb-summary-item {
  border: 1px solid var(--border-primary); border-radius: var(--radius-md);
  padding: 10px 12px; background: var(--bg-card);
}
.kb-summary-name { font-size: 0.78rem; color: var(--text-muted); }
.kb-summary-val { font-size: 1rem; font-weight: 800; color: var(--text-primary); margin-top: 3px; }
.kb-section-title { font-size: 0.95rem; font-weight: 800; margin: var(--space-3) var(--space-4); }
.kb-list { list-style: none; padding: 0; margin: 0; }
.kb-row { display: flex; align-items: center; gap: var(--space-3);
  padding: 11px var(--space-4); border-bottom: 1px solid var(--border-primary); }
.kb-row-ico { font-size: 1.1rem; width: 28px; text-align: center; }
.kb-row-lbl { flex: 1; }
.kb-row-time { color: var(--text-muted); font-size: 0.78rem; }
.kb-row-amt { color: #00c896; font-weight: 800; }
.kb-guide-lead { color: var(--text-muted); font-size: 0.88rem;
  line-height: 1.8; margin: var(--space-3) var(--space-4); }
.kb-rule {
  padding: 12px 14px; border: 1px solid var(--border-primary);
  border-radius: var(--radius-md); margin: 0 var(--space-4) 8px; background: var(--bg-card);
}
.kb-rule-name { font-weight: 700; color: var(--text-primary); }
.kb-rule-pt { color: #00c896; font-weight: 800; font-size: 0.82rem; margin-left: 4px; }
.kb-rule-desc { color: var(--text-muted); font-size: 0.82rem; margin-top: 3px; }

/* 公式バッジ (specialMark) はユーザカスタムカラー (Misskey 風 user-colors.js が
   --accent-cyan / --accent-purple を上書きできる) の影響を受けない固定色にする。
   PHP twclone はカスタムカラー機能を持たないため、PHP 版の見た目 (常に cyan→purple
   の ✓ 円) と揃えるのが意図。selector specificity 0-1-1 で php-style.css の
   .specialMark (0-1-0) と user-colors の :root, body[class][class] (var の上書き)
   両方に勝つ。adminMark は元々 #1d9bf0 ハードコードなので対応不要。 */
body .specialMark {
  background: linear-gradient(135deg, #00e5ff, #7c4dff);
}

/* Community notes (view_post.html の投稿詳細下「公共注釈」ブロック専用) -
   注意: /community_notes ページ用のスタイルは php-style.css (.cn-page / .cn-item /
   .cn-status-badge / .cn-rate-helpful 等) を使う。view_post の旧 BEM 命名
   (.cn-note / .cn-note-head / .cn-note-body 等) とクラス名がぶつかるので、
   ここでは必ず親 .cn-note でスコープして community_notes ページに漏らさない。 */
.cn-section { margin: var(--space-5) var(--space-4) 0; padding-top: var(--space-3);
  border-top: 1px solid var(--border-primary); }
.cn-section-title { font-size: 1rem; color: var(--text-muted); margin: 0 0 var(--space-3); }
.cn-note { margin-bottom: var(--space-3); padding: var(--space-3);
  border: 1px solid var(--border-primary); border-radius: var(--radius-md); background: var(--bg-card); }
.cn-note--proposed { opacity: 0.85; border-style: dashed; }
.cn-note--hidden { opacity: 0.5; }
.cn-note .cn-note-head { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; }
.cn-note-status {
  margin-left: auto; padding: 2px 8px; border-radius: var(--radius-full);
  font-size: 0.7rem; font-weight: 700;
}
.cn-note-status--visible { background: var(--action-repost-bg); color: var(--accent-green); }
.cn-note-status--proposed { background: var(--action-bookmark-bg); color: var(--accent-gold); }
.cn-note-status--hidden { background: var(--action-like-bg); color: var(--accent-pink); }
.cn-note .cn-note-body { margin-top: 6px; color: var(--text-primary); font-size: 0.92rem; line-height: 1.55; white-space: pre-wrap; }
.cn-note-actions { display: flex; gap: 8px; margin-top: 8px; align-items: center; font-size: 0.83rem; }
.cn-note-counts { color: var(--text-muted); margin-right: auto; }
.cn-rate-form { margin: 0; }
.cn-note .cn-rate-btn {
  background: transparent; border: 1px solid var(--border-primary); color: var(--text-muted);
  border-radius: var(--radius-full); padding: 4px 12px; font-size: 0.78rem; cursor: pointer;
  flex: none; min-width: 0; font-weight: 600;
}
.cn-note .cn-rate-btn:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }
.cn-note .cn-rate-btn--on { background: var(--accent-cyan); color: #fff; border-color: var(--accent-cyan); }
.cn-note .cn-rate-btn--neg.cn-rate-btn--on { background: var(--accent-pink); border-color: var(--accent-pink); color: #fff; }
.cn-empty { color: var(--text-muted); font-size: 0.88rem; padding: 0 var(--space-4); }
.cn-submit-form {
  margin: var(--space-3) 0 0; padding: var(--space-3);
  border: 1px solid var(--border-primary); border-radius: var(--radius-md); background: var(--bg-card);
}
.cn-submit-btn {
  margin-top: 8px; padding: 8px 22px; border-radius: var(--radius-full); border: none;
  background: var(--gradient-primary); color: #fff; font-weight: 800; cursor: pointer;
}

/* Admin */
.admin-title { margin: var(--space-3) var(--space-4); font-size: 1.3rem; }
.admin-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px; padding: 0 var(--space-4) var(--space-4); }
.admin-stat-card {
  padding: 14px 16px; border: 1px solid var(--border-primary);
  border-radius: var(--radius-md); background: var(--bg-card);
}
.admin-stat-card--urgent { border-color: var(--accent-pink); background: var(--action-like-bg); }
.admin-stat-card--warn { border-color: var(--accent-gold); background: var(--action-bookmark-bg); }
.admin-stat-label { color: var(--text-muted); font-size: 0.82rem; }
.admin-stat-value { color: var(--text-primary); font-size: 1.8rem; font-weight: 800; line-height: 1.2; margin-top: 4px; }
.admin-stat-link { display: inline-block; margin-top: 6px; color: var(--accent-cyan); text-decoration: none; font-size: 0.83rem; }
.admin-nav { display: flex; gap: 10px; flex-wrap: wrap; padding: 0 var(--space-4) var(--space-3); }
.admin-nav-link {
  padding: 8px 14px; border: 1px solid var(--border-primary); border-radius: var(--radius-full);
  text-decoration: none; color: var(--text-primary); font-size: 0.88rem;
}
.admin-nav-link:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }
.admin-table { width: calc(100% - 2*var(--space-4)); margin: 0 var(--space-4);
  border-collapse: collapse; font-size: 0.86rem; }
.admin-table th, .admin-table td { padding: 8px 10px; border-bottom: 1px solid var(--border-primary); text-align: left; }
.admin-table th { color: var(--text-muted); font-weight: 600; }
.admin-table td a { color: var(--accent-cyan); text-decoration: none; }
.admin-table code { background: var(--bg-hover); padding: 1px 6px; border-radius: 4px; font-size: 0.8em; }
.badge {
  display: inline-block; padding: 2px 8px;
  border-radius: var(--radius-full); font-size: 0.7rem; font-weight: 700;
}
.badge--ok      { background: var(--action-repost-bg); color: var(--accent-green); }
.badge--warn    { background: var(--action-bookmark-bg); color: var(--accent-gold); }
.badge--danger  { background: var(--action-like-bg); color: var(--accent-pink); }
.inline-form { display: inline; margin: 0; }
.admin-btn {
  padding: 5px 12px; border: 1px solid var(--border-primary);
  background: transparent; color: var(--text-primary);
  border-radius: var(--radius-full); cursor: pointer; font-size: 0.8rem;
}
.admin-btn:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }
.admin-btn--small { padding: 3px 10px; font-size: 0.76rem; }
.admin-feedback-list { display: flex; flex-direction: column; gap: 10px; padding: 0 var(--space-4); }
.admin-feedback-item { padding: var(--space-3); border: 1px solid var(--border-primary);
  border-radius: var(--radius-md); background: var(--bg-card); }
.admin-feedback-item--new { border-color: var(--accent-cyan); background: var(--action-reply-bg); }
.admin-feedback-head { display: flex; align-items: center; gap: 8px; font-size: 0.86rem; margin-bottom: 6px; }
.admin-feedback-cat { background: var(--bg-hover); padding: 1px 6px; border-radius: 4px; font-size: 0.74rem; }
.admin-feedback-time { margin-left: auto; color: var(--text-muted); }
.admin-feedback-body { color: var(--text-primary); white-space: pre-wrap; font-size: 0.92rem; }

/* Search */
.search-form {
  display: flex; gap: 8px;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-primary);
}
.search-input {
  flex: 1; padding: 10px 14px;
  border: 1px solid var(--border-primary); border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.03); color: var(--text-primary); font: inherit;
}
.search-input:focus { outline: none; border-color: var(--accent-cyan); }

/* 検索ページ専用: col-main-header の sticky chrome (rgba(7,9,22,.85) + blur)
   を捨て、検索フォームを .aside-card と同じ「フロート風カード」装飾にする。
   元は edge-to-edge の暗い帯になり、画面下の本体背景と段差が出ていた。
   タブ (検索結果時) は同じカード内に下続きで配置。 */
.col-main-header.col-main-header--search {
  position: static;
  background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  padding: var(--space-3) var(--space-3) 0;
}
.col-main-header--search .search-form {
  padding: var(--space-3);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  margin: 0;
}
.col-main-header--search .tabs { margin-top: var(--space-3); }

/* 右サイドバー (col-aside) 内の検索帯だけ scope して、角丸 + 余白で
   フロート感を出す。.aside-search 本体 (background / position:sticky) は
   他箇所でも使われているので一切触らず、ここでは radius と padding のみ
   上書き。元は side-padding が 0 で帯が col-aside の content edge まで
   伸び、radial-gradient 背景との段差が square-edged で目立っていた。 */
.col-aside .aside-search {
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
}
.search-submit {
  padding: 10px 22px; border: none; border-radius: var(--radius-full);
  background: var(--gradient-primary); color: #fff; font-weight: 800; cursor: pointer;
}
.search-section-title {
  margin: var(--space-4) var(--space-4) var(--space-2);
  font-size: 1rem; color: var(--text-muted);
  padding-bottom: 6px; border-bottom: 1px solid var(--border-primary);
}

/* Static */
.static-page { padding: var(--space-4); max-width: 720px; }
.static-page h1 { font-size: 1.4rem; margin: var(--space-3) 0; }
.static-page h2 { font-size: 1.05rem; margin: var(--space-5) 0 6px; color: var(--text-primary); }
.static-page p, .static-page ul { color: var(--text-primary); margin: 6px 0; line-height: 1.7; font-size: 0.93rem; }
.static-page ul { padding-left: 22px; }
.static-page a { color: var(--accent-cyan); }

/* reply / view_post */
.reply-section-title {
  font-size: 1rem; color: var(--text-muted);
  margin: var(--space-5) var(--space-4) var(--space-2);
  padding-bottom: 8px; border-bottom: 1px solid var(--border-primary);
}
.reply-empty {
  margin: var(--space-3) var(--space-4); padding: 24px 16px;
  color: var(--text-muted); text-align: center;
  border: 1px dashed var(--border-primary); border-radius: var(--radius-md);
}
.reply-login-hint {
  padding: var(--space-3); margin: var(--space-3) var(--space-4);
  background: var(--action-reply-bg); border: 1px solid var(--border-glow);
  border-radius: var(--radius-md); text-align: center;
  color: var(--text-muted); font-size: 0.9rem;
}
.reply-login-hint a { color: var(--accent-cyan); text-decoration: none; }

[hidden] { display: none !important; }

/* ===== 投稿詳細ページ (view_post) ===== */

/* 親投稿コンテキスト (返信投稿の上に出る親カード) */
.parent-post-context { position: relative; }
.parent-post-context .thread-line {
  position: absolute;
  left: calc(var(--space-4) + 22px);  /* avatar の中央線 */
  top: 56px; bottom: -8px;
  border-left: 2px solid var(--border-primary);
  pointer-events: none;
}

/* 本投稿 (大表示) */
.post-detail {
  padding: var(--space-4);
  border-bottom: 1px solid var(--border-primary);
}
.post-detail:hover { background: transparent; }
.post-detail-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-3);
}
.post-detail-author {
  display: flex; gap: var(--space-3); align-items: center;
  flex: 1; min-width: 0;
}
.post-detail-author .author-link { flex-shrink: 0; }
.post-detail-author .author-meta {
  display: flex; flex-direction: column; min-width: 0;
}
.post-detail-author .author-meta .author-name {
  font-size: 1rem; font-weight: 800; color: var(--text-primary);
  display: inline-flex; align-items: center; gap: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.post-detail-author .author-meta .author-handle {
  font-size: 0.9rem; color: var(--text-muted);
  white-space: nowrap;
}
.post-detail-body {
  font-size: 1.25rem; line-height: 1.45;
  color: var(--text-primary);
  white-space: pre-wrap; word-wrap: break-word;
  margin: var(--space-3) 0;
}
.post-detail-time {
  color: var(--text-muted); font-size: 0.88rem;
  margin-top: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-secondary);
}
.post-detail-stats {
  display: flex; gap: var(--space-4); flex-wrap: wrap;
  padding: var(--space-3) 0;
  color: var(--text-muted); font-size: 0.9rem;
}
.post-detail-stats strong { color: var(--text-primary); font-weight: 800; margin-right: 4px; }
.post-detail-stats a { color: inherit; text-decoration: none; }
.post-detail-stats a:hover strong { text-decoration: underline; }

/* 返信ツリーの depth=1 ノード (full post_card) */
.reply-node { position: relative; }
.reply-node--depth-1.is-continuation::before {
  /* 同一作者連投: 縦線を継続 (OP との連続感) */
  content: ''; position: absolute;
  left: calc(var(--space-4) + 22px);
  top: -1px; height: 16px;
  border-left: 2px solid var(--border-secondary);
}

/* 返信ツリー (深い階層 compact chip)
   設計: Twitter / Mastodon 風の階層 trunk。
   - 各 chip 行は祖先 depth ぶんの "guide column" を flex で並べ、最後に枝列、chip 本体の順
   - 各 guide は ::before で縦線、::after で枝の └ / ├ を描く
   - これにより depth-3 chip は depth-2 trunk の上に自分独自の trunk を
     さらにインデントして持てる → 「親 chip の中に nested する」見た目になる
*/
.reply-tree {
  padding-bottom: var(--space-3);
  --reply-indent-step: 24px;
  /* 返信ツリーの trunk/branch 色は accent-cyan に追従させて user-colors の
     accent 指定が効くようにする (旧: rgba(255,255,255,0.45) ハードコード)。
     color-mix は Safari 16.4+ / Chrome 111+ で対応 (PHP も同じパターンを使用)。 */
  --reply-line-color: color-mix(in srgb, var(--accent-cyan) 45%, transparent);
}
body.theme-light .reply-tree {
  --reply-line-color: color-mix(in srgb, var(--accent-cyan) 40%, transparent);
}

.nested-reply-row {
  display: flex; align-items: stretch;
  /* 1 列目の guide の縦線中心が depth-1 アバター中心 (space-4 + 22) に揃うよう、
     左 padding を `space-4 + 22 - indent-step/2` = `space-4 + 10` にする。 */
  padding: 6px var(--space-4) 6px calc(var(--space-4) + 10px);
  text-decoration: none; color: inherit;
}
.rt-guide {
  width: var(--reply-indent-step);
  flex-shrink: 0;
  position: relative;
  align-self: stretch;
}
/* vline: 祖先 trunk が継続中 → 行の上端〜下端まで縦線を引く */
.rt-guide--vline::before {
  content: ''; position: absolute;
  left: 50%; top: 0; bottom: 0;
  border-left: 2px solid var(--reply-line-color);
}
/* blank: 祖先 trunk が終了 → 何も描かない (= 空白でインデントだけする) */

/* branch-mid (├): 縦線フル + 中央あたりから右に水平の枝 */
.rt-guide--branch-mid::before {
  content: ''; position: absolute;
  left: 50%; top: 0; bottom: 0;
  border-left: 2px solid var(--reply-line-color);
}
.rt-guide--branch-mid::after {
  content: ''; position: absolute;
  left: 50%; top: 18px;
  width: 14px;
  border-top: 2px solid var(--reply-line-color);
}
/* branch-last (└): 縦線を chip 中央で止め、丸い corner + 横線 */
.rt-guide--branch-last::before {
  content: ''; position: absolute;
  left: 50%; top: 0;
  width: 14px; height: 18px;
  border-left: 2px solid var(--reply-line-color);
  border-bottom: 2px solid var(--reply-line-color);
  border-bottom-left-radius: 12px;
}

/* depth=1 カードから最初の chip 行へ trunk を繋ぐ橋渡し。
   reply-node の bottom 中央右寄り (= 最初 guide の縦線位置) に縦線を伸ばして
   次行の guide ::before の上端と接合する。 */
.reply-node--depth-1:has(+ .nested-reply-row)::after {
  content: ''; position: absolute;
  /* guide 1 列目の中心 = padding-left + indent-step/2 = space-4 + 10 + 12 = space-4 + 22 */
  left: calc(var(--space-4) + 22px);
  bottom: -2px; height: 4px;
  border-left: 2px solid var(--reply-line-color);
}

.nested-reply-chip {
  display: flex; gap: 10px;
  background: var(--bg-card);
  padding: 8px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-secondary);
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.nested-reply-chip:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent-cyan);
}
.nested-reply-avatar { flex-shrink: 0; }
.nested-reply-body { flex: 1; min-width: 0; font-size: 0.9rem; }
.nested-reply-head {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-size: 0.85rem;
}
.nested-reply-head strong { font-weight: 700; color: var(--text-primary); }
.nested-reply-head .author-handle {
  color: var(--text-muted); font-size: 0.78rem;
}
/* 「↳ @parent への返信」を chip 内に小さく出して文脈を明示 */
.nested-reply-to {
  color: var(--text-muted); font-size: 0.72rem;
  margin-left: auto; padding-left: 6px;
  white-space: nowrap;
}
.nested-reply-to::before { content: '↳ '; opacity: 0.7; }
.nested-reply-text {
  color: var(--text-primary); margin-top: 3px; white-space: pre-wrap;
  word-wrap: break-word; line-height: 1.5;
}
.nested-reply-actions { margin-top: 4px; }
.nested-reply-actions .action-btn i { width: 28px; height: 28px; font-size: 14px; }

/* light テーマの trunk/branch 色は --reply-line-color (上で .reply-tree に
   theme-light 用 override 済) で統一しているのでここでは何もしない。 */
.reply-collapse > summary {
  cursor: pointer; list-style: none;
  padding: 8px var(--space-4);
  color: var(--text-muted); font-size: 0.85rem;
}
.reply-collapse > summary::-webkit-details-marker { display: none; }
.reply-collapse[open] > summary { border-bottom: 1px solid var(--border-primary); }

/* ============================================================
 * §17 Phase 3: Animations / Toast / Pull-to-refresh
 * ============================================================ */

/* --- 17.1 Animations ---------------------------------- */
@keyframes v2-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes v2-fade-out {
  from { opacity: 1; }
  to   { opacity: 0; transform: translateY(-6px); }
}
@keyframes v2-like-pop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.35); }
  60%  { transform: scale(0.92); }
  100% { transform: scale(1); }
}
@keyframes v2-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
@keyframes v2-spin {
  to { transform: rotate(360deg); }
}

/* タイムライン投稿 fadeIn (初回描画) */
.timeline .post {
  animation: v2-fade-in 320ms ease-out both;
}
/* 新着 PTR 挿入 — 入場時に .post--new で表示前に opacity=0、--in で fadeIn */
.post.post--new { opacity: 0; transform: translateY(-8px); transition: opacity 360ms ease, transform 360ms ease; }
.post.post--new.post--in { opacity: 1; transform: translateY(0); }

/* like / repost / bookmark / share ボタン押下時 pop (PHP @keyframes likePop と同等)。
 * 旧 selector は .action-btn.action-like.is-popping i だったが、テンプレ側の
 * class は .action-btn.like / .repost / .bookmark / .share なので一致せず無効化
 * していた。.action-btn.is-popping i で全 action ボタンに統一適用する。 */
.action-btn.is-popping i {
  animation: likePop 420ms ease-out;
}

/* repost / share メニューを「下方向に開く」に変更。
 * PHP CSS は bottom: calc(100% + 4px) で上に開くが、v2 ホーム上部の post で
 * 開くとコンポーザに被って読めなくなる。X 風に下に開いて自然な視線移動に。 */
.repost-menu, .share-menu {
  top: calc(100% + 4px) !important;
  bottom: auto !important;
  /* 完全不透明にして背後の post が透けないように。backdrop-filter で安心感。 */
  background: #161b22 !important;
  -webkit-backdrop-filter: blur(12px);
          backdrop-filter: blur(12px);
}
/* light テーマでは白寄りの solid に */
body.theme-light .repost-menu,
body.theme-light .share-menu {
  background: #ffffff !important;
  border-color: #e7e9ea !important;
}
/* share は右端ボタンなので右寄せ維持 (php-style L1616 と同等) */
.share-menu { left: auto !important; right: 0 !important; }
/* repost / share / bookmark もタップ時に pop させるための JS-friendly hook */
.action-btn.repost.is-popping i,
.action-btn.share.is-popping i,
.action-btn.bookmark.is-popping i {
  animation: likePop 420ms ease-out;
}

/* shimmer (loading skeleton 用、必要箇所で .skeleton クラスを当てる) */
.skeleton {
  background: linear-gradient(90deg, var(--bg-card) 25%, var(--bg-card-hover) 50%, var(--bg-card) 75%);
  background-size: 800px 100%;
  animation: v2-shimmer 1.2s linear infinite;
  border-radius: var(--radius-md);
}

/* ホバー時の transition 統一 (Phase 2 で散らばってた箇所を補強) */
.action-btn, .author-link, .post {
  transition: background-color 160ms ease, color 160ms ease, transform 160ms ease;
}

/* prefers-reduced-motion 尊重 */
@media (prefers-reduced-motion: reduce) {
  .timeline .post,
  .post.post--new,
  .post.post--new.post--in,
  .action-btn.action-like.is-popping i,
  .skeleton {
    animation: none !important;
    transition: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
}

/* --- 17.2 Toast --------------------------------------- */
.toast-stack {
  position: fixed;
  top: env(safe-area-inset-top, 0);
  right: 16px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  max-width: calc(100vw - 32px);
  padding-top: 12px;
}
.toast {
  pointer-events: auto;
  min-width: 220px;
  max-width: 360px;
  padding: 12px 14px;
  background: var(--bg-card);
  color: var(--text-primary);
  border: 1px solid var(--border-glow);
  border-left: 4px solid var(--accent-cyan);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.92rem;
  line-height: 1.4;
  opacity: 0;
  transform: translateX(20px);
  transition: opacity 240ms ease, transform 240ms ease;
}
.toast--in  { opacity: 1; transform: translateX(0); }
.toast--out { opacity: 0; transform: translateX(20px); }
.toast i { font-size: 1.05rem; flex-shrink: 0; margin-top: 1px; }
.toast-body { flex: 1; word-wrap: break-word; }
.toast-close {
  background: transparent; border: 0; color: var(--text-muted);
  font-size: 1.1rem; cursor: pointer; line-height: 1; padding: 0 0 0 4px;
}
.toast-close:hover { color: var(--text-primary); }
.toast--info    { border-left-color: var(--accent-cyan); }
.toast--info i  { color: var(--accent-cyan); }
.toast--success { border-left-color: #2ecc71; }
.toast--success i { color: #2ecc71; }
.toast--warn    { border-left-color: #f5a524; }
.toast--warn i  { color: #f5a524; }
.toast--error   { border-left-color: #ef4444; }
.toast--error i { color: #ef4444; }

@media (max-width: 600px) {
  .toast-stack { right: 8px; left: 8px; }
  .toast { max-width: none; }
}

/* --- 17.3 Pull-to-refresh ----------------------------- */
.pull-indicator {
  height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--text-muted);
  font-size: 0.9rem;
  transition: height 180ms ease;
  background: linear-gradient(180deg, var(--bg-card) 0%, transparent 100%);
}
.pull-indicator-icon {
  transition: transform 180ms ease;
  font-size: 1rem;
}
.pull-indicator--ready .pull-indicator-icon {
  transform: rotate(180deg);
  color: var(--accent-cyan);
}
.pull-indicator--loading .pull-indicator-icon {
  animation: v2-spin 700ms linear infinite;
  /* arrow を spinner 風に見せるため border-only に上書き */
  border: 2px solid var(--border-primary);
  border-top-color: var(--accent-cyan);
  border-radius: 50%;
  width: 16px;
  height: 16px;
  display: inline-block;
}
.pull-indicator--loading .pull-indicator-icon::before { content: ''; }
.pull-indicator--loading .pull-indicator-label { color: var(--accent-cyan); }

/* ============================================================
 * §18 View Transitions API (Chrome 126+, Safari 18+)
 *   - 同一オリジンのナビゲーション時にブラウザが自動で fade を入れる。
 *   - サポート無いブラウザは無視される (普通のページ遷移)。
 *   - 投稿詳細など、移動先で「同じ post」が欲しい所には
 *     view-transition-name を CSS で当てる。
 * ============================================================ */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 220ms;
  animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
}
/* 投稿カードのモーフィング (一覧 → 詳細で同じ post に滑らかに繋ぐ) */
.post[data-post-id] {
  /* Chrome は属性セレクタの値を view-transition-name に直接使えないので
     名前は付けず、root の fade だけに任せる。
     将来 attr() が view-transition-name で使えるようになったらここで指定。 */
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }
}

/* ============================================================
 * §19  右サイドバー (col-aside) ウィジェット
 *   - .aside-card: トレンド / おすすめユーザー / About 用カード
 *   - .trend-row / .suggestion-row: PHP 版と同等の見た目
 * ============================================================ */
.aside-card {
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
}
.aside-card--mini { padding: var(--space-3); }
.aside-card-title {
  font-size: 1.1rem; font-weight: 800;
  margin: 0 0 var(--space-2) 0;
}
.aside-card-more {
  display: block; margin-top: var(--space-2);
  color: var(--accent-cyan); text-decoration: none;
  font-size: 0.9rem;
}
.aside-card-more:hover { text-decoration: underline; }
.aside-card-links {
  margin-top: var(--space-2);
  display: flex; flex-direction: column; gap: 4px;
}
.aside-card-links a {
  color: var(--text-muted); text-decoration: none; font-size: 0.85rem;
}
.aside-card-links a:hover { color: var(--accent-cyan); }

/* .trend-row は php-style.css L8929 の flex を継承しつつ、
 *   1) border-radius を 0 にする (radius + border-bottom で丸ブラケットに見える対策)
 *   2) border-bottom で各項目を直線で区切る (Twitter/X 風)
 *   3) .trend-rank は「#10」2桁対応で min-width 拡張
 */
.trend-row { border-radius: 0 !important; border-bottom: 1px solid var(--border-primary); padding: 12px 8px !important; }
.trend-row:last-of-type { border-bottom: none; }
.trend-rank { min-width: 48px; width: auto !important; }

/* === 「丸縁ブラケット」対策の一括適用 ===
 * 各「項目リスト」型 component で、border-radius + border-bottom の組み合わせ
 * によりブラケット形が現れていたものを、フラットな直線 separator に統一。
 * .reply-nudge-row    : 返信、忘れていませんか? の各行 (右サイドカード内)
 * .settings-hub-item  : /settings ハブの各メニュー
 * .suggestion-row-main: 検索ホームのおすすめユーザー (radius が付くと丸ブラケット)
 */
.reply-nudge-row { border-radius: 0 !important; }
.settings-hub-item {
  border-radius: 0 !important;
  border-bottom: 1px solid var(--border-primary);
}
.settings-hub-item:last-of-type { border-bottom: none; }
.suggestion-row-main { border-radius: 0 !important; }

.suggestion-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2);
  padding: 10px 0;
  border-bottom: 1px solid var(--border-primary);
}
.suggestion-row:last-of-type { border-bottom: none; }
.suggestion-row-main {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: inherit;
  flex: 1; min-width: 0;
}
.suggestion-row-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  object-fit: cover; flex: 0 0 40px;
}
.suggestion-row-avatar.avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.suggestion-row-info { min-width: 0; overflow: hidden; }
.suggestion-row-name {
  font-weight: 800; font-size: 0.95rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.suggestion-row-handle {
  color: var(--text-muted); font-size: 0.82rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.suggestion-follow-btn {
  background: var(--text-primary); color: var(--bg-primary);
  border: none; border-radius: var(--radius-full);
  padding: 6px 14px;
  font-weight: 800; font-size: 0.85rem; cursor: pointer;
  flex: 0 0 auto;
}
.suggestion-follow-btn:hover { opacity: 0.9; }

/* §20  サイドバーフィードバック ボタン + 右カラムフッター + Settings ハブ */
.sidebar-feedback {
  margin: var(--space-2) 0;
  padding: 0 var(--space-2);
}
.sidebar-feedback-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  padding: 10px 16px;
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-full);
  color: var(--text-muted); text-decoration: none;
  font-size: 0.9rem; font-weight: 600;
  background: transparent;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.sidebar-feedback-btn:hover {
  background: var(--bg-hover); color: var(--text-primary);
}
@media (max-width: 1279px) {
  /* 旧版は .sidebar-feedback-btn span 全部に display:none を当てていたが、
     これだとドロワー (.side-drawer .sidebar-feedback-btn) の「フィードバック」
     文字まで消えて PWA 表示で寂しくなっていた。PHP は narrow PC sidebar
     (.col-nav 配下) でだけ非表示にしているのでそれに揃える。 */
  .col-nav .sidebar-feedback-btn span { display: none; }
  .col-nav .sidebar-feedback-btn { padding: 10px; }
}

.aside-footer {
  padding: var(--space-3) var(--space-2);
  line-height: 1.6;
}
.aside-footer a {
  color: var(--text-muted); text-decoration: none;
}
.aside-footer a:hover { color: var(--accent-cyan); text-decoration: underline; }

/* Settings ハブ (PHP settings.php と同じ大きなカードリスト) */
.settings-hub {
  display: flex; flex-direction: column;
  padding: var(--space-3);
}
.settings-hub-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-lg);
  text-decoration: none; color: inherit;
  transition: background var(--transition-fast);
}
.settings-hub-item:hover { background: var(--bg-hover); }
.settings-hub-icon {
  font-size: 1.5rem;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 40px;
}
.settings-hub-meta { flex: 1; min-width: 0; }
.settings-hub-title { font-weight: 700; font-size: 1rem; }
.settings-hub-desc { color: var(--text-muted); font-size: 0.85rem; margin-top: 2px; }
.settings-hub-arrow { color: var(--text-muted); font-size: 1.5rem; }
.settings-hub-divider {
  height: 1px; background: var(--border-primary);
  margin: var(--space-2) var(--space-3);
}
.settings-hub-danger .settings-hub-title { color: var(--accent-pink); }

/* §21 返信、忘れていませんか? */
.reply-nudge-lead { margin-bottom: var(--space-2); line-height: 1.5; }
.reply-nudge-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-primary);
  text-decoration: none; color: inherit;
}
.reply-nudge-row:last-of-type { border-bottom: none; }
.reply-nudge-row:hover { background: var(--bg-hover); }
.reply-nudge-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  object-fit: cover; flex: 0 0 36px;
}
.reply-nudge-avatar.avatar-placeholder {
  background: var(--gradient-primary); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.reply-nudge-info { flex: 1; min-width: 0; overflow: hidden; }
.reply-nudge-name {
  font-weight: 700; font-size: 0.9rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.reply-nudge-body {
  color: var(--text-muted); font-size: 0.82rem; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.reply-nudge-btn {
  background: rgba(0, 229, 255, 0.1);
  color: var(--accent-cyan);
  border: 1px solid rgba(0, 229, 255, 0.3);
  border-radius: var(--radius-full);
  padding: 4px 10px;
  font-size: 0.8rem; font-weight: 700;
  flex: 0 0 auto;
}

/* ============================================================
 * ポスト区切り位置の修正
 *
 * 問題: home.html / profile.html 等は
 *   <article class="post">…本文…</article>
 *   <div style="padding:…72px;"><div class="post-actions">…</div></div>
 * の 2 要素構造で 1 ポストを描画している。.post に
 * border-bottom が掛かっているため、区切り線が「本文と返信ボタンの間」
 * に出てしまい、アクションが次のポストに属しているように見える。
 *
 * 修正: .post の border-bottom を消し、.post-actions を直接子に持つ
 * 隣接 div (= ラッパー) に border-bottom を移す。
 * 結果: ポスト本文と返信ボタンが一体になり、区切り線が「ポストとポストの間」
 * に出るようになる。
 *
 * 対象スコープ:
 *   - .timeline 直下 (home / profile / bookmarks / search)
 *   - .reply-tree 内の reply-node (view_post の返信ツリー)
 *   - .post-actions-wrap (engagement.html 専用クラス)
 *
 * view_post 単独ポストには影響させない (元の border 配置 + #reply section の
 * border-top をいじると二重線になるリスクがあるため、別タスクで対応)。
 * ============================================================ */
.timeline > .post + div:has(> .post-actions),
.reply-tree .reply-node > div:has(> .post-actions),
.post-actions-wrap {
  border-bottom: 1px solid var(--border-primary);
  padding-bottom: var(--space-3) !important;
}
.timeline > .post:has(+ div > .post-actions),
.reply-tree .reply-node > .post:has(+ div > .post-actions) {
  border-bottom: none !important;
}
/* タイムライン末尾は余計な区切り線を出さない */
.timeline > div:has(> .post-actions):last-child {
  border-bottom: none;
}

/* ===========================================================================
 * §27.5 借入中 (赤字) ユーザの視覚マーク (PHP _layout_header.php L161-200 移植)
 *
 *   .avatar.is-deficit-avatar
 *     タイムライン / 投稿詳細 / 引用カード で投稿者アバターを薄く白黒に。
 *     プロフィールページの大アバターは class を付けないので影響しない。
 *
 *   .profile-deficit-badge
 *     プロフィールの名前横に出す「[🏦] 借入中」赤い丸ピル。
 *
 *   名前のグレー化は意図的に未実装 (ユーザ要望 2026-05-25)。
 * =========================================================================== */
.profile-deficit-badge {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: 6px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(255, 77, 109, 0.12);
  border: 1px solid #ff4d6d;
  color: #ff4d6d !important;
  font-size: 0.74rem; font-weight: 800;
  text-decoration: none;
  vertical-align: middle;
}
.profile-deficit-badge:hover { background: rgba(255, 77, 109, 0.20); }
.profile-deficit-badge i { font-size: 0.78rem; }
body.theme-light .profile-deficit-badge {
  background: #ffe5ec; color: #c8002a !important; border-color: #c8002a;
}
.avatar.is-deficit-avatar {
  opacity: 0.4;
  filter: grayscale(0.85) saturate(0.4) brightness(0.95);
}

/* ===========================================================================
 * §28 言葉の銀行 (kotoba_bank) スタイル
 *
 * 旧 pages/kotoba_bank.html 内に inline <style> として 184 行入っていたのを
 * ここに移動。理由:
 *   - inline は毎リクエスト送信 = キャッシュ不可、HTML 7-8KB 増し
 *   - v2.css に出せば 1 年 immutable で long-cache、Gzip 圧縮もまとめて
 *   - テーマ/カスタムカラー override の対象になる (specificity が揃う)
 * PHP kotoba_bank.php の inline <style> ベース、一部省略・整理済。
 * =========================================================================== */
.wb-wrap   { padding: 12px 14px 56px; }
.wb-flash  { padding:11px 14px; border-radius:10px; margin-bottom:14px; font-size:0.9rem; font-weight:600;
             background:rgba(255,77,109,0.10); border:1px solid #ff4d6d; color:#ff4d6d; }
.wb-info   { font-size:0.8rem; color:var(--text-secondary); background:rgba(124,77,255,0.06);
             border:1px solid var(--border-primary); border-radius:12px; padding:10px 13px; margin-bottom:14px;
             display:flex; gap:9px; align-items:flex-start; line-height:1.65; }
.wb-info i { color:var(--accent-cyan); flex-shrink:0; margin-top:2px; font-size:1rem; }
.wb-info strong { color:var(--text-primary); }

/* ===== 残高カード (Morioka Portal+ ブランド: 紫→シアン) ===== */
.wb-balance { position:relative; overflow:hidden; padding:18px 20px 15px; border-radius:20px;
              margin-bottom:16px; color:#fff !important;
              background:linear-gradient(135deg,#241c4d 0%,#243355 52%,#1c4257 100%);
              border:1px solid rgba(124,77,255,0.22);
              box-shadow:0 8px 22px rgba(0,0,0,0.35); }
.wb-balance::after { content:''; position:absolute; right:-42px; top:-42px; width:175px; height:175px;
                     border-radius:50%; background:radial-gradient(circle,rgba(124,77,255,0.16),transparent 70%);
                     pointer-events:none; }
.wb-balance.is-deficit { background:linear-gradient(135deg,#4a2230 0%,#5e2a39 55%,#6b2f3d 100%);
                         border-color:rgba(196,74,94,0.30);
                         box-shadow:0 8px 22px rgba(0,0,0,0.35); }
/* テキストは常に白 (カスタムテーマの --text-primary に引っ張られないよう固定) */
.wb-balance, .wb-balance .wb-bank-name, .wb-balance .wb-rank,
.wb-balance .wb-balance-label, .wb-balance .wb-pending,
.wb-balance .wb-balance-num, .wb-balance .wb-balance-num .num,
.wb-balance .wb-balance-num .unit, .wb-balance .wb-deficit-note,
.wb-balance .wb-balance-foot, .wb-balance .wb-balance-foot .holder { color:#fff !important; }
.wb-balance-top  { position:relative; z-index:1; display:flex; align-items:center; justify-content:space-between; gap:8px; }
.wb-bank-name    { font-size:0.82rem; font-weight:700; letter-spacing:0.05em; opacity:0.96;
                   display:flex; align-items:center; gap:6px; }
.wb-rank         { background:rgba(255,255,255,0.22); border:1px solid rgba(255,255,255,0.32);
                   border-radius:999px; padding:3px 12px; font-size:0.72rem; font-weight:700; white-space:nowrap; }
.wb-balance-label { position:relative; z-index:1; margin-top:13px; font-size:0.78rem; opacity:0.92;
                    display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.wb-pending      { background:rgba(255,255,255,0.20); border-radius:999px; padding:2px 9px;
                   font-size:0.7rem; font-weight:600; display:inline-flex; align-items:center; gap:4px; }
.wb-balance-num  { position:relative; z-index:1; margin-top:2px; display:flex; align-items:baseline;
                   gap:6px; flex-wrap:wrap; }
.wb-balance-num .num  { font-size:2.9rem; font-weight:900; line-height:1.0; letter-spacing:-0.01em; }
.wb-balance-num .unit { font-size:1.05rem; font-weight:700; opacity:0.95; }
.wb-deficit-badge { font-size:0.72rem; font-weight:900; letter-spacing:0.04em;
                    background:#fff; color:#c44a5e !important; padding:3px 11px; border-radius:999px; }
.wb-deficit-note { position:relative; z-index:1; margin-top:10px; font-size:0.78rem; font-weight:700;
                   background:rgba(0,0,0,0.18); border:1px dashed rgba(255,255,255,0.55);
                   padding:7px 12px; border-radius:9px; }
.wb-balance-foot { position:relative; z-index:1; margin-top:15px; display:flex; align-items:center;
                   justify-content:space-between; gap:8px; font-size:0.8rem; }
.wb-balance-foot .holder { opacity:0.92; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.wb-balance-link { flex-shrink:0; color:#fff !important; text-decoration:none; font-weight:700;
                   background:rgba(255,255,255,0.22); border:1px solid rgba(255,255,255,0.34);
                   border-radius:999px; padding:5px 14px; display:inline-flex; align-items:center; gap:6px;
                   transition:background 0.15s; }
.wb-balance-link:hover { background:rgba(255,255,255,0.32); }

/* ===== アイコンメニュー (Morioka ブランド配色グリッド) ===== */
.wb-menu { display:grid; grid-template-columns:repeat(4,1fr); gap:14px 6px; margin-bottom:20px; }
.wb-menu-item { display:flex; flex-direction:column; align-items:center; gap:7px;
                text-decoration:none; color:var(--text-secondary); }
.wb-menu-item .ic { position:relative; width:58px; height:58px; border-radius:18px;
                    display:flex; align-items:center; justify-content:center; font-size:1.5rem;
                    background:var(--bg-card); border:1px solid var(--border-primary);
                    color:var(--accent-cyan); box-shadow:0 3px 10px rgba(0,0,0,0.10);
                    transition:transform 0.12s, box-shadow 0.12s, background 0.12s; }
.wb-menu-item .lbl { font-size:0.74rem; font-weight:600; text-align:center; line-height:1.25; }
.wb-menu-item:hover .ic { transform:translateY(-3px); box-shadow:0 7px 16px rgba(0,0,0,0.18); border-color:var(--accent-cyan); }
.wb-menu-item.active .ic { background:linear-gradient(135deg,#5238c2,#2c6fae); color:#fff; border-color:transparent; }
.wb-menu-item.active .lbl { color:var(--text-primary); font-weight:800; }
.wb-menu-badge { position:absolute; top:-9px; right:-9px; min-width:26px; height:26px; padding:0 7px;
                 border-radius:999px; background:#ff3b30; color:#fff; font-size:0.92rem; font-weight:800;
                 display:flex; align-items:center; justify-content:center; border:2.5px solid var(--bg-primary);
                 box-shadow:0 2px 6px rgba(0,0,0,0.35); line-height:1; letter-spacing:-0.01em; }
/* 一時停止中のメニュー項目 (さんぽの守バランス調整中など) */
.wb-menu-item.is-disabled { cursor:not-allowed; opacity:0.42; filter:grayscale(1); }
.wb-menu-item.is-disabled:hover .ic { transform:none; box-shadow:0 3px 10px rgba(0,0,0,0.10); border-color:var(--border-primary); }
.wb-menu-item.is-disabled .ic { background:var(--bg-card); color:var(--text-secondary); }
.wb-menu-item.is-disabled .lbl { color:var(--text-secondary); }
.wb-menu-sub { display:block; font-size:0.62rem; font-weight:700; color:var(--text-secondary); margin-top:2px; }
/* さんぽ停止中の本文 */
.walk-suspended { text-align:center; padding:40px 18px; }
.walk-suspended-icon { font-size:3rem; color:var(--text-secondary); opacity:0.5; margin-bottom:14px; filter:grayscale(1); }
.walk-suspended h2 { font-size:1.1rem; margin:0 0 10px; color:var(--text-primary); }
.walk-suspended p { font-size:0.88rem; line-height:1.7; max-width:480px; margin:0 auto; }
/* ===== ライトモード: 明るい背景に調和させる ===== */
body.theme-light .wb-balance {
  background:linear-gradient(135deg,#6a4fe0 0%,#566add 46%,#3f8ed4 100%);
  border-color:rgba(106,79,224,0.30);
  box-shadow:0 10px 26px rgba(94,63,230,0.22);
}
body.theme-light .wb-balance::after { background:radial-gradient(circle,rgba(255,255,255,0.24),transparent 70%); }
body.theme-light .wb-balance.is-deficit {
  background:linear-gradient(135deg,#c44a5e 0%,#d35468 55%,#df6076 100%);
  border-color:rgba(196,74,94,0.32);
}
/* ライトのアイコンタイル: ハードコード白だとカスタムカラー (panel/bg) に追従しないため
   CSS 変数経由にしてユーザのカスタム panel 色が効くようにする (アクティブのグラデは固定)。 */
body.theme-light .wb-menu-item .ic { background:var(--bg-card); border-color:var(--border-primary); color:#5e3fe6;
                                     box-shadow:0 3px 10px rgba(50,80,150,0.10); }
body.theme-light .wb-menu-item:hover .ic { border-color:#5e3fe6; }
body.theme-light .wb-menu-item.active .ic { background:linear-gradient(135deg,#6a4fe0,#3f8ed4);
                                            color:#fff; border-color:transparent; }
body.theme-light .wb-menu-item.active .lbl { color:var(--text-primary); }
body.theme-light .wb-menu-badge { border-color:var(--bg-primary); }

/* ===== 注意書き / 警告 ===== */
.wb-alert { display:flex; align-items:flex-start; gap:9px; padding:11px 14px; border-radius:12px;
            margin-bottom:14px; font-size:0.84rem; line-height:1.6; color:var(--text-primary);
            background:rgba(255,138,0,0.08); border:1px solid rgba(255,138,0,0.35); }
.wb-alert i { color:#ff8a00; margin-top:2px; flex-shrink:0; }
.wb-alert strong { color:#ff8a00; }

.wb-convert { font-size:0.72rem; color:var(--text-secondary); text-align:center; margin:16px 0 4px;
              display:flex; align-items:center; justify-content:center; gap:6px; line-height:1.5; }

.wb-welcome { padding:18px 18px 16px; border-radius:16px; margin-bottom:14px;
              background:linear-gradient(135deg,rgba(124,77,255,0.15),rgba(0,229,255,0.10));
              border:1px solid var(--accent-cyan); }
.wb-welcome h2 { font-size:1.05rem; margin:0 0 5px; color:var(--text-primary); display:flex; align-items:center; gap:8px; }
.wb-welcome h2 i { color:var(--accent-purple); }
.wb-welcome p  { font-size:0.85rem; color:var(--text-secondary); margin:0 0 12px; line-height:1.7; }
.wb-welcome strong { color:var(--text-primary); }

.wb-section-h { font-size:0.82rem; font-weight:700; color:var(--text-secondary);
                margin:18px 0 8px; display:flex; align-items:center; gap:7px;
                text-transform:uppercase; letter-spacing:0.08em; }
.wb-section-h i { color:var(--accent-cyan); }
.wb-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:10px; margin-bottom:14px; }
.wb-card { border:1px solid var(--border-primary); border-radius:14px; padding:13px 15px;
           background:var(--bg-card); display:flex; flex-direction:column; gap:3px;
           text-decoration:none; color:inherit; transition:transform 0.12s, border-color 0.12s; }
.wb-card.link:hover { transform:translateY(-2px); border-color:var(--accent-cyan); }
.wb-card .l { font-size:0.74rem; color:var(--text-secondary); display:flex; align-items:center; gap:6px; }
.wb-card .l i { color:var(--accent-cyan); }
.wb-card .v { font-size:1.25rem; font-weight:800; color:var(--text-primary); line-height:1.1; margin-top:2px; }
.wb-card .v small { font-size:0.72rem; color:var(--text-secondary); font-weight:600; }
.wb-card .s { font-size:0.72rem; color:var(--text-secondary); margin-top:2px; line-height:1.4; }
.wb-card.cta { background:linear-gradient(135deg,rgba(124,77,255,0.10),rgba(0,229,255,0.07)); border-color:var(--accent-cyan); }
.wb-card.warn { border-color:#ff4d6d; }
.wb-card.warn .v { color:#ff4d6d; }

.wb-week { display:flex; flex-wrap:wrap; gap:10px; padding:11px 14px;
           background:var(--bg-card); border:1px solid var(--border-primary); border-radius:12px;
           font-size:0.82rem; color:var(--text-secondary); margin-bottom:14px; align-items:center; }
.wb-week .label { color:var(--text-primary); font-weight:700; display:flex; align-items:center; gap:6px; }
.wb-week .label i { color:var(--accent-cyan); }
.wb-week .stat strong { color:var(--text-primary); font-weight:700; }
.wb-week .total { margin-left:auto; padding:3px 11px;
                  background:linear-gradient(135deg,rgba(0,200,150,0.18),rgba(0,229,255,0.12));
                  border:1px solid #00c896; border-radius:999px; color:#00c896; font-weight:800; }

.wb-sum { display:grid; grid-template-columns:repeat(auto-fit,minmax(155px,1fr)); gap:8px; margin-bottom:16px; }
.wb-sum-it { border:1px solid var(--border-primary); border-radius:12px; padding:11px 13px; background:var(--bg-card); }
.wb-sum-it .t { font-size:0.76rem; color:var(--text-secondary); display:flex; align-items:center; gap:6px; }
.wb-sum-it .t i { color:var(--accent-cyan); }
.wb-sum-it .v { font-size:1.05rem; font-weight:800; color:var(--text-primary); margin-top:4px; }
.wb-sum-it .v.neg { color:#ff4d6d; }
.wb-sum-it .v small { font-size:0.72rem; color:var(--text-secondary); font-weight:600; }

.wb-row { display:flex; align-items:center; gap:12px; padding:11px 4px; border-bottom:1px solid var(--border-primary); }
.wb-row .ic { width:36px; height:36px; border-radius:10px;
              background:linear-gradient(135deg,rgba(124,77,255,0.14),rgba(0,229,255,0.14));
              color:var(--accent-cyan); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.wb-row .meta { flex:1; min-width:0; }
.wb-row .lbl  { color:var(--text-primary); font-size:0.9rem; font-weight:600; }
.wb-row .date { color:var(--text-secondary); font-size:0.74rem; margin-top:1px; }
.wb-row .amt  { color:#00c896; font-weight:800; font-size:0.95rem; white-space:nowrap; }
.wb-row .amt.neg  { color:#ff4d6d; }
.wb-row .amt.pending { color:var(--text-secondary); font-style:italic; }

.wb-empty { text-align:center; color:var(--text-secondary); padding:36px 20px; font-size:0.88rem;
            background:var(--bg-card); border:1px dashed var(--border-primary); border-radius:14px; }
.wb-empty i { display:block; font-size:2rem; margin-bottom:10px; color:var(--accent-cyan); opacity:0.5; }

.wb-item { display:block; padding:14px 15px; border:1px solid var(--border-primary); border-radius:14px;
           margin-bottom:10px; background:var(--bg-card); text-decoration:none; color:inherit;
           transition:transform 0.12s, border-color 0.12s; }
.wb-item:hover { transform:translateY(-1px); border-color:var(--accent-cyan); }
.wb-item-head { display:flex; align-items:center; gap:10px; margin-bottom:8px; }
.wb-item-head .name { flex:1; min-width:0; font-weight:700; color:var(--text-primary); font-size:0.95rem; }
.wb-item-head .name i { color:var(--accent-cyan); margin-right:4px; }
.wb-item-head .age { font-size:0.74rem; color:var(--text-secondary); white-space:nowrap;
                     background:var(--bg-card-hover); padding:2px 9px; border-radius:999px; border:1px solid var(--border-primary); }

.wb-shop-hero { padding:14px 16px; border-radius:14px; margin-bottom:14px;
                background:linear-gradient(135deg,rgba(124,77,255,0.10),rgba(0,229,255,0.07));
                border:1px solid var(--accent-cyan); color:var(--text-primary); font-size:0.86rem; line-height:1.7; }
.wb-shop-hero strong { color:var(--accent-purple); }
.wb-ticket { display:flex; gap:13px; padding:14px; border:1px solid var(--border-primary); border-radius:14px;
             margin-bottom:10px; background:var(--bg-card); }
.wb-ticket .ti { width:54px; height:54px; border-radius:12px;
                 background:linear-gradient(135deg,rgba(124,77,255,0.20),rgba(0,229,255,0.20));
                 color:var(--accent-cyan); display:flex; align-items:center; justify-content:center;
                 font-size:1.45rem; flex-shrink:0; }
.wb-ticket .body { flex:1; min-width:0; }
.wb-ticket .name { font-weight:800; font-size:0.96rem; color:var(--text-primary);
                   display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.wb-ticket .price { background:linear-gradient(135deg,#00c896,#00e5ff); color:#fff;
                    padding:2px 10px; border-radius:999px; font-size:0.74rem; font-weight:800; }
.wb-ticket .desc { color:var(--text-secondary); font-size:0.82rem; margin-top:4px; line-height:1.55; }
.wb-ticket .meta { display:flex; gap:6px; flex-wrap:wrap; margin-top:7px; font-size:0.72rem; color:var(--text-secondary); }
.wb-ticket .meta span { background:var(--bg-card-hover); border:1px solid var(--border-primary); border-radius:8px; padding:2px 8px; }
.wb-ticket .why { margin-top:9px; font-size:0.76rem; color:#ff8a00;
                  background:rgba(255,138,0,0.08); border:1px solid rgba(255,138,0,0.30);
                  border-radius:8px; padding:6px 10px; }
.wb-open-btn { border:none; border-radius:999px; padding:9px 18px; font-weight:800; font-size:0.85rem;
               color:#fff !important; cursor:pointer; margin-top:10px;
               background:linear-gradient(135deg,var(--accent-purple),var(--accent-cyan));
               display:inline-flex; align-items:center; gap:7px; }
.wb-open-btn:hover { filter:brightness(1.08); }

.wb-rule { display:flex; gap:13px; padding:14px; border:1px solid var(--border-primary);
           border-radius:14px; margin-bottom:10px; background:var(--bg-card); }
.wb-rule .ic { width:44px; height:44px; border-radius:12px;
               background:linear-gradient(135deg,rgba(124,77,255,0.20),rgba(0,229,255,0.20));
               color:var(--accent-cyan); display:flex; align-items:center; justify-content:center; font-size:1.2rem; flex-shrink:0; }
.wb-rule .body { flex:1; }
.wb-rule .name { font-weight:800; color:var(--text-primary); font-size:0.92rem;
                 display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.wb-rule .pt { background:linear-gradient(135deg,#00c896,#00e5ff); color:#fff;
               padding:2px 10px; border-radius:999px; font-size:0.74rem; font-weight:800; }
.wb-rule .desc { color:var(--text-secondary); font-size:0.83rem; margin-top:4px; line-height:1.65; }

/* ===== ホームからガイドへの導線 ===== */
.wb-guide-cta { display:flex; align-items:center; gap:11px; padding:13px 16px; border-radius:14px;
                margin-bottom:14px; text-decoration:none; color:var(--text-primary);
                background:linear-gradient(135deg,rgba(124,77,255,0.10),rgba(0,229,255,0.07));
                border:1px solid var(--border-primary); font-size:0.88rem; font-weight:700;
                transition:transform 0.12s, border-color 0.12s; }
.wb-guide-cta:hover { transform:translateY(-1px); border-color:var(--accent-cyan); }
.wb-guide-cta > i:first-child { color:var(--accent-purple); font-size:1.25rem; flex-shrink:0; }
.wb-guide-cta > i:last-child { color:var(--text-secondary); font-size:0.85rem; flex-shrink:0; }
.wb-guide-cta-txt { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.wb-guide-cta-txt b { font-size:0.92rem; font-weight:800; color:var(--text-primary); }
.wb-guide-cta-txt small { font-size:0.76rem; font-weight:600; color:var(--text-secondary); }

/* ===== ガイド (集約版・読みやすさ重視) ===== */
.wb-guide { display:flex; flex-direction:column; gap:13px; }
.wb-guide-hero { display:flex; gap:14px; align-items:flex-start; padding:17px 18px; border-radius:16px;
                 background:linear-gradient(135deg,rgba(124,77,255,0.13),rgba(0,229,255,0.08));
                 border:1px solid var(--border-primary); }
.wb-guide-hero > i { font-size:1.9rem; color:var(--accent-purple); flex-shrink:0; margin-top:3px; }
.wb-guide-hero h2 { margin:0 0 6px; font-size:1.12rem; color:var(--text-primary); }
.wb-guide-hero p  { margin:0; font-size:0.88rem; line-height:1.8; color:var(--text-secondary); }
.wb-guide-hero strong { color:var(--text-primary); }

.wb-guide-sec { padding:15px 17px; border-radius:14px; background:var(--bg-card); border:1px solid var(--border-primary); }
.wb-guide-h   { display:flex; align-items:center; gap:9px; margin:0 0 11px; font-size:1rem;
                color:var(--text-primary); font-weight:800; }
.wb-guide-h i { color:var(--accent-cyan); }
.wb-guide-p   { margin:0; font-size:0.86rem; line-height:1.85; color:var(--text-secondary); }
.wb-guide-p strong { color:var(--text-primary); }
.wb-guide-sec .wb-rule { margin-bottom:8px; }
.wb-guide-sec .wb-rule:last-child { margin-bottom:0; }

.wb-guide-list { margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:10px; }
.wb-guide-list li { position:relative; padding-left:20px; font-size:0.86rem; line-height:1.7; color:var(--text-secondary); }
.wb-guide-list li::before { content:''; position:absolute; left:2px; top:8px; width:7px; height:7px;
                            border-radius:50%; background:var(--accent-cyan); }
.wb-guide-list li b { color:var(--text-primary); font-weight:800; }
.wb-guide-list strong { color:var(--text-primary); }

.wb-guide-note { display:flex; gap:9px; align-items:flex-start; padding:12px 15px; border-radius:12px;
                 font-size:0.82rem; line-height:1.7; color:var(--text-secondary);
                 background:rgba(124,77,255,0.06); border:1px dashed var(--border-primary); }
.wb-guide-note i { color:var(--accent-cyan); flex-shrink:0; margin-top:2px; }
.wb-guide-note strong { color:var(--text-primary); }

/* ===== くじ引き (tab=lottery) ===== */
.wb-lottery { display:flex; flex-direction:column; gap:18px; }
.wb-lottery-head { display:flex; align-items:flex-start; gap:14px; padding:16px;
                   border:1px solid var(--border-primary); border-radius:16px;
                   background:linear-gradient(135deg,rgba(0,200,150,0.10),rgba(0,229,255,0.06)); }
.wb-lottery-head > i { font-size:2rem; color:var(--accent-green,#00c896); flex-shrink:0; }
.wb-lottery-head h2 { margin:0 0 4px; font-size:1.15rem; color:var(--text-primary); }
.wb-lottery-head p { margin:0; font-size:0.85rem; line-height:1.6; }

.wb-lottery-result { text-align:center; padding:22px 16px; border-radius:18px;
                     border:1px solid var(--accent-gold,#ffd700);
                     background:radial-gradient(ellipse at center,rgba(255,215,0,0.18),rgba(255,215,0,0.04));
                     animation:wbLotteryPop 0.5s cubic-bezier(0.34,1.56,0.64,1); }
.wb-lottery-result .wb-lottery-burst { font-size:2.6rem; color:var(--accent-green,#00c896);
                     animation:wbLotterySpin 0.9s ease-out; }
.wb-lottery-result .amt { font-size:2.4rem; font-weight:900; color:var(--accent-gold,#ffd700);
                     margin-top:6px; }
.wb-lottery-result .lbl { font-size:0.95rem; color:var(--text-primary); margin-top:4px; font-weight:700; }
/* 結果カラーバリアント */
.wb-lottery-result.lose {
  border-color: var(--accent-pink, #ff4d6d);
  background: radial-gradient(ellipse at center, rgba(255,77,109,0.22), rgba(255,77,109,0.04));
}
.wb-lottery-result.lose .wb-lottery-burst { color: var(--accent-pink, #ff4d6d); }
.wb-lottery-result.lose .amt { color: var(--accent-pink, #ff4d6d); }
.wb-lottery-result.miss {
  border-color: var(--border-primary);
  background: rgba(255,255,255,0.03);
}
.wb-lottery-result.miss .wb-lottery-burst { color: var(--text-secondary); }
.wb-lottery-result.miss .amt { color: var(--text-secondary); }
.wb-lottery-result.bonus {
  border-color: var(--accent-cyan, #00e5ff);
  background: radial-gradient(ellipse at center, rgba(0,229,255,0.18), rgba(0,229,255,0.04));
}
.wb-lottery-result.bonus .wb-lottery-burst { color: var(--accent-cyan, #00e5ff); }
.wb-lottery-result.bonus .amt { color: var(--accent-cyan, #00e5ff); font-size: 1.6rem; }
@keyframes wbLotteryPop { from { opacity:0; transform:scale(0.85); } to { opacity:1; transform:scale(1); } }
@keyframes wbLotterySpin { from { transform:rotate(-180deg) scale(0.4); } to { transform:rotate(0) scale(1); } }

.wb-prize-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.wb-prize-list li { display:flex; align-items:center; gap:12px; }
.wb-prize-list .amt { width:72px; flex-shrink:0; font-weight:800; color:var(--text-primary);
                      font-size:0.9rem; text-align:right; }
.wb-prize-list .bar { flex:1; height:10px; border-radius:999px; background:var(--bg-secondary,rgba(255,255,255,0.06));
                      overflow:hidden; }
.wb-prize-list .bar i { display:block; height:100%; border-radius:999px;
                        background:linear-gradient(90deg,var(--accent-green,#00c896),var(--accent-cyan)); }

.wb-lottery-action { display:flex; flex-direction:column; align-items:center; padding:6px 0 12px; }
.wb-lottery-btn { display:inline-flex; align-items:center; justify-content:center; gap:10px;
                  padding:15px 40px; border:none; border-radius:999px; cursor:pointer;
                  font-size:1.1rem; font-weight:900; color:#fff;
                  background:linear-gradient(135deg,var(--accent-green,#00c896),var(--accent-cyan));
                  box-shadow:0 6px 20px rgba(0,200,150,0.35); transition:transform 0.12s, box-shadow 0.12s; }
.wb-lottery-btn:hover:not(.is-disabled) { transform:translateY(-2px); box-shadow:0 10px 28px rgba(0,200,150,0.45); }
.wb-lottery-btn:active:not(.is-disabled) { transform:translateY(0); }
.wb-lottery-btn.is-disabled { background:var(--bg-secondary,rgba(255,255,255,0.06));
                  color:var(--text-secondary); box-shadow:none; cursor:not-allowed; }

/* ===== 同好談話室 (danwa) ===== */
.danwa-wrap { padding:14px 16px 60px; display:flex; flex-direction:column; gap:14px; }
.danwa-intro { padding:13px 16px; border-radius:14px; border:1px solid var(--border-primary);
               background:linear-gradient(135deg,rgba(124,77,255,0.08),rgba(0,229,255,0.04)); }
.danwa-intro-head { display:flex; align-items:center; gap:8px; font-weight:800; font-size:0.95rem;
                    color:var(--text-primary); margin-bottom:6px; }
.danwa-intro-head i { color:var(--accent-purple); }
.danwa-intro p { margin:0; font-size:0.84rem; line-height:1.75; color:var(--text-secondary); }
.danwa-intro strong { color:var(--text-primary); }

.danwa-flash { padding:10px 13px; border-radius:10px; font-size:0.85rem; font-weight:600;
               background:rgba(0,229,255,0.05); border:1px solid var(--border-primary); color:var(--text-primary); }
.danwa-flash--ok { background:rgba(0,200,150,0.08); border-color:rgba(0,200,150,0.30); color:#00c896; }
.danwa-flash--err { background:rgba(255,77,109,0.08); border-color:rgba(255,77,109,0.30); color:#ff4d6d; }

.danwa-list { display:flex; flex-direction:column; gap:10px; }
.danwa-card { display:block; padding:14px 16px; border:1px solid var(--border-primary); border-radius:14px;
              background:var(--bg-card); text-decoration:none; color:inherit;
              transition:transform 0.12s, border-color 0.12s; }
.danwa-card:hover { transform:translateY(-1px); border-color:var(--accent-purple); }
.danwa-card.is-member { border-color:rgba(124,77,255,0.4); background:linear-gradient(135deg,rgba(124,77,255,0.05),rgba(0,229,255,0.03)); }
.danwa-card-head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.danwa-card-name { font-weight:800; font-size:0.98rem; color:var(--text-primary);
                   display:inline-flex; align-items:center; gap:8px; }
.danwa-card-name i { color:var(--accent-purple); }
.danwa-card-badge { font-size:0.7rem; font-weight:700; padding:2px 9px; border-radius:999px; display:inline-flex; align-items:center; gap:4px; }
.danwa-card-badge.ok { background:rgba(0,200,150,0.10); color:#00c896; border:1px solid rgba(0,200,150,0.35); }
.danwa-card-badge.open { background:rgba(0,229,255,0.10); color:var(--accent-cyan); border:1px solid rgba(0,229,255,0.35); }
.danwa-card-badge.closed { background:rgba(255,255,255,0.04); color:var(--text-secondary); border:1px solid var(--border-primary); }
.danwa-card.is-closed { opacity:0.78; }
.danwa-fieldset { border:1px solid var(--border-primary); border-radius:10px; padding:10px 12px;
                  background:rgba(255,255,255,0.02); margin:0; }
.danwa-fieldset legend { padding:0 6px; font-size:0.84rem; }
.danwa-hours-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:8px; }
.danwa-hours-row input[type=number] { padding:6px 8px; border:1px solid var(--border-primary); border-radius:6px;
                                      background:var(--bg-card-hover); color:var(--text-primary); font-size:0.92rem; }
.danwa-card-desc { font-size:0.84rem; color:var(--text-secondary); margin-top:6px; line-height:1.6; }
.danwa-card-meta { display:flex; flex-wrap:wrap; gap:11px; margin-top:8px; font-size:0.76rem; color:var(--text-secondary); }
.danwa-card-meta i { margin-right:3px; }
.danwa-card-fee { margin-left:auto; padding:2px 10px; border-radius:999px;
                  background:rgba(124,77,255,0.10); color:var(--accent-purple);
                  border:1px solid rgba(124,77,255,0.30); font-weight:700; }

.danwa-room-card { padding:14px 16px; border:1px solid var(--border-primary); border-radius:14px; background:var(--bg-card); }
.danwa-room-head { display:flex; align-items:flex-start; gap:12px; }
.danwa-room-head > i { font-size:1.7rem; color:var(--accent-purple); flex-shrink:0; }
.danwa-room-name { font-weight:900; font-size:1.1rem; color:var(--text-primary); }
.danwa-room-meta { display:flex; flex-wrap:wrap; gap:10px; margin-top:4px; }
.danwa-room-desc { margin:10px 0 0; font-size:0.86rem; color:var(--text-secondary); line-height:1.65; }
.danwa-room-actions { display:flex; gap:10px; flex-wrap:wrap; margin-top:14px; align-items:center; }
.danwa-room-gate { margin-top:14px; padding:13px 15px; border-radius:12px;
                   background:rgba(124,77,255,0.06); border:1px dashed rgba(124,77,255,0.4); }
.danwa-gate-title { font-weight:800; color:var(--text-primary); margin-bottom:6px; }
.danwa-room-gate p { margin:0 0 10px; font-size:0.85rem; color:var(--text-secondary); line-height:1.6; }

.danwa-form { display:flex; flex-direction:column; gap:14px; padding:16px;
              border:1px solid var(--border-primary); border-radius:14px; background:var(--bg-card); }
.danwa-form label { display:flex; flex-direction:column; gap:5px; }
.danwa-label { font-size:0.85rem; font-weight:700; color:var(--text-primary); }
.danwa-form input[type=text], .danwa-form textarea {
  padding:9px 11px; border:1px solid var(--border-primary); border-radius:8px;
  background:var(--bg-card-hover); color:var(--text-primary); font-size:0.92rem; font-family:inherit; }
.danwa-form textarea { resize:vertical; }
.danwa-submit { display:inline-flex; align-items:center; justify-content:center; gap:8px;
                padding:11px 22px; border:none; border-radius:999px; cursor:pointer;
                font-size:0.95rem; font-weight:800; color:#fff;
                background:linear-gradient(135deg,var(--accent-purple),var(--accent-cyan));
                text-decoration:none; transition:transform 0.12s, filter 0.12s; }
.danwa-submit:hover:not(:disabled) { transform:translateY(-1px); filter:brightness(1.05); }
.danwa-submit:disabled { opacity:0.55; cursor:not-allowed; }
.danwa-leave { padding:9px 16px; border:1px solid var(--border-primary); border-radius:999px;
               background:var(--bg-card-hover); color:var(--text-secondary); cursor:pointer; font-size:0.84rem; font-weight:600; }
.danwa-leave:hover { color:#ff4d6d; border-color:rgba(255,77,109,0.4); }

.danwa-empty { text-align:center; color:var(--text-secondary); padding:36px 20px; font-size:0.88rem;
               background:var(--bg-card); border:1px dashed var(--border-primary); border-radius:14px; }
.danwa-empty i { display:block; font-size:2rem; margin-bottom:10px; color:var(--accent-purple); opacity:0.55; }

/* ===== 同好談話室: 参加者一覧 (<details> で折りたたみ) ===== */
.danwa-members { padding:0; border:1px solid var(--border-primary); border-radius:14px;
                 background:var(--bg-card); margin:14px 0; overflow:hidden; }
/* 既定の三角マーカーを消す */
.danwa-members > summary { list-style:none; cursor:pointer; }
.danwa-members > summary::-webkit-details-marker { display:none; }
.danwa-members-head { display:flex; align-items:center; gap:8px; padding:12px 16px;
                      font-size:0.88rem; color:var(--text-primary); }
.danwa-members-head i { color:var(--accent-cyan); }
.danwa-members-head:hover { background:var(--bg-card-hover); }
.danwa-members-caret { margin-left:auto; transition:transform 0.18s; font-size:0.75rem; }
.danwa-members[open] .danwa-members-caret { transform:rotate(180deg); }
.danwa-members-list { list-style:none; margin:0; padding:8px 12px 12px;
                      display:flex; flex-direction:column; gap:6px; max-height:60vh; overflow-y:auto; }

/* room-card メタ内の「N 人」をボタン化 (タップで上のメンバー一覧を開く) */
.danwa-member-trigger { background:transparent; border:none; padding:0; cursor:pointer;
                        color:inherit; font:inherit; display:inline-flex; align-items:center; gap:4px;
                        text-decoration:underline dotted; text-underline-offset:3px; }
.danwa-member-trigger:hover { color:var(--accent-cyan); }
.danwa-member { display:flex; align-items:center; gap:10px; padding:6px 8px; border-radius:10px;
                transition:background 0.12s; }
.danwa-member:hover { background:var(--bg-card-hover); }
.danwa-member.is-suspended { opacity:0.55; }
.danwa-member-link { display:flex; align-items:center; gap:10px; text-decoration:none; color:inherit; flex:1; min-width:0; }
.danwa-member-meta { display:flex; flex-direction:column; min-width:0; }
.danwa-member-name { font-weight:700; color:var(--text-primary); font-size:0.9rem;
                     overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.danwa-member-handle { font-size:0.76rem; }
.danwa-member-tag { font-size:0.72rem; font-weight:800; padding:2px 9px; border-radius:999px;
                    display:inline-flex; align-items:center; gap:5px; flex-shrink:0; }
.danwa-member-tag.is-host { background:linear-gradient(135deg,#f8c450,#f59e0b); color:#fff; }
.danwa-member-tag.is-paused { background:rgba(255,77,109,0.12); color:#ff4d6d;
                              border:1px solid rgba(255,77,109,0.35); }

/* ==========================================================
 * さんぽ (tab=walk) — 先進的ダッシュボード
 * - ダーク/ライト両対応 (CSS 変数で切替)
 * - ネオングロー / グラデーション / パルスアニメで動的演出
 * - モバイル幅 (< 480px) でもタッチ操作しやすい配置
 * ========================================================== */

.walk-hub { display: flex; flex-direction: column; gap: 14px; }

/* ===== ヒーロー (発光する歩行アイコン) ===== */
.walk-hero {
  position: relative; overflow: hidden;
  border-radius: 18px;
  padding: 22px 18px;
  border: 1px solid rgba(0, 229, 255, 0.22);
  background:
    radial-gradient(120% 100% at 0% 0%, rgba(102, 51, 255, 0.18), transparent 55%),
    radial-gradient(120% 100% at 100% 100%, rgba(0, 229, 255, 0.15), transparent 55%),
    linear-gradient(135deg, rgba(10, 14, 42, 0.55), rgba(7, 9, 22, 0.5));
  box-shadow: 0 12px 30px rgba(0, 229, 255, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.walk-hero-glow {
  position: absolute; inset: -40% -20% auto auto;
  width: 240px; height: 240px;
  background: radial-gradient(circle, rgba(0, 229, 255, 0.35), transparent 65%);
  filter: blur(28px);
  animation: walk-hero-pulse 6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes walk-hero-pulse {
  0%, 100% { opacity: 0.55; transform: translate(0, 0) scale(1); }
  50%      { opacity: 0.85; transform: translate(8px, 8px) scale(1.08); }
}
.walk-hero-content { position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
.walk-hero-head {
  display: flex; align-items: center; gap: 12px; min-width: 0;
}
.walk-hero-icon {
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 14px;
  background: linear-gradient(135deg, #00e5ff, #6633ff);
  color: #fff; font-size: 1.3rem;
  box-shadow: 0 6px 16px rgba(0, 229, 255, 0.35);
  flex-shrink: 0;
}
.walk-hero-title {
  margin: 0; font-size: 1.25rem; font-weight: 900; letter-spacing: -0.01em; line-height: 1.2;
  background: linear-gradient(120deg, var(--text-primary) 0%, var(--accent-cyan) 50%, #a78bfa 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.walk-hero-sub {
  margin: 0; font-size: 0.84rem; color: var(--text-secondary); line-height: 1.6;
  /* 行末に 1〜2 文字だけ取り残されるオーフィン防止 (text-wrap: pretty 対応 Chrome / Safari) */
  text-wrap: pretty;
  /* CJK で単語境界を尊重して中途半端な位置で切らない */
  word-break: keep-all;
  overflow-wrap: anywhere;
}

/* ===== スピードゲージ ===== */
.walk-gauge {
  padding: 14px 16px 16px;
  border-radius: 16px;
  border: 1px solid var(--border-primary);
  background: var(--bg-card);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.walk-gauge-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 4px;
}
.walk-gauge-k { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--text-primary); }
.walk-gauge-k i { color: var(--accent-cyan); }
.walk-gauge-cap { font-size: 0.7rem; opacity: 0.75; }
.walk-gauge-value {
  display: flex; align-items: baseline; gap: 6px;
  font-size: 2.4rem; font-weight: 900; line-height: 1; margin: 8px 0 12px;
  font-variant-numeric: tabular-nums;
  color: var(--accent-cyan);
  text-shadow: 0 0 18px rgba(0, 229, 255, 0.35);
  transition: color 0.2s, text-shadow 0.2s;
}
.walk-gauge-value.is-warn { color: #f59e0b; text-shadow: 0 0 18px rgba(245, 158, 11, 0.4); }
.walk-gauge-value.is-over { color: #ef4444; text-shadow: 0 0 22px rgba(239, 68, 68, 0.55); }
.walk-gauge-value small { font-size: 0.8rem; font-weight: 700; color: var(--text-secondary); text-shadow: none; }
.walk-gauge-bar {
  position: relative; height: 10px; border-radius: 999px;
  background: linear-gradient(90deg, rgba(0, 229, 255, 0.08), rgba(102, 51, 255, 0.08));
  border: 1px solid var(--border-primary);
  /* overflow:hidden だと上限ラインの上ラベルが切れるので overflow visible に */
  overflow: visible;
  /* ラベル分の余白を上に確保 */
  margin-top: 20px;
}
.walk-gauge-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-cyan) 0%, #6633ff 100%);
  box-shadow: 0 0 12px rgba(0, 229, 255, 0.55);
  transition: width 0.35s ease, background 0.25s;
}
.walk-gauge-fill.is-warn { background: linear-gradient(90deg, #fbbf24, #f59e0b); box-shadow: 0 0 12px rgba(245, 158, 11, 0.55); }
.walk-gauge-fill.is-over { background: linear-gradient(90deg, #ef4444, #b91c1c); box-shadow: 0 0 14px rgba(239, 68, 68, 0.6); }

/* 30 km/h 上限ライン (位置 = 30/300 = 10%) */
.walk-gauge-thresh--limit {
  position: absolute; top: -6px; bottom: -6px; left: 10%;
  width: 2px;
  background: linear-gradient(180deg, rgba(239, 68, 68, 0), rgba(239, 68, 68, 0.95) 25%, rgba(239, 68, 68, 0.95) 75%, rgba(239, 68, 68, 0));
}
.walk-gauge-thresh-label {
  position: absolute; left: 50%; top: -18px;
  transform: translateX(-50%);
  font-size: 0.62rem; font-weight: 800; color: #ef4444;
  white-space: nowrap;
  padding: 1px 5px; border-radius: 4px;
  background: rgba(239, 68, 68, 0.10);
  border: 1px solid rgba(239, 68, 68, 0.35);
}
.walk-gauge-thresh-label::after { /* 三角の指針 */
  content: ''; position: absolute; left: 50%; top: 100%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: rgba(239, 68, 68, 0.55);
}

/* 絶対配置の目盛り — 0/30/100/200/300 を位置指定 */
.walk-gauge-marks--abs {
  position: relative; height: 14px; margin-top: 6px;
  font-size: 0.65rem; color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.walk-gauge-marks--abs span {
  position: absolute; top: 0; transform: translateX(-50%);
  white-space: nowrap;
}
.walk-gauge-marks--abs span:first-child { transform: translateX(0); }
.walk-gauge-marks--abs span:last-child { transform: translateX(-100%); }
.walk-gauge-marks .warn { color: #ef4444; font-weight: 700; }

/* ===== 統計カード ===== */
.walk-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.walk-stat {
  position: relative; overflow: hidden;
  padding: 14px 16px;
  border: 1px solid var(--border-primary);
  border-radius: 16px;
  background: var(--bg-card);
  display: flex; flex-direction: column; gap: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}
.walk-stat:hover { border-color: rgba(0, 229, 255, 0.4); box-shadow: 0 6px 20px rgba(0, 229, 255, 0.12); }
.walk-stat-icon {
  position: absolute; top: 12px; right: 12px;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: rgba(0, 229, 255, 0.10);
  color: var(--accent-cyan);
  font-size: 0.85rem;
}
.walk-stat-k { font-size: 0.76rem; color: var(--text-secondary); }
.walk-stat-v {
  display: flex; align-items: baseline; gap: 4px;
  font-size: 1.9rem; font-weight: 900; color: var(--text-primary);
  line-height: 1.05; margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.walk-stat-v small { font-size: 0.78rem; font-weight: 700; color: var(--text-secondary); }
.walk-stat-sub { font-size: 0.7rem; color: var(--text-secondary); margin-top: 2px; }
.walk-stat-bar {
  position: relative; height: 4px; border-radius: 999px; margin-top: 6px;
  background: rgba(255, 255, 255, 0.06);
}
.walk-stat-bar-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-cyan), #a78bfa);
  box-shadow: 0 0 8px rgba(0, 229, 255, 0.4);
  transition: width 0.45s ease;
}
.walk-stat--accent {
  background: linear-gradient(135deg, rgba(0, 229, 255, 0.08), rgba(102, 51, 255, 0.08));
  border-color: rgba(0, 229, 255, 0.3);
}
/* col-span 2 (= 2 列ぶち抜き、full width)。下段の \"今日の打刻\" などに使う。 */
.walk-stat--full { grid-column: 1 / -1; }
.walk-stat--accent .walk-stat-icon {
  background: linear-gradient(135deg, #00e5ff, #6633ff); color: #fff;
}
.walk-stat--accent .walk-stat-v { color: var(--accent-cyan); text-shadow: 0 0 14px rgba(0, 229, 255, 0.3); }

/* ===== メインボタン (パルス ring 付き) ===== */
.walk-checkin-btn {
  position: relative; overflow: visible;
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; padding: 18px 24px;
  border: none; border-radius: 18px; cursor: pointer;
  color: #fff !important;
  background: linear-gradient(135deg, #00e5ff 0%, #6633ff 60%, #a78bfa 100%);
  box-shadow:
    0 0 0 1px rgba(0, 229, 255, 0.45),
    0 14px 36px rgba(102, 51, 255, 0.42),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
  transition: transform 0.12s, box-shadow 0.18s;
}
.walk-checkin-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow:
    0 0 0 1px rgba(0, 229, 255, 0.6),
    0 18px 40px rgba(102, 51, 255, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
.walk-checkin-btn:active:not(:disabled) { transform: translateY(0); }
.walk-checkin-btn:disabled { opacity: 0.6; cursor: wait; }
.walk-checkin-btn.is-active {
  background: linear-gradient(135deg, #c44a5e, #b03a4d);
  box-shadow: 0 0 0 1px rgba(196, 74, 94, 0.5), 0 12px 24px rgba(196, 74, 94, 0.4);
}
.walk-btn-content {
  position: relative; z-index: 2;
  display: inline-flex; flex-direction: column; align-items: center; gap: 4px;
  font-weight: 900;
}
.walk-btn-content i { font-size: 1.5rem; color: #fff !important; }
.walk-btn-label { font-size: 1.05rem; letter-spacing: 0.02em; }
.walk-btn-ring {
  position: absolute; inset: 0; border-radius: 18px;
  border: 2px solid rgba(0, 229, 255, 0.55);
  pointer-events: none;
  animation: walk-ring-pulse 2.4s ease-out infinite;
}
.walk-btn-ring--delay { animation-delay: 1.2s; }
@keyframes walk-ring-pulse {
  0%   { transform: scale(1);    opacity: 0.85; }
  100% { transform: scale(1.18); opacity: 0; }
}
.walk-checkin-btn:disabled .walk-btn-ring,
.walk-checkin-btn.is-active .walk-btn-ring { animation: none; opacity: 0; }

/* walk-geo-msg は walk-gauge カード内に配置。
   min-height で常に枠を予約することで、メッセージ有無による全体レイアウト
   シフトを完全に防ぐ。空のときは何も見せず透明枠だけ確保。 */
.walk-geo-msg {
  margin: 14px 0 0;
  padding: 10px 14px;
  text-align: center; font-size: 0.84rem;
  border-radius: 12px;
  background: transparent;
  border: 1px dashed transparent;
  color: var(--text-secondary);
  min-height: 44px; /* 空でも常にこの高さを確保 */
  display: flex; align-items: center; justify-content: center;
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.walk-geo-msg:empty { /* 空のときは枠線も淡く */
  background: transparent;
  border-color: var(--border-primary);
  opacity: 0.45;
}
.walk-geo-msg:empty::before {
  content: '—';
  color: var(--text-secondary);
  font-size: 0.9rem;
}
.walk-geo-msg.is-show {
  background: rgba(0, 229, 255, 0.06);
  border: 1px solid rgba(0, 229, 255, 0.22);
  animation: walk-msg-in 0.25s ease-out;
}
@keyframes walk-msg-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ===== 累進制バンド表 ===== */
.walk-bracket {
  padding: 16px 18px;
  border-radius: 16px;
  border: 1px solid var(--border-primary);
  background: var(--bg-card);
}
.walk-bracket-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-weight: 800; font-size: 0.95rem; color: var(--text-primary); margin-bottom: 12px;
}
.walk-bracket-head i { color: var(--accent-cyan); }
.walk-bracket-formula {
  margin-left: auto; font-size: 0.72rem; font-weight: 700;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(0, 229, 255, 0.10); color: var(--accent-cyan);
  border: 1px solid rgba(0, 229, 255, 0.25);
}
.walk-bracket-rows { display: flex; flex-direction: column; gap: 8px; }
.walk-bracket-row {
  display: grid; grid-template-columns: 70px 1fr 80px; align-items: center; gap: 10px;
  font-size: 0.78rem; font-variant-numeric: tabular-nums;
}
.walk-bracket-range { color: var(--text-secondary); font-weight: 700; }
.walk-bracket-bar {
  position: relative; height: 8px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  overflow: hidden;
}
.walk-bracket-fill { height: 100%; border-radius: 999px; box-shadow: 0 0 6px currentColor; opacity: 0.92; }
.walk-bracket-rate { text-align: right; font-weight: 700; color: var(--text-primary); }
.walk-bracket-note {
  margin: 12px 0 0; padding-top: 12px;
  border-top: 1px dashed var(--border-primary);
  font-size: 0.76rem; line-height: 1.65; color: var(--text-secondary);
}
.walk-bracket-note strong { color: var(--text-primary); }

/* ===== プライバシー注意書き ===== */
.walk-privacy {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid var(--border-primary);
  background: rgba(0, 229, 255, 0.04);
  font-size: 0.78rem; color: var(--text-secondary); line-height: 1.65;
}
.walk-privacy i { color: var(--accent-cyan); margin-top: 2px; flex-shrink: 0; }
.walk-privacy strong { color: var(--text-primary); }

/* ===== ライトモード上書き ===== */
body.theme-light .walk-hero {
  border-color: rgba(102, 51, 255, 0.22);
  background:
    radial-gradient(120% 100% at 0% 0%, rgba(102, 51, 255, 0.08), transparent 55%),
    radial-gradient(120% 100% at 100% 100%, rgba(0, 229, 255, 0.10), transparent 55%),
    linear-gradient(135deg, #fbfcff, #f3f6ff);
  box-shadow: 0 8px 24px rgba(102, 51, 255, 0.08);
}
body.theme-light .walk-hero-glow { opacity: 0.45; }
body.theme-light .walk-gauge,
body.theme-light .walk-stat,
body.theme-light .walk-bracket { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04); }
body.theme-light .walk-gauge-bar { background: #eef2ff; }
body.theme-light .walk-bracket-bar { background: #eef2ff; }
body.theme-light .walk-stat-bar { background: #eef2ff; }
body.theme-light .walk-privacy { background: rgba(102, 51, 255, 0.04); }
/* 「移動した」ボタンはグラデ背景のうえ。ライトモードの body color: --text-primary
   !important が child span に効いて黒になる事故防止 (ボタン側の !important より
   body セレクタの方が詳細度が高いので、こちらで明示的に白を再宣言する)。 */
body.theme-light .walk-checkin-btn,
body.theme-light .walk-checkin-btn * { color: #fff !important; }

/* ===== モバイル (< 480px) で文字サイズ調整 ===== */
@media (max-width: 480px) {
  .walk-hero { padding: 16px 14px; }
  .walk-hero-icon { width: 38px; height: 38px; font-size: 1.15rem; border-radius: 12px; }
  .walk-hero-head { gap: 10px; }
  .walk-hero-title { font-size: 1.1rem; }
  .walk-hero-sub { font-size: 0.8rem; line-height: 1.55; }
  .walk-gauge-value { font-size: 2rem; }
  .walk-stat-v { font-size: 1.6rem; }
  .walk-bracket-row { grid-template-columns: 60px 1fr 70px; gap: 8px; font-size: 0.72rem; }
  .walk-bracket-formula { font-size: 0.66rem; padding: 2px 7px; }
}

/* ===== 通知: グループのアバタースタック (X 風) ===== */
.notif-actor-stack { display:flex; flex-direction:row; }
.notif-actor-stack .avatar { margin-left:-10px; border:2px solid var(--bg-primary); box-shadow:0 0 0 1px var(--border-primary); }
.notif-actor-stack .avatar:first-child { margin-left:0; }

/* ==========================================================
 * Admin pages (PHP admin/* と互換のフル機能 UI)
 * ========================================================== */

.admin-page { padding: 0 var(--space-4) var(--space-6); }

.admin-section-title {
  font-size: 1.05rem; margin: var(--space-4) 0 var(--space-2);
  color: var(--text-primary); display: flex; align-items: center; gap: 10px;
}
.admin-section-title i { color: var(--accent-cyan); }

.admin-section {
  background: var(--bg-card); border: 1px solid var(--border-primary);
  border-radius: 14px; padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}
.admin-section h2 {
  margin: 0 0 var(--space-3); font-size: 1rem; color: var(--text-primary);
  display: flex; align-items: center; gap: 10px;
}
.admin-section h2 i { color: var(--accent-cyan); }
.admin-subhead { font-size: 0.9rem; color: var(--text-secondary); margin: var(--space-3) 0 var(--space-1); }

.admin-stat-card--active { border-color: var(--accent-cyan); }

.admin-nav-bar {
  display: flex; gap: 8px; flex-wrap: wrap; padding: var(--space-2) 0 var(--space-3);
  border-bottom: 1px solid var(--border-primary); margin-bottom: var(--space-3);
}
.admin-nav-bar .admin-nav-link {
  padding: 6px 12px; border: 1px solid var(--border-primary); border-radius: 999px;
  color: var(--text-secondary); text-decoration: none; font-size: 0.82rem;
  display: inline-flex; align-items: center; gap: 6px;
}
.admin-nav-bar .admin-nav-link:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }

.admin-flash {
  padding: 10px 14px; border-radius: 10px; margin-bottom: var(--space-3);
  font-size: 0.88rem;
}
.admin-flash--ok { background: rgba(0,255,157,0.1); border: 1px solid var(--accent-mint); color: var(--accent-mint); }
.admin-flash--err { background: rgba(255,77,109,0.1); border: 1px solid var(--accent-pink); color: var(--accent-pink); }

.admin-filter-tabs { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: var(--space-3); }
.admin-filter-tab {
  padding: 6px 14px; border: 1px solid var(--border-primary); border-radius: 999px;
  color: var(--text-secondary); text-decoration: none; font-size: 0.84rem;
}
.admin-filter-tab.is-active {
  background: linear-gradient(135deg, var(--accent-purple), var(--accent-cyan));
  color: #fff; border-color: transparent;
}
.admin-spacer { flex: 1 1 auto; }
.admin-allread-form { margin-left: auto; }

.admin-card-list { display: flex; flex-direction: column; gap: 12px; }
.admin-card {
  background: var(--bg-card); border: 1px solid var(--border-primary);
  border-radius: 12px; padding: var(--space-3);
}
.admin-card--pending { border-color: var(--accent-gold); }
.admin-card--reviewed { opacity: 0.85; }
.admin-card--approved { border-color: var(--accent-mint); }
.admin-card--rejected { border-color: var(--accent-pink); }
.admin-card--new { border-color: var(--accent-cyan); }
.admin-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.admin-card-meta { font-size: 0.86rem; color: var(--text-secondary); margin-bottom: 10px; display: grid; gap: 4px; }
.admin-card-meta b { color: var(--text-primary); font-weight: 600; }
.admin-card-detail { font-size: 0.88rem; margin: 8px 0; }
.admin-card-resolved { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-primary); }
.admin-quote {
  background: var(--bg-hover); border-left: 3px solid var(--accent-cyan);
  margin: 8px 0; padding: 8px 12px; font-size: 0.88rem; color: var(--text-primary);
  white-space: pre-wrap;
}

.admin-pill {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  font-size: 0.74rem; font-weight: 600; margin-left: 6px;
}
.admin-pill--warn { background: rgba(255,215,0,0.12); color: var(--accent-gold); border: 1px solid var(--accent-gold); }
.admin-pill--ok { background: rgba(0,255,157,0.12); color: var(--accent-mint); border: 1px solid var(--accent-mint); }
.admin-pill--err { background: rgba(255,77,109,0.12); color: var(--accent-pink); border: 1px solid var(--accent-pink); }
.admin-pill--urgent { background: var(--accent-pink); color: #fff; }
.admin-pill--reason { background: rgba(124,77,255,0.15); color: var(--accent-purple); border: 1px solid var(--accent-purple); }
.admin-pill--cat { background: var(--bg-hover); color: var(--text-secondary); border: 1px solid var(--border-primary); }
.admin-pill--auto { background: rgba(255,138,0,0.15); color: #ff8a00; border: 1px solid #ff8a00; }

.admin-decision-form {
  display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap;
}
.admin-decision-form--vertical { flex-direction: column; align-items: stretch; }
.admin-decision-form select, .admin-decision-form textarea {
  background: var(--bg-input); border: 1px solid var(--border-primary); border-radius: 8px;
  color: var(--text-primary); padding: 6px 10px; font-size: 0.9rem; font-family: inherit;
}
.admin-decision-form textarea { min-height: 60px; resize: vertical; }
.admin-decision-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.admin-btn--ok { background: linear-gradient(135deg, var(--accent-mint), var(--accent-cyan)); color: #fff; border-color: transparent; }
.admin-btn--danger { background: rgba(255,77,109,0.12); border-color: var(--accent-pink); color: var(--accent-pink); }
.admin-btn--danger:hover { background: var(--accent-pink); color: #fff; }
.admin-btn--ghost { background: transparent; }

.admin-search-bar {
  display: flex; gap: 8px; align-items: center; margin-bottom: var(--space-3); flex-wrap: wrap;
}
.admin-search-bar input[type=text], .admin-search-bar input[type=search] {
  background: var(--bg-input); border: 1px solid var(--border-primary); border-radius: 8px;
  color: var(--text-primary); padding: 6px 12px; font-size: 0.9rem; flex: 1 1 240px;
}

.admin-profile-top { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.admin-avatar { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.admin-avatar--placeholder {
  background: linear-gradient(135deg, var(--accent-purple), var(--accent-cyan));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 1.6rem;
}
.admin-kv {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 4px 16px; font-size: 0.86rem; color: var(--text-secondary);
}
.admin-kv b { color: var(--text-primary); font-weight: 600; margin-right: 6px; }
.admin-bio { margin-top: 8px; padding: 8px 12px; background: var(--bg-hover); border-radius: 8px; }

.admin-restriction-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 8px; margin-bottom: var(--space-3);
}
.admin-restriction-item {
  display: flex; gap: 10px; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--border-primary); border-radius: 10px;
  background: var(--bg-card);
}
.admin-restriction-item:hover { border-color: var(--accent-cyan); }
.admin-restriction-item input { margin-top: 3px; }
.admin-restriction-item strong { display: block; color: var(--text-primary); font-size: 0.88rem; }
.admin-restriction-item small { color: var(--text-muted); font-size: 0.78rem; }

.admin-attachments { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.admin-attachments img { max-width: 120px; max-height: 120px; border-radius: 8px; border: 1px solid var(--border-primary); }

.admin-form { display: flex; flex-direction: column; gap: 12px; }
.admin-field { display: flex; flex-direction: column; gap: 4px; }
.admin-field > span { font-size: 0.84rem; color: var(--text-secondary); }
.admin-field input, .admin-field textarea {
  background: var(--bg-input); border: 1px solid var(--border-primary); border-radius: 8px;
  color: var(--text-primary); padding: 8px 12px; font-size: 0.92rem; font-family: inherit;
}

.admin-table--compact th, .admin-table--compact td { padding: 4px 8px; font-size: 0.82rem; }

/* ==========================================================
 * Admin users page (PHP admin/users.php 互換)
 * ========================================================== */
.au-list { display: flex; flex-direction: column; gap: 10px; }
.au-group { display: flex; flex-direction: column; gap: 6px; }
.au-item {
  background: var(--bg-card); border: 1px solid var(--border-primary);
  border-radius: 10px; padding: 14px;
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
}
.au-item--suspended { border-color: var(--accent-pink); background: rgba(255,77,109,0.04); }
.au-item--restricted { border-color: #ffa500; background: rgba(255,165,0,0.04); }
.au-item--flagged { border-color: var(--accent-gold); background: rgba(255,215,0,0.03); }

.au-avatar {
  width: 48px; height: 48px; border-radius: 50%;
  flex-shrink: 0; object-fit: cover;
}
.au-avatar--placeholder {
  background: linear-gradient(135deg, var(--accent-purple), var(--accent-cyan));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 1.2rem;
}
.au-main { flex: 1; min-width: 220px; }
.au-name { color: var(--text-primary); font-weight: 700; font-size: 1rem; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.au-handle { font-size: 0.85rem; }
.au-meta { display: flex; gap: 10px; font-size: 0.8rem; margin-top: 4px; flex-wrap: wrap; align-items: center; }

.au-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.au-actions form { margin: 0; }
.au-actions .admin-btn { font-size: 0.78rem; }
.copied { background: var(--accent-mint) !important; color: #051a10 !important; border-color: var(--accent-mint) !important; }

.au-toggles { display: flex; flex-wrap: wrap; gap: 8px; margin-left: 30px; }
.au-toggle {
  align-self: flex-start; padding: 4px 12px;
  background: transparent; border: 1px dashed var(--border-primary);
  color: var(--text-secondary); border-radius: 999px;
  font-size: 0.78rem; cursor: pointer;
}
.au-toggle:hover { color: var(--accent-cyan); border-color: var(--accent-cyan); }
.au-toggle-suspect { border-color: #ffa500; color: #ffa500; }
.au-toggle-suspect:hover { color: #fff; background: #ffa500; }

.au-children {
  position: relative; margin-left: 30px; padding-left: 18px;
  display: flex; flex-direction: column; gap: 6px;
}
.au-children.collapsed { display: none; }
.au-item--child { position: relative; }
.au-item--child::before {
  content: ''; position: absolute; left: -20px; top: 50%;
  width: 18px; height: 2px; background: var(--border-primary);
}
.au-item--child::after {
  content: ''; position: absolute; left: -20px; top: -3px;
  width: 2px; height: calc(100% + 6px); background: var(--border-primary);
}
.au-item--child:last-child::after { height: calc(50% + 3px); }
.au-children:has(+ .au-children) .au-item--child:last-child::after { height: calc(100% + 6px); }
.au-children-suspect .au-item--child::before,
.au-children-suspect .au-item--child::after { background: #ffa500; }

.au-suspect-email-group { margin: 4px 0; }
.au-suspect-email-group > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.85rem; color: #ffa500;
  padding: 4px 10px; margin: 4px 0 4px 8px;
  border: 1px solid rgba(255,165,0,0.35); border-radius: 999px;
  background: rgba(255,165,0,0.08);
}
.au-suspect-email-group > summary::-webkit-details-marker { display: none; }
.au-suspect-email-group > summary::after {
  content: "\f078"; font-family: "Font Awesome 6 Free"; font-weight: 900;
  font-size: 10px; margin-left: 4px;
}
.au-suspect-email-group[open] > summary::after { content: "\f077"; }
.au-suspect-email-group > summary:hover { background: rgba(255,165,0,0.18); }

/* ==========================================================
 * Admin pages: 両サイドバー (col-nav / col-aside) を隠して
 * col-main をフル幅にする。CSS :has() で .admin-page 検出。
 * ========================================================== */
.layout-3col:has(.admin-page) {
  grid-template-columns: 1fr;
  max-width: 100%;
}
.layout-3col:has(.admin-page) .col-nav,
.layout-3col:has(.admin-page) .col-aside { display: none; }
.layout-3col:has(.admin-page) .col-main { border-right: none; }
.layout-3col:has(.admin-page) .admin-page { max-width: 1200px; margin: 0 auto; padding: var(--space-4); }

/* ==========================================================
 * Admin pages: 全ページで完全に同じ見た目を強制する
 * (header / nav / sections / cards / tables / 入力欄)
 * ========================================================== */

/* ページ全体の枠: 1200px センタリング + 共通パディング */
.layout-3col:has(.admin-page) .col-main { background: transparent; }
.admin-page {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--space-3) var(--space-4) var(--space-6);
}

/* ヘッダー: 全 admin ページで同じ間隔・borders */
.layout-3col:has(.admin-page) .col-main-header {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--space-3) var(--space-4) var(--space-2);
  border-bottom: 1px solid var(--border-primary);
  background: transparent;
  position: sticky;
  top: 0;
  z-index: 10;
  backdrop-filter: blur(10px);
}
.layout-3col:has(.admin-page) .col-main-header h1 {
  margin: 0; font-size: 1.25rem; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.layout-3col:has(.admin-page) .col-main-header h1 i { color: var(--accent-cyan); }

/* 共通ナビゲーション (admin_nav.html) — admin-page 内の最初の要素 */
.admin-nav-bar {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 0 0 var(--space-3);
  padding: var(--space-2);
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
}

/* admin-card / admin-table / admin-section / admin-stat-card のサイズ感を統一 */
.admin-section {
  background: var(--bg-card); border: 1px solid var(--border-primary);
  border-radius: 12px; padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}
.admin-stats { margin-bottom: var(--space-3); gap: 10px; }
.admin-card-list { margin-bottom: var(--space-3); }
.admin-table { width: 100%; margin: 0 0 var(--space-3); }

/* admin_users の au-* item を admin-card と視覚的に揃える */
.au-item {
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
  padding: var(--space-3);
}

/* 検索バー / フィルタタブの位置を統一 */
.admin-search-bar { margin-bottom: var(--space-3); }
.admin-filter-tabs { margin-bottom: var(--space-3); }

/* 全 admin ページのフォーム入力欄を統一 */
.admin-page input[type=text],
.admin-page input[type=search],
.admin-page input[type=number],
.admin-page input[type=email],
.admin-page select,
.admin-page textarea {
  background: var(--bg-input);
  border: 1px solid var(--border-primary);
  border-radius: 8px;
  color: var(--text-primary);
  padding: 7px 12px;
  font-size: 0.9rem;
  font-family: inherit;
}
.admin-page input:focus, .admin-page select:focus, .admin-page textarea:focus {
  outline: none; border-color: var(--accent-cyan);
}

/* モバイル: admin-nav-bar を横スクロール可能に */
@media (max-width: 767px) {
  .admin-nav-bar {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
  }
  .admin-nav-bar .admin-nav-link { flex-shrink: 0; }
  .admin-page { padding: var(--space-2) var(--space-3) var(--space-5); }
}

/* ============================================================
 * §35  sidebar-account-popover を theme token / custom color 追従に
 * ============================================================
 * php-style.css §133 (ライトモード) と §131 (dark) は全部 rgba(124, 77, 255, X) の
 * ハードコード紫で書かれていて、user-colors.js で accent を pink/green 等に変えても
 * popover だけ紫のままだった。ここで全 hardcoded を CSS variable に置換する。
 *
 * specificity 0-2-1 (body[class][class] .x) で php-style.css の 0-2-0 (body.theme-light .x)
 * を超えるので !important 連発を避けつつ確実に勝てる (user-colors.js と同じパターン)。
 */
body[class][class] .sidebar-account-popover {
  background: color-mix(in srgb, var(--bg-card), black 4%);
  border: 1px solid color-mix(in srgb, var(--accent-purple) 28%, var(--border-primary));
}
body[class][class] .sidebar-account-popover .popover-current-account {
  background: color-mix(in srgb, var(--bg-card), var(--accent-purple) 8%);
}
body[class][class] .sidebar-account-popover .popover-other-account:hover {
  background: color-mix(in srgb, var(--bg-card), var(--accent-cyan) 10%);
}
body[class][class] .sidebar-account-popover .popover-action:hover {
  background: color-mix(in srgb, var(--bg-card), var(--accent-purple) 10%);
}
body[class][class] .sidebar-account-popover .popover-action i {
  color: var(--accent-cyan);
}
body[class][class] .sidebar-account-popover .popover-current-mark {
  color: var(--accent-cyan);
}
body[class][class] .sidebar-account-popover .popover-divider {
  background: var(--border-primary);
}
body[class][class] .sidebar-account-popover .popover-avatar-placeholder {
  background: var(--gradient-primary);
}

/* ライトモード時の追加調整: 「現在のアカウント」行の左ボーダを accent に追従 */
body[class][class].theme-light .sidebar-account-popover {
  background: color-mix(in srgb, var(--bg-card), white 6%);
  border: 1px solid color-mix(in srgb, var(--accent-purple) 20%, transparent);
  box-shadow:
    0 12px 32px color-mix(in srgb, var(--accent-purple) 18%, transparent),
    0 4px 16px color-mix(in srgb, var(--accent-cyan) 10%, transparent);
}
body[class][class].theme-light .sidebar-account-popover .popover-current-account {
  background: color-mix(in srgb, var(--bg-card), var(--accent-purple) 6%);
  border-left: 3px solid var(--accent-purple);
}
body[class][class].theme-light .sidebar-account-popover .popover-other-account:hover,
body[class][class].theme-light .sidebar-account-popover .popover-action:not(.popover-action-danger):hover {
  background: color-mix(in srgb, var(--bg-card), var(--accent-purple) 10%);
  color: var(--accent-purple);
}
body[class][class].theme-light .sidebar-account-popover .popover-other-account:hover .popover-account-name,
body[class][class].theme-light .sidebar-account-popover .popover-other-account:hover .popover-account-handle,
body[class][class].theme-light .sidebar-account-popover .popover-other-account:hover i,
body[class][class].theme-light .sidebar-account-popover .popover-action:not(.popover-action-danger):hover i,
body[class][class].theme-light .sidebar-account-popover .popover-action:not(.popover-action-danger):hover span {
  color: var(--accent-purple);
}
/* 危険系 (ログアウト) は accent ではなく赤系のまま (役割の警告色は theme と独立) */

/* drawer-account-menu (モバイル) も同じ理由で hardcoded color の追従漏れを修正。
   現在行や hover bg は php-style.css の元仕様を尊重 (新しい強調を勝手に足さない)、
   ハードコードされてる cyan / 紫グラデだけ accent token に置換する。 */
body[class][class] .drawer-account-other:hover,
body[class][class] .drawer-account-other:active {
  background: color-mix(in srgb, var(--bg-card), var(--accent-cyan) 10%);
}
body[class][class] .drawer-account-other:hover .drawer-switch-icon,
body[class][class] .drawer-account-other:active .drawer-switch-icon {
  color: var(--accent-cyan);
}
body[class][class] .drawer-current-mark {
  color: var(--accent-cyan);
}
body[class][class] .drawer-avatar-placeholder {
  background: var(--gradient-primary);
}

/* ==========================================================
 * /settings/dm — 通話音のプリセット選択カード
 * ========================================================== */
.dm-cfg-section { margin-top: 18px; }
.dm-cfg-section:first-of-type { margin-top: 0; }
.dm-cfg-section-title {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 0.92rem;
  color: var(--text-primary);
  margin-bottom: 10px;
}
.dm-cfg-section-title > i { color: var(--accent-cyan); }
.dm-cfg-section-title #dmCfgVolumeLabel,
.dm-cfg-section-title .muted { font-weight: 400; }

.dm-cfg-presets {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}

.dm-cfg-preset {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
  color: var(--text-primary);
  text-align: left;
  font-family: inherit;
  font-size: 0.88rem;
  cursor: pointer;
  position: relative;
  transition: border-color 0.15s, background 0.15s, transform 0.05s;
  -webkit-tap-highlight-color: transparent;
}
.dm-cfg-preset:hover { border-color: var(--accent-cyan); background: var(--bg-card-hover, rgba(255,255,255,0.03)); }
.dm-cfg-preset:active { transform: scale(0.985); }
.dm-cfg-preset > i:first-child {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 10px;
  background: rgba(255,255,255,0.05);
  color: var(--text-secondary);
  font-size: 1rem;
  flex-shrink: 0;
}
.dm-cfg-preset-body { flex: 1; min-width: 0; }
.dm-cfg-preset-name {
  font-weight: 700; line-height: 1.2;
  color: var(--text-primary);
}
.dm-cfg-preset-desc {
  font-size: 0.74rem;
  color: var(--text-secondary);
  margin-top: 2px;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dm-cfg-preset-check {
  margin-left: auto;
  font-size: 0.86rem;
  color: var(--accent-cyan);
  opacity: 0;
  transition: opacity 0.15s, transform 0.15s;
  transform: scale(0.6);
}

.dm-cfg-preset.is-active {
  border-color: var(--accent-cyan);
  background: linear-gradient(135deg, rgba(0,229,255,0.08), rgba(124,77,255,0.04));
  box-shadow: 0 0 0 1px rgba(0,229,255,0.25), 0 2px 12px rgba(0,229,255,0.08);
}
.dm-cfg-preset.is-active > i:first-child {
  background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple));
  color: #fff;
}
.dm-cfg-preset.is-active .dm-cfg-preset-check {
  opacity: 1;
  transform: scale(1);
}

/* 音量スライダ */
.dm-cfg-volume {
  width: 100%;
  -webkit-appearance: none; appearance: none;
  height: 6px; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-cyan), var(--accent-purple));
  outline: none;
  margin-top: 2px;
}
.dm-cfg-volume::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff;
  cursor: pointer;
  box-shadow: 0 0 0 1px rgba(0,229,255,0.4), 0 2px 8px rgba(0,0,0,0.4);
}
.dm-cfg-volume::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff; border: none;
  cursor: pointer;
}

/* 試聴ボタン行 */
.dm-cfg-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border-primary);
}

/* === /settings/dm カスタム MP3 アップロード関連 === */
.dm-cfg-preset--empty {
  border-style: dashed;
}
.dm-cfg-preset--empty > i:first-child {
  background: rgba(255,255,255,0.03);
  color: var(--accent-cyan);
}
.dm-cfg-preset--empty .dm-cfg-preset-name {
  color: var(--text-secondary);
}
.dm-cfg-custom-controls {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
}

/* ============================================================
 * Pull-to-Refresh: user-colors (Misskey 風カスタムカラー) 対応
 *
 * php-style.css の PtR スタイル (§142.5) はハードコード rgba (cyan
 * 0,229,255 / purple 124,77,255 / 紺 7,9,22) を使っているため、
 * user-colors で primary / accent / bg を変えても反映されない。
 * ここでは CTA ボタン (var(--gradient-primary)) と同じカラー系に
 * 統一して、user-colors の primary / primaryEnd 指定でボタンと
 * 同時に色変えできるようにする。
 *
 * specificity は同等で source order 後勝ち (v2.css は php-style.css
 * の後に読み込まれる)。box-shadow / border のアルファは color-mix で
 * accent-cyan のユーザ指定を反映。
 *
 * 外側の .pull-refresh 80px バーは透明化 (背景 + blur + 下線を全部消す)。
 * mobile-header の下に dark band が残って見えるのを撤去し、引き下げ時は
 * 中央のピル (.pull-refresh-inner) だけがフロートで降りてくる見た目に。
 * 元 PHP では blur 紺帯が前提だったが v2 では「ピルだけ」演出に統一。 */
.pull-refresh {
  background: transparent !important;
  background-image: none !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  border-bottom: none !important;
}
.pull-refresh-ready {
  color: var(--accent-cyan);
}
.pull-refresh-ready .pull-refresh-inner {
  background: var(--gradient-primary);
  color: #fff;
  border-color: color-mix(in srgb, var(--accent-cyan) 55%, transparent);
  box-shadow:
    0 0 24px color-mix(in srgb, var(--accent-cyan) 30%, transparent),
    0 4px 12px rgba(0, 0, 0, 0.30);
}
.pull-refresh-refreshing .pull-refresh-inner {
  background: var(--gradient-primary);
  color: #fff;
  border-color: color-mix(in srgb, var(--accent-cyan) 65%, transparent);
  box-shadow:
    0 0 32px color-mix(in srgb, var(--accent-cyan) 45%, transparent),
    0 6px 16px rgba(0, 0, 0, 0.35);
}
.pull-refresh-toast-inner {
  background: var(--gradient-primary);
  box-shadow:
    0 8px 24px color-mix(in srgb, var(--accent-cyan) 35%, transparent),
    0 4px 12px rgba(0, 0, 0, 0.25);
}
/* light テーマ追従 (php-style.css L12700- の override を上書き) */
body.theme-light .pull-refresh {
  background: transparent !important;
  background-image: none !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  border-bottom: none !important;
}
body.theme-light .pull-refresh-ready {
  color: var(--accent-purple);
}
/* light モードでも pill は常にグラデ + 白文字 (PHP の dark と同じ視認性に揃える)。
 * 旧実装は ready/refreshing のみグラデ → idle (「↓ 下に引いて更新」状態) で
 * 文字色が text-primary (黒) を継承して白背景ピル上で見づらかった。 */
body.theme-light .pull-refresh-inner,
body.theme-light .pull-refresh-ready .pull-refresh-inner,
body.theme-light .pull-refresh-refreshing .pull-refresh-inner,
body.theme-light .pull-refresh-toast-inner {
  background: var(--gradient-primary) !important;
  color: #fff !important;
  border-color: transparent !important;
}
body.theme-light .pull-refresh-inner .pull-refresh-text,
body.theme-light .pull-refresh-inner .pull-refresh-spinner {
  color: #fff !important;
  border-color: #fff transparent #fff #fff !important;
}

/* ============================================================
 * §36 通知 ON 案内バナー (push-nudge.js)
 *
 * アクセス 7 回ごとに画面下から滑り込むスナックバー。
 * bottom-nav が出るモバイル幅では bottom-nav の上に、PC では右下に。
 * ============================================================ */
.mp-push-nudge {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 78px); /* bottom-nav 上 */
  z-index: 220;
  /* 旧 var(--bg-card) は半透明 (rgba(13,19,48,0.55)) で TL が透けて見えていた。
     不透明な base + backdrop-filter で「綺麗に被せる」表示にする。 */
  background: #0b1228;
  border: 1px solid var(--border-primary);
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transform: translateY(140%);
  opacity: 0;
  transition: transform 0.32s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.32s;
}
body.theme-light .mp-push-nudge {
  background: #ffffff;
  box-shadow: 0 18px 44px rgba(60, 100, 180, 0.22), 0 2px 6px rgba(40, 60, 120, 0.10);
  border-color: rgba(40, 60, 120, 0.12);
}
.mp-push-nudge--in  { transform: translateY(0); opacity: 1; }
.mp-push-nudge--out { transform: translateY(140%); opacity: 0; }
.mp-push-nudge-body {
  display: flex; align-items: center; gap: 12px;
}
.mp-push-nudge-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(124, 77, 255, 0.15);
  color: var(--accent-purple);
  font-size: 1.05rem;
  flex-shrink: 0;
}
.mp-push-nudge-text {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.mp-push-nudge-text strong { font-size: 0.95rem; font-weight: 700; }
.mp-push-nudge-text span   { font-size: 0.82rem; color: var(--text-muted); }
.mp-push-nudge-actions {
  display: flex; gap: 8px; justify-content: flex-end;
}
.mp-push-nudge-btn {
  appearance: none;
  border: 1px solid transparent;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 0.88rem;
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
  line-height: 1.2;
}
.mp-push-nudge-btn--primary {
  background: var(--accent-purple);
  color: #fff;
}
.mp-push-nudge-btn--primary:hover { filter: brightness(1.08); }
.mp-push-nudge-btn--ghost {
  background: transparent;
  color: var(--text-primary);
  border-color: var(--border-primary);
}
.mp-push-nudge-btn--ghost:hover { background: var(--bg-hover); }

/* PC (bottom-nav 無し) では右下に小さく */
@media (min-width: 768px) {
  .mp-push-nudge {
    left: auto;
    right: 24px;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 24px);
    max-width: 380px;
  }
}

/* ============================================================
 * §post-button (mobile header 右上の投稿 + ボタン) 視覚調整
 *
 * php-style.css :5393 の base スタイル (36×36 円 / font-size: 1.25rem /
 * font-weight: 700) を v2 側で上書き:
 *   - font-weight 400 → "+" を細くする
 *   - 大きさ補填 (1.4rem)
 *   - line-height 1 + padding-bottom 1px で光学センタリング
 *     ("+" グリフは em-box 上部寄りに描画される font が多く、
 *      flex の geometric center だと下に空きが見える)
 * ============================================================ */
.mobile-header-content .post-button {
  font-weight: 400;
  font-size: 1.4rem;
  line-height: 1;
  padding-bottom: 1px;
}

/* ============================================================
 * §37 森岡証券 (shoken) — kotoba_bank?tab=securities + /shoken/{code}
 * 既存 §28 .wb-* のトークン (var(--accent-*)) を流用してテーマ追従。
 * 「上昇」「下落」は currentColor + 親要素のクラス .up / .down で
 * 緑/赤を渡し、SVG polyline もそのまま吸う設計。
 * ============================================================ */

/* === 一覧 (kotoba_bank の tab=securities ブロック) === */
.sh-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
.sh-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 14px 10px;
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
  text-decoration: none;
  color: var(--text-primary);
  transition: transform 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.sh-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent-purple);
  box-shadow: 0 6px 16px rgba(124, 77, 255, 0.18);
}
/* 株価カード: 上昇=緑 / 下落=ピンク。ライトモードで広域 color 上書きに負けて
   currentColor が text-primary (濃紺) になってしまっていたので !important + 明示で
   テーマ問わず色が出るようにする。spark SVG は stroke="currentColor"。 */
.sh-card.up   { color: var(--accent-green) !important; }
.sh-card.down { color: var(--accent-pink)  !important; }
.sh-card.up   .sh-change,
.sh-card.up   .sh-spark  { color: var(--accent-green) !important; }
.sh-card.down .sh-change,
.sh-card.down .sh-spark  { color: var(--accent-pink)  !important; }
.sh-card.up   .sh-spark polyline { stroke: var(--accent-green) !important; }
.sh-card.down .sh-spark polyline { stroke: var(--accent-pink)  !important; }
body.theme-light .sh-card.up   .sh-change,
body.theme-light .sh-card.up   .sh-spark polyline { color: #00a36a !important; stroke: #00a36a !important; }
body.theme-light .sh-card.down .sh-change,
body.theme-light .sh-card.down .sh-spark polyline { color: #d6195a !important; stroke: #d6195a !important; }
.sh-card-head {
  display: flex; align-items: baseline; gap: 8px;
  color: var(--text-primary);
}
.sh-card .sh-name { font-weight: 700; font-size: 1rem; }
.sh-card .sh-code { font-size: 0.75rem; color: var(--text-muted); letter-spacing: 0.04em; }
.sh-card .sh-sector { color: var(--text-muted); font-size: 0.78rem; }
.sh-card .sh-price {
  color: var(--text-primary);
  font-weight: 800;
  font-size: 1.4rem;
  margin-top: 4px;
}
.sh-card .sh-price small { font-size: 0.7em; font-weight: 600; color: var(--text-muted); margin-left: 2px; }
.sh-card .sh-change {
  font-weight: 700;
  font-size: 0.88rem;
  /* 親 .sh-card.up / .down が currentColor で緑赤を渡す */
}
.sh-spark {
  width: 100%;
  height: 36px;
  margin-top: 2px;
  display: block;
  opacity: 0.85;
}

/* === 保有銘柄 / 売買ログ テーブル (共通) === */
.sh-holdings, .sh-trades {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 18px;
  font-size: 0.88rem;
}
.sh-holdings th, .sh-trades th,
.sh-holdings td, .sh-trades td {
  padding: 8px 10px;
  text-align: left;
  border-bottom: 1px solid var(--border-primary);
}
.sh-holdings th, .sh-trades th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.8rem;
  background: rgba(255,255,255,0.02);
}
.sh-holdings td a, .sh-trades td a {
  color: var(--accent-cyan);
  text-decoration: none;
}
.sh-holdings td a:hover, .sh-trades td a:hover { text-decoration: underline; }
.sh-holdings td.pos, .sh-trades td.pos { color: var(--accent-green); font-weight: 700; }
.sh-holdings td.neg, .sh-trades td.neg { color: var(--accent-pink); font-weight: 700; }
.sh-trades tr.is-buy  td:nth-child(3) { color: var(--accent-pink); }
.sh-trades tr.is-sell td:nth-child(3) { color: var(--accent-green); }

/* === 詳細ページ (/shoken/{code}) === */
.sh-wrap { padding: 14px 16px 30px; max-width: 760px; margin: 0 auto; }

.sh-detail-head {
  display: flex; flex-direction: column; gap: 4px;
  padding: 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 14px;
  margin-bottom: 14px;
}
.sh-detail-head.up   { border-color: var(--accent-green); }
.sh-detail-head.down { border-color: var(--accent-pink); }
.sh-detail-name {
  font-size: 1.15rem; font-weight: 800;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.sh-detail-name .sh-code  { color: var(--text-muted); font-size: 0.85rem; letter-spacing: 0.05em; }
.sh-detail-name .sh-sector { color: var(--accent-cyan); font-size: 0.78rem; font-weight: 600; }
.sh-detail-price {
  font-size: 2.1rem; font-weight: 900;
  margin-top: 4px;
}
.sh-detail-price small { font-size: 0.5em; font-weight: 600; color: var(--text-muted); margin-left: 4px; }
.sh-detail-change {
  font-size: 1rem; font-weight: 700;
  display: flex; align-items: baseline; gap: 12px;
}
.sh-detail-head.up   .sh-detail-change { color: var(--accent-green); }
.sh-detail-head.down .sh-detail-change { color: var(--accent-pink); }
.sh-detail-change small { font-weight: 500; }

.sh-chart-wrap {
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 14px;
  padding: 12px;
  margin-bottom: 14px;
  min-height: 140px;
  display: flex; align-items: center; justify-content: center;
}
.sh-chart-wrap.up   { color: var(--accent-green); }
.sh-chart-wrap.down { color: var(--accent-pink); }
.sh-chart { width: 100%; height: 120px; display: block; }
.sh-chart-empty { font-size: 0.9rem; padding: 30px 10px; text-align: center; }

.sh-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.sh-stat {
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
  padding: 10px 12px;
}
.sh-stat .l { font-size: 0.78rem; color: var(--text-muted); }
.sh-stat .v { font-size: 1.2rem; font-weight: 800; margin-top: 2px; }
.sh-stat .v small { font-size: 0.6em; font-weight: 600; color: var(--text-muted); margin-left: 2px; }
.sh-stat .s { font-size: 0.72rem; margin-top: 2px; }
.sh-stat.up   .v { color: var(--accent-green); }
.sh-stat.down .v { color: var(--accent-pink); }

.sh-trade-forms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.sh-trade-form {
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 14px;
  padding: 14px;
}
.sh-trade-form h3 {
  margin: 0 0 10px;
  font-size: 1rem;
  display: flex; align-items: center; gap: 8px;
}
.sh-trade-form.sh-buy  h3 { color: var(--accent-pink); }
.sh-trade-form.sh-sell h3 { color: var(--accent-green); }
.sh-trade-form label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 0.82rem; color: var(--text-muted);
}
.sh-trade-form input[type="number"] {
  background: var(--bg-input, rgba(255,255,255,0.04));
  border: 1px solid var(--border-primary);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--text-primary);
  font-size: 16px; /* iOS auto-zoom 抑止 */
  width: 100%;
  box-sizing: border-box;
}
.sh-cost-row {
  margin-top: 10px;
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 0.92rem;
}
.sh-cost-row strong { font-size: 1.05rem; }
.sh-buy-btn, .sh-sell-btn {
  width: 100%;
  margin-top: 10px;
  padding: 11px 14px;
  border: none;
  border-radius: 999px;
  font-weight: 800;
  font-size: 0.92rem;
  cursor: pointer;
  color: #fff;
}
.sh-buy-btn  { background: var(--accent-pink); }
.sh-sell-btn { background: var(--accent-green); }
.sh-buy-btn:hover, .sh-sell-btn:hover { filter: brightness(1.08); }
.sh-buy-btn:disabled, .sh-sell-btn:disabled {
  background: var(--border-primary);
  color: var(--text-muted);
  cursor: not-allowed;
}

.sh-other-list {
  display: flex; flex-direction: column; gap: 6px;
  margin-bottom: 18px;
}
.sh-other {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 10px;
  text-decoration: none;
  color: var(--text-primary);
  font-size: 0.9rem;
}
.sh-other:hover { border-color: var(--accent-purple); }
.sh-other-name { font-weight: 700; }
.sh-other-code { letter-spacing: 0.05em; }
.sh-other-price { margin-left: auto; font-weight: 700; color: var(--accent-cyan); }

/* flash の error バリアント (詳細ページで使う) */
.wb-flash.is-error {
  border-color: var(--accent-pink);
  color: var(--accent-pink);
  background: rgba(255, 77, 109, 0.06);
}

/* === ランキング (利益 / 損失 top 10) === */
.sh-rank-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}
.sh-rank-block {
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
  padding: 4px 12px 12px;
}
.sh-rank-block .wb-section-h {
  margin: 10px 0 8px;
  font-size: 0.92rem;
}
.sh-rank {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sh-rank li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 8px;
  font-size: 0.9rem;
  background: rgba(255,255,255,0.02);
}
.sh-rank-up    li:nth-child(1) { background: rgba(255, 215, 0, 0.10); }
.sh-rank-up    li:nth-child(2) { background: rgba(192, 192, 192, 0.10); }
.sh-rank-up    li:nth-child(3) { background: rgba(205, 127, 50, 0.10); }
.sh-rank-down  li:nth-child(1) { background: rgba(255, 77, 109, 0.10); }
.sh-rank-no {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center; justify-content: center;
  background: var(--border-primary);
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 800;
  flex-shrink: 0;
}
.sh-rank-up   li:nth-child(1) .sh-rank-no { background: rgba(255,215,0,0.7);  color: #1a1a1a; }
.sh-rank-up   li:nth-child(2) .sh-rank-no { background: rgba(192,192,192,0.7); color: #1a1a1a; }
.sh-rank-up   li:nth-child(3) .sh-rank-no { background: rgba(205,127,50,0.7);  color: #fff; }
.sh-rank-down li:nth-child(1) .sh-rank-no { background: var(--accent-pink);   color: #fff; }
.sh-rank-user {
  display: flex; align-items: center; gap: 8px;
  text-decoration: none;
  color: var(--text-primary);
  min-width: 0;
  flex: 1;
  overflow: hidden;
}
.sh-rank-user:hover .sh-rank-name { text-decoration: underline; }
.sh-rank-user .avatar { width: 28px; height: 28px; flex-shrink: 0; }
.sh-rank-name {
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sh-rank-pl {
  margin-left: auto;
  font-weight: 800;
  font-size: 0.92rem;
  flex-shrink: 0;
}
.sh-rank-pl.pos { color: var(--accent-green); }
.sh-rank-pl.neg { color: var(--accent-pink); }

/* ==========================================================
 * プレミアム設定ページ (settings_premium.html) — 整えたデザイン
 * ヒーロー + 特典グリッド + 残高&請求カード + アクション
 * ========================================================== */
.prem-wrap { display: flex; flex-direction: column; gap: 18px; padding-bottom: 24px; }

/* ===== ヒーロー (現在の状態) ===== */
.prem-hero {
  position: relative; overflow: hidden;
  padding: 22px 22px 20px; border-radius: 20px; color: #fff;
  background: linear-gradient(135deg, #6a3df0 0%, #5b54ea 45%, #2a7fc4 100%);
  box-shadow: 0 12px 28px rgba(106, 61, 240, 0.30);
}
.prem-hero.is-inactive {
  background: linear-gradient(135deg, #444d6e 0%, #3a4566 60%, #2c354f 100%);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25);
}
.prem-hero, .prem-hero * { color: #fff !important; }
.prem-hero-deco {
  position: absolute; right: -16px; top: -16px; font-size: 8rem;
  opacity: 0.10; pointer-events: none; line-height: 1;
}
.prem-hero-eyebrow {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 0.8rem; font-weight: 700;
  background: rgba(255,255,255,0.18);
  padding: 4px 12px; border-radius: 999px;
}
.prem-hero-eyebrow i { font-size: 0.78rem; }
.prem-hero-expiry { margin-top: 14px; display: flex; flex-direction: column; gap: 2px; }
.prem-hero-expiry .lbl { font-size: 0.78rem; opacity: 0.85; }
.prem-hero-expiry .val { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.01em; }
.prem-hero-expiry .val small { font-size: 0.95rem; font-weight: 700; opacity: 0.92; margin-left: 4px; }
.prem-hero-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.prem-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px; border-radius: 999px; font-size: 0.78rem; font-weight: 700;
  background: rgba(255,255,255,0.18); border: 1px solid rgba(255,255,255,0.28);
}
.prem-pill--on { background: rgba(0, 200, 150, 0.32); border-color: rgba(0, 200, 150, 0.55); }
.prem-pill--off { background: rgba(255, 180, 80, 0.28); border-color: rgba(255, 180, 80, 0.55); }
.prem-pill--cost { background: rgba(255,255,255,0.16); }

/* ===== セクション見出し ===== */
.prem-section-h {
  display: flex; align-items: center; gap: 9px;
  font-size: 0.92rem; font-weight: 800; color: var(--text-primary);
  margin: 4px 0 -6px; letter-spacing: 0.02em;
}
.prem-section-h i { color: var(--accent-cyan); font-size: 0.95rem; }

/* ===== 特典グリッド ===== */
.prem-perks {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 10px;
}
.prem-perk {
  display: flex; gap: 13px; align-items: flex-start;
  padding: 14px 15px; border-radius: 14px;
  background: var(--bg-card); border: 1px solid var(--border-primary);
  transition: transform 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.prem-perk:hover { transform: translateY(-2px); border-color: var(--accent-cyan); box-shadow: 0 6px 14px rgba(0,0,0,0.12); }
.prem-perk-ic {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center; font-size: 1.05rem;
  background: linear-gradient(135deg, rgba(124,77,255,0.18), rgba(0,229,255,0.18));
  color: var(--accent-purple);
}
.prem-perk-body { min-width: 0; flex: 1; }
.prem-perk-title { font-weight: 800; color: var(--text-primary); font-size: 0.92rem; line-height: 1.35; }
.prem-perk-desc { color: var(--text-secondary); font-size: 0.8rem; line-height: 1.55; margin-top: 3px; }
.prem-perk-desc b { color: var(--text-primary); font-weight: 800; }

/* ===== 残高 & 請求カード ===== */
.prem-bill {
  padding: 16px 17px; border-radius: 16px;
  background: var(--bg-card); border: 1px solid var(--border-primary);
  display: flex; flex-direction: column; gap: 12px;
}
.prem-bill.is-low { border-color: rgba(255, 77, 109, 0.45); background: rgba(255, 77, 109, 0.04); }
.prem-bill-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.prem-bill-stat {
  padding: 11px 13px; border-radius: 12px;
  background: linear-gradient(135deg, rgba(124,77,255,0.06), rgba(0,229,255,0.04));
  border: 1px solid var(--border-primary);
}
.prem-bill-stat .k { font-size: 0.74rem; color: var(--text-secondary); font-weight: 600; }
.prem-bill-stat .v {
  margin-top: 2px; font-size: 1.55rem; font-weight: 900; color: var(--text-primary);
  display: flex; align-items: baseline; gap: 3px; line-height: 1.05;
}
.prem-bill-stat .v small { font-size: 0.8rem; font-weight: 700; color: var(--text-secondary); }

.prem-progress {
  height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--bg-secondary, rgba(0, 0, 0, 0.08));
}
.prem-progress i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-purple), var(--accent-cyan));
  transition: width 0.45s ease;
}
.prem-bill.is-low .prem-progress i {
  background: linear-gradient(90deg, #ff7a8e, var(--accent-pink));
}
.prem-bill-note {
  display: flex; gap: 7px; align-items: flex-start;
  font-size: 0.8rem; line-height: 1.6; color: var(--text-secondary);
}
.prem-bill-note i { margin-top: 2px; flex-shrink: 0; color: var(--accent-cyan); }

/* ===== アクション ===== */
.prem-actions { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-top: 4px; }
.prem-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 13px 24px; border: none; border-radius: 999px; cursor: pointer;
  font-size: 0.95rem; font-weight: 800; transition: transform 0.12s, box-shadow 0.12s, filter 0.12s;
  min-width: 240px;
}
.prem-btn--primary {
  color: #fff;
  background: linear-gradient(135deg, #6a3df0, #2a7fc4);
  box-shadow: 0 6px 18px rgba(106, 61, 240, 0.30);
}
.prem-btn--primary:hover { transform: translateY(-1px); box-shadow: 0 9px 22px rgba(106, 61, 240, 0.40); }
.prem-btn--ghost {
  color: var(--text-primary);
  background: var(--bg-card); border: 1px solid var(--border-primary);
}
.prem-btn--ghost:hover { border-color: var(--accent-pink); color: var(--accent-pink); }
.prem-btn--disabled {
  color: var(--text-secondary);
  background: var(--bg-secondary, rgba(0,0,0,0.06)); cursor: not-allowed; opacity: 0.85;
}
.prem-actions-note {
  margin: 0; font-size: 0.78rem; color: var(--text-secondary); text-align: center; line-height: 1.6;
}
.prem-actions-note b { color: var(--text-primary); }

/* ==========================================================
 * 公式ユーザー (specialMark / adminMark) は premiumMark を非表示
 * 隣接兄弟セレクタは間のテキストノード (改行/空白) を跨ぐので、テンプレ側の
 * {{- 有無に依存せず全レンダリング箇所をまとめてカバーする。
 * ========================================================== */
.specialMark + .premiumMark,
.adminMark + .premiumMark { display: none !important; }

/* === TradingView 風チャート (/shoken/{code}) === */
.sh-tv-wrap {
  position: relative;
  background: #0d1118;
  border: 1px solid var(--border-primary);
  border-radius: 14px;
  padding: 12px 0 0 0;
  margin-bottom: 14px;
  overflow: hidden;
}
body.theme-light .sh-tv-wrap { background: #ffffff; }
.sh-tv-wrap.up   { border-color: rgba(34, 197, 133, 0.45); }
.sh-tv-wrap.down { border-color: rgba(255, 77, 109, 0.45); }
.sh-tv-header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding: 6px 16px 4px;
}
.sh-tv-symbol { font-size: 0.95rem; }
.sh-tv-symbol strong { font-size: 1.05rem; letter-spacing: 0.04em; }
.sh-tv-symbol .muted { margin-left: 6px; }
.sh-tv-price-row { display: flex; align-items: baseline; gap: 10px; }
.sh-tv-price { font-size: 1.8rem; font-weight: 900; }
.sh-tv-price small { font-size: 0.5em; font-weight: 600; color: var(--text-muted); margin-left: 2px; }
.sh-tv-change { font-size: 0.95rem; font-weight: 800; }
.sh-tv-change.pos { color: #22c585; }
.sh-tv-change.neg { color: #ff4d6d; }
.sh-tv-chart {
  width: 100%; height: 360px;
  margin-top: 2px;
}
.sh-tv-legend {
  position: absolute; top: 54px; right: 18px;
  pointer-events: none;
  background: rgba(13, 17, 24, 0.65);
  color: #cfd2d4;
  padding: 4px 10px; border-radius: 6px;
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  user-select: none;
}
body.theme-light .sh-tv-legend {
  background: rgba(255,255,255,0.85);
  color: #1a1a1a;
  border: 1px solid rgba(0,0,0,0.08);
}
.sh-tv-empty {
  height: 360px;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.sh-meta-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 4px 0 10px;
  font-size: 0.85rem;
}
.sh-meta-bar .sh-sector { color: var(--accent-cyan); font-weight: 700; }

/* === 森岡証券 レバ + オラクル UI === */
.sh-lev-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--accent-gold, #f5b800), var(--accent-pink, #ff4d6d));
  color: #fff;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.sh-lev-badge i { font-size: 0.65rem; }
.sh-lev-badge-small {
  margin-top: 4px;
  align-self: flex-start;
  font-size: 0.66rem;
  padding: 1px 6px;
}
.sh-oracle-note {
  margin-top: 6px;
  font-size: 0.74rem;
  color: var(--text-muted);
}
.sh-oracle-note i { color: var(--accent-cyan); margin-right: 4px; }
.sh-pl-preview.pos { color: var(--accent-green); }
.sh-pl-preview.neg { color: var(--accent-pink); }
.sh-fee-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(255, 184, 0, 0.15);
  color: var(--accent-gold);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ============================================================
 * §Cosmetic — 装飾アイテム (ハンドル色 + アバター額縁)
 *
 * ハンドル色は inline style="color:..." で適用。CSS なし。
 * アバター額縁はクラスで適用: .avatar-frame.avatar-frame-{key}
 * post_card / post_detail では <a class="author-link"> に当てる。
 * profile では <div class="profile-avatar-container avatar-frame-xl"> に。
 * ============================================================ */
.avatar-frame {
  display: inline-block;
  position: relative;
  border-radius: 50%;
  padding: 2px;
  background: var(--bg-card);
}
.avatar-frame > img.avatar,
.avatar-frame > .avatar {
  display: block;
  border-radius: 50%;
  background: var(--bg-card);
}
/* プロフィール用: .profile-avatar-container はバナーに重ねる absolute 配置。
   .avatar-frame の position:relative / display:inline-block が上書きすると、
   通常フローを占有してアクション/名前が大幅に下へ押し下げられる。
   profile に当たった時だけ元の absolute / block を維持する。 */
.profile-avatar-container.avatar-frame {
  position: absolute;
  display: block;
}
/* ゴールド枠 — 明るい金グラデのリング */
.avatar-frame-gold {
  background: linear-gradient(135deg, #fff5b3, #ffd700, #b8860b, #ffd700);
  box-shadow: 0 0 8px rgba(255, 215, 0, 0.45);
}
/* ネオン枠 — cyan ↔ purple の発光、ゆっくり回転 */
.avatar-frame-neon {
  background: conic-gradient(from 0deg, #00e5ff, #a78bfa, #00e5ff);
  box-shadow: 0 0 10px rgba(0, 229, 255, 0.4), 0 0 16px rgba(167, 139, 250, 0.35);
  animation: avatar-frame-neon-spin 6s linear infinite;
}
@keyframes avatar-frame-neon-spin {
  to { background: conic-gradient(from 360deg, #00e5ff, #a78bfa, #00e5ff); }
}
/* 桜枠 — ピンク〜淡ピンクのグラデ、柔らかな光彩 */
.avatar-frame-sakura {
  background: linear-gradient(135deg, #ffafd7, #ffe4f1, #ff90c6, #ffe4f1);
  box-shadow: 0 0 8px rgba(255, 175, 215, 0.5);
}
/* プロフィール用 (xl): 額縁を大きく */
.avatar-frame-xl { padding: 3px; }

/* === エフェクト枠 ===
 * 枠の外周から ::before / ::after で粒子や波動が出る。
 * .avatar-frame は position:relative なので、::before/::after は
 * absolute で枠の外側に展開できる。pointer-events:none でクリックを邪魔しない。 */

/* キラキラ枠: 2 pseudo に 5 個ずつ 計 10 個の星屑を glow blur 付きで散らし、
   別 timing で瞬かせる。各粒に box-shadow の blur (3-4px) を加えて
   それぞれが光ってる感じに。色は白 + ゴールド mix、サイズも 2-3px 混ぜる。 */
.avatar-frame-sparkle {
  background: linear-gradient(135deg, #ffe082, #ffd700);
  box-shadow: 0 0 8px rgba(255, 215, 0, 0.6);
}
/* グループ A: 白 3px の主粒 + glow + 4 個の追加粒 */
.avatar-frame-sparkle::before {
  content: '';
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: #fff;
  pointer-events: none;
  top: -8px; right: 6px;
  box-shadow:
    /* 自分自身に glow */
    0 0 4px 1px rgba(255,255,255,0.8),
    /* 周辺粒も blur 付きで配置 */
    -34px  18px 3px 0 #fff,
      0px  46px 3px 0 #fff,
    -42px  -2px 3px 0 #ffe082,
     12px -12px 3px 0 #fff;
  animation: avatar-frame-sparkle-twinkle 1.8s ease-in-out infinite;
}
/* グループ B: ゴールド 2px の主粒 + 4 個の追加粒 (0.9s 遅延) */
.avatar-frame-sparkle::after {
  content: '';
  position: absolute;
  width: 2px; height: 2px;
  border-radius: 50%;
  background: #ffd700;
  pointer-events: none;
  top: 8px; left: -6px;
  box-shadow:
    0 0 4px 1px rgba(255,215,0,0.9),
     56px  -8px 3px 0 #ffd700,
     42px  46px 3px 0 #ffd700,
     -4px  56px 3px 0 #ffe082,
     56px  22px 3px 0 #fff;
  animation: avatar-frame-sparkle-twinkle 1.8s ease-in-out infinite;
  animation-delay: 0.9s;
}
@keyframes avatar-frame-sparkle-twinkle {
  0%, 100% { opacity: 0.15; transform: scale(0.55); }
  45%, 55% { opacity: 1.0;  transform: scale(1.6); }
}

/* オーラ枠: 紫↔シアンの 多層 ripple + 枠本体の rainbow conic-gradient 回転。
   ::before / ::after は blur+spread 大の box-shadow で広く柔らかい波動。
   枠本体は conic-gradient を slowly 回転させて常時光ってる感じ。
   背景は transparent なのでアバター本体 (avatar) には被らない。 */
.avatar-frame-aura {
  background: conic-gradient(from 0deg, #a78bfa, #00e5ff, #c084fc, #00e5ff, #a78bfa);
  box-shadow: 0 0 12px rgba(167, 139, 250, 0.6),
              0 0 24px rgba(0, 229, 255, 0.35);
  animation: avatar-frame-aura-spin 4s linear infinite;
}
@keyframes avatar-frame-aura-spin {
  to { background: conic-gradient(from 360deg, #a78bfa, #00e5ff, #c084fc, #00e5ff, #a78bfa); }
}
.avatar-frame-aura::before,
.avatar-frame-aura::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background: transparent;
  animation: avatar-frame-aura-ripple 2.4s ease-out infinite;
}
.avatar-frame-aura::after { animation-delay: 1.2s; }
/* 3 層の box-shadow を spread + blur で同時に外向きに広げる: 紫 / シアン / 桃 */
@keyframes avatar-frame-aura-ripple {
  0%   {
    box-shadow:
      0 0  4px 0px  rgba(167,139,250,0.85),
      0 0  8px 0px  rgba(0,229,255,0.65),
      0 0 12px 0px  rgba(192,132,252,0.45);
    opacity: 1;
  }
  100% {
    box-shadow:
      0 0 14px 16px rgba(167,139,250,0),
      0 0 22px 22px rgba(0,229,255,0),
      0 0 32px 30px rgba(192,132,252,0);
    opacity: 0;
  }
}

/* 火花枠: 赤橙のグラデ枠 + 燃える glow から大きな火の粉が打ち上がって
   重力で落ちる。各粒子に blur:2 を加えて熱い光感、9 個ずつ × 2 グループ、
   別軌道 + 1.2s 遅延で常に火花が舞ってる。 */
.avatar-frame-spark {
  background: conic-gradient(from 0deg, #ff6f3c, #ffae42, #ff8c00, #ff4500, #ff6f3c);
  box-shadow:
    0 0 10px rgba(255, 100, 30, 0.7),
    0 0 20px rgba(255, 140, 0, 0.4);
}
.avatar-frame-spark::before,
.avatar-frame-spark::after {
  content: '';
  position: absolute;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: transparent;
  pointer-events: none;
  top: 50%; left: 50%;
  margin: -2px 0 0 -2px;
}
.avatar-frame-spark::before {
  animation: avatar-frame-spark-arc-a 2.4s ease-out infinite;
}
.avatar-frame-spark::after {
  animation: avatar-frame-spark-arc-b 2.4s ease-out infinite 1.2s;
}
/* グループ A: 右半円 + 中央上方向に打ち上げ → 重力で右下に落下。
   各 box-shadow に blur:2px を加えて発光した火の粉感に。 */
@keyframes avatar-frame-spark-arc-a {
  0% {
    box-shadow:
       14px -12px 2px 1 #ff6f3c,
       24px  -4px 2px 1 #ffae42,
       30px   8px 2px 1 #ff8c00,
       18px  14px 2px 1 #ffae42,
        4px -24px 2px 1 #ff6f3c,
       -8px -18px 2px 1 #ffae42,
       10px -32px 2px 1 #ff8c00,
       36px   0px 2px 1 #ff4500,
       -2px -36px 2px 1 #ffd54f;
    opacity: 1;
  }
  30% {
    box-shadow:
       26px -34px 2px 1 #ff6f3c,
       40px -22px 2px 1 #ffae42,
       48px  -6px 2px 1 #ff8c00,
       34px   8px 2px 1 #ffae42,
       10px -52px 2px 1 #ff6f3c,
       -6px -46px 2px 1 #ffae42,
       22px -64px 2px 1 #ff8c00,
       58px -16px 2px 1 #ff4500,
       -4px -58px 2px 1 #ffd54f;
    opacity: 0.95;
  }
  100% {
    box-shadow:
       46px  64px 2px 1 transparent,
       62px  68px 2px 1 transparent,
       68px  72px 2px 1 transparent,
       50px  78px 2px 1 transparent,
       18px  60px 2px 1 transparent,
        4px  64px 2px 1 transparent,
       30px  56px 2px 1 transparent,
       80px  60px 2px 1 transparent,
       16px  54px 2px 1 transparent;
    opacity: 0;
  }
}
/* グループ B: 左半円 + 中央上方向に打ち上げ → 重力で左下に落下 */
@keyframes avatar-frame-spark-arc-b {
  0% {
    box-shadow:
      -14px -12px 2px 1 #ff8c00,
      -24px  -4px 2px 1 #ffae42,
      -30px   8px 2px 1 #ff6f3c,
      -18px  14px 2px 1 #ffae42,
       -4px -24px 2px 1 #ff8c00,
        8px -18px 2px 1 #ff6f3c,
      -10px -32px 2px 1 #ffae42,
      -36px   0px 2px 1 #ff4500,
        2px -36px 2px 1 #ffd54f;
    opacity: 1;
  }
  30% {
    box-shadow:
      -26px -34px 2px 1 #ff8c00,
      -40px -22px 2px 1 #ffae42,
      -48px  -6px 2px 1 #ff6f3c,
      -34px   8px 2px 1 #ffae42,
      -10px -52px 2px 1 #ff8c00,
        6px -46px 2px 1 #ff6f3c,
      -22px -64px 2px 1 #ffae42,
      -58px -16px 2px 1 #ff4500,
        4px -58px 2px 1 #ffd54f;
    opacity: 0.95;
  }
  100% {
    box-shadow:
      -46px  64px 2px 1 transparent,
      -62px  68px 2px 1 transparent,
      -68px  72px 2px 1 transparent,
      -50px  78px 2px 1 transparent,
      -18px  60px 2px 1 transparent,
       -4px  64px 2px 1 transparent,
      -30px  56px 2px 1 transparent,
      -80px  60px 2px 1 transparent,
      -16px  54px 2px 1 transparent;
    opacity: 0;
  }
}

/* === Animated SVG asset frames (Discord 風 アバター装飾) ===
 * CSS pure では到達できないリッチさを SVG アセット側に焼き込む。
 * ::before で /static/frames/{name}.svg を center/contain で重ねる。
 * 親 .avatar-frame は position:relative、paint 順は親背景 → ::before → img なので
 * アバター本体は ::before の上に描かれる (z-index 指定不要)。
 * .avatar-frame の background を透明化しないと本体の bg-card 円が枠の見えを邪魔する。 */
.avatar-frame-phoenix,
.avatar-frame-wings {
  background: transparent;
  box-shadow: none;
}
.avatar-frame-phoenix::before,
.avatar-frame-wings::before {
  content: '';
  position: absolute;
  pointer-events: none;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
}
/* 青炎の不死鳥: 円形、22% 外側にはみ出して炎を見せる */
.avatar-frame-phoenix::before {
  inset: -22%;
  background-image: url('/static/frames/phoenix.svg');
}
.avatar-frame-phoenix.avatar-frame-xl::before { inset: -27%; }
/* 黄金の翼: viewBox が横長 (240x200) なので左右に大きくはみ出す */
.avatar-frame-wings::before {
  top: -15%; bottom: -15%; left: -38%; right: -38%;
  background-image: url('/static/frames/wings.svg');
}
.avatar-frame-wings.avatar-frame-xl::before {
  top: -18%; bottom: -18%; left: -42%; right: -42%;
}

@media (prefers-reduced-motion: reduce) {
  .avatar-frame-neon,
  .avatar-frame-aura,
  .avatar-frame-sparkle::before,
  .avatar-frame-sparkle::after,
  .avatar-frame-aura::before,
  .avatar-frame-aura::after,
  .avatar-frame-spark::before,
  .avatar-frame-spark::after { animation: none; }
  /* SVG 内 SMIL animation は CSS から止められないため phoenix/wings の
     回転・羽ばたきは継続する (Discord も完全停止はしない仕様)。 */
}

/* 装飾ハンドル色を .author-name-text と .author-handle に伝播させる。
   php-style.css L14069 で .author-name-text に直接
   `color: var(--text-primary) !important` が当たっていて、親 .author-name の
   inline style="color:..." がテキストに届かなかった。inline color が指定された
   時だけ inherit に強制上書きして、親の inline 値をテキストに引き継がせる。
   adjacent sibling (+) で同じ post-author-meta 内の @handle も同色に。
   specificity: .author-name[style*="color"] .author-name-text = (0,0,3,0)
   > 元の .author-name-text = (0,0,1,0) で勝つ。 */
.author-name[style*="color"] .author-name-text,
.author-name[style*="color"] + .author-handle {
  color: inherit !important;
}
/* .author-handle 側は親が違うので、adjacent sibling では取れない。
   代わりに親 .post-author-meta が :has() で「inline color 持ち .author-name」
   を含む時に @handle も色を引き継ぐ (モダンブラウザ向け、未対応ブラウザは
   element 単位の通常色のまま、機能劣化はマイルド)。 */
.post-author-meta:has(> a > .author-name[style*="color"]) .author-handle,
.post-author-meta:has(> .author-link > .author-name[style*="color"]) .author-handle {
  color: var(--text-secondary);
}

/* ========================================
 * TL ピン (post promote) のバッジ
 * ピン中の投稿は post_author_meta の末尾 or detail head に
 *  「↑ ピン留め」chip を出して、ユーザに「Home トップに固定されている」
 *  ことを伝える。色味は accent-gold (cosmetic gold と統一感)。
 * ======================================== */
.promoted-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--bg-primary);
  background: var(--accent-gold);
  border-radius: 999px;
  line-height: 1.4;
  white-space: nowrap;
  flex-shrink: 0;
  margin-left: 4px;
}
.promoted-chip i { font-size: 0.68rem; }
body.theme-light .promoted-chip { color: #fff; }
/* アイコンのみ表示モード: 丸バッジ風にコンパクト化 */
.promoted-chip.promoted-chip-icon {
  gap: 0;
  padding: 0;
  width: 18px;
  height: 18px;
  justify-content: center;
  border-radius: 50%;
}
.promoted-chip.promoted-chip-icon i { font-size: 0.72rem; }

/* ==========================================================
 * Composer 拡張: 添付1ボタン + 現況届/同好談話室 ピッカー
 * ========================================================== */
.cm-video-preview {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 6px 0; padding: 8px 12px; border: 1px solid var(--border-primary);
  border-radius: 10px; background: var(--bg-card-hover); font-size: 0.85rem;
}
.cm-video-preview i { color: var(--accent-cyan); }
.cm-video-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-video-remove,
.cm-target-remove {
  background: transparent; border: none; cursor: pointer; color: var(--text-secondary);
  font-size: 1.05rem; padding: 0 4px; line-height: 1;
}
.cm-video-remove:hover, .cm-target-remove:hover { color: var(--accent-pink); }

.cm-target-chip {
  display: inline-flex; align-items: center; gap: 8px;
  /* 親が flex column のため align-self を指定しないと横幅いっぱいに
     stretch されてチップ右側に大きな余白が出る。内容サイズに縮める。 */
  align-self: flex-start;
  width: fit-content; max-width: 100%;
  margin: 6px 0; padding: 6px 12px;
  border-radius: 999px; font-size: 0.82rem; font-weight: 700;
  background: linear-gradient(135deg, rgba(124,77,255,0.14), rgba(0,229,255,0.10));
  border: 1px solid var(--accent-cyan); color: var(--text-primary);
}
.cm-target-chip i { color: var(--accent-purple); }

/* composer-actions 内の各アクションを等間隔に並べる。
   .cm-attach-btn の margin-right:auto が画像だけ左端に押し付けて隙間が
   開いていた問題を打ち消し、3 つのアイコンが均等に並ぶようにする。 */
.composer-actions.cm-actions-tight { gap: 6px; }
.composer-actions.cm-actions-tight .composer-action { padding: 6px; }
.composer-actions.cm-actions-tight .cm-attach-btn {
  margin-right: 0;                 /* デフォの margin-right:auto を打ち消す */
  border: none;                    /* 枠を外して他のアイコンと統一感 */
  color: var(--accent-cyan);       /* 他の composer-action と同じ色 */
}

/* ピッカー popover — 「選択メニュー」スタイル:
   - ボタンの「下」に開く (上はヘッダ/タブで隠れるため必ず下)
   - 幅はコンパクト (max 300px)
   - 右端切れは JS (composer-extras.js) で開いた直後に translateX 補正
   - 行は 1 行に固定 + 長いラベルは末尾 ellipsis */
.cm-picker-wrap { position: relative; display: inline-flex; }
.cm-picker-popover {
  position: absolute;
  left: 0; right: auto;
  top: calc(100% + 8px); bottom: auto;     /* ← 下方向に開く */
  z-index: 1000;
  min-width: 220px;
  width: max-content;
  max-width: min(300px, calc(100vw - 24px));
  max-height: 320px; overflow-y: auto;
  /* --bg-card は半透明 (rgba(13,19,48,0.55)) なので下の投稿カードが透けて見にくい。
     ポップオーバーは必ず不透明にして下を完全に隠す。カスタムテーマで bg vars が
     半透明になるケースも考慮して backdrop-filter で blur も併用。 */
  background: var(--bg-secondary);
  border: 1px solid var(--border-primary);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
body.theme-light .cm-picker-popover {
  background: #ffffff;
  box-shadow: 0 12px 32px rgba(50,80,150,0.18);
}
.cm-picker-popover[hidden] { display: none; }
.cm-picker-head {
  padding: 10px 14px; border-bottom: 1px solid var(--border-primary);
  font-weight: 800; font-size: 0.86rem; color: var(--text-primary);
  background: var(--bg-card-hover);
}
.cm-picker-list { padding: 6px; display: flex; flex-direction: column; gap: 4px; }
.cm-picker-item {
  text-align: left; background: transparent; border: 1px solid transparent;
  color: var(--text-primary); padding: 10px 12px; border-radius: 10px; cursor: pointer;
}
.cm-picker-item:hover:not(:disabled) { background: var(--bg-card-hover); border-color: var(--accent-cyan); }
.cm-picker-item:disabled { opacity: 0.55; cursor: not-allowed; }
.cm-picker-item-title {
  font-weight: 700; font-size: 0.9rem;
  display: flex; align-items: center; gap: 8px;
  /* 1 行に固定 + 末尾省略 */
  white-space: nowrap; overflow: hidden;
}
/* タイトルの中で「ラベルテキスト本体」だけ ellipsis 対象。
   アイコン (<i>) と末尾の (閉鎖中) chip は ellipsis されないように
   .cm-picker-item-label を巻いておく前提。 */
.cm-picker-item-title .cm-picker-item-label {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cm-picker-item-title i { color: var(--accent-cyan); flex: 0 0 auto; }
.cm-picker-item-title .cm-picker-closed { flex: 0 0 auto; }
.cm-picker-item-sub { color: var(--text-secondary); font-size: 0.75rem; margin-top: 2px; padding-left: 22px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cm-picker-closed { color: var(--accent-pink); font-weight: 700; margin-left: 4px; }
.cm-picker-empty { padding: 18px; text-align: center; color: var(--text-secondary); font-size: 0.85rem; }

/* スマホでも上方向に開く dropdown のまま。ボタンが action-bar 左寄り
   なので、popover は max-width 300px で wrapper の left:0 から右に伸びる
   が、ビューポート (calc(100vw - 24px)) を超えないので端切れしない。 */

/* 現況届ボタンの未投稿バッジ (iOS アプリのバッジに寄せた円形) */
.cm-picker-btn { position: relative; }
.cm-picker-badge {
  position: absolute; top: -4px; right: -4px;
  min-width: 18px; height: 18px; padding: 0 5px;
  background: #ff3b30; color: #fff;
  font-size: 0.7rem; font-weight: 800; line-height: 1;
  letter-spacing: -0.02em;
  border-radius: 999px;
  border: 2px solid var(--bg-primary, #070916);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
  /* iOS 風の微妙な内側ハイライトで立体感を出す (サイズは元のまま) */
  background-image: linear-gradient(180deg, rgba(255,255,255,0.18), rgba(255,255,255,0) 60%);
}
body.theme-light .cm-picker-badge {
  border-color: #ffffff;
  box-shadow: 0 2px 6px rgba(244, 33, 46, 0.35);
}

/* AI に質問する トグルボタン */
.cm-ai-btn {
  position: relative;
  transition: color .15s ease, background .15s ease, box-shadow .15s ease;
}
.cm-ai-btn:hover { color: var(--accent-cyan); }
.cm-ai-btn.is-active {
  color: #fff;
  background: linear-gradient(135deg, #00e5ff 0%, #6633ff 100%);
  border-color: transparent;
  box-shadow: 0 0 0 2px rgba(0, 229, 255, 0.35), 0 4px 14px rgba(102, 51, 255, 0.45);
}
.cm-ai-btn.is-active i { text-shadow: 0 0 6px rgba(255,255,255,0.6); }

/* AI モード時の form 全体 (textarea の縁取りを ネオン化) */
.composer.cm-ai-on .cm-body {
  border-color: var(--accent-cyan);
  box-shadow: 0 0 0 1px rgba(0, 229, 255, 0.45), 0 4px 16px rgba(0, 229, 255, 0.18);
}
/* cm-target-chip を AI モード仕様で上書き */
.cm-target-chip.cm-target-ai {
  background: linear-gradient(135deg, rgba(0,229,255,0.18), rgba(102,51,255,0.18));
  border-color: rgba(0, 229, 255, 0.55);
  color: var(--accent-cyan);
}
.cm-target-chip.cm-target-ai .cm-target-icon {
  color: var(--accent-cyan);
}

/* === ハンドル名 アニメーショングラデ ===
 * users.handle_color に "grad-rainbow" 等を保存し、profile.html / post_card.html /
 * post_detail.html 側で `hasPrefix HandleColor "grad-"` を見て `class="handle-grad
 * grad-rainbow"` を付ける。inline color は付けない (background-clip: text のため
 * color: transparent を強制する必要があり、inline color と衝突する)。
 * background-size: 200% で gradient を 2 倍に引き伸ばし、background-position を
 * 動かして流れるアニメ。WebKit prefix を併記。 */
/* .handle-grad は text 専用 (background-clip: text)。block 要素 (= ショップの
 * スウォッチ等) には .grad-* クラス単独で当てると gradient + animation が
 * そのまま見える。 */
.handle-grad {
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent !important;
  -webkit-text-fill-color: transparent;
  font-weight: 800;
}
/* 全 grad-* 共通: background-size + animation 既定値。
 * .handle-grad と組み合わせれば text、block 要素単独でも同じ動きで流れる。 */
.grad-rainbow,
.grad-blue-sky,
.grad-red-black,
.grad-aurora,
.grad-magma,
.grad-galaxy,
.grad-cyberpunk,
.grad-chrome,
.grad-ocean,
.grad-sakura {
  background-size: 200% 200%;
  background-position: 0% 50%;
  animation: handle-grad-shift 4s linear infinite;
}
.grad-rainbow {
  background-image: linear-gradient(90deg,#ff0000,#ff8800,#ffff00,#00cc00,#00aaff,#6633ff,#ff00cc,#ff0000);
}
.grad-blue-sky {
  background-image: linear-gradient(90deg,#1e3a8a,#3b82f6,#87ceeb,#bfdbfe,#87ceeb,#3b82f6,#1e3a8a);
  animation-duration: 5s;
}
.grad-red-black {
  background-image: linear-gradient(90deg,#000000,#7f1d1d,#dc2626,#ff0000,#dc2626,#7f1d1d,#000000);
  animation-duration: 4.5s;
}

/* === 追加 7 種 (それぞれ別ベクトル: 方向 / 速度 / 動き) === */

/* 1. オーロラ — 斜め (135deg) 緩やかな ease-in-out。背景サイズ大きめで揺らぎ感 */
.grad-aurora {
  background-image: linear-gradient(135deg,#003366,#00ff99,#00ccff,#9d00ff,#00ff99,#003366);
  background-size: 300% 300%;
  animation: handle-grad-diag 7s ease-in-out infinite;
}

/* 2. マグマ — 縦 (0deg) に速め、強い脈動。火が下から立ち上る感 */
.grad-magma {
  background-image: linear-gradient(0deg,#000000,#4a0000,#b91c1c,#ff4500,#ff8c00,#ffd700,#ff8c00,#ff4500,#b91c1c,#4a0000,#000000);
  background-size: 100% 300%;
  animation: handle-grad-vertical 3s ease-in-out infinite;
  text-shadow: 0 0 8px rgba(255, 69, 0, 0.45);
}

/* 3. 銀河 — 斜め + 色相回転で星のきらめき。最長 8s */
.grad-galaxy {
  background-image: linear-gradient(45deg,#0a0033,#1a0080,#4a00ff,#ffffff,#9d00ff,#4a00ff,#1a0080,#0a0033);
  background-size: 300% 300%;
  animation: handle-grad-galaxy 8s linear infinite;
  text-shadow: 0 0 6px rgba(157, 0, 255, 0.55);
}

/* 4. サイバーパンク — 高速横方向 1.6s。マゼンタ⇄シアンが点滅級に走る */
.grad-cyberpunk {
  background-image: linear-gradient(90deg,#ff00ff,#00ffff,#ff00ff,#00ffff,#ff00ff);
  background-size: 200% 100%;
  animation: handle-grad-shift 1.6s linear infinite;
  text-shadow: 0 0 6px rgba(255, 0, 255, 0.55), 0 0 10px rgba(0, 255, 255, 0.35);
}

/* 5. クローム — 110deg の鈍い金属感、ease-in-out で柔らかい反復 */
.grad-chrome {
  background-image: linear-gradient(110deg,#1a1a1a,#888888,#e0e0e0,#ffffff,#e0e0e0,#888888,#1a1a1a);
  background-size: 250% 100%;
  animation: handle-grad-shift 6s ease-in-out infinite alternate;
}

/* 6. オーシャン — 縦 (180deg) 大きな波。深海 → 泡の白 → 深海。中速 6s */
.grad-ocean {
  background-image: linear-gradient(180deg,#001a4d,#003366,#0066cc,#66ccff,#ffffff,#66ccff,#0066cc,#003366,#001a4d);
  background-size: 100% 300%;
  animation: handle-grad-vertical 6s linear infinite;
}

/* 7. 桜吹雪 — 柔らかい斜め流れ ease-in-out。最も落ち着いた変化 */
.grad-sakura {
  background-image: linear-gradient(135deg,#ffe4f1,#ffafd7,#ff7eb6,#ffd1e8,#ffafd7,#ffe4f1);
  background-size: 300% 300%;
  animation: handle-grad-diag 7s ease-in-out infinite alternate;
}

@keyframes handle-grad-shift {
  0%   { background-position:   0% 50%; }
  100% { background-position: 200% 50%; }
}
@keyframes handle-grad-vertical {
  0%   { background-position: 50%   0%; }
  100% { background-position: 50% 200%; }
}
@keyframes handle-grad-diag {
  0%   { background-position:   0%   0%; }
  50%  { background-position: 100% 100%; }
  100% { background-position:   0%   0%; }
}
/* 銀河: 位置 + hue-rotate でランダム感のあるきらめき */
@keyframes handle-grad-galaxy {
  0%   { background-position:   0% 50%; filter: hue-rotate(0deg); }
  50%  { background-position: 100% 50%; filter: hue-rotate(40deg); }
  100% { background-position: 200% 50%; filter: hue-rotate(0deg); }
}
/* prefers-reduced-motion: アニメは止めるが gradient 表示は維持 */
@media (prefers-reduced-motion: reduce) {
  .handle-grad,
  .grad-rainbow, .grad-blue-sky, .grad-red-black,
  .grad-aurora, .grad-magma, .grad-galaxy,
  .grad-cyberpunk, .grad-chrome, .grad-ocean, .grad-sakura {
    animation: none;
  }
}

/* === プロフィール BGM カスタムプレイヤー ===
 * デフォルトの <audio controls> は OS / ブラウザでまちまちでダサいので、
 * 再生ボタン + プログレスバー + 時刻 + ミュート の自前 UI を JS で操作。
 * カスタムカラー (user-colors) 対応: 背景/枠/ボタン/フィルすべて CSS 変数経由。
 * - 背景       = var(--bg-card)          [user-colors panel で上書き可]
 * - 枠         = var(--border-primary)   [user-colors divider で上書き可]
 * - 再生ボタン = var(--gradient-primary) [user-colors primary/primaryEnd で上書き可]
 * - フィル     = var(--gradient-primary)
 * - 文字色     = var(--text-secondary / --text-primary)
 * 再生中グロウは accent-cyan 系を半透明で焼いた静的色 (CSS 変数だけだと alpha 合成
 * できないため。視覚的に控えめなのでテーマで違和感は出ない)。 */
.bgm-player {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  background: var(--bg-card);
  border: 1px solid var(--border-primary);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  max-width: 420px;
  width: 100%;
  box-sizing: border-box;
  margin: 10px 0;
  color: var(--text-primary);
}
.bgm-player .bgm-btn {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  color: #fff;
  background: var(--gradient-primary);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
  transition: transform .12s ease, box-shadow .12s ease;
}
.bgm-player .bgm-btn:hover { transform: scale(1.05); }
.bgm-player .bgm-btn:active { transform: scale(0.95); }
.bgm-player .bgm-btn.bgm-mute {
  background: transparent;
  color: var(--text-secondary);
  box-shadow: none;
  width: 28px; height: 28px;
}
.bgm-player .bgm-btn.bgm-mute:hover { color: var(--text-primary); }
.bgm-player .bgm-progress {
  flex: 1 1 auto;
  position: relative;
  height: 6px;
  background: var(--border-primary);
  border-radius: 999px;
  cursor: pointer;
  overflow: hidden;
  outline: none;
}
.bgm-player .bgm-progress:focus-visible {
  box-shadow: 0 0 0 2px var(--accent-cyan);
}
.bgm-player .bgm-progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: var(--gradient-primary);
  border-radius: 999px;
  transition: width .08s linear;
}
.bgm-player .bgm-time {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  white-space: nowrap;
  color: var(--text-secondary);
}
/* 再生中: 枠を accent 色に切替。box-shadow は alpha 合成の都合で静的 rgba。 */
.bgm-player.is-playing {
  border-color: var(--accent-cyan);
  box-shadow: 0 0 10px rgba(0, 229, 255, 0.18);
}

/* ================================================================
 * §149. くじ引きタブの再設計 (.lot-* 名前空間)
 *
 * 旧 .wb-prize-list の bar 表示は確率を出さない設計で意味を失ったので撤廃。
 * カードグリッドで「起こりうる結果」を直感的に並べる。
 * モバイル優先 (Hub に多い縦スクロール幅 350-414pt 想定)。
 * ================================================================ */

.lot { display: flex; flex-direction: column; gap: 14px; max-width: 720px; margin: 0 auto; }
.lot-card {
  background: var(--bg-card, rgba(255,255,255,0.04));
  border: 1px solid var(--border-primary, rgba(255,255,255,0.08));
  border-radius: 14px;
  padding: 16px;
}
body.theme-light .lot-card {
  background: #fff;
  border-color: rgba(0,0,0,0.08);
  box-shadow: 0 1px 3px rgba(40,80,160,0.05);
}

/* ----- hero ----- */
.lot-hero { padding: 14px 16px; }
.lot-hero-row { display: flex; align-items: center; gap: 12px; }
.lot-hero-icon {
  flex: 0 0 44px; height: 44px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 30% 30%, rgba(0,229,255,0.25), rgba(0,229,255,0.05));
  color: var(--accent-cyan, #00e5ff);
  font-size: 1.4rem;
}
.lot-hero-text { flex: 1 1 auto; min-width: 0; }
.lot-hero-text h2 { margin: 0 0 2px; font-size: 1.05rem; color: var(--text-primary); }
.lot-hero-text p { margin: 0; font-size: 0.78rem; color: var(--text-secondary); line-height: 1.4; }
/* 残り枠 / 直近 1h 活動 (pool は UI 非表示) */
.lot-quota {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px;
}
.lot-quota-it {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 12px; border-radius: 12px;
  background: rgba(0,229,255,0.08);
  border: 1px solid rgba(0,229,255,0.18);
}
.lot-quota-it .k { font-size: 0.7rem; color: var(--text-secondary); letter-spacing: 0.04em; }
.lot-quota-it .v { font-size: 1.4rem; font-weight: 800; color: var(--accent-cyan, #00e5ff); line-height: 1.1; }
.lot-quota-it .v small { font-size: 0.7rem; margin-left: 3px; opacity: 0.8; font-weight: 700; }

/* ----- 抽選結果フラッシュ ----- */
.lot-result { text-align: center; padding: 26px 16px; animation: lotPop 0.42s cubic-bezier(.34,1.56,.64,1); }
.lot-result-icon { font-size: 2.4rem; margin-bottom: 6px; animation: lotSpin 0.8s ease-out; }
.lot-result-amt { font-size: 2.6rem; font-weight: 900; line-height: 1; margin-bottom: 6px; }
.lot-result-amt small { font-size: 0.9rem; font-weight: 700; margin-left: 4px; opacity: 0.8; }
.lot-result-lbl { font-size: 0.9rem; color: var(--text-primary); font-weight: 700; }
.lot-result-win {
  border-color: var(--accent-gold, #ffd700);
  background: radial-gradient(ellipse at center, rgba(255,215,0,0.18), rgba(255,215,0,0.02));
}
.lot-result-win .lot-result-icon, .lot-result-win .lot-result-amt { color: var(--accent-gold, #ffd700); }
.lot-result-lose {
  border-color: var(--accent-pink, #ff4d6d);
  background: radial-gradient(ellipse at center, rgba(255,77,109,0.18), rgba(255,77,109,0.02));
}
.lot-result-lose .lot-result-icon, .lot-result-lose .lot-result-amt { color: var(--accent-pink, #ff4d6d); }
.lot-result-miss {
  border-color: var(--border-primary);
  background: rgba(255,255,255,0.02);
}
.lot-result-miss .lot-result-icon, .lot-result-miss .lot-result-amt { color: var(--text-secondary); }
.lot-result-bonus {
  border-color: var(--accent-cyan, #00e5ff);
  background: radial-gradient(ellipse at center, rgba(0,229,255,0.18), rgba(0,229,255,0.02));
}
.lot-result-bonus .lot-result-icon, .lot-result-bonus .lot-result-amt { color: var(--accent-cyan, #00e5ff); }
.lot-result-bonus .lot-result-amt { font-size: 1.6rem; }
@keyframes lotPop { from { opacity: 0; transform: scale(.88); } to { opacity: 1; transform: scale(1); } }
@keyframes lotSpin { from { transform: rotate(-180deg) scale(.4); } to { transform: rotate(0) scale(1); } }

/* ----- 引くボタン ----- */
.lot-action { text-align: center; }
.lot-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 220px; padding: 14px 24px;
  border: none; border-radius: 999px;
  background: linear-gradient(135deg, var(--accent-cyan, #00e5ff), var(--accent-purple, #6a5cff));
  color: #ffffff; font-weight: 800; font-size: 1rem;
  text-shadow: 0 1px 2px rgba(0,0,0,0.25);
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0,229,255,0.32);
  transition: transform .12s ease, box-shadow .12s ease;
}
.lot-btn i { color: #ffffff; }
.lot-btn:hover { transform: translateY(-1px); box-shadow: 0 10px 28px rgba(0,229,255,0.4); }
.lot-btn:active { transform: translateY(0); }
.lot-btn-bonus { background: linear-gradient(135deg, #00e5ff, #00c896); }
.lot-btn-disabled {
  background: var(--bg-secondary, rgba(255,255,255,0.05)) !important;
  color: var(--text-secondary) !important;
  cursor: not-allowed; box-shadow: none;
}
.lot-note { font-size: 0.78rem; color: var(--text-secondary); margin: 10px 0 0; }

/* ----- 無料チケットカード ----- */
.lot-voucher {
  display: flex; align-items: center; gap: 14px;
  border-color: var(--accent-cyan, #00e5ff);
  background: linear-gradient(135deg, rgba(0,229,255,0.08), rgba(106,92,255,0.04));
}
.lot-voucher-icon { font-size: 1.6rem; color: var(--accent-cyan, #00e5ff); }
.lot-voucher-text { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.lot-voucher-text strong { font-size: 0.95rem; color: var(--text-primary); }

/* ----- カードグリッド (起こりうること) ----- */
.lot-h { margin: 0 0 4px; font-size: 1rem; color: var(--text-primary); display: flex; align-items: center; gap: 8px; }
.lot-h i { color: var(--accent-cyan, #00e5ff); }
.lot-sub { margin: 0 0 12px; font-size: 0.74rem; color: var(--text-secondary); line-height: 1.5; }

.lot-group-title {
  margin: 14px 0 8px;
  font-size: 0.78rem; font-weight: 800; letter-spacing: 0.04em;
  display: flex; align-items: center; gap: 6px;
}
.lot-group-win { color: var(--accent-gold, #ffd700); }
.lot-group-lose { color: var(--accent-pink, #ff4d6d); }
.lot-group-bonus { color: var(--accent-cyan, #00e5ff); }

.lot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
  gap: 8px;
}
.lot-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 12px 8px; border-radius: 12px;
  border: 1px solid var(--border-primary, rgba(255,255,255,0.1));
  background: var(--bg-secondary, rgba(255,255,255,0.04));
  text-align: center;
  min-height: 64px;
}
.lot-tile .amt { font-size: 1rem; font-weight: 800; line-height: 1.1; }
.lot-tile .lbl { font-size: 0.68rem; color: var(--text-secondary); margin-top: 4px; }

.lot-tile-win .amt { color: var(--accent-gold, #ffd700); }
.lot-tile-win {
  border-color: rgba(255,215,0,0.32);
  background: linear-gradient(135deg, rgba(255,215,0,0.10), rgba(255,215,0,0.02));
}
.lot-tile-big .amt { font-size: 1.15rem; }
.lot-tile-mega .amt { font-size: 1.3rem; }
.lot-tile-mega {
  border-color: rgba(255,215,0,0.55);
  background: linear-gradient(135deg, rgba(255,215,0,0.22), rgba(255,140,0,0.08));
  box-shadow: 0 0 14px rgba(255,215,0,0.18) inset;
}

.lot-tile-lose .amt { color: var(--accent-pink, #ff4d6d); }
.lot-tile-lose {
  border-color: rgba(255,77,109,0.32);
  background: linear-gradient(135deg, rgba(255,77,109,0.10), rgba(255,77,109,0.02));
}
.lot-tile-miss .amt { color: var(--text-secondary); }

.lot-tile-bonus .amt { color: var(--accent-cyan, #00e5ff); font-size: 1.3rem; }
.lot-tile-bonus {
  border-color: rgba(0,229,255,0.32);
  background: linear-gradient(135deg, rgba(0,229,255,0.10), rgba(106,92,255,0.04));
}

/* ----- しくみ details ----- */
.lot-details summary {
  cursor: pointer; list-style: none;
  font-weight: 800; font-size: 0.88rem;
  color: var(--text-primary);
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0;
}
.lot-details summary::-webkit-details-marker { display: none; }
.lot-details summary i { color: var(--accent-cyan); }
.lot-details summary::after { content: "▾"; margin-left: auto; color: var(--text-secondary); transition: transform .15s; }
.lot-details[open] summary::after { transform: rotate(180deg); }
.lot-explain {
  margin: 10px 0 0; font-size: 0.82rem; line-height: 1.6;
  color: var(--text-secondary);
}

/* ----- スマホ最終調整 ----- */
@media (max-width: 480px) {
  .lot-hero-row { flex-wrap: wrap; }
  .lot-grid { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }
  .lot-tile { min-height: 60px; padding: 10px 6px; }
  .lot-quota-it { padding: 8px 10px; }
  .lot-quota-it .v { font-size: 1.25rem; }
}

/* ================================================================
 * §150. アンチスパム制限ページ (.rst-*)
 *
 * 制限がかかった時に表示する専用ページ。プレーンテキスト 429 を返す
 * 代わりに redirect でこの画面に飛ばして、状況と対処をやさしく伝える。
 * ================================================================ */

.rst-wrap {
  min-height: calc(100vh - 80px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px; box-sizing: border-box;
}
.rst-card {
  width: 100%; max-width: 480px;
  padding: 36px 28px 28px;
  border-radius: 24px;
  background: linear-gradient(160deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
  border: 1px solid var(--border-primary, rgba(255,255,255,0.08));
  text-align: center;
  position: relative; overflow: hidden;
  box-shadow: 0 16px 48px rgba(0,0,0,0.35);
  animation: rstPop 0.45s cubic-bezier(.34,1.56,.64,1);
}
body.theme-light .rst-card {
  background: linear-gradient(160deg, #ffffff, #f7faff);
  border-color: rgba(50,80,150,0.10);
  box-shadow: 0 16px 48px rgba(50,80,160,0.10);
}
@keyframes rstPop {
  from { opacity: 0; transform: scale(.94) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* バリアント別の縁取り (情報 / 警告 / 危険) */
.rst-card-info  { border-color: rgba(0,229,255,0.32); }
.rst-card-warn  { border-color: rgba(255,180,40,0.42); }
.rst-card-danger{ border-color: rgba(255,77,109,0.52); }

/* アイコン (大きく、リングが脈打つ) */
.rst-icon-wrap {
  position: relative;
  width: 92px; height: 92px; margin: 0 auto 18px;
  display: flex; align-items: center; justify-content: center;
}
.rst-icon-ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid currentColor;
  opacity: 0.25;
  animation: rstPulse 2.4s ease-out infinite;
}
.rst-icon {
  font-size: 2.6rem; line-height: 1;
  position: relative; z-index: 1;
}
.rst-card-info  .rst-icon, .rst-card-info  .rst-icon-ring { color: var(--accent-cyan, #00e5ff); }
.rst-card-warn  .rst-icon, .rst-card-warn  .rst-icon-ring { color: #ffb84d; }
.rst-card-danger.rst-card-danger .rst-icon, .rst-card-danger .rst-icon-ring { color: var(--accent-pink, #ff4d6d); }
@keyframes rstPulse {
  0%   { transform: scale(1);   opacity: 0.35; }
  70%  { transform: scale(1.55); opacity: 0;    }
  100% { transform: scale(1.55); opacity: 0;    }
}

.rst-title {
  font-size: 1.25rem; font-weight: 800; margin: 0 0 12px;
  color: var(--text-primary);
}
.rst-msg {
  font-size: 0.92rem; line-height: 1.55;
  color: var(--text-primary);
  background: rgba(255,255,255,0.04);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 0 0 14px;
}
body.theme-light .rst-msg { background: rgba(50,80,150,0.04); }
.rst-hint {
  font-size: 0.86rem; line-height: 1.6;
  color: var(--text-secondary);
  margin: 0 0 18px;
}
.rst-until {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px; border-radius: 999px;
  background: rgba(255,180,40,0.10);
  border: 1px solid rgba(255,180,40,0.32);
  color: #ffb84d;
  font-size: 0.88rem; font-weight: 700;
  margin: 0 0 22px;
}
.rst-actions {
  display: flex; flex-direction: column; gap: 10px;
  margin: 6px 0 22px;
}
.rst-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 22px;
  border-radius: 999px;
  font-weight: 800; font-size: 0.95rem;
  text-decoration: none;
  transition: transform .12s ease, box-shadow .12s ease, filter .12s ease;
}
.rst-btn:hover { transform: translateY(-1px); }
.rst-btn-primary {
  background: linear-gradient(135deg, var(--accent-cyan, #00e5ff), var(--accent-purple, #6a5cff));
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.25);
  box-shadow: 0 8px 24px rgba(0,229,255,0.30);
}
.rst-btn-primary:hover { filter: brightness(1.05); }
.rst-btn-ghost {
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--border-primary);
  color: var(--text-primary);
}
body.theme-light .rst-btn-ghost { background: #fff; border-color: rgba(0,0,0,0.10); }

.rst-foot {
  font-size: 0.74rem; color: var(--text-secondary);
  line-height: 1.5;
  margin: 8px 0 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.rst-foot i { color: var(--accent-cyan); }
