/* Moving between views, and the chat surfaces.
 *
 * Loaded after app.css and phone.css. nav.js changes the view in place
 * instead of loading a new page; this file is how that change looks. The
 * header, the bands and the bottom bar hold still, and only the scrolling
 * region moves: forward slides in from the right, back slides in from the
 * left, both short enough never to be waited for.
 */

/* --- the view change ------------------------------------------------------ */

/* Only the content moves. Everything with its own name holds still and
   cross-fades only if it actually changed (the tab indicator, a badge). */
html.nav-vt #viewport { view-transition-name: view; }
html.nav-vt .site-header { view-transition-name: app-header; }
html.nav-vt .tabbar { view-transition-name: app-tabbar; }
html.nav-vt .site-footer { view-transition-name: app-footer; }
html.nav-vt .wristband-top { view-transition-name: app-band; }

::view-transition-old(root),
::view-transition-new(root) { animation: none; }

/* Short, on one curve, and only opacity and transform, which the phone's
   graphics chip does by itself: the old view steps back as the new one
   arrives, rather than one waiting for the other. */
::view-transition-old(view) {
  animation: view-out .14s cubic-bezier(.4, 0, 1, 1) both;
}
::view-transition-new(view) {
  animation: view-in .22s cubic-bezier(.2, 0, 0, 1) both;
}
html.nav-back::view-transition-old(view) { animation-name: view-out-back; }
html.nav-back::view-transition-new(view) { animation-name: view-in-back; }

@keyframes view-out      { to   { opacity: 0; transform: translateX(-16px); } }
@keyframes view-in       { from { opacity: 0; transform: translateX(22px); } }
@keyframes view-out-back { to   { opacity: 0; transform: translateX(16px); } }
@keyframes view-in-back  { from { opacity: 0; transform: translateX(-22px); } }

/* Where views change with a transition (nav.js sets nav-smooth when the
   browser can), the page-arrival rise from phone.css is off for good. It
   used to be paused only during the slide, and so started up again the
   moment the slide ended: every view arrived twice. Browsers without view
   transitions keep the rise, because there it is the only motion. */
html.nav-smooth body:not(.no-app) .shell > * { animation: none; }

/* Sign in and Sign out, as buttons that sit level with whatever is beside
   them (the alerts square, or Join). */
.site-header .btn.signout,
.site-header .btn.signin {
  min-height: 38px;
  padding: 7px 14px;
  font-size: .78rem;
  letter-spacing: .04em;
  background: var(--surface);
}

/* A button that has been pressed and is waiting on the server. */
[aria-busy="true"] { cursor: progress; opacity: .75; }

/* --- the loading bar ---------------------------------------------------- */

.nav-progress {
  position: fixed; top: 0; left: 0; z-index: 90;
  height: 3px; width: 0;
  background: var(--accent-grad, var(--accent));
  box-shadow: 0 0 6px rgba(var(--accent-rgb), .45);
  opacity: 0;
  pointer-events: none;
}
.nav-progress.on {
  opacity: 1;
  width: 72%;
  transition: width 2.4s cubic-bezier(.1, .6, .2, 1), opacity .1s linear;
}
.nav-progress.done {
  width: 100%;
  opacity: 0;
  transition: width .18s ease-out, opacity .22s linear .1s;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(view),
  ::view-transition-new(view) { animation: none; }
  .nav-progress.on, .nav-progress.done { transition: none; }
}

/* --- conversation lists, like a phone's messages app ---------------------
 * Face on the left, name and time on one line, the last message under it in
 * grey, a dot for anything unread, hairlines that start where the text does.
 * The dot is the cool bead colour (plum), the one that reads as "unread"
 * next to the rose of your own messages.
 */
.ios-title { margin-bottom: 4px; }
.ios-sub { margin: 0 0 14px; }

.ios-section {
  display: flex; align-items: center; gap: 8px;
  margin: 22px 0 8px; font-size: 1.02rem;
}

.ios-search {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 12px; padding: 0 12px;
  height: 38px; border-radius: 12px;
  background: var(--surface-2);
  color: var(--muted);
}
.ios-search svg {
  width: 17px; height: 17px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.ios-search input {
  flex: 1; min-width: 0; height: 100%;
  border: 0; background: transparent; padding: 0;
  font: inherit; font-size: .98rem; color: var(--text); outline: none;
  box-shadow: none;
}

.ios-list {
  background: var(--surface);
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--line-soft);
}

.ios-row {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px 10px 22px;
  color: inherit; text-decoration: none;
  transition: background-color .15s ease;
}
.ios-row:hover { background: var(--surface-2); }
.ios-row:active { background: var(--line-soft); }

/* The hairline starts at the text, not the screen edge. */
.ios-row + .ios-row::before {
  content: ""; position: absolute; top: 0; right: 0;
  left: 86px; height: 1px; background: var(--line-soft);
}

.ios-dot {
  position: absolute; left: 7px; top: 50%;
  width: 9px; height: 9px; margin-top: -4.5px;
  border-radius: 50%; background: transparent;
}
.ios-row.unread .ios-dot { background: var(--bead-blue, #7b2fc9); }

.ios-row .ios-face,
.ios-row img.avatar {
  width: 52px; height: 52px; flex: none;
  border-radius: 50%; object-fit: cover;
  /* No wristband round a face in a list: it is a thumbnail, not a photo. */
  border: 0; background: var(--surface-2);
}

.ios-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ios-top { display: flex; align-items: baseline; gap: 6px; }
.ios-name {
  flex: 1; min-width: 0;
  font-weight: 600; font-size: 1rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ios-row.unread .ios-name { font-weight: 750; }
.ios-time { flex: none; font-size: .8rem; color: var(--muted); }
.ios-row.unread .ios-time { color: var(--bead-blue, #7b2fc9); font-weight: 600; }
.ios-chev { flex: none; color: var(--muted); opacity: .6; font-size: 1.15rem; line-height: 1; }

.ios-preview {
  font-size: .9rem; color: var(--muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ios-row.unread .ios-preview { color: var(--text); }
.ios-preview .receipt { margin-right: 4px; }
.ios-preview .keen-tag { margin-right: 6px; }
.ios-none { text-align: center; margin: 14px 0; }

/* --- a conversation, like a phone's messages app ------------------------- */

body.chat-open .msgs { gap: 3px; padding: 10px 0 12px; }

body.chat-open .msg {
  max-width: 76%;
  padding: 8px 13px 6px;
  border: 0;
  border-radius: 19px 19px 19px 6px;
  background: #ebe4d8;
  color: var(--text);
  box-shadow: none;
  line-height: 1.38;
  overflow-wrap: anywhere;
}
body.chat-open .msg.mine {
  border-radius: 19px 19px 6px 19px;
  background: linear-gradient(160deg, var(--rose-light, #ff5c93) 0%, var(--shuka, #f72a73) 55%, var(--rose-deep, #d10f58) 100%);
  color: #fffaf2;
  margin-bottom: 0;
}
/* The bead foot and the blue edge belong to the old square bubbles. */
body.chat-open .msg.mine::after { content: none; }

/* A run of bubbles from the same person sits close; a change of speaker
   gets a little air, like any messages app. */
body.chat-open .msg.mine + .msg:not(.mine),
body.chat-open .msg:not(.mine) + .msg.mine { margin-top: 9px; }

body.chat-open .msg .meta {
  margin-top: 2px; font-size: .66rem; opacity: .7; text-align: right;
}
body.chat-open .msg.mine .meta { color: rgba(255, 250, 242, .82); opacity: 1; }

/* Photos sit in the bubble edge to edge, rounded, no frame round them. */
body.chat-open .msg.photo { padding: 3px; background: #ebe4d8; }
body.chat-open .msg.photo.mine { background: #d9a2a0; }
body.chat-open .msg.photo .meta { padding: 0 8px 3px; color: var(--muted); }
body.chat-open .msg img.shot {
  display: block; border: 0; background: none;
  border-radius: 16px; max-width: 100%;
}

/* Your message, on its way: there, but quieter until it is confirmed. */
body.chat-open .msg.pending { opacity: .6; }
body.chat-open .msg.failed {
  opacity: 1; cursor: pointer;
  outline: 2px solid var(--danger, #a3201f); outline-offset: 2px;
}
body.chat-open .msg.failed .meta { color: #fff; font-weight: 600; }

body.chat-open .msg.arriving { animation: bubble-in .22s cubic-bezier(.2, 0, 0, 1) both; }
@keyframes bubble-in {
  from { opacity: 0; transform: translateY(6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
body.chat-open .msg.mine.arriving { transform-origin: 100% 100%; }
body.chat-open .msg:not(.mine).arriving { transform-origin: 0 100%; }

/* "typing", as a little bubble of its own. */
body.chat-open .typing { height: auto; min-height: 0; padding: 0 0 6px; }
body.chat-open .typing:not(:empty) {
  display: inline-block;
  margin: 2px 0 8px; padding: 6px 12px;
  border-radius: 16px; background: #ebe4d8;
  font-size: .78rem; color: var(--muted);
  animation: typing-pulse 1.2s ease-in-out infinite;
}
@keyframes typing-pulse { 50% { opacity: .55; } }

/* The composer: a rounded field and a round send button. */
body.chat-open .composer {
  align-items: flex-end; gap: 8px;
  padding: 8px 12px 12px;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  backdrop-filter: saturate(1.4) blur(12px);
}
body.chat-open .composer textarea {
  min-height: 40px; padding: 9px 15px;
  border-radius: 20px; border: 1px solid var(--line);
  background: var(--surface); resize: none; line-height: 1.35;
  /* chat.js grows the box with the text, so no scrollbar until the cap. */
  overflow-y: hidden;
}
body.chat-open .composer textarea.at-cap { overflow-y: auto; }
body.chat-open .composer .btn {
  min-height: 40px; height: 40px; border-radius: 20px; padding: 0 16px;
}
body.chat-open .composer label.btn {
  width: 40px; padding: 0; display: grid; place-items: center;
  border-radius: 50%;
}

/* Reading further up when something new arrives: a pill, not a yank. */
.new-pill {
  position: sticky; bottom: 76px; z-index: 36;
  display: block; margin: 0 auto 6px;
  padding: 7px 14px; border: 0; border-radius: 18px;
  background: var(--text); color: var(--surface);
  font: inherit; font-size: .8rem; font-weight: 600;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
  cursor: pointer;
  animation: bubble-in .2s ease-out both;
}
.new-pill[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  body.chat-open .msg.arriving, .new-pill, body.chat-open .typing:not(:empty) { animation: none; }
}

/* --- openers, as quick replies -------------------------------------------- */

body.chat-open .openers { margin: 6px 0 10px; }
body.chat-open .openers-label {
  display: block; margin: 0 2px 6px;
  font-size: .76rem; color: var(--muted);
}
/* One swipeable row on a phone, wrapping on a wide screen. */
body.chat-open .openers-row {
  display: flex; gap: 8px;
  overflow-x: auto; scroll-snap-type: x proximity;
  padding: 2px 2px 6px; margin: 0 -2px;
  scrollbar-width: none;
}
body.chat-open .openers-row::-webkit-scrollbar { display: none; }
@media (min-width: 760px) {
  body.chat-open .openers-row { flex-wrap: wrap; overflow: visible; }
}
body.chat-open .opener {
  flex: none; scroll-snap-align: start;
  max-width: 82%;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--surface);
  color: var(--text);
  font: inherit; font-size: .88rem; font-weight: 400;
  line-height: 1.35; text-align: left;
  text-transform: none; letter-spacing: normal;
  white-space: normal;
  box-shadow: 0 1px 2px rgba(60, 40, 25, .06);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, transform .1s ease;
}
body.chat-open .opener:hover { border-color: var(--accent); }
body.chat-open .opener:active { transform: scale(.97); background: var(--accent-soft); }

/* The camera, as a round button with a proper icon size, and Send in plain
   case, like the rest of a messages app. */
body.chat-open .composer label.btn {
  border: 0; background: var(--surface-2);
  font-size: 1.15rem; line-height: 1; color: var(--text);
  box-shadow: none;
}
body.chat-open .composer button[type="submit"] {
  text-transform: none; letter-spacing: normal; font-weight: 650;
}

/* --- the in-app banner (pulse.js) and the badges it moves ----------------- */

.pulse-banner {
  position: fixed; z-index: 95;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  left: 50%; width: min(480px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border-radius: 18px;
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  -webkit-backdrop-filter: saturate(1.6) blur(18px);
  backdrop-filter: saturate(1.6) blur(18px);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(40, 25, 15, .22);
  color: var(--text); text-decoration: none;
  transform: translate(-50%, -140%);
  opacity: 0;
  transition: transform .32s cubic-bezier(.2, 0, 0, 1), opacity .2s ease;
  cursor: pointer;
}
.pulse-banner.show { transform: translate(-50%, 0); opacity: 1; }
.pulse-icon {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: 10px;
  background: var(--accent-grad, var(--accent)); color: #fff; font-size: 1rem;
}
.pulse-text { flex: 1; min-width: 0; font-size: .92rem; line-height: 1.3; }
.pulse-go { flex: none; color: var(--muted); font-size: 1.3rem; }

.tabbar .count.bump, .site-header .badge.bump { animation: badge-bump .4s cubic-bezier(.2, 0, 0, 1); }
@keyframes badge-bump { 40% { transform: scale(1.35); } }

@media (prefers-reduced-motion: reduce) {
  .pulse-banner { transition: none; }
  .tabbar .count.bump, .site-header .badge.bump { animation: none; }
}

/* --- Discover: the score from how alike two people answered --------------- */

.score.alike .score-tune {
  display: inline-block; margin-top: 4px;
  font-size: .78rem; font-weight: 600; color: var(--accent);
  text-decoration: none;
}
.score.alike .score-tune:hover { text-decoration: underline; }

/* The persona face in the Chats list, round like a messages app. */
.ios-face-wrap { flex: none; width: 52px; height: 52px; }
.ios-row .face {
  width: 52px; height: 52px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 1.55rem; line-height: 1;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .35);
}

/* --- the wristband as a border, made of beads ------------------------------
 * Replaces the thin diagonal stripes, which read as an airmail envelope:
 * flat colour, cut on a slant, frames inside frames. This is the beaded
 * band itself, scaled down: three rows of round beads, plum on the outside,
 * then rose, then gold, on cream thread, turning each corner the way the rows
 * on a real bracelet do (html[data-look="kenya"] at the end of this file has
 * the original black, red and green). Every bead is lit from the top left,
 * and the band sits on a soft shadow, so it reads as something raised off
 * the page rather than paint. border-image repeats it along every side in
 * whole beads, so nothing is ever cut in half.
 */
:root {
  --bead-border: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3E%3Cdefs%3E%3CradialGradient id='k' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23c9a0f7'/%3E%3Cstop offset='.5' stop-color='%237b2fc9'/%3E%3Cstop offset='1' stop-color='%233a1170'/%3E%3C/radialGradient%3E%3CradialGradient id='w' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23ffffff'/%3E%3Cstop offset='.5' stop-color='%23fbefe9'/%3E%3Cstop offset='1' stop-color='%23cdb4ae'/%3E%3C/radialGradient%3E%3CradialGradient id='r' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23ffa3c4'/%3E%3Cstop offset='.5' stop-color='%23f72a73'/%3E%3Cstop offset='1' stop-color='%238a0c3c'/%3E%3C/radialGradient%3E%3CradialGradient id='g' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23fff3c2'/%3E%3Cstop offset='.5' stop-color='%23ffc53d'/%3E%3Cstop offset='1' stop-color='%23a87400'/%3E%3C/radialGradient%3E%3CradialGradient id='y' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23ffe3f1'/%3E%3Cstop offset='.5' stop-color='%23ff9ecb'/%3E%3Cstop offset='1' stop-color='%23b3527f'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect width='30' height='30' fill='%23fffaf6'/%3E%3Ccircle cx='1.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='4.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='7.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='10.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='13.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='16.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='19.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='22.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='25.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='1.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='4.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='4.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='7.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='10.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='13.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='16.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='19.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='22.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='4.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='7.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='7.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='7.5' cy='7.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='7.5' cy='10.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='7.5' cy='13.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='7.5' cy='16.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='7.5' cy='19.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='7.5' cy='22.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='7.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='7.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='10.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='10.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='10.5' cy='7.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='10.5' cy='22.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='10.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='10.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='13.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='13.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='13.5' cy='7.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='13.5' cy='22.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='13.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='13.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='16.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='16.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='16.5' cy='7.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='16.5' cy='22.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='16.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='16.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='19.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='19.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='19.5' cy='7.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='19.5' cy='22.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='19.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='19.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='22.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='22.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='22.5' cy='7.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='22.5' cy='10.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='22.5' cy='13.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='22.5' cy='16.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='22.5' cy='19.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='22.5' cy='22.5' r='1.29' fill='url%28%23g%29'/%3E%3Ccircle cx='22.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='22.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='25.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='25.5' cy='4.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='7.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='10.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='13.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='16.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='19.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='22.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='25.5' r='1.29' fill='url%28%23r%29'/%3E%3Ccircle cx='25.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='1.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='4.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='7.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='10.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='13.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='16.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='19.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='22.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='25.5' r='1.29' fill='url%28%23k%29'/%3E%3Ccircle cx='28.5' cy='28.5' r='1.29' fill='url%28%23k%29'/%3E%3C/svg%3E");
  /* Depth: a hairline under the band, a close shadow and a soft far one, and
     a faint shade just inside the band so the content sits a step lower. */
  --band-depth:
    0 1px 0 rgba(60, 40, 25, .08),
    0 4px 8px rgba(60, 40, 25, .10),
    0 16px 34px rgba(60, 40, 25, .16),
    inset 0 0 0 1px rgba(255, 255, 255, .7),
    inset 0 3px 8px rgba(60, 40, 25, .10);
}

/* A card on its own: the full band, raised off the page. */
.card {
  border: 12px solid transparent;
  border-image: var(--bead-border) 9 round;
  background-clip: padding-box;
  box-shadow: var(--band-depth);
}

/* The sheet a scene page sits on wears the band once; the cards on it get a
   quiet edge, so the beads frame the page instead of nesting three deep. */
body.scene-page .shell {
  border: 12px solid transparent;
  border-image: var(--bead-border) 9 round;
  background-clip: padding-box;
}
body.scene-page .shell .card {
  border: 1px solid var(--line);
  border-image: none;
  background-clip: border-box;
  box-shadow: 0 1px 2px rgba(60, 40, 25, .06), 0 6px 16px rgba(60, 40, 25, .07);
}

/* Pictures: a slimmer band of smaller beads, on its own small shadow, like a
   photograph mounted on the page. */
.art-frame,
img.shot, img.art.photo, .photo-grid img, .photos img, .intro-photos img,
.photo-drop-preview img {
  border: 6px solid transparent;
  border-image: var(--bead-border) 9 round;
  /* The old striped edge was a background layer; keep it inside the frame
     so it can never show between the beads. */
  background-clip: padding-box;
  box-shadow: 0 2px 4px rgba(60, 40, 25, .14), 0 8px 18px rgba(60, 40, 25, .14);
}
/* Inside a chat bubble a photo is just a photo, as in any messages app. */
body.chat-open .msg img.shot { border: 0; border-image: none; box-shadow: none; }


/* --- type: one clear, friendly family, a touch bolder -----------------------
 * Figtree for everything: headings, paragraphs, labels, buttons. The serif
 * used to carry paragraphs and bios too, and a soft serif at 14px on a phone
 * is tiring to read. Body text sits at a medium weight rather than regular,
 * which is what makes it read as clear on a small, bright screen. The
 * Pendo wordmark keeps Fraunces: that is the logo, not the reading.
 */
:root {
  --sans: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --serif: var(--sans);
}

body { font-weight: 500; letter-spacing: .003em; }
h1, h2, h3 { font-weight: 800; letter-spacing: -.015em; }
strong, b { font-weight: 750; }
.small { font-size: .875rem; }
.muted { font-weight: 500; }

/* Buttons and labels: bold enough to find with a thumb at a glance. */
.btn { font-weight: 750; }
label, .kicker { font-weight: 750; }

/* The wordmark stays as it was. */
.brand-name {
  font-family: "Fraunces", "Iowan Old Style", Georgia, serif;
  font-weight: 700;
}


/* --- keeping motion smooth --------------------------------------------------
 * The rule for everything that moves: only opacity and transform, nothing
 * that makes the page repaint on every frame, and nothing that runs forever.
 */

/* The beads flowing up the edge of the field you are in stay: the owner
   asked for them back. They pause for the moment you are actually typing
   (phone.js marks the field .is-typing for a breath after each key), so the
   field is not repainted under your fingers, and flow again when you stop. */
html input.is-typing:focus, html textarea.is-typing:focus { animation-play-state: paused; }

/* A blur behind a nearly opaque sheet costs a full re-blur of everything
   under it on every scroll frame and every view change, for a difference
   nobody can see at 95% opacity. Solid instead. */
body.scene-page .shell {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background-color: #fffaf2;
}
body.chat-open .composer {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background: var(--surface);
}

/* The match ring: the ring arrives as one piece instead of every bead
   animating on its own, which ran on the main thread, bead by bead. */
.ring-bead.on { animation: none; }
.ring-wrap .bead-ring { animation: ring-in .32s cubic-bezier(.2, 0, 0, 1) both; }
@keyframes ring-in {
  from { opacity: 0; transform: scale(.9) rotate(-12deg); }
  to   { opacity: 1; transform: none; }
}

/* The next card in the deck: a little quicker and without the overshoot. */
.profile-card:not([hidden]) { animation-duration: .3s; }

/* Things that will move get their own layer up front, so the first frame of
   the motion is not spent creating it. */
.tabbar a .ico::before, .pulse-banner, .nav-progress, .new-pill { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  .ring-wrap .bead-ring { animation: none; }
}


/* --- the scenes, as pictures --------------------------------------------------
 * Every scene behind a page used to be an SVG drawing painted as a background,
 * so a phone redrew every path of it on each change of view. On a slow phone
 * that alone was a third of a second of frozen screen. These are the same
 * drawings, rendered once at phone resolution (1080 px wide) and served as
 * WebP: decoded once, cached, and cheap to paint. The SVGs in
 * templates/_partials/art stay the masters; re-render after changing one.
 */
.scene-hero     { --scene-img: url("/static/img/scenes/hero.webp?v=1"); }
.scene-chai     { --scene-img: url("/static/img/scenes/chai.webp?v=1"); }
.scene-elders   { --scene-img: url("/static/img/scenes/elders.webp?v=1"); }
.scene-heritage { --scene-img: url("/static/img/scenes/heritage.webp?v=1"); }
.scene-table    { --scene-img: url("/static/img/scenes/table.webp?v=1"); }
.scene-market   { --scene-img: url("/static/img/scenes/market.webp?v=1"); }
.scene-empty    { --scene-img: url("/static/img/scenes/empty.webp?v=1"); }
.scene-words    { --scene-img: url("/static/img/scenes/words.webp?v=1"); }
.scene-exchange { --scene-img: url("/static/img/scenes/exchange.webp?v=1"); }
.scene-reveal   { --scene-img: url("/static/img/scenes/reveal.webp?v=1"); }

/* --- thumbs: things on a phone that were too small to hit, or in the way ---- */

/* The "Private by default" flag floated over the bottom right of the page,
   which on a phone is exactly where the chat's Send button and the last
   button of a form sit: a tap meant for Send opened the Safety page. On a
   phone it is a small lock square, and in a chat (already private, and the
   corner belongs to Send) it is not shown at all. */
@media (max-width: 760px) {
  .privacy-flag { padding: 0; width: 40px; height: 40px; justify-content: center; }
  .privacy-flag .flag-text { display: none; }
  .privacy-flag .flag-ico { font-size: 1rem; }
}
body.chat-open .privacy-flag { display: none; }

/* The cross on a photo tile: 32px to aim at, not 24. */
.tile-remove { width: 32px; height: 32px; top: -8px; right: -8px; font-size: 1.1rem; }

/* The way back out of a chat: a 40px square around the arrow. */
.thread-head > a.linkish {
  display: inline-grid; place-items: center;
  min-width: 40px; min-height: 40px; margin: -8px 0 -8px -8px;
  font-size: 1.2rem;
}

/* The profile strength beads are links to what each one needs. The bead
   stays 16px to look at; the space you can tap is 32px tall. (clip-path
   used to round it, and also clipped where a tap could land.) */
.strength-bead { clip-path: none; border-radius: 8px; position: relative; }
.strength-bead::after { content: ""; position: absolute; left: 0; right: 0; top: -8px; bottom: -8px; }

/* "Score them on what you want" under a Discover score. */
.score.alike .score-tune { padding: 9px 6px; margin: -3px 0 -6px; }

/* --- text big enough to read on a phone --------------------------------------
 * Nothing a member has to read is under about 11.5px any more: the bottom bar
 * labels, chat times, the small capital headings, tags and chips were 9.9 to
 * 11.2px. The deliberately tiny ones stay as they were: the bead letters on
 * the wristband bands, numbers inside badge circles, the admin charts.
 */
.tabbar a,
body:not(.no-app) .tabbar a > span:last-child { font-size: .72rem; }
@media (max-width: 380px) {
  .tabbar a,
  body:not(.no-app) .tabbar a > span:last-child { font-size: .7rem; }
}
.kicker, .pill, .msg .meta, body.chat-open .msg .meta, .facts dt, .step-n, .block-head,
.cmp-label, .cmp-side b, .picker-add .add-word, .group-head .muted, .receipt,
.you-face-edit, .join-per, .note-suggest-label, .money-tag, .q-step, .keen-tag,
.personas.compact .persona strong, .date-kind, .date-partner, .todo-go, .badge.new {
  font-size: .74rem;
}
/* The answers on an introduction, and the height choices at sign up
   (centimetres and feet were 9.3 to 9.9px). */
.answers dt { font-size: .76rem; }
.fig-cm, .fig-ft { font-size: .74rem; }


/* --- modern: soft rounded corners, sentence case, soft shadows ---------------
 * The owner's choice on 2026-10-13: "give it a modern feel", soft rounded
 * corners. This replaces the earlier square-corner rule (the comment in
 * phone.css about it is history now). The beadwork stays exactly as it is:
 * the bands, the bead frames (whose corners now curve with the rows of beads
 * following the bend), the beads that flow in the field you are typing in,
 * and the scenes. Since the worldwide rebrand the beads are rose, plum and
 * gold rather than the Kenyan flag.
 */
:root {
  --r-card: 12px;
  --r-ctl: 12px;
  --r-tile: 14px;
  --r-pill: 999px;
  /* The same three-row bead band, drawn with rounded corners. */
  --bead-border: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3E%3Cdefs%3E%3CradialGradient id='k' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23c9a0f7'/%3E%3Cstop offset='.5' stop-color='%237b2fc9'/%3E%3Cstop offset='1' stop-color='%233a1170'/%3E%3C/radialGradient%3E%3CradialGradient id='r' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23ffa3c4'/%3E%3Cstop offset='.5' stop-color='%23f72a73'/%3E%3Cstop offset='1' stop-color='%238a0c3c'/%3E%3C/radialGradient%3E%3CradialGradient id='g' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23fff3c2'/%3E%3Cstop offset='.5' stop-color='%23ffc53d'/%3E%3Cstop offset='1' stop-color='%23a87400'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cpath fill='%23fffaf6' fill-rule='evenodd' d='M9 0 H21 A9 9 0 0 1 30 9 V21 A9 9 0 0 1 21 30 H9 A9 9 0 0 1 0 21 V9 A9 9 0 0 1 9 0 Z M9 9 H21 V21 H9 Z'/%3E%3Ccircle cx='10.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='10.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='10.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='10.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='13.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='13.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='13.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='13.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='16.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='16.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='16.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='16.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='19.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='19.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='19.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='19.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.644' cy='7.537' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='2.764' cy='4.833' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='4.833' cy='2.764' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='7.537' cy='1.644' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='22.463' cy='1.644' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='25.167' cy='2.764' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='27.236' cy='4.833' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.356' cy='7.537' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.356' cy='22.463' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='27.236' cy='25.167' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='25.167' cy='27.236' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='22.463' cy='28.356' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='7.537' cy='28.356' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='4.833' cy='27.236' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='2.764' cy='25.167' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.644' cy='22.463' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='10.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='10.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='10.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='10.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='13.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='13.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='13.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='13.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='16.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='16.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='16.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='16.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='19.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='19.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='19.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='19.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.843' cy='7.278' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='7.278' cy='4.843' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='22.722' cy='4.843' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.157' cy='7.278' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.157' cy='22.722' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='22.722' cy='25.157' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='7.278' cy='25.157' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.843' cy='22.722' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='10.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='10.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='10.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='10.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='13.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='13.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='13.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='13.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='16.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='16.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='16.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='16.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='19.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='19.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='19.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='19.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.939' cy='7.939' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.061' cy='7.939' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.061' cy='22.061' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.939' cy='22.061' r='1.290' fill='url%28%23g%29'/%3E%3C/svg%3E");
}

/* Frames: the bead band is as thick as its corner is round. */
.card { border-radius: var(--r-card); }
body.scene-page .shell { border-radius: 12px; }
body.scene-page .shell .card { border-radius: var(--r-card); }
.art-frame, img.shot, img.art.photo, .photo-grid img, .photos img, .intro-photos img,
.photo-drop-preview img { border-radius: 6px; }

/* Buttons: rounded, in plain sentence case, lifted by a soft shadow rather
   than the hard offset edge. They still press down under the thumb. */
html body .btn {
  border-radius: var(--r-ctl);
  text-transform: none; letter-spacing: .005em;
  font-size: .98rem; font-weight: 750;
}
html body .btn.primary {
  box-shadow: 0 6px 16px rgba(var(--accent-rgb), .26), 0 1px 2px rgba(0, 0, 0, .12);
}
html body .btn.primary:active {
  transform: translateY(1px) scale(.99);
  box-shadow: 0 2px 6px rgba(var(--accent-rgb), .22);
}
html body .btn.small.primary { box-shadow: 0 4px 12px rgba(var(--accent-rgb), .24); }
html body .btn:not(.primary) {
  background: var(--surface);
  border: 1.5px solid rgba(38, 23, 15, .2);
  box-shadow: 0 1px 2px rgba(38, 23, 15, .08);
}
html body .btn:not(.primary):hover { background: var(--surface-2); color: var(--text); }
html body .btn:not(.primary):active { transform: translateY(1px); box-shadow: none; }
html body .btn.ghost { border-color: var(--line); box-shadow: none; }
html body .btn.danger { border-color: var(--danger); box-shadow: none; }
.site-header .btn.signout, .site-header .btn.signin { border-radius: 10px; font-size: .86rem; }

/* Fields: rounded, a lighter edge. The bead stripe and its flow on focus stay. */
html input[type="text"], html input[type="email"], html input[type="password"],
html input[type="number"], html input[type="tel"], html input[type="date"],
html input[type="search"], html select, html textarea {
  border-radius: var(--r-ctl);
  border-width: 1.5px;
}

/* Labels in sentence case: "First name", not "FIRST NAME". The small coloured
   kickers above headings keep their capitals; they are a heading device. */
label {
  text-transform: none; letter-spacing: 0;
  font-size: .9rem; font-weight: 700; color: var(--text);
}

/* Tiles, notices and panels. */
.flash, .score, .cmp, .moment, .stage-banner, .decide, .decide-wait, .empty,
.finder, .join-prompt, .price-card, .todo-panel, .pledge, .date-spot,
.list-item, .you-tile, .group, .q-card, .persona, .note-chip {
  border-radius: var(--r-tile);
}
.q-opt, .picker-tile, .choices label, .icon-btn { border-radius: var(--r-ctl); }

/* Chips, tags and counts: pills. */
.pill, .chip, .badge, .keen-tag, .money-tag, .tabbar .count, .ios-section .chip {
  border-radius: var(--r-pill);
}

/* The bottom bar's selected tab sits on a pill, as on a modern phone. */
body:not(.no-app) .tabbar a .ico::before { border-radius: var(--r-pill); }

/* A face in the match ring is a circle, inside the circle of beads. */
.ring-wrap .card-avatar, .ring-wrap .avatar { border-radius: 50%; }

/* Floating things. */
.modal { border-radius: 18px; }
.install-bar { border-radius: 18px 18px 0 0; }
.privacy-flag { border-radius: var(--r-pill); }

/* The install bar sits in the page's column, just above the bottom bar
   (phone.js puts it there), so the content area shrinks to make room rather
   than the bar covering the last button on a page. Inside a chat it steps
   aside altogether: down there is the message box, and nobody mid-sentence
   wants an offer to install. It comes back on the next screen. */
.install-bar {
  position: relative; flex: none; z-index: 45;
  left: auto; right: auto; bottom: auto;
  animation: install-in .3s var(--ease-decel) both;
}
body.chat-open .install-bar { display: none; }
@media (min-width: 760px) {
  .install-bar { left: auto; transform: none; width: auto; max-width: none; }
}
@keyframes install-in {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .install-bar { animation: none; }
}

/* The rest of the old square rules, rounded to match. */
html body .btn.small { border-radius: 10px; }
html body .quiz .choices .btn { border-radius: var(--r-pill); }
.tile-remove, .picker-add { border-radius: var(--r-ctl); }
.tile, .veil-note { border-radius: var(--r-tile); }
.progress, .meter, .progress span, .meter span { border-radius: var(--r-pill); }
.face { border-radius: 50%; }
.tabbar .dot { border-radius: 50%; }
.admin-nav a { border-radius: 10px; }

/* The selected tab: the same shuka red, as a rounded pill set inside its
   cell rather than a block filling it edge to edge. */
html body:not(.no-app) .tabbar a.on {
  border-radius: 16px;
  margin: 5px 3px;
  height: calc(var(--tab-h) - 10px);
}

/* Titles on the You tiles and the photo's "Change" in sentence case, the
   profile photo and the chat's name bar rounded like the rest. */
.you-label { text-transform: none; letter-spacing: 0; font-size: 1rem; }
.you-face-edit { text-transform: none; letter-spacing: .01em; }
.you-face, .you-face img { border-radius: 18px; overflow: hidden; }
.thread-head { border-radius: 14px; }

/* --- the join form as slides (signup.js) ----------------------------------
   One screen at a time, no scrolling: the drawing shrinks to a strip, the
   heading shows on the first slide only, and Back and Next sit at the foot
   of the card where a thumb is. Without the script none of this applies and
   the form is one page, top to bottom. */

html body.join-stepped.scene-page .viewport {
  background-image:
    linear-gradient(180deg, rgba(59, 36, 22, 0) 0, rgba(59, 36, 22, 0) 24px,
                    var(--earth) 92px),
    var(--scene-img);
  background-size: 100% 100%, var(--scene-w) calc(var(--scene-w) * .75);
  background-position: top center, center calc(var(--scene-w) * -.36);
}
body.join-stepped.scene-page .shell {
  flex: 1 0 auto;
  display: flex; flex-direction: column;
  margin: 56px 8px 10px;
  padding: 14px 14px 12px;
}
body.join-stepped .shell > .flash,
body.join-stepped .shell > .flashes { margin-bottom: 8px; }
body.join-stepped .join-head h1 { font-size: 1.5rem; margin: 2px 0 4px; }
body.join-stepped .join-head .join-lede { margin: 0 0 4px; }
body.join-stepped .shell > p.small.center { margin-top: 8px !important; }

.join-form.is-stepped {
  flex: 1 0 auto;
  display: flex; flex-direction: column;
  gap: 0;
}
.join-form.is-stepped > * + * { margin-top: 0; }

.join-progress { margin: 2px 0 10px; }
.join-beads { display: flex; gap: 6px; justify-content: center; }
.join-bead {
  width: 14px; height: 14px; padding: 0; border: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff 0, #e9dfcf 45%, #bfb4a2 100%);
  box-shadow: inset 0 -1px 2px rgba(0, 0, 0, .25), 0 1px 1px rgba(0, 0, 0, .15);
  transition: transform .2s var(--ease-decel, ease-out);
  cursor: pointer;
}
.join-bead:disabled { cursor: default; opacity: .7; }
.join-bead.done { background: radial-gradient(circle at 35% 30%, #79d68f 0, #20803a 50%, #093313 100%); }
.join-bead.on {
  background: radial-gradient(circle at 35% 30%, #ff8077 0, #c3141e 50%, #5c070c 100%);
  transform: scale(1.3);
}
/* A thumb-sized target around each small bead. */
.join-bead { position: relative; }
.join-bead::after { content: ""; position: absolute; inset: -10px -4px; }
.join-where {
  margin: 8px 0 0; text-align: center;
  font-size: .8rem; font-weight: 600; color: var(--muted);
  white-space: pre;
}

.join-track { position: relative; flex: 1 0 auto; }
.join-form.is-stepped .join-step[hidden],
.join-form.is-stepped .join-step [hidden] { display: none !important; }
.join-step { position: relative; }
.join-step-title { font-size: 1.25rem; margin: 0 0 12px; outline: none; }
.join-form.is-stepped .join-step-no { display: none; }
.join-form:not(.is-stepped) .join-step + .join-step {
  margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--line);
}
.join-step-no {
  display: inline-block; margin-right: 6px;
  font-size: .75rem; font-weight: 700; color: var(--accent);
  vertical-align: middle;
}
.join-form.is-stepped .field + .field,
.join-form.is-stepped .field + [data-field],
.join-form.is-stepped [data-field] + .field { margin-top: 14px; }

/* Sliding: the old slide moves off one way while the new one comes in. */
.join-out { position: absolute; pointer-events: none; margin: 0; }
.join-out-fwd { animation: join-out-fwd .24s var(--ease-accel, ease-in) both; }
.join-out-back { animation: join-out-back .24s var(--ease-accel, ease-in) both; }
.join-in-fwd { animation: join-in-fwd .3s var(--ease-decel, ease-out) both; }
.join-in-back { animation: join-in-back .3s var(--ease-decel, ease-out) both; }
@keyframes join-out-fwd { to { opacity: 0; transform: translateX(-28%); } }
@keyframes join-out-back { to { opacity: 0; transform: translateX(28%); } }
@keyframes join-in-fwd { from { opacity: 0; transform: translateX(28%); } }
@keyframes join-in-back { from { opacity: 0; transform: translateX(-28%); } }
.join-track { overflow-x: clip; }

/* Back and Next, at the foot of the card. */
.join-nav {
  display: flex; gap: 10px; align-items: center;
  margin-top: auto !important; padding-top: 14px;
}
.join-nav .btn { flex: 1; min-height: 48px; }
.join-nav .join-back { flex: 0 0 34%; }
.join-nav .join-back[hidden] + .join-next { flex: 1; }
.join-nav.only-back .join-back { flex: 0 0 auto; padding-inline: 22px; }

/* Where a problem is, said under it. */
.field-error {
  margin: 8px 0 0; padding: 8px 12px;
  border-radius: 10px;
  background: #fde7e4; color: #8a1018;
  border: 1px solid #f3b4ad;
  font-size: .86rem; font-weight: 600; line-height: 1.35;
}
.field-error::before { content: "! "; font-weight: 800; }
.join-general { margin: 0 0 10px; }
.has-error > input:not([type="radio"]):not([type="checkbox"]),
.has-error > textarea, .has-error .dob select,
.has-error .place-picker input[data-place-input] {
  border-color: #c3141e; box-shadow: 0 0 0 3px rgba(195, 20, 30, .14);
}
.q-card.has-error, .persona-group.has-error, .hc-card.has-error {
  box-shadow: 0 0 0 2px #c3141e, 0 6px 18px rgba(195, 20, 30, .15);
}
.join-nudge { animation: join-nudge .36s cubic-bezier(.36, .07, .19, .97) both; }
@keyframes join-nudge {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

/* Slide by slide. */
.join-form.is-stepped .q-group-head,
.join-form.is-stepped .join-questions > .field-error:not([data-error-for]) { display: none; }
.join-form.is-stepped .q-intro { margin: 0 0 10px; }
.join-form.is-stepped .q-intro p.small { display: none; }
.join-form.is-stepped .q-beads { margin: 4px 0 2px; flex-wrap: wrap; gap: 5px; }
.join-form.is-stepped .q-bead { width: 9px; height: 9px; }
.join-form.is-stepped .q-tally { margin: 0; text-align: center; }
.q-group-tag {
  display: inline-block; margin-right: 8px;
  font-size: .72rem; font-weight: 700; color: var(--accent);
}
.join-form.is-stepped .q-list { margin: 0; }
.join-form.is-stepped .q-card { margin: 0; }

.join-form.is-stepped .persona-groups { display: block; }
.join-form.is-stepped .persona-group .personas.compact {
  grid-template-columns: repeat(3, 1fr); margin-left: 0;
}
.join-form.is-stepped .persona-group .personas.compact .persona { padding: 12px 6px; }
.join-form.is-stepped .persona-group .personas.compact .face { width: 48px; height: 48px; font-size: 1.4rem; }
.join-form.is-stepped .persona-group .personas.compact .persona strong { font-size: .8rem; }
.join-page-no {
  display: block; margin-bottom: 2px;
  font-size: .72rem; font-weight: 700; color: var(--accent);
}

.join-form.is-stepped .photo-drop-preview { width: min(200px, 56%); }
.join-form.is-stepped .photo-drop-meta { font-size: .76rem; margin-top: 8px; }
.join-more { margin-top: 10px; }
.join-form.is-stepped .interest-choices { min-height: 0; }

.join-form.is-stepped .pledge { font-size: .86rem; }
.join-form.is-stepped .hc-card { margin-top: 12px; padding: 12px 14px; }
.join-form.is-stepped #signup-submit { margin-top: 14px; }

@media (prefers-reduced-motion: reduce) {
  .join-out-fwd, .join-out-back, .join-in-fwd, .join-in-back, .join-nudge { animation: none; }
}

/* The join slides, sized so each one fits a phone without scrolling. While
   joining, the guest tab bar and the sign-in line step aside (Sign in stays
   in the header): one thing on screen, and nothing to wander off to. */
body.join-stepped .tabbar,
body.join-stepped .shell > p.small.center { display: none; }
body.join-stepped.scene-page .shell { margin-top: 40px; padding-top: 12px; }
body.join-stepped .join-head .kicker,
body.join-stepped .join-head .join-lede { display: none; }
body.join-stepped .join-head h1 { font-size: 1.35rem; margin: 0 0 8px; text-align: center; }

.join-form.is-stepped .join-step-title {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; margin: 0;
}
.join-where { white-space: normal; margin-top: 6px; }
.join-count {
  display: block; font-size: .72rem; font-weight: 700;
  letter-spacing: .04em; color: var(--muted);
}
.join-name { display: block; font-size: 1.15rem; font-weight: 800; color: var(--text); line-height: 1.25; }
.join-progress { margin-bottom: 12px; }

.join-form.is-stepped .field > label,
.join-form.is-stepped [data-field] > label:not(.pledge) { margin-bottom: 6px; font-size: .95rem; }
.join-form.is-stepped .field + .field,
.join-form.is-stepped .field + [data-field],
.join-form.is-stepped [data-field] + .field,
.join-form.is-stepped [data-field] + [data-field] { margin-top: 12px; }
.join-form.is-stepped .field > p.small,
.join-form.is-stepped .field p.small.muted {
  font-size: .78rem; line-height: 1.35; margin-top: 4px !important; margin-bottom: 6px !important;
}
.join-form.is-stepped .choices { gap: 6px; }
.join-form.is-stepped .choices label {
  min-height: 38px; padding: 7px 12px; margin: 0; font-size: .88rem;
}
.join-form.is-stepped .seeking-field { padding: 10px 12px; }
.join-form.is-stepped .intents { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.join-form.is-stepped .intents .intent {
  min-height: 46px; margin: 0; padding: 8px 10px; gap: 8px;
  font-size: .82rem; line-height: 1.2;
}
.join-form.is-stepped .intents .intent-ico { font-size: 1rem; }
.join-form.is-stepped .dob select { min-height: 44px; }
.join-form.is-stepped textarea#bio { min-height: 86px; }
.join-form.is-stepped .community-field label.check { font-size: .78rem; line-height: 1.35; }
.join-form.is-stepped .photo-drop-preview { width: min(160px, 46%); }
.join-form.is-stepped .photo-drop-meta { font-size: .72rem; line-height: 1.35; }
.join-form.is-stepped .pledge { font-size: .8rem; line-height: 1.4; padding: 10px 12px; }
.join-form.is-stepped .hc-card label#hc-prompt { margin-bottom: 8px !important; }
.join-form.is-stepped .q-card { padding-top: 12px; padding-bottom: 12px; }
/* With the tab bar out of the way, the content area takes its room. */
body.join-stepped .viewport {
  max-height: calc(100dvh - var(--header-h) - var(--footer-h));
}

/* The card fills the screen exactly and the page never scrolls: the slide
   sits between the beads and Back/Next, which never move. A slide is made to
   fit a phone; on a very short one the slide alone scrolls a little, with
   Back and Next still in reach. */
body.join-stepped .viewport { overflow-y: hidden; }
body.join-stepped.scene-page .shell {
  flex: 1 1 0; min-height: 0;
}
.join-form.is-stepped { flex: 1 1 0; min-height: 0; }
.join-form.is-stepped .join-track {
  flex: 1 1 0; min-height: 0;
  overflow-x: hidden; overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.join-form.is-stepped .join-track::-webkit-scrollbar { display: none; }
.join-form.is-stepped .photo-drop-meta { display: none; }
.join-form.is-stepped .photo-drop-change { margin-top: 6px; }

/* Shorter phones (most budget Androids, with the browser's own bars). */
@media (max-height: 760px) {
  body.join-stepped.scene-page .shell { margin-top: 10px; padding: 10px 12px 10px; }
  html body.join-stepped.scene-page .viewport { background-position: top center, center calc(var(--scene-w) * -.5); }
  body.join-stepped .join-head h1 { font-size: 1.2rem; margin-bottom: 6px; }
  .join-progress { margin-bottom: 8px; }
  .join-name { font-size: 1.05rem; }
  .join-nav { padding-top: 10px; }
  .join-nav .btn { min-height: 44px; }
  .join-form.is-stepped .choices label { min-height: 36px; padding: 6px 11px; font-size: .85rem; }
  .join-form.is-stepped .intents .intent { min-height: 42px; padding: 6px 8px; }
  .join-form.is-stepped .photo-drop-preview { width: min(130px, 40%); }
  .join-form.is-stepped textarea#bio { min-height: 72px; }
  .join-form.is-stepped .persona-group .personas.compact .persona { padding: 8px 4px; }
  .join-form.is-stepped .persona-group .personas.compact .face { width: 40px; height: 40px; }
}
.join-form.is-stepped .photo-drop-zone { padding: 10px; min-height: 0; }
.join-form.is-stepped .photo-drop-change { margin-top: 4px; min-height: 34px; padding-block: 5px; }

/* Day, month and year on one row in the join slides, even at 360 wide. */
.join-form.is-stepped .dob { grid-template-columns: 4.4rem 1fr 5.4rem; gap: 6px; }
.join-form.is-stepped .dob select:nth-child(2) { grid-column: auto; }
.join-form.is-stepped .dob select { padding: 10px 8px; font-size: .92rem; }

/* Short screens: the help lines under each question go, the questions and
   answers stay, and so does anything that says what needs fixing. */
@media (max-height: 760px) {
  .join-form.is-stepped .field > p.small.muted:not(.pick-count):not(.life-count),
  .join-form.is-stepped .seeking-field > p.small { display: none; }
  .join-form.is-stepped .field { padding: 0; }
  .join-form.is-stepped .field > label,
  .join-form.is-stepped [data-field] > label:not(.pledge) { margin-bottom: 4px; font-size: .9rem; }
  .join-form.is-stepped .field + .field,
  .join-form.is-stepped .field + [data-field],
  .join-form.is-stepped [data-field] + .field,
  .join-form.is-stepped [data-field] + [data-field] { margin-top: 10px; }
  .join-form.is-stepped .seeking-field { padding: 8px 10px; }
  .join-form.is-stepped .q-card { padding-top: 10px; padding-bottom: 10px; }
  .join-form.is-stepped .q-intro { margin-bottom: 6px; }
  .join-form.is-stepped .pledge { font-size: .76rem; line-height: 1.32; padding: 8px 10px; }
  .join-form.is-stepped .hc-card { margin-top: 8px; padding: 10px 12px; }
  .join-form.is-stepped #signup-submit { margin-top: 10px; }
  .join-form.is-stepped .community-field label.check { font-size: .74rem; }
  .join-more { margin-top: 6px; }
}

/* Create account in the bar, in Next's place, on the last slide. */
.join-nav #signup-submit { flex: 1; margin: 0; }
.join-nav #signup-submit[hidden] { display: none; }

/* One row of small beads above the questions, and tighter cards on short
   screens so a question and all its answers sit on one screen. */
.join-form.is-stepped .q-beads { flex-wrap: nowrap; gap: 3px; }
.join-form.is-stepped .q-bead { width: 8px; height: 8px; flex: none; }
@media (max-height: 760px) {
  .join-form.is-stepped .q-head { padding: 10px 12px 8px; gap: 10px; }
  .join-form.is-stepped .q-ico { width: 42px; height: 42px; font-size: 1.2rem; }
  .join-form.is-stepped .q-question { font-size: 1.02rem; }
  .join-form.is-stepped .q-options { gap: 6px; padding: 2px 10px 10px; }
  html body .join-form.is-stepped .q-opt { min-height: 42px; padding: 6px 10px; gap: 8px; font-size: .84rem; }
  .join-form.is-stepped .q-opt::before { width: 15px; height: 15px; }
  .join-form.is-stepped .pledge strong { font-size: .92rem; }
}
@media (max-height: 760px) {
  body.join-stepped .join-head { display: none; }
  .join-form.is-stepped .photo-drop-preview { width: min(112px, 36%); }
  .join-form.is-stepped .photo-drop-zone { padding: 6px; }
}

/* Long answer lists (faith, work) in two compact columns on the slides. */
.join-form.is-stepped .q-options.long { grid-template-columns: 1fr 1fr; gap: 6px; }
html body .join-form.is-stepped .q-options.long .q-opt {
  min-height: 40px; padding: 6px 8px; gap: 6px; font-size: .8rem; line-height: 1.2;
}
.join-form.is-stepped .q-options.long .q-opt::before { width: 14px; height: 14px; }
@media (max-height: 760px) {
  .join-form.is-stepped .q-intro { display: none; }
  .join-form.is-stepped .q-options.figures .fig-ft,
  .join-form.is-stepped .q-note { display: none; }
  html body .join-form.is-stepped .q-options.long .q-opt { min-height: 36px; font-size: .76rem; padding: 5px 7px; }
}
/* Better still for the long lists: answers flow like chips, short ones two
   or three to a row, so thirteen faiths take about eight rows. */
.join-form.is-stepped .q-options.long { display: flex; flex-wrap: wrap; }
html body .join-form.is-stepped .q-options.long .q-opt { flex: 1 1 auto; min-height: 36px; }
.join-form.is-stepped .q-tally { display: none; }
.join-form.is-stepped .q-options.long { gap: 5px; }
html body .join-form.is-stepped .q-options.long .q-opt {
  min-height: 32px; padding: 4px 9px; font-size: .78rem; box-shadow: 0 1px 0 var(--line-soft);
}
@media (max-height: 760px) {
  .join-form.is-stepped .q-card .q-ico { width: 36px; height: 36px; font-size: 1.05rem; }
}
.join-form.is-stepped textarea#bio { height: 74px; min-height: 0; }
@media (max-height: 760px) { .join-form.is-stepped textarea#bio { height: 62px; } }

/* Each bead is a thumb-sized button with the bead drawn in its middle. */
.join-beads { gap: 0; }
.join-bead, .join-bead.done, .join-bead.on {
  width: 26px; height: 34px; background: none; box-shadow: none; transform: none;
}
.join-bead::after { content: none; }
.join-bead::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff 0, #e9dfcf 45%, #bfb4a2 100%);
  box-shadow: inset 0 -1px 2px rgba(0, 0, 0, .25), 0 1px 1px rgba(0, 0, 0, .15);
  transition: transform .2s var(--ease-decel, ease-out);
}
.join-bead.done::before { background: radial-gradient(circle at 35% 30%, #79d68f 0, #20803a 50%, #093313 100%); }
.join-bead.on::before {
  background: radial-gradient(circle at 35% 30%, #ff8077 0, #c3141e 50%, #5c070c 100%);
  transform: scale(1.3);
}
.join-progress { margin-top: -6px; }
.join-bead, .join-bead.done, .join-bead.on { width: 32px; }
@media (max-width: 370px) { .join-bead, .join-bead.done, .join-bead.on { width: 30px; } }

/* Next waits, greyed, until the view is done, then lights up. It still
   answers a tap while greyed, by pointing at what is missing. */
.join-nav .btn { transition: opacity .2s ease, filter .2s ease, transform .1s ease; }
.join-nav .btn.is-waiting {
  opacity: .45; filter: grayscale(.4); box-shadow: none;
}
.join-nav .btn.just-ready { animation: join-ready .32s var(--ease-decel, ease-out); }
@keyframes join-ready { 45% { transform: scale(1.04); } }
@media (prefers-reduced-motion: reduce) { .join-nav .btn.just-ready { animation: none; } }

/* A character family on its slide: flush with the card like a question
   card, its colour down the left edge, and the six faces inside it with room
   on every side, not pressed against that edge. */
.join-form.is-stepped .field > .persona-groups { margin: 0; }
.join-form.is-stepped .persona-group {
  border-left: 5px solid var(--q);
  border-radius: var(--r-card, 12px);
  overflow: hidden;
  padding: 0 0 12px;
}
.join-form.is-stepped .persona-group .group-head { padding: 12px 14px 10px; }
.join-form.is-stepped .persona-group .personas.compact {
  margin: 4px 12px 0 10px; gap: 8px;
}
/* Room for the cards' shadows inside the sliding track. */
.join-form.is-stepped .join-track { margin-inline: -6px; padding-inline: 6px; }

/* The payments switch on the admin desk. */
.pay-switch { border-left: 5px solid var(--bead-green); }
.pay-switch.is-off { border-left-color: var(--bead-yellow); background: #fffbea; }
.pay-switch-row { display: flex; gap: 16px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.pay-switch-words { flex: 1 1 280px; min-width: 0; }
.pay-switch-k { display: block; font-size: .75rem; font-weight: 700; letter-spacing: .06em; color: var(--muted); }
.pay-switch-state { display: block; font-size: 1.25rem; margin: 2px 0 4px; }
.pay-switch.is-on .pay-switch-state { color: var(--bead-green); }
.pay-switch.is-off .pay-switch-state { color: #8a5c00; }
.pay-switch .small { margin: 0; }

/* The header pair: whichever matches the page is the filled one. On the
   sign in pages Sign in is filled and Join steps back to the plain look. */
.site-header .btn.signup:not(.primary) {
  min-height: 38px; padding: 7px 14px;
  font-size: .78rem; letter-spacing: .04em;
  background: var(--surface); color: var(--text);
  border-radius: 10px;
}
html body .site-header .btn.signin.primary {
  background: var(--accent-grad, var(--accent));
  border-color: transparent; color: var(--accent-ink, #fff);
}


/* The sign in pages on a phone: email, password and Sign in on the first
   screen, always. The drawing takes whatever height is left once the form
   has its room (about 560px with the header, the bar and the footer), down
   to a strip on a short phone, with the people kept in view at the bottom of
   it rather than squashed. keep-submit.js keeps Sign in above the keyboard. */
@media (max-width: 760px) {
  body.signin-page.scene-page {
    --scene-h: clamp(96px, calc(100dvh - 560px), calc(var(--scene-w) * .75));
  }
  html body.signin-page.scene-page .viewport {
    background-size: 100% 100%, var(--scene-w) calc(var(--scene-w) * .75);
    background-position: top center, center calc(var(--scene-h) - var(--scene-w) * .75);
  }
}

/* Joining is one thing at a time: the install offer waits until after. */
body.join-stepped .install-bar { display: none; }

/* Women and men see different backgrounds (the owner, October 2026): a soft
   rose wash for women, Tinder-warm but quiet, and a clean white with a faint
   cool tint for men. Signed out and non-binary keep the Kenyan dusk sand.
   Only the page behind changes; cards, bars, the bead frames and the shuka
   red stay the same for everybody. */
html[data-gender="woman"] {
  --bg: #fff0f3;
  --wash: linear-gradient(172deg, #ffc9d6 0%, #ffdfe7 30%, #fff0f3 62%);
}
html[data-gender="man"] {
  --bg: #ffffff;
  --wash: linear-gradient(172deg, #e3ecf5 0%, #f2f6fa 30%, #ffffff 62%);
}

/* --- the photo viewer (lightbox.js) ---------------------------------------
   Full screen on a dark ground; the photo is the only thing that moves. */
html.viewer-open, html.viewer-open body { overflow: hidden; }
.viewer {
  --fade: 1;
  position: fixed; inset: 0; z-index: 300;
  background: rgba(14, 9, 6, calc(.96 * var(--fade)));
  opacity: 0; transition: opacity .2s ease;
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.viewer.show { opacity: 1; }
.viewer-stage {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; touch-action: none;
}
.viewer-img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  transform-origin: center center;
  will-change: transform;
  -webkit-user-drag: none; pointer-events: none;
  border-radius: 4px;
}
.viewer-img.settling { transition: transform .22s cubic-bezier(.2, .8, .2, 1); }
.viewer-img.from-right { animation: viewer-in-right .26s cubic-bezier(.2, .8, .2, 1); }
.viewer-img.from-left { animation: viewer-in-left .26s cubic-bezier(.2, .8, .2, 1); }
@keyframes viewer-in-right { from { opacity: 0; transform: translateX(40px); } }
@keyframes viewer-in-left { from { opacity: 0; transform: translateX(-40px); } }
.viewer.loading .viewer-img { opacity: .4; }

.viewer-top {
  position: absolute; left: 0; right: 0; top: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 12px 10px;
  background: linear-gradient(180deg, rgba(0, 0, 0, .45), transparent);
  transition: opacity .2s ease;
}
.viewer-count { color: #fff; font-weight: 700; font-size: .9rem; letter-spacing: .02em; }
.viewer-close, .viewer-nav {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(20, 12, 8, .55); color: #fff;
  font-size: 1.1rem; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  transition: opacity .2s ease, transform .1s ease;
}
.viewer-close:active, .viewer-nav:active { transform: scale(.92); }
.viewer-nav {
  position: absolute; top: 50%; margin-top: -22px; font-size: 1.8rem;
}
.viewer-prev { left: 10px; }
.viewer-next { right: 10px; }
.viewer-nav[hidden] { display: none; }
@media (hover: none) { .viewer-nav { display: none; } }
.viewer-hint {
  position: absolute; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
  margin: 0; text-align: center; color: rgba(255, 255, 255, .7); font-size: .8rem;
  transition: opacity .2s ease;
}
.viewer.zoomed .viewer-hint { opacity: 0; }
.viewer.chrome-off .viewer-top,
.viewer.chrome-off .viewer-nav,
.viewer.chrome-off .viewer-hint { opacity: 0; pointer-events: none; }

/* A photo that opens in the viewer says so with the cursor. */
img.shot, img.library-photo, img.hero-img:not(.drawn) { cursor: zoom-in; }

@media (prefers-reduced-motion: reduce) {
  .viewer, .viewer-img.settling { transition: none; }
  .viewer-img.from-right, .viewer-img.from-left { animation: none; }
}

/* --- Discover, Tinder style in Pendo's colours ------------------------------
   One person fills the screen from the top: their photo edge to edge (or
   their drawn character on a dusk ground), the name, age and what they want
   over a dark fade at the foot, the score as a ring of beads in the corner,
   and the three bead buttons floating on the photo. Everything else about
   them is on the same card, under the photo: scroll the card, or tap
   "More about". discover.js sets --deck-h to the room the screen has. */
body.discover-page .shell { padding-top: 8px; }
.discover-page .finder { margin: 0 0 8px; }
.discover-page .finder > summary { min-height: 40px; padding: 8px 14px; font-size: .86rem; }

.discover-page .deck-stage { position: relative; }
.discover-page .deck {
  height: var(--deck-h, calc(100dvh - var(--header-h) - var(--tab-h) - var(--footer-h) - 70px));
  min-height: 420px;
}
.discover-page .deck::before, .discover-page .deck::after { display: none; }
.discover-page .deck .profile-card {
  position: absolute; inset: 0; margin: 0; padding: 0 0 112px;
  overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  scrollbar-width: none;
  border-radius: 20px; border: 0;
  background: var(--surface);
  box-shadow: 0 16px 36px rgba(40, 20, 10, .30), 0 2px 0 rgba(40, 20, 10, .06);
}
.discover-page .deck .profile-card::-webkit-scrollbar { display: none; }
.discover-page .deck .profile-card[hidden] { display: none !important; }

/* The photo, the whole card high. */
.discover-page .card-hero {
  position: relative; height: var(--deck-h, 560px); min-height: 420px;
  overflow: hidden; border-radius: 20px 20px 0 0;
  background: #2a1810;
}
.discover-page .card-hero .hero-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; user-select: none; -webkit-user-drag: none;
}
.discover-page .card-hero.is-drawn {
  background:
    radial-gradient(circle at 50% 34%, rgba(255, 236, 200, .95) 0 22%, rgba(255, 236, 200, 0) 46%),
    linear-gradient(170deg, #f8b26a 0%, #e8642a 46%, #8a1c20 100%);
}
.discover-page .card-hero.is-drawn .hero-img {
  inset: 8% 14% 34%; width: 72%; height: 58%;
  object-fit: contain; filter: drop-shadow(0 12px 22px rgba(60, 20, 10, .35));
}
.discover-page .card-hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(20, 10, 5, .25) 0%, rgba(20, 10, 5, 0) 18%,
              rgba(20, 10, 5, 0) 46%, rgba(20, 10, 5, .55) 70%, rgba(20, 10, 5, .9) 100%);
}

/* The score: a ring of beads in the corner, the number inside it. */
.discover-page .hero-score {
  position: absolute; top: 12px; left: 12px; z-index: 3;
  width: 62px; height: 62px; border-radius: 50%;
  background: rgba(20, 10, 5, .55);
  display: grid; place-items: center;
}
.discover-page .hero-score .bead-ring { position: absolute; inset: 0; width: 100%; height: 100%; }
.discover-page .hero-score-n { position: relative; color: #fff; font-weight: 800; font-size: 1.05rem; }
.discover-page .hero-score-n small { font-size: .62rem; font-weight: 700; margin-left: 1px; }

/* Who they are, over the fade. Room at the foot for the buttons. */
.discover-page .hero-info {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 0 18px 100px; color: #fff; text-align: left;
}
.discover-page .hero-info .card-name {
  margin: 0; color: #fff; font-size: 1.95rem; line-height: 1.1; font-weight: 800;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
.discover-page .hero-info .card-name .age { font-weight: 500; opacity: .92; margin-left: 4px; }
.discover-page .hero-meta {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  margin: 6px 0 0; padding: 0; list-style: none;
  color: rgba(255, 255, 255, .92); font-size: .9rem; font-weight: 600;
}
.discover-page .hero-meta li { margin: 0; padding: 0; background: none; border: 0; color: inherit; }
.discover-page .hero-meta li + li::before { content: "\00b7"; margin-right: 12px; opacity: .7; }
.discover-page .hero-meta .want { color: #ffd88a; }
.discover-page .hero-badge {
  display: inline-block; margin: 10px 0 0; padding: 4px 10px;
  border-radius: var(--r-pill, 999px);
  background: rgba(255, 197, 61, .22); border: 1px solid rgba(255, 197, 61, .55);
  color: #ffe6a6; font-size: .76rem; font-weight: 700;
}
.discover-page .hero-more {
  display: block; margin: 10px 0 0; padding: 6px 12px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgba(255, 255, 255, .4); background: rgba(255, 255, 255, .14);
  color: #fff; font: 700 .78rem/1.2 var(--sans); cursor: pointer;
}

/* Under the photo: the details, as before, with some breathing room. */
.discover-page .profile-card .card-head { padding: 18px 18px 4px; text-align: left; }
.discover-page .profile-card > .bio,
.discover-page .profile-card > .card-block,
.discover-page .profile-card > .veil-note,
.discover-page .profile-card > form,
.discover-page .profile-card > details { margin-left: 18px; margin-right: 18px; }

/* The stamps sit on the photo. */
.discover-page .profile-card .stamp { top: 88px; z-index: 4; }

/* The three bead buttons, floating on the photo at the foot of the card. */
.discover-page .deck-actions.swipe-actions {
  position: absolute; left: 0; right: 0; bottom: 18px; z-index: 6;
  margin: 0; pointer-events: none;
}
.discover-page .deck-actions .deck-btn { pointer-events: auto; }
.discover-page .deck-btn.pass {
  background: radial-gradient(circle, #fffaf2 0 60%, rgba(255, 255, 255, .55) 62%);
  color: var(--earth, #3b2416);
}
.discover-page .deck-hint { display: none; }
.discover-page #deck-count { margin: 6px 0 0; font-size: .74rem; }
/* Polish: the line under the name in plain sentence case, the separator at
   the end of each item so a wrapped line never starts with a dot, the age
   readable on the dark, and no counter peeking out under the card. */
.discover-page .hero-meta { text-transform: none; letter-spacing: 0; font-size: .92rem; gap: 2px 0; }
.discover-page .hero-meta li { text-transform: none; letter-spacing: 0; font-weight: 600; }
.discover-page .hero-meta li + li::before { content: none; }
.discover-page .hero-meta li:not(:last-child)::after { content: "\00b7"; margin: 0 9px; opacity: .7; }
.discover-page .hero-info .card-name .age { color: rgba(255, 255, 255, .9); }
.discover-page #deck-count { display: none; }

/* Reading the details under the photo: the buttons get a shelf of the
   card's own colour behind them, like a bottom bar, so they never sit on
   top of words. discover.js sets .reading while the card is scrolled. */
.discover-page .deck-actions.swipe-actions {
  transition: background-color .2s ease, padding .2s ease, bottom .2s ease;
  border-radius: 0 0 20px 20px;
}
.discover-page .deck-stage.reading .deck-actions.swipe-actions {
  bottom: 0; padding: 26px 0 14px;
  background: linear-gradient(180deg, rgba(255, 250, 242, 0) 0%, var(--surface) 38%);
}
.discover-page .profile-card .card-head,
.discover-page .profile-card > .bio,
.discover-page .profile-card > .card-block { text-align: left; }
/* A thumb-sized "More about". */
.discover-page .hero-more { min-height: 36px; padding: 8px 14px; }

/* Fact rows (answers on cards, profiles, introductions): one row, one line
   under it. The label used to be centred in its own box while the answer
   stretched, so the two lines under them ended at different heights, and a
   long label could squeeze the answer into a narrow column. Now both cells
   fill the row and centre their content, the answer always has at least 42%
   of the width, and a two-line answer breaks evenly. */
.answers, .facts {
  grid-template-columns: minmax(0, 1fr) minmax(42%, auto);
  column-gap: 12px;
}
.answers dt, .facts dt,
.answers dd, .facts dd {
  align-self: stretch;
  display: flex; align-items: center;
  padding-top: 10px; padding-bottom: 10px;
  border-bottom: 1px solid var(--line-soft);
}
.answers dt, .facts dt { padding-right: 0; line-height: 1.3; }
.answers dd, .facts dd {
  justify-content: flex-end; text-align: right;
  line-height: 1.3; text-wrap: balance;
}
.answers dt .ico, .facts dt .ico { flex: none; }
/* Proportions rather than a pinned answer column: the label gets 45% and
   the answer 55%, so neither is squeezed into one word a line, and a long
   word in a label may break instead of running into the answer. */
.answers, .facts { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr); }
.answers dt, .facts dt { overflow-wrap: anywhere; hyphens: auto; }
/* One unbroken line under each row, and labels that only break a word that
   truly cannot fit (no more "RELATIONS / HIP"). */
.answers, .facts { column-gap: 0; }
.answers dd, .facts dd { padding-left: 12px; }
.answers dt, .facts dt { letter-spacing: .04em; overflow-wrap: break-word; hyphens: manual; }

/* The owner's palette for the two backgrounds (October 2026): ladies get
   pink running into a soft purple; men get a warm brown running into white.
   Signed out and non-binary keep the dusk sand. */
html[data-gender="woman"] {
  --bg: #fbf2fa;
  --wash: linear-gradient(172deg, #f9c6dd 0%, #ecd3f3 34%, #fbf2fa 66%);
}
html[data-gender="man"] {
  --bg: #ffffff;
  --wash: linear-gradient(172deg, #e2cfb7 0%, #f1e7da 30%, #ffffff 64%);
}
/* Narrow phones: a touch smaller and a touch wider, so the longest label
   words ("relationship", "involvement") fit whole; breaking inside a word
   stays only as the last resort for a word that still cannot fit. */
@media (max-width: 400px) {
  .answers, .facts { grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr); }
  .answers dt, .facts dt { font-size: .64rem; letter-spacing: .02em; overflow-wrap: anywhere; }
  .answers dt .ico, .facts dt .ico { width: 1.2em; margin-right: .3em; }
}

/* Discover on a slow phone. The card's own entrance played on top of the
   page's slide, and a big soft shadow under a full-screen card is costly to
   paint; together they made the first second after arriving stutter. Now:
   no entrance when the page arrives (the slide already brings it), a short
   one only when the next person comes up after a pass, and a tighter shadow
   that looks the same and paints for a fraction of the cost. */
.discover-page .profile-card:not([hidden]) { animation: none; }
.discover-page .profile-card.arrive { animation: card-in .3s cubic-bezier(.2, .8, .2, 1) both; }
.discover-page .deck .profile-card { box-shadow: 0 6px 16px rgba(40, 20, 10, .24); }
@media (prefers-reduced-motion: reduce) { .discover-page .profile-card.arrive { animation: none; } }

/* The details under a Discover photo are out of sight until the card is
   scrolled, so the browser skips laying them out and painting them until
   then. On a slow phone that was most of the work of showing the page. */
.discover-page .profile-card > .card-head,
.discover-page .profile-card > .bio,
.discover-page .profile-card > .card-block,
.discover-page .profile-card > .veil-note,
.discover-page .profile-card > form,
.discover-page .profile-card > details {
  content-visibility: auto;
  contain-intrinsic-size: auto 220px;
}

/* --- the Kenya look (config LOOK=kenya) -------------------------------------
 * The colours from before the worldwide rebrand, kept so going back is one
 * line in .env: the bands and bead frames in the flag's black, red and green
 * rows, shuka red for buttons and your messages, and the Maasai bead set.
 * Only the palette changes; every shape stays the same.
 */
html[data-look="kenya"] {
  --rose: #c1272d;
  --rose-deep: #a81f28;
  --rose-light: #d63a40;
  --shuka-deep: #8e1b22;
  --plum: #1f4e9c;
  --gold: #f2b01e;
  --blush: #2f7d3b;
  --orchid: #e86a1c;
  --cream: #fffaf2;
  --accent-rgb: 193, 39, 45;
  --accent-soft: #fbe4df;
  --band-1: #151515;
  --band-2: #b3121c;
  --band-3: #1d6b2f;
  --band-thread: #fffaf2;
  --tone-2: #2f7d3b;
  --tone-4: #e86a1c;
  --mark-ground: var(--earth);
  --mark-bead: var(--bead-blue);
  --bead-green: #2f7d3b;
  --bead-border: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3E%3Cdefs%3E%3CradialGradient id='k' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%238a8a8a'/%3E%3Cstop offset='.5' stop-color='%231c1c1c'/%3E%3Cstop offset='1' stop-color='%23020202'/%3E%3C/radialGradient%3E%3CradialGradient id='r' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23ff8077'/%3E%3Cstop offset='.5' stop-color='%23c3141e'/%3E%3Cstop offset='1' stop-color='%235c070c'/%3E%3C/radialGradient%3E%3CradialGradient id='g' cx='.35' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%2379d68f'/%3E%3Cstop offset='.5' stop-color='%2320803a'/%3E%3Cstop offset='1' stop-color='%23093313'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cpath fill='%23fffaf2' fill-rule='evenodd' d='M9 0 H21 A9 9 0 0 1 30 9 V21 A9 9 0 0 1 21 30 H9 A9 9 0 0 1 0 21 V9 A9 9 0 0 1 9 0 Z M9 9 H21 V21 H9 Z'/%3E%3Ccircle cx='10.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='10.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='10.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='10.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='13.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='13.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='13.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='13.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='16.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='16.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='16.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='16.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='19.500' cy='1.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='19.500' cy='28.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.500' cy='19.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.500' cy='19.500' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.644' cy='7.537' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='2.764' cy='4.833' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='4.833' cy='2.764' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='7.537' cy='1.644' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='22.463' cy='1.644' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='25.167' cy='2.764' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='27.236' cy='4.833' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.356' cy='7.537' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='28.356' cy='22.463' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='27.236' cy='25.167' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='25.167' cy='27.236' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='22.463' cy='28.356' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='7.537' cy='28.356' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='4.833' cy='27.236' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='2.764' cy='25.167' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='1.644' cy='22.463' r='1.290' fill='url%28%23k%29'/%3E%3Ccircle cx='10.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='10.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='10.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='10.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='13.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='13.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='13.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='13.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='16.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='16.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='16.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='16.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='19.500' cy='4.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='19.500' cy='25.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.500' cy='19.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.500' cy='19.500' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.843' cy='7.278' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='7.278' cy='4.843' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='22.722' cy='4.843' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.157' cy='7.278' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='25.157' cy='22.722' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='22.722' cy='25.157' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='7.278' cy='25.157' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='4.843' cy='22.722' r='1.290' fill='url%28%23r%29'/%3E%3Ccircle cx='10.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='10.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='10.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='10.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='13.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='13.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='13.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='13.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='16.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='16.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='16.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='16.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='19.500' cy='7.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='19.500' cy='22.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.500' cy='19.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.500' cy='19.500' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.939' cy='7.939' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.061' cy='7.939' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='22.061' cy='22.061' r='1.290' fill='url%28%23g%29'/%3E%3Ccircle cx='7.939' cy='22.061' r='1.290' fill='url%28%23g%29'/%3E%3C/svg%3E");
}
