/* 2140 Studio website. A quiet single column: packages/brand/docs/web.md.
   Colours are roles from tokens/2140-palette.css; type stacks from css/fonts.css. */
:root {
  --measure: 36rem;
  --gutter: 1rem; /* 16 px side gutters on phones */
  --body: 1.1875rem; /* 19 px */
  --lead: 1.6875rem; /* 27 px */
  --title: 2.375rem; /* 38 px */
  --display: clamp(2.875rem, 7vw, 4.75rem); /* 46 to 76 px */
  --caption: 0.84375rem; /* 13.5 px */
  --line: calc(var(--body) * 1.55); /* one line of body text: the unit of vertical space */
  --arrive: cubic-bezier(0.23, 1, 0.32, 1);
  --ground: var(--graphite-950); /* what the stone stands on */
  --quiet: var(--graphite-600); /* the ground's quiet colour, for the turn's answer */
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: var(--graphite-800);
    --quiet: var(--graphite-400);
  }
}

:root[data-theme="dark"] {
  --ground: var(--graphite-800);
  --quiet: var(--graphite-400);
}

/* The page is the body; the root is the ground below it, seen only when the page bounces
   past its foot. Above the top, the bounce shows the page's own colour: in the top half of the
   scroll the root takes --bg. Without scroll timelines the ground shows at both ends. */
html {
  background: var(--ground);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

@supports (animation-timeline: scroll()) {
  html {
    animation: overhang linear both;
    animation-timeline: scroll(root);
  }
}

@keyframes overhang {
  0%,
  49.9% {
    background-color: var(--bg);
  }
  50%,
  100% {
    background-color: var(--ground);
  }
}

body {
  margin: 0;
  background: var(--bg);
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--f-body);
  font-size: var(--body);
  font-weight: 400;
  line-height: 1.55;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
}

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

main {
  box-sizing: border-box;
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: calc(var(--measure) + 2 * var(--gutter));
  margin: 0 auto;
  padding: calc(var(--line) * 2) var(--gutter) 0;
  container-type: inline-size;
}

p,
h1,
h2 {
  margin: 0;
}

p {
  text-wrap: pretty;
}

.light {
  font-weight: 300;
}

.bold {
  font-weight: 700;
}

/* "2140" bold, "Studio" light */
.wordmark {
  font-family: var(--f-display);
  font-size: var(--lead);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

/* Machine speed. (300) / Human judgment. (700). "Human judgment." is 8.6 em wide in the stand-in,
   wider than the column at every size web.md allows; it shrinks just enough to stay on one line. */
.display {
  margin-top: calc(var(--line) * 3);
  font-family: var(--f-display);
  font-size: min(var(--display), 11.5cqi);
  line-height: 1.04;
  letter-spacing: -0.02em;
}

.display span,
.title span,
.turn > span {
  display: block;
}

.first {
  margin-top: calc(var(--line) * 2);
}

.first p + p,
.manifesto p + p {
  margin-top: var(--line);
}

.manifesto {
  margin-top: calc(var(--line) * 4);
}

.title {
  margin-bottom: var(--line);
  font-family: var(--f-display);
  font-size: var(--title);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* the turn, as quote treatment D (composition.md, "Quotes"), set as the manifesto poster sets it:
   one step below the title, so it never reads as a second heading. The judgment in Signifier 700
   at lead size, broken by hand as "Speed without judgment / doesn't save time."; the answer right
   under it in GT Standard 575 at 0.875 em in the quiet colour, no marks. */
.manifesto .turn {
  margin-block: calc(var(--line) * 1.5) var(--line);
  font-family: var(--f-display);
  font-size: var(--lead);
  line-height: 1.04;
  letter-spacing: -0.02em;
}

.turn .judgment {
  font-weight: 700;
}

.turn .judgment span {
  display: block;
}

.turn .answer {
  font-family: var(--f-body);
  font-size: 0.875em;
  font-weight: 575;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--quiet);
}

.manifesto .turn + p {
  margin-top: 0;
}

/* the foot: the studio's sign cut by the foot of the page */
.foot {
  margin-top: auto;
  padding-top: calc(var(--line) * 4);
}

/* the only place the website breaks the grid: full column width, cut at three quarters of its box */
.sign {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1000 / 750;
  margin-top: calc(var(--line) * 4); /* more than a module of clear ground at every width */
  overflow: hidden;
}

.sign path {
  fill: var(--accent);
}

/* arrive: opacity 0 to 1 and 6 px up, staggered by block */
.arrive {
  animation: arrive 900ms var(--arrive) both;
  animation-delay: calc(var(--i, 0) * 120ms);
}

@keyframes arrive {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .arrive {
    animation: fade 200ms ease both;
  }
}
