/* Shared page shell — dark background + basic typography for every page
   in the site (the keychains demo and the 4 category pages). */
/* Alturas de ecrã: `svh` em vez de `vh` em tudo o que posiciona ou
   espaça conteúdo que rola.
   No telemóvel a barra de endereço esconde-se e reaparece durante o
   scroll, e `vh` acompanha-a — medido, uma variação de 67px na altura
   do ecrã deslocava todos os projectos 30 a 37px e mexia na posição do
   scroll, a meio do gesto, com o snap obrigatório a re-resolver por
   cima. `svh` é medido com a barra visível e não muda depois disso, por
   isso o layout deixa de depender de uma coisa que se mexe sozinha.
   O `vh` fica declarado antes de cada um como recurso para browsers que
   não conheçam a unidade nova. */

/* Page-to-page fade: see transition.css/transition.js (shared across all
   5 pages) — a plain JS-driven opacity crossfade instead of the
   Chromium-only View Transitions API, so it actually works regardless
   of which browser this is viewed in. */

@font-face {
  font-family: "Ouma Devanagari";
  src: url("assets/font1/fonnts.com-Ouma_Devanagari_Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Ouma Devanagari";
  src: url("assets/font1/fonnts.com-Ouma_Devanagari_Bold.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  width: 100vw;
  min-height: 100vh;
  min-height: 100svh;
}

body {
  /* Four layers, front to back: a faint film-grain tile (blended via
     "overlay" so it reads as texture, not a visible pattern), a soft
     vignette that darkens the edges, a warm, low, soft glow sitting
     roughly behind the keychain hero (like one large studio light
     source), and the photo itself. Solid fallback color is a warm
     charcoal rather than a nearly-black navy — richer and less cold,
     and on aspect ratios narrower than the photo (which "cover" would
     otherwise zoom/crop hard to fill) any sliver left uncovered reads
     as more background instead of a crop. Only safe down to roughly a
     1.2 aspect ratio — narrower than that (phones in portrait) needs
     plain cover instead, see the media query below. */
  background-color: #17140f;
  background-image:
    url("assets/grain.svg"),
    radial-gradient(ellipse 85% 75% at 50% 45%, transparent 55%, rgba(8, 7, 6, 0.5) 100%),
    radial-gradient(circle at 76% 20%, rgba(255, 232, 205, 0.08), transparent 55%),
    url("assets/page-bg.webp");
  background-repeat: repeat, no-repeat, no-repeat, no-repeat;
  background-size: 200px 200px, 100% 100%, 100% 100%, 130% auto;
  background-position: 0 0, center, center, center;
  background-blend-mode: overlay, normal, normal, normal;
  background-attachment: fixed, fixed, fixed, fixed;
  overflow-x: hidden;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: #f2f2f7;
}

@media (max-width: 600px) {
  body {
    background-size: 200px 200px, 100% 100%, 100% 100%, cover;
  }
}

.back-link {
  position: fixed;
  top: 1.5rem;
  left: 1.5rem;
  z-index: 60;
  color: #f2f2f7;
  text-decoration: none;
  font-size: 0.95rem;
  opacity: 0.7;
  transition: opacity 0.2s ease;
}

.back-link:hover,
.back-link:focus-visible {
  opacity: 1;
}

.page-content {
  position: relative;
  z-index: 1;
  max-width: 900px;
  margin: 0 auto;
  padding: 8rem 2rem 6rem;
}

.page-content h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  margin: 0 0 1.5rem;
  letter-spacing: -0.02em;
}

.page-content p {
  font-size: 1.05rem;
  line-height: 1.6;
  color: rgba(242, 242, 247, 0.75);
  max-width: 60ch;
}

/* Home page intro/contact call-outs — plain text blocks (no border/fill)
   sitting on top of the background photo. Held back (opacity/translateY)
   until body carries .kc-settled — added by keychain-cluster.js once the
   hero's entrance swing has settled — so the text only breathes in once
   the object it's introducing feels stable, instead of appearing at the
   same time as everything else. */
/* One colour for everything in these two blocks, and it is the exact
   background of the category pages — so the words that introduce the
   work are already the colour of the ground the work sits on. Stated
   here rather than on each piece of text: heading, paragraphs, button
   and subtitle were each carrying their own value, some of them at
   different opacities, which is why they read as slightly different
   colours from one another. */
.info-box {
  position: fixed;
  z-index: 40;
  color: #ececee;
  /* The measure is chosen for the rag, and both paragraphs share it, so
     it is one setting serving both. Narrowed from 26rem to stop lines
     ending on stranded words: at the old width they finished on
     "…everything in", "…where every", "…with character," and "…social,
     and". The band where all four fall to the next line instead is
     344–368px, and this sits in the middle of it — wide enough that a
     font rendering a shade wide or narrow can't tip the composition
     back. Both paragraphs stay three lines, so the block's height is
     unchanged. */
  max-width: min(22.25rem, calc(100vw - 4rem));
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

body.kc-settled .info-box {
  opacity: 1;
  transform: translateY(0);
}

body.kc-settled .contact-box {
  transition-delay: 0.12s;
}

@media (prefers-reduced-motion: reduce) {
  .info-box {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.info-heading {
  font-family: "Ouma Devanagari", sans-serif;
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 1.15rem;
}

.hello-box {
  top: 16vh;
  top: 16svh;
  left: 60px;
}

.hello-box p {
  margin: 0 0 1.1rem;
  font-size: 0.95rem;
  line-height: 1.65;
}

.hello-box p:last-child {
  margin-bottom: 0;
}

/* An aside rather than a third point: set smaller so it sits below the
   introduction instead of continuing it. Not dimmed to get there — the
   two blocks are deliberately one colour (see .info-box) and size alone
   carries the difference. */
/* Qualified with .hello-box, because the rule setting the paragraph
   size above is `.hello-box p` — a class *and* an element — and a bare
   class on its own loses to it. Unqualified, this silently did nothing. */
.hello-box p.hello-note {
  font-size: 0.78rem;
  letter-spacing: 0.01em;
  margin-top: 1.5rem;
}

.contact-box {
  right: 60px;
  bottom: 13vh;
  bottom: 13svh;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.85rem;
}

.contact-button {
  display: inline-flex;
  align-items: center;
  padding: 0.55rem 1.1rem;
  /* An anchor doesn't inherit colour on its own — the browser's own
     stylesheet gives every link its default blue, and that beats
     anything inherited from an ancestor. Said explicitly here, or the
     button and its ring both come out blue. */
  color: inherit;
  /* currentColor, so the ring can never drift from the word inside it. */
  border: 1.3px solid currentColor;
  border-radius: 999px;
  background-color: rgba(236, 236, 238, 0);
  text-decoration: none;
  cursor: pointer;
  transform: scale(1);
  transition: font-weight 0.25s ease,
              transform 0.4s cubic-bezier(0.16, 1, 0.3, 1),
              background-color 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.contact-button:hover,
.contact-button:focus-visible {
  transform: scale(1.035);
  background-color: rgba(236, 236, 238, 0.08);
}

.contact-button:active {
  transform: scale(0.965);
  transition-duration: 0.15s;
}

@media (prefers-reduced-motion: reduce) {
  .contact-button,
  .contact-button:hover,
  .contact-button:focus-visible,
  .contact-button:active {
    transform: none;
    transition: font-weight 0.25s ease, background-color 0.25s ease;
  }
}

.contact-label {
  font-family: "Ouma Devanagari", sans-serif;
  font-weight: 400;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  transition: font-weight 0.25s ease;
}

.contact-button:hover .contact-label,
.contact-button:focus-visible .contact-label {
  font-weight: 700;
}

.contact-subtitle {
  margin: 0;
  font-size: 0.85rem;
  text-align: right;
}

/* Mobile home layout — a phone doesn't have the spare room for the
   desktop's fixed-corner composition, so below 600px everything drops
   into normal document flow and stacks in a single centered column
   (hero, then intro, then contact), in that order because that's
   already the order they appear in the markup. Desktop rules above are
   untouched; this only overrides what's needed for the narrow layout. */
@media (max-width: 600px) {
  .info-box {
    position: static;
    z-index: auto;
    width: 100%;
    max-width: 26rem;
    margin: 0 auto;
    padding: 0 1.75rem;
  }

  .info-heading {
    font-size: clamp(1.6rem, 7vw, 2.1rem);
    text-align: center;
    margin: 0 0 1.5rem;
  }

  .hello-box {
    margin-top: 1.25rem;
  }

  .hello-box p {
    text-align: center;
    font-size: 1rem;
    line-height: 1.75;
    margin: 0 0 1.35rem;
  }

  /* Kept proportionally smaller here too — the rule above would
     otherwise pull it back up to full size on a phone. */
  .hello-box p.hello-note {
    font-size: 0.82rem;
    margin-top: 1.75rem;
  }

  .contact-box {
    align-items: center;
    text-align: center;
    margin: 4rem auto 4.5rem;
    gap: 1.1rem;
  }

  .contact-button {
    padding: 0.85rem 1.85rem;
  }

  .contact-label {
    font-size: 0.95rem;
  }

  .contact-subtitle {
    text-align: center;
    font-size: 0.95rem;
  }
}


/* --------------------------------------------------------------------
   Fundo em versão leve no telemóvel.

   A fotografia tem 5400px de largura e 1,9 MB, para ecrãs que a mostram
   a 375. A cópia reduzida tem 166 KB e é indistinguível: está esticada
   por trás do conteúdo e nenhum ecrã de telefone tem resolução para
   mostrar a diferença.

   Bloco acrescentado no fim do ficheiro, e não dentro da regra do body.
   Uma tentativa anterior editou essa regra a meio e fechou-a cedo, o que
   atirou o tipo de letra, a cor do texto e o dimensionamento do fundo
   para dentro de uma media query — em ecrãs largos o site perdeu-os
   todos. Aqui não há como isso acontecer: a regra do body fica intacta,
   e isto só pode acrescentar-lhe uma propriedade abaixo dos 700px.
   -------------------------------------------------------------------- */
@media (max-width: 700px) {
  body {
    background-image:
      url("assets/grain.svg"),
      radial-gradient(ellipse 85% 75% at 50% 45%, transparent 55%, rgba(8, 7, 6, 0.5) 100%),
      radial-gradient(circle at 76% 20%, rgba(255, 232, 205, 0.08), transparent 55%),
      url("assets/page-bg-mob.webp");
  }
}


/* --------------------------------------------------------------------
   TELEMÓVEL EM ESPERA — temporário.

   O telemóvel ainda não está afinado, por isso abaixo dos 700px a
   homepage passa a ser a única página: mostra o cluster, o fundo, o
   botão de contacto e um aviso a pedir para abrir no computador. A
   apresentação de três parágrafos fica escondida, e os keychains, apesar
   de continuarem à vista e a baloiçar, deixam de navegar.

   São os keychains que fazem a navegação através de `.kc-hitlayer` — as
   âncoras por baixo têm pointer-events:none e nunca recebem o toque
   (keychain-cluster.js, ~linha 636). Desligar essa camada chega, e não
   obriga a mexer no JavaScript. O teclado continua a funcionar, para
   quem navegue assim.

   PARA DESFAZER: apagar este bloco inteiro, e as duas linhas marcadas
   "Temporário" em index.html. Não há mais nada.

   Está no fim do ficheiro e só acrescenta regras novas — nenhuma regra
   existente é tocada, a nenhuma largura.
   -------------------------------------------------------------------- */
.desktop-hint-heading,
.desktop-hint {
  display: none;
}

@media (max-width: 700px) {
  /* O :not() não é decorativo. Sem ele esta regra também apanhava o
     aviso — é um <p> dentro de .hello-box como os outros — e `.hello-box
     > p` tem mais especificidade que `.desktop-hint`, por isso o
     display:block abaixo perdia e não aparecia nada. */
  .hello-box > h1.info-heading,
  .hello-box > p:not(.desktop-hint) {
    display: none;
  }

  .desktop-hint-heading {
    display: block;
  }

  .desktop-hint {
    display: block;
    /* `.hello-box p` está desligado acima, por isso o tamanho e a
       entrelinha que os parágrafos traziam têm de ser ditos aqui. */
    font-size: 1rem;
    line-height: 1.75;
    text-align: center;
    margin: 0;
  }

  /* "Say hello! Let's work together." sai daqui: com a apresentação
     escondida, ficava a ser a única frase solta na página além do aviso,
     e desviava dele. No desktop mantém-se. */
  .contact-subtitle {
    display: none;
  }

  .kc-hitlayer {
    pointer-events: none;
  }
}
