vlmkit demo · judgment log

汐見窯 マグカップ 青磁

How this e-commerce product page was judged, in the order it happened: every gate run with its whole output, every screenshot that was looked at with what was seen in it, and where each defect came from. Each finished round keeps the pictures of one full-page walk per width; the other shots keep what was seen in them. Open the site.

The brief the builder was given
# Brief: e-commerce product page — 汐見窯 (Shiomi-gama) online shop

- **Directory**: `examples/sites/shop/`
- **Pattern**: e-commerce product page
- **Language**: Japanese (`lang="ja"`)

## What it is

The product page of a fictional pottery studio's online shop, for one mug:
**汐見窯 マグカップ 青磁**. One page, `index.html`, with a working cart drawer.

## Layout and behaviour

- **Header**: the shop name as a wordmark, navigation (新作 / うつわ / 作家 / 読みもの), a search
  button, and a cart button whose badge shows the number of items in the cart.
- **Breadcrumb**: ホーム / うつわ / マグカップ.
- **Gallery**: a large product image and four thumbnails (正面 / 側面 / 上から / 使用例) that switch it.
  The images are drawn with inline SVG or CSS — a mug, in the currently selected glaze. Keyboard
  operable.
- **Product panel**: name, price, rating (4.6, 128件のレビュー), three glaze swatches (青磁 / 白磁 /
  飴釉) whose names are always visible (the colour alone must not carry the choice), a size choice
  (S 240ml / M 320ml), a quantity stepper (1–10), the primary button カートに入れる, a secondary
  お気に入り toggle, the shipping note, and the stock line.
- **Cart drawer**: カートに入れる opens a drawer (a modal dialog) listing the line item with its glaze,
  size and quantity, the subtotal, a レジに進む button and a close button. It traps focus, closes on
  Escape and returns focus; the header badge updates.
- **Details**: an accordion — 商品詳細 / サイズ・容量 / お手入れ / 配送・返品.
- **Reviews**: a distribution of ★5 to ★1 as bars with counts, three reviews (name, fixed date,
  stars, text) and a もっと見る button that reveals three more.
- **Related products**: four cards (plate, bowl, cup, teapot) with drawn images, names and prices.
- **Footer**: a newsletter sign-up (email + 登録), links, and the copyright line.
- **Phones**: the gallery goes full width, and a bar pinned to the bottom of the screen carries the
  price and カートに入れる.

## Visual direction

Calm, warm and crafted: an off-white paper ground, ink-dark text, a celadon accent, generous
whitespace, Japanese typography with room to breathe (line-height around 1.8), tabular figures
for prices.

## Required copy

```
汐見窯 マグカップ 青磁
¥4,180(税込)
128件のレビュー
青磁
白磁
飴釉
カートに入れる
5,000円以上のご注文で送料無料
在庫あり(残り3点)
商品詳細
お手入れ
配送・返品
レジに進む
© 2026 汐見窯
```

## States to show (final round)

Desktop and mobile full page; a different glaze and thumbnail selected; the cart drawer open with
two of the mug in it; one accordion section open; the extra reviews revealed; the pinned bottom
bar on a phone mid-page.

## Gates this brief leans on

`check interactions` (swatches, size, stepper, accordion, drawer), `check a11y focus` (the drawer),
`check a11y touch`, `check color` (swatches must not be colour-only), `check copy` on Japanese,
`check integrity` (Japanese line breaking), `check scroll` (the pinned bar), `check grounding`
(can an agent that only sees the screenshot find カートに入れる?).

Defects

DefectFound byWhatFixChecked by
D1eye L1 on S1

svg #crackle (every mug view)

The celadon crackle is drawn as a bold, regular polygon net of ~13 large cells; it reads as a honeycomb/football pattern stuck on the body, not as fine glaze crackle, and makes the body busy (worst at tablet size, S3).

Replaced the 13-cell net with a fine, irregular crackle: a seeded jittered grid (23px step, ±8.5px jitter), 42% of edges dropped or demoted so cell sizes vary, each edge bent through a jittered midpoint; 258 main segments at 0.8px and 84 finer ones at 0.55px/60%, all at --crackle .30 (was .34 on far heavier lines). The top view now uses the same network untranslated.

Second attempt, after L8-L10 showed the jittered grid still reading as rows of tiles: the crackle is now a Voronoi network of 124 cells from seeded Poisson-disk points (irregular polygons meeting at three-way junctions), 14% of edges dropped as unfinished cracks, the rest split 1:2 into strong (0.8px) and faint (0.55px at 55%) lines, each bent through two jittered points. The outside network is wrapped onto the cylinder (x = 300 + R·sin θ, y shifted by 24·cos θ for the rim ellipse), so cells narrow toward the sides; the well seen from above gets its own flat network (#crackle-flat).

L11
D2eye L1 on S1

#mug-front / #mug-side glaze drips at the foot

The three glaze drips are dark round blobs hanging below the glaze line; at display size they read as little feet under the mug rather than glaze that ran.

Removed the three dark blobs. The foot's top edge is now a wavy line with two shallow tongues where the glaze ran lower (front at x≈239/358, side at x≈277/390), traced by a 1.6px g-deep line at 40%; the throwing lines went from 2px/14% to 1.6px/10%.

L8
D3eye L2 on S2

.footer-nav at 375px

At 375px the third footer column sits alone in a half-width cell and 特定商取引法に基づく表記 wraps to leave a single 記 on its own line.

Below 600px the third footer column spans both columns, and footer link labels use word-break: auto-phrase so a label that does wrap breaks between phrases.

L13
D4eye L4 on S4

#buybar

The pinned bar is translucent enough that the page text under it shows through as grey ghost text beside its own price and variant lines (S2, S3, S4, S5).

The pinned bar's background is now opaque (--card) instead of rgba(252,250,246,.97); top hairline and shadow kept.

L14
D5eye L3 on S3

.lead, .review-body at 600-899px

In the single-column regime the lead paragraph and the review bodies run the full 720px, about 46 Japanese characters a line — too long a measure to read comfortably.

Running text gets a reading measure: .lead max-width 36em, .review-body 38em, accordion paragraphs 40em (about 36-40 characters a line at 15px).

L16
D6gate G2

p.price

check copy cannot find ¥4,180(税込) although it looks right on screen: .price is a flex container, so the amount and (税込) become separate block-level items and the page's text is ¥4,180 / (税込) with a break between them (copy-paste and text extraction get the break too).

.price is no longer a flex container; the amount and (税込) are plain inline runs on one baseline, so the text is one string: ¥4,180(税込).

G22
D7gate G18

div.nl-row (newsletter email + 登録)

At 320px the newsletter row is 324px wide and the page scrolls horizontally by 20px (sweep-overflow in G17, named in G18): the email input's intrinsic width sets the row's min-content, so the 登録 button is pushed past the edge. The search row has the same structure.

.field gets width:100% (a percentage-width input contributes no min-content), and the newsletter and search forms get grid-template-columns: minmax(0,1fr), so neither row can be wider than its column.

G23
D8gate G3

h2#nl-title

h2 renders in three styles: the section titles (26px, x3), the footer column labels (13px/700, x3) and the newsletter title alone at 20px — a one-off heading size with no role of its own.

The newsletter title uses the page's section-title style (serif, 22/26px, .14em) and the one-off .footer-title rule is gone: h2 is now section titles (x4) and footer column labels (x3).

G26
D9gate G12

#qty-inc / #qty-dec

The stepper buttons give no observable response to Enter (inert-control): the new value lands only in the input's value, so a screen-reader user pressing + or − hears nothing, and pressing − at 1 gives no feedback at all.

Added an sr-only role=status line under the buy row. The − / + buttons now say 数量 N点 after each step, and 数量は1点からです / 数量は10点までです when pressed at a bound.

G27
D10eye L21 on S21

.care-list .care-mark

The two care pills have different widths (使えます vs 使えません), so the labels after them start ~6px apart and the two-row list has a ragged left edge.

Care pills get a fixed width (7.5em, flex:none) instead of a min-width, so both are the same width and the labels after them share one left edge.

L31
D11eye L22 on S22

#acc-size .spec-table

The size table stretches over the full 650px accordion width; S and M values sit 200+px apart, so comparing the two sizes means crossing empty space.

The size table is capped at 28em (≈392px); S and M sit next to each other instead of 200px apart.

L31
D12eye L23 on S23

.review-summary (desktop)

With the extra reviews open, the left third of the section is empty for a full screen: the short summary card scrolls away at the top, leaving the layout lopsided and the distribution out of sight while reading.

On desktop the review summary card is position: sticky; top: 24px inside its grid column, so it stays beside the reviews while they scroll and the distribution stays in view.

L34
D13eye L28 on S28

#qty-note

The made-to-order note breaks inside いただきます (ただきます。 alone on line 2) and is plain grey caption text, not recognisable as a notice about a longer delivery time.

The made-to-order note is styled as a notice (paper-2 fill, 3px ochre rule on the left, ink text) and uses word-break: auto-phrase, so it breaks between phrases (いただきます stays whole).

L32
D14eye L29 on S29

#nl-email[aria-invalid=true]

An invalid address changes only the message line under the row; the field itself keeps its normal look, so the error is not marked where the user is looking.

An invalid email field now shows its own error state (2px salmon ring on the dark footer; a dark red border for fields on paper), and the state clears as soon as the typed address becomes valid.

L33
D15eye L35 on S35

#cart-empty

The empty cart drawer is a single grey line in an otherwise blank 800px panel, with no picture and no way forward except the × — it reads as unfinished and gives no next step.

The empty drawer now has a line-drawn mug (64px, control-grey strokes), カートに商品はありません。 in ink bold, a supporting line 気になるうつわがあれば、カートに入れてお進みください。 and an outlined 買い物を続ける button that closes the drawer; flow.json gained two steps for it.

L38
D16eye L50 on S50

#acc-detail .spec-list

In 商品詳細 the spec list's top rule sits ~7px under the paragraph's glyphs: .spec-list { margin: 0 } has the same specificity as the panel's .acc-panel > * + * rhythm rule and comes later, so the list loses its 16px while the note after it keeps its own.

The panel rhythm rule is now .acc-panel > :not(:first-child) { margin-top: 16px } — specificity (0,2,0), so it beats .spec-list / .care-list { margin: 0 } while a first child still starts flush.

L53
D17eye L53 on S53

.acc-panel .note

The small notes in the accordion break mid-word with a short tail: 個体差があり / ます。 in 商品詳細 (3 characters alone), 5mm下ま / での目安です。 in サイズ・容量.

Accordion notes use word-break: auto-phrase (as the headings, footer links and the quantity notice already do), so a short note breaks between phrases instead of leaving a syllable tail.

L54

Rounds

R1 · first draft

builder
N1decision

Gate set, fixed up front. The protocol's final set: check integrity (1280/768/375; Japanese line breaking), check copy --manifest copy.txt, check design, check composition, check color (swatches must not be colour-only; field boundaries), check a11y contrast (one theme: the brief defines no theme parameter and asks for one paper ground, so there is no dark theme to sweep), check a11y focus, check a11y touch, scan scroll (1280 and 375), scan handlers, check interactions (--max-elements 80, the page has more than the default 30 controls). Added for this brief: check scroll at 375x740 (the pinned bottom bar must hold its position), check grounding at 1280x720 and 375x740 (can a screenshot-only agent find カートに入れる — so the button must be above the fold at 1280x720), check breakpoints --sweep (layout changes at 600px and 900px, the pinned bar appears below 900), verify flow --flow flow.json (interactions only proves ARIA transitions; the flow proves the badge count, line items, subtotal and focus return are actually right), scan handlers --probe input (a Japanese shop: IME typing into the search, email and quantity fields), check motion (the drawer slide-in must honour prefers-reduced-motion). check animation is not in the set: nothing animates on load; the only motion is the drawer's 320ms slide on open, which check motion covers declaratively.

S1

index.html · 1280×800 · full page, 4 screen(s)

S1 screen 1S1 screen 2S1 screen 3S1 screen 4
L1 saw

Desktop 1280x800, 4 screens. Screen 1 reads well at first glance: wordmark (celadon seal + 汐見窯 / SHIOMI-GAMA) left, nav centred with うつわ underlined in celadon, 検索 and カート with a grey "0" badge right; breadcrumb ホーム / うつわ / マグカップ. Gallery is a vertical rail of four labelled thumbnails (正面 selected: dark border, bold label) beside a 596px square stage; the panel on the right carries 汐見 透 作, the h1 on one line, ¥4,180(税込), 4.6 stars + underlined 128件のレビュー, the three swatches with names (青磁 ringed and bold), S/M size cards, the − 1 + stepper, カートに入れる (dark celadon, bag icon) beside an outlined お気に入り, then a hairline and three assurance lines. The CTA's bottom edge is at about y=617, so it is above a 720px fold. What looks wrong: the crackle on the mug is drawn as a bold, regular polygon net (13 cells, dark lines) — it reads as a honeycomb / football pattern pasted on the body, not as fine glaze crackle, and together with the three white throwing lines the body is busy. The three glaze drips at the foot are dark round blobs hanging under the glaze line; at this size they read as little feet. The stage bottom lands at about y=725, a few px under a 720 fold (the CTA is still clear). Screen 2: 商品について with a four-line lead and a signature line on the left, the four-row accordion (+ icons) on the right, tops aligned; reviews start with a summary card (4.6 / 5, stars, distribution bars) and the first review. Screen 3: reviews 2–3, an outlined もっと見る with a chevron, then 同じ窯のうつわ with a right-aligned text link and four cards. Screen 4: plate, bowl, yunomi, kyusu drawings (each small in its square, sitting low), names and prices; dark footer with 汐見窯だより, a white email field + 登録, three link columns, © 2026 汐見窯 and the fictional-shop disclaimer. Vertical rhythm between sections (~150px with a hairline) is even. Headings render in Gothic here (no Mincho on this machine), as expected.

D1 defect svg #crackle (every mug view)

The celadon crackle is drawn as a bold, regular polygon net of ~13 large cells; it reads as a honeycomb/football pattern stuck on the body, not as fine glaze crackle, and makes the body busy (worst at tablet size, S3).

D2 defect #mug-front / #mug-side glaze drips at the foot

The three glaze drips are dark round blobs hanging below the glaze line; at display size they read as little feet under the mug rather than glaze that ran.

S2

index.html · 375×812 · full page, 7 screen(s)

S2 screen 1S2 screen 2S2 screen 3S2 screen 4S2 screen 5S2 screen 6S2 screen 7
L2 saw

Mobile 375x812, 7 screens. Screen 1: header row (wordmark, search icon, bag icon with "0" badge) and a second row of four nav items with うつわ underlined; breadcrumb; the stage is full-bleed and square, the four thumbnails sit in a row under it with labels; 汐見 透 作 and the h1 fit on one line; the pinned bar at the bottom shows "青磁・S 240ml / ¥4,180(税込)" and a dark カートに入れる. Screen 2: price, rating, swatches, full-width S/M cards, the stepper on its own row, full-width カートに入れる and お気に入り stacked, the assurance lines — and the pinned bar has correctly stepped aside because the panel's own button is on screen. Screens 3–5: lead paragraph (five lines, ordinary Japanese character breaks), accordion, summary card with bars, reviews, もっと見る, 2-up related cards; the bar is back at the bottom. Two things look off. (a) Text behind the pinned bar seems to show through it faintly — on screen 4 and 5 fragments of review text are visible inside the bar next to the price; I need a close-up to confirm. (b) Screen 7, footer: the third link column 汐見窯について sits alone in a half-width column, and 特定商取引法に基づく表記 wraps to leave a single 記 on its own line — an orphaned character. Everything else checked: no horizontal overflow visible, tap targets look ample, the footer's bottom padding keeps the disclaimer clear of the bar.

D3 defect .footer-nav at 375px

At 375px the third footer column sits alone in a half-width cell and 特定商取引法に基づく表記 wraps to leave a single 記 on its own line.

S3

index.html · 768×1024 · full page, 5 screen(s)

S3 screen 1S3 screen 2S3 screen 3S3 screen 4S3 screen 5
L3 saw

Tablet 768x1024, 5 screens (single-column regime, below 900). Screen 1: header keeps its 検索 / カート labels and badge; the nav row spreads four items across the full width; the stage is 720x540 (4:3, rounded) with the mug large and centred; the thumbnail strip (4 x 104px) is left-aligned under it; 汐見 透 作 and the h1 follow, and the pinned bar sits at the bottom. At this size the crackle is at its worst: big dark polygons across the whole body, like a turtle-shell net. The bar again shows ghost text through it — the price and 128件のレビュー are faintly legible inside the bar at y≈960–1005. Screen 2: price, rating, swatches; S/M cards (≈270px each) share a row with the stepper; カートに入れる and お気に入り share a row; the assurances. The lead paragraph under 商品について runs the full 720px, about 46 characters a line — a long measure for Japanese text. Screen 3: accordion rows, then レビュー with the summary card stretched to 720px (bars ≈580px long) and the first review; review bodies also run ~46 characters a line. Screens 4–5: もっと見る, four related cards in one row (≈162px each), dark footer with the newsletter field and three link columns (特定商取引法に基づく表記 fits on one line here), © 2026 汐見窯 and the disclaimer. No overflow, clipping or overlap seen.

D5 defect .lead, .review-body at 600-899px

In the single-column regime the lead paragraph and the review bodies run the full 720px, about 46 Japanese characters a line — too long a measure to read comfortably.

S4

pinned bar close-up over reviews

index.html · 375×812 · element #buybar · @2x · scroll-to #reviews

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L4 saw

Close-up (2x) of the pinned bar at 375 wide, scrolled to the reviews. The bar holds 青磁・S 240ml over ¥4,180(税込) on the left and a dark celadon カートに入れる on the right; type is crisp and the button's label is centred. But the review underneath is plainly visible through the bar: the title 貫入が育っていくのが楽し… and the meta line 年8月3日 青… sit as grey ghost text behind the variant and price lines. The bar is translucent enough that page text competes with its own text — it confirms the suspicion from S2/S3. The top hairline and shadow read correctly.

D4 defect #buybar

The pinned bar is translucent enough that the page text under it shows through as grey ghost text beside its own price and variant lines (S2, S3, S4, S5).

G1exit 0vlmkit check integrity index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)

verdict clean · findings 0 · fails 0 · warns 0 · exempted 24 · viewports 3

output, 27 line(s), 5.7s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)
  1280x800: 8 component(s), ink 26.3%, 110 text block(s)
  768x900: 8 component(s), ink 29.0%, 113 text block(s)
  375x700: 8 component(s), ink 32.8%, 113 text block(s)

No integrity defects detected.

Exempted candidates (the tool's call — audit the rule, not the page):
  - [text-clipped] span.badge > span:nth-of-type(2) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #search-toggle > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #cart-open > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  … 9 more
G2exit 1vlmkit check copy index.html --manifest copy.txt

missing 2 · placeholders 0 · manifestLines 14 · statesExplored 9 · revealedOnly 0

output, 11 line(s), 1.9s
vlmkit check copy
source: index.html

status: suspect
rendered text: 1084 chars
disclosure states: 9 explored (details / tabs / aria-expanded)
manifest: 14 line(s), missing 2

Issues:
  x copy-missing: Manifest line not found in rendered text or any of 9 revealed disclosure state(s): "¥4,180(税込)" (comparison is whitespace-normalized, case-sensitive).
  x copy-missing: Manifest line not found in rendered text or any of 9 revealed disclosure state(s): "レジに進む" (comparison is whitespace-normalized, case-sensitive).
D6 defect p.price

check copy cannot find ¥4,180(税込) although it looks right on screen: .price is a flex container, so the amount and (税込) become separate block-level items and the page's text is ¥4,180 / (税込) with a break between them (copy-paste and text extraction get the break too).

G3exit 0vlmkit check design index.html

verdict: DRIFT (3 finding(s))

verdict drift · drifting 3 · roles 11

output, 32 line(s), 1.6s
vlmkit check design
source: index.html

verdict: DRIFT (3 finding(s))
  exits 0 — 3 warn(s) did not fail this command. To gate on one: --rule component-drift=suspect
  roles judged: 6 of 11 seen, spacing values: 22
  coverage: 42 of 315 visible element(s) carried an inferable role; 4 skipped as non-resting
    no role: span x82, div x30, li x30, a x26, svg x22, p x16, +18 more tag(s)
    A role comes from role="..." or from button/input/select/textarea/h1-h6. Layout elements
    (div, span, p, a) have none, so a large skip count is normal — this gate judges components,
    not every box. Add role="..." where an element IS a component to widen the coverage.
  text-free: 8 (0 judged on box alone — font-size/weight is not observable without painted text)

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  button          11 inst    6 styles  reuse  1.83x  3 one-off  drift
  h2               7 inst    3 styles  reuse  2.33x  1 one-off  drift
  h3               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  img              6 inst    1 styles  reuse     6x  0 one-off  ok
  tab              3 inst    1 styles  reuse     3x  0 one-off  ok
  input:radio      3 inst    2 styles  reuse   1.5x  1 one-off  drift
  tablist          1 inst    1 styles  reuse     1x  1 one-off  not judged
  tabpanel         1 inst    1 styles  reuse     1x  1 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  spinbutton       1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: tablist (1), tabpanel (1), h1 (1), spinbutton (1), input:email (1) — under --min-instances 3, so no finding can come from them.
  To keep judging them: --min-instances 2 --min-reuse 2 (both — a 2-instance role cannot reach 3x however many instances the floor allows).

Findings
  ! [component-drift] button: 11 "button" elements render 6 distinct styles (used 4x, 2x, 2x, 1x, …; a system reuses each style 3x or more, and this role averages 1.83x). Dominant style, used 4x: padding 12/4/12/4, radius 0, 16px/600, border 0, bg rgba(0, 0, 0, 0). Deviating: button#search-toggle (padding 0/10/0/10, radius 8, 14px/400, border 0, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 10, padding-bottom 12 → 0 and 4 more; button#fav (padding 0/22/0/22, radius 8, 15px/700, border 1, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more; button#add-to-cart (padding 0/22/0/22, radius 8, 16px/700, border 1, bg rgb(47, 97, 83)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more and 2 more. This reports inconsistency, not which style is correct.
  ! [component-drift] h2: 7 "h2" elements render 3 distinct styles (used 3x, 3x, 1x; a system reuses each style 3x or more, and this role averages 2.33x). Dominant style, used 3x: padding 0/0/0/0, radius 0, 26px/600, border 0, bg rgba(0, 0, 0, 0). Deviating: nav.footer-nav>div.footer-col>h2.footer-heading (padding 0/0/0/0, radius 0, 13px/700, border 0, bg rgba(0, 0, 0, 0)) — differs in font-size 26 → 13, font-weight 600 → 700; h2#nl-title (padding 0/0/0/0, radius 0, 20px/600, border 0, bg rgba(0, 0, 0, 0)) — differs in font-size 26 → 20. This reports inconsistency, not which style is correct.
  ! [component-drift] input:radio: 3 "input:radio" elements render 2 distinct styles (used 2x, 1x; a system reuses each style 3x or more, and this role averages 1.5x). Dominant style, used 2x: padding 0/0/0/0, radius 50, 16px/400, border 1, bg rgba(0, 0, 0, 0). Deviating: div.sizes>label.size>input (padding 0/0/0/0, radius 8, 16px/400, border 1, bg rgb(252, 250, 246)) — differs in border-radius 50 → 8, background-color rgba(0, 0, 0, 0) → rgb(252, 250, 246). This reports inconsistency, not which style is correct.
D8 defect h2#nl-title

h2 renders in three styles: the section titles (26px, x3), the footer column labels (13px/700, x3) and the newsletter title alone at 20px — a one-off heading size with no role of its own.

G4exit 0vlmkit check composition index.html

verdict: COMPOSED (0 finding(s))

verdict composed · proximity 0 · flatSteps 0 · railNearMisses 0

output, 17 line(s), 1.7s
vlmkit check composition
source: index.html

verdict: COMPOSED (0 finding(s))
  measured: 0 label(s), 3 heading level(s), 60 wide block(s) on 5 left / 4 right rail(s) — from 267 visible box(es)
  11 label(s) not judged: they open a box that paints its own group edge, so nothing above them could be mis-grouped with

Type hierarchy (largest instance of each declared level)
  h1     30px / 600   h1#product-title
  h2     26px / 600   h2#about-title
  h3     16px / 600   div.accordion>div.acc-item>h3.acc-heading
  body 13px, largest 52px (4x), heaviest +300 weight

Group gaps: 0px between heading-led groups vs 8px inside them (0x, 12 sample(s)). Context only — intact pages measure 0.86-3.00x, so this cannot carry a verdict.

Proximity, alignment and type hierarchy all read consistently.
G5exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f7f3ec · bodyInk #23211d · linkInk #b8b1a5 · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

output, 28 line(s), 1.6s
vlmkit check color
source: index.html

verdict: CONSISTENT (0 finding(s))
  measured: 2 control(s), 26 link(s) in a text flow — from 300 visible box(es)

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  4 distinct
    #f7f3ec   75.9%     4 el  
    #efe9df   12.4%     5 el  section.product>div.gallery>div.stage
    #1f2b27    9.1%     1 el  footer.site-footer
    #fcfaf6    2.6%     3 el  div.sizes>label.size>input
  ink       8 distinct
    #23211d   56.5%    39 el  a.wordmark>span.wordmark-text>span.wordmark-ja
    #4a453e   16.6%    36 el  ul>li>a
    #b8b1a5    9.5%    13 el  div.footer-inner>section.newsletter>p.nl-lead
    #686157    7.6%    21 el  a.wordmark>span.wordmark-text>span.wordmark-en
    #ece6dc    5.7%     6 el  h2#nl-title
    …and 3 more
  marks     6 distinct
    #ddd5c8   54.6%    25 el  header.site-header
    #cbc2b3   17.4%     5 el  main#main>section.about>div.accordion
    #8a8277   11.6%    34 el  div.swatches>label.swatch>input
    #ece6dc    6.3%     1 el  footer.site-footer>div.footer-bottom
    #23211d    5.6%     8 el  button#tab-front>span.thumb-img
    …and 1 more
  base #f7f3ec, body ink #23211d, link ink #b8b1a5 on 11 element(s)
G6exit 0vlmkit check a11y contrast index.html

inspected 119 · failures 0

output, 5 line(s), 1.5s
  vlmkit check a11y contrast
  html: examples/sites/shop/index.html
  inspected 119 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/shop/test-results/a11y-contrast/index-07f7b4b9/report.md
G7exit 1vlmkit check a11y focus index.html

steps 43 · findings 4

output, 9 line(s), 1.8s
  vlmkit check a11y focus
  source: index.html
  captured 43 focus step(s)
  ✗ 4 finding(s)
    [reverse] Focus moved up by 233px (from `main#main>section.product.container>div.panel>div.buy-row>button#fav` at y=561 to `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn` at y=328). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [reverse] Focus moved up by 187px (from `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn` at y=523 to `main#main>section#reviews>div.reviews-grid>div.review-list>button#more-btn` at y=336). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [skip-row] Focus jumped down by 216px (from `main#main>section#reviews>div.reviews-grid>div.review-list>button#more-btn` to `main#main>section.related.container>div.section-head>a.text-link`). Confirm no focusable element was unintentionally skipped.
    [reverse] Focus moved up by 173px (from `main#main>section.related.container>div.section-head>a.text-link` at y=552 to `main#main>section.related.container>ul.cards>li.card>a.card-link` at y=379). Visual order is top-to-bottom; check `tabindex` or DOM order.
  report: examples/sites/shop/test-results/a11y-focus-order/index-07f7b4b9/report.md
G8exit 0vlmkit check a11y touch index.html

level AA · inspected 49 · failures 0 · wcagExempt 0

output, 5 line(s), 1.7s
  vlmkit check a11y touch
  source: index.html  level: WCAG AA (24×24 min)
  inspected 49 interactive element(s)
  ✓ 0 undersized target(s)
  report: examples/sites/shop/test-results/a11y-touch/index-07f7b4b9/report.md
G9exit 0vlmkit scan scroll index.html

containers 0 · overflowX 0 · issues 6

output, 18 line(s), 1.5s
vlmkit scan scroll
source: index.html (1280x720)

status: warn
  exits 0 — 6 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 1280x3066 — horizontal overflow 0px, vertical scroll 2346px
scroll containers: 0 (dead scrollports 1, clipped 6)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G10exit 0vlmkit scan scroll index.html --viewport 375x740

containers 0 · overflowX 0 · issues 8

output, 20 line(s), 1.3s
vlmkit scan scroll
source: index.html (375x740)

status: warn
  exits 0 — 8 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 375x5042 — horizontal overflow 0px, vertical scroll 4302px
scroll containers: 0 (dead scrollports 1, clipped 8)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content #cart-open > span:nth-of-type(1): #cart-open > span:nth-of-type(1) clips 42px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content #search-toggle > span:nth-of-type(1): #search-toggle > span:nth-of-type(1) clips 28px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G11exit 0vlmkit scan handlers index.html

registrations 38 · elements 30 · suspects 0

output, 40 line(s), 1.7s
vlmkit scan handlers
source: index.html

status: 1 warn(s)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
registrations: 38 across 30 element(s), on a page presenting 49 control(s)

  - fieldset.option>div.swatches>label.swatch>input "seiji": change
  - fieldset.option>div.swatches>label.swatch>input "hakuji": change
  - fieldset.option>div.swatches>label.swatch>input "ameyu": change
  - fieldset.option>div.sizes>label.size>input "S": change
  - fieldset.option>div.sizes>label.size>input "M": change
  - section.product>div.gallery>div.thumbs>button#tab-front "正面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-side "側面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-top "上から": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-use "使用例": click, keydown
  - div.options-row>div.option>div.stepper>button#qty-dec "数量を1つ減らす": click
  - div.options-row>div.option>div.stepper>button#qty-inc "数量を1つ増やす": click
  - div.options-row>div.option>div.stepper>input#qty "1": keydown, input, compositionend, change (no role)
  - section.product>div.panel>div.buy-row>button#fav "お気に入り": click
  - section.product>div.panel>div.buy-row>button#add-to-cart "カートに入れる": click
  - aside#buybar>button.btn "カートに入れる": click (no role)
  - header.site-header>div.header-inner>div.header-actions>button#cart-open "カート 0点": click
  - dialog#cart-drawer "カート カートに商品はありません。 あと¥5,000で送料無料になります。 小計": close, click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-head>button#cart-close "カートを閉じる": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-body>ul#cart-lines "": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button#checkout "レジに進む": click (no role)
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn "商品詳細": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-size-btn "サイズ・容量": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-care-btn "お手入れ": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn "配送・返品": click
  - section#reviews>div.reviews-grid>div.review-list>button#more-btn "もっと見る": click
  - header.site-header>div.header-inner>div.header-actions>button#search-toggle "検索": click
  - header.site-header>div#search-panel "キーワードで探す 検索する": keydown (no role)
  - header.site-header>div#search-panel>form#search-form "キーワードで探す 検索する": submit (no role)
  - footer.site-footer>div.footer-inner>section.newsletter>form#nl-form "メールアドレス 登録": submit (delegation container)

Issues:
  warn [unprobed-handler-types] 7 handler type(s) registered and NONE exercised: change, click, close, compositionend, input, keydown, submit — this gate is an inventory and presses nothing. A clean result here says the wiring exists, not that it works. Run 'check interactions --handlers' to focus and activate the controls, add '--probe-drag' for the drag surfaces, or drive the rest with a 'verify flow' script.
G12exit 0vlmkit check interactions index.html --max-elements 80

elements 48 · suspects 0 · warns 2

output, 59 line(s), 21.8s
vlmkit check interactions
source: index.html

status: ok
  exits 0 — 2 warn(s) did not fail this command. To gate on one: --rule inert-control=suspect
interactive elements: 48

  - [link] "本文へスキップ" focus✓
  - [link] "汐見窯 SHIOMI-GAMA" focus✓
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [button] "カート 0点" focus✓ | Enter: focus moves within | opens dialog (focus enters), traps | Esc closes+returns focus
  - [link] "ホーム" focus✓
  - [link] "うつわ" focus✓
  - [link] "マグカップ" focus✓
  - [tab] "正面" focus✓ | ArrowRight: selected true -> false
  - [tab] "側面" unreachable | ArrowRight: focus moves
  - [tab] "上から" unreachable | ArrowRight: focus moves
  - [tab] "使用例" unreachable | ArrowRight: focus moves
  - [link] "128件のレビュー" focus✓
  - [radio] "seiji" focus✓ | ArrowDown: focus moves
  - [radio] "hakuji" unreachable | ArrowDown: focus moves
  - [radio] "ameyu" unreachable | ArrowDown: focus moves
  - [radio] "S" focus✓ | ArrowDown: focus moves
  - [radio] "M" unreachable | ArrowDown: focus moves
  - [button] "数量を1つ減らす" focus✓ | Enter: no response
  - [button] "数量を1つ増やす" focus✓ | Enter: no response
  - [button] "カートに入れる" focus✓ | Enter: focus moves within | announces
  - [button] "お気に入り" focus✓ | Enter: pressed false -> true | announces
  - [button] "商品詳細" focus✓ | Enter: expanded false -> true
  - [button] "サイズ・容量" focus✓ | Enter: expanded false -> true
  - [button] "お手入れ" focus✓ | Enter: expanded false -> true
  - [button] "配送・返品" focus✓ | Enter: expanded false -> true
  - [button] "もっと見る" focus✓ | Enter: expanded false -> true
  - [link] "うつわをすべて見る" focus✓
  - [link] "平皿 白磁 21cm ¥3,520(税込)" focus✓
  - [link] "小鉢 青磁 ¥2,640(税込)" focus✓
  - [link] "湯呑 飴釉 ¥2,860(税込)" focus✓
  - [link] "新作 急須 青磁 360ml ¥9,900(税込)" focus✓
  - [textbox] "" focus✓
  - [button] "登録" focus✓ | Enter: layout change | announces
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [link] "配送・送料" focus✓
  - [link] "返品・交換" focus✓
  - [link] "よくあるご質問" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "工房のこと" focus✓
  - [link] "特定商取引法に基づく表記" focus✓
  - [link] "プライバシーポリシー" focus✓

Issues:
  warn [inert-control] button "数量を1つ減らす" (div.options-row>div.option>div.stepper>button#qty-dec) shows no observable response to Enter — no ARIA change, no layout change. Dead control, or its response is outside this probe.
  warn [inert-control] button "数量を1つ増やす" (div.options-row>div.option>div.stepper>button#qty-inc) shows no observable response to Enter — no ARIA change, no layout change. Dead control, or its response is outside this probe.
D9 defect #qty-inc / #qty-dec

The stepper buttons give no observable response to Enter (inert-control): the new value lands only in the input's value, so a screen-reader user pressing + or − hears nothing, and pressing − at 1 gives no feedback at all.

G13exit 0vlmkit check scroll index.html --viewport 375x740

pageScrolled 1110 · stickyFixed 1 · engagedSticky 0 · snaps 0 · issues 0

output, 12 line(s), 1.4s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1110px
sticky/fixed elements: 1 (sticky engaged by the scroll: 0)
snap containers driven: 0

Sticky / fixed:
  - #buybar: fixed top=671px viewport y 671 -> 671

No scroll-behavior issues detected.
G14exit 0vlmkit check grounding index.html --viewport 1280x720

targets 24 · scale 0.5 · issues 1

output, 33 line(s), 1.3s
vlmkit check grounding
source: index.html (1280x720)

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule ambiguous-target=suspect
frame: 640x360 screenshot px — medium, cap 640x480, scale 0.50 (every coordinate below is in these 640x360 pixels)
targets: 24 actionable in frame (25 disabled or out of the frame)

Action map (click point in screenshot px):
  t2 link "汐見窯 SHIOMI-GAMA" @ (126,18) 211x29 a.wordmark
  t3 link "新作" @ (254,18) 30x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t4 link "うつわ" @ (294,18) 38x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t5 link "作家" @ (334,18) 30x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t6 link "読みもの" @ (378,18) 46x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)
  t7 button "検索" @ (545,18) 38x22 #search-toggle
  t8 button "カート 0 点" @ (595,18) 58x22 #cart-open
  t9 link "ホーム" @ (30,50) 20x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t10 link "うつわ" @ (62,50) 20x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t11 link "マグカップ" @ (101,50) 33x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t12 tab "正面" @ (41,92) 42x54 #tab-front
  t13 tab "側面" @ (41,152) 42x54 #tab-side
  t14 tab "上から" @ (41,212) 42x54 #tab-top
  t15 tab "使用例" @ (41,272) 42x54 #tab-use
  t16 link "128件のレビュー" @ (488,139) 55x15 a.rating-link
  t17 radio "seiji" @ (411,188) 22x22 div.swatches > label:nth-of-type(1) > input:nth-of-type(1)
  t18 radio "hakuji" @ (444,188) 22x22 div.swatches > label:nth-of-type(2) > input:nth-of-type(1)
  t19 radio "ameyu" @ (477,188) 22x22 div.swatches > label:nth-of-type(3) > input:nth-of-type(1)
  t20 radio "S" @ (433,255) 67x24 div.sizes > label:nth-of-type(1) > input:nth-of-type(1)
  t21 radio "M" @ (504,255) 67x24 div.sizes > label:nth-of-type(2) > input:nth-of-type(1)
  … 4 more — --json emits the full map

Issues:
  ! ambiguous-target: 2 links in the frame all read "うつわ" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.
G15exit 0vlmkit check grounding index.html --viewport 1280x720 --json

targets 24 · scale 0.5 · issues 1

output, 1615 line(s), 1.4s
{
  "gate": "check.grounding",
  "command": "check grounding",
  "verdict": "pass",
  "counts": {
    "suspect": 0,
    "warn": 1,
    "info": 0
  },
  "findings": [
    {
      "rule": "ambiguous-target",
      "severity": "warn",
      "message": "2 links in the frame all read \"うつわ\" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.",
      "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)"
    }
  ],
  "suppressed": [],
  "retuned": [],
  "report": {
    "source": "index.html",
    "frame": {
      "resolution": "medium, cap 640x480",
      "width": 640,
      "height": 360,
      "scale": 0.5,
      "viewportWidth": 1280,
      "viewportHeight": 720
    },
    "targets": [
      {
        "id": "t1",
        "selector": "a.skip-link",
        "role": "link",
        "label": "本文へスキップ",
        "point": {
          "x": 42,
          "y": -89
        },
        "cssPoint": {
          "x": 84,
          "y": -177
        },
        "box": {
          "x": 8,
          "y": -100,
          "width": 68,
          "height": 23
        },
        "visibleBox": {
          "x": 8,
          "y": -100,
          "width": 68,
          "height": 23
        },
        "minSide": 23,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t2",
        "selector": "a.wordmark",
        "role": "link",
        "label": "汐見窯 SHIOMI-GAMA",
        "point": {
          "x": 126,
          "y": 18
        },
        "cssPoint": {
          "x": 251,
          "y": 36
        },
        "box": {
          "x": 20,
          "y": 3,
          "width": 211,
          "height": 29
        },
        "visibleBox": {
          "x": 20,
          "y": 3,
          "width": 211,
          "height": 29
        },
        "minSide": 29,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t11",
        "aimMargin": 26.6
      },
      {
        "id": "t3",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "新作",
        "point": {
          "x": 254,
          "y": 18
        },
        "cssPoint": {
          "x": 508,
          "y": 36
        },
        "box": {
          "x": 239,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "visibleBox": {
          "x": 239,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t4",
        "aimMargin": 21
      },
      {
        "id": "t4",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "うつわ",
        "point": {
          "x": 294,
          "y": 18
        },
        "cssPoint": {
          "x": 588,
          "y": 36
        },
        "box": {
          "x": 275,
          "y": 6,
          "width": 38,
          "height": 25
        },
        "visibleBox": {
          "x": 275,
          "y": 6,
          "width": 38,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [
          "ambiguous-target"
        ],
        "nearest": "t3",
        "aimMargin": 25
      },
      {
        "id": "t5",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "作家",
        "point": {
          "x": 334,
          "y": 18
        },
        "cssPoint": {
          "x": 668,
          "y": 36
        },
        "box": {
          "x": 319,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "visibleBox": {
          "x": 319,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t4",
        "aimMargin": 21
      },
      {
        "id": "t6",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "読みもの",
        "point": {
          "x": 378,
          "y": 18
        },
        "cssPoint": {
          "x": 756,
          "y": 36
        },
        "box": {
          "x": 355,
          "y": 6,
          "width": 46,
          "height": 25
        },
        "visibleBox": {
          "x": 355,
          "y": 6,
          "width": 46,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t5",
        "aimMargin": 29
      },
      {
        "id": "t7",
        "selector": "#search-toggle",
        "role": "button",
        "label": "検索",
        "point": {
          "x": 545,
          "y": 18
        },
        "cssPoint": {
          "x": 1091,
          "y": 36
        },
        "box": {
          "x": 526,
          "y": 7,
          "width": 38,
          "height": 22
        },
        "visibleBox": {
          "x": 526,
          "y": 7,
          "width": 38,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t8",
        "aimMargin": 21
      },
      {
        "id": "t8",
        "selector": "#cart-open",
        "role": "button",
        "label": "カート 0 点",
        "point": {
          "x": 595,
          "y": 18
        },
        "cssPoint": {
          "x": 1190,
          "y": 36
        },
        "box": {
          "x": 566,
          "y": 7,
          "width": 58,
          "height": 22
        },
        "visibleBox": {
          "x": 566,
          "y": 7,
          "width": 58,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t7",
        "aimMargin": 31
      },
      {
        "id": "t9",
        "selector": "nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "ホーム",
        "point": {
          "x": 30,
          "y": 50
        },
        "cssPoint": {
          "x": 60,
          "y": 100
        },
        "box": {
          "x": 20,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "visibleBox": {
          "x": 20,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t12",
        "aimMargin": 15
      },
      {
        "id": "t10",
        "selector": "nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "うつわ",
        "point": {
          "x": 62,
          "y": 50
        },
        "cssPoint": {
          "x": 124,
          "y": 100
        },
        "box": {
          "x": 52,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "visibleBox": {
          "x": 52,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [
          "ambiguous-target"
        ],
        "nearest": "t12",
        "aimMargin": 15
      },
      {
        "id": "t11",
        "selector": "nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "マグカップ",
        "point": {
          "x": 101,
          "y": 50
        },
        "cssPoint": {
          "x": 201,
          "y": 100
        },
        "box": {
          "x": 84,
          "y": 43,
          "width": 33,
          "height": 15
        },
        "visibleBox": {
          "x": 84,
          "y": 43,
          "width": 33,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t2",
        "aimMargin": 18
      },
      {
        "id": "t12",
        "selector": "#tab-front",
        "role": "tab",
        "label": "正面",
        "point": {
          "x": 41,
          "y": 92
        },
        "cssPoint": {
          "x": 82,
          "y": 184
        },
        "box": {
          "x": 20,
          "y": 65,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 65,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t13",
        "aimMargin": 33
      },
      {
        "id": "t13",
        "selector": "#tab-side",
        "role": "tab",
        "label": "側面",
        "point": {
          "x": 41,
          "y": 152
        },
        "cssPoint": {
          "x": 82,
          "y": 304
        },
        "box": {
          "x": 20,
          "y": 125,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 125,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t12",
        "aimMargin": 33
      },
      {
        "id": "t14",
        "selector": "#tab-top",
        "role": "tab",
        "label": "上から",
        "point": {
          "x": 41,
          "y": 212
        },
        "cssPoint": {
          "x": 82,
          "y": 424
        },
        "box": {
          "x": 20,
          "y": 185,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 185,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t13",
        "aimMargin": 33
      },
      {
        "id": "t15",
        "selector": "#tab-use",
        "role": "tab",
        "label": "使用例",
        "point": {
          "x": 41,
          "y": 272
        },
        "cssPoint": {
          "x": 82,
          "y": 544
        },
        "box": {
          "x": 20,
          "y": 245,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 245,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t14",
        "aimMargin": 33
      },
      {
        "id": "t16",
        "selector": "a.rating-link",
        "role": "link",
        "label": "128件のレビュー",
        "point": {
          "x": 488,
          "y": 139
        },
        "cssPoint": {
          "x": 976,
          "y": 279
        },
        "box": {
          "x": 460,
          "y": 132,
          "width": 55,
          "height": 15
        },
        "visibleBox": {
          "x": 460,
          "y": 132,
          "width": 55,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t19",
        "aimMargin": 38
      },
      {
        "id": "t17",
        "selector": "div.swatches > label:nth-of-type(1) > input:nth-of-type(1)",
        "role": "radio",
        "label": "seiji",
        "point": {
          "x": 411,
          "y": 188
        },
        "cssPoint": {
          "x": 822,
          "y": 376
        },
        "box": {
          "x": 400,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "visibleBox": {
          "x": 400,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t18",
        "aimMargin": 22
      },
      {
        "id": "t18",
        "selector": "div.swatches > label:nth-of-type(2) > input:nth-of-type(1)",
        "role": "radio",
        "label": "hakuji",
        "point": {
          "x": 444,
          "y": 188
        },
        "cssPoint": {
          "x": 888,
          "y": 376
        },
        "box": {
          "x": 433,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "visibleBox": {
          "x": 433,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t17",
        "aimMargin": 22
      },
      {
        "id": "t19",
        "selector": "div.swatches > label:nth-of-type(3) > input:nth-of-type(1)",
        "role": "radio",
        "label": "ameyu",
        "point": {
          "x": 477,
          "y": 188
        },
        "cssPoint": {
          "x": 954,
          "y": 376
        },
        "box": {
          "x": 466,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "visibleBox": {
          "x": 466,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t18",
        "aimMargin": 22
      },
      {
        "id": "t20",
        "selector": "div.sizes > label:nth-of-type(1) > input:nth-of-type(1)",
        "role": "radio",
        "label": "S",
        "point": {
          "x": 433,
          "y": 255
        },
        "cssPoint": {
          "x": 867,
          "y": 509
        },
        "box": {
          "x": 400,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "visibleBox": {
          "x": 400,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t25",
        "aimMargin": 26
      },
      {
        "id": "t21",
        "selector": "div.sizes > label:nth-of-type(2) > input:nth-of-type(1)",
        "role": "radio",
        "label": "M",
        "point": {
          "x": 504,
          "y": 255
        },
        "cssPoint": {
          "x": 1008,
          "y": 509
        },
        "box": {
          "x": 471,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "visibleBox": {
          "x": 471,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t25",
        "aimMargin": 26
      },
      {
        "id": "t22",
        "selector": "#qty-dec",
        "role": "button",
        "label": "数量を1つ減らす",
        "point": {
          "x": 561,
          "y": 255
        },
        "cssPoint": {
          "x": 1122,
          "y": 509
        },
        "box": {
          "x": 550,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "visibleBox": {
          "x": 550,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "minSide": 22,
        "disabled": true,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t23",
        "aimMargin": 11
      },
      {
        "id": "t23",
        "selector": "#qty",
        "role": "spinbutton",
        "label": "1",
        "point": {
          "x": 585,
          "y": 255
        },
        "cssPoint": {
          "x": 1170,
          "y": 509
        },
        "box": {
          "x": 572,
          "y": 243,
          "width": 26,
          "height": 24
        },
        "visibleBox": {
          "x": 572,
          "y": 243,
          "width": 26,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t22",
        "aimMargin": 13
      },
      {
        "id": "t24",
        "selector": "#qty-inc",
        "role": "button",
        "label": "数量を1つ増やす",
        "point": {
          "x": 609,
          "y": 255
        },
        "cssPoint": {
          "x": 1218,
          "y": 509
        },
        "box": {
          "x": 598,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "visibleBox": {
          "x": 598,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t23",
        "aimMargin": 11
      },
      {
        "id": "t25",
        "selector": "#add-to-cart",
        "role": "button",
        "label": "カートに入れる",
        "point": {
          "x": 468,
          "y": 295
        },
        "cssPoint": {
          "x": 937,
          "y": 589
        },
        "box": {
          "x": 400,
          "y": 281,
          "width": 137,
          "height": 28
        },
        "visibleBox": {
          "x": 400,
          "y": 281,
          "width": 137,
          "height": 28
        },
        "minSide": 28,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t20",
        "aimMargin": 28
      },
      {
        "id": "t26",
        "selector": "#fav",
        "role": "button",
        "label": "お気に入り",
        "point": {
          "x": 581,
          "y": 295
        },
        "cssPoint": {
          "x": 1162,
          "y": 589
        },
        "box": {
          "x": 542,
          "y": 281,
          "width": 78,
          "height": 28
        },
        "visibleBox": {
          "x": 542,
          "y": 281,
          "width": 78,
          "height": 28
        },
        "minSide": 28,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t23",
        "aimMargin": 28
      },
      {
        "id": "t27",
        "selector": "#acc-detail-btn",
        "role": "button",
        "label": "商品詳細",
        "point": {
          "x": 456,
          "y": 465
        },
        "cssPoint": {
          "x": 911,
          "y": 929
        },
        "box": {
          "x": 291,
          "y": 449,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 449,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t28",
        "selector": "#acc-size-btn",
        "role": "button",
        "label": "サイズ・容量",
        "point": {
          "x": 456,
          "y": 497
        },
        "cssPoint": {
          "x": 911,
          "y": 994
        },
        "box": {
          "x": 291,
          "y": 481,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 481,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t29",
        "selector": "#acc-care-btn",
        "role": "button",
        "label": "お手入れ",
        "point": {
          "x": 456,
          "y": 530
        },
        "cssPoint": {
          "x": 911,
          "y": 1059
        },
        "box": {
          "x": 291,
          "y": 514,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 514,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t30",
        "selector": "#acc-ship-btn",
        "role": "button",
        "label": "配送・返品",
        "point": {
          "x": 456,
          "y": 562
        },
        "cssPoint": {
          "x": 911,
          "y": 1124
        },
        "box": {
          "x": 291,
          "y": 546,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 546,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t31",
        "selector": "#more-btn",
        "role": "button",
        "label": "もっと見る",
        "point": {
          "x": 283,
          "y": 997
        },
        "cssPoint": {
          "x": 566,
          "y": 1993
        },
        "box": {
          "x": 244,
          "y": 985,
          "width": 78,
          "height": 24
        },
        "visibleBox": {
          "x": 244,
          "y": 985,
          "width": 78,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t32",
        "selector": "a.text-link",
        "role": "link",
        "label": "うつわをすべて見る",
        "point": {
          "x": 588,
          "y": 1101
        },
        "cssPoint": {
          "x": 1176,
          "y": 2202
        },
        "box": {
          "x": 556,
          "y": 1093,
          "width": 64,
          "height": 17
        },
        "visibleBox": {
          "x": 556,
          "y": 1093,
          "width": 64,
          "height": 17
        },
        "minSide": 17,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t33",
        "selector": "ul.cards > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "平皿 白磁 21cm ¥3,520(税込)",
        "point": {
          "x": 89,
          "y": 1212
        },
        "cssPoint": {
          "x": 178,
          "y": 2425
        },
        "box": {
          "x": 20,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 20,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t34",
        "selector": "ul.cards > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "小鉢 青磁 ¥2,640(税込)",
        "point": {
          "x": 243,
          "y": 1212
        },
        "cssPoint": {
          "x": 486,
          "y": 2425
        },
        "box": {
          "x": 174,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 174,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t35",
        "selector": "ul.cards > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "湯呑 飴釉 ¥2,860(税込)",
        "point": {
          "x": 397,
          "y": 1212
        },
        "cssPoint": {
          "x": 794,
          "y": 2425
        },
        "box": {
          "x": 328,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 328,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t36",
        "selector": "ul.cards > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "新作 急須 青磁 360ml ¥9,900(税込)",
        "point": {
          "x": 551,
          "y": 1212
        },
        "cssPoint": {
          "x": 1102,
          "y": 2425
        },
        "box": {
          "x": 482,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 482,
          "y": 1127,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t37",
        "selector": "#nl-email",
        "role": "textbox",
        "label": "",
        "point": {
          "x": 116,
          "y": 1451
        },
        "cssPoint": {
          "x": 232,
          "y": 2902
        },
        "box": {
          "x": 20,
          "y": 1439,
          "width": 192,
          "height": 24
        },
        "visibleBox": {
          "x": 20,
          "y": 1439,
          "width": 192,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t38",
        "selector": "button.btn.btn-light",
        "role": "button",
        "label": "登録",
        "point": {
          "x": 235,
          "y": 1451
        },
        "cssPoint": {
          "x": 471,
          "y": 2902
        },
        "box": {
          "x": 216,
          "y": 1439,
          "width": 40,
          "height": 24
        },
        "visibleBox": {
          "x": 216,
          "y": 1439,
          "width": 40,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t39",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "新作",
        "point": {
          "x": 298,
          "y": 1405
        },
        "cssPoint": {
          "x": 596,
          "y": 2810
        },
        "box": {
          "x": 291,
          "y": 1397,
          "width": 14,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1397,
          "width": 14,
          "height": 16
        },
        "minSide": 14,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t40",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "うつわ",
        "point": {
          "x": 302,
          "y": 1421
        },
        "cssPoint": {
          "x": 603,
          "y": 2843
        },
        "box": {
          "x": 291,
          "y": 1414,
          "width": 21,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1414,
          "width": 21,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t41",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "作家",
        "point": {
          "x": 298,
          "y": 1438
        },
        "cssPoint": {
          "x": 596,
          "y": 2876
        },
        "box": {
          "x": 291,
          "y": 1430,
          "width": 14,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1430,
          "width": 14,
          "height": 16
        },
        "minSide": 14,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t42",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "読みもの",
        "point": {
          "x": 305,
          "y": 1455
        },
        "cssPoint": {
          "x": 611,
          "y": 2909
        },
        "box": {
          "x": 291,
          "y": 1447,
          "width": 29,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1447,
          "width": 29,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t43",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "配送・送料",
        "point": {
          "x": 423,
          "y": 1405
        },
        "cssPoint": {
          "x": 845,
          "y": 2810
        },
        "box": {
          "x": 405,
          "y": 1397,
          "width": 36,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1397,
          "width": 36,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t44",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "返品・交換",
        "point": {
          "x": 423,
          "y": 1421
        },
        "cssPoint": {
          "x": 845,
          "y": 2843
        },
        "box": {
          "x": 405,
          "y": 1414,
          "width": 36,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1414,
          "width": 36,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t45",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "よくあるご質問",
        "point": {
          "x": 430,
          "y": 1438
        },
        "cssPoint": {
          "x": 859,
          "y": 2876
        },
        "box": {
          "x": 405,
          "y": 1430,
          "width": 50,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1430,
          "width": 50,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t46",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "お問い合わせ",
        "point": {
          "x": 426,
          "y": 1455
        },
        "cssPoint": {
          "x": 852,
          "y": 2909
        },
        "box": {
          "x": 405,
          "y": 1447,
          "width": 43,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1447,
          "width": 43,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t47",
        "selector": "nav.footer-nav > div:nth-of-type(3) > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "工房のこと",
        "point": {
          "x": 536,
          "y": 1405
        },
        "cssPoint": {
          "x": 1072,
          "y": 2810
        },
        "box": {
          "x": 518,
          "y": 1397,
          "width": 36,
          "height": 16
        },
        "visibleBox": {
          "x": 518,
          "y": 1397,
          "width": 36,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t48",
        "selector": "nav.footer-nav > div:nth-of-type(3) > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "特定商取引法に基づく表記",
        "point": {
          "x": 561,
          "y": 1421
        },
        "cssPoint": {
          "x": 1123,
          "y": 2843
        },
        "box": {
          "x": 518,
          "y": 1414,
          "width": 86,
          "height": 16
        },
        "visibleBox": {
          "x": 518,
          "y": 1414,
          "width": 86,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t49",
        "selector": "nav.footer-nav > div:nth-of-type(3) > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "プライバシーポリシー",
        "point": {
          "x": 554,
          "y": 1438
        },
        "cssPoint": {
          "x": 1108,
          "y": 2876
        },
        "box": {
          "x": 518,
          "y": 1430,
          "width": 72,
          "height": 16
        },
        "visibleBox": {
          "x": 518,
          "y": 1430,
          "width": 72,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      }
    ],
    "capped": 0,
    "issues": [
      {
        "kind": "ambiguous-target",
        "severity": "warn",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "message": "2 links in the frame all read \"うつわ\" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one."
      }
    ]
  }
}
G16exit 0vlmkit check grounding index.html --viewport 375x740

targets 15 · scale 0.43 · issues 1

output, 27 line(s), 1.5s
vlmkit check grounding
source: index.html (375x740)

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule ambiguous-target=suspect
frame: 162x320 screenshot px — low, cap 375x320, scale 0.43 (every coordinate below is in these 162x320 pixels)
targets: 15 actionable in frame (35 disabled or out of the frame)

Action map (click point in screenshot px):
  t2 link "汐見窯 SHIOMI-GAMA" @ (38,13) 62x25 a.wordmark
  t3 link "新作" @ (20,35) 24x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t4 link "うつわ" @ (57,35) 31x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t5 link "作家" @ (94,35) 24x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t6 link "読みもの" @ (135,35) 38x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)
  t7 button "検索" @ (119,13) 19x19 #search-toggle
  t8 button "カート 0 点" @ (144,13) 29x19 #cart-open
  t9 link "ホーム" @ (16,56) 17x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t10 link "うつわ" @ (43,56) 17x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t11 link "マグカップ" @ (77,56) 29x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t12 tab "正面" @ (24,257) 34x44 #tab-front
  t13 tab "側面" @ (62,257) 34x44 #tab-side
  t14 tab "上から" @ (100,257) 34x44 #tab-top
  t15 tab "使用例" @ (138,257) 34x44 #tab-use
  t50 button "カートに入れる" @ (121,305) 68x21 button.btn.btn-primary.buybar-cta

Issues:
  ! ambiguous-target: 2 links in the frame all read "うつわ" (t4 at 57,35, t10 at 43,56) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.
G17exit 0vlmkit check breakpoints index.html --sweep

breakpoints 4 · issues 1 · sweepRanges 1

output, 15 line(s), 3.3s
vlmkit check breakpoints
source: index.html

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule sweep-overflow=suspect
width sweep: 320-1280px step 25 (39 widths) — 1 overflow range(s)
breakpoints checked: 599, 600, 899, 900px (each at B-1 / B / B+1)

  599px: clean (max-width: 599px)
  600px: clean (min-width: 600px)
  899px: clean (max-width: 899px)
  900px: clean (min-width: 900px)

Issues:
  ! sweep-overflow: Horizontal overflow at 320px (up to 20px past the viewport) — a width between declared breakpoints that the B±1 checks never render. Look for a fixed-width element inside that regime.
S5

320px first screen (sweep-overflow check)

index.html · 320×700

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L5 saw

320x700, first screen only. Header fits at this width (wordmark, search, bag with 0 badge, no collision), nav row and breadcrumb fit, full-bleed stage and four 64px thumbnails fit, and the pinned bar's price block and カートに入れる fit side by side with ~10px to spare. So the 20px sweep-overflow is not in this screen; it must be further down. What this screen does show clearly is the translucency from S4: the h1 汐見窯 マグカップ and the ¥4,180 below it are legible as grey ghost text inside the pinned bar.

G18exit 1vlmkit scan scroll index.html --viewport 320x700

containers 0 · overflowX 20 · issues 9

output, 20 line(s), 1.4s
vlmkit scan scroll
source: index.html (320x700)

status: suspect
page: 340x5065 — horizontal overflow 20px, vertical scroll 4365px
scroll containers: 0 (dead scrollports 1, clipped 8)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  x page-overflow-x div.nl-row: The page scrolls horizontally by 20px at 320px viewport width — caused by: div.nl-row (extends to x=340px: starts at 16px, 324px wide; shrinking or moving it removes 20px of the overflow), button.btn.btn-light (extends to x=340px: starts at 261px, 79px wide; shrinking or moving it removes 20px of the overflow); 8 other element(s) past the edge were probed and each accounts for 0px or less.
  ! clipped-content #cart-open > span:nth-of-type(1): #cart-open > span:nth-of-type(1) clips 42px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content #search-toggle > span:nth-of-type(1): #search-toggle > span:nth-of-type(1) clips 28px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
D7 defect div.nl-row (newsletter email + 登録)

At 320px the newsletter row is 324px wide and the page scrolls horizontally by 20px (sweep-overflow in G17, named in G18): the email input's intrinsic width sets the row's min-content, so the 登録 button is pushed past the edge. The search row has the same structure.

G19exit 0vlmkit verify flow index.html --flow flow.json

verdict: DONE (8/8 steps)

done true · passed 8 · total 8

output, 35 line(s), 2.3s
vlmkit verify flow
source: index.html

verdict: DONE (8/8 steps)

✓ step 1: step the quantity up to 2
    ✓ #qty aria-valuenow=2 
    ✓ #qty-dec aria-disabled=false 
✓ step 2: カートに入れる opens the drawer with two mugs
    ✓ #cart-drawer visible 
    ✓ #cart-close focused 
    ✓ #cart-lines > li count=1 
    ✓ #cart-lines text~"青磁" 
    ✓ #cart-lines text~"S 240ml" 
    ✓ #cart-subtotal text~"¥8,360" 
    ✓ #cart-count text~"2" 
    ✓ #checkout visible 
✓ step 3: Escape closes the drawer and returns focus
    ✓ #cart-drawer hidden 
    ✓ #add-to-cart focused 
✓ step 4: choose 飴釉 and M
    ✓ html data-glaze=ameyu 
    ✓ #product-title text~"飴釉" 
✓ step 5: size M
    ✓ .buybar-variant text~"M 320ml" 
✓ step 6: a second variant becomes a second line
    ✓ #cart-lines > li count=2 
    ✓ #cart-count text~"4" 
    ✓ #cart-subtotal text~"¥16,720" 
✓ step 7: remove the first line
    ✓ #cart-lines > li count=1 
    ✓ #cart-count text~"2" 
    ✓ #cart-lines text~"飴釉" 
✓ step 8: close button closes
    ✓ #cart-drawer hidden
G20exit 0vlmkit scan handlers index.html --probe input

registrations 38 · elements 30 · suspects 0

output, 44 line(s), 2.3s
vlmkit scan handlers
source: index.html

status: 1 warn(s)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
registrations: 38 across 30 element(s), on a page presenting 49 control(s)

  - fieldset.option>div.swatches>label.swatch>input "seiji": change
  - fieldset.option>div.swatches>label.swatch>input "hakuji": change
  - fieldset.option>div.swatches>label.swatch>input "ameyu": change
  - fieldset.option>div.sizes>label.size>input "S": change
  - fieldset.option>div.sizes>label.size>input "M": change
  - section.product>div.gallery>div.thumbs>button#tab-front "正面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-side "側面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-top "上から": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-use "使用例": click, keydown
  - div.options-row>div.option>div.stepper>button#qty-dec "数量を1つ減らす": click
  - div.options-row>div.option>div.stepper>button#qty-inc "数量を1つ増やす": click
  - div.options-row>div.option>div.stepper>input#qty "1": keydown, input, compositionend, change (no role)
  - section.product>div.panel>div.buy-row>button#fav "お気に入り": click
  - section.product>div.panel>div.buy-row>button#add-to-cart "カートに入れる": click
  - aside#buybar>button.btn "カートに入れる": click (no role)
  - header.site-header>div.header-inner>div.header-actions>button#cart-open "カート 0点": click
  - dialog#cart-drawer "カート カートに商品はありません。 あと¥5,000で送料無料になります。 小計": close, click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-head>button#cart-close "カートを閉じる": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-body>ul#cart-lines "": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button#checkout "レジに進む": click (no role)
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn "商品詳細": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-size-btn "サイズ・容量": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-care-btn "お手入れ": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn "配送・返品": click
  - section#reviews>div.reviews-grid>div.review-list>button#more-btn "もっと見る": click
  - header.site-header>div.header-inner>div.header-actions>button#search-toggle "検索": click
  - header.site-header>div#search-panel "キーワードで探す 検索する": keydown (no role)
  - header.site-header>div#search-panel>form#search-form "キーワードで探す 検索する": submit (no role)
  - footer.site-footer>div.footer-inner>section.newsletter>form#nl-form "メールアドレス 登録": submit (delegation container)

Typed into (plain, and through an IME composition):
  - div.options-row>div.option>div.stepper>input#qty: "vlmkit7" became "", "日本語" became "", composed ""
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email: kept "vlmkit7", kept "日本語", composed "日本語"

Issues:
  warn [unprobed-handler-types] 4 handler type(s) registered and NONE exercised: click, close, keydown, submit — this gate is an inventory and presses nothing. A clean result here says the wiring exists, not that it works. Run 'check interactions --handlers' to focus and activate the controls, add '--probe-drag' for the drag surfaces, or drive the rest with a 'verify flow' script.
G21exit 0vlmkit check motion index.html

activeAnimations 0 · running 0 · issues 0

output, 34 line(s), 1.5s
vlmkit check motion
source: index.html

status: ok
samples: 24
active animations: 0
active transitions: 24
running animations: 0
paused animations: 0
reduced-motion rule: yes

Motion samples:
  - div.search-row > button:nth-of-type(1): animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #tab-front > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-side > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-top > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-use > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - div.swatches > label:nth-of-type(1) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - div.swatches > label:nth-of-type(2) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - div.swatches > label:nth-of-type(3) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - #add-to-cart: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #fav: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #acc-detail-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-size-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-care-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-ship-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #more-btn: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #more-btn > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.2s
  - svg.glaze-hakuji: animation=none 0s running; transition=transform 0.4s
  - ul.cards > li:nth-of-type(2) > a:nth-of-type(1) > span:nth-of-type(1) > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.4s
  - svg.glaze-ameyu: animation=none 0s running; transition=transform 0.4s
  - ul.cards > li:nth-of-type(4) > a:nth-of-type(1) > span:nth-of-type(1) > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.4s

No motion issues detected.
S6

Tab from お気に入り to the first accordion button (focus-order check)

index.html · 1280×720 · focus #fav · press Tab

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L6 saw

1280x720 after focusing お気に入り and pressing Tab. The page has scrolled: お気に入り and カートに入れる are now at the very top edge (y≈0–47) and 商品詳細 — the next Tab stop, with a clearly visible 3px celadon focus ring — sits centred in the viewport at y≈326–394. So on the page focus moved DOWN, from the buy row to the first accordion row in the next section, which is the reading order. The 233px "reverse" the focus gate reported is the difference between お気に入り's viewport y before the scroll (561) and 商品詳細's viewport y after Chrome centred it (328). The ring itself is fine; the outline runs 2px outside the accordion's hairlines, which reads as intended.

S7

cart drawer open, two mugs (first draft)

index.html · 1280×800 · click #qty-inc · click #add-to-cart · wait 600

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L7 saw

Desktop 1280x800 after + and カートに入れる: the drawer is a 440px panel on the right over a dimmed page. Top: カート with a × close button; a celadon-tinted status band カートに追加しました(青磁・S 240ml・2点); one line item — celadon mug thumbnail, 汐見窯 マグカップ 青磁, 釉薬 青磁 / サイズ S 240ml / 数量 2, an underlined 削除, and ¥8,360 right-aligned level with the name. The foot is pinned to the bottom: 送料無料の対象です。 over a full progress bar, 小計 ¥8,360(税込), a full-width dark レジに進む and an outlined 買い物を続ける. Everything aligns on the drawer's 24px padding; the empty space between the single line and the foot is expected for a one-line cart. The header badge is under the backdrop and not readable in this shot. レジに進む appears here verbatim, visible, in the state the brief defines (the drawer open with two mugs in it).

N2false-positiveabout G2

copy-missing for レジに進む: the line exists and is visible verbatim in the cart drawer (S7/L7, the drawer open with two mugs), which is the only place the brief puts it. The drawer is a modal <dialog> opened by adding an item; check copy's sweep opens closed <details>, unselected tabs and aria-expanded=false controls (9 states here) but not a dialog behind a plain button, so the line is unreachable to it. The empty-cart drawer deliberately has no checkout button. The other copy-missing in G2 (¥4,180(税込)) is real and is D6.

N3acceptedabout G3

button drift (6 styles for 11 buttons) is five distinct button kinds, each consistent within itself: accordion rows (x4), header icon buttons (x2), outlined secondary buttons (お気に入り, もっと見る), the one primary CTA, and the two stepper segments — which differ from each other only because − is in its aria-disabled state at quantity 1, a state and not a style. input:radio drift is the glaze swatches (44px circles) against the size cards (48px rounded rectangles): two different option components on purpose. Not merged. The h2 drift in the same run is real and is D8.

N4false-positiveabout G7

The three [reverse] findings are focus-scroll artefacts, not a wrong order. S6/L6: after Tab from お気に入り, Chrome scrolled 商品詳細 to the viewport centre (y≈328) — it is ~370px lower on the page than お気に入り, which was at viewport y 561 before the scroll. The same geometry explains more-btn at 336 (a centred 48px button) and the related-card row. DOM order equals visual order: header → gallery → panel → accordion → reviews → related → footer. The one [skip-row] (もっと見る → うつわをすべて見る, 216px) is the gap between the reviews and the related section; S1 screen 3 shows nothing interactive in it, so nothing was skipped (accepted).

N5false-positiveabout G9

All six clipped-content warns (and the eight in G10, the ones in G18) are the visually-hidden pattern: the sr-only 点 in the cart badge, the sr-only 件 after each distribution count, and on phones the header's 検索 / カート labels. check integrity G1 lists exactly these selectors under exempted as 'visually-hidden (sr-only) pattern — 1px box, text for AT only'. They are text for screen readers, not cut-off content. The dead scrollport div.drawer-body is accepted: it is the cart list's overflow:auto so a long cart scrolls inside the drawer; with the one or two lines this demo holds it fits.

N6acceptedabout G11

unprobed-handler-types is the inventory gate saying it pressed nothing. The handlers it lists are exercised elsewhere in this round: check interactions G12 (Enter/arrows/Escape on every control, the drawer's trap and focus return) and verify flow G19 (stepper, add to cart, two variants, remove, Escape, close — 8/8). Same for G20.

N7acceptedabout G14

ambiguous-target: the header nav's うつわ and the breadcrumb's うつわ are the same destination (the うつわ category), so naming them apart would be describing one link twice; the gate cannot see that because every placeholder link on this one-page demo is href="#". They sit in differently-named landmarks (メインメニュー / パンくずリスト). カートに入れる is t25 in G15's map at CSS (937,589), inside the 1280x720 frame, with no risks; on a phone (G16) the pinned bar's カートに入れる is t50, also risk-free. Same finding in G16.

N8toolabout G7

check a11y focus appears to compare each stop's VIEWPORT y before and after the focus-induced scroll, so moving down the page reads as moving up. Verbatim: "[reverse] Focus moved up by 233px (from `main#main>section.product.container>div.panel>div.buy-row>button#fav` at y=561 to `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn` at y=328). Visual order is top-to-bottom; check `tabindex` or DOM order." S6 shows the second button centred at y≈328 after Chrome scrolled it into view; on the page it is ~370px below the first. Comparing page coordinates (y + scrollY) would remove this class.

N9toolabout G9

scan scroll and check integrity disagree about the same elements. G9: "! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative." G1 on the same page: "[text-clipped] span.badge > span:nth-of-type(2) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only" (exempted). Every sr-only span on a page therefore produces a clipped-content warn in scan scroll (6 at 1280, 8 at 375).

N10toolabout G12

check interactions names radio inputs by their value, not their accessible name: "[radio] \"seiji\" focus✓ | ArrowDown: focus moves" — the radio's name is 青磁, from its wrapping <label>; the email field prints as "[textbox] \"\" focus✓" although <label for=nl-email>メールアドレス</label> names it. And the quantity field, <input type=text role=spinbutton aria-valuenow …>, is not in the 48-element inventory at all (so ArrowUp/Down on it is never probed); scan handlers G11 lists it as "input#qty \"1\": keydown, input, compositionend, change (no role)".

N11toolabout G2

check copy has no way to reach copy that lives behind an action other than a disclosure. Verbatim: "x copy-missing: Manifest line not found in rendered text or any of 9 revealed disclosure state(s): \"レジに進む\"". The line is in a modal <dialog> opened by カートに入れる (S7). A pre-step (e.g. --click <selector> before the sweep, as the judge's shot has) would let a brief's drawer or modal copy be verified instead of noted.

F1fix for D1

Replaced the 13-cell net with a fine, irregular crackle: a seeded jittered grid (23px step, ±8.5px jitter), 42% of edges dropped or demoted so cell sizes vary, each edge bent through a jittered midpoint; 258 main segments at 0.8px and 84 finer ones at 0.55px/60%, all at --crackle .30 (was .34 on far heavier lines). The top view now uses the same network untranslated.

F2fix for D2

Removed the three dark blobs. The foot's top edge is now a wavy line with two shallow tongues where the glaze ran lower (front at x≈239/358, side at x≈277/390), traced by a 1.6px g-deep line at 40%; the throwing lines went from 2px/14% to 1.6px/10%.

F3fix for D3

Below 600px the third footer column spans both columns, and footer link labels use word-break: auto-phrase so a label that does wrap breaks between phrases.

F4fix for D4

The pinned bar's background is now opaque (--card) instead of rgba(252,250,246,.97); top hairline and shadow kept.

F5fix for D5

Running text gets a reading measure: .lead max-width 36em, .review-body 38em, accordion paragraphs 40em (about 36-40 characters a line at 15px).

F6fix for D6

.price is no longer a flex container; the amount and (税込) are plain inline runs on one baseline, so the text is one string: ¥4,180(税込).

F7fix for D7

.field gets width:100% (a percentage-width input contributes no min-content), and the newsletter and search forms get grid-template-columns: minmax(0,1fr), so neither row can be wider than its column.

F8fix for D8

The newsletter title uses the page's section-title style (serif, 22/26px, .14em) and the one-off .footer-title rule is gone: h2 is now section titles (x4) and footer column labels (x3).

F9fix for D9

Added an sr-only role=status line under the buy row. The − / + buttons now say 数量 N点 after each step, and 数量は1点からです / 数量は10点までです when pressed at a bound.

R2 · fix pass

builder
S8

front view close-up after crackle/drip rework

index.html · 1280×800 · element .stage

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L8 saw

Front view close-up (596px stage). The glaze edge at the foot is now a soft wavy line with two shallow tongues (left of centre and right of centre) where the glaze ran a few px lower — it reads as glaze, and the three dark blobs that looked like feet are gone. The throwing lines are fainter. But the new crackle is still wrong: it is a fine mesh of mostly rectangular cells laid out in visible rows and columns — the jittered grid shows through, so it reads as tiles or crazy paving rather than crackle — and it covers the whole body at one even strength, which now makes the body look textured all over instead of glazed. It also ignores the cylinder: cells at the left and right edges are as wide as the ones in the middle, so the pattern looks printed on a flat card.

S9

side view close-up

index.html · 1280×800 · element .stage · click #tab-side

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L9 saw

Side view close-up (tab 側面 clicked). The handle faces the viewer as a vertical rounded bar with a highlight and a soft cast shadow to its right; the small square potter's stamp with a wave sits at the lower left of the body; the wavy glaze edge with its two tongues reads well. The crackle has the same problem as the front view: a regular grid of small rectangles in rows, even strength everywhere, no foreshortening at the sides of the cylinder.

S10

top view close-up

index.html · 1280×800 · element .stage · click #tab-top

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L10 saw

Top view close-up (tab 上から clicked). The rim ring, the pooled deeper celadon at the centre of the well and the two highlight arcs read as a glazed interior seen from above, and the handle projects to the right as a rounded bar. The crackle covers the whole well as a grid of little rectangles — flatter and more obviously gridded here than on the side, because nothing curves it. Needs the same rework as the outside.

V1verified D2 by L8

Front and side close-ups show a wavy glaze edge with two shallow tongues and no blobs.

F10fix for D1

Second attempt, after L8-L10 showed the jittered grid still reading as rows of tiles: the crackle is now a Voronoi network of 124 cells from seeded Poisson-disk points (irregular polygons meeting at three-way junctions), 14% of edges dropped as unfinished cracks, the rest split 1:2 into strong (0.8px) and faint (0.55px at 55%) lines, each bent through two jittered points. The outside network is wrapped onto the cylinder (x = 300 + R·sin θ, y shifted by 24·cos θ for the rim ellipse), so cells narrow toward the sides; the well seen from above gets its own flat network (#crackle-flat).

S11

front view after Voronoi crackle

index.html · 1280×800 · element .stage

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L11 saw

Front view close-up after the second crackle rework. The crackle is now an irregular network of polygon cells of different sizes, meeting at three-way junctions, with some cracks stopping short and roughly a third of the lines stronger than the rest; toward the left and right edges the cells get narrower, so the pattern wraps round the cylinder instead of sitting on it like a card. At this size it reads as a crackled celadon glaze and no longer competes with the body's shading, the highlight or the wavy glaze edge at the foot. The throwing lines are just visible. Nothing else changed in the picture.

S12

top view after Voronoi crackle

index.html · 1280×800 · element .stage · click #tab-top

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L12 saw

Top view close-up after the rework. The well shows a fine irregular crackle network, lighter than on the outside, over the deeper pooled celadon at the centre; the rim ring, the two highlight arcs and the handle to the right are as before. No grid structure is visible any more.

V2verified D1 by L11

Voronoi crackle reads as glaze crackle and wraps the cylinder; the well matches (L12).

S13

mobile footer after the third-column fix

index.html · 375×812 · element .site-footer · scroll-to .footer-nav

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L13 saw

Mobile footer (element shot, 375 wide). 汐見窯だより now uses the same serif section-title style as the other section headings (22px here); lead, メールアドレス label, a white field and the 登録 button in one row. ショップ and ご案内 share the first row of columns; 汐見窯について now spans the full width underneath, and 特定商取引法に基づく表記 sits on one line with no orphaned 記. © 2026 汐見窯 and the disclaimer follow the hairline; the pinned bar at the bottom is opaque and covers only the footer's bottom padding.

S14

pinned bar close-up over reviews, after opaque background

index.html · 375×812 · element #buybar · @2x · scroll-to #reviews

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L14 saw

Pinned bar close-up (2x) at 375, scrolled to the reviews, same framing as S4. The bar is solid: 青磁・S 240ml and ¥4,180(税込) on the left and カートに入れる on the right, with nothing of the review text behind showing through. Top hairline and shadow unchanged.

S15

tablet: lead and reviews measure

index.html · 768×1024 · scroll-to .about

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L15 saw

Tablet 768, scrolled to 商品について. The lead paragraph now stops at about 540px (36em), so each line holds about 36 characters and three lines read comfortably; the signature and the full-width accordion rows follow. One conventional Japanese break remains (焼き上げまし / た。) — ordinary character breaking in body text, not a defect. Above, the assurance lines and buy row are unchanged.

S16

tablet: review bodies measure

index.html · 768×1024 · scroll-to .review-list

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L16 saw

Tablet 768, scrolled to the review list. Review bodies now stop at about 570px (38em), roughly 37 characters a line, while stars, titles, meta lines and the hairlines between reviews keep the full width, so the column still reads as one block. もっと見る and the section rule below it are unchanged; the opaque pinned bar is at the bottom.

V3verified D3 by L13

The third column spans the width at 375; the long label is on one line.

V4verified D4 by L14

No text shows through the bar at 2x.

V5verified D5 by L16

Lead (L15) and review bodies (L16) hold about 36-38 characters a line at 768.

G22exit 1vlmkit check copy index.html --manifest copy.txt

missing 1 · placeholders 0 · manifestLines 14 · invisibleOnly 1 · statesExplored 9 · revealedOnly 0

output, 11 line(s), 1.7s
vlmkit check copy
source: index.html

status: suspect
rendered text: 1083 chars
disclosure states: 9 explored (details / tabs / aria-expanded)
manifest: 14 line(s), missing 1, 1 invisible-only

Issues:
  x copy-invisible: Manifest line found ONLY in text a user cannot see (reason: unknown): "¥4,180(税込)". Invisible text does not satisfy the copy gate — render it visibly or remove the hidden copy. If this invisibility is deliberate (e.g. assistive-tech-only copy), re-run with --allow-invisible unknown.
  x copy-missing: Manifest line not found in rendered text or any of 9 revealed disclosure state(s): "レジに進む" (comparison is whitespace-normalized, case-sensitive).
G23exit 0vlmkit scan scroll index.html --viewport 320x700

containers 0 · overflowX 0 · issues 8

output, 20 line(s), 1.4s
vlmkit scan scroll
source: index.html (320x700)

status: warn
  exits 0 — 8 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 320x5044 — horizontal overflow 0px, vertical scroll 4344px
scroll containers: 0 (dead scrollports 1, clipped 8)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content #cart-open > span:nth-of-type(1): #cart-open > span:nth-of-type(1) clips 42px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content #search-toggle > span:nth-of-type(1): #search-toggle > span:nth-of-type(1) clips 28px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G24exit 0vlmkit check breakpoints index.html --sweep

breakpoints 4 · issues 0 · sweepRanges 0

output, 13 line(s), 3.3s
vlmkit check breakpoints
source: index.html

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 599, 600, 899, 900px (each at B-1 / B / B+1)

  599px: clean (max-width: 599px)
  600px: clean (min-width: 600px)
  899px: clean (max-width: 899px)
  900px: clean (min-width: 900px)

All boundaries consistent.
G25exit 1vlmkit check copy index.html --manifest copy.txt --json

missing 1 · placeholders 0 · manifestLines 14 · invisibleOnly 1 · statesExplored 9 · revealedOnly 0

output, 57 line(s), 2.0s
{
  "gate": "check.copy",
  "command": "check copy",
  "verdict": "fail",
  "counts": {
    "suspect": 2,
    "warn": 0,
    "info": 0
  },
  "findings": [
    {
      "rule": "copy-invisible",
      "severity": "suspect",
      "message": "Manifest line found ONLY in text a user cannot see (reason: unknown): \"¥4,180(税込)\". Invisible text does not satisfy the copy gate — render it visibly or remove the hidden copy. If this invisibility is deliberate (e.g. assistive-tech-only copy), re-run with --allow-invisible unknown."
    },
    {
      "rule": "copy-missing",
      "severity": "suspect",
      "message": "Manifest line not found in rendered text or any of 9 revealed disclosure state(s): \"レジに進む\" (comparison is whitespace-normalized, case-sensitive)."
    }
  ],
  "suppressed": [],
  "retuned": [],
  "report": {
    "source": "index.html",
    "textLength": 1083,
    "manifestLines": 14,
    "forbidLines": 0,
    "forbiddenLines": [],
    "missingLines": [
      "レジに進む"
    ],
    "revealedLines": [],
    "invisibleLines": [
      {
        "line": "¥4,180(税込)",
        "reason": "unknown"
      }
    ],
    "allowedInvisibleLines": [],
    "statesExplored": 9,
    "droppedStates": 0,
    "placeholders": [],
    "issues": [
      {
        "kind": "copy-invisible",
        "severity": "suspect",
        "message": "Manifest line found ONLY in text a user cannot see (reason: unknown): \"¥4,180(税込)\". Invisible text does not satisfy the copy gate — render it visibly or remove the hidden copy. If this invisibility is deliberate (e.g. assistive-tech-only copy), re-run with --allow-invisible unknown."
      },
      {
        "kind": "copy-missing",
        "severity": "suspect",
        "message": "Manifest line not found in rendered text or any of 9 revealed disclosure state(s): \"レジに進む\" (comparison is whitespace-normalized, case-sensitive)."
      }
    ]
  }
}
V6verified D7 by G23

320px: horizontal overflow 0px (was 20px in G18); G24's 320-1280 sweep is clean.

V7verified D6 by G22

What D6 fixed is the block split: G2 said copy-missing (not in rendered text at all), G22 finds ¥4,180(税込) as one string in the rendered text. G22 still fails the line, but for a different reason — see the tool note N12 and false-positive note N13 on G22.

N12toolabout G22

check copy's visible-text match inserts a separator between the text of adjacent inline elements, so a manifest line that crosses inline markup with no whitespace can never match visibly, and is then reported as invisible. Probe on a scratch page (not part of the site): <p><span>汐見</span><span>窯</span></p>, <p>青<b>磁</b>釉</p> and <p>¥4,180<small>(税込)</small></p> each gave "x copy-invisible: Manifest line found ONLY in text a user cannot see (reason: unknown)", while <p><span>潮見</span> <span>窯元</span></p> (a real space between the spans) passed, and so did every plain one-text-node price (¥7,777(税込), ¥8,888, 8,888円(税込), ¥1,234). Japanese has no word spaces, so any line with a styled run inside it (a price with a smaller 税込, a bolded word) trips this; on this page it is the brief's own price line.

N13false-positiveabout G22

Both G22 findings are wrong about this page. ¥4,180(税込): rendered visibly on one baseline in the product panel (S1 screen 1, and in the drawer's 小計 in S7); the markup is <span>¥4,180</span><span>(税込)</span> with no whitespace between, which is exactly the case the probe in N12 shows the gate cannot match — and 'invisible (reason: unknown)' is the gate's fallback, not a hidden element. レジに進む: as N2 — visible in the open drawer (S7), unreachable to the disclosure sweep. Not restyled into one flat text run just to satisfy the matcher: the small (税込) after a large amount is the convention the brief's own copy line describes.

G26exit 0vlmkit check design index.html

verdict: DRIFT (2 finding(s))

verdict drift · drifting 2 · roles 11

output, 31 line(s), 1.6s
vlmkit check design
source: index.html

verdict: DRIFT (2 finding(s))
  exits 0 — 2 warn(s) did not fail this command. To gate on one: --rule component-drift=suspect
  roles judged: 6 of 11 seen, spacing values: 22
  coverage: 42 of 315 visible element(s) carried an inferable role; 4 skipped as non-resting
    no role: span x82, div x30, li x30, a x26, svg x22, p x16, +18 more tag(s)
    A role comes from role="..." or from button/input/select/textarea/h1-h6. Layout elements
    (div, span, p, a) have none, so a large skip count is normal — this gate judges components,
    not every box. Add role="..." where an element IS a component to widen the coverage.
  text-free: 8 (0 judged on box alone — font-size/weight is not observable without painted text)

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  button          11 inst    6 styles  reuse  1.83x  3 one-off  drift
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  img              6 inst    1 styles  reuse     6x  0 one-off  ok
  tab              3 inst    1 styles  reuse     3x  0 one-off  ok
  input:radio      3 inst    2 styles  reuse   1.5x  1 one-off  drift
  tablist          1 inst    1 styles  reuse     1x  1 one-off  not judged
  tabpanel         1 inst    1 styles  reuse     1x  1 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  spinbutton       1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: tablist (1), tabpanel (1), h1 (1), spinbutton (1), input:email (1) — under --min-instances 3, so no finding can come from them.
  To keep judging them: --min-instances 2 --min-reuse 2 (both — a 2-instance role cannot reach 3x however many instances the floor allows).

Findings
  ! [component-drift] button: 11 "button" elements render 6 distinct styles (used 4x, 2x, 2x, 1x, …; a system reuses each style 3x or more, and this role averages 1.83x). Dominant style, used 4x: padding 12/4/12/4, radius 0, 16px/600, border 0, bg rgba(0, 0, 0, 0). Deviating: button#search-toggle (padding 0/10/0/10, radius 8, 14px/400, border 0, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 10, padding-bottom 12 → 0 and 4 more; button#fav (padding 0/22/0/22, radius 8, 15px/700, border 1, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more; button#add-to-cart (padding 0/22/0/22, radius 8, 16px/700, border 1, bg rgb(47, 97, 83)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more and 2 more. This reports inconsistency, not which style is correct.
  ! [component-drift] input:radio: 3 "input:radio" elements render 2 distinct styles (used 2x, 1x; a system reuses each style 3x or more, and this role averages 1.5x). Dominant style, used 2x: padding 0/0/0/0, radius 50, 16px/400, border 1, bg rgba(0, 0, 0, 0). Deviating: div.sizes>label.size>input (padding 0/0/0/0, radius 8, 16px/400, border 1, bg rgb(252, 250, 246)) — differs in border-radius 50 → 8, background-color rgba(0, 0, 0, 0) → rgb(252, 250, 246). This reports inconsistency, not which style is correct.
V8verified D8 by G26

h2: 7 instances, 2 styles, 3.5x — no finding.

G27exit 0vlmkit check interactions index.html --max-elements 80

elements 48 · suspects 0 · warns 0

output, 54 line(s), 22.7s
vlmkit check interactions
source: index.html

status: ok
interactive elements: 48

  - [link] "本文へスキップ" focus✓
  - [link] "汐見窯 SHIOMI-GAMA" focus✓
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [button] "カート 0点" focus✓ | Enter: focus moves within | opens dialog (focus enters), traps | Esc closes+returns focus
  - [link] "ホーム" focus✓
  - [link] "うつわ" focus✓
  - [link] "マグカップ" focus✓
  - [tab] "正面" focus✓ | ArrowRight: selected true -> false
  - [tab] "側面" unreachable | ArrowRight: focus moves
  - [tab] "上から" unreachable | ArrowRight: focus moves
  - [tab] "使用例" unreachable | ArrowRight: focus moves
  - [link] "128件のレビュー" focus✓
  - [radio] "seiji" focus✓ | ArrowDown: focus moves
  - [radio] "hakuji" unreachable | ArrowDown: focus moves
  - [radio] "ameyu" unreachable | ArrowDown: focus moves
  - [radio] "S" focus✓ | ArrowDown: focus moves
  - [radio] "M" unreachable | ArrowDown: focus moves
  - [button] "数量を1つ減らす" focus✓ | Enter: layout change | announces
  - [button] "数量を1つ増やす" focus✓ | Enter: layout change | announces
  - [button] "カートに入れる" focus✓ | Enter: focus moves within | announces
  - [button] "お気に入り" focus✓ | Enter: pressed false -> true | announces
  - [button] "商品詳細" focus✓ | Enter: expanded false -> true
  - [button] "サイズ・容量" focus✓ | Enter: expanded false -> true
  - [button] "お手入れ" focus✓ | Enter: expanded false -> true
  - [button] "配送・返品" focus✓ | Enter: expanded false -> true
  - [button] "もっと見る" focus✓ | Enter: expanded false -> true
  - [link] "うつわをすべて見る" focus✓
  - [link] "平皿 白磁 21cm ¥3,520(税込)" focus✓
  - [link] "小鉢 青磁 ¥2,640(税込)" focus✓
  - [link] "湯呑 飴釉 ¥2,860(税込)" focus✓
  - [link] "新作 急須 青磁 360ml ¥9,900(税込)" focus✓
  - [textbox] "" focus✓
  - [button] "登録" focus✓ | Enter: layout change | announces
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [link] "配送・送料" focus✓
  - [link] "返品・交換" focus✓
  - [link] "よくあるご質問" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "工房のこと" focus✓
  - [link] "特定商取引法に基づく表記" focus✓
  - [link] "プライバシーポリシー" focus✓
V9verified D9 by G27

Both stepper buttons now read 'Enter: layout change | announces'; no inert-control left.

S17

index.html · 1280×800 · full page, 4 screen(s)

S17 screen 1S17 screen 2S17 screen 3S17 screen 4
L17 saw

Desktop 1280x800 after the fix pass, 4 screens. Screen 1: the mug now carries the fine irregular crackle, which at 596px reads as a crackled celadon and no longer fights the highlight; the wavy glaze edge at the foot replaces the blobs. The panel is unchanged and the CTA still ends above y=620. Screen 2: accordion and lead as before; review bodies now stop at 38em (text ends near x=1055 while the hairlines run to 1240) — deliberate measure, and the column still reads as one block with stars, titles and meta on the full width. Screen 3: reviews, もっと見る, section rule, 同じ窯のうつわ. Screen 4: cards, and the footer's 汐見窯だより now in the same serif title style as the other sections, which makes the footer read as part of the page's hierarchy rather than a different system. Checked for regressions from the edits: no overlap, no clipped text, price and (税込) still on one baseline, both forms' rows intact.

S18

index.html · 375×812 · full page, 7 screen(s)

S18 screen 1S18 screen 2S18 screen 3S18 screen 4S18 screen 5S18 screen 6S18 screen 7
L18 saw

Mobile 375x812 after the fix pass, 7 screens. Screen 1: the smaller mug shows the new crackle as a light texture; the pinned bar is solid white-paper with no ghost text. Screen 2: the panel, with the bar correctly stepped aside while the panel's own button is visible. Screens 3–5: lead, accordion, summary card, reviews (at 375 the 38em cap is wider than the column, so nothing changes here), もっと見る, related cards. Screens 6–7: footer with the section-title 汐見窯だより, ショップ / ご案内 side by side and 汐見窯について spanning the width with every label on one line, the copyright and disclaimer clear of the bar. Nothing new looks off.

R3 · interactions and states

builder
S19

白磁 + 側面 selected

index.html · 1280×800 · click input[name=glaze][value=hakuji] · click #tab-side

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L19 saw

Desktop after choosing 白磁 and the 側面 thumbnail. The title reads 汐見窯 マグカップ 白磁, the legend 釉薬:白磁, the 白磁 swatch carries the ink ring and a bold label while 青磁 lost both, and all four thumbnails now show the white mug with 側面 selected (dark border, bold label). The main image is the side view in white porcelain: the body separates from the paper stage through its edge shading and ground shadow, the handle faces the viewer as a vertical bar, the potter's stamp shows at the lower left, and there is no crackle — correct for 白磁. The interior reads grey-white. Price, rating, options and CTA are unchanged. The state is readable without colour: the name, legend and ring all say 白磁.

S20

飴釉 + 使用例 selected

index.html · 1280×800 · click input[name=glaze][value=ameyu] · click #tab-use

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L20 saw

Desktop after choosing 飴釉 and 使用例. The use scene: an amber mug on a linen mat (two celadon stripes) on a wood table, dark tea in it, two white steam lines above, a small white plate with a green wagashi at the left and a sprig at the right, a pale light shaft on the wall. The amber glaze gets the wavy foot edge and throwing lines like the others. Title 汐見窯 マグカップ 飴釉, legend 釉薬:飴釉, 飴釉 ringed and bold; the thumbnail rail shows amber in every view with 使用例 selected. The composition is calm and nothing is clipped; the steam is static.

S21

お手入れ open

index.html · 1280×800 · click #acc-care-btn · scroll-to .about

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L21 saw

Desktop, お手入れ open (the header turned celadon because the pointer is still on it; the + became −). Inside: two rows with status pills — 使えます (celadon tint) 電子レンジ・食器洗浄機 and 使えません (neutral) オーブン・直火 — then the care paragraph at 40em. The two pills are different widths (使えません is wider), so the two labels after them start about 6px apart (x≈676 vs 682): a small but visible ragged left edge in what should be a two-row list. The other three rows stay closed with +.

D10 defect .care-list .care-mark

The two care pills have different widths (使えます vs 使えません), so the labels after them start ~6px apart and the two-row list has a ragged left edge.

S22

サイズ・容量 open

index.html · 1280×800 · click #acc-size-btn · scroll-to .about

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L22 saw

Desktop, サイズ・容量 open: a table with a header row (サイズ / S / M) and four rows (容量, 口径, 高さ, 重さ) with hairlines, then the tolerance note. It reads correctly, but it is stretched over the full 650px accordion width: the S and M columns start at x≈789 and x≈1017, so four short values sit more than 200px apart and the eye has to travel across empty space to compare S with M. For a two-column comparison the table should be compact.

D11 defect #acc-size .spec-table

The size table stretches over the full 650px accordion width; S and M values sit 200+px apart, so comparing the two sizes means crossing empty space.

S23

extra reviews revealed

index.html · 1280×800 · click #more-btn · scroll-to #more-reviews

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L23 saw

Desktop after もっと見る, scrolled to the revealed reviews: カフェオレにちょうどいい (★5, はる さん, 2026年7月21日, 飴釉/M 320ml), 二つ目を買い足しました (★5, 青木 さん, 2026年7月6日), 色は実物を見て選びたかった (★3, Y.M. さん, 2026年6月14日), each with stars, title, meta and a 38em body, separated by hairlines like the first three. The left third of the screen is completely empty for the whole viewport: the summary card (4.6, bars) is short and has scrolled away at the top, so with six reviews open the section is lopsided and the distribution is out of sight while reading.

D12 defect .review-summary (desktop)

With the extra reviews open, the left third of the section is empty for a full screen: the short summary card scrolls away at the top, leaving the layout lopsided and the distribution out of sight while reading.

S24

reviews expanded: button state

index.html · 1280×800 · click #more-btn · scroll-to #more-btn

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L24 saw

Desktop, reviews expanded, scrolled to the button: the last revealed review and then the button, now reading 閉じる with an up chevron (the paper-2 fill is the hover state; the pointer is on it). The section rule and 同じ窯のうつわ follow. The left column is empty here as well, same as S23.

S25

mobile: pinned bar mid-page (reviews)

index.html · 375×812 · scroll-to .review-list

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L25 saw

Mobile 375, scrolled into the review list: the pinned bar sits at the bottom over the reviews, solid, with 青磁・S 240ml, ¥4,180(税込) and カートに入れる; the review text above ends clear of it. This is the brief's "pinned bottom bar on a phone mid-page" state and it reads correctly.

S26

mobile: search open

index.html · 375×812 · click #search-toggle

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L26 saw

Mobile after tapping the search icon: a panel opens under the header with the label キーワードで探す, a text field that has focus (3px celadon ring) and a 検索する button; breadcrumb and gallery move down below it. The icon button keeps a paper-2 fill here, but only because the pointer is still on it — nothing else on the button says the panel is open; the open panel directly below is the cue, which is enough at this distance.

S27

mobile: drawer with two mugs, opened from the pinned bar

index.html · 375×812 · click #qty-inc · scroll-to .review-list · click .buybar-cta · wait 600

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L27 saw

Mobile after + (quantity 2), scrolling to the reviews and tapping カートに入れる in the pinned bar: the drawer takes the full screen. カート with × at the top, the status band カートに追加しました(青磁・S 240ml・2点), one line — thumbnail, 汐見窯 マグカップ 青磁 with ¥8,360 on the same line about 19px apart, 釉薬 青磁 / サイズ S 240ml / 数量 2, 削除 — and the foot with 送料無料の対象です。, a full bar, 小計 ¥8,360(税込), レジに進む and 買い物を続ける (paper-2 fill: the tap point is now over it). Nothing is clipped; the name and price are close but not touching.

S28

quantity 4: made-to-order note

index.html · 1280×800 · element .panel · click #qty-inc · click #qty-inc · click #qty-inc

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L28 saw

Panel close-up after + three times: the stepper reads 4 with − enabled, and a note appears under the buy row: 在庫は残り3点です。4点目からは受注制作となり、お届けまで約3週間い / ただきます。 Two problems: the line breaks inside いただきます, leaving ただきます。 alone on the second line, and the note is plain 13px grey text sitting in the gap between the buttons and the assurance rule — it reads like a stray caption, not like a notice that changes the delivery date.

D13 defect #qty-note

The made-to-order note breaks inside いただきます (ただきます。 alone on line 2) and is plain grey caption text, not recognisable as a notice about a longer delivery time.

S29

newsletter: invalid address

index.html · 1280×800 · element .newsletter · fill #nl-email "shiomi" · click #nl-form button[type=submit]

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L29 saw

Newsletter block after typing "shiomi" and pressing 登録: the message メールアドレスの形式をご確認ください。 appears under the row in a light salmon that is readable on the dark footer. The field itself looks exactly as before — white, no border change, no marker — so the error is only in the line below; a user whose eyes are on the field gets no signal there.

D14 defect #nl-email[aria-invalid=true]

An invalid address changes only the message line under the row; the field itself keeps its normal look, so the error is not marked where the user is looking.

S30

keyboard: ArrowRight on the glaze radios

index.html · 1280×800 · element .panel · focus input[name=glaze][value=seiji] · press ArrowRight

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L30 saw

Panel close-up after focusing the 青磁 radio and pressing ArrowRight: the selection and focus moved to 白磁 together (native radio behaviour); the 白磁 swatch shows the ink selection ring and, outside it, the 3px celadon focus ring at a 7px offset, so selection and focus are both visible and distinct. The title and legend switched to 白磁. The size cards, stepper and buttons are unchanged.

F11fix for D10

Care pills get a fixed width (7.5em, flex:none) instead of a min-width, so both are the same width and the labels after them share one left edge.

F12fix for D11

The size table is capped at 28em (≈392px); S and M sit next to each other instead of 200px apart.

F13fix for D12

On desktop the review summary card is position: sticky; top: 24px inside its grid column, so it stays beside the reviews while they scroll and the distribution stays in view.

F14fix for D13

The made-to-order note is styled as a notice (paper-2 fill, 3px ochre rule on the left, ink text) and uses word-break: auto-phrase, so it breaks between phrases (いただきます stays whole).

F15fix for D14

An invalid email field now shows its own error state (2px salmon ring on the dark footer; a dark red border for fields on paper), and the state clears as soon as the typed address becomes valid.

S31

accordion: お手入れ and サイズ・容量 open after D10/D11

index.html · 1280×800 · element .accordion · click #acc-care-btn · click #acc-size-btn · scroll-to #acc-size

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L31 saw

Accordion close-up with サイズ・容量 and お手入れ both open (multiple panels can be open at once). The size table is now about 392px wide: サイズ / S / M header, then 容量 240ml 320ml, 口径 7.8cm 8.6cm, 高さ 8.2cm 9.4cm, 重さ 約250g 約300g, with the S and M values ~136px apart instead of 228 — easy to compare; the tolerance note follows at its own measure. In お手入れ the 使えます and 使えません pills are now the same width, so 電子レンジ・食器洗浄機 and オーブン・直火 start on one left edge. Both open rows show −, the closed ones +.

S32

quantity 4 note after D13

index.html · 1280×800 · element .panel · click #qty-inc · click #qty-inc · click #qty-inc

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L32 saw

Panel close-up at quantity 4. The note is now a notice: a paper-2 box with a 3px ochre rule on its left, ink text, reading 在庫は残り3点です。4点目からは受注制作となり、お届けまで / 約3週間いただきます。 — the line breaks between phrases and いただきます stays whole. It sits between the buy row and the assurance rule with even spacing and reads as information about delivery, not a caption.

S33

newsletter error after D14

index.html · 1280×800 · element .newsletter · fill #nl-email "shiomi" · click #nl-form button[type=submit]

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L33 saw

Newsletter close-up after an invalid address ("shiomi" + 登録): the field now has a 2px salmon ring around its border on the dark footer, and the same-colour message メールアドレスの形式をご確認ください。 sits below — the error is marked on the field and explained under it.

S34

extra reviews with sticky summary after D12

index.html · 1280×800 · click #more-btn · scroll-to #more-reviews

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L34 saw

Desktop with the extra reviews open, scrolled to them (same framing as S23). The summary card — 4.6 / 5, stars, 128件のレビュー, the five bars — now stays pinned at the top of the left column (y≈24) beside the revealed reviews, so the section is balanced and the distribution is visible while reading; its right edge keeps the 72px gap to the list. The reviews are unchanged.

V10verified D10 by L31

Equal-width pills, aligned labels.

V11verified D11 by L31

Table capped at 28em; S and M side by side.

V12verified D12 by L34

Summary card sticks beside the revealed reviews.

V13verified D13 by L32

Notice style; phrase break.

V14verified D14 by L33

Field shows its own error ring.

G28exit 0vlmkit check scroll index.html --viewport 1280x720

pageScrolled 1080 · stickyFixed 1 · engagedSticky 0 · snaps 0 · issues 0

output, 12 line(s), 1.4s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1080px
sticky/fixed elements: 1 (sticky engaged by the scroll: 0)
snap containers driven: 0

Sticky / fixed:
  - div.review-summary: sticky top=24px viewport y 1393 -> 313

No scroll-behavior issues detected.
G29exit 0vlmkit check scroll index.html --viewport 1280x1000

pageScrolled 1500 · stickyFixed 1 · engagedSticky 1 · snaps 0 · issues 0

output, 12 line(s), 1.4s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1500px
sticky/fixed elements: 1 (sticky engaged by the scroll: 1)
snap containers driven: 0

Sticky / fixed:
  - div.review-summary: sticky top=24px viewport y 1393 -> 24

No scroll-behavior issues detected.
N14toolabout G28

check scroll scrolls a fixed 1.5 viewport heights (G28 at 1280x720: "page scrolled: 1080px … sticky engaged by the scroll: 0 … div.review-summary: sticky top=24px viewport y 1393 -> 313"), so a sticky element that starts lower than that is inventoried but never exercised, and the status is still ok. The report does say engaged 0, but nothing flags it. Re-running at 1280x1000 (G29) scrolls 1500px and shows it working: "sticky engaged by the scroll: 1 … viewport y 1393 -> 24". A --scroll-to or 'scroll until every sticky has engaged' option would close this.

S35

empty cart drawer from the header

index.html · 1280×800 · click #cart-open · wait 500

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L35 saw

Desktop, the header's カート button pressed with nothing in the cart: the drawer opens with カート and × at the top and one centred grey line, カートに商品はありません。, about 70px below the header rule — and then 650px of empty paper down to the bottom of the panel. No foot, no button, no picture. It works (× and Escape close it), but it looks unfinished next to the filled drawer in S7: a first-time visitor who opens the cart gets a blank panel with no next step.

D15 defect #cart-empty

The empty cart drawer is a single grey line in an otherwise blank 800px panel, with no picture and no way forward except the × — it reads as unfinished and gives no next step.

S36

お気に入り pressed

index.html · 1280×800 · element .buy-row · @2x · click #fav

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L36 saw

Buy row close-up (2x) after pressing お気に入り: the button now has a pale celadon tint, an ink border and a filled celadon heart, while カートに入れる next to it is unchanged. The pressed state is carried by the fill of the heart and the border, not by colour alone, and the label stays お気に入り (the state is aria-pressed).

S37

keyboard: ArrowDown twice in the thumbnail tablist

index.html · 1280×800 · element .gallery · focus #tab-front · press ArrowDown · press ArrowDown

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L37 saw

Gallery close-up after focusing the 正面 thumbnail and pressing ArrowDown twice: selection and focus moved to 上から — its thumbnail has the dark selected border, the label is bold, and a 3px celadon focus ring surrounds the whole tab including its label; 正面 and 側面 went back to the light border. The main image switched to the top view. Keyboard operation of the gallery is visible and unambiguous.

F16fix for D15

The empty drawer now has a line-drawn mug (64px, control-grey strokes), カートに商品はありません。 in ink bold, a supporting line 気になるうつわがあれば、カートに入れてお進みください。 and an outlined 買い物を続ける button that closes the drawer; flow.json gained two steps for it.

S38

empty cart drawer after D15

index.html · 1280×800 · click #cart-open · wait 500

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L38 saw

Desktop, empty cart opened from the header after the fix: under カート / × there is now a small line-drawn mug with three steam strokes in control grey, カートに商品はありません。 in bold ink, the supporting line 気になるうつわがあれば、カートに入れて / お進みください。 (broken between phrases), and an outlined 買い物を続ける button, all centred in the top third of the panel. The rest of the panel is empty paper, which now reads as breathing room under a complete block rather than as a missing layout.

G30exit 0vlmkit verify flow index.html --flow flow.json

verdict: DONE (10/10 steps)

done true · passed 10 · total 10

output, 43 line(s), 2.8s
vlmkit verify flow
source: index.html

verdict: DONE (10/10 steps)

✓ step 1: the header cart opens the empty drawer
    ✓ #cart-drawer visible 
    ✓ #cart-empty visible 
    ✓ #cart-foot hidden 
    ✓ #cart-lines > li count=0 
✓ step 2: 買い物を続ける in the empty drawer closes it and returns focus to the cart button
    ✓ #cart-drawer hidden 
    ✓ #cart-open focused 
✓ step 3: step the quantity up to 2
    ✓ #qty aria-valuenow=2 
    ✓ #qty-dec aria-disabled=false 
✓ step 4: カートに入れる opens the drawer with two mugs
    ✓ #cart-drawer visible 
    ✓ #cart-close focused 
    ✓ #cart-lines > li count=1 
    ✓ #cart-lines text~"青磁" 
    ✓ #cart-lines text~"S 240ml" 
    ✓ #cart-subtotal text~"¥8,360" 
    ✓ #cart-count text~"2" 
    ✓ #checkout visible 
✓ step 5: Escape closes the drawer and returns focus
    ✓ #cart-drawer hidden 
    ✓ #add-to-cart focused 
✓ step 6: choose 飴釉 and M
    ✓ html data-glaze=ameyu 
    ✓ #product-title text~"飴釉" 
✓ step 7: size M
    ✓ .buybar-variant text~"M 320ml" 
✓ step 8: a second variant becomes a second line
    ✓ #cart-lines > li count=2 
    ✓ #cart-count text~"4" 
    ✓ #cart-subtotal text~"¥16,720" 
✓ step 9: remove the first line
    ✓ #cart-lines > li count=1 
    ✓ #cart-count text~"2" 
    ✓ #cart-lines text~"飴釉" 
✓ step 10: close button closes
    ✓ #cart-drawer hidden
V15verified D15 by L38

Empty state has an illustration, a next step and a working close button (flow steps 1-2 pass in G30).

S39

reduced motion: drawer 50ms after opening

index.html · 1280×800 · reduced motion · click #cart-open · wait 50

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L39 saw

Desktop with prefers-reduced-motion, 50ms after pressing the header カート: the empty drawer is fully in place at the right edge, backdrop at full dim, content identical to S38.

S40

?animate=0: drawer 50ms after opening

index.html?animate=0 · 1280×800 · click #cart-open · wait 50

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L40 saw

Desktop loaded as index.html?animate=0, 50ms after pressing カート: the drawer is fully in place, identical to S39 — the page loaded fine with the query string from disk.

S41

default motion: drawer 50ms after opening (control)

index.html · 1280×800 · click #cart-open · wait 50

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L41 saw

The control: default motion, 50ms after pressing カート. It is identical to S39 and S40 — the drawer is already fully in place, with no mid-slide frame, although its slide-in is 320ms. So this capture path settles (or outlasts) the animation before the shutter, and the three shots cannot tell the reduced-motion and animate=0 paths apart from the default one. They show only that each path ends in the right place; the evidence that motion is honoured has to come from check motion (G21), not from these pictures.

N15decisionabout S41

Reduced motion is claimed on the strength of check motion (G21: the prefers-reduced-motion rule exists and nothing runs uncontrolled; re-run in the final round) and of the stylesheet, not on S39-S41: the default-motion control S41 already shows the drawer settled 50ms after opening, so the shot tool evidently finishes animations before capturing. Recorded so the three near-identical shots are not read as a demonstration.

S42

index.html · 768×1024 · full page, 5 screen(s)

S42 screen 1S42 screen 2S42 screen 3S42 screen 4S42 screen 5
L42 saw

Tablet 768x1024 after rounds 2-3, 5 screens. Screen 1: 720x540 stage — at this 1.2x scale the crackle is the most prominent it gets (cells ~50px, lines ~1px), still reading as a crackled celadon rather than a pattern; the wavy glaze edge and ground shadow hold up; the thumbnail strip (4 x 104px) sits left-aligned under the stage with ~270px of paper to its right, which is quiet rather than unbalanced; the opaque pinned bar at the bottom. Screen 2: price, rating, swatches, S/M cards sharing a row with the stepper, the buy row, assurances; the lead at 36em. Screen 3: accordion rows, the full-width summary card and the first review at 38em. Screen 4: reviews, もっと見る, four related cards in one row (≈162px) with names and prices on one line each. Screen 5: footer with the serif 汐見窯だより, the email row, three link columns (特定商取引法に基づく表記 on one line) and the copyright/disclaimer. No overlap, clipping or overflow; nothing to fix at this width.

R4 · final check

builder
G31exit 0vlmkit check integrity index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)

verdict clean · findings 0 · fails 0 · warns 0 · exempted 24 · viewports 3

output, 27 line(s), 5.5s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)
  1280x800: 8 component(s), ink 26.3%, 109 text block(s)
  768x900: 8 component(s), ink 28.9%, 112 text block(s)
  375x700: 8 component(s), ink 32.6%, 112 text block(s)

No integrity defects detected.

Exempted candidates (the tool's call — audit the rule, not the page):
  - [text-clipped] span.badge > span:nth-of-type(2) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #search-toggle > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #cart-open > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  … 9 more
G32exit 1vlmkit check copy index.html --manifest copy.txt

missing 1 · placeholders 0 · manifestLines 14 · invisibleOnly 1 · statesExplored 9 · revealedOnly 0

output, 11 line(s), 1.8s
vlmkit check copy
source: index.html

status: suspect
rendered text: 1083 chars
disclosure states: 9 explored (details / tabs / aria-expanded)
manifest: 14 line(s), missing 1, 1 invisible-only

Issues:
  x copy-invisible: Manifest line found ONLY in text a user cannot see (reason: unknown): "¥4,180(税込)". Invisible text does not satisfy the copy gate — render it visibly or remove the hidden copy. If this invisibility is deliberate (e.g. assistive-tech-only copy), re-run with --allow-invisible unknown.
  x copy-missing: Manifest line not found in rendered text or any of 9 revealed disclosure state(s): "レジに進む" (comparison is whitespace-normalized, case-sensitive).
G33exit 0vlmkit check design index.html

verdict: DRIFT (2 finding(s))

verdict drift · drifting 2 · roles 11

output, 31 line(s), 1.6s
vlmkit check design
source: index.html

verdict: DRIFT (2 finding(s))
  exits 0 — 2 warn(s) did not fail this command. To gate on one: --rule component-drift=suspect
  roles judged: 6 of 11 seen, spacing values: 22
  coverage: 42 of 315 visible element(s) carried an inferable role; 4 skipped as non-resting
    no role: span x82, div x30, li x30, a x26, svg x22, p x16, +18 more tag(s)
    A role comes from role="..." or from button/input/select/textarea/h1-h6. Layout elements
    (div, span, p, a) have none, so a large skip count is normal — this gate judges components,
    not every box. Add role="..." where an element IS a component to widen the coverage.
  text-free: 8 (0 judged on box alone — font-size/weight is not observable without painted text)

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  button          11 inst    6 styles  reuse  1.83x  3 one-off  drift
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  img              6 inst    1 styles  reuse     6x  0 one-off  ok
  tab              3 inst    1 styles  reuse     3x  0 one-off  ok
  input:radio      3 inst    2 styles  reuse   1.5x  1 one-off  drift
  tablist          1 inst    1 styles  reuse     1x  1 one-off  not judged
  tabpanel         1 inst    1 styles  reuse     1x  1 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  spinbutton       1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: tablist (1), tabpanel (1), h1 (1), spinbutton (1), input:email (1) — under --min-instances 3, so no finding can come from them.
  To keep judging them: --min-instances 2 --min-reuse 2 (both — a 2-instance role cannot reach 3x however many instances the floor allows).

Findings
  ! [component-drift] button: 11 "button" elements render 6 distinct styles (used 4x, 2x, 2x, 1x, …; a system reuses each style 3x or more, and this role averages 1.83x). Dominant style, used 4x: padding 12/4/12/4, radius 0, 16px/600, border 0, bg rgba(0, 0, 0, 0). Deviating: button#search-toggle (padding 0/10/0/10, radius 8, 14px/400, border 0, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 10, padding-bottom 12 → 0 and 4 more; button#fav (padding 0/22/0/22, radius 8, 15px/700, border 1, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more; button#add-to-cart (padding 0/22/0/22, radius 8, 16px/700, border 1, bg rgb(47, 97, 83)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more and 2 more. This reports inconsistency, not which style is correct.
  ! [component-drift] input:radio: 3 "input:radio" elements render 2 distinct styles (used 2x, 1x; a system reuses each style 3x or more, and this role averages 1.5x). Dominant style, used 2x: padding 0/0/0/0, radius 50, 16px/400, border 1, bg rgba(0, 0, 0, 0). Deviating: div.sizes>label.size>input (padding 0/0/0/0, radius 8, 16px/400, border 1, bg rgb(252, 250, 246)) — differs in border-radius 50 → 8, background-color rgba(0, 0, 0, 0) → rgb(252, 250, 246). This reports inconsistency, not which style is correct.
G34exit 0vlmkit check composition index.html

verdict: COMPOSED (0 finding(s))

verdict composed · proximity 0 · flatSteps 0 · railNearMisses 0

output, 17 line(s), 1.8s
vlmkit check composition
source: index.html

verdict: COMPOSED (0 finding(s))
  measured: 0 label(s), 3 heading level(s), 60 wide block(s) on 5 left / 5 right rail(s) — from 267 visible box(es)
  11 label(s) not judged: they open a box that paints its own group edge, so nothing above them could be mis-grouped with

Type hierarchy (largest instance of each declared level)
  h1     30px / 600   h1#product-title
  h2     26px / 600   h2#about-title
  h3     16px / 600   div.accordion>div.acc-item>h3.acc-heading
  body 13px, largest 52px (4x), heaviest +300 weight

Group gaps: 0px between heading-led groups vs 8px inside them (0x, 12 sample(s)). Context only — intact pages measure 0.86-3.00x, so this cannot carry a verdict.

Proximity, alignment and type hierarchy all read consistently.
G35exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f7f3ec · bodyInk #23211d · linkInk #b8b1a5 · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

output, 28 line(s), 1.6s
vlmkit check color
source: index.html

verdict: CONSISTENT (0 finding(s))
  measured: 2 control(s), 26 link(s) in a text flow — from 301 visible box(es)

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  4 distinct
    #f7f3ec   75.9%     4 el  
    #efe9df   12.3%     5 el  section.product>div.gallery>div.stage
    #1f2b27    9.2%     1 el  footer.site-footer
    #fcfaf6    2.6%     3 el  div.sizes>label.size>input
  ink       8 distinct
    #23211d   55.1%    39 el  a.wordmark>span.wordmark-text>span.wordmark-ja
    #4a453e   16.9%    36 el  ul>li>a
    #b8b1a5    9.7%    13 el  div.footer-inner>section.newsletter>p.nl-lead
    #686157    7.6%    21 el  a.wordmark>span.wordmark-text>span.wordmark-en
    #ece6dc    6.6%     6 el  h2#nl-title
    …and 3 more
  marks     6 distinct
    #ddd5c8   54.6%    25 el  header.site-header
    #cbc2b3   17.4%     5 el  main#main>section.about>div.accordion
    #8a8277   11.6%    34 el  div.swatches>label.swatch>input
    #ece6dc    6.3%     1 el  footer.site-footer>div.footer-bottom
    #23211d    5.6%     8 el  button#tab-front>span.thumb-img
    …and 1 more
  base #f7f3ec, body ink #23211d, link ink #b8b1a5 on 11 element(s)
G36exit 0vlmkit check a11y contrast index.html

inspected 119 · failures 0

output, 5 line(s), 1.5s
  vlmkit check a11y contrast
  html: examples/sites/shop/index.html
  inspected 119 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/shop/test-results/a11y-contrast/index-07f7b4b9/report.md
G37exit 1vlmkit check a11y focus index.html

steps 43 · findings 4

output, 9 line(s), 1.7s
  vlmkit check a11y focus
  source: index.html
  captured 43 focus step(s)
  ✗ 4 finding(s)
    [reverse] Focus moved up by 233px (from `main#main>section.product.container>div.panel>div.buy-row>button#fav` at y=561 to `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn` at y=328). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [reverse] Focus moved up by 188px (from `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn` at y=523 to `main#main>section#reviews>div.reviews-grid>div.review-list>button#more-btn` at y=336). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [skip-row] Focus jumped down by 216px (from `main#main>section#reviews>div.reviews-grid>div.review-list>button#more-btn` to `main#main>section.related.container>div.section-head>a.text-link`). Confirm no focusable element was unintentionally skipped.
    [reverse] Focus moved up by 173px (from `main#main>section.related.container>div.section-head>a.text-link` at y=552 to `main#main>section.related.container>ul.cards>li.card>a.card-link` at y=379). Visual order is top-to-bottom; check `tabindex` or DOM order.
  report: examples/sites/shop/test-results/a11y-focus-order/index-07f7b4b9/report.md
G38exit 0vlmkit check a11y touch index.html

level AA · inspected 49 · failures 0 · wcagExempt 0

output, 5 line(s), 1.5s
  vlmkit check a11y touch
  source: index.html  level: WCAG AA (24×24 min)
  inspected 49 interactive element(s)
  ✓ 0 undersized target(s)
  report: examples/sites/shop/test-results/a11y-touch/index-07f7b4b9/report.md
G39exit 0vlmkit scan scroll index.html

containers 0 · overflowX 0 · issues 6

output, 18 line(s), 1.5s
vlmkit scan scroll
source: index.html (1280x720)

status: warn
  exits 0 — 6 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 1280x3105 — horizontal overflow 0px, vertical scroll 2385px
scroll containers: 0 (dead scrollports 1, clipped 6)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G40exit 0vlmkit scan scroll index.html --viewport 375x740

containers 0 · overflowX 0 · issues 8

output, 20 line(s), 1.5s
vlmkit scan scroll
source: index.html (375x740)

status: warn
  exits 0 — 8 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 375x5021 — horizontal overflow 0px, vertical scroll 4281px
scroll containers: 0 (dead scrollports 1, clipped 8)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content #cart-open > span:nth-of-type(1): #cart-open > span:nth-of-type(1) clips 42px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content #search-toggle > span:nth-of-type(1): #search-toggle > span:nth-of-type(1) clips 28px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G41exit 0vlmkit scan handlers index.html

registrations 40 · elements 32 · suspects 0

output, 42 line(s), 1.6s
vlmkit scan handlers
source: index.html

status: 1 warn(s)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
registrations: 40 across 32 element(s), on a page presenting 49 control(s)

  - fieldset.option>div.swatches>label.swatch>input "seiji": change
  - fieldset.option>div.swatches>label.swatch>input "hakuji": change
  - fieldset.option>div.swatches>label.swatch>input "ameyu": change
  - fieldset.option>div.sizes>label.size>input "S": change
  - fieldset.option>div.sizes>label.size>input "M": change
  - section.product>div.gallery>div.thumbs>button#tab-front "正面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-side "側面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-top "上から": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-use "使用例": click, keydown
  - div.options-row>div.option>div.stepper>button#qty-dec "数量を1つ減らす": click
  - div.options-row>div.option>div.stepper>button#qty-inc "数量を1つ増やす": click
  - div.options-row>div.option>div.stepper>input#qty "1": keydown, input, compositionend, change (no role)
  - section.product>div.panel>div.buy-row>button#fav "お気に入り": click
  - section.product>div.panel>div.buy-row>button#add-to-cart "カートに入れる": click
  - aside#buybar>button.btn "カートに入れる": click (no role)
  - header.site-header>div.header-inner>div.header-actions>button#cart-open "カート 0点": click
  - dialog#cart-drawer "カート カートに商品はありません。 気になるうつわがあれば、カートに入れてお進み": close, click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-head>button#cart-close "カートを閉じる": click (no role)
  - div.drawer-inner>div.drawer-body>div#cart-empty>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-body>ul#cart-lines "": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button#checkout "レジに進む": click (no role)
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn "商品詳細": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-size-btn "サイズ・容量": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-care-btn "お手入れ": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn "配送・返品": click
  - section#reviews>div.reviews-grid>div.review-list>button#more-btn "もっと見る": click
  - header.site-header>div.header-inner>div.header-actions>button#search-toggle "検索": click
  - header.site-header>div#search-panel "キーワードで探す 検索する": keydown (no role)
  - header.site-header>div#search-panel>form#search-form "キーワードで探す 検索する": submit (no role)
  - footer.site-footer>div.footer-inner>section.newsletter>form#nl-form "メールアドレス 登録": submit (delegation container)
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email "": input

Issues:
  warn [unprobed-handler-types] 7 handler type(s) registered and NONE exercised: change, click, close, compositionend, input, keydown, submit — this gate is an inventory and presses nothing. A clean result here says the wiring exists, not that it works. Run 'check interactions --handlers' to focus and activate the controls, add '--probe-drag' for the drag surfaces, or drive the rest with a 'verify flow' script.
G42exit 0vlmkit check interactions index.html --max-elements 80

elements 48 · suspects 0 · warns 0

output, 54 line(s), 21.8s
vlmkit check interactions
source: index.html

status: ok
interactive elements: 48

  - [link] "本文へスキップ" focus✓
  - [link] "汐見窯 SHIOMI-GAMA" focus✓
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [button] "カート 0点" focus✓ | Enter: focus moves within | opens dialog (focus enters), traps | Esc closes+returns focus
  - [link] "ホーム" focus✓
  - [link] "うつわ" focus✓
  - [link] "マグカップ" focus✓
  - [tab] "正面" focus✓ | ArrowRight: selected true -> false
  - [tab] "側面" unreachable | ArrowRight: focus moves
  - [tab] "上から" unreachable | ArrowRight: focus moves
  - [tab] "使用例" unreachable | ArrowRight: focus moves
  - [link] "128件のレビュー" focus✓
  - [radio] "seiji" focus✓ | ArrowDown: focus moves
  - [radio] "hakuji" unreachable | ArrowDown: focus moves
  - [radio] "ameyu" unreachable | ArrowDown: focus moves
  - [radio] "S" focus✓ | ArrowDown: focus moves
  - [radio] "M" unreachable | ArrowDown: focus moves
  - [button] "数量を1つ減らす" focus✓ | Enter: layout change | announces
  - [button] "数量を1つ増やす" focus✓ | Enter: layout change | announces
  - [button] "カートに入れる" focus✓ | Enter: focus moves within | announces
  - [button] "お気に入り" focus✓ | Enter: pressed false -> true | announces
  - [button] "商品詳細" focus✓ | Enter: expanded false -> true
  - [button] "サイズ・容量" focus✓ | Enter: expanded false -> true
  - [button] "お手入れ" focus✓ | Enter: expanded false -> true
  - [button] "配送・返品" focus✓ | Enter: expanded false -> true
  - [button] "もっと見る" focus✓ | Enter: expanded false -> true
  - [link] "うつわをすべて見る" focus✓
  - [link] "平皿 白磁 21cm ¥3,520(税込)" focus✓
  - [link] "小鉢 青磁 ¥2,640(税込)" focus✓
  - [link] "湯呑 飴釉 ¥2,860(税込)" focus✓
  - [link] "新作 急須 青磁 360ml ¥9,900(税込)" focus✓
  - [textbox] "" focus✓
  - [button] "登録" focus✓ | Enter: layout change | announces
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [link] "配送・送料" focus✓
  - [link] "返品・交換" focus✓
  - [link] "よくあるご質問" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "工房のこと" focus✓
  - [link] "特定商取引法に基づく表記" focus✓
  - [link] "プライバシーポリシー" focus✓
G43exit 0vlmkit check scroll index.html --viewport 375x740

pageScrolled 1110 · stickyFixed 1 · engagedSticky 0 · snaps 0 · issues 0

output, 12 line(s), 1.3s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1110px
sticky/fixed elements: 1 (sticky engaged by the scroll: 0)
snap containers driven: 0

Sticky / fixed:
  - #buybar: fixed top=671px viewport y 671 -> 671

No scroll-behavior issues detected.
G44exit 0vlmkit check scroll index.html --viewport 1280x1000

pageScrolled 1500 · stickyFixed 1 · engagedSticky 1 · snaps 0 · issues 0

output, 12 line(s), 1.4s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1500px
sticky/fixed elements: 1 (sticky engaged by the scroll: 1)
snap containers driven: 0

Sticky / fixed:
  - div.review-summary: sticky top=24px viewport y 1393 -> 24

No scroll-behavior issues detected.
G45exit 0vlmkit check grounding index.html --viewport 1280x720

targets 24 · scale 0.5 · issues 1

output, 33 line(s), 1.4s
vlmkit check grounding
source: index.html (1280x720)

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule ambiguous-target=suspect
frame: 640x360 screenshot px — medium, cap 640x480, scale 0.50 (every coordinate below is in these 640x360 pixels)
targets: 24 actionable in frame (25 disabled or out of the frame)

Action map (click point in screenshot px):
  t2 link "汐見窯 SHIOMI-GAMA" @ (126,18) 211x29 a.wordmark
  t3 link "新作" @ (254,18) 30x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t4 link "うつわ" @ (294,18) 38x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t5 link "作家" @ (334,18) 30x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t6 link "読みもの" @ (378,18) 46x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)
  t7 button "検索" @ (545,18) 38x22 #search-toggle
  t8 button "カート 0 点" @ (595,18) 58x22 #cart-open
  t9 link "ホーム" @ (30,50) 20x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t10 link "うつわ" @ (62,50) 20x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t11 link "マグカップ" @ (101,50) 33x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t12 tab "正面" @ (41,92) 42x54 #tab-front
  t13 tab "側面" @ (41,152) 42x54 #tab-side
  t14 tab "上から" @ (41,212) 42x54 #tab-top
  t15 tab "使用例" @ (41,272) 42x54 #tab-use
  t16 link "128件のレビュー" @ (488,139) 55x15 a.rating-link
  t17 radio "seiji" @ (411,188) 22x22 div.swatches > label:nth-of-type(1) > input:nth-of-type(1)
  t18 radio "hakuji" @ (444,188) 22x22 div.swatches > label:nth-of-type(2) > input:nth-of-type(1)
  t19 radio "ameyu" @ (477,188) 22x22 div.swatches > label:nth-of-type(3) > input:nth-of-type(1)
  t20 radio "S" @ (433,255) 67x24 div.sizes > label:nth-of-type(1) > input:nth-of-type(1)
  t21 radio "M" @ (504,255) 67x24 div.sizes > label:nth-of-type(2) > input:nth-of-type(1)
  … 4 more — --json emits the full map

Issues:
  ! ambiguous-target: 2 links in the frame all read "うつわ" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.
G46exit 0vlmkit check grounding index.html --viewport 375x740

targets 15 · scale 0.43 · issues 1

output, 27 line(s), 1.4s
vlmkit check grounding
source: index.html (375x740)

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule ambiguous-target=suspect
frame: 162x320 screenshot px — low, cap 375x320, scale 0.43 (every coordinate below is in these 162x320 pixels)
targets: 15 actionable in frame (35 disabled or out of the frame)

Action map (click point in screenshot px):
  t2 link "汐見窯 SHIOMI-GAMA" @ (38,13) 62x25 a.wordmark
  t3 link "新作" @ (20,35) 24x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t4 link "うつわ" @ (57,35) 31x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t5 link "作家" @ (94,35) 24x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t6 link "読みもの" @ (135,35) 38x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)
  t7 button "検索" @ (119,13) 19x19 #search-toggle
  t8 button "カート 0 点" @ (144,13) 29x19 #cart-open
  t9 link "ホーム" @ (16,56) 17x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t10 link "うつわ" @ (43,56) 17x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t11 link "マグカップ" @ (77,56) 29x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t12 tab "正面" @ (24,257) 34x44 #tab-front
  t13 tab "側面" @ (62,257) 34x44 #tab-side
  t14 tab "上から" @ (100,257) 34x44 #tab-top
  t15 tab "使用例" @ (138,257) 34x44 #tab-use
  t50 button "カートに入れる" @ (121,305) 68x21 button.btn.btn-primary.buybar-cta

Issues:
  ! ambiguous-target: 2 links in the frame all read "うつわ" (t4 at 57,35, t10 at 43,56) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.
G47exit 0vlmkit check grounding index.html --viewport 1280x720 --json

targets 24 · scale 0.5 · issues 1

output, 1615 line(s), 1.4s
{
  "gate": "check.grounding",
  "command": "check grounding",
  "verdict": "pass",
  "counts": {
    "suspect": 0,
    "warn": 1,
    "info": 0
  },
  "findings": [
    {
      "rule": "ambiguous-target",
      "severity": "warn",
      "message": "2 links in the frame all read \"うつわ\" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.",
      "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)"
    }
  ],
  "suppressed": [],
  "retuned": [],
  "report": {
    "source": "index.html",
    "frame": {
      "resolution": "medium, cap 640x480",
      "width": 640,
      "height": 360,
      "scale": 0.5,
      "viewportWidth": 1280,
      "viewportHeight": 720
    },
    "targets": [
      {
        "id": "t1",
        "selector": "a.skip-link",
        "role": "link",
        "label": "本文へスキップ",
        "point": {
          "x": 42,
          "y": -89
        },
        "cssPoint": {
          "x": 84,
          "y": -177
        },
        "box": {
          "x": 8,
          "y": -100,
          "width": 68,
          "height": 23
        },
        "visibleBox": {
          "x": 8,
          "y": -100,
          "width": 68,
          "height": 23
        },
        "minSide": 23,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t2",
        "selector": "a.wordmark",
        "role": "link",
        "label": "汐見窯 SHIOMI-GAMA",
        "point": {
          "x": 126,
          "y": 18
        },
        "cssPoint": {
          "x": 251,
          "y": 36
        },
        "box": {
          "x": 20,
          "y": 3,
          "width": 211,
          "height": 29
        },
        "visibleBox": {
          "x": 20,
          "y": 3,
          "width": 211,
          "height": 29
        },
        "minSide": 29,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t11",
        "aimMargin": 26.6
      },
      {
        "id": "t3",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "新作",
        "point": {
          "x": 254,
          "y": 18
        },
        "cssPoint": {
          "x": 508,
          "y": 36
        },
        "box": {
          "x": 239,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "visibleBox": {
          "x": 239,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t4",
        "aimMargin": 21
      },
      {
        "id": "t4",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "うつわ",
        "point": {
          "x": 294,
          "y": 18
        },
        "cssPoint": {
          "x": 588,
          "y": 36
        },
        "box": {
          "x": 275,
          "y": 6,
          "width": 38,
          "height": 25
        },
        "visibleBox": {
          "x": 275,
          "y": 6,
          "width": 38,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [
          "ambiguous-target"
        ],
        "nearest": "t3",
        "aimMargin": 25
      },
      {
        "id": "t5",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "作家",
        "point": {
          "x": 334,
          "y": 18
        },
        "cssPoint": {
          "x": 668,
          "y": 36
        },
        "box": {
          "x": 319,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "visibleBox": {
          "x": 319,
          "y": 6,
          "width": 30,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t4",
        "aimMargin": 21
      },
      {
        "id": "t6",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "読みもの",
        "point": {
          "x": 378,
          "y": 18
        },
        "cssPoint": {
          "x": 756,
          "y": 36
        },
        "box": {
          "x": 355,
          "y": 6,
          "width": 46,
          "height": 25
        },
        "visibleBox": {
          "x": 355,
          "y": 6,
          "width": 46,
          "height": 25
        },
        "minSide": 25,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t5",
        "aimMargin": 29
      },
      {
        "id": "t7",
        "selector": "#search-toggle",
        "role": "button",
        "label": "検索",
        "point": {
          "x": 545,
          "y": 18
        },
        "cssPoint": {
          "x": 1091,
          "y": 36
        },
        "box": {
          "x": 526,
          "y": 7,
          "width": 38,
          "height": 22
        },
        "visibleBox": {
          "x": 526,
          "y": 7,
          "width": 38,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t8",
        "aimMargin": 21
      },
      {
        "id": "t8",
        "selector": "#cart-open",
        "role": "button",
        "label": "カート 0 点",
        "point": {
          "x": 595,
          "y": 18
        },
        "cssPoint": {
          "x": 1190,
          "y": 36
        },
        "box": {
          "x": 566,
          "y": 7,
          "width": 58,
          "height": 22
        },
        "visibleBox": {
          "x": 566,
          "y": 7,
          "width": 58,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t7",
        "aimMargin": 31
      },
      {
        "id": "t9",
        "selector": "nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "ホーム",
        "point": {
          "x": 30,
          "y": 50
        },
        "cssPoint": {
          "x": 60,
          "y": 100
        },
        "box": {
          "x": 20,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "visibleBox": {
          "x": 20,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t12",
        "aimMargin": 15
      },
      {
        "id": "t10",
        "selector": "nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "うつわ",
        "point": {
          "x": 62,
          "y": 50
        },
        "cssPoint": {
          "x": 124,
          "y": 100
        },
        "box": {
          "x": 52,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "visibleBox": {
          "x": 52,
          "y": 43,
          "width": 20,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [
          "ambiguous-target"
        ],
        "nearest": "t12",
        "aimMargin": 15
      },
      {
        "id": "t11",
        "selector": "nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "マグカップ",
        "point": {
          "x": 101,
          "y": 50
        },
        "cssPoint": {
          "x": 201,
          "y": 100
        },
        "box": {
          "x": 84,
          "y": 43,
          "width": 33,
          "height": 15
        },
        "visibleBox": {
          "x": 84,
          "y": 43,
          "width": 33,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t2",
        "aimMargin": 18
      },
      {
        "id": "t12",
        "selector": "#tab-front",
        "role": "tab",
        "label": "正面",
        "point": {
          "x": 41,
          "y": 92
        },
        "cssPoint": {
          "x": 82,
          "y": 184
        },
        "box": {
          "x": 20,
          "y": 65,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 65,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t13",
        "aimMargin": 33
      },
      {
        "id": "t13",
        "selector": "#tab-side",
        "role": "tab",
        "label": "側面",
        "point": {
          "x": 41,
          "y": 152
        },
        "cssPoint": {
          "x": 82,
          "y": 304
        },
        "box": {
          "x": 20,
          "y": 125,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 125,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t12",
        "aimMargin": 33
      },
      {
        "id": "t14",
        "selector": "#tab-top",
        "role": "tab",
        "label": "上から",
        "point": {
          "x": 41,
          "y": 212
        },
        "cssPoint": {
          "x": 82,
          "y": 424
        },
        "box": {
          "x": 20,
          "y": 185,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 185,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t13",
        "aimMargin": 33
      },
      {
        "id": "t15",
        "selector": "#tab-use",
        "role": "tab",
        "label": "使用例",
        "point": {
          "x": 41,
          "y": 272
        },
        "cssPoint": {
          "x": 82,
          "y": 544
        },
        "box": {
          "x": 20,
          "y": 245,
          "width": 42,
          "height": 54
        },
        "visibleBox": {
          "x": 20,
          "y": 245,
          "width": 42,
          "height": 54
        },
        "minSide": 42,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t14",
        "aimMargin": 33
      },
      {
        "id": "t16",
        "selector": "a.rating-link",
        "role": "link",
        "label": "128件のレビュー",
        "point": {
          "x": 488,
          "y": 139
        },
        "cssPoint": {
          "x": 976,
          "y": 279
        },
        "box": {
          "x": 460,
          "y": 132,
          "width": 55,
          "height": 15
        },
        "visibleBox": {
          "x": 460,
          "y": 132,
          "width": 55,
          "height": 15
        },
        "minSide": 15,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t19",
        "aimMargin": 38
      },
      {
        "id": "t17",
        "selector": "div.swatches > label:nth-of-type(1) > input:nth-of-type(1)",
        "role": "radio",
        "label": "seiji",
        "point": {
          "x": 411,
          "y": 188
        },
        "cssPoint": {
          "x": 822,
          "y": 376
        },
        "box": {
          "x": 400,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "visibleBox": {
          "x": 400,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t18",
        "aimMargin": 22
      },
      {
        "id": "t18",
        "selector": "div.swatches > label:nth-of-type(2) > input:nth-of-type(1)",
        "role": "radio",
        "label": "hakuji",
        "point": {
          "x": 444,
          "y": 188
        },
        "cssPoint": {
          "x": 888,
          "y": 376
        },
        "box": {
          "x": 433,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "visibleBox": {
          "x": 433,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t17",
        "aimMargin": 22
      },
      {
        "id": "t19",
        "selector": "div.swatches > label:nth-of-type(3) > input:nth-of-type(1)",
        "role": "radio",
        "label": "ameyu",
        "point": {
          "x": 477,
          "y": 188
        },
        "cssPoint": {
          "x": 954,
          "y": 376
        },
        "box": {
          "x": 466,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "visibleBox": {
          "x": 466,
          "y": 177,
          "width": 22,
          "height": 22
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t18",
        "aimMargin": 22
      },
      {
        "id": "t20",
        "selector": "div.sizes > label:nth-of-type(1) > input:nth-of-type(1)",
        "role": "radio",
        "label": "S",
        "point": {
          "x": 433,
          "y": 255
        },
        "cssPoint": {
          "x": 867,
          "y": 509
        },
        "box": {
          "x": 400,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "visibleBox": {
          "x": 400,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t25",
        "aimMargin": 26
      },
      {
        "id": "t21",
        "selector": "div.sizes > label:nth-of-type(2) > input:nth-of-type(1)",
        "role": "radio",
        "label": "M",
        "point": {
          "x": 504,
          "y": 255
        },
        "cssPoint": {
          "x": 1008,
          "y": 509
        },
        "box": {
          "x": 471,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "visibleBox": {
          "x": 471,
          "y": 243,
          "width": 67,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t25",
        "aimMargin": 26
      },
      {
        "id": "t22",
        "selector": "#qty-dec",
        "role": "button",
        "label": "数量を1つ減らす",
        "point": {
          "x": 561,
          "y": 255
        },
        "cssPoint": {
          "x": 1122,
          "y": 509
        },
        "box": {
          "x": 550,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "visibleBox": {
          "x": 550,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "minSide": 22,
        "disabled": true,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t23",
        "aimMargin": 11
      },
      {
        "id": "t23",
        "selector": "#qty",
        "role": "spinbutton",
        "label": "1",
        "point": {
          "x": 585,
          "y": 255
        },
        "cssPoint": {
          "x": 1170,
          "y": 509
        },
        "box": {
          "x": 572,
          "y": 243,
          "width": 26,
          "height": 24
        },
        "visibleBox": {
          "x": 572,
          "y": 243,
          "width": 26,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t22",
        "aimMargin": 13
      },
      {
        "id": "t24",
        "selector": "#qty-inc",
        "role": "button",
        "label": "数量を1つ増やす",
        "point": {
          "x": 609,
          "y": 255
        },
        "cssPoint": {
          "x": 1218,
          "y": 509
        },
        "box": {
          "x": 598,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "visibleBox": {
          "x": 598,
          "y": 243,
          "width": 22,
          "height": 24
        },
        "minSide": 22,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t23",
        "aimMargin": 11
      },
      {
        "id": "t25",
        "selector": "#add-to-cart",
        "role": "button",
        "label": "カートに入れる",
        "point": {
          "x": 468,
          "y": 295
        },
        "cssPoint": {
          "x": 937,
          "y": 589
        },
        "box": {
          "x": 400,
          "y": 281,
          "width": 137,
          "height": 28
        },
        "visibleBox": {
          "x": 400,
          "y": 281,
          "width": 137,
          "height": 28
        },
        "minSide": 28,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t20",
        "aimMargin": 28
      },
      {
        "id": "t26",
        "selector": "#fav",
        "role": "button",
        "label": "お気に入り",
        "point": {
          "x": 581,
          "y": 295
        },
        "cssPoint": {
          "x": 1162,
          "y": 589
        },
        "box": {
          "x": 542,
          "y": 281,
          "width": 78,
          "height": 28
        },
        "visibleBox": {
          "x": 542,
          "y": 281,
          "width": 78,
          "height": 28
        },
        "minSide": 28,
        "disabled": false,
        "inFrame": true,
        "clipped": false,
        "risks": [],
        "nearest": "t23",
        "aimMargin": 28
      },
      {
        "id": "t27",
        "selector": "#acc-detail-btn",
        "role": "button",
        "label": "商品詳細",
        "point": {
          "x": 456,
          "y": 465
        },
        "cssPoint": {
          "x": 911,
          "y": 929
        },
        "box": {
          "x": 291,
          "y": 449,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 449,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t28",
        "selector": "#acc-size-btn",
        "role": "button",
        "label": "サイズ・容量",
        "point": {
          "x": 456,
          "y": 497
        },
        "cssPoint": {
          "x": 911,
          "y": 994
        },
        "box": {
          "x": 291,
          "y": 481,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 481,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t29",
        "selector": "#acc-care-btn",
        "role": "button",
        "label": "お手入れ",
        "point": {
          "x": 456,
          "y": 530
        },
        "cssPoint": {
          "x": 911,
          "y": 1059
        },
        "box": {
          "x": 291,
          "y": 514,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 514,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t30",
        "selector": "#acc-ship-btn",
        "role": "button",
        "label": "配送・返品",
        "point": {
          "x": 456,
          "y": 562
        },
        "cssPoint": {
          "x": 911,
          "y": 1124
        },
        "box": {
          "x": 291,
          "y": 546,
          "width": 329,
          "height": 32
        },
        "visibleBox": {
          "x": 291,
          "y": 546,
          "width": 329,
          "height": 32
        },
        "minSide": 32,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t31",
        "selector": "#more-btn",
        "role": "button",
        "label": "もっと見る",
        "point": {
          "x": 283,
          "y": 1011
        },
        "cssPoint": {
          "x": 566,
          "y": 2022
        },
        "box": {
          "x": 244,
          "y": 999,
          "width": 78,
          "height": 24
        },
        "visibleBox": {
          "x": 244,
          "y": 999,
          "width": 78,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t32",
        "selector": "a.text-link",
        "role": "link",
        "label": "うつわをすべて見る",
        "point": {
          "x": 588,
          "y": 1115
        },
        "cssPoint": {
          "x": 1176,
          "y": 2230
        },
        "box": {
          "x": 556,
          "y": 1107,
          "width": 64,
          "height": 17
        },
        "visibleBox": {
          "x": 556,
          "y": 1107,
          "width": 64,
          "height": 17
        },
        "minSide": 17,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t33",
        "selector": "ul.cards > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "平皿 白磁 21cm ¥3,520(税込)",
        "point": {
          "x": 89,
          "y": 1227
        },
        "cssPoint": {
          "x": 178,
          "y": 2453
        },
        "box": {
          "x": 20,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 20,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t34",
        "selector": "ul.cards > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "小鉢 青磁 ¥2,640(税込)",
        "point": {
          "x": 243,
          "y": 1227
        },
        "cssPoint": {
          "x": 486,
          "y": 2453
        },
        "box": {
          "x": 174,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 174,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t35",
        "selector": "ul.cards > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "湯呑 飴釉 ¥2,860(税込)",
        "point": {
          "x": 397,
          "y": 1227
        },
        "cssPoint": {
          "x": 794,
          "y": 2453
        },
        "box": {
          "x": 328,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 328,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t36",
        "selector": "ul.cards > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "新作 急須 青磁 360ml ¥9,900(税込)",
        "point": {
          "x": 551,
          "y": 1227
        },
        "cssPoint": {
          "x": 1102,
          "y": 2453
        },
        "box": {
          "x": 482,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "visibleBox": {
          "x": 482,
          "y": 1141,
          "width": 138,
          "height": 171
        },
        "minSide": 138,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t37",
        "selector": "#nl-email",
        "role": "textbox",
        "label": "",
        "point": {
          "x": 116,
          "y": 1470
        },
        "cssPoint": {
          "x": 232,
          "y": 2941
        },
        "box": {
          "x": 20,
          "y": 1458,
          "width": 192,
          "height": 24
        },
        "visibleBox": {
          "x": 20,
          "y": 1458,
          "width": 192,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t38",
        "selector": "button.btn.btn-light",
        "role": "button",
        "label": "登録",
        "point": {
          "x": 235,
          "y": 1470
        },
        "cssPoint": {
          "x": 471,
          "y": 2941
        },
        "box": {
          "x": 216,
          "y": 1458,
          "width": 40,
          "height": 24
        },
        "visibleBox": {
          "x": 216,
          "y": 1458,
          "width": 40,
          "height": 24
        },
        "minSide": 24,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t39",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "新作",
        "point": {
          "x": 298,
          "y": 1419
        },
        "cssPoint": {
          "x": 596,
          "y": 2838
        },
        "box": {
          "x": 291,
          "y": 1411,
          "width": 14,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1411,
          "width": 14,
          "height": 16
        },
        "minSide": 14,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t40",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "うつわ",
        "point": {
          "x": 302,
          "y": 1436
        },
        "cssPoint": {
          "x": 603,
          "y": 2871
        },
        "box": {
          "x": 291,
          "y": 1428,
          "width": 21,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1428,
          "width": 21,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t41",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "作家",
        "point": {
          "x": 298,
          "y": 1452
        },
        "cssPoint": {
          "x": 596,
          "y": 2905
        },
        "box": {
          "x": 291,
          "y": 1444,
          "width": 14,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1444,
          "width": 14,
          "height": 16
        },
        "minSide": 14,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t42",
        "selector": "nav.footer-nav > div:nth-of-type(1) > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "読みもの",
        "point": {
          "x": 305,
          "y": 1469
        },
        "cssPoint": {
          "x": 611,
          "y": 2938
        },
        "box": {
          "x": 291,
          "y": 1461,
          "width": 29,
          "height": 16
        },
        "visibleBox": {
          "x": 291,
          "y": 1461,
          "width": 29,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t43",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "配送・送料",
        "point": {
          "x": 423,
          "y": 1419
        },
        "cssPoint": {
          "x": 845,
          "y": 2838
        },
        "box": {
          "x": 405,
          "y": 1411,
          "width": 36,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1411,
          "width": 36,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t44",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "返品・交換",
        "point": {
          "x": 423,
          "y": 1436
        },
        "cssPoint": {
          "x": 845,
          "y": 2871
        },
        "box": {
          "x": 405,
          "y": 1428,
          "width": 36,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1428,
          "width": 36,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t45",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "よくあるご質問",
        "point": {
          "x": 430,
          "y": 1452
        },
        "cssPoint": {
          "x": 859,
          "y": 2905
        },
        "box": {
          "x": 405,
          "y": 1444,
          "width": 50,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1444,
          "width": 50,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t46",
        "selector": "nav.footer-nav > div:nth-of-type(2) > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)",
        "role": "link",
        "label": "お問い合わせ",
        "point": {
          "x": 426,
          "y": 1469
        },
        "cssPoint": {
          "x": 852,
          "y": 2938
        },
        "box": {
          "x": 405,
          "y": 1461,
          "width": 43,
          "height": 16
        },
        "visibleBox": {
          "x": 405,
          "y": 1461,
          "width": 43,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t47",
        "selector": "nav.footer-nav > div:nth-of-type(3) > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)",
        "role": "link",
        "label": "工房のこと",
        "point": {
          "x": 536,
          "y": 1419
        },
        "cssPoint": {
          "x": 1072,
          "y": 2838
        },
        "box": {
          "x": 518,
          "y": 1411,
          "width": 36,
          "height": 16
        },
        "visibleBox": {
          "x": 518,
          "y": 1411,
          "width": 36,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t48",
        "selector": "nav.footer-nav > div:nth-of-type(3) > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "role": "link",
        "label": "特定商取引法に基づく表記",
        "point": {
          "x": 561,
          "y": 1436
        },
        "cssPoint": {
          "x": 1123,
          "y": 2871
        },
        "box": {
          "x": 518,
          "y": 1428,
          "width": 86,
          "height": 16
        },
        "visibleBox": {
          "x": 518,
          "y": 1428,
          "width": 86,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      },
      {
        "id": "t49",
        "selector": "nav.footer-nav > div:nth-of-type(3) > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)",
        "role": "link",
        "label": "プライバシーポリシー",
        "point": {
          "x": 554,
          "y": 1452
        },
        "cssPoint": {
          "x": 1108,
          "y": 2905
        },
        "box": {
          "x": 518,
          "y": 1444,
          "width": 72,
          "height": 16
        },
        "visibleBox": {
          "x": 518,
          "y": 1444,
          "width": 72,
          "height": 16
        },
        "minSide": 16,
        "disabled": false,
        "inFrame": false,
        "clipped": true,
        "risks": []
      }
    ],
    "capped": 0,
    "issues": [
      {
        "kind": "ambiguous-target",
        "severity": "warn",
        "selector": "nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1)",
        "message": "2 links in the frame all read \"うつわ\" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one."
      }
    ]
  }
}
G48exit 0vlmkit check breakpoints index.html --sweep

breakpoints 4 · issues 0 · sweepRanges 0

output, 13 line(s), 3.4s
vlmkit check breakpoints
source: index.html

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 599, 600, 899, 900px (each at B-1 / B / B+1)

  599px: clean (max-width: 599px)
  600px: clean (min-width: 600px)
  899px: clean (max-width: 899px)
  900px: clean (min-width: 900px)

All boundaries consistent.
G49exit 0vlmkit verify flow index.html --flow flow.json

verdict: DONE (10/10 steps)

done true · passed 10 · total 10

output, 43 line(s), 2.8s
vlmkit verify flow
source: index.html

verdict: DONE (10/10 steps)

✓ step 1: the header cart opens the empty drawer
    ✓ #cart-drawer visible 
    ✓ #cart-empty visible 
    ✓ #cart-foot hidden 
    ✓ #cart-lines > li count=0 
✓ step 2: 買い物を続ける in the empty drawer closes it and returns focus to the cart button
    ✓ #cart-drawer hidden 
    ✓ #cart-open focused 
✓ step 3: step the quantity up to 2
    ✓ #qty aria-valuenow=2 
    ✓ #qty-dec aria-disabled=false 
✓ step 4: カートに入れる opens the drawer with two mugs
    ✓ #cart-drawer visible 
    ✓ #cart-close focused 
    ✓ #cart-lines > li count=1 
    ✓ #cart-lines text~"青磁" 
    ✓ #cart-lines text~"S 240ml" 
    ✓ #cart-subtotal text~"¥8,360" 
    ✓ #cart-count text~"2" 
    ✓ #checkout visible 
✓ step 5: Escape closes the drawer and returns focus
    ✓ #cart-drawer hidden 
    ✓ #add-to-cart focused 
✓ step 6: choose 飴釉 and M
    ✓ html data-glaze=ameyu 
    ✓ #product-title text~"飴釉" 
✓ step 7: size M
    ✓ .buybar-variant text~"M 320ml" 
✓ step 8: a second variant becomes a second line
    ✓ #cart-lines > li count=2 
    ✓ #cart-count text~"4" 
    ✓ #cart-subtotal text~"¥16,720" 
✓ step 9: remove the first line
    ✓ #cart-lines > li count=1 
    ✓ #cart-count text~"2" 
    ✓ #cart-lines text~"飴釉" 
✓ step 10: close button closes
    ✓ #cart-drawer hidden
G50exit 0vlmkit scan handlers index.html --probe input

registrations 40 · elements 32 · suspects 0

output, 46 line(s), 2.0s
vlmkit scan handlers
source: index.html

status: 1 warn(s)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
registrations: 40 across 32 element(s), on a page presenting 49 control(s)

  - fieldset.option>div.swatches>label.swatch>input "seiji": change
  - fieldset.option>div.swatches>label.swatch>input "hakuji": change
  - fieldset.option>div.swatches>label.swatch>input "ameyu": change
  - fieldset.option>div.sizes>label.size>input "S": change
  - fieldset.option>div.sizes>label.size>input "M": change
  - section.product>div.gallery>div.thumbs>button#tab-front "正面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-side "側面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-top "上から": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-use "使用例": click, keydown
  - div.options-row>div.option>div.stepper>button#qty-dec "数量を1つ減らす": click
  - div.options-row>div.option>div.stepper>button#qty-inc "数量を1つ増やす": click
  - div.options-row>div.option>div.stepper>input#qty "1": keydown, input, compositionend, change (no role)
  - section.product>div.panel>div.buy-row>button#fav "お気に入り": click
  - section.product>div.panel>div.buy-row>button#add-to-cart "カートに入れる": click
  - aside#buybar>button.btn "カートに入れる": click (no role)
  - header.site-header>div.header-inner>div.header-actions>button#cart-open "カート 0点": click
  - dialog#cart-drawer "カート カートに商品はありません。 気になるうつわがあれば、カートに入れてお進み": close, click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-head>button#cart-close "カートを閉じる": click (no role)
  - div.drawer-inner>div.drawer-body>div#cart-empty>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-body>ul#cart-lines "": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button#checkout "レジに進む": click (no role)
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn "商品詳細": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-size-btn "サイズ・容量": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-care-btn "お手入れ": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn "配送・返品": click
  - section#reviews>div.reviews-grid>div.review-list>button#more-btn "もっと見る": click
  - header.site-header>div.header-inner>div.header-actions>button#search-toggle "検索": click
  - header.site-header>div#search-panel "キーワードで探す 検索する": keydown (no role)
  - header.site-header>div#search-panel>form#search-form "キーワードで探す 検索する": submit (no role)
  - footer.site-footer>div.footer-inner>section.newsletter>form#nl-form "メールアドレス 登録": submit (delegation container)
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email "": input

Typed into (plain, and through an IME composition):
  - div.options-row>div.option>div.stepper>input#qty: "vlmkit7" became "", "日本語" became "", composed ""
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email: kept "vlmkit7", kept "日本語", composed "日本語"

Issues:
  warn [unprobed-handler-types] 4 handler type(s) registered and NONE exercised: click, close, keydown, submit — this gate is an inventory and presses nothing. A clean result here says the wiring exists, not that it works. Run 'check interactions --handlers' to focus and activate the controls, add '--probe-drag' for the drag surfaces, or drive the rest with a 'verify flow' script.
G51exit 0vlmkit check motion index.html

activeAnimations 0 · running 0 · issues 0

output, 34 line(s), 1.4s
vlmkit check motion
source: index.html

status: ok
samples: 25
active animations: 0
active transitions: 25
running animations: 0
paused animations: 0
reduced-motion rule: yes

Motion samples:
  - div.search-row > button:nth-of-type(1): animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #tab-front > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-side > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-top > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-use > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - div.swatches > label:nth-of-type(1) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - div.swatches > label:nth-of-type(2) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - div.swatches > label:nth-of-type(3) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - #add-to-cart: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #fav: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #acc-detail-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-size-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-care-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-ship-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #more-btn: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #more-btn > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.2s
  - svg.glaze-hakuji: animation=none 0s running; transition=transform 0.4s
  - ul.cards > li:nth-of-type(2) > a:nth-of-type(1) > span:nth-of-type(1) > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.4s
  - svg.glaze-ameyu: animation=none 0s running; transition=transform 0.4s
  - ul.cards > li:nth-of-type(4) > a:nth-of-type(1) > span:nth-of-type(1) > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.4s

No motion issues detected.
S43

index.html · 1280×800 · full page, 4 screen(s)

4 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L43 saw

Final desktop 1280x800, 4 screens. Screen 1 — what a first-time visitor sees: wordmark, nav with うつわ marked, 検索 and カート (0); breadcrumb; the celadon mug with fine crackle and a wavy glaze edge on a paper stage beside a labelled thumbnail rail; on the right 汐見 透 作, 汐見窯 マグカップ 青磁, ¥4,180(税込), 4.6 and 128件のレビュー, the named swatches, S/M, the stepper, カートに入れる (dark celadon, ends above y=620) with お気に入り, and the three assurance lines. It is obvious what this is and what to do. Screen 2: 商品について and the four closed accordion rows; レビュー with the summary card and the first review at 38em. Screen 3: the summary card is now held at the top of its column (y≈24) while reviews 2–3 and もっと見る scroll beside it — the sticky working in a real capture; then 同じ窯のうつわ. Screen 4: the four drawn items with names and prices, and the dark footer with the serif 汐見窯だより, email row, link columns, © 2026 汐見窯 and the disclaimer. Checked: alignment of the panel's controls on one right edge (1240), even section rhythm, no clipped or colliding text, headings in Gothic here as expected without Mincho.

S44

index.html · 375×812 · full page, 7 screen(s)

7 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L44 saw

Final mobile 375x812, 7 screens. Screen 1: header row + nav row, breadcrumb, full-bleed square stage with the celadon mug, four labelled thumbnails, 汐見 透 作 and the one-line h1, and the solid pinned bar with 青磁・S 240ml / ¥4,180(税込) / カートに入れる. Screen 2: price, rating, swatches, S/M cards, stepper, full-width カートに入れる and お気に入り, assurances — the bar is stepped aside here because the panel's button is on screen. Screens 3–5: lead, accordion, summary card, reviews, もっと見る, 2-up related cards, with the bar back at the bottom. Screens 6–7: footer with ショップ / ご案内 side by side and 汐見窯について full width, labels on one line, copyright and disclaimer clear of the bar. Nothing overflows, overlaps or clips; tap targets are all comfortably large.

S45

final: 飴釉 + 上から selected

index.html · 1280×800 · click input[name=glaze][value=ameyu] · click #tab-top

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L45 saw

Final state, desktop: 飴釉 chosen and the 上から thumbnail selected. The main image is the amber mug from above — a light amber rim ring, a deep brown well with the pooled darker centre, two highlight arcs, the handle to the right; the crackle is almost invisible, as intended for this glaze. Title 汐見窯 マグカップ 飴釉, legend 釉薬:飴釉, the 飴釉 swatch ringed and bold, every thumbnail amber with 上から selected. The cart badge still reads 0.

S46

final: mobile 白磁 + 使用例 selected

index.html · 375×812 · click input[name=glaze][value=hakuji] · click #tab-use · scroll-to .gallery

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L46 saw

Final state, mobile: 白磁 chosen and 使用例 selected, scrolled to the gallery. The full-bleed stage shows the white mug in the use scene (tea, steam, wagashi plate, sprig, linen mat, wood table, light shaft); the thumbnail row shows white mugs with 使用例 selected; below, 汐見窯 マグカップ 白磁, the price and rating, 釉薬:白磁; the pinned bar reads 白磁・S 240ml ¥4,180(税込) — it follows the selection.

S47

final: drawer with two mugs (desktop)

index.html · 1280×800 · click #qty-inc · click #add-to-cart · wait 600

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L47 saw

Final state, desktop: + then カートに入れる. The drawer shows the status band カートに追加しました(青磁・S 240ml・2点), one line (thumbnail, 汐見窯 マグカップ 青磁, 釉薬 青磁 / サイズ S 240ml / 数量 2, 削除, ¥8,360), and the foot with 送料無料の対象です。 over a full bar, 小計 ¥8,360(税込), レジに進む and 買い物を続ける. Two of the mug, correctly priced; the backdrop dims the page behind.

S48

final: drawer with two mugs (mobile, from the pinned bar)

index.html · 375×812 · click #qty-inc · scroll-to .review-list · click .buybar-cta · wait 600

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L48 saw

Final state, mobile: quantity 2, scrolled to the reviews, カートに入れる pressed in the pinned bar. Full-screen drawer with the same content as S47 — status band, the line with 数量 2 and ¥8,360, free-shipping bar, 小計 ¥8,360(税込), レジに進む, 買い物を続ける. Nothing is cut off at 375.

S49

final: header badge after adding two and closing

index.html · 1280×800 · element .header-actions · @2x · click #qty-inc · click #add-to-cart · wait 400 · press Escape

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L49 saw

Header actions close-up (2x) after adding two mugs and pressing Escape: the cart button reads カート with the badge now a filled celadon circle showing 2 in white (it was a grey 0 before), next to 検索. The badge updated.

S50

final: 商品詳細 open

index.html · 1280×800 · click #acc-detail-btn · scroll-to .about

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L50 saw

Final state, desktop: 商品詳細 open (−), the other three closed (+). The panel holds a two-line paragraph, then a spec list (素材 磁器 / 釉薬 青磁釉・白磁釉・飴釉 / 作り手 汐見 透(汐見窯) / 生産 日本) with hairlines, then the tolerance note. One spacing fault: the spec list's top rule sits almost on the paragraph — about 7px under the glyphs of 仕上がります。 — while the note below gets its full 16px, so the list looks jammed against the text above it.

D16 defect #acc-detail .spec-list

In 商品詳細 the spec list's top rule sits ~7px under the paragraph's glyphs: .spec-list { margin: 0 } has the same specificity as the panel's .acc-panel > * + * rhythm rule and comes later, so the list loses its 16px while the note after it keeps its own.

S51

final: extra reviews revealed (desktop)

index.html · 1280×800 · click #more-btn · scroll-to #more-reviews

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L51 saw

Final state, desktop: もっと見る pressed, scrolled to the revealed reviews. The three extra reviews (カフェオレにちょうどいい, 二つ目を買い足しました, 色は実物を見て選びたかった) run down the right column while the summary card stays at the top of the left column; stars, titles, meta lines and 38em bodies match the first three.

S52

final: extra reviews revealed, pinned bar mid-page (mobile)

index.html · 375×812 · click #more-btn · scroll-to #more-reviews

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L52 saw

Final state, mobile: the revealed reviews at 375 and the pinned bar mid-page — the bar holds 青磁・S 240ml ¥4,180(税込) and カートに入れる at the bottom while the review column scrolls behind it; the review bodies wrap at the column width and the bar hides nothing that cannot be scrolled clear.

F17fix for D16

The panel rhythm rule is now .acc-panel > :not(:first-child) { margin-top: 16px } — specificity (0,2,0), so it beats .spec-list / .care-list { margin: 0 } while a first child still starts flush.

S53

final: 商品詳細 and 配送・返品 open after D16

index.html · 1280×800 · element .accordion · click #acc-detail-btn · click #acc-ship-btn · scroll-to #acc-detail

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L53 saw

Accordion close-up with 商品詳細 and 配送・返品 open. In 商品詳細 the two-line paragraph now has its full gap (~20px from the glyphs) above the spec list's first rule, matching the rhythm of the note below; in 配送・返品 the spec list is the first child and starts flush under the header row, its top rule acting as the divider, with 発送 / 送料 / 破損・不良 / 返品 rows (the 返品 row wraps to two lines, aligned under its own column). サイズ・容量 is celadon only because the pointer ended over it after the layout moved. One new fault: the 商品詳細 note ends 形には個体差があり / ます。 — three characters alone on the last line, a short orphan; the same kind of break sits in the サイズ・容量 note (下ま / での目安です。, S31).

D17 defect .acc-panel .note

The small notes in the accordion break mid-word with a short tail: 個体差があり / ます。 in 商品詳細 (3 characters alone), 5mm下ま / での目安です。 in サイズ・容量.

V16verified D16 by L53

Spec list now clears the paragraph by the panel's 16px rhythm.

F18fix for D17

Accordion notes use word-break: auto-phrase (as the headings, footer links and the quantity notice already do), so a short note breaks between phrases instead of leaving a syllable tail.

S54

final: notes after D17 (商品詳細 and サイズ・容量 open)

index.html · 1280×800 · element .accordion · click #acc-detail-btn · click #acc-size-btn · scroll-to #acc-detail

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L54 saw

Accordion close-up with 商品詳細 and サイズ・容量 open after the note fix. The 商品詳細 note now reads 一点ずつ手づくりのため、色味や貫入(表面の細かなひび模様)、形には / 個体差があります。 and the size note 手づくりのため、寸法には±3mmほどの個体差があります。容量は口縁から / 5mm下までの目安です。 — both break between phrases, no syllable tails. Paragraph, spec list, the 28em table and the notes keep the 16px rhythm; hairlines, headers and −/+ icons are unchanged.

V17verified D17 by L54

Both notes break between phrases.

G52exit 0vlmkit check integrity index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)

verdict clean · findings 0 · fails 0 · warns 0 · exempted 24 · viewports 3

output, 27 line(s), 5.6s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)
  1280x800: 8 component(s), ink 26.3%, 109 text block(s)
  768x900: 8 component(s), ink 28.9%, 112 text block(s)
  375x700: 8 component(s), ink 32.6%, 112 text block(s)

No integrity defects detected.

Exempted candidates (the tool's call — audit the rule, not the page):
  - [text-clipped] span.badge > span:nth-of-type(2) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #search-toggle > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #cart-open > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  … 9 more
G53exit 1vlmkit check copy index.html --manifest copy.txt

missing 1 · placeholders 0 · manifestLines 14 · invisibleOnly 1 · statesExplored 9 · revealedOnly 0

output, 11 line(s), 1.9s
vlmkit check copy
source: index.html

status: suspect
rendered text: 1083 chars
disclosure states: 9 explored (details / tabs / aria-expanded)
manifest: 14 line(s), missing 1, 1 invisible-only

Issues:
  x copy-invisible: Manifest line found ONLY in text a user cannot see (reason: unknown): "¥4,180(税込)". Invisible text does not satisfy the copy gate — render it visibly or remove the hidden copy. If this invisibility is deliberate (e.g. assistive-tech-only copy), re-run with --allow-invisible unknown.
  x copy-missing: Manifest line not found in rendered text or any of 9 revealed disclosure state(s): "レジに進む" (comparison is whitespace-normalized, case-sensitive).
G54exit 0vlmkit check design index.html

verdict: DRIFT (2 finding(s))

verdict drift · drifting 2 · roles 11

output, 31 line(s), 1.6s
vlmkit check design
source: index.html

verdict: DRIFT (2 finding(s))
  exits 0 — 2 warn(s) did not fail this command. To gate on one: --rule component-drift=suspect
  roles judged: 6 of 11 seen, spacing values: 22
  coverage: 42 of 315 visible element(s) carried an inferable role; 4 skipped as non-resting
    no role: span x82, div x30, li x30, a x26, svg x22, p x16, +18 more tag(s)
    A role comes from role="..." or from button/input/select/textarea/h1-h6. Layout elements
    (div, span, p, a) have none, so a large skip count is normal — this gate judges components,
    not every box. Add role="..." where an element IS a component to widen the coverage.
  text-free: 8 (0 judged on box alone — font-size/weight is not observable without painted text)

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  button          11 inst    6 styles  reuse  1.83x  3 one-off  drift
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  img              6 inst    1 styles  reuse     6x  0 one-off  ok
  tab              3 inst    1 styles  reuse     3x  0 one-off  ok
  input:radio      3 inst    2 styles  reuse   1.5x  1 one-off  drift
  tablist          1 inst    1 styles  reuse     1x  1 one-off  not judged
  tabpanel         1 inst    1 styles  reuse     1x  1 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  spinbutton       1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: tablist (1), tabpanel (1), h1 (1), spinbutton (1), input:email (1) — under --min-instances 3, so no finding can come from them.
  To keep judging them: --min-instances 2 --min-reuse 2 (both — a 2-instance role cannot reach 3x however many instances the floor allows).

Findings
  ! [component-drift] button: 11 "button" elements render 6 distinct styles (used 4x, 2x, 2x, 1x, …; a system reuses each style 3x or more, and this role averages 1.83x). Dominant style, used 4x: padding 12/4/12/4, radius 0, 16px/600, border 0, bg rgba(0, 0, 0, 0). Deviating: button#search-toggle (padding 0/10/0/10, radius 8, 14px/400, border 0, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 10, padding-bottom 12 → 0 and 4 more; button#fav (padding 0/22/0/22, radius 8, 15px/700, border 1, bg rgba(0, 0, 0, 0)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more; button#add-to-cart (padding 0/22/0/22, radius 8, 16px/700, border 1, bg rgb(47, 97, 83)) — differs in padding-top 12 → 0, padding-right 4 → 22, padding-bottom 12 → 0 and 5 more and 2 more. This reports inconsistency, not which style is correct.
  ! [component-drift] input:radio: 3 "input:radio" elements render 2 distinct styles (used 2x, 1x; a system reuses each style 3x or more, and this role averages 1.5x). Dominant style, used 2x: padding 0/0/0/0, radius 50, 16px/400, border 1, bg rgba(0, 0, 0, 0). Deviating: div.sizes>label.size>input (padding 0/0/0/0, radius 8, 16px/400, border 1, bg rgb(252, 250, 246)) — differs in border-radius 50 → 8, background-color rgba(0, 0, 0, 0) → rgb(252, 250, 246). This reports inconsistency, not which style is correct.
G55exit 0vlmkit check composition index.html

verdict: COMPOSED (0 finding(s))

verdict composed · proximity 0 · flatSteps 0 · railNearMisses 0

output, 17 line(s), 1.7s
vlmkit check composition
source: index.html

verdict: COMPOSED (0 finding(s))
  measured: 0 label(s), 3 heading level(s), 60 wide block(s) on 5 left / 5 right rail(s) — from 267 visible box(es)
  11 label(s) not judged: they open a box that paints its own group edge, so nothing above them could be mis-grouped with

Type hierarchy (largest instance of each declared level)
  h1     30px / 600   h1#product-title
  h2     26px / 600   h2#about-title
  h3     16px / 600   div.accordion>div.acc-item>h3.acc-heading
  body 13px, largest 52px (4x), heaviest +300 weight

Group gaps: 0px between heading-led groups vs 8px inside them (0x, 12 sample(s)). Context only — intact pages measure 0.86-3.00x, so this cannot carry a verdict.

Proximity, alignment and type hierarchy all read consistently.
G56exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f7f3ec · bodyInk #23211d · linkInk #b8b1a5 · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

output, 28 line(s), 1.6s
vlmkit check color
source: index.html

verdict: CONSISTENT (0 finding(s))
  measured: 2 control(s), 26 link(s) in a text flow — from 301 visible box(es)

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  4 distinct
    #f7f3ec   75.9%     4 el  
    #efe9df   12.3%     5 el  section.product>div.gallery>div.stage
    #1f2b27    9.2%     1 el  footer.site-footer
    #fcfaf6    2.6%     3 el  div.sizes>label.size>input
  ink       8 distinct
    #23211d   55.1%    39 el  a.wordmark>span.wordmark-text>span.wordmark-ja
    #4a453e   16.9%    36 el  ul>li>a
    #b8b1a5    9.7%    13 el  div.footer-inner>section.newsletter>p.nl-lead
    #686157    7.6%    21 el  a.wordmark>span.wordmark-text>span.wordmark-en
    #ece6dc    6.6%     6 el  h2#nl-title
    …and 3 more
  marks     6 distinct
    #ddd5c8   54.6%    25 el  header.site-header
    #cbc2b3   17.4%     5 el  main#main>section.about>div.accordion
    #8a8277   11.6%    34 el  div.swatches>label.swatch>input
    #ece6dc    6.3%     1 el  footer.site-footer>div.footer-bottom
    #23211d    5.6%     8 el  button#tab-front>span.thumb-img
    …and 1 more
  base #f7f3ec, body ink #23211d, link ink #b8b1a5 on 11 element(s)
G57exit 0vlmkit check a11y contrast index.html

inspected 119 · failures 0

output, 5 line(s), 1.6s
  vlmkit check a11y contrast
  html: examples/sites/shop/index.html
  inspected 119 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/shop/test-results/a11y-contrast/index-07f7b4b9/report.md
G58exit 1vlmkit check a11y focus index.html

steps 43 · findings 4

output, 9 line(s), 1.6s
  vlmkit check a11y focus
  source: index.html
  captured 43 focus step(s)
  ✗ 4 finding(s)
    [reverse] Focus moved up by 233px (from `main#main>section.product.container>div.panel>div.buy-row>button#fav` at y=561 to `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn` at y=328). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [reverse] Focus moved up by 188px (from `section.about.container>div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn` at y=523 to `main#main>section#reviews>div.reviews-grid>div.review-list>button#more-btn` at y=336). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [skip-row] Focus jumped down by 216px (from `main#main>section#reviews>div.reviews-grid>div.review-list>button#more-btn` to `main#main>section.related.container>div.section-head>a.text-link`). Confirm no focusable element was unintentionally skipped.
    [reverse] Focus moved up by 173px (from `main#main>section.related.container>div.section-head>a.text-link` at y=552 to `main#main>section.related.container>ul.cards>li.card>a.card-link` at y=379). Visual order is top-to-bottom; check `tabindex` or DOM order.
  report: examples/sites/shop/test-results/a11y-focus-order/index-07f7b4b9/report.md
G59exit 0vlmkit check a11y touch index.html

level AA · inspected 49 · failures 0 · wcagExempt 0

output, 5 line(s), 1.5s
  vlmkit check a11y touch
  source: index.html  level: WCAG AA (24×24 min)
  inspected 49 interactive element(s)
  ✓ 0 undersized target(s)
  report: examples/sites/shop/test-results/a11y-touch/index-07f7b4b9/report.md
G60exit 0vlmkit scan scroll index.html

containers 0 · overflowX 0 · issues 6

output, 18 line(s), 1.4s
vlmkit scan scroll
source: index.html (1280x720)

status: warn
  exits 0 — 6 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 1280x3105 — horizontal overflow 0px, vertical scroll 2385px
scroll containers: 0 (dead scrollports 1, clipped 6)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G61exit 0vlmkit scan scroll index.html --viewport 375x740

containers 0 · overflowX 0 · issues 8

output, 20 line(s), 1.5s
vlmkit scan scroll
source: index.html (375x740)

status: warn
  exits 0 — 8 warn(s) did not fail this command. To gate on one: --rule clipped-content=suspect
page: 375x5021 — horizontal overflow 0px, vertical scroll 4281px
scroll containers: 0 (dead scrollports 1, clipped 8)

Dead scrollports (declared scrollable, content fits):
  - div.drawer-body (overflow: auto auto)

Issues:
  ! clipped-content #cart-open > span:nth-of-type(1): #cart-open > span:nth-of-type(1) clips 42px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content #search-toggle > span:nth-of-type(1): #search-toggle > span:nth-of-type(1) clips 28px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content span.badge > span:nth-of-type(2): span.badge > span:nth-of-type(2) clips 19px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
  ! clipped-content ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1): ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) clips 17px of its content behind overflow: hidden — cut-off content unless the oversize is decorative.
G62exit 0vlmkit scan handlers index.html

registrations 40 · elements 32 · suspects 0

output, 42 line(s), 1.6s
vlmkit scan handlers
source: index.html

status: 1 warn(s)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
registrations: 40 across 32 element(s), on a page presenting 49 control(s)

  - fieldset.option>div.swatches>label.swatch>input "seiji": change
  - fieldset.option>div.swatches>label.swatch>input "hakuji": change
  - fieldset.option>div.swatches>label.swatch>input "ameyu": change
  - fieldset.option>div.sizes>label.size>input "S": change
  - fieldset.option>div.sizes>label.size>input "M": change
  - section.product>div.gallery>div.thumbs>button#tab-front "正面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-side "側面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-top "上から": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-use "使用例": click, keydown
  - div.options-row>div.option>div.stepper>button#qty-dec "数量を1つ減らす": click
  - div.options-row>div.option>div.stepper>button#qty-inc "数量を1つ増やす": click
  - div.options-row>div.option>div.stepper>input#qty "1": keydown, input, compositionend, change (no role)
  - section.product>div.panel>div.buy-row>button#fav "お気に入り": click
  - section.product>div.panel>div.buy-row>button#add-to-cart "カートに入れる": click
  - aside#buybar>button.btn "カートに入れる": click (no role)
  - header.site-header>div.header-inner>div.header-actions>button#cart-open "カート 0点": click
  - dialog#cart-drawer "カート カートに商品はありません。 気になるうつわがあれば、カートに入れてお進み": close, click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-head>button#cart-close "カートを閉じる": click (no role)
  - div.drawer-inner>div.drawer-body>div#cart-empty>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-body>ul#cart-lines "": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button#checkout "レジに進む": click (no role)
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn "商品詳細": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-size-btn "サイズ・容量": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-care-btn "お手入れ": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn "配送・返品": click
  - section#reviews>div.reviews-grid>div.review-list>button#more-btn "もっと見る": click
  - header.site-header>div.header-inner>div.header-actions>button#search-toggle "検索": click
  - header.site-header>div#search-panel "キーワードで探す 検索する": keydown (no role)
  - header.site-header>div#search-panel>form#search-form "キーワードで探す 検索する": submit (no role)
  - footer.site-footer>div.footer-inner>section.newsletter>form#nl-form "メールアドレス 登録": submit (delegation container)
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email "": input

Issues:
  warn [unprobed-handler-types] 7 handler type(s) registered and NONE exercised: change, click, close, compositionend, input, keydown, submit — this gate is an inventory and presses nothing. A clean result here says the wiring exists, not that it works. Run 'check interactions --handlers' to focus and activate the controls, add '--probe-drag' for the drag surfaces, or drive the rest with a 'verify flow' script.
G63exit 0vlmkit check interactions index.html --max-elements 80

elements 48 · suspects 0 · warns 0

output, 54 line(s), 22.1s
vlmkit check interactions
source: index.html

status: ok
interactive elements: 48

  - [link] "本文へスキップ" focus✓
  - [link] "汐見窯 SHIOMI-GAMA" focus✓
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [button] "カート 0点" focus✓ | Enter: focus moves within | opens dialog (focus enters), traps | Esc closes+returns focus
  - [link] "ホーム" focus✓
  - [link] "うつわ" focus✓
  - [link] "マグカップ" focus✓
  - [tab] "正面" focus✓ | ArrowRight: selected true -> false
  - [tab] "側面" unreachable | ArrowRight: focus moves
  - [tab] "上から" unreachable | ArrowRight: focus moves
  - [tab] "使用例" unreachable | ArrowRight: focus moves
  - [link] "128件のレビュー" focus✓
  - [radio] "seiji" focus✓ | ArrowDown: focus moves
  - [radio] "hakuji" unreachable | ArrowDown: focus moves
  - [radio] "ameyu" unreachable | ArrowDown: focus moves
  - [radio] "S" focus✓ | ArrowDown: focus moves
  - [radio] "M" unreachable | ArrowDown: focus moves
  - [button] "数量を1つ減らす" focus✓ | Enter: layout change | announces
  - [button] "数量を1つ増やす" focus✓ | Enter: layout change | announces
  - [button] "カートに入れる" focus✓ | Enter: focus moves within | announces
  - [button] "お気に入り" focus✓ | Enter: pressed false -> true | announces
  - [button] "商品詳細" focus✓ | Enter: expanded false -> true
  - [button] "サイズ・容量" focus✓ | Enter: expanded false -> true
  - [button] "お手入れ" focus✓ | Enter: expanded false -> true
  - [button] "配送・返品" focus✓ | Enter: expanded false -> true
  - [button] "もっと見る" focus✓ | Enter: expanded false -> true
  - [link] "うつわをすべて見る" focus✓
  - [link] "平皿 白磁 21cm ¥3,520(税込)" focus✓
  - [link] "小鉢 青磁 ¥2,640(税込)" focus✓
  - [link] "湯呑 飴釉 ¥2,860(税込)" focus✓
  - [link] "新作 急須 青磁 360ml ¥9,900(税込)" focus✓
  - [textbox] "" focus✓
  - [button] "登録" focus✓ | Enter: layout change | announces
  - [link] "新作" focus✓
  - [link] "うつわ" focus✓
  - [link] "作家" focus✓
  - [link] "読みもの" focus✓
  - [link] "配送・送料" focus✓
  - [link] "返品・交換" focus✓
  - [link] "よくあるご質問" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "工房のこと" focus✓
  - [link] "特定商取引法に基づく表記" focus✓
  - [link] "プライバシーポリシー" focus✓
G64exit 0vlmkit check scroll index.html --viewport 375x740

pageScrolled 1110 · stickyFixed 1 · engagedSticky 0 · snaps 0 · issues 0

output, 12 line(s), 1.5s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1110px
sticky/fixed elements: 1 (sticky engaged by the scroll: 0)
snap containers driven: 0

Sticky / fixed:
  - #buybar: fixed top=671px viewport y 671 -> 671

No scroll-behavior issues detected.
G65exit 0vlmkit check scroll index.html --viewport 1280x1000

pageScrolled 1500 · stickyFixed 1 · engagedSticky 1 · snaps 0 · issues 0

output, 12 line(s), 1.4s
vlmkit check scroll
source: index.html

status: ok
page scrolled: 1500px
sticky/fixed elements: 1 (sticky engaged by the scroll: 1)
snap containers driven: 0

Sticky / fixed:
  - div.review-summary: sticky top=24px viewport y 1393 -> 24

No scroll-behavior issues detected.
G66exit 0vlmkit check grounding index.html --viewport 1280x720

targets 24 · scale 0.5 · issues 1

output, 33 line(s), 1.4s
vlmkit check grounding
source: index.html (1280x720)

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule ambiguous-target=suspect
frame: 640x360 screenshot px — medium, cap 640x480, scale 0.50 (every coordinate below is in these 640x360 pixels)
targets: 24 actionable in frame (25 disabled or out of the frame)

Action map (click point in screenshot px):
  t2 link "汐見窯 SHIOMI-GAMA" @ (126,18) 211x29 a.wordmark
  t3 link "新作" @ (254,18) 30x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t4 link "うつわ" @ (294,18) 38x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t5 link "作家" @ (334,18) 30x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t6 link "読みもの" @ (378,18) 46x25 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)
  t7 button "検索" @ (545,18) 38x22 #search-toggle
  t8 button "カート 0 点" @ (595,18) 58x22 #cart-open
  t9 link "ホーム" @ (30,50) 20x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t10 link "うつわ" @ (62,50) 20x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t11 link "マグカップ" @ (101,50) 33x15 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t12 tab "正面" @ (41,92) 42x54 #tab-front
  t13 tab "側面" @ (41,152) 42x54 #tab-side
  t14 tab "上から" @ (41,212) 42x54 #tab-top
  t15 tab "使用例" @ (41,272) 42x54 #tab-use
  t16 link "128件のレビュー" @ (488,139) 55x15 a.rating-link
  t17 radio "seiji" @ (411,188) 22x22 div.swatches > label:nth-of-type(1) > input:nth-of-type(1)
  t18 radio "hakuji" @ (444,188) 22x22 div.swatches > label:nth-of-type(2) > input:nth-of-type(1)
  t19 radio "ameyu" @ (477,188) 22x22 div.swatches > label:nth-of-type(3) > input:nth-of-type(1)
  t20 radio "S" @ (433,255) 67x24 div.sizes > label:nth-of-type(1) > input:nth-of-type(1)
  t21 radio "M" @ (504,255) 67x24 div.sizes > label:nth-of-type(2) > input:nth-of-type(1)
  … 4 more — --json emits the full map

Issues:
  ! ambiguous-target: 2 links in the frame all read "うつわ" (t4 at 294,18, t10 at 62,50) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.
G67exit 0vlmkit check grounding index.html --viewport 375x740

targets 15 · scale 0.43 · issues 1

output, 27 line(s), 1.5s
vlmkit check grounding
source: index.html (375x740)

status: warn
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule ambiguous-target=suspect
frame: 162x320 screenshot px — low, cap 375x320, scale 0.43 (every coordinate below is in these 162x320 pixels)
targets: 15 actionable in frame (35 disabled or out of the frame)

Action map (click point in screenshot px):
  t2 link "汐見窯 SHIOMI-GAMA" @ (38,13) 62x25 a.wordmark
  t3 link "新作" @ (20,35) 24x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t4 link "うつわ" @ (57,35) 31x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t5 link "作家" @ (94,35) 24x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t6 link "読みもの" @ (135,35) 38x19 nav.global-nav > ul:nth-of-type(1) > li:nth-of-type(4) > a:nth-of-type(1)
  t7 button "検索" @ (119,13) 19x19 #search-toggle
  t8 button "カート 0 点" @ (144,13) 29x19 #cart-open
  t9 link "ホーム" @ (16,56) 17x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(1) > a:nth-of-type(1)
  t10 link "うつわ" @ (43,56) 17x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(2) > a:nth-of-type(1) [ambiguous-target]
  t11 link "マグカップ" @ (77,56) 29x13 nav.breadcrumb.container > ol:nth-of-type(1) > li:nth-of-type(3) > a:nth-of-type(1)
  t12 tab "正面" @ (24,257) 34x44 #tab-front
  t13 tab "側面" @ (62,257) 34x44 #tab-side
  t14 tab "上から" @ (100,257) 34x44 #tab-top
  t15 tab "使用例" @ (138,257) 34x44 #tab-use
  t50 button "カートに入れる" @ (121,305) 68x21 button.btn.btn-primary.buybar-cta

Issues:
  ! ambiguous-target: 2 links in the frame all read "うつわ" (t4 at 57,35, t10 at 43,56) — distinguishable only by their surrounding text (新作 うつわ 作家 読みもの / ホーム うつわ マグカップ), so an accessible name carrying it would let an agent name one.
G68exit 0vlmkit check breakpoints index.html --sweep

breakpoints 4 · issues 0 · sweepRanges 0

output, 13 line(s), 3.3s
vlmkit check breakpoints
source: index.html

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 599, 600, 899, 900px (each at B-1 / B / B+1)

  599px: clean (max-width: 599px)
  600px: clean (min-width: 600px)
  899px: clean (max-width: 899px)
  900px: clean (min-width: 900px)

All boundaries consistent.
G69exit 0vlmkit verify flow index.html --flow flow.json

verdict: DONE (10/10 steps)

done true · passed 10 · total 10

output, 43 line(s), 2.8s
vlmkit verify flow
source: index.html

verdict: DONE (10/10 steps)

✓ step 1: the header cart opens the empty drawer
    ✓ #cart-drawer visible 
    ✓ #cart-empty visible 
    ✓ #cart-foot hidden 
    ✓ #cart-lines > li count=0 
✓ step 2: 買い物を続ける in the empty drawer closes it and returns focus to the cart button
    ✓ #cart-drawer hidden 
    ✓ #cart-open focused 
✓ step 3: step the quantity up to 2
    ✓ #qty aria-valuenow=2 
    ✓ #qty-dec aria-disabled=false 
✓ step 4: カートに入れる opens the drawer with two mugs
    ✓ #cart-drawer visible 
    ✓ #cart-close focused 
    ✓ #cart-lines > li count=1 
    ✓ #cart-lines text~"青磁" 
    ✓ #cart-lines text~"S 240ml" 
    ✓ #cart-subtotal text~"¥8,360" 
    ✓ #cart-count text~"2" 
    ✓ #checkout visible 
✓ step 5: Escape closes the drawer and returns focus
    ✓ #cart-drawer hidden 
    ✓ #add-to-cart focused 
✓ step 6: choose 飴釉 and M
    ✓ html data-glaze=ameyu 
    ✓ #product-title text~"飴釉" 
✓ step 7: size M
    ✓ .buybar-variant text~"M 320ml" 
✓ step 8: a second variant becomes a second line
    ✓ #cart-lines > li count=2 
    ✓ #cart-count text~"4" 
    ✓ #cart-subtotal text~"¥16,720" 
✓ step 9: remove the first line
    ✓ #cart-lines > li count=1 
    ✓ #cart-count text~"2" 
    ✓ #cart-lines text~"飴釉" 
✓ step 10: close button closes
    ✓ #cart-drawer hidden
G70exit 0vlmkit scan handlers index.html --probe input

registrations 40 · elements 32 · suspects 0

output, 46 line(s), 2.0s
vlmkit scan handlers
source: index.html

status: 1 warn(s)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
registrations: 40 across 32 element(s), on a page presenting 49 control(s)

  - fieldset.option>div.swatches>label.swatch>input "seiji": change
  - fieldset.option>div.swatches>label.swatch>input "hakuji": change
  - fieldset.option>div.swatches>label.swatch>input "ameyu": change
  - fieldset.option>div.sizes>label.size>input "S": change
  - fieldset.option>div.sizes>label.size>input "M": change
  - section.product>div.gallery>div.thumbs>button#tab-front "正面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-side "側面": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-top "上から": click, keydown
  - section.product>div.gallery>div.thumbs>button#tab-use "使用例": click, keydown
  - div.options-row>div.option>div.stepper>button#qty-dec "数量を1つ減らす": click
  - div.options-row>div.option>div.stepper>button#qty-inc "数量を1つ増やす": click
  - div.options-row>div.option>div.stepper>input#qty "1": keydown, input, compositionend, change (no role)
  - section.product>div.panel>div.buy-row>button#fav "お気に入り": click
  - section.product>div.panel>div.buy-row>button#add-to-cart "カートに入れる": click
  - aside#buybar>button.btn "カートに入れる": click (no role)
  - header.site-header>div.header-inner>div.header-actions>button#cart-open "カート 0点": click
  - dialog#cart-drawer "カート カートに商品はありません。 気になるうつわがあれば、カートに入れてお進み": close, click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-head>button#cart-close "カートを閉じる": click (no role)
  - div.drawer-inner>div.drawer-body>div#cart-empty>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button.btn "買い物を続ける": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div.drawer-body>ul#cart-lines "": click (no role)
  - dialog#cart-drawer>div.drawer-inner>div#cart-foot>button#checkout "レジに進む": click (no role)
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-detail-btn "商品詳細": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-size-btn "サイズ・容量": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-care-btn "お手入れ": click
  - div.accordion>div.acc-item>h3.acc-heading>button#acc-ship-btn "配送・返品": click
  - section#reviews>div.reviews-grid>div.review-list>button#more-btn "もっと見る": click
  - header.site-header>div.header-inner>div.header-actions>button#search-toggle "検索": click
  - header.site-header>div#search-panel "キーワードで探す 検索する": keydown (no role)
  - header.site-header>div#search-panel>form#search-form "キーワードで探す 検索する": submit (no role)
  - footer.site-footer>div.footer-inner>section.newsletter>form#nl-form "メールアドレス 登録": submit (delegation container)
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email "": input

Typed into (plain, and through an IME composition):
  - div.options-row>div.option>div.stepper>input#qty: "vlmkit7" became "", "日本語" became "", composed ""
  - section.newsletter>form#nl-form>div.nl-row>input#nl-email: kept "vlmkit7", kept "日本語", composed "日本語"

Issues:
  warn [unprobed-handler-types] 4 handler type(s) registered and NONE exercised: click, close, keydown, submit — this gate is an inventory and presses nothing. A clean result here says the wiring exists, not that it works. Run 'check interactions --handlers' to focus and activate the controls, add '--probe-drag' for the drag surfaces, or drive the rest with a 'verify flow' script.
G71exit 0vlmkit check motion index.html

activeAnimations 0 · running 0 · issues 0

output, 34 line(s), 1.4s
vlmkit check motion
source: index.html

status: ok
samples: 25
active animations: 0
active transitions: 25
running animations: 0
paused animations: 0
reduced-motion rule: yes

Motion samples:
  - div.search-row > button:nth-of-type(1): animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #tab-front > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-side > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-top > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - #tab-use > span:nth-of-type(1): animation=none 0s running; transition=border-color, box-shadow 0.15s, 0.15s
  - div.swatches > label:nth-of-type(1) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - div.swatches > label:nth-of-type(2) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - div.swatches > label:nth-of-type(3) > input:nth-of-type(1): animation=none 0s running; transition=box-shadow 0.15s
  - #add-to-cart: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #fav: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #acc-detail-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-size-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-care-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #acc-ship-btn > svg:nth-of-type(1) > path:nth-of-type(2): animation=none 0s running; transition=transform 0.2s
  - #more-btn: animation=none 0s running; transition=background-color, border-color, color 0.15s, 0.15s, 0.15s
  - #more-btn > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.2s
  - svg.glaze-hakuji: animation=none 0s running; transition=transform 0.4s
  - ul.cards > li:nth-of-type(2) > a:nth-of-type(1) > span:nth-of-type(1) > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.4s
  - svg.glaze-ameyu: animation=none 0s running; transition=transform 0.4s
  - ul.cards > li:nth-of-type(4) > a:nth-of-type(1) > span:nth-of-type(1) > svg:nth-of-type(1): animation=none 0s running; transition=transform 0.4s

No motion issues detected.
S55

index.html · 1280×800 · full page, 4 screen(s)

S55 screen 1S55 screen 2S55 screen 3S55 screen 4
L55 saw

Final desktop 1280x800 on the final code (after D16/D17), 4 screens — identical to S43 where those fixes do not reach (they live inside closed accordion panels): the product fold with the CTA above y=620, 商品について with four closed rows, reviews with the sticky summary card holding at y≈24 on screen 3, related items and the footer. Re-checked the fold, the panel's right edge, the section rhythm and the footer; nothing moved, nothing new.

S56

index.html · 375×812 · full page, 7 screen(s)

S56 screen 1S56 screen 2S56 screen 3S56 screen 4S56 screen 5S56 screen 6S56 screen 7
L56 saw

Final mobile 375x812 on the final code, 7 screens — same as S44: full-bleed gallery and thumbnails, one-line h1, the solid pinned bar (stepped aside on screen 2 where the panel's button shows), lead and closed accordion, summary card and reviews, 2-up related cards, footer with the full-width third column. No overflow, overlap or clipped text.

S57

index.html · 768×1024 · full page, 5 screen(s)

S57 screen 1S57 screen 2S57 screen 3S57 screen 4S57 screen 5
L57 saw

Final tablet 768x1024 on the final code, 5 screens — same as S42: the 720x540 stage with the crackled celadon mug and left-aligned thumbnail strip, the panel with S/M and the stepper on one row and the buy row, lead and review bodies at their 36/38em measure, four related cards in one row, the footer with three link columns, the solid pinned bar throughout. Nothing to fix.

N16false-positiveabout G53

Final copy run: the same two findings as G22 and nothing else (12 of 14 lines found). ¥4,180(税込) is on screen in the panel (S55 screen 1) and in the drawer's subtotal format (S47); the gate cannot match it across the <span>¥4,180</span><span>(税込)</span> boundary — the separator behaviour isolated by probe in N12. レジに進む is visible in the open drawer with two mugs (S47, S48), which the disclosure sweep cannot open (N2, N11).

N17false-positiveabout G58

Final focus run: the same four findings as G7, same selectors, same numbers (233px / 188px / 173px reverse, one 216px skip-row). The reverses are focus-scroll artefacts shown in S6 (N4, N8); the skip-row is the gap between the reviews and the related section, with nothing focusable in it (S55 screen 3).

N18acceptedabout G54

Final design run: button drift (6 styles / 11) and input:radio drift (2 / 3) as accepted in N3 — five distinct button kinds, each consistent, the − segment differing only by its aria-disabled state; swatch circles vs size cards as two different option components. The h2 drift fixed in D8 stays fixed (h2 3.5x, ok).

N19false-positiveabout G60

Final scan scroll runs (G60 at 1280, G61 at 375): horizontal overflow 0px at both; the clipped-content warns are all sr-only spans (N5, N9), and the dead scrollport is the drawer's overflow:auto list (accepted in N5).

N20acceptedabout G62

Final scan handlers runs (G62, and G70 with --probe input): no pointer-only controls; the one warn is unprobed-handler-types, the inventory reporting that it pressed nothing (N6). The handlers are exercised by G63 (interactions, clean) and G69 (flow, 10/10). G70's IME probe: the email field keeps ASCII, Japanese and the composition; the numeric quantity field drops all three, which is its own filtering and is correctly not reported.

N21acceptedabout G66

Final grounding runs (G66 at 1280x720, G67 at 375x740): only the うつわ/うつわ ambiguity accepted in N7 (the same category, from nav and breadcrumb). カートに入れる is t25 at CSS (937,589) with no risks at 1280x720 (G47's map) and t50 in the pinned bar on a phone.

N22supersededabout G25

G25 was the --json twin of G22, run only to read the report's fields while diagnosing the price line (it has the same two findings). The copy gate's final state is G53, noted in N16.

done

A Japanese product page for a fictional pottery studio's mug, 汐見窯 マグカップ 青磁: a four-view inline-SVG gallery drawn once and recoloured per glaze (青磁 / 白磁 / 飴釉), named swatches, S/M, a 1–10 spinbutton that accepts full-width digits and flags made-to-order beyond the 3 in stock, a modal cart drawer (focus trap, Escape, focus return, badge, free-shipping progress, empty state), accordion, reviews with a sticky distribution and a もっと見る disclosure, related items, newsletter, and a pinned buy bar below 900px. 17 defects over 4 rounds: 13 found only by eye (the crackle twice, drips, a translucent pinned bar, orphaned 記, line measure, care-pill alignment, a sparse table, a lopsided review column, the notice style, the invalid-field state, an unfinished empty cart, a lost margin, note breaks) and 4 by gates (price split by a flex container, 20px overflow at 320px, a one-off h2 size, silent stepper buttons). Final set: integrity, composition, color, contrast, touch, interactions, both scroll checks, the 320–1280 sweep, flow 10/10 and motion clean; copy and focus fail only on documented false positives (a copy matcher that splits inline runs, a modal it cannot open, viewport-relative focus y); remaining warns are accepted with reasons.

R5 · independent review

reviewer
G72exit 0vlmkit check integrity index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)

verdict clean · findings 0 · fails 0 · warns 0 · exempted 24 · viewports 3

output, 27 line(s), 6.0s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 24 exempted)
  1280x800: 8 component(s), ink 26.3%, 109 text block(s)
  768x900: 8 component(s), ink 28.9%, 112 text block(s)
  375x700: 8 component(s), ink 32.6%, 112 text block(s)

No integrity defects detected.

Exempted candidates (the tool's call — audit the rule, not the page):
  - [text-clipped] span.badge > span:nth-of-type(2) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @1280: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(1) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(2) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(3) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(4) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] ul.dist > li:nth-of-type(5) > span:nth-of-type(3) > span:nth-of-type(1) @768: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #search-toggle > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] #cart-open > span:nth-of-type(1) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  - [text-clipped] span.badge > span:nth-of-type(2) @375: visually-hidden (sr-only) pattern — 1px box, text for AT only
  … 9 more
G73exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f7f3ec · bodyInk #23211d · linkInk #b8b1a5 · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

output, 28 line(s), 1.8s
vlmkit check color
source: index.html

verdict: CONSISTENT (0 finding(s))
  measured: 2 control(s), 26 link(s) in a text flow — from 301 visible box(es)

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  4 distinct
    #f7f3ec   75.9%     4 el  
    #efe9df   12.3%     5 el  section.product>div.gallery>div.stage
    #1f2b27    9.2%     1 el  footer.site-footer
    #fcfaf6    2.6%     3 el  div.sizes>label.size>input
  ink       8 distinct
    #23211d   55.1%    39 el  a.wordmark>span.wordmark-text>span.wordmark-ja
    #4a453e   16.9%    36 el  ul>li>a
    #b8b1a5    9.7%    13 el  div.footer-inner>section.newsletter>p.nl-lead
    #686157    7.6%    21 el  a.wordmark>span.wordmark-text>span.wordmark-en
    #ece6dc    6.6%     6 el  h2#nl-title
    …and 3 more
  marks     6 distinct
    #ddd5c8   54.6%    25 el  header.site-header
    #cbc2b3   17.4%     5 el  main#main>section.about>div.accordion
    #8a8277   11.6%    34 el  div.swatches>label.swatch>input
    #ece6dc    6.3%     1 el  footer.site-footer>div.footer-bottom
    #23211d    5.6%     8 el  button#tab-front>span.thumb-img
    …and 1 more
  base #f7f3ec, body ink #23211d, link ink #b8b1a5 on 11 element(s)
G74exit 0vlmkit check a11y contrast index.html

inspected 119 · failures 0

output, 5 line(s), 1.7s
  vlmkit check a11y contrast
  html: examples/sites/shop/index.html
  inspected 119 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/shop/test-results/a11y-contrast/index-07f7b4b9/report.md
G75exit 0vlmkit verify flow index.html --flow flow.json

verdict: DONE (10/10 steps)

done true · passed 10 · total 10

output, 43 line(s), 2.9s
vlmkit verify flow
source: index.html

verdict: DONE (10/10 steps)

✓ step 1: the header cart opens the empty drawer
    ✓ #cart-drawer visible 
    ✓ #cart-empty visible 
    ✓ #cart-foot hidden 
    ✓ #cart-lines > li count=0 
✓ step 2: 買い物を続ける in the empty drawer closes it and returns focus to the cart button
    ✓ #cart-drawer hidden 
    ✓ #cart-open focused 
✓ step 3: step the quantity up to 2
    ✓ #qty aria-valuenow=2 
    ✓ #qty-dec aria-disabled=false 
✓ step 4: カートに入れる opens the drawer with two mugs
    ✓ #cart-drawer visible 
    ✓ #cart-close focused 
    ✓ #cart-lines > li count=1 
    ✓ #cart-lines text~"青磁" 
    ✓ #cart-lines text~"S 240ml" 
    ✓ #cart-subtotal text~"¥8,360" 
    ✓ #cart-count text~"2" 
    ✓ #checkout visible 
✓ step 5: Escape closes the drawer and returns focus
    ✓ #cart-drawer hidden 
    ✓ #add-to-cart focused 
✓ step 6: choose 飴釉 and M
    ✓ html data-glaze=ameyu 
    ✓ #product-title text~"飴釉" 
✓ step 7: size M
    ✓ .buybar-variant text~"M 320ml" 
✓ step 8: a second variant becomes a second line
    ✓ #cart-lines > li count=2 
    ✓ #cart-count text~"4" 
    ✓ #cart-subtotal text~"¥16,720" 
✓ step 9: remove the first line
    ✓ #cart-lines > li count=1 
    ✓ #cart-count text~"2" 
    ✓ #cart-lines text~"飴釉" 
✓ step 10: close button closes
    ✓ #cart-drawer hidden
S58

the product page as a shopper lands

index.html · 1280×800 · full page, 4 screen(s)

S58 screen 1S58 screen 2S58 screen 3S58 screen 4
L58 saw

Desktop (4 screens). Screen 1: a quiet header — the 汐見窯 wordmark with SHIOMI-GAMA under it, four nav items with うつわ underlined in green, 検索 and カート with a 0 badge — then the breadcrumb and a two-column product view: four labelled thumbnails in a column (正面 framed), a large drawn celadon mug with an irregular crackle and a softly lit backdrop, and the product panel: maker line, title, ¥4,180 with a small (税込), stars 4.6 and an underlined review link, three named glaze swatches (青磁 ringed), S/M size cards, a − 1 + stepper, the green カートに入れる and an outlined お気に入り, then shipping, stock and dispatch lines with icons. Screens 2–4: 商品について beside the four-row accordion, the review summary card with ★ bars and counts next to the reviews, もっと見る, four drawn related pieces with prices (新作 on the teapot), and a dark footer with the newsletter form and three link columns. Consistent spacing and type throughout; nothing collides.

S59

the product page as a shopper lands

index.html · 375×812 · full page, 7 screen(s)

S59 screen 1S59 screen 2S59 screen 3S59 screen 4S59 screen 5S59 screen 6S59 screen 7
L59 saw

Phone (7 screens). The header compresses to icons with the cart badge, nav moves to its own row, the gallery goes full width with the four thumbnails in a row beneath it. A bar pinned to the bottom carries the current choice (青磁・S 240ml), the price and カートに入れる — and it is absent on screen 2, where the panel's own button is on screen, so the two never show at once. Swatches, size cards and the stepper keep large targets; the accordion, the review card and reviews stack; related items become a 2×2 grid; the footer stacks its columns. Japanese body text wraps cleanly with comfortable leading. No overflow.

S60

two mugs added, the cart drawer open

index.html · 1280×800 · click #qty-inc · click #add-to-cart · wait 500

1 screen(s), looked at when taken; not kept once the round was done — a round keeps one full-page walk per width.

L60 saw

Desktop, after + and カートに入れる: a drawer slides over the right third of the page with a dimmed backdrop. It confirms 「カートに追加しました(青磁・S 240ml・2点)」 on a pale green strip, lists the mug with its thumbnail, glaze, size, quantity 2 and ¥8,360, and a 削除 link; the footer of the drawer says the order ships free with a full progress bar, shows 小計 ¥8,360(税込), the primary レジに進む and a secondary 買い物を続ける. Clear hierarchy, correct arithmetic, nothing clipped.

N23decision

Independent review: integrity, color, contrast and the 10-step cart flow re-run green; three fresh shots (desktop, phone, the open drawer with two mugs) show nothing the builder's log missed. No defects raised.

done

Reviewer round: gates green on re-run; product page, phone layout with its pinned bar, and the cart drawer all hold up.