/* The host screen: the same watercolor garden as the site, sized for a TV across a room. */
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400&display=swap');

:root {
  --paper: #f8f5ee;
  --ink: #22403a;
  --text: #345953;
  --muted: #587468;
  --faint: #748477;
  --card: #fbf8f0e0;
  --line: #59796a45;
  --growth: 0;
  --growth-fade: 6s;
  --bloom: 80px;
  /* where the room's garden sits; the invite card holds the left of the screen */
  --field-left: 38vw;
  --field-right: 7vw;
  --field-top: 19vh;
  --field-bottom: 22vh;
  /* the cream wash that follows the garden around: centre and radii */
  --veil-x: 67vw; --veil-y: 51vh; --veil-w: 44vw; --veil-h: 52vh;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; background: var(--paper); color: var(--text); }
body { font-family: 'Montserrat', 'Avenir Next', 'Helvetica Neue', sans-serif; font-weight: 300; letter-spacing: .02em; }
body:not(.awake) { cursor: none; }

.garden, .veil { position: fixed; inset: 0; pointer-events: none; }
.garden img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.garden-base { transform: scale(1.01); }
.garden-growth { opacity: var(--growth); transition: opacity 6s ease; transform-origin: 50% 70%; animation: sway 17s ease-in-out infinite alternate; will-change: transform, opacity; }
/* A cream wash under the room's garden, so the blooms read over the painted leaves. */
.veil {
  inset: auto; left: calc(var(--veil-x) - var(--veil-w)); top: calc(var(--veil-y) - var(--veil-h));
  width: calc(var(--veil-w) * 2); height: calc(var(--veil-h) * 2);
  background: radial-gradient(closest-side, #faf7f0ee 0%, #faf7f0c4 58%, #faf7f000 100%);
  transition: left 1.6s cubic-bezier(.22, .61, .36, 1), top 1.6s cubic-bezier(.22, .61, .36, 1), width 1.6s cubic-bezier(.22, .61, .36, 1), height 1.6s cubic-bezier(.22, .61, .36, 1);
}

/* ---------- brand ---------- */
.brand { position: fixed; top: 5.5vh; left: 4vw; max-width: 34vw; }
/* keeps the words readable once the painted garden has grown in behind them */
.brand::before { content: ""; position: absolute; inset: -5vh -5vw -6vh -4vw; z-index: -1; background: radial-gradient(closest-side, #faf7f0f0 0%, #faf7f0c8 60%, #faf7f000 100%); }
.brand h1 { margin: 0; font-weight: 200; font-size: clamp(18px, 2.1vw, 42px); letter-spacing: .34em; text-transform: uppercase; color: var(--text); }
.brand p { margin: 1.1em 0 0; font-size: clamp(11px, .95vw, 19px); line-height: 1.9; letter-spacing: .08em; color: var(--muted); }

/* ---------- the invite: QR code and room code ---------- */
.invite {
  position: fixed; left: 4vw; top: 57%; transform: translateY(-50%);
  width: min(29vw, 52vh); padding: 2.6vmin 2.6vmin 2.2vmin;
  text-align: center; background: var(--card); border-radius: 16px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: 0 24px 70px #3459531c; transition: opacity .9s ease;
}
.invite.fading { opacity: 0; }
.invite .whisper { margin: 0 0 1.6vmin; font-size: clamp(11px, 1.05vw, 21px); letter-spacing: .36em; margin-right: -.36em; text-transform: uppercase; color: var(--muted); }
.qr { display: block; aspect-ratio: 1; background: #fffdf9; border-radius: 10px; }
.qr svg { display: block; width: 100%; height: 100%; }
.qr path { fill: var(--ink); }
.qr-missing { display: grid; place-items: center; height: 100%; padding: 12%; font-size: clamp(12px, 1.1vw, 20px); line-height: 1.7; letter-spacing: .04em; color: #925c4d; }
.code {
  margin: 2vmin 0 .4vmin; line-height: 1.1; color: var(--ink); overflow-wrap: anywhere;
  font-size: calc(clamp(34px, 6vw, 120px) * var(--code-fit, 1)); font-weight: 300;
  letter-spacing: calc(.26em * var(--code-fit, 1)); margin-right: calc(-.26em * var(--code-fit, 1));
}
.url { margin: 0; font-size: clamp(12px, 1.1vw, 22px); letter-spacing: .06em; color: var(--muted); overflow-wrap: anywhere; }
.warn { margin: 1.4vmin 0 0; font-size: clamp(10px, .8vw, 15px); line-height: 1.6; letter-spacing: .03em; color: #925c4d; }

/* Once the room is full enough, the invite tucks into a corner, the way a game keeps its code on screen. */
body.compact { --field-left: 6vw; --field-top: 21vh; --field-bottom: 30vh; --veil-x: 51vw; --veil-y: 47vh; --veil-w: 56vw; --veil-h: 50vh; }
body.compact .invite { top: auto; bottom: 4vh; transform: none; width: min(13.5vw, 25vh); padding: 1.4vmin 1.4vmin 1.2vmin; }
body.compact .invite .whisper { font-size: clamp(9px, .7vw, 14px); letter-spacing: .24em; margin-right: -.24em; margin-bottom: 1vmin; }
body.compact .code { font-size: calc(clamp(18px, 2.2vw, 44px) * var(--code-fit, 1)); margin-top: 1.1vmin; }
body.compact .url, body.compact .brand p { display: none; }

/* ---------- the room's garden ---------- */
.field {
  position: fixed; left: var(--field-left); right: var(--field-right); top: var(--field-top); bottom: var(--field-bottom);
  transition: left 1.6s cubic-bezier(.22, .61, .36, 1), top 1.6s cubic-bezier(.22, .61, .36, 1), bottom 1.6s cubic-bezier(.22, .61, .36, 1);
}
.empty {
  position: absolute; inset: 0; display: grid; place-items: center; margin: 0;
  font-size: clamp(12px, 1.15vw, 22px); letter-spacing: .16em; color: var(--faint);
  animation: breatheText 7s ease-in-out infinite;
}
.empty[hidden] { display: none; }

.bloom {
  position: absolute; width: var(--bloom); height: var(--bloom);
  margin: calc(var(--bloom) / -2) 0 0 calc(var(--bloom) / -2);
  --heart: 0; --open: 0; --petals: 0;
  transition: opacity 2.4s ease, filter 2.4s ease, width 1.6s ease, height 1.6s ease, margin 1.6s ease;
  animation: breathe var(--breath, 8s) ease-in-out var(--delay, 0s) infinite;
}
.bloom::before, .bloom::after { content: ""; position: absolute; inset: 0; border-radius: 50%; transition: transform 2.8s cubic-bezier(.22, .61, .36, 1), opacity 2.8s ease; }
/* six soft washes around the heart - a watercolor blossom */
.bloom::after {
  background:
    radial-gradient(ellipse 25% 25% at 50% 26%, var(--p) 0 42%, var(--pa) 74%, transparent 100%),
    radial-gradient(ellipse 25% 25% at 70.8% 38%, var(--p) 0 42%, var(--pa) 74%, transparent 100%),
    radial-gradient(ellipse 25% 25% at 70.8% 62%, var(--p) 0 42%, var(--pa) 74%, transparent 100%),
    radial-gradient(ellipse 25% 25% at 50% 74%, var(--p) 0 42%, var(--pa) 74%, transparent 100%),
    radial-gradient(ellipse 25% 25% at 29.2% 62%, var(--p) 0 42%, var(--pa) 74%, transparent 100%),
    radial-gradient(ellipse 25% 25% at 29.2% 38%, var(--p) 0 42%, var(--pa) 74%, transparent 100%);
  transform: rotate(var(--turn, 0deg)) scale(var(--open)); opacity: var(--petals);
}
.bloom::before {
  background: radial-gradient(circle closest-side, var(--h) 0 26%, var(--ha) 52%, transparent 100%);
  transform: scale(var(--heart)); z-index: 1;
}
.bloom { --p: #e8836f8c; --pa: #e8836f2e; --h: #c9956ae6; --ha: #c9956a3d; }
/* a seed, then a bud, then open: each person at their own pace */
.bloom[data-stage=arriving] { --heart: .55; --open: .32; --petals: 0; }
.bloom[data-stage=sharing] { --heart: .62; --open: .7; --petals: .62; }
.bloom[data-stage=listening] { --heart: .66; --open: 1; --petals: .95; }
.bloom.resting { opacity: .36; filter: saturate(.3); }
.bloom.new, .bloom.leaving { opacity: 0; --heart: 0; --open: 0; --petals: 0; }

/* the whole garden answers an introduction: a ring, then a shimmer from the middle out */
.ring {
  position: absolute; left: 50%; top: 50%; width: 130%; aspect-ratio: 1; border-radius: 50%;
  border: 1.5px solid #4f8f8a59; pointer-events: none;
  animation: ring 5s cubic-bezier(.22, .61, .36, 1) forwards;
}
.field.wave .bloom::after { animation: glow 2.6s ease calc(var(--d, 0) * 2.2s) 1; }

.moment {
  position: fixed; left: var(--field-left); right: var(--field-right); bottom: calc(var(--field-bottom) - 7vh); margin: 0;
  text-align: center; font-size: clamp(14px, 1.45vw, 28px); letter-spacing: .12em; color: var(--text);
  opacity: 0; transition: opacity 1.6s ease, left 1.6s cubic-bezier(.22, .61, .36, 1), bottom 1.6s cubic-bezier(.22, .61, .36, 1);
  pointer-events: none;
}
.moment.show { opacity: 1; }

/* ---------- the tally ---------- */
.count { position: fixed; top: 3vh; right: 3vw; margin: 0; text-align: right; line-height: 1; padding: 2vmin 2.4vmin 3vmin 4vmin; border-radius: 40px; background: radial-gradient(farthest-side, #faf7f0f2 0%, #faf7f0d0 62%, #faf7f000 100%); }
.count strong { display: block; font-weight: 200; font-size: clamp(40px, 5.6vw, 118px); letter-spacing: .02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.count span { font-size: clamp(11px, .95vw, 19px); letter-spacing: .34em; margin-right: -.34em; text-transform: uppercase; color: var(--muted); }

.tally { position: fixed; right: 4vw; bottom: 5vh; text-align: right; padding: 1.2vmin 1.8vmin; border-radius: 30px; background: #faf7f0c4; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.legend { display: flex; justify-content: flex-end; gap: 2vw; margin: 0; padding: 0; list-style: none; font-size: clamp(10px, .85vw, 17px); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.legend li { display: flex; align-items: center; gap: .6em; white-space: nowrap; }
.legend li[hidden] { display: none; }
.legend span { color: var(--text); font-weight: 400; font-variant-numeric: tabular-nums; }
.bloom.mini { position: relative; display: inline-block; --bloom: 1.9em; animation: none; margin: -.4em 0; }
.intros { margin: .9em 0 0; font-size: clamp(11px, .95vw, 19px); letter-spacing: .1em; color: var(--text); }
.intros:empty { display: none; }

/* ---------- host controls: out of the way until the mouse moves ---------- */
.controls {
  position: fixed; top: 3vh; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: .6vw; opacity: 0; pointer-events: none; transition: opacity .8s ease;
}
body.awake .controls { opacity: 1; pointer-events: auto; }
.controls button {
  border: 1px solid var(--line); background: #faf7f0c9; color: var(--muted); border-radius: 40px;
  padding: .8em 1.4em; font-family: inherit; font-size: clamp(10px, .72vw, 14px); letter-spacing: .14em;
  text-transform: uppercase; cursor: pointer; transition: background .6s;
}
.controls button:hover { background: #e1e9dc; }
.controls button:focus-visible { outline: 2px solid #496f61; outline-offset: 3px; }
.controls button[hidden] { display: none; }
.status { font-size: clamp(10px, .72vw, 14px); letter-spacing: .12em; color: #925c4d; }

@keyframes breathe { 0%, 100% { transform: scale(.94); } 50% { transform: scale(1.04); } }
@keyframes breatheText { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes sway { 0% { transform: translate3d(-7px, 3px, 0) scale(1.015) rotate(-.25deg); } 50% { transform: translate3d(5px, -8px, 0) scale(1.022) rotate(.18deg); } 100% { transform: translate3d(10px, 2px, 0) scale(1.017) rotate(.38deg); } }
@keyframes ring { from { transform: translate(-50%, -50%) scale(.04); opacity: .9; } to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }
@keyframes glow { 0%, 100% { filter: none; } 35% { filter: brightness(1.08) saturate(1.7); } }

/* A portrait screen (or a phone peeking at /host): stack the invite over the garden. */
@media (max-aspect-ratio: 1/1) {
  :root { --field-left: 7vw; --field-right: 7vw; --field-top: 63vh; --field-bottom: 12vh; --veil-x: 50vw; --veil-y: 78vh; --veil-w: 62vw; --veil-h: 26vh; }
  body.compact { --field-top: 26vh; --field-bottom: 22vh; --veil-x: 50vw; --veil-y: 52vh; --veil-w: 64vw; --veil-h: 36vh; }
  .brand { max-width: 60vw; }
  .invite { left: 50%; top: 13vh; transform: translateX(-50%); width: min(62vw, 44vh); }
  body.compact .invite { left: auto; right: 4vw; top: auto; bottom: 3vh; transform: none; width: 26vw; }
  .count { top: 3vh; }
  .tally { bottom: 2vh; right: 50%; transform: translateX(50%); }
  .legend { gap: 3vw; }
  .moment { bottom: 8vh; }
}

@media (prefers-reduced-motion: reduce) {
  .bloom, .garden-growth, .empty, .field.wave .bloom::after { animation: none !important; }
  .ring { display: none; }
}
