/* The home page (layouts/landing.pug). Builds on all.css for the fonts.
 *
 * One bold element — the name, very large on one line — and everything
 * around it quiet: left-aligned, a label column beside a content column, one
 * accent. The palette continues the CV page's, so the two read as one site.
 *
 * (A proportional career chart stood under the name until 2026-10-08; the
 * owner: "the chart does not speak well". The Experience list replaced it.) */

.landing {
	--ink: #16213a;
	--ink-soft: #2f3a52;
	--paper: #f5f7fa;
	--white: #ffffff;
	--signal: #0a5fd6;
	--signal-deep: #0848a3;
	--slate: #5b6579;
	--line: #dde3ec;
	/* the drawings only (art.pug) */
	--signal-soft: #9dbbea;
	--signal-wash: #eaf1fc;
	--art-quiet: #c6cfdc;

	/* NOTHING here is tied to the window width (no vw, no %). Owner,
	   2026-10-09: "small change of the size make the elements move". Sizes
	   and the content width are FIXED per band and change only at the
	   breakpoints below (1040 / 900 / 740 / 520 px), so resizing inside a band
	   only re-centres the column. Proof: tools/dev/check-landing-stable.py. */
	--measure: 40rem;
	--gutter: 3rem;
	/* ONE content width for every section (owner, 2026-10-09: "make sure
	   width of the content is consistent in each section"): the heading
	   column + its gap + the text measure. The hero and the projects used to
	   run to 70rem while the lists stopped at the measure, so the right edges
	   disagreed and the hero drawing drifted far from its text. */
	--head-col: 15rem;
	--col-gap: 3.5rem;
	--content: calc(var(--head-col) + var(--col-gap) + var(--measure));
	--hero-art: 20rem;

	background: var(--paper);
	color: var(--ink);
	/* all.css drops body to 17px at 860 px — a step inside the 740–899 band
	   that nudged the projects' inherited text; this page owns its steps */
	font-size: 18px;
}

.landing .wrap {
	max-width: calc(var(--content) + 2 * var(--gutter));
	margin: 0 auto;
	padding: 0 var(--gutter);
}

.landing a:focus-visible,
.landing .btn:focus-visible {
	outline: 3px solid var(--signal);
	outline-offset: 3px;
	border-radius: 4px;
	text-decoration: none;
}

.skip {
	position: absolute;
	left: var(--gutter);
	top: -3rem;
	padding: 0.4rem 0.8rem;
	background: var(--ink);
	color: var(--white);
	z-index: 1;
}

.skip:focus-visible {
	top: 0.8rem;
	color: var(--white);
}

/* ── hero ───────────────────────────────────────────────────────────────── */

.hero {
	padding: 7rem 0 5rem;
	background: var(--white);
	border-bottom: 1px solid var(--line);
}

/* The name is the type statement, on ONE line (owner, 2026-10-08). Rajdhani
   is condensed, so it can run very large and still fit a phone; it steps
   down at the breakpoints and never wraps. */
.hero-name {
	margin: 0;
	font-size: 8.5rem;
	font-weight: 700;
	line-height: 0.9;
	letter-spacing: -0.015em;
	white-space: nowrap;
	color: var(--ink);
}

.hero-role {
	margin: 1.2rem 0 0;
	font-size: 1.9rem;
	font-weight: 600;
	line-height: 1.2;
	color: var(--signal-deep);
}

.hero-lede {
	max-width: 34rem;
	margin: 1.1rem 0 0;
	font-size: 1.5rem;
	line-height: 1.38;
	color: var(--ink-soft);
}

.hero-place {
	margin: 0.6rem 0 0;
	font-size: 1.1rem;
	color: var(--slate);
}

.hero-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 2rem;
}

.btn {
	display: inline-flex;
	align-items: center;
	min-height: 2.9rem;
	padding: 0.35rem 1.35rem;
	border: 1.5px solid var(--ink);
	border-radius: 6px;
	color: var(--ink);
	font-size: 1.15rem;
	font-weight: 600;
	letter-spacing: 0.01em;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.btn:hover {
	background: var(--ink);
	color: var(--white);
	text-decoration: none;
}

.btn-primary {
	background: var(--signal);
	border-color: var(--signal);
	color: var(--white);
}

.btn-primary:hover {
	background: var(--signal-deep);
	border-color: var(--signal-deep);
}

@media (prefers-reduced-motion: reduce) {
	.btn {
		transition: none;
	}
}

/* ── bands: a label column beside the content ───────────────────────────── */

.band {
	padding: 5rem 0;
	border-bottom: 1px solid var(--line);
}

.band-grid {
	display: grid;
	/* 15rem holds "Beyond iOS" on one line (it was 17rem while the headings
	   carried icons; those were removed 2026-10-09) */
	grid-template-columns: var(--head-col) minmax(0, 1fr);
	gap: 1.5rem var(--col-gap);
	align-items: start;
}

.band-head h2 {
	margin: 0;
	font-size: 2.9rem;
	line-height: 1;
	letter-spacing: -0.005em;
}

.band-intro {
	margin: 0.7rem 0 0;
	font-size: 1.15rem;
	line-height: 1.35;
	color: var(--slate);
}

.points {
	max-width: var(--measure);
	margin: 0;
	padding: 0;
	list-style: none;
}

.points li {
	padding: 1rem 0;
	border-top: 1px solid var(--line);
	font-size: 1.22rem;
	line-height: 1.45;
	color: var(--ink-soft);
}

.points li:first-child {
	padding-top: 0.15rem;
	border-top: 0;
}

.points strong {
	color: var(--ink);
	font-weight: 700;
}

/* Key words in the running text (index.md `keywords:`; owner, 2026-10-12:
   "hightlight key words like Objective-C"): the page's blue on a pale wash,
   so a reader skimming for a technology finds it. The negative margin takes
   back most of the padding, so "MDR-certified" or "Swift," does not gain a
   gap before the punctuation; a two-word name ("React Native") stays on one
   line. */
.kw {
	margin: 0 -0.1em;
	padding: 0.02em 0.18em;
	border-radius: 4px;
	background: var(--signal-wash);
	color: var(--signal-deep);
	font-weight: 600;
	white-space: nowrap;
}

/* "Also good at" — tags closing a section (index.md `good_at:`; owner,
   2026-10-12: "make it look nice and eye-catchy"). Sits on the list's own
   rule, like one more point. */
.good-at {
	max-width: var(--measure);
	margin-top: 0.4rem;
	padding-top: 1.4rem;
	border-top: 1px solid var(--line);
}

.good-at-title {
	margin: 0 0 0.9rem;
	font-size: 1.05rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--signal);
}

.good-at-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.55rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.good-at-tags li {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.32rem 0.9rem 0.32rem 0.75rem;
	border: 1.5px solid var(--signal-soft);
	border-radius: 999px;
	background: var(--white);
	color: var(--ink);
	font-size: 1.08rem;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

/* a small blue dot before each tag */
.good-at-tags li::before {
	content: "";
	width: 0.45rem;
	height: 0.45rem;
	border-radius: 50%;
	background: var(--signal);
}

.good-at-tags li:hover {
	border-color: var(--signal);
	background: var(--signal-wash);
	color: var(--signal-deep);
}

@media (prefers-reduced-motion: reduce) {
	.good-at-tags li {
		transition: none;
	}
}

/* ── experience: when · who · what, most recent first ───────────────────── */

.roles {
	max-width: var(--measure);
	margin: 0;
	padding: 0;
	list-style: none;
}

.role {
	display: grid;
	grid-template-columns: 6.5rem minmax(0, 1fr);
	gap: 0 1.5rem;
	padding: 1rem 0;
	border-top: 1px solid var(--line);
}

.role:first-child {
	padding-top: 0.15rem;
	border-top: 0;
}

.role-when {
	padding-top: 0.1rem;
	font-size: 1.1rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--slate);
}

.role-who {
	display: block;
	font-size: 1.3rem;
	font-weight: 700;
	line-height: 1.25;
	color: var(--ink);
}

.role-what {
	display: block;
	margin-top: 0.15rem;
	font-size: 1.18rem;
	line-height: 1.42;
	color: var(--ink-soft);
}

.more-link {
	display: inline-block;
	font-size: 1.15rem;
	font-weight: 600;
	text-decoration: underline;
	text-decoration-thickness: 1.5px;
	text-underline-offset: 0.22em;
}

.more-link {
	margin-top: 1.2rem;
}

/* ── side projects ──────────────────────────────────────────────────────── */

.band-projects {
	background: var(--white);
}

/* Two columns separated by space alone — no rule between them (owner,
   2026-10-09: the full-height line read as too long). */
.projects {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 2.5rem 4rem;
}

/* block, not flex: the drawing floats right and the text wraps round it */
.project {
	display: block;
}

.project-name {
	margin: 0;
	font-size: 2.6rem;
	line-height: 1;
}

/* the short name, on its own line under the full one */
.project-short {
	display: block;
	margin-top: 0.25rem;
	font-size: 0.5em;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var(--slate);
}

.project-why {
	margin: 0.55rem 0 1rem;
	font-size: 1.3rem;
	font-weight: 600;
	color: var(--signal-deep);
}

.project-text {
	font-size: 1.15rem;
	line-height: 1.45;
	color: var(--ink-soft);
}

/* the layers of the stack, top to bottom, each name above its line */
.project-stack {
	margin: 0 0 1.2rem;
	padding-left: 0.9rem;
	border-left: 2px solid var(--line);
	font-size: 1.05rem;
	line-height: 1.35;
}

.project-stack dt {
	font-weight: 700;
	color: var(--ink);
}

.project-stack dd {
	margin: 0 0 0.6rem;
	color: var(--ink-soft);
}

.project-stack dd:last-child {
	margin-bottom: 0;
}

/* The project's address, as the address itself: small and grey so it reads
   as a reference, not a call to action (owner, 2026-10-09). */
.project-link {
	align-self: flex-start;
	font-size: 1rem;
	font-weight: 500;
	color: var(--slate);
	text-decoration: underline;
	text-decoration-color: var(--line);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.22em;
}

.project-link:hover,
.project-link:focus-visible {
	color: var(--signal-deep);
	text-decoration-color: currentColor;
}

/* ── colophon ───────────────────────────────────────────────────────────── */

.colophon {
	padding: 2.5rem 0 3rem;
	font-size: 1.02rem;
	color: var(--slate);
}

.colophon p {
	margin: 0 0 0.35rem;
}

.colophon a {
	text-decoration: underline;
	text-decoration-color: rgba(10, 95, 214, 0.35);
	text-underline-offset: 0.2em;
}

.colophon-legal {
	font-size: 0.92rem;
}

/* ── drawings (art.pug) ─────────────────────────────────────────────────── */

/* The intro: the name across the full content width, then the description
   and the illustration side by side — the drawing right beside its text and
   ending at the same right edge as every section below (owner, 2026-10-09:
   "the image at the top should be closer to description"). */
.hero-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 0 2.5rem;
	align-items: center;
}

.hero-name {
	grid-column: 1 / -1;
}

.hero-art {
	display: block;
	width: var(--hero-art);
	height: auto;
	margin-top: 1.2rem;
}

/* one palette for every drawing: slate lines, the page's blue for accents */
.art-line,
.art-body {
	stroke: var(--slate);
}

.art-body,
.art-sheet {
	fill: var(--white);
}

.art-body {
	stroke: var(--ink);
}

.art-sheet {
	stroke: var(--ink);
}

.art-sheet-back {
	stroke: var(--signal-soft);
	fill: var(--white);
}

.art-screen {
	fill: var(--signal-wash);
	stroke: var(--signal-soft);
}

.art-card {
	fill: var(--white);
	stroke: var(--signal-soft);
}

.art-fill {
	fill: var(--signal);
}

.art-accent-line {
	stroke: var(--signal);
}

.art-link {
	stroke: var(--signal-soft);
}

/* section headings: a small line icon in the page's blue */
.band-head h2 {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	white-space: nowrap;
}

.head-icon {
	flex: none;
	width: 1.7rem;
	height: 1.7rem;
	color: var(--signal);
}

/* Experience: the domain mark before an employer */
.role-who {
	display: flex;
	align-items: center;
	gap: 0.45rem;
}

.role-mark {
	flex: none;
	width: 1.15rem;
	height: 1.15rem;
	color: var(--signal-deep);
}

/* A drawing at the right of each project's title, the text wrapping round it
   (owner, 2026-10-09, drawn on a printed sheet: arrows from each drawing to
   the right end of its title row; "Right, text wraps"). */
.lab-art {
	float: right;
	/* As large as possible while "House of Things" and "For the fun of
	   programming." each stay on ONE line beside it (owner, 2026-10-09; 14rem
	   broke the title). Measured at 1440 px: title ≈ 17.3rem, tagline ≈ 15rem;
	   with the shared content width (58.5rem) a project column is ≈ 27rem,
	   so 8.5rem + its 1rem gap fits. Fixed — no % of the column, which made it
	   resize with the window; the projects go to one column below 1040 px
	   instead. Both drawings share this size. */
	width: 8.5rem;
	height: auto;
	margin: 0 0 1rem 1rem;
}

/* Under each section heading: a faint texture of code glyphs (art.pug
   `head-pattern`). Owner, 2026-10-09: "make some nice pattern instead, the
   pattern can be related to coding" — and earlier "they must be subtle". Pale
   glyphs, a few in soft blue, fading out from the heading's corner so it
   reads as texture, not as a picture. */
.head-pattern {
	display: block;
	width: 15rem;
	height: auto;
	margin-top: 2rem;
	-webkit-mask-image: radial-gradient(ellipse 100% 100% at 0 0, #000 30%, transparent 80%);
	mask-image: radial-gradient(ellipse 100% 100% at 0 0, #000 30%, transparent 80%);
}

.head-pattern text {
	font-family: ui-monospace, "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;
	font-size: 12px;
	text-anchor: middle;
}

.hp-dot {
	fill: var(--art-quiet);
}

.hp-glyph {
	fill: var(--art-quiet);
}

.hp-accent {
	fill: var(--signal-soft);
}

/* the stack list's left rule must not run under the floated drawing */
.project-stack {
	clear: right;
}

/* ── narrower screens: STEPS, not scaling ───────────────────────────────────
   Each band has a fixed content width that fits the narrowest window in it
   (content + 2 × 3rem gutter), so inside a band nothing changes size. */

/* 900–1039 px: a 50rem column; the projects stack (two 8.5rem drawings
   beside their titles need ≥ 1018 px). */
@media (max-width: 1039px) {
	.landing {
		--measure: 31.5rem;
		--hero-art: 15rem;
	}

	.projects {
		grid-template-columns: minmax(0, 1fr);
		gap: 3rem;
	}
}

/* 740–899 px: one 40rem column; the hero drawing would squeeze the text — drop it */
@media (max-width: 899px) {
	.landing {
		--measure: 40rem;
		--content: 40rem;
	}

	.hero {
		padding: 5rem 0 4rem;
	}

	.hero-name {
		font-size: 7rem;
	}

	.hero-role {
		font-size: 1.7rem;
	}

	.hero-grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.hero-art {
		display: none;
	}

	/* the heading now sits above its content: no empty column to fill */
	.head-pattern {
		display: none;
	}

	.band {
		padding: 4rem 0;
	}

	.band-grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.band-head h2 {
		font-size: 2.5rem;
	}

	.project-name {
		font-size: 2.4rem;
	}
}

/* below 740 px the window is narrower than the 40rem column: it is fluid
   from here down (tablets and phones), with the sizes stepped once more. */
@media (max-width: 739px) {
	.landing {
		font-size: 17px;
	}

	.hero-name {
		font-size: 5rem;
	}
}

/* On a phone the period sits above its role instead of beside it. */
@media (max-width: 520px) {
	.landing {
		--gutter: 1.25rem;
	}

	.hero {
		padding: 3.5rem 0 3rem;
	}

	.hero-name {
		font-size: 3.5rem;
	}

	.hero-role {
		font-size: 1.45rem;
	}

	.hero-lede {
		font-size: 1.25rem;
	}

	.band {
		padding: 3rem 0;
	}

	.band-head h2 {
		font-size: 2.2rem;
	}

	.project-name {
		font-size: 2rem;
	}

	.role {
		grid-template-columns: minmax(0, 1fr);
	}

	/* A phone column (~21rem) cannot hold "House of Things" and a drawing on
	   one line, so the drawing sits above the title instead of beside it —
	   the title and tagline stay unbroken. */
	.lab-art {
		float: none;
		display: block;
		width: 8rem;
		margin: 0 0 0.75rem;
	}
}

/* ── the contact popup (owner, 2026-10-11) ───────────────────────────────── */

/* A fixed width like everything else here (no vw/%); on a phone it spans the
   screen less a margin. `position: fixed` also covers the no-JS case, where
   the server renders the dialog already `open` (non-modal). */
.contact-dialog {
	position: fixed;
	inset: 0;
	z-index: 10;
	box-sizing: border-box;
	width: 34rem;
	height: fit-content;
	margin: auto;
	padding: 2rem 2.25rem 2.25rem;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--white);
	color: var(--ink);
	box-shadow: 0 1.25rem 3rem rgba(22, 33, 58, 0.22);
}

.contact-dialog::backdrop {
	background: rgba(22, 33, 58, 0.45);
}

.contact-dialog h2 {
	margin: 0 2.5rem 1rem 0;
	font-size: 2rem;
	line-height: 1.15;
}

.contact-close {
	position: absolute;
	top: 1rem;
	right: 1rem;
	margin: 0;
}

.contact-x {
	width: 2.4rem;
	height: 2.4rem;
	border: 0;
	border-radius: 6px;
	background: transparent;
	color: var(--slate);
	font: inherit;
	font-size: 1.7rem;
	line-height: 1;
	cursor: pointer;
}

.contact-x:hover,
.contact-x:focus-visible {
	background: var(--paper);
	color: var(--ink);
}

.contact-text {
	margin: 0 0 1.25rem;
	line-height: 1.5;
}

/* Small print directly under the text box (owner, 2026-10-11). */
.contact-notice {
	margin: 0.5rem 0 0;
	color: var(--slate);
	font-size: 0.8rem;
	line-height: 1.4;
}

.contact-label {
	display: block;
	margin-bottom: 0.4rem;
	font-weight: 600;
}

.contact-form textarea {
	display: block;
	box-sizing: border-box;
	width: 100%;
	min-height: 9rem;
	padding: 0.75rem 0.85rem;
	border: 1.5px solid var(--line);
	border-radius: 6px;
	background: var(--white);
	color: var(--ink);
	font: inherit;
	font-size: 1.05rem;
	line-height: 1.45;
	resize: vertical;
}

.contact-form textarea:focus {
	border-color: var(--signal);
	outline: 2px solid var(--signal-wash);
}

.contact-error {
	margin: 0.75rem 0 0;
	color: #b3261e;
	font-size: 0.95rem;
}

.contact-send {
	margin-top: 1.25rem;
	cursor: pointer;
	font-family: inherit;
}

.contact-send:disabled {
	opacity: 0.6;
	cursor: progress;
}

.contact-dialog[data-sent] .contact-body {
	display: none;
}

.contact-sent {
	margin: 0;
	font-size: 1.15rem;
	line-height: 1.5;
}

.hero-actions button.btn {
	cursor: pointer;
	font-family: inherit;
}

@media (max-width: 520px) {
	.contact-dialog {
		width: auto;
		margin: auto 1rem;
		padding: 1.5rem 1.25rem 1.5rem;
	}

	.contact-dialog h2 {
		font-size: 1.7rem;
	}
}
