/* ==========================================================================
   Teconya — base layer.
   ========================================================================== */

/* --- Fonts -------------------------------------------------------------- */

/* Proprietary, supplied by the client via the sister studio. See fonts/README.md. */
@font-face {
	font-family: "TECONYAMONOVF";
	src: url("../fonts/TECONYAMONOVF.woff") format("woff-variations");
	font-weight: 50 200;
	font-style: normal;
	font-display: swap;
}

/* Proprietary, supplied by the client. See fonts/README.md. */
@font-face {
	font-family: "HelveticaProRoman";
	src: url("../fonts/HelveticaProRoman.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

/* Open licence. Covers the codepoints the mono face lacks (accents, etc.). */
@font-face {
	font-family: "JetBrains Mono";
	src: url("../fonts/JetBrainsMono-VF.woff2") format("woff2-variations");
	font-weight: 100 800;
	font-style: normal;
	font-display: swap;
}

/* Arabic faces. Open licence, Arabic subset only: `unicode-range` keeps Latin
   inside Arabic text on the Latin faces above. */
@font-face {
	font-family: "IBM Plex Sans Arabic";
	src: url("../fonts/IBMPlexSansArabic-400.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200F, U+060C, U+061B, U+061F;
}

@font-face {
	font-family: "IBM Plex Sans Arabic";
	src: url("../fonts/IBMPlexSansArabic-600.woff2") format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200F, U+060C, U+061B, U+061F;
}

@font-face {
	font-family: "Noto Kufi Arabic";
	src: url("../fonts/NotoKufiArabic-400.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200F, U+060C, U+061B, U+061F;
}

/* --- Reset -------------------------------------------------------------- */

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

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

	/* Matches the body rule: `clip` contains stray width without turning the
	   element into a scroll container, which would break scroll-linked effects. */
	overflow-x: clip;
}

body {
	margin: 0;
	background: var(--background);
	color: var(--foreground);
	font-family: var(--font-sans);
	font-size: var(--font-sm);
	line-height: 1.4;
	-webkit-font-smoothing: antialiased;

	/* `clip`, not `hidden`: `hidden` makes body its own scroll container and
	   stops viewport scroll propagation, breaking scroll-linked effects. */
	overflow-x: clip;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 400; line-height: 1.1; }
/* Every paragraph reads at --font-p (28px); labels and eyebrows set their own
   size through their classes and are unaffected. */
p { margin: 0 0 1em; font-size: var(--font-p); line-height: 1.35; }
a { color: inherit; text-decoration: none; }
img, video, svg, canvas { display: block; max-width: 100%; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

/* --- Accessibility ------------------------------------------------------ */

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

.skip-link:focus {
	position: fixed;
	top: var(--pad);
	inset-inline-start: var(--pad);
	z-index: 1000;
	width: auto;
	height: auto;
	clip-path: none;
	padding: var(--gap) var(--pad);
	background: var(--accent);
	color: var(--white);
}

:focus-visible { outline: var(--border-width) solid var(--accent); outline-offset: 2px; }

/* --- Twelve-column grid ------------------------------------------------- */

.grid-12 {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	grid-auto-flow: row;
	gap: var(--gap);
}

/* --- Header ------------------------------------------------------------- */

.header .nav {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	grid-auto-flow: row;
	gap: var(--gap);
	position: fixed;
	width: 100%;
	top: 0;
	inset-inline-start: 0;
	padding: var(--pad);
	font-family: var(--font-mono);
	font-size: var(--font-md);
	font-variation-settings: "wght" var(--wght-regular);
	text-transform: uppercase;
	line-height: 1;
	z-index: 4;
	mix-blend-mode: difference;
	color: var(--white);
}

/* The rocket hops between the nav's elements; it is positioned by script
   against the nav's box and must take no space in the grid. */
.nav-rocket {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 16px;
	pointer-events: none;
	will-change: transform;
	z-index: 1;
}

.nav-rocket svg { display: block; width: 100%; height: 100%; shape-rendering: crispEdges; }

/* The exhaust: single cells left along the flight, cooling to nothing. */
.nav-rocket__trail {
	position: absolute;
	top: 0;
	left: 0;
	width: 2px;
	height: 2px;
	background: var(--accent);
	pointer-events: none;
	will-change: transform, opacity;
	z-index: 1;
}

/* A Sadu band along the very top edge — the diamond weave of Najdi textiles,
   at two pixels a cell, faint, blended so it reads on light and dark alike. */
.header::before {
	content: "";
	position: fixed;
	top: 0;
	inset-inline-start: 0;
	width: 100%;
	height: 6px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='6' viewBox='0 0 6 3' shape-rendering='crispEdges'%3E%3Cpath fill='%23fff' d='M2 0h1v1H2zM1 1h3v1H1zM0 2h5v1H0z'/%3E%3C/svg%3E");
	background-size: 12px 6px;
	opacity: 0.16;
	pointer-events: none;
	z-index: 5;
}

/* A fixed strip with a blend mode makes the compositor re-blend it against
   the page on every scrolled frame; a plain band in the theme's ink does not. */
.theme--light .header::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='6' viewBox='0 0 6 3' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' d='M2 0h1v1H2zM1 1h3v1H1zM0 2h5v1H0z'/%3E%3C/svg%3E");
}

.header .nav .logo,
.header .nav .time { grid-column: span 2; }
.header .nav .logo a {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	text-transform: none;
}

/* The logo is eight rows tall — seven for the letters, one for the dots of ت
   above the T. The nav face has a cap height of 0.70em, so 0.80em puts the
   seven letter rows at exactly that, and sitting the mark at the top of the
   line box lands its foot on the type's baseline: the letters line up with
   the clocks and the menu, the dots clear the cap line above them. `color:
   inherit` is what lets the inline mark take the theme. */
.logo-mark {
	width: auto;
	height: 0.8em;
	align-self: flex-start;
	color: inherit;
	flex: none;
}

.header .nav ul {
	/* Five subgrid columns for five items, one each; the language switcher
	   holds column seven. `grid-auto-flow: column` keeps a sixth item on the
	   row rather than wrapping under the first — but it would land in an
	   implicit column past the grid, so widen this span if the menu grows. */
	grid-column: 8 / -1;
	display: grid;
	grid-template-columns: subgrid;
	grid-auto-flow: column;
	justify-items: end;
}

@media only screen and (max-width: 768px) {
	/* The clocks go; the menu moves into the panel below. */
	.header .nav .time { display: none; }
}

.time { font-variant-numeric: tabular-nums; }

/* --- Hover-fill links --------------------------------------------------- */

.button--has-hover,
.awards .awards__item > * {
	--hover-fill-background: var(--foreground-dim);
	--hover-fill-color: var(--background);
	--hover-fill-duration: 0.3s;
	--hover-fill-ease: var(--ease-out-expo);

	position: relative;
	isolation: isolate;
	display: inline-block;
}

.button--has-hover::after,
.awards .awards__item > *::after {
	content: "";
	display: block;
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: var(--border-radius-text);
	background: var(--hover-fill-background);
	transform: scaleX(0);
	transform-origin: right;
	transition: transform var(--hover-fill-duration) var(--hover-fill-ease);
}

.button--has-hover:hover::after,
.button--has-hover:focus-visible::after,
.awards .awards__item:hover > *::after {
	transform: scaleX(1);
	transform-origin: left;
}

.button--has-hover:hover,
.awards .awards__item:hover > * { color: var(--hover-fill-color); }

.button--active { color: var(--foreground-dim); }

/* --- Motion opt-out ----------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* --- Language switcher -------------------------------------------------- */

.lang-switcher {
	grid-column: span 1;
	display: flex;
	gap: 0.5em;
}

@media only screen and (max-width: 768px) {
	.lang-switcher { grid-column: span 2; }
}

/* --- Mobile navigation ----------------------------------------------------
   Four menu items will not share a row with the wordmark and the language
   switcher below 768px, so they move into a panel behind a MENU button. The
   site has no icons anywhere, so neither does this: the button is a word that
   swaps to CLOSE.
   ========================================================================== */

.nav-toggle {
	display: none;
	grid-column: 11 / -1;
	justify-self: end;
	appearance: none;
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	color: inherit;
	text-transform: inherit;
	cursor: pointer;
}

/* The wrapper leaves the list a direct grid child, so every wide-layout rule
   for `.header .nav ul` applies exactly as it did before the panel existed. */
.nav-menu { display: contents; }

@media only screen and (max-width: 768px) {
	/* The bar is a flex row at this width, so the button has to be told not to
	   give up its width — shrinking it clipped the label to two characters. */
	.nav-toggle {
		display: block;
		flex: none;
		white-space: nowrap;
	}

	/* The bar blends with whatever it passes over, which is right for a strip
	   of text and wrong for a panel with a ground of its own. Opening it drops
	   the blend and paints a real surface. */
	.header.is-menu-open .nav {
		mix-blend-mode: normal;
		background: var(--background);
		color: var(--foreground);
	}

	.nav-menu {
		display: block;
		position: fixed;
		top: 0;
		inset-inline: 0;
		padding: calc( var(--pad) * 3.5 ) var(--pad) var(--pad);
		background: var(--background);
		color: var(--foreground);
		transform: translateY( -100% );
		visibility: hidden;
		transition: transform 0.42s var(--ease-out-expo), visibility 0.42s;
		z-index: -1;
	}

	.header.is-menu-open .nav-menu {
		transform: none;
		visibility: visible;
	}

	.header .nav .nav-menu ul {
		display: block;
		grid-column: auto;
		grid-template-columns: none;
	}

	.header .nav .nav-menu li {
		/* The separator is drawn rather than bordered, to sit with the printed
		   rules the rest of the site uses. */
		background-image: repeating-linear-gradient(
			to right,
			currentColor 0 3px,
			transparent 3px 7px
		);
		background-repeat: no-repeat;
		background-position: bottom left;
		background-size: 0 1px;
		opacity: 0;
		transform: translateY( -0.4em );
		transition:
			opacity 0.3s var(--ease-out),
			transform 0.3s var(--ease-out),
			background-size 0.5s var(--ease-out);
	}

	.header .nav .nav-menu li:last-child { background-image: none; }

	.header .nav .nav-menu a {
		display: block;
		padding-block: 0.7em;
		font-size: var(--font-lg);

		/* Logical, so the items hang off the same edge as the button that
		   opened them in either direction. */
		text-align: end;
	}

	.header.is-menu-open .nav-menu li {
		opacity: 1;
		transform: none;
		background-size: 100% 1px;
	}

	.header.is-menu-open .nav-menu li:nth-child(1) { transition-delay: 0.04s; }
	.header.is-menu-open .nav-menu li:nth-child(2) { transition-delay: 0.09s; }
	.header.is-menu-open .nav-menu li:nth-child(3) { transition-delay: 0.14s; }
	.header.is-menu-open .nav-menu li:nth-child(4) { transition-delay: 0.19s; }
	.header.is-menu-open .nav-menu li:nth-child(n+5) { transition-delay: 0.24s; }

	/* Without scripting the panel cannot be opened, so it is simply the menu. */
	.no-js .nav-toggle { display: none; }

	.no-js .nav-menu {
		position: static;
		transform: none;
		visibility: visible;
		padding: 0;
		z-index: auto;
	}

	.no-js .header .nav .nav-menu li { opacity: 1; transform: none; }
}

@media only screen and (max-width: 768px) and (prefers-reduced-motion: reduce) {
	.nav-menu,
	.header .nav .nav-menu li { transition: none; }
}

/* --- Solid button ----------------------------------------------------------
   The page link on an offer, set apart from the "start a conversation" link
   beside it: filled in the accent, with an arrow, so the two cannot be
   mistaken for one another. The hover wipe still runs, in the foreground. */
.button--solid {
	--hover-fill-background: var(--foreground);
	--hover-fill-color: var(--background);

	display: inline-block;
	padding: 0.35em 0.9em;
	background: var(--accent);
	/* In the mono face, like the labels and copy around it. */
	font-family: var(--font-mono);
	font-variation-settings: "wght" var(--wght-regular);
	color: var(--white);
	border-radius: var(--border-radius-text);
}
.button--solid:hover { color: var(--hover-fill-color); }
/* The generic link colour rules below have more weight than one class;
   the fill's white text must win over them. */
a.button.button--solid,
.offer__cta a.button--solid,
.services-teaser__more a.button--solid { color: var(--white); }
a.button.button--solid:hover,
.offer__cta a.button--solid:hover,
.services-teaser__more a.button--solid:hover { color: var(--hover-fill-color); }

/* The clock's hours and minutes are one left-to-right run: with the colon
   blinking to a space, an Arabic line would otherwise swap the two numbers
   every second. */
.time [data-clock-time] { direction: ltr; unicode-bidi: isolate; display: inline-block; }
