:root {
  /* Diâmetro do disco numerado; o trilho pontilhado se alinha por ele. */
  --disco: 2.6rem;
  --trilho: .16rem;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}


main {
  width: min(100% - 2rem, var(--largura-pagina));
  margin-inline: auto;
}

/* ---------------------------------------------------------------- capa --- */

/*
  A ordem é `sobrelinha, titulo, lema, fatos, acao, arte`: quem chega aqui pelo
  QR do panfleto está no festival e precisa, nesta ordem, saber que caiu na
  página certa, o que é, quando e como saber o valor, e só então o botão. A
  ordem do DOM é a mesma da leitura visual em todas as larguras.

  A sobrelinha nomeia o evento porque o h1 fala do produto, não do HackTown, e
  ela é o único lugar do corpo visível onde o nome do festival aparece.
*/
.capa {
  display: grid;
  grid-template-areas:
    "sobrelinha"
    "titulo"
    "lema"
    "fatos"
    "acao"
    "arte";
  gap: 0;
  padding-block: 1.5rem 2.5rem;
}

/* Roxo da campanha sobre o papel: 9,15:1, passa também em corpo pequeno. */
.capa-sobrelinha {
  grid-area: sobrelinha;
  margin-bottom: .5rem;
  color: var(--evento-roxo);
  font-family: var(--sans);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .22em;
  line-height: 1.2;
  text-transform: uppercase;
}

/* Envolve por causa dos dois blocos: juntos passam da largura do celular. */
.capa-fatos {
  grid-area: fatos;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem 1rem;
}

/*
  A margem inferior é maior que a folga óptica aparente porque `line-height`
  .84 deixa o descendente do "g" de "to go" fora da caixa de linha. Com o lema
  logo abaixo do título, essa sobra precisa ser reservada.
*/
h1 {
  grid-area: titulo;
  margin-bottom: 1.9rem;
  font-size: clamp(4rem, 21vw, 9rem);
  font-weight: 560;
  font-variation-settings: "SOFT" 60, "WONK" 1;
  letter-spacing: -.05em;
  line-height: .84;
}

.capa-lema {
  grid-area: lema;
  margin: -1rem 0 1.4rem;
  color: var(--traco);
  font-size: 1.3rem;
  font-weight: 560;
  font-variation-settings: "SOFT" 40, "WONK" 1;
  line-height: 1.25;
}

h1 em {
  display: block;
  color: var(--terracota);
  font-style: italic;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  letter-spacing: -.03em;
}

.capa-arte {
  grid-area: arte;
  margin: 1.4rem 0 0;
}

.capa-arte img {
  display: block;
  width: 100%;
  border-radius: .9rem;
}

/*
  As duas etiquetas de fato dizem, não convidam: ficam em creme com filete,
  para que a única forma cheia da primeira tela seja o botão da campanha.
  Cheias em terracota, elas tinham mais cara de botão que o botão e o visitante
  do QR tocava numa caixa que não leva a lugar nenhum.
*/
.periodo {
  margin: 0;
  padding: .55rem .95rem;
  border: 1px solid color-mix(in srgb, var(--traco) 30%, transparent);
  border-radius: .6rem;
  background: var(--creme);
  color: var(--traco);
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
  text-wrap: balance;
}

/*
  Não publicamos valor: quem decide preço é a Rafa, na conversa. A caixa diz
  onde perguntar, ao lado da data, no mesmo par de fatos. O traço sobre o
  creme mede 7,79:1, então o corpo aqui não precisa ser grande.
*/
.preco {
  flex: none;
  margin: 0;
  padding: .55rem .95rem;
  border: 1px solid color-mix(in srgb, var(--traco) 30%, transparent);
  border-radius: .6rem;
  background: var(--creme);
  color: var(--traco);
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
}

/*
  A ação da capa é o botão da campanha, e é a única forma cheia e clicável da
  primeira tela: antes ela era um link sublinhado, e a etiqueta da data tinha
  mais cara de botão que o próprio botão. O `.botao` traz caixa, alvo de toque
  e contraste; aqui fica só o que a capa acrescenta, as duas linhas empilhadas.
*/
.acao-capa {
  grid-area: acao;
  flex-direction: column;
  align-items: flex-start;
  align-self: start;
  justify-self: start;
  gap: .1rem;
  margin-top: 1.1rem;
}

/* ------------------------------------------------------------ percurso --- */

.percurso-secao {
  padding-block: 1rem 2.5rem;
}

.percurso {
  --vao: 2.75rem;
  position: relative;
  display: grid;
  gap: var(--vao);
  margin: 0;
  padding: 0;
  list-style: none;
}

/*
  Trilho pontilhado ligando 1 a 4. No empilhamento ele é um segmento por
  etapa, de um disco até o próximo: desenhá-lo como uma linha única no `ol`
  faria a ponta descer até o fim do texto da etapa 4, bem abaixo do disco 4.
  A partir de 62rem vira uma linha só, atravessando a fileira na horizontal.
*/
.etapa:not(:last-child)::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: var(--disco);
  bottom: calc(-1 * var(--vao));
  left: calc(var(--disco) / 2 - var(--trilho) / 2);
  width: var(--trilho);
  background-image: repeating-linear-gradient(
    to bottom,
    color-mix(in srgb, var(--verde) 62%, transparent) 0 .35rem,
    transparent .35rem .8rem
  );
  background-size: 100% .8rem;
}

/*
  `align-content: start` é obrigatório aqui. Na fileira de quatro colunas, a
  linha do `ol` tem a altura da etapa mais longa e estica as demais; sem isso
  o grid distribui a sobra pelas linhas automáticas de cada etapa e as quatro
  ilustrações param em alturas diferentes, com até 42px de defasagem.
*/
.etapa {
  position: relative;
  z-index: 1;
  display: grid;
  align-content: start;
  grid-template-columns: var(--disco) minmax(0, 1fr);
  grid-template-areas:
    "numero arte"
    ".      texto";
  column-gap: 1rem;
  row-gap: .9rem;
  align-items: start;
}

.etapa-numero {
  grid-area: numero;
  display: grid;
  place-items: center;
  width: var(--disco);
  height: var(--disco);
  margin: 0;
  border: .28rem solid var(--papel);
  border-radius: 50%;
  background: var(--verde);
  color: var(--papel);
  font-family: var(--sans);
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1;
}

/*
  Sem moldura: a borda fechava a gravura sozinha e a separava do texto a que
  ela pertence. A proporção é 1/1 em toda largura, igual ao arquivo de
  720×720, para que a série tenha um enquadramento só.
*/
.etapa-arte {
  grid-area: arte;
  margin: 0;
}

.etapa-arte img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.etapa-texto {
  grid-area: texto;
}

.etapa h3 {
  margin-bottom: .3rem;
  color: var(--traco);
  font-family: var(--sans);
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .18em;
  line-height: 1.2;
  text-transform: uppercase;
}

.etapa-chamada {
  margin-bottom: .7rem;
  font-size: 1.35rem;
  font-variation-settings: "SOFT" 40, "WONK" 1;
  font-weight: 560;
  line-height: 1.2;
  text-wrap: pretty;
}

.etapa-nota {
  margin: 0;
  color: color-mix(in srgb, var(--tinta) 82%, var(--papel));
  font-family: var(--sans);
  font-size: .88rem;
  line-height: 1.4;
}

.opcoes {
  display: grid;
  gap: .42rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.opcoes li {
  position: relative;
  padding-left: 1.05rem;
  color: var(--traco);
  font-size: 1.06rem;
  font-weight: 600;
  line-height: 1.3;
}

.opcoes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: .42rem;
  height: .42rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--terracota) 78%, transparent);
}

/* ---------------------------------------------------------- tem também --- */

/*
  Sem caixa e sem fundo próprio: o creme do PNG do ramo é exatamente o papel
  da página, então qualquer fundo tingido aqui viraria um retângulo visível
  em volta da ilustração.
*/
.tem-tambem {
  position: relative;
  display: grid;
  grid-template-columns: 5rem minmax(0, 1fr);
  align-items: center;
  gap: .75rem;
  margin-block: .5rem;
  padding-block: 1.6rem;
  border-block: 1px solid var(--linha);
}

.ramo {
  width: 5rem;
}

.titulo-secao,
.tem-tambem h2,
.pedir h2 {
  margin-bottom: .35rem;
  font-size: clamp(1.7rem, 7vw, 2.3rem);
  font-weight: 570;
  font-variation-settings: "SOFT" 45, "WONK" 1;
  line-height: 1.05;
}

/* O título do kit abre uma lista longa e pede mais respiro que os demais. */
.titulo-secao {
  margin-bottom: 1.5rem;
}

.tem-tambem h2 {
  color: var(--traco);
}

.tem-tambem p {
  margin: 0;
  font-size: 1.06rem;
  text-wrap: pretty;
}

/* --------------------------------------------------------------- pedir --- */

/* Margem de topo curta: o bloco vem logo abaixo da capa, que já tem recuo. */
.pedir {
  margin-block: 1rem;
  padding: 1.75rem 1.35rem;
  border-radius: 1rem;
  background: var(--traco);
  color: var(--papel);
}

.pedir h2 {
  color: var(--papel);
}

dl {
  display: grid;
  gap: .9rem;
  margin: 1.3rem 0 1.6rem;
}

dt {
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: .82;
}

dd {
  margin: .15rem 0 0;
  font-size: 1.04rem;
  text-wrap: pretty;
}

/*
  Contraste: o terracota mede 4,37:1 sobre o papel, então o rótulo vai em
  1,2rem/800 (19,2px em negrito), que é texto grande e pede 3:1; o número,
  que é miúdo, fica na tinta.

  Por isso o fundo do botão não muda no hover. Invertê-lo para terracota
  levaria o número a 4,37:1 em corpo pequeno, abaixo do mínimo, e invertê-lo
  para o traço faria o botão sumir dentro do cartão, que já é traço. O estado
  ativo aparece por anel e elevação, sobre a mesma base clara.
*/
.acao-principal {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .1rem;
  min-height: 4.2rem;
  padding: .9rem 1.15rem;
  border-radius: .7rem;
  background: var(--papel);
  color: var(--terracota);
  font-family: var(--sans);
  font-size: 1.2rem;
  font-weight: 800;
  line-height: 1.25;
  text-decoration: none;
  box-shadow: 0 0 0 0 var(--terracota);
  transition: box-shadow 180ms ease, transform 180ms ease;
}

.acao-principal span {
  display: block;
}

.acao-principal small {
  color: color-mix(in srgb, var(--tinta) 85%, var(--papel));
  font-size: .82rem;
  font-weight: 750;
  white-space: nowrap;
}

.acao-principal:hover {
  box-shadow: 0 0 0 .28rem var(--terracota);
}

/* Sobre o cartão traço, o anel de foco precisa ser claro para se destacar. */
.acao-principal:focus-visible {
  outline-color: var(--papel);
}

/* Papel sobre traço mede 8,9:1; a .82 de opacidade fica em 6,6:1. */
.pedir-ressalva {
  margin: .7rem 0 0;
  font-family: var(--sans);
  font-size: .82rem;
  line-height: 1.4;
  opacity: .82;
}

/* ------------------------------------------------------------ desktop --- */

@media (min-width: 46rem) {
  .capa {
    grid-template-areas:
      "sobrelinha arte"
      "titulo     arte"
      "lema       arte"
      "fatos      arte"
      "acao       arte";
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    grid-template-rows: auto auto auto auto 1fr;
    align-items: start;
    column-gap: 2.5rem;
    padding-block: 1.5rem 3.5rem;
  }

  .capa-arte {
    align-self: center;
    margin: 0;
  }

  h1 {
    font-size: clamp(4.4rem, 9.5vw, 7.4rem);
    margin-bottom: 2.6rem;
  }

  .capa-fatos {
    align-self: start;
    gap: 1.25rem;
  }

  .tem-tambem {
    grid-template-columns: 7.5rem minmax(0, 1fr);
    gap: 1.25rem;
    padding-block: 2.25rem;
  }

  .ramo {
    width: 7.5rem;
  }

  .acao-principal {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
  }

  .pedir {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(19rem, .8fr);
    align-items: end;
    gap: 2.5rem;
    padding: 2.25rem;
  }

  .pedir-acao {
    align-self: end;
  }

  dl {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.5rem;
    margin-bottom: 0;
  }
}

@media (min-width: 62rem) {
  .percurso-secao {
    padding-block: 1rem 4rem;
  }

  .percurso {
    --vao: 2rem;
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  /*
    Na fileira, um trilho só, do centro do disco 1 ao centro do disco 4. O
    recuo é metade de uma coluna, e a coluna já desconta os três vãos: por
    isso `(100% - 3 * vão) / 8`, e não 12,5%. Com a porcentagem crua o trilho
    nasceria doze pixels à direita do disco 1 em 1440px, e o erro mudaria de
    tamanho a cada largura de tela.
  */
  .etapa:not(:last-child)::before {
    content: none;
  }

  .percurso::before {
    content: "";
    position: absolute;
    z-index: 0;
    top: calc(var(--disco) / 2 - var(--trilho) / 2);
    right: calc((100% - 3 * var(--vao)) / 8);
    left: calc((100% - 3 * var(--vao)) / 8);
    height: var(--trilho);
    background-image: repeating-linear-gradient(
      to right,
      color-mix(in srgb, var(--verde) 62%, transparent) 0 .35rem,
      transparent .35rem .8rem
    );
    background-size: .8rem 100%;
  }

  .etapa {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "numero"
      "arte"
      "texto";
    justify-items: center;
    row-gap: 1.1rem;
    text-align: center;
  }

  .etapa-arte,
  .etapa-texto {
    width: 100%;
  }

  .opcoes li {
    padding-left: 0;
    padding-top: .95rem;
  }

  .opcoes li::before {
    left: 50%;
    top: .25rem;
    translate: -50% 0;
  }

  .etapa-chamada {
    text-wrap: balance;
  }
}

@media (min-width: 76rem) {
  h1 {
    font-size: 7.8rem;
  }
}

/* ---------------------------------------------------------- movimento --- */
/*
  Todo o movimento vive aqui dentro. Com prefers-reduced-motion a página não
  tem nenhuma animação e nenhum estado inicial escondido.

  A entrada por rolagem usa `animation-timeline: view()`, que é CSS puro e não
  depende de script para o caso mais comum. O estado inicial invisível fica
  dentro de um `@supports` — em navegador sem timeline de rolagem a seção
  aparece pronta, nunca em branco.
*/

@media (prefers-reduced-motion: no-preference) {
  .capa > * {
    animation: surgir 700ms cubic-bezier(.22, .68, .3, 1) both;
  }

  .capa h1 { animation-delay: 60ms; }
  .capa .capa-lema { animation-delay: 120ms; }
  .capa .capa-fatos { animation-delay: 160ms; }
  .capa .acao-capa { animation-delay: 240ms; }
  .capa .capa-arte { animation-delay: 340ms; }

  /*
    O trilho anda três vezes na chegada e para. Em loop infinito ele era
    movimento sem informação, e mantinha uma camada composta viva o tempo
    todo junto com as seis gravuras que flutuavam.
  */
  .etapa:not(:last-child)::before,
  .percurso::before {
    animation: caminhar 1.5s linear 3;
  }

  .acao-principal:hover {
    transform: translateY(-2px);
  }

  @supports (animation-timeline: view()) {
    /*
      A faixa fica inteira dentro de `entry` e fecha aos 55%. Misturar `entry`
      com `cover` produzia uma faixa que as últimas seções da página nunca
      alcançavam: no fim da rolagem, "Tem também" e "Como pedir" ficavam em
      opacidade zero, invisíveis. Terminando em `entry`, a animação fecha
      assim que o elemento entra na viewport, que é sempre alcançável.
    */
    .etapa,
    .tem-tambem,
    .pedir {
      animation: surgir linear both;
      animation-timeline: view();
      animation-range: entry 5% entry 55%;
    }
  }
}

@keyframes caminhar {
  to {
    background-position: 0 .8rem;
  }
}

@media (min-width: 62rem) {
  @keyframes caminhar {
    to {
      background-position: .8rem 0;
    }
  }
}
