/* ==========================================================================
   STREETO UI SYSTEM 1.0
   --------------------------------------------------------------------------
   One contract for every page, browser and the future iOS shell.

   Loaded after style.css. This file does not invent a second look: it turns
   the parts we already use into named tokens and keeps pages on the same
   grid. New UI should use these tokens and components instead of one-off
   pixel values.

   Rules in short:
   - Page width: .shell (1280) / .single (760) / .single--narrow (720).
   - Page header: .pagehead > .pagehead__main (+ optional actions).
   - Actions: .btn + one variant; icon actions: .iconbtn.
   - People: always include partials/avatar.ejs; only the named sizes.
   - Text: never set a fixed height around copy; let it wrap.
   - Mobile: test 390x844; nothing may scroll sideways or sit under the
     fixed menu / chat buttons at the end of a page.
   ========================================================================== */

:root {
  /* spacing, on a 4px grid */
  --ui-space-1: 4px;
  --ui-space-2: 8px;
  --ui-space-3: 12px;
  --ui-space-4: 16px;
  --ui-space-5: 20px;
  --ui-space-6: 24px;
  --ui-space-8: 32px;
  --ui-space-10: 40px;
  --ui-space-14: 56px;

  /* controls */
  --ui-control-sm: 30px;
  --ui-control-md: 36px;
  --ui-control-lg: 44px;
  --ui-control-icon: 36px;
  --ui-control-icon-ghost: 32px;

  /* radii */
  --ui-radius-pill: 999px;
  --ui-radius-control: 12px;
  --ui-radius-card: 16px;
  --ui-radius-sheet: 20px;

  /* avatars */
  --ui-avatar-xs: 26px;
  --ui-avatar-sm: 36px;
  --ui-avatar-md: 46px;
  --ui-avatar-lg: 76px;
  --ui-avatar-xl: 104px;

  /* page */
  --ui-page: 1280px;
  --ui-content: 760px;
  --ui-content-narrow: 720px;
  --ui-gutter: clamp(12px, 4vw, 22px);
  --ui-tabbar: 64px;

  /* safe areas: iOS notch / home indicator and Android gesture bar */
  --ui-safe-top: env(safe-area-inset-top, 0px);
  --ui-safe-right: env(safe-area-inset-right, 0px);
  --ui-safe-bottom: env(safe-area-inset-bottom, 0px);
  --ui-safe-left: env(safe-area-inset-left, 0px);
}

/* --------------------------------------------------------------------------
   Page + text placement
   -------------------------------------------------------------------------- */

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  overflow-wrap: break-word;
}

.shell,
.layout-shell,
.single,
.single--narrow {
  min-width: 0;
}

.single,
.single--narrow {
  width: 100%;
}

/* The page header is always one text block, never loose siblings. */
.pagehead {
  align-items: flex-start;
  row-gap: var(--ui-space-3);
}

.pagehead__main {
  flex: 1 1 320px;
  min-width: 0;
}

.pagehead__main > * {
  max-width: 100%;
}

.pagehead .lede {
  max-width: 72ch;
  overflow-wrap: anywhere;
}

/* Guard older direct-child headers as well. */
.pagehead > .eyebrow,
.pagehead > .display,
.pagehead > .lede {
  flex: 1 1 100%;
}

.pagehead__actions,
.pagehead .btnrow {
  flex: 0 0 auto;
  flex-wrap: wrap;
  row-gap: var(--ui-space-2);
}

/* Older pages put a single .btn / form directly in the header. Keep that
   shape usable, but align it like a proper header action. */
.pagehead > .btn,
.pagehead > .btnrow,
.pagehead > form {
  flex: 0 0 auto;
  margin-left: auto;
}

@media (max-width: 860px) {
  .pagehead__main {
    flex-basis: 100%;
  }

  .pagehead__actions,
  .pagehead .btnrow {
    width: 100%;
    justify-content: flex-end;
    margin-left: 0;
  }

  .pagehead > .btn,
  .pagehead > form {
    align-self: flex-end;
  }

  .pagehead > .btnrow {
    align-self: stretch;
    justify-content: flex-end;
  }
}

/* Copy must be allowed to wrap; a fixed height is a bug waiting to happen. */
.display,
.section-title,
.card__title,
.lede,
.row__id,
.row__id > span,
.field__hint {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  height: auto;
  min-height: var(--ui-control-md);
  max-width: 100%;
  padding: 0 var(--ui-space-4);
  border-radius: var(--ui-radius-pill);
  line-height: 1.15;
  text-align: center;
}

.btn--secondary {
  --btn-bg: rgba(var(--veil), 0.06);
  --btn-bd: var(--line-strong);
  --btn-fg: var(--text);
}

.btn--secondary:hover {
  --btn-bd: rgba(var(--neon-rgb), 0.4);
  background: rgba(var(--neon-rgb), 0.08);
  color: var(--neon);
}

.btn--sm {
  min-height: var(--ui-control-sm);
  padding: 0 var(--ui-space-3);
}

.btn--lg {
  min-height: var(--ui-control-lg);
  padding: 0 var(--ui-space-5);
}

.btn--icon {
  width: var(--ui-control-md);
  min-width: var(--ui-control-md);
  padding: 0;
}

.btn--icon.btn--sm {
  width: var(--ui-control-sm);
  min-width: var(--ui-control-sm);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

.iconbtn {
  width: var(--ui-control-icon);
  height: var(--ui-control-icon);
}

.iconbtn--ghost {
  width: var(--ui-control-icon-ghost);
  height: var(--ui-control-icon-ghost);
}

/* Touch targets are governed by the control sizes; do not add pseudo
   elements outside the control, because they enlarge scrollWidth and make
   dense rows overlap. */

.btnrow {
  align-items: center;
  gap: var(--ui-space-2);
}

/* The Explore tab is the single hub for every section on both desktop and
   mobile. Six equal entries keep the same order everywhere and replace the
   old, easy-to-miss row of pills. */
.explore-hub {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--ui-space-3);
  margin: var(--ui-space-5) 0 var(--ui-space-6);
}

.explore-hub__item {
  display: flex;
  align-items: center;
  gap: var(--ui-space-3);
  min-height: 64px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--ui-radius-card);
  background:
    linear-gradient(135deg, rgba(var(--neon-rgb), 0.06), transparent 55%),
    rgba(var(--veil), 0.025);
  color: var(--text);
  font-family: var(--font-head);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-decoration: none;
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease), transform 0.15s var(--ease);
}

.explore-hub__item:hover,
.explore-hub__item:focus-visible {
  border-color: rgba(var(--neon-rgb), 0.5);
  background:
    linear-gradient(135deg, rgba(var(--neon-rgb), 0.13), transparent 60%),
    rgba(var(--veil), 0.04);
  transform: translateY(-1px);
}

.explore-hub__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border: 1px solid rgba(var(--neon-rgb), 0.25);
  border-radius: 10px;
  background: rgba(var(--neon-rgb), 0.08);
  color: var(--neon);
}

.explore-hub__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Underground keeps its red night identity even inside the normal hub. */
.explore-hub__item--underground {
  border-color: rgba(255, 59, 77, 0.3);
  background:
    linear-gradient(135deg, rgba(255, 59, 77, 0.1), transparent 60%),
    rgba(var(--veil), 0.025);
}
.explore-hub__item--underground .explore-hub__icon {
  border-color: rgba(255, 59, 77, 0.35);
  background: rgba(255, 59, 77, 0.1);
  color: #ff3b4d;
}

@media (max-width: 860px) {
  .explore-hub {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--ui-space-2);
    margin: var(--ui-space-4) 0 var(--ui-space-5);
  }

  .explore-hub__item {
    min-height: 54px;
    padding: 9px 10px;
    font-size: 11.5px;
    gap: 9px;
  }

  .explore-hub__icon {
    width: 30px;
    height: 30px;
    border-radius: 8px;
  }
}

/* --------------------------------------------------------------------------
   Avatars
   -------------------------------------------------------------------------- */

.avatar {
  aspect-ratio: 1 / 1;
  min-width: var(--size);
  object-fit: cover;
  object-position: center;
}

.avatar > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

.avatar--gen {
  line-height: 1;
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.field {
  min-width: 0;
}

.installhero {
  display: flex;
  align-items: center;
  gap: var(--ui-space-4);
}

.installhero__icon {
  flex: 0 0 auto;
  width: 96px;
  height: 96px;
  border-radius: 22px;
  border: 1px solid var(--line);
}

.installhero__body {
  min-width: 0;
  flex: 1;
}

.installgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--ui-space-4);
  margin-top: var(--ui-space-4);
}

.installsteps__list {
  display: grid;
  gap: var(--ui-space-3);
  margin: var(--ui-space-3) 0;
  padding: 0;
  list-style: none;
}

.installsteps__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--ui-space-3);
  color: var(--text-dim);
  line-height: 1.45;
}

.installsteps__n {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(var(--neon-rgb), 0.12);
  color: var(--neon);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
}

.installnote {
  margin-top: var(--ui-space-4);
}

@media (max-width: 620px) {
  .installhero {
    align-items: flex-start;
    flex-direction: column;
  }

  .installhero__icon {
    width: 76px;
    height: 76px;
  }
}

.nearform {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--ui-space-3);
  padding: var(--ui-space-4);
}

.nearform__city {
  flex: 1 1 280px;
}

.nearform__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ui-space-2);
}

.nearform > .small {
  flex-basis: 100%;
  margin: 0;
}

.notifprefs {
  margin-top: var(--ui-space-4);
  padding-top: var(--ui-space-4);
  border-top: 1px solid var(--line-soft);
}

.notifprefs fieldset {
  border: 0;
  padding: 0;
  margin: 0;
}

.notifprefs .check {
  margin-top: var(--ui-space-2);
}

.notifprefs > .btn {
  margin-top: var(--ui-space-3);
  width: 100%;
  height: auto;
  padding-top: 8px;
  padding-bottom: 8px;
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: center;
  line-height: 1.25;
}

.field input,
.field textarea,
.field select,
.form-grid input,
.form-grid textarea,
.form-grid select {
  max-width: 100%;
}

/* The mobile form rule makes every control full-width. A checkbox or radio
   is a control too, but it must stay a checkbox: iOS/Safari otherwise grows
   it to the whole card. The label remains the large tap target. */
.check input[type="checkbox"],
.check input[type="radio"],
.choice input[type="checkbox"],
.choice input[type="radio"],
.field input[type="checkbox"],
.field input[type="radio"],
.form-grid input[type="checkbox"],
.form-grid input[type="radio"] {
  width: 18px;
  height: 18px;
  min-width: 18px;
  max-width: 18px;
  flex: 0 0 auto;
  padding: 0;
  border-radius: 4px;
  accent-color: var(--neon);
  vertical-align: middle;
}

/* --------------------------------------------------------------------------
   Fixed UI and safe areas
   -------------------------------------------------------------------------- */

.topbar {
  padding-top: var(--ui-safe-top);
}

.appmenu__trigger {
  bottom: calc(var(--ui-space-4) + var(--ui-safe-bottom));
  left: calc(var(--ui-space-4) + var(--ui-safe-left));
}

/* --------------------------------------------------------------------------
   Installed PWA launch screen
   --------------------------------------------------------------------------
   Mirrors the Android splash: mark, wordmark, neon line, site name, then a
   short fade. It is markup + CSS, so iOS/PWA gets the same launch feeling as
   the native WebView. Only `html.pwa-booting` (set in <head>) shows it. */
.pwa-splash {
  display: none;
}

html.pwa-booting .pwa-splash {
  position: fixed;
  inset: 0;
  z-index: 5000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: max(24px, calc(var(--ui-safe-top) + 24px)) 24px
    max(42px, calc(var(--ui-safe-bottom) + 42px));
  background:
    radial-gradient(70% 54% at 50% 44%, rgba(104, 24, 46, 0.3), transparent 70%),
    var(--bg);
  color: var(--text);
  pointer-events: auto;
}

html.pwa-booting,
html.pwa-booting body {
  overflow: hidden;
}

.pwa-splash__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.pwa-splash__mark {
  width: 132px;
  height: 132px;
  object-fit: contain;
  opacity: 0;
  transform: scale(0.82);
  animation: pwaSplashMark 650ms cubic-bezier(0.34, 1.56, 0.64, 1) 20ms forwards;
}

.pwa-splash__word {
  margin-top: 16px;
  font-family: var(--font-head);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.24em;
  line-height: 1;
  opacity: 0;
  transform: translateY(12px);
  animation: pwaSplashText 520ms var(--ease) 220ms forwards;
}

.pwa-splash__line {
  display: block;
  width: 58px;
  height: 2px;
  margin-top: 12px;
  border-radius: 2px;
  background: var(--neon);
  opacity: 0;
  transform: scaleX(0);
  animation:
    pwaSplashLine 520ms var(--ease) 460ms forwards,
    pwaSplashPulse 1100ms ease-in-out 1200ms infinite alternate;
}

.pwa-splash__site {
  position: absolute;
  bottom: max(56px, calc(var(--ui-safe-bottom) + 28px));
  font-family: var(--font-head);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--dim);
  opacity: 0;
  transform: translateY(8px);
  animation: pwaSplashText 460ms var(--ease) 680ms forwards;
}

html.pwa-ready .pwa-splash {
  animation: pwaSplashOut 320ms ease forwards;
}

@keyframes pwaSplashMark {
  to { opacity: 1; transform: scale(1); }
}
@keyframes pwaSplashText {
  to { opacity: 1; transform: translateY(0); }
}
@keyframes pwaSplashLine {
  to { opacity: 1; transform: scaleX(1); }
}
@keyframes pwaSplashPulse {
  from { opacity: 0.3; }
  to { opacity: 1; }
}
@keyframes pwaSplashOut {
  to { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  html.pwa-booting .pwa-splash,
  html.pwa-booting .pwa-splash * {
    animation: none !important;
  }
  html.pwa-booting .pwa-splash * {
    opacity: 1;
    transform: none;
  }
}

/* Mobile tab bar: shared by the PWA, iOS Home Screen app and Android WebView. */
.tabbar {
  display: none;
}

.tabbar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  min-height: 52px;
  color: var(--muted);
  text-decoration: none;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.tabbar__item.is-active {
  color: var(--neon);
}

.tabbar__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 26px;
  height: 24px;
}

.tabbar__badge {
  position: absolute;
  top: -5px;
  right: -8px;
}

.tabbar__label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 860px) {
  .tabbar {
    position: fixed;
    z-index: 70;
    left: 0;
    right: 0;
    bottom: 0;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    height: calc(var(--ui-tabbar) + var(--ui-safe-bottom));
    padding: 4px 4px var(--ui-safe-bottom);
    border-top: 1px solid var(--line);
    background: rgba(var(--panel-scrim), 0.97);
    backdrop-filter: blur(20px) saturate(1.2);
    box-shadow: 0 -12px 30px -24px #000;
  }

  .tabbar__item {
    border-radius: 10px;
  }

  .tabbar__item:active {
    background: rgba(var(--neon-rgb), 0.08);
  }

  .appmenu__trigger,
  .chatdock__launcher {
    display: none !important;
  }

  .chatdock {
    bottom: calc(var(--ui-tabbar) + var(--ui-space-2) + var(--kb) + var(--ui-safe-bottom));
  }

  .notif-prompt {
    bottom: calc(var(--ui-tabbar) + var(--ui-space-4) + var(--ui-safe-bottom));
  }

  .update-banner {
    bottom: calc(var(--ui-tabbar) + var(--ui-space-2) + var(--ui-safe-bottom));
  }

  body[data-authed="1"] .shell {
    padding-bottom: calc(var(--ui-tabbar) + var(--ui-space-6) + var(--ui-safe-bottom));
  }
}

/* A standalone PWA and the Android WebView both get the full app treatment. */
html.is-standalone .install-prompt {
  display: none;
}

.chatdock {
  right: calc(var(--ui-space-4) + var(--ui-safe-right));
  bottom: calc(var(--ui-space-4) + var(--kb) + var(--ui-safe-bottom));
}

.notif-prompt {
  bottom: calc(88px + var(--ui-safe-bottom));
}

/* The top bar carries one notification bell, the account menu and the
   language/currency switches. Chat and Meetups live in the menus and the
   floating chat launcher, so no extra icons are needed on small screens. */

@media (max-width: 620px) {
  .notif-prompt {
    bottom: calc(82px + var(--ui-safe-bottom));
  }
}

@media (max-width: 380px) {
  /* The privacy note is information, not a column: let it take its own
     line instead of squeezing into a 50 px strip beside the picker. */
  .composer__scope {
    flex-wrap: wrap;
    row-gap: 4px;
  }

  .composer__scope [data-privacy-note] {
    flex-basis: 100%;
  }
}

.footer {
  padding-bottom: calc(96px + var(--ui-safe-bottom));
}

/* Keyboard focus must always be visible, for desktop and assistive tech. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--neon);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   Internal style guide
   -------------------------------------------------------------------------- */

.share-card-toast {
  position: fixed;
  left: 50%;
  bottom: calc(88px + var(--ui-safe-bottom));
  z-index: 120;
  transform: translateX(-50%);
  max-width: calc(100vw - 32px);
  padding: 10px 16px;
  border: 1px solid rgba(var(--neon-rgb), 0.35);
  border-radius: var(--ui-radius-pill);
  background: rgba(var(--panel-scrim), 0.96);
  color: var(--text);
  font-size: 12.5px;
  box-shadow: var(--shadow-sm);
}

.sg-section {
  margin-top: var(--ui-space-6);
}

.sg-section h2 {
  margin-bottom: var(--ui-space-3);
}

.sg-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--ui-space-4);
}

.sg-demo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ui-space-2);
  padding: var(--ui-space-4);
  border: 1px dashed var(--line);
  border-radius: var(--ui-radius-control);
}

.sg-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

.sg-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--ui-space-2);
}

.sg-swatch {
  min-height: 64px;
  padding: var(--ui-space-2);
  border: 1px solid var(--line);
  border-radius: var(--ui-radius-control);
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text);
}

.sg-swatch--neon { background: var(--neon); color: var(--on-accent); }
.sg-swatch--panel { background: var(--panel); }
.sg-swatch--bg { background: var(--bg); }
.sg-swatch--danger { background: var(--danger); color: #120202; }

.sg-rules {
  display: grid;
  gap: var(--ui-space-2);
  padding-left: 20px;
  color: var(--text-dim);
  line-height: 1.55;
}

.sg-rules li::marker {
  color: var(--neon);
}

@media (max-width: 620px) {
  .sg-demo {
    padding: var(--ui-space-3);
  }
}
