/* ==========================================================================
   APEX base — applies to the authenticated SPA shell (index.html → ls-app).
   Marketing/admin static pages bring their own page-level CSS (marketing.css)
   but share tokens.css.
   ========================================================================== */
* {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
}
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

/* App shell header — sticky, blurred, wordmark left + nav right. */
header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
header h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-hi);
}

/* The nav collapses behind a toggle below --nav-bp. Above it the toggle is
   hidden and the row lays out inline, so the expanded state stops mattering and
   no JS has to watch the viewport. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
}
.nav-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.nav-burger {
  position: relative;
}
.nav-burger,
.nav-burger::before,
.nav-burger::after {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}
.nav-burger::before,
.nav-burger::after {
  content: '';
  position: absolute;
  left: 0;
}
.nav-burger::before {
  top: -6px;
}
.nav-burger::after {
  top: 6px;
}
/* Both nav elements carry a `display` of their own, which would race the UA's
   [hidden] rule. Chromium marks that rule !important so it wins anyway
   (measured), but WebKit has not always, and the target here is iPad Safari.
   Cheap to state outright rather than depend on a UA detail. */
.row[hidden],
.nav-toggle[hidden] {
  display: none;
}

@media (max-width: 640px) {
  header {
    padding: 10px 16px;
  }
  .nav-toggle {
    display: inline-flex;
  }
  .nav-toggle[hidden] {
    display: none;
  }
  /* Measured before this: four 36px buttons wrapped to two rows at 320, 375,
     390 AND 430, giving a 109px sticky header and tap targets under the 44px
     minimum. Dropping to three still wrapped at 320 and 375, so the panel is
     what actually fixes it — full width, one real target each. */
  header [data-nav] {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 8px 16px 12px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
  }
  header [data-nav][data-open] {
    display: flex;
  }
  header [data-nav][hidden] {
    display: none;
  }
  header [data-nav] ls-button,
  header [data-nav] button {
    width: 100%;
    min-height: 44px;
  }
  header [data-nav] button {
    justify-content: flex-start;
  }
}

main {
  max-width: 920px;
  margin: 0 auto;
  padding: 28px 20px 96px;
}

/* An undefined custom element defaults to display:inline, which gives these
   page-level regions no block box of their own. That is not cosmetic: a
   ResizeObserver on an inline element reports a zero-size contentRect and
   effectively never fires, so ls-settings-view's re-scroll after the async
   panels grew silently did nothing and a Billing deep link left you at the top
   of the page. Every entry here is a region wrapping block content. */
ls-app,
ls-auth-view,
ls-billing-locked,
ls-billing-panel,
ls-config-view,
ls-feed-view,
ls-lead-detail-view,
ls-onboarding-view,
ls-security-panel,
ls-settings-view {
  display: block;
}
/* Skip-link target is programmatically focusable (tabindex=-1); no ring. */
#main:focus {
  outline: none;
}

h2,
h3 {
  font-family: var(--font-display);
  color: var(--text-hi);
  letter-spacing: -0.02em;
}

a {
  color: var(--accent);
}

.hidden {
  display: none !important;
}
/* Reaches a screen reader, never the screen. `.hidden` can't do this job —
   display:none removes the text from the accessibility tree too. Needed for
   "ending 4242" beside a masked PAN, and for skeleton status messages.
   (Design-system gap G9 in design/leadsurface/artifacts/README.md.) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* The HTML `hidden` attribute must win even over layout rules like `.row`
   (display:flex) / `.stack`. */
[hidden] {
  display: none !important;
}
.row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
label {
  font-size: 13px;
  color: var(--muted);
}
.auth-wrap {
  max-width: 380px;
  margin: 72px auto;
}

/* Thin accent eyebrow used across SPA section headers. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}

::selection {
  background: rgba(15, 118, 110, 0.35);
  color: #fff;
}

/* Skip link — visually hidden off-screen until focused (keyboard a11y). */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 10px 16px;
  background: var(--panel);
  color: var(--accent);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-weight: 600;
}
.skip-link:focus {
  left: 8px;
  top: 8px;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
