fix(hero): apply gradient to last H1 word post-split so 'revenue.' renders (was clipped by line mask)
|
|
@ -88,6 +88,10 @@ export default function Hero() {
|
||||||
type: "lines,words",
|
type: "lines,words",
|
||||||
linesClass: "hero__line",
|
linesClass: "hero__line",
|
||||||
});
|
});
|
||||||
|
// Apply the brand gradient to the final word ("revenue.") AFTER splitting.
|
||||||
|
// A pre-nested <span class="grad"> got clipped by the line mask and never
|
||||||
|
// revealed; as a normal split word it animates + shows correctly.
|
||||||
|
split.words[split.words.length - 1]?.classList.add("grad");
|
||||||
gsap.set(".hero__h1", { autoAlpha: 1 });
|
gsap.set(".hero__h1", { autoAlpha: 1 });
|
||||||
gsap.set(".hero__line", { overflow: "hidden" });
|
gsap.set(".hero__line", { overflow: "hidden" });
|
||||||
// Fast, tight cascade so the FULL headline — including the last word
|
// Fast, tight cascade so the FULL headline — including the last word
|
||||||
|
|
@ -255,7 +259,7 @@ export default function Hero() {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h1 id="hero-h1" className="hero__h1">
|
<h1 id="hero-h1" className="hero__h1">
|
||||||
Marketing that grows your <span className="grad">revenue.</span>
|
Marketing that grows your revenue.
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p className="hero__sub hero__stagger">
|
<p className="hero__sub hero__stagger">
|
||||||
|
|
|
||||||
BIN
audit2/desktop-faq.png
Normal file
|
After Width: | Height: | Size: 312 KiB |
BIN
audit2/desktop-final.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
audit2/desktop-fold.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
audit2/desktop-full.png
Normal file
|
After Width: | Height: | Size: 7 MiB |
BIN
audit2/desktop-h1.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
audit2/desktop-hero-full.png
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
audit2/desktop-hero-line2.png
Normal file
|
After Width: | Height: | Size: 400 KiB |
BIN
audit2/desktop-hero-top.png
Normal file
|
After Width: | Height: | Size: 5.1 MiB |
BIN
audit2/desktop-howitworks-tile1.png
Normal file
|
After Width: | Height: | Size: 213 KiB |
BIN
audit2/desktop-howitworks-tile2.png
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
audit2/desktop-howitworks-tile3.png
Normal file
|
After Width: | Height: | Size: 298 KiB |
BIN
audit2/desktop-howitworks-tile4.png
Normal file
|
After Width: | Height: | Size: 696 KiB |
BIN
audit2/desktop-howitworks.png
Normal file
|
After Width: | Height: | Size: 313 KiB |
BIN
audit2/desktop-loop-steplist.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
audit2/desktop-manifesto.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
audit2/desktop-scoreboard.png
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
audit2/desktop-services.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
audit2/desktop-testimonials.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
audit2/desktop-trustedby.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
audit2/desktop-work.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
audit2/mobile-fold.png
Normal file
|
After Width: | Height: | Size: 701 KiB |
BIN
audit2/mobile-full.png
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
audit2/mobile-hero-top.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
audit2/mobile-howitworks.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
audit2/mobile-scoreboard.png
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
audit2/mobile-testimonials.png
Normal file
|
After Width: | Height: | Size: 488 KiB |
BIN
audit2/mobile-trustedby.png
Normal file
|
After Width: | Height: | Size: 416 KiB |
1
audit2/page.html
Normal file
165
audit2/sections.json
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
{
|
||||||
|
"scrollHeight": 11848,
|
||||||
|
"sections": [
|
||||||
|
{
|
||||||
|
"i": 0,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "site-head ",
|
||||||
|
"top": 0,
|
||||||
|
"h": 85,
|
||||||
|
"txt": "Feedback Studios Services Work About FAQ Get a growth audit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 1,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "hero",
|
||||||
|
"top": 0,
|
||||||
|
"h": 900,
|
||||||
|
"txt": "RESULTS-DRIVEN DIGITAL MARKETING AGENCY Marketing that grows your revenue. We run paid, SE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 2,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "tape",
|
||||||
|
"top": 900,
|
||||||
|
"h": 133,
|
||||||
|
"txt": "Revenue, not vanity metrics ✱ Paid ✱ SEO ✱ Content ✱ Social ✱ +52% ROAS ✱ +217% demos ✱ +1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 3,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "manifesto frame",
|
||||||
|
"top": 1033,
|
||||||
|
"h": 951,
|
||||||
|
"txt": "THE PROBLEM WITH MOST AGENCIES Most budgets buy activity, not outcomes. Dashboards fill wi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 4,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "proof",
|
||||||
|
"top": 1983,
|
||||||
|
"h": 296,
|
||||||
|
"txt": "TRUSTED BY TEAMS THAT CARE ABOUT THE SALES NUMBER E-commerce B2B SaaS Clinics Professional"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 5,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "services frame",
|
||||||
|
"top": 2374,
|
||||||
|
"h": 1165,
|
||||||
|
"txt": "SERVICES / 06 How we grow your business 01 SEO that compounds Rank for the searches your b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 6,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "sec-head",
|
||||||
|
"top": 2504,
|
||||||
|
"h": 114,
|
||||||
|
"txt": "SERVICES / 06 How we grow your business"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 7,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "score frame",
|
||||||
|
"top": 3539,
|
||||||
|
"h": 797,
|
||||||
|
"txt": "THE SCOREBOARD — SAMPLE DATA Numbers we report on client revenue generated $40M+ client re"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 8,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "sec-head sec-head--center",
|
||||||
|
"top": 3669,
|
||||||
|
"h": 128,
|
||||||
|
"txt": "THE SCOREBOARD — SAMPLE DATA Numbers we report on"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 9,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "work frame",
|
||||||
|
"top": 4336,
|
||||||
|
"h": 1077,
|
||||||
|
"txt": "SELECTED WORK — SAMPLE Proof, not promises 01 E-commerce · Fashion BEFORE Rising ad costs "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 10,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "sec-head",
|
||||||
|
"top": 4466,
|
||||||
|
"h": 114,
|
||||||
|
"txt": "SELECTED WORK — SAMPLE Proof, not promises"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 11,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "loop frame",
|
||||||
|
"top": 5413,
|
||||||
|
"h": 3094,
|
||||||
|
"txt": "THE FEEDBACK LOOP How it works 01 / 04 REVENUE LEAK — DETECTED −$14k/mo wasted spend CHANN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 12,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "sec-head loop__head",
|
||||||
|
"top": 5644,
|
||||||
|
"h": 128,
|
||||||
|
"txt": "THE FEEDBACK LOOP How it works 01 / 04"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 13,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "quotes frame",
|
||||||
|
"top": 8507,
|
||||||
|
"h": 810,
|
||||||
|
"txt": "IN THEIR WORDS — SAMPLE The number is the point “ We were spending $20k a month on ads wit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 14,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "sec-head",
|
||||||
|
"top": 8637,
|
||||||
|
"h": 114,
|
||||||
|
"txt": "IN THEIR WORDS — SAMPLE The number is the point"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 15,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "faq-sec frame",
|
||||||
|
"top": 9317,
|
||||||
|
"h": 1254,
|
||||||
|
"txt": "FAQ Questions about working with a digital marketing agency What does a digital marketing "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 16,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "sec-head",
|
||||||
|
"top": 9447,
|
||||||
|
"h": 280,
|
||||||
|
"txt": "FAQ Questions about working with a digital marketing agency"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 17,
|
||||||
|
"tag": "SECTION",
|
||||||
|
"cls": "final frame",
|
||||||
|
"top": 10571,
|
||||||
|
"h": 737,
|
||||||
|
"txt": "THE BOTTOM LINE Ready to grow? No long contracts. No vanity reports. Marketing you can mea"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 18,
|
||||||
|
"tag": "HEADER",
|
||||||
|
"cls": "",
|
||||||
|
"top": 10724,
|
||||||
|
"h": 280,
|
||||||
|
"txt": "Ready to grow?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"i": 19,
|
||||||
|
"tag": "FOOTER",
|
||||||
|
"cls": "colophon frame",
|
||||||
|
"top": 11308,
|
||||||
|
"h": 540,
|
||||||
|
"txt": "Feedback Studios. Marketing that grows your revenue. Services Work About FAQ Contact Linke"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
1
audit2/site.css
Normal file
85
capture2.js
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
const { chromium } = require('playwright');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const URL = 'https://studiosfeedback.com';
|
||||||
|
const OUT = '/home/claude/agency-web/audit2';
|
||||||
|
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36';
|
||||||
|
|
||||||
|
const VIEWPORTS = [
|
||||||
|
['desktop', 1440, 900],
|
||||||
|
['mobile', 390, 844],
|
||||||
|
];
|
||||||
|
|
||||||
|
// slow scroll, ~250ms per step, to trigger scroll-driven animations & count-ups
|
||||||
|
async function slowScroll(page, perStep = 250, frac = 0.55) {
|
||||||
|
await page.evaluate(async ({ perStep, frac }) => {
|
||||||
|
const step = Math.max(200, Math.round(window.innerHeight * frac));
|
||||||
|
for (let y = 0; y < document.body.scrollHeight; y += step) {
|
||||||
|
window.scrollTo(0, y);
|
||||||
|
await new Promise((r) => setTimeout(r, perStep));
|
||||||
|
}
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
await new Promise((r) => setTimeout(r, 1500));
|
||||||
|
}, { perStep, frac });
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const browser = await chromium.launch();
|
||||||
|
for (const [name, w, h] of VIEWPORTS) {
|
||||||
|
const ctx = await browser.newContext({
|
||||||
|
viewport: { width: w, height: h },
|
||||||
|
userAgent: UA,
|
||||||
|
deviceScaleFactor: 2,
|
||||||
|
});
|
||||||
|
const page = await ctx.newPage();
|
||||||
|
await page.goto(URL, { waitUntil: 'networkidle', timeout: 60000 }).catch(async () => {
|
||||||
|
await page.goto(URL, { waitUntil: 'load', timeout: 60000 });
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const sel of [
|
||||||
|
'text=/^(accept|aceptar|agree|ok|entendido|got it)/i',
|
||||||
|
"[id*='cookie' i] button",
|
||||||
|
"[class*='consent' i] button",
|
||||||
|
]) {
|
||||||
|
try { await page.locator(sel).first().click({ timeout: 700 }); } catch (e) {}
|
||||||
|
}
|
||||||
|
await page.keyboard.press('Escape').catch(() => {});
|
||||||
|
|
||||||
|
// two full slow passes so count-ups & per-step reveals reach final state
|
||||||
|
await slowScroll(page, 250, 0.55);
|
||||||
|
await slowScroll(page, 200, 0.45);
|
||||||
|
|
||||||
|
// fold (top)
|
||||||
|
await page.evaluate(() => window.scrollTo(0, 0));
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
await page.screenshot({ path: `${OUT}/${name}-fold.png` });
|
||||||
|
|
||||||
|
// full page in final animated state
|
||||||
|
await page.screenshot({ path: `${OUT}/${name}-full.png`, fullPage: true });
|
||||||
|
|
||||||
|
if (name === 'desktop') {
|
||||||
|
fs.writeFileSync(`${OUT}/page.html`, await page.content(), 'utf-8');
|
||||||
|
const meta = await page.evaluate(() => {
|
||||||
|
const out = [];
|
||||||
|
document.querySelectorAll('section, header, footer').forEach((el, i) => {
|
||||||
|
const r = el.getBoundingClientRect();
|
||||||
|
out.push({
|
||||||
|
i,
|
||||||
|
tag: el.tagName,
|
||||||
|
cls: (el.className || '').toString().slice(0, 70),
|
||||||
|
top: Math.round(r.top + window.scrollY),
|
||||||
|
h: Math.round(r.height),
|
||||||
|
txt: (el.innerText || '').replace(/\s+/g, ' ').slice(0, 90),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return { scrollHeight: document.body.scrollHeight, sections: out };
|
||||||
|
});
|
||||||
|
fs.writeFileSync(`${OUT}/sections.json`, JSON.stringify(meta, null, 2), 'utf-8');
|
||||||
|
console.log('desktop scrollHeight =', meta.scrollHeight, 'sections =', meta.sections.length);
|
||||||
|
}
|
||||||
|
console.log('captured', name);
|
||||||
|
await ctx.close();
|
||||||
|
}
|
||||||
|
await browser.close();
|
||||||
|
console.log('done');
|
||||||
|
})();
|
||||||
85
crops.js
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
const { chromium } = require('playwright');
|
||||||
|
|
||||||
|
const URL = 'https://studiosfeedback.com';
|
||||||
|
const OUT = '/home/claude/agency-web/audit2';
|
||||||
|
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36';
|
||||||
|
|
||||||
|
async function slowScroll(page, perStep = 250, frac = 0.55) {
|
||||||
|
await page.evaluate(async ({ perStep, frac }) => {
|
||||||
|
const step = Math.max(200, Math.round(window.innerHeight * frac));
|
||||||
|
for (let y = 0; y < document.body.scrollHeight; y += step) {
|
||||||
|
window.scrollTo(0, y);
|
||||||
|
await new Promise((r) => setTimeout(r, perStep));
|
||||||
|
}
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
await new Promise((r) => setTimeout(r, 1500));
|
||||||
|
}, { perStep, frac });
|
||||||
|
}
|
||||||
|
|
||||||
|
// crop targets by CSS selector -> filename
|
||||||
|
const TARGETS = [
|
||||||
|
{ sel: 'section.proof', name: 'trustedby' },
|
||||||
|
{ sel: 'section.score', name: 'scoreboard' },
|
||||||
|
{ sel: 'section.loop', name: 'howitworks' },
|
||||||
|
{ sel: 'section.quotes', name: 'testimonials' },
|
||||||
|
];
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const browser = await chromium.launch();
|
||||||
|
|
||||||
|
// DESKTOP crops
|
||||||
|
let ctx = await browser.newContext({ viewport: { width: 1440, height: 900 }, userAgent: UA, deviceScaleFactor: 2 });
|
||||||
|
let page = await ctx.newPage();
|
||||||
|
await page.goto(URL, { waitUntil: 'networkidle', timeout: 60000 }).catch(async () => {
|
||||||
|
await page.goto(URL, { waitUntil: 'load', timeout: 60000 });
|
||||||
|
});
|
||||||
|
await page.keyboard.press('Escape').catch(() => {});
|
||||||
|
await slowScroll(page, 250, 0.55);
|
||||||
|
await slowScroll(page, 200, 0.45);
|
||||||
|
await page.waitForTimeout(800);
|
||||||
|
|
||||||
|
for (const t of TARGETS) {
|
||||||
|
const el = page.locator(t.sel).first();
|
||||||
|
try {
|
||||||
|
await el.scrollIntoViewIfNeeded();
|
||||||
|
await page.waitForTimeout(900);
|
||||||
|
await el.screenshot({ path: `${OUT}/desktop-${t.name}.png` });
|
||||||
|
console.log('crop desktop', t.name);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('FAIL desktop', t.name, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the long "How it works" loop, also grab the 4 per-step panels individually if present
|
||||||
|
const steps = await page.locator('section.loop [class*="step" i], section.loop article, section.loop .loop__panel').count().catch(() => 0);
|
||||||
|
console.log('loop step-like elements:', steps);
|
||||||
|
|
||||||
|
await ctx.close();
|
||||||
|
|
||||||
|
// MOBILE crops
|
||||||
|
ctx = await browser.newContext({ viewport: { width: 390, height: 844 }, userAgent: UA, deviceScaleFactor: 2 });
|
||||||
|
page = await ctx.newPage();
|
||||||
|
await page.goto(URL, { waitUntil: 'networkidle', timeout: 60000 }).catch(async () => {
|
||||||
|
await page.goto(URL, { waitUntil: 'load', timeout: 60000 });
|
||||||
|
});
|
||||||
|
await page.keyboard.press('Escape').catch(() => {});
|
||||||
|
await slowScroll(page, 250, 0.55);
|
||||||
|
await slowScroll(page, 200, 0.45);
|
||||||
|
await page.waitForTimeout(800);
|
||||||
|
|
||||||
|
for (const t of TARGETS) {
|
||||||
|
const el = page.locator(t.sel).first();
|
||||||
|
try {
|
||||||
|
await el.scrollIntoViewIfNeeded();
|
||||||
|
await page.waitForTimeout(900);
|
||||||
|
await el.screenshot({ path: `${OUT}/mobile-${t.name}.png` });
|
||||||
|
console.log('crop mobile', t.name);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('FAIL mobile', t.name, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await ctx.close();
|
||||||
|
await browser.close();
|
||||||
|
console.log('done');
|
||||||
|
})();
|
||||||
44
looptiles.js
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
const { chromium } = require('playwright');
|
||||||
|
const OUT = '/home/claude/agency-web/audit2';
|
||||||
|
const URL = 'https://studiosfeedback.com';
|
||||||
|
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36';
|
||||||
|
|
||||||
|
async function slowScroll(page, perStep, frac) {
|
||||||
|
await page.evaluate(async ({ perStep, frac }) => {
|
||||||
|
const step = Math.max(200, Math.round(window.innerHeight * frac));
|
||||||
|
for (let y = 0; y < document.body.scrollHeight; y += step) {
|
||||||
|
window.scrollTo(0, y);
|
||||||
|
await new Promise((r) => setTimeout(r, perStep));
|
||||||
|
}
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
await new Promise((r) => setTimeout(r, 1500));
|
||||||
|
}, { perStep, frac });
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const b = await chromium.launch();
|
||||||
|
const ctx = await b.newContext({ viewport: { width: 1440, height: 900 }, userAgent: UA, deviceScaleFactor: 2 });
|
||||||
|
const page = await ctx.newPage();
|
||||||
|
await page.goto(URL, { waitUntil: 'networkidle', timeout: 60000 }).catch(() => {});
|
||||||
|
await page.keyboard.press('Escape').catch(() => {});
|
||||||
|
await slowScroll(page, 250, 0.55);
|
||||||
|
|
||||||
|
const box = await page.evaluate(() => {
|
||||||
|
const loop = document.querySelector('section.loop');
|
||||||
|
const r = loop.getBoundingClientRect();
|
||||||
|
return { top: Math.round(r.top + window.scrollY), h: Math.round(r.height) };
|
||||||
|
});
|
||||||
|
console.log('loop box', JSON.stringify(box));
|
||||||
|
|
||||||
|
const vh = 900;
|
||||||
|
const tiles = Math.ceil(box.h / vh);
|
||||||
|
for (let i = 0; i < tiles; i++) {
|
||||||
|
const y = box.top + i * vh;
|
||||||
|
await page.evaluate((yy) => window.scrollTo(0, yy), y);
|
||||||
|
await page.waitForTimeout(900);
|
||||||
|
await page.screenshot({ path: `${OUT}/desktop-howitworks-tile${i + 1}.png` });
|
||||||
|
console.log('tile', i + 1, 'at y=', y);
|
||||||
|
}
|
||||||
|
await b.close();
|
||||||
|
console.log('done');
|
||||||
|
})();
|
||||||