/* ---------------------------------------------------------------------------
   The home page as a deck.

   Every slide's content is in the HTML. CSS shows one at a time. Nothing is
   built by script and nothing is fetched, which is what keeps the two usual
   objections to a slide-shaped site from landing: a search engine reads the
   whole page, and every slide has its own address in the bar.

   Hidden slides use visibility and position rather than display:none, so the
   text stays in the accessibility tree for a screen reader that walks the
   document rather than the slides.

   ON THE MOTION
   The built-in easings are too weak to read as deliberate, so the curves here
   are named and shared. Slides come in under 300ms: a deck is stepped through
   dozens of times in a sitting, and anything slower starts to feel like waiting
   rather than moving. Content inside a slide is staggered by 45ms, which is
   enough to read as a sequence and not enough to make anyone wait for it.
--------------------------------------------------------------------------- */

:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
}

.deck {
  position: fixed;
  inset: var(--bar-h, 64px) 0 0 0;
  overflow: hidden;
}

.slide {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: clamp(24px, 5vh, 64px) 0 clamp(84px, 11vh, 116px);
  overflow-y: auto;
  overscroll-behavior: contain;

  visibility: hidden;
  opacity: 0;
  transition: opacity 240ms var(--ease-out), visibility 0s linear 240ms;
}
.slide[data-here] {
  visibility: visible;
  opacity: 1;
  transition: opacity 240ms var(--ease-out), visibility 0s linear 0s;
}

/* A slide that scrolls is a slide that did not fit, and on a deck that reads
   as a fault rather than a feature. Scrolling stays available for a short
   window or a long slide, but nothing should need it at a normal size. */
.slide-in {
  width: var(--shell);
  margin-inline: auto;
  max-width: 100%;
}

/* Content arrives in order rather than all at once. Transform and opacity
   only, so it stays off the main thread. */
.slide[data-here] .slide-in > * {
  animation: riseIn 460ms var(--ease-out) both;
}
.slide[data-here] .slide-in > *:nth-child(1) { animation-delay: 40ms; }
.slide[data-here] .slide-in > *:nth-child(2) { animation-delay: 85ms; }
.slide[data-here] .slide-in > *:nth-child(3) { animation-delay: 130ms; }
.slide[data-here] .slide-in > *:nth-child(4) { animation-delay: 175ms; }
.slide[data-here] .slide-in > *:nth-child(5) { animation-delay: 220ms; }
.slide[data-here] .slide-in > *:nth-child(6) { animation-delay: 265ms; }
/* Six is the opening slide with the name field on it. Past that the stagger
   stops earning its keep: anything arriving later than about a third of a
   second after the slide turns is just a wait. */

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

@media (prefers-reduced-motion: reduce) {
  .slide { transition: opacity 1ms linear, visibility 0s linear 1ms; }
  .slide[data-here] { transition: opacity 1ms linear, visibility 0s linear 0s; }
  .slide[data-here] .slide-in > * { animation: none; }
}

/* ---- what a slide is made of ------------------------------------------- */

.s-kicker {
  font: 700 0.72rem/1 var(--display);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--quiet);
  margin: 0 0 20px;
}

/* One idea per slide, so the type can be large enough to read across a room.
   This is the whole difference between a deck and a page. */
.s-title {
  font-size: clamp(2.4rem, 1.3rem + 5vw, 5rem);
  line-height: 0.98;
  letter-spacing: -0.04em;
  margin: 0;
  max-width: 15ch;
}
.s-title + .s-line { margin-top: 26px; }

.s-line {
  font-size: clamp(1.05rem, 1rem + 0.55vw, 1.35rem);
  color: var(--quiet);
  max-width: 46ch;
  margin: 0;
}

.s-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
.s-foot { margin: 18px 0 0; font-size: 0.86rem; color: var(--quiet); opacity: 0.9; }

/* ---- the controls ------------------------------------------------------ */

.deck-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px clamp(16px, 4vw, 40px);
  background: linear-gradient(to top, var(--ink-deep) 58%, transparent);
  pointer-events: none;
}
.deck-bar > * { pointer-events: auto; }

.dots { display: flex; gap: 7px; margin-right: auto; }
.dot {
  width: 8px; height: 8px; padding: 0;
  border-radius: 999px;
  border: 0;
  background: color-mix(in oklab, var(--paper) 30%, transparent);
  cursor: pointer;
  transition: background 200ms var(--ease-out), width 200ms var(--ease-out);
}
.dot:hover { background: color-mix(in oklab, var(--paper) 60%, transparent); }
.dot[aria-current="true"] { background: var(--paper); width: 24px; }

.deck-count { font: 400 0.8rem/1 var(--mono); color: var(--quiet); }

.deck-move { display: flex; gap: 8px; }
.deck-btn {
  display: grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: color-mix(in oklab, var(--ink-deep) 82%, var(--paper));
  color: var(--paper);
  cursor: pointer;
  transition: border-color 160ms var(--ease-out), transform 160ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .deck-btn:hover:not(:disabled) { border-color: var(--paper); }
}
/* Instant feedback that the press was heard. */
.deck-btn:active:not(:disabled) { transform: scale(0.94); }
.deck-btn:disabled { opacity: 0.28; cursor: default; }

/* ---- slide layouts ------------------------------------------------------ */

/* On the opening slide the wordmark is the title, so it is the largest thing
   on it and the line underneath supports rather than competes. Everywhere
   else the headline leads, because everywhere else the brand has already been
   established by the bar. */
.s-open .wordmark--big { height: clamp(74px, 13vw, 156px); margin-bottom: 26px; }
.s-open .s-title {
  font-size: clamp(1.5rem, 1.1rem + 1.9vw, 2.5rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  max-width: 20ch;
}
.s-open .s-title + .s-line { margin-top: 14px; }

/* The commands, given room to be the picture rather than a footnote. */
.s-cmds {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-top: 6px;
}
.s-cmds code {
  font: 400 clamp(0.92rem, 0.88rem + 0.25vw, 1.08rem)/1.5 var(--mono);
  background: color-mix(in oklab, var(--ink-lift) 74%, transparent);
  border: 1px solid color-mix(in oklab, var(--edge) 50%, transparent);
  border-radius: 10px;
  padding: 15px 17px;
  color: var(--paper);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.s-cmds code b { color: var(--cyan); font-weight: 400; }

/* The screenshot is the slide. Nothing competes with it.

   It has to fit the height, not just the width. Sized on width alone it came
   out 737 tall in a slide with about 650 to give, so the one slide made of a
   single picture was the one slide you had to scroll. Bounded by both, and the
   picture keeps its shape. */
.s-shot .slide-in {
  width: min(1560px, 96vw);
  display: flex; flex-direction: column; align-items: center;
  max-height: 100%;
}

/* This slide is a picture, so it gets the room a picture wants: the padding
   every other slide uses is there to keep type off the edges, and type is not
   the problem here. Only the controls at the foot need clearing. */
.slide.s-shot { padding: clamp(14px, 2.5vh, 30px) 0 84px; }
.s-shot figure { min-height: 0; display: flex; flex-direction: column; align-items: center; }
.s-shot img {
  display: block;
  width: auto; max-width: 100%;
  /* Only what is genuinely in the way: the bar above, the controls below, and
     the caption. Two hundred and fifty was a guess and it cost half the
     picture. */
  height: auto; max-height: calc(100dvh - var(--bar-h, 64px) - 132px);
  border-radius: 12px;
  border: 1px solid color-mix(in oklab, var(--edge) 60%, transparent);
  box-shadow: 0 30px 70px -34px oklch(0 0 0 / var(--shadow, 0.9));
}
.s-shot figcaption { margin-top: 14px; font-size: 0.9rem; color: var(--quiet); text-align: center; }

.s-three { display: grid; gap: clamp(22px, 3vw, 40px); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); margin-top: 12px; }
.s-three > div { padding-top: 18px; border-top: 2px solid var(--cyan); }
.s-three h3 { font-size: 1.15rem; margin: 0 0 7px; }
.s-three p { margin: 0; color: var(--quiet); font-size: 0.95rem; }

.s-where { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); margin-top: 12px; }
.s-where .place h3 { font-size: 1.05rem; margin: 0 0 6px; }
.s-where .place p { margin: 0 0 14px; font-size: 0.92rem; }

/* Where it stands: two words and a phrase, not a paragraph in a cell. */
.s-state { display: grid; gap: 1px; margin-top: 14px; background: color-mix(in oklab, var(--edge) 34%, transparent); border-radius: 12px; overflow: hidden; }
.s-state div {
  display: grid; grid-template-columns: minmax(110px, 20%) 1fr; gap: 18px;
  padding: 16px 18px; background: var(--ink-deep);
}
.s-state dt { font: 700 0.82rem/1.4 var(--display); letter-spacing: 0.04em; text-transform: uppercase; color: var(--cyan); margin: 0; }
.s-state dd { margin: 0; color: var(--quiet); font-size: 0.96rem; }
.s-state div:nth-child(3) dt, .s-state div:nth-child(4) dt { color: var(--quiet); }

.s-price { font: 700 clamp(4rem, 2.5rem + 8vw, 9rem)/0.9 var(--display); letter-spacing: -0.05em; margin: 0; }

@media (max-height: 640px) {
  .slide { place-items: start center; }
  .s-title { font-size: clamp(1.8rem, 1.2rem + 3vw, 2.6rem); }
  .s-price { font-size: clamp(3rem, 2rem + 5vw, 5rem); }
}

.deck-page .foot { display: none; }
.deck-page { overflow: hidden; }
