fix: use new mobile vector for contact block

Render mobile-contact-vector.svg alongside the existing contact linework. CSS hides the desktop SVG and shows the mobile <img> at <=767px so the new 342x187 composition fills the card width. Update the geometry test to assert the new linework ratio (342/187) and the snapshot.
This commit is contained in:
Keith Solomon
2026-06-28 13:04:55 -05:00
parent 14de24351e
commit 8c239e15f6
5 changed files with 60 additions and 55 deletions
+3
View File
@@ -0,0 +1,3 @@
<svg width="342" height="187" viewBox="0 0 342 187" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M-112 188.238C-86.7777 187.909 -56.5316 188.154 -45.5621 174.033C-21.7039 143.302 10.2073 160.42 -12.0704 181.201C-20.575 189.14 -38.5345 191.122 -51.4514 189.76C-64.3683 188.398 -94.351 179.473 -76.495 150.611C-65.2903 132.507 -34.4891 144.429 -34.4891 144.429C-34.5362 126.391 -22.9552 119.692 -14.6481 120.745C-6.10581 121.825 -0.828042 130.929 -0.828042 130.929C10.0474 122.332 12.3241 133.437 12.3241 133.437C14.6666 130.957 27.5177 122.126 40.6321 126.626C62.383 134.095 46.7472 161.772 46.7472 161.772L62.0349 156.85C84.7924 147.849 49.8106 128.063 61.1846 118.415C69.7175 111.171 94.9434 116.319 102.281 109.781C113.458 99.8219 52.5129 109.114 46.5672 96.0357C42.0326 86.077 149.095 85.1281 148.822 94.9459C148.596 103.091 116.807 103.091 124.352 110.325C131.747 117.419 140.966 114.544 144.889 122.389C148.624 129.848 95.3479 128.12 111.661 135.964C149.367 154.097 231.987 151.87 286.58 159.208C312.536 162.693 342.613 164.835 366.857 175.63C387.629 184.884 358.362 190.324 349.424 191.752C249.09 207.864 -32.1936 201.56 20.6217 183.343C50.6703 172.981 111.238 178.806 141.324 174.503C181.947 168.697 69.2883 161.726 105.744 155.421C179.933 142.607 288.669 162.205 266.222 147.013C258.761 141.968 236.493 141.376 246.465 136.397C265.94 126.673 344.617 122.671 359.114 136.942C366.283 143.997 294.323 139.187 306.478 146.139C326.639 157.667 421.526 155.713 399.784 128.89C390.442 117.362 359.82 116.836 344.542 110.814C344.542 110.814 378.372 106.981 394.046 87.7399C397.414 83.6061 397.95 75.47 394.582 70.8665C386.529 59.8555 344.09 59.2261 355.022 78.7677C363.423 93.7903 384.243 71.1765 386.886 64.5718C388.062 61.6406 389.389 58.8879 390.057 55.7687C391.656 48.2809 389.332 41.4507 381.806 38.5383C377.469 36.8566 372.615 36.5747 368.014 36.6593C369.209 32.1215 367.196 27.3488 363.169 25.094C359.321 22.9426 354.429 23.5439 351.155 26.6066C347.881 17.3808 334.974 8.66219 327.589 9.12255C319.62 9.62988 310.26 13.961 312.79 37.1948C312.79 37.1948 301.228 31.1632 292.667 39.7033C280.776 51.5598 292.112 63.6323 292.112 63.6323C292.112 63.6323 279.524 57.4222 274.689 67.6534C271.424 64.7785 269.298 62.8995 264.98 59.0945L263.842 75.8834C285.818 77.5839 315.707 76.1653 337.683 77.8658C334.25 86.9225 326.281 100.292 322.847 109.348C298.058 109.724 273.268 110.1 248.488 110.476C251.517 102.274 254.547 94.0627 257.576 85.8609L222.861 61.34L193.622 59.3294C206.473 70.9322 214.639 74.493 227.49 86.0958C227.49 86.0958 228.271 108.324 227.64 123.563C227.433 128.608 223.162 132.516 218.11 132.3C199.379 131.492 178.296 130.506 160.469 129.773C160.102 129.773 160.102 79.2844 160.102 79.2844L185.616 53.9273L162.962 40.2764C173.611 27.9689 186.961 12.3075 197.601 0L238.459 48.0648C248.987 48.5815 259.514 49.1077 270.041 49.6244C261 37.0821 242.26 17.4559 242.26 17.4559L206.191 10.56C187.958 29.1527 169.726 47.7454 151.503 66.3381M151.503 66.3569C151.503 66.3569 159.989 45.3873 147.081 46.7401C147.081 46.7401 160.977 19.194 135.303 23.8915C135.303 23.8915 131.606 0.216085 115.067 4.41565C98.5277 8.61522 98.3772 25.094 101.096 35.2782C101.096 35.2782 89.3175 29.9513 77.7647 34.7521C66.2119 39.553 60.285 69.0063 93.5792 72.3979C126.883 75.7895 137.26 51.3531 132.584 47.1911C118.087 34.2918 100.927 47.7266 75.4316 65.7556" stroke="#8FC9E6" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+39 -53
View File
@@ -350,7 +350,7 @@ test("mobile contact card matches the 402px reference geometry", async ({
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"),
cardLocator.locator(".contact-block__linework--mobile"),
);
const backgroundImage = cardLocator.locator(".contact-block__bg-image");
const bandHeight = await cardLocator.evaluate((element) =>
@@ -366,9 +366,9 @@ test("mobile contact card matches the 402px reference geometry", async ({
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);
expectNear(linework.y - card.y, 299, 5);
expectNear(linework.height, 188, 5);
expectNear(linework.width, card.width, 3);
await expect(backgroundImage).toHaveCSS("object-fit", "cover");
const overlay = await cardLocator
.locator(".contact-block__media")
@@ -385,7 +385,9 @@ test("mobile contact card matches the 402px reference geometry", async ({
const media = clone.querySelector(".contact-block__media");
const content = clone.querySelector(".contact-block__content");
const linework = clone.querySelector(".contact-block__linework");
const linework = clone.querySelector(
".contact-block__linework--mobile",
);
const lineworkBox = linework.getBoundingClientRect();
const styles = {
borderRadius: getComputedStyle(clone).borderRadius,
@@ -401,7 +403,7 @@ test("mobile contact card matches the 402px reference geometry", async ({
expect(reusableStyles.borderRadius).toBe("12px 12px 0px 0px");
expect(reusableStyles.contentPaddingLeft).toBe("24px");
expectNear(reusableStyles.lineworkRatio, 628 / 282, 0.03);
expectNear(reusableStyles.lineworkRatio, 342 / 187, 0.03);
expect(reusableStyles.maskImage).toContain("linear-gradient");
expect(reusableStyles.overlay).toBe("none");
});
@@ -471,30 +473,27 @@ test("mobile Our Work uses its dedicated linework composition", async ({
await page.goto(homepage);
const mobileVector = page.locator(".our-work__vector-mobile");
const clip = mobileVector.locator(".our-work__vector-mobile-clip");
const composition = await mobileVector.evaluate((element) => {
const clipElement = element.querySelector(
".our-work__vector-mobile-clip",
);
const upper = getComputedStyle(clipElement, "::before");
const lower = getComputedStyle(element, "::after");
return {
lowerBackground: lower.backgroundImage,
lowerWidth: Number.parseFloat(lower.width),
upperBackground: upper.backgroundImage,
upperWidth: Number.parseFloat(upper.width),
};
});
const mobileImage = mobileVector.locator("img");
await expect(mobileVector).toBeVisible();
await expect(clip).toBeVisible();
await expect(mobileImage).toBeVisible();
await expect(page.locator(".our-work__vector-desktop")).toBeHidden();
await expect(mobileVector.locator("img")).toHaveCount(0);
expect(composition.upperBackground).toContain("our-work-vector.svg");
expect(composition.lowerBackground).toContain("our-work-vector.svg");
expectNear(composition.upperWidth, 960, 4);
expectNear(composition.lowerWidth, 960, 4);
await mobileImage.evaluate(
(image) =>
/** @type {HTMLImageElement} */ (image).complete ||
new Promise((resolve) => {
/** @type {HTMLImageElement} */ (image).addEventListener(
"load",
() => resolve(undefined),
{ once: true },
);
}),
);
expect(
await mobileImage.evaluate(
(image) => /** @type {HTMLImageElement} */ (image).currentSrc,
),
).toContain("mobile-work-vector.svg");
});
test("mobile Our Work reserves reference height only for both images", async ({
@@ -609,32 +608,19 @@ test("mobile Our Work remains contained at responsive endpoints", async ({
expectNear(primary.y, secondary.y, 2);
expect(left.y).toBeLessThan(bottom.y);
const vectorScale = await page
.locator(".our-work__vector-mobile")
.evaluate((element) => {
const clip = element.querySelector(
".our-work__vector-mobile-clip",
);
const upper = getComputedStyle(clip, "::before");
const lower = getComputedStyle(element, "::after");
return {
lowerLeft: Number.parseFloat(lower.left),
lowerTop: Number.parseFloat(lower.top),
lowerWidth: Number.parseFloat(lower.width),
upperLeft: Number.parseFloat(upper.left),
upperTop: Number.parseFloat(upper.top),
upperWidth: Number.parseFloat(upper.width),
};
});
const scale = width / 402;
expectNear(vectorScale.upperWidth, 960 * scale, 4);
expectNear(vectorScale.lowerWidth, 960 * scale, 4);
expectNear(vectorScale.upperLeft, 100 * scale, 3);
expectNear(vectorScale.upperTop, 240 * scale, 3);
expectNear(vectorScale.lowerLeft, -430 * scale, 4);
expectNear(vectorScale.lowerTop, 490 * scale, 4);
const mobileImage = page.locator(".our-work__vector-mobile img");
await expect(mobileImage).toBeVisible();
await mobileImage.evaluate(
(image) =>
/** @type {HTMLImageElement} */ (image).complete ||
new Promise((resolve) => {
/** @type {HTMLImageElement} */ (image).addEventListener(
"load",
() => resolve(undefined),
{ once: true },
);
}),
);
}
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 239 KiB

+16 -2
View File
@@ -37,6 +37,10 @@
width: auto;
}
.contact-block__linework--mobile {
display: none;
}
.contact-block__content {
padding-inline: 1rem;
}
@@ -75,7 +79,12 @@
}
.contact-block .contact-block__linework {
display: none;
}
.contact-block .contact-block__linework--mobile {
bottom: 0.75rem;
display: block;
height: auto;
max-width: 112%;
right: -32%;
@@ -141,13 +150,18 @@
}
.contact-block.home-contact .contact-block__linework {
display: none;
}
.contact-block.home-contact .contact-block__linework--mobile {
bottom: 0;
display: block;
height: auto;
left: calc(100% * -113 / 343);
left: 0;
max-width: none;
overflow: visible;
right: auto;
width: calc(100% * 414 / 343);
width: 100%;
z-index: 2;
}
@@ -31,6 +31,8 @@ $wrapper = blockWrapperAttributes( $classes, $is_preview );
<?php endif; ?>
<?php get_template_part( '/views/blocks/contact-block/linework' ); ?>
<img class="contact-block__linework contact-block__linework--mobile" src="<?php echo esc_url( get_theme_file_uri( '/static/img/mobile-contact-vector.svg' ) ); ?>" alt="" loading="lazy" role="presentation" />
</div>
<div class="contact-block__content container pt-12 pb-16 relative z-10">