* { box-sizing: border-box; margin: 0; }

:root {
  --dim: 0.12;
  --ink: rgba(255, 255, 255, 0.96);
  --ink-soft: rgba(255, 255, 255, 0.62);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
}

html, body { height: 100%; }
body {
  background: #07080a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
  overflow: hidden;
}

/* Page-wide wash of the current backdrop, so the stage does not sit on black */
.ambient {
  position: fixed;
  inset: -80px;
  background: center / cover no-repeat;
  filter: blur(70px) saturate(1.2) brightness(0.45);
  transition: background-image 0.9s linear;
  z-index: -1;
}

/* ---------- the phone-shaped stage ---------- */
.stage {
  position: relative;
  height: min(100vh - 48px, 880px);
  aspect-ratio: 9 / 19.5;
  border-radius: 46px;
  overflow: hidden;
  box-shadow: 0 40px 120px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.08);
  color: var(--ink);
}

.backdrop, .bg, .dim { position: absolute; inset: 0; width: 100%; height: 100%; }
.bg { object-fit: cover; opacity: 0; transition: opacity 1.1s linear; }
.bg.on { opacity: 1; }
.dim { background: rgba(0, 0, 0, var(--dim)); }

/* ---------- glass ---------- */
.glass {
  background: var(--g-fill);
  -webkit-backdrop-filter: blur(var(--g-blur)) saturate(var(--g-sat));
  backdrop-filter: blur(var(--g-blur)) saturate(var(--g-sat));
  border: 1px solid var(--g-edge);
  box-shadow: inset 0 1px 0 var(--g-shine), inset 0 -1px 0 rgba(0, 0, 0, 0.06), 0 10px 34px rgba(0, 0, 0, 0.16);
}
.stage[data-glass="clear"] {
  --g-fill: rgba(255, 255, 255, 0.1);
  --g-blur: 16px; --g-sat: 1.6;
  --g-edge: rgba(255, 255, 255, 0.28);
  --g-shine: rgba(255, 255, 255, 0.45);
}
.stage[data-glass="frosted"] {
  --g-fill: rgba(255, 255, 255, 0.16);
  --g-blur: 26px; --g-sat: 1.7;
  --g-edge: rgba(255, 255, 255, 0.22);
  --g-shine: rgba(255, 255, 255, 0.35);
}
.stage[data-glass="smoked"] {
  --g-fill: rgba(12, 14, 18, 0.42);
  --g-blur: 16px; --g-sat: 1.4;
  --g-edge: rgba(255, 255, 255, 0.14);
  --g-shine: rgba(255, 255, 255, 0.2);
}
/* Bright footage: switch to dark ink, with a touch more body in the glass */
.stage[data-ink="dark"] {
  --ink: rgba(14, 16, 20, 0.94);
  --ink-soft: rgba(14, 16, 20, 0.58);
  --ink-shadow: transparent;
}
.stage[data-ink="dark"][data-glass="clear"] { --g-fill: rgba(255, 255, 255, 0.2); --g-edge: rgba(255, 255, 255, 0.7); }
.stage[data-ink="dark"][data-glass="frosted"] { --g-fill: rgba(255, 255, 255, 0.36); --g-edge: rgba(255, 255, 255, 0.7); }

/* ---------- chat / gallery panes ---------- */
.panes {
  position: absolute; inset: 0;
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  /* no edge-fade mask here: a mask on an ancestor stops the tiles' backdrop blur from seeing the video */
}
.panes::-webkit-scrollbar { display: none; }
.pane {
  flex: 0 0 100%;
  scroll-snap-align: center;
  overflow-y: auto;
  scrollbar-width: none;
  padding: 96px 14px 108px;
}
.pane::-webkit-scrollbar { display: none; }

.thread { display: flex; flex-direction: column; justify-content: flex-end; gap: 10px; min-height: 100%; }
.msg { display: flex; flex-direction: column; align-items: flex-start; max-width: 84%; }
.msg.out { align-self: flex-end; align-items: flex-end; }
.who { font-size: 10.5px; font-weight: 500; color: var(--ink-soft); margin: 0 0 4px 12px; letter-spacing: 0.02em; }
.msg p, .widget, .grid .note { text-shadow: 0 1px 2px var(--ink-shadow, rgba(0, 0, 0, 0.28)); }
.msg p { padding: 10px 14px; border-radius: 20px; font-size: 14.5px; line-height: 1.38; letter-spacing: -0.005em; }
.msg.in p { border-bottom-left-radius: 7px; }
.msg.out p { border-bottom-right-radius: 7px; background: color-mix(in srgb, var(--g-fill), white 14%); }

.msg figure { border-radius: 20px; overflow: hidden; padding: 4px; }
.msg figure img { display: block; width: 190px; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 16px; }
.msg figcaption { font-size: 12.5px; padding: 7px 9px 5px; color: var(--ink-soft); }

.widget { width: 252px; border-radius: 22px; padding: 14px; }
.w-head b { display: block; font-size: 14.5px; font-weight: 600; }
.w-head span { font-size: 12px; color: var(--ink-soft); }
.widget ul { list-style: none; padding: 0; margin: 12px 0; }
.widget li { display: flex; justify-content: space-between; font-size: 13px; padding: 7px 0; border-top: 1px solid color-mix(in srgb, var(--ink), transparent 88%); }
.widget em { font-style: normal; color: var(--ink-soft); }
.widget em.warn { color: #ffb37a; }
.stage[data-ink="dark"] .widget em.warn { color: #b4530c; }
.w-actions { display: flex; gap: 8px; }
.w-actions button {
  flex: 1; border: 1px solid color-mix(in srgb, var(--ink), transparent 80%);
  background: none; color: var(--ink);
  font: 500 12.5px inherit; padding: 9px 0; border-radius: 999px; cursor: pointer;
}
.w-actions .primary { background: var(--ink); color: #0c0e12; border-color: transparent; }
.stage[data-ink="dark"] .w-actions .primary { color: #fff; }

/* "Only you" — placeholder treatment, to be designed properly */
.private p { border-style: dashed; border-color: color-mix(in srgb, var(--ink), transparent 45%); }
.private .who::before { content: "◐ "; }

/* masonry: three columns laid out in app.js (Safari drops tiles from CSS
   multi-column layouts). */
.grid { display: flex; gap: 7px; align-items: flex-start; }
.grid .col { flex: 1; min-width: 0; padding-top: var(--air, 0px); }
.grid figure { margin-bottom: 7px; border-radius: 15px; padding: 3px; overflow: hidden; }
.grid img { display: block; width: 100%; height: auto; border-radius: 12px; }
.grid .note { padding: 12px 10px; min-height: 84px; display: flex; flex-direction: column; justify-content: flex-end; }
.grid .note b { font-size: 12.5px; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.grid .note span { font-size: 10.5px; color: var(--ink-soft); margin-top: 3px; }

/* ---------- compose ---------- */
.compose {
  display: flex; align-items: flex-start; gap: 10px;
  min-height: 44px;
  padding: 12px 20px 12px 16px;
  font-size: 14.5px;
  color: var(--ink-soft);
  cursor: text;
}
.compose span { flex: 1; }
.round {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%; border: 0;
  background: rgba(255, 255, 255, 0.18);
  color: var(--ink);
  font: 300 22px/1 inherit;
  cursor: pointer;
}

/* ---------- phone-width: stage goes full bleed, panel becomes a sheet ---------- */
@media (max-width: 760px) {
  body { display: block; }
  .stage { width: 100%; height: 100dvh; aspect-ratio: auto; border-radius: 0; box-shadow: none; }
  .lab { display: none; } /* no tuning panel on phones */
  .lab-toggle {
    display: block; margin-left: auto;
    border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(18, 20, 24, 0.6);
    backdrop-filter: blur(20px); color: #fff; font: 500 12px inherit;
    padding: 8px 12px; border-radius: 999px;
  }
  .lab-body { display: none; width: min(264px, 100vw - 24px); margin-top: 8px; }
  .lab.open .lab-body { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .bg { transition: none; }
}

.pane { padding-top: 74px; } /* room for the top pill */

/* ---------- dock: the message pill that grows into the keyboard ---------- */
/* One glass shape. At rest it is the floating pill; while typing it stretches
   to the screen edges and down to the bottom, and the keys rise inside it. */
.stage { --dock-open: 284px; --extra: 0px; --spring: cubic-bezier(0.3, 1.18, 0.4, 1); }
.dock {
  position: absolute; z-index: 3;
  left: 14px; right: 14px; bottom: 22px;
  height: calc(46px + var(--extra));
  border-radius: 23px;
  /* an even hairline all round: no inset highlight on this shape */
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.16);
  overflow: hidden;
  transition: left 0.62s var(--spring), right 0.62s var(--spring), bottom 0.62s var(--spring),
    height 0.62s var(--spring), border-radius 0.62s var(--spring);
}
.stage.typing .dock {
  left: -1px; right: -1px; bottom: -1px;
  height: calc(var(--dock-open) + var(--extra));
  border-radius: 0;
}
/* the draft wraps and grows to four lines, then scrolls; --extra is the height
   beyond one line, set from app.js so the dock and chat can grow with it */
.compose #draft {
  line-height: 20px; max-height: 80px;
  white-space: pre-wrap; overflow-wrap: anywhere;
  overflow-y: auto; scrollbar-width: none;
}
.compose #draft::-webkit-scrollbar { display: none; }
.compose #draft:not(.empty) { color: var(--ink); }
.stage.typing #draft::after {
  content: ""; display: inline-block; width: 1.5px; height: 1.15em; margin-left: 1px;
  vertical-align: -0.2em; background: var(--ink); animation: caret 1.1s steps(1) infinite;
}
@keyframes caret { 50% { opacity: 0; } }
/* the chat makes room at the same pace as the dock, in both directions */
.pane { transition: padding-bottom 0.62s var(--spring); }
.pane { padding-bottom: calc(108px + var(--extra)); }
.stage.typing .pane { padding-bottom: calc(var(--dock-open) + var(--extra) + 14px); }

/* pinned to the bottom of the dock, so a taller message field never moves the keys */
.keys {
  position: absolute; left: 0; right: 0; bottom: 31px;
  padding: 0 6px;
  pointer-events: none;
  display: flex; flex-direction: column; gap: 7px;
  user-select: none; -webkit-user-select: none;
  touch-action: manipulation;
}
/* rows rise in one after another on open, and drop away together on close */
.keys .row {
  opacity: 0;
  transform: translateY(16px) scale(0.96);
  transition: opacity 0.18s linear, transform 0.3s var(--ease);
}
.stage.typing .keys { pointer-events: auto; }
.stage.typing .keys .row {
  opacity: 1;
  transform: none;
  transition: opacity 0.4s linear, transform 0.62s var(--spring);
  transition-delay: calc(90ms + var(--i) * 45ms);
}
.keys .row:nth-child(1) { --i: 0; }
.keys .row:nth-child(2) { --i: 1; }
.keys .row:nth-child(3) { --i: 2; }
.keys .row:nth-child(4) { --i: 3; }
.keys .row { display: flex; gap: 5px; justify-content: center; }
.keys .row.inset { padding: 0 5%; }
/* Each key is a full-size invisible touch target; the visible tile (.cap) is
   drawn smaller inside it, so the look can change without shrinking the target. */
.key {
  flex: 1; height: 44px; min-width: 0; padding: 0;
  display: grid; align-items: center;
  border: 0; background: none;
  color: var(--ink);
  font: 400 19px/1 inherit;
  cursor: pointer;
}
.key.wide { flex: 1.5; font-size: 15px; }
.key.space { flex: 5; font-size: 13px; color: var(--ink-soft); letter-spacing: 0.04em; }
.key.mode { flex: 1.7; font-size: 14px; }
.key.send { flex: 1.7; }
.key.space { flex: 4; }
/* the keyboard is one blurred glass panel; keys are lighter tiles resting on it */
.cap {
  height: 34px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: color-mix(in srgb, var(--ink), transparent 88%);
  border: 1px solid color-mix(in srgb, var(--ink), transparent 84%);
  box-shadow: inset 0 1px 0 var(--g-shine);
  transition: transform 0.18s var(--ease), background 0.18s linear;
}
.key.down .cap { transform: scale(0.9); background: color-mix(in srgb, var(--ink), transparent 45%); }

.msg p { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ---------- lightbox ---------- */
/* The tapped asset flies from its tile to the centre; behind it the whole
   screen becomes a blurred, darkened copy of that same asset. */
.grid img, .msg figure img { cursor: zoom-in; }
.lightbox { position: absolute; inset: 0; z-index: 5; pointer-events: none; overflow: hidden; }
.lightbox.open { pointer-events: auto; cursor: grab; touch-action: none; }
.lb-bg {
  position: absolute; inset: -70px;
  background: center / cover no-repeat;
  filter: blur(42px) brightness(0.45) saturate(1.25);
  opacity: 0;
  transition: opacity 0.5s linear;
}
.lb-bg.on { opacity: 1; }
.lb-img {
  position: absolute; z-index: 1;
  object-fit: cover;
  -webkit-user-drag: none; user-select: none;
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
}
.lb-img.fly {
  transition: left 0.6s var(--spring), top 0.6s var(--spring), width 0.6s var(--spring),
    height 0.6s var(--spring), border-radius 0.6s var(--spring), translate 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
/* the message dock stays above the lightbox, so you can talk to ARCADE about the asset */
.dock { z-index: 6; }

/* video tiles: a play mark and running time over the poster */
.grid .vid { position: relative; }
.grid .badge {
  position: absolute; left: 8px; bottom: 8px;
  padding: 3px 7px 3px 6px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.45); color: #fff;
  font-size: 10px; font-weight: 500; font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.grid .badge::before { content: "▶"; font-size: 7px; margin-right: 4px; vertical-align: 1px; }

/* ---------- home masthead ---------- */
/* Fashion-magazine masthead: a high-contrast Didone serif set large and
   tight, with a small tracked kicker line above it. */
.pane.home { position: relative; }
.masthead {
  position: absolute; left: 20px; bottom: 30px;
  color: var(--ink);
  text-shadow: 0 1px 2px var(--ink-shadow, rgba(0, 0, 0, 0.3)), 0 0 30px rgba(0, 0, 0, 0.14);
  user-select: none; -webkit-user-select: none;
}
.wordmark {
  margin: 0;
  font: var(--mast-weight, 400) var(--mast-size, 58px)/0.9 var(--mast-font, "Bodoni Moda"), "Didot", serif;
  font-variation-settings: "opsz" 96;
  letter-spacing: var(--mast-track, -0.015em);
}


/* ---------- tuning panel (tooling, not app design) ----------
   Every row is the same three columns: name | control | value. */
.lab { width: 316px; flex: none; }
@media (min-width: 761px) { .lab-toggle { display: none; } }
.lab-body {
  --col-name: 84px; --col-value: 68px;
  padding: 18px 18px 14px;
  border-radius: 22px;
  background: rgba(18, 20, 24, 0.6);
  backdrop-filter: blur(30px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.72);
  max-height: calc(100vh - 48px); overflow-y: auto; scrollbar-width: thin;
}
.lab h1 { font-size: 13px; font-weight: 600; color: #fff; margin-bottom: 14px; }
.clips { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin-bottom: 16px; }
.clips button {
  aspect-ratio: 9 / 16; border-radius: 9px; border: 0; padding: 0; cursor: pointer;
  background: center / cover; opacity: 0.55;
  outline: 2px solid transparent; outline-offset: 2px;
  transition: opacity 0.3s, outline-color 0.3s;
}
.clips button.on { opacity: 1; outline-color: #fff; }

.lab label, .seg {
  display: grid; grid-template-columns: var(--col-name) 1fr var(--col-value);
  align-items: center; column-gap: 10px;
  min-height: 30px; margin: 0 0 6px;
  white-space: nowrap;
}
.lab label input[type="range"] { grid-column: 2; grid-row: 1; }
.lab output { grid-column: 3; grid-row: 1; text-align: right; color: #fff; font-variant-numeric: tabular-nums; }
/* button groups: fixed name column, then the buttons share the rest by content */
.seg { display: flex; gap: 4px; }
.seg > span { flex: 0 0 var(--col-name); margin-right: 6px; }
.seg > button { flex: 1 1 auto; }
.seg > select { flex: 1 1 auto; }

/* sliders: a hairline track and a small white thumb */
.lab input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 18px; margin: 0; background: none; cursor: pointer; }
.lab input[type="range"]::-webkit-slider-runnable-track { height: 2px; border-radius: 2px; background: rgba(255, 255, 255, 0.18); }
.lab input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; margin-top: -5px; border-radius: 50%; background: #fff; border: 0; }
.lab input[type="range"]::-moz-range-track { height: 2px; border-radius: 2px; background: rgba(255, 255, 255, 0.18); }
.lab input[type="range"]::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 0; }

.seg button, .lab select {
  min-width: 0; height: 26px; padding: 0 6px;
  border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 999px;
  background: none; color: inherit;
  font: inherit; font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
}
.seg button.on { background: #fff; color: #0c0e12; border-color: #fff; }
.lab select { background: rgba(255, 255, 255, 0.08); }

.lab .group { margin: 2px 0 10px; padding-left: 10px; border-left: 1px solid rgba(255, 255, 255, 0.12); }
.lab .group label, .lab .group .seg { --col-name: 78px; }
.lab hr { border: 0; border-top: 1px solid rgba(255, 255, 255, 0.08); margin: 10px 0 12px; }

.meter { position: relative; height: 2px; border-radius: 2px; background: rgba(255, 255, 255, 0.14); margin: 14px 0 10px; }
.meter::after { content: ""; position: absolute; left: 50%; top: -3px; width: 1px; height: 8px; background: rgba(255, 255, 255, 0.4); }
#playhead { position: absolute; top: -2.5px; width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%; background: #fff; }
.hint { font-size: 10.5px; line-height: 1.45; color: rgba(255, 255, 255, 0.45); }

/* ---------- connection card ---------- */
.connect {
  width: 236px;
  padding: 22px 18px 16px;
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px;
}
.g-mark {
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
}
.connect p {
  margin: 0; padding: 0 !important; border: 0 !important; background: none !important; box-shadow: none !important;
  font-size: 13px !important; line-height: 1.4 !important; color: var(--ink-soft);
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
.g-cta {
  width: 100%; padding: 10px 0;
  border: 0; border-radius: 999px;
  background: var(--ink); color: #0c0e12;
  font: 500 13px inherit; cursor: pointer;
}
.stage[data-ink="dark"] .g-cta { color: #fff; }

/* ---------- sign-in: three glass icons, centred, revealed by tapping ARCADE ---------- */
.login {
  position: absolute; inset: 0;
  display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 36px;
  pointer-events: none;
}
.login.on { pointer-events: auto; }
.auth {
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--ink);
  cursor: pointer;
  opacity: 0;
  transform: translateY(26px) scale(0.7);
  transition: opacity 0.22s linear, transform 0.32s var(--ease);
}
.login.on .auth {
  opacity: 1;
  transform: none;
  transition: opacity 0.3s linear, transform 0.62s var(--spring);
  transition-delay: calc(var(--i) * 60ms);
}
.auth:nth-child(1) { --i: 0; }
.auth:nth-child(2) { --i: 1; }
.auth:nth-child(3) { --i: 2; }
.auth:active { transform: scale(0.94); transition-duration: 0.1s; }
.stage[data-ink="dark"] .auth[data-provider="google"] { background: rgba(255, 255, 255, 0.55); }

/* signed in: your own disc, top left of the home screen, half the size of a contact's */
.me {
  position: absolute; top: 18px; left: 18px; z-index: 2;
  width: 45px; height: 45px;
  border-radius: 50%;
  display: grid; place-items: center;
  opacity: 0; scale: 0.6; pointer-events: none;
  transition: opacity 0.3s linear, scale 0.62s var(--spring);
  -webkit-user-select: none; user-select: none;
}
.stage.signed-in .me { opacity: 1; scale: 1; pointer-events: auto; }
.me .av {
  width: 90%; height: 90%; border-radius: 50%;
  background: center / cover no-repeat;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28), inset 0 0 0 1px rgba(255, 255, 255, 0.4);
  pointer-events: none;
}

/* ---------- attach button ---------- */
.plus {
  flex: none; width: 20px; height: 20px; margin: 0; padding: 0;
  display: grid; place-items: center;
  border: 0; background: none; cursor: pointer;
  color: var(--ink-soft);
}
.plus:active { color: var(--ink); }

/* ---------- contacts: discs on a pond ---------- */
.stage .pane.contacts { padding: 0; position: relative; overflow: hidden; }
.disc {
  position: absolute; left: 0; top: 0;
  width: 90px; height: 90px;
  border-radius: 50%;
  display: grid; place-items: center;
  touch-action: none; cursor: grab;
  -webkit-user-select: none; user-select: none;
  transition: scale 0.45s var(--spring);
}
.disc.held { scale: 1.1; cursor: grabbing; z-index: 2; }
.disc .av {
  width: 90%; height: 90%; border-radius: 50%;
  background: center / cover no-repeat;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.28), inset 0 0 0 1px rgba(255, 255, 255, 0.4);
  pointer-events: none;
}
.disc .nm {
  position: absolute; top: 100%; left: 50%;
  translate: -50% 6px;
  font-size: 11px; letter-spacing: 0.02em; white-space: nowrap;
  color: var(--ink-soft);
  text-shadow: 0 1px 2px var(--ink-shadow, rgba(0, 0, 0, 0.3));
  pointer-events: none;
  opacity: 0; transition: opacity 0.25s linear; /* names show only while a disc is held */
}
.disc.held .nm { opacity: 1; }

/* ---------- top pill: the chat you are in ---------- */
.topbar {
  position: absolute; z-index: 3;
  top: 14px; left: 14px; right: 14px; height: 46px;
  border-radius: 23px;
  display: grid; place-items: center;
  padding: 0 20px;
  font: 500 14px inherit; color: var(--ink);
  cursor: pointer;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.16);
}
.topbar span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

/* ---------- sheet: blurred layer with morphing glass choices ---------- */
.sheet {
  position: absolute; inset: 0; z-index: 7;
  opacity: 0; pointer-events: none;
  transition: opacity 0.3s linear;
}
/* The blurred background is a snapshot of the video, blurred as an image
   (sheet-bg), rather than a live backdrop-filter: it covers the whole stage on
   every browser and fades in as one smooth layer. A tint sits over it. */
.sheet-bg {
  position: absolute; left: -80px; top: -80px;
  width: calc(100% + 160px); height: calc(100% + 160px);
}
.sheet::before {
  content: ""; position: absolute; inset: -80px;
  background: rgba(0, 0, 0, 0.16);
}
.sheet.on { opacity: 1; pointer-events: auto; }
.morph {
  position: absolute;
  transition: left 0.6s var(--spring), top 0.6s var(--spring), width 0.6s var(--spring), height 0.6s var(--spring),
    border-radius 0.6s var(--spring), background 0.3s linear, border-color 0.3s linear, box-shadow 0.3s linear,
    -webkit-backdrop-filter 0.3s linear, backdrop-filter 0.3s linear;
}
.morph.dissolve { background: transparent; border-color: transparent; box-shadow: none; -webkit-backdrop-filter: blur(0); backdrop-filter: blur(0); }
.stack {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  width: 232px;
  display: flex; flex-direction: column; gap: 10px;
}
.stack .lead {
  text-align: center; font-size: 12px; color: var(--ink-soft); margin-bottom: 2px;
  text-shadow: 0 1px 2px var(--ink-shadow, rgba(0, 0, 0, 0.3));
}
.stack .pill {
  height: 46px; border-radius: 23px; padding: 0 18px;
  display: grid; place-items: center;
  font: 500 14px inherit; color: var(--ink);
  cursor: pointer;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.16);
}
.stack .pill:disabled { color: var(--ink-soft); cursor: default; }
.stack .pill span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.stack .pill, .stack .lead {
  opacity: 0; transform: translateY(12px) scale(0.92);
  transition: opacity 0.2s linear, transform 0.3s var(--ease);
}
.stack .in {
  opacity: 1; transform: none;
  transition: opacity 0.3s linear, transform 0.6s var(--spring);
  transition-delay: calc(var(--i, 0) * 45ms);
}
.stack { max-height: calc(100% - 140px); overflow-y: auto; scrollbar-width: none; padding: 4px; }
.stack::-webkit-scrollbar { display: none; }

/* ---------- contact profile ---------- */
/* The tapped disc grows and settles at the top centre; name, bio, actions and
   the contact's wall of assets fade in beneath it over a blurred background. */
.sheet.is-profile::before { background: rgba(0, 0, 0, 0.24); }
.morph.portrait {
  display: grid; place-items: center; cursor: pointer; z-index: 2;
  /* moves by translate/scale only (see aimPortrait), so it stays on the compositor */
  transition: translate 0.6s var(--spring), scale 0.6s var(--spring);
  will-change: translate, scale;
  /* the sheet behind it is already a blurred snapshot: a backdrop blur here
     would be invisible and would re-rasterise every frame of the morph */
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.morph.portrait .av {
  width: 78%; height: 78%; border-radius: 50%;
  background: center / cover no-repeat;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.4);
  pointer-events: none;
  transition: scale 0.6s var(--spring);
  will-change: scale;
}
.profile {
  position: absolute; inset: 0;
  overflow-y: auto; scrollbar-width: none;
  padding: 176px 14px 110px; /* clear of the portrait above, room for the message pill below */
  color: var(--ink);
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.35s linear, transform 0.65s var(--spring);
}
.profile::-webkit-scrollbar { display: none; }
.profile.in { opacity: 1; transform: none; }
.profile h2 { margin: 0; text-align: center; font-size: 19px; font-weight: 600; letter-spacing: -0.01em; }
.profile .role { text-align: center; font-size: 12px; color: var(--ink-soft); margin-top: 3px; letter-spacing: 0.02em; }
.profile .bio {
  max-width: 300px; margin: 16px auto 20px;
  text-align: center; font-size: 13.5px; line-height: 1.45;
  color: color-mix(in srgb, var(--ink), transparent 14%);
  text-shadow: 0 1px 2px var(--ink-shadow, rgba(0, 0, 0, 0.3));
}
.profile .wall { margin-top: 26px; }
.lightbox.over { z-index: 8; } /* above the profile sheet when opened from it */

/* the message pill rides above the profile sheet, so writing starts a chat */
.dock.float { z-index: 8; }
/* hidden until the script places them, so nothing flashes on the home screen while loading */
.dock, .topbar { opacity: 0; }

/* the invite disc: an empty glass disc with a plus */
.disc.invite { color: var(--ink-soft); }
.disc .plus-glyph { pointer-events: none; }

/* The name and bio fade with the scroll as a scroll-driven animation: the
   browser's compositor runs it in lockstep with the scroll position, with no
   script involved. Browsers without it fall back to the frame loop in app.js. */
@supports (animation-timeline: scroll()) {
  .profile .intro {
    animation: intro-fade linear both;
    animation-timeline: scroll(nearest block);
    animation-range: 0 60px;
  }
  @keyframes intro-fade {
    from { opacity: 1; translate: 0 0; }
    to { opacity: 0; translate: 0 30px; }
  }
}

/* a mouse drag across the sections: nothing selects or lifts while the strip follows the pointer */
.stage.dragging, .stage.dragging * { cursor: grabbing; -webkit-user-select: none; user-select: none; }
.panes img { -webkit-user-drag: none; }

/* the profile scrolls vertically and swipes away sideways */
.profile { touch-action: pan-y; overflow-x: hidden; -webkit-user-select: none; user-select: none; }
.profile img { -webkit-user-drag: none; }

/* ---------- performance ----------
   Nothing below changes the look; it removes work the GPU was doing for no
   visible result. */
/* Gallery tiles are almost entirely covered by their image, so blurring the
   backdrop behind them was invisible but costly. They keep the glass fill and
   edge without the blur. The contact discs keep theirs: the frosted rim is
   part of the look. */
.grid figure.glass { -webkit-backdrop-filter: none; backdrop-filter: none; }
.disc, .lb-img, .sheet { will-change: translate; }
/* the page-wide wash is behind the full-bleed stage on phones: not visible, so not rendered */
@media (max-width: 760px) { .ambient { display: none; } }
/* (the strip already has overscroll-behavior-x: contain above; the panes
   themselves must not, or a trackpad swipe over a scrolling pane never
   reaches the strip) */
