/* Colours come from the app icon: the sky (#D6ECFF to #A9D3F7), the robot's
   navy visor (#132A5C) and blues, and the sand and wood. */
:root {
  /* Light only, so the sky looks the same everywhere. */
  color-scheme: light;
  --text: #1d1d1f;
  --muted: #3d4a5c;
  --border: rgb(19 42 92 / 0.18);
  /* Darker than the icon's blue so links are readable on the sky. */
  --accent: #0b3f9e;
  --code-bg: rgb(19 42 92 / 0.07);
  --surface: #ffffff;
  /* Like a real sky, the page is darkest at the top: the icon's darker sky
     fades to its light sky, which continues down to the footer. The footer
     is the sandbox: a wooden rim like the icon's, then its sand. */
  --sky-dark: #a9d3f7;
  --sky-light: #d6ecff;
  --sand-top: #edc77f;
  --sand-bottom: #f3dba8;
  --wood-top: #e39b5b;
  --wood-side: #c47a3c;
  --wood-seam: #8f5226;
  --sand-text: #4a3418;
  /* The header's text and controls, which sit on the sky. */
  --hero-text: #132a5c;
  --hero-muted: #2f4a7a;
  --button-bg: rgb(255 255 255 / 0.6);
  --button-border: rgb(19 42 92 / 0.2);
  --button-hover: rgb(255 255 255 / 0.9);
  --primary-bg: #132a5c;
  --primary-text: #ffffff;
  --command-bg: rgb(255 255 255 / 0.45);
  --command-border: rgb(19 42 92 / 0.22);
  --tok-cmd: #b4237a;
  --tok-flag: #0b6e86;
  --tok-op: #6b7fa6;
  --copied: #1e8e4e;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

/* The sky lightens from the top until a little below the header. The column
   layout keeps the footer at the bottom of a window taller than the page. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  background: linear-gradient(var(--sky-dark), var(--sky-light) 800px) top / 100% 800px no-repeat var(--sky-light);
  color: var(--text);
  font: 17px/1.55 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

a {
  color: var(--accent);
}

code {
  font: 0.9em ui-monospace, "SF Mono", Menlo, monospace;
  background: var(--code-bg);
  padding: 0.1em 0.35em;
  border-radius: 5px;
}

.inner {
  max-width: 880px;
  margin: 0 auto;
  padding: 0 16px;
}

/* Wider, for the feature rows with screenshots. */
.inner.wide {
  max-width: 1240px;
}

.hero {
  color: var(--hero-text);
  padding: 96px 0 72px;
}

.hero a {
  color: var(--hero-text);
}

.brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 32px;
}

.artwork {
  flex: none;
  width: 200px;
  height: auto;
  filter: drop-shadow(0 12px 20px rgb(19 42 92 / 0.18));
}

h1 {
  font-size: 56px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
}

.tagline {
  font-size: 22px;
  color: var(--hero-muted);
  margin: 0 0 22px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.button {
  display: inline-block;
  padding: 10px 20px;
  border-radius: 999px;
  border: 1px solid var(--button-border);
  background: var(--button-bg);
  color: var(--hero-text);
  font-weight: 600;
  text-decoration: none;
}

.hero .button.primary {
  background: var(--primary-bg);
  border-color: var(--primary-bg);
  color: var(--primary-text);
}

.install {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 64px;
}

.install .links {
  justify-content: center;
  margin: 16px 0 0;
}

.note {
  color: var(--hero-muted);
  font-size: 15px;
  margin: 8px 0 0;
}

/* A translucent box on the sky, only as wide as the command. The command
   wraps rather than scrolls on narrow windows, breaking inside the URL only
   when it doesn't fit on a line of its own. */
.install-command {
  display: flex;
  align-items: center;
  gap: 16px;
  width: fit-content;
  max-width: 100%;
  padding: 12px 12px 12px 20px;
  background: var(--command-bg);
  border: 2px solid var(--command-border);
  border-radius: 14px;
  backdrop-filter: blur(8px);
}

.install-command code {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 15px;
  line-height: 1.6;
  padding: 0;
  background: none;
  color: var(--hero-text);
}

.tok-cmd {
  color: var(--tok-cmd);
}

.tok-flag {
  color: var(--tok-flag);
}

.tok-url {
  color: var(--hero-text);
}

.tok-op {
  color: var(--tok-op);
}

.links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  font-size: 15px;
}

.band {
  position: relative;
  padding: 80px 0;
}

h2 {
  font-size: 30px;
  letter-spacing: -0.01em;
  margin: 0 0 20px;
}

/* One heading over all the feature rows, centred over both columns. */
.features-title {
  margin-bottom: 56px;
  text-align: center;
}

/* Each row has a small label rather than a heading of its own. */
.feature-label {
  display: inline-block;
  margin: 0 0 14px;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgb(19 42 92 / 0.08);
  color: var(--hero-text);
  font-size: 14px;
  font-weight: 600;
}

/* Feature rows: text on one side and a screenshot on the other, switching
   sides each row. On phones the text comes first, then the screenshot. */
.feature {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  align-items: center;
  gap: 56px;
  padding: 48px 0;
}

/* The section's own padding spaces the first and last rows. */
.feature:first-child {
  padding-top: 0;
}

.feature:last-child {
  padding-bottom: 0;
}

.feature.reverse {
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
}

.feature.reverse .feature-text {
  order: 2;
}

.feature ul {
  margin: 0;
  padding-left: 1.2em;
}

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

/* A window screenshot includes its own title bar and shadow. */
.shot {
  display: block;
  width: 100%;
  height: auto;
}

/* The main window's screenshot, centred below the install command. */
.main-shot {
  max-width: 1000px;
  margin: 64px auto 0;
}

.copy {
  flex: none;
  font: inherit;
  font-size: 14px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}

.copy.icon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 8px;
  border-color: var(--button-border);
  background: var(--button-bg);
  color: var(--hero-text);
}

.copy.icon:hover {
  background: var(--button-hover);
}

.copy.icon svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.copy.icon .done-icon,
.copy.icon.copied .copy-icon {
  display: none;
}

.copy.icon.copied .done-icon {
  display: block;
  color: var(--copied);
}

/* The footer is the sandbox: the rim's top and front, with a seam between
   them as on the icon's walls, then the sand, lighter towards the bottom. */
footer {
  margin-top: auto;
  background:
    linear-gradient(var(--wood-top) 0 6px, var(--wood-seam) 6px 8px, var(--wood-side) 8px 16px) top / 100% 16px no-repeat,
    linear-gradient(var(--sand-top), var(--sand-bottom)) var(--sand-bottom);
  color: var(--sand-text);
  text-align: center;
  font-size: 14px;
  padding: 64px 0 56px;
}

footer a {
  color: var(--hero-text);
}

/* Sections slide up and fade in as they scroll into view, tied to the scroll
   position, so they slide back out when scrolled up again. Screenshots start
   a little after their text. Browsers without scroll-driven animations, and
   visitors with Reduce Motion on, see everything in place. Each one starts
   as it comes into view and settles once it's a little way up the window, so
   the movement happens where it can be seen; that's early enough for the
   sections near the bottom of the page to finish too. */
@keyframes slide-up {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .features-title,
    .feature-text,
    .feature > .shot,
    #requirements .inner,
    #other-install .inner {
      animation: slide-up ease-out both;
      animation-timeline: view();
      animation-range: entry 10% cover 25%;
    }

    .feature > .shot {
      animation-range: entry 20% cover 32%;
    }
  }
}

/* When the page loads, the sandbox rises into place, then the title, the
   install command and the main screenshot fade up one after another. The
   sandbox has settled before the robot starts peeking out of it at 1.2
   seconds (PEEK_DELAY in scripts/generate-app-icon.py). */
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.94);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .artwork {
    animation: rise-in 0.7s cubic-bezier(0.2, 0.8, 0.3, 1) both;
  }

  .brand-text,
  .install,
  .main-shot {
    animation: fade-up 0.6s ease-out both;
  }

  .brand-text {
    animation-delay: 0.15s;
  }

  .install {
    animation-delay: 0.3s;
  }

  .main-shot {
    animation-delay: 0.45s;
  }
}

/* Below this width two columns get too narrow, so the rows stack. */
@media (max-width: 820px) {
  .feature,
  .feature.reverse {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    padding: 32px 0;
  }

  .feature.reverse .feature-text {
    order: 0;
  }
}

@media (max-width: 640px) {
  .hero {
    padding: 56px 0 48px;
  }

  .brand {
    flex-direction: column;
    gap: 16px;
    text-align: center;
  }

  .artwork {
    width: 150px;
  }

  .actions {
    justify-content: center;
  }

  h1 {
    font-size: 42px;
  }

  .tagline {
    font-size: 19px;
  }

  .band {
    padding: 56px 0;
  }

  .main-shot {
    margin-top: 40px;
  }
}
