:root {
  --bg: #131418;
  --bg-deep: #0e1014;
  --panel: rgba(26, 29, 36, 0.84);
  --panel-strong: rgba(18, 20, 26, 0.94);
  --ink: #eee7dc;
  --muted: #9a9589;
  --accent: #ddb171;
  --accent-soft: rgba(221, 177, 113, 0.16);
  --border: rgba(245, 233, 217, 0.08);
  --shadow: 0 24px 60px rgba(0, 0, 0, 0.34);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background:
    radial-gradient(circle at top, rgba(223, 177, 110, 0.12), transparent 28%),
    radial-gradient(circle at 80% 20%, rgba(118, 144, 172, 0.1), transparent 26%),
    linear-gradient(180deg, var(--bg) 0%, #15171d 42%, var(--bg-deep) 100%);
  color: var(--ink);
  font: 15px/1.5 "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
  -webkit-font-smoothing: antialiased;
}

[x-cloak] { display: none !important; }

.root {
  max-width: 900px;
  margin: 0 auto;
  padding: 36px 20px 28px;
  min-height: 100%;
}

.center {
  max-width: 460px;
  margin: 0 auto;
  text-align: center;
  padding-top: 6vh;
}

.logo {
  font-size: clamp(56px, 10vw, 82px);
  margin: 20px 0 10px;
  letter-spacing: -3px;
  font-weight: 600;
}

.muted { color: var(--muted); }
.tiny { font-size: 12px; }
.mt { margin-top: 28px; }
.row { display: flex; gap: 10px; align-items: center; margin: 14px 0; }

.input {
  flex: 1;
  background: rgba(17, 19, 24, 0.85);
  border: 1px solid var(--border);
  color: var(--ink);
  padding: 12px 15px;
  border-radius: 16px;
  font: inherit;
  outline: none;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
}

.input:focus {
  border-color: rgba(221, 177, 113, 0.5);
  box-shadow: 0 0 0 3px rgba(221, 177, 113, 0.08);
}

button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--ink);
  padding: 10px 16px;
  border-radius: 999px;
  font: inherit;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, transform 140ms ease, color 140ms ease;
}

button:hover {
  border-color: rgba(221, 177, 113, 0.45);
  transform: translateY(-1px);
}

button:disabled { opacity: 0.4; cursor: default; transform: none; }

.primary {
  background: var(--accent);
  color: #181510;
  border-color: rgba(221, 177, 113, 0.8);
  font-weight: 600;
}

.primary:hover { filter: brightness(1.04); }
.ghost {
  color: var(--muted);
  border-color: rgba(255,255,255,0.03);
  background: rgba(255,255,255,0.02);
}
.ghost:hover { color: var(--ink); }

/* Quirks list */
.quirks { list-style: none; padding: 0; margin: 12px 0 20px; text-align: left; }
.quirks li { margin: 8px 0; }
.quirk-card {
  width: 100%;
  text-align: left;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 6px 14px;
  align-items: start;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(27, 29, 36, 0.92), rgba(18, 20, 25, 0.94));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
}
.quirk-card.picked { border-color: rgba(221, 177, 113, 0.5); background: linear-gradient(180deg, rgba(43, 35, 23, 0.95), rgba(22, 19, 14, 0.96)); }
.quirk-card.disabled { opacity: 0.45; cursor: not-allowed; }
.quirk-order {
  width: 28px;
  height: 28px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255,255,255,0.08);
  background: rgba(255,255,255,0.03);
  color: #dac4a4;
  font-size: 14px;
  margin-top: 2px;
}
.q-label { font-weight: 600; }
.q-preview {
  grid-column: 2 / 4;
  color: #ece2d3;
  font-size: 14px;
  line-height: 1.45;
}
.q-desc {
  grid-column: 2 / 3;
  color: var(--muted);
  font-size: 13px;
}
.quirk-mood {
  grid-column: 3 / 4;
  align-self: end;
  justify-self: end;
  padding: 4px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.04);
}

.adopt-shell {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.adopt-copy {
  max-width: 620px;
  margin: 0 auto;
}

.adopt-copy h2 {
  margin: 0 0 10px;
  font-size: clamp(30px, 5vw, 44px);
  letter-spacing: -1px;
  line-height: 1.05;
}

.adopt-copy p {
  margin: 0;
}

.adopt-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
  gap: 18px;
  align-items: start;
}

.adopt-preview,
.adopt-form {
  padding: 22px;
}

.adopt-preview-name {
  margin: 4px 0 12px;
  font-size: clamp(26px, 4vw, 36px);
  letter-spacing: -1px;
}

.adopt-mini-scene {
  position: relative;
  overflow: hidden;
  height: 240px;
  border-radius: 24px;
  margin-bottom: 16px;
  background:
    radial-gradient(circle at 26% 22%, rgba(244, 226, 180, 0.12), transparent 18%),
    linear-gradient(180deg, rgba(26, 30, 38, 0.96) 0%, rgba(22, 24, 31, 0.98) 62%, rgba(18, 20, 25, 0.98) 100%);
  border: 1px solid rgba(255,255,255,0.04);
}

.adopt-mini-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 52% 84%, rgba(221, 177, 113, 0.08), transparent 24%);
}

.adopt-mini-floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 72px;
  background: linear-gradient(180deg, #22262e 0%, #16181f 100%);
}

.adopt-mini-rug {
  position: absolute;
  left: 18%;
  right: 18%;
  bottom: 42px;
  height: 40px;
  border-radius: 999px;
  background: linear-gradient(180deg, #694c34 0%, #503825 100%);
}

.adopt-mini-dog {
  position: absolute;
  left: 50%;
  bottom: 54px;
  width: 150px;
  height: 110px;
  transform: translateX(-50%);
}

.adopt-mini-dog span {
  position: absolute;
  display: block;
  background: #cf9561;
}

.adopt-tail {
  left: 14px;
  top: 18px;
  width: 42px;
  height: 14px;
  border-radius: 14px;
  transform: rotate(-24deg);
  background: #b67b47;
}

.adopt-body {
  left: 28px;
  top: 30px;
  width: 78px;
  height: 40px;
  border-radius: 999px;
}

.adopt-head {
  right: 18px;
  top: 26px;
  width: 44px;
  height: 36px;
  border-radius: 18px 18px 22px 22px;
}

.adopt-ear {
  width: 14px;
  height: 20px;
  clip-path: polygon(50% 0, 0 100%, 100% 100%);
  background: #c48751;
}

.adopt-ear-left { right: 44px; top: 12px; }
.adopt-ear-right { right: 24px; top: 12px; }

.adopt-preview-line {
  margin: 0 0 14px;
  color: #e5d8c7;
}

.adopt-preview-list {
  margin: 0;
  padding-left: 18px;
  color: var(--muted);
}

.adopt-preview-list li + li {
  margin-top: 8px;
}

.adopt-label {
  display: block;
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
}

.adopt-section-head {
  margin-top: 18px;
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 12px;
}

.adopt-section-head h3 {
  margin: 0 0 4px;
  font-size: 22px;
}

.selection-badge {
  padding: 6px 10px;
  border-radius: 999px;
  background: rgba(221, 177, 113, 0.12);
  color: #dcc29d;
  white-space: nowrap;
}

.quirk-grid {
  margin-top: 14px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.quirk-grid li {
  margin: 0;
}

.adopt-submit {
  margin-top: 6px;
  padding-inline: 22px;
}

/* Landing */
.landing-shell {
  min-height: calc(100vh - 64px);
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(320px, 0.92fr);
  gap: 18px;
  align-items: center;
}

.landing-scene,
.landing-entry {
  padding: 24px;
}

.landing-logo {
  margin: 0 0 8px;
  line-height: 0.95;
}

.landing-line {
  margin: 0 0 18px;
  font-size: 18px;
  color: #e6dbcb;
  max-width: 26ch;
}

.landing-room {
  position: relative;
  overflow: hidden;
  height: 300px;
  border-radius: 28px;
  margin-bottom: 16px;
  background:
    radial-gradient(circle at 24% 20%, rgba(244, 226, 180, 0.12), transparent 16%),
    radial-gradient(circle at 72% 22%, rgba(123, 143, 168, 0.08), transparent 18%),
    linear-gradient(180deg, rgba(26, 30, 38, 0.97) 0%, rgba(22, 24, 31, 0.98) 60%, rgba(18, 20, 25, 0.98) 100%);
  border: 1px solid rgba(255,255,255,0.04);
}

.landing-room-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 48% 84%, rgba(221, 177, 113, 0.08), transparent 22%);
}

.landing-room-floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 90px;
  background: linear-gradient(180deg, #22262e 0%, #17191f 100%);
}

.landing-room-rug {
  position: absolute;
  left: 20%;
  right: 18%;
  bottom: 52px;
  height: 50px;
  border-radius: 999px;
  background: linear-gradient(180deg, #6e5239 0%, #533b29 100%);
}

.landing-room-warmth {
  position: absolute;
  bottom: 72px;
  width: 56px;
  height: 22px;
  border-radius: 999px;
  background: rgba(233, 190, 131, 0.14);
  filter: blur(1px);
}

.landing-room-warmth-left { left: 18%; }
.landing-room-warmth-right { right: 20%; }

.landing-room-dog {
  position: absolute;
  left: 50%;
  bottom: 68px;
  width: 170px;
  height: 122px;
  transform: translateX(-50%);
}

.landing-room-dog span {
  position: absolute;
  display: block;
  background: #cf9561;
}

.landing-tail {
  left: 18px;
  top: 24px;
  width: 50px;
  height: 16px;
  border-radius: 16px;
  transform: rotate(-26deg);
  background: #b67b47;
}

.landing-body {
  left: 34px;
  top: 38px;
  width: 88px;
  height: 44px;
  border-radius: 999px;
}

.landing-head {
  right: 18px;
  top: 32px;
  width: 48px;
  height: 40px;
  border-radius: 18px 18px 22px 22px;
}

.landing-ear {
  width: 16px;
  height: 22px;
  clip-path: polygon(50% 0, 0 100%, 100% 100%);
  background: #c48751;
}

.landing-ear-left { right: 46px; top: 18px; }
.landing-ear-right { right: 24px; top: 18px; }

.landing-preview {
  margin: 0;
  max-width: 40ch;
}

.landing-entry h2 {
  margin: 0 0 8px;
  font-size: clamp(28px, 4vw, 40px);
  letter-spacing: -1px;
  line-height: 1.05;
}

.landing-copy {
  margin: 0 0 18px;
  max-width: 36ch;
}

.landing-row {
  margin-bottom: 12px;
}

.landing-submit {
  min-width: 132px;
}

.landing-notes {
  margin-top: 18px;
  display: grid;
  gap: 8px;
}

.landing-notes p {
  margin: 0;
}

/* Scene */
.scene {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.scene-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}

.identity-block {
  min-width: 0;
  max-width: 540px;
}

.scene-kicker {
  margin: 0 0 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
}

.name-block {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
  min-width: 0;
  gap: 6px;
}

.name {
  font-size: clamp(34px, 6vw, 54px);
  letter-spacing: -1.6px;
}

.origin { max-width: 36ch; }

.household-strip {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
}

/* Two presence dots — one per human. Brightness tracks who's currently
   connected. When both are bright, a soft shared pulse runs to signal
   "you're in the room together right now." */
.presence-pair {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.06);
  cursor: help;
}
.presence-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(221, 177, 113, 0.22);
  transition: background 600ms ease, box-shadow 600ms ease;
}
.presence-dot.is-on {
  background: rgba(233, 190, 131, 0.95);
  box-shadow: 0 0 6px rgba(233, 190, 131, 0.55);
}
.presence-dot.is-paired {
  animation: presence-pulse 2.6s ease-in-out infinite;
}
.presence-dot-partner.is-paired { animation-delay: 1.3s; }
@keyframes presence-pulse {
  0%, 100% { box-shadow: 0 0 6px rgba(233, 190, 131, 0.55); }
  50% { box-shadow: 0 0 14px rgba(244, 206, 156, 0.85); }
}

.household-pill {
  display: inline-flex;
  align-items: center;
  padding: 7px 11px;
  border-radius: 999px;
  background: rgba(221, 177, 113, 0.12);
  border: 1px solid rgba(221, 177, 113, 0.16);
  color: #ddc3a0;
  font-size: 12px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

.realtime-pill {
  background: rgba(255,255,255,0.05);
  border-color: rgba(255,255,255,0.08);
  color: #cbbfb0;
  /* This pill only appears while the connection is settling, and its copy
     is a sentence fragment ("catching up...") — uppercase chrome would
     make a quiet moment shout. */
  text-transform: none;
  letter-spacing: 0.3px;
  font-style: italic;
}

.realtime-pill.realtime-live {
  background: rgba(123, 176, 129, 0.14);
  border-color: rgba(123, 176, 129, 0.24);
  color: #cfe4c8;
}

.realtime-pill.realtime-warn {
  background: rgba(221, 177, 113, 0.14);
  border-color: rgba(221, 177, 113, 0.24);
  color: #e6cfac;
}

.household-line {
  margin: 0;
  max-width: 44ch;
  font-size: 14px;
}

.ambient-line {
  margin: 14px 0 0;
  max-width: 44ch;
  color: #dfd4c5;
  font-size: 16px;
}

.menu-button { margin-top: 8px; }

.scene-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(240px, 0.72fr);
  gap: 16px;
  align-items: stretch;
}

.canvas-wrap {
  position: relative;
  overflow: hidden;
  min-height: 520px;
  background:
    linear-gradient(180deg, rgba(255, 246, 229, 0.035) 0%, rgba(255, 246, 229, 0) 18%),
    radial-gradient(circle at 24% 18%, rgba(239, 215, 171, 0.14), transparent 16%),
    radial-gradient(circle at 72% 16%, rgba(123, 143, 168, 0.08), transparent 20%),
    repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.012) 0 2px, transparent 2px 10px),
    linear-gradient(180deg, rgba(28, 32, 40, 0.985) 0%, rgba(24, 26, 33, 0.985) 58%, rgba(17, 19, 24, 0.99) 100%);
  border: 1px solid var(--border);
  border-radius: 34px;
  padding: 28px 24px 20px;
  /* Color drains while solo; fills back in when the partner joins.
     The room is incomplete until both humans are in it. */
  filter: saturate(1);
  transition: filter 1.4s ease;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  box-shadow:
    inset 0 1px 0 rgba(255, 247, 234, 0.05),
    inset 0 -40px 90px rgba(7, 9, 13, 0.22),
    var(--shadow);
}

.scene-glow {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 28% 22%, rgba(244, 226, 180, 0.12), transparent 18%),
    radial-gradient(circle at 50% 80%, rgba(221, 177, 113, 0.07), transparent 26%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 28%, transparent 72%, rgba(0, 0, 0, 0.08));
  pointer-events: none;
}

.presence-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: opacity 900ms ease, transform 900ms ease, filter 900ms ease;
}

.presence-glow.presence-awaiting {
  background:
    radial-gradient(circle at 30% 78%, rgba(221, 177, 113, 0.06), transparent 14%),
    radial-gradient(circle at 69% 78%, rgba(255, 255, 255, 0.03), transparent 12%);
  opacity: 0.9;
}

.presence-glow.presence-apart {
  background:
    radial-gradient(circle at 30% 78%, rgba(221, 177, 113, 0.1), transparent 16%),
    radial-gradient(circle at 69% 78%, rgba(123, 143, 168, 0.04), transparent 13%);
  opacity: 0.9;
}

.presence-glow.presence-together {
  background:
    radial-gradient(circle at 30% 78%, rgba(221, 177, 113, 0.13), transparent 16%),
    radial-gradient(circle at 69% 78%, rgba(221, 177, 113, 0.11), transparent 16%),
    radial-gradient(circle at 50% 18%, rgba(244, 226, 180, 0.07), transparent 18%);
  opacity: 1;
}

#dog {
  display: block;
  position: relative;
  width: 100%;
  max-width: 500px;
  height: auto;
  image-rendering: auto;
  filter:
    drop-shadow(0 22px 28px rgba(7, 9, 13, 0.28))
    drop-shadow(0 6px 12px rgba(255, 242, 222, 0.05));
  transform: translateZ(0);
}

.stage-note {
  position: absolute;
  left: 22px;
  bottom: 20px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 12px;
  border-radius: 16px;
  background: rgba(12, 14, 18, 0.38);
  border: 1px solid rgba(255,255,255,0.04);
  backdrop-filter: blur(8px);
}

.stage-note-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.stage-presence {
  margin: 0;
  max-width: 22ch;
  line-height: 1.3;
}

.pose {
  font-variant: small-caps;
  letter-spacing: 1px;
  color: #d8cab6;
}

.scene-sidecar {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.quiet-panel {
  background: linear-gradient(180deg, rgba(24, 27, 33, 0.92), rgba(16, 18, 24, 0.94));
  border: 1px solid var(--border);
  border-radius: 24px;
  box-shadow: var(--shadow);
}

.speech {
  min-height: 136px;
  padding: 18px 18px 20px;
  color: var(--ink);
  font-style: italic;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
}

.speech-empty {
  align-items: center;
  justify-content: center;
  font-style: normal;
}

.speech-kicker {
  margin: 0;
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

.speech-own {
  border-color: rgba(221, 177, 113, 0.18);
}

/* While an action is in flight (~1-2s LLM round-trip) the empty speech
   panel carries a present-tense line in the dog's voice plus a slow
   breathing ellipsis — the room acknowledging you before it answers. */
.speech-thinking {
  border-color: rgba(221, 177, 113, 0.16);
}
.thinking-dots {
  display: inline-block;
  margin-left: 1px;
}
.thinking-dots span {
  opacity: 0.15;
  animation: thinking-dot 1.6s ease-in-out infinite;
}
.thinking-dots span:nth-child(2) { animation-delay: 0.25s; }
.thinking-dots span:nth-child(3) { animation-delay: 0.5s; }
@keyframes thinking-dot {
  0%, 70%, 100% { opacity: 0.15; }
  35% { opacity: 1; }
}

.speech-shared {
  border-color: rgba(146, 180, 211, 0.2);
}

/* Milestone celebration panel. Shows auto-surfaced moments — first walk,
   10th pet, 50th meal, anniversary days — with a gilded border + warm
   gradient so the eye reads it as "this one is different" without
   needing copy to shout. Position: fixed top so the sticky bottom dock
   can't bury it (the sidecar slot was hidden behind the dock on mobile). */
.milestone {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  width: min(92vw, 380px);
  padding: 14px 18px 16px;
  border-radius: 22px;
  border: 1px solid rgba(244, 206, 156, 0.45);
  background: linear-gradient(180deg, rgba(80, 56, 30, 0.92), rgba(40, 28, 15, 0.95));
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(244, 206, 156, 0.10), 0 0 30px rgba(244, 206, 156, 0.18);
  display: flex;
  flex-direction: column;
  gap: 6px;
  cursor: pointer;
  animation: milestone-pulse 4.2s ease-in-out infinite;
}
.milestone-kicker {
  margin: 0;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: #f3d6a5;
}
.milestone-fragment {
  font-style: italic;
  color: #f0e2c9;
  line-height: 1.4;
}
@keyframes milestone-pulse {
  0%, 100% { box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.10), 0 0 24px rgba(244, 206, 156, 0.10); }
  50% { box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.22), 0 0 50px rgba(244, 206, 156, 0.16); }
}

.invite-card {
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.invite-title {
  margin: 0;
  font-size: 18px;
  line-height: 1.3;
}

.invite-link {
  display: block;
  padding: 10px 12px;
  border-radius: 16px;
  background: rgba(255,255,255,0.03);
  color: var(--accent);
  font-size: 12px;
  word-break: break-all;
}

.invite-copy {
  align-self: flex-start;
  padding-inline: 14px;
}

.invite-copy.is-copied {
  color: var(--accent);
  border-color: rgba(221, 177, 113, 0.35);
}

.room-notes {
  padding: 16px 18px 18px;
}

.room-notes-list {
  margin: 10px 0 0;
  padding-left: 18px;
  color: #d8ccbd;
}

.room-notes-list li + li {
  margin-top: 8px;
}

.action-dock {
  padding: 16px 18px 18px;
  border-radius: 28px;
  border: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(18, 20, 25, 0.9), rgba(15, 17, 22, 0.96));
  box-shadow: var(--shadow);
}

/* Response echo: the dog's reply drifting down to the sticky dock when the
   speech panel is scrolled out of view (mobile). Tap to return to the scene. */
.response-echo {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  font-style: italic;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(221, 177, 113, 0.22);
  border-radius: 18px;
  padding: 10px 14px;
  margin-bottom: 10px;
  cursor: pointer;
}
.response-echo-kicker {
  display: block;
  font-style: normal;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 3px;
}
.response-echo-text {
  line-height: 1.4;
}

.canvas-wrap.awaiting-partner {
  filter: saturate(0.45);
}

.canvas-wrap.partner-away {
  filter: saturate(0.82);
}

.canvas-wrap.partner-present {
  filter: saturate(1.08);
  animation: copresence-glow 5.4s ease-in-out infinite;
}

/* Slow warm pulse on the canvas frame when both humans are in the room.
   Subtle enough not to distract, present enough to read as "we're here
   together right now" without needing the small presence dots. */
@keyframes copresence-glow {
  0%, 100% {
    box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.14), 0 0 24px rgba(244, 206, 156, 0.06);
  }
  50% {
    box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.22), 0 0 46px rgba(244, 206, 156, 0.12);
  }
}

/* Brief brighter burst when the partner just stepped in. Overlays the
   slow copresence-glow with a louder one-off pulse so the moment of
   arrival reads as "they're here right now" without needing the user
   to look at the small presence dots. */
.canvas-wrap.partner-arrived-flash {
  animation: partner-arrived 2.4s ease-out 1;
}
@keyframes partner-arrived {
  0% {
    box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.55), 0 0 80px rgba(244, 206, 156, 0.36);
    transform: scale(1);
  }
  40% {
    box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.32), 0 0 60px rgba(244, 206, 156, 0.22);
    transform: scale(1.005);
  }
  100% {
    box-shadow: 0 0 0 1px rgba(244, 206, 156, 0.14), 0 0 24px rgba(244, 206, 156, 0.06);
    transform: scale(1);
  }
}

/* Tap hint shown to first-time visitors over the canvas — disappears on
   first interaction (or 4s timeout), and never shows again
   (localStorage paws_tap_seen). */
.tap-hint {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 8px 18px;
  border-radius: 999px;
  background: rgba(244, 206, 156, 0.18);
  border: 1px solid rgba(244, 206, 156, 0.4);
  color: #f4ce9c;
  font-size: 13px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  pointer-events: none;
  animation: tap-hint-pulse 1.4s ease-in-out infinite;
  z-index: 5;
}
@keyframes tap-hint-pulse {
  0%, 100% { opacity: 0.65; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
}

/* Speech pin button + pinned state. Tap the small ○ to keep a response
   visible past its default 8-12s fadeout. Pinned responses get a
   stronger border so they read as "held". */
.speech { position: relative; }
.speech-pin {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
  color: #b6a890;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.5;
  transition: opacity 200ms ease, background 200ms ease, color 200ms ease;
}
.speech:hover .speech-pin { opacity: 1; }
.speech-pin.is-pinned {
  opacity: 1;
  background: rgba(221, 177, 113, 0.18);
  color: #f3d6a5;
}
.speech.speech-pinned {
  border-color: rgba(221, 177, 113, 0.4);
  box-shadow: 0 0 0 1px rgba(221, 177, 113, 0.12);
}

/* Memory drawer time-grouped sections. Each label sits above its group
   list with a faint divider so the chronology reads at a glance. */
.memory-group { margin-top: 14px; }
.memory-group-label {
  letter-spacing: 1.6px;
  text-transform: uppercase;
  margin: 0 0 6px;
  color: #8e7f6a;
}
.memory-group .room-notes-list { margin-top: 4px; }

/* Wall window — small framed gradient that tracks local time of day.
   Mochi's mood engine has a diurnal arousal curve; the window makes
   it visible. Positioned at the upper-left of canvas-wrap so it doesn't
   compete with the speech overlay on the right. */
.scene-window {
  position: absolute;
  top: 6%;
  left: 6%;
  width: 84px;
  height: 100px;
  border-radius: 10px;
  border: 2px solid rgba(40, 30, 22, 0.85);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.05),
    0 6px 12px rgba(0, 0, 0, 0.4);
  overflow: hidden;
  transition: background 8s linear;
  pointer-events: none;
  z-index: 2;
}
.scene-window::before {
  /* faint horizon line so the window doesn't read as a flat block */
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 28%;
  height: 1px;
  background: rgba(0, 0, 0, 0.18);
}
.scene-window::after {
  /* window cross-frame */
  content: "";
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 2px;
  background: rgba(40, 30, 22, 0.6);
  transform: translateX(-50%);
}
.scene-window-orb {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  transition: left 60s linear, top 60s linear, background 8s linear, box-shadow 8s linear;
}

/* Quick-reactions row — one-tap presets above the composer. Renders as
   small circular emoji buttons; same backend path as "say something". */
.quick-reactions {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-top: 10px;
}
.quick-reaction {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(221, 177, 113, 0.18);
  background: rgba(221, 177, 113, 0.06);
  color: #efe2cd;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: transform 100ms ease, background 150ms ease, border-color 150ms ease;
  display: flex;
  align-items: center;
  justify-content: center;
}
.quick-reaction:active:not(:disabled) {
  transform: scale(0.94);
  background: rgba(221, 177, 113, 0.16);
}
.quick-reaction:disabled { opacity: 0.4; cursor: default; }

/* Fresh-version pill. Server sends app_version on every pet_state; client
   shows this pill if it differs from the version this tab booted with.
   Bottom-center so it doesn't fight the top-of-viewport milestone panel. */
.fresh-version-pill {
  position: fixed;
  bottom: max(80px, calc(env(safe-area-inset-bottom) + 80px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 13;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 4px 4px 14px;
  border-radius: 999px;
  background: rgba(36, 28, 18, 0.96);
  border: 1px solid rgba(244, 206, 156, 0.4);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  color: #f0e2c9;
  font-size: 13px;
}
.fresh-version-pill button {
  background: transparent;
  border: none;
  color: inherit;
  font-size: 13px;
  cursor: pointer;
  padding: 6px 8px;
}
.fresh-version-pill button:first-child {
  font-weight: 500;
}
.fresh-version-pill .dismiss {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  color: #b6a890;
  font-size: 14px;
  line-height: 1;
  padding: 0;
}

/* Onboarding overlay — first-session 3-line ambient narration. Sits
   center-screen, semi-transparent, dismissed on tap or after the third
   line auto-advances. Stored in localStorage paws_onboarded. */
.onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 11;
  background: rgba(8, 10, 14, 0.62);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  cursor: pointer;
  padding: 24px;
}
.onboarding-line {
  margin: 0;
  text-align: center;
  font-size: clamp(22px, 5vw, 32px);
  letter-spacing: -0.4px;
  color: #f0e2c9;
  line-height: 1.35;
  max-width: 22ch;
  animation: onboarding-fade-in 600ms ease;
}
.onboarding-hint {
  margin: 0;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: #8e7f6a;
}
@keyframes onboarding-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

.action-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.action-group-label {
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 8px 4px;
  opacity: 0.65;
}

.secondary-label { margin-top: 18px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.04); margin-bottom: 8px; }
.secondary-actions { margin-top: 0; }

.action-pill {
  min-width: 96px;
  padding: 12px 16px;
  border-color: rgba(221, 177, 113, 0.18);
  background: rgba(221, 177, 113, 0.08);
  transition: transform 100ms ease, background 150ms ease, border-color 150ms ease;
}

.action-pill:active:not(:disabled) {
  transform: scale(0.97);
  background: rgba(221, 177, 113, 0.14);
}

.action-pill.active {
  border-color: rgba(221, 177, 113, 0.42);
  background: rgba(221, 177, 113, 0.16);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02);
}

.action-pill-muted {
  background: rgba(255,255,255,0.03);
  border-color: rgba(255,255,255,0.06);
  color: #d4c7b6;
}

.composer {
  margin-top: 14px;
  display: flex;
  gap: 10px;
  align-items: center;
}

/* Send is the softest gesture — typing at the dog. Don't shout it.
   Slightly nudged from pure ghost so it still reads as the form's action. */
.send-quiet {
  border-color: rgba(221, 177, 113, 0.22);
  color: var(--ink);
}
.send-quiet:hover:not(:disabled) {
  border-color: rgba(221, 177, 113, 0.45);
  color: var(--ink);
}

/* Hold-to-confirm: a fill-bar grows across the button while the user holds.
   If they release early, .is-holding goes away and the bar resets. */
.danger-hold {
  position: relative;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}
.danger-hold::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(211, 125, 120, 0.30);
  width: 0;
  pointer-events: none;
  transition: width 0s linear;
}
.danger-hold.is-holding {
  border-color: rgba(211, 125, 120, 0.6);
}
.danger-hold.is-holding::before {
  width: 100%;
  transition: width 1.5s linear;
}
.danger-hold > span { position: relative; z-index: 1; }

.dock-note {
  margin: 14px 2px 0;
}

.drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: 9;
}

.drawer {
  position: fixed;
  right: 16px;
  top: 16px;
  bottom: 16px;
  width: min(92vw, 360px);
  background: linear-gradient(180deg, rgba(22, 25, 31, 0.98), rgba(15, 17, 22, 0.98));
  border: 1px solid var(--border);
  border-radius: 24px;
  padding: 22px;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 10;
  box-shadow: 0 18px 44px rgba(0,0,0,.5);
}

.drawer-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  color: #d8ccbd;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.drawer-close:hover { background: rgba(255, 255, 255, 0.12); }

/* Recovery card collapses to a single thin pill until the user expands it —
   it was a ~250px wall of instructions between the dog and the room-notes
   that new visitors had to scroll past every refresh. */
.recovery-card { position: relative; }
.recovery-card.collapsed {
  padding: 0;
  border: none;
  background: none;
  box-shadow: none;
}
.recovery-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(221, 177, 113, 0.10);
  border: 1px solid rgba(221, 177, 113, 0.20);
  color: #ddc3a0;
  font-size: 13px;
  cursor: pointer;
  align-self: flex-start;
}
.recovery-pill:hover { background: rgba(221, 177, 113, 0.16); }

.recovery-collapse {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
  color: #d8ccbd;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.recovery-collapse:hover { background: rgba(255, 255, 255, 0.10); }

.drawer .wrap {
  word-break: break-all;
  color: var(--accent);
  font-size: 12px;
}

.drawer hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 10px 0;
}

.status {
  margin-top: 24px;
  text-align: center;
  min-height: 16px;
}

@media (max-width: 860px) {
  .landing-shell {
    min-height: auto;
    grid-template-columns: 1fr;
    align-items: stretch;
  }

  .adopt-layout {
    grid-template-columns: 1fr;
  }

  .scene-stage {
    grid-template-columns: 1fr;
  }

  .canvas-wrap {
    min-height: 460px;
  }
}

@media (max-width: 640px) {
  .root {
    padding: 14px 12px 12px;
  }

  .landing-scene,
  .landing-entry,
  .adopt-preview,
  .adopt-form {
    padding: 18px;
  }

  .quirk-grid {
    grid-template-columns: 1fr;
  }

  .landing-room {
    height: 236px;
  }

  .landing-room-dog {
    transform: translateX(-50%) scale(0.88);
    transform-origin: bottom center;
  }

  /* Compact scene-header so Mochi is visible above the fold. Without these
     overrides the header eats >50% of an iPhone viewport. */
  .scene-header {
    flex-direction: row;
    align-items: flex-start;
    gap: 8px;
  }
  .identity-block {
    flex: 1 1 auto;
    min-width: 0;
  }
  .scene-kicker { display: none; }
  .name { font-size: 28px; letter-spacing: -1px; }
  .origin { display: none; }
  .household-line { font-size: 12px; max-width: 100%; }
  .ambient-line { display: none; }
  .household-strip {
    margin-top: 8px;
    gap: 6px 8px;
  }
  .household-pill, .realtime-pill {
    padding: 4px 8px;
    font-size: 10px;
  }
  /* The presence dots + household sentence already say "both here" — the
     uppercase status pill restates it as dashboard chrome. Drop it on
     mobile; the realtime pill stays since it only appears when the
     connection is actually settling. */
  .household-pill:not(.realtime-pill) { display: none; }
  .menu-button {
    flex: 0 0 auto;
    align-self: flex-start;
    margin-top: 0;
    padding: 6px 10px;
    font-size: 12px;
  }

  .scene-stage { gap: 12px; }

  .canvas-wrap {
    min-height: 300px;
    /* Tighter horizontal padding gives the canvas ~12px more width on each
       side — Mochi reads bigger in the room. */
    padding: 8px 6px 6px;
    border-radius: 20px;
  }

  .scene-sidecar { gap: 10px; }

  .speech {
    min-height: 0;
    padding: 10px 14px;
  }

  /* "quiet, for now." was a thin grey line just above the dock — easy to
     miss. Center it, bump the size + contrast so it reads as a real
     ambient narration line. */
  .speech.speech-empty {
    padding: 14px 18px;
    text-align: center;
    font-size: 14px;
  }
  .speech.speech-empty .muted { color: #d4c7b6; }

  /* Hide the long iOS-share instruction inside the expanded recovery card
     on mobile so the whole expanded panel fits in ~150-180px of visible
     space above the sticky dock — otherwise "got it, hide this" sits
     hidden behind the dock until the user scrolls. */
  .recovery-instructions { display: none; }

  /* Recovery + invite cards are dense walls of text on mobile — shrink them
     so they don't double the scroll length until acknowledged. */
  .invite-card {
    padding: 12px 14px;
    gap: 8px;
  }
  .invite-title {
    font-size: 15px;
    line-height: 1.25;
  }

  /* The raw invite URL is a wall of broken-up token noise on a narrow
     screen — the copy button is the real affordance, and it now confirms
     in place. (The recovery card keeps its visible link: that one is
     about bookmarking, not sharing.) */
  .invite-card:not(.recovery-card) .invite-link { display: none; }

  .composer,
  .row {
    flex-direction: column;
    align-items: stretch;
  }

  .composer button,
  .row button {
    width: 100%;
  }

  .action-pill {
    flex: 1 1 calc(50% - 8px);
    min-width: 80px;
    padding: 10px 14px;
  }

  /* Group labels and the divider above "across the room" read as muted
     chrome on mobile — costs vertical space the dog needs more. */
  .action-group-label,
  .secondary-label,
  .dock-note { display: none; }
  .secondary-actions { margin-top: 6px; }

  /* The stage-note inside canvas-wrap (mood + presence + couple-rhythm
     lines) duplicates info that already shows in the header pill row
     (SYNC LIVE, BOTH HUMANS HERE) and competes with the .speech panel
     just below the canvas. Hide it on mobile to give the canvas its
     full breath and let the speech panel carry the narration alone. */
  .stage-note { display: none; }

  /* Sticky-bottom action dock on mobile so petting + walking are
     always thumb-reachable without scrolling past the speech area.
     `bottom: max(6px, env(...))` keeps the dock clear of the iPhone home
     gesture bar (~34px) when running as a PWA / Safari toolbar-collapsed.
     Background alpha kept lower (0.78/0.88) so the dog reads through the
     dock instead of feeling walled-off. */
  .action-dock {
    padding: 10px 12px 12px;
    position: sticky;
    bottom: max(6px, env(safe-area-inset-bottom));
    z-index: 10;
    background: linear-gradient(180deg, rgba(18, 20, 25, 0.78), rgba(15, 17, 22, 0.88));
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }

  /* Give the page a little padding so the sticky dock doesn't sit flush
     against the last room-note. */
  .scene {
    padding-bottom: 12px;
  }

  /* While composing a quiet note, collapse the dock to just the composer +
     the say-something toggle so the dog stays in viewport above the iOS
     keyboard. Pre-collapse, composer + 6 pills + dock-note = ~450px tall
     which combined with a 336px keyboard leaves nothing for the canvas. */
  .scene.composing .primary-actions { display: none; }
  .scene.composing .secondary-actions .action-pill:not(:last-child) { display: none; }
  .scene.composing .secondary-label { display: none; }
  .scene.composing .canvas-wrap { min-height: 200px; }
}

/* Short-viewport rescue (iPhone SE / 8 / 9 class @ 375x667 and similar).
   Without this, header 175 + canvas-wrap (canvas at 100% width = ~340) +
   dock 228 ≈ 740 > 667 viewport, so the sticky dock covers the dog's
   lower half. The fix is to cap the CANVAS size directly (not just
   wrap min-height — canvas is `width: 100%; aspect-ratio: 1` so the
   wrap is sized by its content not its min-height). */
@media (max-width: 640px) and (max-height: 700px) {
  #dog { max-width: 220px; }
  .canvas-wrap { min-height: 0; padding: 4px; }
  .action-dock { padding: 6px 10px 8px; }
  .action-pill { padding: 8px 12px; }
  .action-group { gap: 6px; }
  .speech.speech-empty { padding: 8px 14px; font-size: 13px; }
  .scene.composing #dog { max-width: 160px; }
  .scene.composing .canvas-wrap { min-height: 0; }
}

/* Access */
.access-body {
  background:
    radial-gradient(circle at top, rgba(230, 179, 106, 0.12), transparent 32%),
    linear-gradient(180deg, #13141a 0%, #16171d 45%, #121318 100%);
}

.access-root {
  display: grid;
  place-items: center;
  max-width: 680px;
}

.access-card {
  width: 100%;
  padding: 22px;
  border-radius: 28px;
  border: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(29,31,39,0.98), rgba(23,24,31,0.98));
  box-shadow: 0 24px 60px rgba(0,0,0,.35);
}

.access-scene {
  position: relative;
  height: 210px;
  border-radius: 22px;
  overflow: hidden;
  background:
    radial-gradient(circle at 24% 24%, rgba(244, 226, 180, 0.12), transparent 18%),
    linear-gradient(180deg, #191c24 0%, #1c2028 60%, #16181f 100%);
  border: 1px solid rgba(255,255,255,0.04);
  margin-bottom: 18px;
}

.access-moon {
  position: absolute;
  top: 28px;
  left: 44px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(244, 226, 180, 0.9);
  box-shadow: 0 0 30px rgba(244, 226, 180, 0.2);
}

.access-floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 56px;
  background: linear-gradient(180deg, #21242c 0%, #171920 100%);
  border-top: 1px solid rgba(255,255,255,0.05);
}

.access-dog {
  position: absolute;
  right: 98px;
  bottom: 42px;
  width: 170px;
  height: 92px;
}

.access-dog span {
  position: absolute;
  display: block;
  background: #cf9561;
}

.access-tail {
  left: 18px;
  top: 12px;
  width: 52px;
  height: 14px;
  border-radius: 14px;
  transform: rotate(-28deg);
  background: #b67b47;
}

.access-body-shape {
  left: 26px;
  top: 24px;
  width: 96px;
  height: 42px;
  border-radius: 999px;
}

.access-head {
  right: 18px;
  top: 18px;
  width: 46px;
  height: 38px;
  border-radius: 18px 18px 22px 22px;
}

.access-copy { text-align: center; margin-bottom: 18px; }
.access-kicker { letter-spacing: 2px; text-transform: uppercase; }
.access-logo { margin: 0 0 8px; }
.access-note { margin: 0 0 8px; }
.access-note-quiet { max-width: 34ch; margin: 0 auto 8px; }
.access-form { max-width: 420px; margin: 0 auto; }
.access-label { display: block; text-align: left; margin-bottom: 6px; }
.access-row { margin: 0; }
.access-status { min-height: 18px; margin: 10px 2px 0; }
.access-footnote { margin: 12px auto 0; max-width: 34ch; text-align: center; }
.access-form.is-error .input { border-color: #d37d78; }

@media (max-width: 640px) {
  .access-card { padding: 16px; border-radius: 22px; }
  .access-scene { height: 160px; }
  .access-dog { right: 34px; transform: scale(0.82); transform-origin: bottom right; }
  .access-row { flex-direction: column; align-items: stretch; }
  .access-row button { width: 100%; }
}
