fix: match mobile contact card design

This commit is contained in:
Keith Solomon
2026-06-27 20:58:36 -05:00
parent d19924e22b
commit 443be4fb89
3 changed files with 124 additions and 23 deletions
+82
View File
@@ -340,6 +340,88 @@ test("media text keeps its configured ordering at 768px", async ({ page }) => {
await expect(contentLocator.locator(".reset")).toHaveCSS("display", "flex");
});
test("mobile contact card matches the 402px reference geometry", async ({
page,
}) => {
await page.goto(homepage);
const cardLocator = page.locator(".contact-block.home-contact");
const card = await getBox(cardLocator);
const heading = await getBox(cardLocator.locator(".contact-block__text"));
const cta = await getBox(cardLocator.locator(".contact-block__cta"));
const linework = await getBox(
cardLocator.locator(".contact-block__linework"),
);
const lineworkLocator = cardLocator.locator(".contact-block__linework");
const backgroundImage = cardLocator.locator(".contact-block__bg-image");
const bandHeight = await cardLocator.evaluate((element) =>
Number.parseFloat(getComputedStyle(element).borderBottomWidth),
);
expectNear(card.width, 343, 3);
expectNear(card.height, 502, 5);
expectNear(card.x, (402 - card.width) / 2, 2);
expectNear(bandHeight, 16, 1);
expectNear(heading.x - card.x, 33, 3);
expectNear(heading.y - card.y, 31, 4);
expectNear(cta.x - card.x, 33, 3);
expectNear(cta.y - card.y, 219, 5);
expectNear(cta.width, 173, 4);
expectNear(linework.y - card.y, 300, 5);
expectNear(linework.height, 186, 5);
expect(linework.x).toBeLessThanOrEqual(card.x);
await expect(lineworkLocator).toHaveCSS("overflow", "visible");
await expect(backgroundImage).toHaveCSS("object-fit", "fill");
await expect(cardLocator).toHaveCSS("border-radius", "16px 16px 0px 0px");
});
test("mobile contact card scales proportionally and remains contained", async ({
page,
}) => {
for (const width of [320, 767]) {
await page.setViewportSize({ width, height: 900 });
await page.goto(homepage);
const cardLocator = page.locator(".contact-block.home-contact");
const card = await getBox(cardLocator);
const heading = await getBox(
cardLocator.locator(".contact-block__text"),
);
expect(card.x).toBeGreaterThanOrEqual(0);
expect(card.x + card.width).toBeLessThanOrEqual(width);
expectNear(card.width / width, 343 / 402, 0.015);
expectNear(card.height / card.width, 502 / 343, 0.025);
expectNear((heading.x - card.x) / card.width, 33 / 343, 0.01);
}
});
test("contact card restores the desktop layout at 768px", async ({ page }) => {
await page.setViewportSize({ width: 768, height: 900 });
await page.goto(homepage);
const card = page.locator(".contact-block.home-contact");
await expect(card).toHaveCSS("position", "absolute");
await expect(card).toHaveCSS("border-bottom-width", "16px");
await expect(card).toHaveCSS("border-radius", "24px 24px 0px 0px");
});
test("mobile contact card matches the supplied visual reference", async ({
page,
}) => {
await page.goto(homepage);
await expect(page.locator(".contact-block.home-contact")).toHaveScreenshot(
"contact-reference.png",
{
animations: "disabled",
maxDiffPixelRatio: 0.025,
threshold: 0.08,
},
);
});
test("mobile recent posts exposes previous and next controls", async ({
page,
}) => {
Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

+42 -23
View File
@@ -2,17 +2,24 @@
.contact-block {
background-color: var(--color-navy, #0d1f35);
border-bottom: 1rem solid var(--color-orange, #F26B53);
border-bottom: 1rem solid var(--color-orange, #f26b53);
overflow: hidden;
position: relative;
em { color: var(--color-secondary); font-style: normal; }
em {
color: var(--color-secondary);
font-style: normal;
}
.contact-block__media {
inset-block: 0;
inset-inline-end: 0;
mask-image: linear-gradient(to right, transparent 0%, black 30%);
-webkit-mask-image: linear-gradient(to right, transparent 0%, black 30%);
-webkit-mask-image: linear-gradient(
to right,
transparent 0%,
black 30%
);
position: absolute;
}
@@ -30,10 +37,6 @@
width: auto;
}
.contact-block__content {
}
&.home-contact {
bottom: -25%;
left: 50%;
@@ -45,46 +48,62 @@
@media (max-width: 767px) {
.contact-block {
border-bottom-width: 0.75rem;
border-radius: 0.75rem 0.75rem 0 0;
border-bottom-width: calc(100vw * 16 / 402);
border-radius: calc(100vw * 16 / 402) calc(100vw * 16 / 402) 0 0;
box-sizing: border-box;
padding-inline: 0 !important;
padding-top: 0 !important;
}
.contact-block .contact-block__media {
inset: 0;
mask-image: linear-gradient(to bottom, rgb(0 0 0 / 0.9) 0%, rgb(0 0 0 / 0.45) 100%);
-webkit-mask-image: linear-gradient(to bottom, rgb(0 0 0 / 0.9) 0%, rgb(0 0 0 / 0.45) 100%);
mask-image: none;
-webkit-mask-image: none;
}
.contact-block .contact-block__bg-image {
object-fit: cover;
object-fit: fill;
}
.contact-block .contact-block__linework {
bottom: 0.75rem;
bottom: 0;
height: auto;
max-width: 112%;
right: -32%;
width: 22rem;
left: calc(100% * -113 / 343);
max-width: none;
overflow: visible;
right: auto;
width: calc(100% * 414 / 343);
}
.contact-block .contact-block__content {
min-height: 18.5rem;
padding: 2.25rem 1.5rem 2.75rem !important;
.contact-block.home-contact .contact-block__content {
margin: 0 !important;
max-width: none !important;
padding: calc(100vw * 31 / 402) calc(100vw * 33 / 402) 0 !important;
position: relative;
left: calc(100vw * 33 / 402 - 1rem);
width: 100% !important;
z-index: 2;
}
.contact-block .contact-block__text {
font-size: clamp(1.9rem, 8.7vw, 2.45rem);
line-height: 1.02;
max-width: 16rem !important;
font-size: calc(100vw * 28 / 402);
line-height: 1.08;
margin-bottom: calc(100vw * 37 / 402);
max-width: calc(100% * 260 / 343) !important;
}
.contact-block .contact-block__cta {
padding-block: calc(100vw * 8.5 / 402);
}
.contact-block.home-contact {
bottom: auto;
height: calc(100vw * 502 / 402);
left: 50%;
margin: 2.5rem auto -3.75rem;
max-width: none;
position: relative;
transform: translateX(-50%);
width: min(calc(100vw - 2rem), 22.5rem);
width: calc(100vw * 343 / 402);
}
}