/*
 * CrossFitOS community — "The Whiteboard", on the brand darks
 *
 * The social app wears the marketing site's design language
 * (docs/design-language.md, landing-page/src/styles/home.css): the
 * Bricolage / Hanken / DM Mono type system, 2px borders, hard offset "sticker"
 * shadows and numbered, ruled lists, on the CrossFitOS dark palette.
 *
 * Page #05080f, surface #0c1119, hairlines #1d2735, text #f1f5e9.
 * Lime #b9f200 is the primary accent: the primary action, and anything active,
 * selected or unread. Cyan #00ffe9 is the secondary accent: hard shadows,
 * small mono labels, links and the focus ring. Danger is #ff6b4a.
 * Text that sits on a lime fill is always #05080f. No orange, no blurred
 * shadows, no glow, no gradients on text, no glass.
 *
 * Light mode (html[data-theme="light"], set by ThemeScript) is the marketing
 * site's "paper" variant: warm paper page, ink-black text, and the hard sticker
 * shadows in ink instead of cyan. Lime stays a fill; where lime was text it
 * becomes dark olive (--lime-ink) and where it was a line, --lime-edge. Cyan
 * text becomes deep teal. The override block follows the dark tokens below;
 * dark values are unchanged.
 *
 * Tokens live on body.social-body rather than :root on purpose. brand.css and
 * the dashboard share some of these names (--text, --line, --warn ...) and
 * brand.css is linked *after* this file on the feed and profile pages. A custom
 * property set on <body> beats one inherited from :root regardless of load
 * order, and it never reaches the dashboard, which still loads profile.css for
 * the member drawer.
 *
 * Legacy token names (--brand, --panel, --muted, --paper, --flare ...) are kept
 * and re-pointed so existing markup and profile.css keep working. --ink is the
 * dark used for text on lime.
 */

body.social-body {
  /* palette: the CrossFitOS brand darks, lime and cyan */
  --bg-page: #05080f;
  --surface: #0c1119;
  --surface-2: #111a27;
  --field: #070b13;
  --hairline: #1d2735;
  --edge: #2e3d54; /* 2px card borders */
  --control-edge: #6f7f96; /* form controls need 3:1 against the page */
  --text-hi: #f1f5e9;
  --text-soft: #b7c0cf;
  --text-mute: #8692a4;
  --lime: #b9f200;
  --lime-hover: #cbff2e;
  --cyan: #00ffe9;
  --cyan-soft: #0f8a83; /* repeated cards: a quieter hard cyan offset */
  --danger: #ff6b4a;
  --on-lime: #05080f;
  --on-danger: #05080f; /* text on a --danger fill */
  --on-text: #05080f; /* text on a --text fill (inverted hover) */

  /* lime as text / as a line or ring, and the hard sticker offset colour.
     On dark these are the lime and cyan themselves; light re-points them. */
  --lime-ink: var(--lime);
  --lime-edge: var(--lime);
  --sh-cyan: var(--cyan);

  /* the few literals that need a light twin */
  --error-ink: #ffc8ba;
  --placeholder: #6b6b6b;
  --join-card-top: #141414;
  --bar-rgb: 5 5 5; /* mobile top bar and bottom nav */
  --drop-rgb: 0 0 0; /* soft drop shadows on popovers and panels */
  --drop-k: 1;
  --modal-scrim: rgba(5, 8, 15, 0.78);

  /* legacy names kept so older rules and profile.css keep working.
     --ink is now the dark used for text on a lime fill. */
  --paper: #05080f;
  --paper-deep: #111a27;
  --paper-line: #1d2735;
  --ink: #05080f;
  --ink-soft: #b7c0cf;
  --flare: #ff6b4a;
  --flare-btn: #ff6b4a;
  --flare-deep: #ff6b4a;
  --mark: #b9f200;
  --card: #0c1119;

  --brand: var(--lime);
  --brand-hover: var(--lime-hover);
  --on-brand: var(--on-lime);
  --bg: var(--bg-page);
  --bg-2: var(--surface);
  --panel: var(--surface);
  --panel-2: var(--surface-2);
  --line: var(--hairline);
  --line-2: var(--edge);
  --line-3: #5b6b84;
  --text: var(--text-hi);
  --text-dim: var(--text-soft);
  --muted: var(--text-mute);
  --faint: var(--text-mute);
  --warn: var(--danger);
  --amber: var(--danger);

  /* depth: hard offsets only, in cyan. Never blurred, never black on black. */
  --shadow-sm: 3px 3px 0 var(--cyan-soft);
  --shadow: 4px 4px 0 var(--cyan-soft);
  --shadow-lg: 8px 8px 0 var(--sh-cyan);
  --shadow-hi: 4px 4px 0 var(--sh-cyan);

  /* type */
  --font-head:
    "Bricolage Grotesque", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-body:
    "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, monospace;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --touch: 44px;
}

/* Light: the marketing site's "paper" palette. Values follow the dashboard's
   light theme (src/styles/dashboard-theme.css) so the two apps agree. */
[data-theme="light"] body.social-body {
  --bg-page: #f3efe5;
  --surface: #fbfaf6;
  --surface-2: #ede8dc;
  --field: #ffffff;
  --hairline: #d6cfbd;
  --edge: #c9c0a8;
  --control-edge: #857d68; /* 3:1 against the paper page */
  --text-hi: #16130f;
  --text-soft: #4a443a;
  --text-mute: #5f5a4c;
  --cyan: #006e62;
  --cyan-soft: #c9c0a8;
  --danger: #b4380f;
  --on-danger: #ffffff;
  --on-text: #fbfaf6;

  --lime-ink: #4a6800;
  --lime-edge: #4a6800;
  --sh-cyan: #16130f;

  --error-ink: #8a2a0b;
  --placeholder: #857d68;
  --join-card-top: #fbfaf6;
  --bar-rgb: 243 239 229;
  --drop-rgb: 22 19 15;
  --drop-k: 0.3;
  --modal-scrim: rgba(22, 19, 15, 0.5);

  --paper: #f3efe5;
  --paper-deep: #ede8dc;
  --paper-line: #d6cfbd;
  --ink-soft: #4a443a;
  --flare: #b4380f;
  --flare-btn: #b4380f;
  --flare-deep: #b4380f;
  --card: #fbfaf6;
  --line-3: #9a917a;
}

.social-body {
  margin: 0;
  color-scheme: dark;
  background-color: var(--bg-page);
  /* faint light grain, the dark twin of the marketing site's paper grain */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .95  0 0 0 0 .96  0 0 0 0 .9  0 0 0 .035 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

[data-theme="light"] .social-body {
  color-scheme: light;
  /* the marketing site's paper grain: dark specks instead of light */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .09  0 0 0 0 .07  0 0 0 0 .05  0 0 0 .045 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* Borders are part of the box, so a 44px target is 44px and a card "min(440px, 100%)" fits. */
.social-body *,
.social-body *::before,
.social-body *::after {
  box-sizing: border-box;
}

.social-body ::selection {
  background: var(--mark);
  color: var(--ink);
}

.social-body :focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
}

.social-body h1,
.social-body h2,
.social-body h3 {
  font-family: var(--font-head);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* Bare links (no component class) are cyan. */
.social-body a:where(:not([class])) {
  color: var(--cyan);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--cyan);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.social-body a:where(:not([class])):hover {
  color: var(--lime-ink);
}

/*
 * The surface predates any box-sizing reset, so a `width: 100%` control with
 * padding (the community search, the composer's drop target) rendered wider
 * than its column by exactly its padding + border, and that extra width was
 * what made the page scroll sideways on a phone. Scoped to the social body so
 * the Tailwind dashboard, which shares profile.css, is untouched.
 */
.social-body,
.social-body *,
.social-body *::before,
.social-body *::after {
  box-sizing: border-box;
}

.social-boot {
  display: grid;
  gap: 0.9rem;
  justify-items: center;
  place-content: center;
  min-height: 100vh;
  padding: 2rem;
  text-align: center;
  font-family: var(--font-head);
  font-weight: 600;
}
.social-boot-lead {
  margin: 0;
  max-width: 24ch;
  font-family: var(--font-head);
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
}
.social-boot .btn {
  min-width: 14rem;
}

/* ------------------------------------------------------------------ *
 * Brand lockup
 * ------------------------------------------------------------------ */

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.wordmark-mark {
  display: block;
  height: 32px;
  width: auto;
  border-radius: 6px;
}
.wordmark-text {
  font-family: var(--font-head);
  font-size: 1.4rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--text);
}
.wordmark-text span {
  color: var(--lime-ink);
}

.social-boot-brand,
.join-brand,
.topbar-brand {
  text-decoration: none;
  color: var(--text);
}
.social-boot-logo {
  height: 40px;
}

/* ------------------------------------------------------------------ *
 * Shell and rail
 * ------------------------------------------------------------------ */

.social-shell {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 0;
  min-height: 100vh;
  max-width: 1180px;
  margin: 0 auto;
  transition: grid-template-columns 0.22s ease;
  padding-right: 0;
}
.social-shell.with-thread {
  /* Rail plus a narrower feed, leaving room for the docked panel. */
  grid-template-columns: 260px minmax(0, 1fr);
  padding-right: 420px;
}

.social-rail {
  border-right: 2px solid var(--edge);
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.social-brand {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.045em;
  color: var(--text);
  text-decoration: none;
}
.social-brand span {
  color: var(--lime-ink);
}

.social-scopes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.social-scopes button {
  background: var(--card);
  border: 2px solid var(--control-edge);
  color: var(--text);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  min-height: var(--touch);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  text-transform: capitalize;
}
.social-scopes button.active {
  background: var(--mark);
  box-shadow: 3px 3px 0 var(--sh-cyan);
  font-weight: 700;
  color: var(--on-lime);
}

.social-panel {
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
  padding: 1rem;
}
/* DM Mono small-caps labels, each marked with a lime tick like a whiteboard list. */
.social-panel h3,
.panel-head h3 {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cyan);
}
.social-panel h3::before,
.panel-head h3::before {
  content: "";
  flex: none;
  width: 0.7rem;
  height: 0.7rem;
  background: var(--mark);
  border: 0;
  border-radius: 2px;
}
.panel-head h3 {
  margin: 0;
}

.social-community,
.social-dm {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
}
.social-dm p {
  margin: 0;
}
.social-community:first-of-type,
.social-dm:first-of-type {
  border-top: 0;
}

.social-main {
  /* A grid item's automatic minimum is its content, so a nowrap child (the
     scope tabs) would otherwise widen the whole shell past the viewport and
     drag every `position: fixed` overlay off-screen with it. */
  min-width: 0;
  padding: 1.25rem 1.5rem 4rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  min-width: 0;
}
.social-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.social-header h1 {
  margin: 0;
  font-size: 1.4rem;
}

/* ------------------------------------------------------------------ *
 * Composer and posts
 * ------------------------------------------------------------------ */

.social-composer,
.social-post {
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 1rem;
}
.social-composer {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.social-composer textarea {
  width: 100%;
  min-height: 84px;
  resize: vertical;
  background: var(--field);
  border: 2px solid var(--control-edge);
  border-radius: 10px;
  color: var(--text);
  padding: 0.7rem 0.8rem;
  font: inherit;
}
.social-composer textarea::placeholder,
.comment-compose textarea::placeholder,
.reply-compose input::placeholder,
.browse-search::placeholder,
.join-card input::placeholder,
.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-mute);
  opacity: 1;
}
.social-composer textarea:disabled {
  background: var(--paper-deep);
  cursor: not-allowed;
}
.social-composer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}
.social-composer select {
  background: var(--field);
  color: var(--text);
  border: 2px solid var(--control-edge);
  border-radius: 10px;
  min-height: var(--touch);
  padding: 0.4rem 0.6rem;
  font: inherit;
}

/*
 * Destinations are chips, not a dropdown. A post goes to exactly one community,
 * so these are alternatives. The selected one is the highlighter mark.
 */
.composer-destinations {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  min-width: 0;
}
.dest-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: var(--touch);
  padding: 0.3rem 0.8rem;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
  background: var(--field);
  border: 2px solid var(--control-edge);
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color 0.15s,
    transform 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
}
.dest-chip:hover {
  background: var(--paper-deep);
}
.dest-chip.active {
  background: var(--mark);
  box-shadow: 3px 3px 0 var(--sh-cyan);
  font-weight: 700;
  border-color: var(--lime-edge);
  color: var(--on-lime);
}

/*
 * Emoji picker. The trigger is a Lucide icon so the control matches the rest of
 * the interface; the emoji are content, and only appear once asked for.
 */
.emoji-picker {
  position: relative;
  flex: none;
}
.emoji-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  padding: 0;
  color: var(--text);
  background: transparent;
  border: 2px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.15s;
}
.emoji-trigger:hover:not(:disabled) {
  background: var(--mark);
  border-color: var(--ink);
  color: var(--on-lime);
}
.emoji-trigger:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.emoji-panel {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 0;
  z-index: 60;
  width: 248px;
  padding: 0.6rem;
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-hi);
}
/* Flipped when the trigger is too near the top of the viewport to open upwards. */
.emoji-panel.below {
  bottom: auto;
  top: calc(100% + 0.5rem);
}
.emoji-group + .emoji-group {
  margin-top: 0.6rem;
}
.emoji-group-label {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.emoji-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 0.1rem;
}
.emoji-cell {
  min-height: 28px;
  padding: 0.2rem 0;
  font-size: 1.1rem;
  line-height: 1;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
}
.emoji-cell:hover {
  background: var(--mark);
  border-color: var(--ink);
  color: var(--on-lime);
}

/*
 * Destinations are chips, not a dropdown. A post goes to exactly one community,
 * so these are alternatives — but the two people reach for most (their city,
 * everyone) were previously one unremarkable <option> deep in a select, which is
 * why the composer read as though it could not post outside the gym.
 */
.composer-destinations {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  min-width: 0;
}
.dest-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.32rem 0.6rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition:
    color 0.15s ease,
    border-color 0.15s ease,
    background 0.15s ease;
}
.dest-chip:hover {
  color: var(--text);
  border-color: var(--line-2);
}
.dest-chip.active {
  color: var(--on-lime);
  background: var(--brand);
  border-color: var(--lime-edge);
}
.dest-chip:focus-visible {
  outline: 2px solid var(--lime-edge);
  outline-offset: 2px;
}

/*
 * Emoji picker. The trigger is a Lucide icon so the control matches the rest of
 * the interface; the emoji are content, and only appear once asked for.
 */
.emoji-picker {
  position: relative;
  flex: none;
}
.emoji-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  transition:
    color 0.15s ease,
    background 0.15s ease;
}
.emoji-trigger:hover:not(:disabled) {
  color: var(--lime-ink);
  background: var(--panel-2);
}
.emoji-trigger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.emoji-trigger:focus-visible {
  outline: 2px solid var(--lime-edge);
  outline-offset: 2px;
}

.emoji-panel {
  position: absolute;
  bottom: calc(100% + 0.4rem);
  left: 0;
  z-index: 60;
  width: 232px;
  padding: 0.55rem;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  box-shadow: 0 18px 40px -18px rgb(var(--drop-rgb) / calc(0.95 * var(--drop-k)));
}
/* Flipped when the trigger is too near the top of the viewport to open upwards. */
.emoji-panel.below {
  bottom: auto;
  top: calc(100% + 0.4rem);
}
.emoji-group + .emoji-group {
  margin-top: 0.5rem;
}
.emoji-group-label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.emoji-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 0.1rem;
}
.emoji-cell {
  padding: 0.2rem 0;
  font-size: 1.05rem;
  line-height: 1;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  transition:
    background 0.12s ease,
    border-color 0.12s ease;
}
.emoji-cell:hover {
  background: rgba(182, 255, 0, 0.12);
  border-color: var(--lime-edge);
}
.emoji-cell:focus-visible {
  outline: 2px solid var(--lime-edge);
  outline-offset: 1px;
}

.social-post header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}
.social-body-text {
  margin: 0 0 0.7rem;
  white-space: pre-wrap;
  font-size: 1.02rem;
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.social-media {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.5rem;
  margin-bottom: 0.7rem;
}
.social-media img,
.social-media .media-video {
  width: 100%;
  border: 2px solid var(--edge);
  border-radius: 10px;
  display: block;
}
/* A video plays in its own frame; black letterboxing reads as a player. */
.media-video {
  max-height: 70vh;
  background: #000;
}

.social-feed {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.social-feed > .empty {
  margin: 0;
}
.social-post footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 0.5rem;
  flex-wrap: wrap;
  padding-top: 0.5rem;
  border-top: 1px solid var(--line);
}

.row {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------------ *
 * Buttons
 *
 * .btn is the single primary action (post, send, join, create). Everything
 * else is .tiny / .chip / ghost.
 * ------------------------------------------------------------------ */

.btn,
.chip,
.tiny {
  font: inherit;
  cursor: pointer;
  border-radius: 999px;
  border: 2px solid var(--control-edge);
  background: var(--field);
  color: var(--text);
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--touch);
  padding: 0.55rem 1.4rem;
  background: var(--lime);
  color: var(--on-lime);
  border-color: var(--lime-edge);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.01em;
  line-height: 1.1;
  text-decoration: none;
  box-shadow: var(--shadow-hi);
  transition:
    transform 0.25s var(--ease),
    box-shadow 0.25s var(--ease),
    background-color 0.2s;
}
.btn:hover:not(:disabled) {
  background: var(--lime-hover);
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--sh-cyan);
}
.btn:active:not(:disabled) {
  transform: translate(3px, 3px);
  box-shadow: 1px 1px 0 var(--sh-cyan);
}
.btn:disabled {
  background: var(--surface-2);
  border-color: var(--hairline);
  color: var(--muted);
  box-shadow: none;
  cursor: not-allowed;
}
.btn.ghost,
.chip.ghost {
  background: transparent;
  border-color: var(--control-edge);
  color: var(--text);
  box-shadow: none;
}
.btn.ghost:hover:not(:disabled) {
  background: var(--text);
  border-color: var(--text);
  color: var(--on-text);
  transform: none;
  box-shadow: none;
}
.chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  padding: 0.3rem 0.8rem;
  font-size: 0.85rem;
  font-weight: 600;
}
.chip.on {
  background: var(--mark);
  font-weight: 700;
  box-shadow: 3px 3px 0 var(--sh-cyan);
  color: var(--on-lime);
}
.tiny {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  min-height: var(--touch);
  padding: 0.3rem 1rem;
  font-family: var(--font-head);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  transition:
    background-color 0.15s,
    transform 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
}
.tiny:hover:not(:disabled) {
  background: var(--mark);
  transform: translate(-1px, -1px);
  box-shadow: 3px 3px 0 var(--sh-cyan);
  color: var(--on-lime);
}
.tiny:active:not(:disabled) {
  transform: translate(2px, 2px);
  box-shadow: none;
}
.tiny.ghost {
  background: transparent;
  border-color: var(--line-3);
  color: var(--text-soft);
}
.tiny.ghost:hover:not(:disabled) {
  background: var(--paper-deep);
  border-color: var(--text-soft);
  color: var(--text);
}
.tiny:disabled {
  opacity: 0.55;
  cursor: default;
}

.badge {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  background: var(--mark);
  color: var(--ink);
  border: 1.5px solid var(--lime-edge);
  border-radius: 4px;
  padding: 0.05rem 0.4rem;
  margin-left: 0.35rem;
  line-height: 1.5;
}
.badge.warn {
  background: var(--danger);
  border-color: var(--danger);
  color: var(--on-danger);
}

.muted {
  color: var(--muted);
}
.small {
  font-size: 0.8rem;
}
.pad {
  padding: 2rem;
  text-align: center;
}

/* Timestamps are mono, like the pen marks in a WOD log. */
.post-time {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.social-error {
  position: relative;
  padding: 0.7rem 2.6rem 0.7rem 0.9rem;
  background: rgba(255, 107, 74, 0.12);
  border: 2px solid var(--danger);
  color: var(--error-ink);
  border-radius: 10px;
  font-size: 0.9rem;
}
.social-error .close {
  position: absolute;
  top: 0;
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  background: none;
  border: 0;
  color: inherit;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

/* social/join — two columns: the pitch, then the form. Stacks below 860px. */
.join-wrap {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 2.5rem);
  background:
    radial-gradient(60rem 40rem at 85% -10%, rgba(182, 255, 0, 0.14), transparent 60%),
    radial-gradient(50rem 36rem at -10% 110%, rgba(0, 220, 255, 0.08), transparent 60%),
    linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px) 0 0 / 48px 48px,
    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px) 0 0 / 48px 48px,
    var(--bg);
}
.join-shell {
  width: min(960px, 100%);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
}
.join-checking {
  color: var(--muted);
  font-size: 0.9rem;
}

.join-logo {
  display: block;
  align-self: flex-start;
  height: 40px;
  width: auto;
  margin-bottom: 0.4rem;
}
/* The pitch */
.join-brand {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
.join-eyebrow {
  align-self: flex-start;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lime-ink);
  border: 1px solid rgba(182, 255, 0, 0.35);
  background: rgba(182, 255, 0, 0.08);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
}
.join-headline {
  margin: 0;
  font-size: clamp(2rem, 4.6vw, 3.1rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
  font-weight: 800;
  color: var(--text);
}
.join-headline span {
  color: var(--lime-ink);
}
.join-lede {
  margin: 0;
  max-width: 34rem;
  font-size: 1.02rem;
  color: var(--text-dim);
}
.join-perks {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.85rem;
}
.join-perks li {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  color: var(--text-dim);
  font-size: 0.92rem;
}
.join-perks strong {
  display: block;
  color: var(--text);
  font-size: 0.98rem;
  margin-bottom: 0.1rem;
}
.join-perk-icon {
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: rgba(182, 255, 0, 0.1);
  border: 1px solid rgba(182, 255, 0, 0.25);
  color: var(--lime-ink);
  font-size: 1rem;
}

.join-password {
  position: relative;
  display: flex;
}
.join-password input {
  flex: 1;
  padding-right: 4.2rem;
}
.join-toggle {
  position: absolute;
  right: 0.45rem;
  top: 50%;
  transform: translateY(-50%);
  font: inherit;
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--text-dim);
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 0.3rem 0.5rem;
  cursor: pointer;
}
.join-toggle:hover {
  color: var(--brand);
}
.join-toggle:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
/* The form */
.join-card {
  position: relative;
  background: linear-gradient(180deg, var(--join-card-top), var(--panel));
  border: 1px solid var(--line-2);
  border-radius: 18px;
  padding: 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.95rem;
  box-shadow: 0 30px 80px -30px rgb(var(--drop-rgb) / calc(0.8 * var(--drop-k)));
}
.join-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  border-radius: 18px 18px 0 0;
  background: linear-gradient(90deg, transparent, var(--lime-edge), transparent);
}
.join-card-head h1 {
  margin: 0;
  font-size: 1.35rem;
  letter-spacing: -0.01em;
}
.join-card-head p {
  margin: 0.25rem 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}
.join-field {
  display: flex;
  flex-direction: column;
  gap: 0.38rem;
}
.join-field label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-dim);
}
.join-optional {
  font-weight: 400;
  color: var(--muted);
  opacity: 0.8;
}
.join-field input {
  background: var(--panel-2);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  color: var(--text);
  padding: 0.7rem 0.8rem;
  font: inherit;
  font-size: 0.95rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.join-field input::placeholder {
  color: var(--placeholder);
}
.join-field input:focus {
  outline: none;
  border-color: var(--lime-edge);
  box-shadow: 0 0 0 3px rgba(182, 255, 0, 0.18);
}
.join-field small {
  font-size: 0.76rem;
  color: var(--muted);
}
.join-submit {
  margin-top: 0.3rem;
  font: inherit;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.85rem;
  padding: 0.85rem 1rem;
  border-radius: 12px;
  border: 1px solid var(--lime-edge);
  background: var(--brand);
  color: var(--on-brand);
  cursor: pointer;
  transition: background 0.15s, transform 0.15s, box-shadow 0.15s;
}
.join-submit:hover:not(:disabled) {
  background: var(--brand-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}
.join-submit:disabled {
  opacity: 0.6;
  cursor: progress;
}
.join-switch {
  margin: 0.2rem 0 0;
  text-align: center;
  font-size: 0.88rem;
  color: var(--muted);
}
.join-switch a {
  color: var(--lime-ink);
  font-weight: 600;
  text-decoration: none;
}
.join-switch a:hover {
  text-decoration: underline;
}

@media (max-width: 860px) {
  .join-shell {
    grid-template-columns: minmax(0, 1fr);
    max-width: 440px;
  }
  .join-brand {
    text-align: left;
  }
  .join-perks {
    display: none;
  }
}
@media (max-width: 840px) {
  /* Once the rail no longer fits beside the feed, don't stack it on top of it
     either. Every panel it holds is reachable from the topbar — gyms from
     Communities, requests from Messages, suggestions from People — so keeping
     it would only bury the feed under a screen of chrome. */
  .social-shell {
    grid-template-columns: minmax(0, 1fr);
  }
  .social-rail {
    display: none;
  }
}

/* ------------------------------------------------------------------ *
 * Top navigation
 * ------------------------------------------------------------------ */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 0.5rem 1rem;
  padding: 0.55rem 1.25rem;
  background: var(--bg-page);
  border-bottom: 2px solid var(--edge);
}

.topbar-brand {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  min-height: var(--touch);
}

.topbar-tabs {
  display: flex;
  gap: 0.3rem;
  flex: 1 1 auto;
  overflow-x: auto;
  padding: 4px 4px 6px 2px; /* room for the active tab's sticker shadow */
  scrollbar-width: none;
}
.topbar-tabs::-webkit-scrollbar {
  display: none;
}
.topbar-tabs button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--touch);
  background: transparent;
  border: 2px solid transparent;
  color: var(--text);
  border-radius: 999px;
  padding: 0.3rem 0.9rem;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.topbar-tabs button:hover {
  background: var(--surface-2);
}
/* A link in the tab strip — the profile page's way back — has to line up with
   the buttons around it, so it gets the same pill rather than bare link text. */
.topbar-tabs a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  align-self: center;
  min-height: var(--touch);
  padding: 0.3rem 0.9rem;
  border-radius: 999px;
  white-space: nowrap;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}
.topbar-tabs a:hover {
  background: var(--surface-2);
}
/* A link in the tab strip — the profile page's way back — has to line up with
   the buttons around it, so it gets the same pill rather than bare link text. */
.topbar-tabs a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  align-self: center;
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  white-space: nowrap;
}
.topbar-tabs a:hover {
  background: var(--panel);
}
.topbar-tabs button.active {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--ink);
  font-weight: 700;
  box-shadow: 2px 2px 0 var(--sh-cyan);
}
.topbar-tabs button.active:hover {
  background: var(--mark);
  color: var(--on-lime);
}

.topbar .count,
.count {
  background: var(--surface-2);
  color: var(--text);
  border: 1.5px solid var(--control-edge);
  border-radius: 999px;
  padding: 0 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.5;
  min-width: 1.3rem;
  text-align: center;
}
/* Unread is lime. */
.topbar-tabs button .count:not(.warn) {
  background: var(--mark);
  color: var(--ink);
  border: 1.5px solid var(--lime-edge);
}
.topbar-tabs button.active .count:not(.warn) {
  background: var(--on-lime);
  color: var(--lime);
  border-color: var(--on-lime);
}
.topbar .count.warn,
.count.warn {
  background: var(--danger);
  color: var(--on-danger);
  border: 1.5px solid var(--danger);
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 0 0 auto;
}
.topbar-right .theme-toggle-compact {
  flex: none;
}
.topbar-name {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text-soft);
  max-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Account menu: avatar, name and a panel for dashboard, theme and sign-out. */
.account-menu {
  position: relative;
  flex: 0 0 auto;
}
.account-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--touch);
  padding: 0 0.4rem 0 0.2rem;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 999px;
  color: var(--text-soft);
  font: inherit;
  cursor: pointer;
}
.account-trigger:hover,
.account-trigger[aria-expanded="true"] {
  border-color: var(--edge);
  color: var(--text);
}
.account-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 232px;
  padding: 0.45rem;
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-hi);
  animation: menuIn 0.13s ease-out;
}
.account-who {
  display: flex;
  flex-direction: column;
  padding: 0.4rem 0.6rem 0.5rem;
  border-bottom: 2px solid var(--hairline);
  margin-bottom: 0.25rem;
}
.account-who-name {
  font-family: var(--font-head);
  font-weight: 800;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-who-handle {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-mute);
}
.account-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: var(--touch);
  padding: 0.45rem 0.7rem;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.account-item:hover {
  background: var(--mark);
  color: var(--ink);
}
.account-item.danger {
  color: var(--danger);
}
.account-item.danger:hover {
  background: var(--danger);
  color: var(--on-danger);
}
.account-section {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.4rem 0.6rem 0.5rem;
  border-top: 2px solid var(--hairline);
  border-bottom: 2px solid var(--hairline);
  margin: 0.25rem 0;
}
.account-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-mute);
}

.linkish {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  background: none;
  border: 0;
  color: var(--text-soft);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  text-decoration-color: var(--cyan);
  padding: 0 0.3rem;
}
.linkish:hover {
  color: var(--lime-ink);
}
.topbar-tabs a.linkish {
  text-decoration: none;
}

/* ------------------------------------------------------------------ *
 * Scope tabs (My gyms / Following / My city / Global)
 * ------------------------------------------------------------------ */

.scope-tabs {
  display: flex;
  gap: 0.25rem;
  overflow-x: auto;
  border-bottom: 2px solid var(--edge);
  scrollbar-width: none;
}
.scope-tabs::-webkit-scrollbar {
  display: none;
}
.scope-tabs button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--touch);
  background: transparent;
  border: 0;
  border-bottom: 4px solid transparent;
  margin-bottom: -2px;
  border-radius: 8px 8px 0 0;
  color: var(--text-soft);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  white-space: nowrap;
}
.scope-tabs button:hover {
  color: var(--text);
  background: var(--surface-2);
}
.scope-tabs button.active {
  color: var(--ink);
  background: var(--mark);
  border-bottom-color: var(--cyan);
  font-weight: 700;
}

/* ------------------------------------------------------------------ *
 * Avatars and community rows
 * ------------------------------------------------------------------ */

.social-avatar,
.topbar-avatar,
.composer-avatar,
.post-avatar,
.community-avatar {
  border: 2px solid var(--lime-edge);
  border-radius: 999px;
  object-fit: cover;
  background: var(--mark);
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-head);
  font-weight: 800;
  color: var(--ink);
  box-sizing: border-box;
}
.placeholder {
  font-size: 0.8rem;
}

.topbar-avatar {
  width: 32px;
  height: 32px;
}
.composer-avatar {
  width: 38px;
  height: 38px;
}
.post-avatar {
  width: 38px;
  height: 38px;
}
.community-avatar {
  width: 30px;
  height: 30px;
}
.community-avatar.lg {
  width: 42px;
  height: 42px;
}

.composer-top {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
}
.composer-top textarea {
  min-height: 76px;
}

.post-byline {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 0.3rem;
  min-width: 0;
  flex: 1 1 auto;
}
.post-byline strong {
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.post-byline .muted {
  font-size: 0.85rem;
}

.community-line {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
}
.community-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* A flex row, so the name truncates and the badge stays visible beside it. */
.community-meta strong {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.community-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.community-meta strong .badge {
  flex: none;
  margin-left: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
}

/* ------------------------------------------------------------------ *
 * Community browser
 * ------------------------------------------------------------------ */

.social-browse {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.browse-head h1 {
  margin: 0;
  font-size: clamp(1.7rem, 5vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.04em;
}
.browse-head p {
  margin: 0.3rem 0 0;
}
.browse-search {
  width: 100%;
  box-sizing: border-box;
  min-height: var(--touch);
  background: var(--field);
  border: 2px solid var(--control-edge);
  border-radius: 999px;
  color: var(--text);
  padding: 0.55rem 1.1rem;
  font: inherit;
}
.social-browse h3 {
  margin: 0.6rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--cyan);
}

.community-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}
.community-card {
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  align-items: flex-start;
  transition:
    transform 0.25s var(--ease),
    box-shadow 0.25s var(--ease);
}
.community-card:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--sh-cyan);
}
.community-blurb {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.88rem;
}

.browse-mine {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.empty {
  padding: 0.5rem 0;
}
.empty.big {
  padding: 2.5rem 1rem;
  text-align: center;
  background: transparent;
  border: 2px dashed var(--line-3);
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  align-items: center;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: -0.02em;
}
.empty.big p {
  margin: 0;
}
.empty.big p.small,
.empty.big .muted {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.9rem;
  letter-spacing: 0;
}
/* The AI mascot, used as a character in the empty states only. */
.empty-mascot {
  display: block;
  width: 96px;
  height: auto;
  margin-bottom: 0.25rem;
}

@media (max-width: 720px) {
  /* The header keeps only the brand and the account controls; the section nav
     moves to a bottom bar so all five destinations are on screen at once. */
  .topbar {
    gap: 0.5rem 0.75rem;
    padding: 0.6rem 0.9rem;
    /* backdrop-filter makes an element a containing block for its fixed
       descendants, which would pin the bottom nav inside the header instead of
       the viewport. Drop the blur and use an opaque bar. */
    background: rgb(var(--bar-rgb) / 0.98);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .topbar-name {
    display: none;
  }
  .topbar-right {
    margin-left: auto;
  }
  .topbar-logo {
    height: 22px;
  }

  .topbar-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    justify-content: space-around;
    gap: 0;
    padding: 0.35rem 0.35rem calc(0.35rem + env(safe-area-inset-bottom, 0px));
    background: rgb(var(--bar-rgb) / 0.94);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-top: 1px solid var(--line);
    border-bottom: 0;
    box-shadow: 0 -1px 0 rgba(182, 255, 0, 0.08);
  }
  .topbar-nav button {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.35rem 0.2rem;
    font-size: 0.62rem;
    letter-spacing: 0.02em;
    border-radius: 10px;
  }
  .topbar-nav button svg {
    width: 20px;
    height: 20px;
  }
  /*
   * A tapped tab keeps :hover on touch devices, and the desktop
   * `.topbar-tabs button.active:hover` rule outranks this one and fills the
   * button solid neon — leaving neon icon and text on neon, i.e. invisible.
   * Pin the active appearance across hover/focus so the tab stays readable.
   */
  .topbar-nav button.active,
  .topbar-nav button.active:hover,
  .topbar-nav button.active:focus-visible {
    background: rgba(182, 255, 0, 0.14);
    border-color: transparent;
    color: var(--lime-ink);
    box-shadow: none;
    text-shadow: none;
  }
  .topbar-nav button.active .count {
    background: var(--brand);
    color: var(--on-brand);
  }
  /* No grey tap flash on the bar. */
  .topbar-nav button {
    -webkit-tap-highlight-color: transparent;
  }
  /* The badge rides the icon, since the button is now a vertical stack. */
  .topbar-nav .count {
    position: absolute;
    top: 0.1rem;
    left: 50%;
    transform: translateX(0.35rem);
    margin: 0;
  }

  /* Only the feed page has the bottom bar; give it room so nothing hides under
     it, and leave the profile page (no bar) untouched. */
  .social-body:has(.topbar-nav) {
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px));
  }

  .social-shell {
    grid-template-columns: minmax(0, 1fr);
  }
  .social-main {
    padding: 1rem 0.9rem 1.5rem;
  }

  /* Four scope tabs fit once they share the row evenly instead of scrolling. */
  .scope-tabs {
    gap: 0.1rem;
  }
  .scope-tabs button {
    flex: 1 1 0;
    justify-content: center;
    min-width: 0;
    padding: 0.5rem 0.3rem;
    font-size: 0.8rem;
    gap: 0.25rem;
  }
}

/* ================================================================== *
 * Reactions
 * ================================================================== */

.react-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem;
}

.react {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-width: var(--touch);
  min-height: var(--touch);
  background: transparent;
  border: 2px solid transparent;
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--ink-soft);
  transition:
    transform 0.12s ease,
    background-color 0.15s ease,
    border-color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}
.react:hover {
  background: var(--surface-2);
  color: var(--text);
}
.react:active {
  transform: scale(0.92);
}

.react-icon {
  flex: none;
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.react:hover .react-icon {
  transform: scale(1.15) rotate(-6deg);
}

/* Selected is the highlighter. */
.react.on {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--ink);
  font-weight: 700;
  box-shadow: 2px 2px 0 var(--sh-cyan);
}
.react.on .react-icon {
  transform: scale(1.1);
}

.react-count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
}

/* Pop when a reaction is selected. */
.react.pop .react-icon {
  animation: reactPop 0.42s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes reactPop {
  0% {
    transform: scale(1);
  }
  35% {
    transform: scale(1.55) rotate(10deg);
  }
  60% {
    transform: scale(0.92) rotate(-6deg);
  }
  100% {
    transform: scale(1.1);
  }
}

/* Marker-circle pulse behind the selected reaction. */
.react.pulse::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 999px;
  border: 2px solid var(--cyan);
  animation: ringFade 0.5s ease-out forwards;
  pointer-events: none;
}
@keyframes ringFade {
  from {
    opacity: 0.9;
    transform: scale(0.85);
  }
  to {
    opacity: 0;
    transform: scale(1.5);
  }
}

/* Burst particles: ink-ringed so they read on paper. */
.burst {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7px;
  height: 7px;
  border: 0;
  border-radius: 999px;
  pointer-events: none;
  animation: burstOut 0.55s ease-out forwards;
}
@keyframes burstOut {
  0% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(var(--dx), var(--dy)) scale(0.2);
  }
}

/* ================================================================== *
 * Share
 * ================================================================== */

.share-wrap {
  position: relative;
}

.share {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-width: var(--touch);
  min-height: var(--touch);
  background: transparent;
  border: 2px solid transparent;
  border-radius: 999px;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.85rem;
  padding: 0.2rem 0.6rem;
  cursor: pointer;
  transition:
    transform 0.12s ease,
    background-color 0.15s ease;
}
.share:hover {
  background: var(--surface-2);
  color: var(--text);
}
.share:active {
  transform: scale(0.92);
}
.share.done {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--ink);
  animation: shareCheck 0.5s ease;
}
@keyframes shareCheck {
  0% {
    transform: scale(1);
  }
  40% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.share-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  z-index: 30;
  min-width: 230px;
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  padding: 0.35rem;
  box-shadow: var(--shadow-hi);
  animation: menuIn 0.16s ease-out;
}
@keyframes menuIn {
  from {
    opacity: 0;
    transform: translateY(6px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
.share-menu button {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: var(--touch);
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  padding: 0.5rem 0.7rem;
  cursor: pointer;
  text-align: left;
}
.share-menu button:hover {
  background: var(--mark);
  color: var(--on-lime);
}
.share-menu .emoji {
  font-size: 1.05rem;
}
.share-menu .emoji {
  font-size: 1.05rem;
}

/* Toast: an ink strip with a lime sticker shadow. */
.toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  z-index: 60;
  max-width: calc(100vw - 2rem);
  background: var(--surface-2);
  color: var(--text);
  border: 2px solid var(--lime-edge);
  border-radius: 999px;
  padding: 0.65rem 1.3rem;
  font-weight: 600;
  font-size: 0.92rem;
  box-shadow: 4px 4px 0 var(--lime-edge);
  animation: toastIn 0.25s ease-out;
}
@keyframes toastIn {
  from {
    opacity: 0;
    transform: translate(-50%, 12px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

/* ================================================================== *
 * Comments
 * ================================================================== */

.comment-compose {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  margin: 0.5rem 0 0.9rem;
}
.comment-compose textarea {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--touch);
  max-height: 180px;
  resize: vertical;
  background: var(--field);
  border: 2px solid var(--control-edge);
  border-radius: 12px;
  color: var(--text);
  padding: 0.6rem 0.8rem;
  font: inherit;
}

.comment {
  padding: 0.8rem 0;
  border-top: 1px solid var(--line);
}
.comment-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.2rem 0.4rem;
  margin-bottom: 0.2rem;
}
.comment-head strong {
  font-family: var(--font-head);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.comment-body {
  margin: 0 0 0.35rem;
  white-space: pre-wrap;
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}
.comment-actions {
  display: flex;
  gap: 0.25rem;
  align-items: center;
}
.comment-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-width: var(--touch);
  min-height: var(--touch);
  background: none;
  border: 2px solid transparent;
  color: var(--ink-soft);
  font: inherit;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  transition: background-color 0.15s ease;
}
.comment-action:hover {
  background: var(--surface-2);
  color: var(--text);
}
.comment-action.on {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--ink);
  font-weight: 500;
}
/* A count on the profile page is a read-out, not a button. */
span.comment-action {
  cursor: default;
}
span.comment-action:hover {
  background: none;
}

.replies {
  margin-left: 1.1rem;
  padding-left: 0.8rem;
  border-left: 3px solid var(--lime-edge);
}
.reply-compose {
  display: flex;
  gap: 0.4rem;
  margin: 0.4rem 0 0.2rem;
}
.reply-compose input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--touch);
  box-sizing: border-box;
  background: var(--field);
  border: 2px solid var(--control-edge);
  border-radius: 999px;
  color: var(--text);
  padding: 0.35rem 1rem;
  font: inherit;
  font-size: 0.92rem;
}

.comment-count {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

/* ================================================================== *
 * Lightbox
 * ================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(5, 8, 15, 0.95);
  display: grid;
  place-items: center;
  padding: 2rem;
  animation: fadeIn 0.18s ease-out;
  cursor: zoom-out;
}
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.lightbox img {
  max-width: 100%;
  max-height: 100%;
  border: 2px solid var(--edge);
  border-radius: 10px;
  animation: zoomIn 0.22s var(--ease);
}
@keyframes zoomIn {
  from {
    transform: scale(0.94);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}
.lightbox-close {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  background: none;
  border: 0;
  color: var(--text);
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}

.media-thumb {
  cursor: zoom-in;
  transition: transform 0.2s var(--ease);
}
.media-thumb:hover {
  transform: translate(-1px, -1px);
}

/* ================================================================== *
 * Modal
 * ================================================================== */

.modal-scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--modal-scrim);
  display: grid;
  place-items: center;
  padding: 1.5rem;
  animation: fadeIn 0.16s ease-out;
}
.modal {
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  width: min(680px, 100%);
  max-height: 86vh;
  overflow-y: auto;
  padding: 1.3rem;
  position: relative;
  animation: modalIn 0.22s var(--ease);
}
@keyframes modalIn {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
.modal h2 {
  margin: 0 2.5rem 0.7rem 0;
  font-size: 1.45rem;
  font-weight: 800;
  letter-spacing: -0.035em;
}
.modal-close {
  position: absolute;
  top: 0.35rem;
  right: 0.45rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  background: none;
  border: 0;
  color: var(--text);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}
.modal-close:hover {
  color: var(--lime-ink);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-bottom: 0.8rem;
}
.field label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cyan);
}
.field input,
.field textarea,
.field select {
  background: var(--field);
  border: 2px solid var(--control-edge);
  border-radius: 10px;
  color: var(--text);
  min-height: var(--touch);
  box-sizing: border-box;
  padding: 0.55rem 0.75rem;
  font: inherit;
}
.field textarea {
  min-height: 88px;
}

/* Lists of people, notifications and chats are ruled lists, not cards. */
.person-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.65rem 0;
  border-top: 2px solid var(--edge);
}
.person-row:first-child {
  border-top: 0;
}
.person-row.clickable {
  cursor: pointer;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  margin: 0 -0.5rem;
  transition: background-color 0.15s;
}
.person-row.clickable:hover {
  background: var(--surface-2);
}
.person-row.clickable.read {
  opacity: 0.7;
}
/* Unread alerts carry the lime tick. */
.person-row.clickable.unread {
  box-shadow: inset 5px 0 0 var(--lime-edge);
}
.person-row.active {
  background: var(--mark);
  color: var(--on-lime);
}
.person-row.active:hover {
  background: var(--mark);
  color: var(--on-lime);
}
.person-meta {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.person-meta strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-head);
  font-size: 0.98rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.7rem;
}

/* Direct messages. Mine is lime, theirs is paper, both inked. */
.chat-log {
  max-height: 320px;
  overflow-y: auto;
  margin-bottom: 0.6rem;
  padding: 0.2rem 0.25rem 0.4rem 0;
}
.chat-row {
  display: flex;
  justify-content: flex-start;
  margin: 0.4rem 0;
}
.chat-row.mine {
  justify-content: flex-end;
}
.chat-bubble {
  max-width: 78%;
  padding: 0.5rem 0.85rem;
  background: var(--surface-2);
  color: var(--text);
  border: 2px solid var(--edge);
  border-radius: 16px 16px 16px 4px;
  font-size: 0.93rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.chat-row.mine .chat-bubble {
  background: var(--mark);
  border-radius: 16px 16px 4px 16px;
  box-shadow: 2px 2px 0 var(--sh-cyan);
  color: var(--on-lime);
}

/* ================================================================== *
 * Footer
 * ================================================================== */

.social-footer {
  position: relative;
  background: var(--surface);
  color: var(--text);
  overflow: hidden;
  padding-bottom: 2.5rem;
  margin-top: 2rem;
  border-top: 2px solid var(--edge);
}

.heartbeat {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 1rem;
}
.heartbeat svg path {
  stroke: var(--lime-edge);
}
.heartbeat-icon {
  position: absolute;
  top: -0.75rem;
  color: var(--lime-ink);
}

/* brand.css (linked after this file) also defines .neon-divider and .neon-link
   in the old neon style, so these are scoped to the footer to win on specificity. */
.social-footer .neon-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60px;
  position: relative;
  z-index: 1;
}
.social-footer .neon-divider::before,
.social-footer .neon-divider::after {
  content: "";
  height: 2px;
  width: 100%;
  max-width: 45%;
  background: var(--edge);
  box-shadow: none;
}

.footer-inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
  max-width: 1180px;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 0;
}
@media (min-width: 760px) {
  .footer-inner {
    grid-template-columns: 1.5fr 0.8fr 0.8fr 0.8fr;
    gap: 2.5rem;
  }
}

.footer-tagline {
  font-family: var(--font-head);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1.05;
  color: var(--text);
  margin: 0 0 0.9rem;
}
.footer-blurb {
  margin: 0;
  max-width: 34ch;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-soft);
}

.footer-heading {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--cyan);
  margin: 0 0 1rem;
}

.footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.95rem;
}

.footer-rule {
  position: relative;
  z-index: 1;
  height: 2px;
  width: calc(100% - 2.5rem);
  max-width: 1180px;
  margin: 2.5rem auto 0;
  background: var(--hairline);
}

.footer-copy {
  position: relative;
  z-index: 1;
  text-align: center;
  margin: 1.5rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--text-mute);
}
.footer-copy span {
  color: var(--text);
  font-weight: 500;
}

/* Footer links: soft text, with the lime highlighter drawing in on hover. */
.social-footer .neon-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  color: var(--text-soft);
  font-weight: 600;
  text-decoration: none;
  transition: color 0.2s;
}
.social-footer .neon-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  width: auto;
  bottom: 9px;
  height: 6px;
  background: var(--mark);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
  z-index: -1;
}
.social-footer .neon-link:hover {
  color: var(--on-lime);
  transform: none;
}
.social-footer .neon-link:hover::after {
  width: auto;
  transform: scaleX(1);
}
/* the highlighter sits behind the text, so the link needs its own stacking context */
.footer-links li {
  isolation: isolate;
}

/* ================================================================== *
 * Overflow ("three dots") menu
 * ================================================================== */

.icon-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  padding: 0;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 999px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.icon-action:hover {
  background: var(--surface-2);
  color: var(--text);
}
.icon-action[aria-expanded="true"] {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--ink);
}

.overflow-menu {
  min-width: 200px;
  padding: 0.35rem;
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-hi);
  animation: menuIn 0.13s ease-out;
}

.overflow-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: var(--touch);
  padding: 0.45rem 0.7rem;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.overflow-item:hover {
  background: var(--mark);
  color: var(--ink);
}
.overflow-item.danger {
  color: var(--danger);
}
.overflow-item.danger:hover {
  background: var(--danger);
  color: var(--on-danger);
}

/* ================================================================== *
 * Media dropzone
 * ================================================================== */

.media-zone {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1 1 100%;
  min-width: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.drop-target {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  min-height: var(--touch);
  padding: 0.6rem 0.8rem;
  background: transparent;
  border: 2px dashed var(--line-3);
  border-radius: 12px;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease;
}
.drop-target:hover:not(:disabled) {
  border-color: var(--text-soft);
  background: var(--surface-2);
  color: var(--text);
}
.drop-target.over {
  border-color: var(--lime-edge);
  border-style: solid;
  background: var(--mark);
  color: var(--ink);
  box-shadow: 3px 3px 0 var(--sh-cyan);
}
.drop-target:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.media-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.media-preview li {
  position: relative;
  width: 68px;
  height: 68px;
  border-radius: 10px;
  border: 2px solid var(--lime-edge);
  box-shadow: 2px 2px 0 var(--sh-cyan);
}
.media-preview img,
.media-preview video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 8px;
}
/* Remove: a small visible disc with a 44px hit area around it. */
.media-preview button {
  position: absolute;
  top: -10px;
  right: -10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 999px;
  color: var(--text);
  cursor: pointer;
}
.media-preview button::before {
  content: "";
  position: absolute;
  inset: -9px;
}
.media-preview button:hover {
  background: var(--danger);
  color: var(--on-danger);
}

.media-error {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--danger);
}

/* Composer guidance. Replaces a silently disabled Post button. */
.composer-hint {
  margin: 0.2rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.composer-hint .linkish {
  font-size: 0.9rem;
}

/* Icon sizing for the panels and dialogs that lost their emoji. */
.empty-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  margin-bottom: 0.4rem;
}

.notif-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  background: var(--field);
  border: 2px solid var(--edge);
  color: var(--text);
}

.share-menu button,
.overflow-item {
  align-items: center;
}

/* ================================================================== *
 * Profile page shell
 *
 * The profile component's own styles live in profile.css so the gym dashboard
 * can render the same ProfileView without pulling in this file's broad
 * .btn / .field / .row rules, which would break its Tailwind layout.
 * profile.css is dark-theme and shared with the dashboard, so it is not edited;
 * the Whiteboard overrides for it are at the end of this file, scoped under
 * .social-body so they cannot leak into the dashboard.
 * ================================================================== */

.profile-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 1.25rem 1.25rem 4rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.profile-topline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.profile-posts {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.profile-page .linkish {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.profile-page .linkish.danger {
  color: var(--danger);
}

/* Avatar and name are the affordance into a profile, from either app. */
.profile-link {
  display: inline-flex;
  border-radius: 999px;
  transition: transform 0.2s var(--ease);
}
.profile-link:hover {
  transform: translate(-1px, -1px);
}
.profile-link:hover .post-avatar {
  box-shadow: 2px 2px 0 var(--sh-cyan);
}
.profile-link.strong {
  color: var(--text);
  text-decoration: none;
  font-weight: 700;
  border-radius: 6px;
}
.profile-link.strong:hover {
  color: var(--lime-ink);
  text-decoration: underline;
  text-decoration-color: var(--lime-edge);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  text-shadow: none;
}
.post-avatar {
  transition: box-shadow 0.18s ease;
}

/* The modal reads a post at a larger size than the feed. */
.modal-body {
  font-size: 1.05rem;
}

/* ================================================================== *
 * Mentions
 * ================================================================== */

/* A mention is highlighted like a name circled on the board. */
.mention-link {
  color: var(--lime-ink);
  text-decoration: none;
  font-weight: 700;
  border-radius: 3px;
  padding: 0 0.1em;
}
.mention-link:hover {
  background: rgba(185, 242, 0, 0.16);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.mention-menu {
  position: absolute;
  z-index: 30;
  left: 0.9rem;
  right: 0.9rem;
  bottom: calc(100% + 6px);
  max-height: 240px;
  overflow-y: auto;
  padding: 0.3rem;
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow-hi);
}

.mention-option {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: var(--touch);
  padding: 0.4rem 0.55rem;
  background: transparent;
  border: 0;
  border-radius: 9px;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: var(--text);
}
.mention-option.active,
.mention-option:hover {
  background: var(--mark);
  color: var(--ink);
}
.mention-option-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.mention-option-meta strong {
  font-family: var(--font-head);
  font-size: 0.92rem;
}
.pad-sm {
  padding: 0.5rem 0.6rem;
}

/* ================================================================== *
 * Thread sidepanel
 * ================================================================== */

/* The bar above the thread: back on the left, community on the right. */
.thread-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.4rem 0.75rem;
  border-bottom: 2px solid var(--edge);
  background: var(--bg-page);
  flex: none;
}
.thread-head-title {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.thread-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  flex: none;
  padding: 0;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 999px;
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.thread-back:hover {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--on-lime);
}

.thread-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(420px, 100vw);
  z-index: 45;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border-left: 2px solid var(--edge);
  box-shadow: -6px 0 0 var(--cyan-soft);
  animation: threadSlide 0.22s ease-out;
}
@keyframes threadSlide {
  from {
    transform: translateX(16px);
    opacity: 0;
  }
}

.social-shell {
  transition: grid-template-columns 0.22s ease;
  padding-right: 0;
}
.social-shell.with-thread {
  /* Rail plus a narrower feed, leaving room for the docked panel. */
  grid-template-columns: 260px minmax(0, 1fr);
  padding-right: 420px;
}

.thread-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(420px, 100vw);
  z-index: 45;
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border-left: 1px solid var(--line-2);
  box-shadow: -18px 0 40px -20px rgb(var(--drop-rgb) / calc(0.9 * var(--drop-k)));
  animation: threadSlide 0.22s ease-out;
}
@keyframes threadSlide {
  from {
    transform: translateX(16px);
    opacity: 0;
  }
}

.thread-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 1rem 0;
}

/* The post under discussion is the subject of the panel. */
.thread-parent {
  padding-bottom: 1rem;
  border-bottom: 2px solid var(--edge);
}
.thread-author {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
}
.thread-body {
  margin: 0.6rem 0 0;
  font-size: 1.02rem;
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.thread-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.8rem;
}

/* The reply box follows you down a long thread, on a solid card. */
.thread-panel .comment-compose {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin: 0.5rem -1rem 0;
  padding: 0.7rem 1rem;
  background: var(--card);
  border-top: 2px solid var(--edge);
}

@media (max-width: 1080px) {
  /* No room to dock beside the feed: go full width instead of squeezing both. */
  .social-shell.with-thread {
    padding-right: 0;
  }
  .thread-panel {
    width: min(460px, 100vw);
  }
}

/* ================================================================== *
 * Small screens (390px first)
 * ================================================================== */

@media (max-width: 840px) {
  .social-shell,
  .social-shell.with-thread {
    grid-template-columns: 1fr;
    min-height: 0;
    align-content: start;
  }
  /* The feed is what people came for: the gyms / requests rail goes below it. */
  .social-rail {
    order: 2;
    border-right: 0;
    border-top: 2px solid var(--edge);
  }
}

@media (max-width: 720px) {
  .thread-panel {
    width: 100vw;
    border-left: 0;
  }

  /* Brand + account on the first line, the tabs get a full-width second line. */
  .topbar {
    flex-wrap: wrap;
    padding: 0.4rem 1rem 0;
    gap: 0 0.75rem;
  }
  .topbar-brand {
    order: 1;
  }
  .topbar-right {
    order: 2;
    margin-left: auto;
  }
  .topbar-tabs {
    order: 3;
    flex: 1 0 100%;
    margin: 0 -1rem;
    padding: 4px 1rem 8px;
    border-top: 1px solid var(--line);
  }

  .social-main {
    padding: 1rem 1rem 3rem;
    gap: 1rem;
  }
  .social-composer,
  .social-post {
    padding: 0.85rem;
  }
  .social-feed {
    gap: 1.1rem;
  }
  .modal-scrim {
    padding: 0.75rem;
  }
  .modal {
    padding: 1.1rem;
  }
  .profile-page {
    padding: 1rem 1rem 3rem;
  }
}

/* The emoji grid becomes a bottom sheet on a phone, where a 248px popover
   anchored to a mid-row button would run off the right edge. */
@media (max-width: 520px) {
  .emoji-panel,
  .emoji-panel.below {
    position: fixed;
    top: auto;
    left: 0.75rem;
    right: 0.75rem;
    bottom: 0.75rem;
    width: auto;
    max-width: 380px;
    margin: 0 auto;
    box-shadow: var(--shadow-lg);
  }
  .emoji-grid {
    grid-template-columns: repeat(8, 1fr);
  }
  .emoji-cell {
    min-height: 40px;
  }
  .composer-top textarea {
    min-height: 88px;
  }
}

/* ================================================================== *
 * Whiteboard overrides for profile.css
 *
 * profile.css is shared with the gym dashboard (member drawer) and is still
 * written for the old dark theme: lime used as *text*, neon glows, a gradient
 * cover. Overridden here, under .social-body, so the dashboard is untouched.
 * Most of it already follows via the re-pointed tokens; this is the rest.
 * ================================================================== */

.social-body .profile-header {
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 16px;
  box-shadow: var(--shadow-lg);
}
.social-body .profile-cover {
  height: 132px;
  background-color: var(--mark);
  border-bottom: 2px solid var(--cyan);
  color: var(--on-lime);
}
/* No cover photo: flat lime, the highlighter, instead of the neon gradient. */
.social-body .profile-cover-fallback {
  height: 130px;
  border-bottom: 0;
  background: var(--mark);
  background-image: radial-gradient(rgba(5, 8, 15, 0.2) 1.2px, transparent 1.4px);
  background-size: 16px 16px;
  color: var(--on-lime);
}
.social-body .profile-avatar {
  border: 3px solid var(--bg-page);
  box-shadow: 3px 3px 0 var(--sh-cyan);
  background: var(--mark);
  color: var(--on-lime);
}
.social-body .profile-avatar .placeholder {
  font-family: var(--font-head);
  font-weight: 800;
  color: var(--ink);
}
.social-body .profile-names h1 {
  font-size: clamp(1.6rem, 6vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.04em;
}
.social-body .profile-title {
  color: var(--lime-ink);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.social-body .profile-self-tag {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--ink);
  background: var(--mark);
  border: 2px solid var(--lime-edge);
}
.social-body .profile-bio {
  color: var(--text);
  font-size: 1rem;
}
.social-body .profile-facts {
  color: var(--ink-soft);
}
.social-body .profile-block,
.social-body .profile-counts,
.social-body .profile-guard {
  border-top: 2px solid var(--edge);
}
.social-body .profile-block-title {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--cyan);
}
.social-body .profile-posts > .profile-block-title {
  margin: 0;
}
.social-body .profile-credentials li {
  color: var(--text);
}
.social-body .profile-credentials svg {
  color: var(--lime-ink);
}
.social-body .profile-stat {
  background: var(--field);
  border: 2px solid var(--edge);
  border-radius: 12px;
}
.social-body .profile-stat svg {
  color: var(--ink-soft);
}
.social-body .profile-stat.neon {
  background: var(--mark);
  border-color: var(--lime-edge);
  box-shadow: 3px 3px 0 var(--sh-cyan);
  color: var(--on-lime);
}
.social-body .profile-stat.neon svg {
  color: var(--ink);
}
.social-body .profile-stat-value {
  font-family: var(--font-head);
  font-weight: 800;
  letter-spacing: -0.03em;
}
.social-body .profile-stat-label {
  font-family: var(--font-mono);
  color: var(--ink-soft);
}
.social-body .pill {
  border: 2px solid var(--control-edge);
  background: var(--field);
  color: var(--text);
  font-weight: 600;
}
.social-body .pill a:hover {
  color: var(--lime-ink);
  text-decoration: underline;
}
.social-body .pill.neon {
  background: var(--mark);
  border-color: var(--lime-edge);
  color: var(--ink);
  box-shadow: none;
}
.social-body .pill.muted-pill {
  color: var(--ink-soft);
}
.social-body .profile-counts dt {
  color: var(--ink-soft);
}
.social-body .profile-counts dd {
  font-family: var(--font-mono);
  font-weight: 500;
}
.social-body .profile-post-community {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.social-body .profile-post-community a {
  color: var(--cyan);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--cyan);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.social-body .profile-post-community a:hover {
  color: var(--lime-ink);
  text-shadow: none;
}
.social-body .profile-editor {
  background: var(--card);
  border: 2px solid var(--edge);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.social-body .profile-empty {
  color: var(--ink-soft);
}
.social-body .profile-tabs {
  border-bottom: 2px solid var(--edge);
  overflow-x: auto;
}
.social-body .profile-tabs button {
  min-height: var(--touch);
  margin-bottom: -2px;
  border-bottom-width: 4px;
  border-radius: 8px 8px 0 0;
  color: var(--ink-soft);
  font-size: 0.92rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  white-space: nowrap;
}
.social-body .profile-tabs button:hover {
  color: var(--text);
  background: var(--surface-2);
}
.social-body .profile-tabs button.active {
  color: var(--ink);
  background: var(--mark);
  border-bottom-color: var(--cyan);
  font-weight: 700;
}
.social-body .profile-tabs button:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: -3px;
}
.social-body .connection-list li + li {
  border-top: 1px solid var(--line);
}
.social-body .profile-actions {
  flex-wrap: wrap;
}
/* Beside the avatar, the name starts below the cover edge instead of straddling it. */
@media (min-width: 560px) {
  .social-body .profile-id {
    align-items: flex-start;
  }
  .social-body .profile-names,
  .social-body .profile-actions {
    padding-top: 3.4rem;
  }
}

/* ================================================================== *
 * Motion
 * ================================================================== */

@media (prefers-reduced-motion: reduce) {
  .social-body *,
  .social-body *::before,
  .social-body *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }
  .burst,
  .react.pulse::after {
    display: none;
  }
  .react:hover .react-icon,
  .btn:hover,
  .tiny:hover,
  .community-card:hover {
    transform: none !important;
  }
}

/* Text that sits on a lime fill is always the page dark, including secondary
   text that would otherwise inherit a muted grey. */
.person-row.active .muted,
.person-row.active .person-meta strong,
.mention-option.active .muted,
.profile-stat.neon .profile-stat-label,
.profile-stat.neon .profile-stat-value {
  color: var(--on-lime);
}
.social-body .profile-stat.neon .profile-stat-label,
.social-body .profile-stat.neon .profile-stat-value {
  color: var(--on-lime);
}

/* ------------------------------------------------------------------ *
 * Guest view: inline sign-in in the header, sign-up in a dialog.
 * ------------------------------------------------------------------ */
.guest-right {
  flex: 1 1 auto;
  justify-content: flex-end;
  min-width: 0;
}
.guest-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-left: auto;
}
.guest-bar input {
  width: 11.5rem;
  min-height: 2.25rem;
  padding: 0.4rem 0.7rem;
  border: 2px solid var(--edge);
  border-radius: 999px;
  background: var(--card);
  color: inherit;
  font: inherit;
  font-size: 0.9rem;
}
.guest-bar input:focus {
  outline: none;
  border-color: var(--lime-edge);
}
.guest-bar .btn {
  min-height: 2.25rem;
  padding: 0.4rem 0.9rem;
}
.guest-bar-error {
  flex-basis: 100%;
  margin: 0;
  text-align: right;
  font-size: 0.82rem;
  color: var(--warn);
}
.guest-main {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 4rem;
}
.guest-hero {
  display: grid;
  gap: 0.6rem;
  margin-bottom: 2rem;
}
.guest-hero h1 {
  margin: 0;
  font-family: var(--font-head);
  font-size: clamp(1.8rem, 4vw, 2.4rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
}
.guest-heading {
  margin: 0 0 0.75rem;
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 700;
}
.guest-note {
  color: var(--muted);
  font-size: 0.92rem;
}
.guest-communities {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}
.guest-communities a {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 1rem;
  border: 2px solid var(--edge);
  border-radius: 12px;
  background: var(--card);
  color: inherit;
  text-decoration: none;
}
.guest-communities a:hover {
  border-color: var(--lime-edge);
}
.guest-community-name {
  font-family: var(--font-head);
  font-weight: 700;
}
.guest-community-meta {
  color: var(--muted);
  font-size: 0.82rem;
  white-space: nowrap;
}

.dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: rgb(0 0 0 / 0.6);
}
.dialog {
  position: relative;
  max-height: 92vh;
  overflow: auto;
  border-radius: 14px;
}
.dialog .join-card {
  box-shadow: var(--shadow-lg);
}
.dialog-close {
  position: absolute;
  top: 0.6rem;
  right: 0.7rem;
  z-index: 1;
  width: 2rem;
  height: 2rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

@media (max-width: 720px) {
  .guest-bar input {
    width: 100%;
    flex: 1 1 100%;
  }
  .guest-bar .btn {
    flex: 1 1 auto;
  }
}

/* ================================================================== *
 * Phones
 *
 * The rail is already gone below 840px and the topbar reflows below
 * 720px; what is left is the furniture that assumed a desktop gutter —
 * dialogs, the thread panel, nested replies and the toast.
 * ================================================================== */

@media (max-width: 720px) {
  /* Full-bleed panels: a dialog's desktop gutter eats most of a phone width. */
  .modal-scrim {
    padding: 0.75rem;
  }
  .modal {
    padding: 1rem;
    max-height: 90vh;
  }
  .lightbox {
    padding: 1rem;
  }
  .lightbox-close {
    top: 0.5rem;
    right: 0.6rem;
  }

  /* Popovers never grow wider than the space they open into. */
  .emoji-panel {
    width: min(232px, calc(100vw - 2rem));
  }
  .share-menu {
    min-width: 200px;
  }

  /* Nested replies keep a visible thread line without eating the body width. */
  .replies {
    margin-left: 0.5rem;
    padding-left: 0.5rem;
  }

  .thread-scroll {
    padding: 0.9rem 0.9rem 0;
  }

  /* A toast pinned to the centre must not run off the sides. */
  .toast {
    max-width: calc(100vw - 2rem);
    text-align: center;
  }

  /* Scrollable strips lose their scrollbar chrome; the cut-off pill is the cue. */
  .scope-tabs,
  .topbar-tabs {
    scrollbar-width: none;
  }
  .scope-tabs::-webkit-scrollbar,
  .topbar-tabs::-webkit-scrollbar {
    display: none;
  }

  /* Comfortable tap targets for the icon-only controls. */
  .icon-action,
  .thread-back {
    width: 34px;
    height: 34px;
  }

  /* In the thread the full timestamp competes with the author for one line and
     splits the name in two; give the date its own line instead. */
  .thread-parent .post-byline {
    flex-wrap: wrap;
    row-gap: 0.15rem;
  }
  .thread-parent .post-byline > .muted {
    flex-basis: 100%;
  }

  .social-media {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  }
}
