/*
Theme Name: Boxware 2026
Theme URI: https://www.boxware.net
Author: Boxware, LLC
Author URI: https://www.boxware.net
Description: Minimal single-page block theme for Boxware: flat, sharp, ASCII art.
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 7.4
Version: 1.10.3
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: boxware-2026
Tags:
*/

/*
 * Colors, type, spacing and element styles live in theme.json.
 * This file covers what theme.json can't: the ASCII logo, the prompts and
 * their output, the cursor, and the Gravity Forms contact form.
 *
 * Like a terminal, the page has one font and one size: Source Code Pro at
 * 0.786rem (the logo keeps the system monospace it was drawn in). Bold is
 * kept for prompts, headlines and directory names, green for the prompt,
 * the cursor and focus.
 *
 * The vertical rhythm is the terminal line (--bw-line: 0.786rem x 1.618).
 * A command's output follows its prompt directly, and one blank line
 * separates one command from the next (theme.json's block gap is one line).
 * Other spacing uses the golden-ratio presets in theme.json:
 * 0.382 / 0.618 / 1 / 1.618 / 2.618 / 4.236 / 6.854rem (phi^-2 ... phi^4).
 *
 * Prompts, arrows and brackets are drawn in CSS with empty alt text
 * (content: "x" / ""), so screen readers hear the words, not the chrome.
 */

:root {
	--bw-line: calc(var(--wp--preset--font-size--micro) * 1.618);
	--bw-shadow: var(--wp--preset--color--muted);
}

html {
	color-scheme: dark;
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

/* Wide screens: the whole screen prints one size up. */
@media (min-width: 1200px) {
	html {
		font-size: 112.5%;
	}
}

body {
	font-variant-ligatures: none;
	-webkit-tap-highlight-color: transparent;
}

::selection {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}

a {
	text-decoration-thickness: 1px;
	text-underline-offset: 0.382em;
}

/* Header, main and footer are spaced by their own padding, not the block gap. */
.wp-site-blocks > * {
	margin-block-start: 0;
}

/*
 * The output runs down the left edge of the screen and wraps at 80 columns
 * (theme.json's content size) instead of sitting in a centered column.
 */
:is(.wp-site-blocks, .editor-styles-wrapper) .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	margin-left: 0 !important;
}

/* Idle prompt and shell ------------------------------------------------------
 *
 * The session ends with a prompt and the blinking cursor, printed after the
 * footer by boxware_2026_idle_prompt() in functions.php. terminal.js turns it
 * into a shell: what's typed goes in a field after the prompt, and commands
 * and their output print above it, in the content's column.
 */
.bw-term__end {
	padding: var(--bw-line) var(--wp--style--root--padding-right, 1rem) var(--bw-line) var(--wp--style--root--padding-left, 1rem);
}

.bw-term__line,
.bw-term__log {
	max-width: var(--wp--style--global--content-size, 80ch);
	margin: 0;
}

.bw-term__line {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: 1ch;
}

.bw-term__line > .bw-ps1 {
	flex: none;
	white-space: nowrap;
}

.bw-term__log > *,
.bw-term__run > * {
	margin: 0;
}

/* Each typed command and its output, with a blank line under it like the page's commands. */
.bw-term__log > .bw-term__run {
	margin-bottom: var(--bw-line);
}

.bw-term__out,
.bw-term__echo {
	margin: 0;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

.bw-term__out.is-muted {
	color: var(--wp--preset--color--muted);
}

/* Fixed-width dumps scroll sideways on a narrow screen instead of wrapping. */
.bw-term__out--dump {
	overflow-x: auto;
	white-space: pre;
	overflow-wrap: normal;
}

/* neofetch: the box in green, the keys in bold green, the palette as blocks. */
.bw-neofetch {
	white-space: pre;
}

.bw-neofetch .is-logo,
.bw-neofetch .is-key {
	color: var(--wp--preset--color--accent);
}

.bw-neofetch .is-key {
	font-weight: 700;
}

/*
 * The field: no box, the system caret hidden. The block cursor follows the
 * caret instead (terminal.js sets --bw-caret in characters), inverting the
 * character under it, and turns hollow while the field isn't focused, the
 * way a terminal shows a window in the background. The grey "help" is a
 * suggestion, like fish's: the right arrow takes it.
 */
.bw-term__field {
	position: relative;
	flex: 1 1 12ch;
	min-width: 12ch;
	cursor: text;
}

.bw-term__input {
	display: block;
	box-sizing: border-box;
	width: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: var(--wp--preset--color--contrast);
	caret-color: transparent;
	font: inherit;
	line-height: inherit;
	-webkit-appearance: none;
	appearance: none;
}

.bw-term__input:focus {
	outline: 0;
}

.bw-term__input::placeholder {
	color: var(--wp--preset--color--muted);
	opacity: 1;
}

.bw-term__field .bw-term__cursor {
	position: absolute;
	top: 50%;
	left: calc(var(--bw-caret-x, 0px) - var(--bw-scroll, 0px));
	width: var(--bw-caret-w, 0.6em);
	transform: translateY(-50%);
	pointer-events: none;
	mix-blend-mode: difference;
}

/* An outline, not a shadow, so the hollow cursor survives forced colors too. */
.bw-term__input:not(:focus) + .bw-term__cursor {
	background: transparent;
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: -1px;
	mix-blend-mode: normal;
}

.bw-term__field.is-typing .bw-term__cursor {
	animation: none;
}

/* While a game runs the prompt waits out of sight (its field still takes the keys). */
.bw-term__line.is-playing {
	opacity: 0;
}

/* Touch screens zoom into text fields set under 16px. */
@media (pointer: coarse) {
	.bw-term__field {
		font-size: max(16px, 1em);
	}
}

/* The game: snake.js draws its board here. If the screen narrows mid-game, the board scrolls in its own box. */
.bw-snake {
	max-width: 100%;
	overflow-x: auto;
}

.bw-snake__board {
	margin: 0;
	color: var(--wp--preset--color--muted);
	font: inherit;
	line-height: 1.1;
	white-space: pre;
	touch-action: none;
	-webkit-user-select: none;
	user-select: none;
}

.bw-snake__board .is-label,
.bw-snake__board .is-note,
.bw-snake__board .is-bug,
.bw-snake__board .is-message {
	color: var(--wp--preset--color--contrast);
}

.bw-snake__board .is-worm,
.bw-snake__board .is-live {
	color: var(--wp--preset--color--accent);
}

.bw-snake__board .is-worm,
.bw-snake__board .is-bug,
.bw-snake__board .is-message {
	font-weight: 700;
}

/* The worm's head, and the head of a falling drop in the segfault: solid cells, like the cursor. */
.bw-snake__board .is-head,
.bw-snake__board .is-drop {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	font-weight: 700;
}

.bw-snake__status {
	margin: 0;
	color: var(--wp--preset--color--muted);
	white-space: pre-wrap;
}

.bw-snake__quit {
	margin: 0 0 0 2ch;
	padding: 0 var(--wp--preset--spacing--10);
	border: 0;
	border-radius: 0;
	background: none;
	color: var(--wp--preset--color--muted);
	cursor: pointer;
	font: inherit;
}

.bw-snake__quit::before {
	content: "[";
	content: "[" / "";
}

.bw-snake__quit::after {
	content: "]";
	content: "]" / "";
}

.bw-snake__quit:hover,
.bw-snake__quit:focus-visible {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* The one cursor, waiting at the end of the session. */
.bw-term__cursor {
	display: inline-block;
	width: 0.6em;
	height: 1.15em;
	background: var(--wp--preset--color--accent);
	vertical-align: text-bottom;
	animation: bw-blink 1.2s steps(1, end) infinite;
}

@keyframes bw-blink {
	50% {
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bw-term__cursor {
		animation: none;
	}
}

/* Boot: the session replays ---------------------------------------------------
 *
 * While <html> has the bw-boot class (added in <head> by boxware_2026_boot()),
 * a curtain hides the output that hasn't printed yet. terminal.js moves its
 * top edge, the print head, down a line at a time; the cursor rides at the
 * start of the next line. CSS lifts the curtain after 2.5s regardless, so a
 * failed script can't keep the page hidden.
 */
.bw-boot .wp-site-blocks {
	position: relative;
}

.bw-boot .wp-site-blocks::after {
	position: absolute;
	z-index: 100;
	top: var(--bw-print, 0px);
	right: 0;
	bottom: 0;
	left: 0;
	background:
		linear-gradient(var(--wp--preset--color--accent), var(--wp--preset--color--accent)) var(--wp--style--root--padding-left, 1rem) 0.234em / 0.6em 1.15em no-repeat,
		var(--wp--preset--color--base);
	content: "";
	animation: bw-boot-lift 0s 2.5s forwards;
}

.bw-boot .bw-term__end {
	visibility: hidden;
	animation: bw-boot-show 0s 2.5s forwards;
}

@keyframes bw-boot-lift {
	to {
		visibility: hidden;
	}
}

@keyframes bw-boot-show {
	to {
		visibility: visible;
	}
}

/* Prompts --------------------------------------------------------------------
 *
 * Every command opens with the prompt, green and bold, and the command after
 * it in plain text: root@boxware:~# ls. The page's session runs as root, with
 * root's "#"; the prompt left open at the end is the visitor's, as guest
 * ("$"). Phones shorten them to ~# and ~$.
 */
.bw-ps1,
.bw-pwd,
.bw-hero::before,
.bw-prompt::before {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
}

.bw-cmd {
	margin: 0;
}

@media (max-width: 479px) {
	.bw-ps1__host,
	.bw-pwd__ps1 {
		display: none;
	}
}

/* Masthead: the logo prints like a login banner. --------------------------- */

.bw-masthead {
	padding-top: var(--wp--preset--spacing--40);
}

/* ASCII logo (links home) -------------------------------------------------- */

.bw-logo {
	--bw-logo-cols: 75;
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-weight: 700;
	line-height: 1;
	container-type: inline-size;
}

/* The whole wordmark is the home link. It doesn't react to the pointer; keyboard focus gets a green frame. */
.bw-logo a,
.bw-logo a:hover {
	display: inline-block;
	margin: calc(-1 * var(--wp--preset--spacing--10)) calc(-1 * var(--wp--preset--spacing--20));
	padding: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20);
	background: none;
	color: inherit;
	text-decoration: none;
}

.bw-logo a:focus-visible {
	background: none;
	color: inherit;
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: 0;
}

/*
 * The art prints at the terminal size (0.786rem) and shrinks to fit narrow
 * screens without wrapping: width / (columns x 0.62em, the widest common
 * monospace advance; Apple's SF Mono is 0.618em, Menlo 0.602em).
 */
.bw-logo__art {
	display: block;
	font-size: min(var(--wp--preset--font-size--micro), (100vw - 2rem) / (var(--bw-logo-cols) * 0.62));
	font-weight: 700;
	letter-spacing: 0;
	line-height: 1.15;
	white-space: pre;
	font-kerning: none;
	font-variant-ligatures: none;
	font-feature-settings: "liga" 0, "calt" 0;
}

@supports (width: 1cqi) {
	.bw-logo__art {
		font-size: min(var(--wp--preset--font-size--micro), 100cqi / (var(--bw-logo-cols) * 0.62));
	}
}

/*
 * Animation (assets/js/logo.js): scrambling glyphs print green, and the head
 * of a falling drop is a solid green cell, like the cursor.
 */
.bw-logo__art .is-live {
	color: var(--wp--preset--color--accent);
}

.bw-logo__art .is-head {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}

/* Phones get the same lettering stacked BOX / WARE. */
.bw-logo__art--stack {
	--bw-logo-cols: 42;
	display: none;
}

@media (max-width: 479px) {
	.bw-logo__art--wide {
		display: none;
	}

	.bw-logo__art--stack {
		display: block;
	}
}

/* Links in the output: lowercase, inverted under the pointer ------------------ */

.bw-anchors__list,
.bw-social {
	display: flex;
	flex-wrap: wrap;
	gap: 0 2ch;
	margin: 0;
	padding: 0;
	list-style: none;
	text-transform: lowercase;
}

/* Inverted hover needs a little room around short links. */
.bw-anchors__list a,
.bw-social a,
.bw-legal a,
.bw-term__out a {
	display: inline-block;
	min-width: 24px;
	margin: 0 calc(-1 * var(--wp--preset--spacing--10));
	padding: 0 var(--wp--preset--spacing--10);
	text-align: center;
}

/*
 * Nav: `ls` in the home directory. The prompt's "~" is the home link and the
 * current path is filled in by boxware_2026_pwd() (~/terms# ls); the output
 * lists the sections like directories, in bold.
 */
.bw-masthead > .bw-anchors {
	margin-block-start: var(--bw-line);
}

.bw-pwd {
	margin: 0;
	white-space: nowrap;
}

.bw-pwd a {
	color: inherit;
	text-decoration: none;
}

.bw-pwd a:hover,
.bw-pwd a:focus-visible {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.bw-pwd__cmd {
	color: var(--wp--preset--color--contrast);
	font-weight: 400;
}

/* Paths and commands that PHP prints are <code> only to keep WordPress's typography off them (functions.php). */
.bw-code {
	padding: 0;
	background: none;
	color: inherit;
	font: inherit;
}

.bw-anchors > .bw-anchors__list {
	margin: 0;
}

.bw-anchors__list a {
	font-weight: 700;
}

#about {
	scroll-margin-top: var(--wp--preset--spacing--40);
}

/* Hero: whoami ------------------------------------------------------------------ */

main.wp-block-group {
	padding-top: var(--bw-line);
	padding-bottom: 0;
}

/*
 * The prompt hangs off the section and the command ("whoami") off its first
 * line of output, whatever that is (a headline, or just the lead), so the
 * editor shows only the output.
 */
.bw-hero {
	position: relative;
}

.bw-hero::before {
	position: absolute;
	top: 0;
	left: 0;
	line-height: 1.618;
	content: "root@boxware:~#";
	content: "root@boxware:~#" / "";
}

.bw-hero > :first-child::before {
	display: block;
	padding-left: 16ch;
	color: var(--wp--preset--color--contrast);
	font-weight: 400;
	content: "whoami";
	content: "whoami" / "";
}

/* A headline, if there is one, prints in bold white, the same size as everything else. */
.bw-hero__title {
	margin: 0;
	line-height: 1.618;
}

.bw-hero > .bw-hero__lead {
	margin: 0;
	color: var(--wp--preset--color--muted);
}

/* Projects: `tree` output ----------------------------------------------------
 *
 * In the editor this is a plain list of projects, optionally with a nested
 * list of services under each. CSS draws the tree: the root path and the |--
 * connectors. With no services it prints as `tree -d`, directories only.
 */
.wp-block-group.bw-projects,
.wp-block-group.bw-contact {
	margin-block-start: var(--bw-line);
}

.bw-projects {
	scroll-margin-top: var(--wp--preset--spacing--40);
}

/* "$ tree ~/projects": the green "$", then the command, then the heading text. */
.bw-prompt--tree {
	display: flex;
	white-space: pre;
}

.bw-prompt--tree::before {
	order: -2;
}

/* `tree -d` (directories only), unless there are services under the projects. */
.bw-prompt--tree::after {
	order: -1;
	content: "tree -d ~/";
	content: "tree -d ~/" / "";
}

.bw-prompt--tree:has(+ .bw-tree li li)::after {
	content: "tree ~/";
	content: "tree ~/" / "";
}

.bw-tree,
.bw-tree ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.bw-projects > .bw-tree {
	margin: 0;
}

.bw-tree {
	line-height: 1.272;
}

.bw-tree li li {
	/* Long entries wrap under their own text, not under the connectors ("|   |-- " is 8ch). */
	padding-left: 8ch;
	text-indent: -8ch;
}

.bw-tree::before,
.bw-tree li::before {
	color: var(--wp--preset--color--muted);
	white-space: pre;
}

.bw-tree::before {
	display: block;
	content: "/root/projects";
	content: "/root/projects" / "";
}

.bw-tree > li::before {
	content: "|-- ";
	content: "|-- " / "";
}

.bw-tree > li:last-child::before {
	content: "`-- ";
	content: "`-- " / "";
}

.bw-tree > li:not(:last-child) li::before {
	content: "|   |-- ";
	content: "|   |-- " / "";
}

.bw-tree > li:not(:last-child) li:last-child::before {
	content: "|   `-- ";
	content: "|   `-- " / "";
}

.bw-tree > li:last-child li::before {
	content: "    |-- ";
	content: "    |-- " / "";
}

.bw-tree > li:last-child li:last-child::before {
	content: "    `-- ";
	content: "    `-- " / "";
}

/* Directories print bold, like `tree -C`; they invert on hover like every link. */
.bw-tree > li > a {
	font-weight: 700;
}

.bw-tree > li > a:hover,
.bw-tree > li > a:focus-visible {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* Contact: the command, a note, and the key that opens the form ------------- */

.bw-prompt {
	margin: 0;
	font-weight: 400;
	line-height: 1.618;
	text-transform: lowercase;
	scroll-margin-top: var(--wp--preset--spacing--40);
}

.bw-prompt::before {
	content: "root@boxware:~# ";
	content: "root@boxware:~# " / "";
}

@media (max-width: 479px) {
	.bw-hero::before {
		content: "~#";
		content: "~#" / "";
	}

	.bw-hero > :first-child::before {
		padding-left: 3ch;
	}

	.bw-prompt::before {
		content: "~# ";
		content: "~# " / "";
	}
}

.bw-contact > .bw-lead {
	margin: 0;
	color: var(--wp--preset--color--muted);
}

.bw-lead {
	color: var(--wp--preset--color--muted);
}

.bw-contact > .bw-dialog-open {
	margin: var(--bw-line) 0 0;
}

/* Keys -----------------------------------------------------------------------
 *
 * Buttons are BIOS-style keys: a solid block with a hard shadow one cell to
 * the right and half a cell down. Pressing one pushes it into its shadow.
 */
.bw-key,
.gform_wrapper .gform_button,
.gform_wrapper .gform_footer input[type="submit"] {
	min-height: var(--wp--preset--spacing--50);
	margin: 0;
	padding: 0 var(--wp--preset--spacing--40);
	border: 0;
	border-radius: 0;
	background: var(--wp--preset--color--contrast);
	box-shadow: 1ch 0.5em 0 0 var(--bw-shadow);
	color: var(--wp--preset--color--base);
	cursor: pointer;
	font: inherit;
	font-weight: 700;
	line-height: 1;
	text-transform: lowercase;
	-webkit-appearance: none;
	appearance: none;
	transition: none;
}

.bw-key:hover,
.bw-key:focus-visible,
.gform_wrapper .gform_button:hover,
.gform_wrapper .gform_button:focus-visible,
.gform_wrapper .gform_footer input[type="submit"]:hover,
.gform_wrapper .gform_footer input[type="submit"]:focus-visible {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}

.bw-key:focus-visible,
.gform_wrapper .gform_button:focus-visible,
.gform_wrapper .gform_footer input[type="submit"]:focus-visible {
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

.bw-key:active,
.gform_wrapper .gform_button:active,
.gform_wrapper .gform_footer input[type="submit"]:active {
	box-shadow: none;
	transform: translate(1ch, 0.5em);
}

/* Contact dialog --------------------------------------------------------------
 *
 * The form opens in a box like `dialog --form`: a double-line frame with the
 * title in its top edge and a hard shadow, over a dithered screen.
 * boxware_2026_contact_dialog() wraps the form block in the <dialog>; "new
 * message" or a link to #contact opens it, Esc, "esc" or a click outside
 * closes it. It stays laid out (just invisible) while closed, so the spam
 * check inside it loads as usual. Without JavaScript the form prints in place.
 */
.bw-js .bw-dialog {
	position: fixed;
	inset: 0;
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
	width: min(80ch, 100% - 2 * var(--wp--style--root--padding-left, 1rem));
	max-width: none;
	height: fit-content;
	max-height: calc(100% - 2 * var(--wp--preset--spacing--50));
	margin: auto;
	padding: 0;
	overflow: visible;
	border: 3px double var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--base);
	box-shadow: 2ch 1em 0 0 #000;
	color: var(--wp--preset--color--contrast);
}

.bw-js .bw-dialog:not([open]) {
	visibility: hidden;
	pointer-events: none;
}

.bw-dialog::backdrop {
	background: repeating-conic-gradient(#34332f 0 25%, #0d0d0c 0 50%) 0 0 / 4px 4px;
	opacity: 0.92;
}

html:has(.bw-dialog[open]) {
	overflow: hidden;
}

.bw-dialog__title {
	position: absolute;
	top: -1.5px;
	left: 50%;
	margin: 0;
	padding: 0 1ch;
	background: var(--wp--preset--color--base);
	font-weight: 700;
	line-height: 1.618;
	white-space: nowrap;
	transform: translate(-50%, -50%);
}

.bw-dialog__body {
	flex: 1 1 auto;
	min-height: 0;
	overflow: auto;
	padding: calc(var(--bw-line) + var(--wp--preset--spacing--20)) 2ch var(--bw-line);
	overscroll-behavior: contain;
}

.bw-dialog__body > * {
	margin-top: 0;
}

/* "[esc]" sits in the frame's top edge, right. */
.bw-dialog__close {
	position: absolute;
	top: -1.5px;
	right: 2ch;
	margin: 0;
	padding: 0 1ch;
	border: 0;
	border-radius: 0;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--muted);
	cursor: pointer;
	font: inherit;
	line-height: 1.618;
	transform: translateY(-50%);
}

.bw-dialog__close::before {
	content: "[";
	content: "[" / "";
}

.bw-dialog__close::after {
	content: "]";
	content: "]" / "";
}

.bw-dialog__close:hover,
.bw-dialog__close:focus-visible {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.bw-dialog__close:focus-visible {
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* Without JavaScript: no key, no frame, the form prints after the note. */
html:not(.bw-js) .bw-dialog-open,
html:not(.bw-js) .bw-dialog__title,
html:not(.bw-js) .bw-dialog__close {
	display: none;
}

html:not(.bw-js) .bw-dialog {
	position: static;
	display: block;
	width: auto;
	max-width: none;
	height: auto;
	margin: var(--bw-line) 0 0;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
}

html:not(.bw-js) .bw-dialog__body {
	padding: 0;
	overflow: visible;
}

/* Footer: cat ~/.signature && su - guest ------------------------------------
 *
 * root's last command. The links print on one line, like ls (terms joins the
 * social links), and the copyright on the line under them; "su - guest" hands
 * the terminal to the visitor's prompt after the footer. The legal group's own
 * box steps aside (display: contents) so its two paragraphs line up with the
 * links.
 */
.bw-footer {
	padding-top: var(--bw-line);
}

.bw-footer > .bw-footer__inner {
	flex-flow: row wrap;
	align-items: baseline;
	justify-content: flex-start;
	gap: 0 2ch;
	margin: 0;
}

/* Two spaces between the links space them out enough, so they skip the 24px minimum (which padded "x" out of line). */
.bw-footer .bw-social a,
.bw-footer .bw-legal a,
.bw-term__out a {
	min-width: 0;
}

body:not(.editor-styles-wrapper) .bw-footer .bw-legal {
	display: contents;
}

.bw-legal p {
	margin: 0;
}

.bw-legal > p:not(.bw-copyright) {
	order: 1;
}

.bw-legal > .bw-copyright {
	flex-basis: 100%;
	order: 2;
	color: var(--wp--preset--color--muted);
	text-transform: lowercase;
}

.bw-legal a {
	text-transform: lowercase;
}

/* Gravity Forms: an interactive shell prompt ---------------------------------
 *
 * Questions print like a CLI prompt ("? Budget"), answers sit in thin boxes
 * with a ">" prompt, choices are [ ] / [x], and state is shown by inversion
 * and the green signal color. Written for Gravity Forms with its own CSS
 * turned off (as on boxware.net); works with legacy and current markup.
 */

.gform_wrapper {
	--bw-field-h: var(--wp--preset--spacing--50);
	--bw-field-pad: var(--wp--preset--spacing--20);
	--bw-prompt-w: 2ch;
}

.gform_wrapper ul.gform_fields,
.gform_wrapper div.gform_fields {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	margin: 0;
	padding: 0;
	list-style: none;
}

.gform_wrapper .gfield {
	grid-column: 1 / -1;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
}

/* Field widths set in the Gravity Forms editor sit side by side on wider screens. */
@media (min-width: 640px) {
	.gform_wrapper ul.gform_fields,
	.gform_wrapper div.gform_fields {
		grid-template-columns: repeat(12, minmax(0, 1fr));
	}

	.gform_wrapper .gfield--width-half,
	.gform_wrapper .gf_left_half,
	.gform_wrapper .gf_right_half {
		grid-column: span 6;
	}

	.gform_wrapper .gfield--width-third,
	.gform_wrapper .gf_left_third,
	.gform_wrapper .gf_middle_third,
	.gform_wrapper .gf_right_third {
		grid-column: span 4;
	}

	.gform_wrapper .gfield--width-two-thirds {
		grid-column: span 8;
	}

	.gform_wrapper .gfield--width-quarter {
		grid-column: span 3;
	}

	.gform_wrapper .gfield--width-three-quarter {
		grid-column: span 9;
	}
}

/* Visible questions print like a CLI prompt: "? What is your budget?" */
.gform_wrapper .gfield_label,
.gform_wrapper legend.gfield_label {
	display: inline-block;
	margin: 0 0 var(--wp--preset--spacing--10);
	padding: 0;
	font-weight: 400;
	line-height: 1.618;
}

.gform_wrapper .gfield_label:not(.screen-reader-text)::before {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
	content: "? ";
	content: "? " / "";
}

.gform_wrapper .gfield_label.screen-reader-text {
	margin: -1px;
	padding: 0;
}

.gform_wrapper .gfield_required {
	padding-left: 0.25em;
	color: var(--wp--preset--color--muted);
	font-weight: 400;
}

.gform_wrapper .gfield_required .gfield_required {
	padding-left: 0;
}

/* Answers: thin boxes with a ">" prompt that lights up while you type. */
.gform_wrapper .ginput_container {
	position: relative;
}

.gform_wrapper :is(.ginput_container_text, .ginput_container_email, .ginput_container_phone, .ginput_container_website, .ginput_container_number, .ginput_container_textarea)::before {
	position: absolute;
	top: calc(var(--bw-field-h) / 2);
	left: var(--bw-field-pad);
	color: var(--wp--preset--color--muted);
	font-weight: 700;
	line-height: 1;
	transform: translateY(-50%);
	pointer-events: none;
	content: ">";
	content: ">" / "";
}

.gform_wrapper .ginput_container:focus-within::before {
	color: var(--wp--preset--color--accent);
}

.gform_wrapper .ginput_container input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="submit"], [type="button"], [type="file"]),
.gform_wrapper .ginput_container select,
.gform_wrapper .ginput_container textarea {
	display: block;
	box-sizing: border-box;
	width: 100%;
	max-width: none;
	height: var(--bw-field-h);
	margin: 0;
	padding: 0 var(--bw-field-pad) 0 calc(2 * var(--bw-field-pad) + var(--bw-prompt-w));
	border: 1px solid var(--wp--preset--color--muted);
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: var(--wp--preset--color--contrast);
	caret-color: var(--wp--preset--color--accent);
	font: inherit;
	line-height: 1.618;
	-webkit-appearance: none;
	appearance: none;
	transition: none;
}

/* Touch screens zoom into text fields set under 16px, so there they get 16px. */
@media (pointer: coarse) {
	.gform_wrapper .ginput_container input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="submit"], [type="button"], [type="file"]),
	.gform_wrapper .ginput_container select,
	.gform_wrapper .ginput_container textarea {
		font-size: max(16px, 1em);
	}
}

.gform_wrapper .ginput_container ::placeholder {
	color: var(--wp--preset--color--muted);
	opacity: 1;
}

.gform_wrapper .ginput_container textarea {
	height: auto;
	min-height: calc(7 * 1.618em + 2px);
	padding-top: calc((var(--bw-field-h) - 1.618em) / 2 - 1px);
	padding-bottom: calc((var(--bw-field-h) - 1.618em) / 2 - 1px);
	resize: vertical;
}

/* Selects keep a plain left edge and print a "v" on the right. */
.gform_wrapper .ginput_container select {
	padding-left: var(--bw-field-pad);
	padding-right: calc(var(--bw-field-pad) * 3);
	background: var(--wp--preset--color--base);
	cursor: pointer;
}

.gform_wrapper .ginput_container_select::after {
	position: absolute;
	top: calc(var(--bw-field-h) / 2);
	right: var(--bw-field-pad);
	color: var(--wp--preset--color--muted);
	font-weight: 700;
	line-height: 1;
	transform: translateY(-50%);
	pointer-events: none;
	content: "v";
	content: "v" / "";
}

/* Focus: the box lights up in the signal color. */
.gform_wrapper .ginput_container :is(input, select, textarea):focus-visible {
	border-color: var(--wp--preset--color--accent);
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: 0;
}

.gform_wrapper .gfield:focus-within > .gfield_label:not(.screen-reader-text) {
	background: var(--wp--preset--color--contrast);
	box-shadow: 0 0 0 var(--wp--preset--spacing--10) var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.gform_wrapper .gfield:focus-within > .gfield_label::before,
.gform_wrapper .gfield:focus-within > .gfield_label .gfield_required {
	color: inherit;
}

/* Checkboxes and radios print as [ ] / [x] and ( ) / (*). */
.gform_wrapper .gfield_checkbox,
.gform_wrapper .gfield_radio {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
	gap: var(--wp--preset--spacing--10) var(--wp--preset--spacing--40);
	margin: 0;
	padding: 0;
	list-style: none;
}

.gform_wrapper .gchoice {
	position: relative;
	display: flex;
	margin: 0;
	padding: 0;
}

.gform_wrapper .gchoice input {
	position: absolute;
	top: 0;
	left: 0;
	width: 1px;
	height: 1px;
	margin: 0;
	opacity: 0;
}

/* The marker sits in its own column, so long choices wrap under the text. */
.gform_wrapper .gchoice label {
	display: grid;
	grid-template-columns: 4ch minmax(0, 1fr);
	margin: 0 calc(-1 * var(--wp--preset--spacing--10));
	padding: 0 var(--wp--preset--spacing--10);
	line-height: 1.618;
	cursor: pointer;
}

.gform_wrapper .gchoice label::before {
	color: var(--wp--preset--color--muted);
	white-space: pre;
}

.gform_wrapper .gchoice input[type="checkbox"] + label::before {
	content: "[ ] ";
	content: "[ ] " / "";
}

.gform_wrapper .gchoice input[type="checkbox"]:checked + label::before {
	content: "[x] ";
	content: "[x] " / "";
}

.gform_wrapper .gchoice input[type="radio"] + label::before {
	content: "( ) ";
	content: "( ) " / "";
}

.gform_wrapper .gchoice input[type="radio"]:checked + label::before {
	content: "(*) ";
	content: "(*) " / "";
}

.gform_wrapper .gchoice input:checked + label::before {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
}

.gform_wrapper .gchoice label:hover,
.gform_wrapper .gchoice input:focus-visible + label {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.gform_wrapper .gchoice label:hover::before,
.gform_wrapper .gchoice input:focus-visible + label::before {
	color: inherit;
}

.gform_wrapper .gchoice input:focus-visible + label {
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* Secondary text: counters and descriptions. */
.gform_wrapper .gfield_description:not(.validation_message),
.gform_wrapper .ginput_counter {
	margin: var(--wp--preset--spacing--10) 0 0;
	padding: 0;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--micro);
	line-height: 1.618;
}

.gform_wrapper .ginput_counter {
	text-align: right;
}

/* Submit: a BIOS key (see Keys, above). */
.gform_wrapper .gform_footer {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	margin: var(--bw-line) 0 0;
	padding: 0;
}

/* No spinner image: the shell prints a status line while sending. */
.gform_wrapper .gform_ajax_spinner {
	display: none;
}

.gform_wrapper .gform_footer:has(.gform_ajax_spinner)::after {
	color: var(--wp--preset--color--muted);
	content: "sending...";
}

/* Errors: an inverted "[!]" banner, "!" on the question, dashed boxes, a ^ note. */
.gform_wrapper .gform_validation_errors,
.gform_wrapper .validation_error {
	margin: 0 0 var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
	border: 0;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-weight: 700;
	line-height: 1.618;
}

.gform_wrapper .gform_validation_errors:focus {
	outline: 1px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

.gform_wrapper .gform_submission_error {
	margin: 0;
	font: inherit;
}

.gform_wrapper .gform_submission_error::before,
.gform_wrapper .validation_error::before {
	content: "[!] ";
	content: "[!] " / "";
}

/* No icons: GF's error glyph is replaced by the [!] above. */
.gform_wrapper .gform-icon {
	display: none;
}

.gform_wrapper .gfield_error .ginput_container :is(input, select, textarea) {
	border-color: var(--wp--preset--color--contrast);
	border-style: dashed;
}

.gform_wrapper .gfield_error > .gfield_label:not(.screen-reader-text)::before {
	color: var(--wp--preset--color--contrast);
	content: "! ";
	content: "! " / "";
}

.gform_wrapper .validation_message {
	margin: var(--wp--preset--spacing--10) 0 0;
	padding: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	line-height: 1.618;
}

.gform_wrapper .validation_message::before {
	content: "^ ";
	content: "^ " / "";
}

/* Sent: the form is replaced by a green "[ok]" line. */
.gform_confirmation_message {
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	font-weight: 700;
	line-height: 1.618;
}

.gform_confirmation_message::before {
	content: "[ok] ";
	content: "[ok] " / "";
}

/* Hidden helpers that Gravity Forms' own CSS would normally hide. */
.gform_wrapper .gform_validation_container,
.gform_wrapper .gfield_visibility_hidden,
.gform_wrapper .gform_hidden {
	display: none !important;
}

@media (forced-colors: active) {
	.gform_confirmation_message,
	.gform_wrapper .gform_validation_errors,
	.gform_wrapper .validation_error {
		border: 2px solid CanvasText;
	}

	.bw-term__cursor {
		background: CanvasText;
	}

	.bw-key,
	.gform_wrapper .gform_button {
		border: 2px solid ButtonText;
	}
}

/*
 * If Gravity Forms' Orbital theme is switched on, its own CSS loads; these
 * tokens keep it close to the terminal look (palette and size come from
 * boxware_2026_gform_default_styles() in functions.php).
 */
.gform_wrapper.gform-theme--framework {
	--gf-radius: 0px !important;
	--gf-radius-max-sm: 0px !important;
	--gf-radius-max-md: 0px !important;
	--gf-radius-max-lg: 0px !important;
	--gf-ctrl-shadow: none;
	--gf-font-size-primary: var(--wp--preset--font-size--micro);
	--gf-ctrl-outline-color-focus: var(--wp--preset--color--accent);
	--gf-ctrl-outline-width-focus: 1px;
	--gf-ctrl-outline-offset: 0px;
	--gf-ctrl-border-color-focus: var(--wp--preset--color--accent);
	--gf-color-danger: var(--wp--preset--color--contrast);
	--gf-color-danger-rgb: 230, 228, 222;
	--gf-ctrl-border-style-error: dashed;
	--gf-ctrl-label-color-req: var(--wp--preset--color--muted);
	--gf-ctrl-btn-text-transform: lowercase;
	--gf-ctrl-btn-shadow: 1ch 0.5em 0 0 var(--bw-shadow);
	--gf-ctrl-btn-shadow-hover: 1ch 0.5em 0 0 var(--bw-shadow);
	--gf-ctrl-btn-shadow-focus: 1ch 0.5em 0 0 var(--bw-shadow);
	--gf-ctrl-btn-bg-color-hover-primary: var(--wp--preset--color--accent);
	--gf-ctrl-btn-border-color-hover-primary: var(--wp--preset--color--accent);
	--gf-ctrl-btn-color-hover-primary: var(--wp--preset--color--base);
	--gf-form-validation-bg-color: var(--wp--preset--color--contrast);
	--gf-form-validation-border-color: var(--wp--preset--color--contrast);
	--gf-form-validation-color: var(--wp--preset--color--base);
	--gf-form-validation-heading-color: var(--wp--preset--color--base);
	--gf-form-validation-radius: 0px;
	--gf-form-validation-shadow: none;
}
