Commit Graph
18 Commits
Author SHA1 Message Date
andre f297e128fd fix(gallery): open lightbox on click and keep mouse drag alive
Pointer capture on pointerdown redirected the click to the strip, so photos
never opened; capture now starts only after a 5px drag. Native link drag is
blocked so it no longer cancels the mouse drag.
2026-10-26 20:40:17 +00:00
andre 4f44bc1609 feat(images): JPEG XL optimizer with webp/jpg fallback and <picture> serving
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.
2026-10-26 11:18:13 +00:00
andre 14dbabcad5 style(site): logo gym buttons without face or glow, gallery off scroll hover, Mensalidades brand glow 2026-10-26 09:59:51 +00:00
andreandClaude Sonnet 5.5 3d2a696162 fix(site): restore CSS lost in 6c14e64; gallery click-and-drag; no link underline + colour/glow hover; brand-colour CrossFit pill; lighter trial link; no gloss on team photos
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 18:49:53 +01:00
andreandClaude Sonnet 5.5 6c14e644b1 feat(site): auto-scrolling gallery strip (full-height + 2x2), centre-of-screen hover state, trial link as text under the hero button
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 18:44:31 +01:00
andreandClaude Sonnet 5 4bf177289a feat(site): horário — esconde botão ao abrir, setas no desktop, swipe no telemóvel
- "Ver Horário das aulas" desaparece assim que o acordeão abre (clique no
  próprio botão ou o link "Horário" da navbar a abrir por JS) — deixa de
  ficar um botão grande por cima da grelha já visível.
- Setas ‹ › junto ao dia em foco também no desktop (vista de 3 dias): só o
  dia central as mostra, os laterais continuam sem elas (já são clicáveis
  diretamente).
- Deslizar no telemóvel/tablet muda de dia, com o mesmo efeito das setas —
  só reage a arrastos maioritariamente horizontais, para não roubar o
  scroll vertical da página.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 11:18:51 +01:00
andreandClaude Sonnet 5 7e2798d0b7 feat(site): informações e contactos sem ícones, horário em texto; entra na frota
- Informações e contactos: os ícones fas ao lado do texto saem (desalinhavam
  em layout centrado — fa-envelope é mais largo que os outros e o texto ficava
  a começar em posições diferentes). Horário de Funcionamento deixa de ser
  cartões (dt/dd com barra escura) e passa a texto simples centrado, uma
  linha por dia, a condizer com o resto da coluna.
- Textarea "Mensagem" deixa de esticar até à base do mapa (chegava a 763px
  de altura, vazio) — volta ao min-height:150px + resize:vertical do CSS.
- CrossFit: removida a secção "A nossa Localização" duplicada, agora que a
  página tem a sua própria secção de Contactos com mapa incluído.
- Reviews: "Ver todas no Google" passa a link de texto simples (sublinhado);
  "Deixa a tua review" mantém-se o botão em destaque.
- api/health.php, api/hub_ops.php, api/hub_pair.php: stubs de uma linha para
  o platform-tools (mesmo padrão da fotografia/design/dance) — preparam a
  entrada do fitme3070 na Frota do hub.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 08:46:49 +01:00
andreandClaude Sonnet 5 65182eecd6 feat(site): horário sem barra de dias em cima, CrossFit ganha contactos
- Horário de aulas (home e CrossFit, mesmo componente partilhado): removida
  a barra de botões Seg/Ter/Qua/Qui/Sex/Sab acima da grelha — o próprio
  cabeçalho do dia (já existente) passa a ser sempre visível (antes só em
  desktop, 3 dias) e ganha setas ‹ › ao lado do nome do dia para mudar de
  dia em ecrãs de telemóvel/tablet. No desktop (3 dias lado a lado) as
  setas ficam escondidas — clicar no dia lateral já muda o dia em foco.
  CSS/JS morto do botão-filtro removido.
- Informações e contactos extraído para site/includes/contactos.php,
  partilhado pela home e pelo CrossFit — a página CrossFit ganha a mesma
  secção de contactos (localização, telefone, e-mail, horário de
  funcionamento, mapa, formulário) em vez de só linkar de volta à home.
  Hero e restantes secções do CrossFit não foram tocados.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 08:19:12 +01:00
andreandClaude Sonnet 5 1e2068bea2 feat(css): site público passa de Bootstrap 4.3.1 (EOL) para 5.3.3
Auditoria: "Site público em Bootstrap 4.3.1 (EOL); backoffice em
5.3.3" — o backoffice já usa a 5.3.3 vendorizada (assets/vendor/bootstrap5/),
o site público passa a usar a mesma cópia em vez da 4.3.1.

Levantamento antes de mexer: a folha de estilo própria (style.css)
quase não usa classes utilitárias cruas do Bootstrap (grep confirma
zero ml-/mr-/pl-/pr-/float-left/float-right/custom-select/
custom-control/badge-/sr-only/font-weight-/text-left/text-right —
tudo classes próprias como .site-btn). O que precisava de mudar:

- CSS/JS: assets/vendor/bootstrap/ -> assets/vendor/bootstrap5/
  (bundle, inclui Popper).
- Os 7 atributos data-toggle/data-target/data-dismiss (BS4) ->
  data-bs-toggle/data-bs-target/data-bs-dismiss (BS5): toggle da nav
  mobile, os dois modais (aula experimental, inscrição), o botão de
  fechar do alerta. O seletor em main.js que lê data-target também
  mudou para não parar de encontrar os botões.
- .close -> .btn-close (BS5 renomeou o componente; markup sem o
  &times; interno, que o BS5 desenha via CSS).
- .form-row -> .row (BS4 tinha form-row com gutters menores; BS5 não
  tem, style.css não tinha overrides para form-row, confirmado).
- O apanhado maior: dois <script> inline chamavam
  jQuery('#trialModal').modal('show') ao estilo de plugin jQuery do
  BS4 (para reabrir o modal depois de um erro de submissão) — o BS5
  não regista plugins jQuery nenhuns, isto ficava morto em silêncio.
  Trocado por new bootstrap.Modal(...).show(), a API JS nativa do
  BS5. grep confirma zero outras chamadas .modal()/.collapse()/etc.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:47:15 +01:00
andre ff1d0fdc07 Site polish: tighter modalidades spacing, less schedule redundancy, plan section styling
- Modalidades: reduce gap between cards
- Horário: drop the day-title above the grid in single-day mode (the active
  day-filter button already names it); restyle "Guardar horário" as a plain
  link and drop the "(JPG)" suffix
- Mensalidades: give "Escolhe o teu plano" the same dark hammered-metal
  background as the reviews/footer sections instead of the plain light one
2026-09-25 13:01:47 +01:00
andreandClaude Opus 5.5 d70f13aea0 feat(galeria): masonry em JS com lightbox, em vez do slider
- «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>
2026-09-25 07:05:25 +01:00
andreandClaude Opus 5.5 cb0e4540f2 feat(modalidades): 6 ícones em falta, ícones animados, ícone centrado no cartão aberto
- Ícones novos (Bootcamp, YourFit Core, Run3070, Total Workout, On Ramp, Jump)
  do mesmo conjunto; só o LPO continua sem ícone no ficheiro de design.
- Os ícones fitme-*.svg passam a ir embutidos (modalidade_icon_html): cada
  traço tem pathLength=1 e desenha-se ao aparecer, no hover e ao abrir o
  cartão; cada família tem um movimento (levantar, soco, respirar, saltar,
  chama, pedalar, correr). Outros ícones continuam <img>.
- No cartão de detalhe (desktop) o ícone e o nome deslizam até ao centro
  vertical da coluna.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:02:58 +01:00
andreandClaude Opus 5.5 0587be7d14 feat: borda verde a rodar nos planos, textura metálica, contactos numa só fonte
- Mensalidades: ao passar o rato, a borda do cartão ganha um brilho verde num
  conic-gradient que roda (@property --pc-a animável), centrado no cursor; o
  cartão inclina-se e desliza para o rato como os da equipa.
- «O que dizem de nós» e rodapé: textura discreta de metal preto mate (grão de
  pintura eletrostática, brilho difuso, riscas quase invisíveis), em SVG/CSS.
- Contactos: o site lê só fitme3070_info (Gestão → Contactos). Os campos
  contact_*/social_* de Sistema → Definições não eram usados e foram editados
  por engano — saem do formulário, com um aviso a apontar para Contactos.
  site_info() deixa o WhatsApp só com dígitos (wa.me não aceita + nem espaços).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:57:15 +01:00
andreandClaude Opus 5.5 ee3fe69afb feat(modalidades): faixa rolável, cartão de detalhe como o da equipa, ícones novos
- A faixa de modalidades passa a ser um scroller a sério: toque, trackpad,
  roda do rato, arrastar e setas; continua a deslizar sozinha (~20px/s) e
  pára enquanto alguém interage, retomando 2,5s depois. Loop infinito sobre
  uma cópia do conjunto (a posição é mantida em float — scrollLeft += 0.3
  arredondava para zero).
- Em vez do «Saber mais», o cartão com descrição abre um painel que nasce do
  próprio cartão e estica para o lado (para a esquerda junto à margem
  direita), com inclinação 3D a seguir o rato; no telemóvel voa para o
  centro com o fundo escurecido. O painel vive fora do scroller para o
  overflow não o cortar.
- 14 ícones novos (SVG, traço 3) em uploads/modalidades/icons/fitme-*.svg.
- Títulos dos cartões em <h3>, h2#modalidades-title + aria-labelledby; sem
  ícone não se gera <img> vazio.
- #modalidades entra só com opacidade: o transform deixado pela animação de
  entrada prendia o fundo escurecido (position:fixed) dentro da secção.
- prefers-reduced-motion: os cartões de detalhe (equipa e modalidades)
  ficam fora da regra global que reduzia as transições a 0,01ms — com ela
  (ativa por defeito em Remote Desktop / Windows sem animações) o cartão
  aparecia de repente em vez de esticar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:47:17 +01:00
andreandClaude Opus 5.5 8ebf20f52f feat: horário em 3 dias, horário de funcionamento compacto, textura na equipa, estrutura/SEO
- 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>
2026-09-24 21:46:21 +01:00
andreandClaude Opus 5.5 90ee2a93bc feat(equipa): o cartão de detalhe nasce da foto, estica e segue o rato
O cartão abre por cima da própria foto (mesmo sítio, tamanho e inclinação),
endireita-se e estica para o lado — para a esquerda nas fotos da ponta
direita — com o texto a entrar por trás. Aberto, inclina-se em 3D e desliza
uns píxeis na direção do rato; ao sair volta a dobrar-se para dentro da foto.
No telemóvel voa da foto para o centro (FLIP) e volta ao fechar.

- clip-path em px calculados no JS: o Chrome não interpola inset() com
  calc(100% - …) e o recorte saltava em vez de esticar.
- O cartão é posicionado sem transição antes de abrir; senão a transição do
  estado fechado arrancava primeiro e a abertura partia de valores antigos.
- Tira o «Saber mais» do cartão da equipa.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:28:32 +01:00
andreandClaude Opus 5.5 f95c9ebc52 feat: contactos editáveis, equipa com título/aptidões, mensalidades e reviews Google
- Contactos: nova página no backoffice (fitme3070_info) e 964 201 137 como
  telefone principal; o telefone secundário só aparece quando existe.
- Equipa: título, aptidões/funções e formações; o cartão mostra foto, nome e
  título e abre um cartão horizontal de detalhe (hover no desktop, toque no
  telemóvel) sem mexer na grelha.
- Mensalidades: cartões editáveis com um destaque, modal de inscrição que
  guarda o pedido (RGPD + estado + campos reservados para o CRM) e avisa o
  ginásio por e-mail; lista de pedidos com estados, notas e CSV.
- Reviews Google via Places API (New), filtradas por classificação mínima e
  em cache configurável; página de configuração com pesquisa do Place ID.
- Assets com ?v=<mtime>: site/assets é servido com cache imutável de 1 ano.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 14:58:57 +01:00
andreandClaude Opus 4.8 e68d357177 Initial import of fitme3070.pt platform
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>
2026-06-12 10:44:58 +01:00