/*
 * TownSquare embed stylesheet.
 *
 * Scoped to the widget mount point so external host pages are not restyled.
 * TownSquare host pages also load page.css for full-page chrome.
 */
@import url("./tokens.css");

#townsquare-root {
  color-scheme: light;
  font-family: var(--font);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

#townsquare-root[data-townsquare-theme="auto"] {
  color-scheme: light dark;
}

#townsquare-root[data-townsquare-theme="dark"] {
  color-scheme: dark;
}

#townsquare-root,
#townsquare-root * {
  box-sizing: border-box;
}

.townsquare {
  --ts-stage-height: 180px;
  /* Space below the stage for the touch toolbar (see .townsquare__toolbar). */
  --ts-toolbar-reserve: 80px;
  /* The scene's vertical anchor. --ts-ground-offset is the height of the ground
     band from the stage's bottom edge; the band's 1px top border is the ground
     line, so the walkable plane is the band's top edge — exactly --ts-ground-offset
     up. A fixed px so it holds at any stage height, including the tall expanded
     stage. --ts-ground-level is that same plane, named for what stands on it:
     every prop/figure is bottom-anchored to it, and every SVG's art is authored
     to reach its viewBox bottom edge (see the props in site-config-core.mjs and
     figure.mjs), so element bottom = art baseline = the line, at any scale. The
     fixed-px stroke rounding (vector-effect: non-scaling-stroke) overlaps the
     1px line slightly, which is what "standing on the line" looks like. */
  --ts-ground-offset: 52px;
  --ts-ground-level: var(--ts-ground-offset);
  /* Bench seat plank height above the plane: plank centerline y=8 in the 18-unit
     bench art rendered 1:1 px (site-config-core.mjs BENCH_SVG). */
  --ts-bench-seat-height: 10px;
  position: relative;
  min-height: calc(var(--ts-stage-height) + var(--ts-toolbar-reserve));
  overflow: hidden;
}

.townsquare__controls {
  position: absolute;
  z-index: 2147483001;
  top: 8px;
  right: 4px;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 6px;
}

.townsquare__control {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin: 0;
  padding: 0;
  border: 1px solid color-mix(in oklab, var(--hair-2) 76%, transparent);
  border-radius: 8px;
  background: color-mix(in oklab, var(--surface) 78%, transparent);
  color: var(--ink-soft);
  box-shadow: 0 4px 12px -10px rgba(42, 41, 38, 0.38);
  backdrop-filter: blur(8px);
  cursor: pointer;
}

.townsquare__control:hover,
.townsquare__control:focus-visible,
.townsquare__control--active {
  color: var(--ink);
  border-color: var(--hair-2);
  background: var(--surface);
}

.townsquare__control:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--you) 48%, transparent);
  outline-offset: 2px;
}

.townsquare__control:disabled {
  opacity: 0.42;
  cursor: default;
}

.townsquare__control svg {
  width: 16px;
  height: 16px;
}

.townsquare__enable-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 36px;
  height: 30px;
  margin: 0;
  cursor: pointer;
}

.townsquare__enable-toggle-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.townsquare__enable-toggle-track {
  position: relative;
  display: block;
  width: 36px;
  height: 20px;
  border: 1px solid color-mix(in oklab, var(--hair-2) 76%, transparent);
  border-radius: 999px;
  background: color-mix(in oklab, var(--surface) 78%, transparent);
  box-shadow: 0 4px 12px -10px rgba(42, 41, 38, 0.38);
  backdrop-filter: blur(8px);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.townsquare__enable-toggle-track::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 3px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ink-soft);
  transform: translateY(-50%);
  transition: transform 0.15s ease, background 0.15s ease;
}

.townsquare__enable-toggle-input:checked + .townsquare__enable-toggle-track {
  background: color-mix(in oklab, var(--you) 32%, var(--surface));
  border-color: color-mix(in oklab, var(--you) 48%, var(--hair-2));
}

.townsquare__enable-toggle-input:checked + .townsquare__enable-toggle-track::after {
  transform: translate(16px, -50%);
  background: var(--you-deep);
}

.townsquare__enable-toggle-input:focus-visible + .townsquare__enable-toggle-track {
  outline: 2px solid color-mix(in oklab, var(--you) 48%, transparent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .townsquare__enable-toggle-track,
  .townsquare__enable-toggle-track::after {
    transition: none;
  }
}

.townsquare__actions {
  position: absolute;
  z-index: 2147483001;
  right: 8px;
  bottom: 12px;
  display: flex;
  gap: 8px;
}

.townsquare__action {
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  margin: 0;
  padding: 0;
  border: 1px solid color-mix(in oklab, var(--hair-2) 76%, transparent);
  border-radius: 8px;
  background: color-mix(in oklab, var(--surface) 84%, transparent);
  color: var(--ink);
  box-shadow: 0 8px 20px -14px rgba(42, 41, 38, 0.42);
  backdrop-filter: blur(8px);
  cursor: pointer;
  font: 700 18px/1 var(--font);
}

.townsquare__action:hover,
.townsquare__action:focus-visible {
  border-color: var(--hair-2);
  background: var(--surface);
}

.townsquare__action:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--you) 48%, transparent);
  outline-offset: 2px;
}

.townsquare__action svg {
  width: 19px;
  height: 19px;
}

.townsquare__reaction-dock {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
}

.townsquare__reaction-tray {
  position: absolute;
  right: 0;
  bottom: calc(100% + 8px);
  z-index: 2;
  display: grid;
  gap: 8px;
  padding: 7px;
  border: 1px solid color-mix(in oklab, var(--hair-2) 76%, transparent);
  border-radius: 8px;
  background: color-mix(in oklab, var(--surface) 92%, transparent);
  box-shadow: var(--tray-shadow);
  backdrop-filter: blur(12px);
}

.townsquare__reaction-tray[hidden] {
  display: none;
}

.townsquare__reaction-group {
  display: grid;
  grid-template-columns: repeat(3, 34px);
  gap: 6px;
}

.townsquare__reaction-group--invites {
  border-top: 1px solid color-mix(in oklab, var(--hair-2) 58%, transparent);
  padding-top: 7px;
}

.townsquare__reaction-group-label {
  grid-column: 1 / -1;
  margin: 0 1px -1px;
  color: var(--ink-faint);
  font: 800 0.64rem/1 var(--font);
  letter-spacing: 0;
  text-transform: uppercase;
}

.townsquare__reaction-option {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  min-height: 34px;
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  box-shadow: none;
  cursor: pointer;
  font: 700 1.08rem/1 var(--font);
}

.townsquare__reaction-option:hover,
.townsquare__reaction-option:focus-visible {
  background: color-mix(in oklab, var(--ink) 7%, transparent);
  outline: none;
}

.townsquare__reaction-option:focus-visible {
  box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--you) 40%, transparent);
}

.townsquare__courtship-prompt {
  position: absolute;
  left: 50%;
  bottom: 60px;
  z-index: 2147483003;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: min(calc(100% - 24px), 360px);
  min-height: 38px;
  padding: 5px 6px 5px 12px;
  border: 1px solid color-mix(in oklab, var(--hair-2) 66%, transparent);
  border-radius: 999px;
  background: color-mix(in oklab, var(--surface) 90%, transparent);
  box-shadow: var(--tray-shadow);
  backdrop-filter: blur(14px);
  transform: translateX(-50%);
}

.townsquare__courtship-prompt[hidden] {
  display: none;
}

.townsquare__courtship-text {
  min-width: 0;
  overflow: hidden;
  color: var(--ink);
  font: 750 0.8rem/1.15 var(--font);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.townsquare__courtship-accept,
.townsquare__courtship-dismiss {
  display: inline-grid;
  place-items: center;
  height: 28px;
  min-height: 28px;
  margin: 0;
  border: 1px solid transparent;
  border-radius: 999px;
  box-shadow: none;
  cursor: pointer;
  font: 800 0.74rem/1 var(--font);
}

.townsquare__courtship-accept {
  padding: 0 10px;
  background: var(--you);
  color: var(--surface);
}

.townsquare__courtship-dismiss {
  width: 28px;
  padding: 0;
  background: color-mix(in oklab, var(--ink) 7%, transparent);
  color: var(--ink-muted);
}

.townsquare__courtship-accept:hover,
.townsquare__courtship-accept:focus-visible,
.townsquare__courtship-dismiss:hover,
.townsquare__courtship-dismiss:focus-visible {
  filter: brightness(0.96);
  outline: none;
}

.townsquare__help-button {
  font: 650 0.92rem/1 var(--font);
}

.townsquare__help-scrim {
  position: fixed;
  inset: 0;
  z-index: 2147483646;
  display: grid;
  place-items: center;
  padding: 24px;
  background: color-mix(in oklab, var(--ink) 34%, transparent);
  backdrop-filter: blur(6px);
}

.townsquare__help-scrim[hidden] {
  display: none;
}

.townsquare__help-panel {
  width: min(320px, calc(100vw - 48px));
  max-height: min(80vh, 520px);
  overflow: auto;
  padding: 16px;
  border: 1px solid var(--hair-2);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--tray-shadow);
}

.townsquare__help-panel strong {
  display: block;
  margin-bottom: 6px;
  font-size: 0.9rem;
}

.townsquare__help-panel p {
  margin: 0 0 8px;
  color: var(--ink-soft);
  font-size: 0.84rem;
  line-height: 1.35;
}

.townsquare__help-panel p:last-of-type {
  margin-bottom: 0;
}

.townsquare__help-links {
  margin-bottom: 0;
}

.townsquare__help-panel a {
  color: var(--you-deep);
  font-size: 0.84rem;
  font-weight: 650;
  text-decoration: none;
}

.townsquare__help-panel a:hover,
.townsquare__help-panel a:focus-visible {
  text-decoration: underline;
}

.townsquare__status {
  position: absolute;
  z-index: 2147483001;
  top: 8px;
  left: 4px;
  right: 124px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.3;
  pointer-events: none;
}

.townsquare__status[hidden] {
  display: none;
}

.townsquare__stage {
  position: relative;
  height: var(--ts-stage-height);
  border-radius: var(--r) var(--r) 0 0;
  background: transparent;
  /* horizontal touch swipes walk; vertical gestures still pan the host page */
  touch-action: pan-y pinch-zoom;
  /* Speech bubbles, trays, and composers size against the stage (cqw), not the
     viewport — otherwise a long line in a narrow embed renders wider than the
     stage and bleeds past its clipped edge. */
  container-type: inline-size;
}

/* The ground: a flat band filling the bottom --ts-ground-offset of the stage,
   with its top border drawn as the ground line. Anchored to the stage's bottom
   edge (not a percentage) so it holds its height at any stage height — the
   default 180px stage and the tall flex-sized expanded stage alike. Painted
   only when a customization layer is active (preview or pasted site CSS). */
.townsquare__ground {
  position: absolute;
  inset: auto 0 0;
  height: var(--ts-ground-offset);
  background: transparent;
}

/* Sky and ground are two flat colors: --scene fills the whole stage as the sky,
   the .townsquare__ground band paints --ground-fill over the bottom on top of
   it, and the band's top border is the --ground-line where they meet.
   --page/--ground are the pre-rename token names; the var() fallbacks keep CSS
   pasted before the rename painting (the stock values also live under those
   names in tokens.css, so the fallback chain covers the defaults too).

   Painted only when a customization layer is active: the live preview / overlay
   set data-townsquare-surface via applySiteStyle (with an inline palette), and
   host embeds set it at mount (see townsquare.mjs) so this paints straight from
   the palette tokens the site pastes in (buildSiteCss). The palette tokens are
   the only thing a hosted site pastes — the paint lives here, in one place. */
#townsquare-root[data-townsquare-surface] .townsquare__stage {
  background: var(--scene);
}

#townsquare-root[data-townsquare-surface] .townsquare__ground {
  background: var(--ground-fill, var(--page));
  border-top: 1px solid var(--ground-line, var(--ground));
}

.townsquare .prop {
  position: absolute;
  bottom: var(--ts-ground-level);
  transform: translateX(-50%);
  color: var(--prop-ink);
  opacity: 0.5;
  pointer-events: none;
}

.townsquare .prop svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.townsquare .prop svg * {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* Neighbouring-town fingerposts at the stage edges. */
.townsquare .townsquare-signpost {
  position: absolute;
  bottom: var(--ts-ground-level);
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--prop-ink);
  cursor: pointer;
  z-index: 3;
}

.townsquare .townsquare-signpost--left {
  left: 12px;
}

.townsquare .townsquare-signpost--right {
  right: 12px;
}

.townsquare-signpost__sign {
  display: block;
  width: 22px;
  height: 38px;
  opacity: 0.6;
  transition: opacity 120ms ease, color 120ms ease;
}

.townsquare-signpost__sign svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.townsquare-signpost__sign svg * {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.townsquare-signpost:hover .townsquare-signpost__sign,
.townsquare-signpost:focus-visible .townsquare-signpost__sign,
.townsquare-signpost--near .townsquare-signpost__sign {
  color: var(--ink);
  opacity: 1;
}

.townsquare-signpost:focus-visible {
  outline: none;
}

.townsquare-signpost:focus-visible .townsquare-signpost__sign {
  outline: 2px solid color-mix(in oklab, var(--you) 48%, transparent);
  outline-offset: 2px;
  border-radius: 4px;
}

.townsquare-signpost__hint {
  position: absolute;
  bottom: calc(100% + 4px);
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--you);
  color: #fff;
  font-size: 10px;
  line-height: 1.3;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 120ms ease, transform 120ms ease;
  pointer-events: none;
}

.townsquare-signpost--left .townsquare-signpost__hint {
  left: 0;
}

.townsquare-signpost--right .townsquare-signpost__hint {
  right: 0;
}

.townsquare-signpost--near .townsquare-signpost__hint {
  opacity: 1;
  transform: translateY(0);
}

/* Owner message board: a clickable notice prop with an unread "!" badge. */
.townsquare .townsquare-board {
  --board-accent: var(--you);
  position: absolute;
  bottom: var(--ts-ground-level);
  transform: translateX(-50%);
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--prop-ink);
  cursor: pointer;
  z-index: 3;
}

.townsquare-board__art {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0.6;
  transition: opacity 120ms ease, color 120ms ease;
}

.townsquare-board__art svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.townsquare-board__art svg * {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.townsquare-board:hover .townsquare-board__art,
.townsquare-board:focus-visible .townsquare-board__art {
  color: var(--ink);
  opacity: 1;
}

.townsquare-board:focus-visible {
  outline: none;
}

.townsquare-board:focus-visible .townsquare-board__art {
  outline: 2px solid color-mix(in oklab, var(--you) 48%, transparent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Art variants fill the panel differently; the line-art frame is shared. */
.townsquare-board--corkboard .townsquare-board__art .panel {
  fill: color-mix(in oklab, var(--board-accent) 18%, var(--surface));
}

.townsquare-board--chalkboard .townsquare-board__art .panel {
  fill: color-mix(in oklab, var(--ink) 78%, var(--surface));
}

.townsquare-board--chalkboard .townsquare-board__art .note {
  stroke: var(--surface);
}

/* "sign" keeps the default outline-only panel. */

.townsquare-board__badge {
  position: absolute;
  top: -6px;
  right: -6px;
  display: none;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: var(--board-accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 1px 3px -1px rgba(42, 41, 38, 0.5);
}

.townsquare-board--unread .townsquare-board__badge {
  display: block;
}

/* Message board modal — mirrors the connections overlay shape. */
.townsquare-board-modal {
  --board-accent: var(--you);
  position: absolute;
  inset: 0;
  z-index: 2147483005;
  display: flex;
  align-items: center;
  justify-content: center;
}

.townsquare-board-modal__backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--ink) 38%, transparent);
}

.townsquare-board-modal__panel {
  position: relative;
  z-index: 1;
  width: min(320px, 88%);
  max-height: 86%;
  overflow: auto;
  padding: 14px 16px;
  border: 1px solid var(--hair-2);
  border-top: 3px solid var(--board-accent);
  border-radius: 14px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 18px 40px -24px rgba(42, 41, 38, 0.6);
}

.townsquare-board-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.townsquare-board-modal__title {
  font-size: 14px;
  font-weight: 600;
}

.townsquare-board-modal__close {
  border: 0;
  background: transparent;
  color: var(--ink-soft);
  font-size: 20px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}

.townsquare-board-modal__close:hover,
.townsquare-board-modal__close:focus-visible {
  color: var(--ink);
}

.townsquare-board-modal__body {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* "Walk over" modal listing the towns on one side. */
.townsquare-connections {
  position: absolute;
  inset: 0;
  z-index: 2147483005;
  display: flex;
  align-items: center;
  justify-content: center;
}

.townsquare-connections__backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--ink) 38%, transparent);
}

.townsquare-connections__panel {
  position: relative;
  z-index: 1;
  width: min(280px, 86%);
  max-height: 86%;
  overflow: auto;
  padding: 14px 16px;
  border: 1px solid var(--hair-2);
  border-radius: 14px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 18px 40px -24px rgba(42, 41, 38, 0.6);
}

.townsquare-connections__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.townsquare-connections__title {
  font-size: 14px;
  font-weight: 600;
}

.townsquare-connections__close {
  border: 0;
  background: transparent;
  color: var(--ink-soft);
  font-size: 20px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}

.townsquare-connections__close:hover,
.townsquare-connections__close:focus-visible {
  color: var(--ink);
}

.townsquare-connections__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.townsquare-connections__item {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "name go"
    "host go";
  align-items: center;
  column-gap: 10px;
  padding: 9px 11px;
  border: 1px solid color-mix(in oklab, var(--hair-2) 70%, transparent);
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  transition: border-color 120ms ease, background 120ms ease;
}

.townsquare-connections__item:hover,
.townsquare-connections__item:focus-visible {
  border-color: var(--you);
  background: var(--you-tint);
  outline: none;
}

.townsquare-connections__item-name {
  grid-area: name;
  font-size: 13px;
}

.townsquare-connections__item-host {
  grid-area: host;
  font-size: 11px;
  color: var(--ink-soft);
}

.townsquare-connections__item-go {
  grid-area: go;
  font-size: 12px;
  color: var(--you-deep);
  white-space: nowrap;
}

.townsquare--quiet {
  min-height: 46px;
  overflow: visible;
}

.townsquare--quiet .townsquare__status,
.townsquare--quiet .townsquare__actions,
.townsquare--quiet .townsquare__toolbar,
.townsquare--quiet .townsquare__stage {
  display: none;
}

.townsquare--quiet .townsquare__control--expand {
  display: none;
}

.townsquare--expanded {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  width: 100vw;
  height: 100dvh;
  /* Reserve room at the bottom for the docked toolbar (absolute, bottom:7px) so
     the flex stage — and the figures' name tags at its base — never sit under
     the chat input. Mirrors --ts-toolbar-reserve in non-expanded mode. No
     horizontal padding: it would expose the container background as a colored
     strip down each side of the full-bleed stage. */
  padding: 0 0 var(--ts-toolbar-reserve);
  border-top: 0;
  border-radius: 0;
  /* Opaque backdrop so the fullscreen overlay always covers the host page. The
     flat stage paints --scene over the whole scene, so this only shows through
     where --scene is transparent (then reading as neutral Canvas, never the
     ground color) or behind the docked toolbar. */
  background: Canvas;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.townsquare--expanded::after {
  content: "";
  display: block;
  flex: 0 0 var(--ts-keyboard-scroll-room, 0px);
}

.townsquare--expanded .townsquare__controls {
  top: 10px;
  right: 18px;
}

.townsquare--expanded .townsquare__status {
  top: 10px;
  left: 18px;
  right: 148px;
}

.townsquare--expanded .townsquare__stage {
  flex: 1 1 auto;
  min-height: 0;
}

.townsquare .prop--tree .canopy {
  fill: var(--tree-canopy);
  stroke: var(--tree-canopy);
}

.townsquare .prop--tree .trunk {
  fill: var(--tree-trunk);
  stroke: var(--tree-trunk);
}

.townsquare .prop--lamp {
  z-index: 1;
}

.townsquare .prop__light {
  position: absolute;
  top: 16%;
  left: 75%;
  width: 90px;
  height: 88%;
  transform: translateX(-50%);
  clip-path: polygon(38% 0%, 62% 0%, 100% 100%, 0% 100%);
  background: linear-gradient(
    to bottom,
    rgba(253, 230, 160, 0.5) 0%,
    rgba(253, 230, 160, 0.2) 42%,
    rgba(253, 230, 160, 0.04) 100%
  );
  opacity: 0.34;
}

.townsquare__birds {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

/* Ambient drifting clouds — only painted in expanded mode, where the taller
   sky gives them room. Kept display:none while collapsed so the drift keyframes
   don't tick in the background. */
.townsquare__clouds {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
  display: none;
}

.townsquare--expanded .townsquare__clouds {
  display: block;
}

.cloud {
  position: absolute;
  top: var(--cloud-top, 12%);
  left: 0;
  width: calc(64px * var(--cloud-scale, 1));
  color: rgba(255, 255, 255, 0.82);
  filter: drop-shadow(0 2px 6px rgba(70, 90, 120, 0.12));
  will-change: transform;
  animation: cloud-drift var(--cloud-duration, 60s) linear infinite;
  animation-delay: var(--cloud-delay, 0s);
}

.cloud svg {
  display: block;
  width: 100%;
  height: auto;
}

.cloud svg path {
  fill: currentColor;
}

@keyframes cloud-drift {
  from { transform: translateX(-140px); }
  to { transform: translateX(calc(100cqw + 40px)); }
}

/* Freeze the drift but keep the clouds in place — the negative start delays
   leave them spread across the sky rather than parked off-screen. */
@media (prefers-reduced-motion: reduce) {
  .cloud { animation-play-state: paused; }
}

.bird {
  position: absolute;
  left: calc(var(--bird-x) * 100%);
  bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px));
  width: 12px;
  height: 8px;
  transform: translateX(-50%);
  color: var(--prop-ink);
  opacity: 0.45;
  pointer-events: none;
}

.bird svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.bird svg * {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.bird--arriving svg,
.bird--fleeing svg {
  transform: scaleX(var(--bird-facing, 1));
  transform-origin: 50% 50%;
}

.bird--arriving .bird-wing,
.bird--fleeing .bird-wing {
  transform-box: fill-box;
  animation-duration: 0.16s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

.bird--arriving .bird-wing--left,
.bird--fleeing .bird-wing--left {
  transform-origin: 100% 0%;
  animation-name: bird-wing-left;
}

.bird--arriving .bird-wing--right,
.bird--fleeing .bird-wing--right {
  transform-origin: 0% 0%;
  animation-name: bird-wing-right;
}

.bird--arriving {
  animation: bird-arrive 1.2s ease-out forwards;
}

.bird--perched {
  width: 16px;
  height: 11px;
  animation: bird-bob 3s ease-in-out infinite;
}

.bird--perched svg {
  transform: scaleX(var(--bird-facing, 1));
  transform-origin: 50% 100%;
}

.bird--fleeing {
  animation: bird-flee 0.7s ease-in forwards;
}

@keyframes bird-wing-left {
  from {
    transform: rotate(16deg);
  }

  to {
    transform: rotate(-22deg);
  }
}

@keyframes bird-wing-right {
  from {
    transform: rotate(-16deg);
  }

  to {
    transform: rotate(22deg);
  }
}

@keyframes bird-arrive {
  from {
    left: calc(var(--bird-from) * 100%);
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px) + 24px);
    opacity: 0;
  }

  25% {
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px) + 20px);
  }

  50% {
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px) + 26px);
  }

  75% {
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px) + 18px);
  }

  to {
    left: calc(var(--bird-to) * 100%);
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px));
    opacity: 0.45;
  }
}

@keyframes bird-bob {
  0%,
  100% {
    transform: translateX(-50%) translateY(0);
  }

  50% {
    transform: translateX(-50%) translateY(-2px);
  }
}

@keyframes bird-flee {
  from {
    left: calc(var(--bird-x) * 100%);
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px));
    opacity: 0.45;
  }

  35% {
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px) + 28px);
  }

  to {
    left: calc((var(--bird-x) + var(--bird-dir, 1) * 0.18) * 100%);
    bottom: calc(var(--ts-ground-level) + var(--bird-lift, 0px) + 42px);
    opacity: 0;
  }
}

.townsquare-avatar {
  --walk-cycle: 0.8s;
  --townsquare-avatar-walk-filter: ;
  --townsquare-avatar-shade-filter: ;
  --townsquare-avatar-light-filter: ;
  /* Horizontal position rides the compositor: --avatar-x (0–100, set per frame
     by renderAvatar) is a percentage of the stage width via cqw, and the
     trailing translateX(-50%) centres the figure on it. Keeping position off
     `left` means walking never dirties layout. Jump/high-five keyframes reuse
     --avatar-pos so their hop composes on top of the live position. */
  --avatar-pos: translateX(calc(var(--avatar-x, 50) * 1cqw)) translateX(-50%);
  position: absolute;
  bottom: var(--ts-ground-level);
  left: 0;
  width: 18px;
  height: 46px;
  transform: var(--avatar-pos);
  transition: transform 80ms linear;
  /* --speak-order: most recent speaker stacks on top when columns must overlap */
  z-index: var(--speak-order, 0);
}

.townsquare-avatar.townsquare-avatar--flipped svg {
  transform: scaleX(-1);
  transform-origin: 50% 50%;
}

.townsquare-avatar svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.townsquare-avatar svg * {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.townsquare-avatar svg circle.head {
  fill: currentColor;
}

.townsquare-avatar--self {
  color: var(--you);
  z-index: 2147483001;
}
.townsquare-avatar--peer { color: var(--other); }

/* peers are clickable (recent-message tray); the cursor also marks the slim
   figure as interactive, and on iOS Safari makes taps produce click events */
.townsquare-avatar--peer { cursor: pointer; }

/* widen the 18px figure's click/tap zone so "click a person" doesn't need
   precision — clicks here open their tray instead of walking */
.townsquare-avatar--peer::before {
  content: "";
  position: absolute;
  inset: -8px -14px;
}

/* a character's lingering bubbles are part of "them": clicking one opens
   their tray (the container keeps pointer-events: none for walk taps) */
.townsquare-avatar--peer .townsquare-avatar__bubble {
  pointer-events: auto;
  cursor: pointer;
}

/* while the tray is open the faded-out bubbles must not block clicks on it */
.townsquare-avatar--tray-open .townsquare-avatar__bubble {
  pointer-events: none;
}

/* Reading a character's tray outranks everything in the scene — neighbours'
   speak-order stacking AND the self figure (2147483001), so the open tray is
   never painted over by your own figure/bubbles. Stays below the overlay panels
   (message board / connections, 2147483005) and the help modal. */
.townsquare-avatar--has-history:hover,
.townsquare-avatar--has-history:focus-within,
.townsquare-avatar--tray-open { z-index: 2147483003; }
.townsquare-avatar:is(.townsquare-avatar--walking, .townsquare-avatar--shaded, .townsquare-avatar--lit) {
  filter: var(--townsquare-avatar-shade-filter) var(--townsquare-avatar-walk-filter) var(--townsquare-avatar-light-filter);
}
.townsquare-avatar.townsquare-avatar--walking { --townsquare-avatar-walk-filter: drop-shadow(0 2px 5px rgba(0,0,0,0.12)); }
.townsquare-avatar--jumping {
  animation: presence-jump 560ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.townsquare-avatar--high-five {
  animation: presence-high-five-root 760ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.townsquare-avatar--dancing {
  animation: presence-dance-root 1500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.townsquare-avatar__reaction {
  position: absolute;
  left: 50%;
  top: -30px;
  z-index: 4;
  display: block;
  width: max-content;
  min-width: 0;
  height: auto;
  padding: 0;
  background: transparent;
  box-shadow: none;
  font-size: 1.35rem;
  line-height: 1;
  opacity: 0;
  pointer-events: none;
  text-shadow: 0 1px 3px rgba(36, 43, 46, 0.14);
  transform: translateX(-50%) translateY(6px) scale(0.94);
}

.townsquare-avatar__reaction--active {
  animation: presence-reaction 1150ms cubic-bezier(0.18, 0.82, 0.22, 1) both;
}
.townsquare-avatar--reading-away > svg,
.townsquare-avatar--reading-away .townsquare-avatar__below {
  opacity: 0.22;
}

/* Long-idle figures fade away entirely; returning to the tab brings them back. */
.townsquare-avatar--asleep {
  opacity: 0;
  pointer-events: none;
  transition: opacity 600ms ease;
}

.townsquare-avatar--reading-away::after {
  content: "Zz";
  position: absolute;
  left: 50%;
  top: -12px;
  transform: translateX(-50%) rotate(-8deg);
  padding: 1px 4px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--surface) 70%, transparent);
  color: color-mix(in oklab, currentColor 58%, transparent);
  font-size: 10px;
  font-weight: 720;
  line-height: 1;
  letter-spacing: 0;
  pointer-events: none;
}

.townsquare-avatar--typing:not(.townsquare-avatar--raised-hand)::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -16px;
  width: 26px;
  height: 15px;
  padding: 0;
  transform: translateX(-50%);
  border-radius: 999px;
  background-color: color-mix(in oklab, var(--surface) 88%, transparent);
  background-image:
    radial-gradient(circle, currentColor 2px, transparent 2.5px),
    radial-gradient(circle, currentColor 2px, transparent 2.5px),
    radial-gradient(circle, currentColor 2px, transparent 2.5px);
  background-position: 5px 6px, 11px 8px, 17px 8px;
  background-repeat: no-repeat;
  background-size: 5px 5px;
  color: color-mix(in oklab, currentColor 62%, transparent);
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  animation: presence-typing 900ms ease-in-out infinite;
  pointer-events: none;
}

@keyframes presence-typing {
  0%, 80%, 100% { background-position: 5px 8px, 11px 8px, 17px 8px; }
  20% { background-position: 5px 4px, 11px 8px, 17px 8px; }
  40% { background-position: 5px 8px, 11px 4px, 17px 8px; }
  60% { background-position: 5px 8px, 11px 8px, 17px 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .townsquare-avatar--typing::after { animation: none; }
}

.townsquare-avatar--raised-hand::after {
  content: "🙌";
  position: absolute;
  left: 50%;
  top: -18px;
  transform: translateX(-50%);
  font-size: 13px;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));
  pointer-events: none;
}

/* Pose anchors: each pose sinks the element box below the plane by exactly the
   distance its lowest rotated foot ends above the box bottom, so the feet stay
   planted on the ground line while the pose bends the legs. Derived from the
   figure geometry (figure.mjs, 0.9 px/unit; feet at y=42 = box bottom) and the
   pose rotations below:
   - sitting (bench): hip 70–74°, knee −80/−84° → lowest foot at y≈38.3
     → drop (42 − 38.3) × 0.9 ≈ 3.3px. The hip (torso end, y=26 → 14.4px above
     the box bottom) then lands 14.4 − 3.3 ≈ 11.1px above the plane, resting on
     the 10px bench seat plank (--ts-bench-seat-height + half strokes).
   - resting (under a tree): hip 118/120°, knee −85/−88°, core −10° → lowest
     foot at y≈33.8 → drop (42 − 33.8) × 0.9 ≈ 7.4px. */
.townsquare-avatar--sitting { bottom: calc(var(--ts-ground-level) - 3.3px); }
.townsquare-avatar--resting { bottom: calc(var(--ts-ground-level) - 7.4px); }
.townsquare-avatar--shaded { --townsquare-avatar-shade-filter: brightness(0.88); }
.townsquare-avatar--lit {
  --townsquare-avatar-light-filter: drop-shadow(0 0 3px rgba(253, 230, 160, 0.7)) drop-shadow(0 0 6px rgba(253, 230, 160, 0.25));
}

/* Walk-sandbox preview: fills the preview box instead of standing on a stage. */
.townsquare-avatar--preview {
  position: static;
  width: 100%;
  height: 100%;
  transform: none;
  transition: none;
}

.townsquare-avatar--preview.townsquare-avatar--walking { filter: none; }
.townsquare-avatar--preview svg * { stroke-width: 1.4; }

.townsquare-avatar svg :is(g.figure-core, g.joint) {
  transform-box: view-box;
}

.townsquare-avatar svg g.figure-core { transform-origin: 10px 24px; }
.townsquare-avatar svg g.arm-l { transform-origin: 9.4px 14px; }
.townsquare-avatar svg g.arm-r { transform-origin: 10.6px 14px; }
.townsquare-avatar svg g.elbow-l { transform-origin: 6.1px 20px; }
.townsquare-avatar svg g.elbow-r { transform-origin: 13.9px 20px; }
.townsquare-avatar svg g.leg-l { transform-origin: 9.2px 26px; }
.townsquare-avatar svg g.leg-r { transform-origin: 10.8px 26px; }
.townsquare-avatar svg g.knee-l { transform-origin: 7.1px 34px; }
.townsquare-avatar svg g.knee-r { transform-origin: 12.9px 34px; }

.townsquare-avatar.townsquare-avatar--walking svg :is(g.figure-core, g.joint) {
  animation-duration: var(--walk-cycle);
  /* linear between frames: the easing lives in the keyframe spacing itself,
     so motion doesn't decelerate/re-accelerate at every keyframe. */
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

.townsquare-avatar.townsquare-avatar--walking svg g.figure-core { animation-name: presence-body-bob; }
.townsquare-avatar.townsquare-avatar--walking svg g.leg-l { animation-name: presence-leg-a; }
.townsquare-avatar.townsquare-avatar--walking svg g.leg-r { animation-name: presence-leg-b; }
.townsquare-avatar.townsquare-avatar--walking svg g.knee-l { animation-name: presence-knee-a; }
.townsquare-avatar.townsquare-avatar--walking svg g.knee-r { animation-name: presence-knee-b; }
.townsquare-avatar.townsquare-avatar--walking svg g.arm-l { animation-name: presence-arm-a; }
.townsquare-avatar.townsquare-avatar--walking svg g.arm-r { animation-name: presence-arm-b; }
.townsquare-avatar.townsquare-avatar--walking svg g.elbow-l { animation-name: presence-forearm-a; }
.townsquare-avatar.townsquare-avatar--walking svg g.elbow-r { animation-name: presence-forearm-b; }

.townsquare-avatar--jumping svg :is(g.figure-core, g.joint) {
  animation-duration: 560ms;
  animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
  animation-iteration-count: 1;
}

.townsquare-avatar--jumping svg g.figure-core { animation-name: presence-jump-body; }
.townsquare-avatar--jumping svg g.leg-l { animation-name: presence-jump-leg-a; }
.townsquare-avatar--jumping svg g.leg-r { animation-name: presence-jump-leg-b; }
.townsquare-avatar--jumping svg g.knee-l { animation-name: presence-jump-knee-a; }
.townsquare-avatar--jumping svg g.knee-r { animation-name: presence-jump-knee-b; }
.townsquare-avatar--jumping svg g.arm-l { animation-name: presence-jump-arm-a; }
.townsquare-avatar--jumping svg g.arm-r { animation-name: presence-jump-arm-b; }
.townsquare-avatar--jumping svg g.elbow-l { animation-name: presence-jump-forearm-a; }
.townsquare-avatar--jumping svg g.elbow-r { animation-name: presence-jump-forearm-b; }

.townsquare-avatar.townsquare-avatar--high-five svg :is(g.figure-core, g.joint) {
  animation-duration: 760ms;
  animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
  animation-iteration-count: 1;
}

.townsquare-avatar.townsquare-avatar--high-five svg g.figure-core { animation-name: presence-high-five-body; }
.townsquare-avatar.townsquare-avatar--high-five svg g.arm-l { animation-name: presence-high-five-arm-idle; }
.townsquare-avatar.townsquare-avatar--high-five svg g.elbow-l { animation-name: presence-high-five-forearm-idle; }
.townsquare-avatar.townsquare-avatar--high-five svg g.arm-r { animation-name: presence-high-five-arm; }
.townsquare-avatar.townsquare-avatar--high-five svg g.elbow-r { animation-name: presence-high-five-forearm; }

.townsquare-avatar.townsquare-avatar--dancing svg :is(g.figure-core, g.joint) {
  animation-duration: 500ms;
  animation-timing-function: ease-in-out;
  animation-iteration-count: 3;
}

.townsquare-avatar.townsquare-avatar--dancing svg g.figure-core { animation-name: presence-dance-body; }
.townsquare-avatar.townsquare-avatar--dancing svg g.leg-l { animation-name: presence-dance-leg-a; }
.townsquare-avatar.townsquare-avatar--dancing svg g.leg-r { animation-name: presence-dance-leg-b; }
.townsquare-avatar.townsquare-avatar--dancing svg g.arm-l { animation-name: presence-dance-arm-a; }
.townsquare-avatar.townsquare-avatar--dancing svg g.arm-r { animation-name: presence-dance-arm-b; }
.townsquare-avatar.townsquare-avatar--dancing svg g.elbow-l { animation-name: presence-dance-forearm-a; }
.townsquare-avatar.townsquare-avatar--dancing svg g.elbow-r { animation-name: presence-dance-forearm-b; }

/*
  Walk cycle, figure facing right (the flipped state mirrors it for left —
  the pose data itself never changes with direction).

  Sign conventions in the un-mirrored pose:
    legs/arms  positive deg = limb swung backward, negative = forward
    knees      positive deg = flexion (heel toward butt); never negative
    elbows     negative deg = flexion (hand swings forward); never positive

  Phase layout: left-leg heel strike at 0%, right-leg heel strike at 50%.
  Each leg spends ~60% of the cycle in stance and ~40% in swing, with peak
  knee flexion mid-swing for ground clearance.
*/
@keyframes presence-body-bob {
  0%, 50%, 100% { transform: translateY(0.4px) rotate(0.6deg); }
  6%, 56% { transform: translateY(0.7px) rotate(0.9deg); }
  28%, 78% { transform: translateY(-0.6px) rotate(1.2deg); }
}

@keyframes presence-leg-a {
  0%, 100% { transform: rotate(-20deg); }
  8% { transform: rotate(-18deg); }
  30% { transform: rotate(-2deg); }
  45% { transform: rotate(10deg); }
  55% { transform: rotate(14deg); }
  62% { transform: rotate(15deg); }
  75% { transform: rotate(-4deg); }
  88% { transform: rotate(-17deg); }
  94% { transform: rotate(-21deg); }
}

@keyframes presence-leg-b {
  0%, 100% { transform: rotate(12deg); }
  5% { transform: rotate(14deg); }
  12% { transform: rotate(15deg); }
  25% { transform: rotate(-4deg); }
  38% { transform: rotate(-17deg); }
  44% { transform: rotate(-21deg); }
  50% { transform: rotate(-20deg); }
  58% { transform: rotate(-18deg); }
  80% { transform: rotate(-2deg); }
  95% { transform: rotate(10deg); }
}

@keyframes presence-knee-a {
  0%, 100% { transform: rotate(4deg); }
  8% { transform: rotate(12deg); }
  20% { transform: rotate(6deg); }
  40% { transform: rotate(5deg); }
  55% { transform: rotate(18deg); }
  65% { transform: rotate(32deg); }
  72% { transform: rotate(38deg); }
  80% { transform: rotate(28deg); }
  90% { transform: rotate(8deg); }
  96% { transform: rotate(3deg); }
}

@keyframes presence-knee-b {
  0%, 100% { transform: rotate(14deg); }
  5% { transform: rotate(18deg); }
  15% { transform: rotate(32deg); }
  22% { transform: rotate(38deg); }
  30% { transform: rotate(28deg); }
  40% { transform: rotate(8deg); }
  46% { transform: rotate(3deg); }
  50% { transform: rotate(4deg); }
  58% { transform: rotate(12deg); }
  70% { transform: rotate(6deg); }
  90% { transform: rotate(5deg); }
}

@keyframes presence-arm-a {
  0%, 100% { transform: rotate(12deg); }
  12% { transform: rotate(10deg); }
  30% { transform: rotate(1deg); }
  50% { transform: rotate(-10deg); }
  60% { transform: rotate(-11deg); }
  75% { transform: rotate(-5deg); }
  90% { transform: rotate(7deg); }
}

@keyframes presence-arm-b {
  0%, 100% { transform: rotate(-10deg); }
  10% { transform: rotate(-11deg); }
  25% { transform: rotate(-5deg); }
  40% { transform: rotate(7deg); }
  50% { transform: rotate(12deg); }
  62% { transform: rotate(10deg); }
  80% { transform: rotate(1deg); }
}

@keyframes presence-forearm-a {
  0%, 100% { transform: rotate(-6deg); }
  15% { transform: rotate(-7deg); }
  35% { transform: rotate(-10deg); }
  55% { transform: rotate(-14deg); }
  68% { transform: rotate(-15deg); }
  85% { transform: rotate(-9deg); }
}

@keyframes presence-forearm-b {
  0%, 100% { transform: rotate(-13deg); }
  5% { transform: rotate(-14deg); }
  18% { transform: rotate(-15deg); }
  35% { transform: rotate(-9deg); }
  50% { transform: rotate(-6deg); }
  65% { transform: rotate(-7deg); }
  85% { transform: rotate(-10deg); }
}

@keyframes presence-jump {
  0%, 100% { transform: var(--avatar-pos) translateY(0); }
  12% { transform: var(--avatar-pos) translateY(1px) scaleY(0.96); }
  45% { transform: var(--avatar-pos) translateY(-30px) scaleY(1.03); }
  78% { transform: var(--avatar-pos) translateY(-6px); }
}

@keyframes presence-jump-body {
  0%, 100% { transform: translateY(0) rotate(0); }
  12% { transform: translateY(1.8px) rotate(-2deg); }
  36%, 62% { transform: translateY(-0.8px) rotate(2deg); }
  82% { transform: translateY(1px) rotate(-1deg); }
}

@keyframes presence-jump-leg-a {
  0%, 100% { transform: rotate(-4deg); }
  12% { transform: rotate(20deg); }
  38%, 62% { transform: rotate(-28deg); }
  82% { transform: rotate(12deg); }
}

@keyframes presence-jump-leg-b {
  0%, 100% { transform: rotate(4deg); }
  12% { transform: rotate(24deg); }
  38%, 62% { transform: rotate(24deg); }
  82% { transform: rotate(14deg); }
}

@keyframes presence-jump-knee-a {
  0%, 100% { transform: rotate(6deg); }
  12% { transform: rotate(34deg); }
  38%, 62% { transform: rotate(48deg); }
  82% { transform: rotate(18deg); }
}

@keyframes presence-jump-knee-b {
  0%, 100% { transform: rotate(6deg); }
  12% { transform: rotate(38deg); }
  38%, 62% { transform: rotate(42deg); }
  82% { transform: rotate(18deg); }
}

@keyframes presence-jump-arm-a {
  0%, 100% { transform: rotate(6deg); }
  12% { transform: rotate(24deg); }
  38%, 62% { transform: rotate(118deg); }
  82% { transform: rotate(28deg); }
}

@keyframes presence-jump-arm-b {
  0%, 100% { transform: rotate(-6deg); }
  12% { transform: rotate(-24deg); }
  38%, 62% { transform: rotate(-118deg); }
  82% { transform: rotate(-28deg); }
}

@keyframes presence-jump-forearm-a {
  0%, 100% { transform: rotate(-8deg); }
  12% { transform: rotate(-18deg); }
  38%, 62% { transform: rotate(10deg); }
  82% { transform: rotate(-14deg); }
}

@keyframes presence-jump-forearm-b {
  0%, 100% { transform: rotate(-8deg); }
  12% { transform: rotate(-18deg); }
  38%, 62% { transform: rotate(10deg); }
  82% { transform: rotate(-14deg); }
}

@keyframes presence-high-five-root {
  0%, 100% { transform: var(--avatar-pos) translateY(0); }
  42% { transform: var(--avatar-pos) translateY(-2px); }
  56% { transform: var(--avatar-pos) translateY(1px); }
}

@keyframes presence-high-five-body {
  0%, 100% { transform: translateY(0) rotate(1deg); }
  28%, 62% { transform: translateY(-0.8px) rotate(5deg); }
}

@keyframes presence-high-five-arm {
  0%, 100% { transform: rotate(-132deg); }
  30% { transform: rotate(-112deg); }
  46%, 58% { transform: rotate(-82deg); }
  72% { transform: rotate(-118deg); }
}

@keyframes presence-high-five-forearm {
  0%, 100% { transform: rotate(16deg); }
  30% { transform: rotate(6deg); }
  46%, 58% { transform: rotate(-8deg); }
  72% { transform: rotate(10deg); }
}

@keyframes presence-high-five-arm-idle {
  0%, 100% { transform: rotate(8deg); }
  42%, 62% { transform: rotate(16deg); }
}

@keyframes presence-high-five-forearm-idle {
  0%, 100% { transform: rotate(-8deg); }
  42%, 62% { transform: rotate(-14deg); }
}

@keyframes presence-dance-root {
  0%, 100% { transform: var(--avatar-pos) translateY(0) rotate(0); }
  16% { transform: var(--avatar-pos) translateY(-2px) rotate(-4deg); }
  34% { transform: var(--avatar-pos) translateY(1px) rotate(4deg); }
  52% { transform: var(--avatar-pos) translateY(-2px) rotate(-3deg); }
  70% { transform: var(--avatar-pos) translateY(1px) rotate(3deg); }
}

@keyframes presence-dance-body {
  0%, 100% { transform: translateY(0) rotate(0); }
  50% { transform: translateY(-1px) rotate(4deg); }
}

@keyframes presence-dance-leg-a {
  0%, 100% { transform: rotate(-8deg); }
  50% { transform: rotate(16deg); }
}

@keyframes presence-dance-leg-b {
  0%, 100% { transform: rotate(10deg); }
  50% { transform: rotate(-12deg); }
}

@keyframes presence-dance-arm-a {
  0%, 100% { transform: rotate(22deg); }
  50% { transform: rotate(-18deg); }
}

@keyframes presence-dance-arm-b {
  0%, 100% { transform: rotate(-24deg); }
  50% { transform: rotate(20deg); }
}

@keyframes presence-dance-forearm-a {
  0%, 100% { transform: rotate(-12deg); }
  50% { transform: rotate(-28deg); }
}

@keyframes presence-dance-forearm-b {
  0%, 100% { transform: rotate(-16deg); }
  50% { transform: rotate(-4deg); }
}

@keyframes presence-reaction {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(6px) scale(0.9);
  }

  16% {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }

  72% {
    opacity: 1;
    transform: translateX(-50%) translateY(-5px) scale(1);
  }

  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-13px) scale(0.96);
  }
}

.townsquare-avatar--sitting svg :is(g.figure-core, g.joint),
.townsquare-avatar--resting svg :is(g.figure-core, g.joint) {
  animation: none !important;
  transition: transform 220ms ease;
}

.townsquare-avatar--sitting svg g.figure-core { transform: translateY(0) rotate(0); }
.townsquare-avatar--sitting svg g.leg-l { transform: rotate(74deg); }
.townsquare-avatar--sitting svg g.leg-r { transform: rotate(70deg); }
.townsquare-avatar--sitting svg g.knee-l { transform: rotate(-84deg); }
.townsquare-avatar--sitting svg g.knee-r { transform: rotate(-80deg); }
.townsquare-avatar--sitting svg g.arm-l,
.townsquare-avatar--sitting svg g.arm-r { transform: rotate(16deg); }
.townsquare-avatar--sitting svg g.elbow-l { transform: rotate(24deg); }
.townsquare-avatar--sitting svg g.elbow-r { transform: rotate(-24deg); }

.townsquare-avatar--resting svg g.figure-core { transform: translateY(0) rotate(-10deg); }
.townsquare-avatar--resting svg g.leg-l { transform: rotate(120deg); }
.townsquare-avatar--resting svg g.leg-r { transform: rotate(118deg); }
.townsquare-avatar--resting svg g.knee-l { transform: rotate(-88deg); }
.townsquare-avatar--resting svg g.knee-r { transform: rotate(-85deg); }
.townsquare-avatar--resting svg g.arm-l,
.townsquare-avatar--resting svg g.arm-r { transform: rotate(45deg); }
.townsquare-avatar--resting svg g.elbow-l { transform: rotate(10deg); }
.townsquare-avatar--resting svg g.elbow-r { transform: rotate(-30deg); }

/* ── Ghost stack: history lives in the scene as fading bubbles above the figure ── */
.townsquare-avatar__above {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 12px);
  /* --bubble-shift: collision-avoidance nudge; --bubble-scale / --bubble-fade:
     proximity prominence — all set per frame by bubble-layout */
  transform: translateX(calc(-50% + var(--bubble-shift, 0px))) scale(var(--bubble-scale, 1));
  transform-origin: bottom center;
  opacity: var(--bubble-fade, 1);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: max-content;
  max-width: min(240px, 72cqw);
  pointer-events: none;
  transition: opacity 140ms ease, transform 160ms ease;
}

/* Narrow stages (phones / small embeds): cap bubbles tighter so a long line
   wraps to more rows (taller) instead of eating the width — that lets the
   column solver pack more speakers side by side. Short lines are unaffected
   (width: max-content). Container query, so it tracks the widget's own width. */
@container (max-width: 460px) {
  .townsquare-avatar__above {
    max-width: min(190px, 52cqw);
  }
}

.townsquare-avatar__above:empty { display: none; }

/* hovering to read history yields the live stack to the tray */
.townsquare-avatar--has-history:hover .townsquare-avatar__above,
.townsquare-avatar--has-history:focus-within .townsquare-avatar__above,
.townsquare-avatar--tray-open .townsquare-avatar__above { opacity: 0; }

.townsquare-avatar__bubble {
  position: relative;
  max-width: 100%;
  padding: 11px 16px 12px;
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-speech);
  line-height: 1.28;
  font-weight: var(--fw-speech);
  letter-spacing: -0.005em;
  box-shadow: var(--bshadow);
  transform-origin: bottom center;
  transition: opacity 280ms ease, transform 280ms ease, box-shadow 280ms ease;
}

.townsquare-avatar__bubble-text {
  display: block;
  overflow-wrap: anywhere;
}

.townsquare-avatar__tail {
  position: absolute;
  left: 50%;
  bottom: -11px;
  width: 160px;
  height: 12px;
  background: var(--surface);
  /* The base slides along the bubble's flat bottom (--tail-shift) and the tip
     leans the rest of the way to the speaker (--tail-tip), so the pointer
     always lands on whoever spoke even when the column was nudged aside. */
  transform: translateX(calc(-50% + var(--tail-shift, 0px)));
  clip-path: polygon(
    calc(50% - 8px) 0,
    calc(50% + 8px) 0,
    calc(50% + var(--tail-tip, 0px) + 1.5px) 100%,
    calc(50% + var(--tail-tip, 0px) - 1.5px) 100%
  );
  filter: drop-shadow(2px 3px 2px rgba(60, 40, 20, 0.14));
  transition: transform 160ms ease, clip-path 160ms ease;
}

/* only the live (bottom) bubble keeps its tail */
.townsquare-avatar__bubble--ghost .townsquare-avatar__tail { display: none; }

.townsquare-avatar__bubble--ghost {
  opacity: 0.72;
  transform: scale(0.92);
  box-shadow: none;
}

.townsquare-avatar__bubble--ghost.townsquare-avatar__bubble--far {
  opacity: 0.54;
  transform: scale(0.88);
}

.townsquare--expanded .townsquare-avatar__bubble--ghost {
  opacity: 0.82;
  transform: scale(0.94);
}

.townsquare--expanded .townsquare-avatar__bubble--ghost.townsquare-avatar__bubble--far {
  opacity: 0.66;
  transform: scale(0.9);
}

/* each line fades out on its own timer, oldest first */
.townsquare-avatar__bubble--expiring {
  opacity: 0;
  transform: scale(0.8);
}

/* ── History tray: hover a character to recover their recent lines ── */
.townsquare-avatar__tray {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 12px);
  z-index: 3;
  width: max-content;
  min-width: min(220px, 88cqw);
  max-width: min(360px, 88cqw);
  max-height: min(280px, 58vh);
  padding: 5px 4px;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--tray-shadow);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  opacity: 0;
  pointer-events: none;
  transform: translate(calc(-50% + var(--tray-shift, 0px)), 4px);
  transition: opacity 140ms ease, transform 140ms ease;
}

.townsquare-avatar--has-history:hover .townsquare-avatar__tray,
.townsquare-avatar--has-history:focus-within .townsquare-avatar__tray,
.townsquare-avatar--tray-open .townsquare-avatar__tray {
  opacity: 1;
  pointer-events: auto;
  transform: translate(calc(-50% + var(--tray-shift, 0px)), 0);
}

/* composing: your tray would sit over neighbours' speech bubbles */
.townsquare-avatar--self.townsquare-avatar--composing .townsquare-avatar__tray,
.townsquare-avatar--self.townsquare-avatar--has-history:focus-within .townsquare-avatar__tray,
.townsquare-avatar--self.townsquare-avatar--has-history:has(.townsquare-avatar__below:hover) .townsquare-avatar__tray {
  opacity: 0;
  pointer-events: none;
  transform: translate(calc(-50% + var(--tray-shift, 0px)), 4px);
}

.townsquare-avatar--self.townsquare-avatar--composing .townsquare-avatar__above,
.townsquare-avatar--self.townsquare-avatar--has-history:focus-within .townsquare-avatar__above,
.townsquare-avatar--self.townsquare-avatar--has-history:has(.townsquare-avatar__below:hover) .townsquare-avatar__above {
  opacity: var(--bubble-fade, 1);
}

/* transparent bridge across the gap so hover survives figure → tray travel */
.townsquare-avatar__tray::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 16px;
}

.townsquare-avatar__tray-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: 14px;
  row-gap: 3px;
  padding: 8px 13px;
}

.townsquare-avatar__tray-row + .townsquare-avatar__tray-row {
  box-shadow: 0 -1px 0 var(--hair);
}

.townsquare-avatar__tray-msg {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.28;
  font-size: var(--fs-history);
  font-weight: var(--fw-history);
  color: var(--ink);
}

.townsquare-avatar__tray-time {
  font-size: var(--fs-time);
  font-weight: var(--fw-time);
  line-height: 1.28;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

@media (max-width: 420px) {
  .townsquare-avatar__tray-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .townsquare-avatar__tray-time {
    justify-self: start;
  }
}

/* ── Nameplate / composer: the persistent way in, below your figure ── */
.townsquare-avatar__below {
  position: absolute;
  left: 50%;
  top: calc(100% + 9px);
  /* --label-shift de-conflicts overlapping name tags (see layoutNameLabels in
     bubble-layout.mjs), so no tag — including your own — covers another. */
  transform: translateX(calc(-50% + var(--label-shift, 0px)));
  /* --label-fade recedes distant tags so crowded narrow stages stay legible;
     near 1 on wide stages (see layoutNameLabels). */
  opacity: var(--label-fade, 1);
  transition: opacity 140ms ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
}

/* Hovering or focusing a faded distant character restores its tag to full. */
.townsquare-avatar:hover .townsquare-avatar__below,
.townsquare-avatar:focus-within .townsquare-avatar__below {
  opacity: 1;
}

.townsquare-avatar__below[hidden] { display: none; }

.townsquare-avatar__below--peer {
  pointer-events: auto;
}

.townsquare-avatar--peer.townsquare-avatar--has-reading:not(.townsquare-avatar--has-display-name):not(:hover):not(:focus-within):not(.townsquare-avatar--label-open) .townsquare-avatar__below {
  display: none;
}

.townsquare-avatar__plate-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.townsquare-avatar__plate {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 13px 6px 11px;
  border: 0;
  border-radius: 11px;
  background: var(--surface);
  box-shadow: var(--bshadow);
  cursor: pointer;
  font-family: var(--font);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.townsquare-avatar__plate:hover { transform: translateY(-1px); }
.townsquare-avatar__plate:focus-visible,
.townsquare-avatar__profile-button:focus-visible,
.townsquare-avatar__swatch:focus-visible,
.townsquare-avatar__profile-done:focus-visible {
  outline: 2px solid var(--you);
  outline-offset: 2px;
}

.townsquare-avatar__plate[hidden],
.townsquare-avatar__profile-button[hidden] { display: none; }

.townsquare-avatar__identity-label {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 62px;
  max-width: min(126px, calc(100cqw - 16px));
  padding: 5px 9px 6px;
  border-radius: 8px;
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  color: currentColor;
  box-shadow: 0 7px 16px -14px rgba(60, 40, 20, 0.42);
  overflow: hidden;
}

.townsquare-avatar__identity-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  max-width: 100%;
  gap: 2px;
}

.townsquare-avatar__plate-name-row {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  min-width: 0;
}

.townsquare-avatar__plate-name {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12.5px;
  font-weight: var(--fw-name);
  line-height: 1.05;
  letter-spacing: 0;
  color: var(--you);
  text-transform: lowercase;
}

.townsquare-avatar__match-meta {
  display: block;
  max-width: 100%;
  overflow: hidden;
  color: var(--ink-faint);
  font-size: 10.2px;
  font-weight: 650;
  letter-spacing: 0;
  line-height: 1.05;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.townsquare-avatar__match-meta[hidden] { display: none; }

.townsquare-avatar__peer-label {
  gap: 1px;
}

.townsquare-avatar__peer-name-row {
  display: inline-flex;
  align-items: baseline;
  max-width: 100%;
  min-width: 0;
}

.townsquare-avatar__peer-name {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12.5px;
  font-weight: var(--fw-name);
  line-height: 1.05;
  letter-spacing: 0;
  text-transform: lowercase;
}

.townsquare-avatar__identity-label :is(.townsquare-avatar__plate-name, .townsquare-avatar__peer-name) {
  color: var(--ink);
}

.townsquare-avatar__peer-name[hidden] { display: none; }

/* Owner badge: a server-verified crown that ordinary visitors cannot fake. */
.townsquare-avatar__owner-crown {
  flex-shrink: 0;
  margin-right: 4px;
  font-size: 0.95em;
  /* Render the emoji in its own colors even when the name is tinted. */
  -webkit-text-fill-color: initial;
  cursor: default;
}

.townsquare-avatar__owner-crown[hidden] { display: none; }

.townsquare-avatar__owner-crown:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--you) 48%, transparent);
  outline-offset: 2px;
  border-radius: 4px;
}

.townsquare-avatar__owner-role {
  display: none;
  align-self: stretch;
  max-width: 100%;
  overflow: hidden;
  color: var(--ink-faint);
  font-size: 10.5px;
  font-weight: 620;
  letter-spacing: 0;
  line-height: 1.15;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.townsquare-avatar__owner-role[hidden] { display: none; }

.townsquare-avatar--owner.townsquare-avatar--peer:has(.townsquare-avatar__owner-crown:hover) .townsquare-avatar__owner-role,
.townsquare-avatar--owner.townsquare-avatar--peer:has(.townsquare-avatar__owner-crown:focus-visible) .townsquare-avatar__owner-role {
  display: block;
}

.townsquare-avatar--owner.townsquare-avatar--peer:has(.townsquare-avatar__owner-crown:hover) .townsquare-avatar__reading,
.townsquare-avatar--owner.townsquare-avatar--peer:has(.townsquare-avatar__owner-crown:focus-visible) .townsquare-avatar__reading {
  display: none !important;
}

.townsquare-avatar--owner .townsquare-avatar__peer-label,
.townsquare-avatar--owner .townsquare-avatar__plate,
.townsquare-avatar--owner .townsquare-avatar__self-id {
  background: var(--owner-badge-bg, color-mix(in oklab, var(--surface) 70%, gold 14%));
  box-shadow: 0 6px 14px -9px rgba(150, 110, 20, 0.5);
}

.townsquare-avatar__reading {
  display: none;
  align-items: baseline;
  gap: 3px;
  align-self: stretch;
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
  color: var(--ink-faint);
  font-size: 10.5px;
  font-weight: 620;
  letter-spacing: 0;
  line-height: 1.15;
  text-decoration: none;
}

.townsquare-avatar--peer:hover .townsquare-avatar__reading--available,
.townsquare-avatar--peer:focus-within .townsquare-avatar__reading--available,
.townsquare-avatar--label-open .townsquare-avatar__reading--available {
  display: inline-flex;
}

.townsquare-avatar__reading-prefix {
  flex: 0 0 auto;
  font-weight: 520;
}

.townsquare-avatar__reading-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.townsquare-avatar__reading:hover,
.townsquare-avatar__reading:focus-visible {
  color: currentColor;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.townsquare-avatar__reading[hidden] { display: none; }

.townsquare-avatar__plate-hint {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-faint);
}

.townsquare-avatar__profile-button {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink-soft);
  box-shadow: var(--bshadow);
  cursor: pointer;
}

.townsquare-avatar__profile-button:hover,
.townsquare-avatar__profile-button[aria-expanded="true"] {
  color: var(--ink);
}

.townsquare-avatar__profile-button svg {
  width: 15px;
  height: 15px;
}

.townsquare-avatar__profile {
  display: grid;
  grid-template-columns: minmax(86px, 120px) auto;
  align-items: center;
  gap: 7px;
  padding: 7px;
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--tray-shadow);
}

.townsquare-avatar__profile[hidden] { display: none; }

.townsquare-avatar__profile-input {
  min-width: 0;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--hair);
  border-radius: 7px;
  outline: 0;
  background: var(--surface-2);
  color: var(--ink);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 520;
}

.townsquare-avatar__profile-input::placeholder { color: var(--ink-faint); }

.townsquare-avatar__swatches {
  display: grid;
  grid-template-columns: repeat(3, 18px);
  gap: 5px;
}

.townsquare-avatar__swatch {
  width: 18px;
  height: 18px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  background: var(--swatch);
  box-shadow: inset 0 0 0 1px rgba(42, 41, 38, 0.18);
  cursor: pointer;
}

.townsquare-avatar__swatch[aria-pressed="true"] {
  border-color: var(--surface);
  box-shadow: 0 0 0 2px var(--ink), inset 0 0 0 1px rgba(42, 41, 38, 0.18);
}

.townsquare-avatar__composer {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 7px 7px 19px;
  min-width: 300px;
  max-width: min(340px, 80cqw);
  border-radius: 26px;
  background: var(--surface);
  box-shadow: var(--tray-shadow);
}

.townsquare-avatar__composer[hidden] { display: none; }

/* Slow-mode "Wait Ns…" caption, floating just above the composer pill. */
.townsquare-avatar__composer-hint {
  position: absolute;
  left: 19px;
  bottom: calc(100% + 6px);
  margin: 0;
  padding: 3px 10px;
  border-radius: 12px;
  background: var(--surface);
  box-shadow: var(--tray-shadow);
  color: var(--ink-soft);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  pointer-events: none;
}

.townsquare-avatar__composer-hint[hidden] { display: none; }

.townsquare-avatar__input {
  flex: 1;
  min-width: 0;
  min-height: 30px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  font-weight: 460;
}

.townsquare-avatar__input::placeholder { color: var(--ink-faint); }

.townsquare-avatar__send {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--ink-soft);
  box-shadow: inset 0 0 0 1px var(--hair);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;
}

.townsquare-avatar__send svg { width: 17px; height: 17px; display: block; }

.townsquare-avatar__send--ready {
  background: var(--you);
  color: #fff;
  box-shadow: none;
}

@media (max-width: 640px) {
  .townsquare__status { flex-direction: column; gap: 4px; }
  .townsquare-avatar__composer { min-width: min(260px, 80cqw); }
}

/* ── Bottom toolbar ──
   Chat lives in a fixed bar at the bottom of the widget — for every pointer
   type — instead of floating under the (moving) figure: an always-visible
   input, the rename pencil, and the jump / high-five actions. The figure keeps
   a compact identity label, peer name tags are never covered, and the virtual
   keyboard can't clip any of it. The space is reserved via --ts-toolbar-reserve. */
.townsquare__toolbar {
  position: absolute;
  z-index: 2147483002;
  left: 10px;
  right: 10px;
  bottom: 7px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Actions (jump / high-five) are docked into the toolbar, so the floating
   container that once held them bottom-right is always empty. */
.townsquare__actions {
  display: none;
}

/* The docked composer fills the bar instead of floating on its own. */
.townsquare__toolbar .townsquare-avatar__composer--docked {
  position: static;
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
}

/* Pencil + rename editor anchor inside the bottom bar. */
.townsquare-avatar__profile-dock {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
}

/* Pencil matches the action buttons' touch target inside the bar. */
.townsquare__toolbar .townsquare-avatar__profile-button {
  width: 42px;
  height: 42px;
}

.townsquare__toolbar .townsquare-avatar__profile-button svg {
  width: 17px;
  height: 17px;
}

/* Rename editor pops above the bar rather than docking in the row. */
.townsquare__toolbar .townsquare-avatar__profile {
  position: absolute;
  right: 0;
  bottom: calc(100% + 8px);
  z-index: 1;
}

/* Compact identity under the figure: display name, or "you" when unset. */
.townsquare-avatar__self-id {
  color: var(--you);
}

/* In expanded (fixed) mode the page can't scroll, so ride above the keyboard. */
.townsquare--expanded .townsquare__toolbar {
  bottom: calc(7px + var(--ts-keyboard, 0px));
}

@media (pointer: coarse) {
  .townsquare__control {
    width: 40px;
    height: 40px;
  }

  .townsquare__control svg {
    width: 18px;
    height: 18px;
  }

  .townsquare__status {
    right: 152px;
  }

  /* fingers need an even wider tap zone than mouse pointers */
  .townsquare-avatar--peer::before {
    inset: -10px -20px;
  }
}
