/* ==========================================================================
   Biscuit
   --------------------------------------------------------------------------
   All of the theme's CSS but the blog's, Gravity Forms' and print's, loaded
   on every page after brand-tokens.css and biscuit-variables.css. No build
   step: edit this file directly.

   Contents, in cascade order. Search for a name to jump to it. Moving a
   part changes which rule wins a tie, so a move is a change to check, not a
   tidy-up.

     RESET                     Bootstrap's reboot, rewritten for the brand
     GLOBAL ELEMENTS           body, links, the new-tab mark, lists, quotes,
                               hr, images
     HEADING TAGS              h1 to h6, the brand defaults
     TEXT SIZES & COLOR        .text-xl to .text-xs, the editor's font sizes
     STRUCTURE
     SECTION BACKGROUNDS       .white-bg to .black-bg, ACF's ground choices
     BUTTONS IN COLOR BGS
     SECTION MENUS
     CALLOUTS
     QUOTE
     BIO / STAFF
     BOOTSTRAP VIDEO IFRAMES
     PARTNER LOGOS
     MISC
     AJAX LOAD MORE PLGIN
     BLOG & POST LISTING PAGES
     IMAGES                    captions and alignment
     BUTTONS                   the .btn family and every color
     FORM FIELDS               text fields, selects, checkboxes, any form
     biscuit-base.css          brand type, .btn basics, cream and dark grounds
     biscuit-layout.css        the span-* grid ACF values still print
     biscuit-components.css    gutter, pill, tooltip, bullets, circles,
                               cursor, Lenis
     biscuit-nav.css           Header, Menu overlay, Child pages, Side column
     biscuit-footer.css
     biscuit-content.css       Prose, Section frame, Flexible pages, Grounds,
                               every flexible section, Dialogs, FAQs,
                               Galleries, Lightbox, Embedded video
     biscuit-sections.css      Hero, Statement, What we do, Selected Works,
                               the project page and its morph

   Not in here, on purpose:
     brand-tokens.css           a byte-identical copy of Brand/brand-tokens.css
     biscuit-variables.css      every variable the theme defines; the editor
                                loads it too
     biscuit-blog.css           blog pages only
     biscuit-gravity-forms.css  pages with a form only
     biscuit-print.css          print only
     style.css                  the theme header WordPress reads, nothing else

   Joined October 13, 2026: seven files in step 8d of
   wordpress-conversion-2026.md, then the rules from style.css in front of
   them, in the order they loaded, in phase 5 of the stylesheet
   reorganization.
   ========================================================================== */

/* ==========================================================================
   biscuit-reset.css: moved to the top of style.css in step 8d, and here with
   the rest of style.css in phase 5, October 13, 2026. It loaded first, so it
   stays first.
   ========================================================================== */

/* ==========================================================================
   Biscuit reset
   --------------------------------------------------------------------------
   What Bootstrap's reboot did for the site, now ours, so Bootstrap can go.
   Loads first, in the place bootstrap.min.css held, so every rule after it
   still wins as it did.

   Taken rule for rule from Bootstrap 5.3.8's reboot (MIT), with its
   --bs-* variables written out. Sizes and spacing keep Bootstrap's values,
   so nothing on the page moves. Colors become brand tokens: Bootstrap's
   near black, link blue and code pink were never Biscuit's, and style.css
   and the newer files set the real colors anyway.

   Left out on purpose:
   - :root { scroll-behavior: smooth }. With ScrollTrigger the root must not
     have it (THEME-RULES.md); Lenis does the smooth scrolling.
   - Bootstrap's dark-mode and RTL variants.

   Checked by measurement, October 13, 2026, step 8: every element's
   computed styles on every page at 1280 and 375 wide, with this file and
   Bootstrap both loaded and then with Bootstrap switched off.

   Thinned the same day, phase 3 of the stylesheet reorganization: every
   declaration a later rule with the same selector always overrides is
   gone (body's type and colors, heading sizes and weights, p, blockquote
   and link colors), so what is left here is what still applies.
   ========================================================================== */

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

body {
	margin: 0;
	-webkit-text-size-adjust: 100%;
	-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

hr {
	color: inherit;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
	margin-top: 0;
	margin-bottom: .5rem;
	line-height: 1.2;
	color: inherit;
}

abbr[title] {
	text-decoration: underline dotted;
	cursor: help;
	text-decoration-skip-ink: none;
}

address {
	font-style: normal;
}

ol,
ul {
	padding-left: 2rem;
}
ol,
ul,
dl {
	margin-top: 0;
	margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
	margin-bottom: 0;
}
dt { font-weight: 700; }
dd {
	margin-bottom: .5rem;
	margin-left: 0;
}

small,
.small { font-size: .875em; }

mark {
	padding: .1875em;
	color: var(--biscuit-heading);
	background-color: var(--biscuit-cream);
}

sub,
sup {
	position: relative;
	font-size: .75em;
	line-height: 0;
	vertical-align: baseline;
}
sub { bottom: -.25em; }
sup { top: -.5em; }

a {
	text-decoration: underline;
}
a:not([href]):not([class]),
a:not([href]):not([class]):hover {
	color: inherit;
	text-decoration: none;
}

pre,
code,
kbd,
samp {
	font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
	font-size: 1em;
}
pre {
	display: block;
	margin-top: 0;
	margin-bottom: 1rem;
	overflow: auto;
	font-size: .875em;
}
pre code {
	font-size: inherit;
	color: inherit;
	word-break: normal;
}
code {
	font-size: .875em;
	color: var(--biscuit-link);
	word-wrap: break-word;
}
a > code { color: inherit; }
kbd {
	padding: .1875rem .375rem;
	font-size: .875em;
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border-radius: .25rem;
}
kbd kbd {
	padding: 0;
	font-size: 1em;
}

figure { margin: 0 0 1rem; }

img,
svg { vertical-align: middle; }

iframe { border: 0; }

table {
	caption-side: bottom;
	border-collapse: collapse;
}
caption {
	padding-top: .5rem;
	padding-bottom: .5rem;
	color: var(--biscuit-muted);
	text-align: left;
}
th {
	text-align: inherit;
	text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
	border-color: inherit;
	border-style: solid;
	border-width: 0;
}

label { display: inline-block; }

button { border-radius: 0; }
button:focus:not(:focus-visible) { outline: 0; }

input,
button,
select,
optgroup,
textarea {
	margin: 0;
	font-family: inherit;
	font-size: inherit;
	line-height: inherit;
}
button,
select { text-transform: none; }
[role=button] { cursor: pointer; }
select { word-wrap: normal; }
select:disabled { opacity: 1; }
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
	display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
	-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
	cursor: pointer;
}
::-moz-focus-inner {
	padding: 0;
	border-style: none;
}
textarea { resize: vertical; }

fieldset {
	min-width: 0;
	padding: 0;
	margin: 0;
	border: 0;
}
legend {
	float: left;
	width: 100%;
	padding: 0;
	margin-bottom: .5rem;
	font-size: calc(1.275rem + .3vw);
	line-height: inherit;
}
@media (min-width: 1200px) {
	legend { font-size: 1.5rem; }
}
legend + * { clear: left; }

::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
	padding: 0;
}
::-webkit-inner-spin-button { height: auto; }
[type=search] {
	-webkit-appearance: textfield;
	outline-offset: -2px;
}
[type=search]::-webkit-search-cancel-button {
	cursor: pointer;
	filter: grayscale(1);
}
::-webkit-search-decoration { -webkit-appearance: none; }
::-webkit-color-swatch-wrapper { padding: 0; }
::file-selector-button {
	font: inherit;
	-webkit-appearance: button;
}

output { display: inline-block; }

summary {
	display: list-item;
	cursor: pointer;
}

progress { vertical-align: baseline; }

[hidden] { display: none !important; }

/* ==========================================================================
   style.css, the original rules. Moved here in phase 5 of the stylesheet
   reorganization, October 13, 2026, in the order they loaded.
   ========================================================================== */

/*-------------------------------------------------------------------------*/

/* GLOBAL ELEMENTS */

/*-------------------------------------------------------------------------*/

html {
    position: relative;
    min-height: 100%;
}
body {
	color: var(--biscuit-body);
	/* background: var(--biscuit-white) url(../images/bg_image.png) repeat top left; */
	background: var(--biscuit-white);
	font-size: var(--text-m);
	font-weight: var(--biscuit-weight-body);
	line-height: 1.6;
	font-variant-ligatures: no-common-ligatures; /* no ligatures */	
}
header, a, img, li {
    transition: all 0.3s ease;
}
a {
	color: var(--biscuit-link);
    transition: all 0.3s ease;
}
a:hover {
	color: var(--biscuit-link-hover);
}
a:active,
a:focus {
	color: var(--biscuit-link-hover);
}
a.no-border {
	text-decoration: none !important;
}
a:hover.no-border {
	text-decoration: none !important;
	filter: alpha(opacity=60);
    opacity: 0.6;
}
/* The new-tab mark: Tabler's external-link icon (MIT), drawn from an inline
   SVG in the link's color. It came from the Tabler Icons webfont, loaded
   from jsDelivr at @latest for this one glyph, until step 8, October 13,
   2026. A .5em box with a 4px gap: the drawing inside it is about half the
   height of a capital beside it. It was 1em until Jason halved it, October
   13, 2026. An inline box, not an inline-block, so it never wraps away from
   the last word, as the font glyph never did; its padding gives it the
   width, and contain keeps the drawing square and centered in the line.
   The second content line gives the mark alt text, so a screen reader says
   "opens in a new tab" where a sighted reader sees the icon. A browser that
   cannot read that syntax drops the line and keeps the first. Step 8e.
   October 19, 2026: up from .5em to .7em, and the color is now a square
   gradient the size of the icon rather than a background-color. An inline
   box is taller than it is wide, as tall as the line's text, and at .5em
   the strip of color above and below the drawing showed through as a dark
   orange bar where the mask let it. Painting only the square means nothing
   outside the drawing can show, whatever the browser does with the mask.
   No underline: the box holds no text, so the link's underline has nothing
   to draw under. Jason, October 19, 2026. */
a[target="_blank"]:after {
	content: "";
	content: "" / "(opens in a new tab)";
	display: inline;
	padding-left: .7em;
	margin-left: .3em;
	text-decoration: none;
	background: linear-gradient(currentColor, currentColor) center / .7em .7em no-repeat;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6'/%3E%3Cpath d='M11 13l9 -9'/%3E%3Cpath d='M15 4h5v5'/%3E%3C/svg%3E") center / .7em .7em no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6'/%3E%3Cpath d='M11 13l9 -9'/%3E%3Cpath d='M15 4h5v5'/%3E%3C/svg%3E") center / .7em .7em no-repeat;
}
/* The arrow link: Tabler's arrow-right icon (MIT) after the label, drawn the
   same way as the new-tab mark, in the link's color, and it steps right on
   hover. Add the class to the link (Formats > Link: arrow); no <i> or span,
   which TinyMCE would strip. An inline-block so it can move, and so the
   underline stops at the last word. Jason, October 22, 2026. */
a.link-arrow::after {
	content: "";
	display: inline-block;
	width: .85em; height: .85em;
	margin-left: .3em;
	vertical-align: -.1em;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l14 0'/%3E%3Cpath d='M13 18l6 -6'/%3E%3Cpath d='M13 6l6 6'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l14 0'/%3E%3Cpath d='M13 18l6 -6'/%3E%3Cpath d='M13 6l6 6'/%3E%3C/svg%3E") center / contain no-repeat;
	transition: transform .3s var(--ease);
}
a.link-arrow:hover::after,
a.link-arrow:focus-visible::after { transform: translateX(.3em); }
@media (prefers-reduced-motion: reduce) {
	a.link-arrow::after { transition: none; }
}
a img {
	display: inline-block;
}
a[href^="tel:"] {
	white-space: nowrap;
}

p {
	margin: 0 0 24px 0;
}
body :is(p, h1, h2, h3, h4, h5, h6) {
	text-wrap: pretty;
}
ul, ol {
	margin: 0 0 24px 0;
}
li {
	/* line-height: 1.4; */
	margin: 0 0 12px 0;
}
li li {
	margin-top: 12px;
}
ol {
	list-style-type: decimal;
}
ol li {
	margin: 0 0 12px 6px;
    padding-left: 6px;
}
ol ol {
	list-style: disc;
}
ol ol ol {
	list-style: lower-roman;
}
ol ol ol ol {
	list-style: lower-alpha;
}
em, i {
	font-style: italic;
}
address {
    margin-bottom: 12px;
	font-size: var(--text-s);
	font-weight: var(--biscuit-weight-body);
	line-height: 1.6;
}
/* The 2026 quote, the default for any quote: a 3px orange rule, not italic, no drop cap. The
   face and weight are in biscuit.css. Jason, October 13, 2026; it was italic, with a 5px rule
   and a giant first letter. */
blockquote {
	clear: both;
	margin: 1.6em 0;
	padding: 0 0 0 clamp(18px, 2vw, 28px);
	border-left: 3px solid var(--biscuit-accent);
	font-size: var(--text-xl);
	line-height: 1.3;
	color: var(--biscuit-heading);
	overflow: hidden;
}
blockquote p:last-child {
	margin: 0;
}

/* The list line's shape and color (the rule tokens). Was 1px off-white,
   which hardly showed on white. October 20, 2026. */
hr {
	clear: both;
	background-color: var(--rule-color);
	border: 0;
	border-radius: var(--rule-radius);
	height: var(--rule-line);
	margin: 36px 0;
	opacity: 1.0;
}
embed,
object,
video {
	max-width: 100%;
	margin-bottom: 24px;
}
iframe {
	max-width: 100%;
	margin-bottom: 0;
}
img, a img {
	border: none;
	vertical-align: bottom;
	max-width: 100%;
	height: auto;
}
a img {
   cursor: pointer;
}

/*-------------------------------------------------------------------------*/

/* HEADING TAGS */

/*-------------------------------------------------------------------------*/

/* The brand's heading color, never uppercase. Components set their own size and spacing.
   Jason, October 13, 2026; h1 and h2 were orange and uppercase. */

h1, .h1 {
	color: var(--biscuit-heading);
	font-size: var(--h1);
	line-height: 1.1;
	margin-block-end: 0.5em;
}
h2, .h2 {
	color: var(--biscuit-heading);
	font-size: var(--h2);
	line-height: 1.2;
	margin-block-end: 0.5em;
}
h3, .h3 {
	color: var(--biscuit-heading);
	font-size: var(--h3);
	line-height: 1.3;
	margin-block-end: 0.5em;
}
h4, .h4 {
	color: var(--biscuit-heading);
	font-size: var(--h4);
	line-height: 1.4;
	margin-block-end: 0.5em;
}
h5, .h5 {
	color: var(--biscuit-heading);
	font-size: var(--h5);
	line-height: 1.5;
	margin-block-end: 0.5em;
}
h6, .h6 {
	color: var(--biscuit-heading);
	font-size: var(--h6);
	line-height: 1.5;
	margin-block-end: 0.5em;
}

/*-------------------------------------------------------------------------*/

/* TEXT SIZES & COLOR  */

/*-------------------------------------------------------------------------*/

.text-xl {
	font-size: var(--text-xl);
	line-height: 1.6;
}
.text-l {
	font-size: var(--text-l);
	line-height: 1.6;
}
.text-m {
	font-size: var(--text-m);
	line-height: 1.6;
}
.text-s {
	font-size: var(--text-s);
	line-height: 1.5;
}
.text-xs {
	font-size: var(--text-xs);
	line-height: 1.5;
}

/*-------------------------------------------------------------------------*/

/* STRUCTURE */

/*-------------------------------------------------------------------------*/

/* The 2026 header floats over the top of the page, so nothing is pushed down for it. */

#content {
	clear: both;
}
footer {
    clear: both;
	background-color: var(--biscuit-near-black);
}

/*-------------------------------------------------------------------------*/

/* SECTION BACKGROUNDS  */

/*-------------------------------------------------------------------------*/

.white-bg {
	background-color: var(--biscuit-white);
}
.gray-bg {
	background-color: var(--biscuit-page-alt);
}
.primary-bg {
	background-color: var(--biscuit-orange-deep);
	color: var(--biscuit-white);
}
.secondary-bg {
	background-color: var(--biscuit-near-black);
}
.tertiary-bg {
	background-color: var(--biscuit-gray);
}

.black-bg {
	background-color: var(--biscuit-near-black);
	color: var(--biscuit-white);
}
.primary-bg a,
.secondary-bg a,
.black-bg a {
	color: var(--biscuit-white);
}
.tertiary-bg a {
	color: var(--biscuit-white);
}

/* --- BACKGROUND PATTERN --- */

.pattern-1 {
	background-image: url(../images/bg_1.svg);
	background-repeat: repeat;
	background-position: top 0 left 0;
}
.pattern-2 {
	background-image: url(../images/bg_2.svg);
	background-repeat: repeat;
	background-position: top 0 left 0;
}
.pattern-3 {
	background-image: url(../images/bg_3.svg);
	background-repeat: no-repeat;
	background-position: bottom 20px right 20px;
}

/* --- BACKGROUND HEADING COLORS --- */

.primary-bg h1, .primary-bg h2, .primary-bg h3, .primary-bg h4, .primary-bg h5, .primary-bg h6,
.primary-bg h1 a, .primary-bg h2 a, .primary-bg h3 a, .primary-bg h4 a, .primary-bg h5 a, .primary-bg h6 a,
.primary-bg .h1, .primary-bg .h2, .primary-bg .h3, .primary-bg .h4, .primary-bg .h5, .primary-bg .h6,
.primary-bg .h1 a, .primary-bg .h2 a, .primary-bg .h3 a, .primary-bg .h4 a, .primary-bg .h5 a, .primary-bg .h6 a,
.secondary-bg h1, .secondary-bg h2, .secondary-bg h3, .secondary-bg h4, .secondary-bg h5, .secondary-bg h6,
.secondary-bg h1 a, .secondary-bg h2 a, .secondary-bg h3 a, .secondary-bg h4 a, .secondary-bg h5 a, .secondary-bg h6 a,
.secondary-bg .h1, .secondary-bg .h2, .secondary-bg .h3, .secondary-bg .h4, .secondary-bg .h5, .secondary-bg .h6,
.secondary-bg .h1 a, .secondary-bg .h2 a, .secondary-bg .h3 a, .secondary-bg .h4 a, .secondary-bg .h5 a, .secondary-bg .h6 a,
.black-bg h1, .black-bg h2, .black-bg h3, .black-bg h4, .black-bg h5, .black-bg h6,
.black-bg h1 a, .black-bg h2 a, .black-bg h3 a, .black-bg h4 a, .black-bg h5 a, .black-bg h6 a,
.black-bg .h1, .black-bg .h2, .black-bg .h3, .black-bg .h4, .black-bg .h5, .black-bg .h6,
.black-bg .h1 a, .black-bg .h2 a, .black-bg .h3 a, .black-bg .h4 a, .black-bg .h5 a, .black-bg .h6 a {
	color: var(--biscuit-white);
}
.tertiary-bg h1, .tertiary-bg h2, .tertiary-bg h3, .tertiary-bg h4, .tertiary-bg h5, .tertiary-bg h6,
.tertiary-bg h1 a, .tertiary-bg h2 a, .tertiary-bg h3 a, .tertiary-bg h4 a, .tertiary-bg h5 a, .tertiary-bg h6 a,
.tertiary-bg .h1, .tertiary-bg .h2, .tertiary-bg .h3, .tertiary-bg .h4, .tertiary-bg .h5, .tertiary-bg .h6,
.tertiary-bg .h1 a, .tertiary-bg .h2 a, .tertiary-bg .h3 a, .tertiary-bg .h4 a, .tertiary-bg .h5 a, .tertiary-bg .h6 a {
	color: var(--biscuit-white);
}

/* BUTTONS IN COLOR BGS */

.primary-bg .btn-white {
	color: var(--biscuit-orange-deep);
    text-decoration: none;
}
.secondary-bg .btn-white {
	color: var(--biscuit-near-black);
    text-decoration: none;
}
.tertiary-bg .btn-white {
	color: var(--biscuit-gray);
    text-decoration: none;
}

.black-bg .btn-white {
	color: var(--biscuit-heading);
	text-decoration: none;
}
.primary-bg a.btn {
	color: var(--biscuit-orange-deep);
}
.secondary-bg a.btn {
	color: var(--biscuit-near-black);
}
.tertiary-bg a.btn {
	color: var(--biscuit-gray);
}

.primary-bg a.btn:hover,
.secondary-bg,
.tertiary-bg,
.black-bg a.btn {
	color: var(--biscuit-white);
}

/*-------------------------------------------------------------------------*/

/* SECTION MENUS */

/*-------------------------------------------------------------------------*/

.page-menu {
    display: none;
}
@media (min-width: 576px) {
	.page-menu {
	    display: block;
		position: fixed;
	    bottom: 0;
	    background-color: var(--biscuit-white);
	    border-top: 1px solid var(--biscuit-white);
		padding-top: 26px;
		padding-bottom: 0;
	    width: 100%;
	    z-index: 9000;
	}
}
.page-menu ul {
	list-style: none;
    text-align: center;
	margin: 0 auto;
	padding: 0;
    width: -webkit-fit-content;
    width: -moz-fit-content;
    width: fit-content;
}
.page-menu li {
	float: left;
    font-size: var(--text-xs);
    text-align: center;
    line-height: 1.0;
    text-transform: uppercase;
    margin: 0 6px 26px 2px !important;
    white-space: nowrap;
}
.page-menu li a {
	font-size: var(--text-xs);
	font-weight: var(--weight-bold);
	line-height: 1.0;
    border: none;
    border-radius: var(--border-radius-m);
	background-color: var(--biscuit-white);
	text-decoration: none;
    padding: 10px 10px;
	white-space: nowrap;
}
.page-menu li a:hover {
	color: var(--biscuit-white);
	background-color: var(--biscuit-orange-deep);
	text-decoration: none;
}
.page-menu span {
	float: left;
	color: var(--biscuit-heading);
	font-size: var(--text-xs);
    font-weight: var(--weight-bold);
	text-transform: uppercase;
	padding: 14px 10px 13px 0;
}

/*-------------------------------------------------------------------------*/

/* CALLOUTS  */

/*-------------------------------------------------------------------------*/

.callout {
	border-top: 24px solid rgba(255, 255, 255, 0.12);
	border-bottom: 24px solid rgba(255, 255, 255, 0.12);
	margin-top: 7px;
	margin-bottom: 7px;
}

.callout p {
	font-size: var(--text-xl);
	font-weight: var(--biscuit-weight-body);
	line-height: 1.5;
	text-wrap: pretty;
}
@media (min-width: 768px) {
	.callout p {
		font-size: var(--h3);
	}
}

/*-------------------------------------------------------------------------*/

/* QUOTE  */

/*-------------------------------------------------------------------------*/

.quote {
    background: url(../icons/icon_blockquote_top.png) no-repeat center 0 / 75px 56px;
    font-size: var(--text-l);
    font-style: italic;
    text-align: center;
	border-top: 2px solid rgba(255, 255, 255, 0.35);
	border-bottom: 2px solid rgba(255, 255, 255, 0.35);
	margin: 80px auto;
	padding-top: 80px;
	padding-bottom: 50px;
	max-width: 880px;
	overflow: visible !important;
}
.white-bg .quote,
.gray-bg .quote {
    background: url(../icons/icon_blockquote_top_gray.png) no-repeat center 0 / 75px 56px;
	border-top: 2px solid rgba(0, 0, 0, 0.07);
	border-bottom: 2px solid rgba(0, 0, 0, 0.07);
}
.quote p {
	font-size: var(--text-l);
    font-weight: var(--biscuit-weight-quote);
    line-height: 1.6;
	margin-bottom: 24px;
}
.quote span {
	font-size: var(--text-m);
	font-weight: var(--weight-bold);
	font-style: normal;
	text-align: center;
    text-transform: uppercase;
}

/*-------------------------------------------------------------------------*/

/* BIO / STAFF */

/*-------------------------------------------------------------------------*/

/* --- MAKE 5 COLUMNS --- */

.col-xs-5ths,
.col-sm-5ths,
.col-md-5ths,
.col-lg-5ths {
    position: relative;
    min-height: 1px;
    padding-right: 10px;
    padding-left: 10px;
}
.col-xs-5ths {
    width: 100%;
    float: left;
}
@media (min-width: 768px) {
    .col-sm-5ths {
        width: 50%;
        float: left;
    }
}
@media (min-width: 992px) {
    .col-md-5ths {
        width: 20%;
        float: left;
    }
}
@media (min-width: 1200px) {
    .col-lg-5ths {
        width: 20%;
        float: left;
    }
}

/*-------------------------------------------------------------------------*/

/* BOOTSTRAP VIDEO IFRAMES */

/*-------------------------------------------------------------------------*/

.wp-video {
	margin-bottom: 24px;
}

/*-------------------------------------------------------------------------*/

/* PARTNER LOGOS */

/*-------------------------------------------------------------------------*/

/* --- ADD SPACE TO PARTNER LOGOS - GRID --- */

.partner-logos {
	display: flex;
	justify-content: center;
	align-items: center;
	flex-wrap: wrap;
}

/*-------------------------------------------------------------------------*/

/* MISC */

/*-------------------------------------------------------------------------*/

.hentry {
	width: 100%;
}

/*-------------------------------------------------------------------------*/

/* AJAX LOAD MORE PLGIN */

/*-------------------------------------------------------------------------*/

#ajax-load-more {
	width: 100%;
}
.alm-btn-wrap {
	text-align: center;
	margin: 0 auto 15px auto;
}

/* --- ALM FILTER SEARCH --- */

.alm-filters-container {
	padding-left: 15px !important;
}

.alm-filters-container .alm-filter--text-wrap {
	width: auto !important;
	max-width: 100% !important;
	-webkit-border-radius: 8px !important;
	border-radius: 8px !important;
	padding: 0 !important;
	background-color: transparent !important;
	border: none !important;
	height: 52px !important;
}

.alm-filter--search .alm-filter--text-wrap input[type=text] {
	border-radius: 8px !important;
	font-size: var(--text-m) !important;
	max-width: 100% !important;
	height: 52px !important;
	padding-left: 12px !important;
}
.alm-filter--search .alm-filter--text-wrap input[type=text]:focus {
	background-color: var(--biscuit-white) !important;
}
@media (min-width: 768px) {
	.alm-filter--search .alm-filter--text-wrap input[type=text] {
		max-width: 50% !important;
	}
}
.alm-filter--search .alm-filter--text-wrap button[type=button] {
	color: var(--biscuit-white) !important;
	background-color: var(--biscuit-muted) !important;
	font-size: var(--text-s) !important;
	border: none !important;
	border-radius: 8px !important;
	box-shadow: -3px 0 5px rgba(0, 0, 0, .1);
	padding: 10px 14px !important;
	transition: all ease-in-out 0.3s;
}
.alm-filter--search .alm-filter--text-wrap button[type=button]:hover {
	color: var(--biscuit-white) !important;
	background-color: var(--biscuit-near-black) !important;
}
.alm-filters-container .alm-filters--controls {
	margin: 0 !important;
	justify-content: center;
}

/* --- ALM TURN CHECKBOXES INTO BUTTONS --- */

.alm-filter--taxonomy ul li {
	display: inline-block !important;
	margin-right: 12px !important;
}

.alm-filters-container .alm-filter li div.alm-filter--link:before {
	top: 9px !important;
	left: 8px !important;
	width: 20px !important;
	height: 20px !important;
	background: var(--biscuit-white);
	border: 1px solid var(--biscuit-rule);
}
.alm-filters-container .alm-filter li div.alm-filter--link:after {
	top: 13px !important;
	left: 15px !important;
}

/* --- ALM HIDE NO MORE POSTS BUTTON --- */

.alm-btn-wrap .alm-load-more-btn.done,
.alm-btn-wrap .alm-load-more-btn:disabled {
	display: none !important;
}

/*-------------------------------------------------------------------------*/

/* BLOG & POST LISTING PAGES */

/*-------------------------------------------------------------------------*/

/* --- POSTMETADATA IN LISTINGS --- */

.postmetadata {
	color: var(--biscuit-muted);
	font-size: var(--text-xs);
	font-weight: var(--biscuit-weight-body);
	text-transform: uppercase;
	line-height: 1.6;
	font-feature-settings: 'lnum'; /* even number height */
}
.postmetadata a {
	color: var(--biscuit-muted);
	text-decoration: none;
}
.postmetadata a:hover {
	color: var(--biscuit-heading);
	text-decoration: underline;
}
.postmetadata p {
	margin: 0 0 12px 0;
}

/*-------------------------------------------------------------------------*/

/* IMAGES */

/*-------------------------------------------------------------------------*/

.alignleft {
	display: block;
	clear: both;
	float: none;
	margin: 0 0 20px 0;
}
.alignright {
	display: block;
	clear: both;
	float: none;
	margin: 0 0 20px 0;
}
.aligncenter {
	display: block;
	margin-left: auto;
	margin-right: auto;
}
.wp-caption.alignleft,
img.alignleft {
	margin: 6px 0 12px 0;
}
.wp-caption.alignright,
img.alignright {
	margin: 6px 0 12px 0;
}
.wp-caption.aligncenter,
img.aligncenter {
	margin: 12px auto 24px auto;
}
@media (min-width: 640px) {
	.alignleft {
		display: inline;
		clear: none;
		float: left;
	}
	.alignright {
		display: inline;
		clear: none;
		float: right;
	}
	.wp-caption.alignleft,
	img.alignleft {
		margin: 6px 24px 12px 0;
	}
	img.alignleft.icon {
		margin: 0 12px 0 0;
	}
	.wp-caption.alignright,
	img.alignright {
		margin: 6px 0 12px 24px;
	}
	.wp-caption.aligncenter,
	img.aligncenter {
		margin: 12px auto 24px auto;
	}
}

/* Image reveal: an image with the img-reveal class (Formats > Image: reveal
   on scroll, or the image's CSS Class) opens upward from its bottom edge and
   settles from a slight zoom as it scrolls in, as a post card's image does
   (biscuit-blog.css). biscuit.js wraps it in .img-reveal__frame, moves its
   alignment class to the frame, and adds .is-in. With no script, or under
   reduced motion, there is no frame and the image is simply there.
   Jason, October 22, 2026. */
.img-reveal__frame {
	display: block;
	width: fit-content;
	max-width: 100%;
	overflow: hidden;
	clip-path: inset(100% 0 0 0);
	transition: clip-path 1.2s var(--ease);
}
.img-reveal__frame > img {
	display: block;
	margin: 0;
	scale: 1.14;
	transition: scale 1.6s var(--ease);   /* not style.css's transition: all */
}
.img-reveal__frame.is-in { clip-path: inset(0 0 0 0); }
.img-reveal__frame.is-in > img { scale: 1; }
/* The frame takes the image's place, so it takes its alignment margins. */
.img-reveal__frame.alignleft,
.img-reveal__frame.alignright { margin: 6px 0 12px 0; }
.img-reveal__frame.aligncenter { margin: 12px auto 24px auto; }
@media (min-width: 640px) {
	.img-reveal__frame.alignleft  { display: block; margin: 6px 24px 12px 0; }
	.img-reveal__frame.alignright { display: block; margin: 6px 0 12px 24px; }
}

/* Ensure caption containers never overflow the page */
.wp-caption {
  max-width: 100% !important;
}
/* For centered captions, let images scale to fill the container */
.wp-caption.aligncenter img {
  width: auto !important;
  height: auto;
}
/* For left/right captions, force the image to use its intrinsic (user‑defined) width 
   but still prevent overflow if it’s too big for the page */
.wp-caption.alignleft img,
.wp-caption.alignright img {
  height: auto;
  max-width: 100% !important;
}
.wp-caption-text {
	width: 100%;
	display: block;
}
.wp-caption-text,
.gallery-caption,
.entry-caption {
	color: var(--biscuit-muted);
	font-size: var(--text-xs);
	font-style: italic;
	line-height: 1.2;
	text-align: center;
	margin-top: 1em;
}

@media (max-width: 768px) {
  .wp-caption {
	width: auto !important;
	max-width: 100% !important;
  }
  .wp-caption img {
	width: 100%;
	height: auto;
  }
}

/*-------------------------------------------------------------------------*/

/* BUTTONS */

/*-------------------------------------------------------------------------*/

/* Every size is a pill, like the theme's own .pill buttons, so a button added
   in the editor matches them. Jason, October 15, 2026. */
.btn {
	font-size: var(--text-s);
	font-weight: var(--weight-bold);
	text-decoration: none;
    text-transform: uppercase;
	border-radius: 999px;
	margin-top: 4px;
	padding: 14px 18px;
	white-space: normal;
	transition: all 0.5s ease;
}
.btn-lg {
    font-size: var(--text-m);
	border-radius: 999px;
	padding: 14px 24px;
}
.btn-md {
    font-size: var(--text-s);
	border-radius: 999px;
	padding: 14px 18px;
}
.btn-sm {
    font-size: var(--text-xs);
	border-radius: 999px;
	padding: 12px 12px;
}
a.btn,
a.btn:hover {
	text-decoration: none !important;
}

/* --- PRIMARY - ORANGE --- */

.btn-primary {
	color: var(--biscuit-white);
	background-color: var(--biscuit-button);
	border: none;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-button-hover);
	border: none;
}
.btn-primary:active {
	background-image: none;
}

/* --- PRIMARY OUTLINE - ORANGE --- */

.btn-primary-outline {
	color: var(--biscuit-button);
	background-color: transparent;
	border: 2px solid var(--biscuit-button);
}
.btn-primary-outline:hover,
.btn-primary-outline:focus,
.btn-primary-outline:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-button-hover);
	border: 2px solid var(--biscuit-button-hover);
}
.btn-primary-outline:active {
	background-image: none;
}

/* --- SECONDARY - MUD --- */

.btn-secondary {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-secondary:hover,
.btn-secondary:focus,
.btn-secondary:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-secondary:active {
	background-image: none;
}

/* --- SECONDARY OUTLINE - MUD --- */

.btn-secondary-outline {
	color: var(--biscuit-near-black);
	background-color: transparent;
	border: 2px solid var(--biscuit-near-black);
}
.btn-secondary-outline:hover,
.btn-secondary-outline:focus,
.btn-secondary-outline:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: 2px solid var(--biscuit-near-black);
}
.btn-secondary-outline:active {
	background-image: none;
}

/* --- TERTIARY - BEIGE --- */

.btn-tertiary {
	color: var(--biscuit-white);
	background-color: var(--biscuit-gray);
	border: none;
}
.btn-tertiary:hover,
.btn-tertiary:focus,
.btn-tertiary:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-tertiary:active {
	background-image: none;
}

/* --- TERTIARY OUTLINE - BEIGE --- */

.btn-tertiary-outline {
	color: var(--biscuit-gray);
	background-color: transparent;
	border: 2px solid var(--biscuit-gray);
}
.btn-tertiary-outline:hover,
.btn-tertiary-outline:focus,
.btn-tertiary-outline:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: 2px solid var(--biscuit-near-black);
}
.btn-tertiary-outline:active {
	background-image: none;
}

/* --- ACCENT - BLUE --- */

.btn-accent {
	color: var(--biscuit-white);
	background-color: var(--biscuit-orange-deep);
	border: none;
}
.btn-accent:hover,
.btn-accent:focus,
.btn-accent:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-accent:active {
	background-image: none;
}

/* --- ACCENT OUTLINE - BRIGHT BLUE --- */

.btn-accent-outline {
	color: var(--biscuit-orange-deep);
	background-color: transparent;
	border: 2px solid var(--biscuit-orange-deep);
}
.btn-accent-outline:hover,
.btn-accent-outline:focus,
.btn-accent-outline:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: 2px solid var(--biscuit-near-black);
}
.btn-accent-outline:active {
	background-image: none;
}

/* --- WHITE --- */

.btn-white {
	color: var(--biscuit-button);
	background-color: var(--biscuit-white);
	border: none;
}
.btn-white:hover,
.btn-white:focus,
.btn-white:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-white:active {
	background-image: none;
}

/* --- WHITE OUTLINE --- */

.btn-white-outline {
	color: var(--biscuit-white);
	background-color: transparent;
	border: 2px solid var(--biscuit-white);
}
.btn-white-outline:hover,
.btn-white-outline:focus,
.btn-white-outline:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: 2px solid var(--biscuit-near-black);
}
.btn-white-outline:active {
	background-image: none;
}

/* --- BLACK --- */

.btn-black {
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-black:hover,
.btn-black:focus,
.btn-black:active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-gray);
	border: none;
}
.btn-black:active {
	background-image: none;
}

/* --- BLACK OUTLINE --- */

.btn-black-outline  {
	color: var(--biscuit-heading);
	background-color: transparent;
	border: 2px solid var(--biscuit-near-black);
}
.btn-black-outline :hover,
.btn-black-outline :focus,
.btn-black-outline :active {
	color: var(--biscuit-white);
	background-color: var(--biscuit-gray);
	border: 2px solid var(--biscuit-near-black);
}
.btn-black-outline :active {
	background-image: none;
}

/* --- GRAY --- */

.btn-gray {
	color: var(--biscuit-heading);
	background-color: var(--biscuit-panel);
	border: none;
}
.btn-gray:hover,
.btn-gray:focus,
.btn-gray:active{
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: none;
}
.btn-gray:active {
	background-image: none;
}

/* The three in the editor's Add a button (orange, black, cream) keep their own label on any ground.
   BUTTONS IN COLOR BGS was written for white buttons and turned the cream label white on a dark
   ground and the orange label orange on the deep orange. Jason, October 21, 2026. */
a.btn.btn-primary,
a.btn.btn-black { color: var(--biscuit-white); }
a.btn.btn-gray { color: var(--biscuit-heading); }
a.btn.btn-gray:is(:hover, :focus, :active) { color: var(--biscuit-white); }

/* --- GRAY OUTLINE --- */

.btn-gray-outline {
	color: var(--biscuit-muted);
	background-color: transparent;
	border: 2px solid var(--biscuit-muted);
}
.btn-gray-outline:hover,
.btn-gray-outline:focus,
.btn-gray-outline:active{
	color: var(--biscuit-white);
	background-color: var(--biscuit-near-black);
	border: 2px solid var(--biscuit-near-black);
}
.btn-gray-outline:active {
	background-image: none;
}

/*-------------------------------------------------------------------------*/

/* FORM FIELDS */

/*-------------------------------------------------------------------------*/

/* Every text field, select, checkbox and radio on the site, in or out of a form.
   Gravity Forms' own rules are in biscuit-gravity-forms.css. */

select:not(:where(.gform-theme--framework *)),
textarea:not(:where(.gform-theme--framework *)),
input[type="text"]:not(:where(.gform-theme--framework *)),
input[type="password"]:not(:where(.gform-theme--framework *)),
input[type="datetime"]:not(:where(.gform-theme--framework *)),
input[type="datetime-local"]:not(:where(.gform-theme--framework *)),
input[type="date"]:not(:where(.gform-theme--framework *)),
input[type="month"]:not(:where(.gform-theme--framework *)),
input[type="time"]:not(:where(.gform-theme--framework *)),
input[type="week"]:not(:where(.gform-theme--framework *)),
input[type="number"]:not(:where(.gform-theme--framework *)),
input[type="email"]:not(:where(.gform-theme--framework *)),
input[type="url"]:not(:where(.gform-theme--framework *)),
/*input[type="search"],*/
input[type="tel"]:not(:where(.gform-theme--framework *)),
input[type="color"]:not(:where(.gform-theme--framework *)) {
	color: var(--biscuit-heading) !important;
	font-size: calc(var(--text-m) / 1.1) !important;
	background-color: var(--biscuit-white) !important;
	border: 1px solid var(--biscuit-white) !important;
	border-radius: var(--border-radius-m) !important;
	box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.10) !important;
	padding: 12px !important;
}

/* Every field above but the textarea. On a textarea it beat Gravity Forms'
   Field Height setting (textarea.small, .medium and .large in basic.min.css,
   96, 192 and 288px), so every size drew at its 10 rows, about 247px. A
   textarea outside a form has no height set, so it still sizes to its rows.
   Jason, October 16, 2026. */
select:not(:where(.gform-theme--framework *)),
input[type="text"]:not(:where(.gform-theme--framework *)),
input[type="password"]:not(:where(.gform-theme--framework *)),
input[type="datetime"]:not(:where(.gform-theme--framework *)),
input[type="datetime-local"]:not(:where(.gform-theme--framework *)),
input[type="date"]:not(:where(.gform-theme--framework *)),
input[type="month"]:not(:where(.gform-theme--framework *)),
input[type="time"]:not(:where(.gform-theme--framework *)),
input[type="week"]:not(:where(.gform-theme--framework *)),
input[type="number"]:not(:where(.gform-theme--framework *)),
input[type="email"]:not(:where(.gform-theme--framework *)),
input[type="url"]:not(:where(.gform-theme--framework *)),
input[type="tel"]:not(:where(.gform-theme--framework *)),
input[type="color"]:not(:where(.gform-theme--framework *)) {
	height: auto !important;
}

select:focus:not(:where(.gform-theme--framework *)),
textarea:focus:not(:where(.gform-theme--framework *)),
input[type="text"]:focus:not(:where(.gform-theme--framework *)),
input[type="password"]:focus:not(:where(.gform-theme--framework *)),
input[type="datetime"]:focus:not(:where(.gform-theme--framework *)),
input[type="datetime-local"]:focus:not(:where(.gform-theme--framework *)),
input[type="date"]:focus:not(:where(.gform-theme--framework *)),
input[type="month"]:focus:not(:where(.gform-theme--framework *)),
input[type="time"]:focus:not(:where(.gform-theme--framework *)),
input[type="week"]:focus:not(:where(.gform-theme--framework *)),
input[type="number"]:focus:not(:where(.gform-theme--framework *)),
input[type="email"]:focus:not(:where(.gform-theme--framework *)),
input[type="url"]:focus:not(:where(.gform-theme--framework *)),
/*input[type="search"]:focus,*/
input[type="tel"]:focus:not(:where(.gform-theme--framework *)),
input[type="color"]:focus:not(:where(.gform-theme--framework *)) {
	color: var(--biscuit-heading) !important;
	font-size: calc(var(--text-m) / 1.1) !important;
	background-color: var(--biscuit-white) !important;
	border: 1px solid var(--biscuit-white) !important;
	border-radius: var(--border-radius-m) !important;
	box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.10) !important;
	padding: 12px !important;
}
input[type="checkbox"]:not(:where(.gform-theme--framework *)),
input[type="checkbox"]:focus:not(:where(.gform-theme--framework *)) {
	border: 1px solid var(--biscuit-white) !important;
	border-radius: var(--border-radius-m) !important;
	box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.10) !important;
}
input[type="radio"]:not(:where(.gform-theme--framework *)),
input[type="radio"]:focus:not(:where(.gform-theme--framework *)) {
	border: 1px solid var(--biscuit-white) !important;
	box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.10) !important;
}
textarea:not(:where(.gform-theme--framework *)),
textarea:focus:not(:where(.gform-theme--framework *)) {
	font-weight: var(--biscuit-weight-body) !important;
	font-size: var(--text-m) !important;
	line-height: 130% !important;
}

/* ==========================================================================
   biscuit-base.css
   ========================================================================== */

/* ==========================================================================
   Biscuit base
   --------------------------------------------------------------------------
   Brand type, button basics and the section grounds added to ACF. Loads
   after style.css, so it wins a tie. Values come from brand-tokens.css,
   the copy of Brand/brand-tokens.css, and biscuit-variables.css. The reset that replaced Bootstrap's
   reboot is at the top of style.css, step 8.

   Started October 9, 2026, step 1 of wordpress-conversion-2026.md.
   ========================================================================== */

/* --- Type ---------------------------------------------------------------
   Adobe Fonts project pnw0xox serves Neue Haas as neue-haas-grotesk-display
   and neue-haas-grotesk-text. The desktop names in brand-tokens.css only
   work where the font is installed, so the web names go first, in
   --font-display and --font-text in biscuit-variables.css.

   The project serves Display 400, 500 and 600 and Text 400, 500 and 700.
   Display Roman 400 for quotes, Text Roman 400 for body and Text Medium 500
   for bold all match the installed fonts. Display 400 and Text 500 were
   added October 9, 2026.

   Headings are the exception. brand.md's Display Medium 65 is weight 500
   in the installed fonts, but Adobe serves that cut at 600; its 500 is a
   lighter one the installed family does not have. Measured October 9,
   2026, by the width of one line at 100px: installed 500 and Adobe 600
   both 1078px, Adobe 500 1048px, and 400 is 998px on both. So the theme
   sets headings at 600 through --weight-heading, the same way
   --font-display stands in for the desktop name. The brand token stays
   500, which is right wherever the font is installed.

   Every weight is a variable. The brand's four roles come from
   brand-tokens.css; the theme adds --weight-heading above and
   --weight-bold, Text Bold 75, for buttons, the page menu, quote
   attributions and Gravity Forms field labels. Jason kept those at 700
   on October 14, 2026. brand.md has labels and attributions in Text
   Roman 400, so this is the site's choice, not the brand's. dt is still
   a bare 700. Adobe serves no Display 700: a 700 in the Display face
   (.quote span) renders as Display 600 in Chrome, same width, measured
   October 14, 2026.                                                        */

body {
	font-family: var(--font-text);
	/* As in the prototype. Grayscale smoothing on a Mac, which is how the
	   type was judged there. */
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
}
blockquote,
.quote {
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
}
b,
strong {
	font-weight: var(--biscuit-weight-strong);
}

/* --- Buttons ------------------------------------------------------------
   style.css sets the look of .btn and its colors. These are the parts
   Bootstrap supplied, with Bootstrap's values. Every style and size the
   editor's button tool offers was measured with Bootstrap on and off,
   step 8: identical but for a disabled button taking clicks, hence the
   last rule.                                                               */

.btn {
	display: inline-block;
	line-height: 1.5;
	text-align: center;
	vertical-align: middle;
	cursor: pointer;
	user-select: none;
}
.btn:disabled {
	pointer-events: none;
}

/* --- Section grounds ----------------------------------------------------
   Two choices added to the flexible content color fields October 9, 2026.
   "Gray Background" already renders off-white and is relabeled in ACF.
   Each mirrors the existing ground it sits closest to: cream follows
   .gray-bg, dark follows .black-bg, so sections behave the same.          */

/* Cream, the brand panel color */
.cream-bg {
	background-color: var(--biscuit-cream);
}

/* Dark, #1A1A1A, approved by Lucy October 9, 2026. On this ground the
   brand orange passes AA and the deep orange does not, so links are
   off-white and brighten to the brand orange. See Brand/brand.md.        */
.dark-bg {
	background-color: var(--biscuit-ground-dark);
	color: var(--biscuit-off-white);
}
.dark-bg h1, .dark-bg h2, .dark-bg h3, .dark-bg h4, .dark-bg h5, .dark-bg h6,
.dark-bg .h1, .dark-bg .h2, .dark-bg .h3, .dark-bg .h4, .dark-bg .h5, .dark-bg .h6,
.dark-bg h1 a, .dark-bg h2 a, .dark-bg h3 a, .dark-bg h4 a, .dark-bg h5 a, .dark-bg h6 a {
	color: var(--biscuit-off-white);
}
.dark-bg a:not(.btn) {
	color: var(--biscuit-off-white);
}
.dark-bg a:not(.btn):hover,
.dark-bg a:not(.btn):focus {
	color: var(--biscuit-orange);
}

/* Cards stay white on a dark ground, so their text stays dark. */

/* ==========================================================================
   biscuit-layout.css
   ========================================================================== */

/* ==========================================================================
   Biscuit layout
   --------------------------------------------------------------------------
   The theme's own grid, replacing Bootstrap's container, row and col.
   Same width-and-gutter math as Bootstrap 5 and the same breakpoints, 576,
   768, 992, 1200 and 1400, so a template that moves over keeps its layout
   and the 38 rules in style.css written at 992 still line up.

   Names avoid Bootstrap's on purpose (wrap, grid, span, push), so the
   Bootstrap count can reach zero in step 8.

   Saved ACF values that are Bootstrap classes reach these through
   biscuit_acf_class() in functions.php.

   Started October 9, 2026, step 1 of wordpress-conversion-2026.md.
   Cut to what the theme can still print in step 8, October 13, 2026: the
   flexible sections got their own layouts in step 6, so the wraps, pushes
   and most spans had no markup left. What remains is what
   biscuit_acf_class() can still hand out.
   ========================================================================== */

/* --- Containers -------------------------------------------------------- */

/* --- Grid ---------------------------------------------------------------
   Every child is full width until a span says otherwise.                  */

.grid {
	display: flex;
	flex-wrap: wrap;
	margin-inline: calc(var(--grid-gutter) * -.5);
}
.grid > * {
	flex: 0 0 auto;
	width: 100%;
	max-width: 100%;
	padding-inline: calc(var(--grid-gutter) * .5);
}

/* Vertically centers a column's content. Replaces "d-flex align-items-center". */
.is-centered {
	display: flex;
	align-items: center;
}

/* Text alignment. Replaces text-start, text-center and text-end. */
.align-start  { text-align: start; }
.align-center { text-align: center; }
.align-end    { text-align: end; }

/* --- Spans and pushes, all widths ------------------------------------------ */

.span-12 { width: 100%; }

/* --- Spans and pushes, md, 768px and up ------------------------------------ */
@media (min-width: 768px) {

	.span-md-4 { width: 33.33333333%; }
	
	.span-md-6 { width: 50%; }

}

/* --- Spans and pushes, lg, 992px and up ------------------------------------ */
@media (min-width: 992px) {

	.span-lg-3 { width: 25%; }
	.span-lg-4 { width: 33.33333333%; }
	
	.span-lg-6 { width: 50%; }
	.span-lg-7 { width: 58.33333333%; }
	.span-lg-8 { width: 66.66666667%; }

	.span-lg-fifth { width: 20%; }

}

/* ==========================================================================
   biscuit-components.css
   ========================================================================== */

/* ==========================================================================
   Biscuit components
   --------------------------------------------------------------------------
   Small parts shared by the header, the menu, the footer and, from step 3,
   the home page: the page gutter and display size, the pill button, the
   circle field, mask lines, rules and labels.

   Ported from the motion prototype (Website 2026/motion-prototype, files
   prototype.css and home.css), which is the spec for how these look and
   move. Fonts use --font-display and --font-text from biscuit-variables.css,
   which carry the Adobe Fonts names; the prototype used the desktop names.

   Started October 9, 2026, step 2 of wordpress-conversion-2026.md.
   ========================================================================== */

/* A full-width band with the page gutter, up to 1680px. */
.wide {
	width: 100%;
	max-width: 1680px;
	margin: 0 auto;
	padding: 0 var(--gutter);
}

/* Small uppercase label: eyebrows, attributions, menu headings. */
.label {
	font-size: var(--text-label);
	text-transform: uppercase;
	letter-spacing: var(--biscuit-label-tracking);
	color: var(--biscuit-muted);
}

/* A line of type that rises out of a mask. */
.mask-line { display: block; overflow: hidden; padding-bottom: .12em; margin-bottom: -.12em; }
.mask-line > span { display: block; }

/* The soft bar. Its size, radius and color are the rule tokens in
   biscuit-variables.css, shared with the list lines and hr. */
.rule {
	display: block;
	width: 180px; max-width: 40%; height: var(--rule-bar); border-radius: var(--rule-radius);
	margin: clamp(24px, 2.5vw, 44px) 0;
	background: var(--rule-color);
	transform-origin: 0 50%;
}

/* A rule is one step off its ground: cream on white and off-white (the
   default), off-white on cream, the off-white at .16 on dark. So a bar or a
   line placed anywhere takes its color from where it sits. October 20, 2026. */
.cream-bg,
.services { --rule-color: var(--biscuit-off-white); }
[data-nav="dark"] { --rule-color: rgba(252, 249, 245, .16); }

/* A line across a list: the bar's shape at --rule-line. Placed by each list. */
.svc-list > li::after,
.svc-list::after,
.works-list::before,
.works-item::after,
.faq__q::before,
.faqs::after {
	content: ""; position: absolute; left: 0; right: 0;
	height: var(--rule-line); border-radius: var(--rule-radius);
	background: var(--rule-color);
	pointer-events: none;
}

/* A tooltip: a .tip inside a .has-tip link or button, shown above it on hover
   and on keyboard focus. The .tip repeats a name the element already has (an
   icon's alt text), so it is aria-hidden. It is part of the link, so moving the
   pointer onto it keeps it open, and Escape hides it until the pointer or focus
   moves on (biscuit.js), which is what WCAG 1.4.13 asks of content on hover.
   Added October 13, 2026, for the author's social icons. */
.has-tip { position: relative; }
.tip {
	position: absolute; left: 50%; bottom: 100%; z-index: 5;
	padding-bottom: 8px;                     /* the gap, inside the tip, so hover crosses it */
	transform: translate(-50%, 4px);
	opacity: 0; visibility: hidden;
	transition: opacity .2s ease, transform .2s ease, visibility .2s;
	pointer-events: none;
}
.tip > span {
	position: relative; display: block;
	padding: 6px 10px; border-radius: var(--border-radius-m);
	background: var(--biscuit-near-black); color: var(--biscuit-off-white);
	font-family: var(--font-text); font-size: var(--text-xs); line-height: 1.2; letter-spacing: 0;
	white-space: nowrap;
}
.tip > span::after {
	content: ""; position: absolute; top: 100%; left: 50%;
	margin-left: -5px; border: 5px solid transparent; border-top-color: var(--biscuit-near-black);
}
.has-tip:hover > .tip,
.has-tip:focus-visible > .tip { opacity: 1; visibility: visible; transform: translate(-50%, 0); pointer-events: auto; }
.has-tip.is-tip-hidden > .tip { opacity: 0; visibility: hidden; transition: none; }
@media (prefers-reduced-motion: reduce) { .tip { transition: none; transform: translate(-50%, 0); } }

/* Bullet lists: a row of links with a bullet between them, the footer's links and the menu's
   Follow links. Every item carries a bullet, and the list is pulled left by one bullet's width and
   clipped there, so the item that starts a line hides its own: no bullet hangs at the start of a
   wrapped line. The bullet's box is 1.93em at its .55em size, 1.0615em of the list's type, the
   space the old margins and glyph took. The clip stops 6px short of the first link, so its focus
   outline (2px at a 4px offset) is not cut; the bullet's ink ends further left than that at every
   size the two lists use. The bullet is decoration, so it has empty alt text. Jason, October 13,
   2026: a wrapped line started with a bullet. */
.bullets {
	display: flex; flex-wrap: wrap; align-items: center;
	list-style: none; padding: 0;
	margin: 0 0 0 -1.0615em;
	clip-path: inset(-100vmax -100vmax -100vmax calc(1.0615em - 6px));
}
.bullets > li { margin: 0; padding: 0; transition: none; }   /* style.css spaces every li, `transition: all` */
.bullets > li::before {
	content: "\2022";
	content: "\2022" / "";
	display: inline-block; width: 1.93em; text-align: center;
	font-size: .55em; vertical-align: .25em;
}

@keyframes rise    { to { transform: none; } }
@keyframes fade-up { from { transform: translateY(24px); } to { opacity: 1; transform: none; } }

/* --- Circle field ---------------------------------------------------------
   Outer span is the parallax target (GSAP writes transform, from step 3).
   Inner i is the visible circle (CSS keyframes write transform). They must be
   separate elements or the CSS animation overrides GSAP.
   Breathe animates opacity on the unblurred parent; animating opacity on the
   blurred child re-rasterises the blur each frame and shows rings.
   The fill is a solid disc, not a gradient, so the blur has no stops to band. */

.circles { position: absolute; inset: -12% -8%; z-index: -1; pointer-events: none; }

.circle {
	position: absolute;
	left: var(--x); top: var(--y);
	width: var(--s); height: var(--s);
	will-change: transform, opacity;
	animation: breathe var(--bdur) ease-in-out var(--bdelay) infinite alternate;
}
.circle i {
	display: block; width: 100%; height: 100%;
	border-radius: 50%;
	background: rgba(223, 87, 48, var(--fill, .30));
	filter: blur(58px);
	will-change: transform;
	animation: float var(--dur) ease-in-out var(--delay) infinite alternate;
}

@keyframes float {
	from { transform: translate3d(0, 0, 0) scale(1); }
	to   { transform: translate3d(var(--dx), var(--dy), 0) scale(var(--sc)); }
}
@keyframes drift {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(var(--ddx, var(--dx)), var(--ddy, var(--dy)), 0); }
}
@keyframes breathe {
	from { opacity: var(--o-min, .55); }
	to   { opacity: var(--o-max, .95); }
}

/* Drift, the chosen style: no breathing, no size change, a sideways wander
   on a sine-like curve so it reads as cloud rather than hover-and-reverse. */
.circles.is-drift .circle { animation: none; opacity: var(--o-max, .95); }
.circles.is-drift .circle i {
	animation: drift calc(var(--dur) * 0.31) cubic-bezier(.37, 0, .63, 1) var(--delay) infinite alternate;
}

/* Off screen the field rests (.is-offscreen, biscuit-motion.js). Paused, not
   stopped, so each circle picks up where it was. October 15, 2026. */
.circles.is-offscreen .circle,
.circles.is-offscreen .circle i { animation-play-state: paused; }
/* The menu's field is on screen but hidden while the menu is closed, which
   the observer cannot see, so it rests here. */
html:not(.menu-open) .menu__deco .circle,
html:not(.menu-open) .menu__deco .circle i { animation-play-state: paused; }

/* A circle that names a pre-blurred image (data-baked and --baked,
   section-hero.php) is drawn from it instead of the live blur, in every
   browser. Safari could not draw the live blur smoothly, still or moving, and
   Chrome's, in Brave, shows faint rings the image does not. A circle without
   an image keeps the live blur. The images come from
   Website 2026/bake-circles.py: the same disc, orange and 58px blur at 2x,
   180px of room on each side, the fill solid, so the circle's --fill becomes
   the image's opacity. Matched to the live blur in Chrome within half a level.
   Safari only at first; every browser from the same day. Jason, October 15, 2026. */
.circle[data-baked] i { position: relative; filter: none; background: none; }
.circle[data-baked] i::before {
	content: "";
	position: absolute;
	inset: -180px;
	background: var(--baked) center / 100% 100% no-repeat;
	opacity: var(--fill, .30);
}

/* --- Pill button -----------------------------------------------------------
   One leading circle on the left that widens to fill the button on hover and
   collapses back on the same ease-in-out. The label starts at the circle's
   centre, which is what the 24px left padding buys, and the right side
   matches it, so the filled pill has 24px each end and the label never
   moves. Two custom properties drive every variant. */

.pill {
	position: relative;
	display: inline-flex;
	align-items: center;
	height: 48px;
	padding: 0 24px;
	border-radius: 999px;
	overflow: hidden;
	text-decoration: none;
	font-family: var(--font-text);
	font-size: var(--text-s);
	font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase;
	letter-spacing: .12em;
	color: var(--pill-label, var(--biscuit-heading));
	background: transparent;
	border: 0;
	cursor: pointer;

	--pill-circle: var(--biscuit-panel);      /* cream, for a white ground */
	--pill-label:  var(--biscuit-heading);
}
.pill::before {
	content: "";
	position: absolute;
	left: 0; top: 0;
	width: 48px; height: 48px;
	border-radius: 999px;
	background: var(--pill-circle);
	z-index: 0;
	transition: width .46s ease-in-out;
}
/* The span's -.12em margin takes back the letter-spacing after the last
   letter, which would otherwise add 1.8px to the right side. The label used to
   slide 5px right on hover to even out 24px and 34px sides; the sides are
   even now, so it holds still. Jason, October 16, 2026. */
.pill > span { position: relative; z-index: 1; margin-right: -.12em; }
.pill:hover::before,
.pill:focus-visible::before { width: 100%; }

/* The pill is an <a>, and a generic a:hover outranks .pill, so hold the label. */
.pill:hover,
.pill:focus-visible,
.pill:active { color: var(--pill-label, var(--biscuit-heading)); text-decoration: none; }
.pill:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 3px; }

.pill--on-offwhite { --pill-circle: var(--biscuit-panel); --pill-label: var(--biscuit-heading); }
.pill--on-cream    { --pill-circle: var(--biscuit-white); --pill-label: var(--biscuit-heading); }
.pill--on-dark     { --pill-circle: rgba(252, 249, 245, .16); --pill-label: var(--biscuit-white); }

/* The orange pill. White on #AB3F25 is 6.05:1. It pulses: a ring leaves the
   circle and fades while the circle swells. Both stop on hover. */
.pill--orange { --pill-circle: var(--biscuit-button); --pill-label: var(--biscuit-white); overflow: visible; isolation: isolate; }
.pill--orange::before { animation: pulse-core 2.8s ease-in-out infinite; }
.pill--orange::after {
	content: ""; position: absolute; left: 0; top: 0; z-index: -1;
	width: 48px; height: 48px; border-radius: 50%;
	background: rgba(252, 249, 245, .22);
	border: 2px solid rgba(252, 249, 245, .85);
	animation: pulse-ring 2.8s ease-out infinite;
	pointer-events: none;
}
.pill--orange:hover::before, .pill--orange:focus-visible::before { animation: none; }
.pill--orange:hover::after, .pill--orange:focus-visible::after { animation: none; opacity: 0; }

@keyframes pulse-core { 0%, 100% { scale: 1; } 35% { scale: 1.12; } }
@keyframes pulse-ring { 0% { transform: scale(1); opacity: 1; } 75%, 100% { transform: scale(2.2); opacity: 0; } }

/* --- Custom cursor, from step 3 --------------------------------------------
   One element: the ring and the orange dot inside it are a div and its
   ::after, so they cannot drift apart. It lags the pointer slightly. The
   native cursor is not hidden, so links still look like links.
   Built by assets/js/biscuit-motion.js, which sets html.has-cursor only for a
   fine pointer that can hover and never under reduced motion. Touch, reduced
   motion and no-JS visitors get nothing at all.
   It crosses light and dark sections in one movement, so it uses one neutral
   gray that reads on both rather than a per-section color. */

.cursor { display: none; }

html.has-cursor .cursor {
	display: block;
	position: fixed;
	top: 0; left: 0;
	width: 38px; height: 38px;
	margin: -19px 0 0 -19px;
	border-radius: 50%;
	border: 1px solid rgba(135, 135, 135, .62);
	pointer-events: none;
	z-index: 10000;                         /* above the menu */
	will-change: transform;
	transition: width .3s var(--ease), height .3s var(--ease), margin .3s var(--ease),
	            background-color .3s ease, border-color .3s ease, opacity .3s ease;
}
html.has-cursor .cursor::after {
	content: "";
	position: absolute;
	top: 50%; left: 50%;
	width: 5px; height: 5px;
	margin: -2.5px 0 0 -2.5px;
	border-radius: 50%;
	background: var(--biscuit-accent);
	transition: opacity .25s ease;
}

/* Over anything clickable the ring swells and fills faintly. */
html.has-cursor.cursor-active .cursor {
	width: 76px; height: 76px;
	margin: -38px 0 0 -38px;
	border-color: transparent;
	background: rgba(223, 87, 48, .18);
}

/* A word inside the ring, from data-cursor-label, such as "View" over a
   Selected Works panel. Larger than the hover swell, the dot hidden, the word
   in the pill label style. */
html.has-cursor .cursor::before {
	content: attr(data-label);
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-text);
	font-size: 0.6875rem;
	font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase;
	letter-spacing: var(--biscuit-label-tracking);
	color: var(--biscuit-white);
	opacity: 0;
	transform: scale(.6);
	transition: opacity .25s ease, transform .3s var(--ease);
}
html.has-cursor.cursor-label .cursor {
	width: 92px; height: 92px;
	margin: -46px 0 0 -46px;
	border-color: transparent;
	background: rgba(252, 249, 245, .16);    /* the .pill--on-dark circle */
}
/* On a light ground the faint light circle would vanish. There it takes the
   same faint orange fill as the hover over a light button, and the word turns
   brand near-black so it still reads. Jason, October 12, 2026, for What we do. */
html.has-cursor.cursor-label.cursor-on-light .cursor { background: rgba(223, 87, 48, .18); }
html.has-cursor.cursor-label.cursor-on-light .cursor::before { color: var(--biscuit-heading); }
html.has-cursor.cursor-label .cursor::after { opacity: 0; }
html.has-cursor.cursor-label .cursor::before { opacity: 1; transform: none; }

/* --- Lenis smooth scroll, from step 3 ---------------------------------------
   Lenis puts these classes on <html> when it runs. Bootstrap turns on
   scroll-behavior: smooth, which would fight it. */

html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
/* Not only while Lenis is mid-scroll: whenever it runs. Bootstrap sets
   scroll-behavior: smooth on the root, and ScrollTrigger's refresh jumps to the
   top to measure and back again. With smooth on, that jump does not happen, so
   on a page that loads part way down, every trigger was recorded off by the
   scroll position. Arriving back on a Selected Works panel parked its text 277px
   above center. Proven by toggling this one property, October 12, 2026. */
html.lenis { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

/* --- Reduced motion: every part lands on its end state ------------------- */

@media (prefers-reduced-motion: reduce) {
	.circle, .circle i { animation: none; }
	.circle { opacity: var(--o-max, .95); }
	.pill, .pill::before, .pill::after, .pill > span { transition: none; }
	.pill--orange::before, .pill--orange::after { animation: none; }
}

/* ==========================================================================
   biscuit-nav.css
   ========================================================================== */

/* ==========================================================================
   Biscuit header and full-screen menu
   --------------------------------------------------------------------------
   Ported from the motion prototype's nav.css (Website 2026/motion-prototype),
   which is the spec. Markup is in header.php; behavior in biscuit.js.

   Mark on the left, "Let's talk" and the menu button on the right. The header
   hides on the way down and fades back on the way up, and its colors follow
   the ground under it. The menu is five panels that drop like blinds, the
   links rise out of masks, and the panels leave through the floor on close.

   The full-screen menu is the only menu: no dropdowns, no mega menu. Child
   pages show as small links under their parent (Jason, October 9, 2026).

   Differences from the prototype, each on purpose:
   - Fonts use --font-display and --font-text, which carry the Adobe Fonts
     names. The prototype used the desktop names.
   - Focus colors are held explicitly. style.css has a global a:focus rule
     that would turn a focused menu link orange.
   - No room is made for the WordPress admin bar. functions.php turns it off
     on the front end for everyone, admins included, so .admin-bar never
     applies here. Removed October 21, 2026, at Jason's request.

   Started October 9, 2026, step 2 of wordpress-conversion-2026.md.
   ========================================================================== */

.skip-link {
	position: fixed; left: 16px; top: -80px; z-index: 100;
	padding: 12px 18px; border-radius: 999px;
	background: var(--biscuit-near-black); color: var(--biscuit-white);
	font-size: var(--text-xs); text-decoration: none;
	transition: top .2s ease;
}
.skip-link:focus { top: 16px; color: var(--biscuit-white); }

/* ---------- Header --------------------------------------------------------- */

.site-header {
	--nav-fg: var(--biscuit-near-black);

	position: fixed; inset: 0 0 auto 0; z-index: 60;
	display: flex; align-items: center; justify-content: space-between;
	/* Lines up with .wide, which stops at 1680px. Above that the gutter grows by half the extra width,
	   so the logo and the menu button sit on the content's edges rather than the window's. They were
	   24px outside at 1728 and 120px at 1920. Jason, October 13, 2026. */
	padding: clamp(18px, 2.4vw, 34px) max(var(--gutter), calc((100% - 1680px) / 2 + var(--gutter)));
	color: var(--nav-fg);
	view-transition-name: site-header;   /* holds still while a page transition runs under it */
	transition: opacity .8s ease-in-out, visibility 0s linear 0s, color .4s ease;
	/* backwards, not both: both would hold opacity 1 for good and block the fade. */
	animation: nav-in 1s var(--ease) .1s backwards;
}

/* Landing on an anchor, from another page (/about/#standard) or this one: the
   spot stops below the header with room to breathe, not under it. The header
   is the 68px menu button plus its padding above and below, 104px on a phone
   and 136px wide; the last clamp is the breathing room. Anything with its own
   scroll-margin (.sw-panel, .works-list rows) is more specific and keeps it.
   biscuit.js hands the same number to Lenis, which ignores scroll-margin.
   Jason, October 16, 2026. */
:root { --anchor-offset: calc(68px + 2 * clamp(18px, 2.4vw, 34px) + clamp(16px, 2.5vw, 40px)); }
[id] { scroll-margin-top: var(--anchor-offset); }

/* The full-ground sections (Hero, Statement, What we do, Selected Works) land
   flush with the top. Their own top padding already clears the header, so the
   offset above stopped 172px short on a wide screen and left the bottom of the
   section before showing. Works List is a plain section with an editor-set
   padding, which can be smaller than the header, so it keeps the offset.
   Jason, October 21, 2026. */
:is(.hero, .statement, .services, .sw)[id] { scroll-margin-top: 0; }

/* Over a dark section, and always while the menu is open. */
.site-header[data-nav-theme="dark"],
html.menu-open .site-header {
	--nav-fg: var(--biscuit-off-white);
}

/* Fades out on the way down and leaves the tab order, so a hidden header
   cannot be focused or clicked. Returns on the way up, at the old .8s.
   The fade out is .4s and eases out, so it is visibly going from the first
   frame; at .8s ease-in-out it barely moved for the first quarter second.
   Jason, October 13, 2026. */
.site-header.is-hidden {
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity .4s ease-out, visibility 0s linear .4s, color .4s ease;
}
html.menu-open .site-header { opacity: 1; visibility: visible; pointer-events: auto; }

/* Its ground, once it is off the top of the page (.is-solid, biscuit.js), so
   it reads over the content when it comes back on the way up. Off-white over
   a light section, the dark ground over a dark one, both a touch see-through
   with a blur. Clear over the hero at the top, and while the menu is open.
   A layer of its own so it can fade. Jason, October 13, 2026. */
.site-header::before {
	content: ""; position: absolute; inset: 0; z-index: -1;
	background: rgba(252, 249, 245, .92);
	opacity: 0; pointer-events: none;
	transition: opacity .4s ease, background-color .4s ease;
}
.site-header[data-nav-theme="dark"]::before { background: rgba(26, 26, 26, .9); }
/* The blur only while the ground shows. Set on the hidden ground too, the
   browser re-blurs whatever scrolls under the header on every frame for
   nothing, and Safari is slowest at it. October 15, 2026. */
.site-header.is-solid::before {
	opacity: 1;
	-webkit-backdrop-filter: blur(12px);
	        backdrop-filter: blur(12px);
}
html.menu-open .site-header::before {
	opacity: 0;
	-webkit-backdrop-filter: none;
	        backdrop-filter: none;
}

@keyframes nav-in { from { opacity: 0; transform: translateY(-18px); } }

.site-logo {
	position: relative; display: block;
	height: clamp(40px, 3.75vw, 54px);
	aspect-ratio: 374 / 798;               /* the bare mark's artwork ratio */
}
.site-logo img {
	position: absolute; inset: 0; width: 100%; height: 100%;
	transition: opacity .4s ease, transform .6s var(--ease);
}
.site-logo__light { opacity: 0; }
.site-header[data-nav-theme="dark"] .site-logo__dark,
html.menu-open .site-logo__dark { opacity: 0; }
.site-header[data-nav-theme="dark"] .site-logo__light,
html.menu-open .site-logo__light { opacity: 1; }
.site-logo:focus-visible,
.nav-talk:focus-visible,
.nav-btn:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 6px; }

.site-header__right { display: flex; align-items: center; gap: clamp(20px, 2.6vw, 40px); }

.nav-talk {
	position: relative;
	padding: 6px 0;
	font-family: var(--font-text);
	font-size: var(--text-s); font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase; letter-spacing: .12em;
	text-decoration: none; color: inherit;
}
.nav-talk:hover,
.nav-talk:focus,
.nav-talk:active { color: inherit; text-decoration: none; }
/* 2px, not 1px. At 1px it antialiased to a half-tone and read lighter than
   the type, though both are currentColor. Jason, October 13, 2026. */
.nav-talk::after {
	content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
	background: currentColor; transform-origin: 100% 50%;
	transition: transform .5s var(--ease);
}
.nav-talk:hover::after { transform: scaleX(0); }
@media (max-width: 520px) {
	.nav-talk { font-size: var(--text-xs); letter-spacing: .1em; }
	.site-header__right { gap: 12px; }
}

/* Two long lines, no circle. The circle arrives on hover or focus. The button
   is bigger than the bars so the circle has room, and a negative right margin
   keeps the bars lined up with the page gutter. */
.nav-btn {
	position: relative; isolation: isolate; overflow: hidden;
	width: 68px; height: 68px; margin-right: -16px; padding: 0; border: 0; border-radius: 50%;
	background: transparent; color: var(--nav-fg);
	cursor: pointer;
	transition: color .6s ease;
}
.nav-btn::before {
	content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 50%;
	background: var(--biscuit-button); transform: scale(0);
	transition: transform .8s var(--ease);
}
.nav-btn:hover::before, .nav-btn:focus-visible::before { transform: scale(1); }
.nav-btn:hover, .nav-btn:focus-visible { color: var(--biscuit-white); }

.nav-btn i {
	position: absolute; left: 50%; top: 50%;
	width: 36px; height: 4px; margin: -2px 0 0 -18px;
	background: currentColor; border-radius: 4px;
	transition: transform .9s var(--ease-io);
}
.nav-btn i:nth-child(1) { transform: translateY(-5px); }
.nav-btn i:nth-child(2) { transform: translateY(5px); }
/* No size change on hover: changing the width of a line already rotated into
   the cross moves its centre and the X jumps. */
html.menu-open .nav-btn i:nth-child(1) { transform: rotate(45deg); }
html.menu-open .nav-btn i:nth-child(2) { transform: rotate(-45deg); }

/* ---------- Menu overlay ---------------------------------------------------- */

.menu {
	position: fixed; inset: 0; z-index: 50; overflow: hidden;
	visibility: hidden; pointer-events: none;
	color: var(--biscuit-off-white);
	/* Stays painted until the panels have left, then drops out of the tab order. */
	transition: visibility 0s linear 1s;
}
html.menu-open .menu { visibility: visible; pointer-events: auto; transition-delay: 0s; }
html.menu-open, html.menu-open body { overflow: hidden; }

/* Five panels. Closed: collapsed onto the bottom edge. Open: they grow down
   from the top edge, left to right. Closing flips the origin back to the
   bottom, so they keep going and leave through the floor. */
.menu__bg { position: absolute; inset: 0; display: flex; }
.menu__bg i {
	flex: 1; margin-right: -1px;          /* -1px hides the sub-pixel seam */
	background: var(--biscuit-near-black);
	transform: scaleY(0); transform-origin: 50% 100%;
	transition: transform .7s var(--ease-io) calc((4 - var(--i)) * .05s);
}
html.menu-open .menu__bg i {
	transform: scaleY(1); transform-origin: 50% 0;
	transition-delay: calc(var(--i) * .07s);
}

/* Decoration sits between the panels and the links. */
.menu__deco { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .4s ease; }
html.menu-open .menu__deco { opacity: 1; transition: opacity 1s ease .55s; }
.menu__deco .circles { --o-min: .3; --o-max: .5; inset: -10%; z-index: 0; }
.menu__deco .circle i { --fill: .46; }
.menu__grid {
	position: absolute; inset: 0;
	-webkit-mask-image: linear-gradient(100deg, transparent 30%, #000 100%);
	        mask-image: linear-gradient(100deg, transparent 30%, #000 100%);
}
.menu__grid .biscuit-grid { position: absolute; inset: 0; --biscuit-grid-color: rgba(252, 249, 245, .1); }

.menu__inner {
	position: relative; height: 100%;
	display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
	gap: clamp(32px, 5vw, 96px);
	align-items: end;
	/* The header's side padding, so the links stay under the logo above 1680px. */
	padding: clamp(110px, 17vh, 170px) max(var(--gutter), calc((100% - 1680px) / 2 + var(--gutter))) clamp(36px, 7vh, 72px);
	overflow-y: auto;
}

.menu__nav ol { list-style: none; margin: 0; padding: 0; }
/* style.css spaces every li, and indents ol li by 12px. Not in the menu. */
.menu__nav li { margin: 0; padding: 0; }

.menu__link {
	/* Centered, not on the baseline, so the small number sits on the middle of its word rather than
	   at its foot. Jason, October 13, 2026. */
	position: relative; display: flex; align-items: center; gap: clamp(14px, 2vw, 32px);
	font-size: min(var(--display-xl), 14vh);   /* the em basis for the dot too */
	padding: .02em 0; text-decoration: none; color: var(--biscuit-off-white);
	transition: opacity .4s ease, transform .6s var(--ease);
}
.menu__link:hover,
.menu__link:focus,
.menu__link:active { color: var(--biscuit-off-white); text-decoration: none; }
/* Dim the other top-level items, for the pointer and for keyboard focus. */
.menu__nav ol:hover > li:not(:hover) .menu__link,
.menu__nav ol:has(.menu__link:focus-visible) .menu__link:not(:focus-visible) { opacity: .32; }
.menu__link:hover, .menu__link:focus-visible { transform: translateX(.18em); }
.menu__link:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 4px; }

.menu__num {
	min-width: 2.2em;
	font-family: var(--font-text);
	font-size: var(--text-label); font-weight: var(--biscuit-weight-strong);
	letter-spacing: var(--biscuit-label-tracking);
	color: rgba(252, 249, 245, .6);
	/* Fades in as its word rises and out as the words drop. It had no state of its own, so it showed
	   the moment the menu became visible, before the panels, and stayed until the menu hid, a
	   second after closing. Jason, October 13, 2026. */
	opacity: 0;
	transition: opacity .25s ease;
}
html.menu-open .menu__num {
	opacity: 1;
	transition: opacity .8s ease calc(.6s + var(--i) * .08s);
}

.menu__mask { display: block; overflow: hidden; padding-bottom: .12em; margin-bottom: -.12em; }
.menu__text {
	display: block;
	font-family: var(--font-display); font-weight: var(--weight-heading);
	font-size: 1em;
	line-height: 1; letter-spacing: -0.035em;
	transform: translateY(112%);
	transition: transform .35s ease-in;
}

/* An orange dot that grows in front of the link under the pointer or focus.
   Graphic, not text, so the brand orange is fine on the dark panel. Centered
   on the word, the same line the number is centered on; it sat at 52%.
   Jason, October 13, 2026. */
.menu__link::before {
	content: ""; position: absolute; left: -.3em; top: 50%;
	width: .22em; height: .22em; margin-top: -.11em; border-radius: 50%;
	background: var(--biscuit-orange);
	transform: scale(0); transition: transform .5s var(--ease);
}
.menu__link:hover::before, .menu__link:focus-visible::before { transform: scale(1); }
html.menu-open .menu__text {
	transform: none;
	transition: transform 1s var(--ease) calc(.5s + var(--i) * .08s);
}

/* ---------- Child pages ------------------------------------------------------
   Small links under their parent, lined up with the parent's text: the
   number is 2.2 x 12px wide, plus the same gap as the link. They rise in
   after the parent. */
.menu__sub {
	display: flex; flex-wrap: wrap; gap: 6px 24px;
	list-style: none; margin: 0; padding: .35em 0 .9em calc(12px * 2.2 + clamp(14px, 2vw, 32px));
	opacity: 0; transform: translateY(12px);
	transition: opacity .3s ease, transform .3s ease;
}
html.menu-open .menu__sub {
	opacity: 1; transform: none;
	transition: opacity .9s ease calc(.75s + var(--i) * .08s),
	            transform 1s var(--ease) calc(.75s + var(--i) * .08s);
}
.menu__sublink {
	font-family: var(--font-text);
	font-size: var(--text-m); line-height: 1.5;
	color: rgba(252, 249, 245, .8); text-decoration: none;
}
.menu__sublink:hover,
.menu__sublink:focus,
.menu__sublink:active,
.menu__sublink[aria-current="page"] {
	color: var(--biscuit-off-white);
	text-decoration: underline; text-underline-offset: 4px;
}
.menu__sublink:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 4px; }

/* ---------- Side column ---------------------------------------------------- */

.menu__info { display: grid; gap: 28px; justify-items: start; padding-bottom: .4em; }
.menu__info p, .menu__info a { margin: 0; font-size: var(--text-m); line-height: 1.55; }
.menu__info a,
.menu__info a:focus { color: var(--biscuit-off-white); text-decoration: none; }
.menu__info a:hover { color: var(--biscuit-off-white); text-decoration: underline; text-underline-offset: 4px; }
.menu__info a:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 4px; }
.menu__info .label { display: block; margin-bottom: 8px; color: rgba(252, 249, 245, .6); }
/* Separated by bullets, as the footer's links are (.bullets, under "Bullet lists" above). No
   new-tab icon (Jason, October 13, 2026), but the mark's alt text in style.css stays, so a screen
   reader still hears "(opens in a new tab)". */
.menu__social { gap: 8px 0; font-size: var(--text-m); line-height: 1.55; }
.menu__social a[target="_blank"]::after { padding: 0; margin: 0; background: none; -webkit-mask: none; mask: none; }

.menu__info > div {
	opacity: 0; transform: translateY(18px);
	transition: opacity .3s ease, transform .3s ease;
}
html.menu-open .menu__info > div {
	opacity: 1; transform: none;
	transition: opacity .9s ease calc(.85s + var(--i) * .08s),
	            transform 1s var(--ease) calc(.85s + var(--i) * .08s);
}

@media (max-width: 820px) {
	.menu__inner { grid-template-columns: 1fr; align-items: start; gap: 40px; }
	.menu__info { gap: 22px; }
}

/* ---------- Print and motion off --------------------------------------------- */

@media print {
	.site-header, .menu, .skip-link { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
	.site-header { animation: none; transition: none; }
	.menu__bg i { transform: scaleY(1); transition: none; opacity: 0; }
	html.menu-open .menu__bg i { opacity: 1; transition: opacity .25s ease; }
	.menu__text { transform: none; }
	.menu__num, .menu__sub, .menu__info > div { opacity: 1; transform: none; }
	.nav-btn i, .nav-btn::before, .site-logo img { transition: none; }
}

/* ==========================================================================
   biscuit-footer.css
   ========================================================================== */

/* ==========================================================================
   Biscuit footer
   --------------------------------------------------------------------------
   Ported from the motion prototype's home.css (Website 2026/motion-prototype),
   which is the spec. Markup is in footer.php.

   A large heading and the orange pill, a soft rule, a row of links, and the
   small print, on near-black with the brand grid fading in from the right.
   The heading, links and small print rise in on scroll from step 3, when GSAP
   arrives; without it they simply sit in place.

   Differences from the prototype, each on purpose: style.css sizes every h2,
   so the footer heading sets its own; and focus colors are held because of
   style.css's global a:focus rule.

   Started October 9, 2026, step 2 of wordpress-conversion-2026.md.
   ========================================================================== */

.site-footer {
	--foot-h: var(--display-xl);

	position: relative; overflow: hidden; isolation: isolate;
	padding: clamp(100px, 12.8vw, 230px) 0 clamp(140px, 18vw, 320px);
	background: var(--biscuit-near-black);
	color: var(--biscuit-off-white);
	font-family: var(--font-text);
}

.site-footer__grid {
	position: absolute; inset: 0; z-index: -1; pointer-events: none;
	-webkit-mask-image: linear-gradient(90deg, transparent 38%, #000 100%);
	        mask-image: linear-gradient(90deg, transparent 38%, #000 100%);
}
.site-footer__grid .biscuit-grid { position: absolute; inset: 0; --biscuit-grid-color: rgba(252, 249, 245, .1); }

.site-footer__top { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 48px; }

.site-footer h2 {
	max-width: 9ch;
	margin: 0;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: var(--foot-h);
	line-height: 1; letter-spacing: -0.01em;
	color: var(--biscuit-off-white);
}

/* Lines up with the middle of the heading's first line: half the line height,
   less half the button's 48px. Only when they share a row. */
@media (min-width: 700px) {
	.site-footer .pill--orange { margin-top: calc(var(--foot-h) / 2 - 24px); }
}

.site-footer .rule { margin:clamp(28px, 2.8vw, 50px) 0 clamp(28px, 3.6vw, 62px); }

.footer-links {
	gap: 10px 0;                         /* the rest is .bullets, under "Bullet lists" above */
	font-size: var(--text-l); letter-spacing: -0.01em;   /* Jason, October 12, 2026: was 20 to 34px, too large */
}
/* No new-tab icon here. style.css adds a Tabler icon after every target="_blank" link. */
.footer-links a[target="_blank"]::after { content: none; }
/* style.css spaces every li and gives it `transition: all .3s`. GSAP animates these items in, and
   when ScrollTrigger re-measures (after the fonts load) it reads the computed values mid-transition
   and records the hidden state as the end, so they stayed invisible. No transition here. */
.footer-links li { margin: 0; padding: 0; transition: none; }
.footer-links a,
.footer-links a:hover,
.footer-links a:focus,
.footer-links a:active {
	color: var(--biscuit-off-white);
	text-decoration: none;
}
.footer-links a {
	background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
	transition: background-size .5s var(--ease);
}
.footer-links a:hover, .footer-links a:focus-visible { background-size: 100% 1px; }
.footer-links a:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 4px; }

.footer-small {
	margin-top: clamp(32px, 3.6vw, 62px);
	font-size: var(--text-s); line-height: 1.9;
	color: rgba(252, 249, 245, .8);
}
.footer-small p { margin: 0; }
.footer-small a,
.footer-small a:focus,
.footer-small a:active { color: rgba(252, 249, 245, .8); text-decoration: none; }
.footer-small a:hover { color: var(--biscuit-off-white); text-decoration: underline; text-underline-offset: 3px; }
.footer-small a:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 3px; }
.footer-small .sep { margin: 0 .9em; }

@media print {
	.site-footer { display: none !important; }
}

/* ==========================================================================
   biscuit-content.css
   ========================================================================== */

/* ==========================================================================
   Biscuit content
   --------------------------------------------------------------------------
   Two things every page can use:

   1. .prose, the type for text an editor writes in a WYSIWYG field: the
      flexible sections and the body of a post. Moved here from
      biscuit-blog.css in step 6 so a post and a page read the same.
   2. The flexible content sections rebuilt in step 6, family (a): 1, 2 and
      3 Columns, the two image-and-text halves, two videos, Full Width
      Image, Callout, Quote and Page Menu.

   Sections share one frame. Every section sits in .wide, so its left edge
   is the header's and the footer's. Narrow and Standard cap the content at
   800px, the width of a post's text, and 1280px, centered in that frame;
   Wide fills it. Jason, October 13 and 14, 2026. From
   step 6 until October 13 they were two thirds and five sixths of the frame, from
   the left, after the motion prototype, whose pages all hang off one edge.
   The grounds keep their saved class names, which style.css colors. The
   spacing fields become sec--pt-* and sec--pb-* (biscuit_section_attrs()),
   which scale with the screen.

   style.css sets global rules on p, li, a and footer (margins,
   `transition: all`). Each block resets what reaches it, marked "style.css".
   Headings and quotes have brand defaults there since phase 3 of the
   stylesheet reorganization, October 13, 2026, so they need no reset.

   Started October 12, 2026, step 6 of wordpress-conversion-2026.md.
   ========================================================================== */

/* ---------- Prose ------------------------------------------------------------
   Colors are custom properties set by the ground, not by .prose, so they
   inherit: a dark section sets them dark, a white card inside it sets them
   back. See "Grounds" below. Light values are the fallbacks. */

.prose {
	font-size: var(--text-m);
	line-height: 1.7;
	color: var(--prose-body, var(--biscuit-body));
}
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose p { margin: 0 0 1.3em; }

.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
	margin: 1.9em 0 .6em;
	letter-spacing: -0.01em;
	color: var(--prose-heading, var(--biscuit-heading));
}
/* Bold is Text Medium 500; inside a heading that asks Adobe for Display 500,
   the lighter cut, so a heading wrapped in <strong> came out thinner. */
.prose :is(h1, h2, h3, h4, h5, h6) :is(strong, b) { font-weight: inherit; }
/* A typed h1 is a page's title, so it is set as the template's title is (.page-head__title):
   40 to 88px, line height 1, the same tracking. Jason, October 13, 2026; it was 38 to 72px. */
.prose h1 { font-size: var(--h1); line-height: 1; letter-spacing: -0.025em; text-wrap: balance; margin-bottom: .5em; }
.prose h2 { font-size: var(--h2); line-height: 1.16; }
.prose h3 { font-size: var(--h3); line-height: 1.22; }
.prose h4 { font-size: var(--h4); line-height: 1.3; }
.prose h5,
.prose h6 { font-size: var(--h5); line-height: 1.4; }
/* A heading class sets the size whatever the tag, so an h2 can be set at h1 size and keep the
   page's outline. Two classes outrank .prose h2 above. Jason, October 21, 2026. */
.prose .h1 { font-size: var(--h1); line-height: 1; letter-spacing: -0.025em; text-wrap: balance; }
.prose .h2 { font-size: var(--h2); line-height: 1.16; }
.prose .h3 { font-size: var(--h3); line-height: 1.22; }
.prose .h4 { font-size: var(--h4); line-height: 1.3; }
.prose .h5,
.prose .h6 { font-size: var(--h5); line-height: 1.4; }
.prose h1 + h2,
.prose h2 + h3,
.prose h3 + h4 { margin-top: .8em; }

.prose ul,
.prose ol { margin: 0 0 1.3em; padding-left: 1.3em; }
.prose li { margin: 0 0 .5em; padding-left: .2em; transition: none; }  /* style.css */
.prose li::marker { color: var(--prose-marker, var(--biscuit-accent)); }

/* List styles from the Formats dropdown, a class on the ul: columns, ruled and tags. Small text and
   tight rows, for lists of short items such as the services on About. Columns and ruled run two
   columns where the text is wide enough and one where it is not (columns: 2 14em), reading down
   each column, with no item split across the break. The rule and tag colors follow the ground.
   Jason, October 21, 2026. */
.prose :is(.list-columns, .list-ruled, .list-tags) { font-size: var(--text-s); line-height: 1.45; }
.prose :is(.list-columns, .list-ruled) { font-size: 1rem; }   /* 16px; tags stay 15. Jason, October 21, 2026 */
.prose :is(.list-columns, .list-ruled) { columns: 2 14em; column-gap: clamp(32px, 4vw, 64px); }
.prose :is(.list-columns, .list-ruled) > li { break-inside: avoid; }

.prose .list-columns { list-style: disc; padding-left: 1.1em; }
.prose .list-columns > li { margin: 0 0 .45em; padding-left: .15em; }

.prose .list-ruled { list-style: none; padding-left: 0; }
.prose .list-ruled > li { margin: 0; padding: .6em 0; border-top: 1px solid var(--prose-rule, var(--biscuit-rule)); }

.prose .list-tags { display: flex; flex-wrap: wrap; gap: .5em; list-style: none; padding-left: 0; }
.prose .list-tags > li {
	margin: 0;
	padding: .4em 1em;
	border-radius: 999px;
	background: var(--prose-tag, var(--biscuit-cream));
	color: var(--prose-heading, var(--biscuit-heading));
}

/* Not .btn or .pill: a button keeps its own label color.
   The underline is drawn, not text-decoration, so it can redraw on hover: it
   wipes off to the right, then draws in from the left, line by line on a link
   that wraps. Same gradient as the blog card titles. At rest it sits where the
   old underline did (.18em under the baseline, about 1px). --link-line-end
   stops it short of the new-tab mark and the arrow, as the old one did. Not on
   a link around an image, which the old underline never drew under.
   Jason, October 22, 2026. */
.prose a:not(.btn, .pill) { color: var(--prose-link, var(--biscuit-link)); }
.prose a:not(.btn, .pill, :has(img)) {
	--link-line: max(1px, .06em);
	--link-line-end: 0px;
	text-decoration: none;
	background: linear-gradient(currentColor, currentColor) left 0 bottom 0 / calc(100% - var(--link-line-end)) var(--link-line) no-repeat;
}
.prose a[target="_blank"]:not(.btn, .pill) { --link-line-end: 1em; }
.prose a.link-arrow { --link-line-end: 1.15em; }
.prose a:not(.btn, .pill):hover,
.prose a:not(.btn, .pill):focus-visible { color: var(--prose-link-hover, var(--biscuit-link-hover)); }
.prose a:not(.btn, .pill, :has(img)):hover,
.prose a:not(.btn, .pill, :has(img)):focus-visible { animation: link-redraw .7s var(--ease-io); }
@keyframes link-redraw {
	0%   { background-position: right var(--link-line-end) bottom 0; background-size: calc(100% - var(--link-line-end)) var(--link-line); }
	40%  { background-position: right var(--link-line-end) bottom 0; background-size: 0 var(--link-line); }
	50%  { background-position: left 0 bottom 0; background-size: 0 var(--link-line); }
	100% { background-position: left 0 bottom 0; background-size: calc(100% - var(--link-line-end)) var(--link-line); }
}
@media (prefers-reduced-motion: reduce) {
	.prose a:not(.btn, .pill, :has(img)):is(:hover, :focus-visible) { animation: none; }
}

/* The circle button from the editor's Add a button (a .pill, see "Pill button"): its circle and label
   follow the ground, cream and near black on a light one, faint off-white and off-white on a dark one,
   so one choice in the editor works in any section. Jason, October 21, 2026. */
.prose .pill {
	--pill-circle: var(--prose-pill, var(--biscuit-panel));
	--pill-label: var(--prose-heading, var(--biscuit-heading));
	isolation: isolate;
	padding-right: calc(24px - .12em);   /* the span's -.12em, as the right padding */
}
/* TinyMCE drops a span with no attributes, so the label is bare text here, not the span that lifts it
   in a template. The circle goes under the text instead. Jason, October 21, 2026. */
.prose .pill::before { z-index: -1; }

.prose img { display: block; max-width: 100%; height: auto; }
.prose h1 img,
.prose h2 img,
.prose p img { margin: 0; }
.prose iframe { max-width: 100%; }

/* The quote's look is the global blockquote in style.css; here its color follows the ground. */
.prose blockquote { color: var(--prose-heading, var(--biscuit-heading)); }

.prose hr { margin: 2em 0; }

/* ---------- Section frame ------------------------------------------------------ */

.sec {
	padding-top: var(--sec-pt, 0);
	padding-bottom: var(--sec-pb, 0);
}

.sec--pt-l { --sec-pt: clamp(64px, 7vw, 130px); }
.sec--pt-m { --sec-pt: clamp(32px, 3.6vw, 64px); }
.sec--pt-s { --sec-pt: 0px; }
.sec--pb-l { --sec-pb: clamp(64px, 7vw, 130px); }
.sec--pb-m { --sec-pb: clamp(32px, 3.6vw, 64px); }
.sec--pb-s { --sec-pb: 0px; }

/* ---------- Flexible pages -----------------------------------------------------
   page-flexible.php: a white page with no hero band, like the project and
   blog pages. The head prints only when the page has no h1 of its own (see
   the template), at the project head's size. When it does not print, the
   first section's own h1 is the head, and that section's top padding grows
   to clear the fixed header. The 2026 Hero carries no .sec, so it still
   starts at the very top. */

.page-main__sections { background: var(--biscuit-page); }

.page-head {
	padding-top: clamp(130px, 13vw, 210px);
	padding-bottom: clamp(36px, 4vw, 64px);
}
.page-head__title {
	margin: 0;
	font-size: var(--h1);
	line-height: 1;
	letter-spacing: -0.025em;
	text-wrap: balance;
}
.page-head__title .mask-line > span {
	transform: translateY(108%);
	animation: rise 1.15s var(--ease) .1s forwards;
}
@media (prefers-reduced-motion: reduce) {
	.page-head__title .mask-line > span { transform: none; animation: none; }
}

.page-main__sections > .sec:first-child {
	padding-top: max(var(--sec-pt, 0px), clamp(130px, 13vw, 210px));
}
/* After the head, the first section starts close under it. */
.page-head + .sec.sec--pt-l { --sec-pt: clamp(32px, 3.6vw, 64px); }

/* The password form and the members gate. */
.page-gate { padding: clamp(60px, 8vw, 120px) 0; }

/* A small label over a page head: the 404 page. */
.page-head .label { margin: 0 0 clamp(14px, 1.4vw, 22px); }
/* A pill after a section's text: the 404 page's way home. */
.single-page__back { margin: clamp(32px, 3.6vw, 56px) 0 0; }

/* ---------- Bio and testimonial pages ----------------------------------------------
   single-bio.php and single-testimonial.php, step 7c, October 13, 2026. A bio
   reads as its dialog does (.pop__bio, under "Bios"), opened out to the page:
   the photo beside the name. A testimonial is the person, then the whole quote
   large, in Display Roman like the slides. */
.single-page {
	padding-top: clamp(130px, 13vw, 210px);
	padding-bottom: clamp(64px, 7vw, 130px);
}
.single-page .bio__title { margin-top: clamp(10px, 1vw, 16px); font-size: var(--text-m); }
.single-page .bio__links { margin-top: 18px; }
.single-page .pop__bio .prose { margin-top: clamp(28px, 3vw, 44px); }

.testi-page { margin: 0; max-width: 60rem; }
.testi-page .label { margin: 0 0 clamp(16px, 1.6vw, 24px); }
.testi-page .who__name {
	margin: 0;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: var(--h2);
	line-height: 1.15;
	letter-spacing: -0.01em;
}
.testi-page .who__company { font-size: var(--text-s); }
.testi-page blockquote {
	margin: clamp(32px, 3.6vw, 56px) 0 0;
	padding: 0;
	border: 0;
	overflow: visible;
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
	font-size: clamp(1.375rem, 2.2vw, 2.25rem);
	line-height: 1.3;
	letter-spacing: -0.01em;
	color: var(--biscuit-heading);
}
.testi-page blockquote::before {
	content: "\201C";
	display: block;
	height: .5em;
	font-weight: var(--weight-heading);
	font-size: 3em;
	line-height: 1;
	color: var(--biscuit-accent);
}

/* ---------- Grounds --------------------------------------------------------------
   A section says its tone in data-nav (which the header also reads), a card
   in data-tone; both come from biscuit_ground() in functions.php. The dark
   grounds are the deep orange, near black, gray and #1A1A1A: text turns
   off-white. On the deep orange the brand orange would vanish, so links and
   list markers stay off-white there. A light card resets the colors, so it
   reads the same on any section. */
.sec[data-nav="dark"],
[data-tone="dark"],
.sec-full {
	--prose-heading: var(--biscuit-off-white);
	--prose-body: var(--biscuit-off-white);
	--prose-link: var(--biscuit-off-white);
	--prose-link-hover: var(--biscuit-orange);
	--prose-marker: var(--biscuit-orange);
	--prose-rule: rgba(252, 249, 245, .16);
	--prose-tag: rgba(252, 249, 245, .1);
	--prose-pill: rgba(252, 249, 245, .16);
	--stat-num: var(--biscuit-off-white);
	color: var(--biscuit-off-white);
}
.sec.primary-bg,
[data-tone="dark"].primary-bg { --prose-link-hover: var(--biscuit-off-white); --prose-marker: var(--biscuit-off-white); }
[data-tone="light"] {
	--prose-heading: var(--biscuit-heading);
	--prose-body: var(--biscuit-body);
	--prose-link: var(--biscuit-link);
	--prose-link-hover: var(--biscuit-link-hover);
	--prose-marker: var(--biscuit-accent);
	--prose-rule: var(--biscuit-rule);
	--prose-tag: var(--biscuit-cream);
	--prose-pill: var(--biscuit-cream);
	--stat-num: var(--biscuit-accent);
	color: var(--biscuit-body);
}

/* Widths. Narrow is a post's text column (800px, .post-body in biscuit-blog.css), Standard
   1280px; Wide is the whole frame, up to 1680px less the gutter. Narrow and Standard are
   centered in the frame. Below those widths each simply fills the frame. Under .wide so they
   outrank ul.tiles, whose margin is 0. Jason, October 13, 2026. On October 14, 2026 hanging
   them from the left and a 1144px Standard were both tried and turned back the same day
   (Lucy chose 1280px), so keep these. */
.wide .is-narrow,
.wide .is-standard { margin-left: auto; margin-right: auto; }
.wide .is-narrow   { max-width: 800px; }
.wide .is-standard { max-width: 1280px; }

/* Text held to Narrow's 800px inside a wider section, from its left edge, so a
   Standard section's text lines up with a Standard image row and still reads at
   a comfortable length. Typed on a paragraph, heading, list or div in the
   editor's Text tab: <p class="max-800">. Jason, October 14, 2026. */
.max-800 { max-width: 800px; }

/* ---------- 2 and 3 Columns ------------------------------------------------------ */

.sec-cols {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(28px, 3vw, 48px) clamp(32px, 5vw, 96px);
}
@media (min-width: 992px) {
	.sec-cols.is-8-4   { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
	.sec-cols.is-6-6   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.sec-cols.is-4-8   { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
	.sec-cols.is-thirds { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.sec-cols.is-middle { align-items: center; }
}
/* Column Order applies only while the two are stacked, as it did before. */
@media (max-width: 991px) {
	.sec-cols.is-right-first .sec-cols__right { order: -1; }
}

/* ---------- Image and text, half and half ------------------------------------- */

.sec-split {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	padding-top: 0;
	padding-bottom: 0;
}
.sec-split__media {
	position: relative;
	margin: 0;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--biscuit-panel);
}
.sec-split__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sec-split__media figcaption,
.sec-full figcaption {
	font-size: var(--text-xs);
	line-height: 1.4;
}
.sec-split__media figcaption {
	position: absolute;
	left: 0; right: 0; bottom: 0;
	padding: 40px 16px 12px;
	color: var(--biscuit-white);
	background: linear-gradient(to top, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0));
}
.sec-split.is-image-right .sec-split__media figcaption { text-align: right; }

.sec-split__text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: max(var(--sec-pt, 0px), 48px) var(--gutter) max(var(--sec-pb, 0px), 48px);
}
@media (min-width: 992px) {
	.sec-split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.sec-split__media { aspect-ratio: auto; min-height: clamp(420px, 40vw, 760px); }
	.sec-split.is-image-right .sec-split__media { order: 2; }
	.sec-split__text { padding-left: clamp(40px, 6vw, 120px); padding-right: clamp(40px, 6vw, 120px); }
	/* The outer side lines up with the page gutter. */
	.sec-split.is-image-left .sec-split__text  { padding-right: max(var(--gutter), clamp(40px, 6vw, 120px)); }
	.sec-split.is-image-right .sec-split__text { padding-left: var(--gutter); }
}

/* ---------- Image Grid ------------------------------------------------------------
   section-image-grid.php, added October 14, 2026, from Jason's whiteboard of seven
   layouts. From 768px every arrangement sits on one grid of six columns and two
   rows: a half spans three columns, a third two, two thirds four, so edges line up
   when rows stack. The row's Height sets its shape, so every image in it is the
   same height, and each image is cropped to fill its cell (Crop Focus picks the
   part kept). Original fits the row to the images, so the crop is nil or a sliver. Images 30px apart, 16px on a phone (Jason). Two Image Grids in a row
   on the same ground sit one gap apart: the template adds .is-joined-top and
   .is-joined-bottom. Left and right edges are the text frame, .wide and Width. */
.sec-images { --img-gap: 16px; }
.sec-images.is-joined-top    { --sec-pt: var(--img-gap); }
.sec-images.is-joined-bottom { --sec-pb: 0px; }

.img-grid {
	display: grid;
	gap: var(--img-gap);
}
.img-grid__cell {
	position: relative;
	margin: 0;
	overflow: hidden;
	background: var(--biscuit-panel);
}
.img-grid__cell img {
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	margin: 0;
	object-fit: cover;
}
.img-grid__cell.is-focus-top img    { object-position: center top; }
.img-grid__cell.is-focus-bottom img { object-position: center bottom; }
.img-grid__cell.is-focus-left img   { object-position: left center; }
.img-grid__cell.is-focus-right img  { object-position: right center; }
.img-grid__cell figcaption {
	position: absolute;
	left: 0; right: 0; bottom: 0;
	padding: 40px 16px 12px;
	font-size: var(--text-xs);
	line-height: 1.4;
	color: var(--biscuit-white);
	background: linear-gradient(to top, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0));
}

/* Phones: one image to a line, each keeping its wide-screen shape (Jason,
   October 14, 2026). --ar is worked out per image in the template, from the
   arrangement, the Height and the 30px gap. */
@media (max-width: 767px) {
	.img-grid__cell { aspect-ratio: var(--ar, 3 / 2); }
}

@media (min-width: 768px) {
	.sec-images { --img-gap: 30px; }
	.img-grid {
		grid-template-columns: repeat(6, minmax(0, 1fr));
		grid-template-rows: repeat(2, minmax(0, 1fr));
		aspect-ratio: 2 / 1;
	}
	.img-grid.is-short { aspect-ratio: 21 / 9; }
	.img-grid.is-tall  { aspect-ratio: 16 / 9; }
	/* The template repeats these three ratios ($grid_ratios) and the areas
	   below ($grid_shapes) to work out --ar; change one, change the other.
	   Original (the default, October 14, 2026) takes its height from the
	   images: k times the row's width plus c, worked out in the template as
	   --grid-k and --grid-c. The row's width is the section's .wide, capped by
	   Width, so the .wide is a size container and 100cqw is its width. */
	.img-grid.is-original {
		--grid-max: 100cqw;
		aspect-ratio: auto;
		height: calc(var(--grid-k) * min(100cqw, var(--grid-max)) + var(--grid-c));
	}
	.img-grid.is-original.is-narrow   { --grid-max: 800px; }
	.img-grid.is-original.is-standard { --grid-max: 1280px; }
	.sec-images .wide:has(> .img-grid.is-original) { container-type: inline-size; }

	.img-grid__cell:nth-child(1) { grid-area: a; }
	.img-grid__cell:nth-child(2) { grid-area: b; }
	.img-grid__cell:nth-child(3) { grid-area: c; }

	/* Image 1 is the left image, or the large one in a split. */
	.img-grid.is-full        { grid-template-areas: "a a a a a a" "a a a a a a"; }
	.img-grid.is-halves      { grid-template-areas: "a a a b b b" "a a a b b b"; }
	.img-grid.is-third-left  { grid-template-areas: "a a b b b b" "a a b b b b"; }
	.img-grid.is-third-right { grid-template-areas: "a a a a b b" "a a a a b b"; }
	.img-grid.is-split-right { grid-template-areas: "a a a b b b" "a a a c c c"; }
	.img-grid.is-split-left  { grid-template-areas: "b b b a a a" "c c c a a a"; }
	.img-grid.is-thirds      { grid-template-areas: "a a b b c c" "a a b b c c"; }
}

/* ---------- Two videos --------------------------------------------------------- */

.sec-videos__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(20px, 2.5vw, 40px);
}
@media (min-width: 768px) {
	.sec-videos__row { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
}
.sec-videos__frame { aspect-ratio: 16 / 9; background: var(--biscuit-near-black); }
.sec-videos__frame iframe { display: block; width: 100%; height: 100%; margin: 0; border: 0; }

/* ---------- Full Width Image ----------------------------------------------------- */

.sec-full { margin: 0; }

.sec-full.is-parallax {
	position: relative;
	display: flex;
	align-items: center;
	min-height: clamp(360px, 46vw, 780px);
	overflow: hidden;
	isolation: isolate;
	background: var(--biscuit-near-black);
	color: var(--biscuit-off-white);
}
.sec-full__media { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
/* 10% of slack top and bottom for the travel, written by biscuit-motion.js. */
.sec-full__parallax { position: absolute; left: 0; right: 0; top: -10%; height: 120%; will-change: transform; }
.sec-full__parallax img { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; }
/* A dark wash only when text sits on the photo. Black at low alpha, a shade not a color. */
.sec-full.has-text .sec-full__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, .45);
}
.sec-full__text {
	max-width: 40em;
	padding: clamp(64px, 8vw, 140px) 0;
}

.sec-full.is-fixed img { display: block; width: 100%; height: auto; }
.sec-full.is-fixed figcaption,
.sec-full__caption {
	margin: 0;
	padding-top: 12px;
	padding-bottom: 12px;
	font-size: var(--text-xs);
	color: var(--biscuit-muted);
}

/* ---------- Callout ------------------------------------------------------------------
   The text set large in the display face, a step lighter than headings, as
   the brand sets quotes. */

.sec-callout .prose {
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
	font-size: clamp(1.5rem, 2.6vw, 2.75rem);
	line-height: 1.22;
	letter-spacing: -0.005em;
	color: var(--prose-heading, var(--biscuit-heading));
}
.sec-callout .prose p { margin-bottom: .7em; }

/* ---------- Quote ----------------------------------------------------------------- */

.sec-quote__figure { margin: 0; max-width: 24em; font-size: clamp(1.75rem, 3.4vw, 3.625rem); }
.sec-quote__figure::before {
	content: "\201C";
	display: block;
	height: .55em;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: 2.6em;
	line-height: 1;
	color: var(--biscuit-accent);
}
.sec.primary-bg .sec-quote__figure::before { color: var(--biscuit-off-white); }

/* The section sets its own size and spacing over the global blockquote in style.css. */
.sec-quote blockquote {
	margin: 0;
	font-size: inherit;
	padding: 0;
	border: 0;
	background: none;
	overflow: visible;
}
.sec-quote blockquote p {
	margin: 0;
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
	font-size: 1em;
	line-height: 1.14;
	letter-spacing: -0.01em;
	color: var(--biscuit-heading);
}
.sec-quote figcaption.label { margin-top: clamp(20px, 2vw, 32px); font-weight: var(--biscuit-weight-strong); }

/* The ground classes are on the section itself, the same element as .sec-quote. */
.sec-quote.primary-bg blockquote p,
.sec-quote.secondary-bg blockquote p,
.sec-quote.tertiary-bg blockquote p,
.sec-quote.black-bg blockquote p,
.sec-quote.dark-bg blockquote p { color: var(--biscuit-off-white); }
.sec-quote.primary-bg figcaption,
.sec-quote.secondary-bg figcaption,
.sec-quote.tertiary-bg figcaption,
.sec-quote.black-bg figcaption,
.sec-quote.dark-bg figcaption { color: rgba(252, 249, 245, .75); }
/* At .75 on the deep orange the label measures 3.93:1 and fails; full off-white is 5.77:1. */
.sec-quote.primary-bg figcaption { color: var(--biscuit-off-white); }

/* ---------- Page Menu ------------------------------------------------------------------
   A bar of pill links held at the bottom of the screen from 576px, under the
   full-screen menu (z-index 50). Below 576px it is left out, as before. */

.page-nav { display: none; }
@media (min-width: 576px) {
	.page-nav {
		position: fixed;
		left: 50%;
		bottom: 20px;
		z-index: 40;
		display: block;
		width: max-content;                /* as wide as its links */
		max-width: calc(100% - var(--gutter) * 2);
		translate: -50% 0;
		padding: 6px;
		overflow-x: auto;
		border-radius: 999px;
		background: var(--biscuit-white);
		box-shadow: 0 8px 32px rgba(0, 0, 0, .12);
	}
}
.page-nav ul {
	display: flex;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.page-nav li { margin: 0; padding: 0; transition: none; white-space: nowrap; }   /* style.css */
.page-nav p { margin: 0; }
.page-nav a,
.page-nav span {
	display: block;
	padding: 10px 16px;
	font-family: var(--font-text);
	font-size: var(--text-label);
	font-weight: var(--biscuit-weight-strong);
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: var(--biscuit-label-tracking);
	white-space: nowrap;
}
.page-nav span { color: var(--biscuit-muted); }
.page-nav a {
	border-radius: 999px;
	color: var(--biscuit-heading);
	text-decoration: none;
	transition: background-color .3s ease;
}
.page-nav a:hover,
.page-nav a:focus-visible { color: var(--biscuit-heading); background: var(--biscuit-panel); }
.page-nav a:focus-visible { outline: 2px solid var(--biscuit-accent); outline-offset: -2px; }

/* ---------- Cards and Stat Cards (family b) ------------------------------------
   One tile for both layouts. A row holds 1 to 5 on a wide screen (per-N,
   from Cards per Row), two from 768px, one on a phone. Each tile carries its
   own Card Background and tone, so a white card on a dark section reads
   dark-on-white. Show Card Borders draws a hairline rule. */

.tiles {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(20px, 2.2vw, 36px);
}
@media (min-width: 768px) {
	.tiles:not(.per-1) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 992px) {
	.tiles.per-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.tiles.per-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.tiles.per-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.tile {
	display: flex;
	flex-direction: column;
	min-width: 0;
	overflow: hidden;
}
.tile.has-line { border: 1px solid var(--biscuit-rule); }
.tile.has-line[data-tone="dark"] { border-color: rgba(252, 249, 245, .16); }

.tile__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--biscuit-panel); }
.tile__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tile__video { aspect-ratio: 16 / 9; background: var(--biscuit-near-black); }
.tile__video iframe { display: block; width: 100%; height: 100%; margin: 0; border: 0; }

.tile__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: clamp(20px, 2vw, 32px);
}
.tile .prose { font-size: var(--text-m); line-height: 1.65; }
.tile .prose h2 { font-size: var(--h3); }
.tile .prose h3 { font-size: var(--h4); }
/* Buttons sit at the foot of the card, so a row of cards lines them up. */
.tile__buttons { margin-top: auto; padding-top: 16px; }
.tile__button { margin: 8px 0 0; }

/* Masonry: columns of uneven height, read down each column. */
.tiles.is-masonry { display: block; columns: 1; column-gap: clamp(20px, 2.2vw, 36px); }
.tiles.is-masonry > .tile { display: flex; margin-bottom: clamp(20px, 2.2vw, 36px); break-inside: avoid; }
@media (min-width: 768px) {
	.tiles.is-masonry:not(.per-1) { columns: 2; }
}
@media (min-width: 992px) {
	.tiles.is-masonry.per-3 { columns: 3; }
	.tiles.is-masonry.per-4 { columns: 4; }
	.tiles.is-masonry.per-5 { columns: 5; }
}

/* Horizontal: two to a row from 992px, each an image beside its text; the
   image swaps sides from one card to the next. Images are often icons, so
   no panel behind them. */
@media (min-width: 992px) {
	.tiles.is-horizontal { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.tiles.is-horizontal .tile__media {
	flex: none;
	width: clamp(96px, 12vw, 180px);
	aspect-ratio: 1;
	margin: clamp(20px, 2vw, 32px) clamp(20px, 2vw, 32px) 0;
	background: none;
}
@media (min-width: 576px) {
	.tiles.is-horizontal .tile { flex-direction: row; align-items: center; }
	.tiles.is-horizontal .tile.is-flipped { flex-direction: row-reverse; }
	.tiles.is-horizontal .tile__media { margin: clamp(20px, 2vw, 32px); margin-right: 0; }
	.tiles.is-horizontal .tile.is-flipped .tile__media { margin-right: clamp(20px, 2vw, 32px); margin-left: 0; }
}

/* Stats. The number in the display face, brand orange on a light ground
   (display type, which brand.md allows), off-white on a dark one. */
.stat__num {
	margin: 0 0 .3em;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: var(--h1);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--stat-num, var(--biscuit-accent));
}

/* Stats on a photo: the intro, then the numbers straight on the image, or in
   faint light panels with Show Card Borders on. */
.sec-stats-photo .wide { padding-top: clamp(24px, 3vw, 48px); padding-bottom: clamp(24px, 3vw, 48px); }
.sec-stats-photo__intro { max-width: 40em; margin-bottom: clamp(32px, 4vw, 56px); }
.tile.is-on-photo { padding: 0; }
.tile.is-on-photo.has-line {
	padding: clamp(20px, 2vw, 32px);
	border-color: rgba(252, 249, 245, .22);
	background: rgba(252, 249, 245, .08);
}

/* ---------- Dialogs ----------------------------------------------------------------
   Native <dialog class="pop">, opened by biscuit.js. Replaces Bootstrap's
   modal for testimonials and bios. The browser handles focus, Escape and the
   top layer; the backdrop is the near-black at alpha, a shade not a color.
   October 22, 2026: more padding, most of it on wide screens (32px on a
   phone, 96px from 1600px up, was 28 to 64), and the rule's round corners.
   --pop-pad is the padding, and the close button reads it to find the
   corner. Jason. */

dialog.pop {
	--pop-pad: clamp(32px, 6vw, 96px);
	width: min(960px, calc(100% - var(--gutter) * 2));
	max-height: calc(100dvh - 48px);
	margin: auto;
	padding: var(--pop-pad);
	border: 0;
	border-radius: var(--rule-radius);
	background: var(--biscuit-white);
	color: var(--biscuit-body);
	overflow: auto;
	overscroll-behavior: contain;
	--prose-heading: var(--biscuit-heading);
	--prose-body: var(--biscuit-body);
	--prose-link: var(--biscuit-link);
	--prose-link-hover: var(--biscuit-link-hover);
	--prose-marker: var(--biscuit-accent);
	--prose-rule: var(--biscuit-rule);
	--prose-tag: var(--biscuit-cream);
	--prose-pill: var(--biscuit-cream);
}
dialog.pop::backdrop { background: rgba(26, 26, 26, .72); }
dialog.pop[open] { animation: pop-in .45s var(--ease) both; }
@keyframes pop-in { from { opacity: 0; transform: translateY(18px); } }

/* The close button: a cream circle with a drawn X, the pill's circle.
   October 22, 2026: 36px, was 48, and a fixed inset from the corner
   (--pop-close-inset) rather than half the padding, so it sits up in the
   corner however wide the padding grows. Jason.
   The sticky never held until then: the button's <form method="dialog"> has
   no height, and a sticky element cannot leave its parent, so it scrolled
   away with the text. display: contents takes the form's box out, and the
   dialog becomes the parent. A sticky top counts from inside the padding,
   so the inset less the padding puts it at the corner. Worked out.
   It moves right with translate, not a negative right margin: once the
   button is the dialog's own float, Chrome counts that margin as width and
   the dialog scrolled 13px sideways. translate moves only the drawing. The
   left margin gives the 16px gap back to the text it wraps. Worked out. */
dialog.pop > form[method="dialog"] { display: contents; }
.pop__close {
	--pop-close-inset: clamp(14px, 1.5vw, 24px);
	--pop-close-shift: calc(var(--pop-pad) - var(--pop-close-inset));
	position: relative;
	display: block;
	z-index: 1;
	width: 36px; height: 36px;
	margin: calc(var(--pop-close-shift) * -1) 0 8px auto;
	translate: var(--pop-close-shift) 0;
	border: 0;
	border-radius: 50%;
	background: var(--biscuit-panel);
	cursor: pointer;
	transition: background-color .3s ease;
}
/* Below 992px the button is a row of its own at the top right, not a float:
   the text starts under it and runs the full width, padding the same both
   sides, and the button scrolls away with it. From 992px it fits inside the
   right padding (the padding less the inset reaches 36px at about 834px
   wide), so it floats there and sticks. Jason, October 22, 2026. */
@media (min-width: 992px) {
	.pop__close {
		position: sticky;
		top: calc(var(--pop-close-inset) - var(--pop-pad));
		float: right;
		margin-left: calc(16px - var(--pop-close-shift));
	}
}
.pop__close span,
.pop__close span::before {
	position: absolute;
	left: 50%; top: 50%;
	width: 14px; height: 2px;
	margin: -1px 0 0 -7px;
	background: var(--biscuit-heading);
	transform: rotate(45deg);
}
.pop__close span::before { content: ""; left: 0; top: 0; margin: 0; transform: rotate(90deg); }
.pop__close:hover,
.pop__close:focus-visible { background: rgba(223, 87, 48, .18); }
.pop__close:focus-visible { outline: 2px solid var(--biscuit-accent); outline-offset: 3px; }

.pop__title {
	margin: 0;
	font-size: clamp(1.875rem, 3.4vw, 3.25rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
}
.pop__quote { margin: 0; }
.pop__quote blockquote {
	margin: 0 0 28px;
	padding: 0;
	border: 0;
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
	font-size: var(--text-xl);
	line-height: 1.4;
	color: var(--biscuit-heading);
}

/* ---------- Testimonials ------------------------------------------------------------ */

.sec-testi__intro { margin-bottom: clamp(32px, 4vw, 56px); }

/* One person: a round photo, the name, the company. */
.who { display: flex; align-items: center; gap: 14px; margin: 0; }
.who__photo { flex: none; width: 52px; height: 52px; overflow: hidden; border-radius: 50%; background: var(--biscuit-panel); }
.who__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.who__text { display: flex; flex-direction: column; line-height: 1.3; }
.who__name { font-weight: var(--biscuit-weight-strong); color: var(--prose-heading, var(--biscuit-heading)); }
.who__company { font-size: var(--text-s); color: var(--biscuit-muted); }
/* Muted text on a dark ground: the off-white at reduced emphasis (brand.md),
   because #6A6A6A measures 3.22:1 on #1A1A1A. On the deep orange even that
   fails (3.93:1), so it is full off-white there (5.77:1). */
.sec[data-nav="dark"] :is(.who__company, .post-card__label) { color: rgba(252, 249, 245, .75); }
.sec.primary-bg :is(.who__company, .post-card__label) { color: var(--biscuit-off-white); }
/* A light card inside a dark section keeps the gray. */
.sec [data-tone="light"] :is(.who__company, .post-card__label) { color: var(--biscuit-muted); }

/* The card: the start of the quote in Display Roman, then the person. */
.quote-tile { margin: 0; }
.quote-tile blockquote {
	margin: 0 0 24px;
	padding: 0;
	border: 0;
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
	font-style: normal;
	font-size: var(--text-l);
	line-height: 1.4;
	color: var(--biscuit-heading);
}
.quote-tile blockquote::before {
	content: "\201C";
	display: block;
	height: .5em;
	font-weight: var(--weight-heading);
	font-size: 3em;
	line-height: 1;
	color: var(--biscuit-accent);
}
.quote-tile blockquote p { margin: 0; }

/* ---------- Sliding rows ------------------------------------------------------------
   One slide to a view, snapping. The buttons come from biscuit.js and
   hide when everything fits. */

.slides { min-width: 0; }
.slides__track {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	overscroll-behavior-x: contain;
}
.slides__track::-webkit-scrollbar { display: none; }
.slides__track:focus-visible { outline: 2px solid var(--biscuit-accent); outline-offset: 6px; }
.slide { flex: 0 0 100%; margin: 0; scroll-snap-align: start; padding-right: 2px; }

.slides__nav { display: flex; gap: 10px; margin-top: clamp(24px, 2.5vw, 40px); }
.slides.is-static .slides__nav { display: none; }
.slides__nav button {
	width: 48px; height: 48px;
	border: 0;
	border-radius: 50%;
	background: var(--biscuit-panel);
	color: var(--biscuit-heading);
	font-size: 1.125rem;
	cursor: pointer;
	transition: background-color .3s ease, opacity .3s ease;
}
.slides__nav button:hover,
.slides__nav button:focus-visible { background: rgba(223, 87, 48, .18); }
.slides__nav button:focus-visible { outline: 2px solid var(--biscuit-accent); outline-offset: 3px; }
.slides__nav button:disabled { opacity: .35; cursor: default; background: var(--biscuit-panel); }
[data-nav="dark"] .slides__nav button { background: rgba(252, 249, 245, .16); color: var(--biscuit-off-white); }

/* A testimonial slide: the quote large, then the person. */
.quote-slide blockquote {
	margin: 0 0 clamp(24px, 2.5vw, 40px);
	padding: 0;
	border: 0;
	max-width: 24em;
	font-family: var(--font-display);
	font-weight: var(--biscuit-weight-quote);
	font-style: normal;
	font-size: clamp(1.5rem, 2.8vw, 2.875rem);
	line-height: 1.18;
	letter-spacing: -0.01em;
	color: var(--prose-heading, var(--biscuit-heading));
}
.sec-testi.is-half-page .quote-slide blockquote { font-size: clamp(1.375rem, 2vw, 2rem); }
.quote-slide blockquote p { margin: 0; }
.quote-slide figcaption { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; }
.slide__more { font-size: var(--text-s); color: var(--prose-link, var(--biscuit-link)); text-underline-offset: .18em; }
.slide__more:hover,
.slide__more:focus-visible { color: var(--prose-link-hover, var(--biscuit-link-hover)); }

/* ---------- Bios ---------------------------------------------------------------- */

ul.tiles { margin: 0; padding: 0; list-style: none; }
.tile.bio { margin: 0; padding: 0; transition: none; }   /* style.css li */
.bio__photo { aspect-ratio: 4 / 5; overflow: hidden; background: var(--biscuit-panel); }
.bio__photo img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--ease); }
.bio__name {
	margin: 0;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: var(--h4);
	line-height: 1.15;
	color: var(--biscuit-heading);
}
.bio__title { margin: 6px 0 0; font-size: var(--text-s); color: var(--biscuit-muted); }
.bio__links { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin: 14px 0 0; font-size: var(--text-s); }
.bio__links img { display: block; width: 24px; height: 24px; }
.bio__links a { color: var(--biscuit-link); }
/* The first icon's tooltip starts at the icon rather than centering on it: a
   bio card clips what crosses its edge, and the icon is 23px in. The arrow
   stays on the icon's middle. Jason, October 22, 2026. */
.bio__links .has-tip:first-child > .tip { left: 0; transform: translate(0, 4px); }
.bio__links .has-tip:first-child:is(:hover, :focus-visible) > .tip { transform: translate(0, 0); }
.bio__links .has-tip:first-child > .tip > span::after { left: 12px; }

/* A bio with text: the whole card opens it, through the name button
   stretched over the card. The links stay clickable above it. */
.bio.has-dialog { position: relative; cursor: pointer; }
.bio__open {
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	color: inherit;
	text-align: left;
	cursor: pointer;
}
.bio__open::after { content: ""; position: absolute; inset: 0; }
.bio__open:focus-visible { outline: none; }
.bio.has-dialog:has(.bio__open:focus-visible) { outline: 3px solid var(--biscuit-accent); outline-offset: 4px; }
.bio.has-dialog .bio__links { position: relative; z-index: 1; }
.bio.has-dialog:hover .bio__photo img { transform: scale(1.04); }
.bio.has-dialog:hover .bio__name { color: var(--biscuit-link); }

.pop__bio { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(24px, 3vw, 48px); }
@media (min-width: 768px) {
	.pop__bio { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); align-items: start; }
}
.pop__bio .prose { margin-top: 24px; }

/* ---------- Partner/Client Logos ------------------------------------------------------- */

.logos__list { display: flex; flex-wrap: wrap; align-items: center; margin: 0; padding: 0; list-style: none; }
.logos__item { margin: 0; padding: 0; transition: none; }   /* style.css li */
.logos__item img {
	display: block;
	width: auto;
	max-width: 180px;
	height: clamp(44px, 4.5vw, 72px);
	object-fit: contain;
}
.logos__item a { display: block; transition: opacity .3s ease; }
/* style.css puts a new-tab icon after every link that opens one. Not under a logo or an icon. */
.logos__item a[target="_blank"]::after,
.bio__links a[target="_blank"]:has(img)::after { content: none; }
.logos__item a:hover,
.logos__item a:focus-visible { opacity: .7; }

.logos.is-grid .logos__list { gap: clamp(28px, 4vw, 64px) clamp(36px, 5vw, 80px); }

/* The marquee: two copies side by side, moved left by exactly one copy's
   width, so the second lands where the first began. About 4 seconds a logo. */
.logos.is-marquee { overflow: hidden; }
.logos__run { display: flex; width: max-content; animation: logos-run calc(var(--logo-count, 8) * 4s) linear infinite; }
.logos.is-marquee .logos__list { flex-wrap: nowrap; gap: 0; }
/* Each copy is at least a screen wide, so a short list still loops with
   no empty stretch; a few logos spread out across it. */
.logos.is-marquee .logos__list { min-width: 100vw; justify-content: space-around; }
.logos.is-marquee .logos__item { padding-right: clamp(40px, 5vw, 88px); }
.logos.is-marquee:hover .logos__run { animation-play-state: paused; }
@keyframes logos-run { to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
	.logos__run { animation: none; width: auto; padding: 0 var(--gutter); }
	.logos__run .logos__list[aria-hidden] { display: none; }
	.logos.is-marquee .logos__list { flex-wrap: wrap; gap: 28px 0; }
}

/* ---------- Featured Blog Posts ----------------------------------------------------------- */

/* Any pill on a dark section takes the dark-ground circle and a white label. */
.sec[data-nav="dark"] .pill:not(.pill--orange) { --pill-circle: rgba(252, 249, 245, .16); --pill-label: var(--biscuit-white); }

.sec-feat__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: clamp(36px, 4vw, 64px);
}
.sec-feat__title {
	margin: 0;
	font-size: var(--display-xl);
	line-height: .96;
	letter-spacing: -0.02em;
	color: var(--prose-heading, var(--biscuit-heading));
}

/* ---------- Reduced motion ------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	dialog.pop[open] { animation: none; }
	.bio__photo img { transition: none; }
	.slides__track { scroll-behavior: auto; }
}

/* ---------- FAQs (family d) -----------------------------------------------------------
   Native <details>, ruled top and bottom like What We Do. The answer grows
   open where the browser can animate to auto height (::details-content and
   interpolate-size); elsewhere it simply opens. */

/* Round-ended lines in the ground's rule color (the rule tokens), as What we
   do and the Works List have, from October 20, 2026; they were 1px. Each
   question draws the line above it and the list the last. On <summary>
   rather than <details>, whose own ::before browsers do not all draw. */
.faqs { position: relative; interpolate-size: allow-keywords; padding-bottom: var(--rule-line); }
.faqs::after { bottom: 0; }

.faq__q {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding: calc(clamp(20px, 2.2vw, 32px) + var(--rule-line)) 0 clamp(20px, 2.2vw, 32px);
	list-style: none;
	cursor: pointer;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: var(--h3);
	line-height: 1.25;
	color: var(--prose-heading, var(--biscuit-heading));
	transition: color .3s ease;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::before { top: 0; }
.faq__q:hover { color: var(--biscuit-link); }
[data-nav="dark"] .faq__q:hover { color: var(--biscuit-orange); }
.faq__q:focus-visible { outline: 2px solid var(--biscuit-accent); outline-offset: 4px; }

/* A plus in the pill's cream circle that turns to a minus when open. */
.faq__icon {
	position: relative;
	flex: none;
	width: 40px; height: 40px;
	border-radius: 50%;
	background: var(--biscuit-panel);
	transition: background-color .3s ease;
}
[data-nav="dark"] .faq__icon { background: rgba(252, 249, 245, .16); }
.faq__icon::before,
.faq__icon::after {
	content: "";
	position: absolute;
	left: 50%; top: 50%;
	width: 14px; height: 2px;
	margin: -1px 0 0 -7px;
	background: var(--prose-heading, var(--biscuit-heading));
	transition: transform .4s var(--ease);
}
.faq__icon::after { transform: rotate(90deg); }
.faq[open] .faq__icon::after { transform: rotate(0deg); }
.faq__q:hover .faq__icon { background: rgba(223, 87, 48, .18); }

.faq__a { max-width: 46em; padding-bottom: clamp(20px, 2.2vw, 32px); }

.faq::details-content {
	block-size: 0;
	overflow: hidden;
	transition: block-size .5s var(--ease), content-visibility .5s allow-discrete;
}
.faq[open]::details-content { block-size: auto; }

@media (prefers-reduced-motion: reduce) {
	.faq::details-content,
	.faq__icon::after { transition: none; }
}

/* ---------- Galleries ----------------------------------------------------------------
   The [gallery] shortcode (my_post_gallery() in functions.php), step 7d, October
   13, 2026. The column counts arrive as --cols, --cols-m and --cols-s from
   biscuit_gallery_cols(): two at most on a phone, four at most from 768px, the
   full count from 992px. Gallery Settings' Layout picks the arrangement at
   any size. Rows, the default: a grid, left to right in the editor's order,
   an image shorter than its row at the top of it. Columns (.is-flowing): CSS
   columns, filled down each column, which packs images of different heights.
   Until October 17, 2026 the size chose: Medium and larger were columns. */
.gallery {
	--gallery-gap: clamp(12px, 1.4vw, 20px);
	display: grid;
	grid-template-columns: repeat(var(--cols-s, 1), minmax(0, 1fr));
	align-items: start;
	gap: var(--gallery-gap);
	margin: 1.6em 0;
}
.gallery.is-flowing { display: block; columns: var(--cols-s, 1); column-gap: var(--gallery-gap); }
@media (min-width: 768px) {
	.gallery { grid-template-columns: repeat(var(--cols-m, 1), minmax(0, 1fr)); }
	.gallery.is-flowing { columns: var(--cols-m, 1); }
}
@media (min-width: 992px) {
	.gallery { grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr)); }
	.gallery.is-flowing { columns: var(--cols, 1); }
}
.gallery-item { margin: 0; }
.gallery.is-flowing .gallery-item { margin-bottom: var(--gallery-gap); break-inside: avoid; }
.gallery-item a { display: block; }
.gallery-item img { display: block; width: 100%; height: auto; margin: 0; }
.gallery-caption {
	margin: 8px 0 0;
	font-size: var(--text-xs);
	font-style: normal;                    /* style.css */
	line-height: 1.4;
	text-align: left;                      /* style.css */
	color: var(--biscuit-muted);
}

/* ---------- Lightbox -----------------------------------------------------------------
   Any link in the page content that opens an image file shows it here instead,
   in place of FooBox (Jason, October 13, 2026). Built to FooBox's popup as the
   site had it, its Metro style: a #2A2A2A screen, the image in a white frame
   that fills the screen less 20px, small white square buttons, the frame
   growing from half size as it opens, and a slideshow with a thin white bar
   along the bottom. The script is in biscuit.js, "Lightbox". Differences on
   purpose: every button is named; the buttons are at .7 and full on hover or
   focus, where FooBox's close sat at .2, too faint to find; Tabler icons, as
   the rest of the site; no share, fullscreen, zoom or #foobox links. */
dialog.lightbox {
	--lb-pad: 20px;
	position: fixed; inset: 0;
	width: 100%; height: 100%; max-width: none; max-height: none;
	margin: 0; padding: 0; border: 0;
	background: var(--biscuit-near-black);
	color: var(--biscuit-off-white);
	overflow: hidden;
	overscroll-behavior: contain;
}
dialog.lightbox::backdrop { background: transparent; }
dialog.lightbox[open] { display: grid; place-items: center; animation: lb-fade .4s ease-in-out both; }
@keyframes lb-fade { from { opacity: 0; } }

/* The frame is the image's own size, scaled to fit the screen less the
   padding, up as well as down (FooBox's "fit to screen"). --lb-ratio is the
   image's width over its height, set by the script once it has loaded. */
.lightbox__frame {
	position: relative;
	width: min(100vw - var(--lb-pad) * 2, (100dvh - var(--lb-pad) * 2) * var(--lb-ratio, 1));
	aspect-ratio: var(--lb-ratio, 1);
	background: var(--biscuit-white);      /* a transparent logo sits on white, as in FooBox */
	transition: transform .4s ease-in-out, opacity .4s ease-in-out;
	touch-action: pan-y pinch-zoom;        /* sideways swipes come to the script */
}
.lightbox.is-loading .lightbox__frame,
.lightbox.is-changing .lightbox__frame { opacity: 0; transform: scale(.5); }
.lightbox.is-changing .lightbox__frame { transition-duration: .2s; transform: scale(.94); }
.lightbox__img { display: block; width: 100%; height: 100%; margin: 0; object-fit: contain; }

/* The spinner: FooBox's white square, shown only if an image is slow. */
.lightbox__spinner {
	position: absolute; top: 50%; left: 50%;
	width: 80px; height: 80px; margin: -40px 0 0 -40px;
	border-radius: 3px; background: var(--biscuit-white);
	box-shadow: 0 0 3px rgba(0, 0, 0, .4);
	opacity: 0; visibility: hidden; transition: opacity .2s ease, visibility .2s;
}
.lightbox__spinner::after {
	content: ""; position: absolute; inset: 22px;
	border: 3px solid var(--biscuit-rule); border-top-color: var(--biscuit-muted); border-radius: 50%;
	animation: lb-spin .9s linear infinite;
}
@keyframes lb-spin { to { transform: rotate(1turn); } }
.lightbox.is-slow .lightbox__spinner { opacity: 1; visibility: visible; }

/* Buttons: a 28px white square, the 3px clear border a bigger target. */
.lightbox__btn {
	position: fixed; z-index: 2;
	display: grid; place-items: center;
	width: 34px; height: 34px; padding: 0;
	border: 3px solid transparent; border-radius: 6px;
	background: var(--biscuit-white); background-clip: padding-box;
	color: var(--biscuit-muted);
	opacity: .7; cursor: pointer;
	transition: opacity .2s ease, color .2s ease;
}
.lightbox__btn:hover,
.lightbox__btn:focus-visible { opacity: 1; color: var(--biscuit-near-black); }
.lightbox__btn:focus-visible { outline: 2px solid var(--biscuit-orange); outline-offset: 2px; }
.lightbox__btn svg { display: block; width: 16px; height: 16px; }
.lightbox__close { top: calc(var(--lb-pad) - 3px); right: calc(var(--lb-pad) - 3px); }
.lightbox__play  { top: calc(var(--lb-pad) + 47px); right: calc(var(--lb-pad) - 3px); }
.lightbox__prev,
.lightbox__next  { top: 50%; height: 46px; margin-top: -23px; }
.lightbox__prev  { left: calc(var(--lb-pad) - 3px); }
.lightbox__next  { right: calc(var(--lb-pad) - 3px); }
.lightbox.is-single :is(.lightbox__prev, .lightbox__next, .lightbox__play) { display: none; }
.lightbox__play .is-pause,
.lightbox.is-playing .lightbox__play .is-play { display: none; }
.lightbox.is-playing .lightbox__play .is-pause { display: block; }

/* The caption: FooBox's bar along the bottom of the screen, over the image. */
.lightbox__caption {
	position: fixed; left: 0; right: 0; bottom: 0; z-index: 1;
	margin: 0; padding: 12px var(--lb-pad);
	background: rgba(26, 26, 26, .72);
	font-family: var(--font-text); font-size: var(--text-xs); line-height: 1.4; text-align: center;
	color: var(--biscuit-off-white);
}
.lightbox__caption:empty { display: none; }

/* The slideshow's bar, along the bottom of the screen, filling as it waits. */
.lightbox__progress {
	position: fixed; left: 0; bottom: 0; z-index: 3;
	width: 0; height: 5px; background: rgba(255, 255, 255, .5);
}
.lightbox.is-playing .lightbox__progress { animation: lb-progress var(--lb-delay, 6s) linear both; }
@keyframes lb-progress { to { width: 100%; } }

/* Read out as each image shows: "Image 2 of 4", and its caption. */
.lightbox__status {
	position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* A phone: 10px around the image, room above it for the buttons, and bigger
   targets for a thumb. */
@media (max-width: 575px) {
	dialog.lightbox { --lb-pad: 10px; }
	.lightbox__frame { width: min(100vw - 20px, (100dvh - 120px) * var(--lb-ratio, 1)); }
	.lightbox__btn { width: 44px; height: 44px; border-width: 8px; }
	.lightbox__close { top: 2px; right: 2px; }
	.lightbox__play  { top: 2px; right: 46px; }
	.lightbox__prev,
	.lightbox__next  { height: 56px; margin-top: -28px; }
	.lightbox__progress { height: 3px; }
}

@media (prefers-reduced-motion: reduce) {
	dialog.lightbox[open] { animation: none; }
	.lightbox__frame { transition: none; }
	.lightbox.is-loading .lightbox__frame,
	.lightbox.is-changing .lightbox__frame { transform: none; }
	.lightbox.is-playing .lightbox__progress { animation-name: none; }
}

/* ---------- Embedded video -----------------------------------------------------------
   The editor's video tool (biscuit-button-block.js) wraps an embed in
   .video-embed, at 16:9, full width. It used Bootstrap's .ratio until step 8,
   October 13, 2026. */
.video-embed { aspect-ratio: 16 / 9; margin: 0 0 1.3em; }
.video-embed iframe { display: block; width: 100%; height: 100%; }

/* ==========================================================================
   biscuit-sections.css
   ========================================================================== */

/* ==========================================================================
   Biscuit sections, the 2026 flexible content layouts
   --------------------------------------------------------------------------
   Hero, Statement, What We Do and Selected Works. Each is a layout in the
   Flexible Page Content field group, so they can sit on any flexible page;
   the home page is built from them.

   Ported from the motion prototype (Website 2026/motion-prototype, files
   prototype.css, home.css and selected-works.css), which is the spec for how
   these look and move. Parts shared with the header and footer (the gutter,
   pill, circles, mask lines, rules) are in biscuit-components.css. Scroll
   motion is in assets/js/biscuit-motion.js. Without that script, or under
   reduced motion, every section is already in its finished state.

   style.css sets global rules on p, ol and li (margins, list indents,
   `transition: all` on li). Each section resets what reaches it, marked
   "style.css". Headings have brand defaults there since phase 3 of the
   stylesheet reorganization, October 13, 2026.

   Started October 9, 2026, step 3 of wordpress-conversion-2026.md.
   ========================================================================== */

/* ---------- Hero ----------------------------------------------------------- */

.hero {
	position: relative;
	overflow: hidden;
	isolation: isolate;
	/* Full screen on every device. svh is the height with mobile browser
	   chrome showing, so the hero never sits behind an address bar. */
	min-height: 100vh;
	min-height: 100svh;
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: clamp(150px, 16vw, 260px) 0 clamp(110px, 12vw, 200px);
	background: var(--biscuit-ground-dark);
	color: var(--biscuit-off-white);
}

/* The circles carry more of the page on the dark ground: a stronger fill,
   faded right back as a layer. Drift holds each circle at --o-max, so that
   one number is the whole control. Jason, October 4, 2026. */
.hero .circle i { --fill: .46; }
.hero .circles  { --o-min: .12; --o-max: .32; }

/* style.css spaces h1 and h2 below. */
.hero__title {
	margin: 0;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: var(--display-xl);
	line-height: .957;
	letter-spacing: -0.015em;
	color: var(--biscuit-off-white);
}

/* The orange word. style.css makes every em italic. */
.accent { font-style: normal; color: var(--biscuit-accent); }

.hero__blurb {
	max-width: 20.5em;
	margin: clamp(24px, 2.5vw, 44px) 0 0;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: clamp(1.5rem, 3vw, 3.25rem);
	line-height: 1.06;
	color: var(--biscuit-off-white);
}
/* Each row of the field is a span. From 992px each starts a line, so the
   editor chooses the break, as in the headline. Jason, October 13, 2026. */
@media (min-width: 992px) {
	.hero__blurb > span { display: block; }
}
/* Its color is the dark ground's rule color, .16, as in the footer. Was .13
   until October 20, 2026, Jason. */
.hero .rule { margin: clamp(24px, 2.5vw, 44px) 0 0; }
.hero__cta  { margin: clamp(24px, 2.5vw, 44px) 0 0; }

/* Load-in, CSS only, so it runs before any script and survives without one.
   Each line carries its own --i, so any number of lines staggers. */
.hero__title .mask-line > span {
	transform: translateY(108%);
	animation: rise 1.25s var(--ease) forwards;
	animation-delay: calc(.25s + var(--i, 0) * .13s);
}
.hero__blurb,
.hero__cta { opacity: 0; animation: fade-up 1.1s var(--ease) forwards; }
.hero__blurb { animation-delay: .85s; }
.hero__cta   { animation-delay: 1.05s; }

/* ---------- Statement ------------------------------------------------------ */

/* Figma: 171px above the statement and 143px below the button, at 1440. */
.statement {
	padding: clamp(96px, 11.9vw, 210px) 0 clamp(80px, 9.9vw, 175px);
	background: var(--biscuit-page-alt);
}

.reveal {
	max-width: 15em;                       /* four lines at 1440 */
	margin: 0;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: clamp(1.875rem, 4.45vw, 4.875rem);
	line-height: 1.06;
	letter-spacing: -0.01em;
	color: var(--biscuit-heading);
}
/* The script splits the words; they start muted and scrub to orange. */
.reveal .w { display: inline-block; color: var(--biscuit-muted); }

/* Words wrapped in <mark> in the field sit on a cream bar. It is drawn full
   width here; biscuit-motion.js runs --mark-fill from 0% as the visitor
   scrolls, so it sweeps in from the left. October 20, 2026. */
.reveal mark {
	--mark-fill: 100%;
	padding: 0 .1em;
	margin: 0 -.1em;                       /* the bar runs past the words, the words stay put */
	color: inherit;
	background: linear-gradient(var(--biscuit-cream), var(--biscuit-cream)) no-repeat left center / var(--mark-fill) 100%;
}

/* ---------- What we do ----------------------------------------------------- */

/* Figma: 180px above the title and below the button, 48px title to first rule. */
.services {
	--svc-gap: clamp(16px, 3vw, 48px);
	/* The number's column. The title, topics and paragraph start one gap past
	   it. 17% was tried on October 19, 2026, with the number's padding-left
	   doubled to 14% to hold it in place, and put back to 34% the same day.
	   Jason. */
	--svc-col: 34%;
	/* One visible gap between the title, the topics and the paragraph. The
	   calc()s below take off each line's own leading so the gaps look equal. */
	--svc-v: clamp(18px, 1.67vw, 30px);
	padding: clamp(100px, 12.5vw, 220px) 0;
	background: var(--biscuit-panel);
}

.services__title {
	margin: 0 0 clamp(32px, 3.3vw, 58px);
	font-size: var(--display-xl);
	line-height: 1;
	letter-spacing: -0.02em;
}

/* The Figma rules are 5px bars. Round-ended lines from October 20, 2026, in
   the off-white this cream ground gives them (the rule tokens), where they
   were square white borders. Each row draws the line above it and the list
   the last; the padding holds the space the borders took, so the rows keep
   their height. */
.svc-list { position: relative; list-style: none; margin: 0; padding: 0 0 var(--rule-line); }
.svc-list::after { bottom: 0; }

.svc-list > li {
	position: relative; isolation: isolate;
	margin: 0; padding: var(--rule-line) 0 0;   /* style.css */
	transition: none;                      /* style.css */
}
.svc-list > li::after { top: 0; }

/* Hover, focus or open: a rounded off-white tile, as wide as the lines and
   inset from them by the tile gap. */
.svc-list > li::before {
	content: ""; position: absolute; z-index: -1;
	inset: calc(var(--rule-line) + var(--rule-tile-gap)) 0 var(--rule-tile-gap);
	border-radius: var(--rule-radius);
	background: var(--biscuit-off-white);
	opacity: 0;
	transition: opacity .5s ease;
}
.svc-list > li:hover::before,
.svc-list > li:focus-within::before,
.svc-list > li.is-open::before { opacity: 1; }

/* Keyboard focus rings the tile rather than the button, so the ring has the
   tile's corners. Where :has() is missing the button keeps its own ring. */
@supports selector(:has(*)) {
	.svc-list > li:has(.svc:focus-visible)::before { outline: 2px solid var(--biscuit-accent); outline-offset: -2px; }
	.svc-list .svc:focus-visible { outline: none; }
}

/* style.css and Bootstrap both style h3; this one only wraps the button. */
.svc__head { margin: 0; font: inherit; color: inherit; text-transform: none; }

.svc {
	display: grid;
	grid-template-columns: var(--svc-col) minmax(0, 1fr);
	align-items: start;
	gap: 0 var(--svc-gap);
	width: 100%;
	/* Figma: 64px above the title, 60 to 87px below the last line. */
	padding: clamp(36px, 4.4vw, 78px) 0 clamp(34px, 4.2vw, 74px);
	border: 0; background: none; border-radius: 0;
	font: inherit; text-align: left; letter-spacing: inherit;
	color: var(--biscuit-heading);
	transition: padding-bottom .8s var(--ease);
}
button.svc { cursor: pointer; }
/* Open: pull the paragraph up under the topics by the same gap as above them. */
.svc-list > li.is-open .svc { padding-bottom: calc(var(--svc-v) - 12px); }
.svc:hover { color: var(--biscuit-heading); }
.svc:focus-visible { outline: 2px solid var(--biscuit-accent); outline-offset: -2px; }

/* The right side steps in by the gap, as both sides do on one column, so a
   long topics line stops short of the hover tile's edge. On this column
   rather than the row, so the 34% number column and the title do not move.
   Jason, October 20, 2026. */
.svc__body { display: block; min-width: 0; padding-right: var(--svc-gap); }

/* The plus, on the one-column layout only (820px and under), so a row
   reads as something to open on a phone, where there is no hover and no
   cursor. Placed and sized in that media query below. Above it there is no
   plus: it was taken off October 9, 2026, tried again on desktop October 19,
   2026, and taken off desktop again the same day. Jason.
   The same plus-to-minus as the FAQs. An outlined circle, no fill, light
   gray at rest so it sits back from the title, turning orange with it. The
   gray is the near-black at .3, a step darker than the rules, which
   brand.md allows as a shading of an existing color rather than a new one.
   Rows with nothing to open print no icon. */
.svc__icon {
	--svc-icon-gray: rgba(42, 42, 42, .3);
	display: none;
	position: relative;
	border-radius: 50%;
	border: 1.5px solid var(--svc-icon-gray);
	transition: border-color .4s ease;
}
.svc__icon::before,
.svc__icon::after {
	content: "";
	position: absolute;
	left: 50%; top: 50%;
	width: 36%; height: 1.5px;
	transform: translate(-50%, -50%);
	background: var(--svc-icon-gray);
	transition: transform .4s var(--ease), background-color .4s ease;
}
.svc__icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.svc[aria-expanded="true"] .svc__icon::after { transform: translate(-50%, -50%) rotate(0deg); }
button.svc:hover .svc__icon,
button.svc:focus-visible .svc__icon,
.svc[aria-expanded="true"] .svc__icon { border-color: var(--biscuit-accent); }
button.svc:hover .svc__icon::before, button.svc:hover .svc__icon::after,
button.svc:focus-visible .svc__icon::before, button.svc:focus-visible .svc__icon::after,
.svc[aria-expanded="true"] .svc__icon::before, .svc[aria-expanded="true"] .svc__icon::after { background: var(--biscuit-accent); }

.svc__num {
	padding: clamp(12px, 1.4vw, 22px) 0 0 7%;     /* Figma: 90px in from the 80px margin */
	font-family: var(--font-text);
	font-size: var(--text-s);
	font-weight: var(--biscuit-weight-strong);
	letter-spacing: .12em;
	color: var(--biscuit-heading);
}

.svc__title {
	display: block;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: clamp(2rem, 4.25vw, 4.625rem);
	line-height: 1.06;
	letter-spacing: -0.005em;
	color: var(--biscuit-heading);
	transition: color .4s ease;
	/* Set this large, the space a capital carries on its left reads as an
	   indent, so the small topics and paragraph under it look further left.
	   B, D, E and M start .055em in; pulling the title back .05em lines the
	   stems up by eye. Scales with the type, so it holds at every width.
	   Jason, October 16, 2026. */
	margin-left: -0.05em;
}
button.svc:hover .svc__title,
button.svc:focus-visible .svc__title,
.svc[aria-expanded="true"] .svc__title { color: var(--biscuit-accent); }

.topics {
	display: flex; flex-wrap: wrap; gap: 6px 0;
	margin: calc(var(--svc-v) - 6px) 0 0;
	font-family: var(--font-text);
	font-size: var(--text-xs);
	font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase;
	letter-spacing: .1em;
	color: var(--biscuit-heading);
}
/* The bullet rides at the end of the topic before it, so each topic and its
   bullet wrap as one unit and no line starts with a bullet. Same idea as
   .works-item__meta. Jason, October 16, 2026. */
.topics > span:not(:last-child)::after { content: "\2022"; margin: 0 .95em; }

/* The paragraph. Grows a grid row from 0fr to 1fr, so it needs no measured
   heights, and closed means out of the tab order too. */
.svc__panel {
	display: grid; grid-template-rows: 0fr;
	visibility: hidden;
	padding-left: calc(var(--svc-col) + var(--svc-gap));
	padding-right: var(--svc-gap);         /* as the row above it */
	transition: grid-template-rows .8s var(--ease), visibility 0s linear .8s;
}
.svc-list > li.is-open .svc__panel { grid-template-rows: 1fr; visibility: visible; transition-delay: 0s; }
.svc__panel-inner { min-height: 0; overflow: hidden; }

.svc__desc {
	max-width: 37em;
	margin: 0 0 clamp(34px, 4.2vw, 74px);
	font-size: var(--text-m);
	line-height: 1.6;
	color: var(--biscuit-heading);
	opacity: 0; transform: translateY(14px);
	transition: opacity .5s ease, transform .8s var(--ease);
}
.svc-list > li.is-open .svc__desc { opacity: 1; transform: none; transition-delay: .2s; }
/* With a button under it, the paragraph's bottom space moves below the button. */
.svc__desc:has(+ .svc__more) { margin-bottom: 0; }

/* No display here: .pill is inline-flex, which is what centers its label. */
.svc__more { margin: clamp(20px, 2vw, 32px) 0 clamp(34px, 4.2vw, 74px); }
.svc__more.pill { opacity: 0; transition: opacity .5s ease; }
.svc-list > li.is-open .svc__more.pill { opacity: 1; transition-delay: .3s; }

.services__more { margin: clamp(32px, 3.3vw, 58px) 0 0; }   /* Figma: 48px under the last rule */

/* One column. The row's off-white ground runs edge to edge with the rules, so
   the type steps in from both sides, open or closed, or it would sit on the
   ground's edge. Jason, October 16, 2026. */
@media (max-width: 820px) {
	.svc { grid-template-columns: minmax(0, 1fr); padding-inline: var(--svc-gap); }
	.svc__num { grid-column: 1 / -1; padding: 0 0 18px; }
	.svc__body { grid-column: 1; padding-right: 0; }   /* the row's own inline padding steps it in here */
	/* The plus sits on the number's line, at the right, so the title keeps
	   the full width. The 18px under the number becomes the row gap, so the
	   number and the plus center on each other. The circle is as tall as the
	   number's line, 24px, so it never makes that line taller. It was 40px,
	   held in by a negative margin, until Jason, October 19, 2026. */
	button.svc { grid-template-columns: minmax(0, 1fr) auto; row-gap: 18px; align-items: center; }
	button.svc .svc__num { grid-column: 1; padding: 0; }
	button.svc .svc__body { grid-column: 1 / -1; }
	.svc__icon { display: block; grid-column: 2; grid-row: 1; width: 24px; height: 24px; }
	.svc__icon::before, .svc__icon::after { width: 42%; }
	.svc__panel { padding-inline: var(--svc-gap); }
	/* Open: the paragraph needs more room under the topics here. The rule
	   above leaves 6px at this size, which read as touching. 18px, plus the
	   paragraph's own leading. Jason, October 16, 2026. */
	.svc-list > li.is-open .svc { padding-bottom: var(--svc-v); }
}

/* ---------- Selected Works -------------------------------------------------- */

/* The heading: two words that slide in from either side. Figma: 180px above,
   48px below, at 1440. */
.sw-head {
	padding: clamp(90px, 12.5vw, 220px) 0 clamp(36px, 3.3vw, 64px);
	overflow: hidden;                      /* the words start off to the sides */
	background: var(--biscuit-page-alt);
}

.sw-head__title {
	/* Figma: a centered block 5.56 times the type size wide. */
	width: min(5.56em, 100%);
	margin: 0 auto;
	font-size: var(--display-xl);
	line-height: 1;
	letter-spacing: -0.02em;
}
.sw-head__title span { display: block; will-change: transform; }
.sw-head__title span + span { text-align: right; color: var(--biscuit-accent); }

/* The panels sit in the page's frame, as wide as What we do (.wide), one
   Image Grid gap apart: 30px, 16px on a phone. The heading's ground shows
   around them, and the gutter again under the last. Edge to edge until Jason,
   October 15, 2026. */
.sw { background: var(--biscuit-page-alt); }

/* The optional button under the panels, on the panels' left edge, in the same
   1680px frame. Above it, the list's gutter plus this padding come to three
   quarters of the first version's (gutter + 16 to 32px): 73px at 1280, 30px
   on a phone. Jason, October 16, 2026. */
.sw-more {
	max-width: 1680px;
	margin: 0 auto;
	padding: max(0px, calc(.75 * (var(--gutter) + clamp(16px, 2vw, 32px)) - var(--gutter))) var(--gutter) clamp(60px, 7vw, 120px);
}
.sw-list {
	--sw-gap: 16px;
	display: grid;
	gap: var(--sw-gap);
	max-width: 1680px;
	margin: 0 auto;
	padding: 0 var(--gutter) var(--gutter);
}
@media (min-width: 768px) {
	.sw-list { --sw-gap: 30px; }
}

/* The panels. */
.sw-item {
	position: relative;
	display: grid;
	place-items: center;
	height: 100vh;
	height: 100svh;
	min-height: 560px;
	overflow: hidden;
	isolation: isolate;
	text-decoration: none;
	color: var(--biscuit-white);
	background: var(--biscuit-near-black);    /* shows while the image loads */
}

/* The image in three layers, each owning one thing:
     .sw-media     the clip
     .sw-parallax  the scroll offset, written by GSAP
     img           the muted filter, written by CSS
   GSAP writes inline `scale: none` on anything it moves, so a CSS effect on
   the same element as the parallax would be silently cancelled. */
.sw-media {
	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
	background: var(--biscuit-near-black);
}

.sw-parallax {
	position: absolute;
	left: 0; right: 0;
	top: -12%;
	height: 124%;                /* 12% of slack top and bottom for the travel */
	will-change: transform;
}

.sw-parallax img {
	display: block;
	width: 100%;
	height: 100%;                /* style.css sets img height auto */
	max-width: none;
	object-fit: cover;
	/* The muted look: saturation and brightness down, a touch of contrast back. */
	filter: saturate(.5) brightness(.66) contrast(1.06);
	transition: filter .9s var(--ease);
}

/* A soft dark wash where the type sits, so white text holds on bright photos
   without darkening the whole frame. Black at low alpha, a shade not a color. */
.sw-media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		radial-gradient(ellipse 60% 45% at 50% 50%, rgba(0, 0, 0, .34), rgba(0, 0, 0, 0) 72%),
		rgba(0, 0, 0, .18);
	pointer-events: none;
}

/* No hover effect at all: the "View" cursor is the only signal. Jason,
   October 10, 2026. The color lift the prototype had is gone. */

/* The panel is an <a>, and the generic a:hover and a:focus rules would turn
   the type orange. Hold it white. */
.sw-item:hover,
.sw-item:focus,
.sw-item:active { color: var(--biscuit-white); text-decoration: none; }
.sw-item:focus-visible { outline: 3px solid var(--biscuit-accent); outline-offset: -3px; }

/* The type over the image. GSAP writes y here for the text parallax. */
.sw-text {
	position: relative;
	text-align: center;
	padding: 0 20px;
	will-change: transform;
}

/* Each line sits in a mask so it can rise into place on first view. The box
   hugs its text, which the morph in step 4 needs to scale from the right point. */
.sw-line {
	display: block;
	width: fit-content;
	margin-left: auto; margin-right: auto;
	overflow: hidden;
	padding-bottom: .08em;
}
.sw-line > span { display: inline-block; }

.sw-cat {
	margin: 0 auto;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: clamp(3rem, 7.4vw, 7rem);
	line-height: .9;
}

.sw-client {
	margin-top: .45em;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: clamp(1.5rem, 3.1vw, 2.75rem);
	line-height: 1.1;
	letter-spacing: -0.02em;
}

.sw-services {
	margin: 14px auto 0;
	font-family: var(--font-text);
	font-size: var(--text-xs);
	font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase;
	letter-spacing: .1em;
	line-height: 1.8;
}
/* Each service is one no-wrap unit, so a phone breaks the line between
   services, never inside one. The bullet rides at the end of the item before
   it, so no line starts with a bullet. */
.sw-svc { white-space: nowrap; }
.sw-services i { font-style: normal; padding: 0 .35em 0 .7em; opacity: .7; }

/* "View" in a circle, under the type: the desktop cursor's labelled circle,
   parked, for screens with no cursor to show it. Jason's pick, October 19,
   2026, so phone visitors know a panel opens. Shown wherever the cursor is
   not: no hover, a coarse pointer, or reduced motion. Desktop keeps the
   cursor as its only signal, per October 10, 2026.
   Absolute, under the services, so the type stays centered on the panel as
   it was. Three layers, so nothing contends with GSAP, which scales the
   element itself as it pops in (biscuit-motion.js):
     ::before  the faint disc, which swells once
     ::after   the ring that leaves it and fades, the footer button's pulse
   Both run once, when .is-pulsing goes on after the pop. */
.sw-view { display: none; }
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
	.sw-view {
		position: absolute;
		top: 100%; left: 0; right: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 80px; height: 80px;
		margin: clamp(24px, 4vh, 40px) auto 0;
		isolation: isolate;
		font-family: var(--font-text);
		font-size: 0.6875rem;
		font-weight: var(--biscuit-weight-strong);
		text-transform: uppercase;
		letter-spacing: var(--biscuit-label-tracking);
		color: var(--biscuit-white);
	}
	.sw-view::before,
	.sw-view::after {
		content: "";
		position: absolute;
		inset: 0;
		z-index: -1;
		border-radius: 50%;
	}
	.sw-view::before { background: rgba(252, 249, 245, .16); }   /* the .pill--on-dark circle */
	.sw-view::after { border: 2px solid rgba(252, 249, 245, .85); opacity: 0; }
	.sw-view.is-pulsing::before { animation: pulse-core 1.6s ease-in-out 1; }
	.sw-view.is-pulsing::after { animation: pulse-ring 2.4s ease-out 1; }
}

/* Landing back on a panel from its project. The id is on this wrapper, not the
   link, so arriving does not focus the link and draw its focus ring. */
.sw-panel { display: block; }
.sw-panel:target { scroll-margin-top: 0; }

/* ---------- Works List ----------------------------------------------------------
   The Work page's list of projects: the first Selected Work in the motion
   prototype (index.html and prototype.css, "WORK LIST"), turned off there
   October 8, 2026. One ruled row per project: a number, the category over the
   name with its services under it, the featured image on the right. On hover the row steps
   in, the name turns orange and the image opens. Rows rise in on first view
   (biscuit-motion.js). The name and category morph into the project page's
   heading. October 15, 2026. */

/* Round-ended cream lines (the rule tokens) from October 20, 2026, where
   they were 1px near-black at .14. The list draws the top line; each row
   draws the one under it, inside the row, so it rises in with the row. */
.works-list {
	position: relative;
	list-style: none;
	margin: 0;
	padding: var(--rule-line) 0 0;
}
.works-list::before { top: 0; }

/* On a light ground the lines are the near-black at .026, a neutral gray as
   light as the off-white (L* 97.9 against 98.1 on white), and the hover tile
   below takes the same color, so lines and tile match as What we do's do.
   A shading of the near-black, not a new color (brand.md). Translucent, so
   it stays a step darker on any light ground. A dark section keeps its own
   rule color. Not keyed to [data-nav="light"], which main.page-main carries
   on every page, dark sections included. Jason, October 20, 2026. */
.works-list { --rule-color: rgba(42, 42, 42, .026); }
[data-nav="dark"] .works-list { --rule-color: rgba(252, 249, 245, .16); }
.works-list > li { margin: 0; padding: 0; transition: none; }   /* style.css */

/* GSAP writes y and opacity on the row, so its transition names only
   padding-left (THEME-RULES.md, GSAP and CSS transitions). The name and its
   services stack on the left; the image sits on the right. */
.works-item {
	/* In from the ground's edges, so the type and the image do not sit on
	   them when it shows. */
	--wl-pad: clamp(12px, 1.6vw, 24px);
	position: relative; isolation: isolate;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: clamp(20px, 3vw, 44px);
	padding: 30px var(--wl-pad) calc(30px + var(--rule-line));
	color: var(--biscuit-heading);
	text-decoration: none;
	transition: padding-left .4s var(--ease);
}
/* The row is an <a>, and the generic a:hover and a:focus rules would color it. */
.works-item:hover,
.works-item:focus,
.works-item:active { color: var(--biscuit-heading); text-decoration: none; }
.works-item:hover,
.works-item:focus-visible { padding-left: calc(var(--wl-pad) + 14px); }
.works-item::after { bottom: 0; }

/* Hover or focus: a tile between the rules, as the What we do rows have.
   Absolute, so it takes no grid cell. Jason, October 16, 2026. Rounded and
   inset from the lines by the tile gap, and the lines' own color (the gray
   above), from October 20, 2026. It was off-white. */
.works-item::before {
	content: ""; position: absolute; z-index: -1;
	inset: var(--rule-tile-gap) 0 calc(var(--rule-line) + var(--rule-tile-gap));
	border-radius: var(--rule-radius);
	background: var(--rule-color);
	opacity: 0;
	transition: opacity .5s ease;
}
.works-item:hover::before,
.works-item:focus-visible::before { opacity: 1; }
/* Keyboard focus rings the tile, so the ring has its corners. */
.works-item:focus-visible { outline: none; }
.works-item:focus-visible::before { outline: 2px solid var(--biscuit-accent); outline-offset: -2px; }

/* The number, then the category, name and services stacked beside it. The
   number sits in the name's row, centered on it, with the category above and
   the services below. A narrow column, not the 34% the What we do rows use,
   to leave the services and the image their room. Jason, October 16, 2026. */
.works-item__text {
	display: grid;
	grid-template-columns: clamp(40px, 4.5vw, 72px) minmax(0, 1fr);
	grid-template-areas: ". cat" "num title" ". meta";
	min-width: 0;
}
.works-item__num {
	grid-area: num;
	align-self: center;
	font-family: var(--font-text);
	font-size: var(--text-s);
	font-weight: var(--biscuit-weight-strong);
	letter-spacing: .12em;
	color: var(--biscuit-heading);
}
.works-item__cat   { grid-area: cat; }
.works-item__title { grid-area: title; }
.works-item__meta  { grid-area: meta; min-width: 0; }

.works-item__title {
	/* Pulled back by the space a capital carries on its left, so it lines up
	   by eye with the small type above and below, as the What we do titles do. */
	margin-left: -0.05em;
	display: block;
	width: fit-content;
	font-family: var(--font-display);
	font-weight: var(--weight-heading);
	font-size: clamp(1.5rem, 3.4vw, 2.625rem);
	line-height: 1.1;
	letter-spacing: -0.02em;
	transition: color .3s ease;
}
.works-item:hover .works-item__title,
.works-item:focus-visible .works-item__title { color: var(--biscuit-accent); }

/* Under the name, set like the services on a panel and on the project page.
   Each service is one no-wrap unit, so a long list breaks between services,
   never inside one. The bullet rides at the end of the item before it, so no
   line starts with one. */
.works-item__meta {
	display: block;
	margin-top: 10px;
	font-family: var(--font-text);
	font-size: var(--text-xs);
	font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase;
	letter-spacing: .1em;
	line-height: 1.8;
	color: var(--biscuit-muted);
}
/* An inline box rather than nowrap: it still moves to the next line whole,
   but one service wider than the line, Conference & Tradeshow Graphics on a
   phone beside the number, wraps inside itself instead of running off the
   edge. October 16, 2026. */
.works-item__svc { display: inline-block; max-width: 100%; }
.works-item__meta i { font-style: normal; padding: 0 .35em 0 .7em; }
/* Over the name, set as the project page's label (.project-head__cat), so the
   morph carries it to the same place. A box that hugs the text, so the morph
   scales from the right point. */
.works-item__cat {
	display: block;
	width: fit-content;
	margin: 0 0 10px;
	font-weight: var(--biscuit-weight-strong);
}

/* The image, closed until the row is hovered or focused, then opening from
   the top while it settles from 115% to 102%. After catalinvintila.design/work,
   Jason, October 15, 2026. On a screen that cannot hover it is simply open.
   Not on a phone, where the row is one column. */
.works-item__thumb {
	display: block;
	width: clamp(180px, 20vw, 280px);
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background: var(--biscuit-panel);
	clip-path: inset(0 0 100% 0);
	transition: clip-path .6s var(--ease);
}
.works-item__thumb img {
	display: block;
	width: 100%;
	height: 100%;                /* style.css sets img height auto */
	max-width: none;
	object-fit: cover;
	transform: scale(1.15);
	transition: transform 1s var(--ease);   /* style.css sets all on img */
	/* Its own layer from the start. Without it the browser lifts the image onto
	   a layer when the first hover starts and drops it when the scale ends,
	   redrawing it both times, which showed as a flicker just after it filled
	   in. Not seen here; Jason saw it, first hover only. October 16, 2026. */
	will-change: transform;
}
.works-item:hover .works-item__thumb,
.works-item:focus-visible .works-item__thumb { clip-path: inset(0 0 0 0); }
.works-item:hover .works-item__thumb img,
.works-item:focus-visible .works-item__thumb img { transform: scale(1.02); }

@media (hover: none) {
	.works-item__thumb { clip-path: none; }
	.works-item__thumb img { transform: none; }
}

@media (max-width: 767px) {
	.works-item { grid-template-columns: minmax(0, 1fr); padding-block: 22px calc(22px + var(--rule-line)); }
	.works-item__thumb { display: none; }
}

/* Arriving back from a project on its row (wl-{slug}): the row lands a third
   of the way down the screen, clear of the header. */
.works-list > li:target { scroll-margin-top: 33vh; }

/* ---------- Project page: the heading the panel morphs into ---------------------
   Step 4 built a full-bleed hero here. Jason, October 12, 2026: no large image,
   a plain white page like the live site's project pages. The panel's category
   and name still morph into the label and the h1 below. */

.project-head {
	padding-top: clamp(130px, 13vw, 210px);
	padding-bottom: clamp(36px, 4vw, 64px);
}

/* The big centered word on the panel arrives here as a small label. The box
   hugs the text, so the morph scales from the right point. */
.project-head__cat {
	width: fit-content;
	margin: 0 0 18px;
	font-weight: var(--biscuit-weight-strong);
	color: var(--biscuit-muted);
}

.project-head__title {
	width: fit-content;
	max-width: 100%;
	margin: 0;
	font-size: var(--h1);
	line-height: 1;
	letter-spacing: -0.025em;
	text-wrap: balance;
	/* Pulled back by the space a capital carries on its left, so it lines up
	   by eye with the label above and the services below, as the What we do
	   and Works List names do. Jason, October 16, 2026. */
	margin-left: -0.05em;
}

.project-head__services {
	margin: 22px 0 0;
	font-family: var(--font-text);
	font-size: var(--text-xs);
	font-weight: var(--biscuit-weight-strong);
	text-transform: uppercase;
	letter-spacing: .1em;
	line-height: 1.8;
	color: var(--biscuit-muted);
}
.project-head__services i { font-style: normal; padding: 0 .35em 0 .7em; }

/* The way back, and the two gates. */
.project-back { padding: clamp(60px, 8vw, 120px) 0; background: var(--biscuit-page); }
.project-gate { padding: clamp(60px, 8vw, 120px) 0; }

/* ---------- The morph ---------------------------------------------------------
   Cross-document view transitions, turned on for every front-end page by an
   inline @view-transition rule from functions.php (the home page and project
   pages only until October 14, 2026). Pure CSS: matching names on both pages,
   and the browser does the rest. Browsers without it, Firefox today, and
   anyone asking for reduced motion, load the page normally.

   Between any two pages, October 14, 2026, at Jason's request, after
   Baunfire's: the old page fades out to the page ground, then the new one
   fades in and rises a little. One after the other, never both at once: two
   moving snapshots double up wherever they overlap. The ground is painted
   on the transition's own layer, so the live page cannot show through the
   gap. The header holds still over all of it (view-transition-name:
   site-header). */
::view-transition { background: var(--biscuit-page); }
::view-transition-old(root) { animation: vt-out .28s ease-in both; }
::view-transition-new(root) { animation: vt-in .5s var(--ease) .28s both; }
@keyframes vt-out { to   { opacity: 0; } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(24px); } }

/* The panel's image has no partner on the plain project page, so it is not
   named and goes with the page, fading out with the rest of it. The image
   morph and its handoff rules went October 12, 2026, in step 5. */

/* The name moves from the panel to the heading. */
::view-transition-group(*.sw-client),
::view-transition-group(*.sw-cat) {
	animation-duration: .9s;
	animation-timing-function: var(--ease-io);
}

/* The big category shrinks to a label: crossfade the two sizes quickly, so the
   change happens inside the move rather than as a jump at the end. */
::view-transition-old(*.sw-cat) { animation: sw-fade-out .35s ease both; }
::view-transition-new(*.sw-cat) { animation: sw-fade-in .5s ease .3s both; }
@keyframes sw-fade-out { to   { opacity: 0; } }
@keyframes sw-fade-in  { from { opacity: 0; } }

/* ---------- Reduced motion: every section lands on its end state ------------ */

@media (prefers-reduced-motion: reduce) {
	.hero__title .mask-line > span { animation: none; transform: none; }
	.hero__blurb, .hero__cta { animation: none; opacity: 1; }
	.reveal .w { color: var(--biscuit-accent); }
	.svc, .svc__title, .svc-list > li::before, .svc__panel, .svc__desc, .svc__more.pill,
	.svc__icon, .svc__icon::before, .svc__icon::after { transition: none; }
	.sw-parallax img { transition: none; }
	.works-item, .works-item::before, .works-item__title, .works-item__thumb, .works-item__thumb img { transition: none; }
}
