/* About — styles
   Generated by the page composer — do not edit.
   Concatenated in load order:
     css/about/sections/_base.css
     css/about/sections/_hero.css
     css/about/sections/_board.css
     css/about/sections/_tour.css
     css/about/sections/tour-left.css
     css/about/sections/moments.css
     css/about/sections/stack.css
     css/about/sections/client-wall.css
     css/about/sections/principles.css
     css/about/sections/now.css
     css/about/pages/_seams.css
*/

/* ===== css/about/sections/_base.css ===== */
/* ==========================================================================
   About section library — shared base

   Ships on every about-lab page before the section files. Every rule is scoped
   under html.about-v2, the root class the builder puts on <html>, and every class
   it defines carries the ab- prefix, so nothing here can reach the production
   about.html or a contact-lab page.

   It is the sibling of css/contact/sections/_base.css, not a copy of it: the two
   labs share a house style but not a subject — contact is instruments (clocks,
   bands, checkboxes), about is photographs, names and dates — so their bases are
   allowed to drift. What they do share on purpose is the palette and the vertical
   rhythm, restated here in about's own names so the two pages read as one site.
   ========================================================================== */

html.about-v2 {
	/* the vertical rhythm between body sections: sections pad themselves with this */
	--ab-row: clamp(96px, 11vw, 176px);
	--ab-row-small: clamp(56px, 6vw, 96px);
	/* the same greens and greys the contact lab and the homepage use */
	--ab-green: #3ecf8e;
	--ab-grey: #999999;
	--ab-grey-2: #8a8a8a;
	--ab-grey-3: #767676;
	--ab-plate: #2b2b2b;
	--ab-hair: rgba(255, 255, 255, 0.14);
	--ab-prose: #bdbdbd;
	--ab-bg: #171717;
}

/* sections own their spacing; the template's trailing pad would double the last seam */
html.about-v2 #main-content { padding-bottom: 0; }

/* full-bleed sections (a band, a marquee) need the column's clip off */
html.about-v2 #main-page-content { overflow: visible; }

/* ---------- one trap worth naming -----------------------------------------

   This template styles bare elements, so an ordinary tag can arrive pre-positioned.

   Do not use <header> (or <footer>) inside a section. style.css line 1545 styles the
   bare element as the site's navigation bar — `position: fixed; height: 120px;
   z-index: 1000; pointer-events: none` — so a <header> wrapping a section's title
   silently becomes an invisible fixed bar at the top of the viewport, and the
   section renders with its heading missing and the space it would have taken
   collapsed. A <div> is the right wrapper.

   <figcaption> is usable but not free: style.css line 371 pins it to the bottom
   right of its figure (`position: absolute; bottom: 0; right: 0`) with its own
   background and 10px type. Place one yourself and release BOTH edges — setting
   `top` while leaving the inherited `bottom: 0` stretches it the full height.

   <section>, <figure>, <ol>, <dl> and <div> carry nothing.
   -------------------------------------------------------------------------- */

/* ---------- helpers ------------------------------------------------------- */

/* screen-reader-only text */
html.about-v2 .ab-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* a body section's root: it pads itself vertically and keeps the column's horizontal edges */
html.about-v2 .ab-section {
	position: relative;
	padding: var(--ab-row) 0;
}
html.about-v2 .ab-section.ab-section-flush { padding: 0; }

/* full-bleed helper: a block as wide as the viewport inside the padded column */
html.about-v2 .ab-bleed {
	width: 100vw;
	margin-left: calc(50% - 50vw);
}

/* the site's focus ring, on every control a section authors */
html.about-v2 .ab-section :is(a, button, input, select, textarea, [tabindex]):focus-visible,
html.about-v2 #hero :is(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 2px solid #fff;
	outline-offset: 4px;
}

/* A one-line cursor label (S.bindCursorLabel called with a single string). The template's
   #ball p is position:static and #ball p.first adds padding-top:22px to sit under a second
   line, so a single-line label needs the positioned box and the padding reset. Same fix as
   the contact base makes for .cs-ball-single — the shared _shared.js emits that class, so
   this rule restates it for pages that carry only the about base. */
html.about-v2 #ball p.cs-ball-single {
	position: relative;
	padding-top: 0;
	top: 50%;
	transform: translateY(-50%);
}

/* ---------- shared type roles --------------------------------------------- */

/* a section heading, a lead under it, and a prose block. A section whose idea IS the
   type sets its own; everything else takes these so the page reads as one voice. */
/* The section heading. Capped on purpose.

   The template sizes only two things in viewport units — `.hero-title` and
   `.next-hero-title`, both 5vw — and every other size in content.css is fixed px,
   stepped down by max-width breakpoints. Nothing there grows above 1467.

   This library put viewport units into the *body*, which means a heading keeps
   growing while the prose beside it (18px), the vertical rhythm (`--cs-row` caps at
   176px around a 1600px viewport) and the measure (`.cs-prose` max-width: 720px) all
   stand still. The composition does not scale up on a large screen, it distorts:
   heading-to-prose went from 2.2x at 1440 to 3.2x at 2560.

   `min()` rather than a smaller size, so nothing at or below 1440 moves — the cap is
   the value this already had at 1440, which is the width every review was done at. */
html.about-v2 .ab-h2 {
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: min(calc(1rem + 1.6vw), 39px);
	line-height: 1.1;
	font-weight: normal;
	color: #fff;
	margin: 0 0 0.6em;
}
html.about-v2 .ab-lead {
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 18px;
	line-height: 30px;
	color: var(--ab-grey);
	max-width: 640px;
	margin: -0.2em 0 0;
}
html.about-v2 .ab-prose {
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 18px;
	line-height: 30px;
	color: var(--ab-prose);
	max-width: 720px;
	margin: 0;
}
html.about-v2 .ab-prose + .ab-prose { margin-top: 1em; }

/* the small all-caps label that dates a block or names a column */
html.about-v2 .ab-kicker {
	display: block;
	font-family: 'Poppins', sans-serif;
	font-weight: 500;
	font-size: 12px;
	line-height: 20px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ab-grey-3);
	margin: 0 0 14px;
}

/* the hairline every section rules a row or a column with */
html.about-v2 .ab-rule {
	display: block;
	height: 1px;
	border: 0;
	margin: 0;
	background-color: var(--ab-hair);
}

@media (max-width: 767px) {
	html.about-v2 .ab-h2 { font-size: calc(1rem + 3.2vw); }
	html.about-v2 .ab-lead,
	html.about-v2 .ab-prose { font-size: 15px; line-height: 24px; }
}

/* ---------- the column edge ----------------------------------------------- */

/* One column edge, at every width. The template caps and centres `.content-max-width`
   at 1320px, but `#main-page-content` carries `max-width: none` on an id selector
   (css/content.css 501), which outranks the class — so the body column never caps while
   a hero caption using the same class does, and at 1920 the caption sits 300px right of
   every section under it. Neutralising the cap on our own hero captions makes hero and
   body share one left edge at every width. Measured and corrected in the contact lab;
   the same chrome, so the same correction. */
html.about-v2 #hero-caption.content-max-width,
html.about-v2 #hero-caption.content-full-width {
	max-width: none;
}

/* ---------- the harness --------------------------------------------------- */

/* the stand-in hero used when a body section is captured alone (build-about-page.mjs --section) */
html.about-v2 .ab-harness-hero #hero-caption {
	height: auto;
	min-height: 0;
	padding: 150px 60px 24px;
}
@media only screen and (min-width: 1467px) {
	html.about-v2 .ab-harness-hero #hero-caption { padding-left: 80px; padding-right: 80px; }
}
@media only screen and (max-width: 1024px) {
	html.about-v2 .ab-harness-hero #hero-caption { padding-left: 40px; padding-right: 40px; }
}
@media only screen and (max-width: 767px) {
	html.about-v2 .ab-harness-hero #hero-caption { padding-left: 30px; padding-right: 30px; }
}
@media only screen and (max-width: 479px) {
	html.about-v2 .ab-harness-hero #hero-caption { padding-left: 20px; padding-right: 20px; }
}
html.about-v2 .ab-harness-hero .hero-title {
	font-family: 'Poppins', sans-serif;
	font-size: 12px;
	line-height: 20px;
	letter-spacing: 0.04em;
	color: var(--ab-grey-3);
	margin: 0;
}


/* ===== css/about/sections/_hero.css ===== */
/* ==========================================================================
   About section library — the hero shell every about hero shares

   Three heroes open the about pages — a drawn board, a portrait card, a
   photograph — and they should differ in their subject, not in where the name
   sits. So the arrangement is settled once here and each hero's own stylesheet
   declares only how big its subject is and where it hangs.

   The arrangement is the contact page's, on purpose: caption at the top and
   centred, the subject behind and below it, the template's scroll arrow at the
   foot of the band. A visitor moving from Contact to About should feel the same
   page continuing.

   A hero owns its size through custom properties on its own #hero, never by
   restating a rule here — every hero stylesheet loads after this file, so a
   width set directly would out-order the mobile stack at the bottom and keep a
   desktop size on a phone.
   ========================================================================== */

html.about-v2 #hero.ab-hero #hero-caption {
	height: 100vh;
	padding-top: 150px;
	padding-bottom: 0;
	z-index: 2;
	/* the caption is a sheet over the subject; only its controls take the pointer */
	pointer-events: none;
}

html.about-v2 #hero.ab-hero #hero-caption .inner {
	vertical-align: top;
}

/* Anything clickable in the caption has to opt back in. `.hero-arrow` is a <div>,
   not a link or a button, so listing only a/button left the template's scroll-down
   control dead: bound by js/common.js, styled, visible, and unable to receive a
   click. (The contact lab had the identical bug.) */
html.about-v2 #hero.ab-hero #hero-caption a,
html.about-v2 #hero.ab-hero #hero-caption button,
html.about-v2 #hero.ab-hero #hero-caption .hero-arrow {
	pointer-events: auto;
}

/* the template centres the arrow at the foot of the band through
   `.text-align-center .hero-arrow`; it only needs lifting off the very edge */
html.about-v2 #hero.ab-hero .hero-arrow {
	bottom: 40px;
}

/* ---------- the availability light ---------------------------------------- */

/* the same 7px green dot the homepage caption and the contact hero carry */
html.about-v2 .ab-dot {
	display: inline-block;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--ab-green);
	box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.55);
	margin: 0 10px 0 0;
	vertical-align: 1px;
}

/* the subtitle quotes a month in <strong>; it is a value, not an emphasis */
html.about-v2 #hero.ab-hero .hero-subtitle strong {
	font-weight: inherit;
}

/* ---------- the subject --------------------------------------------------- */

/* centred, low, behind the type — the same place the contact hero puts its map */
html.about-v2 #hero.ab-hero .ab-subject {
	position: absolute;
	top: var(--ab-subject-top, 60%);
	left: 50%;
	transform: translate(-50%, -50%);
	width: var(--ab-subject-w, 62vh);
	max-width: var(--ab-subject-max, 52vw);
	z-index: 1;
}

/* ---------- breakpoints — the template's own ------------------------------ */

@media only screen and (max-width: 1466px) {
	html.about-v2 #hero.ab-hero .ab-subject { top: var(--ab-subject-top-narrow, 61%); }
}

@media only screen and (max-width: 1024px) {
	/* the hero stacks: the subject is the second child in the markup, so the column
	   is reversed to keep the name first — the same reading order as the wide layout */
	html.about-v2 #hero.ab-hero #hero-styles {
		display: flex;
		flex-direction: column-reverse;
		justify-content: flex-start;
		min-height: 100vh;
		padding: 120px 0 70px;
		box-sizing: border-box;
	}

	html.about-v2 #hero.ab-hero .ab-subject {
		position: static;
		transform: none;
		width: auto;
		max-width: none;
		margin: 40px 40px 0;
	}

	/* only the vertical padding goes: the caption's own column class still owns the
	   horizontal padding that keeps the name off the screen edge */
	html.about-v2 #hero.ab-hero #hero-caption {
		height: auto;
		padding-top: 0;
		padding-bottom: 0;
	}

	/* The arrow goes below 1024. It is a scroll affordance for a full-height band,
	   and in the stacked layout it cannot be one: the caption is on top and the
	   subject below it, so an arrow inside the caption lands in the *middle* of the
	   hero, pointing at a picture rather than at the page. A phone does not need
	   telling that a page scrolls. (The contact lab keeps its arrow on mobile
	   because its stack puts the caption last, so the arrow is genuinely at the
	   foot — a hero that stacks the other way cannot borrow that.) */
	html.about-v2 #hero.ab-hero .hero-arrow {
		display: none;
	}
}

@media only screen and (max-width: 767px) {
	html.about-v2 #hero.ab-hero .ab-subject { margin: 34px 30px 0; }
}

@media only screen and (max-width: 479px) {
	html.about-v2 #hero.ab-hero .ab-subject { margin: 30px 20px 0; }
	html.about-v2 #hero.ab-hero .hero-title { font-size: 11vw; line-height: 12vw; }
}


/* ===== css/about/sections/_board.css ===== */
/* ==========================================================================
   About section library — the board family, shared base (ab-board)

   Two sections draw the same object: `board-hero` plays it full size behind the
   name, `moves` shows it small beside the sentence it illustrates. Everything that
   makes them one drawing lives here — the hairline weights, the square wash, the
   knight's line and its stops. Each section's own stylesheet holds nothing but its
   composition.

   The entrance is the contact lab's js/contact/sections/_trail.js, unchanged: the
   beats are written in the markup as data-draw / data-fade and that module builds
   the timeline from them. It needs one structural hook, the measured box, which is
   `.ab-plot` here. Everything below starts *visible*, so a page whose GSAP never
   arrives still shows a finished board.

   Geometry contract: `.ab-canvas` takes its aspect ratio from --ab-board-ratio, set
   in the markup next to the svg's viewBox, so the two can never drift.
   ========================================================================== */

html.about-v2 .ab-board { position: relative; }
html.about-v2 .ab-plot { position: relative; }

html.about-v2 .ab-canvas {
	position: relative;
	aspect-ratio: var(--ab-board-ratio, 640 / 640);
	overflow: visible;
}

html.about-v2 .ab-svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

/* every stroke is measured in screen pixels, so a hairline stays a hairline at any
   size — and _trail.js computes its dash pattern on that same assumption */
html.about-v2 .ab-svg :is(path, circle, rect, line) { vector-effect: non-scaling-stroke; }

/* ---------- the board ----------------------------------------------------- */

/* the outer frame: one unbroken stroke, the brightest line in the drawing */
html.about-v2 .ab-frame {
	fill: none;
	stroke: #fff;
	stroke-width: 1.5px;
	stroke-linejoin: round;
	stroke-linecap: round;
	opacity: 0.55;
}

/* the sixty-three interior lines, a third of the frame's weight */
html.about-v2 .ab-hair {
	fill: none;
	stroke: #fff;
	stroke-width: 1px;
	stroke-linecap: round;
	opacity: 0.16;
}

/* the dark squares: a wash, never a colour — the board should read as drawn, not printed */
html.about-v2 .ab-squares rect {
	fill: #fff;
	fill-opacity: 0.06;
	stroke: none;
}

/* ---------- the knight ---------------------------------------------------- */

/* the seven moves as one line. Green is the site's accent — the same #3ecf8e the
   availability dot and the contact page's overlap band use. */
html.about-v2 .ab-move {
	fill: none;
	stroke: var(--ab-green);
	stroke-width: 2px;
	stroke-linejoin: round;
	stroke-linecap: round;
}

/* a square the knight stood on */
html.about-v2 .ab-stop {
	fill: var(--ab-green);
	stroke: none;
}
html.about-v2 .ab-stop-first {
	fill: none;
	stroke: var(--ab-green);
	stroke-width: 2px;
}
html.about-v2 .ab-stop-last { fill: #fff; }

/* the ring that closes the move: it arrives scaled down and opens onto the square */
html.about-v2 .ab-ring {
	fill: none;
	stroke: #fff;
	stroke-width: 1.5px;
	opacity: 0.5;
}

/* ---------- reduced motion ------------------------------------------------- */

/* _trail.js plays a timeline; when the visitor asks for less movement the board is
   simply there. The module's own guard is GSAP's global respect for the query, so
   this rule only makes sure nothing is left mid-draw if the timeline never runs. */
@media (prefers-reduced-motion: reduce) {
	html.about-v2 .ab-svg :is(path, circle, rect, g) {
		stroke-dasharray: none !important;
		stroke-dashoffset: 0 !important;
	}
}


/* ===== css/about/sections/_tour.css ===== */
/* ==========================================================================
   About section library — the tour family, shared base (tr)

   Seven variants of one hero: a knight crossing a chessboard. They share every
   weight and colour here, and each variant's own stylesheet holds nothing but
   what makes it that variant.

   The first board hero drew the route and nothing else, and the note on it was
   that a web of green lines does not read as "a knight moving on a board". So
   the piece itself is now on the board at every moment, the board is drawn a
   little heavier, and the route is drawn a little lighter — the knight is the
   subject and the route is its record, not the other way round.

   Geometry contract: `.ab-canvas` takes its ratio from --ab-board-ratio, set in
   the markup beside the svg's viewBox, so the two cannot drift.
   ========================================================================== */

/* ---------- the board ----------------------------------------------------- */

/* heavier than the first version's 0.55: the board has to read as a board before
   anything drawn on it can mean anything */
html.about-v2 .tr-hero .ab-frame { opacity: 0.7; }
html.about-v2 .tr-hero .ab-hair { opacity: 0.22; }
html.about-v2 .tr-hero .ab-squares rect { fill-opacity: 0.11; }

/* the rank and file letters, for the variants that name them */
html.about-v2 .tr-coord {
	fill: var(--ab-grey-3);
	font-family: 'Poppins', sans-serif;
	font-size: 19px;
	letter-spacing: 0.08em;
}

/* ---------- squares the knight has been to -------------------------------- */

/* Two ways of answering "which squares are left". `.tr-visited` lights a square as
   it is landed on, so the board fills up behind the piece; `.tr-remaining` starts
   lit everywhere and goes out square by square, so what is still showing is what is
   still to do. Both paint under the grid lines, so a filled square is still a square.

   The transition is on the element, not in the timeline: the driver only flips
   opacity between 0 and 1 on every frame, and a bare flip of thirty-two squares in
   eight seconds strobes. A 0.45s ease turns each one into a soft arrival. */
html.about-v2 .tr-visited,
html.about-v2 .tr-remaining {
	stroke: none;
	transition: opacity 0.45s ease-out;
}
html.about-v2 .tr-visited {
	fill: var(--ab-green);
	fill-opacity: 0.22;
}
/* White at 0.1 disappeared into the checker wash it sits on — the two are within a
   few per cent of each other on this ground. 0.19 is the point at which a lit square
   and a dark one are unmistakable without the board turning grey. */
html.about-v2 .tr-remaining {
	fill: #fff;
	fill-opacity: 0.19;
}

/* ---------- the route ----------------------------------------------------- */

/* one continuous line, lighter than the knight so the piece stays the subject */
html.about-v2 .tr-trail {
	fill: none;
	stroke: var(--ab-green);
	stroke-width: 1.6px;
	stroke-linejoin: round;
	stroke-linecap: round;
	opacity: 0.75;
}

/* a square the knight has stood on */
html.about-v2 .tr-stop {
	fill: var(--ab-green);
	stroke: none;
	opacity: 0.9;
}

/* the square it started from */
html.about-v2 .tr-start {
	fill: none;
	stroke: var(--ab-green);
	stroke-width: 2px;
}

/* the move number a square takes as the knight lands on it */
html.about-v2 .tr-number {
	fill: #fff;
	font-family: 'Poppins', sans-serif;
	font-size: 21px;
	font-weight: 400;
	text-anchor: middle;
	opacity: 0.72;
}

/* the eight squares a knight on this square could move to */
html.about-v2 .tr-reach {
	fill: none;
	stroke: #fff;
	stroke-width: 1.6px;
	opacity: 0.8;
}

/* ---------- the piece ----------------------------------------------------- */

/* The piece carries its own white fill and black stroke inline (it is vendored
   artwork — see images/about/chess/NOTICE.md), so nothing here colours it. On this
   ground its black outline reads as the separation it needs from the green route. */

/* it sits above the board and casts just enough shadow to lift off the squares */
html.about-v2 .tr-knight { filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55)); }

/* every stroke measured in screen pixels, so a hairline stays a hairline — and the
   driver computes the trail's dash pattern on that same assumption */
html.about-v2 .tr-hero .ab-svg :is(path, circle, rect, line) { vector-effect: non-scaling-stroke; }
/* …except the piece, whose stroke is part of the artwork and is authored in its own
   800-unit space: under non-scaling-stroke its 29.2 would be 29.2 SCREEN pixels and
   the knight renders as a black blob. The selector has to carry `.tr-hero .ab-svg`
   as well — without them it is one class less specific than the rule above and loses,
   which is exactly how the blob got shipped. */
html.about-v2 .tr-hero .ab-svg .tr-knight :is(path, circle) { vector-effect: none; }

/* ---------- the caption and the readout ----------------------------------- */

/* The caption is allowed to be wider than the board it sits under — `left: 50%` +
   `translateX(-50%)` centres a block wider than its parent, which `margin: auto`
   cannot do.

   It sets on two lines on purpose. The copy runs to about 150 characters, which needs
   roughly 975px on one line: far wider than the 414px board it captions, and it would
   read as a strapline rather than a note. 600px breaks it into two even lines at about
   the board's own width, and `text-wrap: balance` keeps them even rather than leaving
   three words on the second. The board is sized and hung to leave room for both lines
   above the scroll arrow — see the placement block at the foot of this file. */
html.about-v2 .tr-note {
	position: relative;
	left: 50%;
	transform: translateX(-50%);
	width: max-content;
	max-width: min(600px, 88vw);
	text-wrap: balance;
	margin: 16px 0 0;
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 12px;
	line-height: 20px;
	letter-spacing: 0.06em;
	color: var(--ab-grey-3);
	text-align: center;
}

/* The square the knight is standing on, set into the caption line. It is fixed-width
   and right-aligned: the name changes sixty-four times and a caption that shifts
   sideways on every landing is unreadable. */
html.about-v2 .tr-square {
	display: inline-block;
	min-width: 2.4em;
	margin-right: 0.85em;
	padding: 2px 8px;
	border-radius: 3px;
	background: rgba(255, 255, 255, 0.09);
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: 13px;
	letter-spacing: 0.04em;
	text-align: center;
	color: #fff;
	font-variant-numeric: tabular-nums;
}

/* ---------- placement ------------------------------------------------------ */

/* The band has to hold four things in 100vh: the name, the line under it, the board,
   and a two-line caption clear of the template's scroll arrow (which sits 40px off the
   foot). At 46vh/65% the board's foot was at 792 of 900 and the second caption line
   landed on the arrow. 42vh/62% puts the foot at 747 and the caption at 763–803, which
   clears the arrow by a comfortable margin and still leaves the board the largest thing
   on the band.

   The 63.4% rather than a round 62% evens the two gaps around the board. Measured at
   1440x900: the subtitle's last line ended 24px above the frame and the file letters
   sat 34px above the caption, so the board reads as crowded from above. Ten pixels
   down settles it, and the caption's second line still clears the scroll arrow by
   about 35px. (The asymmetry is inherent: the svg keeps 32 units of margin on all
   four sides of the frame, but only the bottom one carries anything — the a-h
   letters — so the drawing's visual bottom edge is lower than its box implies.) */
html.about-v2 #hero.tr-hero {
	--ab-subject-w: 42vh;
	--ab-subject-max: 36vw;
	--ab-subject-top: 63.4%;
	--ab-subject-top-narrow: 63.4%;
}

@media only screen and (max-width: 1024px) {
	html.about-v2 #hero.tr-hero .tr-board { max-width: 400px; margin: 40px auto 0; }
}

@media only screen and (max-width: 767px) {
	html.about-v2 #hero.tr-hero .tr-board { max-width: 310px; margin-top: 34px; }
	html.about-v2 .tr-note { font-size: 11px; line-height: 18px; margin-top: 14px; }
	html.about-v2 .tr-square { font-size: 12px; }
	html.about-v2 .tr-number { font-size: 21px; }
	html.about-v2 .tr-coord { font-size: 19px; }
}

@media (prefers-reduced-motion: reduce) {
	html.about-v2 .tr-hero .ab-svg :is(path, circle, rect, g) {
		stroke-dasharray: none !important;
		stroke-dashoffset: 0 !important;
	}
}


/* ===== css/about/sections/tour-left.css ===== */
/* ==========================================================================
   About section — tour-left (tr09), tour lab

   The inverse: every square starts lit and goes out as the knight reaches it, so the lit squares are always the ones still to visit. The board empties instead of filling.

   Composition only: the board, the route, the piece and the placement are all in
   _tour.css and _board.css. Anything here is what makes this variant itself.
   ========================================================================== */


/* ===== css/about/sections/moments.css ===== */
/* ==========================================================================
   About section — moments (mm)

   The production page tells these three chapters through the template's pinned
   gallery: six full-bleed panes that pin and swap, photo then coloured card,
   photo then coloured card. It is a lot of machinery and a lot of scrolling for
   three short paragraphs, and the coloured cards (#63412c, #35445a, #410908) are
   the only place on the site where a block of flat colour appears.

   Here they are three rows instead — photograph beside text, alternating sides,
   each one dated. No pinning, no scroll hijack: the chapters pass at the speed
   the visitor is already scrolling, and the page stays the same dark ground as
   every other section.
   ========================================================================== */

html.about-v2 .mm-head { margin-bottom: clamp(48px, 6vw, 88px); }
html.about-v2 .mm-head .ab-lead { margin-top: 0; }

html.about-v2 .mm-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: clamp(64px, 8vw, 128px);
}

html.about-v2 .mm-chapter {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: clamp(32px, 4.5vw, 80px);
	align-items: center;
	margin: 0;
	padding: 0;
}

/* the middle chapter mirrors, so the eye crosses the column between the three */
html.about-v2 .mm-chapter:nth-child(even) .mm-figure { order: 2; }

html.about-v2 .mm-figure {
	position: relative;
	margin: 0;
}

/* the clipped box the photograph and any annotation on it live in; the figure
   itself stays unclipped so a caption can sit under it on a narrow screen */
html.about-v2 .mm-frame {
	position: relative;
	overflow: hidden;
	border-radius: 8px;
}

html.about-v2 .mm-photo {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 11;
	object-fit: cover;
	/* the photographs are brighter than everything around them; this is the only
	   place on the page where an image sits on the dark ground, so it is dimmed
	   to the ground's own key rather than punching a hole in it */
	filter: brightness(0.82) saturate(0.9);
	transform: scale(1.001); /* keeps the cover edge clean against the radius */
	transition: filter 0.6s ease-out, transform 0.6s ease-out;
}
html.about-v2 .mm-figure:hover .mm-photo {
	filter: brightness(1) saturate(1);
	transform: scale(1.03);
}

/* each photograph has its subject off-centre; the crop follows him rather than
   the frame. Measured against the production page's own object-position notes. */
html.about-v2 .mm-photo-trophy { object-position: 72% 50%; }
html.about-v2 .mm-photo-diploma { object-position: 50% 42%; }
html.about-v2 .mm-photo-andorra { object-position: 68% 40%; }

html.about-v2 .mm-text { max-width: 520px; }

html.about-v2 .mm-name {
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: clamp(28px, 2.6vw, 42px);
	line-height: 1.16;
	font-weight: normal;
	color: #fff;
	margin: 0 0 0.5em;
}

html.about-v2 .mm-copy + .mm-copy { margin-top: 1em; }

@media only screen and (max-width: 1024px) {
	html.about-v2 .mm-chapter {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}
	/* stacked, every chapter reads photo-then-text; the mirror only means
	   something when the two sit side by side */
	html.about-v2 .mm-chapter:nth-child(even) .mm-figure { order: 0; }
	html.about-v2 .mm-text { max-width: 620px; }
	html.about-v2 .mm-photo { aspect-ratio: 16 / 10; }
}

@media only screen and (max-width: 767px) {
	html.about-v2 .mm-photo { aspect-ratio: 4 / 3; }
}

/* ---------- the annotated chapter ------------------------------------------

   The trophy photograph has three boys in it and Remy is the one on the right,
   twenty years younger and not recognisable from anything else on the site. Six
   ways of marking him were built and looked at (arrow and chip, spotlight, marker
   ring, leader line, tag, legend, type on the image) and none of them earned its
   place: every one put ink on a photograph that reads perfectly well without it.
   A caption saying which one he is does the whole job.

   It is set right, under the picture, so it reads as a note on the photograph
   rather than as body copy — and because the thing it points at is on the right.

   The frame keeps the source image's native ratio (1075 x 785) rather than the
   row's 16/11, so `cover` crops nothing: a caption that says "the one on the
   right" should not be able to lose him off the edge at some width.
   -------------------------------------------------------------------------- */

html.about-v2 .mm-figure-annotated .mm-photo {
	aspect-ratio: 1075 / 785;
	object-position: 50% 50%;
}

/* style.css:371 styles the bare <figcaption> as a caption pinned to the bottom right
   of its figure — `position: absolute; bottom: 0; right: 0`, with its own background
   and 10px type. All of that has to be undone before it can simply sit under the
   picture. */
html.about-v2 .mm-note {
	position: static;
	bottom: auto;
	right: auto;
	z-index: auto;
	background: none;
	border: 0;
	margin: 14px 0 0;
	padding: 0;
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 13px;
	line-height: 21px;
	color: var(--ab-grey);
	text-align: right;
}

@media only screen and (max-width: 767px) {
	html.about-v2 .mm-note { margin-top: 12px; font-size: 12.5px; line-height: 20px; }
}


/* ===== css/about/sections/stack.css ===== */
/* ==========================================================================
   About section — stack (sk)

   The production page runs the stack past as two marquees: one big line of
   "TypeScript • React.js • Next.js • Node.js •" and one of everything else. A
   marquee is motion where a reader wants a list — you cannot scan it, you cannot
   copy it into a brief, and on the second pass it says nothing new.

   Four columns instead, named for what the thing is for. The four names the
   homepage leads with keep the larger size, so the section still has a headline
   and the rest reads as the detail under it.
   ========================================================================== */

html.about-v2 .sk-title { margin-bottom: 0.5em; }

/* the caveat before the list: the list is the answer to a question the section
   itself thinks is slightly the wrong question, and it says so */
html.about-v2 .sk-lead {
	max-width: 720px;
	margin: 0 0 clamp(32px, 4vw, 56px);
}
html.about-v2 .sk-lead em {
	font-style: italic;
	color: #ededed;
}

html.about-v2 .sk-columns {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(24px, 3vw, 56px);
	max-width: 1100px;
	border-top: 1px solid var(--ab-hair);
	padding-top: 30px;
}

html.about-v2 .sk-column .ab-kicker { margin-bottom: 20px; }

html.about-v2 .sk-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

html.about-v2 .sk-item {
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: 18px;
	line-height: 32px;
	color: var(--ab-prose);
}

/* the four the homepage leads with: same list, one step up in size and to white */
html.about-v2 .sk-item-lead {
	font-size: 24px;
	line-height: 38px;
	color: #fff;
}

/* ---- brand marks --------------------------------------------------------
   Five of the thirteen entries are products with an official logo; the other
   eight are practices, which have none and must not be given an invented one.
   So the mark is a fixed-width *slot* rather than a plain inline image: any
   column carrying a logo reserves the slot on every one of its lines, and
   Accessibility keeps the same left edge as React above it. Quality is
   practices all the way down and gets no slot — a gutter that never fills
   reads as a mistake rather than as alignment. */

html.about-v2 .sk-list-marked {
	--sk-slot: 26px;
	--sk-slot-gap: 14px;
	--sk-logo: 20px;
}

html.about-v2 .sk-list-marked .sk-item {
	display: flex;
	align-items: center;
	gap: var(--sk-slot-gap);
}

/* the lead four are a size up, so their marks are too, or the logo reads as an
   afterthought pinned to a bigger word */
html.about-v2 .sk-list-marked .sk-item-lead { --sk-logo: 23px; }

html.about-v2 .sk-mark {
	flex: 0 0 var(--sk-slot);
	display: flex;
	align-items: center;
	justify-content: center;
	height: var(--sk-logo);
}

/* the client wall's treatment, for the client wall's reason: five brand
   palettes at once would shout over a section whose whole job is to be
   scanned. The colour arrives on the line being pointed at.

   Every mark goes through the *same four functions in the same order*, with only
   the numbers varying, because `filter` interpolates pairwise: give the two ends
   of the transition filter lists of different lengths and the browser gives up on
   interpolating and cuts between them instead. GraphQL and Next.js each need a
   correction the other three do not, so a per-mark `filter:` of its own would
   have been exactly that mismatch — and both marks snapped rather than faded.
   Corrections are therefore expressed as variables inside one shared list. */
html.about-v2 .sk-logo {
	--sk-desaturate: 100%;
	--sk-flatten: 1;
	--sk-lift: 1;
	--sk-fade: 0.68;

	display: block;
	max-width: var(--sk-logo);
	max-height: var(--sk-logo);
	object-fit: contain;
	filter: grayscale(var(--sk-desaturate)) contrast(var(--sk-flatten)) brightness(var(--sk-lift)) opacity(var(--sk-fade));
	transition: filter 0.35s ease-out;
}

/* Per-mark corrections at rest, the client wall's problem again: one grey cannot
   serve five marks drawn to different densities. GraphQL is a thin magenta
   outline that all but vanishes under a flat 0.68, so it is lifted. */
html.about-v2 .sk-logo-graphql { --sk-lift: 1.8; --sk-fade: 0.82; }

/* Next.js needs `contrast()`, not `grayscale()`. Its mark is already black and
   white, so desaturating it changes nothing: it rendered as a near-black disc
   (mean luminance 29 against a ground of 23) lit by an N spiking to 220, while
   the four SVGs sit evenly at 88-112. Pulling contrast to a quarter collapses
   both poles toward mid-grey and lands it at 93 — Node.js's weight — with the N
   still a step lighter than the disc, so the mark stays readable. */
html.about-v2 .sk-logo-next { --sk-flatten: 0.25; --sk-lift: 1.15; --sk-fade: 0.75; }

/* hover returns every mark to its true rendering by neutralising all four
   numbers, so each one fades home through the same list it greys out along */
html.about-v2 .sk-item:hover .sk-logo {
	--sk-desaturate: 0%;
	--sk-flatten: 1;
	--sk-lift: 1;
	--sk-fade: 1;
}

/* a page that already makes the AI point in the lead blanks this var; an empty
   paragraph must then take no space rather than leaving a clamp of margin */
html.about-v2 .sk-closing:empty { display: none; }

html.about-v2 .sk-closing {
	max-width: 640px;
	margin: clamp(40px, 4.5vw, 68px) 0 0;
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 18px;
	line-height: 30px;
	color: var(--ab-grey);
}

@media only screen and (max-width: 1024px) {
	html.about-v2 .sk-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 40px; }
}

@media only screen and (max-width: 479px) {
	/* one column below 480: two columns of four items each leave a ragged, short
	   measure that reads worse than a single run */
	html.about-v2 .sk-columns { grid-template-columns: minmax(0, 1fr); row-gap: 34px; }
	html.about-v2 .sk-item { font-size: 16px; line-height: 28px; }
	html.about-v2 .sk-item-lead { font-size: 20px; line-height: 32px; }
	html.about-v2 .sk-list-marked { --sk-slot: 22px; --sk-slot-gap: 12px; --sk-logo: 16px; }
	html.about-v2 .sk-list-marked .sk-item-lead { --sk-logo: 20px; }
	html.about-v2 .sk-closing { font-size: 15px; line-height: 25px; }
}


/* ===== css/about/sections/client-wall.css ===== */
/* ==========================================================================
   About section — client-wall (cn)

   The production page shows these nine as logos alone, on a flex wrap, each one
   tuned by an id selector (#upply-logo, #pango-logo …) carrying its own width and
   its own brightness filter. Two problems: a visitor who does not already know a
   mark learns nothing from it, and every image is `alt="client"`, so a screen
   reader hears the word "client" nine times.

   So each cell is named. The logo is the picture and the name is the label, the
   image is decorative (alt="") because the name beside it already says who it is,
   and the per-client size and brightness corrections move from ids to classes so
   they travel with the markup instead of with the page.
   ========================================================================== */

html.about-v2 .cn-head { margin-bottom: clamp(40px, 5vw, 72px); }
html.about-v2 .cn-head .ab-lead { margin-top: 0; }

/* The grid rules itself with one hairline per cell edge rather than a border on
   each cell, which would double up between neighbours. Each cell draws its own
   top and left; the container draws the closing right and bottom. */
html.about-v2 .cn-grid {
	list-style: none;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	margin: 0;
	padding: 0;
	max-width: 1100px;
	border-right: 1px solid var(--ab-hair);
	border-bottom: 1px solid var(--ab-hair);
}

html.about-v2 .cn-cell {
	margin: 0;
	padding: 0;
	border-top: 1px solid var(--ab-hair);
	border-left: 1px solid var(--ab-hair);
}

html.about-v2 .cn-link {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 22px;
	min-height: 200px;
	padding: 36px 24px;
	box-sizing: border-box;
	text-decoration: none;
	transition: background-color 0.35s ease-out;
}
html.about-v2 .cn-link:hover { background-color: rgba(255, 255, 255, 0.04); }

html.about-v2 .cn-mark {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 64px;
}

html.about-v2 .cn-logo {
	display: block;
	width: 100%;
	height: 100%;
	max-width: 150px;
	object-fit: contain;
	/* grey at rest so nine different brand palettes do not fight each other or the
	   page; the colour arrives on the cell the visitor is actually looking at */
	filter: grayscale(100%) opacity(0.68);
	transition: filter 0.35s ease-out;
}
html.about-v2 .cn-link:hover .cn-logo { filter: grayscale(0%) opacity(1); }

/* Per-client corrections, carried from the production page's id rules. Some marks
   are drawn small inside a large canvas and some are near-black on transparent, so
   a single width and a single filter cannot serve all nine. */
html.about-v2 .cn-logo-ftv { max-width: 58px; }
html.about-v2 .cn-logo-eneance { max-width: 58px; }
html.about-v2 .cn-logo-ecocea { max-width: 116px; }
html.about-v2 .cn-logo-perfectstay { max-width: 150px; }
/* transparent PNGs whose mark is near-black: lifted off the ground before the grey,
   or they disappear into it */
html.about-v2 .cn-logo-upply { max-width: 116px; filter: grayscale(100%) brightness(2) opacity(0.68); }
html.about-v2 .cn-logo-pango { max-width: 92px; filter: grayscale(100%) contrast(0) brightness(2) opacity(0.68); }
html.about-v2 .cn-logo-moona { max-width: 70px; filter: grayscale(100%) contrast(0) brightness(2) opacity(0.68); }
html.about-v2 .cn-link:hover .cn-logo-upply { filter: grayscale(0%) brightness(2) opacity(1); }
html.about-v2 .cn-link:hover .cn-logo-pango,
html.about-v2 .cn-link:hover .cn-logo-moona { filter: grayscale(100%) contrast(0) brightness(2.4) opacity(1); }

/* IpsoSenso and Nobo shipped as JPEGs — light marks flattened onto a near-black
   rectangle (40,32,19) and (20,52,39). Near-black is not this page's black, so each
   one read as a faint grey card floating in its cell, and the production page's
   `brightness(200%)` only made the card brighter. Both are re-cut as PNGs with that
   ground keyed out and the colour un-premultiplied off it (images/about/clients-logos/
   *-logo-alpha.png), so they now need no correction at all beyond the shared one. */
html.about-v2 .cn-logo-ipsosenso { max-width: 96px; }
html.about-v2 .cn-logo-nobo { max-width: 92px; }

html.about-v2 .cn-name {
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 13px;
	line-height: 20px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ab-grey-3);
	text-align: center;
	transition: color 0.35s ease-out;
}
html.about-v2 .cn-link:hover .cn-name { color: #fff; }

@media only screen and (max-width: 767px) {
	html.about-v2 .cn-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	/* nine cells in two columns leave a lone one on the last row, and beside it an
	   empty half-cell that reads as a missing client. The odd one out takes the row. */
	html.about-v2 .cn-cell:last-child:nth-child(odd) { grid-column: span 2; }
	html.about-v2 .cn-link { min-height: 160px; padding: 26px 16px; gap: 16px; }
	html.about-v2 .cn-mark { height: 48px; }
	html.about-v2 .cn-name { font-size: 11px; letter-spacing: 0.08em; }
}


/* ===== css/about/sections/principles.css ===== */
/* ==========================================================================
   About section — principles (pp)

   Four claims, each with the one line that earns it. The sentences are the site's
   own — the hero paragraph on the production about page and the homepage caption
   — pulled out of the prose they were buried in and given a number each.

   A 2x2 rather than a column of four: these are four independent statements, not
   a sequence, and a numbered rail (which the contact page's `process` uses for
   four steps that *are* a sequence) would say the wrong thing about them.
   ========================================================================== */

html.about-v2 .pp-title { margin-bottom: clamp(28px, 3.4vw, 48px); }

html.about-v2 .pp-grid {
	list-style: none;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0;
	margin: 0;
	padding: 0;
	max-width: 1100px;
}

/* the rules are drawn by the items, so the grid needs no gap to keep them apart:
   each item owns its top rule and, in the second column, its left rule */
html.about-v2 .pp-item {
	margin: 0;
	padding: 34px 0 42px;
	border-top: 1px solid var(--ab-hair);
}
html.about-v2 .pp-item:nth-child(even) {
	padding-left: clamp(28px, 3.4vw, 56px);
	border-left: 1px solid var(--ab-hair);
}
html.about-v2 .pp-item:nth-child(odd) { padding-right: clamp(28px, 3.4vw, 56px); }

html.about-v2 .pp-num {
	display: block;
	font-family: 'Poppins', sans-serif;
	font-weight: 500;
	font-size: 12px;
	line-height: 20px;
	letter-spacing: 0.16em;
	color: var(--ab-grey-3);
	margin-bottom: 18px;
}

html.about-v2 .pp-claim {
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: clamp(22px, 1.9vw, 30px);
	line-height: 1.2;
	font-weight: normal;
	color: #fff;
	margin: 0 0 0.6em;
}

html.about-v2 .pp-line { max-width: 460px; }

@media only screen and (max-width: 767px) {
	/* one column: the left rule becomes meaningless and every item rules its top */
	html.about-v2 .pp-grid { grid-template-columns: minmax(0, 1fr); }
	html.about-v2 .pp-item:nth-child(even) { padding-left: 0; border-left: 0; }
	html.about-v2 .pp-item:nth-child(odd) { padding-right: 0; }
	html.about-v2 .pp-item { padding: 26px 0 32px; }
	html.about-v2 .pp-line { max-width: none; }
}


/* ===== css/about/sections/now.css ===== */
/* ==========================================================================
   About section — now (nw)

   The last section before the page-nav block, and the one place on About that
   asks for something. It answers "who would I be writing to, and is he even
   awake" with the two facts that settle it: the hour where he is, and the month
   he is free from.

   The clock is the display type here, so it needs tabular figures — without them
   the minute digits change width every tick and the whole block twitches once a
   minute.
   ========================================================================== */

html.about-v2 .nw-title { margin-bottom: clamp(28px, 3.4vw, 48px); }

html.about-v2 .nw-instrument {
	display: grid;
	grid-template-columns: minmax(0, auto) minmax(0, 1fr);
	gap: clamp(32px, 5vw, 88px);
	align-items: start;
	max-width: 1100px;
	border-top: 1px solid var(--ab-hair);
	padding-top: clamp(28px, 3.2vw, 44px);
}

html.about-v2 .nw-clock {
	display: block;
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: clamp(56px, 7.4vw, 116px);
	line-height: 1;
	color: #fff;
	/* the minutes tick; without tabular figures the block jumps every sixty seconds */
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum' 1;
	letter-spacing: -0.01em;
}

html.about-v2 .nw-place {
	display: block;
	margin-top: 16px;
	font-family: 'Poppins', sans-serif;
	font-weight: 500;
	font-size: 12px;
	line-height: 20px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ab-grey-3);
}

html.about-v2 .nw-state {
	margin: 0;
	font-family: 'basis_grotesque_promedium', sans-serif;
	font-size: clamp(21px, 1.9vw, 30px);
	line-height: 1.3;
	color: #fff;
	max-width: 520px;
}

html.about-v2 .nw-free {
	margin: 18px 0 0;
	font-family: 'Poppins', sans-serif;
	font-weight: 400;
	font-size: 16px;
	line-height: 28px;
	color: var(--ab-grey);
}

html.about-v2 .nw-actions { margin-top: clamp(28px, 3vw, 44px); }

@media only screen and (max-width: 767px) {
	html.about-v2 .nw-instrument {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}
	html.about-v2 .nw-free { font-size: 15px; line-height: 26px; }
}


/* ===== css/about/pages/_seams.css ===== */
/* ==========================================================================
   About lab — shared page rhythm

   `.ab-section` pads `--ab-row` top *and* bottom, so every adjacency between two
   body sections costs twice that — about 316px at 1440. That is right for a page
   of two or three sections; the about pages run five to seven, and at the full
   measure the page becomes a long walk between short blocks.

   So every seam halves to `--ab-row-small` (~172px at 1440), except the first
   section's top: that one is answering a 100vh hero and needs the full measure.
   The last section's bottom stays halved too — the template's page-nav block
   brings its own generous space. A flush section (`.ab-section-flush`) is exempt
   by its own rule in _base.css and must stay that way.

   The same decision the contact lab made in css/contact/pages/_seams.css, for the
   same reason: the two pages should be walked at the same pace.

   Applies to any page carrying the `about-tight` root class.
   ========================================================================== */

/* ---------- the column ------------------------------------------------------

   The template caps and centres `.content-max-width` at 1320px — but
   `#main-page-content` carries `max-width: none` on an *id* selector
   (css/content.css 501), which outranks the class, so the body column never caps.
   Below 1466 that is invisible: a 1320 box centred in 1440 lands on the same 60px
   the padding already gives. At 1920 it is not invisible at all — the sections run
   from 80px while a centred hero sits in the middle of the screen, and the page
   reads as though its content fell to the left.

   `_base.css` uncaps the hero caption so hero and body share one left edge, which
   is the lab's answer for a left-hung caption. These heroes are centred
   (`content-full-width text-align-center`), so they need the opposite: give the
   body back the column the template intended.

   The page-nav block is capped with it — a page whose sections sit in a centred
   column and whose sign-off runs to the far left reads as two pages. The same
   decision, and the same reasoning, as css/contact/pages/_seams.css.
   ------------------------------------------------------------------------- */

html.about-tight #main-page-content.content-max-width,
html.about-tight #page-nav .page-nav-caption {
	max-width: 1320px;
	margin-left: auto;
	margin-right: auto;
}

/* ---------- the rhythm ---------------------------------------------------- */

html.about-tight #main-page-content > .ab-section:not(.ab-section-flush) {
	padding-top: var(--ab-row-small);
	padding-bottom: var(--ab-row-small);
}

html.about-tight #main-page-content > .ab-section:not(.ab-section-flush):first-child {
	padding-top: var(--ab-row);
}

