/* Plus Jakarta Sans (SIL Open Font License, fonts/OFL.txt), served from here rather than Google */

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("fonts/plus-jakarta-sans-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("fonts/plus-jakarta-sans-latin-ext.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #fff;
  --fg: #17172b;
  --muted: #5c5c70;
  --line: #ececf2;

  /* the dots: every person who joins is one of them */
  --mono: #0a0a0a;
  --sage: #3fbf8f;
  --sun: #ffc23d;
  --mist: #d4d4d4;

  --gutter: clamp(1.25rem, 5vw, 4rem);
  --label-col: clamp(6rem, 16vw, 14rem);
  --max: 78rem;

  --sans: "Plus Jakarta Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* the black band at the top of every page: the header, and on the front page the wordmark */

.band {
  --bg: #0a0a0a;
  --fg: #fff;
  --muted: #a3a3a3;
  --mono: #fff;
  background: var(--bg);
  color: var(--fg);
}

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 4.5rem; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, dl, dd, ol, ul { margin: 0; padding: 0; }
ol, ul { list-style: none; }

a { color: inherit; text-decoration: none; }
a:focus-visible { outline: 1px solid var(--fg); outline-offset: 4px; }

::selection { background: var(--fg); color: var(--bg); }

/* layout: every section shares one grid — a label column and a content column */

.bar,
.hero,
main > section,
.foot {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

main > section {
  display: grid;
  grid-template-columns: var(--label-col) 1fr;
  gap: 1rem var(--gutter);
  padding-block: clamp(3rem, 8vw, 6rem);
  border-top: 1px solid var(--line);
}

main > section:first-child { border-top: 0; }

@media (max-width: 40rem) {
  main > section { grid-template-columns: 1fr; }
}

.label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* header */

.bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-block: 1rem;
  font-size: 0.9375rem;
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* each dot is a third of the mark, as tall as the name's o's (0.565em in Plus Jakarta Sans 600) */
.mark svg { width: 1.7em; height: 1.7em; }

.link { color: var(--muted); transition: color 0.2s; }
.link:hover,
.link[aria-current="page"] { color: var(--fg); }
.nav { display: flex; gap: 1.5rem; }

/* the header stays at the top while the page scrolls */
.head {
  position: sticky;
  top: 0;
  z-index: 10;
}

/* on phones the links fold into a three-line button */
.menu { display: none; }

@media (max-width: 40rem) {
  .bar { flex-wrap: wrap; padding-block: 0.5rem; }

  .menu {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 2.75rem;
    height: 2.75rem;
    margin-right: -0.625rem;
    padding: 0.625rem;
    border: 0;
    background: none;
    color: inherit;
    cursor: pointer;
  }

  .menu span {
    height: 1.5px;
    border-radius: 1px;
    background: currentColor;
    transition: transform 0.2s, opacity 0.2s;
  }

  .menu[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .menu[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .menu[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

  .nav {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    gap: 0;
    padding-block: 0.5rem;
    font-size: 1.25rem;
  }

  .bar.open .nav { display: flex; }

  .nav .link {
    padding-block: 0.75rem;
    border-top: 1px solid color-mix(in srgb, var(--fg) 12%, transparent);
    color: var(--fg);
  }
}

/* hero — the word starts as the logo: the four dots close together. They move apart to
   where the e's and o's are, the t's come in between, and the dots stay: ●tt● over ●tt●. */

.hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 2rem clamp(2.5rem, 7vw, 6rem);
  padding-block: clamp(2rem, 6vw, 4.5rem) clamp(3rem, 7vw, 5.5rem);
}

/* beside the word: the tagline, the lede and the button */
.intro .tag { margin-top: 0; }

@media (max-width: 48rem) {
  .hero { grid-template-columns: 1fr; }
  .intro .tag { margin-top: 0.5rem; }
}

.wordmark {
  font-weight: 200;
  font-size: clamp(3.5rem, 13vw, 8.5rem);
  line-height: 0.92;
  letter-spacing: -0.05em;
  margin-left: -0.05em;
}

.wordmark .line { display: block; }

.round,
.tt { display: inline-block; }

/*
 * On the front page the hero collapses into the header as the page scrolls (hero.js):
 * the dots fly up to be the mark, the t's fly into the name, then the e's and o's fade
 * in. So the word flies over the header, and the mark and name start hidden.
 */
.wordmark {
  position: relative;
  z-index: 11;
  pointer-events: none;
}

.wordmark .tt { display: inline-flex; justify-content: center; }

@media (prefers-reduced-motion: no-preference) {
  .js .mark[data-collapse] svg,
  .js .mark[data-collapse] .name > span { opacity: 0; }

  /* the finishing touch: the e's and o's fade in where they stand */
  .js .mark[data-collapse] .name-eo { transition: opacity 1.6s ease-in-out; }
  .js .mark[data-collapse] .name-eo.shown { opacity: 1; }
}

/* the e's and o's stay in the text for screen readers and search, drawn as their dots */
.round {
  position: relative;
  color: transparent;
}

/*
 * The dot: about the size of the letter's bowl, centred on it. In the logo the dots
 * are 1.25 dot-widths apart (0.675em); in Plus Jakarta Sans 200 the letters are
 * 1.253em apart across and 0.92em down. So each dot starts 0.1225em towards the
 * middle row (--y), and the o's dots start 0.578em to the left (--x), next to the e's.
 */
.round::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0.62em;
  width: 0.54em;
  height: 0.54em;
  margin: -0.27em 0 0 -0.245em;
  border-radius: 50%;
  background: var(--c);
  animation:
    appear 0.5s ease-out 0.1s backwards,
    apart 0.9s cubic-bezier(0.65, 0, 0.35, 1) 1.1s backwards;
}

.tt { animation: letter-up 0.8s cubic-bezier(0.2, 0, 0, 1) 1.7s backwards; }

@keyframes appear {
  from { opacity: 0; }
}

@keyframes apart {
  from { transform: translate(calc(var(--x) * -0.578em), calc(var(--y) * 0.1225em)); }
}

@keyframes letter-up {
  from { opacity: 0; transform: translateY(0.08em); }
  to   { opacity: 1; transform: none; }
}

.tag {
  margin-top: 2rem;
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.lede {
  margin-top: 0.75rem;
  max-width: 40rem;
  font-size: clamp(1.25rem, 2.6vw, 1.625rem);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

/* mission */

.statement { max-width: 44rem; }

.statement p {
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
  line-height: 1.35;
  letter-spacing: -0.015em;
}

.statement p + p { margin-top: 1.5rem; }
.statement p:not(:last-child) { color: var(--muted); }

/* meaning */

dl { max-width: 34rem; }
dt { font-weight: 500; margin-top: 2rem; }
dt:first-child { margin-top: 0; }
dd { color: var(--muted); }
dd em { font-style: normal; color: var(--fg); }
.term { letter-spacing: -0.01em; }

/* approach — each step a tinted card with its dots */

.steps {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
}

@media (max-width: 40rem) {
  .steps { grid-template-columns: 1fr; }
}

.steps li {
  padding: clamp(1.5rem, 3vw, 2rem);
  border-radius: 1.5rem;
  background: color-mix(in srgb, var(--mono) 9%, var(--bg));
}

.steps li:nth-child(2) { background: color-mix(in srgb, var(--mist) 10%, var(--bg)); }

.dots {
  display: block;
  height: 1.5rem;
  width: auto;
  margin-bottom: 1.25rem;
}

.steps h3 {
  font-size: 1.625rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.steps p {
  margin-top: 0.75rem;
  max-width: 26rem;
  color: var(--muted);
}

/* together — the network illustration on black, right before the waitlist (network.js) */

main > section.network {
  max-width: none;
  padding-inline: max(var(--gutter), (100% - var(--max)) / 2 + var(--gutter));
  border-top: 0;
}

.network + section { border-top: 0; }

.network-body {
  display: grid;
  gap: 2rem;
  justify-items: start;
}

/* the grid (--cols × --rows, set by network.js) has three rows of room above it: centred
   at first, then it moves down so the lifted dot can float above it */
.net {
  --room: 3;
  position: relative;
  width: min(100%, 40rem, 70svh * var(--cols) / (var(--rows) + var(--room)));
  aspect-ratio: calc(var(--cols)) / calc(var(--rows) + var(--room));
  overflow: hidden;
}

.net-world {
  position: absolute;
  top: calc(var(--room) / 2 / (var(--rows) + var(--room)) * 100%);
  left: 0;
  width: 100%;
  height: calc(var(--rows) / (var(--rows) + var(--room)) * 100%);
  transform-origin: 0 0;
  transition: transform 1.6s cubic-bezier(0.65, 0, 0.35, 1), top 1.4s cubic-bezier(0.65, 0, 0.35, 1);
}

.net.lifting .net-world { top: calc(var(--room) / (var(--rows) + var(--room)) * 100%); }

/* one cell of the grid; the dot fills 80% of it, as in the logo */
.net-world span {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(100% / var(--cols));
  height: calc(100% / var(--rows));
  transition: transform 1.4s cubic-bezier(0.65, 0, 0.35, 1);
}

/* redrawn straight into the end state, without moving */
.net.settled .net-world,
.net.settled .net-world span,
.net.settled .net-world span::after { transition: none; }

.net-world span::after {
  content: "";
  position: absolute;
  inset: 10%;
  border-radius: 50%;
  background: var(--c);
  transition: background-color 0.6s;
}

.net-world span.off::after { background: #262626; }

.caption {
  max-width: 26rem;
  color: var(--muted);
}

/* work — each belief gets a dot of its own */

.list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 0.25rem var(--gutter);
  padding-block: 1.25rem;
  border-bottom: 1px solid var(--line);
}

.list li:first-child { padding-top: 0; }
.list li:last-child { border-bottom: 0; padding-bottom: 0; }
.list li span:first-child { font-weight: 500; }
.list li span:last-child { color: var(--muted); }

.list li span:first-child::before {
  content: "";
  display: inline-block;
  width: 0.625rem;
  height: 0.625rem;
  margin-right: 0.75rem;
  border-radius: 50%;
  background: var(--mono);
}

.list li:nth-child(4n + 2) span:first-child::before { background: var(--sage); }
.list li:nth-child(4n + 3) span:first-child::before { background: var(--sun); }
.list li:nth-child(4n + 4) span:first-child::before { background: var(--mist); }

@media (max-width: 40rem) {
  .list li { grid-template-columns: 1fr; }
}

/* team */

.people {
  display: grid;
  gap: 3rem;
}

.person {
  display: grid;
  grid-template-columns: minmax(8rem, 14rem) minmax(0, 1fr);
  gap: 1.5rem var(--gutter);
  align-items: start;
}

@media (max-width: 40rem) {
  .person { grid-template-columns: 1fr; }
}

.person img {
  display: block;
  width: 100%;
  max-width: 16rem;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 1.5rem;
}

@media (max-width: 40rem) {
  .person img { max-width: 9rem; }
}

.person h3 {
  font-size: 1.5rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.person .role {
  margin-top: 0.25rem;
  color: var(--muted);
}

.person .bio {
  margin-top: 1.25rem;
  max-width: 34rem;
  color: var(--muted);
}

.person .bio + .bio { margin-top: 1rem; }

/* waitlist */

.waitlist-body { max-width: 44rem; }

.waitlist-lede {
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
  line-height: 1.35;
  letter-spacing: -0.015em;
}

.signup { margin-top: 2.5rem; }

.kinds {
  margin: 0;
  padding: 0;
  border: 0;
}

.kinds legend { padding: 0; margin-bottom: 1rem; }

/* the two kinds are circles: light grey, and their own dot colour when chosen */
.kind-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.kind {
  --dot: var(--sage);
  position: relative;
  cursor: pointer;
}

.kind + .kind { --dot: var(--sun); }

.kind input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.kind-title {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 7.5rem;
  aspect-ratio: 1;
  padding: 1rem;
  border-radius: 50%;
  background: var(--mist);
  text-align: center;
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.02em;
  transition: background-color 0.2s;
}

.kind:hover .kind-title { background: color-mix(in srgb, var(--dot) 35%, var(--mist)); }
.kind:has(input:checked) .kind-title { background: var(--dot); }
.kind:has(input:focus-visible) .kind-title { outline: 1px solid var(--fg); outline-offset: 3px; }
/* the same from waitlist.js, for browsers without :has (Safari before 15.4); kept
   as separate rules, since one unknown selector drops a whole rule there */
.kind.is-checked .kind-title { background: var(--dot); }

/* below the circles, only the chosen kind's description */
.kind-info {
  max-width: 34rem;
  margin-top: 1.25rem;
  font-size: 0.9375rem;
  color: var(--muted);
}

.kinds:has(input[value="app_user"]:checked) .kind-info[data-kind="business"],
.kinds:has(input[value="business"]:checked) .kind-info[data-kind="app_user"] { display: none; }
.kinds[data-chosen="app_user"] .kind-info[data-kind="business"],
.kinds[data-chosen="business"] .kind-info[data-kind="app_user"] { display: none; }

/* For myself: the devices, then for each chosen one its system. All pills. */
.devices,
.os {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.devices { margin-top: 2.5rem; }
.devices[hidden],
.os[hidden],
.sizes[hidden] { display: none; }

/* For a business: how many people work there, as pills under the company */
.sizes { min-width: 0; margin: 0; padding: 0; border: 0; }
.sizes legend {
  padding: 0;
  margin-bottom: 0.6rem;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.devices legend { padding: 0; margin-bottom: 1rem; }

.device-choices,
.os {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.os { align-items: center; margin-top: 1rem; }

.os legend {
  float: left;
  min-width: 7.5rem;
  margin-right: 0.4rem;
  padding: 0;
  font-size: 0.8125rem;
  line-height: 2.2rem; /* the height of the pills beside it */
  letter-spacing: 0.04em;
  color: var(--muted);
}

.pick {
  position: relative;
  cursor: pointer;
}

.pick input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.pick span {
  display: inline-block;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  background: var(--mist);
  font-size: 1rem;
  transition: background-color 0.2s;
}

.os .pick span { padding: 0.35rem 0.95rem; font-size: 0.9375rem; }

.pick:hover span { background: color-mix(in srgb, var(--sage) 35%, var(--mist)); }
.pick:has(input:checked) span { background: var(--sage); }
.pick:has(input:focus-visible) span { outline: 1px solid var(--fg); outline-offset: 3px; }
.pick.is-checked span { background: var(--sage); }

.fields {
  display: grid;
  gap: 1.5rem;
  margin-top: 2rem;
}

.field { display: grid; gap: 0.35rem; }
.field[hidden] { display: none; }

.field span {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.field em { font-style: normal; opacity: 0.7; }

.field input,
.field textarea {
  width: 100%;
  padding: 0.5rem 0;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--fg) 30%, transparent);
  border-radius: 0;
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 1.125rem;
  transition: border-color 0.2s;
}

.field textarea { resize: vertical; }

.field input:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--fg);
}

.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.join {
  margin-top: 2rem;
  padding: 0.85rem 1.6rem;
  border: 1px solid var(--fg);
  border-radius: 999px;
  background: var(--fg);
  color: var(--bg);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}

.join:hover { background: transparent; color: var(--fg); }
.join:focus-visible { outline: 1px solid var(--fg); outline-offset: 3px; }
.join:disabled { opacity: 0.5; cursor: wait; }

/* The same button as a link: the hero's, which scrolls down to the waitlist. */
a.join { display: inline-block; margin-top: 2rem; }

.status {
  min-height: 1.6em;
  margin-top: 1rem;
  font-size: 0.9375rem;
}

.status.error { color: var(--muted); }

/* contact */

.mail {
  justify-self: start;
  font-size: clamp(1.5rem, 4.5vw, 3rem);
  font-weight: 200;
  letter-spacing: -0.03em;
  line-height: 1.1;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s;
}

.mail:hover { border-bottom-color: var(--fg); }

/* footer */

.foot {
  display: flex;
  justify-content: space-between;
  padding-block: 2rem 3rem;
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .round::before,
  .tt { animation: none; }
  .net-world,
  .net-world span,
  .net-world span::after { transition: none; }
}
