/* ============================================================
   SERGEBOT — shared UI chrome for every page, including the
   self-contained homepage (which does not load site.css):
   mobile nav drawer (nav.js) and its no-JS fallback.
   Load AFTER site.css / the homepage inline <style>. Bump ?v= on change.
   ============================================================ */

/* ---------- Mobile nav drawer ---------- */
.nav-links-cta { display: none; }

html.nav-open,
html.nav-open body { overflow: hidden; }

@media (max-width: 900px) {
  .menu-toggle { width: 44px; height: 44px; flex-shrink: 0; }
  .js .nav-island { position: relative; }

  /* Panel drops below the header bar so the logo and the close (X) stay visible. */
  .js #siteNav {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: 0;
    max-height: calc(100vh - 140px);
    max-height: calc(100dvh - 140px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 12px;
    background: rgba(8, 8, 12, 0.98);
    border: 1px solid var(--line-active);
    border-radius: 20px;
    box-shadow: 0 24px 48px -16px rgba(0, 0, 0, 0.9);
  }
  .js.nav-open #siteNav { display: block; }

  #siteNav .nav-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    width: 100%;
    margin: 0;
    padding: 0;
    border: 0;
  }
  #siteNav .nav-links a {
    display: flex;
    align-items: center;
    min-height: 48px;
    padding: 0 16px;
    border-radius: 12px;
    font-size: 1rem;
    color: var(--text);
  }
  #siteNav .nav-links a:hover,
  #siteNav .nav-links a:focus-visible {
    background: rgba(167, 139, 250, 0.08);
    transform: none;
  }
  #siteNav .nav-links a.active { color: var(--violet-soft); }
  .nav-links-cta { display: block; margin-top: 8px; }
  #siteNav .nav-links-cta .btn { justify-content: center; color: #050508; }

  /* No JS: no drawer. The header joins the page flow and shows the links as a wrapped list. */
  html:not(.js) header { position: relative; top: auto; left: auto; transform: none; margin: 24px auto 0; }
  html:not(.js) .menu-toggle { display: none; }
  html:not(.js) .nav-island { flex-wrap: wrap; border-radius: 20px; }
  html:not(.js) #siteNav { display: block; width: 100%; }
  html:not(.js) #siteNav .nav-links { flex-direction: row; flex-wrap: wrap; gap: 0 4px; padding-top: 8px; }
  html:not(.js) #siteNav .nav-links a { min-height: 44px; padding: 0 10px; font-size: .9rem; }
  html:not(.js) .nav-links-cta { display: none; }
}

/* The 48px wordmark (241px wide) left no room for a 44px toggle on 320-360px screens. */
@media (max-width: 420px) {
  .logo img { height: 36px; }
}

/* ---------- Top-nav Subscribe: subtle accent, must not compete with the CTA ---------- */
.nav-links a.nav-subscribe { color: var(--violet-soft); }
@media (min-width: 901px) {
  .nav-links a.nav-subscribe {
    padding: 4px 11px;
    border: 1px solid var(--line-active);
    border-radius: 999px;
  }
  .nav-links a.nav-subscribe:hover { border-color: var(--violet); color: var(--text); }
}

/* Room for the 7th item: the island is capped at 1000px, so the link gap tightens
   (36px -> 20px) and the CTA never shrinks. Measured: no overflow at 901-1280px. */
@media (min-width: 901px) {
  .nav-links { gap: 20px; }
  .nav-cta { flex-shrink: 0; }
}
@media (min-width: 901px) and (max-width: 1100px) {
  header { width: 96%; }
  .logo img { height: 36px; }
  .nav-links { gap: 14px; }
  .nav-links a { font-size: .85rem; }
}

/* ---------- Subscribe modal (subscribe-modal.js) ---------- */
html.modal-open,
html.modal-open body { overflow: hidden; }

/* From 600px wide subscribe-modal.js only opens the dialog when it fits the viewport (else
   it goes to the Brevo share page). Under 600px it always opens and this overlay scrolls
   when the dialog is taller than the screen (the frame itself never scrolls). */
.sbm-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 24px 16px;
}
.sbm-overlay[hidden] { display: none; }
.sbm-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(5, 5, 8, 0.8);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.sbm-dialog {
  position: relative;
  margin: auto;
  width: 100%;
  max-width: 588px;
  padding: 20px 24px 8px;
  background: #050508;
  border: 1px solid var(--line-active);
  border-radius: 20px;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.9), 0 0 40px -10px rgba(167, 139, 250, 0.25);
}
.sbm-head { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
/* The title row (with the close X) stays pinned while the overlay scrolls (short phones). */
.sbm-head {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 1;
  margin: -20px -24px 0;
  padding: 20px 24px 0;
  border-radius: 20px 20px 0 0;
  background: #050508;
}
.sbm-frame-wrap { display: block; }
/* /blog/#subscribe target (no-JS links, footer links, old shared URLs): land the block top
   24px below the fixed header. --sb-header-bottom is the measured header bottom, set by
   subscribe-modal.js (90-94px at all widths; 94px until it runs). No ring on programmatic focus. */
#subscribe { scroll-margin-top: calc(var(--sb-header-bottom, 94px) + 24px); }
#subscribe[tabindex="-1"]:focus { outline: none; }
.sbm-title { margin: 0; min-width: 0; line-height: 0; }
/* The B logo is the title from 600px up; 24px gap to the X = the brand clear space
   (cap height of SERGEBOT). Under 600px a text title replaces it (see the media query). */
.sbm-logo { display: block; max-width: 100%; height: auto; }
.sbm-title-text {
  display: none;
  font-family: 'Sora', sans-serif;
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--text);
}
/* #A78BFA on #050508: 7.5:1 contrast (AA for normal-size text). */
.sbm-title-accent { color: #A78BFA; }
@media (max-width: 599px) {
  .sbm-logo { display: none; }
  .sbm-title-text { display: block; }
}
.sbm-close {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line-active);
  background: transparent;
  color: var(--text);
  font-size: 1.05rem;
  cursor: pointer;
}
.sbm-close:hover { border-color: var(--violet); }
.sbm-close:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.sbm-lead {
  margin: 10px 0 0;
  font-family: 'Sora', sans-serif;
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--text);
}
.sbm-line { margin: 6px 0 0; color: var(--muted); font-size: 0.92rem; line-height: 1.5; }
.sbm-copy { margin: 6px 0 10px; color: var(--muted); font-size: 0.85rem; line-height: 1.5; }
/* No inner scrollbar: fixed heights = the taller of Brevo's error and success states
   + >=50px. Swept 2026-10-09 18:07-18:10 (UTC+2) on the trimmed card (email field and
   button only), tallest state bottom by frame width: 376 (>=509w), 406 (500w),
   418 (380-480w), 434 (310-364w), 452 (280-300w), 474 (270w), 490 (264w).
   Error is the taller state at every width (success 332-414). */
.sbm-frame {
  display: block;
  width: 100%;
  max-width: 540px;
  height: 426px;
  margin: 0 auto;
  border: 0;
  overflow: hidden;
}
@media (max-width: 600px) {
  /* Phones: tighter chrome and type so the dialog fits 740px-tall screens without
     scrolling; shorter ones scroll the overlay. The frame heights (error/success headroom)
     are not traded for it. */
  .sbm-overlay { padding: 8px; }
  .sbm-dialog { padding: 12px 14px 4px; }
  .sbm-head { margin: -12px -14px 0; padding: 12px 14px 0; }
  .sbm-lead { margin-top: 8px; font-size: 1rem; }
  .sbm-line { margin-top: 4px; font-size: 0.875rem; line-height: 1.45; }
  .sbm-copy { margin: 4px 0 8px; font-size: 0.8rem; line-height: 1.45; }
  .sbm-frame { height: 468px; }
}
/* Phone frame width = viewport - 46px; breakpoints follow the sweep bands above. */
@media (max-width: 425px) {
  .sbm-frame { height: 484px; }
}
@media (max-width: 355px) {
  .sbm-frame { height: 502px; }
}
@media (max-width: 325px) {
  .sbm-frame { height: 524px; }
}
@media (max-width: 315px) {
  .sbm-frame { height: 540px; }
}
/* Wide screens: copy beside the form, so the dialog fits 768px-tall laptop viewports
   (stacked it needs ~800px). Reading order is unchanged: logo, Line 1, Line 2, subhead, form.
   The 510px frame column keeps Brevo in its widest (shortest) layout. */
@media (min-width: 960px) {
  .sbm-dialog {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 510px;
    /* The three copy rows stay at their own height; the spare height of the tall frame
       (sized for Brevo's error/success states) goes to an empty last row, so the blank space
       sits under both columns instead of spreading the copy apart. */
    grid-template-rows: auto auto auto auto 1fr;
    column-gap: 32px;
    align-items: start;
    max-width: 900px;
  }
  .sbm-head { grid-column: 1 / -1; }
  .sbm-lead, .sbm-line, .sbm-copy { grid-column: 1; }
  .sbm-lead { margin-top: 16px; }
  .sbm-frame-wrap { grid-column: 2; grid-row: 2 / -1; }
}
