/* ==========================================================================
   Fundamentum · landing page
   Identidade: preto e branco, Helvetica Neue LT Pro (Adobe Fonts), faixas horizontais.
   Página em tema escuro com um único bloco claro (serviços); as faixas da
   marca enquadram a secção da equipa. Toda a página é a preto e branco, incluindo as
   fotografias e os vídeos. Abre com o "E" da marca feito de três faixas de
   vídeo; os trabalhos passam na horizontal enquanto se faz scroll.

   Sistema:
   - Largura fluida. O conteúdo ocupa a largura do ecrã com margens de 4%,
     dos 320 aos 2560 px. Acima de 1440 px, o tamanho de base cresce com o
     ecrã (16 px a 24 px) e, como tudo está em rem, tipografia e espaçamento
     crescem juntos.
   - Tipografia: uma família, escala de razão 1,25 (base 16 px no telemóvel,
     18 px no desktop). Legendas e metadados a 13 px, em caixa normal.
   - Espaçamento: grelha de 8 px (0,5 rem). O meio passo de 4 px só aparece
     dentro de componentes compactos (botões e navegação).
   - Movimento: entradas de 700 ms, sempre desligadas com "reduzir movimento".
   ========================================================================== */

/* A fonte vem do kit ynz5mlj do Adobe Fonts, ligado no <head> de cada página.
   Pesos disponíveis: 100, 200, 300, 400, 500 e 700, com itálicos (não há 600). */

:root {
  color-scheme: dark;

  --black: #0d0d0d;   /* preto do site, um pouco aberto; o #000 da marca fica no favicon */
  --white: #ffffff;
  --g-950: #161616;
  --g-800: #272727;
  --g-600: #4a4a4a;
  --g-400: #8e8e8e;   /* texto secundário sobre preto, AA */
  --g-300: #bdbdbd;   /* corpo sobre preto */
  --g-100: #ececec;

  --bg: var(--black);
  --fg: var(--white);
  --fg-body: var(--g-300);
  --fg-muted: var(--g-400);
  --line: var(--g-800);

  --font: "helvetica-neue-lt-pro", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Escala tipográfica, razão 1,25. Cada passo é fluido entre 375 e 1440 px;
     acima disso cresce com o tamanho de base (ver html). */
  --fs-meta: 0.8125rem;                                        /* 13 px */
  --fs-0: clamp(1rem, 0.956rem + 0.188vw, 1.125rem);           /* 16 a 18 */
  --fs-1: clamp(1.25rem, 1.195rem + 0.235vw, 1.406rem);        /* 20 a 22,5 */
  --fs-name: clamp(1.563rem, 1.339rem + 0.954vw, 2.197rem);    /* 25 a 35 */
  --fs-h2: clamp(1.953rem, 1.432rem + 2.223vw, 3.433rem);      /* 31 a 55 */
  --fs-h1: clamp(2.441rem, 1.79rem + 2.779vw, 4.292rem);       /* 39 a 69 */
  --fs-score: clamp(3.815rem, 3.269rem + 2.328vw, 5.364rem);   /* 61 a 86 */

  /* Espaçamento entre letras, um passo por gama de tamanhos: a Helvetica Neue
     fecha nos tamanhos grandes e abre um pouco nos pequenos. O texto corrido
     (16 a 18 px), os botões e a navegação ficam a 0. */
  --ls-score: -0.04em;     /* números das avaliações, 61 a 86 px */
  --ls-display: -0.03em;   /* títulos de secção, 31 a 55 px */
  --ls-title: -0.02em;     /* nomes da equipa, 25 a 35 px */
  --ls-lead: -0.01em;      /* lead e citações, 20 a 22,5 px */
  --ls-meta: 0.01em;       /* legendas e metadados, 13 px */
  --ls-caps: 0.06em;       /* palavras em maiúsculas, 13 px */

  --container: 2560px;                       /* só limita ecrãs ultralargos */
  --gutter: max(1rem, 4vw);
  --section: clamp(4rem, 9vw, 8rem);         /* respiro vertical das secções */
  --stack: clamp(2rem, 4vw, 3.5rem);         /* do título ao conteúdo */
  --gap-media: clamp(0.5rem, 1.2vw, 1rem);   /* entre fotografias */
  --nav-h: 4rem;
  --to-top: 3rem;                            /* lado do botão "voltar ao topo" */
  --to-top-gap: clamp(1rem, 2.5vw, 2rem);    /* distância do botão ao fundo do ecrã */

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-word: cubic-bezier(0.19, 1, 0.22, 1);   /* saída longa: palavras e linhas de preços (do site da MEAN) */
  --ease-io: cubic-bezier(0.77, 0, 0.175, 1);    /* entra e sai: fotos a abrir (do site da MEAN) */
  --ease-line: cubic-bezier(0.625, 0.05, 0, 1);  /* sublinhados: arranque firme e chegada longa e macia */
  --t-fast: 180ms;
  --t-slow: 700ms;
}

/* O bloco claro inverte os tokens, nunca as regras. */
.theme-light {
  color-scheme: light;
  --bg: var(--white);
  --fg: var(--black);
  --fg-body: #2b2b2b;
  --fg-muted: #666666;   /* 5,7:1 sobre branco */
  --line: var(--g-100);
}

/* Reset ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Tamanho de base: 100% até 1440 px de largura, depois cresce até 150% aos 2560 px. */
  font-size: clamp(100%, 0.3571rem + 0.7143vw, 150%);
  /* Barra de scroll da página: o cursor branco sobre a calha preta. */
  scrollbar-color: var(--white) var(--black);
}
/* O Safari antigo não conhece scrollbar-color: a mesma barra, desenhada à mão. */
@supports not (scrollbar-color: auto) {
  html::-webkit-scrollbar { width: 0.625rem; background: var(--black); }
  html::-webkit-scrollbar-thumb { background: var(--white); border: 2px solid var(--black); }
}
/* No telemóvel e no tablet (ecrã tátil) não há barra de scroll. */
@media (hover: none) and (pointer: coarse) {
  html { scrollbar-width: none; }
  html::-webkit-scrollbar { display: none; }
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-weight: 400;
  font-size: var(--fs-0);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-kerning: normal;            /* o kerning da fonte sempre ligado, também nos tamanhos pequenos */
  overflow-x: clip;
}
img { display: block; max-width: 100%; height: auto; }
figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p, dl, dd, blockquote { margin: 0; }
a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
:focus-visible { outline: 2px solid var(--fg); outline-offset: 4px; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute; left: var(--gutter); top: -100px;
  padding: 0.5rem 1rem; background: var(--white); color: var(--black);
  z-index: 100; text-decoration: none;
}
.skip:focus { top: 0.5rem; }

/* Texto só para leitores de ecrã. */
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* Ao navegar por âncora, o título da secção fica 40 px abaixo da barra fixa. */
section[id] { scroll-margin-top: calc(var(--nav-h) + 2.5rem - var(--section)); }

/* Tipografia --------------------------------------------------------------- */
.h2 {
  font-size: var(--fs-h2);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: var(--ls-display);
  text-wrap: balance;
}
.lead {
  color: var(--fg-body);
  font-size: var(--fs-1);
  line-height: 1.5;
  letter-spacing: var(--ls-lead);
  max-width: 42ch;
}
/* Texto de 13 px: um pouco mais aberto para se ler bem. */
.item__time, .group__title, .services__note,
.team__role, .quote__by, .contact__label, .contact__small, .day dt, .day dd,
.footer__legal, .footer__credit, .page .page__meta { letter-spacing: var(--ls-meta); }
/* Ligações de texto: em repouso, um sublinhado esbatido, para se perceber que são
   ligações. Ao passar o cursor, a linha cheia desenha-se por cima, como no header:
   da esquerda para a direita, devagar e a abrandar no fim; ao sair, recolhe para a
   direita mais depressa. Só o tamanho tem transição: a posição muda de imediato,
   quando a linha está vazia (entrada) ou cheia (saída), e por isso não se vê. */
.link {
  text-decoration: none;
  --uy: 100%;
  background-image: linear-gradient(currentColor, currentColor),
                    linear-gradient(color-mix(in srgb, currentColor 35%, transparent), color-mix(in srgb, currentColor 35%, transparent));
  background-repeat: no-repeat;
  background-position: 100% var(--uy), 0 var(--uy);
  background-size: 0 1px, 100% 1px;
  padding-bottom: 0.125rem;
  transition: background-size 450ms var(--ease-io);
}
.link:hover, .link:focus-visible {
  background-position: 0 var(--uy), 0 var(--uy);
  background-size: 100% 1px, 100% 1px;
  transition: background-size 800ms var(--ease-line);
}

/* Botões -------------------------------------------------------------------
   Ao passar o cursor, uma faixa da cor inversa atravessa o botão da esquerda
   para a direita (o gesto das faixas da marca) e a seta avança. Ao sair, a
   faixa continua e sai pela direita. */
.btn {
  --btn-bg: var(--white);
  --btn-fg: var(--black);
  position: relative; isolation: isolate; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.75rem;
  min-height: 3rem; padding: 0 1.5rem;
  font-weight: 500; font-size: 1rem;
  text-decoration: none; white-space: nowrap;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid var(--btn-bg);
  transition: color 320ms var(--ease), transform 160ms var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: -1px; z-index: -1;
  background: var(--btn-fg);
  transform: scaleX(0); transform-origin: right center;
  transition: transform 520ms var(--ease);
}
.btn::after {
  content: ""; flex: none;
  width: 0.4375rem; height: 0.4375rem;
  border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 420ms var(--ease);
}
.btn--dark { --btn-bg: var(--black); --btn-fg: var(--white); }

/* "Marcar agora" das secções: maior, texto à esquerda e seta à direita. Ao passar
   o cursor, três faixas entram de lados alternados (como as do hero) e enchem o
   botão; a seta sai pela direita e volta a entrar pela esquerda. */
.btn--bands { min-width: 15rem; min-height: 3.5rem; padding: 0 1.5rem; justify-content: space-between; gap: 2rem; transition: color 320ms var(--ease) 120ms, transform 160ms var(--ease); }
.btn--bands::before { display: none; }
.btn__bands { position: absolute; inset: 0; z-index: -1; display: grid; grid-template-rows: repeat(3, 1fr); pointer-events: none; }
.btn__bands i { background: var(--btn-fg); transform: scaleX(0); transform-origin: left center; transition: transform 620ms var(--ease); }
.btn__bands i:nth-child(2) { transform-origin: right center; transition-delay: 80ms; }
.btn__bands i:nth-child(3) { transition-delay: 160ms; }
.btn--bands:focus-visible .btn__bands i { transform: scaleX(1); }
@media (hover: hover) {
  .btn--bands:hover .btn__bands i { transform: scaleX(1); }
  .btn--bands:hover::after { animation: arrow-through 640ms var(--ease) both; }
}
@keyframes arrow-through {
  0%   { transform: translateX(0) rotate(45deg); opacity: 1; }
  40%  { transform: translateX(1.5rem) rotate(45deg); opacity: 0; }
  41%  { transform: translateX(-1.5rem) rotate(45deg); opacity: 0; }
  100% { transform: translateX(0) rotate(45deg); opacity: 1; }
}
.btn[hidden] { display: none; }

@media (hover: hover) {
  .btn:hover { color: var(--btn-bg); }
  .btn:hover::before { transform: scaleX(1); transform-origin: left center; }
  .btn:hover::after { transform: translateX(0.3125rem) rotate(45deg); }
}
.btn:focus-visible { color: var(--btn-bg); }
.btn:focus-visible::before { transform: scaleX(1); transform-origin: left center; }
.btn:active { transform: scale(0.97); }

/* Navegação ---------------------------------------------------------------
   Sem logótipo: as secções e o "Marcar agora", todos como links, à direita.
   Por cima do hero, a barra fica transparente e o logótipo e os links invertem a
   cor do que está por trás (mix-blend-mode: difference), para se lerem sobre as
   zonas claras e escuras dos vídeos. Fora do hero, ou com o menu aberto, é preta
   (classe nav--clear, gerida em js/main.js). */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: var(--black);
  border-bottom: 1px solid var(--g-800);
  transition: background-color 320ms var(--ease), border-color 320ms var(--ease);
}
.nav--clear:not(.nav--open) { background: transparent; border-color: transparent; mix-blend-mode: difference; }
.nav__inner {
  height: var(--nav-h);
  display: flex; justify-content: flex-end;   /* sem logótipo: só os links (ou o botão do menu), à direita */
  align-items: center;
  gap: 1rem;
}
/* Idioma: "PT / EN" no canto esquerdo da barra; o atual a branco, o outro a cinzento. */
.nav__lang { display: flex; align-items: center; gap: 0.75rem; margin-right: auto; font-size: clamp(0.75rem, 0.95vw, 0.9375rem); font-weight: 500; }
.nav__lang a { display: inline-flex; align-items: center; min-height: 2.75rem; text-decoration: none; color: var(--g-400); transition: color var(--t-fast); }
.nav__lang a:hover, .nav__lang a:focus-visible, .nav__lang a[aria-current] { color: var(--white); }
/* Por cima do hero (barra transparente) o seletor fica escondido; aparece quando a
   barra ganha fundo, ao sair do hero, ou com o menu do telemóvel aberto. */
.nav__lang { transition: opacity 320ms var(--ease), visibility 0s; }
.nav--clear:not(.nav--open) .nav__lang { opacity: 0; visibility: hidden; transition: opacity 320ms var(--ease), visibility 0s linear 320ms; }
/* O tamanho e o espaço acompanham a largura do ecrã, para os cinco links caberem
   na zona preta à direita da primeira faixa do hero, com margem até ao vídeo. */
.nav__links { display: flex; justify-content: flex-end; gap: clamp(0.75rem, 1.1vw, 1.5rem); }
.nav__links a {
  display: inline-flex; align-items: center; min-height: 2.75rem;
  text-decoration: none; font-weight: 500; font-size: clamp(0.75rem, 0.95vw, 0.9375rem);
  color: var(--g-400); transition: color var(--t-fast);
}
.nav__links a:hover, .nav__links a:focus-visible { color: var(--white); }
/* No ecrã largo, ao passar o cursor, um sublinhado desenha-se da esquerda para a direita,
   devagar e a abrandar no fim; ao sair, recolhe para a direita mais depressa. */
@media (min-width: 1200px) {
  .nav__links a { position: relative; }
  .nav__links a::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0.5rem; height: 1px;
    background: currentColor; transform: scaleX(0); transform-origin: right center;
    transition: transform 450ms var(--ease-io);
  }
  .nav__links a:hover::after, .nav__links a:focus-visible::after {
    transform: scaleX(1); transform-origin: left center;
    transition: transform 800ms var(--ease-line);
  }
}
.nav__actions { display: none; align-items: center; justify-self: end; gap: 0.75rem; }   /* só tem o botão do menu, que só existe no telemóvel */
/* Botão do menu no telemóvel: três riscas que passam a um X, em dois tempos.
   Ao abrir, as riscas de cima e de baixo juntam-se ao centro e depois rodam;
   a do meio (o fundo do próprio elemento) encolhe e sai pela direita enquanto
   elas se juntam. Ao fechar, o X desfaz-se, as riscas afastam-se e a do meio
   volta a entrar pela esquerda (o gesto das faixas dos botões). Movimento e
   rotação usam as propriedades translate e rotate em separado, cada uma com o
   seu tempo. A margem negativa alinha as riscas com a margem do conteúdo. */
.nav__toggle { display: none; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; margin-right: -0.625rem; }
.nav__bars {
  position: relative; display: block; width: 1.5rem; height: 0.125rem;
  background: linear-gradient(currentColor, currentColor) no-repeat left center / 100% 100%;
  transition: background-size 300ms var(--ease) 300ms;
}
.nav__bars::before, .nav__bars::after {
  content: ""; position: absolute; left: 0; width: 100%; height: 100%;
  background: currentColor;
  transition: rotate 200ms var(--ease), translate 220ms var(--ease) 180ms;
}
.nav__bars::before { top: -0.4375rem; }
.nav__bars::after { top: 0.4375rem; }
.nav--open .nav__bars { background-position: right center; background-size: 0 100%; transition: background-size 200ms var(--ease); }
.nav--open .nav__bars::before,
.nav--open .nav__bars::after { transition: translate 200ms var(--ease), rotate 280ms var(--ease) 180ms; }
.nav--open .nav__bars::before { translate: 0 0.4375rem; rotate: 45deg; }
.nav--open .nav__bars::after { translate: 0 -0.4375rem; rotate: -45deg; }

/* Abaixo dos 1200 px os cinco links já não cabem ao lado da primeira faixa do
   hero: passam para o menu das três riscas. */
@media (max-width: 1199px) {
  .nav__toggle { display: inline-flex; }
  .nav__actions { display: flex; }
  .nav__lang { font-size: 0.9375rem; }
  /* O painel abre de cima para baixo, como uma cortina, e as linhas entram uma
     a uma. Fechado fica invisível (visibility), por isso os links não recebem
     foco. Ao fechar recolhe mais depressa do que abre. */
  .nav__links {
    display: flex;
    position: absolute; left: 0; right: 0; top: var(--nav-h);
    flex-direction: column; gap: 0;
    background: var(--black); border-bottom: 1px solid var(--g-800);
    padding: 0.5rem var(--gutter) 1rem;
    visibility: hidden; clip-path: inset(0 0 100% 0);
    transition: clip-path 320ms var(--ease), visibility 0s linear 320ms;
  }
  .nav--open .nav__links { visibility: visible; clip-path: inset(0); transition: clip-path 520ms var(--ease), visibility 0s; }
  .nav__links > * { opacity: 0; transform: translateY(-0.5rem); transition: opacity 160ms var(--ease), transform 160ms var(--ease), color 320ms var(--ease); }
  .nav--open .nav__links > * {
    --d: calc(100ms + var(--i, 0) * 45ms);   /* só a entrada de cada linha tem atraso; a cor não */
    opacity: 1; transform: none;
    transition: opacity 360ms var(--ease) var(--d), transform 480ms var(--ease) var(--d), color 320ms var(--ease);
  }
  .nav__links > :nth-child(2) { --i: 1; }
  .nav__links > :nth-child(3) { --i: 2; }
  .nav__links > :nth-child(4) { --i: 3; }
  .nav__links > :nth-child(5) { --i: 4; }
  .nav__links a { padding: 1rem 0; font-size: 1.25rem; border-top: 1px solid var(--g-800); }
}
@media (max-width: 899px) {
  :root { --to-top: 2.75rem; }
}

/* Hero ----------------------------------------------------------------------
   O "E" da marca: três faixas de vídeo desencontradas, com os cortes do manual
   a 34,4% e 65,6% da largura. Sem texto; o título existe só para leitores de
   ecrã. Ocupa o ecrã inteiro e começa por trás da barra (margem negativa).
   As unidades de contentor (cqw, cqh) medem o próprio hero. */
.hero {
  position: relative; container-type: size;
  height: 100dvh; min-height: 32rem;
  margin-top: calc(-1 * var(--nav-h) - 1px);   /* 1px: a linha de baixo da barra */
}
.hero .bar { position: absolute; margin: 0; overflow: hidden; background: var(--g-950); }   /* .hero: ganha a .clip { position: relative } */
.bar img, .bar video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); }
.bar--a { top: 0; height: 30cqh; left: 0; width: 65.6cqw; }
.bar--b { top: 35cqh; height: 30cqh; left: 34.4cqw; right: 0; }
.bar--b img, .bar--b video { object-position: 50% 15%; }   /* perto do topo: a cara do Rui inteira e, no perfil do cliente, o cabelo todo */
.bar--c { top: 70cqh; height: 30cqh; left: 0; width: 65.6cqw; }
.bar--c img, .bar--c video { object-position: 50% 58%; }   /* o salão vazio, da altura das paredes de musgo até às cadeiras */

@media (max-width: 899px) {
  /* No telemóvel as faixas empilham e dividem a altura do ecrã entre si. */
  .hero { container-type: normal; height: 100svh; min-height: 30rem; display: flex; flex-direction: column; gap: 0.5rem; }
  .hero .bar { position: relative; inset: auto; flex: 1; width: 85%; height: auto; }
  .hero .bar--b { margin-left: 15%; }
}

/* Faixas da marca ----------------------------------------------------------
   Padrão do manual: três linhas que se repetem. Cada linha é metade preta,
   metade branca, com cortes a 34,4% e 65,6% da largura. Fazem a passagem do
   hero para os serviços e dos serviços para os trabalhos, e enquadram a equipa. */
.bands { display: grid; background: var(--white); overflow: hidden; }
.band { position: relative; height: clamp(1rem, 2.4vw, 2rem); background: var(--white); }
.band i { position: absolute; inset: 0; background: var(--black); }
.band--a i { left: 65.6%; }
.band--b i { left: 0; }
.band--c i { right: 65.6%; }

/* Serviços ---------------------------------------------------------------- */
.services { background: var(--bg); color: var(--fg); padding-block: var(--section); }
.services__grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
}
.services__intro { position: sticky; top: calc(var(--nav-h) + 2rem); }
.services__intro .lead { margin-top: 1.5rem; }
.services__intro .btn { margin-top: 2rem; }

.group + .group { margin-top: clamp(2rem, 3vw, 2.5rem); }
.group__title {
  font-size: var(--fs-meta); font-weight: 500;
  color: var(--fg-muted);
  padding-bottom: 0.5rem; border-bottom: 1px solid var(--fg);
}
/* Colunas de largura fixa: em todas as linhas, a duração começa no mesmo sítio
   e o preço ocupa a mesma caixa, alinhado à direita. */
.group__items { padding-top: 0.5rem; }
.group__items li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 6rem 3.5rem;
  gap: 0.5rem 1.5rem;
  align-items: baseline;
  padding: 0.5rem 0;
  font-size: var(--fs-0);          /* lista compacta: nomes e preços ao tamanho do corpo de texto */
}
.item__name { font-weight: 500; }
.item__time { color: var(--fg-muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.item__price { font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; }
.services__note { margin-top: 2rem; color: var(--fg-muted); font-size: var(--fs-meta); max-width: 60ch; }

@media (max-width: 899px) {
  .services__grid { grid-template-columns: 1fr; }
  .services__intro { position: static; }
  .group__items li { grid-template-columns: minmax(0, 1fr) 3.5rem; grid-template-areas: "name price" "time price"; gap: 0 1rem; }
  .item__name { grid-area: name; }
  .item__time { grid-area: time; }
  .item__price { grid-area: price; align-self: start; }
}

/* Trabalhos ----------------------------------------------------------------
   Uma fila de cortes. Em ecrãs largos, com suporte para animações ligadas ao
   scroll, a secção fica presa ao ecrã e a fila anda para a esquerda; --travel
   (quanto tem de andar) é medido em js/main.js. Sem suporte, no telemóvel ou
   com "reduzir movimento", a fila desliza com o dedo ou com a barra.
   O preto e branco é dado por CSS: as fotos e os vídeos originais estão a cores. */
.pan__sticky { padding-block: var(--section); }
.pan__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: 1rem 3rem; }
.pan__track {
  display: flex; gap: var(--gap-media); margin-top: var(--stack);
  padding-inline: var(--gutter); overflow-x: auto;
  scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: none;
}
.pan__track::-webkit-scrollbar { display: none; }
.card { flex: none; width: clamp(15rem, 70vw, 19rem); scroll-snap-align: start; }
.card__media { position: relative; overflow: hidden; aspect-ratio: 3 / 5; background: var(--g-950); }
.card__media img, .card__media video { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); }
@supports (animation-timeline: view()) {
  @media (min-width: 900px) and (prefers-reduced-motion: no-preference) {
    .js .pan { height: calc(100dvh - var(--nav-h) + var(--travel, 0px)); view-timeline-name: --pan; }
    .js .pan__sticky {
      position: sticky; top: var(--nav-h); height: calc(100dvh - var(--nav-h)); overflow: hidden;
      display: flex; flex-direction: column; justify-content: center; padding-block: 2rem;
    }
    .js .pan__track { overflow: visible; width: max-content; animation: pan linear both; animation-timeline: --pan; animation-range: contain 0% contain 100%; }
    .js .card { width: calc((100dvh - var(--nav-h) - 11rem) * 0.6); }
  }
}
@keyframes pan { to { transform: translateX(calc(-1 * var(--travel, 0px))); } }
#trabalhos { scroll-margin-top: var(--nav-h); }   /* o link do menu chega com a fila no início */

/* Espaço -------------------------------------------------------------------
   Texto fixo à esquerda; à direita, vídeos em duas colunas desencontradas. */
.space { padding-block: var(--section); border-top: 1px solid var(--line); }
.space__grid { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--gutter); }
.space__text { position: sticky; top: calc(var(--nav-h) + 2.5rem); align-self: start; }
.space__text .lead { margin-top: 1.5rem; }
.space__media { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-media); align-items: start; }
.space__col { display: grid; gap: var(--gap-media); }
.space__col:nth-child(2) { margin-top: clamp(4rem, 12vw, 12rem); }
.tile { position: relative; overflow: hidden; aspect-ratio: 3 / 4; background: var(--g-950); }
.tile img, .tile video { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); }
@media (max-width: 899px) {
  .space__grid { grid-template-columns: 1fr; }
  .space__text { position: static; margin-bottom: 1.5rem; }
  .space__col:nth-child(2) { margin-top: 3rem; }
}
/* Botão por cima de cada quadrado do espaço (criado em js/main.js): carregar
   pára e retoma o vídeo. É invisível: só se vê o contorno de foco no teclado. */
.tile__toggle { position: absolute; inset: 0; z-index: 1; }
.tile__toggle:focus-visible { outline-offset: -0.25rem; }

/* Vídeos em loop: a imagem é o primeiro fotograma e fica sempre por baixo.
   O vídeo aparece por cima quando começa a tocar (ver js/main.js). */
.clip { position: relative; }
.clip video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 400ms var(--ease);
}
.clip video.is-playing { opacity: 1; }

/* Instagram -----------------------------------------------------------------
   Seis publicações numa fila, em proporção 3:4 como a grelha do Instagram.
   No telemóvel e no tablet, três colunas. A preto e branco por CSS. */
.insta { padding-block: var(--section); border-top: 1px solid var(--line); }
.insta__head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 1rem 2rem;
}
.insta__handle { color: var(--fg-body); }
.insta__grid {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--gap-media);
  margin-top: var(--stack);
}
.insta__item { overflow: hidden; background: var(--g-950); }
.insta__item a { display: block; }
.insta__item img {
  width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover;
  filter: grayscale(1);
  transition: transform var(--t-slow) var(--ease);
}
@media (hover: hover) {
  .insta__item a:hover img { transform: scale(1.03); }
}
.insta__item a:focus-visible { outline-offset: -2px; }

@media (max-width: 899px) {
  .insta__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Equipa ------------------------------------------------------------------
   Enquadrada pelas faixas da marca, em cima e em baixo; junto às faixas não há linha. */
.team { padding-block: var(--section); border-top: 1px solid var(--line); }
.bands + .team, .bands + .reviews { border-top: 0; }
.team__list {
  margin-top: var(--stack);
  display: grid; grid-template-columns: repeat(2, minmax(0, 20rem));
  gap: clamp(1rem, 4vw, 4rem);
}
/* Cada barbeiro: o retrato vertical e, por baixo, o nome e a função. */
.team__member { display: flex; flex-direction: column; align-items: flex-start; gap: 1.25rem; }
.team__member img { width: 100%; max-width: 20rem; height: auto; aspect-ratio: 4 / 5; object-fit: cover; }   /* 400 x 500 px no ficheiro */
.team__name { font-size: var(--fs-name); font-weight: 500; letter-spacing: var(--ls-title); line-height: 1.1; }
.team__role { margin-top: 0.5rem; color: var(--fg-muted); font-size: var(--fs-meta); }

/* Avaliações -------------------------------------------------------------- */
.reviews { padding-block: var(--section); border-top: 1px solid var(--line); }
.ratings {
  display: flex; flex-wrap: wrap; gap: clamp(2rem, 6vw, 6rem);
  margin-top: var(--stack);
}
.rating { display: flex; flex-direction: column; text-decoration: none; }
.rating__score {
  font-size: var(--fs-score);
  font-weight: 500; line-height: 0.95; letter-spacing: var(--ls-score);
  font-variant-numeric: tabular-nums;
}
/* O sublinhado é o das ligações (.link), desenhado no fundo: o text-decoration não
   passava para dentro das máscaras das palavras e só aparecia nos espaços. O hover
   é no cartão inteiro. */
.rating__label { align-self: flex-start; margin-top: 0.5rem; color: var(--fg-body); }
.rating:hover .rating__label, .rating:focus-visible .rating__label {
  background-position: 0 var(--uy), 0 var(--uy);
  background-size: 100% 1px, 100% 1px;
  transition: background-size 800ms var(--ease-line);
}

.quotes {
  margin-top: clamp(2.5rem, 6vw, 5rem);
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 0;
}
.quote { padding: 0.5rem clamp(1rem, 3vw, 2.5rem); border-left: 1px solid var(--line); }
.quote:first-child { padding-left: 0; border-left: 0; }
.quote blockquote {
  font-size: var(--fs-1);
  font-weight: 400; line-height: 1.4; letter-spacing: var(--ls-lead);
  text-wrap: pretty;
}
.quote__by { margin-top: 1rem; color: var(--fg-muted); font-size: var(--fs-meta); }

@media (max-width: 899px) {
  .quotes { grid-template-columns: 1fr; gap: 2rem; }
  .quote { padding-inline: 0; border-left: 0; }
}

/* Contactos --------------------------------------------------------------- */
.contact { padding-block: var(--section); border-top: 1px solid var(--line); }
.contact__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  margin-top: var(--stack);
}
.contact__label { font-size: var(--fs-meta); font-weight: 500; color: var(--fg-muted); margin-bottom: 1rem; }
.contact__block p + p { margin-top: 1rem; }
.contact__small { color: var(--fg-muted); font-size: var(--fs-meta); }
/* Horário: a semana em sete células, com o dia de hoje a branco (js/main.js).
   Quando o bloco é estreito, os dias passam a linhas. */
.contact__block--hours { container-type: inline-size; }
.week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-left: 1px solid var(--line); }
.day { display: flex; flex-direction: column; gap: 2rem; padding: 0.625rem 0.5rem; border: solid var(--line); border-width: 1px 1px 1px 0; }
.day dt { font-size: var(--fs-meta); font-weight: 500; color: var(--fg-body); }
.day dd { font-size: var(--fs-meta); line-height: 1.3; font-variant-numeric: tabular-nums; }
.day--off dd { color: var(--fg-muted); }
.day__to { display: none; }
.day.is-today { background: var(--white); border-color: var(--white); }
.day.is-today dt, .day.is-today dd { color: var(--black); }
@container (max-width: 22rem) {
  .week { grid-template-columns: 1fr; border-left: 0; border-top: 1px solid var(--line); }
  .day { flex-direction: row; justify-content: space-between; gap: 1rem; padding: 0.625rem 0; border-width: 0 0 1px 0; }
  .day dd br { display: none; }
  .day__to { display: inline; }
  .day.is-today { padding-inline: 0.75rem; }
}
.contact__status { margin-top: 1rem; color: var(--fg-body); }
/* O fundo é do quadro e do mapa, não da moldura: assim nada muda de cor no fim da animação de entrada. */
.map { margin-top: var(--stack); }
.map iframe { display: block; width: 100%; height: clamp(17.5rem, 40vw, 30rem); border: 0; background: var(--g-950); filter: grayscale(1) invert(0.92) contrast(0.9); }
/* Antes de aceitar os cookies, o lugar do mapa mostra este quadro. */
.map__placeholder {
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 1.5rem;
  min-height: clamp(17.5rem, 40vw, 30rem); padding: var(--gutter);
  border: 1px solid var(--line); background: var(--g-950); color: var(--fg-body);
}
.map__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 2rem; }

@media (max-width: 899px) {
  .contact__grid { grid-template-columns: 1fr; }
}

/* Rodapé ------------------------------------------------------------------ */
/* O logótipo fica a meio caminho entre a linha de cima e a linha dos links: o mesmo espaço acima e abaixo. */
.footer { --footer-gap: clamp(2.5rem, 6vw, 5rem); padding-block: var(--footer-gap) 2rem; border-top: 1px solid var(--line); }
.footer__logo { width: 100%; height: auto; }
/* Três zonas na mesma linha: morada e política à esquerda, links ao centro da
   página, créditos à direita. No telemóvel empilham, centradas. */
.footer__row {
  margin-top: var(--footer-gap);
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  grid-template-areas: "legal links credit";
  align-items: center; gap: 1rem 2.5rem;
}
.footer__links { grid-area: links; display: flex; flex-wrap: wrap; justify-content: center; gap: 0 1.5rem; }
.footer__links .link { display: inline-flex; align-items: center; min-height: 2.75rem; font-size: 0.9375rem; --uy: calc(50% + 0.85em); padding-bottom: 0; }   /* o tamanho dos links da barra */
.footer__legal, .footer__credit { color: var(--fg-muted); font-size: var(--fs-meta); }
.footer__legal { grid-area: legal; justify-self: start; }
.footer__credit { grid-area: credit; justify-self: end; text-align: right; }
.footer__extra { margin-left: 1rem; }
.footer__cookies { margin-left: 1rem; padding: 0 0 0.125rem; font-size: inherit; letter-spacing: inherit; line-height: inherit; color: inherit; }   /* sem a margem interior dos botões: o sublinhado fica do tamanho da palavra */
/* Nome do estúdio: em maiúsculas, sem sublinhado; fica branco ao passar o cursor. */
.footer__credit a { text-decoration: none; letter-spacing: var(--ls-caps); transition: color var(--t-fast); }
.footer__credit a:hover, .footer__credit a:focus-visible { color: var(--fg); }

@media (max-width: 899px) {
  .footer__row { grid-template-columns: 1fr; grid-template-areas: "links" "legal" "credit"; justify-items: center; text-align: center; }
  .footer__legal, .footer__credit { justify-self: center; text-align: center; }
}

/* Voltar ao topo -------------------------------------------------------------
   Quadrado branco, alinhado com a margem do conteúdo. É o último elemento do
   <main> e usa position: sticky: fica preso ao fundo do ecrã enquanto se
   percorre a página e pára no fim do <main>, logo acima do rodapé, sem nunca
   entrar nele. A margem negativa em cima anula a altura que ocuparia.
   Ao passar o cursor, a faixa preta sobe de baixo para cima (o gesto dos
   botões, na vertical) e a seta avança. Com JavaScript, só aparece depois do hero. */
.to-top {
  position: sticky; z-index: 40;
  bottom: var(--to-top-gap);
  margin: calc(-1 * (var(--to-top) + var(--to-top-gap))) var(--gutter) var(--to-top-gap) auto;
  isolation: isolate; overflow: hidden;
  display: grid; place-items: center;
  width: var(--to-top); height: var(--to-top);
  background: var(--white); color: var(--black);
  border: 1px solid var(--black);   /* preta em repouso, para se ver sobre a secção branca */
  transition: color 320ms var(--ease), border-color 320ms var(--ease), opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), visibility 0s;
}
.to-top::before {
  content: ""; position: absolute; inset: -1px; z-index: -1;
  background: var(--black);
  transform: scaleY(0); transform-origin: center top;
  transition: transform 520ms var(--ease);
}
/* O ícone: em repouso, três riscas verticais lado a lado (as do menu, de pé).
   Ao passar o cursor, as dos lados juntam-se à do meio e rodam a partir do topo
   até à diagonal, formando uma seta para cima, e o conjunto sobe um pouco.
   Deslocação e rotação usam translate e rotate em separado. */
.to-top__lines, .to-top__lines::before, .to-top__lines::after {
  display: block; width: 0.125rem; height: 1rem; background: currentColor;
}
.to-top__lines { position: relative; transition: transform 420ms var(--ease); }
.to-top__lines::before, .to-top__lines::after {
  content: ""; position: absolute; left: 0; top: 0;
  transform-origin: center top;
  transition: translate 360ms var(--ease), rotate 420ms var(--ease);
}
.to-top__lines::before { translate: -0.375rem 0; }
.to-top__lines::after { translate: 0.375rem 0; }
.to-top:focus-visible .to-top__lines::before { translate: 0 0; rotate: 45deg; }
.to-top:focus-visible .to-top__lines::after { translate: 0 0; rotate: -45deg; }
.js .to-top:not(.is-visible) {
  opacity: 0; visibility: hidden; transform: translateY(0.5rem);
  transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), visibility 0s linear var(--t-fast);
}
@media (hover: hover) {
  .to-top:hover { color: var(--white); border-color: var(--white); }   /* como o "Marcar agora": preto com borda branca */
  .to-top:hover::before { transform: scaleY(1); transform-origin: center bottom; }
  .to-top:hover .to-top__lines { transform: translateY(-0.1875rem); }
  .to-top:hover .to-top__lines::before { translate: 0 0; rotate: 45deg; }   /* seta: as dos lados na diagonal */
  .to-top:hover .to-top__lines::after { translate: 0 0; rotate: -45deg; }
}
.to-top:focus-visible { color: var(--white); border-color: var(--white); outline-color: var(--white); outline-offset: 2px; }
.to-top:focus-visible::before { transform: scaleY(1); transform-origin: center bottom; }
.to-top:active { transform: scale(0.94); }

/* Aviso de cookies -----------------------------------------------------------
   Painel preto no canto inferior esquerdo, por cima de tudo; no telemóvel ocupa
   a largura entre margens. Os dois botões são iguais, para nenhum ter mais peso. */
.cookies {
  position: fixed; z-index: 60;
  left: var(--gutter); bottom: var(--to-top-gap);
  width: min(30rem, calc(100% - 2 * var(--gutter)));
  padding: 1.5rem; background: var(--black); border: 1px solid var(--g-800);
  color: var(--fg-body); font-size: var(--fs-meta); letter-spacing: var(--ls-meta); line-height: 1.5;
}
.cookies[hidden] { display: none; }
.cookies__actions { display: flex; gap: 0.75rem; margin-top: 1.25rem; }
.cookies__actions .btn { flex: 1; min-height: 2.75rem; padding-inline: 1rem; font-size: 0.9375rem; }
.cookies__actions .btn::after { display: none; }

/* Páginas de texto (política de privacidade) ------------------------------ */
.page { padding-block: clamp(3rem, 7vw, 6rem) var(--section); }
.page__inner { max-width: 68ch; }
.page h1 { font-size: var(--fs-h2); font-weight: 500; line-height: 1.02; letter-spacing: var(--ls-display); }
.page h2 { font-size: var(--fs-1); font-weight: 500; letter-spacing: var(--ls-lead); margin-top: 2.5rem; }
.page p, .page li { color: var(--fg-body); margin-top: 1rem; }
.page ul { padding-left: 1.2em; list-style: disc; }
.page .page__meta { color: var(--fg-muted); font-size: var(--fs-meta); }

/* Movimento ----------------------------------------------------------------
   Os estados iniciais escondidos só existem com JavaScript (classe .js no
   <html>). Sem ele, a página aparece completa. */
/* Entrada ao scroll: sobe 2,5 rem enquanto aparece. A opacidade chega primeiro
   e o movimento termina devagar. O atraso de cada elemento vem do js/main.js. */
.js .reveal { opacity: 0; transform: translate3d(0, 2.5rem, 0); }
/* A transição só existe na entrada: esconder é instantâneo, para nada aparecer e
   desaparecer se o script correr depois de a página já estar à vista. */
.js .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 1100ms cubic-bezier(0.33, 1, 0.68, 1), transform 1500ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
/* Fotos: o gesto das faixas do hero, na vertical. O conteúdo da moldura (foto,
   vídeo, link) abre de baixo para cima e a foto assenta, de 112% para o tamanho
   normal. A imagem solta dos barbeiros é ela própria recortada. */
.js .reveal--wipe { opacity: 1; transform: none; background: transparent; }   /* sem a caixa escura da moldura enquanto a foto abre */
.js .reveal--wipe > *, .js img.reveal--wipe { clip-path: inset(100% 0 0 0); }
.js .reveal--wipe > img, .js .reveal--wipe > a > img { transform: scale(1.12); }
.js .reveal--wipe.is-in > *, .js img.reveal--wipe.is-in {
  clip-path: inset(0);
  transition: clip-path 1250ms var(--ease-io), transform 1500ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.js .reveal--wipe.is-in > img, .js .reveal--wipe.is-in > a > img {
  transform: none;
  transition: clip-path 1250ms var(--ease-io), transform 1500ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

/* Títulos e textos de entrada (o gesto do site da MEAN, sem o desfoque): cada
   palavra está numa máscara (.w) e sobe de dentro dela (.wi). As palavras da
   mesma linha entram juntas e as linhas seguem 90 ms umas atrás das outras.
   A folga da máscara não corta acentos nem letras com perna. */
.w { display: inline-block; overflow: hidden; vertical-align: top; padding: 0.1em 0 0.16em; margin: -0.1em 0 -0.16em; }
.wi { display: inline-block; }
.js .reveal--lines { opacity: 1; transform: none; }
/* O sublinhado das ligações só se desenha depois de as palavras entrarem. */
.js .reveal--lines .link, .js .reveal--lines.link { background-size: 0 1px; transition: none; }
.js .reveal--lines .wi { transform: translate3d(0, 115%, 0); }
.js .reveal--lines.is-in .wi {
  transform: none;
  transition: transform 1150ms var(--ease-word);
  transition-delay: calc(var(--reveal-delay, 0ms) + var(--i, 0) * 90ms);
}

/* Scroll suave (Lenis, em js/vendor). Regras da própria biblioteca; com ela
   ativa, o scroll-behavior do CSS fica desligado para não se somarem. */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* As faixas do hero abrem a partir do lado onde estão presas, uma de cada vez. */
@media (prefers-reduced-motion: no-preference) {
  .bar { animation: open-right 1300ms var(--ease) both; }
  .bar--b { animation-name: open-left; animation-delay: 150ms; }
  .bar--c { animation-delay: 300ms; }
}
@keyframes open-right { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0); } }
@keyframes open-left { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0); } }

/* As faixas da marca entram de lados alternados quando aparecem. */
.band i { transition: transform var(--t-slow) var(--ease); }
.js .bands:not(.is-in) .band--a i { transform: translateX(100%); }
.js .bands:not(.is-in) .band--c i { transform: translateX(-100%); }
.js .bands:not(.is-in) .band--b i { transform: scaleX(0); transform-origin: left; }
.band:nth-child(2) i { transition-delay: 60ms; }
.band:nth-child(3) i { transition-delay: 120ms; }
.band:nth-child(4) i { transition-delay: 180ms; }
.band:nth-child(5) i { transition-delay: 240ms; }
.band:nth-child(6) i { transition-delay: 300ms; }

/* Cursor -------------------------------------------------------------------
   Só com rato. Uma bola branca com mix-blend-mode: difference, ou seja, o negativo
   do que está por baixo: preta sobre o branco, branca sobre o preto. Tem sempre o
   mesmo tamanho; só encolhe um pouco enquanto se carrega.
   O JavaScript cria o cursor e esconde o do sistema (html.has-cursor). */
.cursor {
  position: fixed; top: 0; left: 0; z-index: 1000;
  pointer-events: none; mix-blend-mode: difference;
  transition: opacity 200ms var(--ease);
}
.cursor--hidden { opacity: 0; }
.cursor__dot {
  display: block; width: 0.875rem; height: 0.875rem; border-radius: 50%;
  background: var(--white);
  translate: -50% -50%;
  transition: transform 220ms var(--ease);
}
.cursor--down .cursor__dot { transform: scale(0.8); }
.has-cursor, .has-cursor * { cursor: none !important; }
.has-cursor img, .has-cursor a { -webkit-user-drag: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .band i { transition: none; }
  .js .bands:not(.is-in) .band i { transform: none; }
  .btn, .btn::before, .btn::after, .nav__links a, .nav__links a::after, .btn__bands i, .nav__lang, .nav--clear:not(.nav--open) .nav__lang { transition: none; }
  .btn--bands:hover::after { animation: none; }
  .nav__bars, .nav__bars::before, .nav__bars::after,
  .nav--open .nav__bars, .nav--open .nav__bars::before, .nav--open .nav__bars::after,
  .nav__links, .nav--open .nav__links, .nav__links > *, .nav--open .nav__links > * { transition: none; }
  .link, .link:hover, .link:focus-visible { transition: none; }
  .cursor__dot { transition: none; }
  .clip video { transition: none; }
  .insta__item img { transition: none; }
  .insta__item a:hover img { transform: none; }
  .to-top, .to-top::before, .to-top__lines, .to-top__lines::before, .to-top__lines::after, .js .to-top:not(.is-visible) { transition: none; }
  .js .to-top:not(.is-visible), .to-top:active { transform: none; }
  .to-top:hover .to-top__lines { transform: none; }
}
