:root{
  --bg:#0a0c0f; --panel:#11141a; --card:#141821; --line:#232935;
  --ink:#e7eaee; --dim:#8d96a3; --faint:#7d8797; --live:#3fb950;
}
*{box-sizing:border-box}
[hidden]{display:none !important}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:16px/1.65 ui-sans-serif,-apple-system,"SF Pro Text",system-ui,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased;
  display:flex; flex-direction:column; min-height:100vh;
}
nav{
  display:flex; align-items:center; gap:16px; padding:0 26px; min-height:62px;
  flex-wrap:wrap; row-gap:0;
  border-bottom:1px solid var(--line); background:rgba(17,20,26,.72);
  backdrop-filter:blur(10px); position:sticky; top:0; z-index:10;
}
.brand{display:flex; align-items:center; gap:10px; flex:0 0 auto;
  color:var(--ink); text-decoration:none}
.brand img{width:24px; height:24px; border-radius:6px; display:block}
.brand span{font-size:12px; font-weight:600; letter-spacing:.26em}
.spacer{flex:1}
.navlink{color:var(--dim); text-decoration:none; font-size:13px}
.navlink:hover{color:var(--ink)}
.navuser{color:var(--faint); font-size:13px;
  max-width:16ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
button{font:inherit; cursor:pointer; border-radius:7px; transition:all .15s}
button.ghost{
  background:transparent; color:var(--dim); border:1px solid var(--line);
  padding:7px 15px; font-size:13px;
}
button.ghost:hover{color:var(--ink); border-color:#39424f; background:#161a22}
/* Same look on a link, for the demo button beside the primary in the hero. */
a.ghost{
  display:inline-block; background:transparent; color:var(--dim); border:1px solid var(--line);
  border-radius:7px; padding:11px 22px; font-size:14.5px; text-decoration:none; transition:all .15s;
}
a.ghost:hover{color:var(--ink); border-color:#39424f; background:#161a22}
button.primary{
  background:var(--ink); color:#0a0c0f; border:1px solid var(--ink);
  padding:12px 24px; font-size:14.5px; font-weight:500;
}
button.primary:hover{background:#fff; border-color:#fff}

/* body is a flex column, and a stretched flex item's cross size is floored by
   its own min-content width — so one unshrinkable descendant (the admin
   table, the guide's nowrap chip strip) widened <main> to max-content and
   scrolled the whole page sideways, heading and footer with it. A definite
   width:100% resolves against the body box instead and cannot be floored. */
nav,main,footer{width:100%; min-width:0; max-width:100%}
main{flex:1}
.hero{position:relative; overflow:hidden; padding:78px 26px 60px; isolation:isolate}

/* Invented street map (see dashboard/tools/make-mapbg.py). Texture only —
   never contrast enough to fight the type sitting on it. */
.herobg{position:absolute; inset:0; z-index:-1; pointer-events:none}
.mapbg{
  width:100%; height:100%; display:block; pointer-events:none; border:0;
  -webkit-mask-image:radial-gradient(128% 118% at 52% 42%, #000 52%, transparent 94%);
  mask-image:radial-gradient(128% 118% at 52% 42%, #000 52%, transparent 94%);
}
/* Scrim: the type has to stay readable whatever the map does underneath. */
.herobg::after{
  content:""; position:absolute; inset:0;
  background:
    radial-gradient(50% 80% at 15% 48%,
      rgba(10,12,15,.96) 0%, rgba(10,12,15,.88) 52%, rgba(10,12,15,.64) 76%,
      rgba(10,12,15,.14) 92%, transparent 100%),
    linear-gradient(to bottom, rgba(10,12,15,.18) 0%, rgba(10,12,15,0) 32%, rgba(10,12,15,.52) 82%, var(--bg) 100%);
}

/* Single column since the sign-in card moved into the nav. The scrim behind
   it is a radial weighted to the left, so the copy keeps a max-width and stays
   there rather than spreading across the full 1080 and running out from under
   its own backdrop. */
.hero-inner{max-width:1080px; margin:0 auto}
.hero-copy{text-align:left; padding-top:6px; max-width:720px}
@media (max-width:940px){
  .hero{padding:64px 22px 52px}
  .hero-copy{text-align:center; max-width:none}
  .mapbg{-webkit-mask-image:radial-gradient(150% 82% at 50% 30%, #000 38%, transparent 88%);
         mask-image:radial-gradient(150% 82% at 50% 30%, #000 38%, transparent 88%)}
  .herobg::after{background:
    linear-gradient(to bottom,
      rgba(10,12,15,.55) 0%, rgba(10,12,15,.82) 14%, rgba(10,12,15,.82) 60%,
      rgba(10,12,15,.42) 78%, var(--bg) 100%)}
}
.eyebrow{
  margin:0 0 20px; font-size:11.5px; letter-spacing:.24em; text-transform:uppercase;
  color:var(--live);
}
h1{
  margin:0 0 22px; font-size:52px; line-height:1.08; letter-spacing:-.025em;
  font-weight:600;
}
.lede{margin:0 0 30px; max-width:560px; font-size:17.5px; color:var(--dim)}
@media (max-width:940px){ .lede{margin-left:auto; margin-right:auto} }
.actions{display:flex; gap:20px; align-items:center; flex-wrap:wrap; margin-top:4px}
@media (max-width:940px){ .actions{justify-content:center} }
.link{color:var(--dim); text-decoration:none; font-size:14.5px; border-bottom:1px solid var(--line)}
.link:hover{color:var(--ink)}
.note{margin:22px 0 0; font-size:13.5px; color:var(--faint); min-height:20px}
.note.err{color:#e5837c}

.cards{
  max-width:1060px; margin:0 auto; padding:20px 26px 84px;
  display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:18px;
}
.cards article{
  background:var(--card); border:1px solid var(--line); border-radius:11px; padding:26px 24px;
}
.cards h3{margin:0 0 10px; font-size:16px; font-weight:600; letter-spacing:-.005em}
.cards p{margin:0; font-size:14.5px; color:var(--dim); line-height:1.7}

.how{max-width:760px; margin:0 auto; padding:0 26px 96px}
.how h2{font-size:13px; letter-spacing:.2em; text-transform:uppercase; color:var(--faint);
  margin:0 0 26px; font-weight:600}
.how ol{margin:0; padding:0; list-style:none; counter-reset:step}
.how li{
  counter-increment:step; position:relative; padding:0 0 26px 46px;
  color:var(--dim); font-size:15.5px;
}
.how li::before{
  content:counter(step); position:absolute; left:0; top:1px;
  width:28px; height:28px; border-radius:50%; background:var(--card);
  border:1px solid var(--line); color:var(--faint);
  display:grid; place-items:center; font-size:12.5px;
}
.how li b{color:var(--ink); font-weight:500}
.fine{
  margin:12px 0 0; padding:16px 18px; background:#12161d; border:1px solid var(--line);
  border-left:2px solid #7a6320; border-radius:7px;
  font-size:13px; color:var(--faint); line-height:1.65;
}
footer{
  border-top:1px solid var(--line); padding:24px 26px; display:flex; gap:14px;
  flex-wrap:wrap; row-gap:8px; align-items:center;
  font-size:12.5px; color:var(--faint);
}
footer .dim{color:#414954}
@media (max-width:600px){
  h1{font-size:38px}
  .hero{padding:52px 20px 44px}
}

/* ---------- account panel ----------
   The sign-in form used to occupy half the hero. It now hangs off the nav
   button, which leaves the landing page to say what the product is.

   Anchored to .authwrap rather than to nav: nav is a flex row whose items
   move as links drop out at the narrow breakpoints, and an absolute child of
   nav itself would be positioned against the whole bar. nav sets no overflow,
   so nothing clips it, and nav's own z-index puts the panel over the hero. */
.authwrap{position:relative; flex:0 0 auto}
.authpop{
  position:absolute; top:calc(100% + 11px); right:0; z-index:20;
  width:min(370px, calc(100vw - 32px));
  animation:pop .13s ease-out;
}
@keyframes pop{from{opacity:0; transform:translateY(-6px)} to{opacity:1; transform:none}}
@media (prefers-reduced-motion:reduce){ .authpop{animation:none} }
.authpop .authcard + .authcard{margin-top:10px}

/* A chip, not a message: the panel can be dismissed, so a signed-in account
   with an unconfirmed address needs something persistent to click back into. */
.alertchip{
  background:rgba(210,153,34,.12); color:#d29922; border:1px solid rgba(210,153,34,.3);
  padding:6px 12px; font-size:12.5px; white-space:nowrap;
}
.alertchip:hover{background:rgba(210,153,34,.2); color:#e5ad33}

.authcard{
  text-align:left;
  box-shadow:0 24px 60px rgba(0,0,0,.5);
  background:var(--card); border:1px solid var(--line); border-radius:12px; padding:22px;
}
.tabs{display:flex; gap:4px; background:#0d1117; border:1px solid var(--line);
  border-radius:8px; padding:4px; margin-bottom:20px}
.tab{
  flex:1; background:none; border:none; color:var(--dim); padding:8px;
  font-size:13.5px; border-radius:6px;
}
.tab.on{background:#232935; color:var(--ink)}
.authcard label{display:flex; flex-direction:column; gap:6px; margin-bottom:14px}
.authcard label span{font-size:11.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--faint)}
.authcard input{
  background:#0a0d12; border:1px solid var(--line); border-radius:7px;
  padding:11px 13px; color:var(--ink); font:inherit; font-size:15px;
}
.authcard input:focus{outline:none; border-color:#3a4557}
.authcard .primary{width:100%; margin-top:4px; padding:12px}
button.wide{width:100%; padding:11px; font-size:14px}
.links{margin:16px 0 0; text-align:center; font-size:13px}
.links a{color:var(--dim); text-decoration:none; border-bottom:1px solid var(--line)}
.links a:hover{color:var(--ink)}
.note{margin:16px 0 0; font-size:13px; color:var(--faint); min-height:18px; text-align:center; line-height:1.6}
.note.err{color:#e5837c}
.note.ok{color:#5fbf75}
.authcard code{
  display:inline-block; margin-top:6px; background:#0a0d12; border:1px solid var(--line);
  border-radius:4px; padding:3px 7px; font-size:11.5px; color:var(--dim); word-break:break-all;
}

/* Terms acceptance. The checkbox label breaks the .authcard label rule
   (column layout, uppercase caption), so it opts out explicitly. */
.agree:not([hidden]){
  display:flex !important; flex-direction:row !important; align-items:flex-start;
  gap:10px; margin:2px 0 16px; cursor:pointer;
}
.agree input{
  width:16px; height:16px; flex:0 0 auto; margin-top:2px; padding:0;
  accent-color:var(--live, #3fb950);
}
.agree span{
  font-size:12.5px !important; letter-spacing:0 !important; text-transform:none !important;
  color:var(--dim); line-height:1.55;
}
.agree a{color:var(--ink); text-decoration:none; border-bottom:1px solid var(--line)}
.agree a:hover{border-color:var(--dim)}
.accept-h{margin:0 0 10px; font-size:16px; color:var(--ink)}
.accept-p{margin:0 0 16px; font-size:13.5px; color:var(--dim); line-height:1.65}

/* On a phone the width cap already does the work: the panel is right-aligned
   to a button that sits ~20px from the edge and is at most 32px narrower than
   the viewport, so it spans the screen with an even margin without being
   pinned to it.

   Deliberately NOT position:fixed here. nav carries backdrop-filter, which
   makes it the containing block for fixed descendants — so "fixed" would
   resolve against the bar rather than the viewport, and would drift the moment
   nav wrapped to two rows. Absolute follows the button, which is what we want.
   The height cap uses svh so an iOS URL bar cannot push the submit button off
   the bottom. */
@media (max-width:560px){
  .authpop{ max-height:calc(100vh - 84px); overflow-y:auto; overscroll-behavior:contain; }
  @supports (height:100svh){ .authpop{max-height:calc(100svh - 84px)} }
}

/* ---------- mobile ----------
   Everything below narrows the shared shell. The ordering matters: 760 is the
   tablet/phone boundary, 560 is where the nav genuinely runs out of room and
   has to start dropping links, 400 is small phones. */

/* iOS Safari zooms the page whenever a focused input's text is under 16px, and
   never zooms back out. Every form on the site was hitting it. */
@media (max-width:760px){
  input,select,textarea,.authcard input{font-size:16px}
  /* Tap targets: a 13px link with no padding is ~18px tall, well under the
     44px Apple and 48px Material both ask for. Padding only, so the nav's
     min-height still governs its own height. */
  nav .navlink{padding:10px 0}
}

@media (max-width:760px){
  nav{gap:14px; padding:0 20px}
  .hero{padding:56px 20px 46px}
  .cards{padding:16px 20px 64px; gap:14px}
  .cards article{padding:22px 20px}
  .how{padding:0 20px 72px}
  footer{padding:20px 20px}
}

/* Narrow phones: the nav was wrapping "My events" and the button onto second
   lines. The events link needs a sign-in anyway, so it is the one to drop. */
@media (max-width:560px){
  nav{gap:10px; padding:0 16px}
  nav .navlink[href="/events"]{display:none}
  nav button{white-space:nowrap}
  .brand span{font-size:11px; letter-spacing:.18em}
  /* Signed in, the nav carries brand + 2 links + address + Sign out, which
     overflowed off the right edge. The button already says you are signed in. */
  nav .navuser{display:none}
  /* The tagline gets its own line rather than squeezing the links off-screen. */
  footer .dim{flex:1 1 100%; order:3}
  footer .spacer{display:none}
}

/* Small phones. The nav is measured, not guessed: at 320px the brand, two
   links and the button come to ~298px inside 12px padding, so it stays on one
   line. flex-wrap above is the safety net if a longer label ever appears. */
@media (max-width:400px){
  h1{font-size:32px}
  .hero{padding:44px 16px 38px}
  .cards{padding:12px 16px 56px}
  .how{padding:0 16px 60px}
  .authcard{padding:20px 18px}
  footer{padding:18px 16px; gap:10px}
  nav{gap:8px; padding:0 12px}
  .brand img{width:20px; height:20px}
  .brand span{font-size:10px; letter-spacing:.14em}
  .navlink{font-size:12.5px}
  button.ghost{padding:6px 11px; font-size:12.5px}
}

/* Page-wide map ground, used on every page except /dashboard — which has a
   real Leaflet map, and a decorative fake one behind it would be worse than
   confusing. Held at .30 opacity: measured, --dim stays 5.55:1 over the
   brightest road, comfortably past AA. The homepage hero uses the same file
   far more assertively, because its copy sits in a scrimmed column. */
.pagebg{position:fixed; inset:0; z-index:-1; pointer-events:none; overflow:hidden}
.pagebg object{
  width:100%; height:100%; display:block; border:0; pointer-events:none; opacity:.40;
  -webkit-mask-image:radial-gradient(150% 128% at 50% 8%, #000 48%, transparent 98%);
  mask-image:radial-gradient(150% 128% at 50% 8%, #000 48%, transparent 98%);
}
/* Only .20 — measured. Anything heavier and the map may as well not be here;
   anything lighter and --faint drops under AA on the brightest road. */
.pagebg::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(to bottom, rgba(10,12,15,.14) 0%, rgba(10,12,15,.20) 46%, rgba(10,12,15,.34) 100%),
    rgba(10,12,15,.20);
}

/* Route into the GroupTrack comparison from the homepage — it is the page most
   likely to be someone's entry point from search, so it needs a way in from
   the one they land on. */
.compare-link{margin:0 0 22px; font-size:14.5px; color:var(--faint)}

/* ---------- screenshots ----------
   Real captures of the live demo, so they are wide, dark-edged images on a
   dark page. A hairline border and a radius keep them from bleeding into the
   background; the caption carries the explanation so the image never has to. */
.shots{max-width:1000px; margin:0 auto; padding:0 26px 96px}
.shots h2{
  font-size:13px; letter-spacing:.2em; text-transform:uppercase; color:var(--faint);
  margin:0 0 14px; font-weight:600;
}
.shots-lede{margin:0 0 40px; color:var(--dim); font-size:15.5px; max-width:620px}
.shots figure{margin:0 0 48px}
.shots img{
  display:block; width:100%; height:auto; border:1px solid var(--line);
  border-radius:11px; background:var(--card);
  box-shadow:0 18px 44px rgba(0,0,0,.45);
}
.shots figcaption{
  margin-top:16px; color:var(--dim); font-size:15px; line-height:1.72; max-width:660px;
}
.shots figcaption b{color:var(--ink); font-weight:600}
/* The phone capture is portrait; at full width it would be a tower. */
.shots figure.narrow img{max-width:300px; margin:0 auto}
.shots figure.narrow figcaption{margin-left:auto; margin-right:auto; text-align:center}
@media (max-width:760px){
  .shots{padding:0 20px 72px}
  .shots figure{margin-bottom:36px}
  .shots figcaption{font-size:14.5px; margin-top:13px}
  .shots figure.narrow img{max-width:250px}
}
