/* ============================================================================
   AI Syndicate site chrome — the top nav and the footer.
   ONE file for the whole site: the React shell (index.html links it) and every
   static page in public/ (each links it in <head>). Self-contained: literal
   colours and fonts, namespaced under .site-nav / .site-footer, so it never
   depends on a page's own variables and nothing else can collide with it.

   Footer layout and motion follow the 21st.dev "Sticky Footer" component
   (Sep 22 2026): the footer is a fixed-height panel (--sf-h) that the page content
   slides up to reveal, clipped to its own box; the brand column and each
   link group blur-in once, staggered. Under 880px the footer is a normal
   in-flow block (a 720px fixed panel would cover a whole phone screen).
   ========================================================================== */

.site-nav, .site-footer {
  --sc-fg: #0a2245;
  --sc-muted: #566d8a;
  --sc-faint: #9eb1c7;
  --sc-rule: #e1e8f0;
  --sc-bg: #ffffff;
  --sc-bg-2: #f5f8fb;
  --sc-accent: #4f46e5;
  --sc-accent-hover: #4338ca;
  --sc-accent-text: #4338ca;
  --sc-font: "Inter", "Inter Fallback", system-ui, -apple-system, sans-serif;
  --sc-display: "Inter Tight", "Inter Tight Fallback", "Inter", system-ui, sans-serif;
  /* The component ships 720px for 4 columns of 14 links. Our six groups run
     ~7 links each, so 720px left 300px of blank panel; 520px keeps the same
     reveal with room to breathe. Raise it if the groups grow. */
  --sf-h: 520px;
  font-family: var(--sc-font);
  color: var(--sc-fg);
  -webkit-font-smoothing: antialiased;
}
.site-nav *, .site-footer * { box-sizing: border-box; }

/* ---------------------------------------------------------------- top nav */
.site-nav {
  position: sticky; top: 0; z-index: 60;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--sc-rule);
}
/* the footer's three light shafts, running through the bar. Clipped to the
   bar, behind the content, never hit-testable. */
.sn-glow { position: absolute; inset: 0; z-index: 0; overflow: hidden; contain: strict; pointer-events: none; }
.sn-glow > div { position: absolute; top: 0; border-radius: 9999px; }
.sn-glow-1 {
  width: 560px; height: 1280px; left: 8%;
  transform: translateY(-620px) rotate(-45deg);
  background: radial-gradient(68.54% 68.72% at 55.02% 31.46%, rgba(10, 34, 69, 0.045) 0, hsla(0, 0%, 55%, 0.02) 50%, rgba(10, 34, 69, 0.01) 80%);
}
.sn-glow-2 {
  width: 240px; height: 1280px; left: 38%;
  translate: 0 -50%; rotate: -45deg;
  background: radial-gradient(50% 50% at 50% 50%, rgba(10, 34, 69, 0.04) 0, rgba(10, 34, 69, 0.01) 80%, transparent 100%);
}
.sn-glow-3 {
  width: 240px; height: 1280px; left: 70%;
  transform: translateY(-620px) rotate(-45deg);
  background: radial-gradient(50% 50% at 50% 50%, rgba(10, 34, 69, 0.04) 0, rgba(10, 34, 69, 0.01) 80%, transparent 100%);
}
.sn-inner {
  position: relative; z-index: 1;
  max-width: 1280px; margin: 0 auto;
  height: 64px; padding: 0 24px;
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 16px;
}
/* the footer's blur-in, on load: logo, then each link, then the buttons, each
   item carrying its own --d. A CSS animation, not a JS-armed transition: it
   plays from the first paint whether the page is static or prerendered-then-
   hydrated, and needs no script — so a blocked script can never leave the bar
   blank. (A JS-armed version was a no-op whenever JS ran after first paint,
   which is the production case on the homepage.) */
.sn-anim {
  /* fill-mode backwards, not both: the end keyframe equals the natural state,
     and "both" would pin a computed blur(0px) filter on every item forever
     (a needless render surface inside a backdrop-filtered sticky header) */
  animation: sn-item-in 1.1s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
  animation-delay: var(--d, 0s);
}
.sn-logo {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--sc-fg); text-decoration: none; white-space: nowrap;
  justify-self: start;
}
.sn-logo .logo-mark, .sn-mark { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sn-mark svg, .sn-logo .logo-mark svg { width: 100%; height: 100%; display: block; }
.sn-wordmark {
  display: inline-flex; align-items: baseline;
  font-family: var(--sc-display); font-weight: 700; font-size: 17px;
  letter-spacing: -0.01em; line-height: 1;
}
.sn-ai { color: var(--sc-accent-text); font-weight: 800; }
.sn-syn { color: var(--sc-fg); font-weight: 700; letter-spacing: 0.02em; }

.sn-links { display: flex; align-items: center; gap: 2px; }
.sn-links a {
  display: inline-flex; align-items: center; height: 36px; padding: 0 12px;
  border-radius: 8px;
  color: var(--sc-muted); text-decoration: none;
  font-size: 14px; font-weight: 500; white-space: nowrap;
  transition: color 0.3s ease, background-color 0.3s ease;
}
.sn-links a:hover { color: var(--sc-fg); background: rgba(10, 34, 69, 0.045); }
.sn-links a.active { color: var(--sc-fg); }
.sn-links a:focus-visible, .sn-btn:focus-visible, .sn-toggle:focus-visible,
.sf-social a:focus-visible, .sf-group a:focus-visible, .sf-bottom a:focus-visible, .ais-motion-toggle:focus-visible {
  outline: 2px solid var(--sc-accent); outline-offset: 2px;
}

.sn-actions { display: flex; align-items: center; gap: 8px; justify-self: end; }
.sn-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px; padding: 0 14px; border-radius: 8px;
  font: inherit; font-size: 14px; font-weight: 500; line-height: 1; white-space: nowrap;
  text-decoration: none; cursor: pointer;
  border: 1px solid transparent;
  transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.sn-btn--outline { background: var(--sc-bg); color: var(--sc-fg); border-color: var(--sc-rule); }
.sn-btn--outline:hover { background: var(--sc-bg-2); border-color: #cdd9e5; }
/* The softer ask, sitting next to the accent Buy now: no border, no fill, so
   the two CTAs read as a clear first and second choice rather than a pair. */
.sn-btn--ghost { background: transparent; color: var(--sc-fg); border-color: transparent; }
.sn-btn--ghost:hover { background: var(--sc-bg-2); color: var(--sc-accent-text); }
.sn-btn--primary { background: var(--sc-accent); color: #fff; box-shadow: 0 1px 2px rgba(10, 34, 69, 0.12); }
.sn-btn--primary:hover { background: var(--sc-accent-hover); }
.sn-btn .arr { display: inline-block; transition: transform 0.3s ease; }
.sn-btn:hover .arr { transform: translateX(2px); }

/* hamburger — hidden on desktop */
.sn-toggle {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0;
  background: var(--sc-bg); border: 1px solid var(--sc-rule); border-radius: 8px;
  color: var(--sc-fg); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.sn-toggle:hover { background: var(--sc-bg-2); }
.sn-toggle-bars, .sn-toggle-bars::before, .sn-toggle-bars::after {
  display: block; width: 18px; height: 2px; border-radius: 2px;
  background: currentColor; transition: transform 0.2s ease, background 0.2s ease;
}
.sn-toggle-bars { position: relative; }
.sn-toggle-bars::before, .sn-toggle-bars::after { content: ""; position: absolute; left: 0; }
.sn-toggle-bars::before { top: -6px; }
.sn-toggle-bars::after { top: 6px; }
.sn-toggle.is-open .sn-toggle-bars, .sn-toggle[aria-expanded="true"] .sn-toggle-bars { background: transparent; }
.sn-toggle.is-open .sn-toggle-bars::before, .sn-toggle[aria-expanded="true"] .sn-toggle-bars::before { transform: translateY(6px) rotate(45deg); }
.sn-toggle.is-open .sn-toggle-bars::after, .sn-toggle[aria-expanded="true"] .sn-toggle-bars::after { transform: translateY(-6px) rotate(-45deg); }

/* mobile panel — sits under the 64px bar. The bar has a backdrop-filter, which
   makes it the containing block for this fixed child, so pin an explicit
   viewport-relative height instead of relying on bottom: 0. */
.sn-mobile {
  display: none;
  position: fixed; top: 64px; left: 0; right: 0;
  height: calc(100vh - 64px); height: calc(100dvh - 64px);
  overflow-y: auto; z-index: 95;
  background: var(--sc-bg);
  flex-direction: column;
  padding: 8px 20px 24px;
  animation: sn-fade-in 0.22s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.sn-mobile a:not(.sn-btn) {
  display: flex; align-items: center; min-height: 52px; padding: 4px 2px;
  color: var(--sc-fg); text-decoration: none;
  font-family: var(--sc-display); font-size: 19px; font-weight: 600;
  border-bottom: 1px solid var(--sc-rule);
}
.sn-mobile a:not(.sn-btn):hover, .sn-mobile a:not(.sn-btn).active { color: var(--sc-accent-text); }
.sn-mobile:not([hidden]) > a, .sn-mobile:not([hidden]) > .sn-mobile-actions {
  animation: sn-item-in 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
  animation-delay: calc(0.05s + var(--i, 0) * 0.07s);
}
@keyframes sn-item-in {
  from { opacity: 0; filter: blur(4px); transform: translateY(-8px); }
  to   { opacity: 1; filter: none;      transform: none; }
}
.sn-mobile-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 20px; }
.sn-mobile-actions .sn-btn { height: 44px; font-size: 15px; }
@keyframes sn-fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* 881–1040px: seven links + two buttons do not fit a 64px row at full size.
   Drop the outline Sign in (it is in the footer and the mobile panel) and
   tighten the links so the primary CTA is never pushed off the edge. */
@media (max-width: 1040px) {
  .sn-inner { padding: 0 16px; gap: 10px; }
  .sn-links a { padding: 0 8px; font-size: 13.5px; }
  .sn-signin { display: none; }
}
@media (max-width: 880px) {
  .sn-inner { grid-template-columns: 1fr auto; padding: 0 16px; }
  .sn-links, .sn-signin { display: none; }
  .sn-toggle { display: inline-flex; }
  .sn-mobile:not([hidden]) { display: flex; }
  .sn-btn--primary.sn-cta { height: 34px; padding: 0 12px; font-size: 13px; }
}
@media (max-width: 380px) { .sn-wordmark { display: none; } }

/* ------------------------------------------------------------------ footer */
.site-footer {
  /* 53 static pages still carry a bare `footer { padding: 80px 0 32px }` in
     their inline CSS; the class selector must win on the box too. */
  padding: 0; margin: 0;
  /* a page whose <body> is a flex column with height:100% (purchase-complete)
     would squash the footer to whatever was left; it must keep its full box */
  flex: none;
  text-align: left; /* a centred page (purchase-complete) must not centre the footer */
  position: relative; width: 100%; height: var(--sf-h);
  clip-path: polygon(0% 0, 100% 0%, 100% 100%, 0 100%);
  background: var(--sc-bg);
}
.sf-fixed { position: fixed; bottom: 0; left: 0; width: 100%; height: var(--sf-h); }
.sf-sticky { position: sticky; top: calc(100vh - var(--sf-h)); height: 100%; overflow-y: auto; }
.sf-body {
  position: relative; width: 100%; height: 100%;
  display: flex; flex-direction: column; justify-content: space-between; gap: 20px;
  border-top: 1px solid var(--sc-rule);
  padding: 32px 48px;
  background: var(--sc-bg);
}
/* the three soft light shafts from the component, in our navy at low alpha */
.sf-glow { position: absolute; inset: 0; z-index: 0; isolation: isolate; contain: strict; overflow: hidden; pointer-events: none; }
.sf-glow > div { position: absolute; top: 0; left: 0; border-radius: 9999px; }
.sf-glow-1 {
  width: 560px; height: 1280px;
  transform: translateY(-350px) rotate(-45deg);
  background: radial-gradient(68.54% 68.72% at 55.02% 31.46%, rgba(10, 34, 69, 0.045) 0, hsla(0, 0%, 55%, 0.02) 50%, rgba(10, 34, 69, 0.01) 80%);
}
.sf-glow-2 {
  width: 240px; height: 1280px;
  translate: 5% -50%; rotate: -45deg;
  background: radial-gradient(50% 50% at 50% 50%, rgba(10, 34, 69, 0.04) 0, rgba(10, 34, 69, 0.01) 80%, transparent 100%);
}
.sf-glow-3 {
  width: 240px; height: 1280px;
  transform: translateY(-350px) rotate(-45deg);
  background: radial-gradient(50% 50% at 50% 50%, rgba(10, 34, 69, 0.04) 0, rgba(10, 34, 69, 0.01) 80%, transparent 100%);
}

.sf-main { position: relative; z-index: 1; margin-top: 40px; display: flex; flex-direction: column; gap: 32px; }
.sf-brand { width: 100%; max-width: 384px; min-width: 288px; display: flex; flex-direction: column; gap: 16px; }
.sf-logo { display: inline-flex; align-items: center; gap: 10px; color: var(--sc-fg); text-decoration: none; width: max-content; }
.sf-logo-mark { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sf-logo-mark svg { width: 100%; height: 100%; display: block; }
.sf-wordmark { display: inline-flex; align-items: baseline; font-family: var(--sc-display); font-weight: 700; font-size: 17px; letter-spacing: -0.01em; line-height: 1; }
.sf-ai { color: var(--sc-accent-text); font-weight: 800; }
.sf-syn { color: var(--sc-fg); font-weight: 700; letter-spacing: 0.02em; }
.sf-brand p { margin: 0; color: var(--sc-muted); font-size: 14px; line-height: 1.55; }
.sf-social { display: flex; gap: 8px; }
.sf-social a {
  width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--sc-rule); border-radius: 8px; background: var(--sc-bg);
  color: var(--sc-fg); text-decoration: none;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.sf-social a:hover { background: var(--sc-bg-2); border-color: #cdd9e5; }
.sf-social svg { width: 16px; height: 16px; }

.sf-groups { flex: 1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px 24px; }
.sf-group h3 {
  margin: 0; font-family: inherit; font-size: 14px; font-weight: 500;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--sc-fg);
}
.sf-group ul { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 14px; }
.sf-group a {
  display: inline-flex; align-items: center;
  color: var(--sc-muted); text-decoration: none;
  transition: color 0.3s ease, transform 0.3s ease;
}
.sf-group a:hover { color: var(--sc-fg); }

.sf-bottom {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 8px;
  border-top: 1px solid var(--sc-rule); padding-top: 8px;
  font-size: 14px; color: var(--sc-muted);
}
.sf-bottom p { margin: 0; }
.sf-bottom a { color: inherit; text-decoration: none; }
.sf-bottom a:hover { color: var(--sc-fg); }
/* "Pause animations" (WCAG 2.2.2) — public/motion-pref.js. A real button styled
   as a footer link; 24px min height for target size (WCAG 2.5.8). */
.ais-motion-toggle {
  appearance: none; background: none; border: 0; padding: 0; min-height: 24px;
  font: inherit; color: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.ais-motion-toggle:hover { color: var(--sc-fg); }
.sf-dot { margin: 0 8px; color: var(--sc-faint); }

/* blur-in reveal (the component's AnimatedContainer). Elements are visible by
   default; JS adds .sf-js to the footer, which arms the hidden start state,
   then .in on each element as it enters the viewport — so no JS = no missing
   footer. Delay: 0.1s for the brand column, +0.15s per group via --d.
   Timing (1.1s, ease-out) is deliberately a touch slower than the component's
   0.8s — Ryder's call, Sep 22 2026; the nav's .sn-anim matches it. */
.sf-js .sf-anim {
  opacity: 0; filter: blur(4px); transform: translateY(-8px);
  transition: opacity 1.1s cubic-bezier(0.22, 0.61, 0.36, 1), filter 1.1s cubic-bezier(0.22, 0.61, 0.36, 1), transform 1.1s cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: var(--d, 0.1s);
}
.sf-js .sf-anim.in { opacity: 1; filter: none; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .sf-js .sf-anim { opacity: 1; filter: none; transform: none; transition: none; }
  .sn-anim, .sn-mobile, .sn-mobile:not([hidden]) > a, .sn-mobile:not([hidden]) > .sn-mobile-actions { animation: none; }
  .sn-btn .arr, .sf-group a { transition: none; }
}

@media (min-width: 768px) {
  .sf-main { flex-direction: row; }
  .sf-bottom { flex-direction: row; }
  .sf-groups { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1100px) {
  .sf-groups { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (min-width: 1280px) {
  .sf-main { margin-top: 0; }
}

/* tablet: the six groups fall into two rows of three, so the panel needs more
   height (content measured at 622px wide-tablet, Sep 22 2026) */
@media (min-width: 881px) and (max-width: 1099px) {
  .site-footer { --sf-h: 700px; }
}

/* small screens — and SHORT screens (tablet landscape, small laptop windows):
   plain in-flow footer, no fixed panel. The panel is --sf-h tall and cannot
   scroll, so if the viewport is shorter than panel + 64px nav the top rows
   would sit behind the nav for good. 780px covers the 700px tablet panel. */
@media (max-width: 880px), (max-height: 780px) {
  .site-footer { height: auto; clip-path: none; }
  .sf-fixed { position: static; height: auto; }
  .sf-sticky { position: static; height: auto; overflow: visible; top: auto; }
  .sf-body { padding: 40px 20px 24px; gap: 40px; }
  .sf-main { margin-top: 0; }
  .sf-brand { min-width: 0; max-width: none; }
  .sf-group h3 { font-size: 13px; }
}

/* ------------------------------------------------- keyboard focus floor
   WCAG 2.4.7 (Focus Visible). Loaded on every page (React shell + all static
   pages), so this is the one place that guarantees a visible keyboard focus
   indicator site-wide: ~55 page-level rules set `outline: none` on summaries,
   custom inputs and cards, and a rule like that silently strips the only cue a
   keyboard user has. :focus-visible only matches keyboard-style focus, so mouse
   clicks on buttons and links are unchanged. Text fields keep their own focus
   styling (border/ring on focus), and programmatic focus targets
   (tabindex="-1", e.g. <main> after the skip link) are left alone. */
:where(a[href], button, summary, select, [tabindex]:not([tabindex="-1"]), [role="button"], [role="tab"], [role="link"], input[type="checkbox"], input[type="radio"]):focus-visible {
  outline: 2px solid #4f46e5 !important;
  outline-offset: 2px !important;
}
