/* MoNomo. Blue halos on cool white; gold is reserved for actions and easter eggs.
   Dark mode is called Outer Darkness, obviously, and it's where the halos look best. */
:root {
  --bg: #f4f6f9;
  --surface: #ffffff;
  --surface-2: #e9edf3;
  --ink: #10141c;
  --ink-soft: #5b6475;
  --line: #dfe4ec;
  --halo: #3d8bff;
  --halo-soft: rgb(61 139 255 / .22);
  --halo-faint: rgb(61 139 255 / .08);
  --halo-fill: #2563d6;   /* solid fills behind white text (4.5:1+) */
  --halo-ink: #2458b8;    /* small text in halo blue */
  --danger-fill: #c8381f;
  --ok-fill: #2f7a4f;
  --gold: #dda941;        /* logo gold, sampled */
  --brand-ink: #0d0d0c;   /* logo black (light-mode M) */
  --danger: #c8381f;
  --care: #1d6f6a; --care-fill: #1d6f6a; /* crisis and hotline help: calm teal, never alarm red (phone theme.ts care) */
  --ok: #2f7a4f;
  --shadow: 0 1px 2px rgb(16 20 28 / .06), 0 6px 18px rgb(16 20 28 / .06);
  --radius: 16px;
  --nav-h: 96px;          /* room kept clear for the orb button */
  --safe-b: env(safe-area-inset-bottom, 0px);
  color-scheme: light;
}
:root[data-theme="dark"] {
  --bg: #090d14;
  --surface: #111824;
  --surface-2: #1a2333;
  --ink: #e8edf5;
  --ink-soft: #8b96a8;
  --line: #1f2939;
  --halo: #5aa9ff;
  --halo-soft: rgb(90 169 255 / .3);
  --halo-faint: rgb(90 169 255 / .1);
  --halo-fill: #2f6fd6;
  --halo-ink: #8cc2ff;
  --danger-fill: #c23a28;
  --ok-fill: #2f7a4f;
  --gold: #dda941;
  --brand-ink: #f9ebd0; /* logo cream (dark-mode M) */
  --danger: #ff6b55;
  --care: #6fd1c4; --care-fill: #1d6f6a; /* white on care-fill 5.9:1 */
  --ok: #6fcf97;
  --shadow: 0 1px 2px rgb(0 0 0 / .4), 0 6px 20px rgb(0 0 0 / .35);
  color-scheme: dark;
}
/* No explicit pick: follow the phone. Same tokens as above. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #090d14;
    --surface: #111824;
    --surface-2: #1a2333;
    --ink: #e8edf5;
    --ink-soft: #8b96a8;
    --line: #1f2939;
    --halo: #5aa9ff;
    --halo-soft: rgb(90 169 255 / .3);
    --halo-faint: rgb(90 169 255 / .1);
    --halo-fill: #2f6fd6;
    --halo-ink: #8cc2ff;
    --danger-fill: #c23a28;
    --ok-fill: #2f7a4f;
    --gold: #dda941;
    --brand-ink: #f9ebd0; /* logo cream (dark-mode M) */
    --danger: #ff6b55;
    --care: #6fd1c4; --care-fill: #1d6f6a; /* white on care-fill 5.9:1 */
    --ok: #6fcf97;
    --shadow: 0 1px 2px rgb(0 0 0 / .4), 0 6px 20px rgb(0 0 0 / .35);
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  font: 16px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--ink);
  min-height: 100dvh;
  padding-bottom: calc(var(--nav-h) + var(--safe-b));
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}
button, input, textarea, select { font: inherit; color: inherit; }
a { color: inherit; text-decoration-color: var(--halo); text-underline-offset: 3px; }
h1, h2, h3 { line-height: 1.2; margin: 0; }
h1 { font-size: 2.3rem; font-weight: 800; letter-spacing: -.035em; }
h2 { font-size: 1.1rem; }
.muted { color: var(--ink-soft); }
.small { font-size: .85rem; }

/* ---------- Top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; padding-top: max(10px, env(safe-area-inset-top));
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 8px; background: none; border: 0; padding: 4px; cursor: pointer; }
.logo-mark { height: 34px; width: auto; display: block; transition: transform .15s; }
/* The header mark follows the theme: black M on light, cream M on dark. */
.mark-dark { display: none; }
:root[data-theme="dark"] .mark-light { display: none; }
:root[data-theme="dark"] .mark-dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mark-light { display: none; }
  :root:not([data-theme="light"]) .mark-dark { display: block; }
}
.brand:active .logo-mark { transform: scale(.9) rotate(-6deg); }
.wordmark { font-weight: 800; font-size: 1.3rem; letter-spacing: -.02em; color: var(--brand-ink); }
.wordmark b { color: var(--gold); }
.icon-btn {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line); cursor: pointer;
}
.icon-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; }

.banner {
  margin: 12px 16px 0; padding: 10px 4px 10px 14px; border-radius: var(--radius);
  background: var(--gold); color: #1f1b16; font-weight: 600; font-size: .92rem;
  display: flex; align-items: flex-start; gap: 6px;
}
.banner[hidden], .announcement[hidden] { display: none; }

/* ---------- Layout ---------- */
main { padding: 16px; max-width: 680px; margin: 0 auto; outline: none; }
main > div { animation: page-in .28s ease-out; }
@keyframes page-in { from { opacity: 0; } }  /* opacity only: a transform here would unpin the fixed composer and + button mid-fade */
.page-head { margin-bottom: 14px; }
.page-head p { margin: 4px 0 0; color: var(--ink-soft); }
.stack > * + * { margin-top: 12px; }
.stack > .card + .card { margin-top: 0; }
.row { display: flex; gap: 8px; align-items: center; }
.spacer { flex: 1; }

.card {
  background: none; border: 0; border-bottom: 1px solid var(--line);
  border-radius: 0; padding: 18px 2px; box-shadow: none;
}
.card.crisis { border: 2px solid var(--care); border-radius: var(--radius); padding: 14px; margin-bottom: 8px; }
.card h3 { font-size: 1.05rem; }
.card p { margin: 6px 0 0; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 0 16px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface-2); cursor: pointer;
  font-weight: 600; text-decoration: none; color: var(--ink);
}
.btn.primary { background: var(--gold); border-color: var(--gold); color: #1f1b16; }
.btn.danger { background: var(--danger-fill); border-color: var(--danger-fill); color: #fff; }
.btn.care { background: var(--care-fill); border-color: var(--care-fill); color: #fff; }
.btn.ghost { background: none; }
.btn.on { background: var(--ok-fill); border-color: var(--ok-fill); color: #fff; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.block { width: 100%; }

.chips { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.chip {
  flex: none; min-height: 44px; padding: 0 16px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); font-size: .9rem; font-weight: 600;
}
.chip[aria-pressed="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }

.field { display: block; }
.field span { display: block; font-size: .85rem; font-weight: 600; margin-bottom: 4px; color: var(--ink-soft); }
.input, textarea.input, select.input {
  width: 100%; min-height: 44px; padding: 10px 12px;
  border-radius: 10px; border: 1px solid var(--line); background: var(--surface);
}
textarea.input { min-height: 110px; resize: vertical; }
.input:focus { outline: 2px solid var(--halo); outline-offset: 1px; }
/* Form errors (ui.js formError): red text under the field that caused it, or one line above the submit button */
.input[aria-invalid="true"] { border-color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger); }
.field-error, .form-error { margin: 4px 0 0; color: var(--danger); font-size: .85rem; font-weight: 600; line-height: 1.35; }
.field-error::before, .form-error::before { content: "! " / ""; font-weight: 800; } /* a mark that is not only color; silent to screen readers */
.stack > .field-error { margin-top: 4px; }
.form-error { padding: 10px 12px; border: 1px solid var(--danger); border-radius: 10px; }

/* ---------- Events ---------- */
.event { display: grid; grid-template-columns: 58px minmax(0, 1fr); gap: 12px; }
.event .ev-cover { grid-column: 1 / -1; width: 100%; max-height: 180px; object-fit: cover; border-radius: 12px; background: var(--surface-2, rgba(127,127,127,.12)); }
.datebox {
  width: 54px; height: 54px; border-radius: 50%; display: grid; place-content: center; text-align: center;
  border: 1px solid color-mix(in srgb, var(--halo) 55%, transparent);
  box-shadow: 0 0 0 4px var(--halo-faint), 0 0 16px var(--halo-soft); align-self: start;
}
.datebox .m { font-size: .62rem; font-weight: 800; text-transform: uppercase; color: var(--halo-ink); letter-spacing: .06em; }
.datebox .d { font-size: 1.25rem; font-weight: 800; line-height: 1; }
.event .meta { font-size: .85rem; color: var(--ink-soft); margin-top: 2px; }
.event .actions { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; } /* wrap: at 390px the RSVP button ran off the card */
.tag { font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--ink-soft); }
.fab {
  position: fixed; right: 16px; bottom: calc(var(--safe-b) + 24px); z-index: 15;
  width: 56px; height: 56px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--gold); color: #1f1b16; font-size: 30px; font-weight: 400; box-shadow: var(--shadow);
}

.segments { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; margin-bottom: 14px; border-radius: 999px; background: var(--surface-2); }
.segments a { text-align: center; padding: 12px 0; border-radius: 999px; text-decoration: none; color: var(--ink-soft); font-weight: 700; font-size: .9rem; }
.segments a[aria-current="page"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.evangelical { margin-top: 26px; padding: 16px; border-radius: 28px; border: 1.5px dashed var(--halo); box-shadow: 0 0 30px var(--halo-faint) inset; }
.evangelical > p { margin: 4px 0 12px; }

/* ---------- Resources ---------- */
.guide h2 { margin-bottom: 4px; }
.guide ul { margin: 6px 0 0; padding-left: 20px; }
.guide li + li { margin-top: 4px; }
.guide-foot { text-align: center; margin-top: 20px; }

/* ---------- Critical thinking game ---------- */
.quote { margin: 14px 0; padding: 14px 16px; border-left: 4px solid var(--halo); background: var(--surface); border-radius: 0 var(--radius) var(--radius) 0; font: 600 1.05rem/1.45 Georgia, serif; }
.btn.wrong { background: var(--danger-fill); border-color: var(--danger-fill); color: #fff; }
.btn.opt:disabled { opacity: 1; }
.btn.opt:disabled:not(.on):not(.wrong) { opacity: .45; }
.crisis h2 { color: var(--care); }
.res { display: block; text-decoration: none; color: inherit; }
.res .host { font-size: .8rem; color: var(--ink-soft); font-weight: 600; }
.res.guide-card .host { color: var(--halo-ink); }
/* Library cards (10/11): kind label, creator + year, caution chips, a heads-up note. */
.res .res-kind { color: var(--halo-ink); text-transform: uppercase; letter-spacing: .06em; font-size: .72rem; font-weight: 800; }
.res .res-by { margin: 2px 0 4px; font-size: .85rem; color: var(--ink-soft); }
.res-cw { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }
.cw-chip { display: inline-block; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--line); font-size: .74rem; font-weight: 700; color: var(--ink-soft); background: var(--bg); }
.cw-chip.cw-x, .cw-chip.cw-h { border-color: color-mix(in srgb, var(--danger) 55%, var(--line)); }
.cw-chip.cw-b { border-color: color-mix(in srgb, var(--halo) 60%, var(--line)); color: var(--halo-ink); }
.res-note { margin: 8px 0 0; color: var(--ink-soft); }
.res-more { margin-top: 8px; }
.res-kinds { margin-top: 2px; }
.res-kinds .chip { min-height: 40px; padding: 0 12px; }
.chip-n { font-weight: 500; opacity: .75; margin-left: 2px; }
.section-title { margin: 22px 0 8px; font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft); }
dl.gloss { margin: 0; }
dl.gloss dt { font-weight: 800; margin-top: 12px; }
dl.gloss dd { margin: 2px 0 0; color: var(--ink-soft); }

/* ---------- Messages ---------- */
.thread-row { display: flex; gap: 12px; align-items: center; text-decoration: none; color: inherit; }
.avatar {
  flex: none; width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center; font-weight: 800; font-size: 1rem;
  background: var(--surface); color: var(--halo-ink); border: 1px solid color-mix(in srgb, var(--halo) 50%, transparent); box-shadow: 0 0 12px var(--halo-soft);
}
.thread-row .preview { font-size: .88rem; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.thread-row .who { font-weight: 700; }
.thread-row > div:not(.avatar) { min-width: 0; flex: 1; }
.unread { width: 10px; height: 10px; border-radius: 50%; background: var(--halo); box-shadow: 0 0 8px var(--halo); flex: none; }

.chat { display: flex; flex-direction: column; gap: 8px; padding-bottom: 76px; }
.bubble { max-width: 82%; padding: 9px 13px; border-radius: 18px; background: var(--surface); border: 1px solid var(--line); }
.bubble.me { align-self: flex-end; background: var(--halo-fill); border-color: var(--halo-fill); color: #fff; border-bottom-right-radius: 6px; }
.bubble.them { align-self: flex-start; border-bottom-left-radius: 6px; }
.bubble .from { display: block; font-size: .72rem; font-weight: 700; color: var(--halo-ink); }
.typing { align-self: flex-start; font-size: .85rem; color: var(--ink-soft); font-style: italic; }
.composer {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 15;
  display: flex; gap: 8px; padding: 10px 16px; padding-bottom: calc(10px + var(--safe-b)); background: var(--bg); border-top: 1px solid var(--line);
}
.composer .input { border-radius: 999px; }
.chat-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.chat-head a { text-decoration: none; font-size: 1.4rem; width: 44px; height: 44px; display: grid; place-items: center; margin-left: -10px; color: var(--ink); }

/* ---------- Rage ---------- */
.shelf-wrap { position: relative; height: 304px; margin: 10px 0 6px; overflow: hidden; --shelf-edge: #7f8999; } /* --shelf-edge: 3:1 borders, same as the phone's inputLine */
:root[data-theme="dark"] .shelf-wrap { --shelf-edge: #606d84; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .shelf-wrap { --shelf-edge: #606d84; } }
/* One rigid unit (same as the phone): books, plank, and the L brackets under it all ride the sag about
   one center, so the books sit on the plank and nothing static touches a tilting edge. */
.shelf-unit { position: absolute; left: 0; right: 0; bottom: 146px; transform: rotate(var(--sag, 0deg)); transition: transform .3s; }
.shelf-items { display: flex; align-items: flex-end; gap: 4px; flex-wrap: wrap-reverse; padding: 0 6px; }
.book {
  flex: none; width: 34px; height: 66px; border-radius: 4px 4px 2px 2px; color: #fff; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
/* Only the book just shelved drops in (views/rage.js drawShelf marks it .new); the rest stay put */
.book.new { animation: drop .35s ease-out; }
/* The spine label (views/rage.js, shelf-lines.js spineLines): up to two whole-word lines, each ending in an ellipsis if a word won't fit.
   58 long on a 66 tall book (phone SPINE_W): the first letter clears the bottom edge and the ellipsis the rounded top. */
.book .spine { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 13px; font-weight: 700; line-height: 15px; letter-spacing: -.2px; text-align: center; }
.book .spine b { display: block; height: 58px; font-weight: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plank { height: 12px; box-sizing: border-box; border-radius: 3px; background: linear-gradient(#a0703f, #6b4226); border-bottom: 3px solid #4a2e1a; }
.shelf-wrap.broken .shelf-unit { animation: snap .9s forwards; }
.shelf-wrap.broken .book { animation: fall 1s forwards; }

/* The family portrait hanging under the shelf. Knocked crooked when the shelf goes. */
.portrait { position: absolute; left: calc(50% - 95px); bottom: 16px; width: 190px; margin: 0; text-align: center; transform-origin: 50% 0; transition: transform .5s cubic-bezier(.3, 1.6, .5, 1); }
.portrait svg { display: block; margin: 0 auto; width: 150px; height: 104px; filter: drop-shadow(0 3px 4px rgb(0 0 0 / .25)); }
.portrait figcaption { font: italic 600 .62rem/1 Georgia, serif; color: var(--ink-soft); margin-top: 6px; letter-spacing: .02em; }
.portrait.crooked { transform: rotate(-9deg); }
@keyframes drop { from { transform: translateY(-40px); opacity: 0; } }
@keyframes snap { 40% { transform: rotate(14deg); } 100% { transform: rotate(32deg) translateY(60px); opacity: 0; } }
@keyframes fall { to { transform: rotate(60deg) translateY(160px); opacity: 0; } }
/* The L brackets hang under the plank, inside .shelf-unit; the whole shelf goes down together and comes back with a line (views/rage.js rebuild()) */
.shelf-brackets { position: relative; height: 14px; }
.shelf-bracket { position: absolute; top: 0; width: 6px; height: 14px; border-radius: 2px; background: #4a2e1a; }
.shelf-bracket::after { content: ''; position: absolute; top: 0; width: 18px; height: 5px; border-radius: 2px; background: #4a2e1a; }
.shelf-bracket.l { left: 18%; } .shelf-bracket.l::after { left: 0; }
.shelf-bracket.r { right: 18%; } .shelf-bracket.r::after { right: 0; }
.shelf-wrap.down .shelf-unit { visibility: hidden; }
/* Down: a dashed ghost where the plank goes, the Rebuild chip sitting on it. Both edges 3:1, or a dark card hides them. */
.shelf-wrap.down::before { content: ''; position: absolute; left: 0; right: 0; bottom: 160px; height: 12px; box-sizing: border-box; border: 1px dashed var(--shelf-edge); border-radius: 3px; animation: ghost-in .25s ease-out backwards; }
.shelf-rebuild[hidden] { display: none; }
.shelf-rebuild { position: absolute; bottom: 144px; left: 50%; transform: translateX(-50%); min-height: 44px; padding: 6px 16px; font-size: .85rem; border-color: var(--shelf-edge); animation: chip-in .25s cubic-bezier(.33, 1, .68, 1) backwards; }
@keyframes ghost-in { from { opacity: 0; } }
@keyframes chip-in { from { opacity: 0; transform: translateX(-50%) scale(.9); } }
/* The line sits just above the empty plank (304 - 184 - 6 = 114px down), then rises once books go up */
.shelf-line { position: absolute; top: 6px; left: 8px; right: 8px; margin: 0; text-align: center; font-size: 1rem; line-height: 1.35; font-style: italic; color: var(--ink); opacity: .85; transition: opacity .2s, translate .25s cubic-bezier(.33, 1, .68, 1); }
.shelf-wrap.empty .shelf-line { translate: 0 calc(114px - 100%); }
.shelf-wrap.line-off .shelf-line { opacity: 0; }
/* Rebuild: falls from above the frame at full opacity, squashes on contact, wobbles; the books ride it down.
   Every keyframe keeps the sag in it, or the shelf sat level until the animation ended and then snapped to the tilt. */
.shelf-wrap.rebuilt .shelf-unit { animation: plank-in .3s cubic-bezier(.55, 0, 1, .45), plank-wobble .5s .5s; }
.shelf-wrap.rebuilt .plank { animation: plank-squash .2s .3s ease-out; }
.shelf-wrap.rebuilt .shelf-line { animation: line-in .38s .36s ease-out backwards; }
/* The impact is what knocks the portrait straight: held crooked until contact, jolted, then settles */
.shelf-wrap.rebuilt .portrait { transition: none; animation: portrait-knock .6s .3s backwards; }
@keyframes plank-in { from { transform: translateY(-260px) rotate(var(--sag, 0deg)); } }
@keyframes plank-squash { 0% { transform: scale(1.04, .6); } 45% { transform: scale(.99, 1.12); } 100% { transform: none; } }
@keyframes portrait-knock { 0% { transform: rotate(-9deg); } 10% { transform: rotate(-12deg); } 45% { transform: rotate(2.5deg); } 70% { transform: rotate(-1deg); } 100% { transform: none; } }
/* Reduce Motion: the global rule shortens animations but keeps their delays; the rebuilt shelf just appears */
@media (prefers-reduced-motion: reduce) { .shelf-wrap.rebuilt .plank, .shelf-wrap.rebuilt .shelf-unit, .shelf-wrap.rebuilt .shelf-line, .shelf-wrap.rebuilt .portrait { animation: none !important; } }
@keyframes plank-wobble { 20% { transform: rotate(calc(var(--sag, 0deg) - 2.5deg)); } 45% { transform: rotate(calc(var(--sag, 0deg) + 1.6deg)); } 70% { transform: rotate(calc(var(--sag, 0deg) - .7deg)); } }
@keyframes line-in { from { opacity: 0; transform: translateY(-8px); } }

.rage-card { text-align: center; overflow: hidden; --rage-gold: #a77a1e; --rage-ink: #c23a28; --rage-care: #1d6f6a; --rage-fly: #7a1e10; --rage-fly-shadow: rgb(255 255 255 / .9);
  --rage-w0: #1f5fd1; --rage-w1: #a8480c; --rage-w2: #c23a28; --rage-fly-blur: 2px; --rage-ghost: #b8862a; --rage-ghost-a: .85; --rage-ghost-ink: #8a6417; }
:root[data-theme="dark"] .rage-card { --rage-gold: #dda941; --rage-ink: #ff6b55; --rage-care: #6fd1c4; --rage-fly: #ffd9cc; --rage-fly-shadow: rgb(0 0 0 / .5);
  --rage-w0: #8cc2ff; --rage-w1: #ff9a3c; --rage-w2: #ff6b55; --rage-fly-blur: 1px; --rage-ghost: #f9ebd0; --rage-ghost-a: .9; --rage-ghost-ink: rgb(249 235 208 / .9); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .rage-card { --rage-gold: #dda941; --rage-ink: #ff6b55; --rage-care: #6fd1c4; --rage-fly: #ffd9cc; --rage-fly-shadow: rgb(0 0 0 / .5);
  --rage-w0: #8cc2ff; --rage-w1: #ff9a3c; --rage-w2: #ff6b55; --rage-fly-blur: 1px; --rage-ghost: #f9ebd0; --rage-ghost-a: .9; --rage-ghost-ink: rgb(249 235 208 / .9); } }
.rage-plate {
  text-align: left; margin-top: 12px; padding: 8px 12px; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--line) 65%, #ff6b55); background: color-mix(in srgb, var(--surface) 90%, #c23a28);
  transition: opacity .25s, transform .35s cubic-bezier(.3, 1.4, .5, 1);
}
.rage-plate.gone { opacity: 0; transform: translateY(-14px); }
.rage-plate.swap { animation: plate-in .4s cubic-bezier(.3, 1.4, .5, 1); }
@keyframes plate-in { from { opacity: 0; transform: translateY(-14px); } }
.rage-plate-top { display: flex; align-items: center; }
.rage-over { flex: 1; font-size: .8rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--rage-ink); }
.rage-skip { background: none; border: 0; padding: 6px 0 6px 10px; color: var(--ink-soft); font: inherit; font-size: .8rem; text-decoration: underline; cursor: pointer; }
.rage-name { margin: 2px 0 0; font-size: 1.15rem; display: inline-block; position: relative; }
/* the next smash earns a rare stamp: a gold dashed hint (an egg hint, so gold) */
.rage-next { display: table; margin: 2px 0; padding: 0 8px; border: 1px dashed var(--rage-gold); border-radius: 10px;
  color: var(--rage-gold); font-size: 13px; font-weight: 700; line-height: 18px; }
.rage-next[hidden] { display: none; }
/* one reserved line under the name (hint or 'Next unfinished target'), so the stage never moves */
.rage-slot { height: 24px; margin: 1px 0; display: flex; align-items: center; }
.rage-nextup { background: none; border: 0; padding: 0; font: inherit; font-size: 13px; font-weight: 700; color: var(--rage-gold); text-decoration: underline; cursor: pointer; }
.rage-nextup[hidden] { display: none; }
/* Set complete: a gold pill with the set's three mini stamps, in the slot (where you look mid-mash) */
.rage-slot { position: relative; }
.rage-plate.setdone .rage-slot > :not(.rage-setpill) { visibility: hidden; }
.rage-setpill { position: absolute; left: 0; top: 0; bottom: 0; display: flex; align-items: center; gap: 6px; padding: 0 6px 0 10px; border-radius: 12px;
  background: #dda941; border: 1px solid #b8862a; color: #3a2400; font-size: 13px; line-height: 18px; pointer-events: none; max-width: 100%; }
.rage-setpill[hidden] { display: none; }
.rage-setpill b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.rage-setpill i { flex: none; width: 14px; height: 14px; border-radius: 3px; border: 1.5px solid #fff; background: #c23a28; rotate: -6deg; box-sizing: border-box; }
.rage-setpill i:nth-of-type(2) { background: #f9ebd0; border-color: #a3271a; }
.rage-setpill i:nth-of-type(3) { background: #dda941; border-color: #f9ebd0; }
.rage-plate.unstrike .rage-name::after { transform-origin: right center; animation: rage-unstrike .18s cubic-bezier(.55, 0, 1, .45) forwards; }
@keyframes rage-unstrike { from { transform: scaleX(1); } to { transform: scaleX(0); } }
/* the smashed target stays on the plate and gets struck through when the stamp lands */
.rage-plate.struck .rage-name::after { content: ''; position: absolute; left: -2px; right: -2px; top: 50%; height: 2px; margin-top: 1px;
  background: var(--rage-ink); transform-origin: left center; animation: rage-strike .22s cubic-bezier(.33, 1, .68, 1) both; }
.rage-plate.strike-now .rage-name::after { animation: none; }
@keyframes rage-strike { from { transform: scaleX(0); } }
.rage-sub { margin: 0; }
.rage-stage { position: relative; height: 290px; display: flex; justify-content: center; }
.rage-ring-box { position: absolute; top: 66px; width: 216px; height: 216px; --heat: 0; --wave-grow: -65px; }
/* heat glow: ONE soft radial disc (three stacked discs banded) */
.rage-glow { position: absolute; left: -30%; top: -30%; width: 160%; height: 160%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgb(255 107 85 / .55), rgb(255 107 85 / .18) 60%, rgb(255 107 85 / 0));
  opacity: calc(.1 + var(--heat) * .9); transform: scale(calc(.72 + var(--heat) * .34)); transition: opacity .14s, transform .14s; }
.rage-ring { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.rage-ring circle { fill: none; stroke-width: 10; }
.rage-ring .track { stroke: color-mix(in srgb, var(--line) 70%, var(--ink-soft)); stroke-opacity: .6; }
.rage-ring .hair { stroke: color-mix(in srgb, var(--line) 70%, var(--ink-soft)); stroke-width: 1; }
.rage-ring .fill { stroke-linecap: round; transition: stroke-dashoffset .12s linear, stroke .12s linear; }
.rage-ring .fill.pulse { animation: rage-pulse .2s ease-out; }
/* the head start banked under the stamp: a thin cream ghost arc on its own inner track (r = R - 7), never over the meter */
.rage-ring .ghost { stroke: var(--rage-ghost); stroke-width: 4; stroke-linecap: round; stroke-opacity: 0; }
.rage-ring .ghost.on { stroke-opacity: var(--rage-ghost-a); } /* same as the phone: cream on dark, deep gold on light */
/* a banked head start waiting for its tap breathes (.9 -> .51 -> .9 on dark, .85 -> .49 -> .85 on light), and is named over the ring */
.rage-ring .ghost.on.wait { animation: rage-ghost .7s ease-in-out infinite; }
@keyframes rage-ghost { 50% { stroke-opacity: calc(var(--rage-ghost-a) * .571); } }
@media (prefers-reduced-motion: reduce) { .rage-ring .ghost.on.wait { animation: none; } }
.rage-hs { position: absolute; left: 50%; top: -24px; translate: -50% 0; white-space: nowrap; pointer-events: none; z-index: 1;
  font-size: 13px; line-height: 18px; font-weight: 700; letter-spacing: 1.5px; color: var(--rage-ghost-ink); }
.rage-hs[hidden] { display: none; }
@keyframes rage-pulse { 50% { stroke-width: 13; } }
.rage-wave { position: absolute; border-radius: 50%; border: 8px solid #ff9a3c; opacity: 0; pointer-events: none; inset: 2px; }
.rage-btn {
  position: absolute; left: 24px; top: 24px; width: 168px; height: 168px; border-radius: 50%; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; overflow: hidden;
  border: 3px solid #e2513d; cursor: pointer; color: #fff; touch-action: manipulation; user-select: none; -webkit-tap-highlight-color: transparent;
  background: radial-gradient(circle at 38% 32%, #ff8a6a, #c23a28 55%, #6e1d11);
  box-shadow: 0 7px 0 #6e1d11, 0 14px 30px rgb(194 65 45 / .35);
  transition: transform .05s, box-shadow .05s;
}
.rage-btn::before { content: ''; position: absolute; left: 14%; top: 13%; width: 52%; height: 26%; border-radius: 50%;
  background: radial-gradient(closest-side, rgb(255 255 255 / .42), transparent); pointer-events: none; }
.rage-btn::after { content: ''; position: absolute; inset: 0; background: #ff9a3c; pointer-events: none;
  opacity: calc(max(0, var(--heat) - .5) * .64); }
.rage-btn.down { transform: translateY(5px) scale(.93); box-shadow: 0 2px 0 #6e1d11, 0 6px 16px rgb(194 65 45 / .35); transition: transform .05s; }
.rage-btn:not(.down) { transition: transform .35s cubic-bezier(.3, 1.8, .5, 1), box-shadow .2s; }
.rage-word { position: relative; z-index: 1; font-size: 1.6rem; font-weight: 900; letter-spacing: .12em; transition: opacity .16s; }
.rage-combo { position: relative; z-index: 1; font-size: .8rem; font-weight: 700; color: #ffe3d9; min-height: 1em; transition: opacity .16s; }
/* while the stamp is up the button's own label steps aside (out in .06s before the slam, back in .16s after the lift) */
.rage-ring-box.stamped .rage-word, .rage-ring-box.stamped .rage-combo { opacity: 0; transition-duration: .06s; }
.rage-cracks { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; }
.rage-cracks path { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.rage-cracks .lite { stroke: rgb(255 220 200 / .55); stroke-width: 2.4; }
.rage-cracks .dark { stroke: #3d0d06; stroke-width: 1.2; }
.rage-cracks g { display: none; }
.rage-ring-box[data-cracks="1"] [data-crack="1"],
.rage-ring-box[data-cracks="2"] [data-crack="1"], .rage-ring-box[data-cracks="2"] [data-crack="2"],
.rage-ring-box[data-cracks="3"] g { display: inline; }
.rage-flash { position: absolute; inset: 0; opacity: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(closest-side, rgb(255 227 217 / .12), rgb(255 227 217 / .3) 55%, rgb(255 227 217 / .95)); }
.rage-ring-box.hot .rage-btn:not(.down) { animation: rage-tremble .18s linear infinite; }
@keyframes rage-tremble { 25% { translate: 2.5px 0; } 75% { translate: -2.5px 0; } }
.rage-ring-box.erupt .rage-flash { animation: rage-flash .12s ease-out; }
.rage-ring-box.erupt .rage-wave { animation: rage-wave .5s cubic-bezier(.33, 1, .68, 1); }
.rage-ring-box.erupt.gold .rage-wave { animation: rage-wave-gold .3s cubic-bezier(.33, 1, .68, 1); }
/* a warm rim-bright flash (center about .1), so SMASH xN stays legible under it */
@keyframes rage-flash { from { opacity: .8; } to { opacity: 0; } }
/* hot shockwave: grows from the ring to 1.6x (capped to the stage by --wave-grow), 8px thinning to 1,
   full strength for the first 40% so it reads as heat */
@keyframes rage-wave { from { opacity: 1; inset: 2px; border-width: 8px; border-color: #ff9a3c; }
  40% { opacity: 1; }
  to { opacity: 0; inset: var(--wave-grow); border-width: 1px; border-color: #ff6b55; } }
/* the 10th stamp's wave: gold, quicker, a ring of light */
@keyframes rage-wave-gold { from { opacity: 1; inset: 2px; border-width: 8px; border-color: #dda941; }
  40% { opacity: 1; }
  to { opacity: 0; inset: var(--wave-grow); border-width: 1px; border-color: #dda941; } }
/* flying words stay inside the stage, never up into the plate */
.rage-words-clip { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.rage-words { position: absolute; left: 50%; top: 174px; width: 0; height: 0; }
.rage-fly { position: absolute; white-space: nowrap; font-weight: 700; font-size: 13px; line-height: 18px; letter-spacing: 1px;
  color: var(--rage-w0); text-shadow: 0 1px var(--rage-fly-blur) var(--rage-fly-shadow); translate: -50% -50%; }
/* the words escalate with the meter: blue halo ink, orange past the 36 snap, vent red past 70 */
.rage-fly.w1 { color: var(--rage-w1); }
.rage-fly.w2 { color: var(--rage-w2); }
/* combo milestone: one gold pill (an easter egg, so gold) above the ring */
.rage-pill { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); max-width: min(330px, 94%); z-index: 4;
  padding: 5px 14px; border-radius: 999px; background: #1b2434; border: 1px solid color-mix(in srgb, #1b2434 55%, #dda941);
  color: #dda941; font-weight: 700; font-size: 15px; line-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; }
.rage-pill[hidden] { display: none; }
.rage-gold { position: absolute; left: 50%; top: 164px; border-radius: 1.5px; pointer-events: none; z-index: 5; }
.rage-stamp { position: absolute; top: 130px; left: 50%; translate: -50% 0; rotate: -8deg; padding: 8px 16px; border-radius: 10px;
  border: 3px solid #fff; background: #c23a28; color: #fff; pointer-events: none; z-index: 3; }
.rage-stamp { width: max-content; text-align: center; } /* max-width + the verdict's font size are set per stamp (rage-button.js) */
.rage-stamp b { display: block; font: 700 30px/1.12 Georgia, serif; letter-spacing: 1px; }
.rage-stamp span { display: block; font-size: 13px; line-height: 18px; font-weight: 600; letter-spacing: 1.5px; margin-top: 2px; color: #ffe3d9; font-variant-numeric: tabular-nums; }
/* the slam + lift run in rage-button.js (WAAPI, ms offsets: a rare stamp holds 400ms longer) */
/* every 5th: cream face, red ink, dashed gold rule. every 10th: gold face, dark ink, cream rule */
.rage-stamp.rare-1, .rage-stamp.rare-2 { border-width: 2px; }
.rage-stamp.rare-1::before, .rage-stamp.rare-2::before { content: ''; position: absolute; inset: 4px; border-radius: 7px; pointer-events: none; }
.rage-stamp.rare-1 { background: #f9ebd0; border-color: #a3271a; color: #a3271a; }
.rage-stamp.rare-1::before { border: 1.5px dashed #dda941; }
.rage-stamp.rare-2 { background: #dda941; border-color: #b8862a; color: #3a2400; }
.rage-stamp.rare-2::before { border: 3px solid #f9ebd0; }
.rage-stamp.rare-1 span, .rage-stamp.rare-2 span { color: inherit; font-size: 13px; font-weight: 600; letter-spacing: 1.5px; margin-top: 2px; }
.rage-stamp.rare-2.reissue::before { border: 1.5px dashed #3a2400; } /* every 10th past the first: a reprint */
/* today's docket, first max-out: cream like a court slip, dark ink, a solid gold rule */
.rage-stamp.docket { background: #f9ebd0; border: 2px solid #3a2400; color: #3a2400; }
.rage-stamp.docket::before { content: ''; position: absolute; inset: 4px; border-radius: 7px; border: 2px solid #dda941; pointer-events: none; }
.rage-stamp.docket span { color: inherit; }
.rage-over.dk { color: var(--rage-gold); }
.rage-dk { display: none; width: 7px; height: 7px; border-radius: 50%; background: #dda941; margin-right: -1px; flex: none; box-sizing: border-box; }
.rage-chip.docket .rage-dk { display: inline-block; }
.rage-chip.docket:not(.hit) .rage-dk { border: 1px solid #b8862a; }
/* a 10th's receipt sits over the level line for 2.8s: a small cream slip, like the set pill */
.rage-levelbox { position: relative; z-index: 2; } /* grows to the receipt slip (min-height set in rage-button.js) */
.rage-level.under { visibility: hidden; } /* (its line fades run as WAAPI with fill, so opacity here would lose) */
.rage-onstage { position: absolute; left: 50%; top: 0; translate: -50% 0; width: max-content; max-width: min(330px, 100%); box-sizing: border-box; margin: 0;
  padding: 5px 12px; border-radius: 8px; background: #f9ebd0; border: 1.5px dashed #b8862a; color: #3a2400;
  font-family: inherit; font-size: 13px; line-height: 18px; font-weight: 600; text-align: center; transform: rotate(-1deg); cursor: pointer; }
.rage-onstage[hidden] { display: none; }
.rage-onstage:focus-visible { outline: 2px solid var(--halo); outline-offset: 2px; }
.rage-streak { margin: 8px 0 0; color: var(--ink-soft); }
:root[data-theme="dark"] .rage-streak { color: #f9ebd0; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .rage-streak { color: #f9ebd0; } }
.rage-streak[hidden] { display: none; }
.rage-togo { line-height: 18px; }
.rage-togo[hidden] { display: none; }
.rage-stamp span em { font-style: normal; }
/* the Case File sheet for a finished set: only the stamp is gold */
.rage-case h2 { margin: 2px 0 0; }
.rage-case-over { margin: 12px 0 4px; font-size: .8rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.rage-case-stamp { display: flex; justify-content: center; margin: 18px 0; }
.rage-case-stamp b { position: relative; padding: 10px 18px; border-radius: 10px; background: #dda941; border: 2px solid #b8862a; color: #3a2400; rotate: -6deg;
  font: 700 24px/28px Georgia, serif; letter-spacing: 1px; text-align: center; }
.rage-case-stamp b::before { content: ''; position: absolute; inset: 4px; border-radius: 7px; border: 3px solid #f9ebd0; pointer-events: none; }
.rage-case-receipt { border: 1.5px dashed var(--line); border-radius: 10px; padding: 4px 12px 10px; }
.rage-case-receipt p { margin: 4px 0 0; }
.rage-case-hist { list-style: none; margin: 0; padding: 0; }
.rage-case-hist li { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line);
  animation: rage-deal .22s cubic-bezier(.33, 1, .68, 1) var(--d, 0ms) backwards; }
@keyframes rage-deal { from { opacity: 0; translate: 0 6px; } }
@media (prefers-reduced-motion: reduce) { .rage-case-hist li { animation: none; } }
.rage-case-hist li:last-child { border-bottom: 0; }
.rage-case-hist small { flex: 1; color: var(--ink-soft); font-size: .8rem; }
.rage-case-hist em { font-style: normal; font-size: .8rem; font-weight: 600; text-align: right; }
/* each history row is a mini stamp in its own ink: red usual, cream rare, gold only for the 10th */
.rage-case-mini { flex: 0 0 auto; width: max-content; max-width: 160px; box-sizing: border-box; height: 28px; line-height: 24px; padding: 0 8px; border-radius: 5px; rotate: -4deg;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font: 700 11.5px/24px Georgia, serif; letter-spacing: .3px;
  background: #c23a28; color: #fff; border: 2px solid #fff; }
.rage-case-cell { flex: 0 0 160px; display: flex; }
.rage-case-mini[data-j="1"] { background: #f9ebd0; color: #a3271a; border: 2px dashed #a3271a; }
.rage-case-mini[data-j="2"] { background: #dda941; color: #3a2400; border-color: #b8862a; }
/* the stamps earned before the records started share one dashed outline, its legend on the edge */
.rage-case-note { margin: 0 0 6px; }
.rage-case-nof { position: relative; border: 1.5px dashed color-mix(in srgb, var(--line) 55%, var(--ink-soft)); border-radius: 10px; padding: 0 10px; margin-bottom: 4px; }
.rage-case-legend { position: absolute; right: 10px; top: -9px; padding: 0 4px; font-size: .75rem; color: var(--ink-soft); background: var(--bg); }
.rage-count small { display: block; text-align: right; font-size: .75rem; opacity: .8; }
.rage-card { scroll-margin-top: 84px; } /* 'Swing at it again' lands the whole card (title first) below the sticky header */
.rage-case .row { margin-top: 16px; }
.rage-case .row .btn { flex: 1; }
.rage-level { font-weight: 700; min-height: 2.8em; margin: 0; }
.rage-stats { display: flex; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.rage-stats div { flex: 1; display: flex; flex-direction: column; }
.rage-stats b { font-size: 1.2rem; font-variant-numeric: tabular-nums; }
.rage-stats span { font-size: .8rem; color: var(--ink-soft); }
.rage-help { display: inline-block; margin-top: 12px; font-size: .82rem; color: var(--rage-care); }
/* Smashed so far: one chip per target */
.rage-shelf { margin-top: 12px; text-align: left; }
.rage-shelf-top { display: flex; align-items: baseline; gap: 8px; }
.rage-count { font-variant-numeric: tabular-nums; }
.rage-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.rage-chip { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 10px; border-radius: 16px; font: inherit; font-size: .8rem;
  color: var(--ink-soft); background: transparent; border: 1px dashed color-mix(in srgb, var(--line) 65%, var(--ink-soft)); cursor: pointer; }
.rage-chip b { display: none; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 11px; background: #6e1d11; color: #ffe3d9;
  font-size: .75rem; line-height: 22px; text-align: center; font-variant-numeric: tabular-nums; }
.rage-chip.hit { background: #c23a28; border: 1px solid #c23a28; color: #fff; font-weight: 700; padding-right: 4px; }
.rage-chip.hit b { display: inline-block; }
/* stamp tally: usual, 5th, 10th. Filled = seen; the rare two in gold (eggs) */
.rage-dots { display: none; gap: 2px; margin: 0 2px 0 -2px; }
.rage-chip.hit .rage-dots { display: inline-flex; }
.rage-dots i { width: 6px; height: 6px; border-radius: 50%; border: 1px solid #ffe3d9; box-sizing: border-box; }
.rage-dots i + i { border-color: #dda941; }
.rage-dots i.on { background: #ffe3d9; }
.rage-dots i + i.on { background: #dda941; }
/* Stamps: the three for the target on the plate, ??? until earned */
.rage-stamps { display: flex; gap: 8px; margin-top: 8px; }
.rage-mini { flex: 1; display: flex; flex-direction: column; align-items: center; min-width: 0; }
.rage-mini b { align-self: stretch; min-height: 52px; display: flex; align-items: center; justify-content: center; padding: 6px; border-radius: 8px;
  border: 1px dashed color-mix(in srgb, var(--line) 65%, var(--ink-soft)); color: var(--ink-soft); font-size: 13px; line-height: 16px; text-align: center; }
.rage-mini.on b { background: #c23a28; color: #fff; border: 2px solid #fff; font-family: Georgia, serif; rotate: -3deg; position: relative; }
.rage-mini.on.rare b::before { content: ''; position: absolute; inset: 3px; border-radius: 5px; pointer-events: none; }
.rage-mini.on[data-j="1"] b { background: #f9ebd0; color: #a3271a; border-color: #a3271a; }
.rage-mini.on[data-j="1"] b::before { border: 1.5px dashed #dda941; }
.rage-mini.on[data-j="2"] b { background: #dda941; color: #3a2400; border-color: #b8862a; }
.rage-mini.on[data-j="2"] b::before { border: 2px solid #f9ebd0; }
/* the 10th stamp completes the set: a gold banner over the row */
.rage-stamps { position: relative; }
.rage-banner { position: absolute; left: 50%; top: 26px; transform: translate(-50%, -50%) rotate(-2deg); z-index: 2; white-space: nowrap; pointer-events: none;
  padding: 4px 14px; border-radius: 6px; background: #dda941; border: 2px solid #f9ebd0; color: #3a2400;
  font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.rage-banner[hidden] { display: none; }
.rage-mini span { margin-top: 4px; font-size: .8rem; color: var(--ink-soft); }
/* the earned 10th flips (rotateY, rage-button.js FLIP_MS) to a receipt: the year on a cream slip, the line under the row */
.rage-card3d { align-self: stretch; position: relative; transform-style: preserve-3d; perspective: 600px; }
.rage-card3d b, .rage-back { backface-visibility: hidden; }
.rage-card3d.flipped { transform: rotateY(180deg); }
.rage-back { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 8px; rotate: -3deg;
  background: #f9ebd0; border: 1.5px dashed #3a2400; transform: rotateY(180deg); font-style: normal; }
.rage-back small { font-size: 13px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: #a3271a; line-height: 16px; }
.rage-back strong { font: 700 20px/24px Georgia, serif; color: #3a2400; font-variant-numeric: tabular-nums; }
.rage-mini.can-flip { cursor: pointer; }
.rage-mini.can-flip span { color: var(--rage-gold); font-weight: 700; text-decoration: underline; }
.rage-mini.can-flip:focus-visible { outline: 2px solid var(--halo); outline-offset: 2px; border-radius: 8px; }
.rage-receipt { margin: 8px 0 0; text-align: center; }
.rage-receipt[hidden] { display: none; }
.rage-chip.cur { border: 2px solid var(--rage-ink); }
.rage-chip:focus-visible { outline: 2px solid var(--halo); outline-offset: 2px; }
.meter { height: 14px; border-radius: 999px; background: var(--surface-2); overflow: hidden; border: 1px solid var(--line); }
.meter > i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--halo), var(--danger)); transition: width .12s; }
.shake { animation: shake .5s; }
@keyframes shake {
  10%, 90% { transform: translateX(-2px); } 20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-8px); } 40%, 60% { transform: translateX(8px); }
}
.burning { animation: burn 1.6s forwards; }
@keyframes burn {
  0% { color: var(--ink); text-shadow: none; }
  30% { color: #ff9a3c; text-shadow: 0 0 8px #ff5a1f, 0 -6px 14px #ffb341; }
  100% { color: transparent; text-shadow: 0 -40px 30px transparent; filter: blur(4px); transform: translateY(-20px); }
}

/* ---------- Toasts and sheets ---------- */
.toasts {
  position: fixed; left: 16px; right: 16px; top: calc(max(10px, env(safe-area-inset-top)) + 62px); z-index: 60;
  display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none;
}
.toast {
  max-width: 460px; padding: 12px 6px 12px 16px; border-radius: 14px; pointer-events: auto;
  background: var(--ink); color: var(--bg); box-shadow: var(--shadow); font-size: .93rem;
  animation: toast-in .25s ease-out;
  display: flex; align-items: flex-start; gap: 6px;
}
/* Swipe up or sideways to put a pop-up away (dismissable() in ui.js); pulling down stays the page's (pan-up = the finger moving down). */
.toast, .banner, .announcement { touch-action: pan-up; user-select: none; -webkit-user-select: none; }
.toast.leaving, .banner.leaving, .announcement.leaving { pointer-events: none; }
.toast.egg { background: var(--gold); color: #1f1b16; }
.toast.error { border-left: 4px solid var(--danger); }
.toast-text { flex: 1; min-width: 0; padding-top: 1px; }
.toast-x { flex: none; width: 44px; height: 44px; margin: -10px -2px -10px 0; border: 0; border-radius: 999px; background: transparent; color: inherit; cursor: pointer; display: grid; place-items: center; }
.toast-x svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; fill: none; }
.toast-x:hover { background: rgb(127 127 127 / .2); }
.toast-x:focus-visible { outline: 2px solid var(--halo); outline-offset: -2px; }
.toast.egg b { display: block; font-size: .75rem; text-transform: uppercase; letter-spacing: .08em; }
@keyframes toast-in { from { transform: translateY(-16px); opacity: 0; } }

.scrim { position: fixed; inset: 0; z-index: 50; background: rgb(0 0 0 / .45); display: flex; align-items: flex-end; animation: fade .2s; }
.sheet {
  width: 100%; max-height: 88dvh; overflow-y: auto; background: var(--bg);
  border-radius: 22px 22px 0 0; padding: 8px 16px calc(24px + var(--safe-b));
  animation: up .25s ease-out;
}
.sheet .grab { width: 64px; height: 24px; margin: -4px auto 6px; cursor: grab; touch-action: none; position: relative; }
.sheet .grab::before { content: ""; position: absolute; left: 12px; right: 12px; top: 9px; height: 5px; border-radius: 9px; background: var(--line); }
.sheet:focus { outline: none; }
body.sheet-open { overflow: hidden; }
@keyframes fade { from { opacity: 0; } }
@keyframes up { from { transform: translateY(40%); } }

.egg-list { list-style: none; margin: 0; padding: 0; }
.egg-list li { display: flex; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: .92rem; }
.egg-list li .mark { flex: none; width: 22px; text-align: center; }
.egg-list li.found { font-weight: 600; }
.egg-list li:not(.found) { color: var(--ink-soft); font-style: italic; }
.stat { font-size: 2rem; font-weight: 900; line-height: 1; }
.switch { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; }

/* ---------- Easter egg effects ---------- */
.seer {
  position: fixed; inset: 0; z-index: 80; background: #0b0906; color: #e9dcc0;
  display: grid; place-items: center; text-align: center; padding: 24px; touch-action: none;
}
.seer .glyphs { font-family: Georgia, serif; font-size: 1.25rem; max-width: 22ch; line-height: 1.6; }
.seer .hat {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at var(--x, 50%) var(--y, 45%), transparent 0 64px, rgb(11 9 6 / .97) 120px);
}
.seer .close { position: absolute; top: max(16px, env(safe-area-inset-top)); right: 16px; z-index: 2; }
.seer .prompt { position: absolute; bottom: 40px; left: 0; right: 0; font-size: .9rem; color: #8e826d; z-index: 2; pointer-events: none; }

/* The Jell-O egg wobbles each Resources section block, never the Safety section ([data-noegg], library.js NO_EGG_SECTIONS). */
#res-list { scroll-margin-top: 72px; } /* "See all" and a section link land the section title below the sticky header */
#res-list.jello .res-sec:not([data-noegg]) {
  --bg: #c9f27a; --surface: #e3ff9e; --surface-2: #b5e35c; --ink: #1f2a0c; --ink-soft: #46601a; --line: #9ccc45;
  background: var(--bg); color: var(--ink); border-radius: var(--radius); padding: 2px 12px 12px; margin: 8px -12px 0;
  animation: wobble .8s ease-in-out 3;
}
@keyframes wobble {
  0%, 100% { transform: skew(0) scale(1); } 25% { transform: skew(-4deg, 2deg) scale(1.02, .98); }
  50% { transform: skew(3deg, -2deg) scale(.98, 1.02); } 75% { transform: skew(-2deg, 1deg); }
}
.steam { position: fixed; z-index: 70; font-size: 2.2rem; pointer-events: none; animation: rise 2.2s ease-out forwards; }
@keyframes rise { to { transform: translateY(-260px) rotate(-12deg); opacity: 0; } }

.lost { text-align: center; padding-top: 30px; }
.lost .big { font-size: 4rem; font-weight: 900; color: var(--gold); line-height: 1; }

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

/* ---------- Orbit and halo circles ---------- */
.web { position: relative; overflow: hidden; touch-action: pan-y; }
.web-links { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.web-links line { stroke: var(--halo); stroke-opacity: .35; stroke-width: 1.5; }

.node {
  position: absolute; left: 0; top: 0; padding: 0; border-radius: 50%;
  display: grid; place-content: center; text-align: center; gap: 1px;
  color: var(--ink); cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
  will-change: transform;
  background: radial-gradient(circle at 50% 38%, color-mix(in srgb, var(--surface) 82%, var(--halo)), var(--surface) 72%);
  border: 1px solid color-mix(in srgb, var(--halo) 60%, transparent);
  box-shadow: 0 0 0 6px var(--halo-faint), 0 0 30px 2px var(--halo-soft), inset 0 0 18px var(--halo-faint);
  transition: box-shadow .2s;
}
.node.grabbed { cursor: grabbing; box-shadow: 0 0 0 10px var(--halo-faint), 0 0 46px 8px var(--halo-soft), inset 0 0 22px var(--halo-soft); }
.node:focus-visible { outline: 2px solid var(--halo); outline-offset: 6px; }
.node-label { font-weight: 800; font-size: clamp(12px, calc(var(--r) * .34), 22px); letter-spacing: -.01em; pointer-events: none; }
.node-sub { font-size: clamp(9px, calc(var(--r) * .2), 12px); color: var(--ink-soft); max-width: calc(var(--r) * 1.6); line-height: 1.15; pointer-events: none; }
.node.you { background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--halo-fill) 80%, #fff), var(--halo-fill) 75%); color: #fff; border-color: transparent;
  box-shadow: 0 0 0 7px var(--halo-soft), 0 0 0 16px var(--halo-faint), 0 0 50px 8px var(--halo-soft); }
.node.you .node-sub { color: rgb(255 255 255 / .85); }
.node.pulse::after {
  content: ""; position: absolute; inset: -1px; border-radius: 50%; border: 2px solid var(--halo);
  animation: ping 2.4s ease-out infinite; pointer-events: none;
}
@keyframes ping { from { transform: scale(1); opacity: .7; } to { transform: scale(1.6); opacity: 0; } }
.node.leaf { background: var(--surface); }
.leaf-init { font-size: clamp(10px, calc(var(--r) * .5), 13px); font-weight: 800; color: var(--halo-ink); pointer-events: none; }
.leaf-label { position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%); white-space: nowrap; font-size: .66rem; font-weight: 700; color: var(--ink-soft); pointer-events: none; }
.node.ghost { opacity: .22; box-shadow: none; border-style: dashed; background: none; }
.node.ghost:hover { opacity: .4; }
.node.bubble .node-label { font-size: clamp(11px, calc(var(--r) * .27), 16px); padding: 0 6px; }
.node.bubble.active { background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--halo-fill) 80%, #fff), var(--halo-fill) 75%); color: #fff;
  box-shadow: 0 0 0 7px var(--halo-soft), 0 0 46px 6px var(--halo-soft); }

body.home { padding-bottom: 0; }
body.home main { padding: 0; max-width: none; }
.orbit { height: calc(100dvh - 61px); }
.orbit-hint { margin: 4px 24px calc(18px + var(--safe-b)); text-align: center; font-size: .8rem; color: var(--ink-soft); }
.bubbles { height: 290px; margin: 0 -16px; }
/* The ball pit's floor: a soft shadow line the pile rests on. */
.bubbles.pit { margin: 0; }
.pit { border-bottom: 2px solid color-mix(in srgb, var(--halo) 35%, transparent); background: linear-gradient(to top, var(--halo-faint), transparent 30%); }
.pit .node { transform-origin: center; }
.bubble-hint { margin: 16px 0 0; }
/* While a search runs the pit folds away so the results sit right under the field. */
.pit-wrap.folded { height: 0; overflow: hidden; visibility: hidden; }

.zoom { position: fixed; z-index: 90; border-radius: 50%; background: var(--halo); transform-origin: center; pointer-events: none;
  transition: transform .33s cubic-bezier(.6, 0, .4, 1), opacity .3s; }
.zoom.fade { opacity: 0; }
.ghost-face { width: 64px; height: 64px; margin: 4px auto; border-radius: 50%; border: 1.5px dashed var(--ink-soft); opacity: .5; }

/* ---------- Orb navigation ---------- */
.orbnav { position: fixed; left: 50%; bottom: calc(18px + var(--safe-b)); width: 64px; height: 64px; margin-left: -32px; z-index: 30; transition: transform .3s cubic-bezier(.3, 1, .5, 1); }
body.orb-away .orbnav { transform: translateY(calc(110px + var(--safe-b))); }
body.home .orbnav, body.thread .orbnav { display: none; }
body.thread { padding-bottom: 0; }
.orb {
  position: relative; z-index: 2; width: 64px; height: 64px; border-radius: 50%; padding: 12px; cursor: pointer;
  background: var(--surface); border: 1px solid color-mix(in srgb, var(--halo) 60%, transparent);
  box-shadow: 0 0 0 6px var(--halo-faint), 0 0 28px var(--halo-soft); transition: transform .3s;
}
.orb svg { width: 100%; height: 100%; fill: var(--halo); stroke: var(--halo); }
body.fan-open .orb { transform: rotate(90deg) scale(.92); }
.fan a {
  --a: calc(180deg + var(--i) * 180deg / 7); /* eight items across the half circle */
  position: absolute; left: 50%; top: 50%; width: 62px; height: 62px; margin: -31px 0 0 -31px; border-radius: 50%;
  display: grid; place-content: center; text-decoration: none; font-size: .72rem; font-weight: 800; color: var(--ink);
  background: var(--surface); border: 1px solid color-mix(in srgb, var(--halo) 60%, transparent);
  box-shadow: 0 0 0 5px var(--halo-faint), 0 0 22px var(--halo-soft);
  opacity: 0; pointer-events: none; transform: scale(.3);
  transition: transform .32s cubic-bezier(.3, 1.4, .5, 1), opacity .2s; transition-delay: calc(var(--i) * 25ms);
}
/* 144px: eight 62px circles 64px apart (chord 2R sin(90/7 deg)); narrower than 360px it pulls in so the ends stay on screen. */
body.fan-open .fan a { opacity: 1; pointer-events: auto; transform: rotate(var(--a)) translateX(min(144px, calc(50vw - 36px))) rotate(calc(-1 * var(--a))); }
.fan a[aria-current="page"] { background: var(--halo-fill); color: #fff; }
body.fan-open main, body.fan-open #banner { filter: blur(4px); opacity: .5; transition: filter .2s, opacity .2s; }

/* Toggle switch: a checkbox wearing a halo. Still a real checkbox for screen readers. */
input[type="checkbox"].toggle {
  appearance: none; -webkit-appearance: none; flex: none; position: relative; cursor: pointer; margin: 0;
  width: 52px; height: 30px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line);
  transition: background .2s, box-shadow .2s;
}
input[type="checkbox"].toggle::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--ink-soft); transition: transform .25s cubic-bezier(.3, 1.4, .5, 1), background .2s;
}
input[type="checkbox"].toggle:checked { background: var(--halo); border-color: var(--halo); box-shadow: 0 0 16px var(--halo-soft); }
input[type="checkbox"].toggle:checked::after { transform: translateX(22px); background: #fff; }
input[type="checkbox"].toggle:focus-visible { outline: 2px solid var(--halo); outline-offset: 3px; }

.demo-note { text-align: center; margin-top: 20px; font-size: .85rem; color: var(--ink-soft); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
body.fan-open .fab { opacity: 0; pointer-events: none; }  /* the fan's outer circle lands on it at 360px */
.tag.age { background: none; border: 1px solid var(--ink-soft); color: var(--ink); }
/* r4: "Not ex-Mormon specific" on listings for people leaving any religion. Dashed so it reads as a note, not a topic. */
.tag.general { background: none; border: 1px dashed var(--ink-soft); color: var(--ink); }
.map-pop .tag.general { display: inline-block; margin-top: 4px; border-color: #5b6475; color: #10141c; }
.cal-btn { width: 44px; height: 44px; }
.cal-btn svg { stroke: var(--halo-ink); }
.safety-line { margin: 8px 0 0; }
.top-actions { display: flex; gap: 10px; }
.msg-btn { position: relative; color: var(--ink); }
.badge {
  position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px;
  background: var(--halo-fill); color: #fff; font-size: .7rem; font-weight: 800; display: grid; place-items: center;
  box-shadow: 0 0 0 2px var(--bg), 0 0 10px var(--halo-soft);
}
.badge[hidden] { display: none; }
.msg-btn[aria-current="page"] { border-color: var(--halo); box-shadow: 0 0 12px var(--halo-soft); }

/* ---------- Network and profiles ---------- */
.friends-web { height: 300px; }
.profile { text-align: center; padding-top: 4px; }
.profile-orb {
  width: 112px; height: 112px; margin: 6px auto 14px; border-radius: 50%; display: grid; place-items: center;
  font-size: 2.6rem; font-weight: 800; color: #fff;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--halo-fill) 80%, #fff), var(--halo-fill) 75%);
  box-shadow: 0 0 0 8px var(--halo-soft), 0 0 0 18px var(--halo-faint), 0 0 60px 10px var(--halo-soft);
}
.profile h1, .profile .profile-title { font-size: 2rem; }
.profile-bio { font-size: 1.05rem; margin: 14px 0; }
.profile-tags { justify-content: center; flex-wrap: wrap; overflow: visible; }
.profile-tags .chip { cursor: default; min-height: 36px; display: inline-flex; align-items: center; }
.profile-empty { text-align: center; padding-top: 40px; }
.reasons { border: 0; padding: 0; margin: 0; }
.reason { display: flex; gap: 12px; align-items: center; min-height: 44px; border-bottom: 1px solid var(--line); cursor: pointer; }
.reason input { width: 20px; height: 20px; accent-color: var(--halo-fill); flex: none; }
.safety-list { padding-left: 20px; margin: 10px 0 0; }
.safety-list li + li { margin-top: 8px; }

/* ---------- 18+ gate ---------- */
body.gated { overflow: hidden; }
body.gated .orbnav, body.gated main, body.gated .topbar { visibility: hidden; }
.gate { position: fixed; inset: 0; z-index: 95; background: var(--bg); overflow-y: auto; display: grid; place-items: center; padding: 24px 20px; }
.gate-inner { max-width: 420px; width: 100%; }
.gate-inner h1 { margin: 6px 0 10px; }
.gate-orb { font-size: 1.8rem; width: 96px; height: 96px; }

/* ---------- Sharing ---------- */
.share-btn { flex: none; }
.share-btn svg { stroke: var(--halo-ink); }
.share-what { margin: 2px 0 0; }
.share-people { display: flex; gap: 14px; overflow-x: auto; padding: 4px 2px 10px; scrollbar-width: none; }
.share-person { flex: none; display: flex; flex-direction: column; align-items: center; gap: 6px; background: none; border: 0; cursor: pointer; font-size: .78rem; font-weight: 600; min-width: 56px; }
.share-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-top: 10px; }
.share-grid .btn { width: 100%; }
.bubble.shared { padding: 6px; }
.link-card { display: block; padding: 8px 10px; border-radius: 12px; background: rgb(255 255 255 / .16); color: #fff; text-decoration: none; font-weight: 700; }
.link-host { display: block; font-size: .7rem; font-weight: 600; opacity: .85; }
.title-row { display: flex; align-items: flex-start; gap: 8px; }
.title-row h3 { flex: 1; padding-top: 10px; }
.title-row .share-btn { margin: -2px -6px 0 0; border-color: transparent; background: none; }
.res-row { display: flex; gap: 8px; align-items: flex-start; }
.res-row .res { flex: 1; min-width: 0; }
.res-row .news-thumb { display: block; width: 100%; aspect-ratio: 1.91; object-fit: cover; border-radius: 12px; margin-bottom: 8px; background: var(--surface-2, rgba(127,127,127,.12)); }
.res-row .share-btn { border-color: transparent; background: none; margin-right: -6px; }
.res-row.guide-card .host, .res.guide-card .host { color: var(--halo-ink); }

.thread-row .row-link { display: flex; gap: 12px; align-items: center; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.thread-row .row-link > div:not(.avatar) { min-width: 0; flex: 1; }
.star { flex: none; width: 44px; height: 44px; border: 0; background: none; cursor: pointer; display: grid; place-items: center; }
.star svg { width: 24px; height: 24px; fill: none; stroke: var(--ink-soft); stroke-width: 1.6; stroke-linejoin: round; transition: transform .2s; }
.star[aria-pressed="true"] svg { fill: var(--gold); stroke: var(--gold); transform: scale(1.1); }
/* A long name (40 characters max) wraps, and Star/Share drop under it instead of off the screen. */
.profile-name { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px; max-width: 100%; }
.profile-name h1, .profile-name .profile-title { margin-right: 4px; min-width: 0; max-width: 100%; overflow-wrap: break-word; text-align: center; }
.profile-name .share-btn { border-color: transparent; background: none; }
.node.bubble.fav { box-shadow: 0 0 0 4px var(--gold), 0 0 0 10px var(--halo-faint), 0 0 30px var(--halo-soft); }

.news-section { margin-bottom: 8px; }
.news-older { margin: 16px 0 8px; }
.news-older summary { cursor: pointer; list-style: none; min-height: 44px; display: flex; align-items: center; }
.news-older summary::-webkit-details-marker { display: none; }
.news-older summary .section-title { margin: 0; }
.news-older summary .section-title::after { content: " \25BE"; color: var(--ink-soft); }
.news-older[open] summary .section-title::after { content: " \25B4"; }
.news-source { margin: -4px 0 4px; }
.news-more { display: inline-block; margin: 10px 0 4px; font-weight: 700; font-size: .9rem; min-height: 44px; line-height: 44px; }
.title-row .star { margin: -2px -10px 0 0; }
.res-row .star { margin-right: -12px; }
/* Phone width with two or more actions (star, share, "..."): they sat in a full-height column and squeezed the
   text to ~190px. Here they drop to one row under the card instead, right-aligned. */
@media (max-width: 480px) {
  .res-row:has(> .res + * + *) { flex-wrap: wrap; row-gap: 0; }
  .res-row:has(> .res + * + *) > .res { flex-basis: 100%; }
  .res-row:has(> .res + * + *) > .res + * { margin-left: auto; }
  .res-row:has(> .res + * + *) .star { margin-right: 0; }
}

/* ---------- Ex-versary ---------- */
.exv-today { text-align: center; padding: 10px 0 2px; }
.exv-today .stat { font-size: 1.7rem; color: var(--gold); }
.node.you.exv { background: radial-gradient(circle at 50% 35%, #f1be4b, #cd9735 75%); color: #1f1b16;
  box-shadow: 0 0 0 7px rgb(221 169 65 / .35), 0 0 0 16px rgb(221 169 65 / .12), 0 0 60px 10px rgb(221 169 65 / .35); }
.node.you.exv .node-sub { color: #1f1b16; }
.confetti { position: fixed; inset: 0; z-index: 99; pointer-events: none; overflow: hidden; }
.confetti i { position: absolute; top: -12px; width: 8px; height: 14px; border-radius: 2px; animation: confetti-fall linear forwards; }
@keyframes confetti-fall {
  to { transform: translate(var(--drift), 105vh) rotate(var(--spin)); opacity: .9; }
}

/* ---------- Favorite notifications ---------- */
.node-badge {
  position: absolute; top: 2px; right: 2px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px;
  background: var(--gold); color: #1f1b16; font-size: .7rem; font-weight: 800; display: grid; place-items: center;
  box-shadow: 0 0 0 2px var(--bg), 0 0 12px rgb(221 169 65 / .5); pointer-events: none;
}
.node.leaf .node-badge { top: -4px; right: -4px; min-width: 18px; height: 18px; font-size: .62rem; }
.update-note {
  margin: 8px 0 0; padding: 8px 10px; border-radius: 10px; font-size: .88rem;
  background: color-mix(in srgb, var(--gold) 14%, transparent); border-left: 3px solid var(--gold);
}

/* ---------- Hub colors ----------
   Six hubs, six hues, spread around the wheel (plus the paper-colored Journal). A hub's satellites, its links,
   and its own page all wear its color. --halo-fill is the darker shade that
   white text sits on (all 5.3:1 or better); --halo-ink is small colored text. */
.c-gather    { --halo: #5aa9ff; --halo-fill: #2563d6; --halo-soft: rgb(90 169 255 / .28); --halo-faint: rgb(90 169 255 / .1); }
.c-resources { --halo: #4cd38a; --halo-fill: #1d7a48; --halo-soft: rgb(76 211 138 / .26); --halo-faint: rgb(76 211 138 / .09); }
.c-network   { --halo: #9b7bff; --halo-fill: #6046d0; --halo-soft: rgb(155 123 255 / .28); --halo-faint: rgb(155 123 255 / .1); }
.c-news      { --halo: #ff6fb5; --halo-fill: #b8306f; --halo-soft: rgb(255 111 181 / .26); --halo-faint: rgb(255 111 181 / .09); }
.c-vent      { --halo: #ff6b55; --halo-fill: #c23a28; --halo-soft: rgb(255 107 85 / .25); --halo-faint: rgb(255 107 85 / .08); }
/* Discuss: lime, the one open gap on the wheel (gold 40, green 148). Raw lime is 1.6:1 on white, so light mode
   rings it a shade darker (2.5:1, like the blue and pink rings); the fill under white text is 6.2:1, as ink 6.2:1 on white. */
.c-discuss   { --halo: #7cb518; --halo-fill: #4b6b12; --halo-soft: rgb(124 181 24 / .26); --halo-faint: rgb(124 181 24 / .1); }
:root[data-theme="dark"] .c-discuss { --halo: #a8e04b; --halo-soft: rgb(168 224 75 / .24); --halo-faint: rgb(168 224 75 / .08); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .c-discuss { --halo: #a8e04b; --halo-soft: rgb(168 224 75 / .24); --halo-faint: rgb(168 224 75 / .08); } }
.c-gather, .c-resources, .c-network, .c-news, .c-vent, .c-discuss { --halo-ink: var(--halo-fill); }
:root[data-theme="dark"] :is(.c-gather, .c-resources, .c-network, .c-news, .c-vent, .c-discuss) { --halo-ink: var(--halo); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) :is(.c-gather, .c-resources, .c-network, .c-news, .c-vent, .c-discuss) { --halo-ink: var(--halo); }
}
.web-links line[class] { stroke: var(--halo); }

/* ---------- News tabs and hearts ---------- */
.heart { flex: none; width: 44px; height: 44px; border: 0; background: none; cursor: pointer; display: grid; place-items: center; margin-right: -8px; }
.heart svg { width: 22px; height: 22px; fill: none; stroke: var(--ink-soft); stroke-width: 1.7; stroke-linejoin: round; transition: transform .2s; }
.heart[aria-pressed="true"] svg { fill: var(--halo); stroke: var(--halo); transform: scale(1.12); }
/* News: raw pink is 2.6:1 on a white card; the hub ink (fill in light, glow in dark) clears 3:1. */
.c-news .heart[aria-pressed="true"] svg { fill: var(--halo-ink); stroke: var(--halo-ink); }
.seg-count { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; margin-left: 4px; border-radius: 999px; background: var(--halo-fill); color: #fff; font-size: .68rem; }
.c-news .segments a[aria-current="page"] { box-shadow: 0 0 0 1px var(--halo), var(--shadow); }
.thread-row.request .btn { min-height: 40px; padding: 0 14px; flex: none; }
.thread-row.request .btn.ghost { width: 44px; padding: 0; font-size: 1.4rem; }

/* ---------- Settings, You page, profile builder ---------- */
.top-actions { gap: 8px; }
.sheet .card { padding: 16px 2px; }
.segments.wording { grid-template-columns: 1fr 1fr; margin: 0; }
.segments.wording button { border: 0; background: none; cursor: pointer; padding: 12px 0; border-radius: 999px; font-weight: 700; color: var(--ink-soft); }
.segments.wording button[aria-checked="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
#me-btn[aria-current="page"] { border-color: var(--halo); box-shadow: 0 0 12px var(--halo-soft); }
.profile-form { text-align: left; }
.profile-form small { display: block; margin-top: 4px; font-size: .78rem; }
.tag-box { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.tag-box .chip { min-height: 36px; }
.chip.on { background: var(--halo-fill); border-color: var(--halo-fill); color: #fff; }
.tag-input { flex: 1; min-width: 120px; border: 0; background: none; padding: 8px; outline: none; }
.tag-ideas { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.tag-ideas .chip { min-height: 34px; font-size: .82rem; color: var(--ink-soft); }
.eggs-card summary { cursor: pointer; list-style: none; min-height: 44px; display: flex; align-items: center; }
.eggs-card summary::-webkit-details-marker { display: none; }
.eggs-card summary h3::after { content: " \25BE"; color: var(--ink-soft); }
.eggs-card[open] summary h3::after { content: " \25B4"; }

/* ---------- Journal (paper: sepia in light, cream in dark) ---------- */
.c-journal { --halo: #b07a3a; --halo-fill: #7d5323; --halo-soft: rgb(176 122 58 / .26); --halo-faint: rgb(176 122 58 / .09); --halo-ink: #7d5323; }
:root[data-theme="dark"] .c-journal { --halo: #f9ebd0; --halo-soft: rgb(249 235 208 / .22); --halo-faint: rgb(249 235 208 / .08); --halo-ink: #f9ebd0; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .c-journal { --halo: #f9ebd0; --halo-soft: rgb(249 235 208 / .22); --halo-faint: rgb(249 235 208 / .08); --halo-ink: #f9ebd0; } }
.private-note { font-size: .85rem; padding: 10px 12px; border-radius: 12px; background: var(--surface-2); color: var(--ink-soft); margin: 0 0 12px; }
/* ---------- You page (10/12): each item, its value, and its Public / On profile boxes ---------- */
.me-card { display: flex; align-items: center; gap: 12px; }
.me-card .profile-orb { flex: none; margin: 0; }
.me-card-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.card .me-card-text p { margin: 2px 0 0; }
.inline-link { background: none; border: 0; padding: 0; font: inherit; color: var(--halo-ink); text-decoration: underline; cursor: pointer; }
.me-hint { margin: -2px 0 4px; }
.me-rows { padding-top: 0; padding-bottom: 0; }
.me-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.me-rows .me-row:last-child { border-bottom: 0; }
.me-row-flat { border-bottom: 0; border-top: 1px solid var(--line); margin-top: 12px; }
.me-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.me-row-label { font-size: .8rem; font-weight: 700; color: var(--ink-soft); }
.me-row-value { overflow-wrap: anywhere; }
/* The value is the edit button (10/12): it looks like the value, not like a button. */
.me-value { align-self: flex-start; max-width: 100%; min-height: 28px; margin: 0; padding: 2px 0; background: none; border: 0; border-radius: 4px; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.me-value:hover [data-verbatim] { text-decoration: underline dotted; text-underline-offset: 3px; }
.me-add { color: var(--halo-ink); font-weight: 600; text-decoration: underline; }
.me-inline { display: flex; flex-direction: column; gap: 8px; margin: 2px 0 4px; }
.me-inline .field { margin: 0; }
.me-inline textarea { min-height: 88px; }
.me-row-open { align-items: flex-start; }
.me-boxes { display: flex; flex-direction: column; align-items: flex-end; flex: none; }
.pub-box { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; font-size: .85rem; font-weight: 600; cursor: pointer; white-space: nowrap; }
.pub-box input { width: 20px; height: 20px; margin: 0; accent-color: var(--halo-fill); cursor: inherit; }
.pub-box.off { opacity: .55; cursor: default; }
.wall-post p { margin: 0; }
.card .wall-text { margin-top: 4px; white-space: pre-wrap; overflow-wrap: anywhere; }
.wall-acts { justify-content: flex-end; }
.wall-list { margin-top: 8px; }
/* You = your profile, Edit profile = the controls (10/12 r3) */
.me-top { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.me-viewing { display: flex; align-items: center; gap: 10px; }
.me-viewing .segments { flex: 1; margin: 0; max-width: 320px; }
.me-viewing .segments button { padding: 8px 0; min-height: 40px; }
.me-top #as-note { margin: 0; }
.me-profile { margin-top: 6px; }
.me-profile .prompt-card { text-align: left; }
.me-edit-head { display: flex; align-items: flex-start; gap: 12px; }
.me-edit-head > div { flex: 1; min-width: 0; }
.me-card .row { flex-wrap: wrap; gap: 8px; }
h2.section-title[tabindex="-1"]:focus, .me-card[tabindex="-1"]:focus { outline: none; }
.prompt-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: .95rem; }
.mood-chips { flex-wrap: wrap; overflow: visible; }
.mood-chips .chip[aria-pressed="true"] { background: var(--halo-fill); border-color: var(--halo-fill); color: #fff; }
.journal-text { min-height: 160px; font-family: Georgia, serif; font-size: 1.02rem; line-height: 1.55; scroll-margin-top: 84px; } /* focus: clear of the sticky top bar */
.journal-body { white-space: pre-wrap; font-family: Georgia, serif; line-height: 1.55; }
.journal-entry .chips { margin-top: 6px; }
/* A saved entry's moods are small outlined tags (as on the phone), not 44px buttons with the label stuck to the top. */
.journal-entry .chip { min-height: 0; padding: 4px 10px; font-size: .8rem; font-weight: 500; line-height: 1.3; display: inline-flex; align-items: center; cursor: default; background: none; color: var(--ink-soft); }
.c-journal { position: relative; }
.c-journal [hidden] { display: none; } /* .btn's display beat the hidden attribute: Cancel showed on new entries */
/* Save pop (views/journal.js popSave): the Save button's bubble double, its ring and spray. Glass like the ball pit. */
.jpop { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
/* The Save button shrinking into the bubble: a solid gold layer over the glass (a radial fill, faint in the
   middle and stronger at the rim, like the ball pit), a full gold rim, the label, and a highlight arc. */
.jpop-bubble { position: absolute; display: grid; place-items: center; overflow: hidden; box-sizing: border-box; border: 1.5px solid var(--gold); border-radius: 999px;
  color: #1f1b16; font-weight: 700; white-space: nowrap; }
.jpop-bubble > i { position: absolute; inset: 0; }
.jpop-solid { background: var(--gold); border-radius: 999px; } /* the button's own fill: fades to the glass over the last 60ms, once round */
.jpop-glass { background: radial-gradient(closest-side, color-mix(in srgb, var(--gold) 8%, transparent), color-mix(in srgb, var(--gold) 12%, transparent) 79%, color-mix(in srgb, var(--gold) 34%, transparent)); }
.jpop-bubble > span { position: relative; }
/* The specular: a soft blob at the upper left and a small catch-light (a stroke arc read as a spinner). */
.jpop-bubble > .jpop-shine { opacity: 0; }
.jpop-shine::before, .jpop-shine::after { content: ''; position: absolute; border-radius: 50%; }
.jpop-shine::before { left: 14%; top: 17%; width: 32%; height: 18%; transform: rotate(-35deg); background: radial-gradient(closest-side, rgb(255 255 255 / .55), rgb(255 255 255 / 0)); }
.jpop-shine::after { left: calc(62% - 1.5px); top: calc(30% - 1.5px); width: 3px; height: 3px; background: rgb(255 255 255 / .35); }
/* The bubble's glow: its own fixed circle that fades in once the bubble is round (a shadow on the
   resizing pill drew a square-cornered bar on the phone). */
.jpop-glow { position: absolute; border-radius: 50%; box-shadow: 0 0 16px color-mix(in srgb, var(--gold) 60%, transparent); opacity: 0; }
.jpop-ring { position: absolute; box-sizing: border-box; border-radius: 50%; border: 1.5px solid var(--gold); background: none; opacity: 0; }
.jpop-drop { position: absolute; border-radius: 50%; background: var(--gold); opacity: 0; }
.jpop-ghost { position: absolute; pointer-events: none; white-space: pre-wrap; overflow: hidden; overflow-wrap: anywhere; z-index: 3; }
.journal-entry { position: relative; }
/* The flying card's shell (views/journal.js popSave): the capsule's glass behind the words, opening into
   the row; at landing its rim glows identity blue once and it melts into the flat row. body still has the
   page's blue (.c-journal repaints --halo as sepia/cream for its own chips). */
body { --jpop-blue: var(--halo); }
.journal-entry.jpop-flying { isolation: isolate; }
.jpop-shell { position: absolute; top: 0; left: 0; z-index: -1; box-sizing: border-box; pointer-events: none;
  background: var(--surface); }
/* The flying card's rim: the card's own line, drawn OVER its content (a border under it let the moods
   cross the rim as they came in), glowing blue once at the landing. */
.jpop-rim { position: absolute; top: 0; left: 0; z-index: 2; box-sizing: border-box; pointer-events: none; border: 1px solid var(--line); }
.journal-entry.jpop-flying { border-bottom-color: transparent; }
/* What falls out of the burst: the entry, a plain disc in the card surface with the card line and one gold catch-light. */
.jpop-disc { position: absolute; box-sizing: border-box; border-radius: 50%; border: 1px solid var(--line); opacity: 0; background: var(--surface); }
.jpop-disc > .jpop-shine { display: none; }
.jpop-disc::after { content: ''; position: absolute; left: 27%; top: 22%; width: 5px; height: 5px; border-radius: 50%; background: var(--gold); }
/* While it falls the shell is a plain disc (no glass: stretched, the radial read as a muddy vignette) and
   carries a one-line preview of the words, clipped by its shape. */
.jpop-shell { overflow: hidden; }
.jpop-line { position: absolute; left: 0; display: block; box-sizing: border-box; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis; font-family: Georgia, serif; font-style: normal; color: var(--ink); opacity: 0; }
/* The Save button growing back: solid gold, a disc stretching into the pill (never a fade). */
.jpop-return { position: absolute; width: 0; height: 0; display: grid; place-items: center; overflow: hidden; background: var(--gold);
  color: #1f1b16; font-weight: 700; white-space: nowrap; }
/* The count crossfading as the card lands. Tabular digits, so "151" right-aligned on "152" puts every
   digit on the same pixels (proportional ones drew a doubled "1"). */
.c-journal .section-title { position: relative; font-variant-numeric: tabular-nums; }
/* Wide enough for "Tap again", so arming Delete doesn't push Edit aside. */
.journal-entry [data-delete] { min-width: 7.5em; }
.jpop-count { position: relative; display: inline-block; }
.jpop-was { position: absolute; right: 0; top: 0; white-space: nowrap; }
/* The older entries while a new one lands (popSave): held under the disc, then the shell, by one variable. */
.journal-entry.jpop-older { translate: 0 var(--jpop-off, 0px); }

/* ---------- More menu, discussion, feed, badges, prompts ---------- */
.more-btn { position: relative; border-color: transparent; background: none; flex: none; }
.more-btn svg { fill: var(--ink-soft); stroke: none; }
.more-count { position: absolute; top: 2px; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--surface-2); color: var(--ink); font-size: .6rem; font-weight: 800; display: grid; place-items: center; }
.back-btn { width: 44px; height: 44px; border: 0; background: none; font-size: 1.4rem; cursor: pointer; color: var(--ink); margin-left: -10px; }
.discuss-title { font-size: 1.6rem; }
.comment p { margin: 6px 0 0; white-space: pre-wrap; }
.comment .row { gap: 8px; }
.discuss-form { margin-top: 16px; }
.feed-item p { margin: 0; }
.feed-item a { text-decoration: none; color: inherit; }
.feed-item .small { margin-top: 4px; }
.profile-sub { text-align: center; margin: 16px 0 6px; }
.badge-row { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.badge-chip { padding: 6px 12px; border-radius: 999px; font-size: .8rem; font-weight: 700; border: 1px solid var(--gold); color: var(--ink); background: color-mix(in srgb, var(--gold) 14%, transparent); }
.prompt-card { text-align: left; margin-top: 12px; padding: 12px 14px; border-radius: var(--radius); background: var(--surface-2); }
.prompt-card p { margin: 0; }
.prompt-card .small { margin-bottom: 4px; }
.prompt-edit { margin-top: 10px; }
.prompt-edit textarea { min-height: 70px; margin-top: 6px; }
.segments.two { grid-template-columns: 1fr 1fr; }
.segments.two button { border: 0; background: none; cursor: pointer; padding: 12px 0; border-radius: 999px; font-weight: 700; color: var(--ink-soft); }
.segments.two button[aria-checked="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.segments.three { grid-template-columns: repeat(3, 1fr); margin: 0; }
.segments.three button { border: 0; background: none; cursor: pointer; padding: 12px 0; border-radius: 999px; font-weight: 700; color: var(--ink-soft); }
.segments.three button[aria-checked="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.match { color: var(--halo-ink); margin-left: 4px; } /* with .c-network: the network hub ink, like the phone */
.exv-row .btn { flex: none; }
.small-card { margin: 14px 0 0; padding: 14px; border-radius: var(--radius); background: color-mix(in srgb, var(--gold) 14%, transparent); }
.small-card .btn { margin-top: 10px; }
.fun-card { display: block; text-decoration: none; color: inherit; border-left: 3px solid var(--gold); padding-left: 12px; }

/* ---------- Filters and content warnings ---------- */
[data-filterable], [data-cw-check], [data-cw] { position: relative; }
.filtered > :not(.filtered-note) { display: none; }
.filtered-note, .cw-cover {
  display: block; width: 100%; min-height: 44px; margin: 4px 0; padding: 10px 12px; border-radius: 12px; cursor: pointer; text-align: left;
  border: 1px dashed var(--line); background: var(--surface-2); color: var(--ink-soft); font-size: .88rem;
}
.cw-hidden > :not(.cw-cover) { filter: blur(9px); pointer-events: none; user-select: none; }
.cw-cover { border-style: solid; border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); color: var(--ink); }

/* ---------- Groups and the map ---------- */
.group-filters { display: grid; gap: 10px; margin-bottom: 8px; }
/* 1.5: Gather's one search box, the Filters button row and panel, the time slider, Welcome to attend */
.gather-search { position: relative; }
.gather-search .input { width: 100%; padding-right: 48px; }
.gather-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; } /* ours has the x */
.gather-search-x { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); border: 0; background: transparent; font-size: 1.4rem; color: var(--ink-soft); }
.gather-search-x[hidden] { display: none; }
.filter-bar { gap: 8px; align-items: center; flex-wrap: wrap; }
.filter-bar .filter-summary { flex: 1; min-width: 0; }
.filter-btn.is-on { border-color: var(--halo); box-shadow: 0 0 10px var(--halo-soft); }
.count-pill { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; margin-left: 4px; border-radius: 999px;
  background: var(--halo-fill); color: #fff; font-size: .72rem; font-weight: 800; }
.filter-panel { display: grid; gap: 8px; }
.filter-panel[hidden] { display: none; }
.filter-panel .section-title { margin: 6px 0 0; font-size: .95rem; }
.filter-panel .input { width: 100%; }
/* Where (where.js): the place box + typeahead list, radius chips. The list floats over what's below it. */
.where { display: grid; gap: 8px; }
.field-label { font-weight: 600; font-size: .9rem; }
.place-combo { position: relative; }
.place-list { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 32; margin: 0; padding: 4px 0; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); max-height: 50vh; overflow-y: auto; }
.place-list[hidden] { display: none; }
.place-list li { min-height: 44px; display: flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer; }
.place-list li:hover, .place-list li[aria-selected="true"] { background: var(--surface-2); }
.place-list li[aria-selected="true"] { box-shadow: inset 3px 0 0 var(--halo); }
/* The Filters panel's "Show N" bar: pinned to the bottom of the screen while the panel scrolls under it,
   full width, over the orb (z 30) and the + button, lifted above an on-screen keyboard (--kb, where.js). */
.filter-foot { position: sticky; bottom: var(--kb, 0px); z-index: 31; display: flex; gap: 10px; margin: 8px -18px -18px;
  padding: 12px 18px calc(22px + var(--safe-b)); background: var(--bg); border-top: 1px solid var(--line); box-shadow: 0 -10px 20px -14px rgb(0 0 0 / .35); }
.filter-foot .btn { flex: 1; }
.filter-foot .btn.primary { flex: 2; }
/* The pager's track is its own stacking context, so the bar can't paint over the orb or the + button: while a
   Filters panel is open on the showing pane they step aside (the bar is the way out; they're back on close). */
body:has(.pager-pane.on .filter-panel:not([hidden])) .orbnav { transform: translateY(calc(110px + var(--safe-b))); }
body:has(.pager-pane.on .filter-panel:not([hidden])) .fab { opacity: 0; pointer-events: none; }
.tag.aud { color: var(--halo-ink); background: transparent; border: 1px solid var(--halo); }
.range-label { font-weight: 700; margin-bottom: 4px; }
.range-track { position: relative; height: 44px; }
.range-track::before { content: ''; position: absolute; left: 14px; right: 14px; top: 19px; height: 6px; border-radius: 999px; background: var(--surface-2); }
.range-fill { position: absolute; top: 19px; height: 6px; border-radius: 999px; background: var(--halo); }
.range-track input { position: absolute; inset: 0; width: 100%; height: 44px; margin: 0; background: none; pointer-events: none;
  -webkit-appearance: none; appearance: none; z-index: 1; }
.range-track input + input { z-index: 2; }
.range-track input::-webkit-slider-runnable-track { background: none; border: 0; }
.range-track input::-moz-range-track { background: none; border: 0; }
.range-track input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; pointer-events: auto; width: 28px; height: 28px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--halo); cursor: grab; }
.range-track input::-moz-range-thumb { pointer-events: auto; width: 22px; height: 22px; border-radius: 50%; background: var(--surface); border: 3px solid var(--halo); cursor: grab; }
.range-track input:focus-visible { outline: none; }
.range-track input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--halo-soft); }
.range-track input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--halo-soft); }
.filter-row { gap: 8px; }
.filter-row .input { flex: 1; min-width: 0; padding: 8px 10px; }
.filter-row .btn { flex: none; }
.mission-langs { align-items: center; }
.chip.lang { border-color: var(--halo); color: var(--halo-ink); }
.chips.wrap { flex-wrap: wrap; overflow: visible; }
a.chip { display: inline-flex; align-items: center; text-decoration: none; color: inherit; }
.chips .chip[aria-pressed="true"].lang, .chips.wrap .chip[aria-pressed="true"] { background: var(--halo-fill); border-color: var(--halo-fill); color: #fff; }
.group-card .meta { margin-top: 3px; }
.group-tags { flex-wrap: wrap; overflow: visible; margin-top: 8px; gap: 6px; align-items: center; }
.group-tags .chip { min-height: 30px; padding: 0 10px; font-size: .8rem; cursor: default; }
.group-actions { margin-top: 10px; gap: 6px; flex-wrap: wrap; }
.group-card.is-evangelical { border-left: 2px dashed var(--halo); padding-left: 10px; }
/* Gather map (r4): MapLibre + Protomaps. Colors match web/js/mapdots.js DOT_COLORS (events lime, groups blue,
   clubs a blue ring, the Evangelical Corner gold, clusters lime/blue/cream by what they hold). */
.map-modes { gap: 6px; align-items: center; margin-bottom: 6px; flex-wrap: wrap; }
.map-modes .chip[aria-checked="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
/* 360px: Events | Groups | Both and "Near me" stay on one row (they used to wrap "Near me" onto its own). */
@media (max-width: 420px) { .map-modes .chip, .map-modes #me-loc { padding: 0 11px; } }
.map-evfilters { margin: 2px 0 6px; }
.map-wrap { position: relative; }
.group-map { height: 52vh; min-height: 300px; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); margin: 6px 0 8px; background: var(--bg); z-index: 0; }
.map-empty { position: absolute; left: 12px; right: 12px; top: 18px; margin: 0; padding: 10px 14px; border-radius: 12px; background: var(--surface); color: var(--ink); border: 1px solid var(--line); box-shadow: var(--shadow); text-align: center; pointer-events: none; }
.group-map .maplibregl-ctrl-attrib { font-size: 12px; }
:root[data-theme="dark"] .group-map .maplibregl-ctrl-attrib { background: rgb(9 13 20 / .8); color: #c3cad6; }
:root[data-theme="dark"] .group-map .maplibregl-ctrl-attrib a { color: #c3cad6; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .group-map .maplibregl-ctrl-attrib { background: rgb(9 13 20 / .8); color: #c3cad6; }
  :root:not([data-theme="light"]) .group-map .maplibregl-ctrl-attrib a { color: #c3cad6; } }
.map-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 2px 0 6px; color: var(--ink-soft); }
.map-legend .lg { display: inline-flex; align-items: center; gap: 6px; }
.lg-dot { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px rgb(0 0 0 / .25); flex: none; font-style: normal; }
.lg-event { background: #a8e04b; }
.lg-group { background: #5aa9ff; }
.lg-club { background: #fff; border: 3px solid #5aa9ff; }
.lg-evangelical { background: #dda941; }
.lg-cluster { width: 22px; height: 22px; background: #f9ebd0; color: #0d0d0c; font-size: 11px; font-weight: 700; }
.map-list summary { cursor: pointer; font-weight: 700; padding: 8px 0; }
.map-list ul { list-style: none; margin: 0; padding: 0; }
.map-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.map-row a { font-weight: 700; color: inherit; }
.map-row .small { flex: 1; min-width: 120px; }
.group-map .maplibregl-popup-content { border-radius: 12px; padding: 10px 12px; }
.map-pop { font: 14px/1.4 system-ui, sans-serif; color: #10141c; min-width: 180px; }
.map-pop .muted { color: #5b6475; }
.map-pop-actions { display: flex; gap: 10px; margin-top: 8px; align-items: center; }
.map-pop-actions a, .map-pop-actions button { font-weight: 700; color: #2563d6; background: none; border: 0; padding: 6px 0; cursor: pointer; font-size: 14px; }

/* ---------- Accounts: sign in, sign up, pending ---------- */
body.auth .top-actions, body.auth .orbnav { display: none; }
.auth { max-width: 420px; margin: 0 auto; padding-top: 10px; }
.auth-head { text-align: center; margin-bottom: 16px; }
.auth-head h1 { margin: 10px 0 4px; }
.auth-mark { height: 64px; width: auto; margin: 0 auto; }
.auth-mark.mark-dark { display: none; }
:root[data-theme="dark"] .auth-mark.mark-light { display: none; }
:root[data-theme="dark"] .auth-mark.mark-dark { display: block; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .auth-mark.mark-light { display: none; } :root:not([data-theme="light"]) .auth-mark.mark-dark { display: block; } }
.auth-alt { text-align: center; margin-top: 16px; }
.auth-note { margin: 0 0 14px; text-align: center; }
/* Idle sign-out (js/idle.js): a real modal <dialog>, top layer, background inert. */
.idle-dialog { width: min(380px, calc(100vw - 32px)); max-width: none; box-sizing: border-box; padding: 22px 20px 16px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--surface); color: var(--ink); box-shadow: var(--shadow); text-align: center; }
.idle-dialog::backdrop { background: rgb(9 13 20 / .55); }
.idle-dialog h2 { margin: 0 0 8px; font-size: 1.25rem; }
.idle-dialog p { margin: 0 0 12px; line-height: 1.45; }
.idle-count { font-size: 2.4rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--halo-ink); margin: 4px 0 14px !important; }
.idle-foot { margin: 12px 0 0 !important; }
.consent { display: flex; gap: 10px; align-items: flex-start; font-size: .88rem; line-height: 1.45; cursor: pointer; }
.consent input { width: 22px; height: 22px; flex: none; margin-top: 2px; accent-color: var(--halo-fill); }
.field small { display: block; margin-top: 4px; font-size: .78rem; }
.at-wrap { position: relative; display: block; }
.at-wrap .at { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--ink-soft); pointer-events: none; }
.at-wrap .input { padding-left: 28px; }
.code-input { font-size: 1.6rem; letter-spacing: .3em; text-align: center; font-variant-numeric: tabular-nums; }
.handle { font-size: .9rem; }
.gate-card { border-left: 3px solid var(--halo); padding-left: 14px; }
.gate-card > .btn { margin-top: 10px; }
/* Password with a Show/Hide button inside the box */
.pw-wrap { position: relative; display: block; }
.pw-wrap .input { padding-right: 72px; width: 100%; }
.field .pw-wrap { margin: 0; font-size: 1rem; font-weight: 400; color: inherit; }
.pw-show { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); min-height: 40px; min-width: 60px; border: 0; border-radius: 999px;
  background: transparent; color: var(--halo-ink); font: inherit; font-weight: 700; font-size: .85rem; cursor: pointer; }
.pw-show:focus-visible { outline: 2px solid var(--halo); }

/* ---------- Photos ---------- */
.avatar.photo { object-fit: cover; padding: 0; }
.profile-orb.has-photo { padding: 0; overflow: hidden; }
.profile-orb img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.small-orb { width: 72px; height: 72px; margin: 0; font-size: 1.6rem; }
.photo-edit { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.msg-photo { position: relative; display: block; margin: 2px 0 6px; }
.msg-photo img { display: block; max-width: 100%; max-height: 320px; border-radius: 12px; }
/* Photos from non-friends: blurred until tapped. Report and Block are in the message's "...". */
.msg-photo.blurred img { filter: blur(24px); }
.photo-gate { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: rgb(0 0 0 / .35); border-radius: 12px; color: #fff; font-size: .8rem; text-align: center; padding: 8px; }
.photo-gate button { min-height: 32px; padding: 0 12px; border-radius: 999px; border: 0; cursor: pointer; background: rgb(0 0 0 / .7); color: #fff; font-weight: 700; }
.dm-banner { margin-bottom: 12px; }
.composer[hidden], .attach[hidden], .more-btn[hidden] { display: none; }
.chat-head a.btn { width: auto; font-size: 1rem; margin-left: 0; padding: 0 12px; }
.reconnecting { text-align: center; }
.attach { width: 44px; padding: 0; font-size: 1.4rem; flex: none; cursor: pointer; }
.attach-label { cursor: pointer; }

/* ---------- Announcement + admin dot ---------- */
.announcement { display: flex; align-items: flex-start; gap: 6px; margin: 12px 16px 0; padding: 10px 4px 10px 14px; border-radius: var(--radius); border: 1px solid var(--halo); background: color-mix(in srgb, var(--halo) 12%, transparent); font-weight: 600; font-size: .92rem; }
#settings-btn { position: relative; }
#settings-btn.has-dot::after { content: ""; position: absolute; top: 4px; right: 4px; width: 10px; height: 10px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 0 2px var(--bg); }
/* Someone else's message sits in a row with its "..." (Report, Block). */
.msg-row { display: flex; align-items: center; gap: 2px; align-self: flex-start; max-width: 88%; }
.msg-row .bubble { max-width: none; min-width: 0; }
.msg-more { width: 36px; height: 36px; min-height: 36px; padding: 0; }
.msg-more svg { width: 18px; height: 18px; }

/* ---------- Search wheel (js/searchwheel.js, twin of the phone's SearchWheel) ---------- */
.wheel-field { display: flex; align-items: center; gap: 8px; text-align: left; cursor: pointer; color: var(--ink); font: inherit; }
.wheel-field:disabled { cursor: not-allowed; opacity: .6; }
.field .wheel-field span, .wheel-field span { display: inline; margin: 0; font-size: inherit; font-weight: 400; color: inherit; }
.field .wheel-field .wheel-field-text, .wheel-field-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.field .wheel-field .wheel-field-text.muted, .wheel-field-text.muted { color: var(--ink-soft); }
.field .wheel-field .wheel-caret, .wheel-caret { flex: none; color: var(--ink-soft); font-size: .8rem; }
.wheel-chips { margin-top: 8px; }
.wheel-chips .chip { display: inline-flex; align-items: center; gap: 6px; }
.wheel-search { margin: 4px 0 6px; }
.wheel-count { margin: 0 0 4px; }
.wheel { position: relative; height: calc(var(--row) * var(--shown)); }
.wheel-band { position: absolute; left: 0; right: 0; top: calc(var(--row) * 2); height: var(--row); border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--halo); pointer-events: none; }
.wheel-list { position: relative; list-style: none; margin: 0; padding: calc(var(--row) * 2) 0; height: 100%; overflow-y: auto;
  scroll-snap-type: y mandatory; scrollbar-width: none; overscroll-behavior: contain; border-radius: 10px; }
.wheel-list::-webkit-scrollbar { display: none; }
.wheel-list:focus-visible { outline: 2px solid var(--halo); outline-offset: 2px; }
.wheel-list li { height: var(--row); display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 0 8px;
  scroll-snap-align: center; cursor: pointer; transform-origin: center; }
.wheel-name { font-size: 1.05rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.wheel-sub { font-size: .78rem; color: var(--ink-soft); line-height: 1.1; }
.wheel-list li[aria-selected="true"] .wheel-name { font-weight: 800; }
.wheel-empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; text-align: center; margin: 0; }
.wheel-empty[hidden] { display: none; }
.wheel-actions { margin-top: 14px; }
.wheel-actions .btn { flex: 1; }
.wheel-actions .btn.primary { flex: 2; }
@media (prefers-reduced-motion: reduce) { .wheel-list { scroll-behavior: auto; } }
.field .wheel-chips span { display: inline; margin: 0; font-size: inherit; font-weight: inherit; color: inherit; }

/* ---------- Balloon toggle (js/balloon.js; phone: BalloonToggle.tsx) ----------
   One balloon in the hub color slides between the options; drag it or tap. --x is the balloon's
   position in option widths, --sx/--sy its squash, --tilt the knot's lean. The grey options sit
   UNDER the balloon; .bt-clip is the balloon's box with a white copy of the labels lined up inside,
   so letters are white exactly where the balloon covers them (balloon.js paint() sizes it). */
.balloon-toggle { position: relative; display: grid; grid-template-columns: repeat(var(--n), 1fr); padding: 4px; margin-bottom: 14px;
  border-radius: 999px; background: var(--surface-2); border: 1px solid color-mix(in srgb, var(--halo) 14%, var(--surface-2));
  touch-action: pan-y; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
/* The latex, same recipe as the phone: flat hub fill, a faint shade low down, a soft top-left highlight, a specular dot. */
.balloon-toggle .balloon { position: absolute; z-index: 2; left: 4px; top: 4px; height: 46px; width: calc((100% - 8px) / var(--n)); border-radius: 999px;
  background: linear-gradient(to bottom, transparent 60%, rgb(0 0 0 / .12)), var(--halo-fill);
  border: 1.5px solid var(--halo); box-shadow: 0 0 16px color-mix(in srgb, var(--halo) 60%, transparent);
  transform: translateX(calc(var(--x, 0) * 100%)) scale(var(--sx, 1), var(--sy, 1)); transition: scale .15s ease, box-shadow .15s ease; pointer-events: none; }
.balloon-toggle .balloon::before { content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(ellipse 60% 70% at 28% 22%, rgb(255 255 255 / .38) 0%, rgb(255 255 255 / 0) 60%); }
.balloon-toggle .balloon::after { content: ""; position: absolute; left: 16%; top: 17%; width: 3px; height: 3px; border-radius: 50%; background: rgb(255 255 255 / .55); }
/* the knot (a little tie pointing down, in the balloon's own color) and a wisp of string, swaying together */
.balloon-toggle .bt-knot { position: absolute; left: calc(50% - 3.5px); top: calc(100% - 1.5px); width: 0; height: 0;
  border-left: 3.5px solid transparent; border-right: 3.5px solid transparent; border-top: 5px solid var(--halo-fill);
  transform-origin: 50% 0; transform: rotate(var(--tilt, 0deg)); }
.balloon-toggle .bt-knot::after { content: ""; position: absolute; left: -.5px; top: 0; width: 1px; height: 5px;
  background: color-mix(in srgb, var(--halo) 50%, transparent); }
.balloon-toggle.pressed .balloon { scale: 1.05; box-shadow: 0 0 22px color-mix(in srgb, var(--halo) 85%, transparent); }
.balloon-toggle .bt-opt, .balloon-toggle .bt-row > span { display: flex; align-items: center; justify-content: center; min-height: 46px; padding: 0 6px;
  gap: 5px; font: inherit; font-weight: 700; font-size: .9rem; white-space: nowrap; overflow: hidden; }
.balloon-toggle .bt-t { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* The count pill: dark ink on the glow in the grey row, the hub fill on white inside the balloon. */
.balloon-toggle .bt-n { flex: none; min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box; border-radius: 9px;
  background: var(--halo); color: #0b1220; font-size: .75rem; line-height: 18px; text-align: center; }
.balloon-toggle .bt-row .bt-n { background: #fff; color: var(--halo-fill); }
.balloon-toggle .bt-opt { position: relative; z-index: 1; border: 0; background: none; border-radius: 999px; text-decoration: none; cursor: pointer;
  color: var(--ink-soft); -webkit-user-drag: none; }
.balloon-toggle .bt-opt:focus-visible { outline: 2px solid var(--halo); outline-offset: 2px; }
/* Before balloon.js first paints, the clip sits on the chosen option (--cl). */
.balloon-toggle .bt-clip { position: absolute; z-index: 3; left: calc(4px + (100% - 8px) / var(--n) * var(--cl, 0)); top: 4px; height: 46px;
  width: calc((100% - 8px) / var(--n)); border-radius: 999px; overflow: hidden; pointer-events: none; }
.balloon-toggle .bt-row { position: absolute; left: 0; top: 0; display: grid; grid-template-columns: repeat(var(--n), 1fr);
  width: calc(100% * var(--n)); transform: translateX(calc(-100% * var(--cl, 0) / var(--n))); color: #fff; }
@media (prefers-reduced-motion: reduce) {
  .balloon-toggle .balloon, .balloon-toggle.pressed .balloon { scale: 1; transition: none; }
  .balloon-toggle .bt-knot { display: none; }
}
/* Gather's subtitle: all three stacked in one grid cell, only the current one visible, so the box is
   as tall as the longest and the toggle never hops between tabs. */
.gather-sub { display: grid; }
.gather-sub > span { grid-area: 1 / 1; }
.gather-sub > span[aria-hidden] { opacity: 0; } /* gather.js cross-fades them (inline opacity) while the balloon travels */
/* The pager under a balloon toggle (js/pager.js): panes side by side, the track slides with the balloon.
   At rest only the current pane takes room; the others collapse (and are inert). */
/* The pager bleeds into main's 16px side padding and each pane puts it back, so on a phone a pane slides
   out at the screen edge (not 16px in) with a 32px gutter between two panes. */
.pager { overflow-x: clip; margin-inline: -16px; }
.pager-track { display: flex; align-items: flex-start; will-change: transform; }
/* min-height: every pane can scroll the header away, so a switch can always put each one back where you left it */
/* overflow-x clip: a too-wide card must not paint into the next pane while they slide */
.pager-pane { flex: 0 0 100%; min-width: 0; box-sizing: border-box; padding-inline: 16px; min-height: 100dvh; overflow-x: clip; touch-action: pan-y; }
.pager:not(.moving) .pager-pane:not(.on) { height: 0; min-height: 0; overflow: hidden; visibility: hidden; }
.pager .fab { display: none; } /* a fixed button inside a sliding pane would slide too: gather.js keeps one outside */

/* ---------- Resources (views/resources.js): crisis strip, five-tab toggle, Hotlines ---------- */
/* Always one tap from help, on every tab. No jokes, no eggs, no theming here. */
.crisis-strip { display: flex; align-items: center; gap: 6px; margin-bottom: 14px; padding: 8px 8px 8px 14px; border: 1.5px solid var(--care); border-radius: 16px; background: var(--surface); }
.crisis-strip b { flex: 1; font-size: .9rem; }
.crisis-strip .btn { min-height: 40px; padding: 0 14px; font-size: .88rem; }
/* Five options on a 360px phone: less padding and a slightly smaller label so "Podcasts" still fits. */
.balloon-toggle[style*="--n:5"] .bt-opt, .balloon-toggle[style*="--n:5"] .bt-row > span { padding: 0 2px; font-size: .84rem; }
/* Under 360px (a 320px phone), four options get the same squeeze so "Podcasts" isn't cut to "Podca...". */
@media (max-width: 359px) { .balloon-toggle .bt-opt, .balloon-toggle .bt-row > span { padding: 0 2px; font-size: .8rem; gap: 3px; } }
.hotline h3 { margin: 0 0 4px; }
.hotline p { margin: 0 0 4px; }
.hotline-acts { flex-wrap: wrap; margin-top: 10px; }
.hotline-acts .btn { min-height: 40px; padding: 0 14px; font-size: .88rem; }

/* ---------- Resources > Podcasts (views/podcasts.js) ---------- */
.pod-strip { display: flex; gap: 8px; overflow-x: auto; margin: 6px -16px 18px; padding: 0 16px 4px; scroll-snap-type: x proximity; }
.pod-tile { flex: none; width: 220px; scroll-snap-align: start; display: flex; flex-direction: column; gap: 6px; padding: 12px; border-radius: var(--radius); text-decoration: none; color: var(--ink);
  background: color-mix(in srgb, var(--surface) 92%, var(--halo)); border: 1px solid color-mix(in srgb, var(--halo) 35%, transparent); }
.pod-tile-head { display: flex; align-items: center; gap: 8px; font-size: .8rem; color: var(--ink-soft); min-width: 0; }
.pod-tile-head > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pod-tile-t { font-weight: 600; font-size: .9rem; line-height: 1.35; min-height: 3.6em; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pod-tile-d { font-size: .78rem; color: var(--ink-soft); }
.pod-tile-d.on { color: var(--halo-ink); }
.pod-kinds { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.pod-row-h { margin: 4px 0 4px; }
.pod-bubble { width: var(--s); height: var(--s); flex: none; border-radius: 50%; object-fit: cover; display: grid; place-items: center; font-weight: 700; font-size: calc(var(--s) * .36);
  color: var(--halo-ink); background: color-mix(in srgb, var(--halo) 14%, transparent); border: 2px solid var(--halo); }
.pod-card { margin-bottom: 8px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface); overflow: hidden; transition: border-color .2s, box-shadow .2s, background .2s; }
.pod-card.open { border-color: color-mix(in srgb, var(--halo) 60%, transparent); background: color-mix(in srgb, var(--surface) 94%, var(--halo)); box-shadow: 0 0 18px var(--halo-soft); }
.pod-head { all: unset; box-sizing: border-box; width: 100%; display: flex; align-items: center; gap: 12px; padding: 12px; cursor: pointer; }
.pod-head:focus-visible { outline: 2px solid var(--halo); outline-offset: -2px; border-radius: var(--radius); }
.pod-title { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pod-name { font-weight: 600; font-size: 1rem; }
.pod-new { display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 999px; font-size: .72rem; font-weight: 700; color: var(--halo); background: var(--halo-soft); vertical-align: 2px; }
.pod-meta { font-size: .8rem; color: var(--ink-soft); }
.pod-focus { margin-top: 2px; font-size: .88rem; color: var(--ink-soft); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pod-chev { color: var(--ink-soft); font-size: 1.2rem; transition: transform .2s; }
.pod-card.open .pod-chev { transform: rotate(90deg); }
/* The heart sits beside the card's head button (a button can't hold a button). Hub green when on. */
.pod-top { display: flex; align-items: center; }
.pod-top .pod-head { flex: 1; min-width: 0; padding-right: 4px; }
.pod-heart { margin: 0 4px 0 0; }
.pod-card { scroll-margin-top: 84px; } /* a satellite's jump lands below the sticky header */
.pod-heart:focus-visible { outline: 2px solid var(--halo); outline-offset: -4px; border-radius: 50%; }
@media (prefers-reduced-motion: reduce) { .pod-heart svg { transition: none; } }
.pod-body { padding: 0 12px 12px; animation: pod-in .22s ease-out .05s both; }
.pod-body p { margin: 0 0 10px; }
.pod-links { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.pod-link { min-height: 36px; display: inline-flex; align-items: center; padding: 0 12px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--halo) 45%, transparent); color: var(--ink); text-decoration: none; font-size: .82rem; font-weight: 600; }
.pod-link:hover { background: var(--halo-faint); }
.pod-eps { list-style: none; margin: 4px 0 0; padding: 0; }
.pod-eps li + li { border-top: 1px solid var(--line); }
.pod-eps a { display: flex; gap: 8px; padding: 10px 0; color: var(--ink); text-decoration: none; font-size: .9rem; }
.pod-eps .dot { width: 6px; height: 6px; margin-top: 7px; flex: none; border-radius: 50%; background: var(--line); }
.pod-eps .dot.on { background: var(--halo); }
.pod-eps .t { flex: 1; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pod-eps .d { color: var(--ink-soft); font-size: .78rem; white-space: nowrap; }
@keyframes pod-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .pod-body { animation: none; } .pod-card, .pod-chev { transition: none; } }
.overline { margin: 14px 0 6px; font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }

/* ---------- Discussion boards: a comment feed, not a stack of cards (phone: app/discuss/[key].tsx) ---------- */
.cm-head { display: flex; align-items: center; gap: 4px; margin: -4px 0 6px; }
.cm-head .back-btn { flex: none; }
.cm-head-t { min-width: 0; display: flex; flex-direction: column; }
.cm-head .discuss-title { font-size: 1.4rem; line-height: 1.2; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cm-blurb, .cm-rules, .cm-link { margin: 4px 0 0; }
.cm-link a { font-weight: 600; font-size: .9rem; color: var(--halo-ink); }
.cm-rules { margin-bottom: 10px; font-size: .8rem; }
.cm-page { display: flex; flex-direction: column; min-height: calc(100dvh - var(--cm-top, 96px)); }
.cm-feed { flex: 1; border-top: 1px solid var(--line); }
.cm { display: grid; grid-template-columns: 36px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.cm-av { --hue: var(--hl, var(--halo-ink)); width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; flex: none;
  font-weight: 700; font-size: .8rem; color: var(--hue); border: 2px solid var(--hue); background: color-mix(in srgb, var(--hue) 14%, transparent); }
:root[data-theme="dark"] .cm-av { --hue: var(--hd, var(--halo-ink)); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .cm-av { --hue: var(--hd, var(--halo-ink)); } }
.cm-body { min-width: 0; }
.cm-line { display: flex; align-items: center; min-height: 20px; }
/* A long name gives way, never the time: only the name ellipsizes. */
.cm-meta { flex: 0 1 auto; min-width: 0; display: flex; align-items: baseline; font-size: .875rem; white-space: nowrap; }
.cm-meta b { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cm-ago, .cm-pin { flex: none; white-space: pre; }
.cm-ago { color: var(--ink-soft); font-size: .8rem; }
.cm.pinned .cm-meta b, .cm-pin { color: var(--halo-ink); font-weight: 700; }
.cm-more { width: 44px; height: 44px; min-height: 44px; margin: -12px -12px -12px 0; padding: 0; }
.cm-more svg { width: 20px; height: 20px; }
.cm-line > .cm-more { margin-left: auto; }
.cm-text { margin: 2px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical; overflow: hidden; }
.cm-text.open { display: block; -webkit-line-clamp: none; }
.cm-textbtn { border: 0; background: none; padding: 2px 0; font: inherit; font-size: .875rem; font-weight: 600; color: var(--halo-ink); cursor: pointer; }
.cm-textbtn[hidden] { display: none; }
.cm-img { display: block; margin-top: 8px; max-width: 100%; max-height: 320px; width: auto; border-radius: 12px; background: var(--surface-2); }
.cm-older { display: block; width: 100%; min-height: 44px; border: 0; border-bottom: 1px solid var(--line); background: none; font: inherit; font-size: .875rem; font-weight: 600; color: var(--halo-ink); cursor: pointer; }
.cm-empty { text-align: center; margin-top: 24px; }
.cm-quote { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: pre-wrap; margin: 2px 0 8px; }
/* Runs: the same person again within 10 minutes, chat-style. No avatar, no name, no hairline between. */
.cm.run { border-bottom: 0; padding-bottom: 4px; }
.cm.grouped { padding-top: 2px; }
.cm-av-gap { width: 36px; }
.cm-line-g { align-items: flex-start; }
.cm-gtext { flex: 1; min-width: 0; }
.cm.grouped .cm-text { margin-top: 0; }
.cm-reply { flex: none; border: 0; background: none; padding: 12px 8px 12px 0; margin: -12px 0; font: inherit; font-size: .8125rem; font-weight: 600; color: var(--ink-soft); cursor: pointer; }
/* Reply rides the name line ("Stef . 1d . Reply"), so it adds no height to the row. */
.cm-reply::before { content: "\00b7"; display: inline-block; margin: 0 .3em; font-weight: 400; }
.cm-reply:hover { color: var(--ink); text-decoration: underline; }
/* Replies (1.5): one level deep, hung under their top comment on a thread line that starts under its avatar. */
.cm-thread { border-bottom: 1px solid var(--line); }
.cm-thread .cm { border-bottom: 0; }
.cm-thread > .cm:first-child { padding-bottom: 4px; }
.cm-replies { margin-left: 17px; padding: 0 0 8px 29px; border-left: 2px solid var(--line); }
.cm.reply { grid-template-columns: 28px 1fr; gap: 10px; padding: 8px 0; }
.cm.reply .cm-av { width: 28px; height: 28px; font-size: .68rem; }
.cm-more-replies { display: block; min-height: 44px; padding: 0 0 0 38px; }
.cm-gone .cm-text { margin: 0; font-style: italic; }
/* Fold a thread (discuss-links.js): the chevron button under a top comment; tapping the top comment does the same. */
.cm-fold { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin: -8px 0 -4px 48px; padding: 0 8px 0 0; border: 0; background: none;
  font: inherit; font-size: .8125rem; font-weight: 600; color: var(--halo-ink); cursor: pointer; }
.cm-fold svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform 160ms ease; }
.cm-fold[aria-expanded="false"] svg { transform: rotate(-90deg); }
.cm-replies[hidden] { display: none; }
.cm-thread.folds > .cm:first-child { cursor: pointer; }
@media (prefers-reduced-motion: reduce) { .cm-fold svg { transition: none; } }
/* Names and avatars open profiles. A hidden (friends-only) profile stays plain text. */
a.cm-name { color: inherit; text-decoration: none; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
a.cm-name:hover b, a.cm-name:focus-visible b { text-decoration: underline; }
a.cm-av-link { display: block; width: fit-content; height: fit-content; border-radius: 50%; text-decoration: none; }
/* Board share button in the header; one-thread view (a shared thread link). */
.cm-head .share-btn { margin-left: auto; border-color: transparent; background: none; }
.cm-focus { margin: 8px 0 4px; padding: 10px 12px; border-radius: 12px; background: var(--halo-faint); border: 1px solid var(--halo-soft); font-size: .875rem; }
.cm-focus a { color: var(--halo-ink); font-weight: 600; white-space: nowrap; }
.cm-replying { display: flex; align-items: center; gap: 8px; margin: 0 0 6px 40px; font-size: .875rem; color: var(--ink-soft); }
.cm-replying[hidden] { display: none; }
.cm-replying-t { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cm-replying b { color: var(--ink); }
.cm-replying .cm-textbtn { min-height: 44px; margin: -12px 0; }
.cm-new { animation: cm-in 240ms ease-out backwards; } /* backwards, not both: a held end state would pin opacity and stop .cm-out fading it */
@keyframes cm-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.cm.cm-out { opacity: 0; height: 0 !important; padding-top: 0; padding-bottom: 0; border-bottom-width: 0; overflow: hidden;
  transition: opacity 160ms ease-in, height 240ms cubic-bezier(.65, 0, .35, 1), padding 240ms cubic-bezier(.65, 0, .35, 1), border-width 240ms; }
@media (prefers-reduced-motion: reduce) { .cm-new { animation: none; } .cm.cm-out { transition: none; } }
/* One comment's "..." sheet: an action list, not a stack of buttons. */
.cm-sheet-h { margin: 0; font-size: 1.15rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cm-acts { border-top: 1px solid var(--line); }
.cm-act { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 8px 0; border: 0; border-bottom: 1px solid var(--line); background: none;
  font: inherit; font-size: 1rem; font-weight: 600; color: var(--ink); text-align: left; text-decoration: none; cursor: pointer; }
.cm-act:last-child { border-bottom: 0; }
.cm-act:hover { background: var(--surface-2); }
.cm-act svg { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.cm-act-t { display: flex; flex-direction: column; min-width: 0; }
.cm-act-sub { font-size: .8rem; font-weight: 400; color: var(--ink-soft); margin-top: 1px; }
.cm-act.bad { color: var(--danger); }
.cm-act.armed { background: var(--danger-fill); color: #fff; border-radius: 12px; border-bottom-color: transparent; margin: 0 -12px; padding: 8px 12px; width: calc(100% + 24px); }
.cm-act.armed .cm-act-sub { color: #fff; }
/* Composer: pinned like a chat (body.thread hides the orb on this route). */
.cm-composer { position: sticky; bottom: 0; z-index: 15; margin: 8px -16px 0; padding: 8px 12px calc(8px + var(--safe-b)); background: var(--bg); border-top: 1px solid var(--line); }
.cm-compose-row { display: flex; align-items: flex-end; gap: 8px; }
.cm-compose-row .cm-av { width: 32px; height: 32px; margin-bottom: 4px; font-size: .72rem; }
.cm-compose-row textarea.input { flex: 1; min-height: 40px; max-height: 120px; padding: 9px 14px; border-radius: 20px; resize: none; line-height: 1.3; }
.cm-photo { width: 44px; height: 40px; min-height: 40px; flex: none; cursor: pointer; display: grid; place-items: center; color: var(--ink-soft); border: 0; background: none; box-shadow: none; }
.cm-post { min-width: 44px; height: 40px; border: 0; background: none; font: inherit; font-weight: 700; color: var(--ink-soft); opacity: .6; cursor: default; }
/* Gold only once there is something to send (gold is for actions). */
.cm-post:not(:disabled) { color: #a77a1e; opacity: 1; cursor: pointer; }
:root[data-theme="dark"] .cm-post:not(:disabled) { color: var(--gold); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .cm-post:not(:disabled) { color: var(--gold); } }
.cm-attached { display: flex; align-items: center; gap: 8px; margin: 0 0 8px 40px; }
.cm-attached[hidden] { display: none; }
.cm-attached img { width: 56px; height: 56px; object-fit: cover; border-radius: 10px; }
/* Resources > Discuss: the topic board list. */
.board-list { margin-top: 8px; border-top: 1px solid var(--line); }
.board-row { display: flex; gap: 12px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--line); text-decoration: none; color: inherit; }
.board-ico { width: 32px; height: 32px; margin-top: 2px; border-radius: 50%; flex: none; display: grid; place-items: center; background: var(--halo-faint); }
.board-ico svg { width: 16px; height: 16px; fill: none; stroke: var(--halo-ink); stroke-width: 1.8; }
.board-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.board-top { display: flex; align-items: baseline; gap: 8px; }
.board-top b { flex: 1; min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.board-meta { font-size: .8rem; color: var(--ink-soft); white-space: nowrap; }
.board-blurb { margin-top: 2px; font-size: .875rem; color: var(--ink-soft); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.board-row:hover b { text-decoration: underline; }
/* Discuss > Archive (weekly boards): past weeks, newest first, and the read-only note on an archived week. */
.arc-week { margin-top: 18px; }
/* Archive rows: the board name wraps instead of truncating; the counts sit on their own line under it. */
.board-top b.arc-name { white-space: normal; overflow: visible; }
.arc-h { display: flex; align-items: baseline; gap: 8px; justify-content: space-between; margin: 0; font-size: 1rem; font-weight: 700; }
/* Archive search (r5): words, floor, dates. Results are board rows with a snippet; hits get a halo wash, never gold. */
.arc-find { margin: 10px 0 4px; display: grid; gap: 8px; }
.arc-filters { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
.arc-f { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.arc-f .input { width: 100%; min-width: 0; }
@media (max-width: 480px) { .arc-filters { grid-template-columns: 1fr 1fr; } .arc-f:first-child { grid-column: 1 / -1; } }
.arc-clear { justify-self: start; }
.arc-count { margin: 8px 0 0; }
.arc-snip { -webkit-line-clamp: 3; }
.arc-snip mark { background: var(--halo-faint); color: inherit; border-radius: 3px; padding: 0 1px; box-shadow: inset 0 -1px 0 var(--halo-ink); }
.arc-hit .board-meta:last-child { margin-top: 2px; }
.cm-archived { margin: 8px 0 4px; padding: 10px 12px; border-radius: 12px; background: var(--halo-faint); border: 1px solid var(--halo-soft); font-size: .875rem; }
.cm-floor-rules { margin: 10px 0 4px; padding: 12px 14px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); font-size: .9rem; }
.cm-floor-rules p { margin: 6px 0 0; }
.cm-floor-rules a { color: var(--halo-ink); font-weight: 600; }
.cm-floor-rules-h { margin: 0; font-size: 1rem; }
.cm-floor-warn { padding-top: 8px; border-top: 1px solid var(--line); }
.cm-claim { margin: 6px 0 4px; }
.cm-claim a, .cm-claim-t { color: var(--halo-ink); font-weight: 600; text-decoration: underline; }
.cm-claim-btn { min-height: 44px; text-align: left; font-weight: 400; }
.cm-archived a { color: var(--halo-ink); font-weight: 600; white-space: nowrap; }
.cm-composer[hidden] { display: none; }

/* Local dev only (api.js): which TEST API this tab talks to. Never drawn on the live site. Bottom left: at the top
   it covered the Settings gear and Profile on a 320 to 360px screen. */
.test-api-pill { position: fixed; bottom: calc(6px + env(safe-area-inset-bottom, 0px)); left: 6px; z-index: 1000; pointer-events: none;
  padding: 2px 8px; border-radius: 999px; font: 700 .68rem/1.5 system-ui, sans-serif; letter-spacing: .04em;
  background: var(--danger-fill); color: #fff; opacity: .85; }

/* Discussion Board: the guidelines note on top of the boards (operator, 10/11) */
.house-rules { border: 1px solid var(--halo-soft, var(--line)); margin-bottom: 14px; }
.house-rules p { margin: 0 0 4px; }
.house-rules a { font-weight: 700; color: var(--halo-ink, inherit); }
