/* Persistent device-readiness objective: one missing essential at a time. */
.setup-reminder {
  /* In the flow under the app header (push.js inserts it before .shell-body), so it pushes
     content down instead of floating over titles, checkboxes and the chat header. */
  margin:8px 14px 0;
  min-height:56px
}

.setup-reminder:empty {
  display:none
}

.setup-reminder:not(:empty) {
  display:grid;
  grid-template-columns:1fr 40px;
  gap:6px;
  align-items:center
}

.setup-dismiss {
  width:40px;
  height:40px;
  border-radius:50%;
  border:1px solid #ffb54766;
  background:#1b2530f5;
  color:#ffc96f;
  font-size:20px;
  line-height:1;
  display:grid;
  place-items:center
}

.setup-nudge {
  width:100%;
  min-height:48px;
  border:1px solid #ffb547aa;
  border-radius:16px;
  padding:7px 12px;
  display:grid;
  grid-template-columns:22px 1fr 16px;
  gap:10px;
  align-items:center;
  text-align:left;
  color:#fff4d7;
  background:linear-gradient(135deg,#45280aee,#1b2530f5 60%);
  box-shadow:0 7px 26px #0009,0 0 22px #ff9d2428,inset 0 1px #fff2;
  backdrop-filter:blur(14px);
  pointer-events:auto;
  animation:setup-nudge-pulse 2.4s ease-in-out infinite
}

.setup-nudge>i {
  width:13px;
  height:13px;
  justify-self:center;
  border-radius:50%;
  background:#ffb547;
  box-shadow:0 0 0 5px #ffb54718,0 0 15px #ff9d24
}

.setup-nudge span {
  display:flex;
  flex-direction:column;
  font-size:14px;
  font-weight:750;
  line-height:1.15
}

.setup-nudge small {
  color:#ffc96f;
  font-size:9px;
  font-weight:800;
  letter-spacing:.13em;
  text-transform:uppercase;
  margin-bottom:3px
}

.setup-nudge>b {
  font-size:25px;
  font-weight:300;
  color:#ffc96f
}

body.keyboard-open .setup-reminder,
body:has(dialog[open]) .setup-reminder {
  opacity:0;
  visibility:hidden;
  pointer-events:none
}

body.keyboard-open .setup-nudge,
body:has(dialog[open]) .setup-nudge {
  pointer-events:none
}

@keyframes setup-nudge-pulse {
  0%,72%,100% { transform:translateY(0); box-shadow:0 7px 26px #0009,0 0 18px #ff9d2420,inset 0 1px #fff2 }
  78% { transform:translateY(-2px); box-shadow:0 8px 28px #0009,0 0 30px #ff9d2450,inset 0 1px #fff2 }
  84% { transform:translateY(0) }
  90% { transform:translateY(-1px) }
}

@media (prefers-reduced-motion:reduce) {
  .setup-nudge { animation:none }
}


/* The setup banner sits in the flow above the page, so full-height views subtract its measured
   height (--setup-h, set by push.js; 0 when there is no banner) instead of guessing. */
body:not(.keyboard-open) .conversation {
  height:calc(var(--vvh,100dvh) - 44px - env(safe-area-inset-top) - var(--nav-h,calc(69px + env(safe-area-inset-bottom))) - 2px - var(--setup-h,0px))
}

body:not(.keyboard-open) .discover:has(.direction-stage) {
  height:calc(var(--vvh,100dvh) - 44px - env(safe-area-inset-top) - var(--nav-h,calc(69px + env(safe-area-inset-bottom))) - var(--setup-h,0px))
}

body.keyboard-open {
  overscroll-behavior:none
}

/* Bigger Radar/Grid switch; a handle you can actually grab. */
.segmented button {
  font-size:14px;
  min-height:38px;
  padding:6px 18px
}

.sheet-handle {
  height:6px;
  width:56px;
  border-radius:6px;
  background:#7d8f9c;
  margin:2px auto 24px
}

.sheet-handle::before {
  inset:-20px -80px -24px
}

/* Portrait only on phones: in landscape, a full-screen notice covers the app. */
.rotate-notice {
  display:none
}

@media (orientation:landscape) and (max-height:500px) and (hover:none) and (pointer:coarse) {
  .rotate-notice {
    display:flex;
    position:fixed;
    inset:0;
    z-index:100;
    align-items:center;
    justify-content:center;
    background:#0a1622;
    color:var(--ink);
    text-align:center;
    padding:24px
  }

  /* Freeze the app underneath instead of hiding it, so its layout doesn't reflow on rotate-back. */
  .app-shell,
  .login-shell {
    visibility:hidden
  }

  .rotate-notice svg {
    width:44px;
    height:44px;
    fill:none;
    stroke:var(--ice);
    stroke-width:1.6;
    stroke-linecap:round;
    transform:rotate(90deg);
    margin-bottom:12px
  }

  .rotate-notice p {
    margin:0;
    font-size:16px
  }
}





/* Me: who has your pic, blocked list; no sideways scroll anywhere. */
html,body {
  overflow-x:hidden
}

main {
  overflow-x:hidden
}

.stats-field .stat-grid > * {
  min-width:0
}

.stats-field .stat-grid input[type=date] {
  width:100%;
  font:inherit;
  color:var(--ink);
  background:#122330;
  border:1px solid #3c4e5d;
  border-radius:10px;
  padding:9px 10px;
  font-size:15px;
  -webkit-appearance:none;
  appearance:none
}


.access-row {
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap:12px;
  font-size:14px;
  padding:9px 0;
  border-bottom:1px solid var(--line)
}

.access-row.head {
  justify-content:flex-start;
  color:var(--muted);
  border-bottom:0
}

.access-row .text-button {
  font-size:13px
}

/* Ask him to unlock a photo. */
.thumb.locked {
  cursor:pointer;
  flex-direction:column;
  gap:3px;
  font:inherit
}

.thumb.locked small {
  font-size:9px;
  letter-spacing:.4px;
  text-transform:uppercase;
  color:#9fb6c4
}

.thumb.locked.asked {
  border-style:solid;
  border-color:#4cd8e866
}

.bubble.request {
  display:inline-flex;
  align-items:center;
  gap:8px;
  font-style:italic;
  opacity:.85
}

/* Individual photo files fill their frame. */
.avatar>img:not(.photo-sheet):not(.body-tile):not(.photo-tile) {
  width:100%;
  height:100%;
  object-fit:cover
}



.star-button {
  position:absolute;
  left:16px;
  top:16px;
  width:44px;
  height:44px;
  font-size:22px;
  color:#b4c5d2;
  background:none;
  border:0
}

.star-button.on {
  color:#ffd66b;
  text-shadow:0 0 10px #ffd66b80
}

.grid-star {
  position:absolute;
  left:8px;
  bottom:8px;
  color:#ffd66b;
  font-size:14px;
  z-index:2;
  text-shadow:0 0 6px #000
}

.bubble[data-unsend] {
  cursor:pointer
}

/* iOS still pans sideways when only html/body hide overflow; clip at the shell and paint-contain the avatars. */
.app-shell {
  overflow-x:clip;
  width:100%;
  position:relative
}

main {
  overflow-x:clip
}

.avatar {
  contain:paint
}

.me-section,.me-section form,.stats-field {
  max-width:100%;
  min-width:0
}

.type-options {
  flex-wrap:wrap;
  max-width:100%
}


#profile-form .primary.saved {
  background:#6fdca4;
  color:#0b2318
}

.editor-avatar,.editor-avatar.avatar {
  width:104px;
  height:104px;
  border-radius:16px
}

.avatar-choice .avatar {
  border-radius:12px
}

/* iOS date field: it has an intrinsic width the grid must be allowed to squash. */
.stats-field .stat-grid {
  grid-template-columns:minmax(0,1fr) minmax(0,1fr)
}

.stats-field .stat-grid input[type=date] {
  display:block;
  width:100%;
  max-width:100%;
  min-width:0;
  min-height:42px;
  box-sizing:border-box;
  text-align:left
}

input[type=date]::-webkit-date-and-time-value {
  text-align:left;
  min-height:1.2em
}

input[type=date]::-webkit-calendar-picker-indicator {
  margin:0;
  padding:0
}

/* Settings sub-screen and unlock banner. */
.settings-row {
  display:grid;
  grid-template-columns:1fr auto;
  gap:2px 12px;
  width:100%;
  text-align:left;
  margin:26px 0 12px;
  padding:14px 16px;
  border-radius:14px;
  background:#12222e;
  border:1px solid #2c4252;
  color:var(--ink);
  font:inherit
}

.settings-row span {
  grid-column:1;
  font-size:15px;
  font-weight:600
}

.settings-row small {
  grid-column:1;
  color:var(--muted);
  font-size:12px;
  line-height:1.4
}

.settings-row i {
  grid-column:2;
  grid-row:1 / span 2;
  align-self:center;
  font-style:normal;
  font-size:22px;
  color:var(--muted)
}

.settings-section h2 {
  font-size:15px;
  margin:26px 0 8px
}

.settings-section h2 span {
  font-size:12px;
  color:var(--muted);
  margin-left:6px
}

.settings-head {
  display:flex;
  align-items:center;
  gap:8px
}

.settings-head h1 {
  margin:0;
  font-size:22px
}

.settings-head .icon-button {
  min-width:44px
}

.settings-section .connection-note {
  text-align:left
}

.profile-action-cue {
  display:inline-flex;
  align-items:center;
  min-height:40px;
  margin-top:8px;
  color:#8ee7ef;
  font-size:13px;
  font-weight:650;
  text-decoration:none
}

.completion-card {
  margin:14px 0 24px;
  padding:14px 16px;
  border:1px solid #2c5262;
  border-radius:16px;
  background:linear-gradient(135deg,#122b38,#10212d)
}

.completion-card summary {
  display:flex;
  justify-content:space-between;
  gap:12px;
  cursor:pointer;
  list-style:none;
  font-weight:650
}

.completion-card summary small {
  color:var(--muted);
  font-size:12px;
  font-weight:400
}

.completion-card ul {
  display:grid;
  gap:8px;
  margin:14px 0 0;
  padding:0;
  list-style:none;
  color:#c7d7e2;
  font-size:13px
}

.completion-card li {
  display:flex;
  gap:9px
}

.completion-card li.done {
  color:#82d8ca
}

.setup-needed main {
  padding-bottom:max(24px,env(safe-area-inset-bottom))
}

.presence-options {
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:6px;
  padding:5px;
  border:1px solid #2c4252;
  border-radius:14px;
  background:#0d1b25
}

.presence-options button {
  min-height:44px;
  padding:8px 6px;
  border:0;
  border-radius:10px;
  background:transparent;
  color:var(--muted);
  font-family:inherit;
  font-size:12px;
  font-weight:600;
  line-height:1.15
}

.presence-options button.active {
  background:#1f4457;
  color:var(--ink);
  box-shadow:0 1px 8px #0005
}

.presence-status {
  margin:9px 2px 2px;
  color:#8be4da;
  font-size:13px
}

.unit-input {
  position:relative
}

.unit-input input {
  width:100%;
  padding-right:42px
}

.unit-input span {
  position:absolute;
  right:14px;
  top:50%;
  transform:translateY(-50%);
  color:var(--muted);
  pointer-events:none
}

.setup-needed .bottom-nav {
  display:none
}

.unlock-ask {
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:8px 12px;
  padding:10px 12px;
  margin-top:8px;
  border-radius:12px;
  background:#16303f;
  border:1px solid #2f5468;
  font-size:13px;
  flex:none
}

.unlock-ask span {
  display:inline-flex;
  align-items:center;
  gap:8px
}

.unlock-ask .secondary {
  min-height:34px;
  padding:0 14px
}

.notify-banner {
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:6px 12px;
  padding:12px 14px;
  margin-bottom:18px;
  border-radius:12px;
  background:#16303f;
  border:1px solid #2f5468;
  font-size:12px;
  color:#c5d6e2
}

.notify-banner .text-button {
  min-height:44px;
  padding:0 4px;
  white-space:nowrap
}

p.notify-banner {
  display:block;
  color:var(--muted);
  line-height:1.6
}

/* Invite and install tips. */
.invite-row {
  display:grid;
  grid-template-columns:minmax(0,1fr) auto;
  gap:8px;
  align-items:center
}

.invite-link {
  display:block;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  font-size:12px;
  padding:10px 12px;
  border-radius:10px;
  background:#122330;
  border:1px solid #3c4e5d;
  color:var(--ice)
}

.invite-row .secondary {
  width:auto;
  min-height:44px;
  padding:0 16px;
  flex:none
}

/* Under 900px the settings column is too narrow to show a readable link next to the button, so stack them:
   the full link on one line, the button full width beneath it. */
@media(max-width:899px) {
  .invite-row {
    grid-template-columns:minmax(0,1fr)
  }

  .invite-row .secondary {
    width:100%
  }
}

.settings-row.invite-cta {
  margin-top:26px;
  margin-bottom:0
}

.settings-row.invite-cta + .settings-row {
  margin-top:10px
}

.install-tip {
  margin-top:28px;
  padding:14px 16px;
  border-radius:14px;
  background:#12222e;
  border:1px solid #2c4252;
  font-size:13px;
  line-height:1.5;
  color:var(--muted)
}

.install-tip h2 {
  margin:0 0 6px;
  font-size:14px;
  color:var(--ink)
}

.install-tip p {
  margin:6px 0
}

/* Full-screen chat photo, and hold-to-unsend (no iOS save-image callout on the bubbles). */
#lightbox {
  position:fixed;
  inset:0;
  z-index:80;
  display:flex;
  align-items:center;
  justify-content:center;
  background:#000000e6;
  opacity:0;
  pointer-events:none;
  transition:opacity .22s
}

#lightbox.show {
  opacity:1;
  pointer-events:auto
}

#lightbox .lightbox-media {
  width:100%;
  height:100%;
  display:grid;
  place-items:center
}

#lightbox img,
#lightbox video {
  max-width:100vw;
  max-height:100vh;
  max-height:100dvh;
  width:auto;
  height:auto;
  object-fit:contain
}

#lightbox .lightbox-close {
  position:absolute;
  top:calc(8px + env(safe-area-inset-top));
  right:12px;
  width:44px;
  height:44px;
  border:0;
  border-radius:50%;
  background:#ffffff22;
  color:#fff;
  font-size:26px;
  line-height:1;
  cursor:pointer
}

/* The whole thread is hold-to-act, not select-to-copy: a long press at a bubble's edge used to select the
   timestamp under it and pop iOS's Copy / Look Up callout (2026-09-17 re-test, frame 083). */
.message-stream,
.bubble[data-msg],
.bubble[data-unsend],
.bubble.photo,
.bubble.photo img {
  -webkit-touch-callout:none;
  -webkit-user-select:none;
  user-select:none
}

.bubble.photo {
  cursor:zoom-in
}

/* Tablets: the Grid gets the width it has (four columns in a 720px column) instead of a 480px phone
   column in a dark void (review 2026-09-08, item 23). Radar keeps its phone geometry on purpose. */
@media(min-width:600px) and (max-width:899px) {
  body.grid-mode .app-shell,
  body.grid-mode .bottom-nav {
    max-width:720px;
    width:min(100%,720px)
  }

  body.grid-mode .profile-grid {
    grid-template-columns:repeat(4,minmax(0,1fr));
    gap:8px
  }
}

/* Desktop: use the whole window. Phones (under 900px) are untouched. */
@media(min-width:900px) {
  .app-shell {
    max-width:none;
    border-inline:0;
    box-shadow:none
  }

  .profile-arc {
    width:100%
  }

  /* Full-width bar, but the four buttons stay grouped in the middle instead of
     drifting to the monitor's corners (review 2026-09-08, item 25). */
  .bottom-nav {
    width:100%;
    justify-content:center;
    gap:40px
  }

  .bottom-nav button {
    max-width:160px;
    min-width:120px
  }

  .radar-side-labels {
    inset:auto max(0px,calc(50% - var(--radar-w,388px) / 2 - 110px)) 14px
  }

  .profile-grid {
    grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
    gap:8px;
    margin-inline:0
  }

  .chats-section,.conversation,.me-section,.settings-section {
    max-width:760px;
    margin-inline:auto
  }
}

/* Profiles past the radar edge sit on the perimeter as a small marker (status colour kept). */
.distance-dot.beyond>span {
  width:4px;
  height:4px
}

/* Local streets (residential), shown when the drawn range is 6 km or less. */
.map-lane {
  stroke:#8fc4d6;
  stroke-width:.3;
  opacity:.6
}

.stack-map .map-lane {
  stroke-width:.8;
  opacity:.7
}

/* Filters master switch. */
.filters-chip.off {
  text-decoration:line-through;
  opacity:.75
}


/* Chat header: bigger square pic (John, 2026-09-07). Missing chat photos collapse to a note instead of a strip. */
.conversation-header .avatar {
  width:64px;
  height:64px;
  border-radius:14px
}

.conversation-header .avatar img,
.conversation-header .avatar>img:not(.photo-sheet):not(.body-tile):not(.photo-tile) {
  border-radius:13px
}

.bubble.photo {
  min-height:64px
}

.bubble.photo.missing img,
.bubble.photo.missing .photo-reveal {
  display:none
}

.bubble.photo.missing::before {
  content:'Photo no longer available';
  display:block;
  padding:10px 12px 18px;
  color:var(--muted);
  font-size:13px
}

/* Max-distance slider above the radar stage, and the "right here" pill for people hidden under the radar. */
.range-slider[hidden] {
  display:none
}

.range-slider {
  display:flex;
  align-items:center;
  gap:10px;
  height:30px;
  margin:2px 0 0;
  font-size:12px;
  color:var(--muted)
}

.range-slider input {
  flex:1;
  min-width:0;
  accent-color:#5fd0e8;
  height:22px
}

.range-slider output {
  min-width:52px;
  text-align:right;
  font:12px ui-monospace,SFMono-Regular,monospace;
  color:var(--ink)
}

.here-pill {
  position:absolute;
  left:50%;
  bottom:4px;
  transform:translateX(-50%);
  z-index:5;
  padding:4px 10px;
  border-radius:999px;
  border:1px solid #5fd0e880;
  background:#0a1d27e6;
  color:#d7f4fb;
  font-size:12px;
  white-space:nowrap;
  cursor:pointer
}

@media(max-width:340px) {
  .compass-field .map-credit {
    left:auto;
    right:16px;
    bottom:54px
  }
}


/* Section 2 mobile polish: comfortable targets, readable status text, and clear feedback lanes. */

.distance-dot {
  width:44px;
  height:44px
}

.arc-profile .bubble-hit {
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  left:auto;
  transform:none;
  width:max(44px,var(--bubble-size));
  height:max(44px,var(--bubble-size));
  margin-left:calc((var(--bubble-size) - max(44px,var(--bubble-size))) / 2);
  margin-top:calc((var(--bubble-size) - max(44px,var(--bubble-size))) / 2);
  clip-path:none
}

.arc-profile .bubble-hit .avatar {
  width:var(--bubble-size);
  height:var(--bubble-size);
  margin:0
}

.header-discovery .segmented button {
  min-width:44px;
  min-height:44px
}

.here-pill {
  min-height:44px;
  padding:8px 14px
}

.radar-side-labels {
  inset-inline:8px
}

.range-readout,
#radar-direction {
  min-width:44px
}

.conversation-header {
  padding-inline:4px
}

.conversation-header>.icon-button {
  width:44px;
  height:44px
}

.own-photo-grid {
  grid-template-columns:repeat(auto-fill,minmax(138px,1fr))
}

.own-photo-actions {
  width:100%;
  gap:4px
}

.own-photo-actions .icon-button,
.own-photo-actions .text-button,
.own-photo>.subdued {
  min-width:44px;
  min-height:44px
}

.own-photo-actions .text-button {
  flex:1;
  font-size:12px
}

.own-photo>.subdued {
  width:100%;
  font-size:12px
}

.stats-field .stat-grid select,
.stats-field .stat-grid input[type=number],
.stats-field .stat-grid input[type=date] {
  min-height:44px
}

.login-foot {
  font-size:12px;
  line-height:1.4
}

.login-foot a {
  display:inline-flex;
  align-items:center;
  min-height:44px;
  padding-inline:4px
}

.onboard-buttons [data-onboard-skip] {
  min-width:44px;
  padding-inline:12px
}

.bubble-time {
  font-size:12px;
  opacity:1;
  color:#c5d6e2
}

.bubble.outgoing .bubble-time {
  color:#36515f
}

.discovery-filters {
  overflow-x:auto;
  flex-wrap:nowrap;
  scrollbar-width:none;
  overscroll-behavior-inline:contain
}

.discovery-filters::-webkit-scrollbar {
  display:none
}

.discovery-filters .reciprocal-filter,
.discovery-filters .filters-chip,
.discovery-filters .star-filter,
.discovery-filters .map-toggle {
  flex:0 0 auto;
  min-height:44px;
  font-size:13px
}

.discovery-filters .map-toggle {
  margin-left:0
}


/* Bring a candidate forward for a closer look without moving its centre off the sight line. */
.arc-profile .bubble-hit {
  transform:scale(1);
  transform-origin:center;
  transition:transform .24s cubic-bezier(.2,.8,.2,1),filter .24s ease
}

.profile-arc .arc-profile:has(.bubble-hit:hover),
.profile-arc .arc-profile:has(.bubble-hit:focus-visible) {
  z-index:10000!important;
  opacity:1!important
}

.profile-arc:has(.bubble-hit:hover),
.profile-arc:has(.bubble-hit:focus-visible) {
  overflow:visible
}

.arc-profile .bubble-hit:hover,
.arc-profile .bubble-hit:focus-visible {
  transform:scale(var(--hover-scale));
  filter:drop-shadow(0 14px 18px #0009)
}


.range-readout .range-unit {
  display:inline;
  margin:0 0 0 2px
}

.error-card {
  text-align:center
}

.error-card .error-code {
  margin:30px 0 0;
  color:var(--ice);
  font:600 13px ui-monospace,SFMono-Regular,monospace;
  letter-spacing:.12em
}

.error-card .primary {
  display:block;
  margin-top:24px;
  text-decoration:none
}

/* Chat rows: the row is the flex item (so a tall photo is never squashed), the time sits outside the bubble, and
   multi-line messages sit tighter. */
.message-stream>* {
  flex:none
}

.msg-row {
  display:flex;
  flex-direction:column;
  gap:3px;
  max-width:86%
}

.msg-row.outgoing {
  align-self:flex-end;
  align-items:flex-end
}

.msg-row.incoming {
  align-self:flex-start;
  align-items:flex-start
}

.msg-row.photo-row {
  max-width:clamp(74px,22vw,96px)
}

.msg-row.photo-row .bubble.photo {
  width:100%;
  max-width:100%;
  min-height:0;
  aspect-ratio:1
}

.msg-row>.bubble {
  max-width:100%
}

.message-stream .bubble {
  line-height:1.42
}

.msg-row>.bubble-time {
  position:static;
  display:block;
  margin:0;
  padding:0 4px;
  background:none;
  font-size:10px;
  color:var(--muted);
  opacity:.85
}

.bubble.photo img {
  width:clamp(74px,22vw,96px);
  height:clamp(74px,22vw,96px);
  max-width:100%;
  object-fit:cover;
  background:#0b1822
}

.bubble.photo video {
  display:block;
  width:100%;
  height:100%;
  max-height:none;
  object-fit:cover;
  border-radius:12px;
  background:#000
}

.media-play {position:absolute;left:50%;top:50%;translate:-50% -50%;width:34px;height:34px;display:grid;place-items:center;padding-left:2px;border-radius:50%;background:#07121ccc;color:#fff;box-shadow:0 0 0 1px #fff4;pointer-events:none}

