/**
 * COMPONENTS — لمبة.
 *
 * Everything this site draws that base.css does not: the frame's header and
 * footer, the gate and its four ignition mechanics, and Athar's shipped
 * sections dressed in this identity.
 *
 * Nothing here names a colour or a size directly; identity.css owns those.
 * Nothing here is defined in base.css as well: the two files are disjoint on
 * purpose, and tools/css-check.cjs in the plugin fails the build if they stop
 * being.
 */

/* ================================================================== header

   A capsule, not a bar. Saad picked the shape at fixaplan.com: a small panel
   floating at the top centre with the brand and a burger in it, and a second
   panel below it, holding the links, that opens out of a single point.

   What was taken is that shape and that gesture. The rest is this identity's:
   solid rather than glass, because there is no glass anywhere here; dark
   rather than white; and the point the menu opens out of is the filament's
   own yellow, so opening the menu is the gesture the whole site is about.
   Their two burger bars close onto each other into a single line rather than
   crossing into an X — that part is theirs and it is better than an X.

   It sticks rather than floats free, so the room above the page's first
   section is real space and nothing can collide with it. The second capsule
   is taken out of flow instead, which is why the header only ever reserves
   the height of the bar.

   Sits above the room (z 60) and below the gate (z 90). There is no light
   switch in here. There was one, and it is gone by request: the lamp is the
   work, not a control in the corner.
   ======================================================================= */

.site-head {
	/* The two capsules and the hole between them are one component, so it
	   keeps its own three numbers rather than borrowing tokens that mean
	   something else elsewhere. */
	--head-lift: clamp(0.75rem, 1.6vw, 1.4rem);
	--head-gap: 0.55rem;
	--head-dot: 4px;

	position: sticky;
	inset-block-start: 0;
	z-index: 70;

	/* Padding, not margin: a top margin here collapses through the body and
	   takes the header with it. This way the lift is inside the sticky box
	   and survives being stuck. */
	padding-block-start: var(--head-lift);

	/* Closed, the second capsule is still a point of light below the bar, and
	   it is out of flow. This is the room that point needs. A margin and not
	   padding this time: the panel is placed at 100% of the padding box, so
	   padding here would push it away from the bar it belongs to. */
	margin-block-end: calc(var(--head-gap) + 4 * var(--head-dot));

	display: flex;
	flex-direction: column;
	align-items: center;

	/* The strip of nothing between the two capsules is still part of this
	   box, and the page underneath has to stay clickable through it. Each
	   capsule takes the pointer back for itself. */
	pointer-events: none;

	/* It arrives, and no script is involved: `both` holds the from-state
	   through the delay, so the served page drops it in on its own. Under
	   reduced motion base.css collapses the duration and it is simply there. */
	animation: lamba-drop var(--l-dur-3) var(--l-ease) 220ms both;
}

/* Signed in, the admin bar is fixed across the top of the viewport and a
   sticky header knows nothing about it. Both numbers, and the breakpoint, are
   core's rather than this site's. */
.admin-bar .site-head {
	inset-block-start: 32px;
}

@media (max-width: 782px) {
	.admin-bar .site-head {
		inset-block-start: 46px;
	}
}

@keyframes lamba-drop {
	from {
		translate: 0 -100%;
		opacity: 0;
	}
}

.site-head__bar {
	pointer-events: auto;
	display: flex;
	align-items: center;
	/* Theirs is 52px between the wordmark and the burger. The capsule is its
	   content either way, so this is the only number setting how wide it
	   reads. */
	gap: clamp(1.1rem, 3.5vw, 3.25rem);
	padding-block: 0.45rem;
	padding-inline: 0.95rem 0.55rem;
	border: 1px solid var(--l-rule);
	border-radius: var(--l-radius);
	background: var(--l-raise);
	box-shadow: 0 16px 40px -24px var(--l-black);
}

.site-name {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 0.55rem;
	text-decoration: none;
}

.site-name__mark {
	flex: 0 0 auto;
	/* The artwork is half again as tall as it is wide, and it is what sets
	   the height of the whole capsule. */
	inline-size: clamp(1.3rem, 1.8vw, 1.6rem);
}

/* Their drawn word. Sized by height, because the two lockups are different
   shapes: the Arabic word is short and wide at 2.9:1, LAMPAAH is a caps line
   at 6:1, and a single width would set one of them wrong. */
.site-name__word {
	flex: 0 0 auto;
	inline-size: auto;
	block-size: clamp(0.95rem, 1.3vw, 1.15rem);
}

.site-name__word.lamba-word--en {
	block-size: clamp(0.62rem, 0.85vw, 0.75rem);
}

.site-head__tools {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 0.35rem;
}

/* ---------------------------------------------------------- the language

   Athar prints both languages and marks the current one. In a capsule this
   size two whole words is most of the width, so only the language you are
   not reading is shown: the chip becomes a switch, which is what a reader
   wants from it anyway, and the page already says which language it is in. */

.site-head .athar-langs {
	display: flex;
	align-items: center;
}

.site-head .athar-langs__item {
	padding-block: 0.5em;
	padding-inline: 0.7em;
	border-radius: var(--l-radius-pill);
	color: var(--l-faint);
	font-size: var(--l-t-meta);
	letter-spacing: var(--l-track-meta);
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--l-dur-1) var(--l-ease);
}

.site-head .athar-langs__item:hover,
.site-head .athar-langs__item:focus-visible {
	color: var(--l-text);
}

.site-head .athar-langs__item.is-current {
	display: none;
}

/* ------------------------------------------------------------- the burger */

.site-burger {
	position: relative;
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	inline-size: 2.35rem;
	block-size: 2.35rem;
	padding: 0;
	border: 0;
	border-radius: var(--l-radius-pill);
	background: none;
	color: var(--l-text);
	cursor: pointer;
}

/* With no script the menu never closes, so the control that would do nothing
   is never shown. header.php prints the one statement that adds .is-ready. */
.site-head:not(.is-ready) .site-burger {
	display: none;
}

.site-burger__bars {
	position: relative;
	display: block;
	inline-size: 17px;
	block-size: 13px;
}

.site-burger__bars > span {
	position: absolute;
	inset-inline: 0;
	block-size: 2px;
	border-radius: 2px;
	background: currentColor;
	transition:
		translate var(--l-dur-1) var(--l-ease),
		background-color var(--l-dur-1) var(--l-ease);
}

.site-burger__bars > span:first-child {
	inset-block-start: 0;
}

.site-burger__bars > span:last-child {
	inset-block-end: 0;
}

/* Open, the two bars land on each other and become one lit line. */
.site-head.is-open .site-burger__bars > span {
	background: var(--l-yellow);
}

.site-head.is-open .site-burger__bars > span:first-child {
	translate: 0 5.5px;
}

.site-head.is-open .site-burger__bars > span:last-child {
	translate: 0 -5.5px;
}

.site-burger__label {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

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

   Out of flow, so the header reserves the bar's height and not this one's,
   and centred with auto margins rather than a translate — a translate is
   physical, and half the time this site is read right to left.

   What is declared here is the open state, because open is what the server
   sends: a reader with no JavaScript gets every link, in a panel, reachable.
   Only once the one line in header.php has run does .is-ready close it.
   ======================================================================= */

.site-menu {
	position: absolute;
	inset-block-start: calc(100% + var(--head-gap));
	inset-inline: 0;
	margin-inline: auto;
	inline-size: max-content;
	min-inline-size: 12rem;
	max-inline-size: min(92vw, var(--l-col));
	pointer-events: auto;
	padding: 4px;
	border: 1px solid var(--l-rule);
	border-radius: var(--l-radius);
	background: var(--l-raise);
	box-shadow: 0 16px 40px -24px var(--l-black);

	/* The bloom. Closed, all that is left of the panel is a point of the
	   filament's yellow under the bar; opening grows that point out into the
	   panel and the yellow cools to the raised grey. One circle, two radii,
	   and nothing distorts on the way — scaling the panel would stretch the
	   words inside it, which is what makes that trick read as an effect. */
	clip-path: circle(900px at 50% var(--head-dot));
	transition:
		clip-path var(--l-dur-2) var(--l-ease),
		background-color var(--l-dur-2) var(--l-ease),
		border-color var(--l-dur-2) var(--l-ease);
}

.site-head.is-ready .site-menu {
	clip-path: circle(var(--head-dot) at 50% var(--head-dot));
	background: var(--l-yellow);
	border-color: transparent;
	pointer-events: none;
}

.site-head.is-ready.is-open .site-menu {
	clip-path: circle(900px at 50% var(--head-dot));
	background: var(--l-raise);
	border-color: var(--l-rule);
	pointer-events: auto;
}

.site-menu__list {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--l-t-small);
}

/* Hidden, not merely transparent: a link that cannot be seen must not be able
   to take the keyboard either. Visibility waits out the panel closing; on the
   way open it returns at once and the words fade in behind the panel. */
.site-head.is-ready .site-menu__list {
	opacity: 0;
	visibility: hidden;
	transition:
		opacity var(--l-dur-1) var(--l-ease),
		visibility 0s linear var(--l-dur-2);
}

.site-head.is-ready.is-open .site-menu__list {
	opacity: 1;
	visibility: visible;
	transition:
		opacity var(--l-dur-1) var(--l-ease) 140ms,
		visibility 0s;
}

.site-menu__list a {
	display: block;
	padding-block: 0.6rem;
	padding-inline: 1.1rem;
	border-radius: var(--l-radius-pill);
	color: var(--l-quiet);
	text-decoration: none;
	white-space: nowrap;
	transition:
		color var(--l-dur-1) var(--l-ease),
		background-color var(--l-dur-1) var(--l-ease);
}

.site-menu__list a:hover,
.site-menu__list a:focus-visible {
	color: var(--l-text);
	background: var(--l-raise-2);
}

.site-menu__list .current-menu-item > a,
.site-menu__list .current_page_item > a {
	color: var(--l-yellow);
}

/* A row of chips wants the width of every label at once, which a phone does
   not have. Below this the panel is a column and loses the pill. */
@media (min-width: 48rem) {
	.site-menu {
		border-radius: var(--l-radius-pill);
	}

	.site-menu__list {
		flex-direction: row;
		align-items: center;
	}
}

/* ============================================================== foot menu */

.foot-nav__list {
	display: flex;
	flex-wrap: wrap;
	gap: clamp(0.9rem, 2.2vw, 1.9rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* ==================================================================== mark

   Their symbol: a head in profile with a filament burning inside it. The head
   takes the page's text colour, so on this ground the artwork's black reads
   white; the filament keeps the brand yellow exactly.

   The glow is three copies of the filament path — wide amber blur, tight
   yellow blur, sharp shape — so every part of the light is the shape of the
   thing emitting it. That is what stops it reading as layers.
   ======================================================================= */

.lamba-mark {
	display: block;
	block-size: auto;
	overflow: visible;
}

.lamba-mark__body path {
	fill: var(--l-text);
}

.lamba-mark__fil {
	fill: var(--l-yellow);
}

.lamba-mark__wide path {
	fill: #ffb020;
}

.lamba-mark__tight path {
	fill: var(--l-yellow);
}

.lamba-mark__wide {
	opacity: 0.5;
	filter: url("#lamba-glow-wide");
}

.lamba-mark__tight {
	opacity: 0.8;
	filter: url("#lamba-glow-tight");
}

/* The hot core. A 1.5px shadow on a 196-character path costs nothing and is
   the difference between a yellow shape and a lit filament. */
.lamba-mark--lit .lamba-mark__fil {
	filter: drop-shadow(0 0 1.5px #ffe98a);
}

/* Only the outermost halo moves, and only its opacity, so it never leaves the
   compositor. A filament is never perfectly steady. */
.lamba-mark--lit .lamba-mark__wide {
	animation: lamba-breathe 7s ease-in-out infinite;
}

@keyframes lamba-breathe {
	0%, 100% { opacity: 0.5; }
	50% { opacity: 0.36; }
}

/* The word, split out of their stacked lockup. One colour and it is
   currentColor, so it inverts with whatever surface it lands on and there is
   nothing to keep in step by hand. */
.lamba-word {
	display: block;
	fill: currentColor;
	overflow: visible;
}

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

   The fixed layer inc/scenes.php prints, and the scenes stacked inside it.
   lamp.js decides which one is on; everything else about it is here.

   z-index -1, and the body's own background taken away for it. html keeps the
   room colour so the canvas is still ink, this layer paints over the canvas,
   and every line of the page paints over this. Put the layer at 0 instead and
   the body's background — which paints after negative layers, not before —
   would sit on top of it and nothing would ever be seen.

   The room (z 60) and the grain (z 96) still fall on top of all of it, which
   is right: the dark falls on the ground too, and the grain is the air in the
   room rather than a texture on the picture.
   ======================================================================= */

body {
	/* Taken away, not changed: see above. html still carries the room. */
	background: transparent;
}

.lamp-ground {
	position: fixed;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	overflow: clip;
}

.lamp-ground__scene {
	position: absolute;
	inset: 0;
	background: var(--ground-color, var(--l-ground));
	opacity: 0;
}

/* No transition on this line, and that is the whole point. A crossfade here
   would be a dissolve between two rooms; a light switch does not dissolve. */
.lamp-ground__scene.is-on {
	opacity: 1;
}

.lamp-ground__media {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	/* Their work is video, and stills pulled from video swing wildly in
	   temperature. This keeps every ground in the same room as the site. */
	filter: var(--l-photo);
}

/* The veil that keeps a line readable over a picture. Its own layer rather
   than a shadow on the words: a text-shadow under Arabic at this size fills
   the joins between letters and turns the line to mud. */
.lamp-ground__scene--image::after,
.lamp-ground__scene--video::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--l-black);
	opacity: var(--ground-dim, 0.52);
}

/* Where a video keeps its address until lamp.js decides whether to fetch it. */
.lamp-ground__src {
	display: none;
}

/* ---------------------------------------------------------------- the tone

   A pale ground, and the page's ink turns over on it.

   The brand's yellow is one of the four primaries and it is a *light* colour:
   #f6d00d carries about 65% relative luminance, so the site's near-white type
   on it is not dim, it is gone. lamp.js reads the tone the active scene
   declares and puts .lamp-pale on the root.

   Scoped to the content and not to the page, deliberately. The header capsule
   carries its own dark surface with it and reads perfectly well over yellow;
   turn its ink over too and it would be black on near-black. Chrome keeps its
   own tone, and only what sits directly on the ground follows the ground.
   ======================================================================= */

.lamp-pale .site-main,
.lamp-pale .site-foot {
	--l-text: var(--l-ink);
	--l-quiet: rgb(28 28 26 / 0.72);
	--l-faint: rgb(28 28 26 / 0.48);
	--l-rule: rgb(28 28 26 / 0.2);
	--l-rule-soft: rgb(28 28 26 / 0.1);

	/* The accent has to go too: yellow on yellow says nothing. On a pale
	   ground the ink itself is the emphasis, which is exactly how the guide
	   book uses the pair the other way round. */
	--l-yellow: var(--l-ink);

	color: var(--l-text);
}

/* The strike. A lamp catches before it holds, so the room does too: one short
   flare of the filament's colour across the whole ground at the moment it
   changes, and never a second one — this is one flash per change, well under
   the three-per-second that makes a page dangerous to look at. */
.lamp-ground::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--l-yellow);
	opacity: 0;
	mix-blend-mode: screen;
}

.lamp-ground.is-struck::after {
	animation: lamba-flare 260ms var(--l-ease-io);
}

@keyframes lamba-flare {
	0%   { opacity: 0; }
	18%  { opacity: 0.16; }
	42%  { opacity: 0.03; }
	100% { opacity: 0; }
}

/* ===================================================================== hero

   Athar's cover, which is the opening of every page on this site. Not a
   section of its own: adding one would have left an editor choosing between
   two things that mean the same, and stacked two openings on any page that
   already had a cover.

   Saad, looking at the first draft: smaller, one line, centred. So the line
   is one line by construction — nowrap, and a size that scales with the
   viewport rather than a size that wraps.

   It draws no background. Its picture, or its film, is a scene in the fixed
   layer above: that is what lets the picture hold still while these words
   scroll off it, and lets the next scene replace it in a single frame.
   ======================================================================= */

.athar-scope .lamba-hero {
	position: relative;
	display: grid;
	place-items: center;
	/* The header is in the flow above this, so a full 100svh would push the
	   fold down by its height. This lands the opening on exactly one screen,
	   with a sliver of what follows showing under it — which is the only
	   invitation to scroll that has ever really worked. */
	min-block-size: calc(100svh - 7rem);
	padding-block: var(--l-rhythm-tight);
	padding-inline: var(--l-gutter);
	text-align: center;
}

/* A flat colour opening is the style tab's own background, promoted to the
   fixed layer. It is already on screen there; painting it here as well would
   scroll a second copy of it up the page. */
.athar-scope .lamba-hero.athar-s-bg--color {
	background: none;
}

.athar-scope .lamba-hero .athar-cover__body {
	display: grid;
	justify-items: center;
	gap: clamp(0.9rem, 2vw, 1.4rem);
	max-inline-size: 100%;
}

.athar-scope .lamba-hero .athar-cover__heading {
	margin: 0;
	max-inline-size: none;
	font-family: var(--l-display);
	/* Half what the opening used to be. It is the vw term that keeps the
	   promise of one line: at 5.6vw a short line holds on a phone, and the two
	   ends of the clamp stop it becoming either a whisper or a billboard. */
	font-size: clamp(1.5rem, 5.6vw, 4.25rem);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-hero);
	line-height: 1.12;
	white-space: nowrap;
	text-wrap: nowrap;
}

.athar-scope .lamba-hero .athar-cover__sub {
	margin: 0;
	max-inline-size: 46ch;
	color: var(--l-quiet);
	font-size: var(--l-t-h3);
	line-height: var(--l-lh-head);
	text-wrap: pretty;
}

.athar-scope .lamba-hero .athar-cover__button {
	display: inline-flex;
	align-items: center;
	margin-block-start: 0.4rem;
	padding-block: 0.75em;
	padding-inline: 1.5em;
	border-radius: var(--l-radius-pill);
	background: var(--l-yellow);
	color: var(--l-black);
	font-weight: var(--l-w-mid);
	text-decoration: none;
	transition: filter var(--l-dur-1) var(--l-ease);
}

.athar-scope .lamba-hero .athar-cover__button:hover {
	filter: brightness(1.12);
}

/* On a pale ground the button cannot be the ground's own colour. */
.lamp-pale .athar-scope .lamba-hero .athar-cover__button {
	background: var(--l-ink);
	color: var(--l-white);
}

/* The cue: a filament of a line at the foot of the opening, lighting from the
   top down, over and over. It is inside the section, so it leaves when the
   section does and nothing has to remember to take it away. */
.lamba-hero__cue {
	position: absolute;
	inset-block-end: clamp(1.25rem, 4vh, 2.75rem);
	inset-inline: 0;
	margin-inline: auto;
	inline-size: 1px;
	block-size: clamp(2rem, 5vh, 3.5rem);
	background: linear-gradient(to bottom, transparent, var(--l-yellow));
	opacity: 0.5;
	transform-origin: top;
	animation: lamba-cue 2.4s var(--l-ease-io) infinite;
}

@keyframes lamba-cue {
	0%   { scale: 1 0; opacity: 0; }
	35%  { scale: 1 1; opacity: 0.55; }
	70%  { scale: 1 1; opacity: 0.55; }
	100% { scale: 1 1; opacity: 0; }
}

/* =============================================================== entrances

   "تحريك جانبي فجائي" — a sudden sideways arrival. Sections travel in from
   one side and stop dead, alternating sides down the page so it reads as a
   rhythm rather than a conveyor belt.

   No fade with it, deliberately. A fade is the gentle way to arrive and there
   is nothing gentle in this identity; what sells it as a light coming on
   rather than a slide is that it does not drift to a halt, it stops.

   Reversible, because that is what was asked for: the class comes off on the
   way out, so scrolling back up plays it again.
   ======================================================================= */

.site-main {
	/* The travel happens outside the page's width. clip and not hidden: hidden
	   would make this a scroll container and take the sticky header with it. */
	overflow-x: clip;
}

.athar-scope .athar-section:not(.lamba-hero):not(.lamba-rail) {
	--in-x: 7vw;
	transition: translate 420ms var(--l-ease);
}

[dir="ltr"] .athar-scope .athar-section {
	--in-x: -7vw;
}

/* Every other one from the other side. */
.athar-scope .athar-section:nth-child(even) {
	--in-x: -7vw;
}

[dir="ltr"] .athar-scope .athar-section:nth-child(even) {
	--in-x: 7vw;
}

.lamp-js .athar-scope .athar-section:not(.lamba-hero):not(.lamba-rail):not(.is-in) {
	translate: var(--in-x) 0;
}

/* The opening never slides in — a first screen that assembles itself is a
   first screen nobody trusts — so it is excluded above by name rather than
   overridden here. Nothing is left to say about it. */

/* ================================================================== footer */

.site-foot {
	margin-block-start: var(--l-rhythm);
	/* The floor blurs and darkens the bottom of the window, and the foot is
	   the last thing under it. Its own words have to clear that band or the
	   end of every page is read through a smudge. */
	padding-block: var(--l-rhythm-tight) clamp(7rem, 17vh, 13rem);
	font-size: var(--l-t-small);
	color: var(--l-quiet);
}

.site-foot__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--l-gutter);
	align-items: baseline;
	justify-content: space-between;
}

.site-foot a {
	text-decoration: none;
	border-block-end: 1px solid var(--l-rule);
}

.site-foot a:hover {
	color: var(--l-text);
	border-block-end-color: var(--l-yellow);
}

/* ==================================================================== gate

   Full screen, built by lamp.js and never present in the served HTML, so a
   reader with no JavaScript never meets it. Darker than the site it opens
   onto: the room is #1c1c1a, the gate is true black.
   ======================================================================= */

.gate {
	position: fixed;
	inset: 0;
	z-index: 90;
	display: grid;
	background: var(--l-black);
	/* Three of the four mechanics are drags, and a drag across a page selects
	   text on the way. preventDefault on pointerdown covers the pointer path;
	   this covers the rest, including a selection that started before the
	   gate was built. */
	user-select: none;
	-webkit-user-select: none;
	transition:
		opacity var(--l-dur-3) var(--l-ease),
		visibility var(--l-dur-3) step-end;
}

.gate.is-out {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}

.gate__stage {
	grid-area: 1 / 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: clamp(0.9rem, 2.6vh, 1.9rem);
	padding: var(--l-gutter);
	text-align: center;
}

/* The gate's lamp is the brand mark itself, cloned from the header by lamp.js.

   The unlit state is the fiddly part. Dropping the opacity of the brand yellow
   turns it olive over black — the same sludge that made the first build look
   broken — so the unlit filament is not dim yellow, it is a neutral cold grey,
   and --lit interpolates it towards the brand colour. That is also what a real
   filament does: it is grey metal until current reaches it.

   The glow radii are lighter here than the header's on purpose. In the artwork
   the yellow is a filled field inside the head rather than a hairline, and a
   wide blur on an area that size reads as fog rather than as light.
   ======================================================================= */
.gate__orb {
	position: relative;
	inline-size: clamp(7rem, 20vmin, 12rem);
	display: grid;
	place-items: center;
}

.gate__mark {
	inline-size: 100%;
}

.gate__mark .lamba-mark__fil {
	fill: color-mix(in oklab, var(--l-yellow) calc(var(--lit) * 100%), #55554e);
	filter: none;
}

.gate__mark .lamba-mark__wide {
	opacity: calc(var(--lit) * 0.32);
	animation: none;
}

.gate__mark .lamba-mark__tight {
	opacity: calc(var(--lit) * 0.55);
}

/* The head stays readable in the dark so the lamp has a place before it has a
   light, and comes fully up with it. */
.gate__mark .lamba-mark__body path {
	fill: var(--l-text);
	opacity: calc(0.3 + var(--lit) * 0.7);
}

.gate__slogan {
	margin: 0;
	font-family: var(--l-display);
	font-size: var(--l-t-hero);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-hero);
	line-height: var(--l-lh-hero);
	opacity: calc(0.32 + var(--lit) * 0.68);
}

.gate__sub {
	margin: 0;
	font-size: var(--l-t-meta);
	letter-spacing: var(--l-track-meta);
	text-transform: uppercase;
	color: var(--l-faint);
}

.gate__hint {
	margin: 0;
	max-inline-size: 26ch;
	font-size: var(--l-t-small);
	color: var(--l-quiet);
	text-wrap: balance;
	/* Fades out as the light comes up: once you have understood it, it goes. */
	opacity: calc(1 - var(--lit));
}

.gate__skip {
	margin-block-start: 0.5rem;
	padding: 0.4em 0.9em;
	border: 0;
	border-radius: var(--l-radius-pill);
	background: none;
	color: var(--l-faint);
	font: inherit;
	font-size: var(--l-t-small);
	cursor: pointer;
	text-decoration: underline;
	text-underline-offset: 0.3em;
}

.gate__skip:hover {
	color: var(--l-text);
}

/* ---------------------------------------------------------------- cord

   A cord hanging from the top of the screen. The light rises with the pull,
   so the hand is holding the light rather than pressing a button that owns
   it. Identical under a finger and a mouse; the only mechanic that also
   reads as a physical object. */

/* Hangs from the inline start, which is the right in Arabic and the left in
   English. Both put it under the hand that is most likely to reach for it,
   and neither needs an override. */
.cord {
	--pull: 0;
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: clamp(1.5rem, 9vw, 7rem);
	display: flex;
	flex-direction: column;
	align-items: center;
}

.cord__rope {
	inline-size: 1px;
	block-size: calc(18vh + var(--pull) * 190px);
	background: linear-gradient(
		to bottom,
		rgb(237 237 233 / 0.06),
		rgb(237 237 233 / 0.5)
	);
	transition: block-size var(--l-dur-2) var(--l-ease);
}

.cord__grip {
	inline-size: 2.5rem;
	aspect-ratio: 1;
	border: 1px solid var(--l-rule);
	border-radius: 50%;
	background: var(--l-raise);
	cursor: grab;
	/* Or the browser takes the drag for a scroll and the cord never moves. */
	touch-action: none;
	transition: background var(--l-dur-1) var(--l-ease);
}

.cord__grip::after {
	content: "";
	display: block;
	inline-size: 0.5rem;
	aspect-ratio: 1;
	margin: auto;
	border-radius: 50%;
	background: var(--l-faint);
}

.cord__grip.is-held {
	cursor: grabbing;
	background: var(--l-raise-2);
}

/* No easing while a hand is on it: the rope has to be exactly where the
   finger is. The spring back is the only animated part. */
.cord:has(.is-held) .cord__rope {
	transition: none;
}

/* ---------------------------------------------------------------- dial

   A dimmer. The angle of the hand around the knob is the brightness, which
   makes this the one mechanic where the light is genuinely continuous. */

.dial {
	--turn: 0;
	position: relative;
	display: grid;
	place-items: center;
	inline-size: clamp(7rem, 21vmin, 10rem);
	aspect-ratio: 1;
}

.dial__track {
	position: absolute;
	inset: 0;
	border: 1px dashed rgb(237 237 233 / 0.18);
	border-radius: 50%;
}

.dial__track::after {
	content: "";
	position: absolute;
	inset: -9%;
	border-radius: 50%;
	background: conic-gradient(
		from 230deg,
		var(--l-yellow) calc(var(--turn) * 260deg),
		transparent 0
	);
	-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
	mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
}

.dial__knob {
	position: relative;
	inline-size: 66%;
	aspect-ratio: 1;
	border: 1px solid var(--l-rule);
	border-radius: 50%;
	background: var(--l-raise);
	cursor: grab;
	touch-action: none;
	rotate: calc(-130deg + var(--turn) * 260deg);
}

.dial__knob::after {
	content: "";
	position: absolute;
	inset-block-start: 12%;
	inset-inline-start: calc(50% - 1px);
	inline-size: 2px;
	block-size: 26%;
	border-radius: 2px;
	background: var(--l-quiet);
}

.dial__knob.is-held {
	cursor: grabbing;
	background: var(--l-raise-2);
}

/* ---------------------------------------------------------------- hold

   Press and keep pressing. The ring fills, the light comes up with it, and
   letting go early lets it fall back. The simplest one to explain on a
   phone, and the one that needs the clearest instruction. */

.hold {
	--charge: 0;
	display: grid;
	place-items: center;
}

.hold__btn {
	position: relative;
	display: grid;
	place-items: center;
	inline-size: clamp(5rem, 17vmin, 7rem);
	aspect-ratio: 1;
	border: 1px solid var(--l-rule);
	border-radius: 50%;
	background: var(--l-raise);
	cursor: pointer;
	touch-action: none;
	transition: background var(--l-dur-1) var(--l-ease);
}

.hold__btn.is-held {
	background: var(--l-raise-2);
}

.hold__btn::after {
	content: "";
	inline-size: 34%;
	aspect-ratio: 1;
	border-radius: 50%;
	background: var(--l-yellow);
	opacity: calc(0.22 + var(--charge) * 0.78);
	scale: calc(0.8 + var(--charge) * 0.35);
}

.hold__ring {
	position: absolute;
	inset: -8px;
	border-radius: 50%;
	background: conic-gradient(
		from -90deg,
		var(--l-yellow) calc(var(--charge) * 360deg),
		transparent 0
	);
	-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
	mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
}

/* ---------------------------------------------------------------- spot

   The dark room. The hand carries a small pool of light and the switch has to
   be found before it can be thrown. The mask follows the pointer in viewport
   coordinates, which is why the stage is stretched to fill the gate. */

/* The defaults belong on the gate, not on the stage.
   lamp.js writes --tx/--ty onto .gate as the hand moves, and a declaration on
   the stage would shadow the inherited value on the very element that reads
   it: the mask would sit at 50% 45% for ever and the switch, which lives
   outside that pool, could never be found. The same shadowing trap Athar
   documents for --athar-sbw. */
.gate--dark {
	--tx: 50%;
	--ty: 45%;
}

/* The floor is 0.1, not transparent. A pool of light in true black is the
   right drama, but it also means the hint, the skip and the switch are
   invisible until they are stumbled on, and a visitor who does not sweep the
   screen is simply stuck. A tenth of an alpha is enough to say "there is
   something here" without giving away where. */
.gate--dark .gate__stage {
	-webkit-mask-image: radial-gradient(
		circle 21vmin at var(--tx) var(--ty),
		#000 0%,
		rgb(0 0 0 / 0.5) 52%,
		rgb(0 0 0 / 0.1) 78%
	);
	mask-image: radial-gradient(
		circle 21vmin at var(--tx) var(--ty),
		#000 0%,
		rgb(0 0 0 / 0.5) 52%,
		rgb(0 0 0 / 0.1) 78%
	);
}

/* Once lit there is nothing left to hunt for, so the mask lifts. */
.gate--dark.is-out .gate__stage {
	-webkit-mask-image: none;
	mask-image: none;
}

.spot__btn {
	display: grid;
	place-items: center;
	inline-size: 4.5rem;
	aspect-ratio: 1;
	border: 1px solid var(--l-rule);
	border-radius: 50%;
	background: var(--l-raise);
	cursor: pointer;
}

.spot__dot {
	inline-size: 0.75rem;
	aspect-ratio: 1;
	border-radius: 50%;
	background: var(--l-yellow);
	opacity: 0.5;
}

.spot__btn:hover .spot__dot {
	opacity: 1;
}

/* ---------------------------------------------------- the dark and the switch

   The room is dark and a warm pool follows the hand through it, but nothing
   hides. The switch sits mid-room with the mark above it and «بس شغّلها»
   under it: the composition of a lamp, its switch, and the instruction. The
   errand this mechanic used to run — the switch by the door, found by torch —
   was cut on review: the idea is the dark and the throw, not the search.
   ========================================================================= */

.gate--hunt {
	--tx: 50%;
	--ty: 50%;
}

/* The beam. A soft warm pool under the hand, on the gate rather than on the
   stage, so it washes the room and not the words. Until the hand moves it
   rests at the centre — on the switch, which is the room's one promise. */
.gate--hunt::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(
		circle 26vmin at var(--tx) var(--ty),
		rgb(246 208 13 / 0.09) 0%,
		rgb(246 208 13 / 0.03) 45%,
		transparent 72%
	);
	pointer-events: none;
}

/* One line of text on the screen, and it is the one that says what to do. */
.gate--hunt .gate__sub,
.gate--hunt .gate__hint {
	display: none;
}

/* «بالنص» is the switch's row, not the group's middle. One centred column
   would let the mark's height push the switch below centre, so the stage
   becomes three rows with the switch's own row pinned to the middle: the
   flexible rows above and below stay equal, and the switch holds the centre
   of the room no matter how tall the mark or the slogan run. */
.gate--hunt .gate__stage {
	display: grid;
	grid-template-rows: 1fr auto 1fr;
	justify-items: center;
}

/* Smaller and higher than the other gates draw it: here the mark is the lamp
   hanging over its switch, not the hero of the screen. The margin is the
   lift — its air lands between the mark and the switch, while the slogan
   below keeps only the stage gap and stays tight under the switch. */
.gate--hunt .gate__orb {
	align-self: end;
	inline-size: clamp(5.25rem, 15vmin, 9rem);
	margin-block-end: clamp(1rem, 4vh, 2.5rem);
}

/* A step under hero: the slogan is the caption under the switch now, not the
   headline of the room. */
.gate--hunt .gate__slogan {
	align-self: start;
	font-size: clamp(1.8rem, 5.2vw, 4.1rem);
}

/* Small, low, and quiet enough that the slogan is read first — which was the
   whole request. It is still a real button: full size to press, full contrast
   the moment it takes focus. */
.gate--hunt .gate__skip {
	position: absolute;
	inset-inline: 0;
	inset-block-end: clamp(1.25rem, 4vh, 2.5rem);
	margin-inline: auto;
	inline-size: max-content;
	font-size: var(--l-t-meta);
	letter-spacing: var(--l-track-meta);
	color: var(--l-text);
	opacity: 0.28;
	transition: opacity var(--l-dur-1) var(--l-ease);
}

.gate--hunt .gate__skip:hover,
.gate--hunt .gate__skip:focus-visible {
	opacity: 1;
}

/* --------------------------------------------------------------- the switch */

.hunt__plate {
	inline-size: 5rem;
	padding: 0.5rem;
	border: 1px solid rgb(237 237 233 / 0.14);
	border-radius: var(--l-radius);
	background: rgb(35 35 32 / 0.9);
	transition: box-shadow var(--l-dur-1) var(--l-ease);
}

/* The room still answers the hand, just no longer as a reveal: close to the
   plate — not from across the room — it warms. An unlit switch does not glow
   on its own, so the rest state carries nothing. */
.hunt:hover .hunt__plate,
.hunt:focus-within .hunt__plate {
	box-shadow: 0 0 32px rgb(246 208 13 / 0.14);
}

.hunt__rocker {
	display: block;
	inline-size: 100%;
	block-size: 4rem;
	padding: 0;
	border: 0;
	border-radius: var(--l-radius-s);
	background: linear-gradient(to bottom, var(--l-raise-2) 0 52%, var(--l-ink) 52% 100%);
	cursor: pointer;
	transition: background var(--l-dur-2) var(--l-ease);
}

/* The throw: the lit half swaps ends, the same gesture the plain switch makes. */
.hunt.is-up .hunt__rocker {
	background: linear-gradient(to bottom, var(--l-ink) 0 48%, var(--l-raise-2) 48% 100%);
}

/* --------------------------------------------------------- plug and socket

   «من أول ما نشبك الفيش». The plug is dragged along the line into the socket
   at the end of it, and the lead between them shortens as it goes.
   ======================================================================= */

.plug {
	--push: 0;
	position: relative;
	inline-size: min(20rem, 70vw);
	block-size: 3.5rem;
}

/* The plug starts at the reading start and travels to the socket at the end,
   which is why every offset here is logical: the end of the line moves with
	   the language, and a physical translate would send it the wrong way in
   one of the two. */
.plug__socket {
	position: absolute;
	inset-inline-end: 0;
	inset-block-start: 50%;
	margin-block-start: -1.6rem;
	inline-size: 2.6rem;
	block-size: 3.2rem;
	border: 1px solid var(--l-rule);
	border-radius: var(--l-radius-s);
	background: var(--l-raise);
}

/* Two holes, which is what tells a small dark rectangle that it is a socket. */
.plug__socket::before,
.plug__socket::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inline-size: 3px;
	block-size: 0.9rem;
	margin-block-start: -0.45rem;
	border-radius: 2px;
	background: var(--l-black);
}

.plug__socket::before { inset-inline-start: 0.7rem; }
.plug__socket::after  { inset-inline-end: 0.7rem; }

/* The lead pays out behind the plug as it goes. */
.plug__lead {
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: 50%;
	block-size: 1px;
	inline-size: calc(var(--push) * (100% - 6.4rem));
	background: var(--l-rule);
}

.plug__body {
	position: absolute;
	inset-block-start: 50%;
	margin-block-start: -1.45rem;
	inset-inline-start: calc(var(--push) * (100% - 6.4rem));
	/* 44×44 is the floor for a thing a finger has to catch, and this was
	   51×38 — wide enough and a hand short. */
	inline-size: 3.8rem;
	block-size: 2.9rem;
	padding: 0;
	border: 1px solid var(--l-rule);
	border-radius: var(--l-radius-s);
	background: var(--l-raise-2);
	cursor: grab;
	/* Or the browser takes the drag for a scroll and it never moves. */
	touch-action: none;
	transition: background var(--l-dur-1) var(--l-ease);
}

/* The prongs, on the side facing the socket. */
.plug__body::before,
.plug__body::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: -0.55rem;
	inline-size: 0.6rem;
	block-size: 3px;
	border-radius: 2px;
	background: var(--l-faint);
}

.plug__body::before { margin-block-start: -0.45rem; }
.plug__body::after  { margin-block-start: 0.15rem; }

.plug__body.is-held {
	cursor: grabbing;
	background: var(--l-raise);
}

.plug.is-home .plug__body {
	border-color: rgb(246 208 13 / 0.6);
}

/* -------------------------------------------------------------- the switch */

.flip {
	inline-size: 5.5rem;
	padding: 0.5rem;
	border: 1px solid var(--l-rule);
	border-radius: var(--l-radius);
	background: var(--l-raise);
}

.flip__rocker {
	display: block;
	inline-size: 100%;
	block-size: 4.5rem;
	padding: 0;
	border: 0;
	border-radius: var(--l-radius-s);
	background: linear-gradient(to bottom, var(--l-raise-2) 0 52%, var(--l-ink) 52% 100%);
	cursor: pointer;
	transition: background var(--l-dur-2) var(--l-ease);
}

/* The throw: the lit half swaps ends. */
.flip.is-up .flip__rocker {
	background: linear-gradient(to bottom, var(--l-ink) 0 48%, var(--l-raise-2) 48% 100%);
}

.flip__rocker:hover {
	filter: brightness(1.15);
}

/* ------------------------------------------------------------ the filament

   Their mark, used as the control rather than shown as a picture: rub along
   the filament and it heats, and the drawn stroke follows the hand.
   ======================================================================= */

.trace {
	--heat: 0;
	display: grid;
	place-items: center;
}

.trace__pad {
	display: block;
	padding: 1rem;
	border: 0;
	background: none;
	cursor: crosshair;
	touch-action: none;
}

.trace__art {
	inline-size: clamp(7rem, 22vw, 11rem);
}

.trace__art .lamba-mark {
	inline-size: 100%;
}

/* The heat is drawn on the same path the filament is, so what lights is the
   shape of the thing that lights. */
.trace__line {
	fill: none;
	stroke: var(--l-yellow);
	stroke-width: 5;
	stroke-linecap: round;
	stroke-linejoin: round;
	filter: drop-shadow(0 0 6px rgb(246 208 13 / 0.8));
}

/* ------------------------------------------------------------- the spark */

.spark {
	--near: 0;
	position: relative;
	inline-size: min(20rem, 70vw);
	block-size: 3rem;
}

/* The wire is three pixels; the thing you grab is not. A hairline is a
   hairline to look at and a miss to reach for, so the ends are 2.5rem of
   invisible box with the wire drawn across the middle of them. */
.spark__dead,
.spark__live {
	position: absolute;
	inset-block-start: 50%;
	margin-block-start: -1.25rem;
	inline-size: 3.5rem;
	block-size: 2.5rem;
	padding: 0;
	border: 0;
	background: none;
}

.spark__dead::before,
.spark__live::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	inset-block-start: 50%;
	margin-block-start: -1.5px;
	block-size: 3px;
	border-radius: 2px;
	background: var(--l-faint);
}

.spark__live::before {
	background: var(--l-quiet);
}

.spark__dead {
	inset-inline-end: 0;
}

/* The live end travels toward the dead one, and stops just short of it: the
   last of the gap is crossed by the arc, not by the hand. */
.spark__live {
	inset-inline-start: calc(var(--near) * (100% - 7.6rem));
	cursor: grab;
	touch-action: none;
}

.spark__live.is-held {
	cursor: grabbing;
}

/* What is about to cross the gap. */
.spark__arc {
	position: absolute;
	inset-block-start: 50%;
	margin-block-start: -1.5px;
	inset-inline-start: calc(var(--near) * (100% - 7.6rem) + 3.5rem);
	inset-inline-end: 3.5rem;
	block-size: 3px;
	border-radius: 2px;
	background: var(--l-yellow);
	opacity: 0;
}

.spark.is-close .spark__arc {
	opacity: calc((var(--near) - 0.72) * 2.6);
	box-shadow: 0 0 16px rgb(246 208 13 / 0.9);
	animation: lamba-arc 120ms steps(2, jump-none) infinite;
}

.spark.is-arced .spark__arc {
	opacity: 1;
	animation: none;
}

@keyframes lamba-arc {
	0%, 100% { filter: brightness(1); }
	50% { filter: brightness(1.8); }
}

/* ============================================================ Athar: rhythm

   The price of `add_theme_support( 'athar-css-layer' )`, and Athar's readme
   says so plainly: a layered rule loses to *every* unlayered one, including
   WordPress's own. Core ships `:where(figure) { margin: 0 0 1em }`, which has
   zero specificity but is unlayered, so it beat Athar's section rhythm on
   every section whose root is a <figure> — quote, image, gallery, video and
   before/after. Those five sat flush against the section above them while
   every other type kept its air, which reads as a design mistake rather than
   a cascade one.

   Athar's own three declarations, restated unlayered. The custom properties
   are kept, not resolved: the studio's per-section spacing controls write
   --athar-s-mt and --athar-s-mb, and hardcoding the rhythm here would
   silently disable them.
   ======================================================================= */

.athar-scope > .athar-section {
	margin-block-start: var(--athar-s-mt, var(--athar-rhythm));
	margin-block-end: var(--athar-s-mb, 0px);
}

.athar-scope > .athar-section:first-child,
.athar-scope > .athar-langs + .athar-section {
	margin-block-start: var(--athar-s-mt, 0px);
}

/* ============================================================ Athar: widths

   Three widths, and this site's reading of them: normal is a measure, wide is
   the whole column, full bleeds to the viewport edge.

   Athar's own align-wide is a fraction of the viewport (--athar-wide), which
   is the right default for a theme with no column of its own. This one has
   one, and a work grid that is wider than the header above it looks like a
   mistake rather than a decision. Full bleed is left exactly as the plugin
   computes it.

   No !important and no specificity arithmetic: functions.php puts Athar in a
   cascade layer, and an unlayered rule outranks every layered one.
   ======================================================================= */

.athar-scope .athar-section.athar-align-wide {
	margin-inline: 0;
	inline-size: 100%;
	max-inline-size: 100%;
}

/* =========================================================== Athar: stats

   The results block, and the thing their own case-study layout leads with:
   a small yellow label over a very large yellow number.
   ======================================================================= */

/* The opener. A short stroke of filament and a quiet word — this is what
   replaced the rules that used to separate the sections, and it is the one
   device the whole page below the opening now shares. */
.athar-scope .athar-stats__intro {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	margin: 0 0 var(--l-rhythm-tight);
	max-inline-size: none;
	color: var(--l-quiet);
	font-size: var(--l-t-meta);
	letter-spacing: var(--l-track-meta);
	text-transform: uppercase;
}

.athar-scope .athar-stats__intro::before {
	content: "";
	inline-size: clamp(1.5rem, 4vw, 3rem);
	block-size: 1px;
	background: var(--l-yellow);
	opacity: calc(0.3 + var(--lit) * 0.7);
}

/* auto-fit made three figures share a full-width row, so each one floated in
   the middle of a 389px cell with its label adrift under it. They sit together
   now and the row ends where they do. */
.athar-scope .athar-stats__grid {
	display: grid;
	gap: clamp(2rem, 6vw, 5rem);
	grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), max-content));
	justify-content: start;
	margin: 0;
	/* Athar rules the top of this grid off its own hairline token, which this
	   site feeds. Removing the item's rule was not enough; this is the other
	   half of the same line. */
	padding-block-start: 0;
	border-block-start: 0;
}

/* No rule over each figure. A number this size does not need a line to say
   where it starts, and the line was the only thing making three of these look
   like a table. */
/* The number first and the label under it, which is the order they are read
   in. It used to be reversed, on a reading of their case-study layout, and
   what that produced was a figure you met before you knew what it counted. */
.athar-scope .athar-stats__item {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.athar-scope .athar-stats__value {
	font-family: var(--l-display);
	/* Down from the metric scale. It was the largest thing on the page and it
	   is not the most important one. */
	font-size: clamp(2.1rem, 4.6vw, 3.6rem);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-hero);
	line-height: 1;
	color: var(--l-yellow);
	/* Latin figures, and tabular, so three of them line up as a row rather
	   than as three separate widths. */
	font-variant-numeric: tabular-nums lining-nums;
	/* The numbers are the light. They come up with it and never fully leave. */
	opacity: calc(0.4 + var(--lit) * 0.6);
}

/* Up from a caption. It is the half of the pair that carries the meaning. */
.athar-scope .athar-stats__label {
	margin: 0;
	max-inline-size: 18ch;
	color: var(--l-text);
	font-size: var(--l-t-body);
	line-height: var(--l-lh-head);
	text-wrap: pretty;
}

/* ======================================================== Athar: features

   The three pillars: الإنتاج, الإبداع, التواصل. Numbered, because the
   client's chosen homepage reference numbers its services and it reads as
   confidence rather than decoration.
   ======================================================================= */

/* The heading beside the pillars rather than over them. It used to sit in a
   24ch box at the start of a full-width row with a thousand pixels of nothing
   next to it — which is the void, and no amount of spacing was going to fix a
   thing that was structural. */
@media (min-width: 62rem) {
	.athar-scope .athar-features {
		display: grid;
		grid-template-columns: minmax(15rem, 21rem) 1fr;
		column-gap: clamp(2.5rem, 6vw, 6rem);
		align-items: start;
	}

	/* It holds while the three read past it. */
	.athar-scope .athar-features__head {
		position: sticky;
		inset-block-start: clamp(7rem, 18vh, 11rem);
	}
}

.athar-scope .athar-features__head {
	margin-block-end: var(--l-rhythm-tight);
	margin-inline: 0;
	max-inline-size: 22ch;
}

.athar-scope .athar-features__heading {
	margin: 0;
	font-family: var(--l-display);
	font-size: var(--athar-h-l);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	line-height: var(--l-lh-head);
}

.athar-scope .athar-features__intro {
	margin-block: var(--athar-gap-tight) 0;
	color: var(--l-quiet);
	text-wrap: pretty;
}

/* The grid used to be drawn by its own gaps: a one-pixel background showing
   through between cells. It read as a table of contents. Then it was three
   thin columns, which read as a table of contents in a different font. It is
   a list now, and a list of three things is what this actually is. */
.athar-scope .athar-features__grid {
	display: grid;
	/* Declared, not left out. Athar sets its own columns in the layer, and a
	   property this file never names is a property this file never wins — so
	   removing the count rules above changed nothing until this line existed. */
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(2rem, 4vh, 3.25rem);
	margin-block-end: 0;
}

/* The column counts are gone on purpose. Whatever number the editor picks in
   the studio, the pillars read down this site as a list: two or four of them
   side by side is the same thin-column layout that put a paragraph on a 225px
   line. The setting still means something to any other site on Athar; here it
   means nothing, and saying so once is better than a rule per count. */

/* The number beside the words, on the title's own line, rather than stacked
   above them: in a row that wide a number on its own line is a heading nobody
   asked for. */
.athar-scope .athar-features__item {
	counter-increment: pillar;
	position: relative;
	padding: 0;
	display: grid;
	grid-template-columns: auto 1fr;
	column-gap: clamp(1rem, 2.5vw, 2rem);
	align-items: baseline;
}

.athar-scope .athar-features__title,
.athar-scope .athar-features__body,
.athar-scope .athar-features__figure {
	grid-column: 2;
}

/* The number is an index, not a headline. It was briefly set at heading size
   to replace the cell walls that used to divide these, and it ended up louder
   than the titles it was numbering. Small, tracked, and out of the way — the
   titles do the ordering now, because they are the largest thing here. */
.athar-scope .athar-features__item::before {
	content: counter(pillar, decimal-leading-zero);
	grid-column: 1;
	grid-row: 1 / span 3;
	display: block;
	font-size: var(--l-t-meta);
	font-weight: var(--l-w-mid);
	letter-spacing: var(--l-track-meta);
	line-height: 1;
	color: var(--l-yellow);
	font-variant-numeric: tabular-nums lining-nums;
	opacity: calc(0.35 + var(--lit) * 0.45);
	transition: opacity var(--l-dur-1) var(--l-ease);
}

/* Lit, not filled. A background on hover was the cell answering; this is the
   light coming up on the thing being read. */
.athar-scope .athar-features__item:hover::before {
	opacity: 1;
}

.athar-scope .athar-features__title {
	margin: 0 0 0.7em;
	font-family: var(--l-display);
	font-size: var(--l-t-h2);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	line-height: var(--l-lh-head);
	text-wrap: balance;
}

.athar-scope .athar-features__body {
	margin: 0;
	/* A measure, not a column width. It was 34ch inside a 413px cell, which is
	   neither. */
	max-inline-size: 54ch;
	color: var(--l-quiet);
	font-size: var(--l-t-body);
	line-height: var(--l-lh-body);
	text-wrap: pretty;
}

.athar-scope .athar-features__figure {
	margin: 0 0 var(--athar-gap);
	max-inline-size: 2.5rem;
}

/* The grid counts the items, so the counter has to be reset on the section. */
.athar-scope .athar-features {
	counter-reset: pillar;
}

/* ===================================================================== rail

   The work, travelling sideways while the page scrolls down.

   Three boxes and one number. The section is tall — one screen plus however
   far the track has to travel — so there is scroll to spend. The stage inside
   it pins to the top for exactly that distance. The track slides across it.
   When the section runs out, the stage unpins and the page carries on, which
   is the part that has to feel like nothing happened.

   The travel is set in physical pixels with a sign taken from the page's
   direction, not with a logical property: `translate` is physical, and this
   site is read right to left, where the work arrives from the left.

   Everything below only applies once lamp.js has measured the overflow and
   added .is-railed. Before that — and forever, with no script — the stage is
   a strip you push sideways with a finger or a trackpad. That is a real way
   to read a row of work, so there is nothing to apologise for and nothing to
   wait for.
   ======================================================================= */

.athar-scope .lamba-rail {
	padding-block: 0;
}

.lamba-rail__stage {
	display: grid;
	grid-template-rows: auto 1fr;
	gap: clamp(0.9rem, 2vh, 1.6rem);
	padding-block: var(--l-rhythm-tight);
}

.lamba-rail__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--athar-gap);
}

/* Before the measure, and with no script at all: a sideways strip. */
.lamba-rail__window {
	/* One cell, so the track stretches to the stage's row instead of standing
	   at the height of its own content. There used to be a min-block-size on
	   the track doing that job by hand; it was removed as a cap it never was,
	   and the cards immediately collapsed to the height of a title. */
	display: grid;

	/* A grid item's automatic minimum size is its content, so without this the
	   track's full width becomes the stage's column width — and the heading
	   above, which centres in that column, drifts off the screen's centre. */
	min-inline-size: 0;
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	padding-inline: var(--l-gutter);
}

.lamba-rail__window::-webkit-scrollbar {
	display: none;
}

/* Masonry, in the only direction that has room for it: two rows deep, and
   every third card taking both. The columns are one width, so the rhythm
   comes from the heights and not from a ragged grid. */
.lamba-rail__track {
	display: grid;
	grid-auto-flow: column dense;
	grid-template-rows: repeat(2, minmax(0, 1fr));
	/* Wider. They were reading as thumbnails on a wall rather than as work,
	   and a rail exists to give each piece room the page cannot. */
	grid-auto-columns: clamp(17rem, 30vw, 30rem);
	gap: clamp(0.75rem, 1.6vw, 1.5rem);
	margin: 0;
	padding: 0;
	list-style: none;
	inline-size: max-content;
	/* A floor for the state before any measuring — and for a reader with no
	   script, where the stage never pins and nothing stretches. */
	min-block-size: min(58svh, 32rem);
}

.lamba-rail__track > :nth-child(3n + 1) {
	grid-row: span 2;
}

/* In the rail a card is as tall as the row it was dealt, so the 4:3 the card
   states for a grid steps aside. A card that owns both rows then shows more of
   its still and one that shares gets a letterbox — which is the whole point of
   masonry, and the thing a single ratio everywhere quietly cancels. */
.athar-scope .lamba-rail .athar-pcard {
	aspect-ratio: auto;
	block-size: 100%;
}

/* ------------------------------------------------------------- once measured */

.lamba-rail.is-railed {
	/* One screen to pin for, plus the distance the track has to cover. */
	min-block-size: calc(100svh + var(--rail-scroll, 0px));
}

.lamba-rail.is-railed .lamba-rail__stage {
	position: sticky;
	inset-block-start: 0;
	block-size: 100svh;
	align-content: center;
	/* Clip, not hidden: hidden would make this a scroll container and a scroll
	   container cannot be sticky in its own scroller. */
	overflow: clip;
	/* The floor blurs the bottom of the window and the capsule floats over the
	   top, so the stage clears both — and no more than both. Every rem of
	   padding here comes straight off the height of the work. */
	padding-block: clamp(4.5rem, 10vh, 6.5rem) clamp(6rem, 15vh, 12rem);
}

.lamba-rail.is-railed .lamba-rail__window {
	overflow: visible;
	/* Held to the stage. Left to itself a visible box grows to its content,
	   and a window as wide as the track is not a window. The stage clips what
	   hangs out of it. */
	inline-size: 100%;
	padding-inline: var(--l-gutter);
}

.lamba-rail.is-railed .lamba-rail__track {
	translate: var(--rail-x, 0px) 0;
	will-change: transform;
}

/* ============================================================ Athar: work */

.athar-scope .athar-work__head {
	display: flex;
	flex-wrap: wrap;
	gap: var(--athar-gap);
	align-items: baseline;
	justify-content: space-between;
	margin-block-end: var(--athar-gap-loose);
}

.athar-scope .athar-work__heading {
	margin: 0;
	font-family: var(--l-display);
	font-size: var(--athar-h-l);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	line-height: var(--l-lh-head);
}

/* The yellow underline on the first word, which is how their own case-study
   layout sets this heading. Applied to the whole heading's last line would be
   wrong, so it is a span the template writes. */
.athar-scope .athar-work__heading b,
.athar-scope .athar-work__heading strong {
	font-weight: inherit;
	box-shadow: inset 0 -0.18em 0 var(--l-yellow);
}

.athar-scope .athar-work__all {
	font-size: var(--l-t-small);
	color: var(--l-quiet);
	text-decoration: none;
	border-block-end: 1px solid var(--l-rule);
	padding-block-end: 0.25em;
	transition: color var(--l-dur-1) var(--l-ease);
}

.athar-scope .athar-work__all:hover {
	color: var(--l-yellow);
	border-block-end-color: var(--l-yellow);
}

/* ====================================================== Athar: project card

   A picture with a name written on it.

   It was two boxes: a picture box on top, a lighter panel under it, two greys
   a shade apart, so every card read as two rectangles glued together — and on
   a project with no still the top rectangle was most of the card and empty.
   Now the picture is the whole card and the words lie on it under a gradient,
   which is the arrangement the opening uses: a card is a small version of the
   page it sits on.

   The markup it has to do that with is the plugin's, and the shape of it is
   the reason everything below is positioned rather than stacked:

       li.athar-pcard
         a.athar-pcard__link          the whole card is this link's target
           span.athar-pcard__media    the still
           span.athar-pcard__body     the client and the title
         ul.athar-pcard__pills        the services — a SIBLING of the link

   The pills sit outside the link, so no amount of layout inside the link can
   put them under the title. Percentage heights cannot help either: the card
   was taking its height from a grid row and handing nothing definite down, so
   the link resolved 100% against something 44px shorter than itself and left
   a strip of ink under every picture.

   So: the still is taken out of flow and pinned to the card, the card's height
   is stated outright, and everything that is words stacks at the bottom in
   normal flow above it. Nothing here asks a question that needs a number from
   anything else.
   ======================================================================= */

.athar-scope .athar-portfolio__grid {
	display: grid;
	gap: var(--athar-gap);
	grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr));
}

.athar-scope .athar-pcard {
	position: relative;
	display: flex;
	flex-direction: column;
	/* The words sit on the floor of the card and the picture fills it. */
	justify-content: flex-end;
	/* Stated, not inherited: the still is out of flow and cannot give the card
	   a height, so the card says what it is. The rail overrides this with the
	   row it was dealt. */
	aspect-ratio: 4 / 3;
	border-radius: var(--l-radius);
	background: var(--l-ink);
	overflow: hidden;
	isolation: isolate;
	transition:
		box-shadow var(--l-dur-2) var(--l-ease),
		translate var(--l-dur-2) var(--l-ease);
}

/* ------------------------------------------------------------- the still

   The card is off until you turn it on. Greyscale and dimmed at rest; a
   pointer over it, or a finger held on it, and the colour comes up with a
   short catch, the way a lamp strikes rather than fades. This is the site's
   whole idea repeated at card scale. lamp.js sets .is-on for both input
   kinds. */

.athar-scope .athar-pcard__media {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	overflow: hidden;
	background: var(--l-ink);
	filter: grayscale(1) brightness(0.52) contrast(1.15);
	transition: filter var(--l-dur-2) var(--l-ease);
}

.athar-scope .athar-pcard.is-on .athar-pcard__media {
	filter: none;
	animation: lamba-strike 460ms var(--l-ease);
}

/* A lamp catches before it holds: up, dip, then steady. Short enough to read
   as physical rather than as an effect. */
@keyframes lamba-strike {
	0%   { filter: grayscale(1) brightness(0.52) contrast(1.15); }
	22%  { filter: grayscale(0.15) brightness(1.28) contrast(1.05); }
	34%  { filter: grayscale(0.5) brightness(0.78) contrast(1.1); }
	60%  { filter: grayscale(0) brightness(1.1) contrast(1); }
	100% { filter: none; }
}

.athar-scope .athar-pcard__media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	filter: var(--l-photo);
	transition: scale var(--l-dur-3) var(--l-ease);
}

.athar-scope .athar-pcard.is-on .athar-pcard__media img {
	scale: 1.03;
}

/* A project with no still yet.

   There used to be a circle drawn in the middle of it, on the reasoning that
   a mark reads better than a void. It does not: at card size it reads as a
   broken image, and in the rail, where a card can be two rows tall, it was a
   large empty rectangle with a target in it. A still-less card is simply a
   panel with its name on it, which is a card and not a gap. */
.athar-scope .athar-pcard__media--empty {
	background: var(--l-raise);
	filter: none;
}

.athar-scope .athar-pcard.is-on .athar-pcard__media--empty {
	background: var(--l-raise-2);
	filter: none;
	animation: none;
}

/* ------------------------------------------------------------- the words

   One gradient for both of them, on the card rather than on either, because
   they are in different subtrees and a gradient each would seam. */

.athar-scope .athar-pcard::before {
	content: "";
	position: absolute;
	z-index: 1;
	inset-inline: 0;
	inset-block-end: 0;
	block-size: 72%;
	background: linear-gradient(
		to top,
		rgb(0 0 0 / 0.9) 0%,
		rgb(0 0 0 / 0.62) 34%,
		rgb(0 0 0 / 0.22) 66%,
		rgb(0 0 0 / 0) 100%
	);
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--l-dur-1) var(--l-ease);
}

.athar-scope .athar-pcard.is-on::before {
	opacity: 1;
}

/* Nothing to light on a card with no still, so less dark is needed to read
   the name on it. */
.athar-scope .athar-pcard:has(.athar-pcard__media--empty)::before {
	block-size: 100%;
	background: linear-gradient(to top, rgb(0 0 0 / 0.35) 0%, rgb(0 0 0 / 0) 70%);
}

/* Deliberately not positioned. The still is pinned with inset: 0 and has to
   measure that against the card; give the link a position and the link becomes
   the containing block instead, and the picture collapses to the height of the
   title. As a flex item the link takes a z-index without one. */
.athar-scope .athar-pcard__link {
	z-index: 2;
	color: inherit;
	text-decoration: none;
}

/* The whole card is the target, but only the title is the accessible link. */
.athar-scope .athar-pcard__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.athar-scope .athar-pcard__body,
.athar-scope .athar-pcard__pills {
	opacity: 0;
	translate: 0 0.5rem;
	transition:
		opacity var(--l-dur-1) var(--l-ease),
		translate var(--l-dur-1) var(--l-ease);
}

.athar-scope .athar-pcard.is-on .athar-pcard__body,
.athar-scope .athar-pcard.is-on .athar-pcard__pills {
	opacity: 1;
	translate: 0 0;
}

/* No pointer, no reveal to wait for. The tap that would have shown the name
   is the same tap that opens the project, so on a touch screen the card keeps
   saying what it is. */
@media (hover: none) {
	.athar-scope .athar-pcard::before,
	.athar-scope .athar-pcard__body,
	.athar-scope .athar-pcard__pills {
		opacity: 1;
		translate: 0 0;
	}
}

.athar-scope .athar-pcard__body {
	display: block;
	padding: var(--athar-gap) var(--athar-gap) 0;
	text-align: start;
}

.athar-scope .athar-pcard__client {
	display: block;
	margin-block-end: 0.4em;
	font-size: var(--l-t-meta);
	letter-spacing: var(--l-track-meta);
	text-transform: uppercase;
	color: var(--l-quiet);
	transition: color var(--l-dur-1) var(--l-ease);
}

.athar-scope .athar-pcard.is-on .athar-pcard__client {
	color: var(--l-yellow);
}

.athar-scope .athar-pcard__title {
	display: block;
	margin: 0;
	font-family: var(--l-display);
	font-size: var(--athar-h-s);
	font-weight: var(--l-w-mid);
	line-height: var(--l-lh-head);
	text-wrap: balance;
}

.athar-scope .athar-pcard__pills {
	position: relative;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	margin: 0;
	padding: 0.5rem var(--athar-gap) var(--athar-gap);
	list-style: none;
}

/* Small. They are a footnote on a picture, not a second heading — and now
   that they only appear when the card is lit, they can afford to be quiet. */
.athar-scope .athar-pcard__pill {
	padding: 0.22em 0.6em;
	border: 1px solid rgb(237 237 233 / 0.24);
	border-radius: var(--l-radius-pill);
	font-size: 0.6rem;
	letter-spacing: 0.05em;
	line-height: 1.5;
	color: var(--l-quiet);
}

/* The warm spill belongs to the card, so it travels with it and never becomes
   a plane of its own. */
.athar-scope .athar-pcard.is-on {
	box-shadow: 0 18px 60px -18px rgb(246 208 13 / 0.4);
	translate: 0 -3px;
}

/* ============================================================= Athar: cta */

.athar-scope .lamba-cta {
	padding-block: var(--l-rhythm);
	text-align: center;
}

.athar-scope .lamba-cta__inner {
	max-inline-size: var(--athar-measure);
	margin-inline: auto;
}

.athar-scope .lamba-cta__heading {
	margin: 0;
	font-family: var(--l-display);
	font-size: var(--l-t-display);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	line-height: var(--l-lh-display);
	text-wrap: balance;
}

.athar-scope .lamba-cta__text {
	margin-block: var(--athar-gap-tight) 0;
	color: var(--l-quiet);
	text-wrap: pretty;
}

/* The pill button, exactly as their own case-study layout draws it: solid
   brand yellow, black type, and an arrow that follows the reading direction.
   .athar-button is the plugin's own button, used by the cover and the shipped
   call to action; it is dressed here rather than in a second rule so the two
   cannot drift apart. */
.athar-scope .lamba-cta__go,
.athar-scope .athar-button {
	display: inline-flex;
	align-items: center;
	gap: 0.6em;
	margin-block-start: var(--athar-gap);
	padding: 0.75em 1.5em;
	border-radius: var(--l-radius-pill);
	background: var(--l-yellow);
	color: var(--l-black);
	font-weight: var(--l-w-mid);
	text-decoration: none;
	transition:
		gap var(--l-dur-1) var(--l-ease),
		box-shadow var(--l-dur-2) var(--l-ease);
	box-shadow: 0 0 0 rgb(246 208 13 / 0);
}

.athar-scope .lamba-cta__go:hover,
.athar-scope .lamba-cta__go:focus-visible,
.athar-scope .athar-button:hover,
.athar-scope .athar-button:focus-visible {
	gap: 1em;
	box-shadow: 0 0 34px -4px rgb(246 208 13 / 0.55);
}

/* The arrow points the way the text runs, and the text runs both ways. */
.athar-scope .lamba-cta__go [aria-hidden] {
	display: inline-block;
	scale: -1 1;
}

[dir="ltr"] .athar-scope .lamba-cta__go [aria-hidden] {
	scale: 1 1;
}

/* ===================================================================== wire

   The quote, expressing itself.

   «من أول ما نشبك الفيش لين نشغل اللمبة». A cord runs under the line from the
   edge of the screen — the current arrives from outside the page, which is why
   nothing draws a plug: the plug is the edge — and as the section climbs the
   screen the light travels the cord, through the words in the order they are
   read, and reaches the lamp at the end.

   All of it hangs off one number, --p, from 0 to 1. It defaults to 1, so with
   no script the line is lit, the cord is drawn and the lamp is on: the served
   state is the finished state.

   The words are lit by a gradient clipped to the glyphs, not by a box sliding
   over them: a box would have a moving edge across the letterforms, and Arabic
   joins — an edge across a joined word cuts a letter in half rather than
   revealing it. Clipped to the text, the light is inside the strokes.
   ======================================================================= */

.athar-scope .lamba-wire {
	--p: 1;
	/* Physical, because gradients and transform-origin are. This site is read
	   right to left, so the current enters from the right. */
	--wire-from: to left;
	--wire-root: right;

	position: relative;
	max-inline-size: none;
	margin-inline: 0;
	padding-block: var(--l-rhythm);
	padding-inline: var(--l-gutter);
	/* Athar rules a quote off with a bar down its side, from a token this site
	   feeds. A wire does not need a margin note. */
	border-inline-start: 0;
	padding-inline-start: var(--l-gutter);
}

[dir="ltr"] .athar-scope .lamba-wire {
	--wire-from: to right;
	--wire-root: left;
}

.athar-scope .lamba-wire__line {
	margin: 0;
	max-inline-size: 22ch;
	font-family: var(--l-display);
	font-size: var(--l-t-display);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	/* Looser than the display leading. Two lines of this size set at 1.14 sit
	   on top of each other, and this is a sentence to be walked through, not a
	   headline to be taken in at once. */
	line-height: 1.34;
	text-wrap: balance;

	/* Three stops that move together: what the light has passed, the point it
	   is at, and what it has not reached. */
	background-image: linear-gradient(
		var(--wire-from),
		var(--l-text) 0%,
		var(--l-text) calc(var(--p) * 100% - 5%),
		var(--l-yellow) calc(var(--p) * 100%),
		var(--l-quiet) calc(var(--p) * 100% + 6%),
		var(--l-quiet) 100%
	);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* Safari once needed the prefixed pair to keep the text visible at all; if a
   browser ever fails the clip, this keeps the words readable rather than
   invisible. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
	.athar-scope .lamba-wire__line {
		background-image: none;
		color: var(--l-text);
	}
}

.lamba-wire__run {
	position: relative;
	display: flex;
	align-items: center;
	/* Out to the screen's edges from inside whatever column holds it, the same
	   arithmetic Athar's own full-bleed uses. */
	margin-inline: calc(50% - var(--athar-vw, 100vw) / 2);
	inline-size: var(--athar-vw, 100vw);
	margin-block-start: clamp(1.75rem, 5vh, 3.25rem);
}

/* Half the screen, not all of it. The lamp sits at the end of the cord, and
   the end of the cord is now the middle of the page — so the whole run lands
   under the words above it instead of trailing the lamp off to the far edge,
   where it read as something that had come loose rather than as the thing the
   sentence arrives at. */
.lamba-wire__cord {
	position: relative;
	flex: 0 1 auto;
	inline-size: calc(50% - clamp(1.6rem, 3.5vw, 3rem));
	block-size: 1px;
	background: var(--l-rule);
}

/* The live length of it. A scale rather than a width: it stays on the
   compositor, and a hairline that animates its width shimmers. */
.lamba-wire__cord::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--l-yellow);
	box-shadow: 0 0 14px rgb(246 208 13 / 0.55);
	transform: scaleX(var(--p));
	transform-origin: var(--wire-root);
}

.lamba-wire__lamp {
	flex: 0 0 auto;
	display: block;
	padding-inline-start: clamp(0.6rem, 2vw, 1.25rem);
	/* It comes on at the end of the run, not gradually along it: a lamp is on
	   or it is off. */
	opacity: calc(0.18 + clamp(0, (var(--p) - 0.82) * 5.6, 1) * 0.82);
	transition: opacity var(--l-dur-1) var(--l-ease);
}

.lamba-wire__lamp .lamba-mark {
	inline-size: clamp(2.6rem, 5vw, 4rem);
}

/* The attribution, when there is one, sits under the words and not under the
   wire — the wire is the end of the section. */
.athar-scope .lamba-wire .athar-quote__by {
	order: -1;
	margin-block-start: 1.1em;
	color: var(--l-faint);
}

/* ===================================================================== sign

   The slogan, switching on.

   «بس شغّلها» — just turn it on. It was set as a large centred line, which is
   the one thing the sentence asks it not to be. Now it strikes: dark until the
   section arrives, then the catch a tube light has before it holds — up, dip,
   up, steady. The same shape as the card strike and the same shape as a real
   lamp, which is why it reads as switching on rather than as fading in.

   Gated on .lamp-js, because a sign that never receives its class must not be
   left dark: with no script the line is simply lit.
   ======================================================================= */

.lamp-js .athar-scope .lamba-marquee:not(.is-in) .lamba-marquee__line {
	color: rgb(237 237 233 / 0.14);
	text-shadow: none;
}

.lamp-js .athar-scope .lamba-marquee.is-in .lamba-marquee__line {
	animation: lamba-sign 1.1s var(--l-ease) both;
}

@keyframes lamba-sign {
	0%   { color: rgb(237 237 233 / 0.14); text-shadow: none; }
	9%   { color: var(--l-text); text-shadow: 0 0 28px rgb(246 208 13 / 0.55); }
	14%  { color: rgb(237 237 233 / 0.22); text-shadow: none; }
	21%  { color: var(--l-text); text-shadow: 0 0 34px rgb(246 208 13 / 0.6); }
	27%  { color: rgb(237 237 233 / 0.4); text-shadow: none; }
	38%  { color: var(--l-text); text-shadow: 0 0 30px rgb(246 208 13 / 0.5); }
	100% { color: var(--l-text); text-shadow: 0 0 20px rgb(246 208 13 / 0.3); }
}

/* ==================================================== Athar: quiet the rest

   Types this site does not redraw still have to belong to it. */

.athar-scope .athar-text h2,
.athar-scope .athar-text h3,
.athar-scope .athar-split__heading {
	font-family: var(--l-display);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	line-height: var(--l-lh-head);
}

.athar-scope .athar-quote {
	max-inline-size: var(--athar-measure-wide);
	font-family: var(--l-display);
	font-size: var(--l-t-h2);
	font-weight: var(--l-w-body);
	line-height: var(--l-lh-display);
	text-wrap: pretty;
}

.athar-scope .athar-image img,
.athar-scope .athar-split img,
.athar-scope .athar-gallery img {
	border-radius: var(--l-radius);
	filter: var(--l-photo);
}

/* ============================================================= case study

   The still first and edge to edge, then the name against a row of facts.
   Everything below is composed in the studio, so this file stops here.
   ======================================================================= */

.case-hero {
	position: relative;
	/* Out to the viewport edges from inside whatever column holds it, the same
	   arithmetic Athar's own full-bleed uses. --athar-vw is the viewport minus
	   its scrollbar; 100vw includes the scrollbar and overflows by ~15px. */
	margin-inline: calc(50% - var(--athar-vw, 100vw) / 2);
	inline-size: var(--athar-vw, 100vw);
	block-size: min(72vh, 44rem);
	overflow: hidden;
	background: var(--l-black);
}

.case-hero__img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	filter: var(--l-photo);
}

/* The type below has to survive whatever the still happens to be. */
.case-hero__veil {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to bottom,
		rgb(28 28 26 / 0.45) 0%,
		rgb(28 28 26 / 0.1) 40%,
		rgb(28 28 26 / 0.92) 100%
	);
}

.case-head {
	position: relative;
	z-index: 1;
	margin-block-start: var(--l-rhythm-tight);
}

/* Only a head that actually has a still above it climbs into it. Without the
   guard a project with no thumbnail pulled its own title up under the sticky
   header, which is not a hero overlap, it is a collision. */
.case-head--under {
	margin-block-start: calc(var(--l-rhythm) * -0.35);
}

/* The project title when the story opens with its own cover: still the page's
   one <h1> for a screen reader and for search, just not drawn twice. */
.case-title--quiet {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.case-title {
	margin: 0;
	font-family: var(--l-display);
	font-size: var(--l-t-display);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-hero);
	line-height: var(--l-lh-display);
	text-wrap: balance;
}

.case-facts {
	display: grid;
	gap: var(--l-rhythm-tight);
	grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
	margin-block: var(--l-rhythm-tight) 0;
	padding-block-start: var(--l-rhythm-tight);
}

.case-fact__label {
	font-size: var(--l-t-meta);
	letter-spacing: var(--l-track-meta);
	text-transform: uppercase;
	color: var(--l-yellow);
}

.case-fact__value {
	margin: 0.5em 0 0;
	font-size: var(--l-t-small);
	color: var(--l-quiet);
}

/* ============================================== this site's own sections */

/* One sentence, edge to edge, and the light passing across it. */
.athar-scope .lamba-marquee {
	padding-block: var(--l-rhythm);
	padding-inline: var(--l-gutter);
	text-align: center;
}

.athar-scope .lamba-marquee__line {
	max-inline-size: 20ch;
	margin-inline: auto;
	margin-block: 0;
	font-family: var(--l-display);
	font-size: var(--l-t-display);
	font-weight: var(--l-w-display);
	letter-spacing: var(--l-track-display);
	line-height: var(--l-lh-display);
	text-wrap: balance;
}

/* The client wall. 38 white-on-transparent logos: they need no treatment on
   this ground beyond being held back until they are looked at. */
.athar-scope .lamba-clients {
	padding-block: var(--l-rhythm);
}

.athar-scope .lamba-clients__grid {
	display: grid;
	gap: clamp(1.5rem, 4vw, 3.5rem) clamp(1rem, 3vw, 2.5rem);
	grid-template-columns: repeat(auto-fill, minmax(min(8rem, 40%), 1fr));
}

/* No cell. The wall used to be boxes on a one-pixel grid, which is a table
   of logos; thirty-seven marks with air around them is a wall. */
.athar-scope .lamba-clients__cell {
	display: grid;
	place-items: center;
	block-size: clamp(2.6rem, 5vw, 3.6rem);
}

/* Their logos arrive white on transparent, so they need no treatment at all
   beyond being held back until they are looked at — which is the same thing
   the project cards do, and the same thing the whole site is about. A logo
   sitting at half strength on this ground is not dim, it is waiting. */
.athar-scope .lamba-clients__cell img {
	max-block-size: 100%;
	max-inline-size: 100%;
	inline-size: auto;
	block-size: auto;
	object-fit: contain;
	opacity: calc(0.24 + var(--lit) * 0.24);
	transition:
		opacity var(--l-dur-1) var(--l-ease),
		filter var(--l-dur-1) var(--l-ease);
}

.athar-scope .lamba-clients__cell:hover img {
	opacity: 1;
	/* The catch a lamp has before it holds, at logo scale. */
	filter: drop-shadow(0 0 12px rgb(246 208 13 / 0.35));
}
