/* Nearby Close — shared design language.
   Duplicated into each variant's style.css on purpose: layouts.lander links
   exactly one stylesheet per landing, and a second request for ~90 lines of
   custom properties would cost more than the duplication does.

   Friendly geo-app SaaS minimal — the register of a polished location app
   being slightly indiscreet about the neighbourhood. Soft geometry, dotted
   teal ring strokes as the recurring motif, and chips that only ever carry a
   distance or a time. The cool mineral palette is deliberate: the warm skin
   tones of the photography are the hottest thing on the page. */
@import url('https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@500;600;700&family=Manrope:wght@400;600;700;800&display=swap');

:root {
  --ground: #f6f5f2;
  --ink: #201e1b;
  --ink-soft: #6e6a62;
  --card: #ffffff;
  --sand: #ede8df;
  --line: #e4e0d8;
  --accent: #0e7c6b;
  --accent-deep: #0b6357;
  --accent-ink: #ffffff;
  --accent-wash: #e2efec;
  --radius: 18px;
  --radius-sm: 14px;
  --shadow: 0 8px 24px rgba(32, 30, 27, .08);
  --display: 'Schibsted Grotesk', 'Segoe UI', system-ui, sans-serif;
  --body: 'Manrope', 'Segoe UI', system-ui, sans-serif;
  --wrap: 1080px;
}

* { box-sizing: border-box; }

body.lander {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

.nc-wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

.nc-display {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -.015em;
  margin: 0;
}

/* Sentence case, never caps: the register is a friendly app, not a label maker. */
.nc-eyebrow { color: var(--accent); font-size: .85rem; font-weight: 700; margin: 0 0 10px; }

.nc-note { color: var(--ink-soft); font-size: .88rem; margin: 12px 0 0; }

/* The one chip. It carries a DISTANCE or a TIME and nothing else — no status
   words, no online dots, no interest lines. That restraint is what keeps the
   photography reading as live app data rather than profile cards. */
.nc-chip {
  display: inline-flex;
  align-items: center;
  background: var(--sand);
  color: var(--ink);
  border-radius: 999px;
  padding: 6px 12px;
  font-weight: 700;
  font-size: .82rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(32, 30, 27, .14);
}

/* The layout rewires every a.btn to open the signup modal, so a CTA is a
   link, never a button element. */
a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  background: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
  font-weight: 700;
  font-size: 1.02rem;
  /* 44px is the minimum tap target; 54 leaves room for the label to breathe. */
  min-height: 54px;
  padding: 0 30px;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(14, 124, 107, .28);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
/* color: inherit is load-bearing: every CTA wraps its label in a <p>, so any
   section rule that colours paragraphs would land on the label too and beat
   the colour inherited from a.btn. */
a.btn p { margin: 0; color: inherit; }
a.btn:hover { transform: translateY(-1px); background: var(--accent-deep); box-shadow: 0 10px 24px rgba(14, 124, 107, .34); }
a.btn:active { transform: translateY(0); }

/* Every brand logo.svg is authored white, for dark heroes; this brand's
   grounds are all light, so it is recoloured to the ink or it disappears.
   Sized by height — the icon lockup is roughly 6:1, and a width constraint
   would shrink the wordmark to nothing. */
.nc-logo {
  height: 40px;
  width: auto;
  max-width: calc(100vw - 40px);
  filter: brightness(0) opacity(.82);
}

/* Footer chrome is per design; keep it quiet and on-palette. */
footer.legal { padding: 40px 20px 48px; text-align: center; color: var(--ink-soft); font-size: .85rem; }
footer.legal .legal__links { margin-top: 6px; display: flex; justify-content: center; gap: 18px; }
footer.legal a { color: var(--ink-soft); }

/* The modal's submit is a <button>, so the a.btn rules above never reach it
   and form.css supplies layout without colour. An unstyled grey button on the
   actual submit is the most expensive place to leave a default. */
.signup-form__submit {
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: 999px;
  font-weight: 700;
  font-size: 1rem;
  min-height: 54px;
  font-family: var(--body);
}
.signup-modal__title { font-family: var(--display); font-weight: 600; color: var(--ink); }

/* ── Variant B: "List" ───────────────────────────────────────────────────
   A leads with a diagram, B with names: eight tappable rows of name, age and
   distance, one large photo that follows the active row, and the modal opened
   by picking a woman rather than by a timer. The question it answers: does an
   active micro-choice before the ask lift modal completion? */

.b-bar { padding: 22px 0 6px; display: flex; justify-content: center; }

.b-spread { padding: 18px 0 0; text-align: center; }
.b-spread h1 { font-size: clamp(1.8rem, 5.4vw, 2.6rem); }
.b-lede { color: var(--ink-soft); font-size: 1.05rem; max-width: 540px; margin: 12px auto 0; }

.b-cols {
  display: grid;
  grid-template-columns: .95fr 1.05fr;
  gap: 30px;
  align-items: start;
  margin-top: 32px;
  text-align: left;
}

/* Rows carry a name, an age and a distance in tabular figures — deliberately
   no thumbnails, no dots, no interest lines. The list is data; the photo card
   is the payoff. */
.b-list {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px;
}
.b-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 58px;
  padding: 0 16px;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  font-family: var(--body);
  font-size: 1.02rem;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: background .15s ease;
}
.b-row + .b-row { margin-top: 2px; }
.b-row:hover { background: var(--accent-wash); }
.b-row.is-active { background: var(--sand); }
.b-row__name { font-weight: 700; flex: 1; }
.b-row__dist { color: var(--ink-soft); font-weight: 600; font-variant-numeric: tabular-nums; }
.b-row__chev { color: var(--accent); font-size: 1.5rem; line-height: 1; font-weight: 700; }

/* One large photo, never a grid. The offset dotted ring is the brand motif
   standing in for a border. Margin makes room for the outline's offset. */
.b-photo {
  position: sticky;
  top: 24px;
  margin: 8px;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--sand);
  outline: 1.5px dotted var(--accent);
  outline-offset: 6px;
  cursor: pointer;
}
.b-photo__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .35s ease;
}
.b-photo__img.is-shown { opacity: 1; }
.b-photo__chip { position: absolute; top: 14px; left: 14px; z-index: 2; }

.b-band { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 56px 0 64px; }
.b-wide { position: relative; margin: 0; }
.b-wide img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius); box-shadow: var(--shadow); }
.b-wide .nc-chip { position: absolute; top: 14px; left: 14px; }
.b-wide figcaption { color: var(--ink-soft); font-size: .95rem; margin-top: 10px; }

/* Hidden CTA is off-screen rather than display:none — the script clicks it,
   and a display:none element in some browsers does not dispatch. */
.b-hidden-cta { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* The woman painted into the modal by list.js: small square photo, her name
   and distance as the header line. */
.b-meet { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 0 0 14px; }
.b-meet__photo {
  width: 76px;
  height: 76px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  box-shadow: 0 0 0 4px var(--accent-wash), var(--shadow);
}
.b-meet__line {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
  /* form.css repaints the modal; inherit rather than naming a colour. */
  color: inherit;
  margin: 0;
}

@media (max-width: 860px) {
  /* `order: -1`, NOT column-reverse: the photo still comes first without
     reordering the DOM, but the flex axis stays normal. Safari (iPhone)
     miscomputes position:sticky inside a reversed flex axis — the photo
     card rendered as an empty box shoved off-canvas and the page grew
     wider than the viewport, while Chrome (and the review pack's Chrome
     emulation) rendered the same CSS fine. */
  /* align-items must return to stretch here: the base rule's `start` leaks
     into this flex column, children stop stretching, and the photo card —
     whose only contents are absolutely-positioned images — collapses to
     zero width. On the phone that rendered as an empty dotted sliver where
     the photo belongs. */
  .b-cols { display: flex; flex-direction: column; align-items: stretch; gap: 16px; }
  .b-cols > * { min-width: 0; }
  .b-photo {
    order: -1;
    align-self: stretch;
    width: auto;
    position: sticky;
    top: 10px;
    z-index: 5;
    aspect-ratio: auto;
    height: 44vh;
    margin: 8px 8px 10px;
  }
  /* The card is shorter than the 4:5 portraits it crops: anchor the crop
     near the top so faces stay in frame — centred, it lands on the torso. */
  .b-photo__img { object-position: 50% 12%; }
  .b-band { grid-template-columns: 1fr; }
}

/* Full-screen signup modal on phones. Nearby Close only, deliberately: the
   modal is shared chrome, and the same change in form.css would restyle the
   live brands, which were not part of this test. The body prefix is what
   beats form.css, which loads after this file. */
@media (max-width: 640px) {
  .blocker { padding: 0; }

  /* Scoped to the OPEN state on purpose (2026-10-05): jquery-modal moves
     the dialog into .blocker to show it and back to <body> on close, where
     it hides it with an inline display:none. The !important below beats
     that inline style, so an unscoped rule left the dismissed modal
     rendered full-screen at the bottom of the page. Inside .blocker only,
     the rule is inert once the dialog is closed. */
  body.lander .blocker > #signup-modal.container-modal {
    width: 100%;
    max-width: none;
    margin: 0;
    /* dvh so mobile browser chrome does not crop the submit. */
    min-height: 100vh;
    min-height: 100dvh;
    max-height: none;
    border-radius: 0;
    /* Two traps in one line.
       !important: jquery-modal opens the dialog with .show(), which writes
       `display: inline-block` as an INLINE style — no selector outranks that,
       and without this the box goes full screen while its contents stay
       pinned to the top.
       inline-flex, not flex: .blocker centres its child against a full-height
       inline-block ::before spacer. A block-level flex box cannot share that
       line box, so it lands one whole viewport further down the page. */
    display: inline-flex !important;
    flex-direction: column;
    justify-content: center;
    padding: 30px 24px calc(30px + env(safe-area-inset-bottom));
  }

  body.lander #signup-modal.container-modal a.close-modal {
    top: 14px;
    right: 14px;
  }

  /* Full screen has the room the card did not, so the logo gives some of it
     back to the face. */
  .signup-modal__logo { height: 30px; margin-bottom: 18px; }
  .signup-modal__title { font-size: 1.4rem; }
  .b-meet { margin-bottom: 18px; }
  .b-meet__photo { width: 96px; height: 96px; }
  .b-meet__line { font-size: 1.1rem; }
}
