/**
 * The site's chrome, in the language of the landing design: a hairline header
 * with the mark and a mono wordmark on the left, mono nav on the right, and a
 * footer at the end of the scroll.
 *
 * The shell itself is unchanged — the app is a fixed viewport with the view
 * scrolling inside `.site-view`, which is why the header needs no `sticky`: it
 * sits outside the scroller and never moves. The footer is inside it, so it
 * arrives at the end of a long page and rests on the bottom of a short one.
 *
 * Colours are the app's tokens throughout. `--light` and `--light0` are the
 * design's rule and panel, `--text2` its muted ink; moving `--background` and
 * `--text` in `app.css` moves the chrome with them.
 */
.site,
site-layout {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  max-width: 100vw;
  min-height: 100vh;
  min-height: 100dvh;
  height: 100vh;
  height: 100dvh;
}

.site-topbar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 28px;
  z-index: 1;
  width: 100%;
  box-sizing: border-box;
  background: var(--background);
}

@media (max-width: 640px) {
  .site-topbar {
    padding: 14px 20px;
  }
}

/* ---------------- BRAND ---------------- */

/**
 * The mark's reveal, which is the header's opinion rather than the logo's.
 *
 * `site-logo` draws the mark and the wordmark and knows nothing about scrolling;
 * what belongs here is that this particular header starts as the wordmark alone
 * and grows the mark in as the hero leaves. So the rules reach into the logo to
 * collapse its mark, and `.lit` — set by `logic.ts` — lets it back out.
 *
 * A width animation rather than an opacity one because the wordmark has to move
 * over to make room, and the negative margin closes the logo's own 10px gap
 * while the mark is collapsed, so there is no hole where it will be.
 */
.site-topbar site-logo [mark] {
  overflow: hidden;
  width: 0;
  margin-right: -10px;
  opacity: 0;
  transform: scaleY(0.15) translateY(8px);
  transform-origin: 50% 100%;
  transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1), margin-right 320ms cubic-bezier(0.4, 0, 0.2, 1),
    opacity 200ms linear, transform 460ms cubic-bezier(0.18, 1.5, 0.4, 1);
}

.site-topbar site-logo [word] {
  font-weight: 400;
}

.site-topbar.lit site-logo [mark] {
  width: 32px;
  margin-right: 0;
  opacity: 1;
  transform: scaleY(1) translateY(0);
}

.site-topbar.lit site-logo [word] {
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .site-topbar site-logo [mark] {
    transition: none;
  }
}

/* ---------------- NAV ---------------- */

.site-topbar-nav {
  display: flex;
  align-items: center;
  gap: 28px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.04em;
}

.site-topbar-nav a {
  white-space: nowrap;
}

@media (max-width: 640px) {
  .site-topbar-nav {
    gap: 14px;
    font-size: 11.5px;
  }

  .site-topbar-cta {
    padding: 6px 11px;
  }
}

/* The gates are wrappers around whichever of these applies, not boxes of their
   own: `display: contents` puts their children directly into the nav's row, so
   the spacing between "Docs" and "Sign-in" is the same 28px as everywhere else.
   `auth-gate` already declares it; `unauth-gate` does not. */
.site-topbar-nav :is(auth-gate, unauth-gate) {
  display: contents;
}

/**
 * A link is underlined by a rule that wipes in from the left and out to the
 * right — the same figure the buttons use, and the same trick: a pseudo-element
 * scaled from zero with its transform origin flipped between the two states.
 */
.site-topbar-link {
  position: relative;
  display: inline-block;
  overflow: hidden;
  padding-bottom: 3px;
  text-decoration: none;
  color: var(--text);
}

.site-topbar-link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--text);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 340ms cubic-bezier(0.45, 0, 0.2, 1);
}

.site-topbar-link:hover::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.site-topbar-cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--text);
  padding: 7px 14px;
  text-decoration: none;
  color: var(--text);
  transition: color 180ms linear;
}

.site-topbar-cta::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--text);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 340ms cubic-bezier(0.45, 0, 0.2, 1);
}

.site-topbar-cta:hover::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.site-topbar-cta:hover {
  color: var(--background);
}

@media (prefers-reduced-motion: reduce) {
  .site-topbar-link::after,
  .site-topbar-cta::after {
    transition: none;
  }
}

/* The scheme chip reads as a setting rather than as a destination: smaller,
   quieter, and lettered in the same tracked caps as the wordmark. */
.site-scheme {
  font: inherit;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text2);
  background: transparent;
  border: 1px solid var(--light);
  padding: 6px 10px;
  cursor: pointer;
  transition: color 180ms linear, border-color 180ms linear;
}

.site-scheme:hover {
  color: var(--text);
  border-color: var(--text);
}

/* Empty until the logic labels it, and an empty bordered box in the header is
   worse than no box. */
.site-scheme:empty {
  display: none;
}

/* ---------------- VIEWPORT ---------------- */

/**
 * No gap and no squeeze any more: the drawer is a sheet over the page rather than a column beside
 * it, so opening it takes width from nobody. What was here reflowed the whole page sideways as the
 * menu came in — and on a narrow screen left too little for either.
 *
 * The scrim and the sheet are `position: fixed` children of a `display: contents` `site-sidebar`,
 * so they are flex items of this box on paper and out of flow in practice. Nothing here may take a
 * transform, a filter or `contain`: any of those would make this the containing block for them and
 * the sheet would be pinned inside the viewport box rather than to the window.
 */
.site-viewport {
  position: relative;
  display: flex;
  align-items: stretch;
  flex-grow: 1;
  min-height: 0;
  overflow: hidden;
}

@media (max-width: 768px) {
  .site-viewport {
    padding-top: 0;
  }
}

.site-view {
  position: relative;
  flex-grow: 1;
  transition: all ease 300ms;
  overflow: scroll;
  max-width: 100vw;
  display: flex;
}

/**
 * A column now rather than a row, because the footer is the second thing in it.
 * It keeps the absolute positioning and the full-viewport width it always had —
 * views are centred in it and size themselves — and grows past the viewport when
 * the page is long, which is what `.site-view` scrolls.
 */
.site-view-container {
  position: absolute;
  flex-grow: 1;
  min-height: 100%;
  width: 100%;
  width: 100vw;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.site-view-container > * {
  max-width: 100%;
}

.site-view-content {
  display: flex;
  justify-content: center;
  width: 100%;
}

.site-view-content > * {
  max-width: 100%;
}

/* ---------------- FOOTER ---------------- */

/* `margin-top: auto` is what puts it at the bottom of a short page and directly
   under the content of a long one. */
.site-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 28px;
  width: 100%;
  margin-top: auto;
  border-top: 1px solid var(--light);
  padding: 28px;
  box-sizing: border-box;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--text2);
}

.site-footer nav {
  display: flex;
  align-items: center;
  gap: 22px;
}

/* As in the header: the gates are wrappers, not boxes, so their children join
   the row directly and the 22px gap stays the gap between links. */
.site-footer nav :is(auth-gate, unauth-gate) {
  display: contents;
}

.site-footer a {
  text-decoration: none;
  color: var(--text2);
  transition: color 180ms linear;
}

.site-footer a:hover {
  color: var(--text);
}

@media (max-width: 640px) {
  .site-footer {
    padding: 22px 20px;
  }
}

.site-topbar svg {
  max-height: 40px;
  width: auto;
}
