/**
 * Vanshap Capital — components and sections.
 *
 * Class prefix is vc-. Every value resolves to a token from tokens.css.
 *
 * Loaded on the front end AND as an editor stylesheet, so a section looks the
 * same in the editor as it does on the page. Keep it free of anything keyed to
 * GeneratePress's wrappers or to `body` — that belongs in chrome.css.
 */

/* ════ Shared primitives ═══════════════════════════════════════════════ */

.vc-wrap {
	max-width: var(--wrap);
	margin-inline: auto;
}

/* A narrower measure for a page that is mostly a form or a single column of
   prose. The 1140px body measure is right for grids and wrong for a stack of
   inputs: at full width a two-column form row puts a 40-character label above
   500px of empty field, which reads as an admin screen rather than a designed
   page. */
.vc-wrap--narrow {
	max-width: 46rem;
}

.vc-section {
	padding: var(--section-y) var(--gutter-page);
	scroll-margin-top: var(--nav-height);
}

/* The design gives each section its own top and bottom padding. */
.vc-section--about {
	padding-bottom: var(--section-y-sm);
}

.vc-section--thoughts {
	padding-top: var(--section-y-sm);
}

.vc-section--panel {
	background: var(--surface-panel);
}

.vc-section--ocean {
	background: var(--surface-emphasis);
	color: var(--text-on-ocean);
}

/* ── The page header band ─────────────────────────────────────────────────

   The default header for every inner page: an Ocean field carrying the eyebrow,
   the title and the accent rule. Only the front page differs, because it opens
   with a hero instead.

   It lives here rather than in portal.css, where it was written, because it is
   no longer a portal component — the public Thoughts page, the login page and
   the registration page all use it, and none of those loads portal.css. Moved
   1 Sep 2026.

   Declared after .vc-section, whose padding it overrides at equal specificity,
   so it must stay below it in this file.

   The top padding clears the fixed nav, which the front page's sections do via
   the hero instead. Pages carrying this band also cancel the body-level nav
   offset — see the note on .vc-header-band in chrome.css — or they would be
   offset twice. */

.vc-section--portal-head {
	background: var(--surface-emphasis);
	padding-block: calc(var(--nav-height) + var(--space-8)) var(--space-7);
	padding-inline: var(--gutter-page);
}

.vc-section--portal-head .vc-section-title {
	margin-block: var(--space-4) 0;
}

/* That top margin is the gap under the eyebrow. The legal pages dropped their
   eyebrow on 17 Sep 2026, which left it as 16px of dead space above the title
   and a band taller than the design's. Keyed on the title being first rather
   than on which page it is, so it holds for any future header that opens
   straight on its title, and does nothing on the headers that keep an eyebrow. */
.vc-section--portal-head .vc-section-title:first-child {
	margin-block-start: 0;
}

/* The Sky serif line under the title. Optional — a header reads correctly
   without one. */
.vc-portal-standfirst {
	max-width: 42rem;
	margin-block: var(--space-5) 0;
	font-family: var(--font-display);
	font-size: var(--size-body-lg);
	line-height: var(--lh-subhead);
	color: var(--sky);
	text-wrap: pretty;
}

/* The tracked-caps label. The firm's typographic signature. */
.vc-eyebrow {
	font-family: var(--font-text);
	font-size: var(--size-eyebrow);
	font-weight: var(--weight-regular);
	letter-spacing: var(--track-eyebrow);
	text-transform: uppercase;
	color: var(--text-label);
	margin: 0;
}

/* The same label doing a bigger job: heading a section — a group of cards, a
   list of documents, a sidebar's contents — rather than annotating one line.
   Slightly larger is the whole difference, and it is deliberately still the
   eyebrow rather than the serif section title: that was tried on the holdings
   page on 19 Sep 2026 and read as the page's own title rather than as one band
   within it. The 10.5px labels that sit beside a date or a sector stay put. */
.vc-eyebrow--section {
	font-size: var(--size-eyebrow-lg);
}

.vc-eyebrow--sky {
	color: var(--text-label-on-ocean);
}

/* The 64×2px accent rule that sits under every section title. The gap beneath
   it is not uniform in the design: 26px here, 40px in About, 44px in Thoughts. */
.vc-rule {
	width: var(--rule-accent-w);
	height: var(--rule-accent-h);
	background: var(--rule-accent);
	border: 0;
	margin: var(--rule-gap-top) 0 var(--rule-gap-bottom);
}

.vc-section--about > .vc-wrap > .vc-rule {
	margin-bottom: 40px;
}

.vc-section--thoughts > .vc-wrap > .vc-rule {
	margin-bottom: 44px;
}

/* On Ocean the rule is a hairline in white-50%, not the Signal Blue bar. */
.vc-rule--on-ocean {
	height: 0;
	border-top: 1px solid rgba(255, 255, 255, 0.5);
	background: none;
	margin: 18px 0 0;
}

.vc-section-title {
	font-family: var(--font-display);
	font-weight: var(--weight-regular);
	font-size: var(--size-h2);
	line-height: var(--lh-display);
	color: var(--text-display);
	margin: 0;
}

.vc-on-ocean .vc-section-title,
.vc-section--ocean .vc-section-title {
	color: var(--text-on-ocean);
}

/* ── The legal document body ──────────────────────────────────────────────

   What sits under the band on the Privacy, Terms and Cookie pages. It is here
   rather than in portal.css for the same reason the band itself is: these are
   public pages and they never load portal.css.

   The typography is not new. It is .vc-company-thesis__body from portfolio.css,
   which is already this theme's answer to "a run of long-form prose" — light
   weight at the body size on the roomier line height, serif subheads in Ocean.
   Restated here rather than shared, because portfolio.css is portal-only and
   moving it would make every marketing page pay for a portal stylesheet. If a
   third long-form surface appears, promote both to one rule; two is not enough
   to justify the indirection.

   Spacing hangs off the BOTTOM of every child rather than the top of the next
   one, so the last block in a document has nothing to collapse against the
   section's own bottom padding. Headings are the exception and take a top
   margin too, because the gap above a heading belongs to the heading. */

.vc-section--legal-body {
	padding-block: var(--space-8) var(--space-9);
	padding-inline: var(--gutter-page);
	background: var(--surface-page);
}

/* No measure of its own: the document runs the full 1140px page width, flush
   with the band's title above it.

   This was briefly capped at 836px — the materials reading column, being the
   1140px measure less the sidebar and its gutter — on the reasoning that a
   reader moving between the portal and a policy page should meet one line
   length. Daniel's call, 17 Sep 2026: full width. These are reference documents
   people scan for a clause rather than read through, and the cap bought a
   comfortable measure at the cost of making an already long page longer.

   .vc-legal therefore carries only typography now. It is kept as a separate
   element from the .vc-wrap around it rather than merged into it, because it is
   the hook every rule below hangs on and .vc-wrap is used site-wide. */

.vc-legal > * {
	margin-block: 0 var(--space-4);
}

.vc-legal > :last-child {
	margin-block-end: 0;
}

.vc-legal p,
.vc-legal li {
	font-weight: var(--weight-light);
	font-size: var(--size-body);
	line-height: var(--lh-body-lg);
	color: var(--text-body);
	text-wrap: pretty;
}

.vc-legal h2,
.vc-legal h3 {
	font-family: var(--font-display);
	font-weight: var(--weight-regular);
	line-height: var(--lh-subhead);
	color: var(--text-subhead);
}

.vc-legal h2 {
	font-size: var(--size-subhead);
	margin-block-start: var(--space-7);
}

/* .vc-company-thesis__body, which the rest of this treatment is taken from,
   sizes h2 and h3 identically — correct there, where a thesis is a flat run of
   prose. It is wrong here: the Privacy Policy nests a numbered h3 sequence under
   each of its two h2 policies, and at one size the document reads as sixteen
   sibling sections instead of two policies. Stepped on both axes, size and the
   space above, because either alone is too quiet at this scale. */
.vc-legal h3 {
	font-size: var(--size-body-lg);
	margin-block-start: var(--space-6);
}

/* ...except the first, which would otherwise push a rule's worth of space
   between the band and the document's opening heading. */
.vc-legal > :first-child {
	margin-block-start: 0;
}

.vc-legal ul,
.vc-legal ol {
	padding-inline-start: var(--space-5);
}

.vc-legal li + li {
	margin-block-start: var(--space-2);
}

/* The Privacy Policy separates its US and European policies with a plain
   core/separator carrying no theme style, so it is styled by element here
   rather than by an is-style- class the editor would have to set. */
.vc-legal hr {
	width: 100%;
	height: 0;
	background: none;
	border: 0;
	border-top: var(--rule);
	margin-block: var(--space-7);
}

/* Every photograph on this site is grayscale under an Ocean wash. */
.vc-photo {
	position: relative;
	overflow: hidden;
}

.vc-photo img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: var(--photo-filter);
}

.vc-photo::after {
	content: '';
	position: absolute;
	inset: 0;
	background: var(--photo-overlay);
}

.vc-photo__caption {
	position: absolute;
	left: var(--space-5);
	bottom: var(--space-4);
	z-index: 1;
	font-weight: var(--weight-semibold);
	font-size: var(--size-meta);
	color: var(--paper);
}


/* ════ Hero ════════════════════════════════════════════════════════════ */

.vc-hero.wp-block-cover {
	min-height: 82vh;
	display: flex;
	align-items: center;
	background: var(--ocean);
}

.vc-hero .wp-block-cover__image-background {
	filter: var(--photo-filter);
}

/* Two stacked washes, exactly as the design specifies: a flat Ocean tint, then
   a navy gradient falling away to the right so the headline always has ground
   under it regardless of the photograph. */
.wp-block-cover.vc-hero .wp-block-cover__background.has-background-dim.has-background-dim-0 {
	background: var(--hero-wash);
	/* The cover block is set to dimRatio 0 because the wash is these two
	   gradients, not core's flat overlay colour. Core styles that state at
	   0,4,0 specificity (.wp-block-cover .wp-block-cover__background
	   .has-background-dim.has-background-dim-0 { opacity: 0 }), so the
	   selector above has to carry one class more to win. */
	opacity: 1;
}

/* The two corner brackets. */
.vc-hero::before,
.vc-hero::after {
	content: '';
	position: absolute;
	z-index: 2;
	width: 30px;
	height: 30px;
	pointer-events: none;
}

.vc-hero::before {
	top: 100px;
	left: 36px;
	border-top: 2px solid var(--hero-bracket);
	border-left: 2px solid var(--hero-bracket);
}

.vc-hero::after {
	bottom: 36px;
	right: 36px;
	border-bottom: 2px solid var(--hero-bracket);
	border-right: 2px solid var(--hero-bracket);
}

.vc-hero .wp-block-cover__inner-container {
	width: 100%;
}

.vc-hero__inner {
	max-width: var(--wrap-nav);
	margin-inline: auto;
	padding: 120px var(--gutter-page);
	box-sizing: border-box;
}

/* ⚠️ No non-breaking spaces in here, and putting one back is the obvious
   "improvement" to resist. The headline read `Customer&nbsp;Fanatics` until
   20 Sep 2026, which glued the phrase into one unbreakable token — and on a
   390px phone, at the 44px floor of --size-hero's clamp, that token measures
   345px against 342px of available width. Three pixels over.
 *
 * Over is what matters, not by how much. GeneratePress sets
   `overflow-wrap: break-word` globally, so a token that cannot fit is broken
   MID-WORD rather than allowed to overflow, and the headline rendered
   "Customer Fanatic" with a lone "s" on the line below it. Reported from an
   iPhone and reproduced at 390px before anything was changed.
 *
 * Broken at the space instead, the longest single word here is 176px — barely
   half the measure — so nothing can split at any phone width and the hero
   needs no type step-down. That headroom is why this is fixed in the copy
   rather than in the clamp. */
.vc-hero__title {
	font-size: var(--size-hero);
	line-height: var(--lh-hero);
	color: var(--paper);
	max-width: 820px;
	margin: 0;
}

.vc-hero__title em {
	color: var(--sky);
	font-style: italic;
}

.vc-hero .vc-rule {
	margin: var(--space-6) 0;
}

.vc-hero__standfirst {
	font-size: var(--size-body-lg);
	line-height: var(--lh-body);
	color: var(--text-on-ocean-soft);
	max-width: 600px;
	margin: 0;
}

@media (max-width: 600px) {
	.vc-hero__inner {
		padding-block: 96px;
	}

	.vc-hero::before {
		top: 88px;
		left: 20px;
	}

	.vc-hero::after {
		bottom: 20px;
		right: 20px;
	}
}


/* ════ Separator styles ════════════════════════════════════════════════ */

/* Core's separator ships centred with a width; both Vanshap rules are
   left-aligned and their own size. */
.wp-block-separator.vc-rule,
.wp-block-separator.vc-thoughts__topline,
.wp-block-separator.vc-bio__rule {
	margin-inline: 0;
	opacity: 1;
}

.wp-block-separator.is-style-vanshap-accent {
	width: var(--rule-accent-w);
	height: var(--rule-accent-h);
	background: var(--rule-accent);
	border: 0;
}

.wp-block-separator.is-style-vanshap-hairline {
	width: 100%;
	height: 0;
	background: none;
	border: 0;
	border-top: var(--rule);
}

.vc-thoughts__topline.is-style-vanshap-accent {
	width: 100%;
	height: 0;
	background: none;
	border-top: 1px solid var(--signal-blue);
	margin: var(--space-3) 0 0;
}

/* The deck draws this short and Sky — a lighter sibling of the 64×2px accent
   rule under a section title — where the theme's hairline style is full-width
   Mist.

   Overridden here rather than by changing the pattern, and that is the whole
   point: a pattern's markup is frozen into post_content when it is inserted, so
   editing patterns/home-about.php would leave the live page exactly as it is.
   CSS reaches the page that already exists and any future insertion alike.

   The selector carries .wp-block-separator to match the specificity of
   .is-style-vanshap-hairline above, which the frozen markup still names; equal
   specificity, so it wins on source order and must stay below it. */
.wp-block-separator.vc-bio__rule {
	width: var(--rule-accent-w);
	height: 0;
	background: none;
	border: 0;
	border-top: var(--rule-sky);
	margin: var(--space-3) 0 14px;
}


/* ════ Section title block ═════════════════════════════════════════════ */

/* No measure cap: the standfirst runs the full width of .vc-wrap, so it lines
   up with the title above it and the card row below rather than stopping short
   of both. That is a deliberate departure from the design export's 860px, and
   it does buy a long line — roughly 95 characters at 23px on a 1140px wrap. */
.vc-lede {
	font-family: var(--font-display);
	font-size: var(--size-lede);
	line-height: var(--lh-subhead);
	color: var(--text-subhead);
	margin: 0 0 56px;
}

.vc-body-lg {
	font-size: var(--size-body-lg);
	line-height: var(--lh-body-lg);
	margin: var(--space-5) 0 0;
}

.vc-on-ocean .vc-body-lg {
	color: rgba(255, 255, 255, 0.9);
	max-width: 600px;
}

/* A general-purpose editor class, so anything from a placeholder note to a caveat
   on a performance claim lands here. --text-label for the same reason the footer
   disclosure uses it. */
.vc-footnote {
	font-size: var(--size-footnote);
	line-height: 1.5;
	color: var(--text-label);
	margin-top: 36px;
}


/* ════ What we look for — the four cards ═══════════════════════════════ */

/* No column gap, deliberately — see --card-panel-* in tokens.css. The cells
   abut so their top rules join into one line across the row; what separates the
   Panel boxes is their inset within each cell, not a gap between cells. The row
   gap only matters once the row wraps to two. */
.vc-cards {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax(230px, 1fr) );
	column-gap: 0;
	row-gap: var(--space-6);
}

/* Evaluation variant — two across at full width instead of four. See
   patterns/compare-2up-what-we-look-for.php, which is an artefact for comparing
   the two layouts and is not part of the site.

   Above the media queries deliberately: it ties with .vc-cards at 0,1,0, so the
   983px and 600px rules below only win by coming later in the file. Move it
   under them and the variant would stay two across on a phone. */
.vc-cards--2up {
	grid-template-columns: repeat( 2, 1fr );
}

/* Skip the three-across step. Left to itself auto-fit fits a third track as
   soon as the measure allows, which for a set of exactly four means a row of
   three and one orphan — always awkward, and much louder now that each row
   carries its own top rule. Two-by-two instead, until it stacks.

   983px is where four tracks stop fitting: 4 × 230 minimum + 2 × 32 gutter =
   984. If either of those numbers changes, this one has to change with them. */
@media (max-width: 983px) {
	.vc-cards {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media (max-width: 600px) {
	.vc-cards {
		grid-template-columns: 1fr;
	}
}

/* The Panel box is painted as a background image rather than sitting in a
   wrapper element, because a wrapper would mean new markup in the pattern —
   and therefore re-rendering the frozen section into every page that carries
   it — for something that is purely decorative. The gradient is a flat fill;
   size and position inset it from the cell on three sides.

   Percentages here resolve against the padding box, which the 1px top border
   has already inset by a pixel. That is small enough not to matter, and
   background-origin is left alone rather than corrected, so the fill can never
   ride up over the rule. */
.vc-card {
	position: relative;
	background: linear-gradient( var(--surface-panel), var(--surface-panel) ) no-repeat;
	background-size:
		calc( 100% - var(--card-panel-left) - var(--card-panel-right) )
		calc( 100% - var(--card-panel-top) );
	background-position: var(--card-panel-left) bottom;
	border-top: var(--rule-sky);
	padding:
		calc( var(--card-panel-top) + var(--space-6) )
		calc( var(--card-panel-right) + 28px )
		36px
		calc( var(--card-panel-left) + 28px );
}

/* The left vertical. Partial, like the deck's — it drops from the top rule and
   stops around halfway, rather than boxing the card in.

   top:-1px for the reason the bio bracket needs left:-1px: an absolutely
   positioned box is placed against the PADDING box, which the top border has
   already inset, so at 0 the vertical starts a pixel below the rule and leaves
   a notch at the corner where they should meet. */
.vc-card::before {
	content: '';
	position: absolute;
	top: -1px;
	left: 0;
	height: var(--card-bracket);
	border-left: var(--rule-sky);
	pointer-events: none;
}

.vc-card__number {
	font-family: var(--font-display);
	font-size: 28px;
	color: var(--ocean);
	border-bottom: 1px solid var(--sky);
	padding-bottom: 14px;
	margin: 0;
}

.vc-card__title {
	font-family: var(--font-text);
	font-weight: var(--weight-semibold);
	font-size: 17px;
	color: var(--text-display);
	margin: 14px 0 10px;
}

.vc-card__body {
	font-size: var(--size-body);
	line-height: var(--lh-body);
	color: var(--text-body);
	margin: 0;
}


/* ════ How we invest — the asymmetric split ════════════════════════════ */

.vc-split {
	display: grid;
	grid-template-columns: minmax(340px, 1.7fr) minmax(300px, 1fr);
	align-items: stretch;
	scroll-margin-top: var(--nav-height);
}

/* The left padding aligns the text to the 1140px measure while the photograph
   bleeds off the right edge. */
.vc-split__text {
	padding: var(--section-y-lg) var(--space-8) var(--section-y-lg)
		max( var(--gutter-page), calc( ( 100vw - var(--wrap) ) / 2 ) );
	box-sizing: border-box;
}

.vc-split__text .vc-section-title {
	font-size: var(--size-h2-split);
	line-height: 1.25;
	max-width: 640px;
	margin: var(--space-5) 0 0;
}

/* "Focused portfolio" opts out of that and takes the Paper section's title
   block instead — full-size title, 64×2 accent rule beneath it, serif lede —
   rendered white rather than in Navy, Signal Blue and Ocean. The trio is the
   same set of classes the Paper sections use (.vc-section-title, the accent
   separator style, .vc-lede); only the three colours and the split's own
   geometry are restated here.

   Ties with the rule above at 0,2,0 and wins by following it, the same way
   .vc-split--reverse wins over .vc-split. Keep it below. */
.vc-split__text .vc-section-title--full {
	font-size: var(--size-h2);
	line-height: var(--lh-display);
	max-width: none;
	margin: 0;
}

/* The accent rule is Signal Blue on Paper; over Ocean that reads as a bruise,
   so it goes white. Scoped to the split rather than to .vc-on-ocean because
   the portal header bands are Ocean too and keep the blue bar. */
.vc-split__text .wp-block-separator.is-style-vanshap-accent {
	background: var(--text-on-ocean);
}

/* .vc-lede carries its own 56px bottom margin because on Paper it is followed
   by cards. Here it is the last thing in the panel, and that margin would sit
   on top of the panel's 110px bottom padding and throw the panel off centre. */
.vc-split__text .vc-lede {
	color: var(--text-on-ocean);
	margin-bottom: 0;
}

.vc-split__media {
	position: relative;
	min-height: 360px;
}

/* Contact is this same split flipped: photograph left, text right, so the two
   Ocean sections lean opposite ways and bracket the page between them. The
   media panel is first in the DOM as well as first on screen — no CSS `order`,
   so reading order and visual order cannot drift apart.

   Placed ABOVE the stacking media query on purpose. It matches .vc-split at
   0,1,0, so the 1fr in that query only wins by coming later in the file. */
.vc-split--reverse {
	grid-template-columns: minmax(300px, 1fr) minmax(340px, 1.7fr);
}

/* The mirror of .vc-split__text: the measure-aligning value moves to the right
   edge, and the photograph bleeds off the left instead of the right. */
.vc-split--reverse .vc-split__text {
	padding: var(--section-y-lg)
		max( var(--gutter-page), calc( ( 100vw - var(--wrap) ) / 2 ) )
		var(--section-y-lg) var(--space-8);
}

/* The two tracks have 340px + 300px of minimum between them, so the design
   keeps this side by side well below tablet. Stack only once it truly cannot
   fit — stacking at 900px collapsed it several hundred px too early. */
@media (max-width: 640px) {
	.vc-split {
		grid-template-columns: 1fr;
	}

	/* The reversed selector has to be named again here. It is 0,2,0 against
	   this rule's 0,1,0, so without it the flipped section would keep its
	   half-a-viewport right padding all the way down to a phone. */
	.vc-split__text,
	.vc-split--reverse .vc-split__text {
		padding: var(--section-y) var(--gutter-page);
	}

	.vc-split__media {
		min-height: 320px;
	}
}


/* ════ Photographs ═════════════════════════════════════════════════════ */

/* core/image nests the <img> in a <figure>; both need to fill the frame. */
.vc-photo .wp-block-image {
	margin: 0;
	position: absolute;
	inset: 0;
}

.vc-photo .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: var(--photo-filter);
	display: block;
}

.vc-photo::after {
	pointer-events: none;
}


/* ════ About ═══════════════════════════════════════════════════════════ */

.vc-about__intro {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax(320px, 1fr) );
	gap: var(--space-7);
	margin-bottom: 72px;
}

.vc-about__evolution-body {
	font-size: 17px;
	line-height: var(--lh-body-lg);
	color: var(--text-subhead);
	margin: 18px 0 0;
}

.vc-about__quote {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
}

.vc-pullquote {
	font-family: var(--font-display);
	font-size: var(--size-subhead);
	line-height: var(--lh-subhead);
	color: var(--text-subhead);
	border-top: var(--rule);
	padding-top: var(--space-5);
	margin: 0;
}

.vc-tiles {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax(260px, 1fr) );
	gap: var(--space-5);
	margin: 20px 0 80px;
}

.vc-tile {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
}

.vc-team {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax(300px, 1fr) );
	gap: 40px;
	margin-top: var(--space-5);
}

/* The deck's bracket, not a closed box: one full left edge, and two horizontals
   that run part of the way across and stop. The right padding stays even though
   there is no right edge to inset from — it is what keeps a long credential
   line from running into the next column of the grid. */
.vc-bio {
	position: relative;
	border-left: var(--rule-sky);
	padding: var(--pad-bio);
}

/* A border is all-or-nothing along an edge, so both part-length horizontals are
   drawn as pseudo elements instead.

   left:-1px, not 0: an absolutely positioned box is placed against its
   containing block's PADDING box, which the 1px left border has already inset.
   At 0 each line would start one pixel inboard and leave a visible notch at the
   corner where it is meant to meet the left edge.

   The bottom one is border-TOP at bottom:0, not border-bottom. With no bottom
   border on .vc-bio the padding box now ends where the border box does, so a
   1px-tall box sitting on bottom:0 paints exactly where the old border-bottom
   did — flush with the foot of the left edge. bottom:-1px would drop it a pixel
   past the end of that edge and reopen the notch at the other corner. */
.vc-bio::before,
.vc-bio::after {
	content: '';
	position: absolute;
	left: -1px;
	border-top: var(--rule-sky);
	pointer-events: none;
}

.vc-bio::before {
	top: 0;
	width: var(--bio-top);
}

.vc-bio::after {
	bottom: 0;
	width: var(--bio-bottom);
}

.vc-bio__name {
	font-family: var(--font-text);
	font-weight: var(--weight-semibold);
	font-size: 18px;
	color: var(--text-display);
	margin: 0;
}

.vc-bio__role {
	font-weight: var(--weight-regular);
	font-size: var(--size-eyebrow);
	letter-spacing: var(--track-eyebrow);
	text-transform: uppercase;
	color: var(--text-label);
	margin: var(--space-2) 0 0;
}

.vc-bio__body {
	font-size: var(--size-body-sm);
	line-height: var(--lh-body);
	color: var(--text-body);
	margin: 0;
}


/* ════ Thoughts ════════════════════════════════════════════════════════ */

.vc-thoughts {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax(320px, 1fr) );
	gap: var(--space-8);
}

.vc-entry {
	border-bottom: var(--rule);
	padding: 22px 0;
}

.vc-entry__date {
	font-weight: var(--weight-regular);
	font-size: var(--size-eyebrow);
	letter-spacing: var(--track-eyebrow);
	text-transform: uppercase;
	color: var(--text-label);
	margin: 0;
}

.vc-entry__title {
	font-family: var(--font-display);
	font-size: var(--size-subhead);
	margin: 10px 0 8px;
}

.vc-entry__title a {
	color: var(--text-display);
}

.vc-entry__title a:hover,
.vc-entry__title a:focus-visible {
	color: var(--ocean);
}

.vc-entry__note {
	font-family: var(--font-display);
	font-style: italic;
	font-size: var(--size-body);
	color: var(--text-subhead);
	margin: 0;
}

.vc-entry__meta {
	font-size: var(--size-meta);
	color: var(--text-muted);
	margin: 0;
}


/* ════ Latest thoughts — the home page boxes ═══════════════════════════

   Three boxes on a Panel ground: the two most recent public items and the
   archive. Deliberately typographic, with no thumbnails — the section this
   replaced was a dated list, .vc-card next door is a filled box with no image,
   and mixing one poster into a row of three would leave two boxes looking
   unfinished rather than one looking rich.

   auto-FILL, not auto-fit, for the reason .vc-company-grid gives at length: the
   two behave identically once the row is full and differently when it is not.
   With one public item there are two boxes, and auto-fit would stretch them
   across the whole measure — a thin news week rendered as a banner. auto-fill
   keeps the third track empty, which is the honest shape.

   18rem is chosen against the 1140px measure: three tracks fit, four do not, so
   the row is three across at full width, two at tablet and one on a phone with
   no media query of its own.                                                */

.vc-latest {
	display: grid;
	grid-template-columns: repeat( auto-fill, minmax(18rem, 1fr) );
	gap: 20px;
}

/* Paper on Panel. .vc-card fills with Panel because it sits on Paper; this
   section is the inverse, so the box takes the other surface. */
.vc-latest__box {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--surface-page);
	padding: 28px 28px 26px;
	transition: background 0.2s ease;
}

.vc-latest__box:hover,
.vc-latest__box:focus-within {
	background: var(--mist);
}

.vc-latest__kind {
	border-bottom: 1px solid var(--sky);
	padding-bottom: 14px;
}

.vc-latest__title {
	font-family: var(--font-display);
	font-weight: var(--weight-regular);
	font-size: var(--size-subhead);
	line-height: var(--lh-display);
	color: var(--text-display);
	margin: 16px 0 0;
	text-wrap: pretty;
}

.vc-latest__link {
	color: inherit;
	text-decoration: none;
}

/* The whole box is the target, so the hit area matches what reads as
   clickable. Text stays selectable because the overlay sits beneath it in
   paint order, not above. */
.vc-latest__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.vc-latest__link:hover,
.vc-latest__link:focus-visible {
	color: var(--ocean);
}

.vc-latest__note {
	font-family: var(--font-display);
	font-style: italic;
	font-size: var(--size-body);
	line-height: var(--lh-body);
	color: var(--text-subhead);
	margin: 12px 0 0;
	text-wrap: pretty;
}

.vc-latest__meta {
	font-weight: var(--weight-regular);
	font-size: var(--size-meta);
	color: var(--text-muted);
	margin: 10px 0 0;
}

/* The body absorbs the row's spare height so the prompt below sits on one line
   across all three boxes however unevenly the titles and quotes fall.

   Deliberately a flex child rather than `margin-block-start: auto` on the
   prompt itself: an auto margin resolves to zero in the tallest box of the row,
   which would put that box's rule hard against its last line of text while the
   others had a comfortable gap. */
.vc-latest__body {
	flex: 1 1 auto;
}

.vc-latest__cta {
	font-weight: var(--weight-regular);
	font-family: var(--font-text);
	font-size: var(--size-eyebrow);
	letter-spacing: var(--track-eyebrow);
	text-transform: uppercase;
	color: var(--ocean);
	margin: var(--space-5) 0 0;
	padding-top: 16px;
	border-top: var(--rule);
}

.vc-latest__cta::after {
	content: " \2192";
}

/* The archive box takes the same Paper fill as the other two, deliberately.
   It was tried in the section's own Panel fill first, on the reasoning that it
   leads out of the section rather than into an item — and it read as a hole in
   the row rather than as the third box, because Panel on Panel is the same
   colour and only a hairline separated them. It is a box; it looks like one.
   What sets it apart is its eyebrow, its copy and its prompt. */


/* ════ Contact ═════════════════════════════════════════════════════════ */

.vc-contact__title {
	font-size: var(--size-h2-ocean);
	line-height: 1.3;
	max-width: 760px;
	margin-top: var(--space-5);
}

.vc-contact__body {
	max-width: 720px;
	margin-top: 26px;
}

/* Paper at rest, Sky on hover — the reverse of how this was drawn until
   20 Sep 2026. Daniel wanted the address in white; the two states are swapped
   rather than the rest state simply recoloured, because white WAS the hover and
   recolouring alone would have left the link with nothing to answer a pointer
   with. Both read on Ocean, and the underline carries the link cue either way
   so the colour is never doing that job on its own. */
.vc-contact__body a {
	color: var(--paper);
	border-bottom: 1px solid var(--paper);
}

.vc-contact__body a:hover,
.vc-contact__body a:focus-visible {
	color: var(--sky);
	border-bottom-color: var(--sky);
}


/* ════ Core flow-spacing reset ═════════════════════════════════════════ */

/* Core's flow layout adds `margin-block-start` to every child after the first.
   On a grid container that margin offsets the item inside its track and the
   rows visibly stagger. Zeroed on the direct children of Vanshap grids only —
   those wrappers carry no margin in the design, and the gap is the grid's.

   Deliberately NOT applied to every descendant: a blanket reset at this
   specificity would also flatten the internal margins each component sets
   (.vc-card__title and friends), which is what the design actually specifies. */
.vc-cards > *,
.vc-tiles > *,
.vc-team > *,
.vc-thoughts > *,
.vc-latest > *,
.vc-about__intro > *,
.vc-login-grid > *,
.vc-split > * {
	margin-block: 0;
}

/* ════ Inner page top ═══════════════════════════════════════════════════ */

/* The first section of an inner page carries the page title where the front
   page carries a hero. It needs more air above it than a mid-page section,
   since the solid nav sits directly on top of it. */
.vc-section--page {
	padding-top: var(--section-y-lg);
}


/* ════ Investor login ═══════════════════════════════════════════════════ */

/* Tighter above than a mid-page section: the ocean band directly above already
   provides the separation, and the form should not sit under the fold. Matches
   the portal body, which solves the same problem. */
.vc-section--login-body {
	padding-block: var(--space-8) var(--space-9);
}

/* Two panels below the ocean band: the form on the left, the reason a stranger
   cannot simply sign up on the right. The live site puts them side by side and
   the regulatory sentence directly above the register button, so the sentence
   reads as the explanation for the button rather than as page furniture. */
.vc-login-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
	gap: var(--space-9);
	align-items: start;
}

/* This file owns the LAYOUT of the two panels. The form inside the left one is
   PMPro's markup and is skinned in assets/css/login.css, which is where the
   --pmpro--* variable block and the submit rule went on 20 Sep 2026 — a
   vendor's classes break when the vendor reshuffles them, which is a different
   failure from a design change and belongs in its own file. */

/* A hairline rather than a filled panel: the aside is secondary to the form,
   and a second ground on a page that already has the ocean band would read as
   a third element competing with it. */
.vc-login-grid__aside {
	border-left: var(--rule);
	padding-left: var(--space-8);
}

/* --size-h3, the ladder's "section headers inside a portal body" rung, which is
   exactly the role these two play. This said --size-subhead until 20 Sep 2026,
   above a comment claiming there was no h3 rung to use — there is, and at 22px
   against the 44px title in the band above them both headings read as captions
   rather than as the headers of the two halves of the page. */
.vc-login-grid__title {
	font-size: var(--size-h3);
	color: var(--vanshap-navy);
	margin: 0 0 var(--space-5);
}

/* Regular, not the site's Light body weight. This is the sentence that explains
   why a stranger cannot simply sign up, and at Light it read as faint enough to
   skip. The colour was never the problem — --ink is already the darkest body
   colour the palette has, 10:1 on Paper — so the fix is the weight, which is
   the same conclusion the --text-label note in tokens.css reaches for a
   different piece of text that had to be legible. */
.vc-login-grid__aside p {
	color: var(--ink);
	font-weight: var(--weight-regular);
	margin: 0 0 var(--space-6);
	max-width: 46ch;
}

/* Register is the secondary action — outlined, the way the live site draws
   both of its buttons and the way the nav's login control is drawn. Log In is
   left filled by PMPro (now in Ocean via the variables above), so the two read
   as primary and secondary rather than competing.
 *
 * ⚠️ The `a` and the extra ancestor are load-bearing. GeneratePress styles
 * `a.wp-block-button__link:not(.has-background)` from an inline stylesheet,
 * which is (0,2,1) and beats a plain two-class selector — padding and casing
 * applied while the background silently stayed GP's grey. The alternative,
 * giving the block a background attribute so GP's :not() excludes it, would put
 * a hex in the block markup, which tokens.css exists to prevent. */
.vc-login-grid .vc-login-cta a.wp-block-button__link {
	display: inline-block;
	background: transparent;
	color: var(--ocean);
	border: 2px solid var(--ocean);
	padding: 13px 26px;
	font-size: var(--size-nav);
	letter-spacing: var(--track-nav);
	text-transform: uppercase;
	line-height: 1.2;
	transition: background 0.2s ease, color 0.2s ease;
}

.vc-login-grid .vc-login-cta a.wp-block-button__link:hover,
.vc-login-grid .vc-login-cta a.wp-block-button__link:focus-visible {
	background: var(--ocean);
	color: var(--paper);
}

@media (max-width: 900px) {
	.vc-login-grid {
		grid-template-columns: 1fr;
		gap: var(--space-7);
	}

	/* Stacked, the rule has to move to the top edge or it hangs off the side
	   of a full-width block. */
	.vc-login-grid__aside {
		border-left: 0;
		border-top: var(--rule);
		padding-left: 0;
		padding-top: var(--space-7);
	}
}
