/* Self-hosted fonts: only the two weights the design actually uses, and
   only the latin and latin-ext subsets. Keeps third-party hosts out of
   the Content-Security-Policy and removes a request to Google on every
   page load. Generated from the Google Fonts CSS. */
@font-face{font-family:'Unbounded';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/unbounded-500-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Unbounded';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/unbounded-500-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Urbanist';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/urbanist-600-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Urbanist';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/urbanist-600-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Urbanist';font-style:normal;font-weight:700;font-display:swap;src:url('/assets/fonts/urbanist-700-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Urbanist';font-style:normal;font-weight:700;font-display:swap;src:url('/assets/fonts/urbanist-700-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

/* The subset of Urbanist shipped here draws the masculine and feminine ordinal
   indicators — º and ª — as full-size letters, so "2º Esqº" reads as "2o Esqo".
   Portuguese addresses are full of them. Declared after the faces above and
   scoped to those two codepoints, this hands just them to a system face that
   draws them properly and leaves every other character alone. Delete it if the
   font is ever rebuilt with the glyphs corrected. */
@font-face{
  font-family:'Urbanist';font-style:normal;font-weight:600;
  src:local('Helvetica Neue'),local('Arial'),local('Liberation Sans'),local('DejaVu Sans');
  unicode-range:U+00AA, U+00BA;
}
@font-face{
  font-family:'Unbounded';font-style:normal;font-weight:500;
  src:local('Helvetica Neue'),local('Arial'),local('Liberation Sans'),local('DejaVu Sans');
  unicode-range:U+00AA, U+00BA;
}

/* ---------- Design tokens ---------- */
  /* A paleta e as fontes vivem em brand.css, carregado antes deste ficheiro.
     É o único sítio com cores, para um projecto novo trocar um ficheiro em vez
     de andar à procura delas. */
  *,*::before,*::after{box-sizing:border-box;}
  /* `clip` e não `hidden`.
     O painel do menu em telemóvel é `position:fixed` com `translateX(100%)`:
     fechado, está inteiro 312px à direita da margem. O Chrome não conta
     elementos fixos para a largura do documento e não mostra nada; o Safari
     do iPhone conta, e a página passa a arrastar-se de lado — que é o que se
     via. Nenhum conteúdo está lá: é só o painel à espera de entrar.

     `overflow-x:hidden` resolveria e traria outro problema, porque cria um
     contexto de deslocamento e com ele o `position:sticky` do .extra-banner
     passaria a colar-se a esse contexto em vez de ao ecrã. `clip` corta sem
     criar contexto nenhum, e o sticky fica como está. */
  html{scroll-behavior:smooth;overflow-x:clip;}
  body{
    margin:0;font-family:var(--body);color:var(--ink);
    font-weight:600;font-size:16px;line-height:1.5;background:var(--white);
    -webkit-font-smoothing:antialiased;
  }
  img{max-width:100%;display:block;}
  a{color:inherit;text-decoration:none;}
  h1,h2,h3,h4,h5,h6{font-family:var(--display);font-weight:500;line-height:1.12;margin:0;}
  .container{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter);}
  .eyebrow{
    font-family:var(--body);font-size:.72rem;letter-spacing:.28em;text-transform:uppercase;
    color:var(--ink);font-weight:600;margin:0 0 1rem;display:inline-block;
  }
  .lead{font-size:16px;color:var(--muted);max-width:56ch;}
  /* Os títulos de secção, um pouco mais abertos: .03em a 34px é um pixel entre
     letras — chega para a linha respirar sem que as palavras se desfaçam. Em em
     e não em px, para acompanhar o clamp quando o ecrã encolhe.

     Pelas classes e não pela tag: o nível do título é do editor, e uma regra
     escrita como `h2` deixava de se aplicar no dia em que alguém o passasse a
     h3 no backoffice. O hero fica de fora — lá o primeiro diapositivo é h1 e os
     seguintes h2, e uma regra por tag punha-os com espaçamentos diferentes. */
  :is(h1,h2,h3,h4,h5,h6).display{font-size:clamp(15px,2.66vw,34px);letter-spacing:.03em;}
  :is(h1,h2,h3,h4,h5,h6).title{font-size:clamp(15px,2.66vw,34px);letter-spacing:.03em;}
  /* Ao passar o rato, a cor enche o botão da esquerda para a direita.
     O preenchimento é uma imagem de fundo — um gradiente de uma cor só — e não
     um ::before: fica por baixo do texto sem z-index, e um <button> faz o mesmo
     que um <a>. Cada variante diz só com que cor enche, em --btn-fill. Um
     `background:` num hover repunha a imagem a nada, e a cor voltava a aparecer
     de uma vez. */
  .btn{
    display:inline-block;font-family:var(--body);font-size:.78rem;letter-spacing:.18em;
    text-transform:uppercase;font-weight:600;padding:1rem 2.2rem;border:1px solid var(--grey);
    color:var(--ink);background-color:transparent;cursor:pointer;border-radius:2px;
    --btn-fill:var(--grey);
    background-image:linear-gradient(var(--btn-fill),var(--btn-fill));
    background-repeat:no-repeat;background-position:left center;background-size:0 100%;
    /* A cor das letras muda ao ritmo do preenchimento: mais depressa, as da
       ponta direita ficavam da cor do fundo antes de ele lá chegar — amarelo
       sobre amarelo, no botão cheio. */
    transition:.35s,color .45s cubic-bezier(.65,0,.35,1),background-size .45s cubic-bezier(.65,0,.35,1);
  }
  .btn:hover,.btn:focus-visible{background-size:100% 100%;color:#fff;border-color:var(--grey);}
  .btn--solid{background-color:var(--brand-yellow);color:var(--grey);border-color:var(--brand-yellow);}
  .btn--solid:hover,.btn--solid:focus-visible{color:var(--brand-yellow);border-color:var(--grey);}
  .btn--light{--btn-fill:#fff;border-color:#fff;color:#fff;}
  .btn--light:hover,.btn--light:focus-visible{color:var(--ink);}
  @media(prefers-reduced-motion:reduce){
    .btn{transition:.35s,background-size 0s;}
  }
  section{position:relative;}
  /* O cabeçalho é fixo e tapa o topo do ecrã. Sem isto, chegar a uma secção por
     âncora — do menu, ou de uma fotografia do mosaico — deixava o título dela
     escondido por baixo dele. É `scroll-margin` e não `padding`: só conta
     quando alguém chega ali a saltar, e não desloca nada no desenho. */
  section[id]{scroll-margin-top:clamp(84px,9vh,116px);}
  .pad{padding-block:clamp(48px,6.5vw,96px);}

  /* ---------- 1. Header ---------- */
  .site-header{
    position:fixed;inset:0 0 auto 0;z-index:60;
    display:flex;align-items:center;justify-content:space-between;
    --header-pad:22px;
    padding:var(--header-pad) var(--gutter);
    transition:background .4s,padding .4s,transform .45s ease;
  }
  .site-header.hidden{transform:translateY(-100%);}
  /* Cinza da marca a 92%. A primeira linha é o valor literal para browsers sem
     color-mix; a segunda liga-o a --grey para não voltar a ficar dessincronizado. */
  .site-header.scrolled{background:rgba(74,74,73,.92);
    background:color-mix(in srgb, var(--grey) 92%, transparent);
    --header-pad:14px;backdrop-filter:blur(6px);}

  /* Enquanto o menu de telemóvel está aberto, o cabeçalho não pode ter nem
     transform nem backdrop-filter.
     Qualquer um dos dois torna o elemento o bloco de contenção dos seus filhos
     `position:fixed` — e o painel do menu é filho do cabeçalho. Sem isto,
     bastavam 40px de scroll para o painel deixar de se medir pelo ecrã e
     encolher para a altura do cabeçalho: medido, 873px passavam a 132px. Era o
     menu a desfazer-se ao rolar a página.
     Declarado depois de .hidden e de .scrolled de propósito: tem a mesma
     especificidade que ambos e é a ordem que decide. */
  .site-header:has(.nav.open){transform:none;backdrop-filter:none;}
  /* Um tamanho só, em todas as páginas e em qualquer ponto da página. Encolhia
     para 67px ao rolar, e as páginas sem abertura de largura total nasciam já
     com os 67 — o mesmo cabeçalho dava três logótipos diferentes conforme onde
     se estava. O que muda ao rolar é a margem à volta, não a marca. */
  .site-header .logo img{height:88px;width:auto;}
  /* ---- A página que começa em amarelo ----
     O bloco de passos pinta a página inteira, e o cabeçalho é transparente, por
     isso passa a estar sobre o amarelo e não sobre uma fotografia escura: o
     branco do menu desaparecia. Tudo passa ao cinza da marca.

     O logótipo é o mesmo ficheiro, recolorido: brightness(0) leva-o a preto e
     invert(29%) sobe-o até ao cinza — rgb(74,74,74), que é o --grey a menos de
     um ponto. Assim o cliente pode trocar o logótipo sem ter de nos mandar
     também uma segunda versão escura dele. */
  body.tone-sun{background:var(--brand-yellow-soft);}
  body.tone-sun .site-header .logo img{filter:brightness(0) invert(29%);}
  /* `.nav-link` e não `.nav a`: as opções de língua também são <a> dentro do
     menu, e a lista delas abre num painel cinza. Pintadas de cinza, ficavam
     cinza sobre cinza — a língua actual via-se por ser amarela e a outra
     desaparecia. O painel é escuro em qualquer página; o que muda de cor aqui
     são as entradas do menu, e mais nada. */
  body.tone-sun .nav-link,
  body.tone-sun .nav-toggle,
  body.tone-sun .lang-btn{color:var(--grey);}
  body.tone-sun .nav .btn--light{--btn-fill:var(--grey);border-color:var(--grey);color:var(--grey);}
  body.tone-sun .nav .btn--light:is(:hover,:focus-visible){color:var(--brand-yellow-soft);}
  /* Rolar não muda a cor da página, só a espessura da faixa: o cinza translúcido
     do resto do site punha uma barra escura no meio do amarelo. */
  body.tone-sun .site-header.scrolled{
    background:rgba(249,242,169,.92);
    background:color-mix(in srgb, var(--brand-yellow-soft) 92%, transparent);}
  @media(max-width:900px){
    /* O painel do menu continua cinza — é o que se abre por cima da página — e
       dentro dele as letras voltam a ser amarelas. */
    body.tone-sun .nav-link{color:var(--brand-yellow);}
    body.tone-sun .nav .btn--light{--btn-fill:var(--brand-yellow);border-color:var(--brand-yellow);color:var(--brand-yellow);}
    body.tone-sun .nav .btn--light:is(:hover,:focus-visible){color:var(--grey);}
  }

  .nav{display:flex;align-items:center;gap:34px;}
  .nav a{
    color:#fff;font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;font-weight:600;
    opacity:.9;transition:.25s;
  }
  .nav a:hover{opacity:1;}
  /* Underline on hover, and kept on the page you are reading.
     Drawn as a pseudo-element rather than text-decoration so it can grow from
     the middle and sit clear of the descenders — and so the letters do not
     shift by a pixel when it appears. The letter-spacing above pads the right
     edge of the last glyph, which the translate compensates for. */
  .nav .nav-link{position:relative;}
  .nav .nav-link::after{
    content:"";position:absolute;left:0;right:.14em;bottom:-6px;height:1.5px;
    background:currentColor;transform:scaleX(0);transform-origin:center;
    transition:transform .28s ease;
  }
  .nav .nav-link:hover::after,
  .nav .nav-link:focus-visible::after,
  .nav .nav-link.is-current::after{transform:scaleX(1);}
  .nav .nav-link.is-current{opacity:1;}
  @media(prefers-reduced-motion:reduce){
    .nav .nav-link::after{transition:none;}
  }
  .nav .btn{padding:.7rem 1.6rem;}

  /* ---- Selector de língua ----
     Sem fundo, como foi pedido: é a mesma tipografia das entradas do menu e as
     opções assentam sobre o que estiver por baixo. Só aparece com mais do que
     uma língua ligada — ver views/partials/lang.php.

     Fecha por omissão com visibility, e não com display:none, para a lista
     estar sempre medida: assim o painel não salta de largura ao abrir. */
  /* O quanto a lista cai por baixo do botão. Chega para se ler como uma coisa
     à parte, e não tanto que se solte dele. */
  .lang{position:relative;display:flex;align-items:center;--lang-drop:12px;}
  .lang-btn{
    display:inline-flex;align-items:center;gap:7px;
    background:none;border:0;padding:0;cursor:pointer;
    color:#fff;font:inherit;font-size:.78rem;font-weight:600;
    letter-spacing:.14em;text-transform:uppercase;opacity:.9;transition:opacity .25s;
  }
  .lang-btn:hover,.lang-btn:focus-visible{opacity:1;}
  .lang-caret{width:9px;height:auto;flex:none;transition:transform .25s ease;}
  .lang:hover .lang-caret,
  .lang:focus-within .lang-caret,
  .lang.open .lang-caret{transform:rotate(180deg);}

  /* A lista abre no cinza da marca.
     Foi transparente à partida, e a transparência não se aguentou: por baixo do
     cabeçalho o que há é a página, branca em quase todo o site, e nem letras
     brancas nem o amarelo da marca se veem sobre branco. Com fundo próprio, as
     opções voltam a ser lidas como as entradas do menu de que saem — brancas,
     a que está escolhida a amarelo — e é igual em todas as páginas, seja o que
     for que esteja por baixo.

     Abre logo por baixo do botão. Chegou a descer até ao fim da barra — para
     nenhuma opção assentar sobre ela, quando as letras não tinham fundo — mas
     com fundo próprio isso deixou de ser um problema, e a queda até lá deixava
     a lista solta a meio do ecrã, longe do que a abriu. */
  .lang-list{
    position:absolute;top:100%;left:50%;transform:translateX(-50%);
    margin:var(--lang-drop) 0 0;padding:16px 22px;list-style:none;
    background:var(--grey);border-radius:4px;
    box-shadow:0 16px 34px rgba(8,18,20,.22);
    min-width:100%;
    display:flex;flex-direction:column;align-items:center;gap:12px;
    opacity:0;visibility:hidden;pointer-events:none;transition:opacity .22s ease;
  }
  /* A ponte por cima da lista, invisível, à altura do que a separa do botão.
     Sem ela, o ponteiro atravessava esse vão — fora do botão e fora da lista —
     e a lista fechava-se debaixo dele a meio do caminho. */
  .lang-list::before{
    content:"";position:absolute;left:0;right:0;
    top:calc(-1 * var(--lang-drop));height:var(--lang-drop);
  }
  .lang:hover .lang-list,
  .lang:focus-within .lang-list,
  .lang.open .lang-list{opacity:1;visibility:visible;pointer-events:auto;}
  /* Sobre o cinza da lista, as opções são brancas como as entradas do menu, e
     o amarelo marca duas coisas: onde está o ponteiro, e a língua em que já se
     está. A que está escolhida fica também sublinhada — quem não distingue a
     cor continua a ver qual é. */
  .lang .lang-opt{color:#fff;opacity:.75;}
  .lang .lang-opt:hover,
  .lang .lang-opt:focus-visible{color:var(--brand-yellow);opacity:1;}
  .lang .lang-opt.is-current{
    color:var(--brand-yellow);opacity:1;
    text-decoration:underline;text-underline-offset:5px;
  }
  @media(prefers-reduced-motion:reduce){
    .lang-caret,.lang-list{transition:none;}
  }
  /* Padding e não só o glifo: sem ele a área tocável do botão do menu era o
     desenho do caractere, uns 20px de lado. */
  .nav-toggle{display:none;background:none;border:0;color:#fff;font-size:1.6rem;
    cursor:pointer;padding:8px 10px;margin:-8px -10px;line-height:1;}
  @media(max-width:900px){
    /* 88px de logótipo mais 44px de margens davam um cabeçalho de 132px — num
       ecrã de telemóvel em paisagem, um terço do que há para ver. */
    .site-header{padding-inline:20px;}
    .site-header .logo img{height:58px;}
    .nav{
      position:fixed;inset:0 0 0 auto;width:min(80vw,320px);flex-direction:column;
      justify-content:center;gap:26px;
      /* O cinza da marca, o mesmo do cabeçalho e do rodapé. Era um verde-azulado
         que não existe em mais lado nenhum do site. */
      background:var(--grey);
      transform:translateX(100%);transition:transform .4s;padding:40px;
      /* Um menu com muitas entradas, ou um ecrã baixo em paisagem, precisa de
         rolar por dentro — e esse rolar não pode passar para a página atrás. */
      overflow-y:auto;overscroll-behavior:contain;
      box-shadow:-20px 0 60px rgba(8,32,36,.35);
      /* Acima do escurecido. Sem isto o painel ficava por baixo dele: um
         elemento com z-index positivo pinta-se sempre acima de um irmão com
         z-index:auto, por muito que venha antes no HTML. O amarelo saía baço,
         visto através de 50% de preto, e os toques aterravam no escurecido em
         vez de nas ligações. */
      z-index:60;
    }
    .nav.open{transform:translateX(0);}
    .nav-toggle{display:block;z-index:61;}

    /* Sobre o cinza do painel, as ligações tomam o amarelo do logótipo — o
       mesmo que está no cabeçalho, dois dedos acima, e a opacidade sobe a 1
       para o amarelo sair à sua força.
       Só aqui: em ecrã largo o menu assenta sobre fotografia, muitas vezes
       clara, e amarelo sobre céu não se lê. */
    .nav a{color:var(--brand-yellow);opacity:1;}
    .nav .btn--light{--btn-fill:var(--brand-yellow);border-color:var(--brand-yellow);color:var(--brand-yellow);}
    .nav .btn--light:hover,
    .nav .btn--light:focus-visible{color:var(--grey);border-color:var(--brand-yellow);}
    /* O botão de fechar acompanha, senão fica um X branco solto num painel
       inteiro a amarelo. */
    .nav-toggle{color:var(--brand-yellow);}

    /* ---- What a finger can actually hit ----
       Measured at 390px: the menu links were 19px tall, the three language
       choices 18x15, and the button that opens the whole thing 40x42. The
       floor in WCAG is 24x24 and the comfortable mark everyone else uses is
       44. The slideshow dots in this same file already carry an invisible
       34px target for exactly this reason; the menu never got one.

       The links take their height from padding rather than from a bigger
       font, so nothing about the design changes — and the gap comes down by
       as much as the padding adds, so the rhythm of the panel stays where it
       was. Side by side they now touch, which is what a list of rows should
       do: a finger that lands between two entries should reach one of them
       and not the panel behind. */
    .nav{gap:4px;}
    .nav .nav-link{padding-block:13px;}
    .lang-opt{min-width:44px;min-height:44px;display:grid;place-items:center;}
    .nav-toggle{min-width:44px;min-height:44px;}
    /* The button sits beside the links, which no longer have a gap of their
       own, so it brings its own air. */
    .nav .btn{margin-top:18px;}
    .lang{margin-top:14px;}

    /* No painel de telemóvel não há ponteiro para abrir nada, e há altura de
       sobra: as línguas ficam à vista, em linha, e o botão que as abriria não
       tem função nenhuma. */
    .lang{justify-content:center;align-self:auto;}
    .lang-btn{display:none;}
    .lang-list::before{display:none;}
    /* Aqui não há lista flutuante nenhuma: as línguas já estão dentro do painel, que é
       do mesmo cinza. O fundo e a sombra sairiam como uma caixa dentro de uma
       caixa da mesma cor. */
    .lang-list{
      position:static;transform:none;margin:0;padding:0;flex-direction:row;gap:20px;
      background:none;box-shadow:none;border-radius:0;min-width:0;
      opacity:1;visibility:visible;pointer-events:auto;
    }
    .lang .lang-opt{color:var(--brand-yellow);opacity:.6;}
    .lang .lang-opt.is-current{opacity:1;}
    /* O escurecido por trás do painel: dá a entender que a página está à espera,
       e é onde se toca para fechar. */
    .nav-veil{
      position:fixed;inset:0;z-index:59;background:rgba(8,18,20,.5);
      opacity:0;pointer-events:none;transition:opacity .4s;border:0;padding:0;
    }
    .nav-veil.open{opacity:1;pointer-events:auto;}
  }
  /* Acima dos 900px o painel não existe: se o menu ficou aberto e a janela
     cresceu, nada disto deve sobrar. */
  @media(min-width:901px){
    .nav-veil{display:none;}
  }
  @media(prefers-reduced-motion:reduce){
    .nav,.nav-veil{transition:none;}
  }

  /* ---------- 2. Hero slideshow ---------- */
  .hero{height:100vh;min-height:640px;color:#fff;overflow:hidden;}

  /* ---- Slides ----
     Stacked in place and cross-faded. Only the visible one is in the
     accessibility tree and only its button is reachable by keyboard, so a
     reader is never offered a link they cannot see. */
  .hero-slide{position:absolute;inset:0;opacity:0;visibility:hidden;
    transition:opacity .9s ease, visibility 0s linear .9s;}
  .hero-slide.is-active{opacity:1;visibility:visible;
    transition:opacity .9s ease, visibility 0s;}
  /* One slide is the old single-image hero, with nothing to cross-fade. */
  .hero:not(.hero--slides) .hero-slide{opacity:1;visibility:visible;transition:none;}

  /* Directly over the scroll cue, on its centre line: the two together read as
     one set of controls at the foot of the slideshow instead of two unrelated
     marks in opposite corners.

     The offset is the cue's own height, added up from its parts — 26px off the
     floor, ~15px of label, the 8px gap and the 38px rule — plus 16px of air.
     Changing any of those in .scroll-cue means changing this too. */
  .hero-dots{position:absolute;left:50%;transform:translateX(-50%);bottom:103px;
    z-index:16;display:flex;gap:12px;}
  /* No cue to sit above — the last block on the page, or a hero on its own.
     Back to the floor, where the dots would otherwise hang in mid-air. */
  .hero:not(:has(.scroll-cue)) .hero-dots{bottom:34px;}
  /* 9px é o que se vê; a área que se toca tem de ser bem maior — um dedo acerta
     em cerca de 24px, e um ponto de 9px num telemóvel é um controlo que não se
     consegue usar. A área vive num pseudo-elemento invisível por cima, e não em
     padding: com padding o contorno e o fundo cresciam com ela, e os pontos
     passavam a anéis de 34px. Assim o desenho fica exactamente o que era e só
     o alvo cresce, sem afastar os pontos uns dos outros. */
  .hero-dot{width:9px;height:9px;padding:0;border-radius:50%;cursor:pointer;position:relative;
    background-color:rgba(255,255,255,.28);border:1px solid rgba(255,255,255,.55);
    transition:background-color .3s, border-color .3s, transform .3s;}
  .hero-dot::after{content:"";position:absolute;inset:-11px;border-radius:50%;}
  .hero-dot:hover{background-color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.75);}
  .hero-dot.is-active{background-color:rgba(255,255,255,.8);border-color:rgba(255,255,255,.8);
    transform:scale(1.25);}
  .hero-dot:focus-visible{outline:2px solid #fff;outline-offset:3px;}

  @media(prefers-reduced-motion:reduce){
    .hero-slide{transition:none;}
    .hero-dot{transition:none;}
  }

  /* Constant slow motion (infinite pan + zoom) */
  .hero-bg{position:absolute;inset:-4%;background-size:cover;background-position:center;
    will-change:transform;animation:heroMotion 28s ease-in-out infinite alternate;}
  .hero-bg::after{content:"";position:absolute;inset:0;
    background:linear-gradient(180deg,rgba(8,32,36,.35),rgba(8,32,36,.6));}
  @keyframes heroMotion{
    0%  {transform:scale(1.06) translate(0,0);}
    100%{transform:scale(1.14) translate(-2%,-1.5%);}
  }
  @media(prefers-reduced-motion:reduce){.hero-bg{animation:none;}}

  /* ---- The film behind the slides ----
     Sits under everything, because until it is actually playing the
     photographs are what should be on screen: an empty video element over
     them would be a black rectangle for as long as it took to arrive. Once it
     plays, .is-playing fades the photographs off it.

     The wash is the same one the photographs carry — see .hero-bg::after — so
     the white text holds whichever of the two is underneath it. */
  .hero-film{position:absolute;inset:0;z-index:0;overflow:hidden;}
  .hero-film video{display:block;width:100%;height:100%;object-fit:cover;}
  .hero-film::after{content:"";position:absolute;inset:0;
    background:linear-gradient(180deg,rgba(8,32,36,.35),rgba(8,32,36,.6));}
  /* Only the opening slide gives way to the film. The ones behind it keep
     their photographs — the film stands behind the opening and nothing else,
     and they are opaque, so they cover it while they are the one showing.

     Slow, because this is the handover from the opening photograph to the film
     and a cut between two different pictures of Lisbon reads as a fault. */
  /* Onde há filme, a fotografia de abertura fica quieta e enquadrada como ele.
     Ela é o primeiro fotograma do filme — mesmos pixels — e isso só se nota
     se as duas estiverem no mesmo sítio. O `inset:-4%` e a deriva lenta do
     heroMotion, que nas outras fotografias são o efeito, aqui faziam a
     passagem dar um salto de alguns pixels. As outras mantêm-nas. */
  .hero.has-film .hero-slide--opening .hero-bg{inset:0;animation:none;}
  .hero.is-playing .hero-slide--opening .hero-bg{opacity:0;transition:opacity 1.2s ease;}

  .hero-content{
    position:absolute;inset:0;z-index:10;display:flex;flex-direction:column;
    align-items:center;justify-content:center;text-align:center;padding:0 var(--gutter);
  }
  .hero-eyebrow{color:#fff;font-size:clamp(.74rem,1.3vw,.9rem);letter-spacing:.3em;margin-bottom:1.4rem;}
  .hero-title{
    font-family:var(--display);font-weight:500;color:#fff;
    font-size:clamp(23px,4.06vw,52px);line-height:1.12;letter-spacing:normal;
    text-transform:none;margin:0;text-shadow:0 2px 40px rgba(0,0,0,.35);
  }
  /* 32ch e não 28: a linha do segundo diapositivo passou a nomear as cinco
     regiões e media 344px contra os 320 que o limite dava — partia-se em duas,
     com «Madeira» sozinha na segunda. O limite continua lá, e é para continuar:
     é ele que impede uma frase de apoio de atravessar o ecrã todo. Subiu o
     mínimo para a lista caber, e não mais. Num telemóvel parte na mesma, que é
     o que lá deve fazer. */
  .hero-tagline{
    font-family:var(--body);font-weight:600;
    font-size:clamp(16px,1.48vw,19px);color:#f2f7f6;
    margin-top:1.5rem;max-width:32ch;line-height:1.35;
  }
  .hero-content .btn{margin-top:2.2rem;padding:1.05rem 2.6rem;}
  .scroll-cue{position:absolute;bottom:26px;left:50%;transform:translateX(-50%);z-index:15;
    font-size:.68rem;letter-spacing:.22em;text-transform:uppercase;color:#fff;opacity:.8;
    display:flex;flex-direction:column;align-items:center;gap:8px;}
  .scroll-cue::after{content:"";width:1px;height:38px;background:#fff;animation:cue 1.8s infinite;}
  @keyframes cue{0%{transform:scaleY(0);transform-origin:top;}50%{transform:scaleY(1);transform-origin:top;}
    50.1%{transform-origin:bottom;}100%{transform:scaleY(0);transform-origin:bottom;}}

  /* ---------- 3 & 6. Split (image + text) ---------- */
  .split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,6vw,90px);align-items:center;}
  .split.reverse .split-media{order:2;}
  .split-media{position:relative;}
  .split-media img{width:100%;height:100%;object-fit:cover;aspect-ratio:4/5;border-radius:2px;}
  /* O botão do bloco, quando existe. A mesma distância que o mesmo botão guarda
     no bloco de fecho (.offer-do), um pouco mais curta por estar dentro de uma
     coluna e não a meio de uma secção inteira. */
  .split-do{margin:clamp(24px,3vw,38px) 0 0;}
  @media(max-width:820px){.split{grid-template-columns:1fr;}.split.reverse .split-media{order:0;}}

  /* ---------- 4. Services cards ---------- */
  .section-head{text-align:center;max-width:640px;margin:0 auto clamp(32px,4.5vw,56px);}
  /* Os cartões correm mais largos que a medida do site, de propósito: são
     fotografias a toda a largura, não texto, e a 1200px ficavam estreitos ao
     ponto de o recorte 2:3 cortar demasiado de cada uma. O título por cima
     continua dentro do .container, com o resto da página. */
  .cards-wrap{max-width:1720px;margin-inline:auto;padding-inline:clamp(14px,3vw,44px);}
  /* One column per card. How many there are is the client's decision now, and a
     grid fixed at four left a hole the moment there were three. */
  .cards{display:grid;grid-template-columns:repeat(var(--cards,4),1fr);gap:0;}
  /* .66 dava 1,52 de altura por cada 1 de largura; .88 dá 1,14 — os cartões
     ficam um quarto mais baixos sem mudar de largura, porque é a proporção que
     define a altura a partir da largura da coluna. Efeito lateral bem-vindo: o
     recorte das fotografias, que são todas horizontais, deixa de ser tão fundo. */
  .card{position:relative;overflow:hidden;aspect-ratio:.88;}
  .card img{width:100%;height:100%;object-fit:cover;transition:transform 1s ease;}
  .card:hover img{transform:scale(1.05);}
  /* The standing gradient, so the name is readable against any photograph. */
  .card::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
    background:linear-gradient(180deg,transparent 48%,rgba(0,0,0,.28) 74%,rgba(0,0,0,.62));}
  /* The mask that closes over the whole photograph on hover, under the text. */
  .card::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
    background:rgba(8,18,20,.5);opacity:0;transition:opacity .45s ease;}
  .card:hover::before,.card:focus-within::before{opacity:1;}

  .card-body{position:absolute;inset:auto 0 0 0;padding:34px 32px;color:#fff;z-index:3;}
  /* Entrelinha própria: o 1.12 global serve títulos de uma linha, e o nome do
     cartão ocupa duas — a essa altura as linhas quase se tocavam. */
  .card-body :is(h1,h2,h3,h4,h5,h6){font-family:var(--display);font-weight:500;
    font-size:clamp(17px,1.80vw,23px);line-height:1.2;}

  /* The second half of the name. The wrapper's row grows from nothing to the
     line's own height, which is what lifts the title above it rather than
     pushing the card open. */
  /* `0fr` collapses a row only if the item in it is allowed to shrink, which is
     what `overflow:hidden` on that item does — it takes the item's automatic
     minimum height down to zero. Put the clip on the wrapper instead and the
     row never collapses at all.
     The item carries no padding either: padding survives the collapse, and 6px
     of it stood under every title before anyone hovered anything. The gap comes
     from the heading's margin, which opens on the same hover. */
  .tile-sub{display:grid;grid-template-rows:0fr;opacity:0;
    transition:grid-template-rows .45s ease,opacity .35s ease;}
  .tile-sub > span{display:block;overflow:hidden;
    font-family:var(--body);font-weight:600;color:rgba(255,255,255,.94);
    font-size:clamp(14px,1.05vw,17px);line-height:1.3;letter-spacing:normal;text-transform:none;}
  .card:hover .tile-sub,.card:focus-within .tile-sub,
  .gm-item:hover .tile-sub,.gm-item:focus-within .tile-sub{grid-template-rows:1fr;opacity:1;}
  .card-body :is(h1,h2,h3,h4,h5,h6){transition:margin-bottom .45s ease;}
  .card:hover .card-body :is(h1,h2,h3,h4,h5,h6),
  .card:focus-within .card-body :is(h1,h2,h3,h4,h5,h6){margin-bottom:.4rem;}

  /* No pointer, no hover — and half a name is not a name. */
  @media(hover:none){
    .tile-sub{grid-template-rows:1fr;opacity:1;}
    .card-body :is(h1,h2,h3,h4,h5,h6){margin-bottom:.4rem;}
    .card::before{opacity:1;background:rgba(8,18,20,.28);}
  }
  @media(prefers-reduced-motion:reduce){
    .card img,.card::before,.tile-sub,.card-body :is(h1,h2,h3,h4,h5,h6){transition:none;}
  }

  @media(max-width:1000px){.cards{grid-template-columns:repeat(2,1fr);}}
  @media(max-width:560px){.cards{grid-template-columns:1fr;}.card{aspect-ratio:.82;}}

  /* ---------- About stats ---------- */
  .stats{display:flex;gap:clamp(36px,6vw,64px);margin-top:2.4rem;flex-wrap:wrap;}
  .stat-label{display:block;font-family:var(--body);font-weight:600;font-size:1.15rem;color:var(--ink);margin-bottom:.5rem;}
  .stat-num{font-family:var(--body);font-weight:600;font-size:clamp(2.6rem,4.4vw,3.6rem);line-height:1;color:var(--ink);}

  /* ---------- Full-width image banner (Experienced Team) ---------- */
  /* The band was 717px tall at desktop to hold 193px of text, which left about
     290px of empty photograph above it and 234px below. Shorter now, with the
     room around the text set by padding rather than left over from the height —
     so it survives the band getting shorter still on a narrow screen. */
  .feature-banner{
    position:relative;min-height:clamp(340px,36vw,560px);
    padding-block:clamp(56px,7vw,96px);
    background-size:cover;background-position:center;
    display:flex;align-items:center;color:#fff;overflow:hidden;
  }
  .feature-banner::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(90deg,rgba(0,0,0,.58) 0%,rgba(0,0,0,.2) 45%,transparent 72%);}
  .feature-banner .container{position:relative;z-index:2;width:100%;}
  .feature-banner .inner{max-width:640px;}
  .feature-banner .eyebrow{color:#fff;}
  .feature-banner :is(h1,h2,h3,h4,h5,h6){color:#fff;font-size:clamp(15px,2.66vw,34px);line-height:1.14;
    text-shadow:0 2px 26px rgba(0,0,0,.4);}

  /* ---------- Extra Services (full-bleed banner) ---------- */
  /* Sticky reveal: Extra Services pins, Discover scrolls up over it */
  .stack-reveal{position:relative;}
  .extra-banner{position:sticky;top:0;height:100vh;
    background-size:cover;background-position:center;
    display:flex;align-items:center;color:#fff;}
  #discover{position:relative;z-index:2;min-height:100vh;}
  .extra-banner::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(90deg,rgba(3,22,40,.62) 0%,rgba(3,22,40,.2) 52%,transparent 78%);}
  /* Both panels sit on photographs, so both need the light ante-title. The
     scrolling one used to carry the colour as an inline style on the element,
     which is what made it invisible the moment the two panels were written the
     same way. */
  .stack-reveal .eyebrow{color:#fff;}
  .extra-banner :is(h1,h2,h3,h4,h5,h6){color:#fff;font-size:clamp(15px,2.66vw,34px);line-height:1.08;
    margin-top:.4rem;text-shadow:0 2px 26px rgba(0,0,0,.4);}
  .extra-banner .lead{color:rgba(255,255,255,.9);margin-top:1.4rem;max-width:46ch;}

  /* ---- The two sliding panels are written and dressed the same ----
     Both put their text on the page's left margin and their button under it.
     The pinned one used to keep its call to action off to the right as a link
     with a circled arrow, which made one section look like two designs. */
  .stack-reveal .container{position:relative;z-index:2;width:100%;}
  .stack-reveal .inner{max-width:620px;}
  .stack-reveal .btns{margin-top:clamp(1.6rem,2.6vw,2.4rem);}

  /* The veil above runs left to right, which is right while the words sit in
     a 620px column on the left: it is dark where they are and clear where the
     photograph should show. On a telephone the words run edge to edge, and
     past 78% of the width there is no veil at all — which is the end of every
     line. Vertical here, so it covers them wherever they reach. */
  @media(max-width:820px){
    .extra-banner::after{
      background:linear-gradient(180deg,rgba(3,22,40,.48),rgba(3,22,40,.74));
    }

    /* Both photographs are 2400x1248 — almost two to one — and both bands are
       as tall as the screen. On a telephone that box is taller than it is
       wide, so `cover` scales the picture to the height and throws away the
       sides: at 390x844 you are looking at a quarter of its width, magnified
       four times. The chauffeur and the car fall outside the crop and what is
       left reads as a wall.
       
       So the bands stop taking their height from the viewport and take it
       from their own words instead. Shorter box, gentler crop — about half
       the zoom, and the subject back inside it. */
    .extra-banner{height:auto;padding-block:clamp(64px,16vw,112px);}
    #discover{min-height:0;}
    .banner{min-height:0;padding-block:clamp(64px,16vw,112px);}
  }

  /* ---------- Tailored Services ---------- */
  /* Três filhos e não dois: o título, o botão e a coluna da direita. O botão
     é dele próprio para poder mudar de lugar num telemóvel — ver o @media lá
     abaixo. Em ecrã largo fica onde sempre esteve: debaixo do título, na
     coluna da esquerda, com a coluna da direita a acompanhar as duas linhas.
     O espaçamento entre linhas é zero de propósito; o ar debaixo do título é o
     que o botão traz consigo, como era quando estava lá dentro. */
  .ts-grid{display:grid;grid-template-columns:1fr 1fr;
    column-gap:clamp(34px,6vw,84px);row-gap:0;align-items:start;}
  .ts-intro{grid-column:1;grid-row:1;}
  .ts-cta{grid-column:1;grid-row:2;margin-top:1.9rem;}
  .ts-right{grid-column:2;grid-row:1 / span 2;}
  .ts-right .lead{margin:0 0 clamp(2rem,4vw,3rem);}
  .ts-list{list-style:none;margin:0;padding:0;}
  .ts-list li{display:flex;gap:24px;align-items:baseline;padding:clamp(12px,1.6vw,20px) 0;}
  /* O primeiro e o último item não somam o seu espaçamento ao da secção: com
     eles, este bloco fechava 20px mais abaixo do que os vizinhos, e a margem
     inferior lia-se maior que a superior sem nada no CSS a dizer porquê. O
     espaçamento entre itens fica intacto. */
  .ts-list li:first-child{padding-top:0;}
  .ts-list li:last-child{padding-bottom:0;}
  .ts-num{font-family:var(--body);font-weight:600;font-size:clamp(1.3rem,1.7vw,1.7rem);color:var(--muted);min-width:54px;}
  .ts-txt{font-family:var(--body);font-weight:600;font-size:clamp(17px,1.80vw,23px);color:var(--ink);line-height:1.29;}
  /* Numa coluna só, o botão passa para o fim da secção, depois da lista: a
     seguir ao título ele empurrava para baixo o texto que explica o que a
     secção oferece, e pedia a acção antes de a ter explicado. As colocações
     acima são desfeitas, senão a ordem não pega. */
  @media(max-width:820px){
    .ts-grid{grid-template-columns:1fr;row-gap:clamp(20px,4vw,28px);}
    .ts-intro,.ts-cta,.ts-right{grid-column:1;grid-row:auto;}
    .ts-intro{order:1;}
    .ts-right{order:2;}
    .ts-cta{order:3;margin-top:0;}
  }

  /* ---------- Brand-color section ---------- */
  .brand-bg{background:var(--grey);color:var(--brand-yellow-soft);}
  .brand-bg :is(h1,h2,h3,h4,h5,h6),.brand-bg .stat-label,
  .brand-bg .eyebrow,.brand-bg .stat-num,.brand-bg .lead{color:var(--brand-yellow-soft);}
  /* O botão cheio troca as cores ao passar o rato — amarelo com letras cinza
     passa a cinza com letras amarelas. Sobre o cinza da marca isso deixava
     cinza sobre cinza: o botão desaparecia e ficavam as letras soltas. O
     contorno amarelo mantém-no um botão nos dois estados. */
  .brand-bg .btn--solid:hover,
  .brand-bg .btn--solid:focus-visible{border-color:var(--brand-yellow);}

  /* ---------- Video: a title over a player ----------
     O bloco abre páginas, por isso limpa o cabeçalho pelo mesmo critério da
     página de contactos: o body só perde .page-view quando o primeiro bloco
     passa por baixo do cabeçalho. */
  .video-band{padding-block:clamp(48px,6.5vw,96px);}

  /* Quando o bloco abre a página, o texto ocupa o ecrã e o vídeo assoma por
     baixo. A tira que fica à vista é o convite a rolar: sem ela, quem chega vê
     um título e nada que diga que há mais.

     A condição é a posição do bloco e não uma classe do <body>. Era
     `body:not(.page-view)`, que quer dizer "esta página abre por baixo do
     cabeçalho" — verdade também na homepage, onde quem abre é o slideshow. Com
     o bloco movido para lá, ele ficava a limpar um cabeçalho que já não tem por
     cima e a abrir 200px de vazio a meio da página. */
  main > .video-band:first-child{
    padding-top:0;
    /* As quatro medidas que, somadas, é o que o vídeo NÃO tem para si. Escritas
       aqui e usadas em baixo para o vídeo se medir por elas: mudar o espaço
       entre o título e o vídeo passa a ajustar o vídeo sozinho, em vez de o
       empurrar para fora do ecrã. */
    --open-top:clamp(150px,17vh,200px);   /* limpa o cabeçalho fixo */
    --open-title:calc(clamp(23px,4.06vw,52px) * 1.12);   /* uma linha de título */
    --open-gap:clamp(18px,2.6vh,38px);    /* entre o título e o vídeo */
    /* O quanto o vídeo pode passar da dobra. Era o contrário — uma margem
       reservada por baixo, para ele acabar antes — e o resultado é que num
       portátil normal a altura mandava sempre e o vídeo ficava mais estreito
       do que a coluna das regiões que vem a seguir. Duas larguras diferentes
       na mesma página, e a de cima menor do que a de baixo.
       Passa a ser uma tolerância: o vídeo pode acabar uns pixéis abaixo da
       dobra, e é essa ponta que convida a rolar. Só quando nem assim cabe é
       que a altura volta a mandar e o vídeo encolhe. */
    --open-over:clamp(32px,9vh,88px);
  }
  main > .video-band:first-child .video-head{
    /* Limpa o cabeçalho em cima, e por baixo só o que o texto precisa para
       respirar antes do vídeo. Sem altura de ecrã: com ela, o vazio entre a
       frase e o vídeo crescia com o monitor e o vídeo caía para fora de vista. */
    padding-top:var(--open-top);
    padding-bottom:var(--open-gap);
    /* O .section-head traz 56px de margem por baixo, para os blocos onde ele é
       um cabeçalho de secção. Aqui o afastamento até ao vídeo é o --open-gap e
       mais nada: com os dois, o vídeo ficava 56px mais abaixo do que a conta em
       baixo julgava, e passava a dobra por essa exacta medida. */
    margin-bottom:0;
  }
  /* O vídeo cabe inteiro no ecrã com que se abre a página.
     Ia a toda a largura, e 16/9 de 1440px são 810px de altura: com o cabeçalho
     e o título por cima, ficava sempre um pedaço de vídeo por baixo da dobra —
     e num portátil ou num telemóvel deitado faltava mais de metade.

     A ALTURA disponível é o travão: o que sobra do ecrã depois das medidas
     acima, mais a tolerância do --open-over, convertido em largura pela
     proporção do vídeo. Onde a coluna da página for menor do que isso, é ela
     que vale — daí o min(), e é isso que acontece num ecrã de portátil.

     `svh` e não `vh`: no telemóvel, `vh` conta o ecrã sem as barras do browser,
     que estão lá quando a página abre; o vídeo ficava cortado exactamente no
     momento em que é para ser visto. A linha em `vh` fica antes, para os
     browsers que não conhecem `svh` ainda terem uma resposta. */
  main > .video-band:first-child .video-frame{
    margin-inline:auto;
    /* Três limites, e vale o mais apertado dos três:
         1. a largura da página, com as margens do site;
         2. a medida do conteúdo que vem a seguir — as fotografias das regiões
            correm dentro de um .container, e o vídeo alinha com elas, senão
            era a única coisa da página a sair fora da coluna;
         3. o que a altura do ecrã deixa, pela proporção do vídeo.
       Em ecrã largo e alto manda o 2, e o vídeo pára onde o conteúdo pára. Em
       ecrã baixo — um portátil, um telemóvel deitado — manda o 3 e o vídeo
       encolhe para caber. Em ecrã estreito manda o 1. */
    width:min(100%, calc(var(--maxw) - 2 * var(--gutter)),
              calc((100vh  - var(--open-top) - var(--open-title) - var(--open-gap) + var(--open-over)) * 16 / 9));
    width:min(100%, calc(var(--maxw) - 2 * var(--gutter)),
              calc((100svh - var(--open-top) - var(--open-title) - var(--open-gap) + var(--open-over)) * 16 / 9));
  }
  /* O título é um cabeçalho de secção como os outros: centrado, na medida do
     .section-head e no tamanho do .title. Foi desenhado à parte — grande e
     encostado à esquerda — quando este bloco abria uma página sozinho; a meio
     da homepage, ao lado de "Here we are" e "What our travellers say", um
     título com regras próprias lê-se como um bloco de outro site. */
  /* ...com uma excepção: quando o bloco ABRE a página. Aí não é um cabeçalho
     de secção — é a primeira coisa que se lê, no lugar onde a homepage tem
     "The Portuguese Way". Toma a medida desse: a mesma clamp, a mesma
     entrelinha, o mesmo espaçamento entre letras. Duas páginas que abrem devem
     abrir com a mesma voz. A meio de uma página o bloco continua como estava.
     A condição é a posição, e não uma classe posta à mão, pela mesma razão que
     está escrita acima. */
  main > .video-band:first-child .video-head .display{
    font-size:clamp(23px,4.06vw,52px);line-height:1.12;letter-spacing:normal;
  }
  /* Encostado à mesma margem do logótipo. O .container do site pára nos 1200px
     e centra-se, o que num ecrã largo deixava o texto a começar 360px à direita
     do logótipo — duas margens diferentes na mesma página. Aqui a secção usa a
     largura toda com o gutter do site, que é exactamente o que o cabeçalho usa. */
  .video-band > .container{max-width:none;padding-inline:var(--gutter);}
  /* A frase por baixo do título toma o amarelo do bloco em vez do cinza do
     .lead — sobre o cinza da marca, cinza sobre cinza não se lê. */
  .video-line{
    font-family:var(--body);font-weight:600;color:var(--brand-yellow-soft);
    font-size:clamp(14px,1.15vw,17px);line-height:1.5;margin:1.2rem 0 0;
    letter-spacing:.04em;
  }

  .video-frame{position:relative;margin:0;}
  /* O botão é a capa inteira: quem toca em qualquer sítio do vídeo espera que
     ele arranque, não que tenha de acertar num triângulo pequeno. */
  .video-play{
    display:block;width:100%;padding:0;border:0;background:var(--grey-dark);
    aspect-ratio:16/9;overflow:hidden;cursor:pointer;position:relative;border-radius:2px;
  }
  .video-play img{width:100%;height:100%;object-fit:cover;display:block;
    transition:transform 1s ease, filter .4s ease;}
  .video-play:hover img,.video-play:focus-visible img{transform:scale(1.03);filter:brightness(.92);}
  .video-play:focus-visible{outline:2px solid var(--brand-yellow);outline-offset:4px;}
  /* O triângulo, desenhado com bordas: um caractere de play muda de forma
     conforme a fonte que o sistema tiver, e este não pode. */
  .video-mark{
    position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
    width:clamp(64px,7vw,92px);aspect-ratio:1;border-radius:50%;
    background:rgba(255,255,255,.92);transition:transform .35s ease,background .35s ease;
    display:grid;place-items:center;
  }
  .video-mark::before{
    content:"";width:0;height:0;margin-left:18%;
    border-left:clamp(18px,2vw,26px) solid var(--grey);
    border-block:clamp(11px,1.25vw,16px) solid transparent;
  }
  .video-play:hover .video-mark,.video-play:focus-visible .video-mark{
    transform:translate(-50%,-50%) scale(1.08);background:var(--brand-yellow);
  }
  /* O player, depois de alguém carregar. Ocupa o lugar exacto da capa. */
  .video-frame iframe{width:100%;aspect-ratio:16/9;border:0;display:block;border-radius:2px;}
  .video-fallback{display:inline-block;margin-top:14px;color:var(--brand-yellow-soft);
    text-decoration:underline;}

  /* O selo, ao canto superior direito do vídeo. Metade dele sai para fora do
     quadro de propósito — é o que o faz ler como um carimbo pousado por cima e
     não como um botão dentro da imagem. */
  .video-seal{
    position:absolute;top:0;right:0;transform:translate(28%,-28%);
    width:clamp(110px,11vw,168px);aspect-ratio:1;margin:0;
    display:grid;place-items:center;pointer-events:none;
    /* Acima do player. O <iframe> é um elemento substituído e pinta-se por cima
       de tudo o que não tenha camada própria: sem isto, o selo desaparecia no
       instante em que o vídeo arrancasse. */
    z-index:2;
    /* Sem disco, sem sombra e sem ponto ao centro: só as letras a andar à roda,
       como no desenho de referência. O que antes justificava o disco — a
       fotografia por baixo poder ser clara, escura ou às manchas — resolve-se
       aqui pelo sítio onde o selo assenta: metade dele sai para fora do vídeo,
       sobre o fundo da página. */
    background:none;
  }
  .video-seal svg{width:100%;height:100%;overflow:visible;}
  /* Roda o grupo dentro do SVG, não o SVG. Ver o comentário no markup: a
     caixa do elemento rodava com ele e era isso que alargava a página.
     transform-box/transform-origin porque num elemento SVG o `center` é
     resolvido contra a caixa de referência e não contra o seu próprio
     desenho — sem as duas linhas, o anel gira à volta do canto. */
  .video-seal .seal-turn{
    transform-box:view-box;transform-origin:center;
    animation:sealTurn 12s linear infinite;
  }
  /* Sem letter-spacing: quem abre os intervalos é o textLength no SVG, que os
     abre exactamente o que falta para a frase fechar a volta. Declarar os dois
     é somar dois espaçamentos e passar do círculo. */
  .video-seal text{
    font-family:var(--body);font-weight:600;font-size:12px;
    fill:var(--brand-yellow);text-transform:uppercase;
  }
  @keyframes sealTurn{to{transform:rotate(360deg);}}
  @media(prefers-reduced-motion:reduce){
    .video-seal .seal-turn{animation:none;}
    .video-play img,.video-mark{transition:none;}
  }
  /* O selo sai para fora do vídeo de propósito, mas não para fora da página.
     Os 28% da sua largura são 30,8px, e a goteira do container é 5vw — abaixo
     dos 616px de ecrã a goteira é menor do que isso e o selo passava a
     margem. Media-lo deu 1,8px de fora aos 580px: pouco para se ver, o
     suficiente para a página arrastar de lado. O limite está em 640 e não em
     616 para deixar folga ao arredondamento. */
  @media(max-width:640px){
    /* Num ecrã estreito o selo comeria também o canto do vídeo. */
    .video-seal{transform:translate(14%,-30%);}
  }

  /* ---------- Duo: duas fotografias e um texto, desencontrados ----------
     Quatro peças numa grelha de duas colunas por três linhas:

         título        ┐
                       │ fotografia alta
         fotografia    ┘
         pequena         texto
         ─────────────────────  ← acabam à mesma altura

     Duas peças atravessam linhas, e é isso que faz o desenho:

     A fotografia ALTA atravessa as duas primeiras linhas e assenta no topo. É
     isso que encaixa as duas fotografias uma na outra em vez de as empilhar: a
     pequena começa enquanto a alta ainda corre.

     A fotografia PEQUENA atravessa as duas últimas e assenta no fundo, que é a
     mesma linha onde o texto acaba. Assim a base das duas coincide, seja qual
     for o comprimento do texto ou a altura da fotografia. Antes o texto tinha
     linha só para ele, debaixo da fotografia pequena, e ficava um vazio entre
     as duas que crescia com o tamanho das imagens.

     Isto é a grelha a decidir, e não margens somadas à mão: trocar uma
     fotografia por outra de outra forma continua a dar o mesmo desenho. */
  /* Medidas tiradas do desenho de referência, num ecrã de 1920: o conteúdo
     corre 1290px ao meio (dois terços do ecrã), a coluna do título tem 630 e a
     do texto 520, com 140 entre elas. Aqui fica a medida do site — 1200 — que é
     a mesma proporção a menos de 7%, e é a medida a que o resto das páginas já
     está. Correr de margem a margem, como estava, é o que fazia isto ler-se
     como outra coisa: as mesmas peças espalhadas por 1800px em vez de reunidas
     em 1200 deixam de formar um grupo. */
  .duo{
    display:grid;
    grid-template-columns:1.2fr 1fr;
    /* Em vw e não em %: uma percentagem de row-gap conta-se sobre a altura do
       contentor, e a altura desta grelha é a que o conteúdo lhe der — a conta
       fica indefinida e o browser resolve-a como pode. */
    column-gap:clamp(28px,11%,140px);
    row-gap:clamp(24px,3vw,58px);
    align-items:start;
  }
  .duo-head       {grid-area:1 / 1;}
  .duo-photo--tall{grid-area:1 / 2 / span 2 / auto;align-self:start;}
  .duo-photo--low {grid-area:2 / 1 / span 2 / auto;align-self:end;}
  /* Também encostado ao fundo: a linha de baixo é partilhada com a fotografia
     pequena, e é essa linha que as alinha. Encostado ao topo, o texto ficava a
     flutuar no meio da última linha da grelha sempre que a fotografia fosse
     mais alta do que ele. */
  /* Também encostado ao fundo: a linha de baixo é partilhada com a fotografia
     pequena, e é essa linha que as alinha. Encostado ao topo, o texto ficava a
     flutuar no meio da última linha da grelha sempre que a fotografia fosse
     mais alta do que ele.
     Sem a margem de baixo do parágrafo: o alinhamento faz-se pela caixa com
     margens, por isso 16px de margem punham a última linha do texto 16px acima
     da base da fotografia — o suficiente para se ver que não batem certo. */
  .duo-body       {grid-area:3 / 2;align-self:end;margin-bottom:0;}

  /* Espelhado: trocam-se as colunas e não o documento. A ordem por que se lê e
     por que se chega ao bloco pelo teclado é sempre título primeiro.
     As larguras trocam com elas: a coluna do título é a larga dos dois lados,
     senão o bloco invertido dava um título apertado ao lado de uma fotografia
     maior — o inverso da hierarquia, e não o espelho dela. */
  .duo.reverse{grid-template-columns:1fr 1.2fr;}
  .duo.reverse .duo-head       {grid-area:1 / 2;}
  .duo.reverse .duo-photo--tall{grid-area:1 / 1 / span 2 / auto;}
  .duo.reverse .duo-photo--low {grid-area:2 / 2 / span 2 / auto;}
  .duo.reverse .duo-body       {grid-area:3 / 1;}

  .duo-photo{margin:0;}
  .duo-photo img{width:100%;display:block;object-fit:cover;}

  /* O título é o que dá o tom ao bloco. Ao tamanho normal de um título de
     secção — 34px — ficava um rótulo por cima de duas fotografias; na
     referência ocupa a coluna toda em três linhas, e é isso que o põe a
     conversar com as fotografias em vez de as anunciar. A proporção lá é 57px
     numa coluna de 630, que aqui dá cerca de 50. */
  .duo-head .display{font-size:clamp(26px,3.4vw,50px);line-height:1.08;}

  /* A alta ocupa a coluna inteira e encosta ao topo da secção: é a peça que
     ancora o bloco, e recuada deixava de o ancorar. */
  .duo-photo--tall{width:100%;}
  .duo-photo--tall img{aspect-ratio:5/6;}

  /* A pequena ocupa dois terços da sua coluna e encosta ao bordo de dentro. O
     vazio fica todo do lado de fora, por baixo do princípio do título — é esse
     vazio, e não o tamanho das fotografias, que faz o bloco respirar. */
  .duo-photo--low{width:min(65%,100%);justify-self:end;}
  .duo-photo--low img{aspect-ratio:5/7;}
  .duo.reverse .duo-photo--low{justify-self:start;}

  /* O texto toma a largura da coluna, por baixo da fotografia alta. */
  .duo-body{max-width:none;line-height:1.7;}

  /* A outra forma: dois quadrados iguais em colunas iguais. O encaixe entre as
     duas fotografias é o mesmo — o que muda é o peso. Desiguais, o título manda
     e as fotografias acompanham-no; iguais, mandam as fotografias e o título
     abre-lhes o caminho. */
  .duo.squares,.duo.squares.reverse{
    grid-template-columns:1fr 1fr;
    column-gap:clamp(18px,2.4vw,30px);
  }
  .duo.squares .duo-photo--tall,
  .duo.squares .duo-photo--low{width:100%;}
  .duo.squares .duo-photo--tall img,
  .duo.squares .duo-photo--low img{aspect-ratio:1;}

  /* Numa coluna só o desencontro deixa de existir — não há duas colunas para
     desencontrar. Fica a ordem de leitura, que é a do documento: título,
     fotografia alta, fotografia pequena, texto. */
  @media(max-width:820px){
    .duo,.duo.reverse{grid-template-columns:1fr;row-gap:clamp(20px,4vw,32px);}
    .duo :is(.duo-head,.duo-photo--tall,.duo-photo--low,.duo-body),
    .duo.reverse :is(.duo-head,.duo-photo--tall,.duo-photo--low,.duo-body){
      grid-area:auto;justify-self:stretch;align-self:auto;}
    .duo-photo--tall,.duo-photo--low,.duo.reverse .duo-photo--low{width:100%;}
  }

  /* ---------- Counter: números grandes com a palavra por cima ----------
     O número é desenho: fica atrás, enorme e num tom quase branco. A palavra
     assenta-lhe em cima, ao centro, e é ela que se lê. Medidas da referência,
     num ecrã de 1920: número a 170px num tom pálido, palavra a 24px escura,
     cada coluna com 300 de largura e um fio a separá-las. */
  .counter-band{background:var(--sand);}
  .counters{
    list-style:none;margin:0;padding:0;
    display:flex;flex-wrap:wrap;justify-content:center;
    gap:clamp(28px,4vw,64px);
  }
  .counter{
    /* Largura que chegue para a palavra mais comprida em duas linhas. Mais
       estreito e ela parte em três, e três linhas tapam o número por inteiro —
       que é o que aqui há para ver. */
    position:relative;flex:0 1 clamp(240px,28%,340px);
    display:grid;place-items:center;
    min-height:clamp(110px,9vw,170px);
  }
  /* O fio entre colunas, e não à volta de cada uma: um separador desenha-se
     entre duas coisas, por isso não há fio antes da primeira. */
  .counter + .counter::after{
    content:"";position:absolute;left:calc(-1 * clamp(14px,2vw,32px));
    top:15%;bottom:15%;width:1px;background:rgba(27,36,38,.14);
  }
  /* A letra do desenho, a mesma dos títulos. Estava na do texto corrido: a 170px
     o número é a peça grande do bloco, e a peça grande de uma secção não pode
     ser a única coisa da página escrita noutra letra. */
  .counter-num{
    font-family:var(--display);font-weight:500;line-height:1;
    font-size:clamp(80px,9vw,170px);letter-spacing:-.02em;
    /* Branco, e não um tom do texto: sobre o creme da faixa, o número lê-se
       como um vazio recortado e não como um cinza esbatido. É mais claro do
       que o fundo em vez de mais escuro, que é o que o afasta da palavra em
       vez de competir com ela. */
    color:var(--white);
    grid-area:1 / 1;pointer-events:none;user-select:none;
    /* Centrado dentro da própria caixa: enquanto conta, o JavaScript fixa-lhe a
       largura no valor final, e sem isto os algarismos encostavam à esquerda
       dessa caixa em vez de ficarem debaixo da palavra. */
    text-align:center;
  }
  /* A palavra é uma etiqueta e não um título: maiúsculas, letra do texto e o
     espaçamento largo entre letras que o site usa nos ante-títulos. Assim não
     disputa a escala do número — diz o que ele conta e sai da frente. */
  .counter-word{
    grid-area:1 / 1;position:relative;
    font-family:var(--body);font-weight:600;text-align:center;
    font-size:clamp(12px,1vw,16px);line-height:1.5;color:var(--ink);
    letter-spacing:.18em;text-transform:uppercase;
    padding-inline:6px;
  }
  /* Num telemóvel os fios desaparecem. Um separador desenha-se entre duas
     colunas lado a lado; quando elas passam a uma só, cada fio fica pendurado
     à esquerda do seu contador, a separar do nada. O mesmo limite dos 820px por
     onde o resto do site passa a uma coluna. */
  @media(max-width:820px){
    .counter + .counter::after{content:none;}
  }

  /* ---------- News: uma fila de notícias que corre para o lado ----------
     Sem ligação e sem "ler mais": o texto de cada uma está todo aqui. Ver o
     comentário no topo de views/sections/news.php.

     A fila rola na horizontal com o rolamento do próprio browser — dedo,
     trackpad e teclado funcionam sem uma linha de JavaScript. O scroll-snap é
     que a faz parar sempre com uma notícia inteira à vista em vez de a meio. */
  /* As margens vivem no invólucro e não na fila. Postas na fila, seriam
     preenchimento dentro da caixa que rola — e o conteúdo passa por baixo do
     preenchimento, o que deixava a quarta notícia meio à mostra ao lado das
     três. No invólucro, a fila acaba onde a terceira acaba e o que vem a seguir
     fica cortado. */
  .news-wrap{max-width:1720px;margin-inline:auto;padding-inline:var(--gutter);}
  .news{
    --news-gap:clamp(24px,2.6vw,44px);
    display:flex;flex-wrap:nowrap;
    gap:var(--news-gap);
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;
    /* O rolamento desta caixa é seco por omissão: quem o quer suave pede-o no
       momento — ao largar um arrasto, ou ao carregar num ponto. Declarado suave
       aqui, cada pixel de arrasto virava uma viagem animada e a fila arrastava-se
       atrás do rato. */
    scroll-behavior:auto;
    /* A barra de rolamento fica de fora: o que diz que isto rola são os pontos
       por baixo e o ponteiro, e uma barra cinzenta debaixo das fotografias só
       partia o desenho. O rolamento continua todo lá. */
    scrollbar-width:none;
  }
  .news::-webkit-scrollbar{display:none;}
  .news:focus-visible{outline:2px solid var(--grey);outline-offset:6px;}
  /* Enquanto se arrasta, o encaixe sai do caminho: com ele ligado, cada pixel
     de arrasto era puxado de volta para o cartão mais próximo e a fila
     tremia. Volta ao largar, e é aí que arruma. */
  .news.dragging{scroll-snap-type:none;user-select:none;}

  /* Três de cada vez. flex-shrink a zero: sem isso o flex encolhe-as para
     caberem todas, e deixa de haver o que rolar. */
  .news-item{
    flex:0 0 calc((100% - 2 * var(--news-gap)) / 3);
    scroll-snap-align:start;
    display:flex;flex-direction:column;
  }
  .news-shot{display:block;overflow:hidden;}
  .news-shot img{width:100%;height:100%;object-fit:cover;display:block;}
  /* Todas do mesmo tamanho. Chegaram a ter três alturas alternadas, copiadas do
     desencontro da referência; numa fila que rola, o desencontro não se lê como
     ritmo — lê-se como fotografias mal cortadas, porque a que está ao lado
     muda a cada arrasto. */
  .news-shot{aspect-ratio:4/3;}

  .news-tag{
    display:flex;align-items:center;gap:12px;margin-top:clamp(18px,1.8vw,26px);
    font-family:var(--body);font-weight:600;font-size:.72rem;
    letter-spacing:.24em;text-transform:uppercase;color:var(--ink);
  }
  .news-tag::before{content:"";width:26px;height:1px;background:var(--ink);flex:0 0 auto;}
  .news-title{
    font-family:var(--display);font-weight:500;line-height:1.25;
    font-size:clamp(17px,1.5vw,23px);margin:.7rem 0 0;color:var(--ink);
  }
  /* A ligação é o título, mas o que se clica é o cartão todo: o ::after estica
     por cima dele e apanha o clique onde quer que caia. É por isso que o item é
     position:relative — sem isso, o ::after esticaria até ao ecrã inteiro. */
  .news-item{position:relative;}
  /* -webkit-user-drag ao lado do draggable="false" do HTML: o atributo trata do
     Firefox, esta propriedade trata do Chrome e do Safari. Sem os dois, começar
     um arrasto em cima de uma notícia arrastava o endereço dela em vez de rolar
     a fila. */
  .news-link{color:inherit;text-decoration:none;-webkit-user-drag:none;}
  .news-link::after{content:"";position:absolute;inset:0;z-index:1;}
  .news-link:hover{text-decoration:underline;text-underline-offset:4px;}
  .news-link:focus-visible{outline:2px solid var(--grey);outline-offset:3px;}
  /* A fotografia responde ao ponteiro sobre qualquer ponto do cartão, e não só
     sobre ela: quem passa o rato pelo texto está a olhar para a mesma notícia.
     Cresce dentro do invólucro, que a recorta.

     A condição era `:has(.news-link:hover)`, e os cartões deixaram de ter
     ligação quando as notícias deixaram de ser um blogue — a partir daí não
     havia `.news-link` nenhum e a fotografia ficou parada sem que se desse por
     isso. Agora é o cartão que responde, tenha ligação ou não. */
  .news-shot img{transition:transform .8s cubic-bezier(.22,.61,.36,1);}
  .news-item:hover .news-shot img,
  .news-item:focus-within .news-shot img{transform:scale(1.04);}
  @media(prefers-reduced-motion:reduce){
    .news-shot img{transition:none;}
  }
  .news-body{
    font-family:var(--body);font-weight:600;color:var(--muted);
    font-size:15px;line-height:1.65;margin:.8rem 0 0;
  }

  /* Os pontos. Desenhados por JavaScript, porque o número deles depende de
     quantas notícias cabem no ecrã — e isso muda com a largura. */
  .news-dots{display:flex;justify-content:center;gap:10px;
    margin-top:clamp(28px,3vw,48px);}
  .news-dot{
    width:9px;height:9px;padding:0;border:0;border-radius:50%;cursor:pointer;
    background:color-mix(in srgb, var(--ink) 22%, transparent);
    transition:background .25s ease,transform .25s ease;
  }
  .news-dot[aria-current="true"]{background:var(--grey);transform:scale(1.25);}
  .news-dot:focus-visible{outline:2px solid var(--grey);outline-offset:3px;}

  /* O ponteiro: um disco cinza com duas setas amarelas, que segue o rato dentro
     da fila. Ao carregar, as setas aproximam-se uma da outra — é o único aviso
     de que o clique fez alguma coisa, porque o que se move a seguir são as
     notícias e não o ponteiro.
     position:fixed e não absolute: fixed acompanha o rato em coordenadas de
     ecrã, que é o que o evento dá, sem ter de descontar o rolamento da página a
     cada movimento. */
  .news-cursor{
    position:fixed;top:0;left:0;z-index:40;pointer-events:none;
    width:76px;height:76px;margin:-38px 0 0 -38px;border-radius:50%;
    background:var(--grey);color:var(--brand-yellow);
    display:flex;align-items:center;justify-content:center;gap:14px;
    opacity:0;transform:scale(.6);
    transition:opacity .18s ease,transform .18s ease,gap .18s ease;
  }
  .news-cursor.on{opacity:1;transform:scale(1);}
  .news-cursor.press{gap:2px;}
  .news-cursor svg{width:11px;height:16px;display:block;}
  /* Onde o ponteiro próprio está a ser desenhado, o do sistema sai de cena — e
     o de dentro também. Só na fila, o <a> de cada notícia continuava a impor a
     mãozinha do sistema, que aparecia no meio do disco: `cursor` não se herda
     por cima de um valor que o browser já deu ao elemento. */
  .news-rail.has-cursor,
  .news-rail.has-cursor *{cursor:none;}
  @media(prefers-reduced-motion:reduce){
    .news{scroll-behavior:auto;}
    .news-cursor,.news-dot{transition:none;}
  }
  /* Sem rato não há ponteiro que desenhar, e a fila arrasta-se com o dedo. */
  @media(hover:none){
    .news-cursor{display:none;}
    .news-rail.has-cursor{cursor:auto;}
  }

  @media(max-width:1000px){
    .news-item{flex-basis:calc((100% - var(--news-gap)) / 2);}
  }
  @media(max-width:620px){
    .news-item{flex-basis:100%;}
  }

  /* ---------- Offer: a frase a fechar, com uma palavra que anda ---------- */
  /* O mesmo areia dos reviews da homepage. É o bloco que fecha uma página, e o
     fundo é o que o separa do que vem antes: sobre branco, uma frase centrada e
     um botão liam-se como o fim da secção anterior e não como um convite. */
  .offer{background:var(--sand);}
  .offer-in{text-align:center;max-width:900px;}
  .offer-line{margin:0;text-wrap:balance;}
  .offer-do{margin:clamp(28px,3.4vw,48px) 0 0;}

  /* A palavra que se troca. A largura é reservada pelo JavaScript na medida da
     palavra mais comprida da lista: sem isso, a frase encolhe e cresce a cada
     letra escrita, e uma frase centrada a mudar de largura salta de lado no
     ecrã inteiro. Alinhada à esquerda dentro dessa largura, para as letras
     saírem sempre do mesmo ponto. */
  .typed{display:inline-block;text-align:left;white-space:nowrap;}
  /* O cursor. É o que diz que aquilo está a ser escrito e não meio apagado —
     sem ele, uma palavra a meio parece um erro. */
  .typed::after{
    content:"";display:inline-block;width:1px;height:.86em;
    margin-left:.06em;vertical-align:-.08em;
    background:currentColor;animation:typedCaret 1.05s step-end infinite;
  }
  @keyframes typedCaret{0%,49%{opacity:1;}50%,100%{opacity:0;}}
  /* Sem animação nenhuma, o cursor também não faz sentido: fica a primeira
     palavra escrita, como se fosse a única. */
  @media(prefers-reduced-motion:reduce){
    .typed::after{display:none;}
  }

  /* ---------- Story: a página de uma notícia ----------
     Fotografia a toda a largura, caixa do título a subir-lhe por cima, e o
     texto numa medida estreita por baixo. Medidas da referência num ecrã de
     1920: fotografia com cerca de 620 de altura, caixa de 1060 centrada a
     sobrepor-lhe uns 140, e o texto a correr 620. */
  .story{background:var(--sand);padding-bottom:clamp(56px,7vw,110px);}
  .story-photo{
    height:clamp(340px,52vh,620px);
    background-size:cover;background-position:center;
    background-color:var(--grey);
  }
  /* O véu do topo: sendo este o primeiro bloco da página, o cabeçalho assenta
     sobre a fotografia, e sobre um céu claro o menu branco desaparecia. */
  .story-photo{position:relative;}
  .story-photo::before{
    content:"";position:absolute;inset:0 0 auto 0;height:240px;pointer-events:none;
    background:linear-gradient(180deg,rgba(8,32,36,.5),rgba(8,32,36,0));
  }
  .story-head{
    position:relative;z-index:1;
    max-width:1060px;margin:clamp(-120px,-7vw,-60px) auto 0;
    background:var(--sand);text-align:center;
    padding:clamp(28px,3.4vw,52px) clamp(20px,3vw,56px) clamp(8px,1.4vw,18px);
  }
  /* O rectângulo da etiqueta. Cor sólida da marca e letras claras: é a única
     mancha de cor da página, e é o que diz de que assunto se trata antes de se
     ler o título. */
  .story-tag{
    display:inline-block;margin-bottom:clamp(14px,1.6vw,22px);
    background:var(--grey);color:var(--brand-yellow);
    font-family:var(--body);font-weight:600;font-size:.7rem;
    letter-spacing:.22em;text-transform:uppercase;
    padding:.5em 1.1em;border-radius:2px;
  }
  .story-head .display{
    font-size:clamp(26px,3.4vw,50px);line-height:1.12;text-wrap:balance;margin:0;
  }
  /* Setenta letras por linha, no máximo. É a medida a que uma linha de texto
     corrido se lê sem o olho se perder ao voltar ao princípio da seguinte — e
     a largura do ecrã dá o triplo disso. */
  .story-body{
    max-width:66ch;margin-inline:auto;
    padding:clamp(28px,4vw,64px) var(--gutter) 0;
  }
  .story-body p{
    font-family:var(--body);font-weight:600;color:var(--muted);
    font-size:17px;line-height:1.75;margin:0 0 1.5em;
  }
  /* A capitular do primeiro parágrafo. Só do primeiro: repetida, deixava de
     marcar o princípio do texto e passava a decorar cada parágrafo. */
  .story-body > p:first-of-type::first-letter{
    float:left;font-family:var(--display);font-weight:500;color:var(--ink);
    font-size:3.4em;line-height:.82;margin:.06em .12em 0 0;
  }
  .story-back{margin-top:2.4em;}
  .story-back a{color:var(--ink);text-decoration:underline;text-underline-offset:4px;}

  /* ---------- Contact form: a panel over a photograph ----------
     A fotografia é o fundo da secção e o painel assenta em cima dela, encostado
     à direita, com imagem de todos os lados. É outro desenho do anterior, em
     que a fotografia era uma faixa que acabava e o painel descia para lá dela:
     aqui a fotografia acompanha o painel até ao fim, seja qual for a altura que
     o formulário venha a ter.
     A secção não tem altura declarada — quem a dá é o painel mais o ar em
     volta. Com uma altura fixa, bastava o formulário crescer (mais um assunto
     na lista, uma frase de erro por baixo de um campo) para transbordar. */
  .contact-band{
    position:relative;
    /* Por baixo da fotografia, e não branco: enquanto a imagem carrega, e se
       não carregar, o painel continua a assentar sobre alguma coisa. */
    background:var(--grey);
    /* O topo tem de passar por baixo do cabeçalho, que nesta página é
       transparente e assenta sobre a fotografia. */
    padding-block:clamp(150px,17vh,210px) clamp(70px,9vw,130px);
  }
  .contact-photo{
    position:absolute;inset:0;z-index:0;
    background-size:cover;
    /* 62% e não center: o alto desta fotografia é mar aberto, e ao centro
       mostrava-se água a mais e costa a menos. */
    background-position:center 62%;
  }
  /* O véu do topo. Sendo este o primeiro bloco da página, o cabeçalho assenta
     por cima da fotografia — e sobre um mar claro o menu branco desaparecia. */
  .contact-photo::before{
    content:"";position:absolute;inset:0 0 auto 0;height:240px;pointer-events:none;
    background:linear-gradient(180deg,rgba(8,32,36,.55),rgba(8,32,36,0));
  }
  /* O painel encosta à direita, mas não ao bordo: fica-lhe fotografia por fora,
     que é o que o põe *sobre* a imagem em vez de a cortar ao meio. */
  .contact-band > .container{
    position:relative;z-index:1;max-width:none;
    padding-inline:var(--gutter);
    display:flex;justify-content:flex-end;
  }
  .contact-panel{
    background:var(--white);
    width:min(620px,100%);
    margin-right:clamp(0px,7vw,150px);
    padding:clamp(30px,3.4vw,56px) clamp(24px,3.2vw,52px);
    border-radius:2px;box-shadow:0 30px 80px rgba(8,32,36,.28);
  }
  /* Dentro do painel o texto alinha à esquerda. O .section-head centra-se
     porque a meio de uma página é isso que se quer; numa caixa estreita ao lado
     de uma fotografia, não. */
  .contact-panel .section-head{
    text-align:left;max-width:none;margin:0 0 clamp(22px,2.6vw,34px);}
  .contact-panel .lead{margin-inline:0;}

  /* Os três campos curtos partilham uma linha enquanto couberem. auto-fit com
     um mínimo, e não três colunas fixas: acrescentar um campo no futuro não
     obriga a mexer aqui, e num ecrã estreito empilham-se sozinhos. */
  .enquiry-grid{display:grid;gap:clamp(14px,2vw,22px);
    grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
    /* O espaço para o que vem a seguir vive aqui: os campos lá dentro têm a
       margem a zero para o gap da grelha os separar sem somar às margens. */
    margin-bottom:clamp(16px,2vw,22px);}

  .enquiry .field{display:flex;flex-direction:column;gap:7px;margin-bottom:clamp(16px,2vw,22px);}
  .enquiry-grid .field{margin-bottom:0;}

  /* O nome do campo continua no HTML, escondido só de quem vê. Um texto de
     exemplo dentro da caixa não é um nome de campo: desaparece à primeira
     letra escrita, e não é lido como nome nenhum por quem ouve a página. */
  .a11y-only{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap;
  }

  /* Um risco por baixo, e não uma caixa à volta. A caixa de texto herda o fundo
     do painel em vez de trazer branco próprio — sobre o painel branco a caixa
     desenhava-se pela borda, e a borda é justamente o que sai.

     Em repouso o formulário inteiro é cinza claro: o texto, os riscos e o que
     está escrito dentro das caixas. É isso que faz o risco escuro do rato ler-se
     como uma mudança — sobre um formulário já escuro não haveria nada para
     escurecer. Escuros ficam só o título e o ante-título, que são o que se lê
     antes de se começar a preencher.

     O risco que entra é um fundo e não uma segunda borda: um degradado de
     largura zero que cresce até 100% em 0.4s. Um <input> não aceita
     pseudo-elementos, e a alternativa era embrulhar cada campo num <span> só
     para ter onde desenhar a linha. `background-clip` é border-box por
     omissão, por isso o degradado assenta exactamente por cima da borda de
     baixo em vez de ficar um pixel acima dela. */
  .enquiry :is(input[type=text],input[type=email],input[type=tel],textarea,select){
    font-family:var(--body);font-weight:600;font-size:16px;color:var(--muted);
    background-color:transparent;border:0;border-radius:0;
    border-bottom:1px solid color-mix(in srgb, var(--ink) 18%, transparent);
    padding:.7rem 0;width:100%;
    background-image:linear-gradient(var(--ink),var(--ink));
    background-repeat:no-repeat;
    background-position:left bottom;
    background-size:0 1px;
    transition:background-size .4s ease, color .3s ease;
  }
  /* O campo inteiro responde ao rato, e não só a caixa: quem aponta ao nome do
     campo está a apontar ao campo. */
  .enquiry .field:hover :is(input,textarea,select),
  .enquiry :is(input,textarea,select):focus{
    background-size:100% 1px;color:var(--ink);
  }
  .enquiry :is(input,textarea,select):focus{outline:none;}
  .enquiry textarea{resize:vertical;min-height:120px;line-height:1.5;}
  .enquiry ::placeholder{color:var(--muted);opacity:1;}
  @media(prefers-reduced-motion:reduce){
    .enquiry :is(input,textarea,select){transition:none;}
  }

  /* A persiana. O que o browser desenha por sua conta — a seta e a lista que se
     abre — é do sistema e quase não se estiliza; o que se vê fechado é todo
     nosso, e é o que fica igual ao resto do formulário. A seta é desenhada aqui
     em SVG, na cor do texto, para não depender de nenhum tipo de letra. */
  /* `.enquiry .field select` e não `.enquiry select`: a regra do risco acima usa
     um :is(), e um :is() vale a especificidade do seu argumento mais forte —
     input[type=text]. `.enquiry select` ficava por baixo dela e este bloco
     inteiro não chegava a aplicar-se. */
  /* Duas camadas de fundo: a seta, e por baixo dela o mesmo risco que cresce
     nos outros campos. As três listas — imagem, posição e tamanho — têm de
     andar na mesma ordem, ou a seta aparece esticada ao fundo do campo. */
  .enquiry .field select{
    appearance:none;-webkit-appearance:none;cursor:pointer;
    padding-right:26px;
    background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b7a7c' stroke-width='1.6'%3E%3Cpath d='M3 6l5 5 5-5'/%3E%3C/svg%3E"),
      linear-gradient(var(--ink),var(--ink));
    background-repeat:no-repeat, no-repeat;
    background-position:right 2px center, left bottom;
    background-size:13px, 0 1px;
  }
  .enquiry .field:hover select,
  .enquiry .field select:focus{background-size:13px, 100% 1px;}
  /* Enquanto ninguém escolheu, o que lá está é um convite e não uma resposta —
     lê-se na cor dos outros textos de exemplo. A lista aberta é do sistema, por
     isso as opções levam a cor de volta. */
  .enquiry select:has(option[value=""]:checked){color:var(--muted);}
  .enquiry select option{color:var(--ink);}

  /* O campo que falhou é assinalado pela cor e pela frase por baixo. Só pela
     cor não chegava: quem não distingue vermelho ficava sem saber qual era. */
  .enquiry .field--bad :is(input,textarea,select){border-bottom-color:#b3261e;}
  .enquiry .field-note{font-family:var(--body);font-weight:600;font-size:.82rem;
    letter-spacing:normal;text-transform:none;color:#b3261e;}

  /* O que o servidor responde ao formulário: uma linha dentro do painel, com um
     risco à esquerda. Não é uma faixa nem tem fundo próprio — o painel já é a
     caixa, e uma caixa dentro de outra só rouba largura ao que vem a seguir. */
  .enquiry-said{
    font-family:var(--body);font-weight:600;font-size:.95rem;line-height:1.45;
    margin:0 0 clamp(16px,2vw,22px);padding-left:14px;
    border-left:2px solid currentColor;
  }
  .enquiry-said--ok{color:var(--grey);}
  .enquiry-said--bad{color:#b3261e;}

  /* O consentimento e o botão na mesma fila. Em cima o consentimento, que é a
     ordem por que se lê e por que se chega aos dois pelo teclado: primeiro
     concorda-se, depois envia-se. Numa caixa estreita não cabem lado a lado e
     passam a duas linhas, que é a mesma ordem. */
  .enquiry-send{
    display:flex;flex-wrap:wrap;align-items:center;gap:16px 22px;
    margin-top:clamp(18px,2.4vw,28px);
  }
  .check{display:flex;align-items:flex-start;gap:10px;cursor:pointer;
    font-family:var(--body);font-weight:600;font-size:15px;letter-spacing:normal;
    text-transform:none;color:var(--muted);line-height:1.35;
    transition:color .3s ease;}
  .check:hover{color:var(--ink);}
  /* Desenhada à mão e não com accent-color: o accent-color pinta a caixa mas o
     visto vem sempre branco, e o que se quer é o contrário — caixa cinza da
     marca, visto a amarelo. O visto é uma forma recortada, não um caractere:
     um "✓" muda de desenho conforme a fonte que o sistema tiver. */
  .check input{
    appearance:none;-webkit-appearance:none;
    width:18px;height:18px;flex:0 0 auto;margin:1px 0 0;cursor:pointer;
    border:1px solid rgba(27,36,38,.35);border-radius:2px;background:var(--white);
    display:grid;place-items:center;transition:background .2s,border-color .2s;
  }
  .check input:checked{background:var(--grey);border-color:var(--grey);}
  .check input::before{
    content:"";width:10px;height:10px;background:var(--brand-yellow);
    transform:scale(0);transition:transform .15s ease;
    clip-path:polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  }
  .check input:checked::before{transform:scale(1);}
  .check input:focus-visible{outline:2px solid var(--grey);outline-offset:2px;}

  /* Depois de .check e não antes: as regras da caixa desenham a borda, e uma
     excepção declarada acima delas era reescrita por elas sem se ver porquê. */
  .check--consent{align-items:center;}
  .check--consent a,.check--consent u{color:inherit;text-decoration:underline;
    text-underline-offset:3px;}
  .check--bad input{border-color:#b3261e;}
  @media(prefers-reduced-motion:reduce){
    .check input,.check input::before{transition:none;}
  }

  .enquiry-send button[type=submit]{margin:0;}

  /* A armadilha para robôs. Fora do ecrã e não display:none — um robô que leia
     a folha de estilos ignora o que está escondido, mas preenche o que apenas
     não se vê. aria-hidden e tabindex tratam de quem navega por teclado ou por
     leitor de ecrã, que nunca lá chega. */
  .enquiry-trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}

  /* Sem largura para uma coluna de fotografia ao lado, o painel deixa de estar
     encostado a um lado e passa a estar centrado. Encostado num ecrã estreito
     não se lê como sobreposto — lê-se como desalinhado. */
  @media(max-width:1000px){
    .contact-band > .container{justify-content:center;}
    .contact-panel{margin-right:0;}
  }
  @media(max-width:560px){
    .contact-panel{padding-inline:20px;}
  }

  /* ---------- Spread: a wide photograph, in columns ---------- */
  /* A faixa sai do .container e toma a largura da página, com as margens
     laterais do site — as mesmas do cabeçalho. Era isso ou ficar 360px mais
     estreita do que a fotografia que vem antes dela na mesma página. */
  .spread-wrap{padding-inline:var(--gutter);}
  .spread-head{margin-inline:auto;text-align:center;}
  /* Numa página que abre em amarelo, o título assenta no mesmo amarelo e toma
     o cinza da marca, como o bloco de passos que abre a página — ver
     .steps--sun. No preto do texto corrido destoava dos títulos à volta. */
  body.tone-sun .spread-head :is(h1,h2,h3,h4,h5,h6),
  body.tone-sun .spread-head .eyebrow{color:var(--grey);}
  .spread-band{margin-top:clamp(30px,4vw,60px);}

  .spread-photo{position:relative;overflow:hidden;
    min-height:clamp(320px,34vw,520px);}

  /* As fotografias estão todas aqui, empilhadas. A de repouso fica por baixo e
     não se mexe; as das colunas aparecem por cima quando a sua é apontada.
     É opacidade e não troca de `src`: trocar o endereço mandava buscar a
     fotografia à rede a cada passagem do rato, e via-se o buraco. */
  .spread-shot{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
    display:block;opacity:0;transition:opacity .5s ease;}
  .spread-shot--base{opacity:1;}
  .spread-shot.is-on{opacity:1;}

  /* Um escurecimento só em baixo, onde os títulos ficam. A fotografia por cima
     deles fica como é — o véu existe para as palavras se lerem, não para mudar
     a fotografia. */
  .spread-photo::after{content:"";position:absolute;inset:auto 0 0 0;height:62%;
    pointer-events:none;z-index:2;
    background:linear-gradient(to top, rgba(8,18,20,.62), rgba(8,18,20,0));}

  /* As colunas ocupam a altura toda: a zona que responde ao ponteiro é a coluna
     inteira e não as três palavras lá em baixo. O texto é que assenta no fundo,
     e é por assentar no fundo que a lista, ao abrir, empurra o título para
     cima em vez de sair da caixa. */
  .spread-cols{position:absolute;inset:0;z-index:3;list-style:none;margin:0;padding:0;
    display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));}
  .spread-col{position:relative;display:flex;flex-direction:column;justify-content:flex-end;
    padding:clamp(20px,2.4vw,36px);color:#fff;cursor:default;}
  .spread-col:focus-visible{outline:2px solid #fff;outline-offset:-4px;}
  /* Sem fios a separar as colunas. Havia-os, para se ver onde uma acabava e a
     outra começava antes de lá se chegar com o rato — mas riscavam a fotografia
     em cinco, e a fotografia é uma só. Quem aponta uma coluna descobre-a pelo
     escuro que ela ganha, que é resposta bastante. */
  /* A coluna apontada deixa de ser fotografia e passa a ser painel. O escuro é
     opaco de propósito: translúcido, a fotografia por baixo continuava a
     disputar a leitura com a lista que acabou de abrir. */
  .spread-col::before{content:"";position:absolute;inset:0;pointer-events:none;
    background:var(--ink);opacity:0;transition:opacity .4s ease;}
  .spread-col:hover::before,.spread-col:focus-visible::before{opacity:1;}

  .spread-col-name{position:relative;font-family:var(--display);font-weight:500;
    font-size:clamp(13px,1.12vw,18px);line-height:1.25;
    text-shadow:0 2px 18px rgba(8,18,20,.4);}
  /* O traço por baixo do título. É o que o desenho põe lá e é o que separa um
     título do seguinte quando os dois ocupam duas linhas. */
  .spread-col-name::after{content:"";display:block;width:18px;height:1.5px;
    background:currentColor;opacity:.75;margin-top:clamp(10px,1.2vw,16px);}

  /* A lista que só existe com o ponteiro em cima. Abre em altura, como o
     segundo nome dos cartões: reposicionar não se anima, crescer sim. E como a
     coluna assenta o conteúdo no fundo, o que cresce empurra o título para
     cima — que é onde o desenho o põe quando a coluna está aberta. */
  .spread-col-more{position:relative;display:grid;grid-template-rows:0fr;opacity:0;
    transition:grid-template-rows .4s ease,opacity .35s ease;}
  .spread-col-more > span{display:block;overflow:hidden;}
  .spread-col-line{display:block;font-family:var(--body);font-weight:600;
    font-size:clamp(12px,1.05vw,16px);line-height:1.9;color:rgba(255,255,255,.92);}
  .spread-col-line:first-child{padding-top:clamp(14px,1.6vw,22px);}
  .spread-col:hover .spread-col-more,
  .spread-col:focus-visible .spread-col-more{grid-template-rows:1fr;opacity:1;}

  @media(max-width:1000px){
    /* Cinco colunas num ecrã médio dão 140px cada, e «A team to bring together»
       parte-se em cinco linhas. Passam a duas filas. */
    .spread-cols{grid-template-columns:repeat(2,1fr);}

    /* And once they are in rows the band can no longer be a fixed height.
       Below this width there is no pointer, so the lists are all open at once
       — see @media(hover:none) — and three rows of a title and three lines do
       not fit in it: the last column's list was being cut off by the frame.

       So the columns come out of the absolute positioning and the band takes
       its height from them instead. The photographs stay stretched behind it,
       and the min-height below goes on being the floor — the band is now
       whichever is taller, the text or that. */
    .spread-cols{position:relative;}
    .spread-photo{min-height:clamp(420px,86vw,640px);}

    /* Five into two leaves the last column with half a row to itself. The veil
       that makes the words readable is drawn column by column, so that empty
       half showed as a lighter rectangle cut out of the corner — the one thing
       in the band that looked like a mistake. The last column now runs the
       whole width and the veil closes over it. */
    .spread-col:last-child:nth-child(odd){grid-column:1 / -1;}

    /* Two columns on a telephone are narrow enough that a four-word title
       breaks badly: «together» or «privately» ends up alone on its own line. */
    .spread-col-name{text-wrap:balance;}

    /* In one row the titles all sit along the foot of the band, which is why
       the veil only darkens the bottom of it. In three rows they are spread
       down the whole thing, and the top two were landing on open sky. So here
       it covers the band end to end — still heavier at the bottom, so the
       photograph is not flattened into a grey sheet. */
    .spread-photo::after{inset:0;height:auto;
      background:linear-gradient(to top, rgba(8,18,20,.66), rgba(8,18,20,.40));}
  }
  /* Sem ponteiro não há hover: as listas ficam à vista, que é o que elas têm
     para dizer, e não à espera de um gesto que não existe. Abaixo dos 820 isto
     deixa de valer — lá o bloco é um acordeão e abre-se ao toque. */
  @media(hover:none) and (min-width:821px){
    .spread-col-more{grid-template-rows:1fr;opacity:1;}
    .spread-col::before{opacity:.55;}
  }

  /* ---- On a telephone: an accordion ----
     Five columns of one photograph cannot be read side by side on a screen
     this narrow, and opening all five lists at once makes a wall of words. So
     the five become rows of a single column, and one opens at a time.

     The open row is a panel of the photograph with its words on it; the closed
     ones are dark strips of title under it. The photograph itself is still the
     band's and not the row's — it runs behind the whole accordion and changes
     to whichever row is open, which is what the columns do with the pointer on
     a wide screen.

     The collapsing is hung on .is-accordion, which main.js puts there. Without
     JavaScript nothing is collapsed and all five lists stay open, as they were
     — a row that cannot be opened must not start closed. */
  @media(max-width:820px){
    /* Repeated from the rule above rather than leant on: the rows only give
       the band its height while they are in the flow, and this block must not
       depend on another one's breakpoint staying where it is. */
    .spread-cols{grid-template-columns:1fr;position:relative;}

    /* The band is exactly as tall as the accordion: no floor, or a closed
       accordion would leave a bare strip of photograph hanging below it. */
    .spread-photo{min-height:0;}

    /* Lighter than the band's wash above, because down here the dark comes
       from the rows themselves and the two together would bury the
       photograph. */
    .spread-photo::after{background:rgba(8,18,20,.22);}

    /* The row has to carry a real measure even when it is shut, and not the
       `auto` that a grid item gets by default: a transition between `auto` and
       a length does not run at all, and the row was jumping open in a single
       frame. It is also set above what a closed row needs, so the growth
       begins on the first frame instead of waiting for the number to climb
       past the height the content already had.

       All three movements — the row, the veil, the list — share one duration
       and one curve, so the thing opens as one piece. */
    .spread-photo.is-accordion .spread-col{
      min-height:clamp(100px,22vw,128px);
      transition:min-height .5s cubic-bezier(.33,0,.2,1);
    }

    /* Bigger than on the wide band, and deliberately so. There the five
       titles are columns of a photograph and the size is what lets five of
       them stand side by side; here each one is a row of its own with the
       screen's whole width to itself, and at the band's 13px it read as a
       caption rather than as the thing to press. */
    .spread-photo.is-accordion .spread-col-name{font-size:clamp(17px,4.4vw,20px);}
    .spread-photo.is-accordion .spread-col-line{
      font-size:clamp(14px,3.7vw,16px);line-height:1.75;
    }
    .spread-photo.is-accordion .spread-col::before{
      transition:opacity .5s cubic-bezier(.33,0,.2,1);
    }
    .spread-photo.is-accordion .spread-col-more{
      grid-template-rows:0fr;opacity:0;
      transition:grid-template-rows .5s cubic-bezier(.33,0,.2,1),opacity .35s ease;
    }

    /* Closed, which is how it starts: five titles lying on the resting
       photograph, with just enough veil under them to be read. The band is a
       photograph first — darkening it before anybody has asked for anything
       would be hiding it for no reason. */
    .spread-photo.is-accordion .spread-col::before{opacity:.45;}

    /* Once something is open the others go dark. That is what makes the open
       one read as the open one: not its own brightness alone, but the
       difference. .has-open is put there by main.js. */
    .spread-photo.is-accordion.has-open .spread-col::before{opacity:.82;}

    /* The open one: the veil lifts almost clear, the list comes down, and the
       row grows into a panel — which is the only way the photograph gets room
       to be seen at all. */
    .spread-photo.is-accordion .spread-col.is-open{min-height:clamp(240px,54vw,360px);}
    .spread-photo.is-accordion .spread-col.is-open::before{opacity:.20;}
    .spread-photo.is-accordion .spread-col.is-open .spread-col-more{grid-template-rows:1fr;opacity:1;}

    /* It is something to press, so it says so. */
    .spread-photo.is-accordion .spread-col{cursor:pointer;}
  }
  @media(max-width:820px) and (prefers-reduced-motion:reduce){
    .spread-photo.is-accordion .spread-col,
    .spread-photo.is-accordion .spread-col::before,
    .spread-photo.is-accordion .spread-col-more{transition:none;}
  }
  @media(prefers-reduced-motion:reduce){
    .spread-shot,.spread-col::before,.spread-col-more{transition:none;}
  }

  /* ---------- Keywords: words crossing a photograph ---------- */
  /* A largura toda do ecrã, fora do .container — a fotografia encosta às bordas
     como o mosaico. A altura vem de uma proporção com tecto: numa janela muito
     larga a faixa passava a ocupar meio ecrã. */
  /* width:100% is load-bearing and not tidiness. With aspect-ratio and a
     min-height taller than the ratio allows, the ratio starts driving the
     width instead of the height: on a 386px screen the floor of 190px became
     a band 665px wide, and the whole page scrolled sideways. Pinning the
     width puts the ratio back in charge of only the height, with min-height
     as a floor under it — the photograph is object-fit:cover and fills
     whatever shape that leaves. */
  .keyband{position:relative;overflow:hidden;display:grid;align-items:center;
    width:100%;aspect-ratio:2400 / 686;min-height:190px;background:var(--grey);}
  /* A proporção é a da fotografia, e não uma altura com tecto. Era
     `min-height:clamp(190px,28.6vw,560px)`: a partir dos ~1960px a altura
     parava e a faixa continuava a alargar, até 5:1 num ecrã grande — e aí o
     recorte comia as cabeças das pessoas, que é o que a faixa tem para mostrar.
     Presa à proporção, a fotografia nunca é cortada em cima nem em baixo, seja
     qual for a largura. Num telemóvel manda o min-height e o corte passa a ser
     pelos lados, que é onde não há nada a perder. */
  .keyband-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
    display:block;}
  /* Um véu escuro por cima da fotografia. Sem ele, o amarelo das palavras vive
     à sorte do que estiver por baixo: sobre céu ou sobre uma parede branca
     deixava-se de ler. */
  .keyband::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:rgba(8,18,20,.22);}
  /* O tempo é escrito pelo JavaScript, a partir da largura de uma passagem e de
     uma velocidade em pixels por segundo — ver main.js. O valor aqui é o que
     vale antes de ele correr e se ele não correr: uma volta lenta, em vez de
     uma fila parada a meio do ecrã. */
  .keyband-track{position:relative;z-index:2;display:flex;width:max-content;
    animation:keybandRun var(--keyband-time,40s) linear infinite;}
  .keyband-run{display:flex;align-items:baseline;gap:clamp(14px,1.6vw,34px);
    padding-right:clamp(14px,1.6vw,34px);}
  .keyband-word,.keyband-plus{font-family:var(--display);font-weight:500;
    color:var(--brand-yellow-soft);line-height:1.2;white-space:nowrap;
    /* A mesma medida com que as páginas do site abrem — o .hero-title e o
       título do Where in Portugal. A faixa é larga e a fotografia por baixo já
       é o que se vê primeiro; as palavras acompanham-na, não competem com ela. */
    font-size:clamp(23px,4.06vw,52px);
    text-shadow:0 2px 22px rgba(8,18,20,.35);}
  .keyband-plus{opacity:.85;}
  /* Metade, e não a largura toda: as duas passagens são iguais, por isso ao fim
     de metade do percurso a fila está exactamente onde começou. */
  @keyframes keybandRun{from{transform:translateX(0);}to{transform:translateX(-50%);}}
  /* Parada, mas a dizer o mesmo: a primeira passagem fica à vista, encostada à
     esquerda, em vez de a faixa ficar vazia. */
  @media(prefers-reduced-motion:reduce){
    .keyband-track{animation:none;}
  }

  /* ---------- Steps: a photograph and an accordion ---------- */
  /* Abre a página, por baixo do cabeçalho fixo. A folga é a altura dele mais o
     ar que o desenho pede por cima do título — a mesma conta que o bloco de
     vídeo faz em --open-top. */
  main > .steps:first-child{padding-top:clamp(150px,17vh,210px);}
  .steps{--step-mark:clamp(9px,.75vw,11px);--step-gap:clamp(16px,2.6vw,44px);}
  .steps--sun{background:var(--brand-yellow-soft);color:var(--grey);}
  .steps--sun :is(h1,h2,h3,h4,h5,h6),
  .steps--sun .eyebrow,
  .steps--sun .lead,
  .steps--sun .step-text{color:var(--grey);}

  .steps-head{text-align:center;max-width:900px;margin-inline:auto;}
  /* Maior que o .display do resto do site: é o título de uma página e não de
     uma secção dentro dela, e no desenho ocupa metade da largura do ecrã. */
  /* `:is(...)` e não só a classe: o .display do resto do site vale (0,1,1) e
     ganhava a uma classe sozinha, deixando o título de página do tamanho de um
     título de secção.
     A medida é a das outras páginas que abrem — a mesma clamp do .hero-title e
     do título do Where in Portugal. Três páginas que abrem devem abrir com a
     mesma voz. */
  :is(h1,h2,h3,h4,h5,h6).steps-title{font-size:clamp(23px,4.06vw,52px);line-height:1.12;
    letter-spacing:normal;text-wrap:balance;}
  /* E a distância até à frase de apoio é a que a homepage guarda entre o título
     do diapositivo e a linha por baixo dele — ver .hero-tagline. */
  .steps-intro{max-width:none;margin:1.5rem auto 0;text-wrap:balance;}
  .steps-intro p{margin:0;}
  .steps-intro p + p{margin-top:.6rem;}

  /* A fotografia e os passos lado a lado. `align-items:start` para a coluna dos
     passos crescer para baixo quando um abre, em vez de se recentrar — o texto
     que se acabou de abrir saltava para cima ao aparecer. */
  .steps-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    gap:clamp(30px,5vw,80px);align-items:start;margin-top:clamp(40px,6vw,96px);}
  .steps-media img{width:100%;height:auto;display:block;aspect-ratio:.94;object-fit:cover;}

  /* A pauta vertical dos passos em pixéis inteiros — é por isso que daqui para
     baixo há `round()` e números redondos onde antes havia rem e décimas.
     O sublinhado do rato tem um pixel de altura e é desenhado no fundo da
     frase. Quando essa borda cai a meio de um pixel do ecrã, o browser reparte
     o risco por duas fileiras com opacidades diferentes e ele sai mais claro e
     mais grosso. Cada passo caía num ponto diferente do pixel — medidos .42,
     .16, .90, .63 e .37 — e daí os cinco riscos terem cinzentos e espessuras
     diferentes uns dos outros.
     Arredondar a distância de um passo ao seguinte (o intervalo, as entrelinhas
     e os espaços de dentro) põe os cinco no mesmo ponto do pixel: cinco riscos
     iguais. Onde o ponto do pixel cai, isso depende de tudo o que está acima na
     página e não se controla daqui — o que se controla, e o que faltava, é
     serem todos iguais entre si.
     O valor sem `round()` fica declarado antes, para quem não conheça a função
     ficar com o que tinha. */
  .steps-list{display:grid;gap:clamp(26px,3.4vw,50px);
    gap:round(clamp(26px,3.4vw,50px),1px);}
  /* O nome do passo na fonte dos títulos, com a medida do .display. É o título
     do passo e lê-se como tal; a frase por baixo do + é que toma a letra dos
     pontos numerados da homepage.
     Em minúsculas por desenho, e não por o texto estar escrito assim — como o
     antetítulo é maiúsculas por desenho. Quem escreve no backoffice escreve
     «We listen», que é como se escreve, e a página é que decide como o mostra;
     mudar de ideias é mudar esta linha e não cinco textos. */
  .step-name{margin:0 0 9px;line-height:round(1.12em,1px);text-transform:lowercase;}
  /* O botão é a linha, não o nome. Sem moldura nem fundo: o que se vê é o sinal
     de mais e a frase, como no desenho. `width:100%` e `text-align:left` porque
     um <button> centra e encolhe ao conteúdo por omissão. */
  .step-do{display:grid;grid-template-columns:var(--step-mark) 1fr;gap:var(--step-gap);
    align-items:start;width:100%;padding:0;border:0;background:none;color:inherit;
    text-align:left;cursor:pointer;
    /* A letra dos pontos numerados da homepage (.ts-txt), toda ela: a mesma
       fonte, o mesmo peso, o mesmo corpo e a mesma entrelinha. As duas listas
       dizem o mesmo tipo de coisa e devem ler-se da mesma maneira — o título do
       passo, esse, continua na fonte dos títulos. */
    font-family:var(--body);font-weight:600;
    font-size:clamp(17px,1.80vw,23px);line-height:1.29;line-height:round(1.29em,1px);}
  /* O sublinhado que cresce da esquerda, o mesmo do formulário de contactos: um
     degradado de fundo com zero de largura que se estica até 100% em 0.4s. É um
     fundo e não uma borda porque uma borda não se anima de dentro para fora — e
     é a mesma técnica que lá está, para os dois gestos do site se parecerem um
     com o outro.
     Está na frase e não no botão: o botão ocupa a coluna toda, e o risco ia
     muito além da última letra. `max-content` encolhe a caixa ao texto;
     `max-width:100%` devolve-lhe a quebra de linha quando a frase for maior do
     que a coluna, e aí o risco acompanha o bloco de texto, que é o que ele
     mede. */
  .step-line{display:block;width:max-content;max-width:100%;padding-bottom:7px;
    background-image:linear-gradient(currentColor,currentColor);
    background-repeat:no-repeat;
    background-position:left bottom;
    background-size:0 1px;
    transition:background-size .4s ease;}
  /* O passo inteiro responde ao rato, e não só a frase: quem aponta ao nome do
     passo está a apontar ao passo. É o que o campo do formulário faz. */
  .step:hover .step-line,
  .step-do:focus-visible .step-line{background-size:100% 1px;}
  .step-do:focus-visible{outline:2px solid currentColor;outline-offset:6px;}
  @media(prefers-reduced-motion:reduce){
    .step-line{transition:none;}
  }

  /* O + e o − são o mesmo par de barras: a vertical roda até desaparecer. Duas
     barras e não um caractere, para a linha ter a espessura do desenho e não a
     que a fonte quiser dar-lhe. */
  .step-mark{position:relative;display:block;height:1.35em;}
  .step-mark::before,.step-mark::after{content:"";position:absolute;left:0;top:50%;
    width:100%;height:1.5px;background:currentColor;transform:translateY(-50%);
    transition:transform .35s ease,opacity .35s ease;}
  .step-mark::after{transform:translateY(-50%) rotate(90deg);}
  .step-do[aria-expanded="true"] .step-mark::after{transform:translateY(-50%) rotate(0deg);opacity:0;}

  /* A abertura é uma altura a animar, e a altura vem do JavaScript — ver o
     comentário em main.js. A alternativa só-CSS era a grelha a passar de 0fr a
     1fr, como o .tile-sub dos cartões faz; preferiu-se medir a altura porque a
     animação de grid-template-rows é recente e desigual entre browsers, e este
     é um bloco onde a abertura é a única coisa que acontece.
     Sem altura declarada aqui, o painel está aberto — que é como chega a quem
     não tem JavaScript. Fechá-lo é coisa que só quem o sabe reabrir faz. */
  .step-panel{overflow:hidden;transition:height .45s cubic-bezier(.22,.61,.36,1);}
  /* O texto que abre volta ao corpo que sempre teve. Chegou a tomar o dos
     pontos numerados da homepage, como a frase por cima dele, e é mais pequeno
     de propósito: a frase é a que se lê fechado, e esta é a explicação. */
  .step-text{font-family:var(--body);font-size:clamp(14px,1.05vw,16px);
    line-height:1.55;line-height:round(1.55em,1px);
    margin-left:calc(var(--step-mark) + var(--step-gap));}
  /* Também em pixéis inteiros: a altura do painel aberto entra na pauta de
     quem está por baixo, e um painel com meia altura fraccionária voltava a
     desencontrar os riscos desses. */
  .step-text > *{margin:0;padding-top:clamp(10px,1.2vw,16px);
    padding-top:round(clamp(10px,1.2vw,16px),1px);}
  .step-text > * + *{padding-top:11px;}
  /* Os três tempos do «We coordinate». Uma lista de definições porque é o que
     de facto é: uma etapa e o que lá acontece. */
  .step-flow{margin:0;}
  /* A etiqueta de cada tempo acompanha o corpo do texto onde vive, e distingue-se
     pelo peso e não por outra fonte: em Unbounded a 23px passava a ser um
     título dentro de um parágrafo. */
  .step-flow dt{font-weight:700;padding-top:11px;}
  .step-flow dd{margin:0;opacity:.85;}

  /* Sem JavaScript o sinal de mais não promete um gesto que ninguém pode fazer,
     e o texto, estando sempre à vista, não precisa da coluna que o alinhava
     com a frase de cima. */
  .steps-list:not(.is-live) .step-mark{display:none;}
  .steps-list:not(.is-live) .step-do{grid-template-columns:1fr;cursor:default;}
  .steps-list:not(.is-live) .step-text{margin-left:0;}

  @media(max-width:900px){
    /* Uma coluna: a fotografia por cima e os passos por baixo. Lado a lado num
       telemóvel, a coluna dos passos ficava com 150px e cada frase partia-se em
       cinco linhas. */
    .steps-body{grid-template-columns:1fr;}
    .steps-media img{aspect-ratio:4/3;}
  }
  @media(prefers-reduced-motion:reduce){
    .step-panel,.step-mark::before,.step-mark::after{transition:none;}
  }

  /* ---------- 4b. Photo carousel + vertical title ---------- */
  /* largura total, só com as margens laterais do site (--gutter) */
  #gallery{padding-block:0;}

  /* título mais largo que o .section-head base: com 640px este partia em 3 linhas */
  #gallery .section-head{max-width:900px;}
  #gallery .section-head .title{text-wrap:balance;}

  /* --- mosaico: uma imagem dominante e as restantes em redor --- */
  /* As células são quadradas: a altura de cada linha vem da largura da coluna,
     e não de uma medida à parte. Era `grid-auto-rows:clamp(150px,20vw,320px)`,
     que num ecrã largo dava colunas de 480px e linhas de 320 — cada fotografia
     um rectângulo deitado. Com `aspect-ratio` no item e as linhas em `auto`, a
     altura passa a seguir a largura sozinha, seja qual for o ecrã. */
  .gal-mosaic{
    display:grid;gap:0;
    grid-template-columns:repeat(4,1fr);
    grid-auto-rows:auto;
  }
  /* A principal ocupa metade da largura e a altura toda. As outras preenchem
     o resto sem deixar buracos: duas em cima, uma larga em baixo. Havendo uma
     quinta imagem, tirar gm-wide fecha o 2x2 da direita. */
  .gm-lead{grid-column:span 2;grid-row:span 2;}
  .gm-wide{grid-column:span 2;}
  /* O par de cores de cada mosaico, alternado ao longo da fila: um amarelo com
     letras cinza, o seguinte cinza com letras amarelas. Declarado no item e não
     nas regras que o usam, para o hover e o texto lerem sempre o mesmo par. */
  .gm-item{position:relative;overflow:hidden;margin:0;aspect-ratio:1;
    --panel:var(--brand-yellow-soft); --panel-ink:var(--grey);}
  .gm-item:nth-child(even){--panel:var(--grey); --panel-ink:var(--brand-yellow-soft);}
  .gm-item img{width:100%;height:100%;object-fit:cover;display:block;
    transition:transform .8s cubic-bezier(.22,.61,.36,1);}
  .gm-item:hover img{transform:scale(1.06);}
  /* Sem gradiente em repouso. Havia um escurecimento no fundo de cada
     fotografia, e existia por uma razão só: tornar legível o nome que estava lá
     sempre escrito. Com o nome a aparecer apenas no hover, o gradiente ficava a
     sujar a fotografia sem nada para sustentar. */

  /* O painel da marca, que fecha sobre a fotografia inteira. Era um preto
     translúcido; passou a cor sólida, por isso a fotografia desaparece e o
     nome do sítio fica sozinho no meio do quadrado. */
  .gm-item::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
    background:var(--panel);opacity:0;transition:opacity .25s ease;}
  .gm-item:hover::before,.gm-item:focus-within::before{opacity:1;}

  /* A legenda só existe com o ponteiro em cima, e é tudo o que o painel leva:
     o nome e a região, ao centro. Sem moldura — era um fio da cor das letras a
     marcar uma caixa dentro do quadrado, e o quadrado já é a caixa. */
  .gm-caption{position:absolute;inset:0;z-index:3;display:grid;
    align-content:center;justify-items:center;text-align:center;
    padding:22px 24px;color:var(--panel-ink);opacity:0;}
  .gm-item:hover .gm-caption,.gm-item:focus-within .gm-caption{
    /* Reposicionar não se anima. Em vez de deixar o texto saltar, ele aparece
       já no sítio: a animação corre de novo a cada hover, e o `both` deixa-o
       visível no fim. */
    animation:gmRise .3s ease both;}
  @keyframes gmRise{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}

  .gm-name{display:block;font-family:var(--display);font-weight:500;line-height:1.2;
    font-size:clamp(16px,1.5vw,21px);margin-bottom:.4rem;}
  /* A ligação é o nome, mas o que se clica é o quadrado todo: o ::after estica
     por cima dele. Fica por baixo da legenda em z-index para o texto continuar
     a ser seleccionável, e por cima da fotografia e do painel para apanhar o
     clique onde quer que caia. */
  .gm-link{color:inherit;text-decoration:none;}
  .gm-link::after{content:"";position:absolute;inset:0;z-index:4;}
  .gm-link:hover{text-decoration:underline;text-underline-offset:4px;}
  /* O foco pelo teclado abre o painel — é o :focus-within do .gm-item — e o
     contorno desenha-se sobre ele. Sem isto, quem navega por teclado passava
     por cinco quadrados sem ver onde estava. */
  .gm-link:focus-visible{outline:2px solid currentColor;outline-offset:3px;}
  /* A região abre com a legenda e não depois dela: a legenda inteira já é o que
     o hover revela, e uma segunda revelação lá dentro só atrasava a leitura.
     A cor herda do painel, em vez do branco que usava sobre a fotografia. */
  .gm-caption .tile-sub{grid-template-rows:1fr;opacity:1;}
  .gm-caption .tile-sub > span{color:inherit;opacity:.72;}
  @media(max-width:820px){
    .gal-mosaic{grid-template-columns:repeat(2,1fr);}
    .gm-lead{grid-column:span 2;grid-row:span 1;}
    .gm-wide{grid-column:span 2;}
  }
  /* No pointer, no hover — e um quadrado sem nome não diz que região é. Aqui o
     nome fica, sobre um véu escuro em vez da cor sólida: no telemóvel não há um
     segundo estado, e cobrir a fotografia para mostrar o nome era trocar uma
     coisa pela outra. */
  @media(hover:none){
    .gm-item::before{opacity:1;background:rgba(8,18,20,.34);}
    .gm-caption{opacity:1;color:#fff;}
  }
  @media(prefers-reduced-motion:reduce){
    .gm-item img,.gm-item::before{transition:none;}
    .gm-item:hover .gm-caption,.gm-item:focus-within .gm-caption{animation:none;opacity:1;}
  }

  /* ---------- 5. Crew ---------- */
  /* A classe, e não a âncora.
     Isto era `#crew{...}`, o que fazia a cor de fundo depender de um campo que
     o editor controla: quem limpasse a âncora nas definições avançadas — um
     campo que só devia servir para o menu lhe apontar — via o bloco perder o
     amarelo sem qualquer aviso, e sem relação visível entre as duas coisas.
     Foi o que aconteceu. O tema decide o aspecto do bloco; o conteúdo não. */
  .crew-band{background:var(--brand-yellow-soft);}
  /* minmax(0,1fr) e não 1fr: o mínimo implícito de 1fr é `auto`, por isso a
     coluna não encolhia abaixo da largura do nome e o membro com o nome mais
     comprido ficava com a foto maior que os restantes. */
  /* No row gap: with each member sharing the grid's rows, a row gap would sit
     between the photograph and the name and again between the name and the
     role. The space between those comes from their own margins instead, and the
     space between wrapped rows of members is put back in the narrow layout
     below — which is the only layout where members wrap. */
  .crew{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
    column-gap:24px;row-gap:0;grid-template-rows:auto auto auto;}
  .crew-member img{aspect-ratio:3/4;object-fit:cover;width:100%;border-radius:2px;filter:grayscale(.15);transition:.5s;}
  .crew-member:hover img{filter:grayscale(0);}
  /* Sem nowrap, pela mesma razão: um nome que não pode quebrar volta a impor
     a largura da coluna. Prefere-se o nome em duas linhas a fotos desiguais.

     The roles line up because every member shares the same three rows of the
     grid above, so the name row is as tall as the tallest name and no taller.
     It used to be done by reserving two lines on every card, which aligned them
     but left a line of empty space under each one-line name. The reservation
     stays as the fallback where subgrid is not understood. */
  .crew-member :is(h1,h2,h3,h4,h5,h6){font-size:clamp(16px,1.48vw,19px);margin-top:16px;min-height:2.24em;}
  .crew-member span{display:block;margin-top:8px;
    font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--ink);}
  @supports (grid-template-rows: subgrid){
    .crew-member{display:grid;grid-row:span 3;grid-template-rows:subgrid;}
    .crew-member :is(h1,h2,h3,h4,h5,h6){min-height:0;}
  }
  @media(max-width:820px){
    .crew{grid-template-columns:repeat(2,minmax(0,1fr));}
    /* Applied to every member rather than to all but the last row: how many
       members there are is the client's to change, and 40px of air under the
       last one inside an already padded section is not worth a rule that breaks
       on an odd number of them. */
    .crew-member{margin-bottom:40px;}
  }

  /* ---------- 7. Testimonials slider ---------- */
  .testi{background:var(--ocean-dark);color:#fff;}
  .testi .swiper{max-width:820px;margin-inline:auto;}
  .testi .quote{text-align:center;padding:0 10px;}
  .testi .quote p{font-family:var(--body);font-weight:600;font-size:clamp(17px,1.80vw,23px);line-height:1.4;color:#eef4f3;}
  .testi .quote h4{font-size:1.2rem;margin-top:24px;}
  .testi .quote span{font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:#8fc6c0;}
  .testi .swiper-pagination{position:static;margin-top:34px;}
  .testi .swiper-pagination-bullet{background:#fff;}

  /* ---------- 8. Instagram feed ---------- */
  .ig-head{text-align:center;margin-bottom:36px;}
  .ig-head h3{font-family:var(--display);font-weight:500;letter-spacing:.05em;font-size:1.1rem;}
  .ig-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;}
  .ig-grid a{position:relative;aspect-ratio:1;overflow:hidden;}
  .ig-grid img{width:100%;height:100%;object-fit:cover;transition:transform .6s;}
  .ig-grid a:hover img{transform:scale(1.08);}
  @media(max-width:820px){.ig-grid{grid-template-columns:repeat(3,1fr);}}

  /* ---------- 9. Activities / 10. Destinations (full-bleed banners) ---------- */
  .banner{min-height:520px;display:flex;align-items:center;color:#fff;
    background-size:cover;background-position:center;position:relative;}
  .banner::after{content:"";position:absolute;inset:0;background:rgba(8,32,36,.5);}
  .banner .container{position:relative;z-index:2;width:100%;}
  .banner .inner{max-width:560px;}
  .banner.right .inner{margin-left:auto;text-align:left;}
  .banner :is(h1,h2,h3,h4,h5,h6){font-size:clamp(15px,2.66vw,34px);}
  .banner p{color:#e6efee;margin:1rem 0 2rem;}
  .banner .btns{display:flex;gap:16px;flex-wrap:wrap;}

  /* ---------- 11. CTA ---------- */
  .cta{background:var(--sand);text-align:center;}
  .cta h2{font-size:clamp(12px,2.03vw,26px);max-width:18ch;margin-inline:auto;}
  .cta p{margin:1.2rem auto 2.2rem;}

  /* ---------- 11b. Google reviews ---------- */
  .reviews{background:var(--sand);}
  .reviews-summary{display:flex;align-items:center;justify-content:center;gap:14px;
    flex-wrap:wrap;margin-top:1.4rem;font-size:.92rem;color:var(--muted);}
  .reviews-score{font-family:var(--display);font-weight:500;font-size:1.6rem;color:var(--ink);line-height:1;}
  .stars{display:inline-flex;gap:3px;color:#fbbc04;}
  .stars svg{width:17px;height:17px;}
  .reviews-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}
  .review{background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:2px;
    padding:34px 32px;display:flex;flex-direction:column;gap:16px;}
  .review-text{margin:0;color:var(--ink);font-size:16px;line-height:1.6;}
  .review-foot{margin-top:auto;padding-top:14px;border-top:1px solid rgba(0,0,0,.08);
    display:flex;align-items:baseline;justify-content:space-between;gap:12px;}
  /* A link when the review came from Google, plain text when it came from
     the backoffice. Styled the same either way: the link is there because
     Google asks for the author's profile beside their words, not to invite a
     click away from the page. */
  .review-author{font-size:.95rem;color:var(--ink);text-decoration:none;}
  a.review-author:hover{text-decoration:underline;}
  .review-date{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);}
  .reviews-empty{grid-column:1/-1;text-align:center;color:var(--muted);}
  /* Required wherever Places content is shown off a Google map. Quiet, but
     present — it is a condition of showing the reviews at all. */
  .reviews-source{margin:1.4rem 0 0;text-align:center;font-size:.72rem;
    letter-spacing:.14em;text-transform:uppercase;color:var(--muted);}
  @media(max-width:1000px){.reviews-grid{grid-template-columns:repeat(2,1fr);}}
  @media(max-width:640px){.reviews-grid{grid-template-columns:1fr;}}

  /* ---------- 12. Footer ---------- */
  .site-footer{background:var(--grey);color:rgba(255,255,255,.85);padding-block:72px 30px;font-size:.9rem;}
  .site-footer .container{max-width:none;padding-inline:clamp(24px,5vw,80px);}  /* full-width, not boxed */
  .footer-kicker{display:block;font-family:var(--body);text-transform:uppercase;letter-spacing:.28em;
    font-size:.72rem;color:rgba(255,255,255,.7);margin-bottom:38px;}
  .footer-grid{display:grid;grid-template-columns:1.4fr 1.5fr 1.4fr 1fr;gap:40px;}
  /* A quatro colunas os pares não existem: `display:contents` tira-os da
     árvore de caixas e as quatro caixas voltam a ser filhas directas da
     grelha. A ordem é reposta aqui porque no HTML o "Membro de" passou a vir
     logo a seguir ao logótipo — ver o comentário no partial. */
  .footer-stack{display:contents;}
  .footer-brand{order:1;} .footer-plan{order:2;}
  .footer-member{order:3;} .footer-social{order:4;}

  /* The badge and the bodies it stands for, side by side. The badge is a fixed
     width and does not shrink: it is somebody else's mark and squeezing it is
     not ours to do. */
  .footer-member{display:flex;align-items:flex-start;gap:22px;}
  .fmember-badge{flex:none;width:86px;height:auto;display:block;}
  .fmember-names{min-width:0;}
  .site-footer img.flogo{height:88px;width:auto;margin-bottom:20px;display:block;margin-inline:auto;}
  .site-footer p strong{color:#fff;font-weight:600;}
  .site-footer h5{font-family:var(--display);text-transform:uppercase;letter-spacing:.12em;font-size:.74rem;
    color:#fff;margin:0 0 18px;font-weight:500;}
  .site-footer ul{list-style:none;margin:0;padding:0;display:grid;gap:10px;}
  .site-footer a:hover{color:#fff;}
  .social{display:flex;gap:14px;flex-wrap:wrap;}
  .social a{width:42px;height:42px;border:1px solid rgba(255,255,255,.45);border-radius:50%;
    display:grid;place-items:center;color:rgba(255,255,255,.9);transition:.3s;}
  .social a:hover{background:rgba(255,255,255,.18);color:#fff;border-color:#fff;}
  /* Tudo junto e ao centro.
     Esta linha teve `space-between` enquanto não havia páginas legais: o aviso
     ia a uma ponta e as ligações à outra. Com a política de privacidade
     publicada passou a ler-se como duas coisas sem relação, uma em cada
     extremo de um ecrã largo, e o cliente pediu-as seguidas. O `gap` é o que
     as separa agora, e o `flex-wrap` passa-as a duas linhas centradas quando
     não cabem. O caso de um filho só deixou de precisar de regra própria —
     com isto já fica centrado. */
  .footer-bottom{border-top:1px solid rgba(255,255,255,.3);margin-top:54px;padding-top:24px;
    display:flex;justify-content:center;text-align:center;gap:6px 18px;flex-wrap:wrap;
    font-size:.78rem;opacity:.75;}
  @media(max-width:820px){
    /* Duas colunas e, com elas, a altura da linha passa a ser a da coluna mais
       alta — a dos membros, que leva título, lista e emblema. Ao lado fica um
       vazio por baixo dos ícones, e com os 40px de origem entre linhas o
       rodapé ficava com meio ecrã de altura. A folga entre linhas desce; a das
       colunas fica, que é a que separa dois textos lado a lado. */
    .footer-grid{grid-template-columns:1fr 1fr;gap:26px 40px;}

    /* Agora a grelha tem dois filhos — as duas pilhas — e cada uma empilha o
       que leva. O logótipo deixa de esperar pela morada do lado para que o
       "Membro de" possa começar. */
    .footer-stack{display:flex;flex-direction:column;gap:26px;}

    /* Pela mesma razão: estas medidas foram pensadas para quatro colunas
       curtas e não para duas altas. */
    .footer-bottom{margin-top:32px;}
    .site-footer{padding-block:54px 26px;}

    /* Two columns, and the four blocks fall into a square in the order they
       are written: the logo with the way to reach us beside it, the badge
       with the social icons under them. Which is the order that was asked
       for, so nothing needs reordering any more — the column that used to be
       moved, the address, is now part of the one beside the logo.

       What went with it: the rule that pushed the logo to the right edge. It
       was there so the logo and the right-aligned address ended on the same
       line, and with the address gone it would only be a logo pushed over for
       no reason. */

    /* The street wraps where it must, and left alone it drops its last word
       onto a line of its own; balance spreads the break between the two. */
    .footer-plan li{text-wrap:balance;}

    /* Side by side still fits at two columns; below that the badge goes above
       the names rather than squeezing them into nothing. */
    .footer-member{gap:16px;}
  }

  @media(max-width:560px){
    /* O emblema por baixo do que identifica, e não acima.
       Em coluna, o que vem primeiro no markup — o emblema — aparecia antes do
       título que diz de que é que ele é emblema, e lia-se como uma imagem
       solta à espera de legenda. A ordem troca-se aqui e não no markup porque
       em ecrã largo os dois estão lado a lado e a leitura está certa assim.

       Encostado à direita, como a morada na coluna ao lado, e com o emblema
       colado ao texto: ao mesmo espaço das outras colunas ele descaía e
       deixava de se ler como parte do bloco. */
    .footer-member{flex-direction:column;align-items:flex-end;text-align:right;gap:10px;}
    .footer-member .fmember-names{order:1;}
    .footer-member .fmember-badge{order:2;}

    /* Os títulos das colunas chegam-se ao que anunciam. Dezoito pixéis é a
       medida de quando eram quatro colunas curtas lado a lado. */
    .site-footer h5{margin-bottom:12px;}

    /* O emblema desce de 86 para 68 de largura, e com ele 36px de altura.
       Continua à escala: o que o comentário lá em cima recusa é espremê-lo —
       deformar a marca de outrem —, e reduzi-lo por inteiro não é isso. Era a
       peça mais alta do rodapé num ecrã onde ele já ocupava um terço da
       página. */
    .fmember-badge{width:68px;}
  }

  /* ---------- Cookie banner ---------- */
  .cookie{position:fixed;left:20px;bottom:20px;z-index:80;max-width:380px;background:#fff;
    box-shadow:0 12px 40px rgba(0,0,0,.18);border-radius:6px;padding:26px;transform:translateY(160%);
    transition:transform .5s;}
  .cookie.show{transform:none;}
  .cookie h4{font-size:1.3rem;margin-bottom:8px;}
  .cookie p{font-size:.84rem;color:var(--muted);margin:0 0 16px;}
  .cookie .btn{padding:.7rem 1.6rem;font-size:.72rem;}
  /* Os dois botões lado a lado, do mesmo tamanho. Quebram para duas linhas onde
     não couberem, em vez de encolher um deles. */
  .cookie-do{display:flex;flex-wrap:wrap;gap:10px;}

  /* ---------- Reveal-on-scroll ---------- */
  /* Só esconde onde há JavaScript para voltar a mostrar.
     Sem esta condição, um visitante com o script bloqueado — ou com o ficheiro
     por carregar — ficava com a página em branco, porque tudo o que é conteúdo
     está dentro de um .reveal. Na página de contactos isso seria uma fotografia
     e mais nada, sem formulário nenhum.
     Um browser que não conheça `scripting` ignora o bloco inteiro e mostra tudo
     de imediato: perde-se a animação, nunca o conteúdo. */
  @media (scripting: enabled){
    .reveal{opacity:0;transform:translateY(28px);transition:opacity .8s,transform .8s;}
    .reveal.in{opacity:1;transform:none;}
  }

  /* ---------- Editor-authored text (the "Texto" block) ---------- */
  /* The one place on the site where the markup is written by the client rather
     than by a template, so every element the output filter allows needs a size
     and a rhythm here. Without this a heading typed in the editor falls back to
     the browser's own scale, which is nowhere near the rest of the page. */
  /* A coluna centra-se. O título do bloco vive num .section-head, que é
     centrado, e um texto a 72ch encostado à esquerda por baixo de um
     título ao meio lê-se como um erro de alinhamento — era o que a
     política de privacidade mostrava. */
  .rich-text{max-width:72ch;margin-inline:auto;color:var(--ink);font-size:1rem;line-height:1.7;}
  .rich-text > :first-child{margin-top:0;}
  .rich-text > :last-child{margin-bottom:0;}
  .rich-text p{margin:0 0 1.2rem;}
  .rich-text :is(h2,h3,h4,h5,h6){margin:2.2rem 0 .9rem;}
  .rich-text h2{font-size:clamp(20px,2.1vw,28px);}
  .rich-text h3{font-size:clamp(18px,1.7vw,22px);}
  .rich-text h4{font-size:clamp(16px,1.4vw,19px);}
  .rich-text :is(h5,h6){font-size:1rem;letter-spacing:.02em;}
  .rich-text :is(ul,ol){margin:0 0 1.2rem;padding-left:1.4rem;}
  .rich-text li{margin-bottom:.5rem;}
  .rich-text li::marker{color:var(--muted);}
  .rich-text a{text-decoration:underline;text-underline-offset:.18em;}
  .rich-text a:hover{color:var(--muted);}
  /* Havia aqui um contorno de .4px a desenhar à mão o peso que faltava: o site
     só alojava o Urbanist 600, o Chrome atendia com essa face um pedido de 700
     e não sintetizava nada, e carregar no B do editor não mudava coisa nenhuma
     na página. O comentário que aqui estava dizia o que era preciso para o
     tirar — o 700 alojado ao lado do 600 — e é o que passou a haver. Fica só o
     peso, que agora tem uma face de verdade para onde ir. */
  .rich-text strong,.rich-text b{font-weight:700;}
  .rich-text blockquote{margin:1.8rem 0;padding-left:1.4rem;border-left:2px solid var(--grey);
    color:var(--muted);font-size:1.05rem;}
  .rich-text img{margin:1.6rem 0;border-radius:4px;}
  .rich-text figure{margin:1.8rem 0;}
  .rich-text figcaption{margin-top:.6rem;font-size:.82rem;color:var(--muted);}
  .rich-text hr{border:0;border-top:1px solid rgba(0,0,0,.12);margin:2.4rem 0;}
  /* Tables scroll rather than push the page sideways on a phone. */
  .rich-text table{width:100%;border-collapse:collapse;margin:0 0 1.4rem;font-size:.92rem;}
  .rich-text :is(th,td){padding:.6rem .8rem;border:1px solid rgba(0,0,0,.12);text-align:left;}
  .rich-text th{background:rgba(0,0,0,.03);font-weight:700;}
