/* The header every page shares, the docs included (the build puts this file at the top of site.css and of
   docs.css): the brand on the left, the links on the right, fixed at the top. It has no background of its
   own, so a full-screen scene runs behind it; only the brand and the links take the pointer. */
:root {
  /* The room the header takes at the top: the page content starts below it. */
  --head: calc(36px + 1.25rem);
}

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  align-items: flex-start;
  justify-content: space-between;
  gap: 5px 20px;
  min-height: var(--head);
  padding: 20px 20px 0;
  background: var(--head-bg, transparent);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  pointer-events: none;
}

.site-header a {
  color: var(--ascii-text);
  line-height: 1.2;
  text-decoration: none;
  pointer-events: auto;
}

.site-header .brand {
  padding: 4px 8px;
  font-size: 1rem;
  letter-spacing: 0.04em;
}

.site-header .nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 2px;
}

.site-header .nav a {
  padding: 6px 8px;
  font-size: 0.85rem;
}

.site-header .nav a:hover,
.site-header .nav a[aria-current="page"] {
  color: var(--ascii-accent);
}

.site-header .nav a[aria-current="page"] {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.site-header a:focus-visible {
  outline: 2px solid var(--ascii-text);
  outline-offset: 2px;
}

/* On a phone the brand and the links do not fit on one line: the links go on a second line, under the brand. */
@media (max-width: 640px) {
  :root {
    --head: calc(72px + 1.25rem);
  }

  .site-header {
    padding: 20px 12px 0;
  }

  .site-header .brand {
    padding: 4px 6px;
  }

  .site-header .nav {
    flex-basis: 100%;
    justify-content: flex-start;
  }

  .site-header .nav a {
    padding: 6px;
    font-size: 0.8rem;
  }
}

/* The narrowest phones: the five links still fit on one line. */
@media (max-width: 359px) {
  .site-header .nav a {
    padding: 6px 4px;
    font-size: 0.75rem;
  }
}

:root {
  --bg: #080c12;
  --ascii-text: #d8e1ee;
  --ascii-accent: #5fd0c5;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--ascii-text);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

a {
  color: inherit;
}

#hero,
.fill {
  position: fixed;
  inset: 0;
  display: block;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
}

.pitch {
  position: fixed;
  left: 20px;
  bottom: 28px;
  z-index: 1;
  box-sizing: border-box;
  max-width: min(34rem, calc(100vw - 40px));
  /* On a short screen (a phone held sideways, zoomed text) it scrolls inside, below the header, instead of running off the top. */
  max-height: calc(100vh - 28px - var(--head));
  max-height: calc(100dvh - 28px - var(--head));
  overflow-y: auto;
  padding: 14px 16px;
}

h1 {
  margin: 0 0 12px;
  font-size: clamp(1.5rem, 4.5vw, 2.4rem);
  line-height: 1.15;
  font-weight: 600;
}

h2 {
  margin: 0 0 8px;
  font-size: clamp(1.2rem, 3vw, 1.6rem);
  line-height: 1.2;
  font-weight: 600;
}

.pitch p {
  margin: 0 0 18px;
  font-size: 0.95rem;
  line-height: 1.55;
}

.pitch .actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
}

.button {
  display: inline-block;
  padding: 9px 16px;
  border: 1px solid var(--ascii-accent);
  background: var(--ascii-accent);
  color: var(--bg);
  font-size: 0.9rem;
  text-decoration: none;
}

.button.ghost {
  background: transparent;
  color: var(--ascii-accent);
}

/* With reduced motion the scenes are still frames and a click does nothing, so the text does not ask for one. */
@media (prefers-reduced-motion: reduce) {
  .motion-only {
    display: none;
  }
}

.button:focus-visible {
  outline: 2px solid var(--ascii-text);
  outline-offset: 2px;
}

/* Features: the header, a row of tabs, then one scene filling the rest of the window, its caption and one
   small line under it. The page is exactly as tall as the window, so it never scrolls. */
.tour {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  margin: 0;
  padding-top: var(--head);
}

.tour main {
  box-sizing: border-box;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  padding: 0 20px 14px;
}

/* For screen readers only: the page has a title, the tabs say the rest. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* On a narrow screen the row of tabs scrolls sideways inside itself; the padding leaves room for the focus ring. */
.tabs {
  display: flex;
  flex: none;
  gap: 8px;
  margin: 0 -3px;
  padding: 3px;
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs [role="tab"] {
  flex: none;
  min-height: 40px;
  padding: 8px 14px;
  border: 1px solid color-mix(in srgb, var(--ascii-accent) 55%, transparent);
  border-radius: 0;
  background: transparent;
  color: var(--ascii-text);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.tabs [role="tab"]:hover {
  color: var(--ascii-accent);
}

.tabs [role="tab"][aria-selected="true"] {
  border-color: var(--ascii-accent);
  background: var(--ascii-accent);
  color: var(--bg);
}

.tabs [role="tab"]:focus-visible,
.view:focus-visible {
  outline: 2px solid var(--ascii-text);
  outline-offset: 2px;
}

.view {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  margin-top: 10px;
}

.view .box {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
}

.view canvas {
  position: absolute;
  inset: 0;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  border: 1px solid color-mix(in srgb, var(--ascii-text) 18%, transparent);
}

.view .caption {
  flex: none;
  min-height: 1.4em;
  margin: 10px 0 0;
  color: var(--ascii-accent);
  font-size: 0.85rem;
  line-height: 1.4;
}

.tour .later {
  flex: none;
  margin: 6px 0 0;
  color: color-mix(in srgb, var(--ascii-text) 70%, transparent);
  font-size: 0.75rem;
  line-height: 1.4;
}

/* The line that says why the scene is empty. The page's script hides it once the engine runs. */
.view .fallback,
.stage .fallback {
  position: absolute;
  left: 0;
  right: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0 20px;
  font-size: 0.85rem;
  line-height: 1.5;
  text-align: center;
}

.view .fallback {
  top: 50%;
  transform: translateY(-50%);
}

/* The playground's panel covers the lower part of the screen on a phone: the line sits under the header. */
.stage .fallback {
  top: calc(var(--head) + 24px);
}

.view .fallback[hidden],
.stage .fallback[hidden] {
  display: none;
}

@media (max-width: 640px) {
  .tour main {
    padding: 0 12px 10px;
  }

  .tabs [role="tab"] {
    padding: 8px 10px;
  }

  /* Two lines for the caption, so a longer one does not move the scene. */
  .view .caption {
    min-height: 2.8em;
  }
}

/* Playground: one big scene and a panel of controls over it. */
.stage {
  position: fixed;
  inset: 0;
}

.stage canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.panel {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 1;
  box-sizing: border-box;
  width: min(26rem, calc(100vw - 40px));
  padding: 14px 16px 16px;
}

.panel h1 {
  margin-bottom: 6px;
  font-size: 1.4rem;
}

.panel .intro {
  margin: 0 0 14px;
  font-size: 0.85rem;
  line-height: 1.5;
}

.controls {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 12px;
}

.status {
  margin: 10px 0 0;
  color: var(--ascii-accent);
  font-size: 0.85rem;
  line-height: 1.4;
}

/* Empty, it takes no room but stays rendered, so screen readers announce the next message. */
.status:empty {
  margin: 0;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.field.wide {
  grid-column: 1 / -1;
}

.field label {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ascii-accent);
}

.field input,
.field select {
  box-sizing: border-box;
  width: 100%;
  min-height: 40px;
  padding: 6px 10px;
  border: 1px solid color-mix(in srgb, var(--ascii-accent) 55%, transparent);
  border-radius: 0;
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  color: var(--ascii-text);
  color-scheme: dark;
  /* 16px keeps iOS from zooming the page when a field is focused. */
  font: inherit;
  font-size: 16px;
}

.field input:focus-visible,
.field select:focus-visible {
  outline: 2px solid var(--ascii-text);
  outline-offset: 1px;
}

@media (max-width: 640px) {
  .panel {
    left: 12px;
    right: 12px;
    bottom: 12px;
    width: auto;
    padding: 10px 12px 12px;
  }
}

/* Pricing: the scene is fixed behind. The text sits in a box below the header that scrolls on its own on a
   short screen, so it never runs under the header and the offer is never clipped. */
.layer {
  position: fixed;
  top: var(--head);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  overflow-y: auto;
}

.price main {
  box-sizing: border-box;
  max-width: 64rem;
  margin: 0 auto;
  padding: 16px 20px 8vh;
}

.price main > p {
  max-width: 40rem;
  margin: 0 0 14px;
  font-size: 0.95rem;
  line-height: 1.55;
}

.offer {
  box-sizing: border-box;
  max-width: 30rem;
  padding: 18px 20px 20px;
  border: 1px solid color-mix(in srgb, var(--ascii-accent) 55%, transparent);
}

.offer h2 {
  margin-bottom: 14px;
  color: var(--ascii-accent);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.offer .amount {
  margin: 0;
  font-size: clamp(2rem, 8vw, 3rem);
  line-height: 1.1;
  font-weight: 600;
}

.offer .term {
  margin: 4px 0 16px;
  font-size: 0.95rem;
}

.includes {
  margin: 0 0 20px;
  padding-left: 1.2em;
  font-size: 0.95rem;
  line-height: 1.55;
}

.includes li {
  margin-bottom: 8px;
}

.offer .actions {
  margin: 0 0 12px;
}

.offer .note {
  margin: 0;
  color: var(--ascii-accent);
  font-size: 0.85rem;
}
