/**
 * Estils base del Codina Theme.
 *
 * Els tokens viuen a theme.json i arriben aquí com a custom properties
 * (--wp--preset--* i --wp--custom--*). Aquest fitxer només conté el que
 * theme.json no pot expressar.
 */

/* -------------------------------------------------------------------------
 * Reset mínim
 * ---------------------------------------------------------------------- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: clip; /* Cap secció ha de provocar scroll horitzontal (TASKS T49). */
}

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

:where(button, [role="button"]) {
	font: inherit;
}

/* -------------------------------------------------------------------------
 * Tipografia
 * ---------------------------------------------------------------------- */

/**
 * Els fitxers de la Codina tenen com a nom intern dues famílies separades
 * («Codina Light» i «Codina Semibold»). theme.json ja les unifica sota
 * font-family: "Codina" amb pesos 300 i 600, però el navegador no ha de
 * sintetitzar cap pes intermedi ni cap cursiva: no existeixen.
 */
body {
	font-synthesis: none;
}

/**
 * La negreta ha de ser la Semibold, sempre.
 *
 * El `<strong>` del navegador no és `font-weight: 700` sinó `bolder`, que és
 * relatiu al pare: amb el cos a 300, `bolder` es resol a 400 i 400 cau a la
 * Light, així que la negreta no es veia. Per això el cos va a 500 a
 * theme.json (500 també renderitza Light, el text normal no canvia gens).
 *
 * Aquesta regla ho fixa igualment: hi ha contextos que declaren el 300
 * explícitament (cites, llistes de serveis, títols de projecte…) i allà el
 * `bolder` tornaria a fallar. Una regla pròpia sempre guanya a l'herència.
 */
b,
strong {
	font-weight: 600;
}

/**
 * Tagline: mateixa mida que el cos però amb més aire. Al Figma és un estil
 * propi (16/20) i no una mida diferent, així que no és un font-size preset.
 */
.is-style-tagline {
	line-height: var(--wp--custom--line-height--tagline);
}

/* Fletxa dels enllaços externs. Per CSS, per no haver-la de traduir
   ni fer-la llegir al lector de pantalla. */
.is-style-external-link::after {
	content: "\2197";
	display: inline-block;
	margin-inline-start: 0.25em;
	speak: never;
}

/* -------------------------------------------------------------------------
 * Botons «anterior / següent»
 *
 * L'estil de tots els prev/next del lloc, en un sol lloc. És el de la secció
 * de testimonis, que és el que val: sense fons, vora fina i un gris suau en
 * passar-hi per damunt. Qualsevol control nou de tipus anterior/següent ha de
 * portar aquesta classe i no inventar-se cap variant.
 *
 * El SVG que hi va a dins ha de ser la fletxa amb pal de 12 × 12 i
 * `width="100%"`: el `padding` del botó és qui li dona la mida.
 * ---------------------------------------------------------------------- */

.codina-nav-button {
	display: flex;
	justify-content: center;
	align-items: center;
	inline-size: 40px;
	block-size: 40px;
	padding: 12px;
	color: var(--wp--preset--color--cs-black);
	background: none;
	border: 1px solid var(--wp--preset--color--cs-black-10);
	border-radius: var(--wp--custom--radius--full);
	cursor: pointer;
	transition: background-color var(--wp--custom--duration--fast) ease;
}

.codina-nav-button:hover {
	background-color: var(--wp--preset--color--cs-black-10);
}

/* -------------------------------------------------------------------------
 * Patró de punts de fons
 *
 * Punt de 2 px de diàmetre a `rgba(0,0,0,.1)` en graella de 20 × 20 px: és el
 * de codina.studio, que hi pinta un SVG de 100 × 100 amb un cercle de r=5 a
 * `background-size: 20px`. Mana per damunt del Figma, que en deia una el·lipse
 * de 5 px a #F4F4F4 en graella de 24 (decisió del 2026-08-12).
 *
 * Les mides són a theme.json, `custom.pattern`; el `dot` és el RADI.
 * ---------------------------------------------------------------------- */

.has-dot-pattern {
	background-image: radial-gradient(
		circle at center,
		var(--wp--preset--color--cs-black-10) var(--wp--custom--pattern--dot),
		transparent calc(var(--wp--custom--pattern--dot) + 0.1px)
	);
	background-size: var(--wp--custom--pattern--size) var(--wp--custom--pattern--size);
	background-position: 0 0;
	background-repeat: repeat;
	background-color: var(--wp--preset--color--cs-white);

	/*
	 * El canvas del camp de punts hi entra com a fill amb `z-index: -1`, i ha de
	 * caure exactament on cau aquest `background-image`: per damunt del fons del
	 * `<main>` i per sota del seu contingut. Amb un context d'apilament propi
	 * aquell -1 es resol aquí dins i no depèn de si el blanc del lloc acaba a
	 * `html` o a `body`.
	 */
	isolation: isolate;
}

/* -------------------------------------------------------------------------
 * El halo del cursor
 *
 * ⚠️ Aquest canvas **no pinta la graella**: la graella és el `background-image`
 * d'aquí sobre, sempre. Viu a la caixa del `<main>` i per tant el navegador el
 * fa scrollar amb el contingut, clavat. Un canvas fix mogut per JavaScript va
 * sempre un frame enrere de l'scroll —Lenis mou la pàgina dins del seu
 * `requestAnimationFrame` i els esdeveniments arriben després— i es veia com si
 * els punts anessin a una altra velocitat.
 *
 * Aquí només s'hi dibuixen els punts que el cursor ha fet créixer.
 * ---------------------------------------------------------------------- */

.codina-dots {
	position: fixed;

	/*
	 * Una tessel·la de marge per cada costat, perquè un punt que creixi just a
	 * la vora de la finestra hi càpiga sencer. El JavaScript compta amb aquest
	 * mateix marge per situar els punts.
	 */
	inset-block-start: calc(var(--wp--custom--pattern--size) * -1);
	inset-inline-start: calc(var(--wp--custom--pattern--size) * -1);
	z-index: -1;
	pointer-events: none;

	/*
	 * ⚠️ El punt gran es dibuixa damunt del punt del `background-image` que ja
	 * hi ha a sota. Amb una opacitat del 10 % sobre una altra del 10 %, els dos
	 * alfes se sumarien i donarien un 19 %: un punt amb el cor més fosc. Amb
	 * `darken` es guanya el més fosc dels dos, i com que el canvas pinta el gris
	 * ja compost (`cs-black-10-solid`), el resultat és el mateix tant si a sota
	 * hi ha el punt com si hi ha el blanc. Unió perfecta.
	 *
	 * L'`isolation: isolate` de `.has-dot-pattern` és qui conté la barreja.
	 */
	mix-blend-mode: darken;
}

/*
 * El peu no ha de tenir punts, i amb el canvas s'hi cola.
 *
 * El `background-image` del CSS només pinta dins del `<main>`, i el peu en
 * queda fora. El canvas, en canvi, és fix i ocupa tota la finestra: sense un
 * fons opac, la graella li passaria per sota. Es podria retallar el canvas per
 * baix, però la vora hauria de recalcular-se a cada frame d'scroll —el peu és
 * l'últim element del document— i això vol dir repintar la capa. Un blanc opac
 * ho resol sense cost i és exactament el que es veu avui, perquè el que hi ha
 * a sota és el blanc del `body`.
 */
.codina-footer {
	background-color: var(--wp--preset--color--cs-white);
}

/* -------------------------------------------------------------------------
 * El contingut ha de començar a sang
 *
 * La capçalera només conté elements fixos (navegació, Progressive Blur i
 * retolador), així que no ocupa cap alçada al flux. Tot i així WordPress hi
 * posa el `blockGap` entre ella i el `<main>`, i aquells 24 px es queden com
 * a espai mort a dalt de tot.
 * ---------------------------------------------------------------------- */

.wp-site-blocks > header.wp-block-template-part + * {
	margin-block-start: 0;
}

/*
 * ⚠️ I el marge del `<header>` mateix, que és el que realment baixava el lloc.
 *
 * El `<header>` és el primer fill de `.wp-site-blocks` i també rep el
 * `blockGap`. Com que `.wp-site-blocks` no té ni vora ni farciment, el marge
 * **es col·lapsa cap enfora** i empeny tot el bloc 24 px avall. La regla d'aquí
 * sobre només netejava el germà següent, o sigui que els 24 px hi eren igual:
 * mesurat, `.wp-site-blocks` començava a y = 24. On es notava més era a codina
 * world, que fa exactament una finestra d'alt i quedava descentrada.
 */
.wp-site-blocks > header.wp-block-template-part {
	margin-block-start: 0;
}

/* -------------------------------------------------------------------------
 * Barra d'administració
 *
 * Només la veuen els usuaris identificats, però mentre hi és desplaça la
 * pàgina cap avall i taparia els elements fixos ancorats a dalt.
 * ---------------------------------------------------------------------- */

.admin-bar .codina-draw {
	inset-block-start: calc(24px + var(--wp-admin--admin-bar--height, 32px));
}

/* -------------------------------------------------------------------------
 * Ordre d'apilament
 *
 * En un sol lloc, perquè es pugui llegir d'un cop:
 *
 *    -1  camp de punts        (dins del <main>, que té context propi)
 *    30  llenç de dibuix
 *    40  Progressive Blur
 *    50  loader d'entrada     (el CSS és a inc/loader.php, no aquí)
 *    50  cortina de la transició de punts
 *    60  botó del retolador
 *    90  escena de la transició del cub i de la de costat a costat
 *   100  navegació inferior
 *
 * La navegació ha de quedar per damunt de l'escena del cub: si no, durant la
 * transició desapareix darrere de la pàgina que gira i fa un efecte estrany.
 *
 * El loader i la cortina de punts, en canvi, es queden per **sota** del
 * retolador i de la navegació a posta, i comparteixen el mateix nivell: no els
 * tapen, sinó que aquests s'amaguen amb `opacity` i en surten i hi entren per
 * damunt. És la diferència que separa els dos efectes de transició, i per això
 * la cortina no pot anar al 90 de l'escena del cub.
 * ---------------------------------------------------------------------- */

.codina-transition__stage {
	z-index: 90;
}

/* -------------------------------------------------------------------------
 * Hero — Figma 5:209
 *
 * Al Figma fa 1024 px d'alt amb el text centrat verticalment. Aquí es fa
 * servir svh perquè a mòbil la barra del navegador no talli el text.
 * ---------------------------------------------------------------------- */

.codina-hero {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 100svh;
}

.codina-hero p {
	margin-block: 0;
	line-height: var(--wp--custom--line-height--body);

	/**
	 * L'`!important` no és un pegat nostre: WordPress emet els presets de mida
	 * com a `.has-large-font-size { font-size: … !important }`, i el contingut
	 * que ja hi ha desat porta aquella classe. `.codina-hero p` té més
	 * especificitat, així que guanya, i alhora cobreix el marcatge nou del
	 * pattern, que ja no porta cap preset.
	 */
	font-size: 2rem !important;
}

@media (min-width: 1024px) {
	.codina-hero p {
		font-size: 3rem !important;
	}
}

/* -------------------------------------------------------------------------
 * CTA — Figma 8:993
 * ---------------------------------------------------------------------- */

.codina-cta {
	display: flex;
	justify-content: center;
	align-items: center;
	min-height: 900px;
	padding-inline: var(--wp--custom--gutter);
}

@media (max-width: 767px) {
	.codina-cta {
		min-height: auto;
		padding-block: var(--wp--preset--spacing--110);
	}
}

/* -------------------------------------------------------------------------
 * Pàgines sense scroll
 *
 * codina world ocupa exactament una finestra: qui es mou és el tornado, que
 * captura la roda pel seu compte. Qualsevol scroll de pàgina hi competiria.
 * ---------------------------------------------------------------------- */

.codina-no-scroll {
	block-size: 100svh;
	overflow: clip;
}

body:has(.codina-no-scroll) {
	overflow: hidden;
	overscroll-behavior: none;
}

/* -------------------------------------------------------------------------
 * Accessibilitat
 * ---------------------------------------------------------------------- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--cs-black);
	outline-offset: 3px;
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.skip-link:focus {
	position: fixed;
	z-index: 100000;
	inset-block-start: 1rem;
	inset-inline-start: 1rem;
	width: auto;
	height: auto;
	margin: 0;
	padding: 0.75rem 1rem;
	clip-path: none;
	background: var(--wp--preset--color--cs-black);
	color: var(--wp--preset--color--cs-white);
	border-radius: var(--wp--custom--radius--s);
}

/* -------------------------------------------------------------------------
 * Moviment reduït
 *
 * Regla transversal del projecte: cap animació és obligatòria. Les animacions
 * de GSAP també ho comproven per JS; això cobreix les de CSS i el scroll.
 * ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

/* -------------------------------------------------------------------------
 * Transició de pàgina (Fase 10)
 *
 * L'escena del cub la munta i la desmunta el JavaScript; aquí només hi ha el
 * que ha d'existir abans que GSAP hi arribi. El `z-index` és a l'apartat
 * d'ordre d'apilament, més amunt.
 * ---------------------------------------------------------------------- */

.codina-transition__stage {
	pointer-events: none;
}

/*
 * Les dues cares del cub no s'han de veure mai pel darrere. Quan el cub gira
 * 90°, la pàgina que marxa queda mirant cap avall i, sense això, se'n veu el
 * revers per sota de la pàgina nova.
 *
 * Va al CSS i no al `gsap.set()` perquè és una propietat estructural de
 * l'escena, no un valor que s'animi.
 */
.codina-transition__cube,
.codina-transition__cube > *,
.codina-transition__wrapper > * {
	-webkit-backface-visibility: hidden;
	backface-visibility: hidden;
}

/* La cara que marxa no ha de deixar veure res per sota seu. */
.codina-transition__wrapper {
	background-color: var(--wp--preset--color--cs-white);
}

/*
 * L'embolcall de la transició costat a costat, pel mateix motiu: mentre llisca
 * cap a l'esquerra deixa al descobert el que hi ha darrere.
 *
 * La resta de la seva geometria la posa `gsap.set()`, com al cub: aquí només hi
 * ha el que ha d'existir abans que GSAP hi arribi. No comparteix classe amb
 * l'embolcall del cub a posta —les regles de `backface-visibility` d'aquí sobre
 * són de l'escena 3D del cub i aquesta transició no les vol.
 */
.codina-transition__slide {
	background-color: var(--wp--preset--color--cs-white);
}

/* Barba deixa dos contenidors al DOM durant la transició; sense això,
   el segon empenyeria el primer i es veuria un salt abans d'animar. */
[data-barba="wrapper"] {
	position: relative;
}

/* -------------------------------------------------------------------------
 * Cortina de la transició de punts (Fase 17)
 *
 * El boomerang del loader: el fons es desfà fins al blanc i la pàgina següent
 * es torna a construir punt a punt. A diferència de l'escena del cub, aquí no
 * es reparenta res —n'hi ha prou amb una capa opaca al davant—, i per això les
 * mides i la posició les pot fixar el CSS i no cal cap `gsap.set()`.
 *
 * El canvas el dimensiona el JavaScript, com el del loader, i per la mateixa
 * raó va desplaçat una tessel·la: la graella ha de poder començar fora de la
 * finestra.
 * ---------------------------------------------------------------------- */

.codina-transition__curtain {
	position: fixed;
	inset: 0;
	z-index: 50;
	pointer-events: none;
}

/*
 * El buit que deixen les dues pàgines quan s'enfonsen, a la transició costat a
 * costat. El color el tria el client a Opcions → Codina Core i el JavaScript
 * l'escriu a l'escena; aquest negre és el valor de partida, per si el JS no hi
 * arriba a temps.
 */
.codina-transition__stage[data-codina-stage="side"] {
	background-color: #000;
}

.codina-transition__veil {
	position: absolute;
	inset: 0;
	background-color: var(--wp--preset--color--cs-white);

	/* L'estat de partida: la pàgina encara es veu sencera. */
	opacity: 0;
}

.codina-transition__dots {
	position: absolute;
	inset-block-start: calc(var(--wp--custom--pattern--size) * -1);
	inset-inline-start: calc(var(--wp--custom--pattern--size) * -1);
	display: block;
}

/* -------------------------------------------------------------------------
 * Capçalera de l'entrada — Figma 5:7
 *
 * Comparteix amplada i marges amb el cos de l'article. El padding no pot ser
 * els 64 px fixos del disseny: a 375 px deixarien el titular en 247 px.
 * ---------------------------------------------------------------------- */

.codina-article-header {
	inline-size: 100%;
	max-inline-size: 960px;
	margin-inline: auto;
	padding-inline: clamp(var(--wp--custom--gutter), 4vw, 64px);
}

/**
 * La caixa amb la imatge destacada de fons — Figma 45:4.
 *
 * El core imposa 430 px de `min-height` a tot `wp-block-cover`; al Figma
 * l'alçada la dona el contingut (64 + botó + 32 + títol + 64), i un títol
 * d'una sola línia ha de donar una caixa més baixa.
 */
.codina-article-cover.wp-block-cover {
	min-height: 0;

	/* Els 64 px del disseny deixarien el títol en no res a 375 px. */
	padding: clamp(var(--wp--custom--gutter), 5vw, 64px);
}

/* Al Figma el contingut va arrenglerat a l'esquerra, no centrat. */
.codina-article-cover .wp-block-cover__inner-container {
	inline-size: 100%;
}

/**
 * Sense imatge destacada, el vel del 20 % es quedaria sobre el no-res. El core
 * imprimeix igualment el `<span>` de l'overlay amb el color de marca: només
 * cal pujar-li l'opacitat i queda el negre sòlid.
 *
 * El selector va carregat de classes a posta: el del core per a l'opacitat del
 * vel en gasta quatre, i amb menys aquesta regla no arribava a aplicar-se.
 */
.codina-article-cover.wp-block-cover:not(:has(.wp-block-cover__image-background))
	.wp-block-cover__background.has-background-dim {
	opacity: 1;
}

/* El botó de tornada va al revés que a la resta del lloc perquè seu damunt del
   negre: ho resol l'estil «Primari · fons fosc» de `codina/button`, no cap
   pegat de color d'aquí. */

.codina-article-cover :focus-visible {
	outline-color: var(--wp--preset--color--cs-white);
}
