Skip to content

Deck privado ​

/deck é o pitch para investidores e leitores convidados. Não está na navegação pública. Antes do primeiro slide a página pede um e-mail (nome e organização são opcionais). Sem esse passo não há slides: as imagens não ficam em public/.

A página é noindex (meta e cabeçalho X-Robots-Tag) e o robots.txt desautoriza /deck.

O que quem entra vê ​

Um slide por vez, com contador (3 / 11), botões anterior e seguinte, setas do teclado e deslize no telefone. O idioma não segue o do site nem o do navegador. No canto superior direito há um seletor EN | ES. ?lang=es ou ?lang=en ganha; se não vier na URL, usa-se a última escolha guardada no navegador; se não houver nenhuma, o deck abre em inglês. O mesmo seletor traduz a porta. A sessão fica num cookie HttpOnly (futuros_deck) por 14 dias, assinado com HMAC, então não é preciso reescrever o e-mail em cada slide. Não há deck em português.

Onde ficam os e-mails ​

Cada envio válido entra na lista Redis deck:viewers:v1 (Upstash, as mesmas variáveis UPSTASH_REDIS_REST_URL e UPSTASH_REDIS_REST_TOKEN do livro da confiança). Cada linha guarda e-mail, nome e organização se houver, data, user-agent e referrer.

Para lê-los:

  1. Console do Upstash, comando LRANGE deck:viewers:v1 0 -1 (o mais novo fica no fim).
  2. Ou GET /api/deck-access com Authorization: Bearer <DECK_GATE_SECRET>. Sem esse segredo a lista não abre. O cookie de um visitante não lista os outros.
  3. Se o Mailgun já está configurado (MAILGUN_API_KEY, MAILGUN_DOMAIN, MAILGUN_FROM), também sai um e-mail para DECK_NOTIFY_EMAIL ou, se não estiver definida, para marcus@futuros.xyz.

Se o Redis não está configurado, a resposta diz persisted: false. O cookie mesmo assim é emitido, e o evento do PostHog continua levando o e-mail como propriedade da pessoa.

Analítica ​

No domínio de produção o PostHog recebe deck_gate_view, deck_email_submit, deck_slide_view (com slide) e deck_complete. Cada um leva lang (en ou es). Trocar o seletor dispara deck_lang_switch com from, to e slide. O evento do navegador marca via: "client". O servidor manda outro deck_email_submit com via: "api" para um bloqueador não apagar o envio. O aviso por e-mail inclui o idioma no campo Language. O distinct_id é o mesmo pseudônimo sha-256 do resto da plataforma (c_ mais 24 hex), não o e-mail em claro. O e-mail fica como propriedade da pessoa, como na porta de /contribuir.

Variáveis ​

VariávelPara quê
UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKENGuardar a lista deck:viewers:v1. Se não há DECK_GATE_SECRET, o token também assina o cookie.
DECK_GATE_SECRETAssina o cookie e autoriza a lista. 16 caracteres ou mais.
DECK_NOTIFY_EMAILDestino do aviso. Por padrão marcus@futuros.xyz quando o Mailgun já está ativo.
MAILGUN_*As mesmas do resto do produto. Sem elas não há e-mail. A lista no Redis continua sendo o registro.

Os slides ​

Há dois idiomas de slides, as mesmas onze lâminas. O inglês fica em deck-slides/01.webp … 11.webp e é o padrão. O espanhol fica em deck-slides/es/. Um link direto para o espanhol é futuros.xyz/deck?lang=es. /api/deck-slide?n=3&lang=es entrega o arquivo em espanhol e exige o mesmo cookie. Qualquer outro lang volta ao inglês. Cache-Control: private, no-store para a CDN não guardar o slide sem sessão; a chave de cache é a URL completa, inclusive lang.

O PDF em inglês não é publicado. Fica em deck-src/futuros-deck.pdf (imagens achatadas, sem camada de texto). scripts/render-deck-slides.sh o rasteriza para os WebP em inglês (288 dpi, 4× sobre a grade de pontos, 4320×2430, qualidade WebP 100). Esses arquivos não são regenerados a partir de HTML.

A fonte editável do deck em espanhol — e de uma reconstrução em inglês para comparar — é deck-src/html/ (strings.json com os dois idiomas, deck.css). Para rasterizar de novo o espanhol:

bash
bun scripts/render-deck-html.ts es

Isso escreve deck-slides/es/01.webp … 11.webp em 4320×2430. bun scripts/render-deck-html.ts en --out <diretório> escreve uma prova em inglês só nesse diretório, nunca por cima de deck-slides/.

Esses WebP entram no bundle da função (includeFiles: deck-slides/** em vercel.json), não em public/. Se a pasta está vazia, a porta mesmo assim guarda o e-mail e a página diz que não pôde abrir o deck. GET /api/deck-access inclui languages: ["en","es"].

Cada número com sua fonte — a rastreabilidade é o contrato.