/* WrightGate IT Solutions
   The page is a walk through a plan. assets/js/scene.js paints the world on
   the canvas behind everything; the acts below are the words that travel with
   it. Without JS (or with reduced motion) the canvas never turns on and every
   act falls back to an ordinary stacked page. */

:root {
  --bg: #06070A;
  --bg-card: rgba(10, 14, 22, 0.72);
  --line: rgba(248, 247, 248, 0.10);
  --text: #F8F7F8;
  --muted: #A7ADBB;
  --blue: #196EDA;
  --blue-bright: #3B8BF0;
  --radius: 16px;
  --font-head: "Poppins", "Avenir Next", "Segoe UI", sans-serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --header-h: 72px;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-h);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }

h1, h2, h3 {
  font-family: var(--font-head);
  line-height: 1.12;
  margin: 0 0 0.55em;
  letter-spacing: -0.015em;
  /* Um titulo de duas linhas com uma palavra sozinha na segunda le-se pior e
     parece um acidente. `balance` reparte as linhas em vez de encher a
     primeira ate ao fim, e o navegador que nao o conhecer ignora a linha e
     quebra como sempre quebrou: nao ha nada a perder. */
  text-wrap: balance;
}
h1 { font-size: clamp(2.4rem, 5.6vw, 4.3rem); font-weight: 700; }
h1 em {
  font-style: normal;
  background: linear-gradient(100deg, #3B8BF0, #8AC0FF);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
h2 { font-size: clamp(1.65rem, 3.6vw, 2.5rem); font-weight: 600; }
h3 { font-size: 1.08rem; font-weight: 600; margin-bottom: 0.3em; }
p { margin: 0 0 1em; }
a { color: var(--blue-bright); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--blue-bright);
  outline-offset: 3px;
  border-radius: 4px;
}

.container { width: min(1120px, 100% - 2.5rem); margin-inline: auto; }

.eyebrow {
  font-family: var(--font-head);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--blue-bright);
  margin-bottom: 0.9rem;
}

.lead { color: #D3D9E4; font-size: 1.08rem; }

.skip-link {
  position: absolute;
  left: 1rem;
  top: -100%;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--blue);
  color: #fff;
  border-radius: 8px;
  transition: top 0.2s;
}
.skip-link:focus { top: 1rem; }

/* ------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.78rem 1.5rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 1rem;
  border: 1px solid transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn-primary {
  background: var(--blue);
  color: #fff;
  box-shadow: 0 10px 30px rgba(25, 110, 218, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.btn-primary:hover {
  /* Deeper, not lighter: white on --blue-bright is only 3.42:1, which fails
     AA. This is 6:1 and still reads as a response to the pointer. */
  background: #1560C4;
  box-shadow: 0 12px 34px rgba(25, 110, 218, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.btn-ghost {
  color: var(--text);
  border-color: var(--line);
  background: rgba(248, 247, 248, 0.04);
}
.btn-ghost:hover { border-color: rgba(248, 247, 248, 0.28); }
.btn-lg { padding: 1rem 2rem; font-size: 1.1rem; }

/* -------------------------------------------------------- scene layers */

.scene {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
}
.scene-on .scene { display: block; }

/* First paint fades up rather than snapping on. The animation is pure CSS so
   it clears itself even if the engine never starts. */
/* Note the resting state is transparent and the animation only plays the way
   down: if animations never run, the page is simply visible. A cover that
   depends on an animation to get out of the way is a black screen waiting to
   happen. */
.boot {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: var(--bg);
  pointer-events: none;
  opacity: 0;
  animation: bootOut 0.9s ease;
}
@keyframes bootOut { from { opacity: 1; } 60% { opacity: 0.55; } to { opacity: 0; } }

.vignette, .grain { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
/* Three washes: a corner vignette to hold the eye in the middle, a wash at
   the top so the header reads over anything, and one at the foot for the
   instrument and the scroll cue. */
.vignette {
  background:
    linear-gradient(180deg, rgba(3, 4, 8, 0.8), rgba(3, 4, 8, 0) 16%),
    linear-gradient(0deg, rgba(3, 4, 8, 0.72), rgba(3, 4, 8, 0) 14%),
    radial-gradient(118% 88% at 50% 46%, transparent 38%, rgba(2, 3, 6, 0.46) 78%, rgba(2, 3, 6, 0.9) 100%);
}
.grain {
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Without the engine the page still needs a floor to stand on. */
html:not(.scene-on) body {
  background:
    radial-gradient(90% 60% at 50% -10%, rgba(25, 110, 218, 0.16), transparent 60%),
    linear-gradient(180deg, #06070A, #080C14 60%, #06070A);
}

/* A barra de progresso tem duas camadas: o preenchimento e as marcas de
   capítulo. O elemento em si não se transforma, porque escalá-lo escalaria
   também as marcas e elas ficariam todas amontoadas à esquerda. */
.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  z-index: 60;
  height: 2px;
  width: 100%;
  color: rgba(198, 212, 232, 0.5);   /* a cor das marcas, via currentColor */
}
.scroll-progress::before,
.scroll-progress::after {
  content: "";
  position: absolute;
  inset: 0;
}
.scroll-progress::before {
  background: linear-gradient(90deg, var(--blue), #8AC0FF);
  transform: scaleX(var(--sp, 0));
  transform-origin: 0 50%;
}
/* As marcas só no telemóvel: no computador a régua de capítulos e o
   instrumento já dizem onde se está, e três indicadores a dizer o mesmo é
   ruído. */
.scroll-progress::after { display: none; }
@media (max-width: 860px) {
  .scroll-progress { height: 3px; }
  .scroll-progress::after { display: block; background: var(--marcas, none); }
}

/* --------------------------------------------------------------- header */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  height: var(--header-h);
  display: flex;
  align-items: center;
  pointer-events: none;
}
/* O VÉU, e não é decoração: é legibilidade.
 *
 * O cabeçalho é transparente de propósito, para a cena passar por trás dele e a
 * página parecer uma só. O preço disso aparecia numa das etiquetas do desenho: a
 * palavra WRIGHTGATE, que a cena escreve no chão, subia até à faixa do menu e
 * lia-se ali, colada por baixo do selector de língua, como se a marca estivesse
 * escrita duas vezes.
 *
 * Escurecer a faixa inteira mataria o efeito. Um gradiente que só existe onde o
 * texto do menu está, e se desfaz antes de chegar ao fim, dá as duas coisas: a
 * cena continua a atravessar, e o que está escrito por cima dela lê-se sempre.
 *
 * `pointer-events: none` no véu porque ele não é um elemento com que se
 * interaja, e sem isso passaria a tapar os cliques do desenho por trás. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(6, 7, 10, 0.82) 0%,
    rgba(6, 7, 10, 0.62) 55%,
    rgba(6, 7, 10, 0) 100%);
}
.site-header > * { pointer-events: auto; }
.header-inner {
  display: flex;
  align-items: center;
  gap: 1.4rem;
}
/* Never squeezed: a compressed flex item does not clip its text, it paints
   over whatever sits next to it. */
.brand { display: inline-flex; align-items: center; gap: 0.6rem; color: var(--text); flex: none; }
.brand:hover { text-decoration: none; }
.brand-mark { width: 42px; height: auto; overflow: visible; }
.brand-text {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.02rem;
  line-height: 1.1;
  display: flex;
  flex-direction: column;
}
.brand-sub {
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
}
.gate-pillar-hidden { opacity: 0; transition: opacity 0.25s ease; }
.gate-closed .gate-pillar-hidden { opacity: 1; }

.site-nav { margin-left: auto; display: flex; gap: 1.6rem; }
.site-nav a {
  color: var(--muted);
  font-size: 0.94rem;
  font-weight: 500;
}
.site-nav a:hover { color: var(--text); text-decoration: none; }
/* Two-word labels wrapping is what makes the header grow a second line when
   space gets tight; they shrink instead, and the phone menu takes over below
   861px. */
.site-nav a, .header-cta { white-space: nowrap; }

.lang-switch { display: flex; gap: 0.15rem; }
.lang-switch button {
  background: none;
  border: 0;
  color: var(--muted);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 0.3rem 0.45rem;
  cursor: pointer;
  border-radius: 6px;
  /* A faixa tem 56px de altura, portanto 44 cabe sem empurrar nada, e um alvo
     de toque nao deve depender de a pessoa estar num computador. */
  min-height: 44px;
  min-width: 36px;
}
.lang-switch button[aria-pressed="true"] { color: var(--text); background: rgba(248, 247, 248, 0.08); }

/* The way in, and the way back to your own area. Quiet outline when signed
   out; once there is a session it takes the brand blue, because then it is
   the thing a returning client is looking for. */
.header-account {
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 600;
  padding: 0.42rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  white-space: nowrap;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.header-account:hover {
  color: var(--text);
  border-color: rgba(248, 247, 248, 0.26);
  text-decoration: none;
}
:root[data-wg-session="on"] .header-account {
  color: #9ec9ff;
  border-color: rgba(25, 110, 218, 0.5);
  background: rgba(25, 110, 218, 0.12);
}
:root[data-wg-session="on"] .header-account:hover {
  color: #fff;
  border-color: rgba(25, 110, 218, 0.85);
  background: rgba(25, 110, 218, 0.22);
}

.header-cta { padding: 0.55rem 1.15rem; font-size: 0.92rem; }

/* Between the phone menu and a roomy desktop the header carries everything at
   once: brand, four nav links, languages, account and the CTA. It is the one
   band where they have to share, so the gaps close up rather than let anything
   overlap. */
@media (min-width: 861px) and (max-width: 1080px) {
  .header-inner { gap: 0.7rem; }
  .site-nav { gap: 0.85rem; }
  .site-nav a { font-size: 0.84rem; }
  .header-cta { padding: 0.46rem 0.8rem; font-size: 0.82rem; }
  .header-account { font-size: 0.78rem; padding: 0.34rem 0.62rem; }
}

.nav-toggle {
  display: none;
  width: 42px; height: 38px;
  background: none;
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  padding: 9px 10px;
  flex-direction: column;
  justify-content: space-between;
}
.nav-toggle span { display: block; height: 2px; background: var(--text); border-radius: 2px; }

/* ---------------------------------------------------------- chapter rail */

.rail {
  position: fixed;
  left: 1.9rem;
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  display: none;
  flex-direction: column;
  gap: 0.85rem;
}
.scene-on .rail { display: flex; }
.rail a {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
  opacity: 0.62;
  color: #93A2BC;
  transition: opacity 0.3s ease, color 0.3s ease;
}
.rail a:hover { text-decoration: none; opacity: 1; }
/* A RÉGUA ESTÁ À ESCALA DA VIAGEM.
   Os seis capítulos valem de 6,0 a 31,9 por cento do percurso, e a régua
   desenhava seis marcas igualmente espaçadas: mentia sobre a forma da peça.
   Cada entrada passa a ter a altura da fatia que representa, escrita por
   `measure()` em `--span`, e é o ESPAÇAMENTO entre traços que passa a medir.
   O mínimo de 16px existe para o capítulo mais curto continuar a ser alvo de
   rato e de dedo.

   O traço em si não muda. A proposta original mandava esticá-lo
   verticalmente com `align-self: stretch`, e isso transformava-o numa barra
   de 20px de largura por toda a altura da fatia, além de colidir com o
   indicador de progresso, que já usa a largura do traço para dizer quanto
   falta do capítulo. Uma dimensão, um significado. */
.rail a { height: max(16px, calc(var(--span, 0.1667) * 52svh)); }
.rail i {
  width: 20px; height: 1px;
  background: currentColor;
  transition: background 0.35s ease, height 0.35s ease;
}
.rail a span { opacity: 0; transform: translateX(-6px); transition: opacity 0.3s ease, transform 0.3s ease; }
.rail:hover a span { opacity: 1; transform: none; }
.rail a.is-on { opacity: 1; color: var(--text); }
/* The active rule also reports how far through the chapter you are. */
.rail a.is-on i {
  width: calc(22px + var(--p, 0) * 30px);
  height: 2px;
  background: var(--blue-bright);
  box-shadow: 0 0 14px rgba(59, 139, 240, 0.6);
}
.rail a.is-on span { opacity: 1; transform: none; }

/* The instrument: position readout, bottom right. Only with the scene on. */
.hud {
  display: none;
  position: fixed;
  right: 1.9rem;
  bottom: 1.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid rgba(140, 170, 215, 0.22);
  z-index: 40;
  /* A segunda coluna é a dos valores, e leva largura fixa: sem ela o
     mostrador rastejava para a esquerda ao passar de 9 para 10 metros e de
     99 para 100, e um instrumento que dança a cada passo deixa de se ler
     como instrumento. As etiquetas ficam na primeira coluna, em `auto`. */
  grid-template-columns: auto 7ch;
  gap: 0.15rem 0.9rem;
  align-items: baseline;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7C90B0;
  text-align: right;
}
.scene-on .hud { display: grid; }
.hud-v {
  font-family: var(--font-head);
  font-weight: 600;
  color: #C6D4E8;
  font-variant-numeric: tabular-nums;
}

/* ----------------------------------------------------------------- acts */

.journey { position: relative; z-index: 2; }

.act { position: relative; padding: 7rem 0 3rem; }
.act-in { pointer-events: none; }
.act-in a, .act-in button { pointer-events: auto; }

.scene-on .act { padding: 0; }
/* Acts overlap by exactly one viewport. A sticky panel is only pinned for
   (height - 100vh), so without this every act boundary would leave a full
   screen of scrolling with no panel and a frozen camera. */
.scene-on .act:not(:last-child) { margin-bottom: -100vh; margin-bottom: -100svh; }
.scene-on .act-hero     { height: 170vh; height: 170svh; }
.scene-on .act-plan     { height: 190vh; height: 190svh; }
.scene-on .act-rooms    { height: 290vh; height: 290svh; }
.scene-on .act-services { height: 400vh; height: 400svh; }
.scene-on .act-method   { height: 470vh; height: 470svh; }
.scene-on .act-cta      { height: 240vh; height: 240svh; }

.scene-on .act-in {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: grid;
  align-content: center;
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}
.scene-on .act-in.is-live { pointer-events: auto; }
/* Out of view means out of reach for the pointer, but still reachable by
   keyboard: focus scrolls the chapter into view (see scene.js). */
.scene-on .act-in:not(.is-live) a,
.scene-on .act-in:not(.is-live) button { pointer-events: none; }

.scene-on .act-method .act-in {
  align-content: start;
  padding-top: 12vh;
}
/* A narrative type scale. The opening and the close speak loudest; the
   chapters whose meaning is carried by a pinned card step back and let it
   talk. Weight and tracking move with size, not just the size itself. */
.act-plan .act-in h2 {
  font-size: clamp(2rem, 4.3vw, 3.05rem);
  font-weight: 700;
  letter-spacing: -0.022em;
}
.act-plan .lead { font-size: 1.16rem; max-width: 34rem; }

.act-services .act-head h2 { font-size: clamp(1.75rem, 3.4vw, 2.4rem); }

.act-cta h2 {
  font-size: clamp(2.1rem, 4.6vw, 3.2rem);
  font-weight: 700;
  letter-spacing: -0.024em;
}
.act-cta .lead { font-size: 1.12rem; }

.act-method .act-head,
.act-rooms .act-head { max-width: 30rem; }
.act-method .act-head h2,
.act-rooms .act-head h2 {
  font-size: clamp(1.24rem, 2.1vw, 1.6rem);
  font-weight: 600;
  letter-spacing: 0;
  color: #C6D2E4;
}
.act-method .act-head .eyebrow,
.act-rooms .act-head .eyebrow { margin-bottom: 0.55rem; }

/* The closing chapter ties itself to the warm light coming through the gate. */
.act-cta .panel::after {
  background: linear-gradient(180deg,
    rgba(243, 185, 120, 0), #C98A45 14%, #F3B978 52%, #C98A45 84%, rgba(243, 185, 120, 0));
  box-shadow: 0 0 18px rgba(243, 185, 120, 0.35);
}
.act-cta .eyebrow { color: #F3B978; }

.panel-wrap { display: flex; }

/* Nothing on this page is a box. Copy sits on the scene behind a veil of
   darkness that fades out at its own edges, anchored by a single blue rule:
   the pillar of the mark, standing beside every block of text. */
.panel,
.act-head,
.room-cards .card,
.gate-steps li,
.svc-wrap {
  position: relative;
  padding: 0 0 0 1.7rem;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
.panel > *,
.act-head > *,
.room-cards .card > *,
.gate-steps li > *,
.svc-wrap > * { position: relative; z-index: 1; }

/* No veil here: a gradient inside a box is clipped by that box, and the clip
   shows as a hard edge. scene.js paints the veils straight onto the canvas
   under the copy, where they can be as large and as soft as they need. */
.panel::after,
.room-cards .card::after,
.gate-steps li::after,
.svc-wrap::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0.18rem;
  bottom: 0.18rem;
  width: 2px;
  z-index: 1;
  background: linear-gradient(180deg,
    transparent, var(--blue) 16%, #8AC0FF 54%, var(--blue) 78%, transparent);
}

.panel { max-width: 40rem; }
.panel-hero { max-width: 38rem; }
.panel-cta { max-width: 40rem; }
.panel p:last-child { margin-bottom: 0; }

.act-head { max-width: 40rem; margin-bottom: 2rem; }
.act-head h2 { margin-bottom: 0; }
/* A heading already inside a veiled block does not need its own. */
.act-head { padding-left: 0; }
.act-head.bare { margin-bottom: 1.6rem; }
.act-head.bare::before, .act-head.bare::after { content: none; }

/* Composition: the copy takes one side of the frame and leaves the other to
   the scene, alternating chapter by chapter so the walk never feels static. */
.scene-on .act-plan .panel-wrap { justify-content: flex-end; }
.scene-on .act-cta .panel-wrap { justify-content: flex-start; }
.scene-on .act-rooms .act-in,
.scene-on .act-services .act-in { align-content: start; padding-top: 12vh; }
.scene-on .act-services .svc-layout { display: flex; justify-content: flex-end; }
.svc-wrap { max-width: 31rem; }
.scene-on .act-services .act-in { align-content: center; padding-top: 0; }

.row-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.6rem; }

.pills { list-style: none; display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0; margin: 1.6rem 0 0; }
.pills li {
  font-size: 0.83rem;
  color: #C3CBDA;
  border: 1px solid rgba(140, 175, 225, 0.16);
  border-radius: 999px;
  padding: 0.34rem 0.9rem;
  background: rgba(8, 12, 20, 0.72);
}

.scroll-cue {
  display: none;
  position: absolute;
  z-index: 4;
  bottom: 8vh;
  left: 0; right: 0;
  text-align: center;
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.scene-on .scroll-cue { display: block; }
.scroll-cue:hover { color: var(--text); text-decoration: none; }
.scroll-cue span { display: inline-block; animation: cue 2.4s ease-in-out infinite; }
.scroll-cue span::after {
  content: "";
  display: block;
  width: 1px; height: 26px;
  margin: 0.7rem auto 0;
  background: linear-gradient(180deg, var(--blue-bright), transparent);
}
@keyframes cue { 0%, 100% { transform: translateY(0); opacity: 0.75; } 50% { transform: translateY(5px); opacity: 1; } }

/* ---------------------------------------------------------------- cards */

.cards { display: grid; gap: 1rem; }
.cards-3 { grid-template-columns: repeat(3, 1fr); }
.card {
  padding: 1.6rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(160deg, rgba(14, 20, 32, 0.88), rgba(6, 8, 13, 0.8));
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}
.card p { margin: 0; color: var(--muted); font-size: 0.94rem; }
.card-icon {
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  color: var(--blue-bright);
  background: rgba(25, 110, 218, 0.14);
  border: 1px solid rgba(25, 110, 218, 0.28);
  margin-bottom: 1rem;
}
.card-icon svg { width: 21px; height: 21px; }

.svc-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.15rem;
}
.svc-list li {
  display: grid;
  grid-template-columns: 30px 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.85rem;
  padding: 0.62rem 0.6rem 0.62rem 0;
  border-radius: 10px;
  border-bottom: 1px solid rgba(248, 247, 248, 0.06);
  transition: background 0.4s ease;
}
.svc-list li:last-child { border-bottom: 0; }
.svc-ico {
  grid-row: 1 / span 2;
  width: 30px; height: 30px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  color: #6E86A8;
  background: rgba(140, 175, 225, 0.07);
  transition: color 0.4s ease, background 0.4s ease, box-shadow 0.4s ease;
}
.svc-ico svg { width: 17px; height: 17px; }
.svc-list h3 { margin: 0; font-size: 1.02rem; color: #C8D2E2; transition: color 0.4s ease; }
.svc-list p { margin: 0; color: #8590A3; font-size: 0.9rem; line-height: 1.45; }

/* The service you are walking past lights up in the list. */
.svc-list li.is-on { background: rgba(25, 110, 218, 0.09); }
.svc-list li.is-on h3 { color: var(--text); }
.svc-list li.is-on .svc-ico {
  color: #fff;
  background: var(--blue);
  box-shadow: 0 0 22px rgba(25, 110, 218, 0.5);
}

.steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}
.steps li {
  padding: 1.4rem 1.3rem;
  border-radius: 16px;
  border: 1px solid var(--line);
  border-top: 2px solid rgba(25, 110, 218, 0.55);
  background: linear-gradient(160deg, rgba(13, 18, 30, 0.88), rgba(6, 8, 13, 0.78));
}
.steps p { margin: 0; color: var(--muted); font-size: 0.9rem; }
.step-num {
  font-family: var(--font-head);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--blue-bright);
  display: block;
  margin-bottom: 0.6rem;
}

.gate-steps, .room-cards { width: min(1120px, 100% - 2.5rem); margin-inline: auto; }

/* Steps ride the gates: each card is pinned to its gate's opening in 3D. */
.scene-on .gate-steps,
.scene-on .room-cards {
  width: auto;
  position: fixed;
  inset: 0;
  z-index: 3;
  display: block;
  pointer-events: none;
  margin: 0;
  padding: 0;
}
.scene-on .gate-steps li,
.scene-on .room-cards .card {
  position: absolute;
  left: 0;
  top: 0;
  width: min(30rem, 82vw);
  padding: 0 0 0 1.7rem;
  opacity: 0;
  pointer-events: none;
  transform-origin: 50% 50%;
  will-change: transform, opacity;
  /* No surface of its own: the canvas dims the world behind it. */
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* The card is the thing being read at the landing, so it carries its own
   type scale rather than the compact one used in the static list. */
.scene-on .gate-steps li::after,
.scene-on .room-cards .card::after {
  width: 3px;
  background: linear-gradient(180deg,
    rgba(25, 110, 218, 0), #196EDA 12%, #8AC0FF 50%, #196EDA 86%, rgba(25, 110, 218, 0));
  box-shadow: 0 0 16px rgba(59, 139, 240, 0.55);
}
.scene-on .gate-steps li h3,
.scene-on .room-cards .card h3 { font-size: 1.35rem; margin-bottom: 0.45rem; }
.scene-on .gate-steps li p,
.scene-on .room-cards .card p { font-size: 1.02rem; line-height: 1.55; color: #C3CBDA; }
.scene-on .room-cards .card-icon { display: none; }
.scene-on .gate-steps .step-num { font-size: 0.86rem; margin-bottom: 0.75rem; }

/* --------------------------------------------------------------- footer */

.site-footer {
  position: relative;
  z-index: 3;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, #04060A, #030407);
  padding: 4rem 0 1.8rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 2.5rem;
  align-items: start;
}
.footer-brand p {
  color: var(--muted);
  font-size: 0.95rem;
  margin: 1rem 0 0;
  max-width: 22rem;
}
.footer-logo { width: 168px; height: auto; opacity: 0.9; }
/* AS COLUNAS DO RODAPE SAO NAVEGACAO, e portanto sao controlos.
   Media-se: cada ligacao tinha 19 a 22px de altura, abaixo do minimo de 24 da
   norma e muito abaixo dos 44 que um dedo precisa. Sao a unica saida da pagina
   para os termos, para a privacidade, para o email e para o telefone.

   O que cresce e a area e nao a letra. O `gap` desce de 0.55rem para 0.15rem
   porque o padding das proprias ligacoes passa a fazer o espacamento: sem isso
   o rodape ficava com o dobro da altura por causa de uma correccao que devia
   ser invisivel. */
.footer-col { display: flex; flex-direction: column; gap: 0.15rem; }
.foot-h {
  font-family: var(--font-head);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #7C90B0;
  margin: 0 0 0.35rem;
}
.footer-col a {
  color: var(--muted);
  font-size: 0.95rem;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  /* `align-self: start` para a caixa de toque nao se esticar pela coluna toda:
     ela tem a largura do texto, que e o que a pessoa ve e onde ela aponta. */
  align-self: flex-start;
}
/* A ligacao de voltar ao topo tem o mesmo problema e nao esta numa coluna. */
.to-top {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.footer-col a:hover { color: var(--text); text-decoration: none; }
.foot-note { color: #6E7685; font-size: 0.88rem; margin: 0.2rem 0 0; }
.footer-base {
  margin-top: 3rem;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(248, 247, 248, 0.06);
  display: flex;
  flex-wrap: wrap-reverse;
  gap: 0.8rem 1.5rem;
  align-items: center;
  justify-content: space-between;
}
.to-top {
  color: var(--muted);
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.to-top::before {
  content: "";
  width: 20px;
  height: 1px;
  background: currentColor;
}
.to-top:hover { color: var(--text); text-decoration: none; }
.footer-copy { color: #626A79; font-size: 0.8rem; margin: 0; }
/* A identificacao legal: presente e legivel, sem competir com nada. */
.footer-legal { color: #626A79; font-size: 0.78rem; margin: 0.9rem 0 0; line-height: 1.5; }

/* ------------------------------------------------------------ responsive */

@media (max-width: 980px) {
  .cards-3 { grid-template-columns: 1fr; }

  .steps { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 860px) {
  .hud { display: none !important; }
  .footer-grid { grid-template-columns: 1fr; gap: 2rem; }
  .footer-logo { width: 140px; }
  .footer-brand p { max-width: none; }
  .site-footer { padding: 3rem 0 1.6rem; }
  .footer-base { margin-top: 2rem; }
  .site-nav {
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    gap: 0;
    padding: 0 2rem;
    background: linear-gradient(180deg, rgba(4, 6, 11, 0.985), rgba(4, 6, 11, 0.965));
    display: none;
  }
  .site-nav.is-open { display: flex; }
  .site-nav a {
    font-family: var(--font-head);
    font-size: 1.7rem;
    font-weight: 600;
    color: var(--text);
    padding: 1.05rem 0;
    border-bottom: 1px solid rgba(248, 247, 248, 0.08);
  }
  .site-nav.is-open ~ .nav-toggle span { background: var(--text); }
  .nav-toggle { display: flex; }
  .header-cta { display: none; }
  .site-nav { margin-left: 0; }
  .lang-switch { margin-left: auto; }
  /* Narrow headers are tight: the account link stays, because it is the only
     sign on the page that you are signed in, so everything around it gives up
     a little room instead. Without this the wordmark and the language switch
     collide. */
  .header-inner { gap: 0.55rem; }
  .header-account { font-size: 0.78rem; padding: 0.34rem 0.58rem; }
  /* The wordmark keeps its natural width instead of being squeezed: a
     squeezed flex item does not clip, it just paints over its neighbour. The
     tagline goes first, and on the narrowest phones the wordmark follows,
     leaving the gate mark to carry the brand. */
  .brand { flex: none; }
  .brand-mark { width: 34px; }
  .brand-text { font-size: 0.9rem; }
  .lang-switch { gap: 0; }
  /* AO CONTRARIO DO QUE ISTO FAZIA. Aqui estava `font-size: 0.7rem` e um
     `padding` mais apertado, ou seja os botoes de lingua ficavam MAIS PEQUENOS
     no ecra onde se toca neles com o dedo. Medidos a 390px: 26x27 px. O minimo
     da norma (WCAG 2.5.8) e 24x24 e o que a Apple e a Google recomendam e 44.
     Passavam por um triz e nao passavam de proposito: eram o que sobrava.

     A letra fica pequena de proposito, que e o que a faixa precisa; o que
     cresce e a AREA, com padding. Ha espaco de sobra entre a marca e o
     selector, portanto isto nao empurra nada.

     Nao se usa um `::after` esticado a 44px, que seria a maneira habitual de
     aumentar o alvo sem mexer no desenho: sao tres botoes encostados, e tres
     alvos de 44px sobrepunham-se uns aos outros. Um dedo acertaria na lingua
     do lado, que e pior do que o alvo pequeno. */
  .lang-switch button {
    font-size: 0.7rem;
    padding: 0.3rem 0.4rem;
    min-width: 40px;
    min-height: 44px;
  }
  .nav-toggle { width: 44px; height: 44px; padding: 11px 12px; flex: none; }
  .rail { display: none !important; }

  /* The header runs out of room in two steps: first the tagline goes, then
     the wordmark, leaving the gate mark to carry the brand. Each cut is made
     only at the width where the four items stop fitting side by side. */
  @media (max-width: 480px) {
    .brand-sub { display: none; }
  }
  @media (max-width: 400px) {
    .brand-text { display: none; }
  }

  .panel { padding: 1.4rem 1.25rem 1.5rem; border-radius: 18px; }
  .scene-on .act-in {
    align-content: center;
    padding-bottom: 6vh;
    overflow: hidden;
  }
  /* Small screens cannot afford decoration: the icons go, the copy stays. */
  .cards { gap: 0.65rem; }
  .cards .card-icon { display: none; }
  .card { padding: 1rem 1.1rem; }
  .card p { font-size: 0.86rem; line-height: 1.45; }
  .card h3 { font-size: 1rem; }
  .lead { font-size: 0.98rem; }
  .pills li { font-size: 0.78rem; padding: 0.25rem 0.7rem; }
  /* A phone scrolls a screen per swipe, so the walk is shorter there, not
     longer. These used to be above the desktop heights. */
  .scene-on .act-hero     { height: 150vh; height: 150svh; }
  .scene-on .act-plan     { height: 165vh; height: 165svh; }
  .scene-on .act-rooms    { height: 250vh; height: 250svh; }
  .scene-on .act-services { height: 290vh; height: 290svh; }
  .scene-on .act-method   { height: 390vh; height: 390svh; }
  .scene-on .act-cta      { height: 200vh; height: 200svh; }
  .scene-on .gate-steps li,
  .scene-on .room-cards .card { width: min(23rem, 88vw); padding: 1.2rem 1.3rem 1.3rem; }
  .scene-on .gate-steps li h3,
  .scene-on .room-cards .card h3 { font-size: 1.15rem; }
  .scene-on .gate-steps li p,
  .scene-on .room-cards .card p { font-size: 0.94rem; }
  .svc-list li { grid-template-columns: 26px 1fr; column-gap: 0.7rem; padding: 0.5rem 0; }
  .svc-ico { width: 26px; height: 26px; }
  .svc-list p { font-size: 0.84rem; }
  .steps { grid-template-columns: 1fr; }
  .steps li { padding: 0.9rem 1rem; }
  .act-head { margin-bottom: 1.2rem; }
}

@media (max-width: 520px) {
  body { font-size: 1rem; }
  .lead { font-size: 1rem; }
  .cards .card p { font-size: 0.9rem; }
}

/* Short viewports: a phone held sideways, or a small window. Width is the
   dimension everyone tests; height is the one that actually breaks, because
   the panel is pinned to the middle of the screen and has nowhere to go. */
@media (max-height: 560px) {
  :root { --header-h: 56px; }
  .scene-on .act-in { align-content: center; padding-top: 0; padding-bottom: 0; }
  h1 { font-size: clamp(1.5rem, 4.4vw, 2.1rem); }
  h2 { font-size: clamp(1.25rem, 3.4vw, 1.7rem); }
  .act-plan .act-in h2,
  .act-cta h2 { font-size: clamp(1.35rem, 3.6vw, 1.85rem); }
  .lead,
  .act-plan .lead,
  .act-cta .lead { font-size: 0.94rem; line-height: 1.5; }
  .act-head { margin-bottom: 0.9rem; }
  .pills { display: none; }
  .scroll-cue { display: none; }
  .row-actions { margin-top: 0.9rem; }
  .btn { padding: 0.6rem 1.2rem; font-size: 0.94rem; }
  .btn-lg { padding: 0.7rem 1.5rem; font-size: 1rem; }
  .svc-list li { padding: 0.34rem 0; }
  .svc-list p { display: none; }
  .cards .card p { display: none; }
  .scene-on .gate-steps li h3,
  .scene-on .room-cards .card h3 { font-size: 1.1rem; }
  .scene-on .gate-steps li p,
  .scene-on .room-cards .card p { font-size: 0.9rem; line-height: 1.45; }
  .page-main { padding: 4.5rem 0 2rem; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .scroll-cue span { animation: none; }
  .boot { display: none; }
}

/* ---------- as ultimas linhas dos paragrafos ---------- */

/* AS VIUVAS, e contaram-se numa captura. Na lista de servicos, CINCO das seis
   descricoes acabavam com uma palavra sozinha na segunda linha: "SEO.",
   "sozinhos.", "sobressaltos.", "mal.", "desnecessarias.". Nao e um defeito de
   redaccao, e a largura da coluna a cair a um caractere do fim.
 *
 * `pretty` pede ao navegador que evite exactamente isso, ao custo de umas
 * linhas ligeiramente mais curtas antes. Onde nao existir, quebra como antes.
 * Nao vai nos titulos: esses levam `balance`, que reparte, e as duas
 * propriedades nao se somam. */
p, li, .svc-list li span, .card p, .lead, .foot-note {
  text-wrap: pretty;
}
