/*
 * The manual's whole stylesheet: the tokens that hold every value, then one
 * component per block, in native nesting under four layers.
 *
 * The palette starts at the two brands this runtime joins. go.dev paints its
 * mark #00add8, rgb(0, 173, 216); php.net paints its elephant #777bb4,
 * rgb(119, 123, 180). Channel by channel the average is rgb(60, 148, 198).
 * phpscript takes that blue, #3c94c6. Its complement at the same saturation
 * and lightness is #c66f3c, the orange on the $ of the mark and on every
 * action. Rotating the three channels of the brand blue walks its triad:
 * #3c94c6, then #94c63c, then #c63c94. The lime reports a count and the rose
 * marks an argument list the binding leaves unsaid, which are the only two
 * rules either colour appears under.
 *
 * The wireframe reads as a reference manual. php.net opens a symbol with a
 * synopsis panel and lists the sections of the page down the side; pkg.go.dev
 * prints one member per declaration, the signature over the doc comment. This
 * does both, in a sans for the words and a mono for every symbol.
 *
 * The faces named first are the ones a developer machine often installs, and
 * each stack falls back to the system's own. A page requests this file and one
 * script, and no font.
 */

@layer tokens, base, layout, components;

@layer tokens {
	:root {
		color-scheme: dark light;

		--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
		--font-ui: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;

		/* The two brands, kept for the record and for the Go label. */
		--go: #00add8;
		--php: #777bb4;

		--brand: #3c94c6;
		--brand-strong: #6fb3d8;
		--brand-wash: color-mix(in srgb, var(--brand) 14%, transparent);
		--brand-ink: #06121a;

		--accent: #c66f3c;
		--accent-wash: color-mix(in srgb, var(--accent) 16%, transparent);

		--lime: #94c63c;
		--rose: #c63c94;

		--surface-0: #0b1016;
		--surface-1: #111a22;
		--surface-2: #16212c;
		--surface-side: #0e151d;

		/* The bar across the top wears the brand, the way php.net paints its
		   own. Its two inks answer to that blue. */
		--header-bg: #0f2d41;
		--header-ink: #e8f1f7;
		--header-dim: #9dbfd4;
		--line: #1c2935;
		--line-strong: #2a3b4a;
		--text: #dce5ed;
		--text-dim: #93a3b2;
		--text-faint: #68798a;

		--fs-label: 0.68rem;
		--fs-xs: 0.76rem;
		--fs-sm: 0.83rem;
		--fs-body: 0.95rem;
		--fs-lg: 1rem;
		--fs-h2: 1.05rem;
		--fs-title: 1.7rem;

		--ls-label: 0.12em;
		--ls-tight: -0.015em;

		--radius: 6px;
		--radius-sm: 4px;
		--shadow: 0 1px 2px rgb(0 0 0 / 28%);
		--glow: 0 0 10px color-mix(in srgb, var(--brand) 45%, transparent);

		--side: 17rem;
		--measure: 74ch;
		--shell: 86rem;
		--block-gap: 2rem;
		--head-gap: 0.55rem;
		--pad: 1.5rem;
	}

	@media (prefers-color-scheme: light) {
		:root {
			/* go.dev prints its own name in this blue once the page turns white,
			   and the cyan above reads as a highlighter against it. */
			--go: #007d9c;

			--brand: #1f6f9c;
			--brand-strong: #15567a;
			--brand-ink: #ffffff;

			--accent: #a5541f;

			--lime: #4f6b14;
			--rose: #9c2069;

			--surface-0: #f5f8fa;
			--surface-1: #ffffff;
			--surface-2: #eef3f7;
			--surface-side: #e8eff5;

			--header-bg: #19506f;
			--header-ink: #f3f9fc;
			--header-dim: #bcd7e6;
			--line: #dae3ea;
			--line-strong: #b9c7d2;
			--text: #15202a;
			--text-dim: #4a5a69;
			--text-faint: #6a7a89;

			--shadow: 0 1px 2px rgb(21 32 42 / 10%);
			--glow: 0 0 10px color-mix(in srgb, var(--brand) 30%, transparent);
		}
	}

	/* A step up on a desktop: the rem under every other value grows a sixteenth. */
	@media (min-width: 1100px) {
		html {
			font-size: 106.25%;
		}
	}
}

@layer base {
	* {
		box-sizing: border-box;
	}

	[hidden] {
		display: none !important;
	}

	html {
		background: var(--surface-0);
		-webkit-text-size-adjust: 100%;
		scroll-behavior: smooth;

		/* The sidebar's section links land under the header bar. */
		scroll-padding-top: 4.5rem;
	}

	body {
		margin: 0;
		min-height: 100vh;
		display: flex;
		flex-direction: column;
		background: var(--surface-0);
		color: var(--text);
		font: 400 var(--fs-body)/1.65 var(--font-ui);
		font-variant-numeric: tabular-nums slashed-zero;
		-webkit-font-smoothing: antialiased;
	}

	a {
		color: var(--brand);
		text-decoration: none;
		text-underline-offset: 0.2em;

		&:hover {
			color: var(--brand-strong);
			text-decoration: underline;
		}
	}

	:focus-visible {
		outline: 2px solid var(--accent);
		outline-offset: 2px;
		border-radius: var(--radius-sm);
	}

	h1, h2, h3 {
		margin: 0;
		font-weight: 600;
		letter-spacing: var(--ls-tight);
	}

	p {
		margin: 0 0 0.75rem;
	}

	code {
		font-family: var(--font-mono);
		font-size: 0.92em;
		color: var(--text);
		background: var(--surface-2);
		border: 1px solid var(--line);
		border-radius: var(--radius-sm);
		/* Tight: a comma after a name belongs against it, and the padding of a
		   chip reads as a word space. */
		padding: 0 0.2em;
	}

	/* A block of php, which a reader copies. The brand rule on the first edge
	   names the language of the block. */
	pre {
		max-width: var(--measure);
		margin: 0.8rem 0;
		padding: 0.8rem 1rem;
		overflow-x: auto;
		border: 1px solid var(--line);
		border-inline-start: 3px solid var(--brand);
		border-radius: var(--radius);
		background: var(--surface-1);
		box-shadow: var(--shadow);
		font-family: var(--font-mono);
		font-size: var(--fs-sm);
		line-height: 1.75;
		tab-size: 4;

		& code {
			padding: 0;
			border: 0;
			background: none;
			font-size: 1em;
			color: inherit;
		}
	}

	/* The first stop of the page, off screen until the keyboard reaches it. */
	.skip-link {
		position: absolute;
		left: 0.5rem;
		top: -4rem;
		z-index: 100;
		padding: 0.5rem 0.9rem;
		border: 1px solid var(--line-strong);
		border-radius: var(--radius);
		background: var(--surface-1);
		color: var(--text);

		&:focus {
			top: 0.5rem;
		}
	}

	main:focus {
		outline: none;
	}
}

@layer layout {
	/* One measure for the whole document. The header bar and the page below it
	   run full width, and the text inside both stops at the same two edges. */
	.container {
		width: 100%;
		max-width: var(--shell);
		margin-inline: auto;
		padding-inline: var(--pad);
	}

	header.top {
		position: sticky;
		top: 0;
		z-index: 20;
		padding-block: 0.6rem;
		border-bottom: 1px solid color-mix(in srgb, var(--header-bg) 60%, black);
		background: var(--header-bg);
		color: var(--header-ink);
		box-shadow: var(--shadow);

		& .container {
			display: flex;
			align-items: center;
			gap: 0.8rem;
		}

		& .brand {
			margin: 0;
			font-family: var(--font-mono);
			font-size: var(--fs-lg);
			font-weight: 600;
			letter-spacing: var(--ls-tight);
			white-space: nowrap;

			& a {
				display: inline-flex;
				align-items: center;
				gap: 0.55rem;
				color: var(--header-ink);

				&:hover {
					text-decoration: none;
					color: var(--header-ink);

					& .logo .box {
						stroke: var(--brand-strong);
						filter: drop-shadow(0 0 9px color-mix(in srgb, var(--brand) 85%, transparent));
					}
				}
			}
		}

		/* The mark: php$ in a box, the box lit in the brand blue and the $ in
		   its complement. */
		& .logo {
			flex: 0 0 auto;

			& .box {
				fill: color-mix(in srgb, var(--header-bg) 70%, black);
				stroke: var(--brand);
				stroke-width: 1.5;
				filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brand) 60%, transparent));
			}

			& .word {
				font-family: var(--font-mono);
				font-size: 13px;
				font-weight: 700;
				fill: var(--header-ink);
			}

			& .sigil {
				font-family: var(--font-mono);
				font-size: 13px;
				font-weight: 700;
				fill: var(--accent);
				filter: drop-shadow(0 0 5px color-mix(in srgb, var(--accent) 55%, transparent));
			}
		}

		& .brand-tag {
			margin: 0;
			padding: 0.1rem 0.4rem;
			border: 1px solid color-mix(in srgb, var(--header-dim) 45%, transparent);
			border-radius: var(--radius-sm);
			color: var(--header-dim);
			font-size: var(--fs-label);
			letter-spacing: var(--ls-label);
			text-transform: uppercase;
		}

		& .spacer {
			flex: 1;
		}

		& .top-nav {
			display: flex;
			align-items: center;
			gap: 1.2rem;

			& a {
				color: var(--header-dim);
				font-size: var(--fs-sm);

				&:hover {
					color: var(--header-ink);
					text-decoration: none;
				}
			}

			/* The mark closes the row the two words open. inline-flex holds it
			   on the line the two links beside it share. */
			& a.icon {
				display: inline-flex;

				& svg {
					fill: currentcolor;
				}
			}
		}

		& .nav-toggle {
			display: inline-flex;
			align-items: center;
			gap: 0.45rem;
			height: 1.8rem;
			padding: 0 0.6rem;
			border: 1px solid color-mix(in srgb, var(--header-dim) 45%, transparent);
			border-radius: var(--radius-sm);
			background: color-mix(in srgb, var(--header-bg) 70%, black);
			color: var(--header-dim);
			font: inherit;
			font-size: var(--fs-xs);
			letter-spacing: var(--ls-label);
			text-transform: uppercase;
			cursor: pointer;

			& .bars {
				width: 0.8rem;
				height: 0.55rem;
				border-top: 1px solid currentcolor;
				border-bottom: 1px solid currentcolor;
			}

			&[aria-expanded="true"] {
				border-color: var(--brand-strong);
				background: var(--brand);
				color: var(--header-ink);
			}
		}
	}

	.shell {
		position: relative;
		z-index: 1;
		flex: 1;
		display: grid;
		grid-template-columns: var(--side) minmax(0, 1fr);
		gap: 2.4rem;
	}

	/* The menu gets a separate surface, the way php.net sets its sidebar off
	   from the page. A hairline closes it on the reading edge. */
	aside.side {
		margin-inline-start: calc(-1 * var(--pad));
		padding: 1.3rem 1.5rem 2rem;
		border-inline-end: 1px solid var(--line);
		background: var(--surface-side);

		& nav {
			position: sticky;
			top: 3.6rem;
			max-height: calc(100vh - 5rem);
			overflow-y: auto;
		}

		& .side-label {
			margin: 1.3rem 0 var(--head-gap);
			color: var(--text-faint);
			font-size: var(--fs-label);
			font-weight: 600;
			letter-spacing: var(--ls-label);
			text-transform: uppercase;

			&:first-child {
				margin-top: 0;
			}
		}

		& ul {
			margin: 0;
			padding: 0;
			list-style: none;
		}

		& a {
			display: block;
			padding: 0.25rem 0.5rem;
			border-inline-start: 2px solid transparent;
			border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
			color: var(--text-dim);
			font-size: var(--fs-sm);
			overflow-wrap: anywhere;

			&:hover {
				background: var(--surface-2);
				color: var(--text);
				text-decoration: none;
			}

			/* The page the reader opened, with the rail php.net runs down its
			   current item. */
			&.current {
				border-inline-start-color: var(--brand);
				background: var(--brand-wash);
				color: var(--brand-strong);
			}
		}

		& .mono a,
		& .side-toc a {
			font-family: var(--font-mono);
			font-size: var(--fs-xs);
		}

		& .side-toc a {
			color: var(--text-faint);
		}
	}

	main.content {
		min-width: 0;
		padding: 1.3rem 0 4rem;
	}
}

@layer components {
	.crumbs {
		margin-bottom: 1rem;
		font-family: var(--font-mono);
		font-size: var(--fs-xs);
		color: var(--text-faint);

		& ol {
			display: flex;
			flex-wrap: wrap;
			margin: 0;
			padding: 0;
			list-style: none;
		}

		& a {
			color: var(--text-dim);

			&:hover {
				color: var(--brand);
			}
		}

		& li:not(:last-child)::after {
			content: "/";
			margin: 0 0.45rem;
			color: var(--line-strong);
		}
	}

	.page-head {
		padding-bottom: 1rem;
		margin-bottom: var(--block-gap);
		border-bottom: 1px solid var(--line);

		& .kind {
			display: flex;
			align-items: center;
			gap: 0.5rem;
			margin: 0 0 0.35rem;
			color: var(--accent);
			font-size: var(--fs-label);
			font-weight: 600;
			letter-spacing: var(--ls-label);
			text-transform: uppercase;
		}

		& h1 {
			font-family: var(--font-mono);
			font-size: var(--fs-title);
			overflow-wrap: anywhere;
		}

		& .lead {
			margin: 0.5rem 0 0;
			max-width: var(--measure);
			color: var(--text-dim);
		}
	}

	/* A chip beside a title, naming where the page reads its content. The Go
	   label wears go.dev's own colour. */
	.label {
		padding: 0.05rem 0.4rem;
		border: 1px solid currentcolor;
		border-radius: 999px;
		font-size: var(--fs-label);
		font-weight: 600;
		letter-spacing: var(--ls-label);
		text-transform: uppercase;

		&.label-go {
			color: var(--go);
			background: color-mix(in srgb, var(--go) 12%, transparent);
		}
	}

	/* What php.net opens a symbol page with: the declaration, and the members
	   between the braces. */
	.synopsis {
		margin-bottom: var(--block-gap);
		padding: 1rem 1.1rem;
		border: 1px solid var(--line);
		border-inline-start: 3px solid var(--brand);
		border-radius: var(--radius);
		background: var(--surface-1);
		box-shadow: var(--shadow);

		& .signature {
			margin: 0;
			font-family: var(--font-mono);
			font-size: var(--fs-lg);
			color: var(--text-dim);
			overflow-wrap: anywhere;

			& b {
				color: var(--text);
				font-weight: 600;
			}
		}

		& .keyword {
			color: var(--text-faint);
		}

		/* An argument list the binding leaves unsaid. */
		& .unknown {
			color: var(--rose);
		}

		& .members {
			margin: 0.45rem 0;
			padding: 0 0 0 1.6rem;
			list-style: none;
			font-family: var(--font-mono);
			font-size: var(--fs-sm);
			color: var(--text-dim);

			& li {
				padding: 0.1rem 0;
			}

			/* A declaration is the text of the link, the way php.net lists the
			   members of a class. Full ink, and the brand on the way past. */
			& a {
				color: var(--text);

				&:hover {
					color: var(--brand);
					text-decoration: none;
				}
			}
		}
	}

	section.block {
		margin-bottom: var(--block-gap);

		& > h2 {
			display: flex;
			align-items: baseline;
			gap: 0.6rem;
			margin-bottom: var(--head-gap);
			padding-bottom: 0.4rem;
			border-bottom: 1px solid var(--line);
			color: var(--text);
			font-size: var(--fs-h2);
		}

		& > p {
			max-width: var(--measure);
		}

		& > p:last-child {
			margin-bottom: 0;
		}
	}

	/* One member per declaration, the signature over its doc comment, as
	   pkg.go.dev prints a func. */
	dl.member-list {
		margin: 0;

		& dt {
			margin-top: 1.1rem;
			scroll-margin-top: 5rem;

			& code {
				display: inline-block;
				max-width: 100%;
				padding: 0.3rem 0.6rem;
				border-inline-start: 3px solid var(--line-strong);
				background: var(--surface-1);
				font-size: var(--fs-sm);
				overflow-wrap: anywhere;
			}

			&:target code {
				border-inline-start-color: var(--accent);
			}
		}

		& dd {
			margin: 0.5rem 0 0 0.9rem;
			max-width: var(--measure);
			color: var(--text-dim);
		}
	}

	/* Where a member comes from on the Go side. */
	p.binding {
		margin: 0.35rem 0 0;
		color: var(--text-faint);
		font-size: var(--fs-xs);
	}

	ul.links {
		margin: 0;
		padding: 0;
		list-style: none;

		& li {
			padding: 0.2rem 0;
			color: var(--text-dim);
		}
	}

	/* The front page's three ways in. */
	ul.cards {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
		gap: 0.8rem;
		margin: 0;
		padding: 0;
		list-style: none;

		& li {
			padding: 0.9rem 1rem;
			border: 1px solid var(--line);
			border-radius: var(--radius);
			background: var(--surface-1);
			box-shadow: var(--shadow);
			transition: border-color 0.15s ease, transform 0.15s ease;

			&:hover {
				border-color: var(--brand);
				transform: translateY(-1px);
			}
		}

		& a {
			font-family: var(--font-mono);
			font-size: var(--fs-sm);
		}

		& p {
			margin: 0.3rem 0 0;
			color: var(--text-dim);
			font-size: var(--fs-sm);
		}
	}

	ul.symbol-list {
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
		gap: 0 1.6rem;
		margin: 0;
		padding: 0;
		list-style: none;

		& li {
			border-bottom: 1px solid var(--line);
		}

		& a {
			display: block;
			padding: 0.25rem 0.2rem;
			font-family: var(--font-mono);
			font-size: var(--fs-sm);
			color: var(--text-dim);
			overflow-wrap: anywhere;

			&:hover {
				background: var(--brand-wash);
				color: var(--brand-strong);
				text-decoration: none;
			}
		}
	}

	/* The filter the script puts above a rendered list. */
	.filter {
		display: flex;
		align-items: center;
		gap: 0.8rem;
		margin-bottom: var(--block-gap);

		& input {
			flex: 1;
			min-width: 0;
			max-width: 24rem;
			height: 2.4rem;
			padding: 0 0.7rem;
			border: 1px solid var(--line-strong);
			border-radius: var(--radius);
			background: var(--surface-1);
			color: var(--text);
			font-family: var(--font-mono);
			font-size: var(--fs-sm);

			&::placeholder {
				color: var(--text-faint);
			}

			&:focus {
				border-color: var(--brand);
				box-shadow: 0 0 0 3px var(--brand-wash);
				outline: none;
			}
		}

		& output {
			color: var(--lime);
			font-family: var(--font-mono);
			font-size: var(--fs-xs);
			white-space: nowrap;
		}
	}

	/* The link the script hangs off a heading, for a reader who copies the url
	   of one section. */
	a.anchor {
		margin-inline-start: 0.35rem;
		color: var(--text-faint);
		font-family: var(--font-mono);
		font-weight: 400;
		opacity: 0;
		transition: opacity 0.15s ease;

		&:hover,
		&:focus-visible {
			opacity: 1;
			text-decoration: none;
		}

		:hover > & {
			opacity: 1;
		}
	}
}

@media (max-width: 60rem) {
	:root {
		--pad: 1rem;
	}

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

	/* The sidebar becomes a drawer the header's button opens, over the page. */
	aside.side {
		position: fixed;
		z-index: 15;
		inset: 3.3rem 0 auto 0;
		max-height: calc(100vh - 3.3rem);
		overflow-y: auto;
		margin-inline-start: 0;
		border-inline-end: 0;
		border-bottom: 1px solid var(--line-strong);
		box-shadow: var(--shadow);
		padding: 1rem var(--pad);

		& nav {
			position: static;
			max-height: none;
		}
	}

	header.top {
		& .brand-tag {
			display: none;
		}

		/* The two words go, the mark stays. A narrow bar holds the toggle, the
		   brand and one target. The row stops wrapping. */
		& .top-nav a:not(.icon) {
			display: none;
		}
	}
}
