/* EB Garamond is loaded via <link> in the pages that render it (the
   @import here serialized font loading behind this stylesheet, and made
   the dark pages fetch a serif they never use). */

/* Design tokens (colors, fonts, shape, motion) live in tokens.css,
   loaded before this file on every page. */

html,
body {
	margin: 0;
	padding: 0;
	background: var(--parchment);
	color: var(--ink);
	font-family: var(--font-serif);
	font-feature-settings: "liga", "kern", "onum";
	/* Root scale: every rem-based size site-wide keys off this — the
	   unit calibration, the one length outside the quarter grid. */
	font-size: 1.05rem;
}

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

h1,
h2,
h3,
h4,
h5,
h6 {
	font-weight: normal;
	margin: 0;
}

.amber-text {
	color: var(--amber);
}

.button {
	border: var(--emphasis) solid var(--ink);
	border-radius: var(--radius);
	padding: var(--space-05) var(--space-1);
	transition:
		background-color var(--duration-ui) ease-in-out,
		color var(--duration-ui) ease-in-out;
}

.button.amber-text {
	border: var(--emphasis) solid var(--amber);
}

.button:hover {
	background-color: var(--ink);
	color: var(--parchment);
}

.button.amber-text:hover {
	background-color: var(--amber);
	color: var(--parchment);
}

.dark .button.amber-text:hover {
	color: var(--ink);
}

a {
	color: inherit;
	text-decoration: none;
}

header {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	height: var(--nav-height);
	padding: 0 var(--gutter);
	position: fixed;
	border-bottom: var(--hairline) solid var(--rule);
	top: 0;
	left: 0;
	right: 0;
	z-index: 10;
	background-color: var(--glass-light);
	backdrop-filter: blur(var(--glass-blur));
	box-shadow: var(--shadow-bar);
}

header #logo {
	width: auto;
	height: var(--logo-cap);
}

header nav {
	justify-self: center;
}

header nav a {
	margin: 0 var(--space-1);
	/* The stroke's slot is always reserved (transparent when idle) so
	   underlining doesn't grow the box and nudge the row. */
	border-bottom: var(--emphasis) solid transparent;
	transition: border-bottom var(--duration-ui) ease-in-out;
}

header nav a:hover {
	border-bottom-color: var(--ink);
}

header nav a.active {
	font-style: italic;
	border-bottom-color: var(--amber);
}

header #contact-header {
	justify-self: right;
}

/* ── Hamburger + glass menu ─────────────────────────────────── */

/* Injected by menu.js on every page: a hamburger at the bar's right
   end (mobile only, shown by the 900px block below) unfolds the nav
   links in a full-page glass sheet. Each page dresses it to match its
   own nav bar — the dark pages' version lives in demo-dark.css — so
   the sheet always reads as that page's bar extended downward. While
   the sheet is open the hamburger's bars fold into an X.

   Below the threshold the sheet is the page's only overlay: it holds
   the nav links (with the Contact button the bar gives up down here)
   and the demo form as two panels in the same place, and asking for
   the form crossfades them rather than raising a second sheet of the
   same glass over the first. */
#menu-button {
	display: none;
	align-content: center;
	justify-content: center;
	gap: var(--space-025);
	width: var(--space-3);
	height: var(--space-3);
	margin-left: var(--space-1);
	border: none;
	padding: 0;
	background: none;
	cursor: pointer;
	color: var(--ink);
}

#menu-button span {
	width: var(--space-15);
	height: var(--emphasis);
	background-color: currentColor;
	transition:
		translate var(--duration-dialog),
		rotate var(--duration-dialog),
		scale var(--duration-dialog),
		opacity var(--duration-dialog);
}

/* The outer bars travel one row pitch to the middle and cross;
   the middle bar bows out. */
#menu-button[aria-expanded="true"] span:nth-child(1) {
	translate: 0 calc(var(--emphasis) + var(--space-025));
	rotate: 45deg;
}

/* Collapsed as well as faded: a full-width bar fading behind the
   crossed arms can leave its antialiased ends as two dots beside
   the X's center. */
#menu-button[aria-expanded="true"] span:nth-child(2) {
	opacity: 0;
	scale: 0 1;
}

#menu-button[aria-expanded="true"] span:nth-child(3) {
	translate: 0 calc(-1 * (var(--emphasis) + var(--space-025)));
	rotate: -45deg;
}

/* The sheet: the nav bar extending down over the page. menu.js opens
   it non-modally so the bar above stays clickable; it sits just under
   the bar in the stack and grows from the bar's edge to cover the
   viewport, its bottom hairline reading as the bar's own rule
   traveling down. */
#menu {
	position: fixed;
	inset: 0;
	width: 100%;
	max-width: none;
	height: 0;
	max-height: none;
	margin: 0;
	padding: 0;
	/* clip, not hidden: hidden still leaves a scroll CONTAINER, and
	   opening the sheet focuses its first link, which WebKit reveals by
	   scrolling that container — while the sheet is still short, so the
	   panels end up dragged up behind the bar. clip cannot scroll. */
	overflow: clip;
	z-index: 9; /* under the bar's 10, over everything else */
	border: none;
	border-bottom: var(--hairline) solid var(--rule);
	background-color: var(--glass-dialog-light);
	backdrop-filter: blur(var(--glass-blur));
	color: var(--ink);
	transition:
		height var(--duration-dialog),
		display var(--duration-dialog) allow-discrete;
}

#menu[open] {
	height: 100dvh;
}

@starting-style {
	#menu[open] {
		height: 0;
	}
}

/* Both panels hang from the bar and hold that place while the sheet's
   edge sweeps down and reveals them. Ranged left on the bar's own
   gutter, so they sit under the logo's line like the rest of the
   site's copy; each link's underline slot ends with its word.
   Stacked in the one spot, they swap by crossfade: the outgoing panel
   clears first, the incoming one waits that beat and then arrives, so
   the two halves together take the sheet's own opening time and the
   glass never appears to hold two things at once. (The panel that is
   already up when the sheet opens simply appears with it — a dialog
   moving from display:none runs no transitions.) */
#menu .sheet-panel {
	position: absolute;
	top: calc(var(--nav-height) + var(--space-2));
	left: 0;
	right: 0;
	padding: 0 var(--gutter-mobile);
	opacity: 0;
	visibility: hidden;
	transition:
		opacity var(--duration-ui),
		visibility 0s var(--duration-ui);
}

/* The panels take programmatic focus on open and on swap (they carry
   tabindex="-1" so show() has somewhere to land focus). They are
   containers, not controls, so the UA ring they'd get — iOS draws it as
   a blue plate clipped to lines at the panel's edges — marks nothing a
   user can act on. The links and fields inside keep their own rings. */
#menu .sheet-panel:focus {
	outline: none;
}

#menu[data-panel="links"] #menu-links,
#menu[data-panel="form"] .demo-body {
	opacity: 1;
	visibility: visible;
	transition:
		opacity var(--duration-ui) var(--duration-ui),
		visibility 0s;
}

/* Under reduced motion the sheet's sweep, the hamburger's fold and
   the panel crossfade all cut instead. (After the crossfade rules:
   these unwind their transitions by the same selectors.) */
@media (prefers-reduced-motion: reduce) {
	#menu,
	#menu-button span,
	#menu .sheet-panel,
	#menu[data-panel="links"] #menu-links,
	#menu[data-panel="form"] .demo-body {
		transition: none;
	}
}

/* The link panel spans the sheet so its action can sit at the foot of
   the screen rather than trailing the list — the links hang from the
   bar, Contact holds the bottom, and the air between them is whatever
   the page's four links leave over. */
/* Grid, not a flex column with an auto margin on the button: a
   landscape phone can't hold the four links, the air and the button,
   and negative free space goes into an auto margin (WebKit) — the
   list gets dragged up behind the bar. A 1fr track can only collapse,
   so the slack above the button disappears first and the panel
   scrolls, list still under the bar where it belongs. */
#menu-links {
	bottom: var(--space-2);
	display: grid;
	grid-template-rows: auto 1fr;
	overflow-y: auto;
}

/* The form panel needs the same floor as the links panel. Without a
   bottom it sizes to its content against a sheet that is overflow:clip
   with the page scroll locked, so on a landscape phone the Send button
   sits below the fold with no way to reach it. */
#menu .demo-body {
	bottom: var(--space-2);
	overflow-y: auto;
}

#menu nav {
	display: grid;
	justify-items: start;
	gap: var(--space-2);
	margin-bottom: var(--space-3);
}

/* The sheet's two actions — the bar's Contact button, cloned by
   menu.js into the link panel, and the form's own Send — take the
   full measure and a thumb-sized block, so both panels end on the
   same definite edge. Each keeps its page's button dress (.button
   here, .pkBtn on the dark pages); only the size and tap target are
   the sheet's. */
#menu .menu-cta,
#menu .demo-body .button {
	display: flex;
	justify-content: center;
	width: 100%;
	padding-block: var(--space-075);
	font-size: var(--text-control);
}

/* Pushed to the panel's foot, so Contact is where a thumb already is.
   The cap is the form panel's own measure less its gutters
   (demo.css), so on a sheet wider than a phone the two panels end on
   the same edge instead of one button running the full width. */
#menu .menu-cta {
	align-self: end;
	max-width: calc(24rem - 2 * var(--gutter-mobile));
}

/* The page beneath the open sheet holds still. */
body:has(#menu[open]) {
	overflow: hidden;
}

/* Scoped to the link list: the sheet's other anchor is the cloned
   Contact button, which must keep its button dress. */
#menu nav a {
	font-size: var(--text-lede);
	/* Reserved stroke slot, as in the bar: hovering or the active
	   underline must not shift the links around it. */
	border-bottom: var(--emphasis) solid transparent;
	transition: border-bottom var(--duration-ui) ease-in-out;
}

#menu nav a:hover {
	border-bottom-color: var(--ink);
}

/* Keyboard focus lights the link's own underline slot in the darker
   brand orange — the 500 step reads at under 3:1 on parchment, the
   600 clears it there and on ink. No outline: a ring here draws a
   rectangle on the glass, the artifact the form fields also shed.
   The dark sheet recolors this in demo-dark.css. */
#menu nav a:focus-visible {
	outline: none;
	border-bottom-color: var(--piko-orange-600);
}

#menu nav a.active {
	font-style: italic;
	border-bottom-color: var(--amber);
}

/* Below the mobile threshold the bar hands everything but its identity
   to the sheet — links and Contact both — and keeps the logo and the
   hamburger, one at each end of the row. Mirrored by .pkNav in
   dark.css; keep the two in step. */
@media (max-width: 900px) {
	header {
		/* Two items left, so the middle column carries the row's slack
		   rather than the vanished nav's. */
		grid-template-columns: 1fr auto;
		padding: 0 var(--gutter-mobile);
	}

	header nav,
	header #contact-header {
		display: none;
	}

	#menu-button {
		display: grid;
	}
}

main {
	padding-top: var(--nav-height);
}

/* Both CTA dialects — the light pages' section.cta and the dark
   pages' .pkCta — share the one-line headline size (--text-cta).
   Below ~815px the token's floor lets the line wrap (see tokens.css);
   balance evens the two lines — no-op while the line is single. */
main > section.cta .copy h1,
.pkCta .copy h1 {
	font-size: var(--text-cta);
	/* Wrapped lines keep the centered-statement identity (the flex
	   centering only places the box; single lines are unaffected). */
	text-align: center;
	text-wrap: balance;
}

/* ── CTA gorilla ────────────────────────────────────────────── */

/* The Piko gorilla (animated WebP, transparent background) sits in the
   CTA's right corner, logo-sized and vertically centered. Every page's
   CTA section is a positioned box, so the mascot anchors to the
   section itself. Under prefers-reduced-motion the pages' <picture>
   swaps in a static frame (cta-gorilla-static.png), so no CSS hide is
   needed here. */
/* The action row holds the button and — below 900px — the mascot
   beside it. The button sits in the middle track of 1fr/auto/1fr, so
   it keeps the page's centre axis (the one the headline above it is
   centred on) whatever sits beside it; the mascot takes the third
   track. The <picture> is boxless, so the row's only item on desktop
   is the button (the absolute img takes no part in layout), the empty
   fr tracks collapse, and the row renders exactly as the bare button
   did; the .copy column still supplies the gap above it, and the
   button keeps the margin-top the page sheets give it. A wrapper
   rather than a row-direction .copy on small screens: the three page
   sheets all declare .copy's column after this file at equal
   specificity, so a shared override there would lose on source
   order. */
main > section.cta .cta__actions,
.pkCta .cta__actions {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	justify-items: center;
}

main > section.cta .cta__actions .button,
.pkCta .cta__actions .button {
	grid-column: 2;
}

main > section.cta picture,
.pkCta picture {
	display: contents;
}

/* WebKit gives <source> no UA display:none, so dissolving its
   <picture> promotes it to a zero-width item that would draw the row's
   gap and push the button off-centre. It is metadata — never a box. */
main > section.cta .cta__actions source,
.pkCta .cta__actions source {
	display: none;
}

.cta__gorilla {
	position: absolute;
	/* Visible right edge on the gutter's content line (where the
	   header's Contact button ends): the image carries about a grid
	   unit of transparent margin right of the silhouette at this
	   size, so the offset is the gutter minus that optical inset. */
	right: calc(var(--gutter) - var(--space-025));
	top: 50%;
	transform: translateY(-50%);
	height: var(--space-6);
	pointer-events: none;
}

/* Below 1200px the gutter-anchored mascot would collide with the
   centered CTA copy (the h1's right edge overtakes the gorilla's left
   at ~1065px): it steps down to half size and tucks against the
   viewport edge, clear of the text. */
@media (max-width: 1200px) {
	.cta__gorilla {
		height: var(--space-3);
		right: var(--space-1);
	}
}

@media (max-width: 900px) {
	/* Too little room beside the centered copy on small screens: the
	   mascot leaves the corner and joins the action row as the
	   button's neighbour (still the half size above). The row spans
	   the copy so its fr tracks have room to hold the button on the
	   centre axis; the mascot hangs off the button's right edge in
	   the third track. It takes the button's top margin so the two
	   margin boxes share an offset and align-items centers them
	   against each other rather than against the margin. The fr
	   track's floor is its content, so on a viewport too narrow to
	   seat the mascot the track grows and nudges the button off the
	   axis — a slide, never a horizontal overflow. */
	main > section.cta .cta__actions,
	.pkCta .cta__actions {
		width: 100%;
	}

	.cta__gorilla {
		position: static;
		transform: none;
		grid-column: 3;
		justify-self: start;
		margin: var(--gap-copy) 0 0 var(--space-2);
	}
}
