/**
 * Von Mortgage — UI/UX enhancement layer.
 *
 * THE ROOT FIX: the theme sets `html { font-size: 15px }` and drops it to
 * `13px` below 768px. Because the whole theme is authored in rem, that single
 * declaration shrinks *everything* on mobile by 13% — body copy renders 13px,
 * secondary CTAs 11.7px, one footer button 10.4px. It is the reason the site
 * feels cramped on a phone, and no amount of per-component patching fixes it,
 * because page-level selectors like
 * `#team .section-content .container .row .member .member-description` outrank
 * anything sane written here. Restoring the mobile root to 15px lifts the
 * entire scale at once. Measured at 375px across the homepage, FHA, blog,
 * team, refinance and quote pages: no horizontal overflow at 13, 14 or 15px.
 *
 * Loaded after /style.main.min.css, which is a compiled artifact of the legacy
 * Hugo theme and is treated as read-only. Everything here is additive: it
 * refines the existing design rather than replacing it, so removing this one
 * <link> returns the site exactly to its migrated state.
 *
 * Scope, in order of how much it matters:
 *   1. Touch targets and type sizes that fail on mobile today
 *   2. Focus visibility — the theme has none
 *   3. A button system with real hierarchy and states
 *   4. Depth and motion, applied where it clarifies rather than decorates
 *
 * The palette is the client's own: plum #411b58, deep plum #2e1040, gold
 * #c9a95a. Nothing here introduces a new brand colour.
 */

:root {
	/* The theme has no radius at all — every corner is square, which is the
	   single biggest reason it reads as dated. The nav and top bar already use
	   pills, so pills become the button language site-wide. */
	--vm-radius-btn: 999px;
	--vm-radius-card: 14px;
	--vm-radius-input: 10px;

	/* Layered shadows keyed to the brand's plum rather than neutral black, so
	   elevation feels part of the palette instead of grey haze over it. */
	--vm-shadow-sm: 0 1px 2px rgba(46, 16, 64, 0.06), 0 2px 8px rgba(46, 16, 64, 0.06);
	--vm-shadow-md: 0 2px 6px rgba(46, 16, 64, 0.08), 0 12px 28px rgba(46, 16, 64, 0.12);
	--vm-shadow-lg: 0 4px 12px rgba(46, 16, 64, 0.1), 0 24px 56px rgba(46, 16, 64, 0.18);

	--vm-ease: cubic-bezier(0.16, 1, 0.3, 1);
	--vm-dur-fast: 160ms;
	--vm-dur: 260ms;

	/* Minimum comfortable touch target. 44px is the Apple/Google guideline;
	   WCAG 2.2 AA asks only for 24px, so this clears both. */
	--vm-tap: 44px;
}

/* ------------------------------------------------------------- type scale */

/*
 * Mobile root size, restored to the desktop value. See the note at the top —
 * this is the highest-leverage change in the file, and everything in the
 * "type" section below is a top-up for the few places it doesn't reach.
 */
@media only screen and (max-width: 767.98px) {
	html {
		font-size: 15px;
	}
}

/* ------------------------------------------------------------------ focus */

/*
 * The theme actively suppresses focus rings (`outline: none` on links and
 * buttons), so keyboard users get no indication of where they are — on the
 * dark plum surfaces, none at all. `:focus-visible` keeps the ring off mouse
 * clicks while restoring it for keyboard and assistive navigation.
 *
 * NOT written with `:where()`, deliberately: `:where()` contributes zero
 * specificity, so the theme's own `outline: none` would win and this whole
 * block would silently do nothing. (It did, until this was measured.) A plain
 * selector list carries the specificity needed to override it.
 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
summary:focus-visible {
	outline: 3px solid var(--vm-gold, #c9a95a);
	outline-offset: 2px;
	border-radius: 3px;
}

/* On the dark plum and gold surfaces a gold ring disappears; go white. */
.bg-primary-dark a:focus-visible,
.bg-primary-dark button:focus-visible,
.bg-primary-darker a:focus-visible,
.bg-primary-darker button:focus-visible,
[class*="bg-yellow"] a:focus-visible,
[class*="bg-yellow"] button:focus-visible {
	outline-color: #fff;
}

/* ---------------------------------------------------------------- buttons */

/*
 * One button system, three levels of emphasis.
 *
 * The migrated pages give every call to action the same weight — the FHA hero
 * has three identical yellow buttons side by side, so nothing reads as the
 * primary action. The classes below already exist in the markup; this gives
 * them a hierarchy and, more importantly, states.
 */
.btn {
	border-radius: var(--vm-radius-btn);
	transition:
		transform var(--vm-dur-fast) var(--vm-ease),
		box-shadow var(--vm-dur) var(--vm-ease),
		background-color var(--vm-dur-fast) var(--vm-ease),
		color var(--vm-dur-fast) var(--vm-ease);
	will-change: auto;
}

/* Touch targets. The theme's buttons render 32px tall on mobile — below every
   published guideline, and noticeably fiddly on a real phone. */
@media (max-width: 991px) {
	.btn,
	button[type="submit"],
	input[type="submit"] {
		min-height: var(--vm-tap);
		padding-block: 0.7rem;
		display: inline-flex;
		align-items: center;
		justify-content: center;
	}
}

.btn:hover {
	transform: translateY(-2px);
	box-shadow: var(--vm-shadow-md);
}

/* The press should register as a press — without this the lift just drops. */
.btn:active {
	transform: translateY(0);
	box-shadow: var(--vm-shadow-sm);
	transition-duration: 60ms;
}

/*
 * Standalone calls to action inside a content widget — "Get To Know Us ➔",
 * "Click Here! ➔". These are 14–19px tall today, which is a quarter of the
 * minimum target and the hardest thing on the site to hit on a phone.
 *
 * Deliberately `> a` and scoped to #content: it catches CTAs that are direct
 * children of the widget without touching links inside a paragraph, where a
 * 44px line box would wreck the copy. The footer is excluded for the same
 * reason — "NMLS Consumer Access" sits mid-sentence.
 */
#content .html-widget > a:not(.btn) {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	min-height: var(--vm-tap);
	font-weight: 600;
	text-decoration: none;
	transition: color var(--vm-dur-fast) var(--vm-ease);
}

/* The arrow leads on hover — a small, directional cue that the link goes
   somewhere, rather than a colour change alone. */
#content .html-widget > a:not(.btn) span {
	display: inline-block;
	transition: transform var(--vm-dur) var(--vm-ease);
}

#content .html-widget > a:not(.btn):hover span {
	transform: translateX(4px);
}

/*
 * Phone links.
 *
 * For a mortgage broker a tap-to-call is the highest-value action on the site,
 * and these render 15–18px tall. Vertical padding grows the hit area on an
 * inline element without changing the line box, so a number sitting mid-
 * sentence gets an easier target without opening gaps in the copy.
 *
 * This lands them at 32–34px rather than the 44px used for buttons, and stops
 * there deliberately: these are inline links inside paragraphs, and padding
 * past roughly half the line height makes adjacent lines' hit areas overlap,
 * which causes mis-taps. 32px clears the WCAG 2.2 AA minimum (24px) with room
 * to spare; the 44px figure is a guideline for standalone controls.
 */
@media (max-width: 991px) {
	a[href^="tel:"] {
		padding-block: 0.55rem;
		font-weight: 600;
	}
}

/* ------------------------------------------------------------------- type */

/*
 * Mobile body copy sits at 13px, with one CTA at 10.4px. Both are below the
 * point where text is comfortable on a phone, and the 15px+ bump costs no
 * layout — these blocks are single-column at this width anyway.
 */
@media (max-width: 767px) {
	#content p,
	#content li {
		font-size: max(1rem, 15px);
		line-height: 1.65;
	}

	#content .html-widget > a:not(.btn) {
		font-size: 15px;
	}

	/*
	 * The last two the root fix can't reach: the team cards' "Learn More
	 * About …" links (0.9rem) and their "Send Me A Message" button (0.8rem),
	 * both set in page-level CSS that renders *after* this file — so matching
	 * their specificity would still lose on document order.
	 *
	 * The `body` prefix adds one element to the specificity and wins the tie,
	 * which is preferable to `!important`: it leaves the cascade intact, so
	 * anything the client later writes in the admin's custom-CSS box still
	 * overrides this the way they'd expect.
	 */
	body #team .section-content .container .row .member .row .member-btn a {
		font-size: 15px;
	}

	body
		#team
		.section-content
		.container
		.row
		.member
		.row
		.member-info
		.html-widget
		a.btn {
		font-size: 14px;
	}

	/* Long headlines set in Montserrat 800 get tight and cramped on a narrow
	   screen; a touch more leading and a hair less tracking reads better. */
	#content h1,
	#content h2,
	#content .h1 {
		line-height: 1.12;
		letter-spacing: -0.01em;
	}
}

/*
 * Anything under 16px in a form field makes iOS Safari zoom the viewport on
 * focus, which then leaves the page scrolled sideways.
 */
@media (max-width: 991px) {
	input:not([type="checkbox"]):not([type="radio"]),
	select,
	textarea {
		font-size: 16px;
	}
}

/* ------------------------------------------------- article reading rhythm */

/*
 * Long-form typography for blog posts — the site's most-read content, and
 * measurably uncomfortable before this:
 *
 *   line-height: normal  (~1.2)   — far too tight for sustained reading
 *   87 characters per line        — the comfortable range is 45–75
 *   15px between paragraphs       — no clear separation between thoughts
 *
 * Scoped to the article column on post pages, so marketing pages, which are
 * short-form and designed around their own rhythm, are untouched.
 */
body[class*="page-blogs-slash"] .section-right :is(p, li) {
	line-height: 1.7;
}

body[class*="page-blogs-slash"] .section-right p {
	margin-bottom: 1.35em;
	/* ~68 characters at this size. `ch` tracks the font, so the measure holds
	   if the type scale ever changes. The column itself keeps its width — only
	   the text line is capped — so images and embeds stay full width. */
	max-width: 68ch;
}

/* Headings need room above them and a tighter bond to the text they
   introduce, otherwise a run of sections reads as one undifferentiated block. */
body[class*="page-blogs-slash"] .section-right :is(h2, h3, h4) {
	margin-top: 2.2em;
	margin-bottom: 0.6em;
	line-height: 1.25;
}

body[class*="page-blogs-slash"] .section-right :is(h2, h3, h4):first-child {
	margin-top: 0;
}

/* Links inside the article should be visibly links — the theme leaves them
   the same weight as body text, so they're easy to miss mid-paragraph. */
body[class*="page-blogs-slash"] .section-right p a {
	color: var(--vm-plum, #411b58);
	text-decoration: underline;
	text-underline-offset: 0.18em;
	text-decoration-thickness: 0.07em;
	transition: color var(--vm-dur-fast) var(--vm-ease);
}

body[class*="page-blogs-slash"] .section-right p a:hover {
	color: var(--vm-plum-deep, #2e1040);
	text-decoration-thickness: 0.14em;
}

/* ------------------------------------------------------------------ forms */

input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
	border-radius: var(--vm-radius-input);
	transition:
		border-color var(--vm-dur-fast) var(--vm-ease),
		box-shadow var(--vm-dur-fast) var(--vm-ease);
}

/* A focused field should be obvious without relying on the outline alone. */
input:not([type="checkbox"]):not([type="radio"]):focus,
select:focus,
textarea:focus {
	border-color: var(--vm-plum, #411b58);
	box-shadow: 0 0 0 4px rgba(65, 27, 88, 0.12);
}

/* ------------------------------------------------------------------ depth */

/*
 * The blog cards are the site's most repeated component and sit completely
 * flat. Lifting the image on hover — rather than the whole card — keeps the
 * text still and readable while making the target feel live.
 */
.blog__item img {
	border-radius: var(--vm-radius-card);
	transition:
		transform var(--vm-dur) var(--vm-ease),
		box-shadow var(--vm-dur) var(--vm-ease),
		opacity var(--vm-dur) var(--vm-ease);
}

.blog__item:hover img,
.blog__item:focus-visible img {
	transform: translateY(-4px) scale(1.015);
	box-shadow: var(--vm-shadow-md);
}

.blog__item h3 {
	transition: color var(--vm-dur-fast) var(--vm-ease);
}

/* The sidebar promo and the footer's licence badge both read as loose
   fragments; a radius ties them to the card language. */
.vertical-ad img,
.horizontal-ad img {
	border-radius: var(--vm-radius-card);
}

/* -------------------------------------------------------------- image CLS */

/*
 * The importer now writes intrinsic `width`/`height` onto migrated images so
 * the browser can reserve the box before the image decodes — without them each
 * image shoves everything below it down as it loads.
 *
 * `height: auto` is the required other half. The attributes are there to
 * declare an *aspect ratio*, not a rendered size: left unguarded the height
 * attribute wins over the theme's CSS and images render at their intrinsic
 * pixel height, ignoring `width: 100%`. (This is exactly what distorted the
 * blog thumbnails when they were given a height attribute.)
 *
 * Scoped to content images, and it yields to anything that sets its own height
 * inline, so a deliberate fixed-height image is unaffected.
 */
#content img:not([style*="height"]),
.section-left img,
#contact img,
#footer img {
	height: auto;
}

/* ------------------------------------------------------------- navigation */

/*
 * Hover + current-page state for the main nav.
 *
 * The theme only ever styled these on `#menu-sticky` — a clone the legacy
 * bundle builds from a `#menu-sticky-script` template this build doesn't
 * ship — so the visible menu had no hover underline and no way to tell which
 * page you're on. Same visual language as those (dead) sticky rules: a
 * centred gold bar that grows on hover and stays put on the current page.
 * `aria-current="page"` is set server-side in VmNav; a dropdown toggle whose
 * child is current carries `data-active` instead (it isn't the page itself).
 */
#menu > .container > ul > li > .nav-link {
	position: relative;
}

#menu > .container > ul > li > .nav-link::after {
	content: "";
	position: absolute;
	left: 50%;
	bottom: 12px;
	width: 0;
	height: 2px;
	border-radius: 2px;
	background: linear-gradient(90deg, var(--vm-gold, #c9a95a), var(--vm-gold-light, #ddc98f));
	transform: translateX(-50%);
	transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

#menu > .container > ul > li > .nav-link:hover::after,
#menu > .container > ul > li > .nav-link[aria-current="page"]::after,
#menu > .container > ul > li > .nav-link[data-active]::after {
	width: calc(100% - 32px);
	max-width: 72px;
}

/* The logo is a link too, but an underline beneath it reads as a glitch. */
#menu li.nav-home > .nav-link::after {
	display: none;
}

/* Current page inside an open dropdown. */
#menu ul[data-role="menu"] .nav-link[aria-current="page"] {
	color: var(--vm-plum, #411b58);
	font-weight: 700;
	box-shadow: inset 3px 0 0 var(--vm-gold, #c9a95a);
	background: rgba(65, 27, 88, 0.05);
}

/* --------------------------------------------------------------- overflow */

/*
 * One scroll container: the window.
 *
 * The theme declares `body { overflow-y: auto; overflow-x: hidden }` and
 * `#page { overflow: auto; margin-bottom: -20px }`. Both boxes therefore
 * become scroll containers, and both hold content a few pixels taller than
 * themselves (the -20px margin guarantees it) — so wide desktop viewports
 * render THREE stacked vertical scrollbars: the window's, the body's and
 * #page's, each one shifting the layout another 15px leftward.
 *
 * `clip` keeps the clipping without creating a scrollable box, so the inner
 * scrollbars cannot exist no matter how the content mis-measures. Unlike
 * hidden/auto, though, `clip` does NOT establish a formatting context — and
 * the theme leaned on that too: without it, a descendant's top margin
 * collapses up through #page and shoves the whole page 10px down (a white
 * strip above the header). `flow-root` restores the containment explicitly.
 * Browsers too old for `clip` drop that declaration and keep the legacy
 * behaviour.
 */
body,
#page {
	overflow: clip;
	display: flow-root;
}

/*
 * The theme's `body { overflow-x: hidden }` also served as the viewport's
 * horizontal lock (body overflow propagates to the viewport when html's is
 * visible; clip does not propagate the same way). Re-establish the lock on
 * html itself, where viewport scrolling actually belongs — vertical stays
 * the window's own scrollbar.
 */
html {
	overflow-x: clip;
}

/* The theme declares this as `#page #content`, so match its specificity.
   flow-root for the same reason as above: overflow-x:hidden was a BFC,
   overflow-x:clip is not. */
#page #content {
	overflow-x: clip;
	display: flow-root;
}

/*
 * Map sticker (the "Von Mortgage" banner over the Google map).
 *
 * The section's own CSS sizes the sticker by height (--h-x-w: 140px) and
 * relies on `max-width/max-height: 100%` to scale the logo inside it,
 * aspect intact. The importer later added explicit `width`/`height`
 * attributes to every content image to reserve layout space — and that
 * presentational width (1950px) overrides the intended auto width, so the
 * banner rendered 1950×140: squashed flat and bleeding off both edges.
 * Restoring auto lets the section's max-constraints do what they were
 * written to do (≈560×140 on desktop).
 */
.sticker .sticker-img img {
	width: auto;
	height: auto;
}

/*
 * Wide comparison tables in the loan-program pages overflow the viewport on a
 * phone, which scrolls the whole page sideways. Containing the scroll to the
 * table keeps the page itself locked.
 */
@media (max-width: 767px) {
	#content table {
		display: block;
		width: 100%;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}
}

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

/*
 * Scroll reveal.
 *
 * The page is long and uniformly dense — sections arrive with no sense of
 * sequence. A short, small rise as each one enters gives the scroll some
 * rhythm without turning it into a show.
 *
 * `.vm-reveal` is added by script, never in the markup, so with JavaScript off
 * (or before the observer runs) everything is visible by default and nothing
 * can get stuck hidden.
 */
.vm-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition:
		opacity 0.7s var(--vm-ease),
		transform 0.7s var(--vm-ease);
}

.vm-reveal.is-in {
	opacity: 1;
	transform: none;
}

/*
 * Motion is a preference, not a default. Everything above degrades to a plain
 * state change; nothing here is the only way to perceive anything.
 */
@media (prefers-reduced-motion: reduce) {
	.vm-reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.btn:hover,
	.blog__item:hover img {
		transform: none;
	}

	#content .html-widget > a:not(.btn):hover span {
		transform: none;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}
