:root {
  --bg: #0e0f0c;
  --bg-2: #16150f;
  --bg-3: #1e1d16;
  --ink: #ece8dc;
  --title: var(--ink);
  --muted: #9a9584;
  --line: #2a291f;
  --accent: #ff5a1f;
  --accent-2: #ffd36a;
  --ok: #7ec8a3;
  --warn: #e2b15a;
  --danger: #e25a4a;
  --radius: 16px;
  --header: 58px;
  --nav: 64px;
  --font: "IBM Plex Sans", system-ui, sans-serif;
  --font-display: Fraunces, Georgia, serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
  --nav-bg: rgba(14, 15, 12, 0.92);
  --btn-ink: #1a0904;
  --btn-radius: 999px;
  --btn-case: none;
  --btn-track: 0;
  --btn-weight: 600;
  --btn-shadow: none;
  --pulse-a: #ff5a1f;
  --pulse-b: #ffd36a;
  --pulse-ink-a: #fff;
  --pulse-ink-b: #1a0904;
  --tag-bg: #2a220f;
  --focus: #5a3a28;
  --map-filter: saturate(0.7) brightness(0.85);
  --map-bg: #12130f;
  --modal-scrim: rgba(8, 8, 6, 0.72);
}

* { box-sizing: border-box; }
html { color-scheme: dark; }
html[data-theme="tiffany"] { color-scheme: dark; }
html[data-theme="lovable"] { color-scheme: light; }
html, body {
  margin: 0;
  height: 100%;
  height: 100dvh;
  max-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  overflow: hidden;
  overscroll-behavior: none;
  overscroll-behavior-y: none;
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  font-family: var(--font);
  /* Apple HIG Body text is 17pt; iOS renders points ~1:1 with CSS px at
     standard viewport scale, so this is the mobile-first baseline. */
  font-size: 17px;
  line-height: 1.4;
  width: 100%;
  -webkit-tap-highlight-color: transparent;
}
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); text-decoration: none; }
img { max-width: 100%; display: block; }

#app {
  min-height: 100%;
  height: 100%;
  height: 100dvh;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: none;
  -webkit-overflow-scrolling: touch;
  padding-top: env(safe-area-inset-top, 0px);
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  height: 36px;
}
.page-logo-bar {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 10px 16px 4px;
  min-height: 48px;
}
.page-logo {
  display: block;
  width: 36px;
  height: 36px;
  flex: none;
  background-color: currentColor;
  color: var(--accent);
  -webkit-mask-image: url("/static/logo.svg");
  mask-image: url("/static/logo.svg");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}
html[data-theme="tiffany"] .page-logo,
html[data-theme="ferrari"] .page-logo,
html[data-theme="lovable"] .page-logo {
  color: var(--title);
}
.brand-mark { width: 36px; height: 36px; flex: none; object-fit: contain; }
.brand h1 { margin: 0; font-size: 1.15rem; }
.site-foot {
  margin-top: 28px;
  padding: 16px 12px 36px;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
}
.site-foot .slogan { font-family: var(--font-display); font-size: 15px; color: var(--ink); margin: 0 0 8px; }
.site-foot p { margin: 4px 0; }
/* Share row (above the copyright). Pure-CSS brand icons: a colored disc
   with the mark built from pseudo-elements / text -- no images, no SVG. */
.share-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 12px; margin: 6px 0 8px; }
.share-label { font-size: 13px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.share-icons { display: flex; gap: 10px; }
.share-hint { flex: 1 1 100%; text-align: center; font-size: 12px; min-height: 0; }
.share-hint:empty { display: none; }
.share-ico {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; border: 0; border-radius: 50%;
  cursor: pointer; text-decoration: none; overflow: hidden; flex: none;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.share-ico i { position: relative; display: block; font-style: normal; }
/* X: black disc, white bold X */
.share-x { background: #000; }
.share-x i::before { content: "\1D54F"; color: #fff; font: 700 17px/1 system-ui, sans-serif; }
/* Snapchat: yellow disc, white ghost with black outline */
.share-snap { background: #fffc00; }
.share-snap i { width: 16px; height: 17px; background: #fff; border: 1.5px solid #000; border-radius: 8px 8px 3px 3px; }
.share-snap i::before, .share-snap i::after { content: ""; position: absolute; top: 5px; width: 2.5px; height: 3.5px; border-radius: 50%; background: #000; }
.share-snap i::before { left: 3.5px; }
.share-snap i::after { right: 3.5px; }
/* Instagram: brand gradient, white rounded-square camera outline + lens + dot */
.share-ig { background: radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285aeb 90%); }
.share-ig i { width: 16px; height: 16px; border: 2px solid #fff; border-radius: 5px; box-sizing: border-box; }
.share-ig i::before { content: ""; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px; border: 2px solid #fff; border-radius: 50%; box-sizing: border-box; }
.share-ig i::after { content: ""; position: absolute; right: 1.5px; top: 1.5px; width: 2px; height: 2px; border-radius: 50%; background: #fff; }
/* Facebook: blue disc, white lowercase f */
.share-fb { background: #1877f2; }
.share-fb i::before { content: "f"; color: #fff; font: 800 21px/1 Helvetica, Arial, sans-serif; position: relative; top: 2px; }
/* SMS: green disc, white speech bubble */
.share-sms { background: #34c759; }
.share-sms i { width: 17px; height: 13px; background: #fff; border-radius: 50%; }
.share-sms i::after { content: ""; position: absolute; left: 2px; bottom: -3px; border: 3px solid transparent; border-top-color: #fff; border-left-color: #fff; transform: rotate(10deg); }
/* Email: red disc, white envelope with a V flap */
.share-email { background: #ea4335; }
.share-email i { width: 17px; height: 12px; background: #fff; border-radius: 2px; overflow: hidden; }
.share-email i::before { content: ""; position: absolute; left: 1.5px; top: -7px; width: 12px; height: 12px; border: 1.5px solid #ea4335; transform: rotate(45deg); box-sizing: border-box; }
.legal-page { max-width: 40rem; margin: 0 auto; padding: 24px 16px 64px; }
.legal-page .page-logo { margin: 0 0 16px; }
.legal-page h1 { font-family: var(--font-display); font-size: 1.8rem; margin: 0 0 8px; }
.legal-page h2 { font-size: 1.05rem; margin: 1.4em 0 0.4em; }
.legal-page .slogan { font-family: var(--font-display); font-size: 1.1rem; margin: 0 0 12px; }
.legal-page ul { padding-left: 1.2em; }
.hero-mark { width: 72px; height: 72px; margin: 0 auto 12px; object-fit: contain; }

.shell {
  min-height: 100%;
  padding-bottom: calc(var(--nav) + env(safe-area-inset-bottom, 0px) + 18px);
}
.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header);
  padding: 10px 18px;
  gap: 12px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 36px;
}
h1, h2, .name, .brand h1, .hero h1, .legal-page h1, .legal-page h2 {
  color: var(--title);
}
.brand h1 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.03em;
  height: 36px;
  line-height: 36px;
  display: flex;
  align-items: center;
}
.brand .page-logo {
  width: 36px;
  height: 36px;
}
.pill {
  border: 1px solid var(--line);
  background: var(--bg-2);
  border-radius: 999px;
  padding: 6px 10px;
  font-size: 12px;
  color: var(--muted);
}
.pill.paid { color: var(--accent-2); border-color: #4a3a16; }

.nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: calc(var(--nav) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--nav-bg);
  border-top: 1px solid var(--line);
  backdrop-filter: blur(12px);
  z-index: 20;
}
.nav button {
  background: none;
  border: 0;
  color: var(--muted);
  padding: 8px 0 12px;
}
.nav button.on { color: var(--ink); }
.nav small { display: block; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }

.page { padding: 8px 18px calc(var(--nav) + env(safe-area-inset-bottom, 0px) + 32px); max-width: 920px; margin: 0 auto; overscroll-behavior: none; }
.tabs {
  display: flex;
  gap: 0;
  overflow-x: auto;
  margin: 4px 0 12px;
  border-bottom: 1px solid var(--line);
  -webkit-overflow-scrolling: touch;
}
.tabs button {
  flex: 1 0 auto;
  min-width: 64px;
  min-height: 44px;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  padding: 10px 8px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.tabs button.on {
  color: var(--ink);
  border-bottom-color: var(--accent);
}
.tab-panel { display: none; }
.tab-panel.on { display: block; }
.page-deck {
  padding: 0;
  max-width: none;
  /* Regression: this omitted env(safe-area-inset-bottom), which .nav's own
     height includes -- so on any notched/home-indicator device the deck's
     box ran env(safe-area-inset-bottom)px (~34px on a modern iPhone) too
     far down, and that strip sat hidden underneath the fixed nav bar. */
  height: calc(100dvh - var(--header) - var(--nav) - env(safe-area-inset-bottom, 0px));
  min-height: calc(100svh - var(--header) - var(--nav) - env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.page-deck .tabs {
  margin: 0;
  padding: 0 8px;
  flex: 0 0 auto;
  background: var(--bg);
  z-index: 6;
}
.page-deck .row.spread {
  flex: 0 0 auto;
  padding: 8px 16px 0;
}
.page-deck .hint {
  padding: 0 16px;
}
.page-deck #homePanels,
.page-deck #tab-list.on,
.page-deck #tab-offers.on,
.page-deck #tab-mine.on,
.page-deck #tab-people.on {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.meetup-deck {
  position: relative;
  flex: 1;
  min-height: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: pan-y pan-x;
}
.meetup-fs-card {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 16px 16px 12px;
  box-sizing: border-box;
  background: var(--bg);
  /* Hard guarantee against scrolling: the card is exactly one screen tall
     and every child below either flexes to fit or is clipped here rather
     than ever growing the card past its container. */
  overflow: hidden;
}
/* Status tag and the "N / total" counter float on top of the photo
   (like a native card-deck app) instead of taking their own line -- that
   reclaims real vertical space for the photo/text below, and the photo
   always starts right at the card's top edge, so anchoring both to the
   card's own padding box lands them on its top corners. */
.meetup-fs-card > .tag {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 3;
  background: rgba(14, 13, 10, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.deck-count {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 3;
  font-size: 12px;
  color: var(--ink);
  font-family: var(--font-mono);
  background: rgba(14, 13, 10, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  padding: 3px 9px;
  border-radius: 999px;
}
.me-edit-deck { overflow-y: auto; -webkit-overflow-scrolling: touch; }
.me-edit-card { height: auto; min-height: 100%; }
.meetup-fs-photo {
  /* Always a true square, at whatever size actually fits: align-self
     overrides the card's default align-items:stretch (which would
     otherwise force width:100% and break the aspect ratio the moment
     flex-shrink/max-height kick in -- that's what made a "square" photo
     render as a squashed rectangle before). With stretch off, width is
     free to be derived from the flex-resolved height via aspect-ratio.
     The photo is still the one elastic element in the card -- it grows
     to fill whatever space the fixed-size title/location/note block
     doesn't need, up to a cap, and shrinks toward its floor when that
     block needs more room -- so the card always sums to exactly one
     screen and never has to scroll, while the photo itself never
     distorts. object-fit:cover keeps the crop intentional at any size. */
  align-self: center;
  aspect-ratio: 1 / 1;
  width: auto;
  max-width: 100%;
  height: auto;
  flex: 1 1 40%;
  min-height: 72px;
  max-height: 46%;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--bg-3);
  border: 1px solid var(--line);
}
.meetup-fs-body {
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Safety net, not the primary mechanism: in the rare case the fixed
     identity fields below still don't fit after the note has clamped
     down and the photo has shrunk to its floor, this clips silently
     instead of ever introducing a scrollbar. */
  overflow: hidden;
}
.meetup-fs-body > .car-flag {
  align-self: flex-start;
}
/* Name/meta/location/car-flag are identity fields and must never clip --
   only the free-text note/bio below (the least predictable in length,
   and the one field where clamping is an acceptable trade-off) shrinks
   and, in a genuine space crunch, gives way first. */
.meetup-fs-body .name,
.meetup-fs-body .meta,
.meetup-fs-body .meetup-place,
.meetup-fs-body > .car-flag,
.meetup-fs-body .stack {
  flex: 0 0 auto;
}
.meetup-fs-body p,
.meetup-fs-body .hint {
  /* flex-grow:0 on purpose -- this must never soak up leftover space (that
     would pad the note out with blank line-height it doesn't need); the
     photo is the only element allowed to grow into slack space. It only
     shrinks, and only when the card is genuinely tight. */
  flex: 0 1 auto;
  min-height: 0;
  /* Cap to a few lines with an ellipsis rather than let one long note
     consume the whole card, on top of being the element that shrinks
     first when space is tight. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  margin: 0;
}
/* The one exception: the accept-offer flow embeds a real form (live camera
   capture, a date/time picker, a note field) inside the body, which is
   longer than any fixed card and can't be flex-shrunk like plain text --
   that variant scrolls internally instead, same as the profile edit form. */
.meetup-fs-body-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.meetup-fs-body-scroll p,
.meetup-fs-body-scroll .hint {
  flex: 0 0 auto;
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}
.meetup-fs-action {
  flex: 0 0 auto;
  margin-top: auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.meetup-fs-accept {
  width: 100%;
  max-width: 420px;
  min-height: 50px;
  font-size: 17px;
  padding: 14px 20px;
}
.meetup-fs-cancel {
  width: auto;
  min-width: 0;
  /* Visually subdued (smaller text/padding) as the secondary action, but
     still meets Apple's 44pt minimum tappable target. */
  min-height: 44px;
  font-size: 14px;
  padding: 8px 16px;
}
.meetup-fs-confirm,
.meetup-fs-cancel-form {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.meetup-fs-confirm .meetup-fs-cancel,
.meetup-fs-cancel-form .meetup-fs-cancel {
  min-height: 44px;
  font-size: 14px;
  padding: 8px 16px;
}
.deck-arrow {
  /* Click targets for mouse/trackpad users, who have no swipe gesture --
     shown only at desktop widths (below, the touch swipe + on-screen
     .tag/.deck-count already communicate the card is pageable). */
  display: none;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(20, 19, 14, 0.55);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 8;
}
.deck-arrow:disabled { opacity: 0.25; cursor: default; pointer-events: none; }
.deck-arrow-prev { left: 8px; }
.deck-arrow-next { right: 8px; }
.deck-arrow-tri {
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  display: block;
}
.deck-arrow-prev .deck-arrow-tri { border-right: 12px solid var(--ink); margin-right: 2px; }
.deck-arrow-next .deck-arrow-tri { border-left: 12px solid var(--ink); margin-left: 2px; }
@media (min-width: 900px) {
  .meetup-fs-card { max-width: 560px; margin: 0 auto; }
  .deck-arrow { display: flex; }
}
.page-map {
  padding: 0;
  max-width: none;
  height: calc(100dvh - var(--header) - var(--nav) - env(safe-area-inset-bottom, 0px));
  min-height: calc(100svh - var(--header) - var(--nav) - env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.page-map .tabs {
  margin: 0;
  padding: 0 8px;
  flex: 0 0 auto;
  background: var(--bg);
  z-index: 6;
}
.page-map #homePanels {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}
.page-map #tab-map.on {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  position: relative;
}
.page-map #map {
  flex: 1;
  height: auto !important;
  min-height: 0;
  border: 0;
  border-radius: 0;
  margin: 0;
}
.map-float {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
.map-float .hint {
  background: var(--nav-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 10px;
  pointer-events: none;
}
.map-float .btn { pointer-events: auto; }
.map-float-actions { display: flex; gap: 8px; pointer-events: auto; }
.hero {
  padding: 48px 22px 28px;
  max-width: 560px;
  margin: 0 auto;
}
.hero h1 {
  font-family: var(--font-display);
  font-size: clamp(36px, 7vw, 56px);
  line-height: 0.95;
  margin: 0 0 14px;
  letter-spacing: -0.04em;
}
.hero p { color: var(--muted); margin: 0 0 22px; max-width: 42ch; }
.kicker {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}

.card {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin: 0 0 12px;
}
.row { display: flex; gap: 12px; align-items: center; }
.row.spread { justify-content: space-between; }
.stack { display: grid; gap: 10px; }

label.field, .field { display: grid; gap: 6px; font-size: 13px; color: var(--muted); }
label.field[hidden], .field[hidden], .field.off { display: none !important; }
/* The hidden attribute must always win over author display rules (e.g.
   .row's display:flex was showing the camera's Use/Retake buttons before
   any photo was taken). */
[hidden] { display: none !important; }
input, select, textarea {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  min-height: 44px;
  outline: none;
}
select {
  cursor: pointer;
}
input:focus, select:focus, textarea:focus { border-color: var(--focus); }
.when-pick {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 10px;
}
.when-pick:has(input[name$="Today"]) {
  grid-template-columns: 1fr;
}
.when-date {
  display: grid;
  grid-template-columns: 1.4fr 0.8fr;
  gap: 8px;
}
.when-time {
  display: grid;
  grid-template-columns: 1fr 12px 1fr 1fr;
  gap: 8px;
  align-items: center;
}
.when-time .colon {
  text-align: center;
  font-weight: 600;
  color: var(--ink);
}
@media (max-width: 640px) {
  .when-pick { grid-template-columns: 1fr; }
}
textarea { min-height: 88px; resize: vertical; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 640px) { .grid-2 { grid-template-columns: 1fr; } }

button.btn {
  background: var(--accent);
  color: var(--btn-ink);
  border: 0;
  border-radius: var(--btn-radius);
  /* Apple HIG minimum tappable target is 44x44pt; 50pt matches a native
     prominent/CTA button. */
  min-height: 50px;
  padding: 14px 22px;
  font-size: 17px;
  font-weight: var(--btn-weight);
  letter-spacing: var(--btn-track);
  text-transform: var(--btn-case);
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
button.btn.ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}
button.btn.ok { background: var(--ok); color: #0e0f0c; }
button.btn.warn { background: var(--bg-3); color: var(--accent-2); border: 1px solid #4a3a16; }
button.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.err { color: var(--danger); font-size: 14px; min-height: 1.2em; }
.meetup-place {
  margin: 0;
  color: var(--accent-2);
  font-weight: 600;
  font-size: 16px;
}
.notice-ok h2 { color: var(--ok); }
.notice-ok p { color: var(--muted); margin: 0; }
.plan-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.plan-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line);
  background: var(--bg);
  border-radius: 10px;
  padding: 12px;
  color: var(--ink);
  min-height: 48px;
}
.plan-opt:has(input:checked) { border-color: var(--accent); }

#map, .live-map, #liveMap {
  height: 46vh;
  min-height: 280px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  margin-bottom: 12px;
  background: var(--bg-3);
  touch-action: pan-x pan-y;
}
.live-map, #liveMap { height: 58vh; min-height: 320px; }
.approach-flash {
  position: fixed;
  top: calc(var(--header) + 8px);
  left: 12px;
  right: 12px;
  z-index: 90;
  cursor: pointer;
}
.approach-flash-inner {
  animation: approachPulse 0.85s ease-in-out infinite;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  font-weight: 700;
  font-size: 16px;
  padding: 14px 44px 14px 16px;
  border-radius: 14px;
  color: #1a0904;
  letter-spacing: 0.02em;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
}
.approach-flash-text { flex: 1; text-align: center; }
.approach-x {
  position: absolute;
  right: 4px;
  top: 50%;
  margin-top: -22px;
  /* Apple HIG minimum tappable target: 44x44pt. */
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.22);
  color: inherit;
  font-weight: 700;
  font-size: 15px;
  line-height: 44px;
  padding: 0;
  cursor: pointer;
}
@keyframes approachPulse {
  0%, 100% { background: var(--pulse-a); color: var(--pulse-ink-a); transform: scale(1); }
  50% { background: var(--pulse-b); color: var(--pulse-ink-b); transform: scale(1.03); }
}
.modal-back {
  position: fixed;
  inset: 0;
  background: var(--modal-scrim);
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 24px;
}
.modal {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 20px;
  max-width: 420px;
  width: 100%;
}

img.meetup-fs-photo { cursor: zoom-in; }
.photo-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 95;
  background: rgba(6, 6, 5, 0.94);
  align-items: center;
  justify-content: center;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
    env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}
.photo-lightbox.on { display: flex; }
.photo-lightbox img {
  max-width: 92vw;
  max-height: 92dvh;
  width: auto;
  height: auto;
  /* contain, not cover: this is the one place the full uncropped photo
     should be visible, unlike the card's hero crop. */
  object-fit: contain;
  border-radius: 12px;
  cursor: zoom-out;
}
.photo-lightbox-close {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 12px);
  right: 12px;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 24px;
  line-height: 44px;
  padding: 0;
  cursor: pointer;
  z-index: 1;
}

.meetup.locked { opacity: 0.92; }
.person, .meetup {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 12px;
  align-items: center;
  cursor: pointer;
  color: inherit;
  text-decoration: none;
}
a.person:hover, a.meetup:hover {
  border-color: var(--accent);
}
.avatar, .photo-sq {
  width: 64px; height: 64px;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  object-fit: cover;
  background: var(--bg-3);
  border: 1px solid var(--line);
}
.photo-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  max-width: 280px;
}
.photo-pair .photo-sq, .shot-full.photo-sq {
  width: 100%;
  height: auto;
  max-width: 220px;
  aspect-ratio: 1 / 1;
}
.cam-card { padding-bottom: 12px; }
.cam-idle { display: flex; justify-content: flex-start; }
.cam-icon-btn {
  width: 72px;
  height: 72px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--bg-2);
  color: var(--ink);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.cam-icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.cam-square {
  width: 220px;
  height: 220px;
  min-height: 220px;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  position: relative;
  background: #111;
}
.cam-square video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 1 / 1;
  max-height: none;
  cursor: pointer;
}
.cam-square::after {
  content: "Tap to capture";
  position: absolute;
  left: 0; right: 0; bottom: 8px;
  text-align: center;
  font-size: 11px;
  color: #fff;
  pointer-events: none;
}
.meta { color: var(--muted); font-size: 15px; }
.name { font-weight: 700; font-size: 17px; }
/* The full-screen card's title is the hero of the page (like a native
   detail-screen headline, ~HIG Title 2/3) — bigger and bolder than a
   compact list row's name. */
.meetup-fs-body .name {
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.meetup-fs-body .meta { font-size: 15px; }
.meetup-fs-body p,
.meetup-fs-body .hint {
  font-size: 17px;
  line-height: 1.4;
}
.tag {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent-2);
  background: var(--tag-bg);
  padding: 4px 8px;
  border-radius: 999px;
  white-space: nowrap;
}

.camera {
  position: relative;
  background: #111;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.camera.missing, .cam-icon-btn.missing, .cam-card.missing .cam-icon-btn {
  border-color: var(--danger);
  box-shadow: 0 0 0 2px rgba(226, 90, 74, 0.28);
}
.shot-full {
  width: 220px;
  height: 220px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  border-radius: 12px;
  background: var(--bg-3);
}
input.missing, select.missing, textarea.missing,
.field.missing input, .field.missing select, .field.missing textarea {
  border-color: var(--danger);
  box-shadow: 0 0 0 2px rgba(226, 90, 74, 0.28);
}
.field.missing { color: var(--danger); }
.fact {
  display: grid;
  grid-template-columns: minmax(9.5rem, auto) 1fr;
  gap: 4px 10px;
  align-items: baseline;
}
.fact-k { color: var(--muted); font-weight: 600; }
.fact-k::after { content: ":"; }
.fact-v { color: var(--ink); min-width: 0; word-break: break-word; }
@media (max-width: 640px) {
  .fact { grid-template-columns: minmax(7.5rem, auto) 1fr; }
}
.locked { opacity: 0.45; pointer-events: none; }
.hint { color: var(--muted); font-size: 15px; }

/* Pre-launch waitlist gate: the live "X of 500 pre-registered" counter
   shown on the landing page and the post-signup notification page. */
.launch-counter { width: 100%; display: grid; gap: 6px; margin: 4px 0; }
.launch-counter-bar {
  height: 8px;
  border-radius: 999px;
  background: var(--bg-3);
  border: 1px solid var(--line);
  overflow: hidden;
}
.launch-counter-fill {
  height: 100%;
  min-width: 4px;
  background: var(--accent);
  border-radius: inherit;
  transition: width 0.4s ease;
}
.launch-counter-label { color: var(--muted); font-size: 13px; text-align: center; margin: 0; }
.countdown { font-family: var(--font-mono); color: var(--warn); font-size: 12px; }

/* Full-bleed hero background, shared by welcomeView (landing) and
   waitlistView (post-signup notification) -- one continuous photo behind
   both a top overlay (wordmark + headline) and a bottom overlay (CTA/
   counter/buttons), each scrimmed independently so the middle of the
   photo stays clear. Full-bleed on every width by design (no max-width
   cap), unlike CitaCoffee-fork's version which keeps the photo in a
   margined, rounded, width-capped card. */
.landing2-full {
  position: fixed;
  inset: 0;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
}
.landing2-bg { position: absolute; inset: 0; z-index: 0; }
.landing2-bg picture { position: absolute; inset: 0; display: block; }
.landing2-bg img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 2s ease;
}
.landing2-bg img.on { opacity: 1; }
.landing2-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: calc(10px + env(safe-area-inset-top, 0px)) 20px 26px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.78) 0%, rgba(0, 0, 0, 0.5) 42%, rgba(0, 0, 0, 0) 100%);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: landing2-fade-down 1.1s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.landing2-head { display: flex; align-items: center; justify-content: center; gap: 10px; }
.landing2-word {
  font-family: var(--font-mono);
  font-size: clamp(16px, 4.5vw, 24px);
  letter-spacing: 0.16em;
  font-weight: 600;
  color: var(--accent);
}
.landing2-head .page-logo { width: 34px; height: 34px; }
.landing2-headline { text-align: center; max-width: 560px; }
.landing2-headline h1 {
  font-family: var(--font-display);
  font-size: clamp(32px, 8vw, 52px);
  line-height: 1.04;
  margin: 0;
  letter-spacing: -0.03em;
  color: #fff;
}
.landing2-headline p {
  color: rgba(255, 255, 255, 0.88);
  margin: 6px 0 0;
  font-size: clamp(13px, 3.2vw, 17px);
}
.landing2-bottom {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 18px 20px calc(10px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.6) 38%, rgba(0, 0, 0, 0) 100%);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: landing2-fade-up 1.1s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.15s;
}
.landing2-callout {
  color: #fff;
  text-align: center;
  font-size: 14px;
  line-height: 1.45;
  max-width: 440px;
  margin: 0 0 2px;
}
.landing2-bottom .launch-counter { max-width: 380px; }
.landing2-bottom .launch-counter-bar { background: rgba(255, 255, 255, 0.25); border-color: rgba(255, 255, 255, 0.35); }
.landing2-bottom .launch-counter-label { color: rgba(255, 255, 255, 0.85); }
.landing2-bottom .btn { width: 100%; max-width: 380px; }
.landing2-bottom .waitlist-promo {
  width: 100%;
  max-width: 380px;
  text-align: center;
  text-transform: uppercase;
  background: #fff;
  color: #1a1a1a;
  border: 0;
  border-radius: 12px;
  padding: 12px 14px;
  font: inherit;
}
.landing2-bottom .btn.ghost { color: #fff; border-color: rgba(255, 255, 255, 0.6); }
.landing2-bottom .hint { color: rgba(255, 255, 255, 0.85); text-align: center; margin: 2px 0 0; max-width: 380px; }
/* Deliberately understated -- this is a secondary CTA (job applicants),
   not competing for attention with the primary dating signup above it. */
.landing2-joinus {
  color: rgba(255, 255, 255, 0.7);
  font-size: 13px;
  text-align: center;
  text-decoration: underline;
  text-underline-offset: 2px;
  margin: 4px 0 0;
}
.landing2-joinus:hover { color: #fff; }
.landing2-bottom .landing2-partner { margin-top: 6px; }
/* Honeypot for the partner form: off-screen, not display:none (some bots skip hidden inputs). */
.partner-hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.landing2-partner-sub { color: rgba(255, 255, 255, 0.8); font-size: 13px; line-height: 1.4; text-align: center; max-width: 380px; margin: 0; }
.landing2-bottom .site-foot { margin-top: 2px; padding: 0; color: rgba(255, 255, 255, 0.65); }
.landing2-bottom .site-foot .copy { margin: 0; }
@media (min-width: 640px) {
  .landing2-top, .landing2-bottom { padding-left: 40px; padding-right: 40px; }
}

/* Ambient particle/bokeh drift over the hero photo -- pure CSS, no JS,
   adapted from a reference design (warm accent/gold instead of its
   original neon cyan/magenta/purple, to match this brand rather than
   fight it). Sits above the photo (z-index 1) but below the scrimmed
   text bands (z-index 2), so it never affects legibility; pointer-events
   is off throughout so it never intercepts taps. Content is unchanged --
   this is decoration only. */
.particle-network {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}
.particle { position: absolute; border-radius: 50%; opacity: 0; bottom: -10vh; }
.bokeh-1 { width: 130px; height: 130px; left: 8%; background: var(--accent); filter: blur(28px); animation: landing2-float-1 26s infinite ease-in-out; }
.bokeh-2 { width: 170px; height: 170px; left: 84%; background: var(--accent-2); filter: blur(36px); animation: landing2-float-2 29s infinite ease-in-out 2s; }
.bokeh-3 { width: 100px; height: 100px; left: 48%; background: var(--accent); filter: blur(22px); animation: landing2-float-3 23s infinite ease-in-out 5s; }
.bokeh-4 { width: 200px; height: 200px; left: -4%; background: var(--accent-2); filter: blur(44px); animation: landing2-float-1 31s infinite ease-in-out 10s; }
.bokeh-5 { width: 150px; height: 150px; left: 76%; background: var(--accent); filter: blur(32px); animation: landing2-float-2 27s infinite ease-in-out 7s; }
.orb-1 { width: 24px; height: 24px; left: 18%; background: var(--accent-2); box-shadow: 0 0 18px var(--accent-2); filter: blur(1.5px); animation: landing2-float-3 19s infinite ease-in-out 1s; }
.orb-2 { width: 32px; height: 32px; left: 62%; background: var(--accent); box-shadow: 0 0 26px var(--accent); filter: blur(2px); animation: landing2-float-1 21s infinite ease-in-out 4s; }
.orb-3 { width: 20px; height: 20px; left: 38%; background: var(--accent-2); box-shadow: 0 0 14px var(--accent-2); filter: blur(1px); animation: landing2-float-2 16s infinite ease-in-out 8s; }
.orb-4 { width: 40px; height: 40px; left: 82%; background: var(--accent); box-shadow: 0 0 32px var(--accent); filter: blur(3px); animation: landing2-float-3 25s infinite ease-in-out 6s; }
.orb-5 { width: 28px; height: 28px; left: 4%; background: var(--accent-2); box-shadow: 0 0 20px var(--accent-2); filter: blur(1.5px); animation: landing2-float-1 20s infinite ease-in-out 12s; }
.dust-1 { width: 4px; height: 4px; left: 14%; background: #fff; box-shadow: 0 0 5px #fff; animation: landing2-float-2 13s infinite linear; }
.dust-2 { width: 3px; height: 3px; left: 34%; background: var(--accent-2); box-shadow: 0 0 4px var(--accent-2); animation: landing2-float-3 15s infinite linear 2s; }
.dust-3 { width: 5px; height: 5px; left: 56%; background: var(--accent); box-shadow: 0 0 6px var(--accent); animation: landing2-float-1 11s infinite linear 5s; }
.dust-4 { width: 2px; height: 2px; left: 74%; background: #fff; box-shadow: 0 0 3px #fff; animation: landing2-float-2 17s infinite linear 1s; }
.dust-5 { width: 4px; height: 4px; left: 91%; background: var(--accent-2); box-shadow: 0 0 5px var(--accent-2); animation: landing2-float-3 12s infinite linear 7s; }
.dust-6 { width: 3px; height: 3px; left: 24%; background: var(--accent); box-shadow: 0 0 4px var(--accent); animation: landing2-float-1 14s infinite linear 3s; }
.dust-7 { width: 5px; height: 5px; left: 46%; background: #fff; box-shadow: 0 0 6px #fff; animation: landing2-float-2 16s infinite linear 8s; }
.dust-8 { width: 2px; height: 2px; left: 66%; background: var(--accent-2); box-shadow: 0 0 3px var(--accent-2); animation: landing2-float-3 10s infinite linear 4s; }
.dust-9 { width: 4px; height: 4px; left: 86%; background: var(--accent); box-shadow: 0 0 5px var(--accent); animation: landing2-float-1 18s infinite linear 6s; }
.dust-10 { width: 3px; height: 3px; left: 6%; background: #fff; box-shadow: 0 0 4px #fff; animation: landing2-float-2 15s infinite linear 9s; }
/* Reduced motion: keep the particles present but static, don't force
   perpetual movement on anyone who's asked the OS to minimize it. */
@media (prefers-reduced-motion: reduce) {
  .particle { animation: none !important; opacity: 0.35; bottom: 40%; }
  .landing2-top, .landing2-bottom { animation: none !important; }
}

@keyframes landing2-fade-down {
  0% { opacity: 0; transform: translateY(-16px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes landing2-fade-up {
  0% { opacity: 0; transform: translateY(16px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes landing2-float-1 {
  0% { transform: translate(0, 0) scale(0.8); opacity: 0; }
  10% { opacity: 0.55; }
  50% { transform: translate(40px, -60vh) scale(1.2); opacity: 0.35; }
  90% { opacity: 0; }
  100% { transform: translate(80px, -120vh) scale(1); opacity: 0; }
}
@keyframes landing2-float-2 {
  0% { transform: translate(0, 0) scale(1); opacity: 0; }
  15% { opacity: 0.4; }
  50% { transform: translate(-32px, -50vh) scale(0.9); opacity: 0.55; }
  85% { opacity: 0; }
  100% { transform: translate(-64px, -110vh) scale(1.1); opacity: 0; }
}
@keyframes landing2-float-3 {
  0% { transform: translate(0, 0) scale(0.9); opacity: 0; }
  20% { opacity: 0.5; }
  40% { transform: translate(24px, -40vh) scale(1); opacity: 0.3; }
  60% { transform: translate(-24px, -70vh) scale(1.3); opacity: 0.5; }
  80% { opacity: 0; }
  100% { transform: translate(0, -120vh) scale(0.9); opacity: 0; }
}

.chat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 46vh;
}
.bubble {
  max-width: 80%;
  padding: 10px 12px;
  border-radius: 14px;
  background: var(--bg-3);
  border: 1px solid var(--line);
}
.bubble.mine { margin-left: auto; background: var(--tag-bg); border-color: var(--accent); }
.bubble.sys { margin: 0 auto; color: var(--muted); background: transparent; border: 0; font-size: 12px; }
.composer { display: grid; grid-template-columns: 1fr auto; gap: 8px; position: sticky; bottom: calc(var(--nav) + 8px); }

.leaflet-container { background: var(--map-bg); font-family: inherit; touch-action: pan-x pan-y; }
.leaflet-tile { filter: var(--map-filter); }
.leaflet-div-icon.gender-pin {
  background: transparent;
  border: 0;
  width: 28px;
  height: 36px;
}
.gender-pin-wrap {
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
  line-height: 0;
}
.gender-pin.is-me .gender-pin-wrap {
  filter: drop-shadow(0 0 0 2px #fff) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
}
.gender-pin.is-inactive .gender-pin-wrap {
  filter: grayscale(0.15) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35));
  opacity: 0.92;
}
.gender-pin.is-offer .gender-pin-wrap {
  filter: drop-shadow(0 0 0 1px #fff) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
}
.leaflet-div-icon.spider-open .cluster-label { opacity: 0.9; }
.gender-pin.is-cluster {
  width: 48px;
  height: 56px;
  overflow: visible;
}
.cluster-pin-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 0;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45));
}
.cluster-label {
  margin-top: 1px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: #fff;
  background: rgba(17, 24, 39, 0.9);
  border: 1px solid #fff;
  border-radius: 999px;
  padding: 2px 7px;
  white-space: nowrap;
  pointer-events: none;
}
html[data-theme="tiffany"] .cluster-label {
  color: #0a3d3c;
  background: rgba(255, 255, 255, 0.94);
  border-color: #0abab5;
}
.cluster-row {
  font-size: 12px;
  margin-top: 4px;
  color: var(--muted);
}
a.cluster-row {
  display: block;
  color: inherit;
  font-weight: 600;
  text-decoration: none;
}
.check {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 14px;
}
.check input { margin-top: 3px; }
.car-flag {
  display: inline-block;
  margin-top: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ok);
  background: var(--tag-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
.pin-pop { min-width: 8rem; }
.pin-pop a { font-weight: 600; }

/* Male → Ferrari (design-md/ferrari): title #da291c, body #ffffff */
html[data-theme="ferrari"] {
  --bg: #181818;
  --bg-2: #242424;
  --bg-3: #303030;
  --title: #da291c;
  --ink: #ffffff;
  /* QA-caught: #969696 measured 4.46:1 against --bg-3, just under the
     4.5:1 AA minimum. Nudged one shade lighter. */
  --muted: #999999;
  --line: #303030;
  --accent: #da291c;
  --accent-2: #fff200;
  --ok: #03904a;
  --warn: #f13a2c;
  --danger: #f13a2c;
  --radius: 0px;
  --font: "Titillium Web", system-ui, sans-serif;
  --font-display: "Titillium Web", system-ui, sans-serif;
  --font-mono: "Titillium Web", ui-monospace, monospace;
  --nav-bg: rgba(24, 24, 24, 0.94);
  --btn-ink: #ffffff;
  --btn-radius: 0px;
  --btn-case: uppercase;
  --btn-track: 1.4px;
  --btn-weight: 700;
  --btn-shadow: none;
  --pulse-a: #da291c;
  --pulse-b: #fff200;
  --pulse-ink-a: #ffffff;
  --pulse-ink-b: #181818;
  --tag-bg: #3a1210;
  --focus: #da291c;
  --map-filter: saturate(0.85) brightness(0.8);
  --map-bg: #181818;
  --modal-scrim: rgba(8, 8, 8, 0.72);
}

/* Female → Tiffany (design-md Tiffany Blue as page bg, white font) */
html[data-theme="tiffany"] {
  --bg: #0ABAB5;
  --bg-2: #007a7c;
  --bg-3: #089991;
  --title: #ffffff;
  --ink: #ffffff;
  /* QA-caught: #e8ffff (near-white cyan) measures ~2.3:1 against this
     Tiffany-blue --bg -- fails WCAG AA (needs 4.5:1) badly. Because --bg
     is bright (not near-black/near-white like the other themes), no
     *lighter* color can ever reach 4.5:1 here -- only a materially
     darker teal does. ~7.2:1 against --bg here; --bg-2 surfaces
     (.card/.modal/.pill) get their own scoped override further down
     since --bg-2 is darker than --bg and needs the opposite (light) text. */
  --muted: #021f1d;
  --line: #7ee0dc;
  --accent: #007a7c;
  --accent-2: #ffffff;
  --ok: #007a7c;
  /* QA-caught: #81d8d0 measured ~1.5:1 against --bg -- functionally
     invisible for a countdown someone needs to actually read. */
  --warn: #5c2c00;
  --danger: #b42318;
  --radius: 10px;
  --font: "Source Sans 3", "Segoe UI", Calibri, sans-serif;
  --font-display: "Cormorant Garamond", Georgia, serif;
  --font-mono: "Source Sans 3", ui-monospace, monospace;
  --nav-bg: rgba(10, 186, 181, 0.94);
  --btn-ink: #ffffff;
  --btn-radius: 8px;
  --btn-case: none;
  --btn-track: 0.04em;
  --btn-weight: 600;
  --btn-shadow: none;
  --pulse-a: #0ABAB5;
  --pulse-b: #81d8d0;
  --pulse-ink-a: #ffffff;
  --pulse-ink-b: #007a7c;
  --tag-bg: #007a7c;
  --focus: #ffffff;
  --map-filter: none;
  --map-bg: #089991;
  --modal-scrim: rgba(0, 80, 80, 0.28);
}
/* QA-caught: --bg-2 (#007a7c) is darker than --bg, unlike every other
   theme (there bg-2/bg-3 get progressively *lighter* than bg) -- the same
   dark --muted tuned for the bright --bg above only reaches ~2.8:1 against
   --bg-2, well under the 4.5:1 AA minimum, on every .card/.modal/.pill
   surface (form field labels, hints, etc). A single flat --muted can't
   satisfy both --bg (needs dark text) and --bg-2 (needs light text) --
   they're too far apart in lightness -- so --bg-2 surfaces get a locally
   scoped light override instead. */
html[data-theme="tiffany"] .card,
html[data-theme="tiffany"] .modal,
html[data-theme="tiffany"] .pill {
  --muted: #ffffff;
}

/* LGBTQ → Lovable (design-md cream bg, black font) */
html[data-theme="lovable"] {
  --bg: #f7f4ed;
  --bg-2: #fcfbf8;
  --bg-3: #eceae4;
  --title: #000000;
  --ink: #000000;
  --muted: #5f5f5d;
  --line: #eceae4;
  --accent: #1c1c1c;
  --accent-2: #5f5f5d;
  --ok: #3f7d4e;
  --warn: #b45309;
  --danger: #b42318;
  --radius: 12px;
  --font: "Nunito Sans", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Nunito Sans", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Nunito Sans", ui-monospace, monospace;
  --nav-bg: rgba(247, 244, 237, 0.94);
  --btn-ink: #fcfbf8;
  --btn-radius: 9999px;
  --btn-case: none;
  --btn-track: 0;
  --btn-weight: 400;
  --btn-shadow: rgba(255,255,255,0.2) 0px 0.5px 0px 0px inset, rgba(0,0,0,0.2) 0px 0px 0px 0.5px inset, rgba(0,0,0,0.05) 0px 1px 2px 0px;
  --pulse-a: #1c1c1c;
  --pulse-b: #eceae4;
  --pulse-ink-a: #fcfbf8;
  --pulse-ink-b: #1c1c1c;
  --tag-bg: #eceae4;
  --focus: #3b82f6;
  --map-filter: none;
  --map-bg: #eceae4;
  --modal-scrim: rgba(28, 28, 28, 0.35);
}

html[data-theme="lovable"] button.btn.ghost,
html[data-theme="tiffany"] button.btn.ghost {
  color: var(--ink);
}
html[data-theme="ferrari"] .card,
html[data-theme="ferrari"] .person,
html[data-theme="ferrari"] .meetup,
html[data-theme="ferrari"] .modal {
  border-radius: 0;
}

/* Add-to-home-screen popup: one solid red card, white text, white x.
   The steps are plain text (no pill/button styling) so nothing reads as
   tappable except the x and, on Android, the real install button. */
.install-prompt {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  z-index: 80;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  max-width: 460px;
  margin: 0 auto;
  padding: 16px 44px 16px 16px;
  background: #d7263d;
  color: #fff;
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}
.install-prompt-x {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  background: transparent;
  color: #fff;
  font-size: 28px;
  line-height: 36px;
  cursor: pointer;
}
.install-prompt-icon {
  width: 48px;
  height: 48px;
  border-radius: 11px;
  flex: none;
  object-fit: cover;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85);
}
.install-prompt-copy {
  flex: 1 1 160px;
  min-width: 0;
}
.install-prompt-copy strong {
  display: block;
  font-size: 16px;
  color: #fff;
}
.install-prompt-copy p {
  margin: 4px 0 0;
  color: #fff;
  font-size: 14px;
  line-height: 1.45;
}
.install-prompt-steps { list-style: none; margin: 6px 0 0; padding: 0; font-size: 14px; line-height: 1.45; font-weight: 700; }
.install-prompt-steps li + li { margin-top: 4px; }
.install-prompt-os { font-weight: 400; opacity: 0.9; }
.install-prompt-cta {
  flex: 1 1 100%;
  padding: 11px 16px;
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: #d7263d;
  font-weight: 700;
  font-size: 15px;
  cursor: pointer;
}
