/*
 * World Watch Frontend Styles
 * ---
 * Table of Contents:
 *  1. Variables (colors, typography, spacing)
 *  2. Reset & Base
 *  3. Layout (topbar, hero, panels, footer)
 *  4. Cards (news, prayer, devotion)
 *  5. Badges & Tags
 *  6. Filters & Forms
 *  7. Article Modal
 *  8. Toast
 *  9. Animations
 * 10. Responsive
 */

:root {
  /* Core Colors - Bold and Vibrant */
  --bg-primary: #000000;
  --bg-secondary: #0a0a0a;
  --surface-1: #111111;
  --surface-2: #1a1a1a;
  --surface-3: #222222;

  /* Text */
  --text-primary: #ffffff;
  --text-secondary: #e0e0e0;
  --text-muted: #a0a0a0;
  --text-hint: #707070;

  /* Brand Colors - Vibrant and Eye-catching */
  --primary: #7c3aed;
  --primary-light: #a78bfa;
  --primary-dark: #6d28d9;
  --accent: #06b6d4;
  --accent-light: #22d3ee;
  --accent-glow: rgba(6, 182, 212, 0.5);

  /* Status Colors */
  --success: #10b981;
  --warning: #f59e0b;
  --error: #ef4444;

  /* Borders & Shadows */
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.15);
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 8px 30px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.5);
  --glow: 0 0 40px rgba(99, 102, 241, 0.4);

  /* Gradients */
  --gradient-hero: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
  --gradient-primary: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  --gradient-accent: linear-gradient(135deg, var(--accent) 0%, var(--accent-light) 100%);
  --gradient-overlay: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%);

  /* ── Typography Scale ───────────────────────────────
     Use these for px-based font sizes. Fluid sizes (clamp / rem)
     stay ad-hoc when intentional. */
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-base: 13px;
  --fs-md: 14px;
  --fs-lg: 16px;
  --fs-xl: 18px;
  --fs-2xl: 22px;

  /* Font Weight */
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;
  --fw-black: 900;

  /* ── Z-index Scale ──────────────────────────────────
     Semantic layers. Avoid magic numbers above --z-modal;
     escalations should justify themselves in a comment. */
  --z-base: 1;
  --z-elevated: 2;
  --z-sticky: 1000;
  --z-modal: 2000;

  /* ── Radius Scale ───────────────────────────────────
     Covers ~90% of the rounded-corner usage. Pill / circle
     are reserved for tags and avatars. */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-pill: 999px;
  --radius-circle: 50%;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  font-size: var(--fs-lg);
  overflow-x: hidden;
  overscroll-behavior-x: none;
  touch-action: pan-y pinch-zoom;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans JP', Roboto, Oxygen, Ubuntu, sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overscroll-behavior-x: none;
  touch-action: pan-y pinch-zoom;
  position: relative;
  padding-bottom: 72px;
}

/* 2026-05-05 fr GA Phase 2 v3: footer は 1 行薄バー (~32px) の position:fixed。
 * main 末尾の余白で fixed footer との重なりを回避。
 * auth / christian / profile は <footer> を持たないため CSS は影響しない。 */
body.page--viewer main {
  /* 非 PWA: footer ~32px のみ */
  padding-bottom: calc(40px + env(safe-area-inset-bottom, 0px));
}

body[data-pwa-active="1"].page--viewer main {
  /* PWA: pwa-tab-bar (~64px) + footer (~32px) を確保 */
  padding-bottom: calc(100px + env(safe-area-inset-bottom, 0px));
}

/* PWA standalone mode: footer を tab-bar の「下」(画面最下端) に配置。
 * tab-bar は footer の上に積む (bottom: footer height)。
 * 設計判断 (2026-05-05 v4): user 指示で「常に tab-bar の下に footer」のレイアウト。
 * thumb-zone は tab-bar (footer の上) で確保、footer は法的・ポリシー情報の常時可視として
 * 画面最下端に細い帯で固定。
 *
 * v7 (2026-05-05): footer の実際の高さに合わせて tab-bar bottom を再計算。
 *   mobile (font 10, padding 5+5): footer = 5 + ~13 + 5 + safe = 23 + safe
 *   desktop (font 11, padding 6+6): footer = 6 + ~14 + 6 + safe = 26 + safe
 *   両者対応のため 24px を採用 (mobile に最適化、desktop で 2px overlap だが視覚的不可知)。 */
body[data-pwa-active="1"] .footer {
  bottom: 0;
  background: rgba(17, 17, 17, 0.96);
}
body[data-pwa-active="1"] .pwa-tab-bar {
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
}

@media (display-mode: standalone) {
  .footer {
    bottom: 0;
    background: rgba(17, 17, 17, 0.96);
  }
  .pwa-tab-bar {
    bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  }
  body.page--viewer main {
    padding-bottom: calc(100px + env(safe-area-inset-bottom, 0px));
  }
}

/* Static mesh gradient (background) */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background:
    radial-gradient(ellipse at 15% 15%, rgba(124, 58, 237, 0.25) 0%, transparent 40%),
    radial-gradient(ellipse at 85% 20%, rgba(6, 182, 212, 0.2) 0%, transparent 40%),
    radial-gradient(ellipse at 50% 80%, rgba(167, 139, 250, 0.15) 0%, transparent 50%),
    radial-gradient(ellipse at 20% 70%, rgba(34, 211, 238, 0.15) 0%, transparent 45%);
  opacity: 0.85;
  pointer-events: none;
  z-index: -1;
}

a {
  color: var(--accent-light);
  text-decoration: none;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

a:hover {
  color: var(--primary-light);
}

/* Header / Navigation */
.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  /* iPhone landscape の home indicator / notch safe-area を考慮し、
     右端見切れ (PWA で時々発生) の防御として inset-right/left を取り込む。
     env() が解決できない環境では 40px が採用される (max() 第一引数)。*/
  padding:
    calc(16px + env(safe-area-inset-top, 0px))
    max(40px, env(safe-area-inset-right, 0px))
    0
    max(40px, env(safe-area-inset-left, 0px));
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  transition: all 0.3s ease;
  /* 高さ不定による sticky ジッター抑制 */
  min-height: 56px;
  overflow-x: clip;
}

.topbar-top {
  display: flex;
  align-items: center;
  justify-content: center;   /* desktop: brand を中央に（ブランドの主張を維持） */
  width: 100%;
  position: relative;
  margin-bottom: 12px;
}

.topbar-top .actions {
  /* desktop は absolute 配置を維持（中央 brand と並立） */
  position: absolute;
  right: 0;
}

/* Filter bar below brand */
.header-filter {
  width: 100%;
  margin: 0;
  border: none;
  border-top: 1px solid var(--border);
  background: transparent;
  border-radius: 0;
  padding: 0;
  margin-bottom: 0;
}

.topbar::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--gradient-primary);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.topbar:hover::after {
  opacity: 1;
}

.brand {
  font-size: 68px;
  font-weight: var(--fw-black);
  letter-spacing: -0.04em;
  background: var(--gradient-hero);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  cursor: pointer;
  transition: all 0.3s ease;
  filter: drop-shadow(0 0 20px rgba(124, 58, 237, 0.5));
  white-space: nowrap;
  flex-shrink: 0;
}

.brand:hover {
  transform: scale(1.08);
  filter: drop-shadow(0 0 40px rgba(124, 58, 237, 0.9));
}

.nav {
  display: flex;
  gap: 4px;
  align-items: center;
}

.nav a {
  color: var(--text-secondary);
  font-size: 15px;
  font-weight: var(--fw-semibold);
  padding: 12px 20px;
  border-radius: var(--radius-md);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.nav a::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--gradient-primary);
  opacity: 0;
  transition: opacity 0.3s ease;
  border-radius: var(--radius-md);
}

.nav a:hover {
  color: var(--text-primary);
  transform: translateY(-2px);
}

.nav a:hover::before {
  opacity: 0.15;
}

/* Nav divider (kept for potential reuse) */
/* ── Filter Bar: 2-row region + theme ── */
.filter-bar {
  margin-bottom: 2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-1);
}

.filter-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  padding: 10px 16px;
  overflow-x: clip;
}

.filter-row + .filter-row {
  border-top: 1px solid var(--border);
}

/* 横スクロール可能ヒント（右端フェード）。search-row は対象外 */
.filter-row:not(.search-row)::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 32px;
  pointer-events: none;
  background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.85));
  z-index: 1;
}

@media (min-width: 1024px) {
  .filter-row:not(.search-row)::after {
    display: none;
  }
}

.filter-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-hint);
  min-width: 32px;
  margin-right: 12px;
  flex-shrink: 0;
}

.filter-scroll {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  touch-action: pan-x;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 2px;
}

.filter-scroll::-webkit-scrollbar {
  display: none;
}

/* Region tabs */
.region-tab {
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  padding: 6px 14px;
  border-radius: var(--radius-xl);
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  transition: all 0.2s ease;
  white-space: nowrap;
  flex-shrink: 0;
}

.region-tab:hover {
  color: var(--text-primary);
  background: var(--surface-2);
  border-color: var(--border);
}

.region-tab.active {
  color: #fff;
  background: var(--primary);
  border-color: var(--primary);
}

/* Theme chips */
.theme-chip {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  padding: 5px 12px;
  border-radius: var(--radius-xl);
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  transition: all 0.2s ease;
  white-space: nowrap;
  flex-shrink: 0;
}

.theme-chip:hover {
  color: var(--accent-light);
  background: rgba(6, 182, 212, 0.1);
  border-color: rgba(6, 182, 212, 0.3);
}

.theme-chip.active {
  color: var(--accent-light);
  background: rgba(6, 182, 212, 0.15);
  border-color: var(--accent);
}

.actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* Identity link: avatar (gradient initial) + name as a borderless pill linking to /profile/.
   ボタンと差別化することで「アクション」ではなく「自分自身」であることを視覚的に伝える。 */
.identity-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px 6px 6px;
  border-radius: var(--radius-pill);
  text-decoration: none;
  color: var(--text-primary);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.01em;
  transition: background-color 160ms ease, transform 160ms ease;
}
.identity-link:hover {
  background: rgba(255, 255, 255, 0.06);
  transform: translateY(-1px);
}
.identity-link:focus-visible {
  outline: 2px solid var(--accent-light, #22d3ee);
  outline-offset: 2px;
}

.identity-avatar {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-circle);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
  color: #fff;
  font-size: var(--fs-base);
  font-weight: var(--fw-extrabold);
  line-height: 1;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 4px 12px rgba(118, 75, 162, 0.25);
}

.identity-name {
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Icon-only button (e.g. logout). 正方形・小さめ。hover で破壊的アクションのシグナルとして赤を出す。 */
.btn.btn-icon {
  width: 40px;
  height: 40px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  color: var(--text-muted, #a0a0a0);
  transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}
.btn.btn-icon:hover {
  color: #f87171;
  border-color: rgba(248, 113, 113, 0.45);
  background: rgba(248, 113, 113, 0.06);
}

/* Language toggle: 短縮形 (EN / 日本語) を 1 ボタンで切替。
   .btn の汎用 padding が太いので少し詰める。modal 開いている間も常時クリック可。*/
.btn.btn-lang-toggle {
  padding: 10px 14px;
  font-size: var(--fs-base);
  letter-spacing: 0.04em;
  min-width: 64px;
}

/* Phase 0 UX-1: 言語選択 popover (3+ 言語対応)。
   HTML に <ul id="langMenu"> がある場合のみ表示。binary toggle (auth/profile 等)
   は従来通り。fr GA で registry に fr を追加すると自動的に menu に Français が登場。 */
.lang-selector {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.btn.btn-lang-toggle .lang-current {
  font-weight: 700;
}

.btn.btn-lang-toggle .lang-caret {
  margin-left: 4px;
  font-size: 10px;
  opacity: 0.7;
  transition: transform 0.15s ease;
}

.btn.btn-lang-toggle[aria-expanded="true"] .lang-caret {
  transform: rotate(180deg);
}

.lang-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 1100;
  min-width: 160px;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  background: var(--surface-2, #1a1a1a);
  border: 1px solid var(--border-strong, rgba(255, 255, 255, 0.15));
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

.lang-menu[hidden] {
  display: none;
}

.lang-menu-item {
  margin: 0;
  padding: 0;
}

.lang-menu-item a[role="menuitem"] {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  color: var(--text-primary, #fff);
  text-decoration: none;
  font-size: var(--fs-base, 14px);
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.1s ease;
}

.lang-menu-item a[role="menuitem"]:hover,
.lang-menu-item a[role="menuitem"]:focus-visible {
  background: rgba(124, 58, 237, 0.18);
  outline: none;
}

.lang-menu-item.is-current a[role="menuitem"] {
  background: rgba(124, 58, 237, 0.28);
  color: var(--accent-light, #22d3ee);
  cursor: default;
}

.lang-menu-item.is-current a[role="menuitem"]::after {
  content: '✓';
  margin-left: auto;
  font-weight: 700;
  color: var(--accent-light, #22d3ee);
}

@media (max-width: 480px) {
  .lang-menu {
    right: -8px;
    min-width: 180px;
  }
}

/* sr-only: aria-live announce 用 (視覚的に隠す) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* skip-link: キーボードユーザー向けのメインコンテンツ直行リンク。
   通常は画面外。:focus-visible で画面上部に滑り込む。topbar より高い
   z-index を取り、safe-area-inset-top を尊重する (PWA standalone)。*/
.skip-link {
  position: fixed;
  top: -100px;
  left: 0;
  z-index: 10000;
  padding: 12px 20px;
  background: var(--primary);
  color: #fff;
  font-weight: var(--fw-bold);
  text-decoration: none;
  border-radius: 0 0 var(--radius-sm) 0;
  transition: top 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.skip-link:focus,
.skip-link:focus-visible {
  top: env(safe-area-inset-top, 0px);
  outline: 2px solid var(--accent-light);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* Buttons - Premium Design */
.btn {
  position: relative;
  border: none;
  background: var(--surface-2);
  color: var(--text-primary);
  padding: 14px 28px;
  border-radius: 14px;
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  cursor: pointer;
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  border: 1px solid var(--border);
  white-space: nowrap;
}

.btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border-radius: var(--radius-circle);
  background: rgba(255, 255, 255, 0.1);
  transform: translate(-50%, -50%);
  transition: width 0.6s ease, height 0.6s ease;
}

.btn:hover::before {
  width: 300px;
  height: 300px;
}

.btn:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
  border-color: var(--border-strong);
}

.btn.primary {
  background: var(--gradient-primary);
  border: 1px solid var(--primary-light);
  box-shadow: 0 0 40px rgba(124, 58, 237, 0.6), 0 8px 24px rgba(0, 0, 0, 0.4);
  position: relative;
  overflow: hidden;
}

.btn.primary:hover {
  box-shadow: 0 0 80px rgba(124, 58, 237, 0.8), 0 12px 36px rgba(0, 0, 0, 0.5);
  transform: translateY(-4px) scale(1.03);
}

.btn.ghost {
  background: transparent;
  border: 1px solid var(--border-strong);
}

.btn.ghost:hover {
  background: var(--surface-2);
}

/* Main Content */
main {
  max-width: 1600px;
  margin: 0 auto;
  padding: 0 max(40px, env(safe-area-inset-right, 0px)) 60px max(40px, env(safe-area-inset-left, 0px));
}

/* Hero Section - Magazine Style */
.hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  align-items: center;
  padding: 80px 0;
  margin-bottom: 80px;
  position: relative;
}

.hero::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 1200px;
  height: 1200px;
  background: radial-gradient(circle, rgba(124, 58, 237, 0.25) 0%, rgba(6, 182, 212, 0.15) 30%, transparent 70%);
  opacity: 0.7;
  pointer-events: none;
  filter: blur(60px);
}

.eyebrow {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: var(--fs-xs);
  font-weight: var(--fw-black);
  color: var(--accent-light);
  margin-bottom: 24px;
  padding: 10px 20px;
  background: linear-gradient(135deg, rgba(124, 58, 237, 0.2), rgba(6, 182, 212, 0.2));
  border: 1px solid var(--accent);
  border-radius: 24px;
  box-shadow: 0 0 30px rgba(6, 182, 212, 0.3);
}

.hero h1 {
  font-size: clamp(3.5rem, 8vw, 6rem);
  font-weight: var(--fw-black);
  line-height: 1.05;
  margin: 0 0 32px;
  letter-spacing: -0.04em;
  background: linear-gradient(135deg, #ffffff 0%, #a78bfa 50%, #22d3ee 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: fadeInUp 0.8s ease-out;
  text-shadow: 0 0 80px rgba(124, 58, 237, 0.3);
}

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

/* Panel Sections */
.panel {
  margin: 100px 0;
  position: relative;
}

.panel h2 {
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: var(--fw-black);
  letter-spacing: -0.02em;
  position: relative;
  display: inline-block;
}

.panel h2::after {
  content: '';
  position: absolute;
  bottom: -12px;
  left: 0;
  width: 120px;
  height: 4px;
  background: var(--gradient-primary);
  border-radius: 2px;
  box-shadow: 0 0 20px rgba(124, 58, 237, 0.6);
}

.hint {
  color: var(--text-muted);
  font-size: var(--fs-lg);
  max-width: 500px;
}

/* Grid System */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 32px;
}

/* Cards - Premium Design */
.card {
  position: relative;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 32px;
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  opacity: 0;
}
.card[data-article-id] {
  cursor: pointer;
}

/* 記事カードのサムネイル画像（カード上端にフルブリード、16:9） */
.card-figure {
  margin: -32px -32px 20px -32px;
  overflow: hidden;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  aspect-ratio: 16 / 9;
  background: var(--surface-2);
  position: relative;
  z-index: 1;
}
.card-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}
/* placeholder SVG は zoom せず、実写真のみ hover ズーム */
.card:hover .card-image.card-image-photo {
  transform: scale(1.03);
}

.card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--gradient-primary);
  opacity: 0;
  transition: opacity 0.4s ease;
}

.card::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--gradient-primary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.card:hover {
  transform: translateY(-12px) scale(1.02);
  box-shadow: 0 25px 70px rgba(124, 58, 237, 0.4), 0 0 50px rgba(6, 182, 212, 0.2);
  border-color: var(--primary-light);
}

.card:hover::before {
  opacity: 0.08;
}

.card:hover::after {
  transform: scaleX(1);
  box-shadow: 0 0 20px rgba(124, 58, 237, 0.6);
}

.card h3 {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  margin: 0 0 16px;
  line-height: 1.3;
  position: relative;
  z-index: 1;
}

.summary {
  color: var(--text-secondary);
  margin: 16px 0;
  line-height: 1.7;
  position: relative;
  z-index: 1;
  /* 著作権配慮: ティーザーのみ表示し、詳細は元記事遷移前提。
     JS (createTeaser) で既に切り詰めているが CSS でも 2 行に制限するダブルセーフ */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.card-read-more {
  display: block;
  color: var(--accent-light);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  margin-top: 4px;
  position: relative;
  z-index: 1;
}

/* Badge */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: linear-gradient(135deg, rgba(124, 58, 237, 0.2), rgba(6, 182, 212, 0.2));
  border: 1px solid var(--primary);
  color: var(--primary-light);
  border-radius: var(--radius-xl);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  transition: all 0.3s ease;
  box-shadow: 0 0 20px rgba(124, 58, 237, 0.3);
}

/* Card date */
.card-date {
  display: block;
  font-size: var(--fs-sm);
  color: var(--text-hint);
  margin-bottom: 8px;
  font-style: normal;
}

/* Card head layout */
.card-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

.card-head .source {
  margin-left: auto;
  font-size: var(--fs-sm);
  color: var(--text-hint);
  font-weight: 500;
  /* バッジが多い時に溢れないよう省略 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  max-width: 60%;
}

/* Theme badge - same family as region badge, slightly subdued */
.badge-theme {
  background: rgba(124, 58, 237, 0.08);
  border-color: rgba(124, 58, 237, 0.35);
  color: rgba(167, 139, 250, 0.85);
  box-shadow: none;
  margin-left: 6px;
}

/* AI translation badge は SEO P1-5 で廃止 (論点 1 A+C ハイブリッド整合)。
   個別バッジは情報量ゼロのため、包括 AI 開示は footer (.footer-ai-disclosure)
   と /ai-policy §2.1 に集約。構造化データ NewsArticle.translator は seo.js で維持。 */

/* SSR 記事本文は標準では hidden 属性で隠す (SEO 用、人間ユーザーにはモーダル表示)。
   <noscript> で hidden 解除し JS 無効ユーザーが記事を閲覧できるようにする。 */
#article-ssr {
  display: none;
}

.badge:hover {
  background: linear-gradient(135deg, rgba(124, 58, 237, 0.3), rgba(6, 182, 212, 0.3));
  transform: scale(1.1);
  box-shadow: 0 0 30px rgba(124, 58, 237, 0.5);
}

/* Tags */
.tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 20px;
  position: relative;
  z-index: 1;
}

.tags span {
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 6px 14px;
  border-radius: var(--radius-lg);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  transition: all 0.3s ease;
  cursor: pointer;
}

.tags span:hover {
  background: var(--surface-3);
  border-color: var(--primary);
  color: var(--primary-light);
  transform: translateY(-2px);
}

/* Scripture & Prayer */
.scripture {
  background: rgba(20, 184, 166, 0.05);
  border-left: 4px solid var(--accent);
  padding: 24px;
  margin: 24px 0;
  border-radius: 0 16px 16px 0;
  position: relative;
  z-index: 1;
}

.scripture-ref {
  color: var(--accent-light);
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  margin-bottom: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.scripture-text {
  color: var(--text-secondary);
  font-style: italic;
  line-height: 1.8;
}

.prayer-box {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px;
  margin-top: 20px;
  position: relative;
  z-index: 1;
  transition: all 0.3s ease;
}

.prayer-box:hover {
  border-color: var(--primary);
  background: var(--surface-3);
}

.prayer-box strong {
  display: block;
  color: var(--accent);
  font-weight: var(--fw-bold);
  margin-bottom: 12px;
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.prayer-box.small {
  padding: 18px;
  font-size: var(--fs-md);
}

/* Facts List */
.facts {
  padding-left: 24px;
  margin: 20px 0;
  color: var(--text-secondary);
  position: relative;
  z-index: 1;
}

.facts li {
  margin: 12px 0;
  line-height: 1.7;
}

.facts li::marker {
  color: var(--accent);
  font-weight: bold;
}

/* Links */
.links {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 20px;
  position: relative;
  z-index: 1;
}

.links a {
  padding: 10px 20px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  transition: all 0.3s ease;
}

.links a:hover {
  background: var(--surface-3);
  border-color: var(--primary);
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
}

/* 翻訳プロキシ拒否サイト向けの常時表示ヒント */
.link-hint {
  font-size: var(--fs-sm);
  color: var(--text-muted, rgba(255, 255, 255, 0.5));
  align-self: center;
  line-height: 1.4;
}

/* Filters */
.filters {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

select {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  padding: 12px 20px;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: all 0.3s ease;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L6 6L11 1' stroke='%23a0a0a0' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 40px;
}

select:hover {
  border-color: var(--primary);
  background-color: var(--surface-3);
}

select:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
}

/* Devotion Section */
.devotion {
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: 24px;
  padding: 48px;
  position: relative;
  overflow: hidden;
}

.devotion::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--gradient-accent);
}

.devotion-card {
  background: var(--surface-2);
  border-color: var(--border-strong);
}

/* Footer */
/* 2026-05-05 fr GA Phase 2 v3: position:fixed + 1 行 inline layout。
 * 旧 v2 (2 行 grid) は web/PWA で見た目が悪く、PWA で異常に縦長になる問題があった。
 * 設計:
 *   Desktop: brand · tagline(ellipsis) · nav 4 リンク [right] © copy ── 1 行
 *   Mobile/PWA: brand · nav 4 リンク [right] © copy ── 1 行 (tagline 非表示)
 *   AI disclosure / attribution は冗長 (about/ai-policy で参照可能) のため非表示。
 * 想定高さ ~32px (1 行)、PWA mode は tab-bar の上に配置する。
 */
.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
  margin-top: 0;
  padding: 6px clamp(12px, 3vw, 24px) calc(6px + env(safe-area-inset-bottom, 0px));
  background: rgba(17, 17, 17, 0.94);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 10px 14px;
  flex-wrap: nowrap;
  overflow: hidden;
  font-size: 11px;
  line-height: 1.3;
}

.footer > div:first-child {
  display: flex;
  align-items: center;
  gap: 10px 14px;
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: nowrap;
  overflow: hidden;
}

.footer strong {
  font-size: 12px;
  font-weight: var(--fw-extrabold);
  background: var(--gradient-hero);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  white-space: nowrap;
  opacity: 0.95;
  flex-shrink: 0;
}

.footer > div:first-child > p[data-i18n="footer.tagline"] {
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-hint);
  opacity: 0.75;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 38ch;
}

.footer-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  flex-shrink: 0;
}

/* AI disclosure と attribution は冗長 (about/ai-policy で参照可能) のため hide。 */
.footer-ai-disclosure,
.footer .meta p[data-i18n="footer.attribution"] {
  display: none !important;
}

.footer .meta {
  flex-shrink: 0;
  text-align: right;
  margin-left: auto;
}

.footer p {
  color: var(--text-hint);
  margin: 0;
  line-height: 1.4;
  font-size: 10px;
}

.footer-link {
  color: var(--accent-light);
  text-decoration: none;
  font-weight: var(--fw-semibold);
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s ease;
}

.footer-link:hover,
.footer-link:focus-visible {
  border-bottom-color: var(--accent-light);
  outline: none;
}

/* Toast */
.toast {
  position: fixed;
  bottom: 32px;
  right: 32px;
  background: var(--gradient-primary);
  color: white;
  padding: 16px 28px;
  border-radius: var(--radius-lg);
  font-weight: var(--fw-bold);
  opacity: 0;
  transform: translateY(20px) scale(0.9);
  transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
  box-shadow: var(--glow);
  z-index: 10000;
  border: 1px solid var(--primary-light);
}

.toast.show {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* Announcement Banner — Web ブラウザ専用（PWA standalone では JS で非表示）。
   全文を 1 ブロックで常時表示するシンプル構造（icon + details + close）。 */
.announcement-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 16px 0 0;
  padding: 10px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  color: var(--text-secondary);
  font-size: var(--fs-base);
  line-height: 1.5;
}

.announcement-icon {
  flex-shrink: 0;
  font-size: var(--fs-lg);
  line-height: 1.4;
}

.announcement-body {
  flex: 1;
  min-width: 0;
}

.announcement-details {
  margin: 0;
  color: var(--text-muted);
  font-size: 12.5px;
  line-height: 1.6;
}

.announcement-close {
  flex-shrink: 0;
  align-self: flex-start;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--fs-xl);
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.announcement-close:hover {
  color: var(--text-primary);
  background: var(--surface-3);
}

@keyframes announcementHide {
  from {
    opacity: 1;
    max-height: 200px;
    margin-top: 16px;
    padding: 10px 14px;
  }
  to {
    opacity: 0;
    max-height: 0;
    margin-top: 0;
    padding: 0 14px;
    border-width: 0;
  }
}

.announcement-hiding {
  animation: announcementHide 0.3s ease-out forwards;
  overflow: hidden;
}

/* Loading States */
.loading {
  text-align: center;
  padding: 80px 20px;
  color: var(--text-muted);
  position: relative;
}

.loading::before {
  content: '';
  display: inline-block;
  width: 48px;
  height: 48px;
  margin-bottom: 20px;
  border: 3px solid var(--border);
  border-top-color: var(--primary);
  border-radius: var(--radius-circle);
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.error {
  color: #fca5a5;
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: var(--radius-lg);
  padding: 32px;
  margin: 40px 0;
  text-align: center;
}

/* showError() 構造化エラーステート (uiHelpers.js)
   棒読みの "エラー: Failed to fetch" を撤廃し、icon + 主タイトル + 詳細 + retry の 4 段構成 */
.error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 48px 24px;
  margin: 24px 0;
  border: 1px solid rgba(239, 68, 68, 0.25);
  background: rgba(239, 68, 68, 0.06);
  border-radius: var(--radius-lg);
  grid-column: 1 / -1;
}
.error-state__icon {
  font-size: 32px;
  line-height: 1;
  color: #fca5a5;
  margin-bottom: 4px;
}
.error-state__title {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.error-state__detail {
  margin: 0;
  font-size: var(--fs-base);
  color: var(--text-muted);
  max-width: 36ch;
  word-break: break-word;
}
.error-state__retry {
  margin-top: 12px;
  padding: 10px 24px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--text-primary);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.error-state__retry:hover:not(:disabled),
.error-state__retry:focus-visible {
  background: var(--surface-3);
  border-color: var(--primary);
  color: var(--primary-light);
  outline: none;
}
.error-state__retry:disabled {
  opacity: 0.6;
  cursor: progress;
}

.empty-message {
  text-align: center;
  padding: 80px 20px;
  color: var(--text-muted);
  font-style: italic;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;
  grid-column: 1 / -1;
}
.empty-state .empty-icon {
  font-size: 40px;
  display: block;
  margin-bottom: 12px;
}
.empty-state .empty-hint {
  color: var(--text-hint);
  font-size: var(--fs-base);
  margin: 8px 0 16px;
}
.empty-state .empty-reset {
  font-size: var(--fs-base);
  padding: 6px 20px;
  border-radius: var(--radius-xl);
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-primary);
  cursor: pointer;
  transition: all 0.2s ease;
}
.empty-state .empty-reset:hover {
  background: var(--surface-2);
  border-color: var(--primary);
  color: var(--primary);
}

/* --- Search Bar --- */
.search-row {
  padding: 8px 16px;
}
.search-wrapper {
  position: relative;
  flex: 1;
  max-width: 400px;
}
.search-input {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  color: var(--text-primary);
  padding: 7px 36px 7px 14px;
  font-size: var(--fs-base);
  font-family: inherit;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.search-input::placeholder {
  color: var(--text-hint);
}
.search-input:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.2);
}
.search-clear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--text-hint);
  font-size: var(--fs-lg);
  cursor: pointer;
  padding: 4px 6px;
  line-height: 1;
  border-radius: var(--radius-circle);
  transition: color 0.15s ease;
}
.search-clear:hover {
  color: var(--text-primary);
}
@media (max-width: 767px) {
  .search-wrapper {
    max-width: none;
  }
}

/* --- Date Separator --- */
.date-separator {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 0 8px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--text-hint);
  letter-spacing: 0.05em;
  grid-column: 1 / -1;
}
.date-separator::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* --- Load More Area --- */
.load-more-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 32px 16px;
  margin-top: 24px;
}
.load-more-count {
  font-size: var(--fs-base);
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.load-more-bar {
  width: 100%;
  max-width: 480px;
  height: 4px;
  background: var(--surface-2);
  border-radius: 2px;
  overflow: hidden;
}
.load-more-bar-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 2px;
  transition: width 0.4s ease;
}
.load-more-btn {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  padding: 10px 32px;
  border-radius: 24px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-primary);
  cursor: pointer;
  transition: all 0.2s ease;
  min-width: 200px;
}
.load-more-btn:hover {
  background: var(--surface-2);
  border-color: var(--primary);
  color: var(--primary);
}
.load-more-btn:disabled {
  opacity: 0.6;
  cursor: wait;
}
.load-more-end {
  font-size: var(--fs-base);
  color: var(--text-hint);
  text-align: center;
  line-height: 1.6;
}
@media (max-width: 767px) {
  .load-more-btn {
    width: 100%;
  }
}

/* Animations */
.fade-in-up {
  animation: fadeInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Stagger animations via custom property (set inline or via JS) */
.card {
  animation-delay: var(--stagger, 0s);
}

/* Responsive Design */
@media (max-width: 1200px) {
  .grid {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  }

}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 40px;
    padding: 60px 0;
  }

  main {
    padding: 0 24px 40px;
  }

  .topbar {
    padding: 16px 24px;
    flex-wrap: wrap;
  }

  .nav {
    order: 3;
    width: 100%;
    justify-content: center;
  }

  .filter-bar {
    border-radius: var(--radius-md);
  }

  .filter-label {
    display: none;
  }

  .panel {
    margin: 60px 0;
  }

  .devotion {
    padding: 32px 24px;
  }
}

@media (max-width: 640px) {
  main {
    padding: 0 max(20px, env(safe-area-inset-right, 0px)) 32px max(20px, env(safe-area-inset-left, 0px));
  }

  .hero {
    padding: 40px 0;
  }

  .hero h1 {
    font-size: 2.5rem;
  }

  .grid {
    padding: 12px 20px;
  }

  .topbar {
    padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 0;
    min-height: 48px;
  }

  /* mobile: 中央寄せ + 絶対配置だと narrow viewport で brand と actions が
     重なるため、space-between flex に切替（mobile 限定） */
  .topbar-top {
    justify-content: space-between;
    gap: 8px;
  }
  .topbar-top .actions {
    position: static;
    right: auto;
    flex-shrink: 0;
  }

  .brand {
    font-size: clamp(22px, 6vw, 32px);
    letter-spacing: -0.03em;
    /* mobile では brand をシュリンク許容 */
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    /* 2026-05-05 v6: 左端 hugged な見た目を緩和、半文字分右にオフセット */
    margin-left: 1em;  /* v8: 0.5em → 1em (font-size 1 つ分 ≈ 22-32px の右オフセット) */
  }

  .actions { gap: 6px; }
  .btn.btn-lang-toggle {
    padding: 8px 12px;
    font-size: var(--fs-sm);
    min-width: 52px;
  }
  /* 通常 ghost ボタン（ログイン等）も詰める。btn-icon と btn-lang-toggle は除外 */
  .topbar-top .actions .btn:not(.btn-icon):not(.btn-lang-toggle) {
    padding: 8px 14px;
    font-size: var(--fs-sm);
  }
  /* logout icon button: tap target を 38x38 に確保 */
  .topbar-top .actions .btn.btn-icon {
    width: 38px;
    height: 38px;
  }
  .topbar-top .actions .btn.btn-icon svg {
    width: 16px;
    height: 16px;
  }
  /* identity-link: アバター・名前のサイズを詰める */
  .identity-link {
    padding: 4px 10px 4px 4px;
    font-size: var(--fs-base);
    gap: 8px;
  }
  .identity-avatar {
    width: 26px;
    height: 26px;
    font-size: var(--fs-sm);
  }
  .identity-name {
    max-width: 88px;
  }

  .card {
    padding: 24px;
  }

  /* 2026-05-05 fr GA Phase 2 v3: mobile では tagline + brand を非表示にして
   * nav リンクを横スクロール可能にする。footer は ~32px の極薄バー。 */
  .footer {
    padding: 5px 10px calc(5px + env(safe-area-inset-bottom, 0px));
    gap: 8px;
    font-size: 10px;
  }

  /* mobile: tagline 非表示 (brand + nav + © のみ) */
  .footer > div:first-child > p[data-i18n="footer.tagline"] {
    display: none;
  }

  /* mobile: brand 非表示 (面積優先、nav リンクで充足) */
  .footer strong {
    display: none;
  }

  /* mobile: nav リンクは横スクロール (折り返さず 1 行) */
  .footer > div:first-child {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .footer > div:first-child::-webkit-scrollbar {
    display: none;
  }

  .footer-nav {
    gap: 10px;
    flex-wrap: nowrap;
  }

  .footer-nav .footer-link {
    white-space: nowrap;
    font-size: 10px;
  }

  /* mobile/PWA: © copy 全体を非表示 (Pattern C, 2026-05-05 v5)。
   * 32px の薄バーに ja/fr の 4 nav リンクを収めるため © を切る。
   * © は about.html / privacy.html に既存表記あり → 法的にも問題なし。 */
  .footer .meta {
    display: none;
  }

  /* フィルタ行のコンパクト化: ラベル非表示 + 行 padding 圧縮で
   * モバイル ヘッダー高さを ~140px → ~100px に短縮 */
  .filter-label {
    display: none;
  }

  .filter-row {
    padding: 6px 16px;
  }

  .region-tab,
  .theme-chip {
    font-size: var(--fs-sm);
  }

  .announcement-banner {
    margin: 12px 0 0;
    padding: 8px 12px;
    font-size: 12.5px;
    gap: 8px;
  }

  .announcement-icon {
    font-size: 15px;
  }

  .announcement-details {
    font-size: var(--fs-sm);
  }
}

/* Mobile (<768px): タップ領域を Apple HIG (44×44) に近づける */
@media (max-width: 767px) {
  .region-tab,
  .theme-chip {
    min-height: 40px;
    padding: 9px 14px;
    display: inline-flex;
    align-items: center;
  }
}

/* 2026-05-05 fr GA Phase 2 v2: 小型端末向け旧 normal flow rule は撤去
 * (footer 自体が ~36-50px の薄バーで縦積みは不要) */

/* iPhone SE / mini 向け: さらに詰めて縦スクロール量を削減 */
@media (max-width: 400px) {
  main {
    padding: 0 max(14px, env(safe-area-inset-right, 0px)) 24px max(14px, env(safe-area-inset-left, 0px));
  }

  .hero--digest {
    padding: 20px 14px;
  }

  .hero--digest .digest-headline {
    font-size: clamp(1.15rem, 5.2vw, 1.4rem);
  }

  .hero--digest .digest-summary {
    font-size: 0.9rem;
  }

  .filter-row {
    padding: 5px 14px;
  }

  .region-tab,
  .theme-chip {
    font-size: var(--fs-xs);
    padding: 8px 12px;
  }

  .panel {
    margin: 32px 0;
  }

  .section-header h2 {
    font-size: clamp(20px, 6vw, 24px);
  }

  .brand {
    font-size: var(--fs-xl);
  }
}

/* Accessibility */
*:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Performance optimizations */
.card,
.btn,
.badge,
.tags span {
  will-change: transform;
}

/* ── 試験運用中オーバーレイ (featureFlags.AUTH_TRIAL_MODE) ─────
   /auth/login.html で使用（過去 TOP とも共用していた経緯から styles.css に置く）。 */
.trial-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 17, 35, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: var(--z-sticky);
}
.trial-card {
  background: linear-gradient(135deg, rgba(155, 89, 182, 0.15), rgba(52, 152, 219, 0.12));
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius-xl);
  padding: 2.25rem 2rem;
  width: 100%;
  max-width: 460px;
  color: #fff;
  text-align: center;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.trial-emoji { font-size: 2rem; line-height: 1; }
.trial-card h2 {
  font-size: 1.35rem;
  margin: 0.25rem 0 1.25rem;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.02em;
}
.trial-card p {
  font-size: 0.98rem;
  line-height: 1.85;
  color: rgba(255, 255, 255, 0.92);
  margin: 0 0 0.75rem;
}
.trial-card p.trial-muted {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.9rem;
}
.trial-btn {
  display: inline-block;
  margin-top: 1.25rem;
  padding: 0.85rem 1.5rem;
  border-radius: 10px;
  border: none;
  font-size: 0.95rem;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  text-decoration: none;
  background: linear-gradient(135deg, #9b59b6 0%, #8e44ad 100%);
  color: #fff;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.trial-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(155, 89, 182, 0.4);
}

/* Article Modal */
.article-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  /* iOS PWA で背景 body への touch passthrough を抑止する。
     body 側で position:fixed scroll lock を撤去 (close 時の renderer hang 対策)
     したため、modal 全体で touch を捕捉する必要がある。
     modal-content には別途 touch-action: pan-y で内部スクロールを許可する。 */
  touch-action: none;
}

.article-modal-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(10px);
}

.article-modal-content {
  position: relative;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: 24px;
  max-width: 800px;
  width: 100%;
  /* dvh 優先 + vh フォールバック (古い iOS Safari は dvh 未対応) */
  max-height: 90vh;
  max-height: 90dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* parent の touch-action: none を上書きして垂直スクロールのみ許可。
     pinch-zoom も明示的に許可 (画像読みやすさ確保)。 */
  touch-action: pan-y pinch-zoom;
  box-shadow: var(--shadow-lg);
}

/* モバイル: モーダルをボトムシート化して画面幅を最大活用 */
@media (max-width: 500px) {
  .article-modal { padding: 0; align-items: flex-end; }
  .article-modal-content {
    max-width: 100vw;
    max-height: 92vh;
    max-height: 92dvh;
    border-radius: 16px 16px 0 0;
    /* iPhone home indicator dead zone を吸収 */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
}

/* Modal header: sticky で modal 上部に張り付き close ボタンを常に右上に保つ。
 * 旧 .article-modal-close に position:sticky + float:right を併用していたが、
 * sticky と float の組合せは CSS 仕様で挙動未定義 (iOS Safari の特定状況で
 * close ボタンが見えたり消えたりする) ため、header div に分離した。
 * - pointer-events:none で header 透過部分は modal 本文の scroll/click に干渉しない
 * - 内部の close ボタンは pointer-events:auto で touch/click を拾う */
.article-modal-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  justify-content: flex-end;
  padding: 1rem;
  pointer-events: none;
}
.article-modal-header > * {
  pointer-events: auto;
}

.article-modal-close {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-primary);
  width: 40px;
  height: 40px;
  border-radius: var(--radius-circle);
  font-size: 24px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.article-modal-close:hover {
  background: var(--surface-3);
  border-color: var(--primary);
  transform: scale(1.1);
}

.article-modal-image {
  width: 100%;
  height: 300px;
  object-fit: cover;
  border-radius: 24px 24px 0 0;
}

.article-modal-body {
  padding: 2rem;
}

.article-modal-meta {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.article-source {
  color: var(--accent-light);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-md);
}

.article-date {
  color: var(--text-muted);
  font-size: var(--fs-md);
}

.article-author {
  color: var(--text-muted);
  font-size: var(--fs-md);
  margin-bottom: 1.5rem;
}

.article-content {
  color: var(--text-secondary);
  line-height: 1.8;
  font-size: var(--fs-lg);
  margin-bottom: 1.5rem;
  white-space: pre-wrap;
}

/* News hook badge (Sprint 3 C5) — LLM が翻訳時に検出した報道角度カテゴリ */
.news-hook-badge {
  display: inline-block;
  padding: 4px 10px;
  margin: 8px 0 4px;
  border: 1px solid var(--accent);
  border-radius: 12px;
  background: rgba(6, 182, 212, 0.08);
  color: var(--accent-light);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* AI 翻訳ディスクロージャ (Sprint 3 H19) — 全記事 100% AI 翻訳の事実を本文上に明示 */
.ai-translation-disclosure {
  display: block;
  margin: 4px 0 12px;
  font-size: 11px;
  color: var(--text-hint);
  letter-spacing: 0.02em;
}

.article-links {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.article-links a {
  padding: 10px 20px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  transition: all 0.3s ease;
}

.article-links a:hover {
  background: var(--surface-3);
  border-color: var(--primary);
}

/* ─────────────────────────────────────────────────────────
   Article Share footer (記事モーダル下部のシェア導線)
   - X / LINE / URL コピー / Web Share (mobile only)
   - articleModal.js の buildShareFooter() が DOM を構築し、
     articleModalController.js の wireShareControls() が href / handler を bind
   ───────────────────────────────────────────────────────── */
.article-share {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.article-share-label {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-bottom: 0.75rem;
  font-weight: var(--fw-semibold);
}

.article-share-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.article-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
  /* button 要素の reset */
  font-family: inherit;
  line-height: 1.2;
}

.article-share-btn:hover,
.article-share-btn:focus-visible {
  background: var(--surface-3);
  border-color: var(--primary);
  color: var(--text);
}

.article-share-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.article-share-btn[hidden] {
  display: none;
}

/* href 未バインドの <a> シェアボタン (wireShareControls 失敗時のセーフティ) は無効化表示 */
a.article-share-btn:not([href]) {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.article-share-icon {
  flex: none;
}

/* X (旧 Twitter) — モノクロのままサイト基調に合わせる */
.article-share-btn-x:hover { color: #fff; background: #111; border-color: #111; }

/* LINE 公式色 */
.article-share-btn-line:hover { color: #fff; background: #06c755; border-color: #06c755; }

.article-share-status {
  margin-top: 0.5rem;
  min-height: 1.25em;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.article-share-status.is-error {
  color: var(--accent-light, #f87171);
}

@media (max-width: 480px) {
  .article-share-buttons { gap: 6px; }
  .article-share-btn { padding: 7px 11px; font-size: var(--fs-xs, 0.8rem); }
}

/* News Card with Image */
.news-card {
  cursor: pointer;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.news-card-thumb {
  width: 100%;
  height: 180px;
  border-radius: 20px 20px 0 0;
  overflow: hidden;
  position: relative;
  flex-shrink: 0;
}

.news-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.news-card-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.news-card-placeholder .placeholder-icon {
  font-size: 40px;
  line-height: 1;
}

.news-card-placeholder .placeholder-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: rgba(255,255,255,0.45);
  text-transform: uppercase;
  letter-spacing: 0.15em;
}

.news-card-body {
  padding: 24px;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.news-card-body h3 {
  margin: 0;
}

.news-card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: auto;
  padding-top: 12px;
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.source {
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

/* Language Toggle */
.lang-toggle {
  font-weight: var(--fw-bold);
  font-size: var(--fs-base);
  padding: 10px 16px;
  letter-spacing: 0.05em;
}

.lang-toggle:hover {
  color: var(--accent-light);
}

/* Responsive Modal */
@media (max-width: 640px) {
  .article-modal {
    padding: 1rem;
  }

  .article-modal-content {
    border-radius: var(--radius-lg);
  }

  .article-modal-image {
    height: 200px;
    border-radius: 16px 16px 0 0;
  }

  .article-modal-body {
    padding: 1.5rem;
  }
}

/* =========================================================
   Section Header (todaysBoard / regionDashboard / breaking 共通)
   ========================================================= */
.section-header {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
.section-header h2 {
  font-size: clamp(22px, 3.2vw, 30px);
  font-weight: var(--fw-bold);
  line-height: 1.25;
  margin: 0;
  color: var(--text, #e5e7eb);
  letter-spacing: 0.02em;
}
.section-sub {
  font-size: var(--fs-md);
  letter-spacing: 0.02em;
  color: var(--text-muted, #9ca3af);
}

/* =========================================================
   Region Digest Section (Phase 1 MVP / 12h cadence)
   設計 doc: 2026-04-27-multi-axis-digest.md §6.2 改 (2026-04-28)

   見た目は region-panel と揃え、枠線は撤廃する。
   主役は LLM が選んだ 5 記事 (リスト) で、サマリーは 1 行コンテキストに留める。
   ========================================================= */
/* .panel の margin に統合管理させる (重複した margin-bottom は削除、digest 間の隙間が大きすぎる問題への対応 2026-04-29) */
.region-digest-section { margin-bottom: 0; }

/* digest セクション → digest セクション / digest → panel--board の間は
   標準の panel margin (mobile 32px) を完全に消し、連続感を最大化する。
   読者は region 12h cadence → theme 12h cadence → live news の編集差を
   一目で見比べたいので、セクション分断を最小に (2026-04-29 PWA 反復)。
   prev (.region-digest-section) は margin-bottom: 0 なので margin-collapse は
   発生せず、ここで指定する margin-top がそのまま実 gap になる。
   panel--board は padding-top: 24px を持つので margin-top:0 でも視覚上 24px
   は確保される (header underline と digest card 上端の間の最小余白として機能)。 */
.region-digest-section + .region-digest-section,
.region-digest-section + .panel--board {
  margin-top: 0;
}

/* 同じ理由で digest カード下端の余白も詰める (default padding-bottom: 18px →
   8px)。LLM が選んだ 5 記事の最終行直下に視覚的な「終端記号」が無いため、
   そこから panel margin が 0 でも次セクションの h2 underline が壁として
   機能して整理感は保たれる。 */
body[data-layout="board"] .axis-digest-card.board-column {
  padding-bottom: 8px;
}

/* digest カードの list は固定 5 件 (LLM 選定) なので、flex:1 で空白を吸収
   させない (board の生記事カードは可変件数なので flex:1 を維持)。
   .region-digest-row 側に align-items: flex-start を入れていても、card 内部
   の list が `flex: 1` だと 280px min-height との差を空白で埋めてしまう。 */
body[data-layout="board"] .axis-digest-card .board-column-list {
  flex: 0 0 auto;
}
.region-digest-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
@media (max-width: 900px) { .region-digest-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .region-digest-row { grid-template-columns: 1fr; } }

/* PWA / board layout: 横スワイプ slider (todaysBoard の board-columns と同挙動) */
body[data-layout="board"] .region-digest-row {
  display: flex;
  grid-template-columns: none;
  gap: 16px;
  overflow-x: auto;
  overflow-y: visible;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding-bottom: 0;
  margin-bottom: 0;
  scroll-padding-inline: 4px;
  /* flex の default stretch だと最も背の高いカードに合わせて他カードも伸び、
     items 少ないカードの底部に空白が出る (visual gap が大きく見える原因)。
     flex-start で各カードを自身のコンテンツ高さに収める。 */
  align-items: flex-start;
}
body[data-layout="board"] .region-digest-row::-webkit-scrollbar {
  display: none;
}
/* モバイル 1 列幅では mandatory で「次のカード」にスッと吸着させる (board と統一) */
@media (max-width: 480px) {
  body[data-layout="board"] .region-digest-row {
    scroll-snap-type: x mandatory;
  }
}
@media (prefers-reduced-motion: reduce) {
  body[data-layout="board"] .region-digest-row {
    scroll-behavior: auto;
  }
}

/* PWA: digest カード (= board-column) を board-columns と同じ可変幅にし snap 単位化。
   board-column 自体は既に min-height: 280px / background / border-radius 等が
   定義済みなので、ここでは横並び slider 用の flex/snap だけを足す。
   2026-05-02: viewport 基準 (calc(100vw - 80px)) は scrollbar 出現時に再計算で
   親 max-width を突き抜けて右見切れを起こすため、親幅基準 (calc(100% - 48px))
   に変更。値は board-column と統一。 */
body[data-layout="board"] #regionDigestRow > .board-column.axis-digest-card {
  flex: 0 0 min(400px, calc(100% - 48px));
  scroll-snap-align: start;
}

/* digest 固有: head の直下に挿入する 1-2 文 context (任意、空文字なら省略) */
.axis-digest-context {
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--text-muted, #9ca3af);
  margin: 0 0 0.6rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px dashed rgba(148, 163, 184, 0.15);
}

/* digest 固有: 「最終更新 N 時間前」メタ行 (axisDigestContext.js injectAxisDigestMeta)。
   board (生記事) との編集差を一目で示す。context が空でも単独で表示する。 */
.axis-digest-meta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-xs);
  line-height: 1.4;
  color: var(--text-muted, #9ca3af);
  margin: 0 0 0.6rem;
  letter-spacing: 0.01em;
  cursor: help;
}
.axis-digest-meta::before {
  content: '🕒';
  font-size: 10px;
}

/* =========================================================
   Region Dashboard (3×2 グリッド)
   ========================================================= */
.region-dashboard { margin-bottom: 1.5rem; }
.region-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
@media (max-width: 900px) { .region-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .region-grid { grid-template-columns: 1fr; } }

.region-panel {
  background: rgba(30, 41, 59, 0.55);
  border: 1px solid rgba(139, 92, 246, 0.18);
  border-radius: 14px;
  padding: 1rem 1.1rem 0.9rem;
  display: flex;
  flex-direction: column;
  min-height: 220px;
  transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.region-panel:hover {
  border-color: rgba(139, 92, 246, 0.45);
  background: rgba(30, 41, 59, 0.7);
  transform: translateY(-2px);
}
.region-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
  padding-bottom: 0.55rem;
  border-bottom: 1px solid rgba(148, 163, 184, 0.15);
}
.region-panel-title {
  font-size: 1rem;
  font-weight: var(--fw-semibold);
  color: var(--text, #e5e7eb);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.region-panel-count {
  font-size: 0.75rem;
  color: var(--text-muted, #9ca3af);
  background: rgba(139, 92, 246, 0.12);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
}
.region-panel-list {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  flex: 1;
}
.region-panel-item {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.4rem 0.5rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.12s ease;
}
.region-panel-item:hover {
  background: rgba(139, 92, 246, 0.08);
}
.region-panel-item-title {
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--text, #e5e7eb);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* 長い英語 URL / 単語 (例: "Quantitative Tightening") が grid 子要素を突き抜けて
     右側見切れを起こすのを防ぐ。line-clamp と併用しても安全。 */
  overflow-wrap: anywhere;
  word-break: break-word;
}
.region-panel-item-meta {
  font-size: 0.72rem;
  color: var(--text-muted, #9ca3af);
  display: flex;
  gap: 0.5rem;
}
.region-panel-item-meta .dot { opacity: 0.5; }
.region-panel-empty {
  font-size: 0.85rem;
  color: var(--text-muted, #9ca3af);
  padding: 0.5rem;
  text-align: center;
}
.region-panel-more {
  align-self: flex-start;
  background: transparent;
  border: none;
  color: #a78bfa;
  font-size: 0.82rem;
  font-weight: 500;
  padding: 0.3rem 0;
  cursor: pointer;
  transition: color 0.12s ease;
}
.region-panel-more:hover { color: #c4b5fd; text-decoration: underline; }

/* 既読カード: スキャン時は薄く後ろに引く (タッチ端末では常に薄表示)
 * NOTE: 一部カード (.card) の opacity は .fade-in-up animation が制御しているため、
 *       既読のディミングは子要素側に適用する（.article-highlight と同じ衝突回避方針）。
 *
 * Phase 2 (全カード種別に拡張):
 *   - .card                   : breaking_news (createNewsCard)
 *   - .board-snippet          : Today's Board (boardSection.buildSnippet)
 *   - .digest-highlight-card  : hero digest highlight (digestSection)
 *   - .region-panel-item      : region/theme digest 列項目 (regionPanel)
 *
 * region-panel-item は内部に .region-panel-item-link を挟むため、子セレクタの
 * 階層が 1 段深い点に注意（個別ルールで対応）。
 *
 * Phase 2.2 (タッチ端末の sticky :hover / :focus-within 排除):
 *   :focus-within での opacity 復帰は撤去 (closeArticleModal が a11y 標準に従い
 *   modalTriggerEl.focus() でフォーカスを戻すため、tap 直後に薄表示が即座に
 *   全色に戻る UX バグ)。
 *   :hover での復帰も @media (hover: hover) で「実ホバー可能なデバイス」に限定。
 *   iOS Safari / Android Chrome のタッチ端末は tap 後に :hover が sticky に
 *   残り続ける仕様 (次の tap まで :hover 解除されない) で、これも同様に
 *   「タップ → modal 閉じる → 薄表示が元に戻る」UX バグを引き起こすため。
 *   キーボードユーザーは focus outline で位置がわかるので dim 維持で問題ない。
 */
.card.is-read > *,
.board-snippet.is-read > *,
.digest-highlight-card.is-read > * {
  opacity: 0.65;
  transition: opacity 0.2s ease;
}
.region-panel-item.is-read > .region-panel-item-link > * {
  opacity: 0.65;
  transition: opacity 0.2s ease;
}
.card.is-read h3,
.board-snippet.is-read .board-snippet-title,
.digest-highlight-card.is-read .digest-highlight-title,
.region-panel-item.is-read .region-panel-item-title {
  color: var(--text-muted);
  transition: color 0.2s ease, opacity 0.2s ease;
}

/* マウスデバイス限定の :hover 復帰。
 * iOS / Android のタッチ端末は (hover: none) なのでこのブロックは適用されず、
 * 既読カードは常に薄表示となる (sticky :hover による「元に戻る」現象を回避)。 */
@media (hover: hover) {
  .card.is-read:hover > *,
  .board-snippet.is-read:hover > *,
  .digest-highlight-card.is-read:hover > * {
    opacity: 1;
  }
  .region-panel-item.is-read:hover > .region-panel-item-link > * {
    opacity: 1;
  }
  .card.is-read:hover h3,
  .board-snippet.is-read:hover .board-snippet-title,
  .digest-highlight-card.is-read:hover .digest-highlight-title,
  .region-panel-item.is-read:hover .region-panel-item-title {
    color: var(--text-primary);
  }
}

/* 地域別ダイジェストから遷移した記事カードのフラッシュハイライト
 * NOTE: .fade-in-up の animation shorthand を上書きしないよう、transition + outline ベースで実装する
 */
.card.article-highlight {
  outline: 2px solid rgba(139, 92, 246, 0.9);
  outline-offset: 2px;
  box-shadow: 0 0 24px rgba(139, 92, 246, 0.55);
  transition: outline-color 1.2s ease-out, box-shadow 1.2s ease-out;
}

/* ───────────────────────────────────────────
 * News card skeleton (読込中 placeholder)
 * 実カード (.card) と同じ外寸・figure 比率を持ち、描画完了時の layout shift を抑える。
 * ─────────────────────────────────────────── */
.card.card-skeleton {
  opacity: 1; /* .card の opacity:0 (fade-in-up 前提) を打ち消す */
  pointer-events: none;
}
.card-skeleton .skeleton-figure {
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.09) 50%, rgba(255,255,255,0.04) 100%);
  background-size: 200% 100%;
  animation: skeletonPulse 1.6s ease-in-out infinite;
}
.card-skeleton .skeleton-chip {
  display: inline-block;
  width: 68px;
  height: 20px;
  border-radius: 10px;
  background: rgba(255,255,255,0.06);
  margin-right: 8px;
}
.card-skeleton .skeleton-line {
  height: 14px;
  margin: 10px 0;
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.10) 50%, rgba(255,255,255,0.05) 100%);
  background-size: 200% 100%;
  animation: skeletonPulse 1.6s ease-in-out infinite;
}
.card-skeleton .skeleton-title {
  height: 20px;
  margin-top: 14px;
}
.card-skeleton .skeleton-line-short {
  width: 65%;
}
@keyframes skeletonPulse {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .card-skeleton .skeleton-figure,
  .card-skeleton .skeleton-line { animation: none; }
}

/* ───────────────────────────────────────────
 * Hero digest skeleton (heroDigest 取得待機中の placeholder)
 * 実描画と同じ DOM 階層で .digest-headline / .digest-summary / .digest-highlights の
 * 中身だけ shimmer 付き block に置換する。@keyframes skeletonPulse は上記 .card-skeleton と共用。
 * ファイル末尾のグローバル prefers-reduced-motion クエリで反復アニメは一括抑制される。
 * ─────────────────────────────────────────── */
.hero--digest-skeleton {
  /* skeleton 中は実描画前のチラつき・誤クリックを防ぐ（aria-hidden の li も含めて一括無効化） */
  pointer-events: none;
}
.hero--digest-skeleton .digest-date::before {
  /* 日付テキストが空のときアクセント縦線だけ浮くのを防ぐ */
  display: none;
}
.skeleton-block {
  display: block;
  height: 14px;
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.10) 50%, rgba(255,255,255,0.05) 100%);
  background-size: 200% 100%;
  animation: skeletonPulse 1.6s ease-in-out infinite;
}
.skeleton-block--headline {
  height: clamp(28px, 4vw, 36px);
  width: 88%;
  border-radius: 6px;
}
.skeleton-block--summary {
  height: 16px;
  margin: 8px 0;
  width: 100%;
}
.skeleton-block--short {
  width: 62%;
}
.skeleton-block--card-title {
  height: 14px;
  width: 90%;
}
.skeleton-block--card-meta {
  height: 11px;
  width: 55%;
  margin-top: 6px;
}
.skeleton-figure {
  /* 幅・高さはホスト要素 (.digest-highlight-thumb 等) が指定する。
     既存 .card-skeleton .skeleton-figure (specificity 0,2,0) はスコープ済みなので衝突しない。 */
  background: linear-gradient(90deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.09) 50%, rgba(255,255,255,0.04) 100%);
  background-size: 200% 100%;
  animation: skeletonPulse 1.6s ease-in-out infinite;
}

/* Hero Daily Digest */
.hero--digest {
  /* 上下のパディングと date→headline の余白を詰めて、ヘッダー直下から見出しまでの
     縦の死に空間 (PWA 縦長 viewport で特に目立つ) を圧縮。横は既存維持 */
  padding: 28px 24px 32px;
  /* PWA standalone (notch / Dynamic Island) で左右の安全領域を尊重。
     viewport-fit=cover を index.html で有効化済み。 */
  padding-left: max(24px, env(safe-area-inset-left, 24px));
  padding-right: max(24px, env(safe-area-inset-right, 24px));
  background: linear-gradient(180deg, rgba(124, 58, 237, 0.05), rgba(6, 182, 212, 0.03), transparent);
  border-bottom: 1px solid var(--border);
  margin-bottom: 24px;
}
/* ── アンビェントフォト + summary toggle 要素 ───────────────
 * PC / mobile web では非表示。@media (display-mode: standalone) で初めて表示する。
 * (HTML 上は常に存在するが視覚的にゼロ影響) */
.digest-ambient,
.digest-ambient-vignette,
.digest-summary-toggle {
  display: none;
}
.hero--digest .digest-date {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: clamp(12px, 1vw, 14px);
  font-weight: var(--fw-bold);
  color: var(--accent-light, #22d3ee);
  margin-bottom: 6px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
/* 日付の前に短い縦線アクセントを置き、紙面の「日付ライン」風にする */
.hero--digest .digest-date::before {
  content: '';
  display: inline-block;
  width: 28px;
  height: 2px;
  background: linear-gradient(90deg, var(--accent, #06b6d4), var(--primary-light, #a78bfa));
  border-radius: 1px;
}
.hero--digest .digest-headline {
  font-size: clamp(1.5rem, 4vw, 2rem);
  font-weight: var(--fw-extrabold);
  line-height: 1.3;
  margin: 0 0 16px;
  color: var(--text-primary);
}

/* hero fallback (sessionStorage 復元) 描画時の「前回取得分」notice。
   通常成功時は hidden で非表示。stale 描画時のみ visible になり、ユーザーに
   「最新ではない」ことを警告する。色は warning 寄り (amber/orange) にして
   通常の date ラベル (cyan/accent) と区別。 */
.digest-stale-notice {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  margin: 0 0 10px;
  border-radius: var(--radius-sm, 6px);
  background: rgba(245, 158, 11, 0.12); /* amber-500/12 */
  border: 1px solid rgba(245, 158, 11, 0.4);
  color: #fbbf24; /* amber-400 */
  font-size: 12px;
  font-weight: var(--fw-semibold, 600);
  letter-spacing: 0.02em;
}
.digest-stale-notice[hidden] {
  display: none;
}
.digest-stale-notice::before {
  content: '⚠';
  font-size: 13px;
  line-height: 1;
}
.hero--digest .digest-summary {
  font-size: 1rem;
  line-height: 1.8;
  color: var(--text-secondary);
  margin: 0 0 20px;
}

/* v3.5-evidence-linked: 文単位でホバー/タップすると根拠記事ポップオーバー */
.hero--digest .digest-summary--sentenced {
  /* 文を横並びで流し込む。<span> の折返しは inline 要素として自然に処理される */
  word-break: auto-phrase; /* safari 対応: normal へフォールバック */
}
.digest-sentence {
  text-decoration: underline dotted;
  text-decoration-color: color-mix(in srgb, currentColor 38%, transparent);
  text-decoration-thickness: 1.2px;
  text-underline-offset: 3px;
  cursor: pointer;
  border-radius: 3px;
  transition: background 0.15s, text-decoration-color 0.15s;
}
.digest-sentence:hover,
.digest-sentence:focus-visible {
  background: color-mix(in srgb, var(--accent, #3b82f6) 10%, transparent);
  text-decoration-color: currentColor;
  outline: none;
}
.digest-sentence--no-evidence {
  /* 根拠記事が引けない文はインタラクション対象外として下線も消す */
  text-decoration: none;
  cursor: default;
}

/* Popover: 文→根拠記事リスト (ダークテーマ前提、viewer 既存トークンを使用) */
.digest-evidence-popover {
  position: absolute;
  z-index: 40;
  max-width: min(360px, calc(100vw - 24px));
  min-width: 220px;
  background: var(--surface-2, #1a1a1a);
  color: var(--text-primary, #ffffff);
  border: 1px solid var(--border-strong, rgba(255, 255, 255, 0.15));
  border-radius: 10px;
  box-shadow: var(--shadow-md, 0 8px 30px rgba(0, 0, 0, 0.4));
  padding: 10px 12px;
  font-size: 0.875rem;
  line-height: 1.5;
}
.digest-evidence-popover__label {
  margin: 0 0 8px;
  font-size: 0.7rem;
  color: var(--text-hint, #707070);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--fw-semibold);
}
.digest-evidence-popover__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.digest-evidence-popover__item {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-primary, #ffffff);
  font: inherit;
  line-height: 1.45;
  transition: background 0.12s;
}
.digest-evidence-popover__item:hover,
.digest-evidence-popover__item:focus-visible {
  background: var(--surface-3, #222222);
  outline: none;
}
.digest-evidence-popover__source {
  display: block;
  margin-top: 2px;
  color: var(--text-muted, #a0a0a0);
  font-size: 0.8em;
}

/* ───────────────────────────────────────────────────────────
 * Evidence bottom sheet (PWA / タッチ端末)
 * 2026-04-30 UX feedback: sentence 直下の popover が読書面に被るため、
 * PWA / touch 環境では画面下端に固定する bottom sheet 形態に切替。
 * デスクトップは引き続き .digest-evidence-popover を使用。
 * ─────────────────────────────────────────────────────────── */
.digest-evidence-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 1900;
  opacity: 0;
  transition: opacity 240ms cubic-bezier(0.4, 0, 0.2, 1);
  /* 背景 body への touch passthrough を抑止 (body の position:fixed lock を撤去
     したため、backdrop 側で touch を捕捉する必要がある)。
     articleModal と同じ pattern (commit 0530c98)。 */
  touch-action: none;
}
.digest-evidence-sheet-backdrop.is-open {
  opacity: 1;
}

.digest-evidence-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1950;
  /* 上半分は読書領域として残す: 50dvh を上限、内容が短ければ縮む */
  max-height: min(50dvh, 480px);
  background: var(--surface-1, #111);
  border-top: 1px solid var(--border-strong, rgba(255, 255, 255, 0.15));
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -16px 48px rgba(0, 0, 0, 0.6);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  display: flex;
  flex-direction: column;
  /* iPhone home indicator dead zone を吸収 */
  padding-bottom: env(safe-area-inset-bottom, 0px);
  /* 初期は画面外、is-open でスライドイン */
  transform: translateY(100%);
  transition: transform 280ms cubic-bezier(0.32, 0.72, 0, 1);
  will-change: transform;
  /* sheet 内部は垂直 scroll を許可、pinch-zoom も維持 */
  touch-action: pan-y pinch-zoom;
  overscroll-behavior: contain;
}
.digest-evidence-sheet.is-open {
  transform: translateY(0);
}

/* 上端の grab handle (装飾) */
.digest-evidence-sheet::before {
  content: '';
  display: block;
  width: 38px;
  height: 4px;
  margin: 8px auto 0;
  background: rgba(255, 255, 255, 0.28);
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}

.digest-evidence-sheet__header {
  padding: 12px 18px 14px;
  border-bottom: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  flex-shrink: 0;
}

.digest-evidence-sheet__label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.digest-evidence-sheet__label {
  margin: 0;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--accent-light, #22d3ee);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.digest-evidence-sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  border-radius: var(--radius-circle);
  color: var(--text-muted, #a0a0a0);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
  font-family: inherit;
  padding: 0;
}
.digest-evidence-sheet__close:hover,
.digest-evidence-sheet__close:focus-visible {
  background: var(--surface-2, #1a1a1a);
  color: var(--text-primary, #fff);
  border-color: var(--border-strong, rgba(255, 255, 255, 0.15));
  outline: none;
}

/* どの文への参照か明示する引用プレビュー (2 行クランプ) */
.digest-evidence-sheet__quote {
  margin: 0;
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--text-muted, #a0a0a0);
  font-style: italic;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.digest-evidence-sheet__quote::before {
  content: '“';
  margin-right: 2px;
  color: var(--accent, #06b6d4);
  font-style: normal;
}
.digest-evidence-sheet__quote::after {
  content: '”';
  margin-left: 2px;
  color: var(--accent, #06b6d4);
  font-style: normal;
}

.digest-evidence-sheet__list {
  list-style: none;
  margin: 0;
  padding: 8px 12px max(12px, env(safe-area-inset-bottom, 12px));
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
}

.digest-evidence-sheet__item {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: 12px 14px;
  cursor: pointer;
  color: var(--text-primary, #fff);
  font: inherit;
  line-height: 1.45;
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.digest-evidence-sheet__item:hover,
.digest-evidence-sheet__item:focus-visible {
  background: var(--surface-2, #1a1a1a);
  border-color: var(--border-strong, rgba(255, 255, 255, 0.15));
  outline: none;
}
.digest-evidence-sheet__item:active {
  transform: scale(0.99);
}

.digest-evidence-sheet__title {
  display: block;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  line-height: 1.45;
  margin-bottom: 4px;
}

.digest-evidence-sheet__source {
  display: block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--accent-light, #22d3ee);
  letter-spacing: 0.04em;
}

/* reduced-motion: アニメーションを切り、即座に表示 */
@media (prefers-reduced-motion: reduce) {
  .digest-evidence-sheet,
  .digest-evidence-sheet-backdrop {
    transition: none;
  }
}

/* Hero highlight articles (3–5 cards) */
.hero--digest .digest-highlights-wrap {
  margin-top: 24px;
}
.hero--digest .digest-highlights-title {
  font-size: 0.85rem;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 0 0 12px;
}
.hero--digest .digest-highlights {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
.hero--digest .digest-highlight-card {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 12px;
  padding: 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  width: 100%;
  color: inherit;
  font: inherit;
  transition: background 120ms ease, transform 120ms ease, border-color 120ms ease;
}
.hero--digest .digest-highlight-card:hover,
.hero--digest .digest-highlight-card:focus-visible {
  background: rgba(255, 255, 255, 0.08);
  border-color: var(--accent-light, rgba(124, 58, 237, 0.6));
  transform: translateY(-1px);
  outline: none;
}
.hero--digest .digest-highlight-thumb {
  width: 96px;
  height: 64px;
  border-radius: 6px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.05);
  flex-shrink: 0;
}
.hero--digest .digest-highlight-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.hero--digest .digest-highlight-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hero--digest .digest-highlight-title {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.4;
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hero--digest .digest-highlight-meta {
  font-size: 0.75rem;
  color: var(--text-muted);
  display: flex;
  gap: 8px;
  align-items: center;
}
/* カードと元記事リンクを同じ視覚コンテナに収める。<li> を relative にして
   外部リンクアイコンをカード右上隅に重ねる（button 内に a を置けない制約回避）。*/
.hero--digest .digest-highlights > li {
  position: relative;
}
.hero--digest .digest-highlight-external {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  line-height: 1;
  color: var(--accent-light, #22d3ee);
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background 120ms ease, border-color 120ms ease, transform 120ms ease, color 120ms ease;
  z-index: 2;
}
.hero--digest .digest-highlight-external:hover,
.hero--digest .digest-highlight-external:focus-visible {
  background: rgba(124, 58, 237, 0.35);
  border-color: var(--accent-light, #22d3ee);
  color: #fff;
  transform: translateY(-1px);
  outline: none;
  text-decoration: none;
}

/* Mobile (<640px): compact カードで縦スクロールを短くする */
@media (max-width: 639px) {
  .hero--digest {
    padding: 24px 16px;
  }
  .hero--digest .digest-headline {
    font-size: clamp(1.25rem, 5vw, 1.5rem);
  }
  .hero--digest .digest-summary {
    font-size: 0.95rem;
    line-height: 1.6;
  }
  .hero--digest .digest-highlights-wrap {
    margin-top: 20px;
  }
  .hero--digest .digest-highlight-card {
    grid-template-columns: 80px 1fr;
    gap: 10px;
    padding: 8px;
  }
  .hero--digest .digest-highlight-thumb {
    width: 80px;
    height: 56px;
  }
  .hero--digest .digest-highlight-title {
    font-size: 0.88rem;
  }
  .hero--digest .digest-highlight-meta {
    font-size: 0.7rem;
  }
  /* タップ領域を 32×32 に拡大（44px ガイドラインに近づける） */
  .hero--digest .digest-highlight-external {
    width: 32px;
    height: 32px;
    top: 4px;
    right: 4px;
    font-size: 0.95rem;
  }
}

/* Tablet (640–1023px): hero は縦積みのまま、highlights だけ 2 col 化 */
@media (min-width: 640px) and (max-width: 1023px) {
  .hero--digest .digest-highlights {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 14px;
  }
}

/* Desktop (1024–1399px): hero を 2 col に、右カラム内の highlights は 2 col コンパクト化 */
@media (min-width: 1024px) {
  .hero--digest {
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: 40px;
    padding: 56px 32px;
    align-items: start;
    overflow: hidden; /* 長 URL / 幅要素の右流出を物理的に遮断 */
  }
  .hero--digest > * {
    min-width: 0; /* grid child の overflow を防ぐ（長文要素の強制折返し） */
  }
  .hero--digest .digest-highlights-wrap {
    margin-top: 0;
  }
}

/* Desktop 以上 (1024px+): hero 2 col layout だが右カラム内の highlights は常に 1 col。
   カードは viewport に応じてコンパクト化する。1 col 統一で読みやすさを優先。 */
@media (min-width: 1024px) {
  .hero--digest .digest-highlights {
    grid-template-columns: 1fr;
    gap: 10px;
  }
}

/* Desktop 中 (1024-1399px): 右カラム 500-700px 想定でカードをコンパクト化 */
@media (min-width: 1024px) and (max-width: 1399px) {
  .hero--digest .digest-highlight-card {
    grid-template-columns: 72px 1fr;
    gap: 10px;
    padding: 8px;
  }
  .hero--digest .digest-highlight-thumb {
    width: 72px;
    height: 54px;
  }
  .hero--digest .digest-highlight-title {
    font-size: 0.9rem;
    line-height: 1.4;
    -webkit-line-clamp: 2;
  }
  .hero--digest .digest-highlight-meta {
    font-size: 0.72rem;
  }
  .hero--digest .digest-highlight-external {
    top: 4px;
    right: 4px;
    width: 28px;
    height: 28px;
    font-size: 0.85rem;
  }
}

/* Wide (≥1400px): 右カラムを広めにし、1 col でゆったり */
@media (min-width: 1400px) {
  .hero--digest {
    grid-template-columns: 1fr 1.4fr;
    gap: 48px;
    padding: 64px 40px;
  }
  .hero--digest .digest-highlights {
    gap: 14px;
  }
}

/* ============================================================
 * PWA standalone Hero — アンビエントフォト案 (2026-04-30)
 * ホーム画面から起動された PWA のみ適用。PC / mobile web は無影響。
 *
 * 設計意図: 文字が「飛び込んでくる」フィードバックに対し、
 *   1) 背景にアンビエント写真 (top highlight の image_url)
 *   2) 大文字 headline の fadeInUp 0.8s + translateY(30px) を解除
 *   3) headline + summary を viewport 下部に寄せ、上部に余白を確保
 * の 3 点で「気配で伝える」hero に切り替える。
 * 写真が無いときは CSS gradient フォールバックで暗い単色背景になる。
 * ============================================================ */
@media (display-mode: standalone) {
  .hero--digest {
    /* 既存 padding を解除し、digest-text に押し戻す (写真領域を full-bleed にするため) */
    padding: 0;
    background: none;
    border-bottom: none;
    margin-bottom: 24px;
    /* 1 col grid に固定 (Wide breakpoint の 2 col grid を打ち消す) */
    grid-template-columns: 1fr !important;
    gap: 0 !important;
  }
  .hero--digest .digest-text {
    position: relative;
    /* 2026-05-01: 70vh → 50vh に縮小。iPhone 縦長 viewport で「date と headline の
       間に大きな空白」と感じられる実機 feedback を反映。写真ヒーローの "気配" は
       残しつつ、見出しが画面内に収まる縦サイズへ。 */
    min-height: 50vh;
    /* overflow: hidden は撤去 (2026-04-30): summary 展開時に line-clamp 切替で
       iOS PWA の renderer が hang し、画面 scroll もブロックされる事案
       ("テキストを下にスクロールしても画面がついてこない") の根本対策。
       ambient layer (.digest-ambient / -vignette) は inset:0 で digest-text の
       box に収まるため overflow:hidden が無くても外にはみ出さない。 */
    isolation: isolate; /* z-index ローカル化 */
    display: flex;
    flex-direction: column;
    padding: 28px max(20px, env(safe-area-inset-left, 20px)) 36px;
  }

  /* 写真レイヤー (z-index: -2) — JS が backgroundImage を流し込む */
  .digest-ambient {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -2;
    /* fallback: 写真未設定時の暗いグラデ */
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 60%, #0a0a14 100%);
    background-size: cover;
    background-position: center;
    filter: saturate(0.85) contrast(0.95);
  }
  /* Vignette (z-index: -1) — 端を暗くしてテキストを浮き立たせる */
  .digest-ambient-vignette {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
      linear-gradient(180deg, rgba(10, 10, 20, 0.55) 0%, rgba(10, 10, 20, 0.32) 35%, rgba(10, 10, 20, 0.85) 100%),
      radial-gradient(ellipse at center, transparent 30%, rgba(10, 10, 20, 0.5) 100%);
  }

  /* Date は viewport 上部に固定 (DOM 順で先頭) */
  .hero--digest .digest-date {
    align-self: flex-start;
    margin-bottom: 0;
    color: var(--accent-light, #22d3ee);
  }

  /* Headline + summary を viewport 下部寄りに配置。
     経緯:
       2026-05-05 (Phase 1):    margin-top:auto → clamp(48px,12vh,96px)
                                 ただし元 auto 実値 (~136px @ iPhone 14) から 96px へ約 30%
                                 縮小しか達成せず実機 feedback「変わっていない」
       2026-05-05 (Phase 1.1):  clamp(48px,12vh,96px) → 32px (固定値)
                                 元 ~136px から 32px へ約 76% 縮小 (user 要求の「1/3」相当)
                                 静的 chrome に clamp は不要 / 制御性・デバッグ容易性を優先
     気配 hero (写真 + 短いリード + action) の差別化は min-height:50vh で維持。 */
  .hero--digest .digest-headline {
    margin-top: 32px;
    margin-bottom: 14px;
    /* 既存 fadeInUp 0.8s + translateY(30px) を打ち消す */
    animation: heroFadePwa 0.25s ease-out !important;
    /* グラデ文字 → 白 (写真背景で読みやすさ優先) */
    background: none !important;
    -webkit-text-fill-color: #fff !important;
    color: #fff !important;
    text-shadow: 0 2px 16px rgba(0, 0, 0, 0.5);
    /* 長すぎる headline は 3 行で抑える (フォールバック) */
    font-size: clamp(28px, 7.5vw, 44px);
    line-height: 1.2;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Summary はリードとして 5 行に抑える。続きは「続きを読む」action button で展開。
     2026-04-30 実機 feedback の経緯:
       1) clamp(2) → 2 行で truncate されたが action 不在で続きが読めなかった
       2) clamp 撤去 → 全文出てヒーローが text dump になり「気配 hero」消失
       3) clamp(2) + action button (.digest-summary-toggle) で「頭だけ + action」に着地
     2026-05-05 (Phase 2 / 2.1):
       4) clamp(2) → clamp(4): Phase 1.1 で余白縮小したが「テキスト 2 行のままで
          物足りない」feedback。当初要求 (4 行表示) に合わせ拡張。
       5) clamp(4) → clamp(5): Phase 2 後「もう 1 行分だけ広く」feedback で微調整。
          action button は維持し「リード 5 行 + 続きを読む」へ更新。
     展開時は .is-expanded で line-clamp を解除する。 */
  .hero--digest .digest-summary {
    color: rgba(255, 255, 255, 0.88);
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .hero--digest .digest-summary.is-expanded {
    -webkit-line-clamp: unset;
    display: block;
    overflow: visible;
  }

  /* 「続きを読む」/ 「閉じる」action button (PWA 専用)。
     2026-05-01: brand 紫 gradient → ニュートラル glass に変更。「閉じる」は
     副次アクションで brand を主張する場面ではない。写真背景の上で色相を消す
     ことで、Apple Photos の controls と同じく「行儀よく浮かぶ」表現に。
     icon は ▼/▲ Unicode から CSS chevron (border 回転)。 */
  .digest-summary-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
    padding: 10px 20px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: var(--radius-pill);
    background: rgba(0, 0, 0, 0.42);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    backdrop-filter: blur(20px) saturate(140%);
    color: #fff;
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    transition:
      background 220ms cubic-bezier(0.4, 0, 0.2, 1),
      border-color 220ms ease,
      box-shadow 220ms ease,
      transform 220ms ease;
    box-shadow:
      0 6px 22px rgba(0, 0, 0, 0.45),
      inset 0 1px 0 rgba(255, 255, 255, 0.14);
  }
  .digest-summary-toggle:hover,
  .digest-summary-toggle:focus-visible {
    background: rgba(0, 0, 0, 0.55);
    border-color: rgba(255, 255, 255, 0.34);
    transform: translateY(-1px);
    box-shadow:
      0 10px 30px rgba(0, 0, 0, 0.5),
      inset 0 1px 0 rgba(255, 255, 255, 0.2);
    outline: none;
  }
  .digest-summary-toggle:active {
    transform: translateY(0);
  }
  /* CSS chevron — border 2 辺で矢印を作り transform で回転させる。
     収納時は ▼ 相当 (下向き)、.is-expanded 時は ▲ 相当 (上向き)。 */
  .digest-summary-toggle::before {
    content: '';
    width: 7px;
    height: 7px;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    transform: rotate(45deg) translate(-1px, -2px);
    transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  .hero--digest .digest-summary.is-expanded + .digest-summary-toggle::before {
    transform: rotate(-135deg) translate(1px, 2px);
  }

  /* sentence span 内のリンク色も白寄りに */
  .hero--digest .digest-summary .digest-sentence {
    color: inherit;
  }

  /* Highlights は 70vh の hero 下に自然に流れる (DOM 順で digest-text の後)。
     特別な再配置は不要。ただし上部マージンを少し空けて区切りを明示する。 */
  .hero--digest .digest-highlights-wrap {
    margin-top: 24px;
    padding: 0 max(20px, env(safe-area-inset-left, 20px));
  }

  @keyframes heroFadePwa {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* prefers-reduced-motion 対応: heroFadePwa も抑制 */
}
@media (display-mode: standalone) and (prefers-reduced-motion: reduce) {
  .hero--digest .digest-headline { animation: none !important; }
}

/* ============================================================
 * Responsive hardening (OS / browser / viewport robustness)
 * ============================================================ */

/* ── 1. ルート overflow ガード ───────────────────────────── */
/* html/body/main が viewport を超えないよう `100%` 基準で width を束ねる。
   critical CSS の main は width:100% を追加済。ここでは念押しと safe-area 統合。 */
html, body {
  max-width: 100%;
}

/* ── 2. safe-area を考慮した main padding ─────────────────
   critical CSS は clamp(16px,4vw,40px) で viewport 依存。
   iOS notch / Android navigation bar などの env(safe-area-inset-*) も保証する。 */
@supports (padding: max(0px)) {
  body.page--viewer main {
    padding-left: max(clamp(16px, 4vw, 40px), env(safe-area-inset-left, 0px));
    padding-right: max(clamp(16px, 4vw, 40px), env(safe-area-inset-right, 0px));
  }
  .topbar {
    padding-left: max(clamp(16px, 4vw, 40px), env(safe-area-inset-left, 0px));
    padding-right: max(clamp(16px, 4vw, 40px), env(safe-area-inset-right, 0px));
  }
}

/* ── 3. 長単語・URL の overflow 防止 ──────────────────────
   日本語/英語混在・SNS URL・長カタカナ語などで親幅を超える現象を全体抑止。
   見出し・本文・カード title に限定適用（コード表示や pre は除外したいので深く広げない）。 */
.digest-headline,
.digest-summary,
.digest-highlight-title,
.digest-highlight-meta,
.board-column-title,
.board-snippet-title,
.board-snippet-source,
.announcement-details,
.pwa-view-title {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* grid/flex child の min-width: 0 で親幅を超えない */
.hero--digest .digest-highlight-body,
.hero--digest .digest-text,
.hero--digest .digest-highlights-wrap,
.board-column > *,
.board-snippet > *,
.region-panel > * {
  min-width: 0;
}

/* 画像コンテナが aspect-ratio 非対応ブラウザでも高さ維持 */
.hero--digest .digest-highlight-thumb,
.board-snippet-figure {
  flex-shrink: 0;
}

/* ── 4. announcement banner を main 幅内に収める ──────── */
.announcement-banner {
  max-width: 100%;
  box-sizing: border-box;
}

.announcement-banner .announcement-details {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ── 5. iOS Safari 100vh ずれ & Android Chrome URL bar 対策 ──
   dvh (dynamic viewport height) 対応ブラウザでは URL bar の伸縮を自動追従 */
@supports (height: 100dvh) {
  body.page--viewer {
    min-height: 100dvh;
  }
}

/* ── 6. overflow-x fallback (Safari 15 以前 / Firefox 旧版) ──
   body に overflow-x: clip を設定済 (index.html critical)。非対応環境は
   先行の overflow-x: hidden 宣言で fallback する二段指定を critical 側で行っている */

/* ── 7. scrollbar 非表示 fallback ──────────────────────── */
@supports not (scrollbar-width: none) {
  .board-columns,
  .board-theme-strip {
    scrollbar-color: transparent transparent;
  }
}

/* ── 8. hero--digest は常時 overflow: hidden で内部要素の右流出を遮断 ── */
.hero--digest {
  overflow: hidden;
}

/* ── 9. モバイル (<640px) ファイン調整 ──────────────────── */
@media (max-width: 639px) {
  /* main padding を更に縮めて狭い viewport での content 幅を確保 */
  body.page--viewer main {
    padding-left: max(12px, env(safe-area-inset-left, 0px));
    padding-right: max(12px, env(safe-area-inset-right, 0px));
  }
  .topbar {
    padding-left: max(12px, env(safe-area-inset-left, 0px));
    padding-right: max(12px, env(safe-area-inset-right, 0px));
  }
  /* 見出しフォントは .section-header h2 の @media (max-width:768px) override に委譲。
     panel--board 固有の override は撤去（統一スタイル）。 */
}

/* ── 10. printing（稀だが robust の一環）──────────────── */
@media print {
  .topbar,
  .pwa-tab-bar,
  .breaking-expander,
  .board-column-more {
    display: none !important;
  }
}

/* ── 11. reduced-motion 対応（全 hover / transition をキャンセル） ── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =============================================================
 * 11. Utility Classes
 * ============================================================= */

/* 表示制御 */
.u-hidden { display: none; }

/* padding-top */
.u-pt-100 { padding-top: 100px; }

/* リンクの下線除去（topbar の brand 等で使用） */
.u-no-underline { text-decoration: none; color: inherit; }

/* メンバー系サブページ用の中央寄せレイアウト */
.page-main {
    max-width: 880px;
    margin: 0 auto;
    padding: 2rem 1.25rem 4rem;
}
@media (max-width: 640px) {
    .page-main { padding: 1.25rem 0.75rem 3rem; }
}

/* テキスト色 */
.u-text-white { color: #fff; }
.u-text-muted-7 { color: rgba(255, 255, 255, 0.7); }

/* margin-bottom */
.u-mb-4 { margin-bottom: 1rem; }
.u-mb-8 { margin-bottom: 2rem; }

/* テキスト装飾 */
.u-no-underline { text-decoration: none; }

/* about ページ固有 hint テキスト */
.u-about-hint {
  margin-top: 16px;
  color: var(--text-hint);
  font-size: var(--fs-base);
}

/* devotions ページ pagination の pageInfo span */
.u-page-info {
  color: #fff;
  padding: 0.5rem 1rem;
}

/* =============================================================
 * 12. ユーザー環境設定対応 (reduced-motion / standalone / backdrop-filter)
 * ============================================================= */

/* アニメーション抑制: OS の reduced-motion 設定を尊重。背景 mesh の
 * 20s 無限ループや hover transform を無効化し、CPU / バッテリーを節約。 */
@media (prefers-reduced-motion: reduce) {
  body::before {
    animation: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* PWA standalone: ブラウザ UI が無い状態。
 * - 背景アニメを停止しバッテリー持続を優先
 * - topbar 背景を完全不透明化し、透過時の色滲みを防止 */
@media (display-mode: standalone) {
  body::before {
    animation: none;
    opacity: 0.6;
  }

  .topbar {
    background: rgb(0, 0, 0);
  }

  /* ホーム画面から開いた PWA ではスクロール時の rubber band を抑制 */
  html {
    overscroll-behavior-y: none;
  }
}

/* Service Worker 更新バナー
 * sw-register.js が「新しいバージョンが利用可能です」を動的に挿入する際の見た目。
 * 画面下部に fixed で配置し、safe-area-inset-bottom を尊重。 */
.sw-update-banner {
  position: fixed;
  left: 16px;
  right: 16px;
  top: calc(16px + env(safe-area-inset-top, 0px));
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: rgba(15, 23, 42, 0.95);
  color: #fff;
  border: 1px solid rgba(148, 163, 184, 0.3);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  font-size: var(--fs-md);
  animation: sw-update-banner-slide 0.3s ease-out;
}

@keyframes sw-update-banner-slide {
  from {
    transform: translateY(-20px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.sw-update-msg {
  flex: 1;
  min-width: 0;
  line-height: 1.4;
}

.sw-update-apply {
  flex-shrink: 0;
  padding: 8px 16px;
  background: var(--accent-light, #7c3aed);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background 0.2s ease;
}

.sw-update-apply:hover:not(:disabled) {
  background: var(--primary-light, #a78bfa);
}

.sw-update-apply:disabled {
  opacity: 0.6;
  cursor: default;
}

.sw-update-dismiss {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  padding: 0;
  background: transparent;
  color: rgba(255, 255, 255, 0.7);
  border: none;
  border-radius: var(--radius-circle);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.sw-update-dismiss:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

/* backdrop-filter 未対応ブラウザ向けフォールバック
 * （Android Chrome 旧版や一部 in-app browser） */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topbar {
    background: rgba(0, 0, 0, 0.98);
  }

  .footer {
    background: rgba(17, 17, 17, 0.98);
  }
}

/* 高コントラスト優先のユーザー向け: 透過を弱める */
@media (prefers-reduced-transparency: reduce) {
  .topbar {
    background: rgb(0, 0, 0);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .footer {
    background: rgb(17, 17, 17);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* ============================================================ */
/* Today's Board (feature/news-list-ux-redesign)                */
/* 地域列 + テーマ帯で 24h を並置する「読者主導の探索層」        */
/* layout=board 時のみ表示、legacy は region-dashboard を温存    */
/* ============================================================ */

.panel--board {
  padding-top: 24px;
}

/* section-header 自体は .section-header / .section-sub の統一ルールに委譲。
   Today's Board 固有の override は不要（regionDashboard / breaking と完全統一）。 */

.board-loading {
  color: var(--text-hint);
  font-size: var(--fs-base);
  padding: 32px 0;
  text-align: center;
}

/* Q2 fix: grid→flex で横スクロールを常時有効化。
   ワイドスクリーンでは 4 列自然にフィット、narrow ではスワイプで次列へ移動できる。
   scroll-snap で「列」単位で止まるスワイプ感覚を提供する。 */
.board-columns {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  overflow-y: visible;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  /* スクロールバー非表示 (wheel 縦→横変換 + trackpad swipe で操作可能) */
  scrollbar-width: none;
  padding-bottom: 0;
  margin-bottom: 24px;
  scroll-padding-inline: 4px;
}

.board-columns::-webkit-scrollbar {
  display: none;
}

/* モバイル 1 列表示幅では mandatory で「次までスッと」吸着させる */
@media (max-width: 480px) {
  .board-columns {
    scroll-snap-type: x mandatory;
  }
}

/* OS の動き低減設定を尊重 */
@media (prefers-reduced-motion: reduce) {
  .board-columns {
    scroll-behavior: auto;
  }
}

.board-column {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 280px;
  /* 2026-05-02: viewport 基準 (calc(100vw - 80px)) はスクロールバー出現時に
     再計算で親 max-width を突き抜け、PWA で右側見切れを起こす。
     親幅基準 (calc(100% - 48px)) に切り替え、min(400px, ...) で上限維持。 */
  flex: 0 0 min(400px, calc(100% - 48px));
  scroll-snap-align: start;
}

/* 6 列固定、常に横スクロールできる設計。
   2000px 超のワイドなら全列が視界に入るが、その場合でも overflow-x: auto は無害
   （親幅以下なら scrollbar が出ないので、視覚的な副作用もない）。*/

.board-column-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.board-column-icon {
  font-size: 20px;
  line-height: 1;
}

.board-column-title {
  font-size: 15px;
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  margin: 0;
  letter-spacing: 0.01em;
}

.board-column-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}

.board-column-empty {
  font-size: var(--fs-sm);
  color: var(--text-hint);
  text-align: center;
  padding: 20px 0;
  margin: 0;
}

.board-column-more {
  margin-top: 4px;
  padding: 8px 12px;
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  border-radius: 10px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.board-column-more:hover,
.board-column-more:focus-visible {
  color: var(--text-primary);
  border-color: var(--primary);
  background: rgba(124, 58, 237, 0.08);
  outline: none;
}

.board-snippet {
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.board-snippet:last-child {
  border-bottom: none;
}

.board-snippet:hover,
.board-snippet:focus-visible {
  opacity: 0.85;
  outline: none;
}

.board-snippet-title {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  margin: 0 0 4px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* 長い英語タイトルが board-column 内の幅を突き抜けて
     右側見切れを起こすのを防ぐ。line-clamp と併用しても安全。 */
  overflow-wrap: anywhere;
  word-break: break-word;
}

.board-snippet-meta {
  display: flex;
  gap: 8px;
  font-size: var(--fs-xs);
  color: var(--text-hint);
  align-items: center;
}

.board-snippet-source {
  font-weight: var(--fw-semibold);
}

/* Q3 fix: 右端フェードとスクロールバー明示化で「続きがある」ことを伝える */
.board-theme-wrap {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
  position: relative;
}

/* 2 本目以降のテーマ帯は区切り線を薄めに、間隔も詰める（縦の間延び抑制） */
.board-theme-wrap + .board-theme-wrap {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px dashed var(--border);
}

.board-theme-head {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0 0 12px;
}

.board-theme-strip {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  /* スクロールバー非表示。続きがあることは右端フェードで示唆する */
  scrollbar-width: none;
  padding-bottom: 0;
  scroll-snap-type: x mandatory;
}

.board-theme-strip::-webkit-scrollbar {
  display: none;
}

/* 右端フェード: 親 wrap に絶対配置で overlay（pointer-events: none で操作透過） */
.board-theme-wrap::after {
  content: '';
  position: absolute;
  top: 36px; /* board-theme-head + margin 分を下げる */
  right: 0;
  bottom: 0;
  width: 48px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--bg-primary, #000) 80%);
  z-index: 1;
  border-radius: 0 0 8px 0;
}

/* テーマ帯の snippet は写真付きカード。地域列の文字ベースと対比を作る */
.board-theme-strip .board-snippet {
  flex: 0 0 240px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0;
  background: var(--surface-1);
  scroll-snap-align: start;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.board-snippet-figure {
  width: 100%;
  aspect-ratio: 16 / 9;
  margin: 0;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.04);
  flex-shrink: 0;
}

.board-snippet-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.25s ease;
}

/* 実写真のみ hover ズーム、placeholder は拡大しない（変形を避ける） */
.board-snippet-image--photo {
  object-position: center;
}

.board-theme-strip .board-snippet:hover .board-snippet-image--photo,
.board-theme-strip .board-snippet:focus-visible .board-snippet-image--photo {
  transform: scale(1.04);
}

.board-theme-strip .board-snippet-title {
  padding: 10px 12px 4px;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 1;
}

.board-theme-strip .board-snippet-meta {
  padding: 0 12px 10px;
  margin: 0;
}

/* ── Breaking expander (layout=board 時のみ折りたたみ UI) ── */

.breaking-expander {
  margin-top: 24px;
}

.breaking-expander > .breaking-summary {
  cursor: pointer;
  padding: 12px 16px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  list-style: none;
  font-size: var(--fs-md);
  transition: color 0.15s ease, border-color 0.15s ease;
}

.breaking-expander > .breaking-summary::-webkit-details-marker {
  display: none;
}

.breaking-expander > .breaking-summary::after {
  content: ' →';
  color: var(--primary);
}

.breaking-expander[open] > .breaking-summary::after {
  content: ' ↓';
}

.breaking-expander > .breaking-summary:hover,
.breaking-expander > .breaking-summary:focus-visible {
  color: var(--text-primary);
  border-color: var(--primary);
  outline: none;
}

/* legacy 時: details の summary を隠し、内容を常時平文扱いにする */
body[data-layout="legacy"] .breaking-expander > .breaking-summary {
  display: none;
}

body[data-layout="legacy"] .breaking-expander {
  margin-top: 0;
}

/* board 時: summary ボタンは常時非表示。expander は app.js の制御で
   検索・地域ドリルダウン時のみ hidden 解除される */
body[data-layout="board"] .breaking-expander > .breaking-summary {
  display: none;
}

/* ============================================================ */
/* PWA Topic Tabs (Phase 2: feature/news-list-ux-redesign)       */
/* PWA standalone or viewport ≤768px で下部タブバー＆view 切替   */
/* ============================================================ */

/* デフォルト非表示: desktop では PWA view も TabBar も見えない */
.pwa-view {
  display: none;
}

.pwa-tab-bar {
  display: none;
}

/* PWA mode (standalone or ≤768px) では Bottom Tab に一本化、上部の重複 chip を隠す。
   data-pwa-hide="1" は index.html の地域 row / 分野 row / ソース row / 検索 row に付与。
   フィルタ機能自体は tabRouter.js の picker view + PWA icon row から維持される。 */
body[data-pwa-active="1"] [data-pwa-hide="1"] {
  display: none;
}
/* 検索アイコンタップ時に search-row を一時表示するためのオーバーライド */
body[data-pwa-active="1"] [data-pwa-hide="1"][data-pwa-toggle-visible="1"] {
  display: flex;
}

/* data-pwa-show 要素は PWA モードで flex 表示（breadcrumb 等） */
body[data-pwa-active="1"] [data-pwa-show="1"] {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
}
/* PWA mode: ロゴは少しだけ大きめ（ただしモバイルで悪目立ちしない範囲） */
body[data-pwa-active="1"] .brand {
  font-size: clamp(32px, 7vw, 52px);
  letter-spacing: -0.03em;
}
body[data-pwa-active="1"] .topbar {
  padding-bottom: 4px;
}

/* PWA: brand 行と filter 行の間隔を最小化（Issue 1: ヘッダー下の不要な隙間） */
body[data-pwa-active="1"] .topbar-top {
  margin-bottom: 4px;
}

/* PWA: header-filter 内の filter rows は data-pwa-hide="1" で全て非表示。
   残るのは breadcrumb のみ。空のときは container ごと畳んで dead space を排除。 */
body[data-pwa-active="1"] .header-filter {
  border-top: none;
}
body[data-pwa-active="1"]:not([data-has-active-filter="1"]) .header-filter {
  display: none;
}
/* 検索オープン時は header-filter 親コンテナも強制表示（子の .search-row だけでは
   親が display:none のため画面に出ない問題への対処） */
body[data-pwa-active="1"][data-search-open="1"] .header-filter {
  display: block;
}

/* PWA mode で検索クエリが入力されている間のみ、検索結果 (#breakingExpander)
   以外の今日のセクションを隠して結果に集中できるようにする。
   E 改善 (2026-04-30): 旧版は data-search-open (= 検索 row の可視) で hide
   していたが、空欄で開いただけでも 5 セクションが消えるため、複合フィルタ
   操作中の layout shift が大きすぎた。data-search-active (= クエリ実行中)
   に切り替え、空欄→入力→空欄でセクションが復帰するようにする。 */
body[data-pwa-active="1"][data-search-active="1"] #heroDigest,
body[data-pwa-active="1"][data-search-active="1"] #regionDigestSection,
body[data-pwa-active="1"][data-search-active="1"] #themeDigestSection,
body[data-pwa-active="1"][data-search-active="1"] #todaysBoard,
body[data-pwa-active="1"][data-search-active="1"] #regionDashboard {
  display: none !important;
}

/* iOS Safari は input の font-size < 16px のとき focus 時に自動 zoom し、
   PWA mode ではその結果フッタータブが画面外へ押し出される / レイアウトが
   崩れる問題が起きる。PWA mode では .search-input を 16px に上げて auto-zoom
   を抑止する。デスクトップ表示は 13px のまま影響を受けない。 */
body[data-pwa-active="1"] .search-input {
  font-size: var(--fs-lg);
}

/* PWA × narrow viewport: 旧版は actions を絶対配置していたが、brand と重なるため撤去。
   通常モードと同じ flex space-between レイアウトに統一。サイズだけ PWA 用に微調整。 */
@media (max-width: 640px) {
  body[data-pwa-active="1"] .brand {
    /* PWA のロゴ強調を mobile では揃える */
    font-size: clamp(22px, 6vw, 32px);
  }
  body[data-pwa-active="1"] .topbar-top .actions .btn:not(.btn-icon) {
    padding: 6px 12px;
    font-size: 11.5px;
    border-radius: 10px;
  }
}

/* 超 narrow（< 360px / iPhone SE 等）: 保険として更に詰める */
@media (max-width: 360px) {
  .brand {
    font-size: 20px;
    letter-spacing: -0.04em;
  }
  .actions { gap: 4px; }
  .btn.btn-lang-toggle {
    padding: 6px 10px;
    min-width: 44px;
    font-size: var(--fs-xs);
  }
  .topbar-top .actions .btn:not(.btn-icon):not(.btn-lang-toggle) {
    padding: 6px 10px;
    font-size: var(--fs-xs);
  }
  .identity-name { max-width: 60px; }
}

/* breadcrumb: 現在の active フィルタを示す小 chip 群 */
.pwa-breadcrumb {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  justify-content: center;
}
.pwa-breadcrumb:empty {
  display: none;
}
.pwa-breadcrumb-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: rgba(124, 58, 237, 0.18);
  border: 1px solid rgba(124, 58, 237, 0.4);
  color: var(--text-primary);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.pwa-breadcrumb-clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: var(--fs-md);
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-circle);
}
.pwa-breadcrumb-clear:hover,
.pwa-breadcrumb-clear:focus {
  background: rgba(255, 255, 255, 0.12);
  color: var(--text-primary);
}

/* body[data-pwa-active="1"] を tabRouter.js が立てた時のみ有効化 */
/* 2026-05-05 v6: footer を画面最下端に置き、tab-bar はその上にオフセット。
 * footer 総高さ = 6+20+6+env(safe-area) ≈ 32 + safe-area。
 * tab-bar bottom = footer 総高さ = 32 + safe-area。
 * 設計詳細は line 136 周辺コメント参照。 */
body[data-pwa-active="1"] .pwa-tab-bar {
  display: flex;
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  left: 0;
  right: 0;
  z-index: 900;
  background: rgba(0, 0, 0, 0.95);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border-top: 1px solid var(--border-strong);
  padding: 8px 0;  /* safe-area-inset-bottom は footer 側で処理 */
  justify-content: space-around;
  align-items: stretch;
}

/* PWA では topbar を上部固定、下のタブバー分の padding とあわせて main 上下を確保 */
body[data-pwa-active="1"] .topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
body[data-pwa-active="1"] main {
  /* 上: topbar (brand + actions のみ) 高さ。breadcrumb なしの最小値。
     ブランド最大 52px + 上下 padding + safe-area で 108px 程度。
     下: タブバー 80px + safe-area。
     breadcrumb (active filter chip) がある時は has-active-filter で +52px 拡張。 */
  padding-top: calc(108px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px));
}
body[data-pwa-active="1"][data-has-active-filter="1"] main {
  padding-top: calc(160px + env(safe-area-inset-top, 0px));
}
/* デスクトップ幅では topbar が縦方向に詰まる */
@media (min-width: 641px) {
  body[data-pwa-active="1"] main {
    padding-top: calc(96px + env(safe-area-inset-top, 0px));
  }
  body[data-pwa-active="1"][data-has-active-filter="1"] main {
    padding-top: calc(140px + env(safe-area-inset-top, 0px));
  }
}

.pwa-tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 0;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-family: inherit;
  transition: color 0.15s ease, transform 0.1s ease;
  -webkit-tap-highlight-color: transparent;
}

.pwa-tab:active {
  transform: scale(0.95);
}

.pwa-tab-icon {
  font-size: var(--fs-2xl);
  line-height: 1;
}

.pwa-tab-label {
  font-size: 10px;
  font-weight: var(--fw-bold);
  letter-spacing: 0.03em;
}

.pwa-tab.active {
  color: var(--primary);
}

/* アクション系タブ (トップ / ソース / 検索 等) は通常タブと同じ muted 色で統一し、
   active view タブ（今日/地域/テーマ）の紫色ハイライトと差をつけない。
   色のばらつきはむしろタブバーの整列感を損なうため避ける。 */

/* P2-a (2026-04-29): picker を bottom sheet に変更。
   旧仕様は view=region/theme で today セクション群を display:none にして
   全画面 picker を見せていた。新仕様は today を背景に残したまま、画面下から
   sheet をスライドアップさせる。背景の今日のリストが透けて見えることで
   絞り込みの効果を即時プレビューできる。

   既存の `.pwa-view { display: none }` (desktop 用) は残し、PWA mode では
   常に DOM 描画 + transform で表示制御する。 */
body[data-pwa-active="1"] .pwa-view {
  display: block;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  max-height: 70vh;
  overflow-y: auto;
  /* picker view は backdrop (z-index:1500) より上、modal (z-index:2000) より下。 */
  z-index: 1600;
  background: var(--bg-primary, #fff);
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.18);
  /* 下方向に 100% 移動 = 画面外。tabBar 高さ分だけ底上げしてから隠す */
  transform: translateY(100%);
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
  /* tabBar (~80px) + safe-area の重なりを避けるため余白を持つ */
  padding: 12px 16px calc(env(safe-area-inset-bottom, 0px) + 96px);
  pointer-events: none;
}

body[data-pwa-active="1"][data-pwa-view="region"] #pwaRegionView,
body[data-pwa-active="1"][data-pwa-view="theme"] #pwaThemeView {
  transform: translateY(0);
  pointer-events: auto;
}

/* sheet 表示中は背景 main を tap/scroll しないよう半透明 backdrop を被せる。
   topbar (z-index:1000) より上 = picker view より下 の階層に置く。
   旧 z-index:49 は topbar に隠れて backdrop tap が topbar にインターセプトされ、
   sheet を閉じられない bug があった (e2e 検出 2026-04-30)。 */
.pwa-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 1500;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease-out;
}

body[data-pwa-active="1"][data-pwa-view="region"] .pwa-sheet-backdrop,
body[data-pwa-active="1"][data-pwa-view="theme"] .pwa-sheet-backdrop {
  opacity: 1;
  pointer-events: auto;
}

/* view 内のレイアウト */
.pwa-view-title {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-extrabold);
  margin: 24px 0 20px;
  text-align: center;
  color: var(--text-primary);
}

/* picker view を閉じる × ボタン (右上)。backdrop tap と機能は同じだが、
   明示的に「閉じる」アフォーダンスを示すために配置する。 */
.pwa-view-close {
  position: absolute;
  top: 8px;
  right: 12px;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--radius-circle);
  color: var(--text-muted);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  transition: color 0.12s ease, background 0.12s ease;
}

.pwa-view-close:hover,
.pwa-view-close:focus-visible {
  color: var(--text-primary);
  background: var(--surface-1);
  outline: none;
}

.pwa-region-grid,
.pwa-theme-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  padding: 8px 0 40px;
}

.pwa-region-btn,
.pwa-theme-btn {
  padding: 18px 14px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  font-size: 15px;
  font-weight: var(--fw-semibold);
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
  font-family: inherit;
  -webkit-tap-highlight-color: transparent;
  min-height: 60px;
}

.pwa-region-btn:active,
.pwa-theme-btn:active {
  transform: scale(0.97);
  background: var(--surface-2);
  border-color: var(--primary);
}

.pwa-region-btn:focus-visible,
.pwa-theme-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* モバイル時も board の横スクロール UI は維持（snack feed の一体感） */
@media (max-width: 600px) {
  body[data-pwa-active="1"] .board-column {
    flex: 0 0 min(280px, calc(100vw - 48px));
    min-height: 220px;
  }
}

/* ── Q4 fix: PWA/narrow viewport で hero digest の横見切れ対策 ── */
body[data-pwa-active="1"] main {
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}

body[data-pwa-active="1"] .hero--digest {
  padding-left: max(16px, env(safe-area-inset-left, 16px));
  padding-right: max(16px, env(safe-area-inset-right, 16px));
  padding-top: 32px;
  padding-bottom: 32px;
  margin-left: calc(-1 * max(16px, env(safe-area-inset-left, 0px)));
  margin-right: calc(-1 * max(16px, env(safe-area-inset-right, 0px)));
}

body[data-pwa-active="1"] .hero--digest .digest-headline,
body[data-pwa-active="1"] .hero--digest .digest-summary {
  overflow-wrap: anywhere;
  word-break: break-word;
}

body[data-pwa-active="1"] .hero--digest .digest-highlight-card {
  grid-template-columns: 72px 1fr;
  gap: 10px;
  padding: 8px;
}

body[data-pwa-active="1"] .hero--digest .digest-highlight-thumb {
  width: 72px;
  height: 54px;
}

body[data-pwa-active="1"] .hero--digest .digest-highlight-title {
  font-size: 0.9rem;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* board の列も hero と揃えて main 端まで引き伸ばし、スワイプを main 端まで効かせる */
body[data-pwa-active="1"] .panel--board {
  margin-left: calc(-1 * max(16px, env(safe-area-inset-left, 0px)));
  margin-right: calc(-1 * max(16px, env(safe-area-inset-right, 0px)));
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}

/* ============================================================ */
/* Source Dropdown (feature/source-filter)                      */
/* ============================================================ */

.source-dropdown-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-xl);
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
  font-family: inherit;
  max-width: 260px;
}

.source-dropdown-btn:hover,
.source-dropdown-btn:focus-visible {
  color: var(--text-primary);
  border-color: var(--primary);
  outline: none;
}

.source-dropdown-btn.has-selection {
  color: var(--accent-light);
  background: rgba(6, 182, 212, 0.12);
  border-color: var(--accent);
}

.source-dropdown-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 200px;
}

.source-dropdown-caret {
  font-size: var(--fs-xs);
  color: var(--text-hint);
  flex-shrink: 0;
}

/* ── Bottom sheet 化 ────────────────────────────────────────────
   旧 panel は button rect 起点の position:fixed dropdown だったが、
   iOS PWA standalone でキーボード解除と onChange 発火が交錯し、
   下部タブバー (position:fixed; bottom:0) が消失する不具合があった。
   ボトムシート + backdrop に統一し、visualViewport API で計算した
   --keyboard-inset を bottom に積んで sheet がキーボード直上に来るよう調整する。
   sourceDropdown.js が DOM/state を制御。
   ─────────────────────────────────────────────────────────────── */

.source-dropdown-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1700;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.source-dropdown-backdrop.open {
  opacity: 1;
}
.source-dropdown-backdrop[hidden] {
  display: none;
}

.source-dropdown-panel {
  position: fixed;
  left: 0;
  right: 0;
  /* キーボード直上に sheet を出す。--keyboard-inset は JS が動的に設定。 */
  bottom: var(--keyboard-inset, 0px);
  z-index: 1800;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--surface-2);
  border-top: 1px solid var(--border-strong);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -16px 40px rgba(0, 0, 0, 0.55);
  padding: 8px 16px max(env(safe-area-inset-bottom, 0px), 16px);
  /* 高さ: viewport の 80% を上限。dvh で iOS PWA の URL バー揺れにも追随 */
  max-height: min(80vh, 80dvh);
  /* slide-up animation */
  transform: translateY(100%);
  transition: transform 0.22s cubic-bezier(0.32, 0.72, 0.18, 1);
  will-change: transform;
}
.source-dropdown-panel.open {
  transform: translateY(0);
}
.source-dropdown-panel[hidden] {
  display: none;
}

/* Desktop: 中央寄せのモーダル風プレゼンテーション */
@media (min-width: 768px) {
  .source-dropdown-panel {
    left: 50%;
    right: auto;
    bottom: auto;
    top: 50%;
    width: min(480px, calc(100vw - 32px));
    max-height: min(70vh, 70dvh);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-strong);
    transform: translate(-50%, -50%) scale(0.96);
    transform-origin: center;
  }
  .source-dropdown-panel.open {
    transform: translate(-50%, -50%) scale(1);
  }
}

/* ドラッグハンドル: モバイルのみ表示。視覚的アフォーダンスのみ */
.source-dropdown-handle {
  width: 40px;
  height: 4px;
  margin: 4px auto 8px;
  border-radius: 2px;
  background: var(--border-strong);
  flex-shrink: 0;
}
@media (min-width: 768px) {
  .source-dropdown-handle { display: none; }
}

.source-dropdown-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.source-dropdown-title {
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  color: var(--text-primary);
}

.source-dropdown-close {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--radius-circle);
  color: var(--text-muted);
  font-size: var(--fs-2xl);
  line-height: 1;
  cursor: pointer;
  transition: color 0.12s ease, background 0.12s ease;
}

.source-dropdown-close:hover,
.source-dropdown-close:focus-visible {
  color: var(--text-primary);
  background: var(--surface-1);
  outline: none;
}

.source-dropdown-search {
  width: 100%;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: var(--fs-lg); /* iOS の auto-zoom 抑止 (16px 未満で zoom される) */
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s ease;
  flex-shrink: 0;
}

.source-dropdown-search::placeholder {
  color: var(--text-hint);
}

.source-dropdown-search:focus {
  border-color: var(--primary);
}

.source-dropdown-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.source-dropdown-list::-webkit-scrollbar {
  width: 6px;
}

.source-dropdown-list::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}

.source-dropdown-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* 44px tap target を確保（Apple HIG）。bottom sheet では特に重要。 */
  padding: 12px 14px;
  min-height: 44px;
  background: transparent;
  border: none;
  border-radius: 10px;
  color: var(--text-primary);
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.12s ease, color 0.12s ease;
}

.source-dropdown-option:hover,
.source-dropdown-option:focus-visible {
  background: var(--surface-1);
  outline: none;
}

.source-dropdown-option.active {
  background: rgba(6, 182, 212, 0.12);
  color: var(--accent-light);
}

.source-dropdown-option-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.source-dropdown-empty {
  padding: 20px 12px;
  color: var(--text-hint);
  font-size: var(--fs-base);
  text-align: center;
  margin: 0;
}

/* 狭い viewport では panel を画面幅に合わせる */
@media (max-width: 640px) {
  .source-dropdown-btn {
    max-width: calc(100vw - 100px);
  }
}

/* ═══════════════════════════════════════════════
   Bookmark Button (★ toggle) — newsCard / articleModal 共用
   ─────────────────────────────────────────────── */
.ww-bookmark-btn {
  appearance: none;
  border: none;
  cursor: pointer;
  background: transparent;
  color: #ffffff;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease, background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
.ww-bookmark-btn:focus-visible {
  outline: 2px solid var(--accent, #8b5cf6);
  outline-offset: 2px;
}
.ww-bookmark-btn:disabled {
  opacity: 0.5;
  cursor: wait;
}
.ww-bookmark-btn.is-pending {
  opacity: 0.45;
}
.ww-bookmark-btn__icon {
  line-height: 1;
  color: inherit;
}

/* card variant: 画像右上にオーバーレイ表示。半透明黒の円形背景 */
.ww-bookmark-btn--card {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-circle);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  z-index: 2;
  font-size: var(--fs-xl);
  color: rgba(255, 255, 255, 0.85);
}
.ww-bookmark-btn--card:hover {
  background: rgba(0, 0, 0, 0.75);
  transform: scale(1.08);
}
.ww-bookmark-btn--card.is-bookmarked {
  color: #fbbf24;
  background: rgba(0, 0, 0, 0.7);
}

/* modal variant: タイトル横にインラインで出す */
.article-modal-title-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  justify-content: space-between;
}
.article-modal-title-row h2 {
  flex: 1 1 auto;
  margin: 0;
}
.ww-bookmark-btn--modal {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-circle);
  background: var(--surface-2, rgba(255, 255, 255, 0.06));
  color: rgba(255, 255, 255, 0.65);
  font-size: var(--fs-2xl);
}
.ww-bookmark-btn--modal:hover {
  background: var(--surface-3, rgba(255, 255, 255, 0.12));
  color: rgba(255, 255, 255, 0.9);
}
.ww-bookmark-btn--modal.is-bookmarked {
  color: #fbbf24;
}

/* ═══════════════════════════════════════════════
   Bookmarks Page — /bookmarks/
   ─────────────────────────────────────────────── */
.bookmarks-header {
  margin-bottom: 32px;
}
.bookmarks-header h1 {
  margin: 0 0 8px;
}
.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 32px;
}
@media (max-width: 640px) {
  .cards-grid { grid-template-columns: 1fr; gap: 20px; }
}

/* ═══════════════════════════════════════════════
   PWA / Tablet / Landscape 堅牢化 (2026-04-27)
   - iPad portrait/landscape の中間ブレークポイント
   - iPhone landscape の notch (left/right) 対応
   - 古い iOS Safari の dvh 未対応 fallback
   - tap target 44pt 確保
   ─────────────────────────────────────────────── */

/* iPhone landscape: 画面側面の notch を吸収。topbar / tab-bar / main の
   左右に safe-area-inset を加える（縦持ち時は 0 で透過）。 */
.topbar,
body[data-pwa-active="1"] .pwa-tab-bar {
  padding-left: max(0px, env(safe-area-inset-left, 0px));
  padding-right: max(0px, env(safe-area-inset-right, 0px));
}
body.page--viewer main {
  padding-left: max(clamp(16px, 4vw, 40px), env(safe-area-inset-left, 0px));
  padding-right: max(clamp(16px, 4vw, 40px), env(safe-area-inset-right, 0px));
}

/* iPad portrait (768-1023px): topbar をやや圧縮、タブを大きめに。
   PWA 下タブも文字を読みやすく。 */
@media (min-width: 768px) and (max-width: 1023px) {
  .topbar { padding-top: calc(20px + env(safe-area-inset-top, 0px)); }
  .brand { font-size: clamp(36px, 5vw, 52px); }
  .filter-row { padding: 12px 24px; }
  .region-tab,
  .theme-chip { font-size: var(--fs-md); padding: 8px 18px; }
  body[data-pwa-active="1"] .pwa-tab-bar {
    padding: 10px 0 calc(10px + env(safe-area-inset-bottom, 0px));
  }
  body[data-pwa-active="1"] .pwa-tab-icon { font-size: 26px; }
  body[data-pwa-active="1"] .pwa-tab-label { font-size: var(--fs-xs); }
  body[data-pwa-active="1"] main {
    padding-top: calc(150px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  }
  /* 記事カードグリッドが 2 列で詰まり過ぎない */
  .grid,
  .region-grid,
  .cards-grid {
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    gap: 24px;
  }
}

/* iPhone landscape (短辺 < 500px): 上下が窮屈なので topbar / tab-bar を圧縮 */
@media (max-height: 500px) and (orientation: landscape) {
  .topbar { padding-top: calc(8px + env(safe-area-inset-top, 0px)); }
  .topbar-top { margin-bottom: 6px; }
  .filter-row { padding: 6px 16px; }
  body[data-pwa-active="1"] .pwa-tab-bar {
    padding: 4px 0 calc(4px + env(safe-area-inset-bottom, 0px));
  }
  body[data-pwa-active="1"] .pwa-tab-icon { font-size: var(--fs-xl); }
  body[data-pwa-active="1"] .pwa-tab-label { font-size: 9px; }
  body[data-pwa-active="1"] main {
    padding-top: calc(110px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px));
  }
  .article-modal-content { max-height: 96vh; max-height: 96dvh; }
}

/* iPad Pro / 大型タブレット landscape (1024-1366px) で PWA tab を中央寄せ */
@media (min-width: 1024px) and (max-width: 1366px) and (orientation: landscape) {
  body[data-pwa-active="1"] .pwa-tab-bar {
    /* 横長すぎる場合タブを中央寄せして幅を抑える */
    max-width: 720px;
    margin: 0 auto;
    border-left: 1px solid var(--border-strong);
    border-right: 1px solid var(--border-strong);
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
  }
}

/* tap target サイズの最低保証 (Apple HIG: 44x44pt)
   - filter chip は横スクロール内で連続するため除外（視覚的圧迫を避ける）
   - 単発の操作ボタン・タブのみに適用 */
.btn,
.btn-icon,
.pwa-tab,
.bottom-sheet-trigger,
.modal-close,
.article-modal-close {
  min-height: 44px;
  min-width: 44px;
}
/* filter chip は視覚的に小さく保ちつつ ::before で hit area を縦に拡張 */
.region-tab,
.theme-chip {
  position: relative;
}
.region-tab::before,
.theme-chip::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -8px;
  bottom: -8px;
}

/* 古い Safari (iOS 15 以前) の dvh 未対応 fallback。@supports で囲んで
   主流ブラウザに影響しない */
@supports not (height: 100dvh) {
  body.page--viewer { min-height: -webkit-fill-available; }
  .article-modal-content { max-height: 90vh; }
}

/* PWA standalone 時に Safari のオーバースクロールバウンスを完全停止
   （body は既存ルールで対応済、main も追加保険） */
@media (display-mode: standalone) {
  html, body { overscroll-behavior: none; }
  /* tap target 上の long-press 文字選択 callout を抑制（タップと干渉するため）。
     ボタン・タブ・カードクリック領域のみで、本文・モーダル・入力は影響なし。 */
  .pwa-tab,
  .region-tab,
  .theme-chip,
  .btn,
  .btn-icon,
  .news-card,
  .pwa-breadcrumb-clear {
    -webkit-user-select: none; user-select: none;
    -webkit-touch-callout: none;
  }
}

/* :focus-visible が古いブラウザ未対応時の fallback。
   :focus-visible 対応ブラウザでは :focus を消し、対応していない環境では
   従来通り :focus でアウトラインを出す。 */
@supports selector(:focus-visible) {
  button:focus:not(:focus-visible),
  a:focus:not(:focus-visible),
  [role="button"]:focus:not(:focus-visible) { outline: none; }
}

/* iPhone X+ home indicator 帯にコンテンツが届いた時のグラデーション保険。
   PWA の下タブが無い画面 (login 等) で home indicator が読みづらくなるのを防ぐ */
@media (display-mode: standalone) {
  body:not([data-pwa-active="1"])::after {
    content: '';
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: env(safe-area-inset-bottom, 0px);
    background: linear-gradient(to top, rgba(0,0,0,.6), transparent);
    pointer-events: none;
    z-index: 800;
  }
}

/* ─────────────────────────────────────────────────────────
 * PWA install banner (mobile, browser-mode only)
 * 設計: docs/design/2026-04-29-pwa-install-banner-and-events.md
 * ───────────────────────────────────────────────────────── */
.pwa-install-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--surface-2, #1a1a1a);
  border-top: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.6);
  z-index: 8000;
  font-size: var(--fs-md);
  line-height: 1.4;
}
.pwa-install-banner[hidden] { display: none; }

.pwa-install-banner__icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  flex: 0 0 auto;
}

.pwa-install-banner__text {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}

.pwa-install-banner__title {
  font-weight: var(--fw-bold);
  color: var(--text-primary, #ffffff);
  font-size: var(--fs-md);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pwa-install-banner__subtitle {
  color: var(--text-muted, #a0a0a0);
  font-size: var(--fs-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pwa-install-banner__cta {
  flex: 0 0 auto;
  min-height: 36px;
  padding: 8px 14px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--accent, #06b6d4);
  color: #ffffff;
  font-weight: var(--fw-bold);
  font-size: var(--fs-base);
  cursor: pointer;
}
.pwa-install-banner__cta:active { opacity: 0.85; }

.pwa-install-banner__dismiss {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--radius-circle);
  background: transparent;
  color: var(--text-muted, #a0a0a0);
  font-size: var(--fs-2xl);
  line-height: 1;
  cursor: pointer;
}
.pwa-install-banner__dismiss:active { background: rgba(255, 255, 255, 0.08); }

/* main の bottom padding を確保し、既存 footer / pwa-tab-bar との重なりを避ける */
body[data-pwa-banner] {
  padding-bottom: 96px;
}

/* iOS 手順 sheet: 中央モーダル */
.pwa-ios-sheet {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pwa-ios-sheet[hidden] { display: none; }

.pwa-ios-sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
}

.pwa-ios-sheet__content {
  position: relative;
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow: auto;
  background: var(--surface-2, #1a1a1a);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  border-radius: 14px;
  padding: 20px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.6);
}

.pwa-ios-sheet__title {
  margin: 0 0 12px;
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--text-primary, #ffffff);
}

.pwa-ios-sheet__steps {
  margin: 0 0 16px;
  padding-left: 22px;
  color: var(--text-primary, #ffffff);
  font-size: var(--fs-md);
  line-height: 1.6;
}
.pwa-ios-sheet__steps li + li { margin-top: 6px; }

.pwa-ios-sheet__notice {
  margin: 0 0 12px;
  padding: 10px 12px;
  background: rgba(245, 158, 11, 0.16);
  border-radius: var(--radius-sm);
  color: var(--text-primary, #ffffff);
  font-size: var(--fs-base);
}
.pwa-ios-sheet__notice[hidden] { display: none; }

.pwa-ios-sheet__close {
  display: block;
  width: 100%;
  min-height: 40px;
  padding: 10px 14px;
  border: 0;
  border-radius: 10px;
  background: var(--accent, #06b6d4);
  color: #ffffff;
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  cursor: pointer;
}

/* 標準 PWA tab-bar とのスタッキング: standalone では banner を出さないが
   念のため非表示にしておく（installed フラグが未保存で誤判定した場合の保険）。 */
body[data-pwa-active="1"] .pwa-install-banner { display: none; }

/* WCAG 2.3.3 / Apple HIG / Material — reduced motion preference
   skeleton pulse と sw-update-banner-slide も含めすべての反復/遷移を抑制する */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}



/* === Hero meta header (Phase D / SEO P1-5、論点 2 案 d セクション包括表示) === */
.hero-meta-header {
    position: relative;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 12px;
    margin-bottom: 12px;
    background: rgba(124, 58, 237, 0.08);
    border-left: 3px solid var(--primary);
    border-radius: 4px;
    font-size: 12px;
}

.hero-ai-badge {
    color: var(--accent-light);
    font-weight: 600;
    letter-spacing: 0.02em;
}

.hero-meta-link {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 11px;
    border-bottom: 1px solid transparent;
    transition: border-color 0.15s ease, color 0.15s ease;
}

.hero-meta-link:hover,
.hero-meta-link:focus-visible {
    color: var(--accent-light);
    border-bottom-color: var(--accent-light);
    outline: none;
}

@media (max-width: 640px) {
    .hero-meta-header {
        font-size: 11px;
        padding: 6px 10px;
    }
    .hero-meta-link {
        font-size: 10px;
    }
}

/* === Footer extension styles (SEO P1-5、リンク間の区切り改善) ============ */
/* Footer extension styles — consolidated SEO P1-5 (commit 4 → commit 10 リファクタ).
   既存 .footer は position: fixed (line 1099-1116) + flex layout。footer-ai-disclosure
   と footer-nav はその flex item として並ぶ。font-size と gap を全 viewport で
   コンパクトに統一 (旧 mobile media query で 13px 強制していたバグを修正)。 */
.footer-ai-disclosure {
    /* margin-top / max-width は既存 flex 配置を破壊するため使わない */
    font-size: 10px;
    color: var(--text-hint);
    line-height: 1.4;
    opacity: 0.85;
}

.footer-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: center;
    /* margin-top は不要 (.footer > div の flex gap で間隔確保) */
}

.footer-nav .footer-link {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 11px;
    font-weight: 400;
    padding: 0;
    border-bottom: 1px solid transparent;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.footer-nav .footer-link:hover,
.footer-nav .footer-link:focus-visible {
    color: var(--accent-light);
    border-bottom-color: currentColor;
    outline: none;
}

@media (max-width: 480px) {
    .footer-nav {
        gap: 4px 10px;
    }
    .footer-nav .footer-link {
        font-size: 10px;
    }
}

/* === Topbar actions 配置調整 (SEO P1-5、右に寄りすぎ防止) =================== */
.topbar-top .actions {
    right: 16px;
}

@media (min-width: 768px) {
    .topbar-top .actions {
        right: 24px;
    }
}

/* === Hero meta header 控えめ化 (SEO P1-5、蛍光トーン → ニュートラル) ====== */
.hero-meta-header {
    background: rgba(255, 255, 255, 0.03);
    border-left: 1px solid var(--border-strong);
    border-radius: 4px;
    padding: 6px 12px;
    font-size: 11px;
}

.hero-ai-badge {
    color: var(--text-muted);
    font-weight: 500;
    letter-spacing: 0.02em;
}

/* === Footer (SEO P1-5 commit 8 + fr GA Phase 2 v3 — 2026-05-05) ===============
 *
 * 設計履歴:
 *   v0 (旧): position: fixed + flex 1 行 → fr 長文で行折り返し → 厚いバー
 *   v1 (fr GA Phase 2): normal flow → 「下に貼り付かない」UX 退化
 *   v2 (fr GA Phase 2 v2): position: fixed + 2 行 grid + AI disclosure 削除
 *     → mobile/PWA で異常に縦長、web も見た目悪い
 *   v3 (fr GA Phase 2 v3, 本コミット): 1 行 inline。tagline は ellipsis、
 *     mobile では tagline+brand 非表示、nav 横スクロール。~32px 極薄バー。
 * ============================================================================ */
.footer-nav .footer-link {
    font-size: 11px;
    padding: 2px 0;
    white-space: nowrap;
}

/* === Hero meta header を inline (内容ベース幅、配置改善 commit 6 維持) ======== */
.hero-meta-header {
    display: inline-flex;
    gap: 16px;
    width: auto;
}

/* === Topbar 言語切替ボタンの右余白拡大 (commit 6 維持、もう少し内側に) ======== */
.topbar-top .actions {
    right: 32px;
}

@media (min-width: 768px) {
    .topbar-top .actions {
        right: 48px;
    }
}

/* === 2026-05-04 hero-meta-header を「digest 直下」の注釈位置に配置 ==========
 * SEO P1-5 で追加した <header class="hero-meta-header"> を以下の位置に統一:
 *   - WEB ≥1024px (非 PWA): 既存 2-col grid (digest 左 / highlights 右) の
 *     左 col 内・digest 直下。highlights は右 col で 2 行 span (全高)。
 *   - mobile <1024px / PWA standalone: flex column で
 *     digest-text → hero-meta-header → highlights の順序制御。
 *
 * 旧スタイル (紫枠 box, 最上段) → 上に divider 線 + 控えめ font の
 * 注釈フットノート風トーンへ。
 * ============================================================================ */

.hero-meta-header {
    display: flex;
    width: fit-content;
    max-width: 100%;
}

/* 共通トーン: 枠/背景撤去, 上 divider 線, 控えめ font */
.hero--digest > .hero-meta-header {
    background: transparent;
    border-left: none;
    border-top: 1px solid var(--border);
    padding: 8px 0 0;
    margin: 10px 0 0;
    font-size: 11px;
    opacity: 0.6;
    gap: 8px;
}

.hero--digest > .hero-meta-header .hero-ai-badge {
    font-weight: 400;
    letter-spacing: 0.04em;
}

.hero--digest > .hero-meta-header .hero-meta-link {
    font-size: 10px;
}

/* mobile <1024px / PWA standalone: flex column 化
 * デフォルトは digest-text → hero-meta-header → highlights の順
 * PWA standalone では order:99 で最下段に上書き (下記 PWA ルール参照) */
@media (max-width: 1023px), (display-mode: standalone) {
    .hero--digest {
        display: flex;
        flex-direction: column;
    }
    .hero--digest > .hero-meta-header {
        order: 1;
        align-self: flex-start;
    }
    .hero--digest > .digest-highlights-wrap {
        order: 2;
    }
}

/* WEB ≥1024px: 既存 2-col grid (line 3177) を活かしつつ
 * grid-template-areas で digest 左下に badge、highlights は右 col で全高 span */
@media (min-width: 1024px) {
    .hero--digest {
        grid-template-areas:
            "digest highlights"
            "badge  highlights";
        grid-template-rows: auto auto;
    }
    .hero--digest > .digest-text { grid-area: digest; }
    .hero--digest > .digest-highlights-wrap { grid-area: highlights; }
    .hero--digest > .hero-meta-header {
        grid-area: badge;
        justify-self: start;
    }
}

/* PWA standalone: badge を最下段 (highlights の下) に小さく出す
 * 上記 mobile/PWA ルールの order:1 / order:2 を打ち消し、
 * digest-text → highlights → hero-meta-header の順に並べ替え */
@media (display-mode: standalone) {
    .hero--digest > .hero-meta-header {
        order: 99;
        padding: 10px max(20px, env(safe-area-inset-left, 20px)) 0;
        margin-top: 16px;
        font-size: 9px;
        opacity: 0.5;
    }
    .hero--digest > .digest-highlights-wrap {
        order: 0;
    }
    .hero--digest > .hero-meta-header .hero-meta-link {
        font-size: 9px;
    }
}
