/* iSpirits Cloud — Product app shell styles
 * Ported from design pack 2026-05-16 (styles.css). Source design file
 * kept verbatim with @import path redirected to tokens.css.
 *
 * NOT YET LOADED by any page. Phase 3 wires this in via the AppShell
 * component (frontend/src/components/AppShell.js, pending).
 *
 * Selectors are product-page specific (.app-shell, .sidebar, .topbar,
 * .stat-card, .recap-banner, .ds-card, etc.). When loaded, scope via
 * `<body class="product-page">` so no rule leaks to marketing pages.
 *
 * Token contract: every color/spacing/typography value resolves via
 * tokens.css. Cozy mode cascades automatically.
 */

@import url('/chinese/src/styles/tokens.css?v=20260730-personaguard2');

/* Screen-reader-only utility. Several pages (search.html, missions.html) use
   class="visually-hidden" on form labels but only loaded app-shell.css, where
   the class was undefined — so the "hidden" labels rendered as visible text
   (QA round 76). Standard clip pattern. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

:root {
  --radius-sm: 10px; --radius-md: 14px; --radius-lg: 18px; --radius-xl: 24px;
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:24px; --space-6:32px;
  --shadow-md: 0 6px 18px rgba(0,0,0,0.28);
  /* Deeper blue->violet so white label text clears WCAG AA (~5-6:1) on every
     surface using --gradient-brand (.btn-primary, avatars, .filter-pill.active,
     .bubble.user, level-badge). Was #4FACFE->#9479FF (white 2.4-3.3:1, failed). */
  --gradient-brand: linear-gradient(135deg, #2563EB 0%, #7C3AED 100%);
  --sidebar-w: 256px;
}
:root[data-ux-mode="cozy"] {
  --radius-sm: 12px; --radius-md: 18px; --radius-lg: 22px; --radius-xl: 28px;
  --shadow-md: 0 6px 18px rgba(90, 60, 30, 0.10);
  --gradient-brand: linear-gradient(135deg, #B69763 0%, #C66B6B 100%);
}

* { box-sizing: border-box; }
html, body { margin:0; padding:0; }
body {
  font-family: var(--font-sans);
  background: var(--bg-body);
  background-color: var(--bg-solid);
  color: var(--fg);
  font-size: 15px;
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
/* font-size reads --cozy-text-base (cozy-theme.css) rather than a literal:
   this rule loads AFTER cozy-theme.css at equal specificity, so a hardcoded
   16px here silently overrode cozy's own base size and made cozy body text
   identical to standard. Owner directive 2026-07-30: same families as
   standard, a bit larger. Fallback keeps this safe if loaded standalone. */
[data-ux-mode="cozy"] body { font-family: var(--font-body-cozy); font-size: var(--cozy-text-base, 17px); line-height: 1.7; }

button { font: inherit; color: inherit; cursor: pointer; background: none; border: 0; }
input { font: inherit; color: inherit; }
/* Anchor reset — every <a> in the product chrome inherits color and is unadorned;
   underlines are reserved for inline text links inside prose (blog/journal/help). */
a { color: inherit; text-decoration: none; }
a:hover { text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-family: var(--font-display); font-weight: 600; letter-spacing: -0.02em; }
[data-ux-mode="cozy"] h1, [data-ux-mode="cozy"] h2, [data-ux-mode="cozy"] h3 {
  font-family: var(--font-serif); font-weight: 600; letter-spacing: -0.01em;
}

.eyebrow {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--fg-muted); display: inline-block; margin-bottom: 8px;
}

/* ─── Typography hierarchy cap (product pages only) ──────────────────────────
   src/styles/base/typography.css defines a global h1=clamp(2.5rem,5vw,4rem)
   and h2=clamp(2rem,4vw,3rem) for marketing/landing pages. Inside the product
   shell those bounds explode at 1440px (h2 → 48px, competing with .page-head
   h1 = 32px). Re-anchor h2/h3 here so visual hierarchy holds. Scoped to
   body.product-page so marketing pages are untouched. Component-scoped
   overrides (h3.card-title, h2.modal-title, h2.feed-title, h3.level-name,
   h3.tl-year) keep their explicit sizes via higher specificity. (typo audit) */
body.product-page h1 { font-size: 32px; line-height: 1.15; letter-spacing: -0.02em; }
body.product-page h2 { font-size: 22px; line-height: 1.25; letter-spacing: -0.01em; }
body.product-page h3 { font-size: 16px; line-height: 1.3; }
body.product-page h4 { font-size: 14px; line-height: 1.3; }
@media (max-width: 720px) {
  body.product-page h1 { font-size: 26px; }
  body.product-page h2 { font-size: 20px; }
}

/* ─── App Shell ─── */
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }
.sidebar {
  position: sticky; top: 0; height: 100vh;
  background: var(--surface-raised);
  border-right: 1px solid var(--border);
  padding: 20px 14px; display: flex; flex-direction: column; gap: 22px;
  overflow-y: auto;
}
/* Cozy override: design ref 21-app-cozy-mode keeps the sidebar dark navy,
   only the main content flips to cream paper. Without this rule the sidebar
   inherits the cozy --surface-raised (cream) and reads illegible. */
[data-ux-mode="cozy"] .sidebar {
  background: #0d1526;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  color: #e6edf3;
}
[data-ux-mode="cozy"] .sidebar .nav-item { color: rgba(230, 237, 243, 0.78); }
[data-ux-mode="cozy"] .sidebar .nav-item.active { color: #fff; background: rgba(255,255,255,0.06); }
[data-ux-mode="cozy"] .sidebar .nav-label { color: rgba(230, 237, 243, 0.55); }
[data-ux-mode="cozy"] .sidebar .brand-text small { color: rgba(230, 237, 243, 0.65); }
/* The global cozy-theme.css rule `[data-ux-mode="cozy"] span:not([class*=icon])`
   forces dark ink on EVERY span — which lands invisibly (1.17:1) on the dark
   navy sidebar. These !important overrides win that specificity war so the
   sidebar nav labels, count badges, brand wordmark, and user-chip stay light. */
[data-ux-mode="cozy"] .sidebar .nav-item span,
[data-ux-mode="cozy"] .sidebar .nav-count,
[data-ux-mode="cozy"] .sidebar .brand-text,
[data-ux-mode="cozy"] .sidebar .brand-text small,
[data-ux-mode="cozy"] .sidebar .user-chip span,
[data-ux-mode="cozy"] .sidebar .nav-label { color: rgba(230, 237, 243, 0.85) !important; }
[data-ux-mode="cozy"] .sidebar .nav-item.active span { color: #fff !important; }
[data-ux-mode="cozy"] .sidebar .nav-label { color: rgba(230, 237, 243, 0.55) !important; }
[data-ux-mode="cozy"] #appShellUserAvatar { background: var(--gradient-brand, linear-gradient(135deg, #4FACFE, #9479FF)); color: #fff !important; }
.brand { display: flex; align-items: center; gap: 10px; padding: 4px 6px; }
.brand-mark {
  width: 36px; height: 36px; border-radius: var(--radius-md);
  background: #0a0a18; display: grid; place-items: center; overflow: hidden;
  box-shadow: 0 0 22px rgba(148, 121, 255, 0.45);
}
.brand-mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
[data-ux-mode="cozy"] .brand-mark { box-shadow: 0 4px 14px rgba(182, 151, 99, 0.30); background: #1A2438; }
.brand-text { font-family: var(--font-display); font-weight: 600; font-size: 15px; line-height: 1.2; }
[data-ux-mode="cozy"] .brand-text { font-family: var(--font-serif); }
.brand-text small { display: block; font-weight: 400; font-size: 11px; color: var(--fg-muted); letter-spacing: 0.04em; }

.nav-section { display: flex; flex-direction: column; gap: 2px; }
.nav-label {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--fg-muted); padding: 0 10px 6px;
}
.nav-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: var(--radius-sm);
  font-size: 14px; color: var(--fg-muted); text-align: left; transition: all 0.18s;
}
.nav-item:hover { background: rgba(255,255,255,0.04); color: var(--fg); }
[data-ux-mode="cozy"] .nav-item:hover { background: rgba(198, 107, 107, 0.08); }
.nav-item.active {
  background: linear-gradient(90deg, rgba(79,172,254,0.12), rgba(148,121,255,0.10));
  color: var(--fg-strong); border: 1px solid var(--border-subtle);
}
[data-ux-mode="cozy"] .nav-item.active {
  background: rgba(198, 107, 107, 0.08); color: var(--accent-rose, #C66B6B);
  border: 1px solid rgba(198,107,107,0.20);
}
.nav-item .ico { display: grid; place-items: center; width: 18px; }
.nav-item .count { margin-left: auto; font-size: 11px; color: var(--fg-faded); }
/* nav-count is the actual class AppShell.js emits (legacy `.count` retained
   for back-compat). Push right + give a subtle pill so the number doesn't
   collide with the label text. */
.nav-count {
  margin-left: auto;
  font-size: 11px;
  font-weight: 500;
  color: var(--fg-muted);
  padding: 2px 8px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.05);
  min-width: 22px;
  text-align: center;
}
.nav-item.active .nav-count {
  background: rgba(255, 255, 255, 0.10);
  color: var(--fg);
}
.nav-count:empty { display: none; }

.sidebar-footer { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }
.theme-toggle {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--surface-flat); padding: 4px; border-radius: var(--radius-md);
  border: 1px solid var(--border);
}
.theme-toggle button {
  /* min-height 44px: WCAG 2.5.5 tap target (§15.3). Height-only on purpose —
     the 2026-05-24 "Cozy" clipping was WIDTH overflow from padding/font
     inflation; vertical size can grow safely (flex centering absorbs it). */
  min-height: 44px;
  display: flex; align-items: center; justify-content: center; gap: 6px; padding: 7px 0;
  font-size: 12px; color: var(--fg-muted); border-radius: 9px; transition: all 0.18s;
}
.theme-toggle button.active { background: var(--surface-2); color: var(--fg-strong); box-shadow: var(--shadow-md); }

/* Sidebar footer account actions — Send feedback / Log out (QA 2026-07-16 r2
   P1: no logout or feedback control was reachable on AppShell pages). */
.sidebar-actions { display: flex; gap: 8px; }
.sidebar-actions button {
  min-height: 44px; /* WCAG 2.5.5 tap target (§15.3) — height-only, see above */
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 0; font-size: 12px; color: var(--fg-muted); cursor: pointer;
  background: var(--surface-flat); border: 1px solid var(--border); border-radius: 9px;
  transition: all 0.18s;
}
.sidebar-actions button:hover,
.sidebar-actions button:focus-visible { color: var(--fg-strong); background: var(--surface-2); }

/* ── 侧栏按钮护甲（2026-07-18）─────────────────────────────────────────
   styles.css 的通配规则 `button:not(.icon-btn):not(.btn):not(.primary)
   :not(.danger)`（特异性 0-4-1）会把所有无类名按钮刷成 44px 蓝色渐变主按钮，
   9 个同时加载两个样式表的页面上，侧栏的 Standard/Cozy 切换和
   发送反馈 / 退出登录被撑成两行大按钮。用 id 级特异性（1-1-1）把
   壳自身的按钮固定为唯一标准外观 —— 通配规则设置的每个属性这里都
   刻意重新声明，勿删减。 */
#appShellSidebar .theme-toggle button,
#appShellSidebar .sidebar-actions button {
  padding: 7px 0;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: normal;
  line-height: 1.4;
  color: var(--fg-muted);
  background: transparent;
  border: 0;
  border-radius: 9px;
  min-height: 44px; /* tap target — matches the base rule above (§15.3) */
  min-width: 0;
  box-shadow: none;
}
#appShellSidebar .sidebar-actions button {
  padding: 8px 0;
  background: var(--surface-flat);
  border: 1px solid var(--border);
}
#appShellSidebar .theme-toggle button.active {
  background: var(--surface-2);
  color: var(--fg-strong);
  box-shadow: var(--shadow-md);
}
#appShellSidebar .theme-toggle button:hover,
#appShellSidebar .theme-toggle button:focus-visible,
#appShellSidebar .sidebar-actions button:hover,
#appShellSidebar .sidebar-actions button:focus-visible {
  color: var(--fg-strong);
  background: var(--surface-2);
  filter: none;
}
#appShellSidebar .theme-toggle button:active,
#appShellSidebar .sidebar-actions button:active {
  transform: none;
}


.user-chip {
  display: flex; align-items: center; gap: 10px; padding: 10px;
  background: var(--surface-flat); border-radius: var(--radius-md); border: 1px solid var(--border);
}
.user-avatar {
  width: 32px; height: 32px; border-radius: 50%; background: var(--gradient-brand);
  display: grid; place-items: center; color: white; font-weight: 600; font-size: 13px;
}
.user-name { font-size: 13px; font-weight: 600; }
.user-tier { font-size: 11px; color: var(--fg-muted); }

/* ─── Main / Topbar ─── */
.main { min-width: 0; padding-bottom: 60px; }
.topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 12px;
  padding: 14px 32px;
  background: color-mix(in srgb, var(--bg-solid) 80%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
[data-ux-mode="cozy"] .topbar { background: rgba(247,239,224,0.85); }
.menu-btn { display: none; width: 36px; height: 36px; border-radius: 10px; border: 1px solid var(--border); display: none; place-items: center; }
.topbar-search {
  flex: 1; min-width: 0; max-width: 460px; display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; background: var(--surface-flat); border: 1px solid var(--border); border-radius: var(--radius-md);
  color: var(--fg-muted);
}
.topbar-search input { flex: 1; border: 0; background: transparent; outline: none; font-size: 14px; }
/* Restore a visible keyboard focus ring (QA round 70 K6) — outline:none alone
   was a WCAG 2.4.7 fail; :focus-visible shows it for keyboard, not mouse. */
.topbar-search input:focus-visible { outline: 2px solid var(--accent-purple, #9479ff); outline-offset: -2px; border-radius: 6px; }
.topbar-search input::placeholder { color: var(--fg-faded); }
.topbar-actions { margin-left: auto; display: flex; gap: 6px; }

/* ─── Buttons ─── */
.btn {
  display: inline-flex; align-items: center; gap: 6px; padding: 9px 14px; border-radius: var(--radius-sm);
  background: var(--surface-flat); border: 1px solid var(--border); color: var(--fg); font-size: 14px; font-weight: 600;
  line-height: 1.2;
  transition: all 0.18s;
}
.btn:hover { background: rgba(255,255,255,0.06); border-color: var(--border-strong); }
[data-ux-mode="cozy"] .btn:hover { background: rgba(198, 107, 107, 0.08); }
.btn-primary { background: var(--gradient-brand); color: #ffffff; border-color: transparent; box-shadow: 0 0 0 1px rgba(148,121,255,0.30); }
.btn-primary:hover { transform: translateY(-1px); }
/* §97 — see EN app-shell.css. Standard-mode-scoped AA restore for primary CTAs
   (white on --gradient-brand ~5.2:1); cozy excluded; secondary/outline untouched. */
:root:not([data-ux-mode="cozy"]) .btn-primary,
:root:not([data-ux-mode="cozy"]) .pagination-btn,
:root:not([data-ux-mode="cozy"]) .month-glance-navbtn,
:root:not([data-ux-mode="cozy"]) .tf-habit-btn,
:root:not([data-ux-mode="cozy"]) .persona-picker-chip {
  background: var(--gradient-brand);
  color: #ffffff;
}
/* Cozy: a .btn with no explicit fill inherits the cream surface-flat and
   white/light label text → fails AA. Give cozy .btn a warm paper fill with
   dark ink, and .btn-primary a solid rose fill that clears 4.5:1 with white. */
[data-ux-mode="cozy"] .btn {
  background: #fffbf2; border-color: rgba(166,130,85,0.30); color: #1a2438;
}
[data-ux-mode="cozy"] .btn-primary {
  background: var(--cozy-rose, #A8475F); color: #fff; border-color: transparent; box-shadow: none;
}
[data-ux-mode="cozy"] .btn-primary:hover { background: var(--cozy-rose-dark, #8F3A4F); }
.btn-sm { padding: 6px 10px; font-size: 13px; }
.btn-ghost { background: transparent; border: 0; }
.btn-icon { width: 36px; height: 36px; padding: 0; justify-content: center; }
.btn:active { transform: scale(0.96); }

/* Topbar action icon-buttons (Notifications, Help) rendered as blank squares in
   STANDARD mode (reported 2026-05-24). Two compounding causes:
   (1) the global `.btn` rule in styles.css applies `padding:12px 20px` — 40px of
       horizontal padding on a ~44px button flex-crushed the 18px SVG to ~2px wide,
       so the glyph was an invisible sliver (same crush the cozy block below fixes);
   (2) that rule's gradient + the page-level dark `--fg` also left the icon dark on a
       blue gradient. Give these buttons compact icon-button geometry, a visible dark
       surface, a hard-sized non-shrinking SVG, and a topbar-light stroke. Cozy keeps
       its own !important rule, so this is standard-mode-only in effect. */
.topbar .topbar-actions .btn-icon {
  width: 38px;
  height: 38px;
  padding: 0;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  background: var(--surface-flat);
  background-image: none;
  color: #e6edf3;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.topbar .topbar-actions .btn-icon svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  stroke: #e6edf3;
}
.topbar .topbar-actions .btn-icon:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: var(--border-strong, var(--border));
}

/* ─── Page-head action buttons — readability floor (2026-05-17) ───
   User report: top-right action buttons (Guide / Show all events / Add moment /
   New entry / Build a wizard / Voice / Deep thinker) had text matching the
   button bg + too small to read. Lift font-size + force readable text colors
   centrally so page-specific CSS can't silently regress contrast. */
.page-head-actions .btn,
.page-head .btn {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  padding: 9px 14px;
  min-height: 36px;
  color: var(--fg);
}
.page-head-actions .btn-primary,
.page-head .btn-primary {
  color: #ffffff;
}
.page-head-actions .btn-ghost,
.page-head .btn-ghost {
  color: var(--fg);
  background: transparent;
}
.page-head-actions .btn .icon svg,
.page-head .btn .icon svg,
.page-head-actions .btn [data-icon] svg,
.page-head .btn [data-icon] svg {
  width: 16px; height: 16px;
}

/* ─── Page ─── */
.page { padding: 28px 32px 80px; max-width: 1600px; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-bottom: 28px; flex-wrap: wrap; }
.page-head h1 { font-size: 32px; line-height: 1.15; margin-bottom: 6px; }
.page-head p { margin: 0; color: var(--fg-muted); max-width: 540px; font-size: 14px; }
.page-head-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; flex-wrap: wrap; padding-top: 4px; }

/* ─── Stat Cards ─── */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; margin-bottom: 24px; }
.stat-card {
  padding: 18px; border-radius: var(--radius-md); background: var(--surface-2);
  border: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px; position: relative; overflow: hidden;
}
[data-ux-mode="cozy"] .stat-card { background: var(--surface-raised, #FFFBF2); }
.stat-card::after {
  content: ""; position: absolute; right: -20px; top: -20px; width: 90px; height: 90px;
  border-radius: 50%; background: var(--gradient-brand); opacity: 0.06; filter: blur(10px);
}
.stat-ico {
  width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center;
  background: rgba(79, 172, 254, 0.10); color: var(--accent-cyan); margin-bottom: 8px;
}
[data-ux-mode="cozy"] .stat-ico { background: rgba(198,107,107,0.12); color: #C66B6B; }
.stat-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em; color: var(--fg-muted); }
.stat-value { font-family: var(--font-display); font-size: 28px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.15; }
/* Defeat legacy .stat-card .stat-value=2.2rem (35.2px) override in
   src/features/progress/progress.css. The shared 28px sits inside the
   28-32px design-ref band; the legacy 35px overshot it. (typo audit) */
.stat-card .stat-value { font-size: 28px; }
[data-ux-mode="cozy"] .stat-value { font-family: var(--font-serif); }
.stat-delta { font-size: 12px; color: var(--fg-muted); }

.level-card {
  grid-column: span 2; padding: 18px; border-radius: var(--radius-md); background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  background-image: linear-gradient(135deg, rgba(79,172,254,0.06), rgba(148,121,255,0.06));
}
[data-ux-mode="cozy"] .level-card { background-image: linear-gradient(135deg, rgba(182,151,99,0.08), rgba(198,107,107,0.06)); border-color: rgba(182,151,99,0.30); }
.level-row { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.level-badge {
  width: 48px; height: 48px; border-radius: 14px; background: var(--gradient-brand);
  display: grid; place-items: center; color: white; font-family: var(--font-display); font-weight: 700; font-size: 22px;
  box-shadow: 0 4px 16px rgba(148,121,255,0.35);
}
.level-name { font-size: 18px; font-family: var(--font-display); }
[data-ux-mode="cozy"] .level-name { font-family: var(--font-serif); }
.level-xp { font-size: 12px; color: var(--fg-muted); }
.progress-bar {
  height: 8px; border-radius: 99px; background: var(--surface-flat); overflow: hidden; position: relative;
  border: 1px solid var(--border);
}
.progress-bar-fill { height: 100%; background: var(--gradient-brand); border-radius: 99px; transition: width 0.6s cubic-bezier(0.22,1,0.36,1); }
.level-progress-meta { display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: var(--fg-muted); }

/* ─── Cards ─── */
.card {
  padding: 22px; border-radius: var(--radius-lg); background: var(--surface-2);
  border: 1px solid var(--border); margin-bottom: 18px;
}
[data-ux-mode="cozy"] .card { background: var(--surface-raised, #FFFBF2); }
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; gap: 12px; }
.card-title { font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.card-title svg { color: var(--accent-cyan); }
[data-ux-mode="cozy"] .card-title svg { color: #C66B6B; }
.card-eyebrow { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em; color: var(--fg-muted); }

.two-col { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; margin-bottom: 18px; }

/* ─── Today panes ─── */
.today-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.today-pane {
  padding: 14px; border-radius: var(--radius-md); background: var(--surface-flat);
  border: 1px solid var(--border); display: flex; flex-direction: column; gap: 10px;
}
.today-pane h4 {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--fg-muted); font-weight: 600;
  margin-bottom: 4px; display: flex; align-items: center; gap: 6px;
}
.today-pane .dot { width: 8px; height: 8px; border-radius: 50%; }
.today-pane .item {
  padding: 10px; border-radius: var(--radius-sm); background: var(--surface-2);
  border: 1px solid var(--border); font-size: 13px;
}
.today-pane .item .meta { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--fg-muted); margin-top: 6px; }
.item-action { color: var(--accent-cyan); cursor: pointer; }
[data-ux-mode="cozy"] .item-action { color: #C66B6B; }

/* ─── Milestones ─── */
.milestone-list { display: flex; flex-direction: column; gap: 10px; }
.milestone {
  display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: start;
  padding: 14px; border-radius: var(--radius-md); background: var(--surface-flat); border: 1px solid var(--border);
}
.milestone-status-dot { width: 12px; height: 12px; border-radius: 50%; margin-top: 4px; }
.milestone-status-dot.in-progress { background: var(--accent-cyan); box-shadow: 0 0 10px rgba(79,172,254,0.5); }
.milestone-status-dot.done { background: var(--success); }
.milestone-title { font-size: 14px; font-weight: 600; margin-bottom: 4px; }
.milestone-desc { font-size: 12px; color: var(--fg-muted); margin: 0 0 10px; }
.milestone-progress { display: flex; align-items: center; gap: 8px; }
.milestone-progress .progress-bar { flex: 1; height: 6px; }
.milestone-progress span { font-size: 11px; font-weight: 600; color: var(--fg-muted); min-width: 32px; text-align: right; }
.milestone-date { font-size: 11px; color: var(--fg-muted); white-space: nowrap; }

/* ─── Achievements ─── */
.achievement-list { display: flex; flex-direction: column; gap: 8px; }
.achievement {
  display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center;
  padding: 10px 12px; border-radius: var(--radius-md); background: var(--surface-flat); border: 1px solid var(--border);
}
.achievement-medal {
  width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; color: white;
}
.achievement-medal.gold { background: linear-gradient(135deg, #f59e0b, #fbbf24); }
.achievement-medal.silver { background: linear-gradient(135deg, #94a3b8, #cbd5e1); }
.achievement-medal.bronze { background: linear-gradient(135deg, #b45309, #d97706); }
.achievement-title { font-size: 13px; font-weight: 600; }
.achievement-meta { font-size: 11px; color: var(--fg-muted); }
.achievement-xp { font-size: 12px; font-weight: 600; color: var(--accent-cyan); }
[data-ux-mode="cozy"] .achievement-xp { color: #C66B6B; }

/* ─── Chart ─── */
.chart-card { padding: 22px; }
.chart-svg { width: 100%; height: 200px; }

/* ─── Wizards (timeline) ─── */
.wizard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; margin-bottom: 28px; }
.wizard-card {
  display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center;
  padding: 16px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  text-align: left; transition: all 0.18s;
}
.wizard-card:hover { transform: translateY(-1px); border-color: var(--border-strong); }
.wizard-card.primary {
  background: linear-gradient(135deg, rgba(79,172,254,0.10), rgba(148,121,255,0.10));
  border-color: var(--border-subtle);
}
[data-ux-mode="cozy"] .wizard-card.primary { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.08)); }
.wizard-ico {
  width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center;
  background: rgba(79,172,254,0.12); color: var(--accent-cyan);
}
[data-ux-mode="cozy"] .wizard-ico { background: rgba(198,107,107,0.12); color: #C66B6B; }
.wizard-card.primary .wizard-ico { background: var(--gradient-brand); color: white; }
.wizard-body h4 { font-size: 14px; margin-bottom: 2px; }
.wizard-body p { font-size: 12px; color: var(--fg-muted); margin: 0; }
.wizard-arrow { color: var(--fg-faded); }

/* ─── Timeline ─── */
.timeline-filters { display: flex; align-items: center; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.filter-pill {
  padding: 6px 12px; border-radius: 99px; background: var(--surface-flat); border: 1px solid var(--border);
  font-size: 12px; color: var(--fg-muted); transition: all 0.18s;
}
.filter-pill:hover { color: var(--fg); border-color: var(--border-strong); }
.filter-pill.active { background: var(--gradient-brand); color: white; border-color: transparent; }

.tl-rail { position: relative; padding-left: 28px; }
.tl-rail::before { content: ""; position: absolute; left: 9px; top: 8px; bottom: 0; width: 2px; background: linear-gradient(180deg, var(--accent-cyan), var(--accent-purple), transparent); opacity: 0.5; }
.tl-year {
  font-family: var(--font-display); font-size: 22px; margin: 24px 0 14px; position: relative;
}
[data-ux-mode="cozy"] .tl-year { font-family: var(--font-serif); }
.tl-year::before {
  content: ""; position: absolute; left: -28px; top: 8px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--gradient-brand); box-shadow: 0 0 16px rgba(148,121,255,0.5);
}
.tl-event {
  position: relative; padding: 16px; border-radius: var(--radius-md); background: var(--surface-2);
  border: 1px solid var(--border); margin-bottom: 12px;
}
[data-ux-mode="cozy"] .tl-event { background: var(--surface-raised, #FFFBF2); }
.tl-event::before {
  content: ""; position: absolute; left: -22px; top: 22px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent-cyan); box-shadow: 0 0 0 3px var(--bg-solid);
}
.tl-event.cat-milestone::before { background: var(--accent-purple); }
.tl-event.cat-goal::before { background: var(--success); }
.tl-event.cat-challenge::before { background: var(--warning); }
.tl-event.cat-reflection::before { background: var(--accent-cyan); }
.tl-event.cat-relationship::before { background: var(--danger); }
.tl-event-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.tl-event-title { font-size: 15px; font-weight: 600; }
.tl-event-date { font-size: 11px; color: var(--fg-muted); white-space: nowrap; }
.tl-event-body { font-size: 13px; color: var(--fg-muted); margin: 0 0 10px; line-height: 1.55; }
[data-ux-mode="cozy"] .tl-event-body { color: var(--fg); font-style: italic; opacity: 0.85; }
.tl-event-meta { display: flex; gap: 6px; }

.chip {
  padding: 3px 9px; border-radius: 99px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;
  background: var(--surface-flat); border: 1px solid var(--border); color: var(--fg-muted);
}
.chip.purple { background: rgba(148,121,255,0.10); color: var(--accent-purple); border-color: rgba(148,121,255,0.30); }
.chip.cyan { background: rgba(79,172,254,0.10); color: var(--accent-cyan); border-color: rgba(79,172,254,0.30); }
.chip.success { background: rgba(52,211,153,0.10); color: var(--success); border-color: rgba(52,211,153,0.30); }
.chip.warning { background: rgba(245,158,11,0.10); color: var(--warning); border-color: rgba(245,158,11,0.30); }

/* ─── Wisdom ─── */
.wisdom-tabs {
  display: flex; gap: 4px; padding: 4px; background: var(--surface-flat); border: 1px solid var(--border);
  border-radius: var(--radius-md); margin-bottom: 22px; width: fit-content; max-width: 100%; overflow-x: auto;
}
.wisdom-tab { padding: 8px 16px; font-size: 13px; color: var(--fg-muted); border-radius: 10px; transition: all 0.18s; white-space: nowrap; }
.wisdom-tab.active { background: var(--surface-2); color: var(--fg-strong); box-shadow: var(--shadow-md); }

.ispirit-card {
  display: grid; grid-template-columns: 200px 1fr; gap: 24px; padding: 28px; border-radius: var(--radius-xl);
  background: linear-gradient(135deg, rgba(79,172,254,0.08), rgba(148,121,255,0.08));
  border: 1px solid var(--border-subtle); margin-bottom: 22px; align-items: center;
}
[data-ux-mode="cozy"] .ispirit-card { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.08)); border-color: rgba(182,151,99,0.30); }
.ispirit-avatar { width: 200px; height: 200px; border-radius: 50%; background: radial-gradient(circle, rgba(148,121,255,0.20), transparent 70%); display: grid; place-items: center; }
.ispirit-avatar img { width: 90%; height: 90%; object-fit: contain; }
.ispirit-meta { display: flex; flex-direction: column; gap: 12px; }
.ispirit-name { font-size: 28px; font-family: var(--font-display); }
[data-ux-mode="cozy"] .ispirit-name { font-family: var(--font-serif); }
.ispirit-tagline { font-size: 15px; color: var(--fg); font-style: italic; line-height: 1.55; max-width: 540px; }
[data-ux-mode="cozy"] .ispirit-tagline { font-family: var(--font-serif); }
.ispirit-stats { display: flex; gap: 24px; flex-wrap: wrap; }
.ispirit-stat .l { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--fg-muted); margin-bottom: 2px; }
.ispirit-stat .v { font-size: 18px; font-weight: 600; font-family: var(--font-display); }
[data-ux-mode="cozy"] .ispirit-stat .v { font-family: var(--font-serif); }

.w-section { margin-bottom: 24px; }
.w-section-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; }
.w-section-title { font-size: 18px; font-family: var(--font-display); }
[data-ux-mode="cozy"] .w-section-title { font-family: var(--font-serif); }
.w-section-count { font-size: 11px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.12em; }
.wisdom-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.w-card {
  padding: 18px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 10px; transition: all 0.2s;
}
[data-ux-mode="cozy"] .w-card { background: var(--surface-raised, #FFFBF2); }
.w-card:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.w-card-head { display: flex; align-items: start; justify-content: space-between; gap: 8px; }
.w-card-title { font-size: 16px; font-weight: 600; line-height: 1.3; flex: 1; }
[data-ux-mode="cozy"] .w-card-title { font-family: var(--font-serif); }
.w-card-content { font-size: 13px; color: var(--fg-muted); line-height: 1.55; margin: 0; }
[data-ux-mode="cozy"] .w-card-content { color: var(--fg); opacity: 0.78; }
.w-card-foot { display: flex; align-items: center; justify-content: space-between; font-size: 11px; color: var(--fg-faded); margin-top: auto; }
.w-card-actions { display: flex; gap: 6px; }
.save-btn { width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; color: var(--fg-muted); transition: all 0.18s; }
.save-btn:hover { background: var(--surface-flat); color: var(--fg); }
.save-btn.saved { color: var(--accent-cyan); background: rgba(79,172,254,0.10); }
[data-ux-mode="cozy"] .save-btn.saved { color: #C66B6B; background: rgba(198,107,107,0.10); }

.reflection-card {
  padding: 20px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  border-left: 3px solid var(--accent-purple);
}
[data-ux-mode="cozy"] .reflection-card { background: var(--surface-raised, #FFFBF2); border-left: 3px solid #B69763; }
.reflection-card .date { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--fg-muted); margin-bottom: 8px; font-weight: 600; }
.reflection-card .body { font-size: 15px; line-height: 1.65; font-style: italic; }
[data-ux-mode="cozy"] .reflection-card .body { font-family: var(--font-serif); font-size: 17px; }

/* ─── Mobile / Bottom nav ─── */
.bottom-nav { display: none; }
@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; width: 280px; z-index: 50;
    transform: translateX(-100%); transition: transform 0.3s, visibility 0.3s; box-shadow: var(--shadow-md);
    /* visibility:hidden takes the off-screen sidebar OUT of the tab order +
       a11y tree (QA round 70 K5) — translateX alone left ~12 invisible links
       focusable, sending focus off-screen on mobile. */
    visibility: hidden;
  }
  .sidebar.open { transform: translateX(0); visibility: visible; }
  .menu-btn { display: grid; }
  .topbar { padding: 12px 16px; }
  /* Let the search shrink and the action buttons stay on-screen (they were
     pushed off the right edge + unreachable at ~390px). */
  .topbar-search { max-width: none; }
  /* 通用语音输入助手会给顶栏搜索框附加一个 64px 麦克风按钮；在拥挤的移动端顶栏里
     放不下，会溢出右边缘并被 body{overflow-x:hidden} 裁掉。输入区已提供语音输入，
     移动端的搜索麦克风冗余 —— 隐藏它，让 wrapper+input 填满搜索条。(移动端布局审计 2026-06-30) */
  /* !important to beat the inline display:flex that applyVoiceButtonStyles() sets. */
  .topbar-search .voice-input-btn { display: none !important; }
  .topbar-search .voice-input-wrapper { flex: 1; min-width: 0; display: flex; }
  .topbar-search .voice-input-wrapper input { flex: 1; min-width: 0; }
  /* Keep page-head action buttons inside the viewport — they wrap instead of
     overflowing (timeline Guide / Show all / Add moment ran off the right). */
  .page-head-actions { max-width: 100%; }
  .page { padding: 20px 16px 100px; }
  .page-head h1 { font-size: 26px; }
  .two-col { grid-template-columns: 1fr; }
  .today-grid { grid-template-columns: 1fr; }
  .level-card { grid-column: span 1; }
  .ispirit-card { grid-template-columns: 1fr; text-align: center; }
  .ispirit-avatar { width: 150px; height: 150px; margin: 0 auto; }
  .ispirit-stats { justify-content: center; }
  .bottom-nav {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
    background: var(--surface-raised); backdrop-filter: blur(14px); border-top: 1px solid var(--border);
    padding: 8px 4px env(safe-area-inset-bottom, 8px);
  }
  .bottom-nav button, .bottom-nav a {
    flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    font-size: 10px; color: var(--fg-muted); padding: 6px 4px; border-radius: 10px;
    min-height: 44px;  /* iOS minimum tap target (focus-mode links were 41px) */
    /* QA R2: without min-width:0 the flex items keep their content min-width
       (~100px each), so all 6 = ~600px and Forum/Journal/iSpirit fell off the
       375px viewport (untappable, body{overflow-x:hidden} hard-clips them).
       min-width:0 lets flex:1 share the bar equally; overflow:hidden clips any
       long label to its ~62px cell instead of forcing overflow. */
    min-width: 0; overflow: hidden;
  }
  .bottom-nav button > span, .bottom-nav a > span:not(.ico) {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .bottom-nav button.active, .bottom-nav a.active { color: var(--accent-cyan); }
  [data-ux-mode="cozy"] .bottom-nav button.active { color: #C66B6B; }
  .bottom-nav .ico { display: grid; place-items: center; }
}

/* ─── Animations ─── */
@keyframes fadeInUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.page > * { animation: fadeInUp 0.4s cubic-bezier(0.22,1,0.36,1) both; }
.page > *:nth-child(2) { animation-delay: 0.05s; }
.page > *:nth-child(3) { animation-delay: 0.10s; }
.page > *:nth-child(4) { animation-delay: 0.15s; }
.page > *:nth-child(5) { animation-delay: 0.20s; }

/* ─── Action tiles (Journal) ─── */
.action-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; margin-bottom: 24px; }
.action-tile {
  display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: center;
  padding: 16px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  text-align: left; transition: all 0.18s; color: var(--fg);
}
.action-tile:hover { transform: translateY(-1px); border-color: var(--border-strong); }
.action-tile.primary { background: linear-gradient(135deg, rgba(79,172,254,0.10), rgba(148,121,255,0.10)); border-color: var(--border-subtle); }
[data-ux-mode="cozy"] .action-tile.primary { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.08)); }
.action-ico {
  width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
  background: rgba(79,172,254,0.12); color: var(--accent-cyan);
}
[data-ux-mode="cozy"] .action-ico { background: rgba(198,107,107,0.12); color: #C66B6B; }
.action-tile.primary .action-ico { background: var(--gradient-brand); color: white; }
.action-tile h4 { font-size: 14px; margin-bottom: 2px; }
.action-tile p { font-size: 12px; color: var(--fg-muted); margin: 0; }

/* ─── Journal entries ─── */
.entry-list { display: flex; flex-direction: column; gap: 10px; }
.entry-card {
  display: grid; grid-template-columns: auto 1fr auto; gap: 16px; align-items: start;
  padding: 18px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  transition: all 0.2s; cursor: pointer;
}
[data-ux-mode="cozy"] .entry-card { background: var(--surface-raised, #FFFBF2); }
.entry-card:hover { transform: translateY(-1px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.entry-side { display: flex; flex-direction: column; align-items: center; gap: 4px; padding-top: 4px; min-width: 32px; }
.mood-dot { width: 10px; height: 10px; border-radius: 50%; box-shadow: 0 0 10px currentColor; }
.mood-num { font-size: 11px; font-weight: 600; color: var(--fg-muted); }
.entry-meta { display: flex; gap: 12px; flex-wrap: wrap; font-size: 11px; color: var(--fg-muted); margin-bottom: 8px; align-items: center; }
.entry-date { font-weight: 600; letter-spacing: 0.04em; }
.entry-type { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 99px; background: var(--surface-flat); border: 1px solid var(--border); }
.entry-words { color: var(--fg-faded); }
/* 设计评审 P1-2 —— 标题使用全强度颜色，避免长列表变成一片灰蒙蒙的墙。 */
.entry-title { font-size: 16px; font-weight: 600; margin-bottom: 6px; color: var(--fg-strong); }
[data-ux-mode="cozy"] .entry-title { font-family: var(--font-serif); }

/* 来源标签 —— 用颜色区分每条记录的来源（手动 / 灵宠生成 / 历史），
   一眼即可辨认。纯文本（不依赖图标），无需 inflate。设计评审 P1-2。 */
.entry-source-chip {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 99px; line-height: 1.5;
  border: 1px solid var(--border); background: var(--surface-flat); color: var(--fg-muted);
}
/* 用 color-mix 取代固定的冷紫色，让色调在 cozy 模式下自动变暖
   （--accent-purple → 金色），而不是在奶油纸面上显示冷紫。 */
.entry-source-chip[data-src="auto"] {
  color: var(--accent-purple);
  background: color-mix(in srgb, var(--accent-purple) 12%, transparent);
  border-color: var(--border-subtle);
}
.entry-source-chip[data-src="history"] {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  border-color: color-mix(in srgb, var(--warning) 30%, transparent);
}
.entry-source-chip[data-src="external"] {
  color: var(--success, #2e7d32);
  background: color-mix(in srgb, var(--success, #2e7d32) 12%, transparent);
  border-color: color-mix(in srgb, var(--success, #2e7d32) 30%, transparent);
}
.entry-card[data-source-type="cec_output"],
.entry-card[data-source-type="cec_review"],
.entry-card[data-source-type="cec_plan"] {
  border-color: var(--border-subtle);
  background: color-mix(in srgb, var(--accent-purple) 5%, var(--surface-2));
}
.entry-card[data-source-type="history"],
.entry-card[data-source-type="on_this_day"],
.entry-card[data-source-type="imported"] {
  border-color: color-mix(in srgb, var(--warning) 30%, transparent);
  background: color-mix(in srgb, var(--warning) 5%, var(--surface-2));
}

/* 按天分隔，让多条记录读起来是分开的几天，而不是一整片。 */
.journal-day-divider {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 12px;
  margin: var(--space-5, 24px) 2px 6px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--fg-faded);
}
.journal-day-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border-subtle);
}
.journal-day-divider:first-child { margin-top: 0; }
.entry-body { font-size: 13px; color: var(--fg-muted); line-height: 1.55; margin: 0 0 10px; }
[data-ux-mode="cozy"] .entry-body { color: var(--fg); opacity: 0.78; font-style: italic; }
.entry-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.entry-tag { font-size: 11px; color: var(--fg-faded); padding: 2px 6px; border-radius: 6px; background: var(--surface-flat); }
.entry-arrow { color: var(--fg-faded); padding-top: 4px; }

/* ─── Habits ─── */
.challenge-banner {
  display: grid; grid-template-columns: auto 1fr auto; gap: 16px; align-items: center;
  padding: 18px 22px; margin-bottom: 22px;
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, rgba(245,158,11,0.10), rgba(148,121,255,0.10));
  border: 1px solid var(--border-subtle);
}
.challenge-ico {
  width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center;
  background: linear-gradient(135deg, #f59e0b, #fbbf24); color: white;
}
.challenge-body h3 { font-size: 17px; margin: 4px 0 4px; }
.challenge-body p { font-size: 12px; color: var(--fg-muted); margin: 0; }

.habit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; margin-bottom: 18px; }
.habit-card {
  padding: 18px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 10px; transition: all 0.2s;
}
[data-ux-mode="cozy"] .habit-card { background: var(--surface-raised, #FFFBF2); }
.habit-card:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.habit-head { display: flex; justify-content: space-between; align-items: center; }
.habit-streak {
  display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600;
  color: #f59e0b; background: rgba(245,158,11,0.10); padding: 3px 8px; border-radius: 99px; border: 1px solid rgba(245,158,11,0.22);
}
.habit-title { font-size: 15px; font-weight: 600; line-height: 1.3; }
[data-ux-mode="cozy"] .habit-title { font-family: var(--font-serif); }
.habit-when { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--fg-muted); margin: 0; }
.habit-progress { display: flex; align-items: center; gap: 8px; }
.habit-progress .progress-bar { flex: 1; height: 6px; }
.habit-progress span { font-size: 11px; font-weight: 600; color: var(--fg-muted); }
.habit-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 4px; }
.habit-level { font-size: 11px; color: var(--fg-faded); text-transform: uppercase; letter-spacing: 0.10em; font-weight: 600; }
.check-btn {
  padding: 7px 12px; font-size: 12px; font-weight: 600; border-radius: 99px;
  background: var(--surface-flat); border: 1px solid var(--border); color: var(--fg-muted);
  display: inline-flex; align-items: center; gap: 5px; transition: all 0.18s;
}
.check-btn:hover { color: var(--fg); border-color: var(--border-strong); }
.check-btn.checked { background: rgba(52,211,153,0.12); color: var(--success); border-color: rgba(52,211,153,0.30); }
.habit-reward {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--fg-faded);
  padding: 6px 10px; border-radius: 8px; background: var(--surface-flat); border: 1px dashed var(--border);
}

/* ─── Chat ─── */
.chat-shell { display: grid; grid-template-columns: 1fr 320px; gap: 18px; align-items: start; }
.chat-thread {
  display: flex; flex-direction: column; gap: 14px;
  padding: 18px; border-radius: var(--radius-lg); background: var(--surface-2); border: 1px solid var(--border);
  min-height: 560px;
}
[data-ux-mode="cozy"] .chat-thread { background: var(--surface-raised, #FFFBF2); }
.chat-thread-head { display: flex; justify-content: space-between; align-items: center; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.chat-spirit { display: flex; align-items: center; gap: 12px; }
.chat-spirit-av { width: 40px; height: 40px; border-radius: 50%; background: radial-gradient(circle, rgba(148,121,255,0.20), transparent 70%); display: grid; place-items: center; }
.chat-spirit-av img { width: 90%; height: 90%; object-fit: contain; }
.chat-spirit-name { font-weight: 600; font-size: 14px; }
.chat-spirit-status { font-size: 11px; color: var(--fg-muted); display: flex; align-items: center; gap: 6px; }
.online-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); box-shadow: 0 0 8px rgba(52,211,153,0.6); }

.chat-log { display: flex; flex-direction: column; gap: 12px; padding: 6px 0; }
.bubble-row { display: flex; gap: 10px; align-items: flex-end; }
.bubble-row.user { flex-direction: row-reverse; }
.bubble-av { width: 32px; height: 32px; border-radius: 50%; background: rgba(148,121,255,0.14); display: grid; place-items: center; flex: 0 0 32px; }
.bubble-av img { width: 26px; height: 26px; }
.bubble-av.user { background: var(--gradient-brand); color: white; font-weight: 600; font-size: 13px; }
.bubble {
  max-width: 70%; padding: 12px 14px; border-radius: 16px;
  background: var(--surface-flat); border: 1px solid var(--border);
}
.bubble.user { background: var(--gradient-brand); color: white; border-color: transparent; border-bottom-right-radius: 4px; }
.bubble.spirit { border-bottom-left-radius: 4px; }
.bubble-text { font-size: 14px; line-height: 1.55; }
.bubble-time { font-size: 10px; opacity: 0.6; margin-top: 4px; }

.chat-suggest { display: flex; gap: 6px; flex-wrap: wrap; }
.suggest-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 7px 12px; border-radius: 99px;
  background: var(--surface-flat); border: 1px solid var(--border);
  font-size: 12px; color: var(--fg-muted); transition: all 0.18s;
}
.suggest-pill:hover { color: var(--fg); border-color: var(--border-strong); }

.composer {
  display: grid; grid-template-columns: auto auto 1fr auto; gap: 8px; align-items: center;
  padding: 8px; border-radius: 14px; background: var(--surface-flat); border: 1px solid var(--border);
}
.composer-btn { width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; color: var(--fg-muted); transition: all 0.18s; }
.composer-btn:hover { background: rgba(255,255,255,0.04); color: var(--fg); }
.composer textarea {
  width: 100%; resize: none; border: 0; outline: none; background: transparent; font-size: 14px; color: var(--fg);
  padding: 6px; min-height: 22px; max-height: 120px; line-height: 1.4;
}
.composer-send {
  display: inline-flex; align-items: center; gap: 5px; padding: 8px 14px; border-radius: 99px;
  background: var(--gradient-brand); color: white; font-size: 12px; font-weight: 600;
}
.composer-send:disabled { opacity: 0.5; cursor: not-allowed; }

.chat-side .card { padding: 16px; }
.guide-block { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border); }
.guide-block:first-of-type { border-top: 0; }
.guide-block h4 { font-size: 12px; font-weight: 600; margin-bottom: 6px; color: var(--fg); }
.guide-line { font-size: 12px; color: var(--fg-muted); font-family: var(--font-mono, monospace); padding: 4px 0; opacity: 0.85; }

.hold-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.hold-list li { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 13px; padding: 8px 10px; background: var(--surface-flat); border: 1px solid var(--border); border-radius: 10px; }

/* ─── iSpirit ─── */
.spirit-hero {
  display: grid; grid-template-columns: 280px 1fr; gap: 32px; padding: 32px;
  border-radius: var(--radius-xl); margin-bottom: 22px; align-items: center;
  background: linear-gradient(135deg, rgba(79,172,254,0.10), rgba(148,121,255,0.12));
  border: 1px solid var(--border-subtle);
  position: relative; overflow: hidden;
}
[data-ux-mode="cozy"] .spirit-hero { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.08)); border-color: rgba(182,151,99,0.30); }
.spirit-portrait { position: relative; width: 240px; height: 240px; display: grid; place-items: center; margin: 0 auto; }
.spirit-aura { position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle, rgba(148,121,255,0.30), transparent 65%); animation: pulse 4s ease-in-out infinite; }
.spirit-aura.ring2 { background: radial-gradient(circle, rgba(79,172,254,0.18), transparent 70%); animation-delay: 1s; }
@keyframes pulse { 0%,100%{transform:scale(1);opacity:0.85;} 50%{transform:scale(1.08);opacity:1;} }
.spirit-portrait img { position: relative; width: 80%; height: 80%; object-fit: contain; z-index: 1; }
.spirit-meta { display: flex; flex-direction: column; gap: 14px; }
.spirit-row { display: flex; gap: 6px; flex-wrap: wrap; }
.spirit-name { font-size: 26px; line-height: 1.2; max-width: 540px; font-family: var(--font-display); }
[data-ux-mode="cozy"] .spirit-name { font-family: var(--font-serif); }
.spirit-quote { font-size: 15px; color: var(--fg); font-style: italic; line-height: 1.6; max-width: 580px; }
[data-ux-mode="cozy"] .spirit-quote { font-family: var(--font-serif); }
.spirit-stats { display: flex; gap: 24px; flex-wrap: wrap; }
.energy-bar { max-width: 320px; }

.obs-list { display: flex; flex-direction: column; gap: 10px; }
.obs { padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-flat); border: 1px solid var(--border); display: flex; gap: 10px; align-items: start; }
.obs p { margin: 0; font-size: 13px; line-height: 1.55; }
.obs-kind {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.10em;
  padding: 3px 8px; border-radius: 99px; flex-shrink: 0; margin-top: 1px;
}
.obs-kind.pattern { background: rgba(148,121,255,0.12); color: var(--accent-purple); }
.obs-kind.echo { background: rgba(79,172,254,0.12); color: var(--accent-cyan); }
.obs-kind.quiet { background: rgba(245,158,11,0.10); color: var(--warning); }

.voice-list { display: flex; flex-direction: column; gap: 8px; }
.voice-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center;
  padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--surface-flat); border: 1px solid var(--border); transition: all 0.18s; text-align: left;
}
.voice-row:hover { border-color: var(--border-strong); }
.voice-row.active { background: linear-gradient(90deg, rgba(79,172,254,0.10), rgba(148,121,255,0.08)); border-color: var(--border-subtle); }
.voice-radio { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--border-strong); display: grid; place-items: center; }
.voice-row.active .voice-radio { border-color: var(--accent-purple); }
.voice-radio span { width: 8px; height: 8px; border-radius: 50%; background: var(--accent-purple); }
.voice-meta h4 { font-size: 13px; margin-bottom: 2px; }
.voice-meta p { font-size: 11px; color: var(--fg-muted); margin: 0; }

.stage-rail { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; position: relative; padding: 18px 0 8px; }
.stage-rail::before { content: ""; position: absolute; left: 5%; right: 5%; top: 30px; height: 2px; background: var(--border); border-radius: 1px; z-index: 0; }
.stage-step { display: flex; flex-direction: column; align-items: center; gap: 8px; position: relative; z-index: 1; font-size: 12px; color: var(--fg-muted); }
.stage-dot {
  width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface-flat); border: 2px solid var(--border); font-size: 11px; font-weight: 600; color: var(--fg-muted);
}
.stage-step.done .stage-dot { background: var(--gradient-brand); border-color: transparent; color: white; }
.stage-step.active .stage-dot { box-shadow: 0 0 0 4px rgba(148,121,255,0.20); }
.stage-step.active span { color: var(--fg-strong); font-weight: 600; }

/* ─── Profile ─── */
.profile-hero {
  display: grid; grid-template-columns: auto 1fr auto; gap: 24px; align-items: center;
  padding: 24px; margin-bottom: 22px;
  border-radius: var(--radius-xl); background: var(--surface-2); border: 1px solid var(--border);
}
[data-ux-mode="cozy"] .profile-hero { background: var(--surface-raised, #FFFBF2); }
.profile-av {
  width: 88px; height: 88px; border-radius: 50%; background: var(--gradient-brand);
  display: grid; place-items: center; color: white; font-family: var(--font-display); font-weight: 700; font-size: 32px;
  box-shadow: 0 8px 28px rgba(148,121,255,0.35);
}
/* Cozy: the brand gradient's gold stop gives white text only ~2.1:1 (WCAG AA
   fail). Use the reconciled rose gradient — white on --cozy-rose is 5.63:1,
   on --cozy-rose-dark 7.28:1. Mirrors EN app-shell.css (Dev Rule #16). */
[data-ux-mode="cozy"] .profile-av {
  background: linear-gradient(135deg, var(--cozy-rose), var(--cozy-rose-dark));
}
.profile-id h2 { font-size: 24px; margin-bottom: 6px; }
[data-ux-mode="cozy"] .profile-id h2 { font-family: var(--font-serif); }
.profile-line { font-size: 13px; color: var(--fg-muted); margin-bottom: 10px; }
.profile-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.profile-coverage { display: flex; align-items: center; gap: 14px; }
.cov-ring {
  --cov: 0;
  width: 72px; height: 72px; border-radius: 50%;
  background: conic-gradient(var(--accent-cyan) calc(var(--cov) * 1%), var(--surface-flat) 0);
  display: grid; place-items: center; position: relative;
}
.cov-ring::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--surface-2); }
[data-ux-mode="cozy"] .cov-ring::before { background: var(--surface-raised, #FFFBF2); }
.cov-ring span { position: relative; font-weight: 600; font-size: 14px; z-index: 1; }
.cov-meta h4 { font-size: 13px; margin-bottom: 2px; }
.cov-meta p { font-size: 11px; color: var(--fg-muted); margin: 0; max-width: 200px; }

.setting-list { display: flex; flex-direction: column; gap: 8px; }
.setting-row {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-flat); border: 1px solid var(--border);
  font-size: 13px;
}
.toggle {
  width: 38px; height: 22px; border-radius: 99px; background: var(--surface-2); border: 1px solid var(--border); position: relative; padding: 0; transition: all 0.2s;
}
.toggle span { position: absolute; left: 2px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; border-radius: 50%; background: var(--fg-faded); transition: all 0.2s; }
.toggle.on { background: var(--gradient-brand); border-color: transparent; }
.toggle.on span { left: 19px; background: white; }

.about-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.about-card { padding: 18px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border); }
[data-ux-mode="cozy"] .about-card { background: var(--surface-raised, #FFFBF2); }
.about-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.about-head h4 { font-size: 14px; }
.cov-pill { font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: 99px; background: var(--surface-flat); color: var(--fg-muted); border: 1px solid var(--border); }

.data-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
.data-tile {
  display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start;
  padding: 14px; border-radius: var(--radius-md); background: var(--surface-flat); border: 1px solid var(--border);
  text-align: left; color: var(--fg); transition: all 0.18s;
}
.data-tile:hover { border-color: var(--border-strong); }
.data-tile.danger { color: var(--danger); }
.data-tile h4 { font-size: 13px; margin-bottom: 2px; }
.data-tile p { font-size: 11px; color: var(--fg-muted); margin: 0; }

/* ─── Wizards ─── */
/* QA R5 residual: app.js wraps each featured <a class="wizard-feature"> + its
   favourite-star <button> in this div so the star is a SIBLING, never a
   descendant of the link (nested-interactive a11y violation). */
.wiz-feature-wrap { position: relative; }
.wiz-feature-wrap > .wizard-feature { width: 100%; height: 100%; box-sizing: border-box; }
.wizard-feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; margin-bottom: 22px; }
/* display:grid above beats the UA [hidden] rule — restore it so app.js can hide the grid when a wizard is active */
.wizard-feature-grid[hidden] { display: none; }
.wizard-feature {
  display: grid; grid-template-columns: auto 1fr; gap: 14px; align-items: start;
  padding: 20px; border-radius: var(--radius-lg); background: var(--surface-2); border: 1px solid var(--border);
  text-align: left; color: var(--fg); transition: all 0.2s;
}
[data-ux-mode="cozy"] .wizard-feature { background: var(--surface-raised, #FFFBF2); }
.wizard-feature:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.wizard-feature.primary { background: linear-gradient(135deg, rgba(79,172,254,0.10), rgba(148,121,255,0.10)); border-color: var(--border-subtle); }
[data-ux-mode="cozy"] .wizard-feature.primary { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.08)); }
.wf-ico { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; background: rgba(79,172,254,0.12); color: var(--accent-cyan); }
.wizard-feature.primary .wf-ico { background: var(--gradient-brand); color: white; }
.wf-body h3 { font-size: 16px; margin-bottom: 6px; }
[data-ux-mode="cozy"] .wf-body h3 { font-family: var(--font-serif); }
.wf-body p { font-size: 13px; color: var(--fg-muted); line-height: 1.5; margin: 0 0 12px; }
.wf-meta { display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: var(--fg-muted); }
.wf-arrow { display: inline-flex; align-items: center; gap: 4px; color: var(--accent-cyan); font-weight: 600; }
[data-ux-mode="cozy"] .wf-arrow { color: #C66B6B; }

.wizard-tmpl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; }
.wizard-tmpl {
  padding: 16px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 8px; transition: all 0.2s;
}
[data-ux-mode="cozy"] .wizard-tmpl { background: var(--surface-raised, #FFFBF2); }
.wizard-tmpl:hover { border-color: var(--border-strong); }
.wt-head { display: flex; justify-content: space-between; align-items: start; gap: 8px; }
.wt-head h4 { font-size: 14px; }
.wizard-tmpl p { font-size: 12px; color: var(--fg-muted); line-height: 1.5; margin: 0; flex: 1; }
.wt-foot { display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: var(--fg-faded); margin-top: 4px; }
.wt-cta { display: inline-flex; align-items: center; gap: 4px; color: var(--accent-cyan); font-weight: 600; font-size: 12px; }
[data-ux-mode="cozy"] .wt-cta { color: #C66B6B; }

.run-list { display: flex; flex-direction: column; gap: 8px; }
.run-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center;
  padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-flat); border: 1px solid var(--border);
}
.run-status { width: 10px; height: 10px; border-radius: 50%; }
.run-status.complete { background: var(--success); }
.run-status.running { background: var(--accent-cyan); box-shadow: 0 0 10px rgba(79,172,254,0.6); }
.run-title { font-size: 13px; font-weight: 600; margin-bottom: 2px; }
.run-outcome { font-size: 12px; color: var(--fg-muted); }
.run-date { font-size: 11px; color: var(--fg-muted); }

/* ─── Chat responsive ─── */
@media (max-width: 1100px) { .chat-shell { grid-template-columns: 1fr; } }
@media (max-width: 900px) {
  .spirit-hero { grid-template-columns: 1fr; text-align: center; }
  .spirit-portrait { width: 200px; height: 200px; }
  .spirit-stats { justify-content: center; }
  .profile-hero { grid-template-columns: 1fr; text-align: center; justify-items: center; }
  .stage-rail { grid-template-columns: repeat(3, 1fr); row-gap: 18px; }
  .stage-rail::before { display: none; }
  /* Touch targets: WCAG 2.5.5 / mobile ergonomics — composer controls ≥44px. */
  .composer-send { min-height: 44px; padding-top: 10px; padding-bottom: 10px; }
  .composer-btn { width: 44px; height: 44px; }
  .composer .voice-input-btn { min-width: 44px; min-height: 44px; }
  /* Round 58 LOW-3：页头工具栏按钮（日记「新建」「批量导入」、进度「刷新」等）
     在手机上仅 29-37px 高。注意：聊天页的 #send 需在 chat_inline.css 单独处理 ——
     其 ID 特异性覆盖会压过这里的任何规则（MED-4）。 */
  .page-head .btn, .page-head-actions .btn { min-height: 44px; }
  .voice-input-btn { min-width: 44px; min-height: 44px; }
}

/* ─── Embedded mission inside room ─── */
.missions-page.embedded { padding: 0; max-width: none; }
.missions-page.embedded > * { animation: none; }
.room-mission-wrap { margin-top: -4px; }
.missions-page { max-width: 100%; }
.mission-picker { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; margin-bottom: 18px; }
.mission-tab {
  text-align: left; padding: 14px 16px; border-radius: var(--radius-md);
  background: var(--surface-2); border: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 6px; color: var(--fg); transition: all 0.18s;
}
[data-ux-mode="cozy"] .mission-tab { background: var(--surface-raised, #FFFBF2); }
.mission-tab:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.mission-tab.active { background: linear-gradient(135deg, rgba(79,172,254,0.10), rgba(148,121,255,0.10)); border-color: var(--border-subtle); }
.mt-head { display: flex; align-items: center; gap: 8px; }
.mt-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.mt-dot.on-track { background: var(--success); }
.mt-dot.watch { background: var(--warning); }
.mt-dot.risk { background: var(--danger); }
.mt-title { font-size: 13px; font-weight: 600; line-height: 1.3; }
[data-ux-mode="cozy"] .mt-title { font-family: var(--font-serif); }
.mt-meta { font-size: 11px; color: var(--fg-muted); display: flex; gap: 6px; }
.mt-bar { height: 4px; border-radius: 2px; background: var(--surface-flat); overflow: hidden; }
.mt-bar span { display: block; height: 100%; background: var(--gradient-brand); border-radius: 2px; }

.legend {
  display: flex; gap: 16px; flex-wrap: wrap; padding: 10px 14px; margin-bottom: 14px;
  background: var(--surface-flat); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 11px; color: var(--fg-muted); align-items: center;
}
.legend > span { display: inline-flex; align-items: center; gap: 6px; }
.legend .lg.dot { width: 8px; height: 8px; border-radius: 50%; }
.legend .lg-line { width: 22px; height: 2px; }
.legend .lg-line.solid { background: var(--accent-cyan); }
.legend .lg-line.dashed { border-top: 2px dashed var(--fg-faded); }
.legend-hint { margin-left: auto; font-style: italic; opacity: 0.7; }

.mission-canvas-wrap { overflow-x: auto; padding: 4px; }
.mission-canvas {
  position: relative; min-width: 1080px; min-height: 600px;
  background: var(--surface-flat); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 32px 28px;
}
.mission-edges { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.mission-edges path { fill: none; transition: stroke-width 0.18s, opacity 0.18s; }
.mission-edges path.s-done { stroke: var(--success); }
.mission-edges path.s-active, .mission-edges path.s-doing { stroke: var(--accent-cyan); }
.mission-edges path.s-upcoming, .mission-edges path.s-todo { stroke: var(--fg-faded); }
.mission-edges path.s-blocked { stroke: var(--danger); }
.mission-edges path.is-dep { stroke: var(--fg-faded); stroke-dasharray: 4 5; stroke-width: 1.2; }
.mission-edges path.is-flow { stroke-width: 1.8; opacity: 0.55; }
.mission-edges path.is-hot { stroke-width: 2.5; opacity: 1; }
.mission-edges path.is-dim { opacity: 0.18; }
.mission-grid {
  display: grid; grid-template-columns: 220px 260px 1fr; gap: 70px;
  align-items: center; position: relative; z-index: 1;
}
.col { display: flex; flex-direction: column; gap: 16px; }
.goal-col { justify-content: center; min-height: 540px; }
.milestone-col { gap: 18px; }

.node {
  position: relative; cursor: pointer; transition: all 0.18s;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-md);
}
[data-ux-mode="cozy"] .node { background: var(--surface-raised, #FFFBF2); }
.node:hover { transform: translateY(-1px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.node.primary { border-color: var(--accent-cyan); box-shadow: 0 0 0 2px rgba(79,172,254,0.20); }
.node.related { border-color: var(--border-subtle); background: linear-gradient(135deg, rgba(79,172,254,0.06), rgba(148,121,255,0.06)); }

/* Goal node */
.goal-node {
  padding: 18px; display: flex; flex-direction: column; gap: 10px;
  background: linear-gradient(135deg, rgba(79,172,254,0.10), rgba(148,121,255,0.12));
  border-color: var(--border-subtle);
}
[data-ux-mode="cozy"] .goal-node { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.08)); }
.node-kind {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--accent-cyan); align-self: flex-start;
  padding: 3px 8px; border-radius: 99px; background: rgba(79,172,254,0.10); border: 1px solid rgba(79,172,254,0.22);
}
[data-ux-mode="cozy"] .node-kind { color: #C66B6B; background: rgba(198,107,107,0.10); border-color: rgba(198,107,107,0.22); }
.goal-title { font-size: 17px; line-height: 1.3; }
[data-ux-mode="cozy"] .goal-title { font-family: var(--font-serif); }
.goal-progress { display: flex; align-items: center; gap: 8px; }
.goal-progress .progress-bar { flex: 1; height: 6px; }
.goal-progress span { font-size: 12px; font-weight: 600; color: var(--fg-muted); }
.goal-meta { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--fg-muted); }
.goal-meta span { display: inline-flex; align-items: center; gap: 5px; }
.health-pill {
  align-self: flex-start; font-size: 10px; font-weight: 600; padding: 3px 8px; border-radius: 99px;
  text-transform: uppercase; letter-spacing: 0.08em;
}
.health-pill.on-track { background: rgba(52,211,153,0.10); color: var(--success); border: 1px solid rgba(52,211,153,0.30); }
.health-pill.watch { background: rgba(245,158,11,0.10); color: var(--warning); border: 1px solid rgba(245,158,11,0.30); }
.health-pill.risk { background: rgba(239,68,68,0.10); color: var(--danger); border: 1px solid rgba(239,68,68,0.30); }

/* Milestone node */
.milestone-node { padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.milestone-node.status-done { border-left: 3px solid var(--success); }
.milestone-node.status-active { border-left: 3px solid var(--accent-cyan); }
.milestone-node.status-upcoming { border-left: 3px solid var(--fg-faded); }
.milestone-node.status-blocked { border-left: 3px solid var(--danger); }
.m-head { display: flex; align-items: center; gap: 8px; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.status-dot.done { background: var(--success); }
.status-dot.active, .status-dot.doing { background: var(--accent-cyan); box-shadow: 0 0 8px rgba(79,172,254,0.6); }
.status-dot.upcoming, .status-dot.todo { background: var(--fg-faded); }
.status-dot.blocked { background: var(--danger); }
.status-tag {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.10em;
  color: var(--fg-muted);
}
.m-due { margin-left: auto; font-size: 11px; color: var(--fg-muted); }
.m-title { font-size: 14px; font-weight: 600; line-height: 1.3; }
[data-ux-mode="cozy"] .m-title { font-family: var(--font-serif); }
.m-progress { display: flex; align-items: center; gap: 8px; }
.m-progress .progress-bar { flex: 1; height: 5px; }
.m-progress span { font-size: 11px; font-weight: 600; color: var(--fg-muted); min-width: 30px; text-align: right; }
.m-foot { display: flex; gap: 10px; font-size: 11px; color: var(--fg-faded); flex-wrap: wrap; }
.m-foot span { display: inline-flex; align-items: center; gap: 4px; }

/* Task node */
.task-cluster { display: flex; flex-direction: column; gap: 8px; }
.task-cluster + .task-cluster { padding-top: 14px; border-top: 1px dashed var(--border); }
.task-node { padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; }
.task-node.status-done { opacity: 0.72; }
.task-node.status-done .t-title { text-decoration: line-through; text-decoration-color: var(--fg-faded); }
.task-node.status-doing { border-color: rgba(79,172,254,0.40); }
.task-node.status-blocked { border-color: rgba(239,68,68,0.40); background: rgba(239,68,68,0.04); }
.t-row { display: flex; align-items: center; gap: 8px; }
.t-title { font-size: 13px; font-weight: 500; line-height: 1.3; flex: 1; }
.t-meta { font-size: 11px; color: var(--fg-muted); display: flex; gap: 5px; padding-left: 16px; }
.t-block {
  font-size: 11px; color: var(--danger); padding: 4px 8px; border-radius: 6px;
  background: rgba(239,68,68,0.08); border: 1px solid rgba(239,68,68,0.20);
  display: inline-flex; align-items: center; gap: 4px; margin-top: 4px;
}

/* Detail drawer */
.mission-detail {
  position: fixed; top: 80px; right: 24px; width: 340px; max-height: calc(100vh - 110px);
  overflow-y: auto; padding: 22px;
  background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: 0 20px 60px rgba(0,0,0,0.45);
  z-index: 30; animation: slideInRight 0.25s cubic-bezier(0.22,1,0.36,1);
}
[data-ux-mode="cozy"] .mission-detail { background: var(--surface-raised, #FFFBF2); box-shadow: 0 20px 60px rgba(90,60,30,0.18); }
@keyframes slideInRight { from { transform: translateX(20px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
.md-close {
  position: absolute; top: 12px; right: 12px; width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center; color: var(--fg-muted);
  background: var(--surface-flat); border: 1px solid var(--border);
}
.md-close:hover { color: var(--fg); }
.md-kind {
  display: inline-block; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--accent-cyan); padding: 3px 8px; border-radius: 99px;
  background: rgba(79,172,254,0.10); border: 1px solid rgba(79,172,254,0.22); margin-bottom: 10px;
}
[data-ux-mode="cozy"] .md-kind { color: #C66B6B; background: rgba(198,107,107,0.10); border-color: rgba(198,107,107,0.22); }
.md-title { font-size: 18px; line-height: 1.3; margin-bottom: 8px; padding-right: 32px; }
[data-ux-mode="cozy"] .md-title { font-family: var(--font-serif); }
.md-desc { font-size: 13px; color: var(--fg-muted); line-height: 1.55; margin: 0 0 16px; }
.md-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 16px; }
.md-stats > div { padding: 10px 12px; background: var(--surface-flat); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.md-stats .l { font-size: 10px; text-transform: uppercase; letter-spacing: 0.10em; color: var(--fg-muted); margin-bottom: 3px; font-weight: 600; }
.md-stats .v { font-size: 13px; font-weight: 600; }
.md-section { margin-bottom: 14px; }
.md-section h4 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--fg-muted); margin-bottom: 8px; font-weight: 600; }
.md-mini {
  display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center;
  padding: 8px 10px; background: var(--surface-flat); border: 1px solid var(--border); border-radius: var(--radius-sm);
  margin-bottom: 6px; cursor: pointer; transition: all 0.15s;
}
.md-mini:hover { border-color: var(--border-strong); }
.mini-title { font-size: 12px; line-height: 1.3; }
.mini-pct { font-size: 11px; color: var(--fg-muted); font-weight: 600; }
.md-block { padding: 10px 12px; font-size: 12px; background: rgba(239,68,68,0.08); border: 1px solid rgba(239,68,68,0.22); color: var(--danger); border-radius: var(--radius-sm); }
.md-actions { display: flex; gap: 6px; }

@media (max-width: 1100px) {
  .mission-detail { position: fixed; top: auto; right: 12px; left: 12px; bottom: 80px; width: auto; }
  .mission-grid { gap: 60px; }
}
@media (max-width: 900px) {
  .mission-canvas { padding: 20px 16px; min-width: 980px; }
  .mission-grid { grid-template-columns: 200px 280px 1fr; gap: 50px; }
}

/* ─── Recap banner (Progress + Group Room) ─── */
.recap-banner {
  display: grid; grid-template-columns: auto 1fr auto; gap: 16px; align-items: start;
  padding: 16px 18px; margin-bottom: 22px;
  background: linear-gradient(135deg, rgba(79,172,254,0.08), rgba(148,121,255,0.08));
  border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
}
[data-ux-mode="cozy"] .recap-banner { background: linear-gradient(135deg, rgba(182,151,99,0.10), rgba(198,107,107,0.06)); border-color: rgba(182,151,99,0.30); }
.recap-ico {
  width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center;
  background: var(--gradient-brand); color: white; flex-shrink: 0;
}
.recap-body { display: flex; flex-direction: column; gap: 6px; }
.recap-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.recap-list li { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--fg); }
.recap-it-ico { display: inline-flex; color: var(--accent-cyan); }
[data-ux-mode="cozy"] .recap-it-ico { color: #C66B6B; }
.recap-close { width: 28px; height: 28px; border-radius: 8px; color: var(--fg-muted); display: grid; place-items: center; transition: all 0.15s; }
.recap-close:hover { background: rgba(255,255,255,0.04); color: var(--fg); }

/* ─── Today's signals (iSpirit hero) ─── */
.today-signals {
  position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 4px; width: 320px;
  pointer-events: none;
}
/* Inside #ispiritExtras the signals are a normal-flow strip, not a portrait
   overlay — the empty 240px .spirit-portrait anchor they used to ride on
   left a large blank gap mid-page (QA 2026-07-16 r2). */
.ispirit-extras .today-signals {
  position: static; transform: none; width: auto; max-width: 340px;
  margin: 0 auto;
}
.signal {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 99px;
  background: var(--surface-2); border: 1px solid var(--border-subtle);
  font-size: 11px; color: var(--fg-muted);
  animation: fadeInUp 0.5s cubic-bezier(0.22,1,0.36,1) both;
  pointer-events: auto;
}
[data-ux-mode="cozy"] .signal { background: var(--surface-raised, #FFFBF2); }
.signal:nth-child(2) { animation-delay: 0.1s; }
.signal:nth-child(3) { animation-delay: 0.2s; }
.signal-ico { color: var(--accent-cyan); display: inline-flex; flex-shrink: 0; }
[data-ux-mode="cozy"] .signal-ico { color: #C66B6B; }
.signal-cap { line-height: 1.4; }

/* ─── Identity panel (iSpirit) ─── */
.identity-card { margin-bottom: 18px; }
.identity-rows { display: flex; flex-direction: column; gap: 12px; }
.identity-row { display: grid; grid-template-columns: 140px 1fr; gap: 16px; align-items: center; padding: 10px 0; border-bottom: 1px dashed var(--border); }
.identity-row:last-child { border-bottom: 0; }
.identity-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.10em; color: var(--fg-muted); font-weight: 600; }
.identity-value { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.identity-value.v-italic { font-style: italic; color: var(--fg); }
[data-ux-mode="cozy"] .identity-value.v-italic { font-family: var(--font-serif); }
.cov-bar { flex: 1; max-width: 260px; height: 6px; border-radius: 3px; background: var(--surface-flat); overflow: hidden; }
.cov-bar span { display: block; height: 100%; background: var(--gradient-brand); border-radius: 3px; }
.identity-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.word-chip {
  padding: 4px 10px; border-radius: 99px; font-size: 12px;
  background: var(--surface-flat); border: 1px solid var(--border); color: var(--fg);
  font-family: var(--font-mono, monospace);
}

/* ─── Empire stage rail (replaces default) ─── */
.stage-rail.empire { grid-template-columns: repeat(5, 1fr); padding: 24px 0 12px; }
.stage-rail.empire::before { left: 8%; right: 8%; top: 38px; }
.stage-rail.empire .stage-step { gap: 10px; padding: 0 4px; text-align: center; }
.stage-rail.empire .stage-dot { width: 32px; height: 32px; }
.stage-lbl { font-weight: 600; color: var(--fg); font-size: 13px; }
.stage-step.done .stage-lbl, .stage-step:not(.done):not(.active) .stage-lbl { color: var(--fg-muted); font-weight: 500; }
.stage-step.active .stage-lbl { color: var(--fg-strong); }
.stage-desc { font-size: 11px; color: var(--fg-faded); line-height: 1.4; max-width: 130px; }
.stage-step.active .stage-desc { color: var(--fg-muted); }

/* ─── Action proposal card (Chat + Group Room) ─── */
.proposal-card {
  margin-top: 12px; padding: 14px;
  border-radius: var(--radius-sm); background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  position: relative;
}
.bubble.user .proposal-card { background: rgba(255,255,255,0.10); border-color: rgba(255,255,255,0.20); }
.prop-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.prop-kind {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em;
  padding: 2px 8px; border-radius: 99px;
  background: var(--gradient-brand); color: white;
}
.prop-type { font-size: 11px; color: var(--fg-muted); font-family: var(--font-mono, monospace); }
.bubble.user .prop-type { color: rgba(255,255,255,0.7); }
.prop-title { font-size: 14px; font-weight: 600; margin-bottom: 6px; line-height: 1.3; }
.prop-payload { font-size: 12px; color: var(--fg-muted); margin: 0 0 8px; font-family: var(--font-mono, monospace); padding: 8px 10px; background: var(--surface-flat); border-radius: 6px; border: 1px solid var(--border); }
.bubble.user .prop-payload { background: rgba(0,0,0,0.20); color: rgba(255,255,255,0.85); }
.prop-rationale { font-size: 12px; color: var(--fg-muted); margin: 0 0 12px; font-style: italic; line-height: 1.5; }
.bubble.user .prop-rationale { color: rgba(255,255,255,0.8); }
.prop-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.prop-resolved { font-size: 12px; color: var(--fg-muted); display: inline-flex; align-items: center; gap: 5px; padding: 6px 10px; background: var(--surface-flat); border-radius: 6px; }
.prop-resolved.success { color: var(--success); background: rgba(52,211,153,0.08); }

/* ─── Shared goals rail (Missions) ─── */
.shared-rail { margin-bottom: 22px; }
.shared-rail-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; }
.shared-rail-head h3 { font-size: 16px; display: flex; align-items: center; gap: 8px; }
.shared-rail-head h3 svg { color: var(--accent-cyan); }
[data-ux-mode="cozy"] .shared-rail-head h3 svg { color: #C66B6B; }
.shared-rail-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.shared-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 16px; border-radius: var(--radius-md);
  background: var(--surface-2); border: 1px solid var(--border);
  text-align: left; color: var(--fg); transition: all 0.18s;
}
[data-ux-mode="cozy"] .shared-card { background: var(--surface-raised, #FFFBF2); }
.shared-card:hover { transform: translateY(-1px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.shared-card.add { background: transparent; border: 1px dashed var(--border-strong); align-items: center; justify-content: center; text-align: center; color: var(--fg-muted); }
.shared-card.add small { font-size: 10px; opacity: 0.7; margin-top: -4px; }
.shared-card-top { display: flex; justify-content: space-between; align-items: center; }
.role-badge {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.10em; font-weight: 600;
  padding: 3px 8px; border-radius: 99px;
}
.role-badge.owner { background: rgba(148,121,255,0.14); color: var(--accent-purple); border: 1px solid rgba(148,121,255,0.30); }
.role-badge.collaborator { background: rgba(79,172,254,0.10); color: var(--accent-cyan); border: 1px solid rgba(79,172,254,0.28); }
.sg-health-dot { width: 8px; height: 8px; border-radius: 50%; }
.sg-health-dot.on-track { background: var(--success); }
.sg-health-dot.watch { background: var(--warning); }
.sg-health-dot.risk { background: var(--danger); }
.shared-card h4 { font-size: 14px; line-height: 1.3; }
[data-ux-mode="cozy"] .shared-card h4 { font-family: var(--font-serif); }
.shared-meta { display: flex; gap: 10px; font-size: 11px; color: var(--fg-muted); align-items: center; flex-wrap: wrap; }
.shared-meta span { display: inline-flex; align-items: center; gap: 4px; }
.unread-badge { background: var(--gradient-brand); color: white !important; padding: 2px 7px; border-radius: 99px; font-weight: 600; font-size: 10px; }
.last-act { margin-left: auto; }
.sg-spirit-on { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--success); padding-top: 4px; border-top: 1px dashed var(--border); margin-top: 4px; }

/* ─── Group Room ─── */
.room-head { align-items: center; }
.back-link { font-size: 11px; color: var(--fg-muted); display: inline-flex; align-items: center; gap: 4px; margin-bottom: 8px; transition: color 0.15s; }
.back-link:hover { color: var(--fg); }
.avatar-stack { display: flex; align-items: center; }
.stack-av {
  width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  background: var(--gradient-brand); color: white; font-weight: 600; font-size: 12px;
  border: 2px solid var(--bg-solid); position: relative;
}
[data-ux-mode="cozy"] .stack-av { border-color: var(--bg-solid); }

.room-tabs { margin-bottom: 18px; }
.tab-badge {
  margin-left: 6px; padding: 1px 6px; border-radius: 99px; font-size: 10px; font-weight: 600;
  background: var(--surface-flat); color: var(--fg-muted); border: 1px solid var(--border);
}
.wisdom-tab.active .tab-badge { background: var(--accent-cyan); color: white; border-color: transparent; }
[data-ux-mode="cozy"] .wisdom-tab.active .tab-badge { background: #C66B6B; }

.room-chat-shell { display: grid; grid-template-columns: 1fr 320px; gap: 18px; align-items: start; }
@media (max-width: 1100px) { .room-chat-shell { grid-template-columns: 1fr; } }

.room-thread { min-height: 600px; }
.bubble-from { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--fg-muted); margin-bottom: 4px; }
.bubble-from strong { font-weight: 600; color: var(--fg); font-size: 12px; }
.bubble.user .bubble-from strong { color: white; }
.bubble.user .bubble-from { color: rgba(255,255,255,0.75); }
.ispirit-badge {
  font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.10em;
  padding: 1px 6px; border-radius: 4px;
  background: rgba(148,121,255,0.14); color: var(--accent-purple);
}
.bubble.human { background: var(--surface-2); border-color: var(--border-strong); }
[data-ux-mode="cozy"] .bubble.human { background: var(--surface-raised, #FFFBF2); }
.bubble-av.human { background: linear-gradient(135deg, #f59e0b, #34d399); color: white; font-weight: 600; font-size: 11px; }
.bubble-av.human img { display: none; }

.system-line {
  display: flex; justify-content: center; align-items: center; gap: 10px;
  font-size: 11px; color: var(--fg-faded); padding: 6px 0;
}
.system-line span { font-style: italic; }
.system-line .time { font-style: normal; opacity: 0.7; }

.typing { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.typing-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; border-radius: 16px;
  background: var(--surface-flat); border: 1px solid var(--border);
  font-size: 12px; color: var(--fg-muted); font-style: italic;
}
.dots { display: inline-flex; gap: 3px; margin-left: 4px; }
.dots span { width: 5px; height: 5px; border-radius: 50%; background: var(--fg-faded); animation: dotPulse 1.4s ease-in-out infinite; }
.dots span:nth-child(2) { animation-delay: 0.2s; }
.dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dotPulse { 0%,80%,100%{transform:scale(0.5);opacity:0.4;} 40%{transform:scale(1);opacity:1;} }

.member-list { display: flex; flex-direction: column; gap: 8px; }
.member-row { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--surface-flat); border: 1px solid var(--border); }
.member-row.is-me { background: linear-gradient(90deg, rgba(79,172,254,0.06), rgba(148,121,255,0.06)); border-color: var(--border-subtle); }
.member-row.big { padding: 14px 16px; }
.member-av { width: 32px; height: 32px; border-radius: 50%; background: var(--gradient-brand); color: white; display: grid; place-items: center; font-weight: 600; font-size: 12px; }
.member-av.big { width: 44px; height: 44px; font-size: 14px; }
.member-meta { min-width: 0; }
.member-name { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.member-row.big .member-name { font-size: 15px; }
.member-spirit { font-size: 11px; color: var(--fg-muted); }
.me-tag { font-size: 9px; padding: 1px 6px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 99px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.10em; font-weight: 600; }
.presence { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.presence.online, .presence.writing { background: var(--success); box-shadow: 0 0 8px rgba(52,211,153,0.5); }
.presence.offline { background: var(--fg-faded); }

.invite-row { display: flex; gap: 8px; margin-top: 16px; padding-top: 16px; border-top: 1px dashed var(--border); }
.invite-input { flex: 1; padding: 9px 12px; border-radius: var(--radius-sm); background: var(--surface-flat); border: 1px solid var(--border); color: var(--fg); font-size: 13px; outline: none; }
.invite-input:focus { border-color: var(--accent-cyan); }

.rules-prompt {
  padding: 16px 18px; border-radius: var(--radius-sm);
  background: var(--surface-flat); border: 1px solid var(--border);
  font-size: 14px; line-height: 1.7; color: var(--fg);
  font-family: var(--font-mono, monospace);
  white-space: pre-wrap;
}
[data-ux-mode="cozy"] .rules-prompt { font-family: var(--font-serif); font-style: italic; font-size: 17px; }

.kb-list { display: flex; flex-direction: column; gap: 10px; }
.kb-entry { padding: 16px 18px; border-radius: var(--radius-md); background: var(--surface-flat); border: 1px solid var(--border); }
.kb-entry h4 { font-size: 14px; margin-bottom: 6px; }
.kb-entry p { font-size: 13px; color: var(--fg-muted); margin: 0 0 10px; line-height: 1.55; }
.kb-meta { display: flex; gap: 12px; align-items: center; font-size: 11px; color: var(--fg-faded); }
.kb-actions { margin-left: auto; display: flex; gap: 4px; }

@media (max-width: 900px) {
  .identity-row { grid-template-columns: 1fr; gap: 6px; }
  .today-signals { width: 90vw; max-width: 320px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; }
  .page > * { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* ─── Phase 3: hide legacy nav on opted-in product pages ──────────
   AppShell.js hides #topNav + .mobile-bottom-nav via the `hidden`
   attribute, but if navigation.js races and re-renders the element
   after mount, the `hidden` attr can get cleared. These selectors
   are a belt-and-braces fallback. They only apply on pages that
   set `<body class="product-page">`. */
body.product-page > nav#topNav,
body.product-page > nav.top-nav,
body.product-page > .mobile-bottom-nav,
body.product-page > #mobileBottomNav,
body.product-page > #mobileBottomNavRoot,
body.product-page > #navigation-container { display: none !important; }

/* Tap-target floor at phone width (QA round 55 LOW-1): nav-drawer links
   measured exactly 40px tall and the journal record button 32px wide —
   below the comfortable 44px target. Scoped to coarse-pointer phones so
   desktop density is unchanged. */
@media (max-width: 640px) {
  .nav-item { min-height: 44px; }
  .record-btn { min-height: 44px; min-width: 44px; }
}

/* ============================================================
 * Android-parity mobile polish (≤900px)  — 2026-06-12
 * Brings the web mobile presentation in line with the native
 * Android app's visual quality (Theme.kt / Primitives.kt design
 * pack): gradient active-nav pill, compact stat-tile rhythm,
 * cleaner journal capture tiles, circular chat send. Every rule
 * is scoped inside @media (max-width: 900px) so desktop is
 * pixel-identical. Theme-adaptive tints use color-mix on the
 * accent tokens (Dev Rule #16 frontend note) so cozy warms
 * automatically (purple→gold) instead of staying cold.
 * ========================================================== */
@media (max-width: 900px) {
  /* ── Bottom nav: Android active pill ──────────────────────
     Android draws a soft rounded gradient pill (~16% alpha)
     behind the ACTIVE tab's icon, a slightly larger active
     glyph, and a foreground-strong label; inactive items stay
     plain muted. The icon span (.ico) carries the pill. */
  .bottom-nav { padding-top: 6px; }
  .bottom-nav a, .bottom-nav button {
    gap: 4px; font-weight: 500; transition: color 0.18s;
  }
  .bottom-nav .ico {
    width: 46px; height: 30px; border-radius: 999px;
    transition: background 0.2s ease, box-shadow 0.2s ease;
  }
  .bottom-nav a.active, .bottom-nav button.active {
    color: var(--fg-strong); font-weight: 600;
  }
  .bottom-nav a.active .ico, .bottom-nav button.active .ico {
    background: linear-gradient(135deg,
      color-mix(in srgb, var(--accent-cyan) 22%, transparent),
      color-mix(in srgb, var(--accent-purple) 22%, transparent));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-purple) 30%, transparent);
  }
  .bottom-nav a.active .ico svg, .bottom-nav button.active .ico svg {
    width: 21px; height: 21px;
    color: var(--accent-cyan);
  }
  [data-ux-mode="cozy"] .bottom-nav a.active .ico,
  [data-ux-mode="cozy"] .bottom-nav button.active .ico {
    background: linear-gradient(135deg,
      color-mix(in srgb, var(--accent-cyan) 18%, transparent),
      color-mix(in srgb, var(--accent-purple) 18%, transparent));
  }

  /* ── Progress: compact stat-tile row ──────────────────────
     Android lays the top stats out as compact bordered tiles
     side-by-side rather than full-width stacks. Put the two
     stat-cards 2-up; the level-card spans the full row below.
     Tighten padding + radius to the 14dp card spec. */
  .stat-grid {
    grid-template-columns: 1fr 1fr !important;
    gap: 10px !important;
  }
  .stat-grid .stat-card {
    padding: 14px; gap: 2px;
    border-radius: var(--radius-md);
    border-color: var(--border-subtle);
  }
  .stat-grid .level-card { grid-column: 1 / -1; padding: 16px; }
  .stat-card .stat-ico { width: 28px; height: 28px; margin-bottom: 4px; }
  .stat-card .stat-value { font-size: 24px; }
  .stat-card .stat-delta { font-size: 11px; }

  /* (Journal compact-capture-tile parity lives in journal-cards.css —
     its !important grid rules are load-order-independent only when the
     override sits in the same file; EN/CN load app-shell + journal-cards
     in opposite order, so the journal rules must live there.) */

  /* (Chat composer circular-send is handled in chat_inline.css —
     #send there beats this file on ID specificity.) */

  /* ── Missions / Forum: 14dp card spec polish ──────────────
     Nudge the shared list-card surfaces to the Android border +
     radius spec (subtle violet hairline, 14dp radius) so every
     scrollable list reads as the same card family. */
  .mission-tab, .forum-thread-card, .forum-room-card {
    border-radius: var(--radius-md);
    border-color: var(--border-subtle);
  }
}


/* ── Wide-screen content (2026-06-28) ─────────────────────────────
   Per-page wrappers were capped 880–1280px and centered, leaving ~250px empty
   on each side at 1920px. Raise them to the 1600px app-shell standard. The
   `body ` prefix (specificity 0,1,1) beats inline-<style> and feature-CSS caps
   (0,1,0) regardless of load order, and stays below `.missions-page.embedded`
   (0,2,0) so the embedded group-room keeps max-width:none. */
body .execution-page,        /* progress */
body .missions-page,         /* missions */
body .forum-page,            /* forum */
body .search-page,           /* search */
body .insights-page,         /* insights */
body .presence-page,         /* leaderboard */
body .journal-page,          /* journal */
body .calendar-container,    /* journal-calendar */
body .habits-container,      /* habits */
body .challenges-page,       /* challenges */
body .wisdom-container,      /* wisdom */
body .life-spec-container,   /* life-spec-dashboard */
body .profile-container,     /* user_profile / profile */
body .wizard-page-shell {    /* wizards */
  max-width: 1600px;
}

/* Transient language-mismatch note on the diary card (QA r2 follow-up
   2026-07-17): shown when the overnight narrative's language isn't this
   mirror's language; the usage-captured locale makes the next entry match. */
.narrative-lang-note {
  margin-top: 6px; font-size: 11px; color: var(--fg-muted); font-style: italic;
}
