/* ================================================================
   Inner Table - mobile-first PWA styles
   Warm, candlelit, calm. Dark by default; light theme via [data-theme].
   ================================================================ */

/* Self-hosted, latin subset only: the app works offline and promises no
   third-party requests, so the type cannot come from a font CDN. Both
   faces are SIL Open Font License (see fonts/README.md). */
@font-face {
  font-family: "DM Sans"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(../fonts/dm-sans-latin.woff2) format("woff2");
}
@font-face {
  font-family: "Newsreader"; font-style: normal; font-weight: 500 600; font-display: swap;
  src: url(../fonts/newsreader-latin.woff2) format("woff2");
}

:root {
  --bg: #14110e;
  --bg2: #1b1713;
  --surface: #221d18;
  --surface2: #2b251e;
  --line: #3a322a;
  --ink: #f0e9df;
  --ink-dim: #a89e90;
  --ink-faint: #6f665a;
  --accent: #e8a854;
  --accent-ink: #241a0d;
  --accent-soft: rgba(232, 168, 84, .14);
  --manager: #7c9ce8;
  --firefighter: #e87c6a;
  --exile: #b48ce8;
  --unknown: #8a8f98;
  --self: #f0c987;
  --good: #7fc98b;
  --warn: #e8b45a;
  --danger: #e87c6a;
  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 10px 30px rgba(0,0,0,.35);
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --tabbar-h: 66px;
  --radius-lg: 24px;
  --font-sans: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --font-serif: "Newsreader", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  /* the one deep, lit-from-within card a screen gets (daily check-in) */
  --hero-bg: radial-gradient(120% 140% at 100% 0%, rgba(232,168,84,.26), transparent 55%), linear-gradient(128deg, #2f2416, #1f1914 70%);
  --hero-ink: #f6eee2;
  --hero-dim: #cdbfa9;
  --hero-line: rgba(240, 201, 135, .22);
  color-scheme: dark;
}
[data-theme="light"] {
  --bg: #faf6ef;
  --bg2: #f3ecdf;
  --surface: #ffffff;
  --surface2: #f6f0e5;
  --line: #e5dccc;
  --ink: #2b241b;
  --ink-dim: #6f6555;
  --ink-faint: #a2967f;
  --accent: #c17e22;
  --accent-ink: #fff;
  --accent-soft: rgba(193, 126, 34, .12);
  --self: #b98a2e;
  --shadow: 0 10px 30px rgba(60,40,10,.12);
  --hero-bg: radial-gradient(120% 140% at 100% 0%, rgba(232,168,84,.34), transparent 55%), linear-gradient(128deg, #4a3319, #2f2216 75%);
  --hero-ink: #fbf3e6;
  --hero-dim: #e3d3bb;
  --hero-line: rgba(255, 226, 180, .24);
  color-scheme: light;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { height: 100%; }
body {
  margin: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font: 16px/1.55 var(--font-sans);
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
}
.serif { font-family: var(--font-serif); font-weight: 600; letter-spacing: -.005em; }
.icon { stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; flex: none; display: block; }
.hidden { display: none !important; }
.dim { color: var(--ink-dim); font-size: .9em; }
a { color: var(--accent); }
b { font-weight: 650; }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, textarea, select {
  font: inherit; color: var(--ink);
  background: var(--surface2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 12px 14px; width: 100%;
}
input:focus, textarea:focus, select:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: transparent; }
textarea { resize: vertical; min-height: 90px; }
label.fieldlabel { display: block; font-size: .8rem; color: var(--ink-dim); margin: 14px 0 6px; text-transform: uppercase; letter-spacing: .08em; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 20px; border-radius: 999px; font-weight: 600;
  transition: transform .08s ease, background .15s ease;
  user-select: none;
}
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-ghost { background: transparent; color: var(--ink-dim); }
.btn-soft { background: var(--surface2); border: 1px solid var(--line); }
.btn .icon { margin-right: -2px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-danger { background: transparent; color: var(--danger); border: 1px solid var(--danger); }
.btn-big { width: 100%; padding: 15px 18px; font-size: 1.05rem; }
a.btn { text-decoration: none; box-sizing: border-box; }
a.btn-primary { color: var(--accent-ink); }
.btn[disabled] { opacity: .45; pointer-events: none; }
.iconbtn {
  width: 42px; height: 42px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s ease;
}
.iconbtn:active { background: var(--surface2); }

/* ---------- glyphs (pure CSS/unicode icons) ---------- */
.glyph { display: inline-block; width: 22px; height: 22px; line-height: 22px; text-align: center; font-size: 19px; font-style: normal; }
.glyph-table::before { content: "\1F56F"; }        /* candle */
.glyph-shield::before { content: "\1F6E1"; }
.glyph-lock::before { content: "\1F512"; }
.glyph-moon::before { content: "\25D0"; font-size: 21px; }
.glyph-spark::before { content: "\2727"; }
.glyph-web::before { content: "\1F578"; }
.glyph-book::before { content: "\1F4D6"; }
.glyph-info::before { content: "\24D8"; font-size: 21px; }
.glyph-gear::before { content: "\2699"; font-size: 21px; }
.glyph-parts::before { content: "\25CE"; font-size: 21px; }
.glyph-back::before { content: "\2039"; font-size: 30px; line-height: 20px; }
.glyph-anchor::before { content: "\2693"; }
.glyph-send::before { content: "\2191"; font-weight: 700; }

/* ================= onboarding ================= */
/* Same viewport story as .app below: dvh keeps the bottom of the overlay
   (and the slide's button) above the browser toolbar. */
.onboarding {
  position: fixed; inset: 0; height: 100dvh; z-index: 60; background: var(--bg);
  display: flex; flex-direction: column;
}
.onboard-track { flex: 1; min-height: 0; display: flex; overflow: hidden; }
/* A slide taller than the screen (the "guide, not a therapist" one on a small phone)
   scrolls instead of being clipped. justify-content:center would push the
   overflow off both ends out of reach, so the auto margins on the first and
   last child do the centering - they collapse to 0 once there is no room. */
.onboard-slide {
  min-width: 100%; padding: calc(28px + var(--sat)) 28px 20px;
  display: flex; flex-direction: column; gap: 14px;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  text-align: center; animation: fadeUp .45s ease;
  transition: margin-left .38s cubic-bezier(.3,.8,.3,1);
}
.onboard-slide > :first-child { margin-top: auto; }
.onboard-slide > :last-child { margin-bottom: auto; }
/* the way forward stays on screen while the text scrolls behind it */
.onboard-slide > .btn-big {
  position: sticky; bottom: 0; flex-shrink: 0;
  box-shadow: 0 0 0 14px var(--bg);
}
@media (max-height: 640px) {
  .onboard-slide { gap: 10px; padding-top: calc(16px + var(--sat)); padding-bottom: 12px; }
  .onboard-art { width: 60px; height: 60px; }
  .onboard-slide h1 { font-size: 1.9rem; }
  .onboard-slide h2 { font-size: 1.45rem; }
}
.onboard-art {
  width: 76px; height: 76px; border-radius: 50%; margin: 0 auto 4px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
  box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 6%, transparent);
}
.onboard-slide h1 { font-size: 2.2rem; margin: 0; }
.onboard-slide h2 { font-size: 1.7rem; margin: 0; }
.lead { color: var(--ink); font-size: 1.02rem; margin: 0; }
.rules { text-align: left; margin: 0 auto; padding-left: 22px; color: var(--ink-dim); max-width: 340px; }
.rules li { margin: 6px 0; }
.onboard-dots { display: flex; gap: 8px; justify-content: center; padding: 0 0 calc(26px + var(--sab)); }
.onboard-dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--line); transition: all .3s; }
.onboard-dots i.on { background: var(--accent); width: 22px; border-radius: 5px; }

@keyframes fadeUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ================= app shell ================= */
/* inset:0 alone sizes to the layout viewport, which on a phone does not
   change when the browser's toolbar retracts - so the bar ends up floating
   above the bottom of the screen. dvh follows the viewport that is actually
   visible; browsers without it fall back to inset:0. */
.app { position: fixed; inset: 0; height: 100dvh; display: flex; flex-direction: column; }
/* Installed there is no toolbar to chase, so dvh has nothing left to track -
   except on iOS, where apple-mobile-web-app-status-bar-style=black-translucent
   (see index.html) makes dvh/innerHeight exclude the status-bar height while
   the page still renders full-screen underneath it. 100dvh then falls exactly
   that far short of the real bottom. .ios is set at boot by ui.js; on other
   platforms env(safe-area-inset-top) and the fallback both resolve to 0px, so
   this is a no-op there. */
@media (display-mode: standalone) {
  .app { height: 100dvh; }
  :root.ios .app { height: calc(100dvh + env(safe-area-inset-top, 0px)); }
}
.topbar {
  padding-top: var(--sat);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line); z-index: 5;
}
.topbar-inner { display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; max-width: 1180px; margin: 0 auto; }
.topbar-actions { display: flex; align-items: center; gap: 10px; }
.brand { display: flex; align-items: center; gap: 10px; font-size: 1.3rem; padding: 2px 6px 2px 0; border-radius: 12px; font-family: var(--font-serif); }
.brand:active { transform: scale(.98); }
/* the app icon itself, so the top bar and the home screen show the same mark */
.brand-logo { width: 36px; height: 36px; border-radius: 9px; flex: none; display: block; }
[data-theme="light"] .brand-logo { box-shadow: 0 1px 3px rgba(60,40,10,.18); }
.quietbtn {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-dim);
  transition: background .15s ease, color .15s ease;
}
.quietbtn:hover { color: var(--ink); }
.quietbtn:active { background: var(--surface2); }
.avatar {
  width: 36px; height: 36px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--accent-ink);
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
}
.avatar.large { width: 48px; height: 48px; font-size: .95rem; }
.avatar-btn { border-radius: 50%; padding: 0; transition: box-shadow .15s ease, transform .1s ease; }
.avatar-btn:active { transform: scale(.94); }
.avatar-btn.active, .avatar-btn[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent); }

/* ---------- profile menu (settings, theme, sign out) ---------- */
.menu-scrim { position: fixed; inset: 0; z-index: 44; background: color-mix(in srgb, var(--bg) 35%, transparent); animation: fadeIn .15s ease; }
.profile-menu {
  position: fixed; z-index: 45;
  top: calc(var(--sat) + 62px);
  right: max(12px, calc((100vw - 1180px) / 2 + 12px));
  width: min(310px, calc(100vw - 24px));
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 20px; box-shadow: var(--shadow); padding: 8px;
  animation: menuIn .18s cubic-bezier(.3,.9,.3,1);
  transform-origin: top right;
}
@keyframes menuIn { from { opacity: 0; transform: translateY(-6px) scale(.97); } to { opacity: 1; transform: none; } }
.pm-head { display: flex; align-items: center; gap: 12px; padding: 10px 10px 14px; margin-bottom: 6px; border-bottom: 1px solid var(--line); }
.pm-who { display: flex; flex-direction: column; min-width: 0; }
.pm-who b { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm-who small { color: var(--ink-faint); font-size: .74rem; }
.pm-item {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 11px 10px; border-radius: 12px; text-align: left;
  color: var(--ink-dim); font-size: .92rem; font-weight: 550;
}
.pm-item span { flex: 1; color: var(--ink); }
.pm-item:hover, .pm-item:focus-visible { background: var(--surface2); }
.pm-item:active { background: var(--accent-soft); }
.pm-item.danger, .pm-item.danger span { color: var(--danger); }
.pm-label { font-size: .64rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); padding: 12px 10px 6px; }
.pm-theme { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 0 4px 8px; margin-bottom: 6px; border-bottom: 1px solid var(--line); }
.pm-theme button {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 9px 4px; border-radius: 12px; font-size: .72rem; font-weight: 600;
  background: var(--surface2); border: 1px solid var(--line); color: var(--ink-dim);
}
.pm-theme button.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

main#views { flex: 1; overflow: hidden; position: relative; }
.view { position: absolute; inset: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; animation: fadeUp .25s ease; }
.view-pad { padding: 20px 16px calc(90px + var(--sab)); max-width: 640px; margin: 0 auto; }

/* ---------- page headers ---------- */
.page-head { margin: 6px 2px 20px; }
.eyebrow { color: var(--accent); font-size: .7rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; margin: 0 0 8px; }
.page-head h1 { font-size: clamp(1.9rem, 6.4vw, 2.75rem); font-weight: 500; letter-spacing: -.02em; line-height: 1.08; margin: 0 0 6px; }
.subtitle { color: var(--ink-dim); font-size: .95rem; margin: 0; }
.kicker {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent);
}
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin: 28px 2px 14px; }
.section-head h2 { font-size: 1.55rem; font-weight: 500; margin: 0 0 2px; letter-spacing: -.01em; }
.section-head p { margin: 0; color: var(--ink-dim); font-size: .84rem; }
.text-btn { display: inline-flex; align-items: center; gap: 6px; color: var(--accent); font-size: .84rem; font-weight: 650; padding: 6px 0; white-space: nowrap; }

/* ---------- tab bar ---------- */
.tabbar {
  flex: none; border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  padding-bottom: var(--sab); height: calc(var(--tabbar-h) + var(--sab));
  z-index: 5;
}
.tabbar-inner { display: flex; height: 100%; max-width: 520px; margin: 0 auto; }
.tab {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 4px; padding: 6px 4px 8px;
  color: var(--ink-faint); font-size: .7rem; font-weight: 600;
  line-height: 1; transition: color .15s;
}
.tab-ic {
  width: 58px; height: 30px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s ease, color .2s ease;
}
.tab:hover { color: var(--ink-dim); }
.tab.active { color: var(--accent); }
.tab.active .tab-ic { background: var(--accent-soft); }

/* ================= empty states ================= */
.empty { text-align: center; padding: 48px 24px 30px; max-width: 400px; margin: 0 auto; display: flex; flex-direction: column; gap: 12px; align-items: center; }
.empty-art {
  width: 64px; height: 64px; border-radius: 50%; margin-bottom: 4px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.empty h2 { margin: 0; font-size: 1.6rem; font-weight: 500; }
.empty p { color: var(--ink-dim); margin: 0; }

/* ================= part cards ================= */
/* The library: one card per part, in a grid that is one column on a phone
   and widens to three. Each card leads with who the part is (initial, type),
   then what it is for, then how well it is known. */
.parts-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 560px) { .parts-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .parts-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.part-card {
  --tc: var(--unknown);
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px 18px 14px;
  cursor: pointer; text-align: left;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
  animation: fadeUp .3s ease;
}
.part-card.t-manager { --tc: var(--manager); }
.part-card.t-firefighter { --tc: var(--firefighter); }
.part-card.t-exile { --tc: var(--exile); }
.part-card:hover, .part-card:focus-visible {
  border-color: color-mix(in srgb, var(--tc) 55%, var(--line));
  box-shadow: var(--shadow); transform: translateY(-2px);
}
.part-card:active { transform: scale(.985); }
.pc-top { display: flex; align-items: center; gap: 10px; }
.pc-avatar {
  width: 48px; height: 48px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-size: 1.3rem; font-weight: 600;
  color: var(--tc); background: color-mix(in srgb, var(--tc) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--tc) 45%, transparent);
}
.pc-ready {
  margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
  font-size: .66rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--good);
}
.part-card h3 { font-size: 1.32rem; margin: 16px 0 4px; line-height: 1.2; }
.pc-note {
  color: var(--ink-dim); font-size: .86rem; line-height: 1.5; margin: 0 0 16px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  min-height: 2.6em;
}
.pc-progress { margin-top: auto; }
.pc-plabel { display: flex; justify-content: space-between; font-size: .72rem; color: var(--ink-faint); margin-bottom: 6px; }
.pc-plabel b { color: var(--ink-dim); font-weight: 650; }
.pc-track { display: block; height: 5px; border-radius: 999px; background: var(--surface2); overflow: hidden; }
.pc-track i { display: block; height: 100%; border-radius: inherit; background: var(--accent); transition: width .6s ease; }
.pc-foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 14px; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: .74rem; color: var(--ink-faint);
}
.pc-foot .readydot { width: 7px; height: 7px; }
.pc-when { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.part-card.is-quiet .pc-when { color: var(--warn); }
.add-part-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-height: 200px; padding: 20px; border-radius: var(--radius);
  border: 1.5px dashed var(--line); color: var(--ink-dim); text-align: center;
  transition: border-color .15s ease, background .15s ease;
}
.add-part-card:hover { border-color: var(--accent); background: var(--accent-soft); }
.add-part-card .apc-i {
  width: 46px; height: 46px; border-radius: 50%; margin-bottom: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.add-part-card b { color: var(--ink); font-size: 1.12rem; }
.add-part-card small { color: var(--ink-faint); font-size: .76rem; }

/* compact row form, used where a part is previewed rather than browsed */
.part-row {
  display: flex; align-items: center; gap: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px; margin-bottom: 12px;
}
.ring { position: relative; width: 54px; height: 54px; flex: none; }
.ring svg { transform: rotate(-90deg); }
.ring .ring-bg { stroke: var(--line); }
.ring .ring-fg { stroke: var(--accent); transition: stroke-dashoffset .6s ease; }
.ring .ring-initial {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 1.15rem; font-family: Georgia, serif;
}
.part-card-main { flex: 1; min-width: 0; }
.part-card-name { font-weight: 650; font-size: 1.05rem; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; }
.part-card-sub { color: var(--ink-dim); font-size: .82rem; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.badge {
  font-size: .64rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; color: #14110e;
}
.badge.manager { background: var(--manager); }
.badge.firefighter { background: var(--firefighter); }
.badge.exile { background: var(--exile); }
.badge.unknown { background: var(--unknown); }
.readydot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); flex: none; }
.readydot.ready { background: var(--good); box-shadow: 0 0 8px var(--good); }

/* ================= FAB ================= */
.fab {
  position: fixed; right: 18px; bottom: calc(var(--tabbar-h) + var(--sab) + 18px);
  width: 58px; height: 58px; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  box-shadow: 0 8px 24px rgba(232,168,84,.35);
  display: flex; align-items: center; justify-content: center;
  z-index: 6; transition: transform .12s ease;
}
.fab:active { transform: scale(.92) rotate(90deg); }
/* on a part's page: the panel covers the tab bar, so the + sits lower */
.fab.fab-panel { bottom: calc(var(--sab) + 18px); }
.fab-plus { font-size: 30px; line-height: 1; margin-top: -3px; }

/* ================= sheet ================= */
.sheet-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 40;
  animation: fadeIn .2s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  background: var(--bg2); border-radius: 22px 22px 0 0;
  max-height: 86dvh; display: flex; flex-direction: column;
  animation: sheetUp .3s cubic-bezier(.3,.9,.3,1);
  box-shadow: 0 -10px 40px rgba(0,0,0,.4);
}
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
.sheet.closing { animation: sheetDown .22s ease forwards; }
@keyframes sheetDown { to { transform: translateY(100%); } }
.sheet-grip { width: 40px; height: 4px; border-radius: 2px; background: var(--line); margin: 10px auto 2px; flex: none; }
.sheet-body { overflow-y: auto; padding: 12px 20px calc(24px + var(--sab)); }
.sheet-body h2 { margin: 8px 0 4px; }
.sheet-title { font-size: 1.3rem; margin: 6px 0 2px; }

.menu-item {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 15px 6px; border-bottom: 1px solid var(--line);
  text-align: left; font-size: 1rem;
}
.menu-item:last-child { border-bottom: 0; }
.menu-item:active { background: var(--surface2); }
.menu-item .mi-icon { font-size: 22px; width: 30px; text-align: center; flex: none; }
.menu-item .mi-main { flex: 1; }
.menu-item .mi-sub { display: block; color: var(--ink-dim); font-size: .8rem; }
.menu-item[disabled] { opacity: .4; }
.menu-item .pk-check { color: var(--accent); opacity: 0; font-weight: 700; transition: opacity .12s; }
.menu-item.on { background: var(--accent-soft); }
.menu-item.on .pk-check { opacity: 1; }
.mi-head {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-faint); padding: 16px 6px 4px;
}
.mi-head:first-of-type { padding-top: 8px; }

/* ================= panel (chat / profile) ================= */
.panel {
  position: fixed; inset: 0; z-index: 30; background: var(--bg);
  display: flex; flex-direction: column;
  animation: panelIn .28s cubic-bezier(.3,.9,.3,1);
}
@keyframes panelIn { from { transform: translateX(60px); opacity: 0; } to { transform: none; opacity: 1; } }
.panel.closing { animation: panelOut .2s ease forwards; }
@keyframes panelOut { to { transform: translateX(60px); opacity: 0; } }
.panel-top {
  display: flex; align-items: center; gap: 6px;
  padding: calc(8px + var(--sat)) 10px 8px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.panel-title { flex: 1; min-width: 0; font-weight: 650; font-size: 1.05rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-title small { display: block; overflow: hidden; text-overflow: ellipsis; font-weight: 400; color: var(--ink-dim); font-size: .74rem; }
/* the profile's bar: the part's face beside its name, kept while the page scrolls */
.panel-title.has-face { display: flex; align-items: center; gap: 10px; }
.panel-title .pt-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.panel-title .pt-face {
  width: 36px; height: 36px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); border: 1.5px solid var(--accent);
  font: 700 .95rem/1 Georgia, serif;
}
.panel-title .pt-face.has-pic { background: none; }
.panel-actions { display: flex; align-items: center; gap: 6px; flex: none; }
.panel-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; }

/* ---------- profile view ---------- */
.profile { padding: 18px 18px calc(96px + var(--sab)); max-width: 640px; margin: 0 auto; }   /* room under the last button for the + */
.profile-hero { --tc: var(--accent); text-align: center; padding: 8px 0 18px; }
.profile-hero.t-manager { --tc: var(--manager); }
.profile-hero.t-firefighter { --tc: var(--firefighter); }
.profile-hero.t-exile { --tc: var(--exile); }
.profile-hero h1 { margin: 0; font-size: 1.7rem; }
.profile-hero .sub { color: var(--ink-dim); font-size: .88rem; margin-top: 4px; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 10px; }
.chip { background: var(--surface2); border: 1px solid var(--line); padding: 5px 12px; border-radius: 999px; font-size: .78rem; color: var(--ink-dim); }
.chip b { color: var(--ink); }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; margin-bottom: 14px; box-shadow: var(--shadow); }
.card h3 {
  margin: 0 0 10px; font-size: .8rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-dim);
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.cardedit {
  background: none; border: none; color: var(--ink-faint);
  font-size: .95rem; line-height: 1; padding: 4px 6px; margin: -4px -6px;
  cursor: pointer; border-radius: 8px;
}
.cardedit:active { background: var(--surface2); color: var(--ink); }
.covhint { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--ink-faint); font-size: .7rem; }
.chip-btn { cursor: pointer; }
.covitem { cursor: pointer; }
.card .prose { white-space: pre-wrap; font-size: .95rem; }
.card .prose:empty::before, .prose.none { color: var(--ink-faint); font-style: italic; }
/* copy-prompt page: numbered steps, a quiet privacy line, the prompt folded */
.cp-steps { margin: 0; padding-left: 1.3em; display: grid; gap: 8px; font-size: .95rem; line-height: 1.45; }
.cp-steps b { font-weight: 600; }
.cp-note { margin: 14px 4px; line-height: 1.45; }
.cp-prompt summary { cursor: pointer; font-size: .9rem; color: var(--ink); list-style-position: inside; }
.cp-prompt[open] summary { margin-bottom: 10px; }
.cp-prompt .prose { max-height: 46vh; overflow: auto; font-size: .78rem; overflow-wrap: anywhere; }
.taglist { display: flex; flex-wrap: wrap; gap: 6px; }
.taglist span { background: var(--surface2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; font-size: .84rem; }

.covgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.covitem {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px;
  background: var(--surface2); border: 1px solid var(--line); border-radius: 10px;
  font-size: .78rem;
}
.covitem i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.cov-untouched i { background: var(--line); }
.cov-partial i { background: var(--warn); }
.cov-complete i { background: var(--good); }
.cov-declined i { background: var(--danger); }
.cov-declined { opacity: .75; }

.sessionrow { display: flex; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); font-size: .86rem; }
.sessionrow:last-child { border-bottom: 0; }
.sessionrow .sr-date { color: var(--ink-faint); flex: none; width: 84px; }
.sessionrow .sr-mode { color: var(--accent); flex: none; width: 64px; text-transform: capitalize; }

.readiness { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: var(--radius-sm); font-size: .88rem; margin-bottom: 14px; }
.readiness.ok { background: color-mix(in srgb, var(--good) 14%, transparent); color: var(--good); }
.readiness.no { background: var(--surface2); color: var(--ink-dim); }

.profile-cta { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }

/* ---------- guided questionnaire ---------- */
.qprogress { height: 3px; background: var(--line); border-radius: 2px; margin-bottom: 16px; overflow: hidden; }
.qprogress i { display: block; height: 100%; background: var(--accent); transition: width .3s ease; }
.qtext { font-size: 1.25rem; line-height: 1.45; }

/* ---------- chat ---------- */
/* relative: anchors the absolutely-positioned "ground me" button inside the
   chat area - without it the button lands on the panel header's End & save */
.chat { position: relative; display: flex; flex-direction: column; height: 100%; }
/* padding-top clears the floating "ground me" button, which used to sit on
   top of the first line of the session note */
.chat-scroll { flex: 1; overflow-y: auto; padding: 46px 14px 8px; -webkit-overflow-scrolling: touch; }
.msg { max-width: 86%; margin-bottom: 12px; animation: fadeUp .25s ease; }
.msg .bubble {
  padding: 11px 14px; border-radius: 18px; font-size: .96rem; white-space: pre-wrap;
  word-wrap: break-word; overflow-wrap: break-word;
}
.msg.user { margin-left: auto; }
.msg.user .bubble { background: var(--accent); color: var(--accent-ink); border-bottom-right-radius: 6px; }
.msg.assistant .bubble { background: var(--surface); border: 1px solid var(--line); border-bottom-left-radius: 6px; }
.msg.system-note { max-width: 100%; text-align: center; color: var(--ink-faint); font-size: .78rem; padding: 4px 20px; }
.typing { display: inline-flex; gap: 5px; padding: 14px 16px; }
.typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-faint); animation: blink 1.2s infinite; }
.typing i:nth-child(2) { animation-delay: .2s; }
.typing i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }

/* meeting: a group chat, where each part speaks under its own name and face */
.msg .voice {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--vc, var(--accent));
  border-radius: 14px; border-bottom-left-radius: 5px;
  padding: 9px 13px 10px; margin-bottom: 8px;
  font-size: .96rem; white-space: pre-wrap; overflow-wrap: break-word;
}
.msg .voice:last-child { margin-bottom: 0; }
.msg .voice .vhead { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.msg .voice .vava {
  width: 24px; height: 24px; border-radius: 50%; flex: none; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: Georgia, serif; font-weight: 700; font-size: .66rem;
  background: color-mix(in srgb, var(--vc, var(--accent)) 20%, transparent);
  color: var(--vc, var(--accent));
  border: 1px solid color-mix(in srgb, var(--vc, var(--accent)) 55%, transparent);
}
.msg .voice .vname {
  font-size: .7rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--vc, var(--accent));
}
.msg .voice .vbody { display: block; }
.msg .voice.self-voice { background: var(--accent-soft); border-color: color-mix(in srgb, var(--self) 40%, transparent); }

.chat-input {
  display: flex; gap: 8px; align-items: flex-end;
  padding: 10px 12px calc(10px + var(--sab));
  border-top: 1px solid var(--line); background: var(--bg2);
}
.chat-input textarea {
  flex: 1; min-width: 0; min-height: 44px; height: 44px; max-height: 130px; border-radius: 22px;
  padding: 10px 16px; line-height: 22px; resize: none; overflow-y: auto;
}
.chat-input textarea::placeholder { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sendbtn {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  background: var(--accent); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: 700;
  transition: transform .1s ease;
}
.sendbtn:active { transform: scale(.9); }
.sendbtn[disabled] { opacity: .4; }
.micbtn {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  background: var(--surface2); border: 1px solid var(--line); color: var(--ink);
  display: flex; align-items: center; justify-content: center; font-size: 18px;
  transition: transform .1s ease;
}
.micbtn:active { transform: scale(.9); }
.micbtn.listening {
  background: var(--danger); color: #fff; border-color: var(--danger);
  animation: micPulse 1.2s ease infinite;
}
@keyframes micPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--danger) 45%, transparent); }
  50% { box-shadow: 0 0 0 9px color-mix(in srgb, var(--danger) 0%, transparent); }
}
.btn.voice-on { background: var(--accent); color: var(--accent-ink); }
.groundbtn {
  position: absolute; right: 14px; top: 8px;
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: .78rem; font-weight: 650; line-height: 1; color: var(--ink);
  background: var(--surface2); border: 1px solid var(--line);
  padding: 8px 13px; border-radius: 999px; z-index: 3;
}
.panel-actions .btn { white-space: nowrap; }
.panel-actions .voicebtn { width: 38px; height: 38px; padding: 0; }

/* ================= grounding ================= */
.ground {
  position: fixed; inset: 0; z-index: 70; background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  animation: fadeIn .3s ease;
}
.ground-inner { max-width: 380px; padding: 30px; text-align: center; display: flex; flex-direction: column; gap: 14px; align-items: center; }
/* Ground me is a page of its own: it scrolls, and starts at the top */
#ground { display: block; overflow-y: auto; -webkit-overflow-scrolling: touch; }
#ground.hidden { display: none; }
#ground .ground-inner { max-width: 460px; margin: 0 auto; box-sizing: border-box; padding: calc(28px + var(--sat)) 16px calc(28px + var(--sab)); }
#ground .ground-inner > p, #ground .ground-inner > h2 { margin: 0; }
#ground .breath { margin-bottom: 0; }
.btn-crisis { background: var(--danger); color: #fff; }
a.btn-crisis { color: #fff; }
.ground-crisis-more { margin: -4px 0 6px; font-size: .86rem; }
.ground-crisis-more a { font-weight: 600; }
.ground-plan { width: 100%; display: flex; flex-direction: column; gap: 12px; text-align: left; }
.gp-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.gp-card h3 { margin: 0 0 8px; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-faint); }
.gp-card h4 { margin: 12px 0 4px; font-size: .86rem; }
.gp-card .dim { margin: 0 0 10px; }
.gp-list { margin: 0; padding-left: 18px; line-height: 1.6; }
.gp-list li { margin: 3px 0; }
.gp-starters { display: flex; flex-wrap: wrap; gap: 8px; }
.gp-starters .chip { font-size: .82rem; padding: 7px 12px; text-align: left; color: var(--ink); }
.gp-contact { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-top: 1px solid var(--line); }
.gp-contact:first-of-type { border-top: 0; }
.gp-contact .gp-who { flex: 1; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.gp-contact .gp-who small { display: block; font-weight: 400; color: var(--ink-dim); }
.gp-contact .btn { padding: 8px 14px; font-size: .84rem; }
.gp-more summary { cursor: pointer; font-weight: 600; font-size: .9rem; }
.gp-edit .fieldlabel { margin-top: 16px; }
.gp-edit .gp-hint { margin: -2px 0 6px; font-size: .8rem; }
.gp-edit textarea { min-height: 76px; }
.gp-edit .btn-big { margin-top: 14px; }
.ground-actions { width: 100%; display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.breath { position: relative; width: 130px; height: 130px; display: flex; align-items: center; justify-content: center; margin-bottom: 8px; }
.breath-ring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--accent); background: var(--accent-soft);
  animation: breathe 8s ease-in-out infinite;
}
@keyframes breathe { 0%, 100% { transform: scale(.62); } 45%, 55% { transform: scale(1); } }
.breath span { position: relative; font-size: .8rem; color: var(--accent); letter-spacing: .1em; text-transform: uppercase; }

/* ================= swarm map ================= */
.map-wrap { position: absolute; inset: 0; overflow: hidden; }
.swarm { width: 100%; height: 100%; touch-action: none; display: block; }
.swarm .edge { stroke-width: 2; fill: none; transition: opacity .2s; }
.swarm .edge.protects { stroke: var(--good); marker-end: url(#arrow); }
.swarm .edge.allied-with { stroke: var(--good); }
.swarm .edge.polarized-with { stroke: var(--warn); stroke-dasharray: 7 5; }
.swarm .edge.conflicts-with { stroke: var(--warn); stroke-dasharray: 2 5; }
/* the unasked question: every pair of parts already relates somehow */
.swarm .edge.implicit { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 1 6; }
/* felt but still unnamed: the parts said how they feel about each other at a
   table meeting, so the thread has substance and a tone - and keeps its
   dashes, because what they are to each other is still an open question */
.swarm .edge.felt { stroke: var(--unknown); stroke-dasharray: 5 4; }
.swarm .edge.felt.warm { stroke: var(--good); }
.swarm .edge.felt.cool { stroke: var(--warn); }
/* a thread the parts have spoken about reads as laid down, not drawn */
.swarm .edge.rated { stroke-linecap: round; }
/* invisible, fat, and the only thing a finger has to hit */
.swarm .edge-hit { stroke: transparent; stroke-width: 18; fill: none; cursor: pointer; }
.swarm .edgelabel { font-size: 9px; fill: var(--ink-faint); text-anchor: middle; }
.swarm .node circle { stroke-width: 2.5; }
.swarm .node text { fill: var(--ink); font-size: 12px; font-weight: 600; text-anchor: middle; }
.swarm .node.self circle { fill: var(--accent-soft); stroke: var(--self); }
.swarm .node.self text { fill: var(--self); }
/* a part sat with in the last few days still has a light on in it */
.swarm .node.warm circle { animation: nodeWarm 3.6s ease-in-out infinite; }
@keyframes nodeWarm {
  0%, 100% { filter: none; }
  50% { filter: drop-shadow(0 0 5px var(--accent)); }
}
/* ================= the map key =================
   It began as three rows pinned open in the bottom corner. There is more to
   explain now - five thread styles, the five-point scale a round of the table
   writes onto a thread, and what a part's colour and its fading mean - and
   none of that belongs permanently on top of a 375px canvas. So the key
   closed itself and became a button: opened, it is a sheet off the bottom on
   a phone and a column down the right on anything wider, and the map is whole
   again the moment it closes. */
.map-key-btn {
  /* .map-wrap ends where the tab bar begins, so the offset here is only the
     gap - the bar carries its own safe-area padding. */
  position: absolute; left: 12px; bottom: 14px; z-index: 5; display: flex; align-items: center; gap: 7px;
  font-size: .72rem; font-weight: 650; color: var(--ink-dim);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--line); border-radius: 999px; padding: 7px 13px;
}
.map-key-btn:active { background: var(--surface2); }
/* A filter left switched on is the one thing about the key that has to stay
   visible once it is closed: a map drawing a third of its threads, with the
   reason folded away, is a bug report waiting to be filed. */
.map-key-btn.filtered { color: var(--ink); border-color: var(--accent); background: var(--accent-soft); }
.map-key-btn .mk-swatch { display: none; width: 9px; height: 9px; border-radius: 50%; flex: none; }
.map-key-btn.filtered .mk-swatch { display: inline-block; }

/* Tap anywhere off the key to put it away. Dimmed rather than blacked out -
   the map is what the key is about, and it should stay in view behind it. */
.legend-scrim {
  position: absolute; inset: 0; z-index: 6;
  background: color-mix(in srgb, var(--bg) 45%, transparent);
  animation: fadeIn .18s ease;
}
.map-legend {
  position: absolute; z-index: 7; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow); overflow: hidden;
  font-size: .72rem; color: var(--ink-dim);
  /* phone default: a sheet off the bottom, over the button that opened it */
  left: 8px; right: 8px; bottom: 8px;
  max-height: 78%; border-radius: 16px; animation: fadeUp .2s ease;
}
/* Room for a side panel: it takes the right-hand column and leaves the map
   readable next to it, which is the whole point of putting it there. */
@media (min-width: 700px) {
  .map-legend {
    left: auto; right: 0; top: 0; bottom: 0; width: 340px; max-height: none;
    border-width: 0 0 0 1px; border-radius: 0; animation: panelIn .2s ease;
  }
}
.map-legend .lg-head {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 10px 8px 8px 16px; border-bottom: 1px solid var(--line);
}
.map-legend .lg-head h3 { margin: 0; font-size: 1rem; color: var(--ink); }
.map-legend .lg-head .iconbtn { width: 34px; height: 34px; font-size: 20px; color: var(--ink-dim); }
.map-legend .lg-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 2px 12px 16px; }
.map-legend section + section { margin-top: 10px; padding-top: 4px; border-top: 1px solid var(--line); }
.map-legend h4 {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  margin: 12px 4px 6px; font-size: .62rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; color: var(--ink-faint);
}
.map-legend h4 small { font-size: .66rem; font-weight: 500; letter-spacing: 0; text-transform: none; }
.map-legend .lg, .map-legend .lgrow {
  display: flex; align-items: center; gap: 9px; width: 100%;
  font-size: .72rem; color: var(--ink-dim); text-align: left;
  padding: 5px 7px; border-radius: 8px; border: 1px solid transparent;
}
.map-legend .lg:active { background: var(--surface2); }
.map-legend .lg.on { background: var(--accent-soft); border-color: var(--accent); color: var(--ink); }
.map-legend .lg span, .map-legend .lgrow span { flex: 1; }
.map-legend .lgrow span b { color: var(--ink); font-weight: 650; }
.map-legend .lgrow small { display: block; font-size: .66rem; color: var(--ink-faint); }
.map-legend .lg b { font-variant-numeric: tabular-nums; color: var(--ink); }
.map-legend .lg-hint { font-size: .66rem; color: var(--ink-faint); padding: 4px 7px 0; }
.map-legend .lg-note { margin: 0; padding: 8px 7px 0; font-size: .66rem; line-height: 1.55; color: var(--ink-faint); }
.map-legend .lg-note b { color: var(--ink-dim); font-weight: 650; }
.map-legend .lg-unpin { margin: 10px 7px 2px; }

/* The swatches are the map's own strokes in a 26px box - whatever the key
   draws has to be the line the person is looking at, not an approximation
   of it. Keep these in step with .swarm .edge.* above. */
.map-legend .sw { flex: none; }
.map-legend .ln { width: 26px; height: 0; border-top: 2px solid var(--ink-faint); position: relative; }
.map-legend .ln.protects { border-color: var(--good); }
.map-legend .ln.protects::after {
  content: ""; position: absolute; right: -2px; top: -4px;
  border: 4px solid transparent; border-right: 0; border-left: 6px solid var(--good);
}
.map-legend .ln.allied { border-color: var(--good); }
.map-legend .ln.polarized { border-top-style: dashed; border-color: var(--warn); }
.map-legend .ln.conflicts { border-top-style: dotted; border-color: var(--warn); }
.map-legend .ln.felt { border-top-style: dashed; border-color: var(--unknown); }
.map-legend .ln.felt.warm { border-color: var(--good); }
.map-legend .ln.felt.cool { border-color: var(--warn); }
.map-legend .ln.faint { border-top: 1px dotted var(--ink-faint); }
/* Thickness and fade are things that happen *to* a thread rather than kinds
   of thread, so they get a swatch that shows the range instead of one more
   flat line pretending to be a category. */
.map-legend .sw.wedge {
  width: 26px; height: 9px; background: var(--ink-dim);
  clip-path: polygon(0 40%, 100% 0, 100% 100%, 0 60%);
}
.map-legend .sw.fade { width: 26px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, var(--ink-dim), transparent); }
/* 7 + 12 + 7 keeps a dot in the same 26px column as the lines above it */
.map-legend .dot { width: 12px; height: 12px; margin: 0 7px; border-radius: 50%; border: 2px solid var(--unknown); }
.map-legend .dot.manager { border-color: var(--manager); background: color-mix(in srgb, var(--manager) 25%, transparent); }
.map-legend .dot.firefighter { border-color: var(--firefighter); background: color-mix(in srgb, var(--firefighter) 25%, transparent); }
.map-legend .dot.exile { border-color: var(--exile); background: color-mix(in srgb, var(--exile) 25%, transparent); }
.map-legend .dot.unknown { background: color-mix(in srgb, var(--unknown) 25%, transparent); }
.map-legend .dot.self { border-color: var(--self); background: var(--accent-soft); }
.map-legend .dot.lit { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 6px var(--accent); }
/* The five points of the scale, each in the tone that reading lands on. */
.map-legend .fdot { width: 10px; height: 10px; margin: 0 8px; border-radius: 50%; background: var(--unknown); }
.map-legend .fdot.positive { background: var(--good); }
.map-legend .fdot.negative { background: var(--warn); }
@media (max-width: 480px) {
  .map-hint { font-size: .64rem; padding: 3px 10px; }
}
.rel-tone {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-faint); padding: 10px 2px 4px;
}
.rel-tone.positive { color: var(--good); }
.rel-tone.negative { color: var(--warn); }
.map-empty { position: absolute; inset: 0; margin: auto; height: fit-content; }
.map-card {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--tabbar-h) + var(--sab) + 12px);
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; padding: 10px 12px 10px 16px;
  box-shadow: var(--shadow); z-index: 4; max-width: 88vw;
  animation: toastUp .2s ease;
}
.map-card .mc-name { font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.map-card .mc-sub { display: block; font-size: .72rem; color: var(--ink-dim); font-weight: 400; }
.map-hint {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  font-size: .7rem; color: var(--ink-faint); background: color-mix(in srgb, var(--bg) 75%, transparent);
  padding: 4px 12px; border-radius: 999px; pointer-events: none;
  transition: transform .2s ease;
}
/* The side panel takes the right-hand column of the map, so the hint centres
   itself over what is left of it rather than sliding under the key. */
@media (min-width: 700px) {
  .map-wrap.key-open .map-hint { transform: translateX(calc(-50% - 170px)); }
}

/* Whose turn it is, for someone not reading the screen. Idle collapses to
   nothing so text-only sessions look exactly as they did. */
.voice-orb {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  /* min-height:0 or the flex default (auto) keeps a content-sized floor here
     and the idle state never collapses */
  height: 0; min-height: 0; overflow: hidden; opacity: 0;
  font-size: .72rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-dim); transition: height .2s ease, opacity .2s ease;
}
.voice-orb.speaking, .voice-orb.listening, .voice-orb.thinking { height: 30px; opacity: 1; }
.voice-orb i {
  width: 11px; height: 11px; border-radius: 50%; flex: none;
  background: var(--ink-faint); display: block;
}
.voice-orb.speaking i { background: var(--self); animation: voPulse 1.4s ease-in-out infinite; }
.voice-orb.listening i { background: var(--good); animation: voPulse .9s ease-in-out infinite; }
.voice-orb.thinking i { background: var(--accent); animation: voPulse 2s ease-in-out infinite; }
.voice-orb.listening { color: var(--good); }
@keyframes voPulse {
  0%, 100% { transform: scale(.8); opacity: .55; }
  50% { transform: scale(1.25); opacity: 1; }
}

/* banners on the parts view (resume draft, backup nag) */
.banner {
  display: flex; align-items: center; gap: 12px;
  background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: var(--radius); padding: 14px 16px; margin-bottom: 14px;
  animation: fadeUp .3s ease;
}
.banner.quiet { background: var(--surface); border-color: var(--line); }
.banner .bn-icon {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--accent);
}
.banner.quiet .bn-icon { background: var(--surface2); }
.banner .bn-main { flex: 1; font-size: .88rem; min-width: 0; }
.banner .bn-sub { display: block; font-size: .76rem; color: var(--ink-dim); }
.banner .btn { padding: 8px 14px; font-size: .82rem; flex: none; }

/* ================= settings ================= */
/* One folded card per section: a row with an icon tile that opens onto the
   section's own rows, each leading with an icon tile and the control on the right. */
.set-group {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 18px; overflow: hidden; scroll-margin-top: 64px;
}
.set-group h3 {
  margin: 0; padding: 10px 18px; background: var(--surface2); border-bottom: 1px solid var(--line);
  font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .13em; color: var(--ink-faint);
}
/* Every section starts folded: a row you open, not a page you scroll past */
details.set-group > summary {
  display: flex; align-items: center; gap: 12px; padding: 15px 16px; cursor: pointer;
  list-style: none; font-weight: 650; font-size: .98rem;
}
details.set-group > summary::-webkit-details-marker { display: none; }
details.set-group > summary .sg-sub { display: block; font-weight: 400; font-size: .76rem; color: var(--ink-dim); }
details.set-group > summary .sg-main { flex: 1; min-width: 0; }
details.set-group > summary .sg-chev { color: var(--ink-faint); transition: transform .2s ease; }
details.set-group[open] > summary { border-bottom: 1px solid var(--line); }
details.set-group[open] > summary .sg-chev { transform: rotate(90deg); }
.set-group { margin-bottom: 12px; }
.set-row { display: flex; align-items: center; gap: 13px; padding: 14px 16px; border-bottom: 1px solid var(--line); min-height: 70px; }
.set-row:last-child { border-bottom: 0; }
.set-row .sr-main { flex: 1; min-width: 0; font-weight: 600; font-size: .93rem; }
.set-row .sr-sub, .sr-copy .sr-sub { display: block; font-size: .76rem; font-weight: 400; color: var(--ink-dim); line-height: 1.45; margin-top: 1px; }
.set-row .btn { padding: 9px 16px; font-size: .84rem; flex: none; }
.sr-icon {
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.sr-icon.danger { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.sr-copy { margin-bottom: 12px; }
.sr-copy b { font-weight: 600; font-size: .93rem; }
.set-pad { padding: 14px 16px 16px; border-bottom: 1px solid var(--line); }
.set-pad:last-child { border-bottom: 0; }
.usage-scroll { overflow-x: auto; }
.usage-table { border-collapse: collapse; font-size: .78rem; font-variant-numeric: tabular-nums; }
.usage-table th, .usage-table td { padding: 5px 8px; text-align: right; border-bottom: 1px solid var(--line); white-space: nowrap; }
.usage-table thead th { color: var(--ink-dim); font-weight: 550; }
.usage-table tbody th { text-align: left; font-weight: 550; }
.usage-note { margin: 10px 2px 0; font-size: .76rem; }
.set-note { margin: 0; padding: 12px 18px 14px; font-size: .78rem; line-height: 1.55; color: var(--ink-faint); border-top: 1px solid var(--line); }
.account-card { display: flex; align-items: center; gap: 14px; padding: 16px; border-bottom: 1px solid var(--line); }
.account-card .sr-main b { display: block; font-size: 1.02rem; }
.account-card .sr-sub { display: block; font-size: .76rem; color: var(--ink-dim); }
.theme-options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.theme-options button {
  position: relative; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 6px; border-radius: 12px; font-size: .84rem; font-weight: 550;
  background: var(--bg2); border: 1px solid var(--line); color: var(--ink-dim);
}
.theme-options button.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 650; }
.theme-check {
  position: absolute; top: 5px; right: 5px; width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--accent-ink);
}
.theme-check .icon { stroke-width: 2.6; }
/* a real checkbox underneath (keyboard, forms, screen readers), drawn as a switch */
input.toggle {
  -webkit-appearance: none; appearance: none; flex: none; cursor: pointer;
  width: 46px; height: 27px; padding: 0; border-radius: 999px; border: 0;
  background: var(--line); position: relative; transition: background .2s ease;
}
input.toggle::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 21px; height: 21px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.25); transition: transform .2s ease;
}
input.toggle:checked { background: var(--accent); }
input.toggle:checked::after { transform: translateX(19px); }
input.toggle:focus { outline: none; }
input.toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.privacy-banner { display: flex; align-items: flex-start; gap: 14px; margin: 0 14px 14px; padding: 16px; border-radius: 14px; background: var(--accent-soft); }
.privacy-banner .pb-i { color: var(--accent); margin-top: 2px; }
.privacy-banner b.serif { font-size: 1.1rem; display: block; margin-bottom: 4px; }
.privacy-banner p { margin: 0 0 8px; font-size: .8rem; line-height: 1.55; color: var(--ink-dim); }
.privacy-banner p:last-child { margin: 0; }
details.advanced { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 12px; }
details.advanced summary { cursor: pointer; font-size: .86rem; font-weight: 600; color: var(--ink-dim); }
/* import preview: which field each piece of the text landed in */
.prevrows { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.prevrow {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; padding: 9px 12px; font-size: .86rem;
  white-space: pre-wrap; overflow-wrap: break-word;
}
.prevrow b {
  display: block; font-size: .66rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-dim); margin-bottom: 3px;
}
.prevrow .taglist { margin-top: 2px; }

/* ================= readings (how a part feels toward another) ================= */
.rt-row { margin: 0 0 14px; }
.rt-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.rt-who { font-weight: 600; font-size: .92rem; }
.rt-said { font-size: .72rem; color: var(--ink-faint); }
.likert { display: flex; gap: 4px; }
.likert button {
  flex: 1; padding: 9px 2px; border-radius: 10px; font-size: .66rem; font-weight: 600;
  background: var(--surface2); border: 1px solid var(--line); color: var(--ink-dim);
  line-height: 1.15;
}
.likert button.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.likert button .lk-n { display: block; font-size: .82rem; margin-bottom: 1px; }
/* the shift a round records: where a pair moved since the last one */
.shiftrow { display: flex; align-items: baseline; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: .84rem; }
.shiftrow:last-child { border-bottom: 0; }
.shiftrow .sh-move { margin-left: auto; font-size: .74rem; font-weight: 600; color: var(--ink-faint); }
.shiftrow .sh-move.up { color: var(--good); }
.shiftrow .sh-move.down { color: var(--warn); }

.seg { display: flex; background: var(--surface2); border: 1px solid var(--line); border-radius: 12px; padding: 3px; }
.seg button { flex: 1; padding: 9px 4px; border-radius: 9px; font-size: .82rem; font-weight: 600; color: var(--ink-dim); }
.seg button.on { background: var(--accent); color: var(--accent-ink); }

/* ================= toast ================= */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--tabbar-h) + var(--sab) + 20px);
  transform: translateX(-50%); z-index: 80;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  padding: 11px 18px; border-radius: 999px; font-size: .88rem; font-weight: 600;
  box-shadow: var(--shadow); max-width: 86vw; text-align: center;
  animation: toastUp .25s ease;
}
@keyframes toastUp { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* ================= session list ================= */
.sess-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 12px; cursor: pointer; }
.sess-card:active { background: var(--surface2); }
.sess-card .sc-top { display: flex; justify-content: space-between; gap: 10px; font-size: .78rem; color: var(--ink-faint); margin-bottom: 4px; }
.sess-card .sc-title { font-weight: 650; }
.sess-card .sc-note { color: var(--ink-dim); font-size: .86rem; margin-top: 2px; }

/* transcript */
.transcript { padding: 18px; max-width: 640px; margin: 0 auto; }
.transcript pre { white-space: pre-wrap; font: .84rem/1.6 ui-monospace, Menlo, Consolas, monospace; color: var(--ink-dim); }

/* wider screens: center a phone-ish column, keep it classy */
@media (min-width: 760px) {
  .view-pad { max-width: 720px; padding-top: 34px; }
  .view-pad.wide { max-width: 1120px; padding-left: 28px; padding-right: 28px; }
  .page-head { margin-bottom: 28px; }
  .ritual-copy { padding: 34px 36px 30px; }
  .sheet { max-width: 560px; left: 50%; transform: translateX(-50%); border-radius: 22px 22px 0 0; }
  @keyframes sheetUp { from { transform: translate(-50%, 100%); } to { transform: translate(-50%, 0); } }
  @keyframes sheetDown { to { transform: translate(-50%, 100%); } }
  .sheet.closing { animation: sheetDown .22s ease forwards; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ================= the table ================= */
.room-card {
  background: linear-gradient(158deg, var(--accent-soft), transparent 62%), var(--surface);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--line)); border-radius: var(--radius-lg);
  padding: 22px 20px; margin-bottom: 16px; box-shadow: var(--shadow);
}
.room-card .room-name { font-size: 1.75rem; font-weight: 500; letter-spacing: -.015em; margin: 10px 0 10px; }
.room-card .prose { white-space: pre-wrap; text-align: left; font-size: .95rem; }
.room-card .chip-btn { margin-top: 14px; }
.seatgroup { margin-bottom: 12px; }
.seatgroup:last-child { margin-bottom: 0; }
.seat-head {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-dim); margin-bottom: 6px;
}
.seat-head .dim { text-transform: none; letter-spacing: 0; font-size: .92em; }
.seatchip {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--surface2); border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 14px 4px 4px; margin: 0 6px 8px 0; font-size: .88rem; cursor: pointer;
}
.seatchip:active { transform: scale(.97); }
.seatchip .sc-i {
  width: 32px; height: 32px; border-radius: 50%; background: var(--accent-soft);
  display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
  font-size: .8rem; font-weight: 700; flex: none;
}
.menu-item.tool.on .mi-icon { color: var(--good); }

/* ---------- meeting summary cards ---------- */
.meetcard {
  background: var(--surface2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 12px 14px; margin-bottom: 10px;
  cursor: pointer; transition: border-color .15s ease;
}
.meetcard:last-child { margin-bottom: 0; }
.meetcard:active { border-color: var(--accent); }
.meetcard .mt-top {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: .72rem; color: var(--ink-faint); margin-bottom: 6px;
}
.meetcard .mt-topic { font-size: .86rem; color: var(--ink-dim); font-style: italic; margin-bottom: 10px; }
.mt-voice {
  border-left: 2px solid var(--vc, var(--accent));
  padding: 2px 0 2px 10px; margin-bottom: 9px;
  font-size: .87rem; line-height: 1.5; white-space: pre-wrap; overflow-wrap: break-word;
}
.mt-voice:last-child { margin-bottom: 0; }
.mt-voice .mt-name {
  display: flex; align-items: center; font-size: .64rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--vc, var(--accent)); margin-bottom: 3px;
}
.logrow { cursor: pointer; }
.logrow:active { background: var(--surface2); }
.logq { font-size: .95rem; font-weight: 600; line-height: 1.45; margin-bottom: 8px; }

/* ---------- the seating ceremony ---------- */
/* The one moment where the whole system sits down together, given the pause
   it deserves before the conversation starts. Skipped outright for anyone who
   has asked for reduced motion - see seatingCeremony() in ui.js. */
.seating {
  position: fixed; inset: 0; z-index: 65; background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  animation: fadeIn .3s ease;
}
.seating-inner { text-align: center; padding: 30px 24px; max-width: 430px; width: 100%; }
.seating-room { font-size: 1.45rem; opacity: 0; }
.seating.go .seating-room { animation: fadeUp .5s ease forwards; }
.seating-table { font-size: 44px; margin: 16px 0 24px; opacity: 0; }
.seating-table .glyph { width: auto; height: auto; font-size: 44px; line-height: 1; }
.seating.go .seating-table { animation: fadeUp .6s ease .12s forwards; }
.seating-chairs {
  display: flex; flex-wrap: wrap; gap: 12px 10px; justify-content: center; min-height: 78px;
}
.seating-chairs .chair {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  width: 78px; opacity: 0; transform: translateY(12px);
}
.seating.go .chair { animation: chairIn .5s cubic-bezier(.3,.9,.3,1) var(--d, 0ms) forwards; }
@keyframes chairIn { to { opacity: 1; transform: none; } }
.chair-i {
  width: 52px; height: 52px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
  border: 2px solid var(--accent);
  font-family: Georgia, serif; font-weight: 700; font-size: 1.02rem;
}
.chair-n { font-size: .7rem; color: var(--ink-dim); line-height: 1.25; overflow-wrap: anywhere; }
.seating-line {
  margin-top: 24px; min-height: 20px;
  font-size: .78rem; color: var(--ink-dim); letter-spacing: .08em; text-transform: lowercase;
}
.seating-skip {
  position: absolute; right: 16px; top: calc(14px + var(--sat));
  font-size: .74rem; color: var(--ink-faint); padding: 8px 12px;
}

/* ---------- coach cues (first run only) ---------- */
.coach {
  position: relative;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: 14px 42px 14px 16px;
  margin-bottom: 14px; animation: fadeUp .3s ease;
}
.coach-title { font-size: 1.02rem; margin-bottom: 5px; }
.coach-text { font-size: .87rem; color: var(--ink-dim); line-height: 1.55; }
.coach-more { margin-top: 10px; font-size: .8rem; font-weight: 650; color: var(--accent); padding: 4px 0; }
.coach-x {
  position: absolute; right: 7px; top: 7px;
  width: 30px; height: 30px; border-radius: 50%;
  color: var(--ink-faint); font-size: .8rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.coach-x:active { background: var(--surface2); }
/* on the map there is no document flow to sit in, so it floats over the swarm */
.coach-float { position: absolute; left: 12px; right: 12px; top: 38px; z-index: 4; }
.coach-float .coach { background: var(--bg2); box-shadow: var(--shadow); margin-bottom: 0; }
.chat-coach .coach { margin: 0 0 10px; }

/* ---------- the daily check-in ---------- */
/* The one deep card on the screen: a lit room with a question in it. */
.ritual {
  position: relative; overflow: hidden;
  background: var(--hero-bg); color: var(--hero-ink);
  border: 1px solid var(--hero-line);
  border-radius: var(--radius-lg); margin-bottom: 16px;
  box-shadow: var(--shadow); animation: fadeUp .35s ease;
}
.ritual-copy { position: relative; z-index: 2; padding: 24px 22px 22px; max-width: 600px; }
.ritual .kicker { color: var(--self); margin-bottom: 12px; }
.ritual-q { font-size: clamp(1.5rem, 5.4vw, 2.2rem); font-weight: 500; line-height: 1.15; letter-spacing: -.015em; margin: 0; max-width: 15em; }
.ritual-part { display: flex; align-items: center; gap: 11px; margin: 18px 0; }
.ritual-part .rt-i {
  width: 44px; height: 44px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: rgba(240, 201, 135, .16); color: var(--self);
  border: 1px solid rgba(240, 201, 135, .4);
  font-family: var(--font-serif); font-weight: 600; font-size: 1.1rem;
}
.ritual-part .rt-main { min-width: 0; }
.ritual-part .rt-sub { display: block; font-size: .78rem; color: var(--hero-dim); }
.ritual-cta { display: flex; flex-wrap: wrap; gap: 10px; }
.ritual-cta .btn { padding: 11px 20px; font-size: .9rem; }
.ritual .btn-primary { background: #e8a854; color: #241a0d; }
.ritual .btn-soft { background: rgba(255,255,255,.08); border-color: var(--hero-line); color: var(--hero-ink); }
.ritual .coach-x { color: var(--hero-dim); z-index: 3; }
.orbit-art { position: absolute; right: 0; top: 0; bottom: 0; width: 42%; pointer-events: none; opacity: .9; }
.orbit-art i { position: absolute; display: block; border-radius: 50%; }
.orbit-art .orbit { border: 1px solid var(--hero-line); }
.orbit-art .o1 { width: 270px; height: 270px; right: -60px; top: -40px; }
.orbit-art .o2 { width: 180px; height: 180px; right: -15px; top: 5px; }
.orbit-art .orb { background: #e8a854; border: 5px solid rgba(255,255,255,.08); background-clip: padding-box; }
.orbit-art .b1 { width: 58px; height: 58px; right: 62px; top: 66px; opacity: .85; box-shadow: 0 0 40px rgba(232,168,84,.45); }
.orbit-art .b2 { width: 22px; height: 22px; right: 22px; top: 32px; opacity: .6; }
.orbit-art .b3 { width: 16px; height: 16px; right: 150px; top: 168px; opacity: .45; }
/* On a phone the copy fills the card, so the art shrinks to faint rings in
   the corner behind the question - nothing solid where the buttons are. */
@media (max-width: 559px) {
  .orbit-art { width: 200px; height: 200px; bottom: auto; opacity: .55; }
  .orbit-art .o1 { width: 220px; height: 220px; right: -90px; top: -90px; }
  .orbit-art .o2 { width: 140px; height: 140px; right: -50px; top: -50px; }
  .orbit-art .b1 { width: 26px; height: 26px; right: 22px; top: 58px; border-width: 3px; }
  .orbit-art .b2, .orbit-art .b3 { display: none; }
  .ritual-copy { padding: 22px 20px 20px; }
}

/* how long a part has been left alone, on its card in the library */
.quiettag {
  font-size: .64rem; font-weight: 600; letter-spacing: .04em; white-space: nowrap;
  color: var(--ink-faint); border: 1px solid var(--line);
  padding: 2px 7px; border-radius: 999px;
}

/* ---------- the reference library ---------- */
.learn h3 {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-dim); margin: 22px 0 8px;
}
.learn p { margin: 0 0 12px; font-size: .97rem; line-height: 1.6; }
.learn .learn-list { margin: 0 0 14px; padding-left: 20px; }
.learn .learn-list li { margin: 7px 0; font-size: .95rem; line-height: 1.55; }
.learn a { color: var(--accent); }

/* ---------- readings history: how a pair's readings moved over rounds ---------- */
.hist-dir { margin: 0 0 18px; }
.hist-who { font-weight: 600; font-size: .95rem; margin-bottom: 8px; }
.hist-step { display: flex; align-items: center; gap: 10px; margin: 6px 0; }
.hist-dots { display: flex; gap: 4px; }
.hist-dots .fdot { width: 10px; height: 10px; border-radius: 50%; background: var(--line); }
.hist-dots .fdot.on.positive { background: var(--good); }
.hist-dots .fdot.on.negative { background: var(--warn); }
.hist-dots .fdot.on.unknown { background: var(--unknown); }
.hist-lab { font-size: .85rem; min-width: 64px; }

/* ---------- no-AI meeting: who is speaking ---------- */
.sm-who { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: .9rem; margin: 8px 2px 2px; }
.sm-who .sm-ava { width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; overflow: hidden; color: #fff; font-size: .78rem; flex: none; }

/* ================= a part's picture =================
   Everywhere the app draws a part as a circle with its initial in it, the
   picture can stand in for the initial: the circle keeps its own size,
   border and colour, and the picture simply fills it. A part with one and a
   part without sit side by side without either looking out of place. */
img.pic {
  display: block; width: 100%; height: 100%; object-fit: cover;
  border-radius: inherit; -webkit-user-drag: none; user-select: none;
}
.has-pic { padding: 0; overflow: hidden; }
.pc-avatar.has-pic, .chair-i.has-pic, .seatchip .sc-i.has-pic, .msg .voice .vava.has-pic,
.ritual-part .rt-i.has-pic, .mini-ava.has-pic, .map-card .mc-ava.has-pic { background: none; }
.sm-who .sm-ava.has-pic { background: none !important; }
.menu-item .mi-icon.has-pic { width: 30px; height: 30px; border-radius: 50%; display: block; flex: none; }
.ring .ring-initial.has-pic { inset: 7px; border-radius: 50%; }

/* the small face beside a name in a list: relationships, meeting cards, rounds */
.mini-ava {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; border-radius: 50%; margin-right: 7px; vertical-align: -5px;
  background: var(--accent-soft); color: var(--accent); overflow: hidden;
  font: 700 .62rem/1 Georgia, serif; letter-spacing: 0; text-transform: none;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
}
.mt-voice .mt-name .mini-ava { margin-right: 6px; vertical-align: baseline; }
.rt-who { display: inline-flex; align-items: center; }

/* the profile's portrait, and the same circle on the Table tab's seat sheet:
   tapping it is the way to a picture, so it wears a camera */
.portrait, .portrait .avatar, .avatar.pic-big, .avatar.pic-med { border-radius: 50%; }
.portrait { position: relative; display: block; padding: 0; margin: 0 auto 10px; }
.portrait .avatar, .avatar.pic-big, .avatar.pic-med {
  width: 84px; height: 84px; margin: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 2rem; font-family: Georgia, serif; font-weight: 700;
  background: var(--accent-soft); color: var(--accent);
  border: 2px solid var(--accent);
  transition: transform .15s ease;
}
.portrait:active .avatar { transform: scale(.97); }
.portrait .avatar.has-pic, .avatar.pic-big.has-pic, .avatar.pic-med.has-pic {
  background: none; border-color: var(--tc, var(--accent));
}
.portrait .avatar.has-pic { width: 112px; height: 112px; border-width: 3px; box-shadow: 0 6px 20px rgba(0,0,0,.28); }
.portrait-cam {
  position: absolute; right: -2px; bottom: -2px; width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--accent-ink); border: 3px solid var(--bg);
}
.portrait-cam .icon { stroke-width: 2; }
.hero-look {
  margin: 10px auto 0; max-width: 30em; padding: 0 8px;
  color: var(--ink-dim); font-size: .92rem; font-style: italic; line-height: 1.5;
}
.chip .icon { display: inline-block; vertical-align: -2px; margin-right: 3px; }

.seat-who { display: flex; align-items: center; gap: 14px; margin: 4px 0 10px; }
.seat-who .portrait { margin: 0; flex: none; }
.portrait.small .avatar, .portrait.small .avatar.has-pic { width: 64px; height: 64px; font-size: 1.6rem; border-width: 2px; box-shadow: none; }
.portrait.small .portrait-cam { width: 24px; height: 24px; border-width: 2px; border-color: var(--bg2); }
.seat-who .seat-name { min-width: 0; }
.seat-who .sheet-title { margin: 0; }
.rt-speaker { display: flex; justify-content: center; margin-bottom: 14px; }
.avatar.pic-med { width: 76px; height: 76px; font-size: 1.8rem; }
.avatar.pic-big { width: 132px; height: 132px; font-size: 2.6rem; }
.pic-now { display: flex; justify-content: center; margin: 12px 0 16px; }

.map-card .mc-ava {
  width: 38px; height: 38px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); border: 2px solid var(--accent);
  font: 700 1rem/1 Georgia, serif;
}
.map-card { padding-left: 12px; }

/* framing a new picture: a square window onto it, with the circle drawn over */
.crop {
  position: relative; width: min(100%, 300px, 44dvh); aspect-ratio: 1; margin: 12px auto 4px;
  overflow: hidden; border-radius: 16px; background: #111;
  touch-action: none; cursor: grab; user-select: none; -webkit-user-select: none;
}
.crop:active { cursor: grabbing; }
.crop-img { position: absolute; left: 0; top: 0; max-width: none; transform-origin: 0 0; pointer-events: none; will-change: transform; }
.crop-ring {
  position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  box-shadow: 0 0 0 999px rgba(0, 0, 0, .52);
  outline: 2px solid rgba(255, 255, 255, .85); outline-offset: -2px;
}
.crop-zoom { padding: 0; border: 0; background: none; height: 30px; accent-color: var(--accent); }
.crop-zoom:focus { outline-offset: 2px; }

/* ---------- the meeting room's photo ----------
   A banner across the top of the room card, bleeding to its edges, that is
   itself the way to change it. The card's own padding is 22px 20px, which is
   what the negative margins undo. */
.room-card.has-photo { overflow: hidden; }
.room-photo {
  position: relative; display: block; width: calc(100% + 40px);
  margin: -22px -20px 18px; padding: 0; aspect-ratio: 16 / 9;
  overflow: hidden; background: var(--surface2);
}
.room-photo img.pic { border-radius: 0; }
.room-photo .portrait-cam { right: 12px; bottom: 12px; border-color: rgba(20, 17, 14, .55); }
.room-photo:active img.pic { transform: scale(1.02); }
.room-photo img.pic { transition: transform .25s ease; }
.room-card .chip-btn + .chip-btn { margin-left: 8px; }

/* the photo and its stand-in on the picture sheet */
.pic-room {
  display: block; width: min(100%, 320px); aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: 14px; border: 2px solid var(--accent); background: var(--accent-soft);
}
.pic-room.empty {
  display: flex; align-items: center; justify-content: center;
  border-style: dashed; color: var(--accent);
}

/* the same photo in the seating ceremony, before the room is named */
.seating-photo {
  width: min(260px, 72vw); aspect-ratio: 16 / 9; margin: 0 auto 22px;
  border-radius: 16px; overflow: hidden; opacity: 0;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
.seating.go .seating-photo { animation: fadeUp .5s ease forwards; }

/* framing a wide photo: the window takes the width, not a fixed square */
.crop.wide { width: min(100%, 440px, 64dvh); }

.linkbtn { background: none; border: 0; padding: 0; color: var(--accent); font: inherit; text-decoration: underline; cursor: pointer; }

/* ---- the daily practice (ui-practice.js) ---- */
.quick-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.quick-row .quick { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; font-size: .88rem; }
.nt-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 12px; }
.chip.chip-btn.on { background: var(--accent-soft); border-color: var(--accent); color: var(--ink); }
.chip.tone-self.on { border-color: var(--good); }
.chip.tone-reactive.on { border-color: var(--warn); }
#ntNew, #ntText { width: 100%; box-sizing: border-box; margin-bottom: 10px; }
.nt-hint { margin: 0 2px 14px; font-size: .84rem; min-height: 1.2em; }
.pc-rel { margin-top: auto; display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; font-size: .8rem; }
.pc-feel { padding: 3px 10px; border-radius: 999px; background: var(--surface2); color: var(--ink-dim); border: 1px solid var(--line); }
.pc-feel.tone-self { color: var(--ink); border-color: var(--good); }
.pc-feel.tone-reactive { color: var(--ink); border-color: var(--warn); }
.pc-times { color: var(--ink-dim); }
.pc-depth { opacity: .75; }
.toward-card .pc-rel { margin-top: 4px; }
.lookback { display: flex; align-items: center; gap: 12px; width: 100%; margin: 0 0 16px; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px; color: var(--ink); text-align: left; cursor: pointer; font: inherit; }
.lookback .lb-i { color: var(--accent); display: inline-flex; }
.lookback .lb-main { flex: 1; display: flex; flex-direction: column; }
.lookback .lb-sub { color: var(--ink-dim); font-size: .82rem; }
.lb-list { margin: 6px 0 8px; padding-left: 18px; line-height: 1.7; }
.lb-dir { font-size: .78rem; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); color: var(--ink-dim); }
.lb-dir.warmer { border-color: var(--good); color: var(--ink); }
.lb-dir.cooler { border-color: var(--warn); color: var(--ink); }
details.mi-more { margin-top: 6px; }
details.mi-more summary { cursor: pointer; padding: 12px 4px; color: var(--ink-dim); font-size: .86rem; font-weight: 600; }
.menu-item.is-locked { opacity: .65; }
.pk-why { display: block; margin: 12px 2px 0; font-size: .86rem; }
.ground.standalone #groundEnd { display: none; }
.ground .alone-only { display: none; }
.ground.standalone .alone-only { display: block; }
.ground.standalone .session-only { display: none; }
.ritual-cta .btn-ghost { color: inherit; opacity: .85; }
