Preencha antes de enviar
[nome do servidor][nome do evento][o que é, para quem é, qual edição, duas frases][início e término, fuso horário][nome da organização][e-mail][telefone][se as palestras são gravadas e se são tiradas fotos][domínio][preferência de cor][evento][[NAV]
Use minha conexão com o Opus Growth para isso. Se você não encontrar a ferramenta de que precisa, procure entre as ferramentas do Opus Growth (com search_tools, se estiver na sua lista); se não conseguir acessar as ferramentas de forma alguma, não adivinhe, me avise.
No site [nome do servidor] do meu servidor de hospedagem Opus Growth, crie um site de evento estático e rápido para [nome do evento]. Evento: [o que é, para quem é, qual edição, duas frases]. Data e horário: [início e término, fuso horário]. Local: [nome do local, endereço completo, transporte, estacionamento, instalações de acessibilidade]. Programação: [para cada dia, o horário, o título da sessão, o palestrante e a sala]. Palestrantes: [nome, cargo, organização, título da palestra, bio, link da foto e permissão para publicar a foto]. Ingressos: [ticket types, prices, whether VAT is included, valid dates, the link on the ticketing platform, refund and transfer terms]. Organizador: [nome da organização], [e-mail], [telefone]. Política de gravação e fotos: [se as palestras são gravadas e se são tiradas fotos]. Domínio: [domínio].
Páginas: início (uma linha com data e local, contagem regressiva, breve introdução, o que vai acontecer, quatro dos palestrantes, um resumo do local, FAQ), programação (/program/: abas por dia e um arquivo de calendário .ics), palestrantes (/konusmacilar/), ingressos (/bilet/: tipos de ingresso, o que está incluído, reembolsos, FAQ sobre nota fiscal), local (/mekan/: endereço, transporte, acessibilidade, hospedagem), privacidade (/gizlilik/, incluindo a escolha sobre fotos e gravação) e 404.html.
Estilo: um pôster de conferência. Se nenhuma [preferência de cor] for informada, use uma faixa hero amarelo-sinalização, fundo creme, texto preto e bordas pretas de 2 pixels. Uma fonte larga e em negrito da Fontshare em caixa alta para os títulos (por exemplo Panchang 700) e uma sans arredondada para o texto (por exemplo Chillax 400 e 500); faça preload dos três arquivos da primeira tela. A caixa alta exige `<html lang="tr">`, caso contrário o "i" vira "I". Se um palestrante não tiver foto ou não tiver autorizado a publicação, use um monograma com as iniciais; nunca use a foto de outra pessoa.
Regras de interação (sem biblioteca, um único `ix.js` com defer, somente nas páginas de início, programação e palestrantes):
1. A contagem regressiva fica correta mesmo com JS desativado: o HTML contém o texto "Starts: <time datetime="2027-05-13T09:00:00+03:00">Thursday 13 May 2027, 09.00</time> (Turkey time)" dentro de uma caixa de altura fixa. O JS lê as datas ISO com deslocamento de fuso horário de data-start e data-end com Date.parse e escreve caixas de dia, hora e minuto dentro da mesma caixa. A caixa deve ter a mesma altura nos dois estados (min-height no CSS e uma altura fixa por unidade), caso contrário a primeira tela se desloca. Não exiba segundos; atualize a cada minuto e pare enquanto a aba estiver oculta. As caixas de números ficam com aria-hidden, com uma única frase visualmente oculta para leitores de tela ao lado delas, e sem região live (aria-live), porque seria lida a cada minuto. Quando o evento tiver começado, escreva "happening now"; depois que terminar, escreva "has ended"; nunca mostre números negativos para uma data passada.
2. Abas por dia: no HTML, cada dia é uma seção separada com seu próprio título (id="gun-1", "gun-2") e links para essas seções acima delas; com JS desativado, todos os dias aparecem um sob o outro. O contêiner em volta dos links leva role="group" e um aria-label. O JS os transforma em abas ARIA (tablist, tab, tabpanel, aria-selected, tabindex, teclas de seta, Home e End), seleciona o segundo dia quando a página abre com #gun-2 e atualiza a URL com history.replaceState quando a aba muda, para que um dia possa ser compartilhado como link. Cada sessão é uma linha de lista com um `<time datetime>`: horário, título, um link para a âncora do palestrante na página de palestrantes e a sala; os intervalos têm um fundo separado.
3. Bio do palestrante: no HTML, ela fica em um `<details>` em cada card, para ser legível com JS desativado e pelos mecanismos de busca. O JS intercepta o clique no summary, monta um único `<dialog>`, copia nele o nome, o cargo, o título da palestra e a bio com textContent, abre com showModal e move o foco para o botão "Close"; Esc e um clique no fundo fecham, e o foco volta ao summary. Adicione aria-haspopup="dialog" ao summary. O id de cada card é o slug do palestrante, que é para onde apontam os links da programação.
4. CTA fixo de ingressos: um botão "Get tickets" no cabeçalho no desktop e, no celular, uma barra fixa na parte inferior da tela (data, menor preço e "Get tickets"). A barra é HTML estático no template do rodapé e fica com position: fixed desde a primeira renderização; adicioná-la depois com JS causa mudança de layout. No celular, dê ao body um padding inferior igual à altura da barra para que os últimos links não fiquem escondidos sob ela, adicione `env(safe-area-inset-bottom)` e oculte a barra na página de ingressos por meio de uma classe no body.
5. Arquivo de calendário: `/assets/[evento].ics` baixado a partir da página de programação (VCALENDAR com um VEVENT, DTSTART e DTEND em UTC, SUMMARY, LOCATION, URL, quebras de linha CRLF). Dê ao link o atributo download.
Schema: o mesmo Event (@id /#event) nas páginas de início, programação e ingressos: name, description, startDate e endDate com deslocamento de fuso horário, eventStatus EventScheduled, eventAttendanceMode OfflineEventAttendanceMode, location como um Place com um PostalAddress completo, três imagens nas proporções 1x1, 4x3 e 16x9, organizer, os palestrantes como performer e um array offers (para cada tipo de ingresso name, price, priceCurrency "TRY", availability, validFrom, validThrough para early bird, e a página de vendas como url). O resultado avançado de evento do Google exige location e startDate e não mescla @id entre páginas, então escreva o Event por completo em todas as páginas que o usam; na página de programação, adicione também cada sessão como subEvent. Se o evento for adiado ou cancelado, defina eventStatus como EventPostponed ou EventCancelled em vez de excluir a página. Place na página do local e BreadcrumbList em todas as páginas internas. Patrocinadores, número de participantes ou "esgotado" só devem ser escritos se forem verdadeiros.
Configuração e armadilhas conhecidas (cada uma custou pontos nas medições da demo, não pule nenhuma):
1. Se já houver um site no ar no servidor, avise-me primeiro, porque a configuração sobrescreve index.html e a pasta assets. Mostre a prévia de scaffold_site com confirm=false e chame com confirm=true somente depois que eu aprovar. Em seguida, leia site_design_guide e site_seo_guide. Antes de escrever código, coloque a direção de design (tipografia, cores, grade, elemento marcante, linguagem de movimento e as bibliotecas que NÃO serão carregadas) em um arquivo curto ART.md fora de assets e mostre-o para mim.
2. Compile o Tailwind, não o carregue pela CDN. Instale-o com site_run_command e background=true (`npm i -D tailwindcss@3`) e acompanhe com site_command_status. Os caminhos content em `tailwind.config.js` devem cobrir todos os arquivos HTML, os templates de `_src` e qualquer arquivo JS que escreva classes. `_src/tw.css` contém a linha `@import "../assets/app.css";` mais as três linhas `@tailwind`; compile-o em um único arquivo com `npx tailwindcss -c tailwind.config.js -i _src/tw.css -o assets/site.css --minify`. Remova o script cdn.tailwindcss.com e o tailwind.config inline de todas as páginas e vincule apenas `/assets/site.css`. Recompile após cada alteração no HTML.
3. Hospede as fontes você mesmo. Leia o CSS da família Fontshare escolhida, baixe o woff2 de cada peso separadamente com site_fetch para `assets/fonts/` e escreva as regras @font-face com `font-display: swap` em `assets/app.css`, que é onde o design-check procura uma fonte personalizada. Verifique o nome do font-family no CSS baixado e confirme que a família tem as letras turcas ı, İ, ş e ğ (a Tanker não tem ı). Faça preload de TODOS os pesos usados na primeira tela com `<link rel="preload" as="font" type="font/woff2" crossorigin>`, colocado antes da linha da folha de estilo; se forem mais de três arquivos, use menos pesos. Na demo, um único peso de corpo sem preload levou o LCP no celular a 2,6 segundos e o Performance a 97. A maioria das fontes da Fontshare não tem o símbolo ₺, então escreva os preços com "TL".
4. Faça o menu e o rodapé em HTML estático. Não carregue chrome.js, motion.js nem site.config.js nas páginas. Escreva um pequeno `chrome-stamp.mjs` que leia a lista de navegação de site.config.js e carimbe `_src/header.tpl` e `_src/footer.tpl` entre os marcadores `<!-- nav:start --><!-- nav:end -->` e `<!-- footer:start --><!-- footer:end -->` em todas as páginas, adicionando aria-current="page" ao link ativo. Use placeholders como `[[NAV]]` em vez de `{{...}}` e não dê aos templates a extensão .html, caso contrário o design-check e o seo-check os tratam como páginas inacabadas. Construa o menu mobile com um `<details>` sem JS. Mantenha o nome da empresa, o endereço e o telefone como texto simples no rodapé e faça os links do rodapé e do breadcrumb terem pelo menos 44 pixels de altura.
5. Converta as imagens ao buscá-las com site_fetch: grave a mesma imagem em arquivos separados com resize="480x", "800x" e "1200x", image_format="webp", quality=60 (site_fetch não recorta, então peça a origem na proporção de que você precisa). Dê a cada `<img>` srcset, sizes e width e height que correspondam à proporção real. A imagem que é o elemento LCP da página recebe fetchpriority="high" e não é lazy; todas as outras imagens recebem loading="lazy" decoding="async". Se uma imagem preencher a primeira tela no celular, sirva um recorte menor para o celular com `<picture>`.
6. Adicione `<link rel="icon" href="/favicon.svg" type="image/svg+xml">` a todas as páginas e crie um apple-touch-icon de 180 pixels a partir do logotipo com site_fetch e resize="180x180". Sem um link de favicon, o navegador solicita /favicon.ico, registra um 404 e o Best Practices cai para 96.
7. Regras do validador de HTML: comece cada documento com um `<!DOCTYPE html>` em maiúsculas; cada espaço no texto visível de um link tel: deve ser ` `, inclusive o que vem depois de um prefixo como "Call: 0212..."; não use style=""; dê a todo botão um type; coloque aria-label apenas em landmarks, formulários ou elementos interativos (em um ul ou em uma div sem role, foi um erro); nunca dê o mesmo nome a dois landmarks; não deixe espaços em branco no final das linhas.
8. Não pule níveis de título: em uma página de lista, títulos de card como h3 logo após o h1 derrubaram o Accessibility para 98. Ao reutilizar um card, defina o nível do título por página (h2 em uma página de lista, h3 dentro de uma seção h2).
9. Chame o atributo de movimento de data-reveal (o design-check só reconhece movimento por esse nome). O JS dá o estado inicial oculto apenas aos blocos que ficam abaixo da tela quando a página abre e nunca oculta o conteúdo da primeira tela; use transform, porque esmaecer com opacity reduz a auditoria de contraste. Coloque o atributo no bloco que envolve um título e sua descrição, não só no título; na demo, um título em espera deslizou sobre o parágrafo abaixo dele. Com prefers-reduced-motion: reduce nada é ocultado e as animações ficam desativadas.
SEO, AEO e GEO:
1. Use URLs em estilo de diretório com barra final. Preencha o bloco seo de site.config.js e execute `node seo-stamp.mjs`. Escreva o schema específico de cada página em blocos `<script type="application/ld+json">` separados, vinculados ao grafo base por @id. Não aninhe BreadcrumbList dentro de @graph; mantenha-o em seu próprio bloco, que é a única forma de o seo-check vê-lo.
2. Títulos com no máximo 60 caracteres (o seo-check sinaliza como erro qualquer um abaixo de 25 ou acima de 65), descrições de 130 a 158 caracteres, um h1 por página e pelo menos 150 palavras de conteúdo principal em cada página. Páginas de contato, privacidade e de lista tendem a ficar curtas; acrescente informações específicas da página, não encheção de linguiça.
3. O primeiro parágrafo de cada página responde diretamente à pergunta da página. Escreva FAQs específicas de cada página com `<details>` e marque-as como FAQPage. Mostre o publisher e uma data de "Last updated" em um elemento `<time>`.
4. No robots.txt, escreva sua decisão com o motivo para GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Bingbot e CCBot, e aponte para o sitemap. O sitemap.xml traz datas lastmod reais. O llms.txt contém um resumo preciso do site em duas frases e uma lista das páginas importantes.
5. Sem invenção: não escreva avaliações, notas, prêmios, números de clientes, certificados, horários de funcionamento, coordenadas ou preços sem me perguntar. Deixe totalmente fora do schema qualquer campo que você não conheça.
Gates (em ordem; não diga "pronto" até que todos passem):
1. Com site_run_command, execute `node chrome-stamp.mjs`, o build do Tailwind, `node seo-stamp.mjs`, `node seo-check.mjs` (0 erros, 0 avisos), `node design-check.mjs` (0 erros; justifique qualquer aviso restante) e `npx html-validate "**/*.html"` (0 erros).
2. Veja cada página com site_preview, view="mobile" e view="desktop". O site_preview captura a página com o movimento desativado (reduced-motion); se faltar conteúdo nessa captura, o estado estático está quebrado. Em capturas de página inteira, elementos fixos como uma barra fixa podem aparecer no meio da página e imagens lazy mais abaixo podem aparecer em branco; não conte isso como erro, mas verifique os caminhos delas.
3. Execute core_web_vitals para cada página com strategy="mobile" e strategy="desktop". Critério de aceitação: no celular, Performance de pelo menos 95 (meta de 99 a 100) e Accessibility, Best Practices e SEO 100; no desktop, os quatro em 100. Para uma página que não atingir, use resources=true para encontrar o arquivo que a atrasa, corrija e meça de novo. Depois execute seo_audit na página inicial com strategy="mobile" e runs=2. Nenhum endereço fora do seu próprio domínio pode permanecer na lista de requisições de rede.
4. Sem rolagem horizontal em 360, 390, 768 e 1440 pixels de largura, alvos de toque de pelo menos 44 pixels, sem erros no console.
Verificação de interação: o site_preview não consegue mostrar tempo, abas nem diálogos. Diga-me como verificar que a contagem regressiva mostra a data correta com JavaScript desativado e se transforma em caixas de mesma altura com JS ativado, que /program/#gun-2 abre o segundo dia e que as abas mudam com as teclas de seta, que a bio de um palestrante abre em um modal e o foco volta após o Esc, que no celular a barra de ingressos não cobre os últimos links da página, que o arquivo de calendário chega ao calendário do celular no horário certo e que o Rich Results Test do Google mostra o Event sem erros.
Depois de publicar: faça a prévia da regra `/assets/* Cache-Control: public, max-age=31536000, immutable` com site_headers e aplique-a quando eu aprovar; a partir daí, versione o nome do arquivo sempre que o CSS ou o JS mudar (site-v2.css e assim por diante). Envie o sitemap.xml com gsc_submit_sitemap e verifique a página inicial com gsc_url_inspect. No final, entregue-me: uma tabela de pontuação por página (página, quatro pontuações no celular, quatro no desktop, LCP, CLS), o resultado de cada gate e a lista das correções que você aplicou.