Hallmark vs Impeccable: 118,552 Stars, 259 Watchers, and Each One's Linter Fails the Other's Showcase

Two anti-slop design skills hold 118,552 stars and 259 watchers between them. I ran each one's deterministic linter over the other's showcase: Hallmark's sloplint found 30 FAILs in Impeccable's own demos, including 693px of horizontal overflow at a 320px viewport, while Impeccable's 62-rule detector found 41 findings across Hallmark's 21 gallery pages. One of those 41 is a measurement bug I reproduced in nine lines of CSS.

Two repositories, both claiming to fix the same problem: AI coding agents produce front-end pages that look generated. Both ship a markdown skill for Claude Code, Codex, Cursor and a growing list of other harnesses. Both ship a deterministic linter that runs without a model and without an API key. Together they hold 118,552 GitHub stars.

They hold 259 watchers.

That ratio — 0.22% — is the first thing worth understanding about this category. Stars are a bookmark; watchers are people who asked to be told when the thing changes. A design skill with 86,410 stars and 197 watchers is a design skill that many people installed once.

So I did the thing both products invite and neither product documents: I ran each one’s linter against the other one’s showcase, in a real browser, and then re-ran my own measurements outside either tool.

The results are not a winner-takes-all story. They are two genuinely competent products with complementary blind spots, and one measurement bug that matters more than either of them.

What each one actually is

Hallmark (Nutlope, MIT, created 2026-04-27) is a curated visual system plus a floor. Its SKILL.md lists 16 numbered rules described as “Binds every output in every harness, none of it waivable, even when nothing else is read.” The first rule is that every colour and every font goes through a token declared at :root. The linter is skills/hallmark/scripts/sloplint.mjs, a zero-dependency Node 18+ script that reads HTML/CSS/JSX/TSX/Vue/Svelte and, with --render, drives a real Chrome across multiple viewport widths.

The design payload is 48 themes, each a file under 8 KB with a reference photograph beside it, plus 21 “macrostructures” and a 39,061-byte gates.md that grades checks into Floor, Reflex and Finish tiers.

Impeccable (Paul Bakaus, Apache-2.0, created 2025-11-16) is a Rust engine plus a command vocabulary. One skill, 24 commands (craft, polish, audit, critique, distill, harden, live…), and 62 deterministic detector rules. The engine is a single binary; the CLI is a thin shim over it. impeccable detect scans files or a rendered URL; --json for machine output, --github for Actions annotations.

Its README is explicit about lineage: “Anthropic’s frontend-design was the first widely-used design skill for Claude. Impeccable started from there.”

Both are real software. Neither is a prompt dump with a README.

What you actually download

Repo size is the wrong number to compare and both projects make it easy to look at the wrong one. Here is the working tree I cloned on 2026-10-25, and what a user actually installs.

HallmarkImpeccable
Working tree64,872,784 B (64.9 MB), 819 files80,740,772 B (80.7 MB), 4,205 files
Largest file type.jpg, 52,317,013 B = 80.6% of the repo.json, 30,513,638 B = 37.8%
Markdown102 files, 671,432 B (1.0%)1,081 files, 11,377,387 B (14.1%)
Rustnone424 files, 252,311 lines
What gets installedskill dir, 6,841,340 B (the plugin is documented as “7 MB, not the whole repo”)one provider copy, ≈2,195,400 B

Hallmark’s 64.9 MB is not a design skill. It is a design skill plus its own marketing site’s photo library: site/themes/*/photos/ alone is 122 files and 46,267,651 bytes. GitHub’s language bar never shows this, because it counts code, not photographs — the sidebar reads “CSS 43.3%, HTML 37.4%, JavaScript 18.1%”, and 80.6% of the bytes are JPEGs.

Impeccable’s duplication is worse than it looks and equally invisible. The repo tracks the same skill tree once per supported harness:

22 × 1,100,013 B  identical font-index.json (sha256 47edbdfa…)  = 24,200,286 B
20 × ≈2,195,400 B provider copies of skills/impeccable/          = ≈43.9 MB
26 × tracked SKILL.md / SKILL.src.md files

Twenty-two byte-identical copies of one font index is 24.2 MB — 79% of all JSON bytes in the repository. AGENTS.md is honest about the mechanism: those root harness folders “are generated distribution artifacts that are tracked for direct repo installs, not hand-authored source.” A CI job (sync-generated-output.yml) regenerates and re-commits them. It is a defensible choice for npx skills and submodule users. It is still 24 MB of the same file.

Neither number changes what the tool does. Both matter when you git clone a 32k-star or 86k-star repository because a blog post told you to read the source.

How much instruction text each one puts in front of the model

This is the number that decides how a skill behaves in a long session, and neither README leads with it.

Hallmark’s own Flow step 4 tells the agent to load the layout, imagery, craft, genre and theme files plus gates.md § 1–4. Adding up those named files:

FileBytes
SKILL.md18,239
references/gates.md39,061
references/craft.md19,279
references/layout.md16,134
references/imagery.md14,343
one genre file (genres/editorial.md)1,372
one theme file (themes/atelier.md)7,851
one macrostructure1,554
documented load set117,833 B ≈ 29,500 tokens

The whole references/ tree is 98 markdown files and 632,105 bytes — roughly 158,000 tokens if a run ever reads all of it.

Impeccable’s SKILL.src.md is 12,459 bytes ≈ 3,100 tokens, and each command pulls its own reference file: reference/critique.md is 48,194 B (≈12,000 tokens), reference/new-work.md is 63,661 B (≈15,900 tokens), reference/live.md 36,916 B. Across all 24 commands the reference set is 41 files and 416,023 bytes; 30 of those files are named directly in SKILL.md (348,715 B ≈ 87,000 tokens if everything were loaded at once, which it is not).

Two different designs: Hallmark front-loads a fixed ~29.5k-token rulebook per build; Impeccable keeps the always-on payload at ~3.1k tokens and pays per command. If you run an agent with a tight context budget, that difference decides whether the skill is usable at all.

Governance: what the counters say

All figures from the GitHub API on 2026-10-25.

HallmarkImpeccable
Stars32,14286,410
Watchers62 (0.19%)197 (0.23%)
Forks / stars1,651 / 5.1%5,155 / 6.0%
Releases / tags0 / 090 / 90
Commits2972,534
Contributors5 with commits57
Top contributor share282 / 297 = 94.9% (Luffixos); owner Nutlope 12 = 4.0%1,885 / 2,534 = 74.4% (pbakaus); github-actions[bot] 284 = 11.2%
LicenseMITApache-2.0
Created2026-04-272025-11-16
Open issues4939

Hallmark has no releases and no tags. Its SKILL.md says version: 2.0.0, its commit history says “Hallmark 2.8.0, the launch pass”, and GitHub says “No releases published”. If you need to pin the version of a gate that can block a merge, the only pin available is a commit SHA. That is a real operational difference from Impeccable’s 90 tagged releases, not a cosmetic one.

Hallmark’s contributor distribution has a second implication. The name on the repository is Nutlope (Hassan El Mghari); the person who has written 94.9% of it is Luffixos. Twelve commits from the owner out of 297 is a project where the public face and the maintainer are different people — worth knowing before you file an issue against the account you saw on X.

The cross-test, and how to reproduce it

Neither product claims to be portable to the other’s output, and neither should. sloplint.mjs expects Hallmark’s stamp comment and :root token discipline; impeccable detect expects nothing in particular. So read the two results below as “what each gate reports about the other’s best work,” and I will separate house-style failures from craft failures explicitly.

Reproduction, from a clean clone of each repo:

# both repos, shallow
git clone --depth 1 https://github.com/Nutlope/hallmark.git
git clone --depth 1 https://github.com/pbakaus/impeccable.git
npx -y impeccable@latest --version                            # or: npm i -g impeccable
npm i -g puppeteer-core

# serve both showcases (they are static HTML with linked CSS)
(cd hallmark/site/made       && python3 -m http.server 8899) &
(cd impeccable/demos         && python3 -m http.server 8898) &

# Hallmark's linter, render tier on, against Impeccable's demos
export HALLMARK_PUPPETEER="$(npm root -g)/puppeteer-core"
export CHROME_PATH=/path/to/chrome
node hallmark/skills/hallmark/scripts/sloplint.mjs --url http://127.0.0.1:8898/landing-demo/

# Impeccable's detector against Hallmark's 21 gallery pages
impeccable detect --json http://127.0.0.1:8899/atelier-architect/

Both of those “serve” lines are load-bearing: the rendered engine needs an HTTP origin, and sloplint --url needs a URL it can navigate to. A file:// path works for the static tier and silently skips the render tier.

Round 1 — each linter on its own showcase

Hallmark’s 21 gallery pages, sloplint --render: 0 FAIL, 9 REFLEX, 0 WARN. All 21 pages pass the floor in a real browser, across the viewport widths the render tier checks (320, 375, 414, 1280, 1440, 1920). REFLEX findings are the waivable tier, and the pages carry them on the record — the stamp in atelier-architect/style.css reads dismissed 58, naming the gate it overruled and why.

That is a real result, not a marketing one. A 21-page gallery that survives its own browser-based floor is evidence the floor is enforced by something other than intention.

Impeccable’s 2 demo pages, impeccable detect (rendered): 32 findings across demos/landing-demo/ and demos/landing-demo/classic/, zero clean pages.

Rulelanding-democlassic
icon-tile-stack33
dark-glow—6
low-contrast—5
gradient-text—4
hero-eyebrow-chip11
overused-font11
unbalanced-heading11
straggler11
italic-serif-display, oversized-h1, cream-palette1 each—

Two of those deserve to be quoted back at the README, which says:

Don’t use overused fonts (Arial, Inter, system defaults)

The rendered scan reports overused-font once on each demo page. The first detector hit on landing-demo reads 'Inter', system-ui, sans-serif on body — the same declaration Hallmark’s static linter flags as gate 48 at line 25. Two independent linters, written by different people, agree that Impeccable’s own showcase uses the font Impeccable tells you not to use.

The same README lists “the rounded-square icon tile above every heading” as one of the tells it exists to remove. Its own two demos accumulate six icon-tile-stack findings.

Round 2 — each linter on the other’s showcase

Hallmark’s sloplint --render against Impeccable’s demos: 30 FAILs (9 on landing-demo, 21 on classic), plus 4 REFLEX and 5 WARN.

The failures split cleanly, and the split is the honest part. These are the static-mode counts (79 FAILs across the two demo pages), because that breakdown is exact:

GateFAILsWhat it isHouse style or craft?
4837colour/font literal outside a :root token blockHallmark house style
202no Hallmark stamp on line 1 of the CSSHallmark house style
2a6purple-to-blue gradientcraft
7a5pure #000 / #fff used as a colourcraft
30a7emoji used as an iconcraft
635arrow glued to link textcraft
194copy cliché, em-dash in copycraft
10a2transition: all / animating geometrycraft
26a2no :focus-visible stylingcraft
272motion without prefers-reduced-motioncraft
342no overflow-x: clipcraft
38i1<em>/<i> inside h1craft
542eyebrow above the headingcraft
672tracked uppercase label in a label rolecraft

In the render tier the same two pages add 30 more FAILs on layout gates that only exist when a browser is present — 26a (focus-ring contrast measured at 1.10:1), 34 (horizontal scroll at three widths), 49a (control labels wrapping to two lines), 40 (contrast threshold) and 58 (hero text budget).

Roughly half of the static FAILs are Hallmark’s conventions: 39 of 79 are the stamp (2) and the token block (37). A page that was not built by Hallmark will never carry Hallmark’s stamp, and any design system that does not route every literal through one :root block will trip gate 48 dozens of times. Discount those and Impeccable’s showcase still fails the portable half — including things its own README tells people to avoid.

The most consequential single finding is gate 34, because I could verify it without either tool:

imp landing   320px scrollWidth=693 clientWidth=320  OVERFLOW  ['DIV.nav-links right=524']
imp landing   375px scrollWidth=693 clientWidth=375  OVERFLOW
imp landing   390px scrollWidth=693 clientWidth=390  OVERFLOW
imp landing   768px scrollWidth=768 clientWidth=768  ok
imp classic   320px scrollWidth=689 clientWidth=320  OVERFLOW
hall atelier  320px scrollWidth=320 clientWidth=320  ok
hall bloom    320px scrollWidth=320 clientWidth=320  ok

Impeccable’s two demo pages genuinely scroll sideways on every phone-width viewport — 693px of content in a 320px window, with DIV.nav-links reaching right=524 — while Hallmark’s pages do not. Impeccable’s 62 rules include first-viewport-column-overflow and text-overflow, and none of them caught this. Hallmark’s gate 34 did, because it measures scrollWidth against clientWidth in a browser.

Impeccable’s detect against Hallmark’s 21 gallery pages: 41 findings, 4 pages clean.

RuleFindingsWhat it means
cream-palette9warm off-white page background, “the default ’tasteful’ AI surface”
straggler8a paragraph whose last line holds one word
italic-serif-display6italic serif display type
nested-cards5cards inside cards
low-contrast5contrast ratio below 4.5:1
overused-font4font on its overused list
line-length3measure too wide
cramped-padding1children flush against a border

cream-palette on 9 of 21 pages is the single most interesting verdict in this article, because Hallmark’s themes are built on exactly that surface: atelier’s tokens are oklch(94.5% 0.010 76) paper. One product’s curated material palette is the other product’s AI tell. There is no fact of the matter here; there is a real disagreement about taste, and both sides can cite their own rulebook.

italic-serif-display on 6 pages is the same kind of disagreement (Hallmark’s editorial genre leans on it deliberately). straggler on 8 pages and nested-cards on 5 are closer to craft defects, measurable in the browser and not obviously stylistic.

Round 3 — one of those 41 is a bug, not a finding

The static (non-rendered) scan of Hallmark’s gallery reported flat-type-hierarchy on 11 of 21 pages, with this snippet:

Role sizes: body 16px, h1 16px, h2 16px, h3 16px (largest adjacent step 1.00:1)

Every role at 16px, on a page whose headings are set through var(--text-display), which resolves to clamp(2.75rem, 5vw + 1rem, 5.25rem). Sixteen pixels is the browser default, not a measurement.

The cause is structural: Hallmark’s output links one stylesheet, and that stylesheet @imports the rest.

/* atelier-architect/style.css */
@import url("./tokens.css");   /* the clamp() scale lives here */
@import url("./base.css");     /* h1 { font-size: var(--text-display); } */

Rules that live in an @import-ed file are invisible to the static engine. I reproduced it with three fixtures:

FixtureDetector (static)Rendered h1
sizes inline in <style>clean56px
sizes in a single linked style.cssclean56px
style.css only @imports files holding the sizesflat-type-hierarchy, “h1 16px”80px
same, literal px instead of clamp()flat-type-hierarchy, “h1 16px”56px

Same HTML, same rendered result, different verdict. It is not about clamp() or CSS variables — the single-file fixture with clamp() passes. It is about which file the rule text lives in.

Run the same pages through the rendered engine and the rule disappears entirely: 0 of 21 pages report flat-type-hierarchy in URL mode. So this specific bug only affects impeccable detect <dir>, the mode its own README shows first and the mode a CI job would use. The 11 phantom findings inflate the static count I would otherwise have quoted, so: static 27 findings (11 of them this artifact), rendered 41 findings (none of them).

Impeccable’s docs are unusually candid about the general problem — “A clean detector run is evidence, not proof of visual or accessibility quality: it does not replace inspecting the rendered experience across relevant viewports” — but nothing in the docs warns that a linked-then-imported stylesheet defeats a rule.

Round 4 — the gate that fails open

Hallmark’s own README says:

The browser checks (sloplint --render, screenshots) also need npm i -g puppeteer-core and Chrome; without them the static checks still run.

That sentence is true for files. It is false for URLs, and the difference is load-bearing, because SKILL.md rule 16 tells the agent to run sloplint --render on what it just built — usually a dev server URL.

$ node skills/hallmark/scripts/sloplint.mjs --url http://127.0.0.1:8898/landing-demo/
sloplint: clean. 0 FAIL, 0 REFLEX, 0 WARN across 0 file(s) and 1 URL(s).
render tier not run: no puppeteer-core found locally, globally or via HALLMARK_PUPPETEER
$ echo $?
0

0 file(s) is the tell: in URL mode the page was never fetched for static analysis. The same page scanned as a file, in the same environment, reports 24 FAILs. I hit three separate failure modes and all three printed “clean” and exited 0:

EnvironmentReportExit
no puppeteer-coreclean. 0 FAIL … across 0 file(s) and 1 URL(s)0
puppeteer-core present, no CHROME_PATHclean. 0 FAIL … + render tier not run: no Chrome or Chromium found0
Chrome present, sandbox refuses to startclean. 0 FAIL … + a Chromium crash trace0

With all three fixed, the same command finds 9 FAILs on that page in 4 seconds.

This is the pattern worth internalising, and it is not specific to Hallmark: a gate that cannot run its checks and reports success is worse than a gate that is absent, because an agent reading 0 FAIL will ship. Hallmark does print a one-line note, and its JSON output carries "render": "not run: …" — but the number an agent acts on is the zero, and SKILL.md says “Fix every FAIL.”

Compare the contract on the other side. impeccable detect documents three exit codes — 0 clean, 2 findings, 1 “at least one requested target could not be scanned” — with “operational failure takes precedence for a partial multi-target scan.” That distinction between “found nothing” and “could not look” is exactly what sloplint collapses.

What both get right, on the record

An audit that only lists defects is an indictment, so:

  • Hallmark enforced its floor on its own work. 21/21 pages, 0 FAIL, in a browser, at six viewport widths. The REFLEX findings it does carry are stamped with reasons inside the CSS. That is the behaviour you want from a gate.
  • Hallmark’s gate 34 found a mobile bug in its competitor’s showcase that the competitor’s 62 rules missed. Measuring scrollWidth is unglamorous and it works.
  • Impeccable’s detector is a real binary with a real exit-code contract. --json, --github, --no-advisory, --viewport, --cdp, and 62 rule ids enumerated by name in docs/CLI-CONTRACT.md. One documented flag did not work for me: impeccable detect --list-rules, which the contract says “prints the detector catalog to stdout”, printed nothing at all on npm 4.7.0 (--json returned []), so enumerate rules from the doc instead. Its docs also state the limits of its own evidence.
  • Impeccable ships 90 tagged releases across a 2,534-commit history, so pinning is possible.
  • Both ship the linter as code, not as a promise. Neither asks you to trust a screenshot: sloplint.mjs is 231,622 bytes of readable JavaScript; the detector is a Rust workspace you can build.
  • Neither invents metrics in the product itself. Hallmark’s “26 issues → 0 issues” demo is labelled “The issue counts come from Hallmark’s linter” — self-judged, and it says so. Impeccable’s promotional LCP and bundle-size numbers are labelled as a demo, not a benchmark.

Which one to install

Not a ranking. A decision table.

If your situation is…Reach forBecause
A design gate in CI that must fail the buildImpeccableDocumented exit codes (0/2/1), --github annotations, no browser needed for the static rule set
Building marketing pages from scratch, with a curated lookHallmark48 themes, a browser-enforced floor, and photographs it credits instead of inventing
An existing design system you must not replaceImpeccable/impeccable document reads your tokens into DESIGN.md; Hallmark’s floor demands its own :root discipline
You want the strongest mobile/responsive gateHallmark’s sloplint --renderGate 34 catches horizontal overflow that Impeccable’s rules missed on Impeccable’s own page
Air-gapped or no-network CIImpeccableDeterministic rules run offline; Hallmark’s browser tier needs Chrome, and its URL mode silently no-ops without it
You need to pin a versionImpeccable90 releases/tags vs 0 for Hallmark
You have a tight context budgetImpeccable~3.1k always-on tokens vs Hallmark’s ~29.5k documented load set
You want the agent working in a fixed house styleHallmarkThe floor plus theme dealing is the whole product

If you install either, read the tool’s own failure mode before you trust its zero. For Hallmark that means checking that your run says 1 file(s) and not 0 file(s), and that render tier is not prefixed by not run. For Impeccable it means using URL mode when you care about layout, because the static engine cannot see a rule that lives behind @import.

Verification checklist

Roughly twenty minutes, no accounts, no API keys:

# 1. What you are really downloading
git clone --depth 1 https://github.com/Nutlope/hallmark.git
du -sb hallmark; find hallmark -name '*.jpg' -printf '%s\n' | awk '{s+=$1} END {print s}'

git clone --depth 1 https://github.com/pbakaus/impeccable.git
find impeccable -name font-index.json | xargs sha256sum | awk '{print $1}' | sort | uniq -c

# 2. Whether the counts are counts
python3 -c "import json;d=json.load(open('impeccable/skill/scripts/command-metadata.json'));print(len(d))"
grep -o 'Registry ([0-9]* ids' impeccable/docs/CLI-CONTRACT.md   # 62 rules, listed by name
ls hallmark/skills/hallmark/references/themes/*.md | wc -l        # 48 themes + README

# 3. Whether the gate actually ran
node hallmark/skills/hallmark/scripts/sloplint.mjs <a real page> --json | jq .summary
#    files: 0 and render: "not run" means nothing was checked

# 4. Whether the detector can see your stylesheet
impeccable detect --json path/to/your/page.html
impeccable detect --json path/to/your/page/          # directory, follows linked CSS
#    if the two disagree on type-scale rules, you have the @import blind spot

# 5. The cross-check neither tool offers
#    measure overflow yourself, in the browser, at 320 and 375

FAQ

Is Hallmark’s 64.9 MB repo what I install? No. The plugin ships “only the skill (7 MB, not the whole repo)”. skills/hallmark/ is 6,841,340 bytes. The other 58 MB is the marketing site and its photo library. The number matters only if you clone to read the source.

Does Impeccable really need 22 copies of a font index? It is a distribution choice, not a design flaw. The root harness folders are generated artifacts kept in main so npx skills, direct GitHub installs and submodules all work without a build step. AGENTS.md says so and names the workflow that regenerates them. It does cost 24.2 MB of the clone.

Why did the two linters disagree so hard? Because they measure different things on purpose. Hallmark grades a page against a fixed house floor (tokens, stamp, fold, control wrapping) and requires a browser for the layout rules. Impeccable grades a page against 62 named AI tells and general quality rules, and its strongest mode is also the browser. Each one’s showcase is clean by its own rules, and each one’s showcase is dirty by the other’s.

Is the flat-type-hierarchy finding real on my project? If your type scale lives in an @import-ed stylesheet and you scan a file or directory, no — it is a false positive, reproducible with three files and no framework. Confirm by rendering the page and comparing: I measured h1: 80px on a page the detector insisted was 16px everywhere.

Is sloplint reporting “clean” enough to ship? Only if the summary says files: ≥1 and the render tier ran. In URL mode without puppeteer-core or a launchable Chrome it prints clean. 0 FAIL … across 0 file(s) and exits 0 for a page that fails 24 checks when scanned as a file.

Which one has better taste? They do not agree, and the disagreement is data. Nine of Hallmark’s 21 pages read to Impeccable as cream-palette — “the default ’tasteful’ AI surface.” Six read as italic-serif-display. Hallmark’s whole theme catalog is built on those two choices. That is not a bug in either linter; it is the clearest signal that “anti-slop” is not one aesthetic.

Conclusion

Two products that both work, in ways that are legible and checkable, holding 118,552 stars and 259 watchers.

The useful finding is not that one beats the other. It is that the gates are complementary and neither is complete: Hallmark measures layout in a browser and catches a mobile overflow bug in Impeccable’s demo that all 62 of Impeccable’s rules missed; Impeccable measures tells exhaustively and reads Hallmark’s carefully themed gallery as nine pages of cream. Each one’s zero means “nothing in my rulebook fired,” and in Hallmark’s URL mode it can also mean “nothing ran.”

If you are choosing one today: Impeccable for CI, pinning and existing design systems; Hallmark for building new pages in a fixed, enforced house style. If you are choosing in the abstract, install the linter before you install the skill, run it against a page you already trust, and read what it says about the parts of your design you are proudest of. That reading tells you more about the tool than any number of stars.


Appendix: exact commands behind every figure

# repository measurements (working tree, no .git)
find . -path ./.git -prune -o -type f -printf '%s %p\n' | sort -rn | head

# duplicate detection
find impeccable -name font-index.json -not -path './.git/*' -exec sha256sum {} \; | awk '{print $1}' | sort | uniq -c

# static scan of the gallery
impeccable detect --json hallmark/site/made/atelier-architect/index.html

# rendered scan (the fair comparison)
(cd hallmark/site/made && python3 -m http.server 8899)
impeccable detect --json http://127.0.0.1:8899/atelier-architect/

# Hallmark's linter, render tier, on Impeccable's demos
export HALLMARK_PUPPETEER="$(npm root -g)/puppeteer-core"
export CHROME_PATH=/path/to/chrome
node hallmark/skills/hallmark/scripts/sloplint.mjs --url http://127.0.0.1:8898/landing-demo/ --json

# independent overflow measurement (neither tool)
# Playwright: page.setViewportSize({width:320,height:800}); document.documentElement.scrollWidth