img_optimize() decodes .jxl with djxl or Imagick, resizes with GD, re-encodes
with cjxl and writes foto.jxl.webp beside it; skips cleanly without a decoder.
Gallery, hero, navbar logos and JSON-LD serve the JXL with the fallback, and
trash/removal move the fallback with its .jxl.
- «Conhece as nossas instalações» (e a galeria do CrossFit) passa de slider
Splide a masonry: layout próprio em JS (sem biblioteca), fotos com a
proporção original, coluna mais baixa primeiro e algumas a ocupar duas
colunas (só quando não deixam buraco). Reorganiza ao mudar de largura
(ResizeObserver + resize) e as fotos entram em cascata ao aparecer.
Sem JS fica uma grelha CSS.
- Clicar abre a foto num <dialog>: anterior/seguinte, setas, Esc, deslizar.
- O Splide deixa de ser carregado (CSS e JS).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Horário de aulas: cartões mais pequenos e estreitos; a partir de 992px mostra
o dia anterior, hoje ao centro e o seguinte (a dar a volta à semana), com as
horas alinhadas e os dias laterais esbatidos. O JPG continua a semana toda.
- Horário de funcionamento: cartões compactos numa <dl>, ordenados por hora.
- Equipa: fundo no cinzento da parede do ginásio com juntas de blocos e grão
muito discretos (SVG inline).
- Tira o «FitMe 3070» do header e esconde a newsletter.
- Estrutura: um <main> em todas as páginas públicas (skip link aponta-lhe),
h2 por secção com aria-labelledby, h3 nos itens em vez de h4, sem secções
aninhadas, alts distintos na galeria e no h1 do CrossFit.
- robots.txt e sitemap.xml gerados com o domínio da instalação; SEO_NOINDEX
no .env tira uma cópia de staging dos motores de pesquisa.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plain-PHP fleet platform with id.andmore.pt SSO. Wires shared/platform-tools
as a submodule (platform_update, backups, git/migration tools) like the other
platforms.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>