/* Shared chrome for every page on the site: the colour tokens (light and
   dark), the page base, the layout wrapper, the promo banner, the nav with
   its theme toggle and mobile drawer, and the footer.

   Each page links this before its own <style>, so page rules still win on a
   tie. Colours come from the tokens, never fixed light values, so everything
   here also works in dark mode. The theme itself is set by /site/theme.js
   before first paint and switched by the toggle in /site/site.js. */

:root {
  color-scheme: light;
  --ink: #111311;
  --muted: #5c6359;
  --panel: rgba(var(--paper-rgb), 0.56);
  --blue: #0581fe;
  --orange: #f54d25;
  --acid: #4d7c0f;
  --line: rgba(var(--ink-rgb), 0.14);
  /* surfaces, ink as channels (for alpha), and text on ink or acid fills */
  --paper: #ffffff;
  --ink-rgb: 17, 19, 17;
  --paper-rgb: 255, 255, 255;
  --on-ink: #ffffff;
  --on-acid: #ffffff;
  --max: 1160px;
  /* Height of the promo banner. No banner is running, so it is 0;
     set it back to 48px (38px under 920px) when one returns. */
  --banner-h: 0px;
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --font:
    "Inter", "SF Pro Display", "Segoe UI", Roboto, Helvetica, Arial,
    sans-serif;
  --mono:
    "SFMono-Regular", "SF Mono", Consolas, "Liberation Mono", monospace;
}

/* Dark mode. /site/theme.js sets data-theme on <html> before first
   paint: the visitor's saved choice, else the system setting. The nav
   toggle switches it and saves the choice. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ink: #e8ebe4;
  --muted: #a3ab9e;
  --panel: rgba(28, 31, 28, 0.6);
  --blue: #3a97ff;
  --orange: #ff6b47;
  --acid: #9ccf4f;
  --line: rgba(232, 235, 228, 0.14);
  --paper: #151715;
  --ink-rgb: 232, 235, 228;
  --paper-rgb: 21, 23, 21;
  --on-ink: #111311;
  --on-acid: #111311;
}

/* ---------- Base ---------- */

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
  background: var(--paper);
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  margin: 0;
  overflow-x: hidden;
  font-family: var(--font);
  color: var(--ink);
  background: transparent;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
}

/* Background: soft brand-color glows plus a fine dot grid that fades
   out down the screen. Fixed and static; sits behind all content. */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

body::before {
  background:
    radial-gradient(55% 45% at 0% 0%, rgba(5, 129, 254, 0.13), transparent 70%),
    radial-gradient(45% 40% at 100% 35%, rgba(245, 77, 37, 0.09), transparent 70%),
    radial-gradient(60% 45% at 40% 105%, rgba(77, 124, 15, 0.08), transparent 70%);
}

body::after {
  background-image: radial-gradient(rgba(var(--ink-rgb), 0.16) 1px, transparent 1.4px);
  background-size: 22px 22px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.35) 55%, transparent 90%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.35) 55%, transparent 90%);
}

::selection {
  background: var(--acid);
  color: var(--on-acid);
}

/* ---------- Layout ---------- */

.shell {
  position: relative;
  z-index: 2;
  padding-top: calc(clamp(80px, 9vh, 96px) + var(--banner-h));
}

.wrap {
  width: min(100%, var(--max));
  margin: 0 auto;
  padding: 0 clamp(18px, 4vw, 42px);
}

/* ---------- Promo banner ---------- */

.promo {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  height: var(--banner-h);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 clamp(38px, 6vw, 54px);
  background: #d2f36b;
  font-family: var(--font);
  font-size: 14px;
  color: #111311;
  /* A fixed lime strip with dark type in both themes, so the tokens its
     button and close control read stay on their light values here. */
  --ink-rgb: 17, 19, 17;
  --paper-rgb: 255, 255, 255;
}

.promo[hidden] {
  display: none;
}

.promo p {
  margin: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 12px;
  line-height: 1.2;
}

.promo b {
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.promo-btn {
  margin-left: 8px;
  padding: 7px 14px;
  border-radius: 8px;
  background: rgba(var(--paper-rgb), 0.6);
  color: #111311;
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.24s var(--ease);
}

.promo-btn:hover {
  background: rgba(var(--paper-rgb), 0.9);
}

.promo-close {
  position: absolute;
  right: clamp(8px, 2vw, 16px);
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(var(--ink-rgb), 0.6);
  font-family: inherit;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  transition:
    background 0.24s var(--ease),
    color 0.24s var(--ease);
}

.promo-close:hover {
  background: rgba(var(--ink-rgb), 0.08);
  color: #111311;
}

/* ---------- Navigation ---------- */

.nav {
  position: fixed;
  top: var(--banner-h);
  left: 0;
  right: 0;
  z-index: 20;
  border-bottom: 1px solid transparent;
  transition:
    background 0.32s var(--ease),
    border-color 0.32s var(--ease);
}

/* The bar's blur lives on a pseudo-element: a backdrop-filter on .nav
   itself would make it the containing block for the fixed-position
   mobile drawer, clipping the drawer to the bar once scrolled. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: transparent;
  transition: background 0.32s var(--ease);
}

.nav.is-scrolled::before {
  background: rgba(var(--paper-rgb), 0.82);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.nav.is-scrolled {
  border-bottom-color: var(--line);
}

.nav-inner {
  width: min(100%, var(--max));
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px clamp(18px, 4vw, 42px);
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(var(--ink-rgb), 0.86);
  text-decoration: none;
}

.mark svg {
  width: 40px;
  height: 40px;
  flex: none;
  transition: transform 0.5s var(--ease);
}

.mark:hover svg {
  transform: rotate(180deg);
}

.nav-menu {
  display: flex;
  align-items: center;
  gap: 18px;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-links a,
.nav-links button {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 13px;
  border: 1px solid transparent;
  background: none;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(var(--ink-rgb), 0.68);
  text-decoration: none;
  cursor: pointer;
  transition:
    color 0.22s var(--ease),
    border-color 0.22s var(--ease),
    background 0.22s var(--ease);
}

.nav-links a:hover,
.nav-links button:hover,
.nav-item.open > button {
  color: var(--ink);
  border-color: var(--line);
  background: rgba(var(--ink-rgb), 0.05);
}

.nav-links a:focus-visible,
.nav-links button:focus-visible {
  outline: 2px solid var(--acid);
  outline-offset: 2px;
}

/* The current page's link, e.g. Blog on the blog pages. After :hover so it
   keeps its colour under the pointer. */
.nav-links a[aria-current="page"] {
  color: var(--acid);
}

.nav-item {
  position: relative;
}

.caret {
  width: 8px;
  height: 8px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform 0.28s var(--ease);
}

.nav-item.open .caret {
  transform: rotate(225deg) translateY(-2px);
}

.dropdown {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  min-width: 268px;
  padding: 8px;
  border: 1px solid var(--line);
  background: rgba(var(--paper-rgb), 0.94);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow:
    8px 8px 0 rgba(5, 129, 254, 0.22),
    -8px 8px 0 rgba(245, 77, 37, 0.16);
  opacity: 0;
  transform: translateY(-8px);
  visibility: hidden;
  transition:
    opacity 0.26s var(--ease),
    transform 0.26s var(--ease),
    visibility 0.26s;
}

.nav-item.open .dropdown {
  opacity: 1;
  transform: none;
  visibility: visible;
}

.dropdown a {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  width: 100%;
  padding: 12px 13px;
  text-transform: none;
  letter-spacing: 0;
}

.dropdown a strong {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 650;
  letter-spacing: 0;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.dropdown a small {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(var(--ink-rgb), 0.5);
}

.dropdown a:hover small {
  color: rgba(var(--ink-rgb), 0.72);
}

.dot-b,
.dot-o,
.dot-a {
  width: 7px;
  height: 7px;
  flex: none;
}

.dot-b {
  background: var(--blue);
}

.dot-o {
  background: var(--orange);
}

.dot-a {
  background: var(--acid);
}

.nav-auth {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 18px;
  border: 1px solid rgba(var(--ink-rgb), 0.84);
  border-radius: 999px;
  background: rgba(var(--ink-rgb), 0.95);
  color: var(--on-ink);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  text-decoration: none;
  box-shadow:
    4px 4px 0 rgba(5, 129, 254, 0.72),
    -4px -4px 0 rgba(245, 77, 37, 0.66);
  transition:
    transform 0.24s var(--ease),
    box-shadow 0.24s var(--ease);
}

.nav-cta:hover {
  transform: translate(-1px, -1px);
  box-shadow:
    6px 6px 0 rgba(5, 129, 254, 0.78),
    -6px -6px 0 rgba(245, 77, 37, 0.72);
}

.nav-cta:focus-visible {
  outline: 3px solid var(--acid);
  outline-offset: 4px;
}

/* Light mode: Start free is a pale green pill with dark-green text and
   softer offset shadows; near-black was too loud against the white bar.
   Dark mode keeps the light pill above. */
:root:not([data-theme="dark"]) .nav-cta:not(.is-user) {
  background: #e9f1dc;
  border-color: color-mix(in srgb, var(--acid) 45%, transparent);
  color: #2f4d09;
  box-shadow:
    3px 3px 0 rgba(5, 129, 254, 0.45),
    -3px -3px 0 rgba(245, 77, 37, 0.4);
}

:root:not([data-theme="dark"]) .nav-cta:not(.is-user):hover {
  box-shadow:
    5px 5px 0 rgba(5, 129, 254, 0.6),
    -5px -5px 0 rgba(245, 77, 37, 0.55);
}

/* Signed in (set by ssoCheck in site.js): the pill turns into a quiet
   chip with the visitor's name and a green status dot. Being signed in is
   a state, not a call to action, so the brand offset shadows sit at about
   a third strength and come up to full on hover. */
.nav-cta.is-user {
  max-width: 260px;
  background: var(--paper);
  border-color: rgba(var(--ink-rgb), 0.45);
  color: var(--ink);
  box-shadow:
    3px 3px 0 rgba(5, 129, 254, 0.28),
    -3px -3px 0 rgba(245, 77, 37, 0.24);
}

.nav-cta.is-user:hover {
  border-color: rgba(var(--ink-rgb), 0.45);
  box-shadow:
    4px 4px 0 rgba(5, 129, 254, 0.6),
    -4px -4px 0 rgba(245, 77, 37, 0.55);
}

.nav-cta.is-user::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--acid);
  box-shadow: 0 0 8px color-mix(in srgb, var(--acid) 60%, transparent);
}

.nav-cta-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-burger {
  display: none;
  appearance: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 42px;
  height: 42px;
  padding: 10px;
  border: 1px solid var(--line);
  background: var(--panel);
  cursor: pointer;
}

.nav-burger span {
  display: block;
  height: 2px;
  background: var(--ink);
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}

.nav.menu-open .nav-burger span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav.menu-open .nav-burger span:nth-child(2) {
  opacity: 0;
}

.nav.menu-open .nav-burger span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Theme toggle: top right of the nav (left of the menu button on
   phones). Shows the moon in light mode and the sun in dark. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(var(--paper-rgb), 0.7);
  color: var(--ink);
  cursor: pointer;
  transition:
    border-color 0.2s var(--ease),
    transform 0.3s var(--ease);
}

.theme-toggle:hover {
  border-color: rgba(var(--ink-rgb), 0.4);
  transform: rotate(-20deg);
}

.theme-toggle:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

.theme-toggle svg {
  width: 18px;
  height: 18px;
}

.theme-toggle .sun,
:root[data-theme="dark"] .theme-toggle .moon {
  display: none;
}

:root[data-theme="dark"] .theme-toggle .sun {
  display: block;
}

/* ---------- Footer ---------- */

.footerline {
  width: min(100%, var(--max));
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 26px clamp(18px, 4vw, 42px) 30px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(var(--ink-rgb), 0.68);
}

.footerline .fine {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  color: rgba(var(--ink-rgb), 0.42);
}

.footer-discord {
  display: inline-flex;
  color: rgba(var(--ink-rgb), 0.55);
  transition: color 0.2s var(--ease);
}

.footer-discord:hover {
  color: var(--ink);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
}

.footer-links a {
  color: inherit;
  text-decoration: none;
  transition: color 0.2s var(--ease);
}

.footer-links a:hover {
  color: var(--ink);
}

/* ---------- Responsive ---------- */

@media (max-width: 920px) {
  .promo {
    /* Asymmetric padding: the right side only has to clear the close
       button, so the line keeps its room on narrow phones. */
    padding: 0 46px 0 16px;
    font-size: 12.5px;
  }

  .promo .promo-new {
    display: none;
  }

  .promo-btn {
    margin-left: 0;
    padding: 4px 9px;
  }

  /* Drop the qualifier so the announcement still fits on one line. */
  .promo .promo-aud {
    display: none;
  }

  .nav-burger {
    display: flex;
  }

  .nav-menu {
    position: fixed;
    top: var(--banner-h);
    right: 0;
    bottom: 0;
    z-index: -1;
    width: min(360px, 88vw);
    padding: 96px 26px 30px;
    background: rgba(var(--paper-rgb), 0.96);
    backdrop-filter: blur(22px);
    -webkit-backdrop-filter: blur(22px);
    border-left: 1px solid var(--line);
    transform: translateX(100%);
    /* visibility keeps the closed drawer's links out of the tab order;
       its transition is delayed so the slide-out still animates. */
    visibility: hidden;
    transition:
      transform 0.4s var(--ease),
      visibility 0s linear 0.4s;
    display: flex;
    flex-direction: column;
    gap: 18px;
    overflow-y: auto;
  }

  .nav.menu-open .nav-menu {
    transform: none;
    visibility: visible;
    transition: transform 0.4s var(--ease);
  }

  .nav-links {
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
  }

  .nav-links a,
  .nav-links button {
    width: 100%;
    justify-content: space-between;
    padding: 14px 12px;
    font-size: 13px;
  }

  .dropdown {
    position: static;
    min-width: 0;
    margin: 4px 0 8px;
    box-shadow: none;
    opacity: 1;
    transform: none;
    visibility: visible;
    display: none;
  }

  .nav-item.open .dropdown {
    display: block;
  }

  .nav-auth {
    flex-direction: column;
    align-items: stretch;
  }

  .nav-cta {
    justify-content: center;
  }

  .footerline {
    align-items: flex-start;
    flex-direction: column;
    line-height: 1.35;
    gap: 16px;
  }

  .theme-toggle {
    order: 2;
    margin-left: auto;
  }

  .nav-burger {
    order: 3;
  }
}
