/**
 * STRUCTURE — ديلما.
 *
 * The frame, the primitives and the grain. Colour and type live in
 * identity.css and reach this file only as tokens; nothing below names a
 * colour or a family directly.
 *
 * Diverged from the starter's base.css on purpose: this site is dark, runs two
 * languages at once and carries a texture over everything, and none of that is
 * generic enough to pretend it is shared.
 */

/* ================================================================== ground */

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	/* Full-bleed sections are sized in vw, which counts the scrollbar. Clipping
	   on both elements is what keeps that from becoming a sideways scroll. */
	overflow-x: clip;
}

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

body {
	margin: 0;
	background: var(--d-void);
	color: var(--d-text);
	font-family: var(--d-font);
	font-size: var(--d-t-body);
	font-weight: 400;
	line-height: var(--d-lh-body);
	/* Grain wants a stable surface under it. */
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	overflow-x: clip;
}

img,
svg,
video,
canvas {
	display: block;
	max-inline-size: 100%;
	height: auto;
}

a {
	color: inherit;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.28em;
}

h1, h2, h3, h4 {
	font-weight: 300;
	line-height: var(--d-lh-head);
	text-wrap: balance;
}

/* Tightening is a Latin habit; on a joined script it only crowds the joins. */
:lang(en),
[dir="ltr"] {
	letter-spacing: var(--d-track-hero);
}

p {
	text-wrap: pretty;
}

:focus-visible {
	outline: 2px solid var(--d-glow);
	outline-offset: 3px;
}

::selection {
	background: var(--d-glow);
	color: var(--d-white);
}

/* ================================================================ the grain

   One fixed plane over the whole document. It is the single thing that makes
   this site read the way their photographs do, so it is structure and not
   decoration. Fixed and composited, so scrolling never repaints it, and
   pointer-events:none so it is not in anyone's way.

   The drift is eight discrete offsets that are deliberately not multiples of
   the tile, so the pattern lands somewhere new each step instead of tiling
   back onto itself and looking still.
   ======================================================================== */

.grain {
	position: fixed;
	inset: 0;
	z-index: 9999;
	pointer-events: none;
	/* One grain layer, over the whole site, and this is the only one.

	   It used to blend with `overlay`, which is transparent to black — so on a
	   near-black page the grain was simply not there, and anywhere it was wanted
	   it got added again locally. That is how a grey veil ended up washing the
	   mark section and drawing a seam across the page.

	   Normal blending instead, with a texture built for it: the specks are
	   biased dark, because over a ground of 11 a white speck can climb 244
	   levels and a black one can only fall 11 — balanced noise still lifts hard.
	   Measured, it lifts --d-ground by 1.3 levels and --d-void by 1.1. Close
	   enough to each other that the two rooms keep their difference, and small
	   enough that nothing reads as a wash.

	   Two things about the texture itself, both from Saad seeing squares in it:

	   The specks are blurred by about half a pixel. They were hard-edged single
	   pixels, and a one-pixel speck only stays a speck on a display that happens
	   to be exactly 1:1 — anywhere else each one lands as a little block.

	   And the tile is 256, not 128. A tile repeats, and the smaller it is the
	   sooner the eye finds the repeat and reads it as a grid rather than as
	   grain. Twice the tile is a quarter as many repeats on a wide screen. */
	background-image: url("assets/img/grain.webp");
	background-size: var(--d-grain-size) var(--d-grain-size);
	background-repeat: repeat;
	opacity: var(--d-grain-opacity);
}

/* ============================================================== primitives */

.site-column {
	inline-size: min(100% - (var(--d-gutter) * 2), var(--d-col));
	margin-inline: auto;
}

.d-narrow {
	inline-size: min(100%, var(--d-col-narrow));
}

/* Escape the column to the viewport edge without a wrapper and without
   overflow. The rest of the page keeps its column. */
.d-bleed {
	inline-size: 100vw;
	margin-inline: calc(50% - 50vw);
}

/* Small print. The tracking and the capitals belong to the Latin half only:
   Arabic has no capitals to make, and spacing its letters breaks the joins that
   make it legible. Both are therefore applied to Latin runs, not to the box. */
/* The Arabic face by default, and the mono only where there is Latin to set.

   This was the other way round, and the note in identity.css about --d-mono
   ending in Greta was solving the wrong half of the problem: it only helps if
   nothing earlier in the stack has Arabic glyphs, and on Windows both Cascadia
   Mono and Segoe UI Mono do. So every Arabic label in small print was landing
   in a monospace face — the footer's copyright line, the index's column heads,
   the service badges — and Saad caught it three separate times before I looked
   at the rule they all share. */
.d-meta {
	font-family: var(--d-font);
	font-size: var(--d-t-meta);
	font-weight: 400;
	line-height: 1.5;
	color: var(--d-faint);
}

.d-meta :lang(en),
.d-meta .bi__en,
.d-meta[lang="en"],
.d-meta[dir="ltr"],
[dir="ltr"] .d-meta {
	font-family: var(--d-mono);
	letter-spacing: var(--d-track-meta);
	text-transform: uppercase;
}

.d-rule {
	border: 0;
	margin: 0;
}

.d-photo {
	filter: var(--d-photo);
}

/* The four-point mark as a small inline glyph: bullets, separators, the dot
   before a label. Drawn from brand/Brand elements-02.svg. */
.d-star {
	display: inline-block;
	inline-size: 0.62em;
	block-size: 0.62em;
	vertical-align: 0.02em;
	flex: none;
}

.skip-link {
	position: absolute;
	inset-block-start: -100vh;
	inset-inline-start: var(--d-gutter);
	z-index: 10000;
	padding: 0.7em 1.1em;
	background: var(--d-text);
	color: var(--d-void);
	text-decoration: none;
}

.skip-link:focus {
	inset-block-start: 0.75rem;
}

/* ============================================================= the two lines

   Every heading, label and paragraph on this site carries both languages. The
   Arabic is the line; the English is set beneath it, smaller and quieter, in
   the Latin display face, running the other way. When a field has no English
   in it, nothing is drawn — never the Arabic twice.
   ======================================================================== */

.bi {
	display: block;
}

.bi__en {
	display: block;
	font-family: var(--d-latin);
	font-weight: 400;
	font-size: calc(1em * var(--bi-scale, var(--d-bi-head)));
	line-height: 1.28;
	letter-spacing: 0.005em;
	color: var(--d-quiet);
	text-wrap: balance;
	margin-block-start: 0.5em;

	/* The English runs left to right and is isolated so it cannot reorder the
	   Arabic beside it. */
	direction: ltr;
	unicode-bidi: isolate;

	/* Physical alignment, and deliberately so. `start` resolves against this
	   element's own direction, which is ltr — so on an Arabic page the English
	   would sit against the left edge while the Arabic sat against the right,
	   and the pair would fall apart across the width of the page. The two lines
	   share the reading margin instead. */
	text-align: left;
}

[dir="rtl"] .bi__en {
	text-align: right;
}

.bi--hero .bi__en {
	--bi-scale: var(--d-bi-hero);
	letter-spacing: 0.045em;
	margin-block-start: 0.9em;
	color: var(--d-faint);
}

/* 2.2em of gap used to sit here — a margin and a padding of 1.1em each. The
   padding was holding a hairline off the text, and the hairlines are gone, so
   what was left was twice the space anyone had asked for. */
.bi--body .bi__en {
	--bi-scale: var(--d-bi-body);
	line-height: 1.62;
	margin-block-start: 0.7em;
}

/* Inline pairing, for a label that has no room for two lines: Arabic, a
   hairline slash, then the English at the same size. */
.bi--inline {
	display: inline-flex;
	align-items: baseline;
	gap: 0.55em;
}

.bi--inline .bi__en {
	margin: 0;
	font-size: inherit;
	text-align: inherit;
}

/* The separator hangs off the end of the Arabic rather than the start of the
   English. The English is an isolated ltr run, so a ::before on it lands on its
   own left edge — which in an Arabic row is the far side, and reads as
   "الاستراتيجية /Strategy" instead of "الاستراتيجية / Strategy". */
.bi--inline .bi__ar::after {
	content: "/";
	margin-inline-start: 0.55em;
	color: var(--d-rule);
}

/* ================================================================ the frame */

/* Three zones, after midu.design: the name on the reading margin, a capsule
   floating in the middle, one solid button opposite. The bar itself is air —
   it spans the screen so its three zones can be measured against the screen,
   but a full-width element pinned over the opening screen would swallow every
   click meant for what is behind it. So the bar takes no pointer and each of
   its children takes its own back. */
.site-head {
	position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
	z-index: 900;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	align-items: start;
	gap: clamp(0.5rem, 2vw, var(--d-gutter));
	padding: clamp(0.8rem, 1.6vw, 1.2rem) var(--d-gutter);
	pointer-events: none;
}

.site-head > * {
	pointer-events: auto;
}

/* Set by motion.js once the page has left the top. There is no full-width
   glass any more — the capsule is the glass, and a second pane behind it only
   muddied both. What is left is the bar drawing itself in a little. */
.site-head.is-settled {
	padding-block: clamp(0.55rem, 1.1vw, 0.85rem);
}

.site-name {
	justify-self: start;
	display: block;
	inline-size: clamp(3.75rem, 5.6vw, 5.25rem);
	margin-block-start: 0.55rem;
	color: var(--d-text);
	text-decoration: none;
	transition: opacity var(--d-dur-1) var(--d-ease);
}

/* Over the paper room. The bar is fixed and the ground changes under it, so it
   re-inks rather than staying the dark room's colour on a near-white page.
   motion.js sets the class the moment the paper reaches the bar. */
.site-head.is-on-paper {
	--d-text: var(--d-paper-ink);
	--d-quiet: rgb(22 23 26 / 0.66);
	--d-faint: rgb(22 23 26 / 0.62);
	--d-rule: rgb(22 23 26 / 0.14);
	--d-rule-soft: rgb(22 23 26 / 0.07);
	--d-raise: #dfe3ea;
	--d-white: #ffffff;
	color: var(--d-paper-ink);
}

.site-head.is-on-paper .site-name,
.site-head.is-on-paper .site-capsule__trigger {
	color: var(--d-paper-ink);
}

.site-head.is-on-paper .site-capsule,
.site-head.is-on-paper .site-menu {
	background: rgb(255 255 255 / 0.58);
}

.site-head.is-on-paper .site-menu {
	box-shadow: 0 18px 50px rgb(22 23 26 / 0.14);
}

/* The colour is the only thing that changes, and it changes over the same beat
   as the section arriving underneath. */
.site-head,
.site-name,
.site-capsule,
.site-capsule__trigger {
	transition:
		color var(--d-dur-2) var(--d-ease),
		background-color var(--d-dur-2) var(--d-ease),
		border-color var(--d-dur-2) var(--d-ease);
}

.site-name svg {
	inline-size: 100%;
	block-size: auto;
}

.site-name:hover {
	opacity: 0.72;
}

/* ------------------------------------------------------------ the capsule */

/* Proportioned off midu.design's own bar rather than guessed at. The numbers
   that matter and that this had wrong: a capsule tall enough to be a surface
   (56px, not 34), a radius that reads as a capsule at that height (20px), a
   label at reading size (16px, not 13), and real air inside it. Small and
   tight looked like a browser control; this looks like part of the page.

   The radius is a deliberate exception to --athar-radius: 0. Everything this
   site draws is square because the wordmark and the mark are. This one thing
   is not, because a capsule is the shape the whole interaction is named after,
   and a square one is just a box. */
.site-capsule {
	justify-self: end;
	inline-size: max-content;
	max-inline-size: 100%;
	/* No outline at all. It reads as a pane because of the blur behind it and
	   the ground on it — a hairline around that is the same faint grey line
	   this site has just taken out of every other place it appeared. */
	border: 0;
	border-radius: 20px;
	/* Translucent, not tinted-opaque. The blur is what makes it a pane of glass
	   over the page rather than a dark rectangle on it, and at 0.9 alpha there
	   is nothing left behind it to blur. */
	background: rgb(20 20 22 / 0.55);
	-webkit-backdrop-filter: blur(26px) saturate(1.5);
	backdrop-filter: blur(26px) saturate(1.5);
	/* Not clipped, and its width no longer moves. The panel hangs below it as
	   its own pane rather than growing inside it — see the note on .site-menu. */
	position: relative;
	transition:
		background-color var(--d-dur-2) var(--d-ease),
		box-shadow var(--d-dur-2) var(--d-ease);
}

/* It rests at the width of its own contents and opens to a panel. The growth
   is the interaction — a capsule that is already panel-width has nothing to
   do when you press it. */
/* The bar does not change size when the menu opens. It used to widen to hold
   a panel that grew inside it, and that widening was half the judder — the
   panel below is its own pane now and the bar has nothing to make room for. */
.site-capsule[data-open] {
	background: rgb(20 20 22 / 0.62);
}

.site-capsule__bar {
	display: flex;
	align-items: center;
	gap: 1rem;
	block-size: 56px;
	padding-inline: 18px 20px;
}

.site-capsule__trigger {
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
	flex: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	color: var(--d-text);
	font-family: var(--d-font);
	cursor: pointer;
}

/* Six dots in two columns, which is the reference's own control, and turns
   forty-five degrees when the menu is open. */
.site-capsule__grid {
	display: grid;
	grid-template-columns: repeat(2, 3px);
	gap: 3px;
	flex: none;
	transition: transform var(--d-dur-2) var(--d-spring);
}

.site-capsule__grid i {
	inline-size: 3px;
	block-size: 3px;
	border-radius: 50%;
	background: currentColor;
	opacity: 0.55;
	transition: opacity var(--d-dur-1) var(--d-ease);
}

.site-capsule__trigger:hover .site-capsule__grid i,
.site-capsule__trigger:focus-visible .site-capsule__grid i {
	opacity: 1;
}

.site-capsule[data-open] .site-capsule__grid {
	transform: rotate(45deg);
}

/* Two rolls, nested, on the one control.
   The outer one is state — القائمة when closed, إغلاق when open.
   The inner one is this site's convention — Arabic, and English on hover.
   Both are one-line windows, so they compose without knowing about each other.

   Every height here is --roll-h and not an em. The two languages are set at
   different sizes, and a window measured in ems is a different height for each
   of them — which puts the second line half in view before anyone hovers. */
.site-capsule__roll {
	--roll-h: 1.5rem;
	display: block;
	overflow: hidden;
	block-size: var(--roll-h);
}

.site-capsule__word {
	display: block;
	overflow: hidden;
	block-size: var(--roll-h);
	transition: transform var(--d-dur-2) var(--d-spring);
}

.site-capsule[data-open] .site-capsule__word {
	transform: translateY(-100%);
}

.site-capsule__word > span {
	display: flex;
	align-items: center;
	block-size: var(--roll-h);
	font-size: 1rem;
	color: var(--d-text);
	transition: transform var(--d-dur-2) var(--d-spring);
}

.site-capsule__word > .nav-en {
	font-family: var(--d-mono);
	font-size: var(--d-t-small);
	letter-spacing: var(--d-track-meta);
	text-transform: uppercase;
	direction: ltr;
}

.site-capsule__trigger:hover .site-capsule__word > span,
.site-capsule__trigger:focus-visible .site-capsule__word > span {
	transform: translateY(-100%);
}

/* Arabic, so no tracking and no mono — the stack would drop it to whatever the
   system keeps for Arabic and the line would arrive in a different typeface
   from everything around it. */
.site-capsule__status {
	margin: 0;
	margin-inline-start: auto;
	padding-inline-start: 1rem;
	font-family: var(--d-font);
	font-size: var(--d-t-small);
	line-height: 1.4;
	color: rgb(255 255 255 / 0.55);
	white-space: nowrap;
}

/* ------------------------------------------------------------- the menu */

/* Open by default and closed only once the script says so, for the same reason
   .reveal is: a stylesheet that collapses the navigation is a site with no
   navigation whenever this file arrives and motion.js does not. */
/* The panel is its own pane, hanging under the bar rather than growing inside
   it. That is the whole fix for the judder Saad called a glitch.

   It used to open by animating `grid-template-rows` and `inline-size` together,
   inside a capsule that was itself animating its width to follow — three
   layout animations racing each other on every frame. Layout animation is
   expensive and, worse, it is not smooth: the browser re-measures and re-wraps
   the text inside on every step, so the rows twitch as they arrive.

   Nothing here animates layout. Opacity and transform only, which the
   compositor can run without touching layout at all, and the capsule's own
   width never changes so there is nothing left to race. */
.has-menu .site-menu {
	position: absolute;
	inset-block-start: calc(100% + 0.55rem);
	inset-inline-end: 0;
	inline-size: min(21rem, calc(100vw - (var(--d-gutter) * 2)));
	border-radius: 20px;
	background: rgb(20 20 22 / 0.55);
	-webkit-backdrop-filter: blur(26px) saturate(1.5);
	backdrop-filter: blur(26px) saturate(1.5);
	box-shadow: 0 18px 50px rgb(0 0 0 / 0.34);

	opacity: 0;
	visibility: hidden;
	transform: translateY(-0.6rem) scale(0.975);
	transform-origin: 100% 0;
	pointer-events: none;
	transition:
		opacity var(--d-dur-2) var(--d-ease),
		transform var(--d-dur-2) var(--d-spring),
		visibility 0s linear var(--d-dur-2);
}

[dir="ltr"] .has-menu .site-menu {
	transform-origin: 0 0;
}

.has-menu .site-capsule[data-open] .site-menu {
	opacity: 1;
	visibility: visible;
	transform: none;
	pointer-events: auto;
	transition:
		opacity var(--d-dur-1) var(--d-ease),
		transform var(--d-dur-2) var(--d-spring),
		visibility 0s;
}

/* The rows arrive one after another rather than all together. Cheap — a delay
   on a transform that was going to run anyway — and it is the difference
   between a panel appearing and a panel opening. */
.has-menu .site-menu__list li {
	opacity: 0;
	transform: translateY(-0.4rem);
	transition:
		opacity var(--d-dur-2) var(--d-ease),
		transform var(--d-dur-2) var(--d-spring);
}

.has-menu .site-capsule[data-open] .site-menu__list li {
	opacity: 1;
	transform: none;
}

.has-menu .site-capsule[data-open] .site-menu__list li:nth-child(1) { transition-delay: 40ms; }
.has-menu .site-capsule[data-open] .site-menu__list li:nth-child(2) { transition-delay: 80ms; }
.has-menu .site-capsule[data-open] .site-menu__list li:nth-child(3) { transition-delay: 120ms; }
.has-menu .site-capsule[data-open] .site-menu__list li:nth-child(4) { transition-delay: 160ms; }
.has-menu .site-capsule[data-open] .site-menu__list li:nth-child(5) { transition-delay: 200ms; }

@media (prefers-reduced-motion: reduce) {
	.has-menu .site-menu,
	.has-menu .site-menu__list li {
		transition: opacity var(--d-dur-1) var(--d-ease), visibility 0s;
		transform: none;
	}
}

.site-menu__list {
	margin: 0;
	padding: 10px 20px 14px;
	list-style: none;
}

/* No rule between the rows either. The reference has one; this site is not to
   have any faint grey line anywhere, and the rows are far enough apart to read
   as separate without one. */
.site-menu__list li + li {
	padding-block-start: 0.15rem;
}

/* Generous, like the reference's — its rows are a hundred pixels tall. A menu
   that opens into a tight little list reads as a dropdown; this reads as a
   place you have arrived at. */
.site-menu__list a {
	--roll-h: 1.85rem;
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block: 0.7rem;
	text-decoration: none;
	color: rgb(255 255 255 / 0.62);
	transition: color var(--d-dur-1) var(--d-ease);
}

.nav-roll {
	display: block;
	overflow: hidden;
	block-size: var(--roll-h);
	min-inline-size: 0;
}

.site-menu__list .nav-roll > span {
	display: flex;
	align-items: center;
	block-size: var(--roll-h);
	font-size: 1.35rem;
	white-space: nowrap;
	transition: transform var(--d-dur-2) var(--d-spring);
}

.site-menu__list .nav-roll > .nav-en {
	font-family: var(--d-mono);
	font-size: var(--d-t-small);
	letter-spacing: var(--d-track-meta);
	text-transform: uppercase;
	direction: ltr;
}

.site-menu__list a:hover,
.site-menu__list a:focus-visible,
.site-menu__list .current-menu-item > a {
	color: var(--d-text);
}

.site-menu__list a:hover .nav-roll > span,
.site-menu__list a:focus-visible .nav-roll > span {
	transform: translateY(-100%);
}

/* The picture for the row. It sits quiet until the row is pointed at, then
   lifts — the same bargain the rest of the site makes with its second
   language: there, but only when asked for. */
.nav-thumb {
	flex: none;
	display: block;
	inline-size: 3.6rem;
	block-size: 2.6rem;
	border-radius: 8px;
	overflow: hidden;
	background: rgb(255 255 255 / 0.05);
	opacity: 0.5;
	transform: scale(0.94);
	transition:
		opacity var(--d-dur-2) var(--d-ease),
		transform var(--d-dur-2) var(--d-spring);
}

.nav-thumb__img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	display: block;
	filter: var(--d-photo);
}

.site-menu__list a:hover .nav-thumb,
.site-menu__list a:focus-visible .nav-thumb {
	opacity: 1;
	transform: none;
}

/* The light that runs in from the reading edge under a hovered row. Logical,
   so it enters from the right in Arabic and the left in English. */
.site-menu__list a::before {
	content: "";
	position: absolute;
	inset: 0 -20px;
	background: linear-gradient(to left,
		rgb(255 255 255 / 0.08) 0%,
		transparent 64%);
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--d-dur-1) var(--d-ease);
}

.site-menu__list a:hover::before,
.site-menu__list a:focus-visible::before {
	opacity: 1;
}

:where([dir="ltr"]) .site-menu__list a::before {
	background: linear-gradient(to right,
		rgb(255 255 255 / 0.08) 0%,
		transparent 64%);
}

/* ---------------------------------------------------------- the bottom edge */

/* Progressive blur: panes that each blur more than the last and each fade out
   higher up, so what is behind them softens toward the edge of the screen
   rather than hitting a line where a blur starts. One pane cannot do this — a
   single backdrop-filter has one radius, and a masked one just fades a uniform
   blur in, which reads as a smudge.

   Three panes, not the six this started with. Each one is a full-width backdrop
   snapshot that the compositor re-blurs on every scrolled frame, and six of
   them — over a live shader — was enough to make scrolling stutter on this
   page. Three reads the same and costs half. If this ever needs to be cheaper
   still, the next thing to go is the 14px radius, not another pane: the ramp is
   what makes it progressive. */
.edge-blur {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;
	block-size: clamp(3rem, 5vh, 4.5rem);
	z-index: 800;
	pointer-events: none;
}

.edge-blur i {
	position: absolute;
	inset: 0;
	display: block;
}

.edge-blur i:nth-child(1) {
	-webkit-backdrop-filter: blur(1.5px);
	backdrop-filter: blur(1.5px);
	-webkit-mask-image: linear-gradient(to top, #000 0%, transparent 100%);
	mask-image: linear-gradient(to top, #000 0%, transparent 100%);
}

.edge-blur i:nth-child(2) {
	-webkit-backdrop-filter: blur(5px);
	backdrop-filter: blur(5px);
	-webkit-mask-image: linear-gradient(to top, #000 0%, transparent 58%);
	mask-image: linear-gradient(to top, #000 0%, transparent 58%);
}

.edge-blur i:nth-child(3) {
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
	-webkit-mask-image: linear-gradient(to top, #000 0%, transparent 26%);
	mask-image: linear-gradient(to top, #000 0%, transparent 26%);
}

.edge-blur i:nth-child(n + 4) {
	display: none;
}

/* The same lens at the top edge, and the reason it is a separate element rather
   than a modifier is that it has to sit *under* the bar: z-index 800 against
   the header's 900, so the name and the capsule stay sharp and everything
   scrolling up behind them goes soft.

   It is not there at rest. At the top of the page there is nothing above the
   fold to blur, and a permanent haze under a fixed bar reads as a smudge on the
   screen; .is-settled is already set by motion.js the moment the page leaves
   the top, so it costs nothing to ask for. */
.edge-blur--top {
	inset-block: 0 auto;
	block-size: clamp(3.5rem, 7vh, 6rem);
	opacity: 0;
	transition: opacity var(--d-dur-2) var(--d-ease);
}

.site-head.is-settled ~ .edge-blur--top,
body:has(.site-head.is-settled) .edge-blur--top {
	opacity: 1;
}

.edge-blur--top i:nth-child(1) {
	-webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
	mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
}

.edge-blur--top i:nth-child(2) {
	-webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 58%);
	mask-image: linear-gradient(to bottom, #000 0%, transparent 58%);
}

.edge-blur--top i:nth-child(3) {
	-webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 26%);
	mask-image: linear-gradient(to bottom, #000 0%, transparent 26%);
}

@media (prefers-reduced-motion: reduce) {
	.edge-blur {
		display: none;
	}
}

/* --------------------------------------------------------------- the pill */

/* One button shape, used three times: the header corner, the opening screen,
   and the foot. */
.d-pill {
	--roll-h: 1.25rem;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.62rem 1.05rem;
	border: 1px solid transparent;
	border-radius: 1.4rem;
	font-family: var(--d-font);
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	transition:
		background-color var(--d-dur-1) var(--d-ease),
		border-color var(--d-dur-1) var(--d-ease),
		color var(--d-dur-1) var(--d-ease);
}

/* White at rest and a shade off it on hover, which is the way round the
   reference does it. --d-text is the colour of *text* on this ground and reads
   grey as a fill; a button that is meant to be the brightest thing on the
   screen should be white. */
.d-pill--solid {
	background: var(--d-white);
	color: var(--d-void);
}

.d-pill--solid:hover,
.d-pill--solid:focus-visible {
	background: var(--d-text);
}

/* The one that carries a section rather than sitting in a corner. */
.d-pill--lg {
	--roll-h: 1.5rem;
	padding: 0.95rem 1.65rem;
	border-radius: 2rem;
	gap: 0.65rem;
}

.d-pill--lg .d-pill__label > span {
	font-size: 1rem;
}

.d-pill--lg .d-pill__label > .nav-en {
	font-size: var(--d-t-small);
}

.d-pill--lg .d-pill__star {
	inline-size: 0.92rem;
	block-size: 0.92rem;
}

.d-pill--ghost {
	border-color: var(--d-rule);
	color: var(--d-text);
	background: color-mix(in srgb, var(--d-raise) 60%, transparent);
	backdrop-filter: blur(10px);
}

.d-pill--ghost:hover,
.d-pill--ghost:focus-visible {
	border-color: color-mix(in srgb, var(--d-text) 26%, transparent);
}

/* A quarter turn on a four-pointed star lands the star back on itself and
   nothing appears to happen. Forty-five degrees is the turn that shows. */
.d-pill__star {
	inline-size: 0.72rem;
	block-size: 0.72rem;
	flex: none;
	transition: transform var(--d-dur-2) var(--d-spring);
}

.d-pill:hover .d-pill__star,
.d-pill:focus-visible .d-pill__star {
	transform: rotate(45deg) scale(1.14);
}

.d-pill__label {
	display: block;
	overflow: hidden;
	block-size: var(--roll-h);
}

.d-pill__label > span {
	display: flex;
	align-items: center;
	block-size: var(--roll-h);
	font-size: 0.875rem;
	transition: transform var(--d-dur-2) var(--d-spring);
}

.d-pill__label > .nav-en {
	font-family: var(--d-mono);
	font-size: var(--d-t-meta);
	letter-spacing: var(--d-track-meta);
	text-transform: uppercase;
	direction: ltr;
}

/* :not(:only-child) is load-bearing. Some of these buttons carry a label the
   editor typed, which is one span and has nothing to roll to — without this it
   would roll out of the window on hover and leave an empty button. */
.d-pill:hover .d-pill__label > .nav-ar:not(:only-child),
.d-pill:focus-visible .d-pill__label > .nav-ar:not(:only-child),
.d-pill:hover .d-pill__label > .nav-en,
.d-pill:focus-visible .d-pill__label > .nav-en {
	transform: translateY(-100%);
}

@media (prefers-reduced-motion: reduce) {
	.site-capsule__word,
	.site-capsule__word > span,
	.site-menu__list .nav-roll > span,
	.nav-thumb,
	.site-capsule,
	.d-pill__label > span,
	.d-pill__star,
	.has-menu .site-menu {
		transition: none;
	}
}

/* Under about a phone and a half the capsule cannot hold both the control and
   the availability line, and the three zones cannot hold the capsule between
   them. The name and the button keep their corners; the capsule drops to the
   row beneath and takes the full width. */
/* On a phone the capsule keeps its corner — there are only two things up here
   and they both fit. What goes is the availability line, which is the one part
   that cannot be shortened without becoming a riddle. */
@media (max-width: 40em) {
	.site-capsule__status {
		display: none;
	}

	.site-capsule[data-open] {
		inline-size: min(17rem, 100%);
	}
}

.site-main {
	display: block;
	min-block-size: 60vh;
}

.site-main:focus {
	outline: none;
}

/* The foot answers the opening screen: the hour, the sentence, the ask, and
   the wordmark standing on the floor and cut by it. The padding at the bottom
   is the room the wordmark stands in — take it away and the last row of links
   sits inside the letters. */
.site-foot {
	position: relative;
	/* The same darker room the sheet above it lays down, or the page would
	   lighten again at the very bottom for no reason a reader could name. */
	background-color: var(--d-ground);
	margin-block-start: var(--d-rhythm);
	padding-block: var(--d-rhythm) clamp(8rem, 20vw, 17rem);
	overflow: clip;
	isolation: isolate;
}

/* The blue horizon from references/Asset 15, once, at the bottom of the
   document. It is the last thing the page says. */
.site-foot::before {
	content: "";
	position: absolute;
	inset-block-end: -30%;
	inset-inline: -10%;
	block-size: 70%;
	background: var(--d-bloom);
	opacity: 0.42;
	filter: blur(30px);
	pointer-events: none;
}

.site-foot > * {
	position: relative;
	z-index: 1;
}

/* The wordmark, in the same three stops as the wave and with the same mask.
   It is taller than the space under it and pushed further down still, so the
   floor of the document cuts it — a wordmark that fits is a logo at the bottom
   of a page, which is a different and much smaller idea. */
.foot-word {
	position: absolute;
	z-index: 0;
	inset-inline: var(--d-gutter);
	inset-block-end: 0;
	block-size: min(34svh, 27vw);
	background: linear-gradient(to top,
		var(--d-wave-lift) 0%,
		var(--d-wave-core) 46%,
		color-mix(in srgb, var(--d-wave-dark) 88%, transparent) 82%,
		transparent 100%);
	-webkit-mask-image: url("assets/img/logo.svg");
	mask-image: url("assets/img/logo.svg");
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center top;
	mask-position: center top;
	-webkit-mask-size: auto 130%;
	mask-size: auto 130%;
	opacity: 0.9;
	pointer-events: none;
}

.foot-top {
	display: grid;
	gap: var(--d-rhythm-tight) var(--d-gutter);
	grid-template-columns: 1fr;
}

@media (min-width: 52em) {
	.foot-top {
		grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
		align-items: start;
	}
}

.foot-say {
	display: grid;
	justify-items: start;
	gap: clamp(0.9rem, 2vw, 1.4rem);
}

.foot-clock {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	margin: 0;
}

.foot-clock time,
.foot-clock__place {
	font-family: var(--d-mono);
	font-size: var(--d-t-meta);
	letter-spacing: var(--d-track-meta);
	color: var(--d-quiet);
	direction: ltr;
}

.foot-clock__dot {
	inline-size: 0.4rem;
	block-size: 0.4rem;
	flex: none;
	border-radius: 50%;
	background: var(--d-glow);
}

@media (prefers-reduced-motion: no-preference) {
	.foot-clock__dot {
		animation: delma-tick 2.6s var(--d-ease-io) infinite;
	}
}

@keyframes delma-tick {
	0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--d-glow) 55%, transparent); }
	60%      { opacity: 0.55; box-shadow: 0 0 0 0.32rem color-mix(in srgb, var(--d-glow) 0%, transparent); }
}

.foot-line {
	margin: 0;
	font-size: var(--d-t-h2);
	line-height: var(--d-lh-head);
	color: var(--d-text);
	/* ch is measured on this element's own font size, so a bare 28ch here is
	   wider than a phone. */
	max-inline-size: min(100%, 28ch);
}

.foot-cols {
	display: grid;
	gap: var(--d-rhythm-tight) var(--d-gutter);
	grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
}

.foot-label {
	margin: 0 0 0.9rem;
	color: var(--d-faint);
}

.foot-label span {
	font-family: var(--d-mono);
	letter-spacing: var(--d-track-meta);
	text-transform: uppercase;
}

.foot-list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: 0.55em;
}

.foot-list a {
	display: inline-flex;
	align-items: baseline;
	gap: 0.6em;
	text-decoration: none;
	color: var(--d-quiet);
	transition: color var(--d-dur-1) var(--d-ease);
}

/* The header hides this half until hover; the foot shows both at once, so it
   needs the gap and the quieter weight the header never had to give it.
   Without them the two languages ran together into one word. */
.foot-list .nav-en {
	font-family: var(--d-mono);
	font-size: var(--d-t-meta);
	letter-spacing: var(--d-track-meta);
	text-transform: uppercase;
	color: var(--d-faint);
}

.foot-list--plain a {
	font-family: var(--d-mono);
	font-size: var(--d-t-small);
}

.foot-list a:hover,
.foot-list a:focus-visible {
	color: var(--d-text);
}

.foot-base {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem var(--d-gutter);
	justify-content: space-between;
	align-items: center;
	margin-block-start: var(--d-rhythm);
	padding-block-start: 1.25rem;
}

/* ================================================================== motion

   Reveals are declared here and driven either by scroll-linked animation
   where the browser has it, or by a class that motion.js sets. Both land on
   the same two custom properties, so there is one visual definition of a
   reveal and two ways of triggering it.
   ======================================================================== */

@media (prefers-reduced-motion: no-preference) {
	/* .has-reveal is set by motion.js, so nothing is ever hidden by a
	   stylesheet that arrived without the script that un-hides it. */
	.has-reveal .reveal {
		--reveal-y: 1.6rem;
		--reveal-blur: 6px;
		opacity: 0;
		transform: translate3d(0, var(--reveal-y), 0);
		filter: blur(var(--reveal-blur));
		/* translate is in this list and is not part of the reveal.

		   A revealed element owns its own `transform` — the rule below sets it
		   to none on arrival — so anything that wants to move it afterwards, a
		   hover lift for instance, has to use the separate `translate` property
		   or be silently overruled. It only animates if it is declared here,
		   because this rule out-specifies the component's own. */
		transition:
			opacity var(--d-dur-3) var(--d-ease),
			transform var(--d-dur-3) var(--d-ease),
			filter var(--d-dur-3) var(--d-ease),
			translate var(--d-dur-3) var(--d-spring);
		transition-delay: var(--reveal-delay, 0ms);
	}

	.has-reveal .reveal.is-in {
		opacity: 1;
		transform: none;
		filter: none;
	}

	/* Media arrives from a little further and a little softer. */
	.has-reveal .reveal--media {
		--reveal-y: 2.5rem;
		--reveal-blur: 12px;
	}
}

/* Print gets the page, not the animation's starting position. */
@media print {
	.reveal {
		opacity: 1 !important;
		transform: none !important;
		filter: none !important;
	}

	.grain,
	.edge-blur,
	.site-head {
		display: none;
	}
}
