vlmkit demo · judgment log

ほとり — 海辺の町の古本屋が、夜だけ店を開ける理由

How this editorial long-form article 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: long-form magazine article — 「ほとり」 web magazine

- **Directory**: `examples/sites/magazine/`
- **Pattern**: editorial long-form article
- **Language**: Japanese (`lang="ja"`)

## What it is

One feature article in a fictional web magazine, **ほとり** (hotori — "the water's edge"):
**「海辺の町の古本屋が、夜だけ店を開ける理由」**, about a second-hand bookshop in a small seaside
town that opens only from dusk until midnight. One page, `index.html`. Write the article yourself:
about 3,000 Japanese characters of real, readable prose — not placeholder text.

## Layout and behaviour

- **Masthead**: the magazine's wordmark, section navigation (特集 / 暮らし / 旅 / 本 / インタビュー) and
  a search button. A thin reading-progress bar at the very top grows as the article is read.
- **Article header**: a large drawn illustration (inline SVG — the shop at night), the category
  label 本, the title, a lede, the byline 文・写真 三浦 灯, the date 2026年9月12日 and the reading
  time 約8分.
- **Body**: three or four `h2` sections; a pull quote; a figure with a caption; an interview passage
  with the speakers marked; two or three footnote references that jump to notes at the end, each
  note with a link back. Links in the prose must be distinguishable by more than colour.
- **After the article**: an author card, a "copy link" button that confirms 「リンクをコピーしました」
  in a live region, a 保存 toggle (`aria-pressed`), and three related articles with drawn images.
- **Footer**.
- **Motion**: the progress bar is the only motion; it respects `prefers-reduced-motion`.

## Visual direction

Editorial and quiet: an off-white page, a deep ink colour, one restrained accent, generous margins
and line spacing (around 1.9 for body text), a measure of roughly 35–40 full-width characters on
desktop, and a clear typographic hierarchy between headings, body, captions and notes. Body text
prefers a Mincho serif on real devices (this machine has none — see the protocol); headings may be
Gothic.

## Required copy

```
ほとり
海辺の町の古本屋が、夜だけ店を開ける理由
文・写真 三浦 灯
2026年9月12日
約8分
リンクをコピーしました
関連する記事
注
```

## States to show (final round)

Desktop and mobile full page; mid-article with the progress bar partly filled; the page scrolled to
a footnote after following its reference; the copy-link confirmation; the 保存 toggle pressed;
reduced motion.

## Gates this brief leans on

`check composition` (type hierarchy and grouping over a long page), `check color` (prose links),
`check copy` on Japanese, `check integrity` (Japanese line breaking, clipping), `check scroll`
(the fixed progress bar), `check motion` / `check animation` (reduced motion honoured),
`stress i18n`.

Defects

DefectFound byWhatFixChecked by
D1eye L1 on S1

.lede

Desktop S1-1: the lede's last line splits the owner's name across the break, 汐田律 / 子さんをたずねた。 A display paragraph should not break inside a personal name.

The lede is no longer justified: word-break: auto-phrase (phrase-level Japanese line breaking) and text-wrap: pretty, so lines break between phrases and a name stays whole.

L7
D2eye L1 on S1

font stack (--sans)

Every digit and Latin letter renders fixed-pitch (S1-1 meta 2026 年 9 月 12 日, S1-9 card dates, S2-12 footer 'vlmkit'): the sans stack names IPAGothic, whose Latin glyphs are monospaced (fc-list spacing=90); the proportional IPAPGothic exists on this machine.

The sans stack now names IPAPGothic (proportional Latin and digits) instead of IPAGothic; there is a comment in style.css saying why.

L11
D3eye L1 on S1

.figure__svg (sunbeam overlay)

S1-4: the sunbeam over the shelf ends in a hard vertical edge at x≈720 that cuts through all three shelves; it reads as a rendering glitch, not as light.

The shelf sunbeam is now a gradient polygon that fades from .26 to 0 across the shelf (f-shelfbeam), with no flat-opacity shape and no hard vertical edge.

L7
D4eye L1 on S1

.pullquote blockquote p

S1-6: the pull quote breaks inside a word (…誰かが起 / きている…); on mobile (S2-7) it ends on a lone い。 line. Display type needs phrase-level breaks.

The pull quote uses word-break: auto-phrase + text-wrap: balance, so it breaks between phrases into lines of even length.

L8
D5eye L1 on S1

.site-footer__copy

S1-10 / S2-13: the © 2026 ほとり編集部 line renders at about 10px (<small> inside a 12px paragraph) and is hard to read.

Removed the <small> from the © line; it now renders at the footer's 12px like the note above it.

L7
D6eye L2 on S2

.chapter > p, .figure figcaption

Several paragraphs end on a one- or two-character line (S1-3 た。, S2-2 いく。, S2-4 いる。, S2-8 る。) and the figure caption ends on a lone る。 (S2-5). Short last lines break the texture of justified Japanese text.

text-wrap: pretty on body paragraphs, interview utterances and the figure caption, so the browser rebalances the last lines instead of leaving one or two characters alone.

Second attempt (F6 did not work): the last four visible characters of each body paragraph, interview utterance and the figure caption are wrapped in <span class=tail> with white-space: nowrap (26 tails, made by a one-off script; a tail that would end inside an element takes the whole element, such as the 注1 <sup>). No paragraph can end on a line shorter than four characters; the line above absorbs at most three characters' worth of space as justification.

L13
D7eye L2 on S2

.masthead__inner (mobile)

S2-1: at 375px the 検索 button wraps onto its own row under the tagline, left-aligned, so the masthead is three rows (~165px) before the nav and the button looks misplaced.

Below 700px the tagline is hidden, so the masthead is two rows: wordmark with 検索 on the right, then the section nav.

L8
D8eye L2 on S2

.meta (mobile)

S2-2: the meta row wraps and its second line starts with a stray separator bar: '| 読了時間 約8分'.

Below 700px the byline takes its own line and the date loses its leading separator, so the second line reads '2026年9月12日 | 読了時間 約8分' with the bar only between the two items.

L8
D9eye L2 on S2

.chapter > h2

S2-2: the first h2 wraps with a single character on its second line: 日が沈むと、シャッターが上が / る. Headings need balanced, phrase-level wrapping.

Chapter h2s use word-break: auto-phrase + text-wrap: balance.

L13
D10eye L2 on S2

.backref (mobile)

S2-10: when 本文へ戻る wraps to a new line it starts with a stray indent (its margin-left) that does not line up with the note text.

Replaced the back link's margin-left with a plain space in the markup ('。 <a class=backref>'), which collapses at the start of a line, so a wrapped 本文へ戻る now starts flush with the note text.

L8
D11eye L2 on S2

.share (mobile)

S2-10: the share row breaks badly at 375px: この記事を + リンクをコピー on the first line and 保存 alone on a second line.

Below 700px the この記事を label takes its own line, both buttons share the next, and the confirmation wraps below them.

L8
D12eye L2 on S2

.related__list (mobile)

S2-11 to S2-13: on mobile the three related cards are stacked full-width 335x223 images, so the related section runs over 1,100px and reads like a second article instead of a short list of next reads.

Below 700px each related card is a two-column grid (112px thumbnail, then category, title and date), and the band's padding and margin are reduced to the 64/40/56 steps.

L8
D13eye L3 on S3

.art__svg (quay, left end)

S3: the white sliver at the quay's left end is the page's paper showing through: nothing is painted between the quay's slanted left edge and the water, and the sky rect stops at y=480.

The hero SVG now starts with a full 640x640 night rect under everything, and the quay's left edge is vertical at x=124, where the water begins, so no gap is left unpainted.

L9
D14eye L3 on S3

.art__svg (storefront bulbs)

S3: the three bare bulbs are drawn exactly under the door mullions (x 256/321/386), so the bulbs themselves are hidden and only their glows show.

The bulbs now hang in the middle of the four glass panels (x 224/288/354/418), clear of the mullions, each with a small halo; the customer moved to the third panel.

L9
D15gate G1

svg.art__svg > g:nth-of-type(11) > circle:nth-of-type(2)

check integrity near-misalignment: the middle bulb glow sits 3.5-4px above its two siblings. It was meant to hang on a shorter cord, but in S3 a 4px offset reads as an accident, as the rule says. Either align the bulbs or make the difference unmistakable.

All four bulbs hang at one height (cy 389, cords 374-385): I chose alignment over a 4px variation that only reads as a mistake.

G17
D16eye L3 on S3

.art__svg (light spill)

S3: a small dark bollard dome sits in the middle of the lit spill in front of the door and reads as a stray blob.

Removed both bollards; the light spill in front of the door is clean.

L9
D17eye L3 on S3

.art__svg (quay face)

S3: the quay's front face shows as an outlined box: a light hairline runs along its bottom edge where it meets the water.

The quay face now overlaps the water by 1px on the full-frame background, and the edge highlight is darker and 5px tall, so no light seam outlines the face.

L9
D18eye L5 on S5

font stack (--serif)

S5 vs S6: the body text is in a different Gothic from the headings. No font named in the serif stack exists here, so the generic serif resolves (fc-match serif:lang=ja) to WenQuanYi Zen Hei, a Chinese font: the page mixes two Gothic designs, and the body gets Chinese glyph forms.

The serif stack adds IPAPMincho, then IPAGothic as the last named face before the generic, so a device with no Japanese serif renders Japanese glyph forms in the same design as the headings instead of whatever the generic resolves to (a Chinese font here). There is a comment in style.css saying why.

L10
D19gate G2

h1#story-title

check copy: the required title line is reported copy-invisible (found only in text a user cannot see). The visible h1 is split into two inline-block spans to force the break after 、, so the rendered text has no contiguous 海辺の町の古本屋が、夜だけ店を開ける理由; the only contiguous copy is the document <title>.

The h1 is a single text node again; the two-line break comes from word-break: auto-phrase + text-wrap: balance instead of two inline-block spans.

G18
D20gate G3

h2#notes-title, h2#author-name, h2#related-title

check design component-drift: 7 h2 in 4 styles. The four chapter heads share 25px, but the three secondary heads are 17px (注), 18px (author name) and 20px (関連する記事): three sizes for one role, with no reason for any of them.

注, the author's name and 関連する記事 share one secondary-head rule (20px/700, .08em); the four chapter heads keep 25px, so h2 has two styles, each used at least 3x.

G19
D21gate G3

h3#shop-info-title

check design component-drift: 4 h3 in 2 styles. The shop-info name is 18px against the three card titles at 17px, a 1px difference that is an accident, not a decision.

The shop-info name is 17px like the card titles.

G19
D22gate G3

header#top>div.wrap paddingTop; section.related marginTop

check design scale-outlier (info): masthead padding-top 22px sits next to the page's 20px step, and the related band's 88px margin-top next to the 96px used four times. Both are strays from my own scale.

Masthead padding is 20px top and bottom, and the related band's margin-top is 96px (64px below 700px).

G19
D23gate G4

h3#shop-info-title

check composition proximity-inversion: the shop name sits 4px under its 店舗情報 kicker but 16px above the list it labels, so it groups upward.

The shop-info name margin is now 6px above and 10px below, so it sits closer to the list it labels than the rule's threshold allows it to drift upward.

G20
D24gate G4

li#related-1..3 > a.card__link > h3.card__title

check composition proximity-inversion x3: each card title sits 6px under its category label but 14px above its date, so title and date read as two groups.

Card title margin is 6px 0 2px and the date is a block at 1.5 line-height, so the title is 2px from its date and about 12px from its label.

G20
D25gate G15

.turn (speaker column), .note (number column)

stress i18n: the interview speaker labels (汐田X) and the note numbers (注1X) wrap to two lines under inflation, because both sit in fixed 3.2em / 3em grid columns. A three- or four-character speaker name, or a 注10, would break the same way. The prose rows are ordinary wrapping.

The interview and the notes are each one grid (minmax(3em, max-content) then 1fr) with subgrid rows, so the label column grows to the longest speaker name or note number and every row stays aligned; labels are white-space: nowrap. The notes' :target highlight now uses side box-shadows instead of padding and a negative margin.

L7
D26eye L1 on S1

sup.fnref after ruby (漁火)

S1-5: the ruby いさりび over 漁火 and the 注3 superscript right after it run together into one clump of small text at the same height; the reference needs a little air to read as a separate mark.

A footnote reference that follows ruby gets .4em of left margin (ruby + .fnref); other references keep .12em.

L7
D27eye L7 on S7

font stack (--sans)

Regression from F2: IPAPGothic sets 、。() half-width, so every sans run looks cramped at its punctuation: 日が沈むと、シャッター, 西日から、本の, 零時に、明かり (S7-2/3/6), 宵待書房(よいまち and 水曜日、海が (S7-7/8), and the notes and bio read dense. S10 shows the heading's comma next to the full-width commas of the body.

The sans stack goes back to IPAGothic for Japanese (full-width 、。()), with DejaVu Sans named just before it so Latin and digits resolve to a proportional face first; real devices still use Hiragino / Yu Gothic / Noto, which come earlier in the list.

L11
D28eye L8 on S8

h3.card__title (mobile)

S8-11: in the compact related list, two card titles wrap with widows: 岬の貸本屋に、手紙で本を頼 / む and 潮風と暮らす家の、窓のしつ / らえ. The h3s never got the phrase-level wrapping the h1/h2 got.

A base rule gives h1, h2 and h3 word-break: auto-phrase + text-wrap: balance, which covers the card titles, the shop name and the secondary heads.

L13
D29gate G19

div.brand gap

check design scale-outlier (info): the brand block's 18px gap (wordmark to tagline) sits next to the 16px step used 13 times.

The brand gap is 16px.

G24
D30eye L12 on S12

.masthead__inner (700-999px)

S12-1 / S15: at tablet width the one-row desktop masthead does not fit in 688px, and the flex items shrink until their text wraps a character at a time: ほと / り, 特 / 集, 暮 / ら / し, インタ / ビュー, and a tall 検 / 索 pill. No gate reported it: check integrity at 768 was CLEAN (G17) and the breakpoint sweep was clean (G16), because nothing overflows or overlaps.

The tagline shows only at 1100px and up, where the one-row masthead has the ~910px it needs; from 700 to 999px the nav gap is 20px and the row gap 28px (about 590px needed, 620px available at 700). The wordmark, nav links and buttons are white-space: nowrap, so if a width is ever too narrow the row overflows, which the breakpoint sweep can catch, instead of silently wrapping a character at a time.

L17
D31eye L13 on S13

.figure figcaption

S13-5: the figure caption's last line begins with a small kana (っている。), which strict Japanese line breaking forbids; the caption never got the line-break: strict the body paragraphs have.

line-break: strict is set on body, so the caption, notes, bio and UI text get the same kinsoku as the body paragraphs.

L20
D32eye L21 on S21

input#search-input::-webkit-search-cancel-button

S21: the search field's native cancel × renders in system blue, the only blue on the page.

::-webkit-search-cancel-button is restyled: no native appearance, and a 14px × drawn with two ink-soft gradients.

L28
D33eye L21 on S21

button#search-toggle[aria-expanded=true]

S21/S22: the 検索 toggle has no open state. The only fill in the shots is the pointer's hover, so once the pointer leaves, nothing ties the button to the open panel.

While aria-expanded is true, 検索 takes the panel's paper-deep fill and its magnifier is swapped for a close mark (two icons in the button, toggled in CSS); the visible and accessible name stays 検索.

L28
D34eye L23 on S23

[id^=note-], [id^=ref-] scroll-margin

S23/S24: both footnote jumps land the target 32px under the top edge, with a sliced line of the item above it (the end of 注1 over 注2; the first line of the quoted paragraph over the 注2 reference). The reader lands without context and has to scroll up to re-read the sentence.

Footnote notes and references get scroll-margin-top: 25vh, so a jump lands with the preceding lines in view; the returned-to reference's tint is backed by a 3px tint ring, so it is easier to find.

L29
D35gate G27

#progress-bar (main.js is-ready)

check animation on index.html#note-2: '#progress-bar transform 120ms x1: visible, motion region (319,0) 961x3'. A page opened at a fragment animates the bar on load, sweeping it from about 25% to full width, because the easing is switched on one frame after the script runs and the browser's fragment scroll comes later. The README and the code comment both claim a page opened mid-article does not animate on load.

main.js: the easing class (is-ready) is added by the first wheel, touchstart, keydown or pointerdown (capture, passive, removed after firing), not one frame after load. A fragment or restored scroll made by the browser therefore jumps the bar straight to its place. The README now says this; the reduced-motion and ?animate=0 rules are unchanged.

G28
D36gate G45

aside#shop-info dl.shop-info__list dt

stress i18n: the shop-info labels wrap under inflation: 'dt そのほかXX 77×50 +25px' and 'dt 営業時間XX 77×50 +25px' (one line to two; the dd beside each only grows because the row does). The dt column is a fixed 5.5em, the same fixed-label pattern D25 removed from the interview and the notes; a five-character label such as 最寄りの駅 would wrap it without any inflation.

The shop-info dl is one grid (minmax(5.5em, max-content) then 1fr) with each row a subgrid, and dt is white-space: nowrap, so the label column grows to the longest label and every row stays aligned, as in the interview and notes.

G48
D37eye L39 on S39

.pullquote blockquote p

On desktop the pull quote's first line ends on 誰かが, the subject of the SECOND sentence, so the quote reads 「…思うの。誰かが/起きている明かりが…」. word-break: auto-phrase makes 誰かが a legal break and text-wrap: balance prefers 23/21 characters to the sentence boundary's 20/24, although both sentences fit the 694px column on one line each.

Each sentence of the pull quote is a span, inline-block from 700px, so on wide screens the quote breaks at the sentence boundary; below 700px the spans stay inline and auto-phrase / balance break it as before (the phone version already broke by phrase well).

L41

Rounds

R1 · first draft

builder
N1decision

Gate set. Protocol floor: check integrity, check copy --manifest copy.txt, check design, check composition, check color, check a11y contrast, check a11y focus, check a11y touch, scan scroll, scan handlers, check interactions. The brief defines no theme and no theme URL parameter, so contrast runs on the one light theme. Added for the brief's behaviour: check scroll (the progress bar is position:fixed and must hold the top edge while the page scrolls), check motion + check animation (the bar's easing is the only motion and must stop under prefers-reduced-motion; also ?animate=0), stress i18n (listed by the brief; Japanese text in nav, buttons and meta rows), check breakpoints --sweep (the layout changes at 700px and 1000px and has to be free of horizontal overflow at every width in between). Left out: verify flow (no multi-step flow), check grounding (not asked), scan handlers --probe-drag (nothing is draggable).

S1

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

S1 screen 1S1 screen 2S1 screen 3S1 screen 4S1 screen 5S1 screen 6S1 screen 7S1 screen 8S1 screen 9S1 screen 10
L1 saw

Desktop 1280, full page, 10 screens. S1-1: first read is right: the masthead (wave mark + ほとり, grey tagline, nav right-aligned with 本 in the accent and underlined, 検索 pill) and the title. The progress track is a faint grey hairline at the very top with no fill. Header: text column on the left (boxed 本 label, series line, two-line bold title split exactly after 、, grey lede with なぎうら ruby over 凪浦, meta row under a hairline), 620px night illustration on the right; the text block is centred against it, so about 140px of empty paper sits above the 本 label. Wrong: (a) the lede's last line splits the owner's name: 汐田律 / 子さんをたずねた。 (b) every digit and Latin letter is fixed-pitch, so the meta reads 2026 年 9 月 12 日 like a typewriter; (c) in the illustration a bright white sliver stands at the left end of the quay (x≈720, y≈600-650), and the quay/water join there looks unfinished. S1-2/S1-3: body column 293-986px, about 37 characters a line at 1.9 leading, justified; h2s carry a 36px accent rule; the link 前回訪ねた岬の貸本屋 is accent + underline; 注1 is a small underlined superscript. S1-3: section 2's first paragraph ends on a lone line 「た。」. S1-4: the shelf figure breaks out to 880px and the faded-vs-saturated spines tell the story, but the sunbeam overlay stops at a hard vertical edge (x≈720) through all three shelves, which reads as a rendering glitch rather than light; the 文庫 百円 card covers spines. S1-5: interview between hairlines, speaker labels 三浦 (grey) / 汐田 (accent) aligned to each first line; the ruby いさりび and the 注3 superscript crowd each other. S1-6: pull quote under a 2px ink rule, 26px bold, but the line breaks inside a word: …誰かが起 / きている… S1-7/S1-8: shop-info box with ruled rows; notes 注1-3 with underlined 本文へ戻る; share row (この記事を, リンクをコピー, 保存 pills) between hairlines; author card with the 灯 monogram. S1-9/S1-10: related band, three cards with drawn images (letter + book, cape lighthouse, window with curtain), accent labels, bold titles, grey dates; dark footer with wordmark, underlined links, the fictional-magazine note; the © line is about 10px and hard to read.

D1 defect .lede

Desktop S1-1: the lede's last line splits the owner's name across the break, 汐田律 / 子さんをたずねた。 A display paragraph should not break inside a personal name.

D2 defect font stack (--sans)

Every digit and Latin letter renders fixed-pitch (S1-1 meta 2026 年 9 月 12 日, S1-9 card dates, S2-12 footer 'vlmkit'): the sans stack names IPAGothic, whose Latin glyphs are monospaced (fc-list spacing=90); the proportional IPAPGothic exists on this machine.

D3 defect .figure__svg (sunbeam overlay)

S1-4: the sunbeam over the shelf ends in a hard vertical edge at x≈720 that cuts through all three shelves; it reads as a rendering glitch, not as light.

D4 defect .pullquote blockquote p

S1-6: the pull quote breaks inside a word (…誰かが起 / きている…); on mobile (S2-7) it ends on a lone い。 line. Display type needs phrase-level breaks.

D5 defect .site-footer__copy

S1-10 / S2-13: the © 2026 ほとり編集部 line renders at about 10px (<small> inside a 12px paragraph) and is hard to read.

D26 defect sup.fnref after ruby (漁火)

S1-5: the ruby いさりび over 漁火 and the 注3 superscript right after it run together into one clump of small text at the same height; the reference needs a little air to read as a separate mark.

S2

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

S2 screen 1S2 screen 2S2 screen 3S2 screen 4S2 screen 5S2 screen 6S2 screen 7S2 screen 8S2 screen 9S2 screen 10S2 screen 11S2 screen 12S2 screen 13
L2 saw

Mobile 375, full page, 13 screens. S2-1: the masthead takes three rows (about 165px): wordmark, tagline, then the 検索 button wrapped onto its own line under the tagline, left-aligned, before the nav row (特集 暮らし 旅 本 インタビュー spread edge to edge, 本 underlined). The illustration is 335px square with rounded corners, then 本 + series, a two-line 28px title (clean split), and the lede. S2-2: the meta row wraps and the second line starts with a stray separator bar: "| 読了時間 約8分". The first h2 wraps with a single character on its second line: 日が沈むと、シャッターが上が / る. S2-2 to S2-9: body at 16px, about 19-20 characters a line, justified, strict line breaking; several paragraphs end on a two-character line (いく。 in S2-2, いる。 in S2-4, る。 in S2-8), and the figure caption ends on a lone る。 (S2-5). S2-6: the interview grid holds at this width; interviewer lines grey, speaker column narrow but aligned. S2-7: the pull quote ends on a single い。 line. S2-9: shop info fits, rows wrap cleanly. S2-10: notes: where 本文へ戻る wraps to a new line it starts with a small indent that does not line up with the note text; the share row breaks badly: この記事を + リンクをコピー on one line and 保存 alone on a second line. Author card fine. S2-11 to S2-13: about 85px of blank paper before the related band; the three related cards are stacked as full-width 335x223 images, so the section is over 1,100px tall and reads like a second article; digits in the dates are fixed-pitch; footer links wrap to two rows (プライバシー alone), © line tiny.

D6 defect .chapter > p, .figure figcaption

Several paragraphs end on a one- or two-character line (S1-3 た。, S2-2 いく。, S2-4 いる。, S2-8 る。) and the figure caption ends on a lone る。 (S2-5). Short last lines break the texture of justified Japanese text.

D7 defect .masthead__inner (mobile)

S2-1: at 375px the 検索 button wraps onto its own row under the tagline, left-aligned, so the masthead is three rows (~165px) before the nav and the button looks misplaced.

D8 defect .meta (mobile)

S2-2: the meta row wraps and its second line starts with a stray separator bar: '| 読了時間 約8分'.

D9 defect .chapter > h2

S2-2: the first h2 wraps with a single character on its second line: 日が沈むと、シャッターが上が / る. Headings need balanced, phrase-level wrapping.

D10 defect .backref (mobile)

S2-10: when 本文へ戻る wraps to a new line it starts with a stray indent (its margin-left) that does not line up with the note text.

D11 defect .share (mobile)

S2-10: the share row breaks badly at 375px: この記事を + リンクをコピー on the first line and 保存 alone on a second line.

D12 defect .related__list (mobile)

S2-11 to S2-13: on mobile the three related cards are stacked full-width 335x223 images, so the related section runs over 1,100px and reads like a second article instead of a short list of next reads.

G1exit 0vlmkit check integrity index.html

verdict: NO DEFECTS, 1 WARN (0 fail, 1 warn, 0 exempted)

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

output, 11 line(s), 7.1s
vlmkit check integrity
source: index.html

verdict: NO DEFECTS, 1 WARN (0 fail, 1 warn, 0 exempted)
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule near-misalignment=suspect
  1280x800: 1 component(s), ink 93.6%, 107 text block(s)
  768x900: 1 component(s), ink 92.5%, 107 text block(s)
  375x700: 1 component(s), ink 91.0%, 107 text block(s)

Findings:
  ! [near-misalignment] svg.art__svg > g:nth-of-type(11) > circle:nth-of-type(2) @1280,768,375: svg.art__svg > g:nth-of-type(11) > circle:nth-of-type(2) is off its siblings' shared top edge by 3.5px inside svg.art__svg > g:nth-of-type(11) — siblings align exactly; a 2-8px deviation is almost always an accident (stray margin/padding), not a design choice.
D15 defect svg.art__svg > g:nth-of-type(11) > circle:nth-of-type(2)

check integrity near-misalignment: the middle bulb glow sits 3.5-4px above its two siblings. It was meant to hang on a shorter cord, but in S3 a 4px offset reads as an accident, as the rule says. Either align the bulbs or make the difference unmistakable.

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

missing 1 · placeholders 0 · manifestLines 8 · invisibleOnly 1 · statesExplored 1 · revealedOnly 0

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

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

Issues:
  x copy-invisible: Manifest line found ONLY in text a user cannot see (reason: unknown): "海辺の町の古本屋が、夜だけ店を開ける理由". 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 1 revealed disclosure state(s): "リンクをコピーしました" (comparison is whitespace-normalized, case-sensitive).
D19 defect h1#story-title

check copy: the required title line is reported copy-invisible (found only in text a user cannot see). The visible h1 is split into two inline-block spans to force the break after 、, so the rendered text has no contiguous 海辺の町の古本屋が、夜だけ店を開ける理由; the only contiguous copy is the document <title>.

G3exit 0vlmkit check design index.html

verdict: DRIFT (3 finding(s))

verdict drift · drifting 2 · roles 5

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

verdict: DRIFT (3 finding(s))
  exits 0 — 2 warn(s) did not fail this command. To gate on one: --rule component-drift=suspect
  roles judged: 3 of 5 seen, spacing values: 24
  coverage: 17 of 700 visible element(s) carried an inferable role
    no role: rect x396, p x41, path x40, circle x34, g x28, a x23, +27 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.

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  h2               7 inst    4 styles  reuse  1.75x  3 one-off  drift
  h3               4 inst    2 styles  reuse     2x  1 one-off  drift
  button           3 inst    1 styles  reuse     3x  0 one-off  ok
  img              2 inst    2 styles  reuse     1x  2 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: img (2), h1 (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] h2: 7 "h2" elements render 4 distinct styles (used 4x, 1x, 1x, 1x; a system reuses each style 3x or more, and this role averages 1.75x). Dominant style, used 4x: padding 0/0/0/0, radius 0, 25px/700, border 0, bg rgba(0, 0, 0, 0). Deviating: h2#notes-title (padding 0/0/0/0, radius 0, 17px/700, border 0, bg rgba(0, 0, 0, 0)) — differs in font-size 25 → 17; h2#author-name (padding 0/0/0/0, radius 0, 18px/700, border 0, bg rgba(0, 0, 0, 0)) — differs in font-size 25 → 18; h2#related-title (padding 0/0/0/0, radius 0, 20px/700, border 0, bg rgba(0, 0, 0, 0)) — differs in font-size 25 → 20. This reports inconsistency, not which style is correct.
  ! [component-drift] h3: 4 "h3" elements render 2 distinct styles (used 3x, 1x; a system reuses each style 3x or more, and this role averages 2x). Dominant style, used 3x: padding 0/0/0/0, radius 0, 17px/700, border 0, bg rgba(0, 0, 0, 0). Deviating: h3#shop-info-title (padding 0/0/0/0, radius 0, 18px/700, border 0, bg rgba(0, 0, 0, 0)) — differs in font-size 17 → 18. This reports inconsistency, not which style is correct.

Informational (true, but does not carry the verdict)
  i [scale-outlier]: 2 spacing value(s) sit just off the page's own scale: 22px (1x) next to 20px (14x) — header#top>div.wrap paddingTop; 88px (1x) next to 96px (4x) — main#main>section.related marginTop. Snap them to the established value or add them deliberately.
D20 defect h2#notes-title, h2#author-name, h2#related-title

check design component-drift: 7 h2 in 4 styles. The four chapter heads share 25px, but the three secondary heads are 17px (注), 18px (author name) and 20px (関連する記事): three sizes for one role, with no reason for any of them.

D21 defect h3#shop-info-title

check design component-drift: 4 h3 in 2 styles. The shop-info name is 18px against the three card titles at 17px, a 1px difference that is an accident, not a decision.

D22 defect header#top>div.wrap paddingTop; section.related marginTop

check design scale-outlier (info): masthead padding-top 22px sits next to the page's 20px step, and the related band's 88px margin-top next to the 96px used four times. Both are strays from my own scale.

G4exit 0vlmkit check composition index.html

verdict: UNBALANCED (4 finding(s))

verdict unbalanced · proximity 4 · flatSteps 0 · railNearMisses 0

output, 22 line(s), 1.6s
vlmkit check composition
source: index.html

verdict: UNBALANCED (4 finding(s))
  exits 0 — 4 warn(s) did not fail this command. To gate on one: --rule proximity-inversion=suspect
  measured: 8 label(s), 3 heading level(s), 99 wide block(s) on 10 left / 7 right rail(s) — from 186 visible box(es)
  4 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     42px / 700   h1#story-title
  h2     25px / 700   h2#ch1
  h3     18px / 700   h3#shop-info-title
  body 18px, largest 42px (2.33x), heaviest +300 weight

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

Findings
  ! [proximity-inversion]: h3#shop-info-title (h3) sits 4px below aside#shop-info>p.shop-info__kicker but 16px above the content it labels, inside aside#shop-info — a label reads as belonging to whatever it is CLOSEST to, so this one groups upward. Reduce the gap under it below 11px, or widen the gap above it. This reports the ambiguity, not which gap is correct.
  ! [proximity-inversion]: li#related-1>a.card__link>h3.card__title (h3) sits 6px below li#related-1>a.card__link>span.card__cat but 14px above the content it labels, inside li#related-1>a.card__link — a label reads as belonging to whatever it is CLOSEST to, so this one groups upward. Reduce the gap under it below 13px, or widen the gap above it. This reports the ambiguity, not which gap is correct.
  ! [proximity-inversion]: li#related-2>a.card__link>h3.card__title (h3) sits 6px below li#related-2>a.card__link>span.card__cat but 14px above the content it labels, inside li#related-2>a.card__link — a label reads as belonging to whatever it is CLOSEST to, so this one groups upward. Reduce the gap under it below 13px, or widen the gap above it. This reports the ambiguity, not which gap is correct.
  ! [proximity-inversion]: li#related-3>a.card__link>h3.card__title (h3) sits 6px below li#related-3>a.card__link>span.card__cat but 14px above the content it labels, inside li#related-3>a.card__link — a label reads as belonging to whatever it is CLOSEST to, so this one groups upward. Reduce the gap under it below 13px, or widen the gap above it. This reports the ambiguity, not which gap is correct.
D23 defect h3#shop-info-title

check composition proximity-inversion: the shop name sits 4px under its 店舗情報 kicker but 16px above the list it labels, so it groups upward.

D24 defect li#related-1..3 > a.card__link > h3.card__title

check composition proximity-inversion x3: each card title sits 6px under its category label but 14px above its date, so title and date read as two groups.

G5exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f6f2ea · bodyInk #1d2733 · linkInk #a4462b · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

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

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

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  3 distinct
    #f6f2ea   87.9%     1 el  
    #ede6d8    8.2%     2 el  aside#shop-info
    #1d2733    3.9%     4 el  a.skip
  ink       6 distinct
    #1d2733   80.5%    53 el  div.brand>a.wordmark>span.wordmark__text
    #4a5360   11.9%    25 el  div.story-head__text>p.kicker>span.series
    #e8e3d9    2.1%     5 el  div.wrap>div.site-footer__brand>p.site-footer__mark
    #5b636e    2.0%     7 el  div.wrap>div.brand>p.tagline
    #a4462b    1.8%    16 el  ul>li>a
    …and 1 more
  marks     3 distinct
    #d8d0c0   71.0%    11 el  header#top
    #1d2733   27.5%    14 el  button#search-toggle
    #a4462b    1.6%     5 el  ul>li>a
  base #f6f2ea, body ink #1d2733, link ink #a4462b on 9 element(s)
G6exit 0vlmkit check a11y contrast index.html

inspected 122 · failures 0

output, 5 line(s), 1.7s
  vlmkit check a11y contrast
  html: examples/sites/magazine/index.html
  inspected 122 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/magazine/test-results/a11y-contrast/index-861ad078/report.md
G7exit 1vlmkit check a11y focus index.html

steps 26 · findings 4

output, 9 line(s), 1.9s
  vlmkit check a11y focus
  source: index.html
  captured 26 focus step(s)
  ✗ 4 finding(s)
    [skip-row] Focus jumped down by 617px (from `header#top>div.wrap.masthead__inner>button#search-toggle` to `header.story-head.wrap>div.story-head__text>p.meta>span.meta__item>a`). Confirm no focusable element was unintentionally skipped.
    [reverse] Focus moved left within the same row (from `div#story-body>section.chapter>p>sup.fnref>a#ref-2` at x=927 to `div.interview>p.turn>span.utterance>sup.fnref>a#ref-3` at x=395). Visual order is L-to-R; check `tabindex` or DOM order.
    [reverse] Focus moved up by 424px (from `main#main>section.after>div.share>button#save` at y=612 to `section.related>div.wrap>ul.related__list>li#related-1>a.card__link` at y=188). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [skip-row] Focus jumped down by 351px (from `section.related>div.wrap>ul.related__list>li#related-3>a.card__link` to `div.wrap.site-footer__inner>nav.site-footer__nav>ul>li>a`). Confirm no focusable element was unintentionally skipped.
  report: examples/sites/magazine/test-results/a11y-focus-order/index-861ad078/report.md
G8exit 0vlmkit check a11y touch index.html

level AA · inspected 26 · failures 0 · wcagExempt 11

output, 6 line(s), 1.6s
  vlmkit check a11y touch
  source: index.html  level: WCAG AA (24×24 min)
  inspected 26 interactive element(s)
  ✓ 0 undersized target(s)
  11 undersized target(s) excused by WCAG 2.5.8 itself (9 in a sentence, 2 with clear spacing)
  report: examples/sites/magazine/test-results/a11y-touch/index-861ad078/report.md
G9exit 0vlmkit scan scroll index.html

containers 0 · overflowX 0 · issues 0

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

status: ok
page: 1280x7370 — horizontal overflow 0px, vertical scroll 6650px
scroll containers: 0 (dead scrollports 0, clipped 0)

No scroll issues detected.
G10exit 0vlmkit scan handlers index.html

registrations 7 · elements 5 · suspects 0

output, 16 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: 7 across 5 element(s) + globals, on a page presenting 26 control(s)

  - header#top>div.wrap>button#search-toggle "検索": click
  - header#top>div#search-panel "サイト内検索 検索する 記事のタイトルとセクション名から探します。": keydown (no role)
  - header#top>div#search-panel>div.wrap>form#search-form "サイト内検索 検索する 記事のタイトルとセクション名から探します。": submit (no role)
  - main#main>section.after>div.share>button#copy-link "リンクをコピー": click
  - main#main>section.after>div.share>button#save "保存": click
  - globals: window:scroll, window:resize

Issues:
  warn [unprobed-handler-types] 3 handler type(s) registered and NONE exercised: click, 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.
G11exit 0vlmkit check interactions index.html --handlers

elements 26 · suspects 0 · warns 0

output, 49 line(s), 5.9s
vlmkit check interactions
source: index.html

status: ok
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
interactive elements: 26

  - [link] "本文へスキップ" focus✓
  - [link] "ほとり" focus✓
  - [link] "特集" focus✓
  - [link] "暮らし" focus✓
  - [link] "旅" focus✓
  - [link] "本" focus✓
  - [link] "インタビュー" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [link] "三浦 灯" focus✓
  - [link] "前回訪ねた岬の貸本屋" focus✓
  - [link] "注1" focus✓
  - [link] "注2" focus✓
  - [link] "注3" focus✓
  - [link] "記事の終わりの店舗情報" focus✓
  - [link] "本文へ戻る" focus✓
  - [link] "本文へ戻る" focus✓
  - [link] "本文へ戻る" focus✓
  - [button] "リンクをコピー" focus✓ | Enter: layout change | announces
  - [button] "保存" focus✓ | Enter: pressed false -> true
  - [link] "本 連載 第2回 岬の貸本屋に、手紙で本を頼む 2026年8月8日" focus✓
  - [link] "旅 終点の駅から、灯台まで歩く 2026年7月25日" focus✓
  - [link] "暮らし 潮風と暮らす家の、窓のしつらえ 2026年6月30日" focus✓
  - [link] "ほとりについて" focus✓
  - [link] "執筆者" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "プライバシー" focus✓

vlmkit scan handlers
source: index.html

status: 1 warn(s)
registrations: 7 across 5 element(s) + globals, on a page presenting 26 control(s)

  - header#top>div.wrap>button#search-toggle "検索": click
  - header#top>div#search-panel "サイト内検索 検索する 記事のタイトルとセクション名から探します。": keydown (no role)
  - header#top>div#search-panel>div.wrap>form#search-form "サイト内検索 検索する 記事のタイトルとセクション名から探します。": submit (no role)
  - main#main>section.after>div.share>button#copy-link "リンクをコピー": click
  - main#main>section.after>div.share>button#save "保存": click
  - globals: window:scroll, window:resize

Issues:
  warn [unprobed-handler-types] Handler types registered but NOT exercised by this run's probes: keydown, submit — the probe focuses a control and presses the key its role activates with, so a `click` handler on anything but a native control, and any type outside focus/blur/keyboard, is untested here. Verify those paths with a 'verify flow' script.
G12exit 0vlmkit check scroll index.html

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.progress: fixed top=0px viewport y 0 -> 0

No scroll-behavior issues detected.
G13exit 0vlmkit check motion index.html

activeAnimations 0 · running 0 · issues 0

output, 15 line(s), 1.3s
vlmkit check motion
source: index.html

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

Motion samples:
  - #progress-bar: animation=none 0s running; transition=transform 0.12s

No motion issues detected.
G14exit 0vlmkit check animation index.html

animations 0 · settleMs 0 · issues 0

output, 8 line(s), 1.5s
vlmkit check animation
source: index.html (1280x720)

status: ok
animations: 0 (evaluated 0, infinite 0)
settle: 0ms

No animation issues detected.
G15exit 0vlmkit stress i18n index.html

inflate 1.4 · inspected 152 · overflowing 37

output, 12 line(s), 1.6s
  vlmkit stress i18n
  html: examples/sites/magazine/index.html  inflate: 1.4x
  ! 37 overflow / wrap issue(s) across 152 inspected element(s)
    [vertical-wrap] main#main>article#story>header.story-head.wrap>div.story-head__text>h1#story-title — h 122 → 244
    [vertical-wrap] article#story>header.story-head.wrap>div.story-head__text>h1#story-title>span — h 61 → 122
    [vertical-wrap] article#story>header.story-head.wrap>div.story-head__text>h1#story-title>span — h 61 → 122
    [vertical-wrap] main#main>article#story>header.story-head.wrap>div.story-head__text>p.lede — h 167 → 199
    [vertical-wrap] article#story>div#story-body>section.chapter>figure.pullquote>blockquote — h 91 → 137
    [vertical-wrap] main#main>article#story>div#story-body>section.chapter>figure.pullquote — h 192 → 238
    … 31 more (see the report, or --json for all)
  report: examples/sites/magazine/test-results/i18n-stress/report.md
  exits 0 — 37 warn(s) did not fail this command. To gate on one: --rule vertical-wrap=suspect
D25 defect .turn (speaker column), .note (number column)

stress i18n: the interview speaker labels (汐田X) and the note numbers (注1X) wrap to two lines under inflation, because both sit in fixed 3.2em / 3em grid columns. A three- or four-character speaker name, or a 注10, would break the same way. The prose rows are ordinary wrapping.

G16exit 0vlmkit check breakpoints index.html --sweep

breakpoints 4 · issues 0 · sweepRanges 0

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

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 699, 700, 999, 1000px (each at B-1 / B / B+1)

  699px: clean (max-width: 699px)
  700px: clean (min-width: 700px)
  999px: clean (max-width: 999px)
  1000px: clean (min-width: 1000px)

All boundaries consistent.
S3

hero art close-up

index.html · 1280×800 · element .art · @2x

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

L3 saw

Hero illustration at 2x (1240px). Reads well overall: star field, two hill layers with tiny house lights, the lit two-storey shop with the 宵待書房 fascia and a lamp glow above it, three shelf rows of books, a customer silhouette in the second glass panel, the 古本 hanging board, the 日の入 17:58 chalkboard, the 100-yen crate, a bicycle, a street lamp, the lighthouse with its beam on the breakwater, and warm reflections on the harbour. Defects: (1) the bright white sliver at the left end of the quay (x≈240-248, y≈980-1030 in this 2x frame) is the page's paper showing through: nothing is painted between the quay's slanted left edge and the water, and the sky rect ends at y=480. (2) The three bare bulbs are drawn exactly under the door mullions (x 256, 321, 386), so the bulbs themselves are hidden and only their glows show; the middle glow sits about 4px higher than the other two, which is the circle check integrity G1 flagged as near-misaligned. The middle bulb was meant to hang on a shorter cord, but at 4px it looks accidental, not designed. (3) A small dark dome (a bollard) sits in the middle of the light spill in front of the door and reads as a stray blob. (4) The quay's front face shows as an outlined box: a light hairline runs along its bottom edge against the water.

D13 defect .art__svg (quay, left end)

S3: the white sliver at the quay's left end is the page's paper showing through: nothing is painted between the quay's slanted left edge and the water, and the sky rect stops at y=480.

D14 defect .art__svg (storefront bulbs)

S3: the three bare bulbs are drawn exactly under the door mullions (x 256/321/386), so the bulbs themselves are hidden and only their glows show.

D16 defect .art__svg (light spill)

S3: a small dark bollard dome sits in the middle of the lit spill in front of the door and reads as a stray blob.

D17 defect .art__svg (quay face)

S3: the quay's front face shows as an outlined box: a light hairline runs along its bottom edge where it meets the water.

S4

copy link pressed

index.html · 1280×800 · click #copy-link · wait 300

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

After clicking リンクをコピー (desktop viewport, scrolled to the share row). The confirmation is there and legible: an accent check mark followed by bold ink text 「リンクをコピーしました」, sitting on the same row to the right of the 保存 pill, so the row does not grow or shift at this width. The clicked button shows its light hover fill (the pointer is still over it) and no focus ring, which is right for a mouse click. The progress bar across the top is full, since the article ends above this point. Notes 注1-3 are above with their 本文へ戻る links; the author card and the start of the related band are below. Nothing looks broken in this state. So the copy the gate called missing (G2) is rendered and visible once the action happens.

S5

body paragraph close-up

index.html · 1280×800 · element #story-body > section:first-child > p:nth-of-type(2) · @2x

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

2x close-up of section 1, paragraph 2 (body text, set in the serif stack). Justified at 1.9 leading; the accent link 前回訪ねた岬の貸本屋 has an underline that clears the glyphs. But the body face is visibly a different Gothic from the headings in S6: the kana here are wider and rounder (compare が, と, る, and the heavier ず/ぎ dakuten). None of the fonts named in the serif stack exist on this machine, so the text falls through to the generic serif, and fc-match serif:lang=ja resolves that to WenQuanYi Zen Hei, a Chinese font. The page therefore mixes two Gothic designs (IPAGothic headings over WenQuanYi body), and the body kanji come from a Chinese font rather than a Japanese one. No clipping and no collisions in the paragraph.

D18 defect font stack (--serif)

S5 vs S6: the body text is in a different Gothic from the headings. No font named in the serif stack exists here, so the generic serif resolves (fc-match serif:lang=ja) to WenQuanYi Zen Hei, a Chinese font: the page mixes two Gothic designs, and the body gets Chinese glyph forms.

S6

h2 close-up

index.html · 1280×800 · element #ch1 · @2x

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

2x close-up of the first h2, 日が沈むと、シャッターが上がる. The 36px accent rule sits 20px above the heading; the heading is IPAGothic (the sans stack names it) with synthetic bold, tracked at .06em. Glyphs are crisp and the ideographic comma sits correctly in the lower left of its cell. At desktop width the heading is one line. The only fault in this frame is by comparison with S5: the body text below it is not in this typeface.

N2false-positiveabout G2

copy-missing 'リンクをコピーしました' is state copy: the brief makes it the confirmation that appears in a live region after リンクをコピー is pressed, so at rest the region is empty by design. A pre-filled region would announce nothing and would show a confirmation for an action nobody took. The gate's sweep reveals details, tabs and aria-expanded controls, and this is none of those. S4/L4 shows the line rendered, visible and verbatim after the click, and check interactions G11 records the button as 'announces'. I will also prove it deterministically with a verify flow post-condition.

N3false-positiveabout G7

All four focus-order findings are artifacts of comparing viewport coordinates across scrolls. The report's own table records each stop's position after the browser scrolled it into view: steps 9-16 run from section 1 to the notes, about 4,000px of page, yet all sit between y=350 and 505. reverse 11->12 (注2 x=927 -> 注3 x=395, 'same row') are 1,700px apart in the document; reverse 18->19 (#save y=612 -> #related-1 y=188, 'moved up') goes DOWN the page: S1-8/S1-9 show the share row above the related band. skip-row 7->8 (検索 -> byline) and 21->22 (last card -> footer nav) skip nothing: S1-1 shows only the non-interactive title, lede and illustration between the first pair, and S1-10 only the band's padding between the second. The tab order is DOM order, and DOM order is the visual order.

N4toolabout G7

check a11y focus compares focus stops in viewport coordinates captured after each auto-scroll, so on any page taller than the viewport it reports 'reverse' (a suspect, exit 1) for forward moves. Verbatim: '[reverse] Focus moved up by 424px (from main#main>section.after>div.share>button#save at y=612 to section.related>div.wrap>ul.related__list>li#related-1>a.card__link at y=188)' and '[reverse] Focus moved left within the same row (from ...a#ref-2 at x=927 to ...a#ref-3 at x=395)', where the two footnote links are 1,700px apart in the document. Adding scrollY (document coordinates) to each captured position would remove both.

F1fix for D1

The lede is no longer justified: word-break: auto-phrase (phrase-level Japanese line breaking) and text-wrap: pretty, so lines break between phrases and a name stays whole.

F2fix for D2

The sans stack now names IPAPGothic (proportional Latin and digits) instead of IPAGothic; there is a comment in style.css saying why.

F3fix for D3

The shelf sunbeam is now a gradient polygon that fades from .26 to 0 across the shelf (f-shelfbeam), with no flat-opacity shape and no hard vertical edge.

F4fix for D4

The pull quote uses word-break: auto-phrase + text-wrap: balance, so it breaks between phrases into lines of even length.

F5fix for D5

Removed the <small> from the © line; it now renders at the footer's 12px like the note above it.

F6fix for D6

text-wrap: pretty on body paragraphs, interview utterances and the figure caption, so the browser rebalances the last lines instead of leaving one or two characters alone.

F7fix for D7

Below 700px the tagline is hidden, so the masthead is two rows: wordmark with 検索 on the right, then the section nav.

F8fix for D8

Below 700px the byline takes its own line and the date loses its leading separator, so the second line reads '2026年9月12日 | 読了時間 約8分' with the bar only between the two items.

F9fix for D9

Chapter h2s use word-break: auto-phrase + text-wrap: balance.

F10fix for D10

Replaced the back link's margin-left with a plain space in the markup ('。 <a class=backref>'), which collapses at the start of a line, so a wrapped 本文へ戻る now starts flush with the note text.

F11fix for D11

Below 700px the この記事を label takes its own line, both buttons share the next, and the confirmation wraps below them.

F12fix for D12

Below 700px each related card is a two-column grid (112px thumbnail, then category, title and date), and the band's padding and margin are reduced to the 64/40/56 steps.

F13fix for D13

The hero SVG now starts with a full 640x640 night rect under everything, and the quay's left edge is vertical at x=124, where the water begins, so no gap is left unpainted.

F14fix for D14

The bulbs now hang in the middle of the four glass panels (x 224/288/354/418), clear of the mullions, each with a small halo; the customer moved to the third panel.

F15fix for D15

All four bulbs hang at one height (cy 389, cords 374-385): I chose alignment over a 4px variation that only reads as a mistake.

F16fix for D16

Removed both bollards; the light spill in front of the door is clean.

F17fix for D17

The quay face now overlaps the water by 1px on the full-frame background, and the edge highlight is darker and 5px tall, so no light seam outlines the face.

F18fix for D18

The serif stack adds IPAPMincho, then IPAGothic as the last named face before the generic, so a device with no Japanese serif renders Japanese glyph forms in the same design as the headings instead of whatever the generic resolves to (a Chinese font here). There is a comment in style.css saying why.

F19fix for D19

The h1 is a single text node again; the two-line break comes from word-break: auto-phrase + text-wrap: balance instead of two inline-block spans.

F20fix for D20

注, the author's name and 関連する記事 share one secondary-head rule (20px/700, .08em); the four chapter heads keep 25px, so h2 has two styles, each used at least 3x.

F21fix for D21

The shop-info name is 17px like the card titles.

F22fix for D22

Masthead padding is 20px top and bottom, and the related band's margin-top is 96px (64px below 700px).

F23fix for D23

The shop-info name margin is now 6px above and 10px below, so it sits closer to the list it labels than the rule's threshold allows it to drift upward.

F24fix for D24

Card title margin is 6px 0 2px and the date is a block at 1.5 line-height, so the title is 2px from its date and about 12px from its label.

F25fix for D25

The interview and the notes are each one grid (minmax(3em, max-content) then 1fr) with subgrid rows, so the label column grows to the longest speaker name or note number and every row stays aligned; labels are white-space: nowrap. The notes' :target highlight now uses side box-shadows instead of padding and a negative margin.

F26fix for D26

A footnote reference that follows ruby gets .4em of left margin (ruby + .fnref); other references keep .12em.

R2 · fix pass

builder
G17exit 0vlmkit check integrity index.html

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

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

output, 9 line(s), 7.5s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 0 exempted)
  1280x800: 1 component(s), ink 93.8%, 106 text block(s)
  768x900: 1 component(s), ink 92.7%, 106 text block(s)
  375x700: 1 component(s), ink 92.9%, 105 text block(s)

No integrity defects detected.
G18exit 1vlmkit check copy index.html --manifest copy.txt

missing 1 · placeholders 0 · manifestLines 8 · statesExplored 1 · revealedOnly 0

output, 10 line(s), 1.5s
vlmkit check copy
source: index.html

status: suspect
rendered text: 3461 chars
disclosure states: 1 explored (details / tabs / aria-expanded)
manifest: 8 line(s), missing 1

Issues:
  x copy-missing: Manifest line not found in rendered text or any of 1 revealed disclosure state(s): "リンクをコピーしました" (comparison is whitespace-normalized, case-sensitive).
G19exit 0vlmkit check design index.html

verdict: COHERENT (1 finding(s))

verdict coherent · drifting 0 · roles 5

output, 23 line(s), 2.2s
vlmkit check design
source: index.html

verdict: COHERENT (1 finding(s))
  roles judged: 3 of 5 seen, spacing values: 23
  coverage: 17 of 697 visible element(s) carried an inferable role
    no role: rect x397, p x41, path x38, circle x36, g x27, a x23, +26 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.

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               4 inst    1 styles  reuse     4x  0 one-off  ok
  button           3 inst    1 styles  reuse     3x  0 one-off  ok
  img              2 inst    2 styles  reuse     1x  2 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: img (2), h1 (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).

Informational (true, but does not carry the verdict)
  i [scale-outlier]: 1 spacing value(s) sit just off the page's own scale: 18px (2x) next to 16px (13x) — header#top>div.wrap>div.brand rowGap. Snap them to the established value or add them deliberately.
D29 defect div.brand gap

check design scale-outlier (info): the brand block's 18px gap (wordmark to tagline) sits next to the 16px step used 13 times.

G20exit 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: 8 label(s), 3 heading level(s), 99 wide block(s) on 9 left / 6 right rail(s) — from 183 visible box(es)
  4 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     42px / 700   h1#story-title
  h2     25px / 700   h2#ch1
  h3     17px / 700   h3#shop-info-title
  body 14px, largest 42px (3x), heaviest +0 weight

Group gaps: 12.95px between heading-led groups vs 21.5px inside them (0.6x, 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.
G21exit 0vlmkit stress i18n index.html --json

inflate 1.4 · inspected 148 · overflowing 34

output, 1350 line(s), 1.6s
{
  "gate": "stress.i18n",
  "command": "stress i18n",
  "verdict": "pass",
  "counts": {
    "suspect": 0,
    "warn": 34,
    "info": 0
  },
  "findings": [
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 476px -> 476px (scroll 476px) — \"海辺の町の古本屋が、夜だけ店を開ける理由XXXXXXXX\"",
      "evidence": {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>h1#story-title",
        "tag": "h1",
        "before": {
          "width": 476,
          "height": 121.78125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 182.671875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 476px -> 476px (scroll 476px) — \"文・写真XX 三浦X 灯X\n          2026年9月12日XXXX\n          読了時間XX 約8分X\"",
      "evidence": {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.meta",
        "tag": "p",
        "before": {
          "width": 476,
          "height": 39.09375,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 67.1875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 476px -> 476px (scroll 476px) — \"港の灯りがひとつ、またひとつとともりはじめるころ、XXXXXXXXXX凪浦XなぎうらXXの商店街のはずれで、一軒の古本屋\"",
      "evidence": {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.lede",
        "tag": "p",
        "before": {
          "width": 476,
          "height": 165.703125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 198.84375,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>figure.pullquote>blockquote",
        "tag": "blockquote",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>figure.pullquote",
        "tag": "figure",
        "before": {
          "width": 694,
          "height": 192.09375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 237.59375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"三浦X 夜には、どんなお客さんが来るんですか。XXXXXXXX\n          汐田X いろいろですよ。夜勤に向かう\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>div.interview",
        "tag": "div",
        "before": {
          "width": 694,
          "height": 500.875,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 603.4375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 48px -> 48px (scroll 48px) — \"注1X\"",
      "evidence": {
        "path": "article#story>section#notes>ol.notes__list>li#note-1>span.note__num",
        "tag": "span",
        "before": {
          "width": 48,
          "height": 51.78125,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 77.671875,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 632px -> 632px (scroll 632px) — \"まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に開いてい\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 632px -> 632px (scroll 632px) — \"いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖にいるで\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"汐田X まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"汐田X いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"注1X黒板の日の入り時刻は、汐田さんが毎朝、新聞の暦の欄で確かめて書き直している。九月なかばの凪浦では、日の入りは一日に\"",
      "evidence": {
        "path": "main#main>article#story>section#notes>ol.notes__list>li#note-1",
        "tag": "li",
        "before": {
          "width": 694,
          "height": 71.78125,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 97.671875,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 48px -> 48px (scroll 48px) — \"汐田X\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 48px -> 48px (scroll 48px) — \"汐田X\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX\"",
      "evidence": {
        "path": "div#story-body>section.chapter>figure.pullquote>blockquote>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"零時ちょうど、汐田さんは電球をひとつずつ消していき、最後に入口の明かりを落とした。私は背の焼けていない詩集を一冊抱えて、\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"帰りぎわ、閉店をなぜ零時にしているのかを尋ねた。汐田さんは少し考えてから、「日付が変わるまでは、今日のうちでしょう」と言\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"店の外には、百円均一の文庫を並べた木箱がひとつ出ている。この箱だけは昼も夜も出しっぱなしで、代金は横に置いた缶に入れても\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"「夜の本屋は、灯台みたいなものだと思うの」と汐田さんは言う。「誰かが起きている明かりが、町にひとつあればいい。本を買わな\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 205.125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"十一時を過ぎると、客はさすがにまばらになる。汐田さんは帳場で値札を書きながら、ときどき顔を上げて通りのほうを見る。視線の\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜に売れる本には傾向がある、と汐田さんは言う。昼に比べて、詩集や随筆、古い旅行記がよく出る。反対に、実用書は昼の店ほどに\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"話しているあいだにも、客足は途切れなかった。作業着のまま文庫の棚の前にしゃがみこむ青年がいて、参考書の棚を行ったり来たり\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"ところが夜に店を開けてみると、昼には一度も見かけなかった客がやってくるようになった。最初の晩に来たのは、これから夜勤に向\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"そこで汐田さんは、昼のあいだはシャッターを下ろし、除湿機を回して本を休ませることにした。日の光が届かなくなってから店を開\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"見せてもらった文庫本は、表紙には深い緑が残っているのに、背だけが白茶けた砂の色になっていた。本を傷めるのは光だけではない\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"「うちは店が西を向いているでしょう。午後になると、海に照り返した光まで店の奥に入ってくるの。父の棚を片づけていたら、窓ぎ\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"汐田さんが店を夜だけ開けるようになったのは、十二年前に父親から店を継いでからだ。先代は朝十時に店を開けて夕方六時に閉める\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"店内は奥行きが深く、左右の壁と中央の平台に、ざっと一万冊の本が並ぶ。文庫と新書が半分、残りは詩集や郷土史、古い旅行記。港\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"十七時五十八分。岸壁に腰を下ろして待っていると、水平線に残っていた橙色が消え、背中のほうで、がらがらとシャッターの巻き上\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 205.125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"シャッターの脇には小さな黒板が掛かっていて、白いチョークで「本日の日の入りXXXXXXXXXXXXXXX 十七時五十八分\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"商店街がとぎれ、岸壁が見えてくる手前の角に、その店はある。宵待書房。間口二間ほどの木造二階建てで、昼間に通りかかった人に\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"九月のなかば、夕方の凪浦駅に降りた。駅前から海へまっすぐ延びる商店街は、五時を過ぎると半分ほどの店が戸を閉める。魚屋が店\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 638px -> 638px (scroll 638px) — \"黒板の日の入り時刻は、汐田さんが毎朝、新聞の暦の欄で確かめて書き直している。九月なかばの凪浦では、日の入りは一日に一分ほ\"",
      "evidence": {
        "path": "article#story>section#notes>ol.notes__list>li#note-1>p",
        "tag": "p",
        "before": {
          "width": 638,
          "height": 51.78125,
          "clientWidth": 638,
          "scrollWidth": 638
        },
        "after": {
          "width": 638,
          "height": 77.671875,
          "clientWidth": 638,
          "scrollWidth": 638
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 206px -> 694px (scroll 0px) — \"前回訪ねた岬の貸本屋XXXX\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>p>a",
        "tag": "a",
        "before": {
          "width": 205.921875,
          "height": 18,
          "clientWidth": 0,
          "scrollWidth": 0
        },
        "after": {
          "width": 694,
          "height": 52.1875,
          "clientWidth": 0,
          "scrollWidth": 0
        }
      }
    }
  ],
  "suppressed": [],
  "retuned": [],
  "report": {
    "html": "examples/sites/magazine/index.html",
    "inflateFactor": 1.4,
    "beforeScreenshot": "examples/sites/magazine/test-results/i18n-stress/before.png",
    "afterScreenshot": "examples/sites/magazine/test-results/i18n-stress/after.png",
    "overflowing": [
      {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>h1#story-title",
        "tag": "h1",
        "text": "海辺の町の古本屋が、夜だけ店を開ける理由XXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 476,
          "height": 121.78125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 182.671875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      },
      {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.meta",
        "tag": "p",
        "text": "文・写真XX 三浦X 灯X\n          2026年9月12日XXXX\n          読了時間XX 約8分X",
        "kind": "vertical-wrap",
        "before": {
          "width": 476,
          "height": 39.09375,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 67.1875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      },
      {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.lede",
        "tag": "p",
        "text": "港の灯りがひとつ、またひとつとともりはじめるころ、XXXXXXXXXX凪浦XなぎうらXXの商店街のはずれで、一軒の古本屋",
        "kind": "vertical-wrap",
        "before": {
          "width": 476,
          "height": 165.703125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 198.84375,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>figure.pullquote>blockquote",
        "tag": "blockquote",
        "text": "夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>figure.pullquote",
        "tag": "figure",
        "text": "夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 192.09375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 237.59375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>div.interview",
        "tag": "div",
        "text": "三浦X 夜には、どんなお客さんが来るんですか。XXXXXXXX\n          汐田X いろいろですよ。夜勤に向かう",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 500.875,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 603.4375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "article#story>section#notes>ol.notes__list>li#note-1>span.note__num",
        "tag": "span",
        "text": "注1X",
        "kind": "vertical-wrap",
        "before": {
          "width": 48,
          "height": 51.78125,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 77.671875,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "text": "まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に開いてい",
        "kind": "vertical-wrap",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "text": "いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖にいるで",
        "kind": "vertical-wrap",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "text": "汐田X まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "text": "汐田X いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>section#notes>ol.notes__list>li#note-1",
        "tag": "li",
        "text": "注1X黒板の日の入り時刻は、汐田さんが毎朝、新聞の暦の欄で確かめて書き直している。九月なかばの凪浦では、日の入りは一日に",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 71.78125,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 97.671875,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "text": "汐田X",
        "kind": "vertical-wrap",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "text": "汐田X",
        "kind": "vertical-wrap",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      },
      {
        "path": "div#story-body>section.chapter>figure.pullquote>blockquote>p",
        "tag": "p",
        "text": "夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "零時ちょうど、汐田さんは電球をひとつずつ消していき、最後に入口の明かりを落とした。私は背の焼けていない詩集を一冊抱えて、",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "帰りぎわ、閉店をなぜ零時にしているのかを尋ねた。汐田さんは少し考えてから、「日付が変わるまでは、今日のうちでしょう」と言",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "店の外には、百円均一の文庫を並べた木箱がひとつ出ている。この箱だけは昼も夜も出しっぱなしで、代金は横に置いた缶に入れても",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "「夜の本屋は、灯台みたいなものだと思うの」と汐田さんは言う。「誰かが起きている明かりが、町にひとつあればいい。本を買わな",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 205.125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "十一時を過ぎると、客はさすがにまばらになる。汐田さんは帳場で値札を書きながら、ときどき顔を上げて通りのほうを見る。視線の",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "夜に売れる本には傾向がある、と汐田さんは言う。昼に比べて、詩集や随筆、古い旅行記がよく出る。反対に、実用書は昼の店ほどに",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "話しているあいだにも、客足は途切れなかった。作業着のまま文庫の棚の前にしゃがみこむ青年がいて、参考書の棚を行ったり来たり",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "ところが夜に店を開けてみると、昼には一度も見かけなかった客がやってくるようになった。最初の晩に来たのは、これから夜勤に向",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "そこで汐田さんは、昼のあいだはシャッターを下ろし、除湿機を回して本を休ませることにした。日の光が届かなくなってから店を開",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "見せてもらった文庫本は、表紙には深い緑が残っているのに、背だけが白茶けた砂の色になっていた。本を傷めるのは光だけではない",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "「うちは店が西を向いているでしょう。午後になると、海に照り返した光まで店の奥に入ってくるの。父の棚を片づけていたら、窓ぎ",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "汐田さんが店を夜だけ開けるようになったのは、十二年前に父親から店を継いでからだ。先代は朝十時に店を開けて夕方六時に閉める",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "店内は奥行きが深く、左右の壁と中央の平台に、ざっと一万冊の本が並ぶ。文庫と新書が半分、残りは詩集や郷土史、古い旅行記。港",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "十七時五十八分。岸壁に腰を下ろして待っていると、水平線に残っていた橙色が消え、背中のほうで、がらがらとシャッターの巻き上",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 205.125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "シャッターの脇には小さな黒板が掛かっていて、白いチョークで「本日の日の入りXXXXXXXXXXXXXXX 十七時五十八分",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "商店街がとぎれ、岸壁が見えてくる手前の角に、その店はある。宵待書房。間口二間ほどの木造二階建てで、昼間に通りかかった人に",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "九月のなかば、夕方の凪浦駅に降りた。駅前から海へまっすぐ延びる商店街は、五時を過ぎると半分ほどの店が戸を閉める。魚屋が店",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "article#story>section#notes>ol.notes__list>li#note-1>p",
        "tag": "p",
        "text": "黒板の日の入り時刻は、汐田さんが毎朝、新聞の暦の欄で確かめて書き直している。九月なかばの凪浦では、日の入りは一日に一分ほ",
        "kind": "vertical-wrap",
        "before": {
          "width": 638,
          "height": 51.78125,
          "clientWidth": 638,
          "scrollWidth": 638
        },
        "after": {
          "width": 638,
          "height": 77.671875,
          "clientWidth": 638,
          "scrollWidth": 638
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>p>a",
        "tag": "a",
        "text": "前回訪ねた岬の貸本屋XXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 205.921875,
          "height": 18,
          "clientWidth": 0,
          "scrollWidth": 0
        },
        "after": {
          "width": 694,
          "height": 52.1875,
          "clientWidth": 0,
          "scrollWidth": 0
        }
      }
    ],
    "totalInspected": 148,
    "reportPath": "examples/sites/magazine/test-results/i18n-stress/report.md"
  }
}
G22exit 1vlmkit verify flow index.html --flow flow.json

verdict: FAILED (4/7 steps)

done false · passed 4 · total 7

output, 22 line(s), 1.8s
vlmkit verify flow
source: index.html

verdict: FAILED (4/7 steps)

✓ step 1: 検索 opens the search panel and moves focus into the field
    ✓ #search-toggle aria-expanded=true 
    ✓ #search-panel visible 
    ✓ #search-input focused 
✓ step 2: type a section name
    ✓ #search-input visible 
✓ step 3: Enter submits the form and lists the two 本 articles
    ✓ #search-status text~"「本」に一致する記事が2件あります。" 
    ✓ #search-results li count=2 
✓ step 4: Escape closes the panel and returns focus to the 検索 button
    ✓ #search-panel hidden 
    ✓ #search-toggle aria-expanded=false 
    ✓ #search-toggle focused 
✗ step 5: リンクをコピー shows the confirmation in the live region
    ✗ #share-status text~"リンクをコピーしました" (got: )
    ✗ #share-status visible (got: hidden/absent)
    ✓ #share-status role=status
G23exit 0vlmkit verify flow index.html --flow flow.json

verdict: DONE (8/8 steps)

done true · passed 8 · total 8

output, 27 line(s), 2.0s
vlmkit verify flow
source: index.html

verdict: DONE (8/8 steps)

✓ step 1: 検索 opens the search panel and moves focus into the field
    ✓ #search-toggle aria-expanded=true 
    ✓ #search-panel visible 
    ✓ #search-input focused 
✓ step 2: type a section name
    ✓ #search-input visible 
✓ step 3: Enter submits the form and lists the two 本 articles
    ✓ #search-status text~"「本」に一致する記事が2件あります。" 
    ✓ #search-results li count=2 
✓ step 4: Escape closes the panel and returns focus to the 検索 button
    ✓ #search-panel hidden 
    ✓ #search-toggle aria-expanded=false 
    ✓ #search-toggle focused 
✓ step 5: リンクをコピー is pressed; the live region exists before anything is written to it
    ✓ #share-status role=status 
✓ step 6: within 100ms (the clipboard promise has settled) the confirmation is shown
    ✓ #share-status text~"リンクをコピーしました" 
    ✓ #share-status visible 
✓ step 7: 保存 toggles on
    ✓ #save aria-pressed=true 
✓ step 8: 保存 toggles off again
    ✓ #save aria-pressed=false
N5supersededabout G22

G22's step 5 asserted the confirmation in the same instant as the click, but the page writes it only after navigator.clipboard.writeText() settles (resolved, or rejected and then copied through the execCommand fallback); claiming コピーしました before the copy happened would be wrong. G23 splits the step: click (the live region already exists, role=status), then wait 100ms, then assert. It passes, so the confirmation lands within 100ms. The page did not change between G22 and G23; only the flow did.

N6decisionabout G2

G23 (verify flow, steps 5-6) is the deterministic proof for the one manifest line check copy cannot reach: after リンクをコピー, #share-status contains リンクをコピーしました and is visible. With S4/L4 as the visual evidence, the line is covered both ways.

N7acceptedabout G10

scan handlers is an inventory, and its unprobed-handler-types warn says so. The click handlers are exercised by check interactions --handlers (G11: 検索 expanded false->true, リンクをコピー announces, 保存 pressed false->true); the search panel's keydown (Escape) and the form's submit, the two types G11 could not reach, are exercised by verify flow G23 steps 3-4.

N8acceptedabout G11

unprobed-handler-types (keydown, submit) is closed by verify flow G23: step 3 submits the search form with Enter and gets the result status plus 2 results; step 4 presses Escape inside the panel and gets the panel hidden, aria-expanded=false and focus back on 検索.

S7

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

S7 screen 1S7 screen 2S7 screen 3S7 screen 4S7 screen 5S7 screen 6S7 screen 7S7 screen 8S7 screen 9S7 screen 10
L7 saw

Desktop 1280, full page after the fix pass, 10 screens. S7-1: title breaks after 、 as before, now from auto-phrase + balance on a single text node. The lede is ragged-right and breaks between phrases: …ともりはじめるころ、凪浦の / 商店街のはずれで、… / 店主の汐田律子さんをたずねた。, so the name is whole. Meta digits are proportional now (2026 年 9 月 12 日 no longer typewritten). New problem: every sans run is now IPAPGothic, whose 、。() are half-width, so headings and UI text look cramped at the punctuation: 日が沈むと、シャッター (S7-2), 西日から、本の (S7-3), 零時に、明かり (S7-6), 宵待書房(よいまち… and 水曜日、海が (S7-7/S7-8), the notes and the author bio read dense, and the card titles 貸本屋に、手紙 (S7-9). S7-3: section 2's first paragraph still ends on a lone 「た。」: text-wrap: pretty changed nothing there. S7-4: the shelf sunbeam now fades out across the shelf with no hard edge; the caption reads cleanly. S7-5: interview rows are aligned on one speaker column (labels one line each), and 漁火 注3 now has clear air between the ruby and the reference. S7-6: pull quote breaks between phrases (…思うの。誰かが / 起きている明かりが、…). S7-8: the share row, notes and author card are intact; the author name is now the same 20px secondary head as 注 and 関連する記事. S7-9/S7-10: card title sits 2px over its date with a larger gap to its label; the © line is 12px and readable.

D27 defect font stack (--sans)

Regression from F2: IPAPGothic sets 、。() half-width, so every sans run looks cramped at its punctuation: 日が沈むと、シャッター, 西日から、本の, 零時に、明かり (S7-2/3/6), 宵待書房(よいまち and 水曜日、海が (S7-7/8), and the notes and bio read dense. S10 shows the heading's comma next to the full-width commas of the body.

S8

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

S8 screen 1S8 screen 2S8 screen 3S8 screen 4S8 screen 5S8 screen 6S8 screen 7S8 screen 8S8 screen 9S8 screen 10S8 screen 11
L8 saw

Mobile 375, full page after the fix pass, 11 screens (was 13). S8-1: the masthead is two rows: wave + ほとり with the 検索 pill top-right, then the nav; the tagline is gone at this width. Title is two clean lines, and the lede breaks between phrases (one imperfect split: ともりは / じめるころ). S8-2: meta is 文・写真 三浦 灯 on line 1 and 2026年9月12日 | 読了時間 約8分 on line 2, with no leading bar. The first h2 now fits one line, but only because IPAPGothic is narrower; it has not been tested wrapping. Body paragraphs still end on short lines: いく。 (S8-2), いる。 (S8-4), いた。 (S8-5, the interview intro), so D6 is not fixed. S8-6: interview column aligned; 漁火 注3 separated. S8-7: the pull quote sets as four phrase lines (夜の本屋は、灯台みたいな / ものだと思うの。誰かが / 起きている明かりが、 / 町にひとつあればいい。) with no lone い。. S8-10: every 本文へ戻る follows its note text on the same line with an ordinary space and no indent; the share row is この記事を on its own line, then リンクをコピー and 保存 side by side. S8-11: related is now a compact list (112px thumbnails, label, title, date), about 330px instead of 1,100px, but two titles wrap with widows: 岬の貸本屋に、手紙で本を頼 / む and 潮風と暮らす家の、窓のしつ / らえ. Footer © readable.

D28 defect h3.card__title (mobile)

S8-11: in the compact related list, two card titles wrap with widows: 岬の貸本屋に、手紙で本を頼 / む and 潮風と暮らす家の、窓のしつ / らえ. The h3s never got the phrase-level wrapping the h1/h2 got.

S9

hero art close-up, after fixes

index.html · 1280×800 · element .art · @2x

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

Hero illustration at 2x after the art fixes. The quay's left end is now a clean vertical edge against the dark water, and nowhere does the page's paper show through (the full-frame night rect sits under everything). Four bare bulbs hang in the centres of the four glass panels, all at one height on equal cords, each with a small halo, and none is behind a mullion; the customer silhouette now stands in the third panel under a bulb. The light spill in front of the door is clean (no bollard blob). The quay face reads as a dark band under a soft edge highlight, and there is no light seam along its bottom edge. The lighthouse, fascia, chalkboard, crate, bicycle and street lamp are unchanged and read well. I see nothing wrong in this frame.

S10

section 1 close-up, heading + body

index.html · 1280×800 · element #story-body > section:first-child · @2x

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

Section 1 at 2x: the first h2 and four paragraphs. The body text is now in the same Japanese design as the heading (IPAGothic via the serif stack's last named face): the kana match the heading's shapes, and the punctuation is full-width, so なかば、夕方 and 手前の角に、その have a comfortable cell after each 、. The accent link underline and the 注1 superscript are crisp. The heading directly above is IPAPGothic and shows the problem next to that body text: 日が沈むと、シャッター has a half-width comma that nearly touches シ, noticeably tighter than every comma in the paragraphs below. Paragraph 1 ends on a 13-character line here, which is fine.

V1verified D1 by L7

S7-1: the lede breaks between phrases and ends 店主の汐田律子さんをたずねた。 with the name whole.

V2verified D3 by L7

S7-4: the sunbeam fades across the shelf; no hard vertical edge.

V3verified D4 by L8

S8-7 (mobile): four phrase lines with no lone い。; S7-6 (desktop): …誰かが / 起きている… with no break inside a word.

V4verified D5 by L7

S7-10: the © line renders at 12px and reads cleanly.

V5verified D7 by L8

S8-1: two-row masthead, 検索 top-right beside the wordmark.

V6verified D8 by L8

S8-2: byline alone on line 1; '2026年9月12日 | 読了時間 約8分' on line 2 with no leading bar.

V7verified D10 by L8

S8-10: every 本文へ戻る follows its note text after an ordinary space, with no indent anywhere; a space cannot indent a wrapped line, because it collapses at line start.

V8verified D11 by L8

S8-10: この記事を on its own line, both buttons side by side on the next.

V9verified D12 by L8

S8-11: related is a compact thumbnail list of about 330px instead of 1,100px of stacked images (the title widows it exposed are a separate defect).

V10verified D13 by L9

S9: the quay's left end is a clean vertical edge; no paper shows through.

V11verified D14 by L9

S9: four bulbs visible in the panel centres, clear of the mullions.

V12verified D15 by G17

check integrity is CLEAN at 1280/768/375: no near-misalignment; S9 shows the four bulbs on one line.

V13verified D16 by L9

S9: the light spill in front of the door is clean.

V14verified D17 by L9

S9: the quay face shows no light seam along its bottom edge.

V15verified D18 by L10

S10: the body kana and punctuation now match the heading's Japanese design; no Chinese fallback.

V16verified D19 by G18

check copy no longer reports the title: 7 of 8 manifest lines are found visibly, and only the state-only confirmation line remains (see N2, N6).

V17verified D20 by G19

check design: h2 7 instances, 2 styles, 3.5x reuse, ok.

V18verified D21 by G19

check design: h3 4 instances, 1 style, 4x reuse, ok.

V19verified D22 by G19

22px and 88px are gone from the scale-outlier list; the one remaining info (the brand gap, 18px) is new and raised separately.

V20verified D23 by G20

check composition: COMPOSED, 0 findings; the shop-info heading is no longer reported.

V21verified D24 by G20

check composition: COMPOSED, 0 findings; none of the three card titles is reported.

V22verified D26 by L7

S7-5: 漁火 注3 now has clear air between the ruby and the reference (also S8-6 on mobile).

N9decisionabout D25

Correction to D25's premise: the labels never wrapped. G15 already listed b.speaker at 51x103 and span.note__num at 42x52 before any inflation. Those are grid items stretched to their row (the utterance or note beside them runs 2-4 lines), and the rule counts a taller box as a gained line. G21, after the fix, still lists 汐田X and 注1X at 48px for the same reason. I keep the fix because the old fixed 3.2em/3em columns really would wrap a four-character name or 注10, and the subgrid makes one column for all rows, but it did not change, and could not change, what G21 reports.

N10false-positiveabout G21

Two kinds of vertical-wrap row. (1) b.speaker (汐田X) and span.note__num (注1X), 48px wide: not wrapping. They are stretched grid cells whose height follows the text beside them (see the D25 correction), and they are white-space: nowrap. (2) The other 32 rows (title, lede, meta, pull quote, utterances, paragraphs, notes, the inline link) are prose gaining lines under 1.4x inflation, which is what prose should do. None of them overflows or leaves its parent: 0 horizontal-overflow and 0 extends-beyond-parent.

N11toolabout G21

stress i18n's vertical-wrap infers 'gained a line' from box height, so a grid or flex item stretched by a taller sibling reports as wrapping although its own text is one line. Verbatim: '[vertical-wrap] div#story-body>section.chapter>div.interview>p.turn>b.speaker — 汐田X 51x103 → 51x137 +34px' (G15), where the label is one 13px line in a 103px cell. Comparing line count (height / line-height of the element's own text), or the text's client rects, instead of the box height would separate the two.

V23verified D25 by L7

S7-5 / S8-6: the interview is one grid, every utterance starts on the same column, and the labels are one line each (the column is minmax(3em, max-content)); the notes list keeps 注1-3 on one column too (S7-8).

N12supersededabout D6

F6 did not work: text-wrap: pretty changed none of the short last lines in Chromium. S7-3 still ends 営んでい / た。 at desktop, and S8-2/S8-4/S8-5 still end on いく。 / いる。 / いた。 at mobile, probably because Chromium's pretty looks only for a one-word orphan and a two-kana tail is not one. The second attempt is F-tail below: a fixed 4-character tail per paragraph in white-space: nowrap.

F27fix for D6

Second attempt (F6 did not work): the last four visible characters of each body paragraph, interview utterance and the figure caption are wrapped in <span class=tail> with white-space: nowrap (26 tails, made by a one-off script; a tail that would end inside an element takes the whole element, such as the 注1 <sup>). No paragraph can end on a line shorter than four characters; the line above absorbs at most three characters' worth of space as justification.

F28fix for D27

The sans stack goes back to IPAGothic for Japanese (full-width 、。()), with DejaVu Sans named just before it so Latin and digits resolve to a proportional face first; real devices still use Hiragino / Yu Gothic / Noto, which come earlier in the list.

F29fix for D28

A base rule gives h1, h2 and h3 word-break: auto-phrase + text-wrap: balance, which covers the card titles, the shop name and the secondary heads.

F30fix for D29

The brand gap is 16px.

R3 · type and wrapping

builder
S11

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

S11 screen 1S11 screen 2S11 screen 3S11 screen 4S11 screen 5S11 screen 6S11 screen 7S11 screen 8S11 screen 9S11 screen 10
L11 saw

Desktop 1280, full page after the type pass, 10 screens. Punctuation is full-width again everywhere (IPAGothic for Japanese): the tagline's 届く、暮らし (S11-1), 日が沈むと、シャッター (S11-2), 西日から、本の (S11-3), 零時に、明かり (S11-6), 宵待書房(よいまちしょぼう) and 水曜日、海が (S11-8) all have a comfortable cell after each mark, and the notes and bio no longer read dense. Digits and Latin are proportional (DejaVu Sans): 2026 年 9 月 12 日 in the meta, the card dates, and 'vlmkit' in the footer (S11-10). Paragraph ends: section 2 paragraph 1 now ends on 「んでいた。」 instead of a lone 「た。」 (S11-3), and 「だと思う。」 (S11-7). I found no line in the ten screens that ends on fewer than four characters, and the lines above those tails do not look stretched at this measure. Pull quote, interview, notes, share row, author card, related cards and footer are as in S7, with no regressions.

S12

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

S12 screen 1S12 screen 2S12 screen 3S12 screen 4S12 screen 5S12 screen 6S12 screen 7S12 screen 8
L12 saw

Tablet 768, full page, 8 screens (first tablet look). S12-1 is broken: the one-row desktop masthead does not fit in 688px, so the flex items shrink until their text wraps a character at a time: the wordmark reads ほと / り, the tagline takes two lines, the nav items stack vertically (特 / 集, 暮 / ら / し, インタ / ビュー), and the 検索 pill becomes a tall capsule with 検 / 索 stacked. The masthead is about 130px of wreckage above an otherwise sound page. Nothing overflows, which may be why no gate reported it (check integrity at 768 was CLEAN, and so was the breakpoint sweep). The rest of the tablet layout works: a centred 640px illustration, the title in two lines, a three-line lede, and the meta on one line (S12-2); body at 18px on the 688px measure (S12-2 to S12-6); the figure at full column width (S12-3); pull quote and notes (S12-5/S12-7); three related columns whose titles break as balanced phrases, 岬の貸本屋に、 / 手紙で本を頼む (S12-8). In S12-2 the lede's first line seemed to end 一軒 without its の; S14 checks that.

D30 defect .masthead__inner (700-999px)

S12-1 / S15: at tablet width the one-row desktop masthead does not fit in 688px, and the flex items shrink until their text wraps a character at a time: ほと / り, 特 / 集, 暮 / ら / し, インタ / ビュー, and a tall 検 / 索 pill. No gate reported it: check integrity at 768 was CLEAN (G17) and the breakpoint sweep was clean (G16), because nothing overflows or overlaps.

S13

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

S13 screen 1S13 screen 2S13 screen 3S13 screen 4S13 screen 5S13 screen 6S13 screen 7S13 screen 8S13 screen 9S13 screen 10S13 screen 11S13 screen 12
L13 saw

Mobile 375, full page after the type pass, 12 screens. Masthead two rows as fixed. The first h2 now wraps as a balanced phrase pair, 日が沈むと、 / シャッターが上がる (S13-2), where before it had a lone る. Paragraph ends are all four characters or more: いていく。 (S13-2), 時を刻んでいる。 (S13-3), している。 (S13-4), を聞いた。 (S13-5). The cost is visible in a few lines above a tail, which are justified a little loosely: the interview intro 客の途切れた合間に、店の奥の帳場で話 (S13-5) and the first utterance line 夜には、どんなお客さんが来る (S13-6). It is mild, and better than an orphan. One new flaw: the figure caption's last line begins with a small kana, っている。 (S13-5); the caption has no strict line breaking, unlike the body. Notes: 注2's 本文へ戻る wraps onto its own line and starts flush with the note text (S13-10). Related list: all three titles break as phrases on two lines, 岬の貸本屋に、 / 手紙で本を頼む, 終点の駅から、 / 灯台まで歩く, 潮風と暮らす家の、 / 窓のしつらえ (S13-11). Digits proportional, © readable.

D31 defect .figure figcaption

S13-5: the figure caption's last line begins with a small kana (っている。), which strict Japanese line breaking forbids; the caption never got the line-break: strict the body paragraphs have.

S14

tablet lede close-up

index.html · 768×1024 · element .lede · @2x

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

Tablet lede at 2x: three lines, ragged right at phrase boundaries. Line 1 ends 「…商店街のはずれで、一軒の」, so the の is present and my reading of S12-2 was a misread of the small screenshot, not a clipped glyph. Line 2 「古本屋がシャッターを上げる。開店は日の入り、閉店は午前零時。昼のあいだは一度も」, line 3 「開かない店に、夜ごと人が集まってくるのはなぜなのか。店主の汐田律子さんをたずねた。」. The ruby なぎうら sits centred over 凪浦 without touching the line above. Nothing is clipped; no defect here.

S15

tablet masthead close-up

index.html · 768×1024 · element .masthead · @2x

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 masthead at 2x confirms S12-1: in one flex row at 768px the wordmark wraps as ほ と / り in two lines, the tagline breaks into two grey lines, and every nav item is squeezed to one or two characters wide, so 特集, 暮らし and インタビュー stack vertically (本 keeps its accent underline under a single glyph). The 検索 button is a tall pill with its two characters stacked beside the magnifier. There is no overflow and no overlap, only per-character wrapping, and it looks broken to anyone who opens the page at tablet width.

V24verified D2 by L11

S11-1/S11-9/S11-10: digits and Latin proportional (DejaVu Sans) in the meta, the card dates and 'vlmkit'.

V25verified D27 by L11

S11: full-width 、。() in every heading, label, note and caption; nothing cramped.

V26verified D6 by L13

S13 (mobile, 12 screens) and S11-3/S11-7 (desktop): every paragraph ends on four characters or more; the lone た。 / いく。 / いる。 / いた。 lines are gone.

V27verified D9 by L13

S13-2: at 375 the first h2, now back in the wider IPAGothic, wraps as 日が沈むと、 / シャッターが上がる, a balanced phrase break with no lone character.

V28verified D28 by L13

S13-11: all three card titles wrap as balanced phrase pairs; S12-8 shows the same at tablet.

F31fix for D30

The tagline shows only at 1100px and up, where the one-row masthead has the ~910px it needs; from 700 to 999px the nav gap is 20px and the row gap 28px (about 590px needed, 620px available at 700). The wordmark, nav links and buttons are white-space: nowrap, so if a width is ever too narrow the row overflows, which the breakpoint sweep can catch, instead of silently wrapping a character at a time.

F32fix for D31

line-break: strict is set on body, so the caption, notes, bio and UI text get the same kinsoku as the body paragraphs.

S16

masthead at 700 / 768 / 1000 / 1100

index.html · 700×900 · element .masthead

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

Masthead at 700px, the narrowest width of the one-row layout: wave mark + ほとり on the left, the five nav items on one line with 20px gaps (本 in the accent with its underline), and the 検索 pill on the right, all on a single row with about 30px to spare. No tagline at this width, and nothing wraps or overlaps.

S17

masthead at 700 / 768 / 1000 / 1100

index.html · 768×1024 · element .masthead

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

L17 saw

Masthead at 768px (the width that was broken in S12-1/S15): one clean row. ほとり at full size in one line, 特集 暮らし 旅 本 インタビュー each on one line, and 検索 as a normal single-line pill with its magnifier. The per-character wrapping is gone, with comfortable space between the wordmark and the nav.

S18

masthead at 700 / 768 / 1000 / 1100

index.html · 1000×900 · element .masthead

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

L18 saw

Masthead at 1000px, the first desktop width: still no tagline (it needs 1100px), the nav back to 28px gaps, the pill on the right, and one row with plenty of room. The wordmark, nav baseline and pill are vertically centred on each other, and the 本 underline sits just under its glyph.

S19

masthead at 700 / 768 / 1000 / 1100

index.html · 1100×900 · element .masthead

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

Masthead at 1100px: the tagline 水辺から届く、暮らしと本のウェブマガジン returns in grey after the wordmark, on the same baseline row, with the full-width comma intact. The nav and the 検索 pill still fit on one row with about 100px free, so the 1100px threshold leaves a margin rather than landing exactly at the limit.

V29verified D30 by L17

S17: at 768 the masthead is one clean row; S16 (700), S18 (1000) and S19 (1100) show the edges of both new ranges holding.

S20

mobile caption close-up

index.html · 375×812 · element .figure figcaption · @2x

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

Mobile figure caption at 2x: three ragged lines, 窓ぎわの棚。先代のころに西日を浴びた文庫は、い / まも背の色が抜けたままだ。奥の棚の本は、色を / 保っている。. The last line now starts with 保, not the small っ: strict line breaking moved the break before 保っ, and the four-character tail keeps the end together. Grey caption ink on paper, 13px at 1.75 leading, with nothing clipped.

V30verified D31 by L20

S20: the caption's last line is 保っている。; no line starts with a small kana.

G24exit 0vlmkit check design index.html

verdict: COHERENT (0 finding(s))

verdict coherent · drifting 0 · roles 5

output, 22 line(s), 1.8s
vlmkit check design
source: index.html

verdict: COHERENT (0 finding(s))
  roles judged: 3 of 5 seen, spacing values: 22
  coverage: 17 of 723 visible element(s) carried an inferable role
    no role: rect x397, span x47, p x41, path x38, circle x36, g x27, +26 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.

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               4 inst    1 styles  reuse     4x  0 one-off  ok
  button           3 inst    1 styles  reuse     3x  0 one-off  ok
  img              2 inst    2 styles  reuse     1x  2 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: img (2), h1 (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).

No design drift detected.
G25exit 0vlmkit check breakpoints index.html --sweep

breakpoints 5 · issues 0 · sweepRanges 0

output, 14 line(s), 4.8s
vlmkit check breakpoints
source: index.html

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 699, 700, 999, 1000, 1099px (each at B-1 / B / B+1)

  699px: clean (max-width: 699px)
  700px: clean (min-width: 700px)
  999px: clean (max-width: 999px)
  1000px: clean (min-width: 1000px)
  1099px: clean (max-width: 1099px)

All boundaries consistent.
G26exit 0vlmkit check integrity index.html

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

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

output, 9 line(s), 7.7s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 0 exempted)
  1280x800: 1 component(s), ink 93.8%, 106 text block(s)
  768x900: 1 component(s), ink 92.7%, 105 text block(s)
  375x700: 1 component(s), ink 92.8%, 105 text block(s)

No integrity defects detected.
V31verified D29 by G24

check design: 'No design drift detected', with no scale-outlier info left.

N13toolabout G17

check integrity reported the tablet width clean while its masthead was broken. With the one-row masthead squeezed into 688px, every flex item shrank to its min-content and the text wrapped one or two glyphs per line (ほと / り, 暮 / ら / し, 検 / 索: S12-1, S15). G17 printed 'verdict: CLEAN (0 fail, 0 warn, 0 exempted)' and '768x900: 1 component(s), ink 92.7%, 106 text block(s)', and check breakpoints --sweep G16 printed 'width sweep: 320-1280px step 25 (39 widths) — clean'. Nothing overflowed, collided or clipped, so no rule applies; the defect is the text's shape. A rule comparing a text box's rendered width with its single-line (max-content) width, flagging short labels squeezed to one or two glyphs per line, would have caught it. Only my own tablet look (L12) found it.

R4 · interactions

builder
S21

search panel with results

index.html · 1280×800 · click #search-toggle · fill #search-input "本" · press Enter · wait 200

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, search open after typing 本 and pressing Enter. A darker paper band opens under the masthead and pushes the page down: bold label サイト内検索, the field with the query and a clear 2px ink focus ring, a 検索する pill, the grey hint, the status 「本」に一致する記事が2件あります。 and two underlined results with section and date. It reads as part of the page. Two flaws: the field's native search-cancel × is system blue, the only blue on the page, and it looks foreign in this palette; and the 検索 toggle in the masthead has no open state of its own. Its fill here is only the pointer's hover, so with the pointer elsewhere nothing would connect the button to the open panel.

D32 defect input#search-input::-webkit-search-cancel-button

S21: the search field's native cancel × renders in system blue, the only blue on the page.

D33 defect button#search-toggle[aria-expanded=true]

S21/S22: the 検索 toggle has no open state. The only fill in the shots is the pointer's hover, so once the pointer leaves, nothing ties the button to the open panel.

S22

search panel open, mobile

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

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

Mobile, search panel open. The band spans the width under the two-row masthead: label, an empty field with a visible focus ring (focus moved into it), the 検索する pill beside it, and the hint on one line below. Spacing is even and nothing wraps badly. The 検索 toggle again shows only the pointer's hover fill as its open state (the same issue as S21).

S23

after following 注2

index.html · 1280×800 · click #ref-2 · wait 200

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 clicking 注2 in section 2. The page jumped to the notes, and 注2 is highlighted with the warm tint running 12px past the column on both sides, so the target is obvious. The landing is tight: the note sits 32px under the top edge, and the last line of 注1 (…早くなっていく。 本文へ戻る) is sliced by the viewport edge above it, with the 注 heading out of view, so the reader lands mid-list with a cut line overhead. The share row, author card and related band follow below; the progress bar is full.

D34 defect [id^=note-], [id^=ref-] scroll-margin

S23/S24: both footnote jumps land the target 32px under the top edge, with a sliced line of the item above it (the end of 注1 over 注2; the first line of the quoted paragraph over the 注2 reference). The reader lands without context and has to scroll up to re-read the sentence.

S24

back from note 2

index.html · 1280×800 · click #ref-2 · click #note-2 .backref · wait 200

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, after 注2 and then that note's 本文へ戻る. The page is back in section 2 on the sentence with …背焼け注2していてね, and 注2 carries a faint tint as the returned-to target. The same tightness as S23: the reference's line is the second line on screen, and the paragraph's first line (「うちは店が西を向いているでしょう…) is sliced by the top edge. The reader has to scroll up to re-read the sentence they left. The figure and caption below are intact.

S25

保存 pressed, mobile

index.html · 375×812 · click #save · wait 200

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, after pressing 保存. The toggle is unmistakably on: the pill fills with the ink colour, the bookmark icon turns solid, and 保存 is paper-coloured, against the outlined リンクをコピー beside it. The label stays 保存, so the accessible name is constant while aria-pressed carries the state. The share row stays one line of buttons under この記事を; the notes above and the author card below are unchanged.

S26

first Tab: skip link

index.html · 1280×800 · press Tab · wait 150

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

Desktop, first Tab press. The skip link 本文へスキップ slides in at the top left as an ink pill with paper text and a 2px ink ring outside it. It sits over the wordmark (only り shows beside it), which is the usual skip-link placement and is fine because it disappears on the next Tab. Nothing else moves; the header and illustration are as in S11-1.

S27

focus ring on 注1

index.html · 1280×800 · element #story-body > section:first-child · focus #ref-1 · wait 150

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

Section 1 with keyboard focus on the 注1 reference. A clear rounded 2px ink ring surrounds the small accent superscript at the end of 「…ただひとつの決まりだ注1。」 and stays legible at that size without colliding with the line above. The rest of the section is unchanged, and the progress bar shows as a partial accent line at the top of the frame.

F33fix for D32

::-webkit-search-cancel-button is restyled: no native appearance, and a 14px × drawn with two ink-soft gradients.

F34fix for D33

While aria-expanded is true, 検索 takes the panel's paper-deep fill and its magnifier is swapped for a close mark (two icons in the button, toggled in CSS); the visible and accessible name stays 検索.

F35fix for D34

Footnote notes and references get scroll-margin-top: 25vh, so a jump lands with the preceding lines in view; the returned-to reference's tint is backed by a 3px tint ring, so it is easier to find.

S28

search open, pointer moved away

index.html · 1280×800 · click #search-toggle · fill #search-input "本" · press Enter · hover #story-title · wait 200

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

Desktop, search open with the 本 results and the pointer moved away onto the title. The masthead toggle now shows its open state on its own: the pill takes the panel's paper-deep fill and the magnifier is replaced by a thin ink ×, reading "× 検索" and visibly tied to the band below. The field's cancel mark is a thin ink-grey × drawn in CSS; the system blue is gone. The results and status are unchanged from S21.

S29

after following 注2 (25vh landing)

index.html · 1280×800 · click #ref-2 · wait 200

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

Desktop, after clicking 注2 with the 25vh landing. The whole notes block is in view: the ink rule, the 注 heading, 注1 in full, then the highlighted 注2 about a quarter of the way down with its tint band, then 注3. No line is sliced at the top edge, and the reader sees where they are in the list. The share row and author card sit below.

S30

back from note 2 (25vh landing)

index.html · 1280×800 · click #ref-2 · click #note-2 .backref · wait 200

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

Desktop, after 注2 and then 本文へ戻る. The paragraph containing the reference sits about a quarter of the way down, with the previous paragraph (汐田さんが店を夜だけ開けるように…) fully visible above it, so the sentence can be re-read without scrolling. The returned-to 注2 superscript has a tint with a 3px ring and is easy to spot at the end of …背焼け. The figure follows below.

V32verified D32 by L28

S28: the cancel mark is an ink-grey ×, not system blue.

V33verified D33 by L28

S28: with the pointer elsewhere, the open toggle shows its own state: paper-deep fill and a × icon.

V34verified D34 by L29

S29: 注2 lands at a quarter height with the 注 heading and 注1 above it; S30 does the same for the returned-to reference, whose paragraph and the one before it are fully in view.

G27exit 0vlmkit check animation 'file://$PWD/examples/sites/magazine/index.html#note-2'

animations 1 · settleMs 120 · issues 0

output, 12 line(s), 3.0s
vlmkit check animation
source: file://examples/sites/magazine/index.html#note-2 (1280x720)

status: ok
animations: 1 (evaluated 1, infinite 0)
settle: 120ms
reduced-motion: honored

Evaluated animations:
  - #progress-bar `transform` 120ms x1: visible, motion region (319,0) 961x3, peak frame delta 0.31%

No animation issues detected.
D35 defect #progress-bar (main.js is-ready)

check animation on index.html#note-2: '#progress-bar transform 120ms x1: visible, motion region (319,0) 961x3'. A page opened at a fragment animates the bar on load, sweeping it from about 25% to full width, because the easing is switched on one frame after the script runs and the browser's fragment scroll comes later. The README and the code comment both claim a page opened mid-article does not animate on load.

F36fix for D35

main.js: the easing class (is-ready) is added by the first wheel, touchstart, keydown or pointerdown (capture, passive, removed after firing), not one frame after load. A fragment or restored scroll made by the browser therefore jumps the bar straight to its place. The README now says this; the reduced-motion and ?animate=0 rules are unchanged.

G28exit 0vlmkit check animation 'file://$PWD/examples/sites/magazine/index.html#note-2'

animations 0 · settleMs 0 · issues 0

output, 8 line(s), 1.7s
vlmkit check animation
source: file://examples/sites/magazine/index.html#note-2 (1280x720)

status: ok
animations: 0 (evaluated 0, infinite 0)
settle: 0ms

No animation issues detected.
V35verified D35 by G28

check animation on index.html#note-2: 0 animations, settle 0ms. Opening mid-article no longer moves anything.

N14decisionabout G27

G27 is the only frame-sampled evidence for the brief's reduced-motion clause, and it stays valid after D35. When the bar's transform transition ran (120ms, 'visible'), the gate's reduced-motion pass reported 'reduced-motion: honored'. D35 changed when the easing is switched on (the first user input instead of the first frame), not the CSS that disables it under prefers-reduced-motion: reduce or ?animate=0. After D35 no gate can make the transition run, because none performs user input before sampling, so check motion's declaration check (reduced-motion rule: yes) is the standing evidence from here on.

R5 · final check

builder
G29exit 0vlmkit check integrity index.html

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

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

output, 9 line(s), 7.2s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 0 exempted)
  1280x800: 1 component(s), ink 93.8%, 106 text block(s)
  768x900: 1 component(s), ink 92.7%, 105 text block(s)
  375x700: 1 component(s), ink 92.8%, 105 text block(s)

No integrity defects detected.
G30exit 1vlmkit check copy index.html --manifest copy.txt

missing 1 · placeholders 0 · manifestLines 8 · statesExplored 1 · revealedOnly 0

output, 10 line(s), 1.4s
vlmkit check copy
source: index.html

status: suspect
rendered text: 3461 chars
disclosure states: 1 explored (details / tabs / aria-expanded)
manifest: 8 line(s), missing 1

Issues:
  x copy-missing: Manifest line not found in rendered text or any of 1 revealed disclosure state(s): "リンクをコピーしました" (comparison is whitespace-normalized, case-sensitive).
G31exit 0vlmkit check design index.html

verdict: COHERENT (0 finding(s))

verdict coherent · drifting 0 · roles 5

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

verdict: COHERENT (0 finding(s))
  roles judged: 3 of 5 seen, spacing values: 22
  coverage: 17 of 723 visible element(s) carried an inferable role
    no role: rect x397, span x47, p x41, path x38, circle x36, g x27, +26 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.

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               4 inst    1 styles  reuse     4x  0 one-off  ok
  button           3 inst    1 styles  reuse     3x  0 one-off  ok
  img              2 inst    2 styles  reuse     1x  2 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: img (2), h1 (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).

No design drift detected.
G32exit 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: 8 label(s), 3 heading level(s), 99 wide block(s) on 9 left / 6 right rail(s) — from 209 visible box(es)
  4 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     42px / 700   h1#story-title
  h2     25px / 700   h2#ch1
  h3     17px / 700   h3#shop-info-title
  body 18px, largest 42px (2.33x), heaviest +300 weight

Group gaps: 12.95px between heading-led groups vs 21.5px inside them (0.6x, 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.
G33exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f6f2ea · bodyInk #1d2733 · linkInk #a4462b · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

output, 24 line(s), 1.7s
vlmkit check color
source: index.html

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

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  3 distinct
    #f6f2ea   88.1%     1 el  
    #ede6d8    8.0%     2 el  aside#shop-info
    #1d2733    3.9%     4 el  a.skip
  ink       6 distinct
    #1d2733   79.5%    74 el  div.brand>a.wordmark>span.wordmark__text
    #4a5360   11.6%    28 el  div.story-head__text>p.kicker>span.series
    #5b636e    2.6%     8 el  div.wrap>div.brand>p.tagline
    #b9bfc8    2.5%     3 el  div.wrap>div.site-footer__brand>p.site-footer__tagline
    #e8e3d9    2.1%     5 el  div.wrap>div.site-footer__brand>p.site-footer__mark
    …and 1 more
  marks     3 distinct
    #d8d0c0   71.0%    11 el  header#top
    #1d2733   27.5%    14 el  button#search-toggle
    #a4462b    1.6%     5 el  ul>li>a
  base #f6f2ea, body ink #1d2733, link ink #a4462b on 9 element(s)
G34exit 0vlmkit check a11y contrast index.html

inspected 147 · failures 0

output, 5 line(s), 1.5s
  vlmkit check a11y contrast
  html: examples/sites/magazine/index.html
  inspected 147 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/magazine/test-results/a11y-contrast/index-861ad078/report.md
G35exit 1vlmkit check a11y focus index.html

steps 26 · findings 5

output, 10 line(s), 1.6s
  vlmkit check a11y focus
  source: index.html
  captured 26 focus step(s)
  ✗ 5 finding(s)
    [skip-row] Focus jumped down by 617px (from `header#top>div.wrap.masthead__inner>button#search-toggle` to `header.story-head.wrap>div.story-head__text>p.meta>span.meta__item>a`). Confirm no focusable element was unintentionally skipped.
    [reverse] Focus moved left within the same row (from `div#story-body>section.chapter>p>sup.fnref>a#ref-2` at x=925 to `div.interview>p.turn>span.utterance>sup.fnref>a#ref-3` at x=397). Visual order is L-to-R; check `tabindex` or DOM order.
    [reverse] Focus moved up by 93px (from `div.interview>p.turn>span.utterance>sup.fnref>a#ref-3` at y=443 to `article#story>div#story-body>section.chapter>p>a` at y=351). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [reverse] Focus moved up by 419px (from `main#main>section.after>div.share>button#save` at y=612 to `section.related>div.wrap>ul.related__list>li#related-1>a.card__link` at y=194). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [skip-row] Focus jumped down by 345px (from `section.related>div.wrap>ul.related__list>li#related-3>a.card__link` to `div.wrap.site-footer__inner>nav.site-footer__nav>ul>li>a`). Confirm no focusable element was unintentionally skipped.
  report: examples/sites/magazine/test-results/a11y-focus-order/index-861ad078/report.md
G36exit 0vlmkit check a11y touch index.html

level AA · inspected 26 · failures 0 · wcagExempt 11

output, 6 line(s), 1.6s
  vlmkit check a11y touch
  source: index.html  level: WCAG AA (24×24 min)
  inspected 26 interactive element(s)
  ✓ 0 undersized target(s)
  11 undersized target(s) excused by WCAG 2.5.8 itself (9 in a sentence, 2 with clear spacing)
  report: examples/sites/magazine/test-results/a11y-touch/index-861ad078/report.md
G37exit 0vlmkit scan scroll index.html

containers 0 · overflowX 0 · issues 0

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

status: ok
page: 1280x7364 — horizontal overflow 0px, vertical scroll 6644px
scroll containers: 0 (dead scrollports 0, clipped 0)

No scroll issues detected.
G38exit 0vlmkit scan scroll index.html --viewport 375x812

containers 0 · overflowX 0 · issues 0

output, 8 line(s), 1.4s
vlmkit scan scroll
source: index.html (375x812)

status: ok
page: 375x8980 — horizontal overflow 0px, vertical scroll 8168px
scroll containers: 0 (dead scrollports 0, clipped 0)

No scroll issues detected.
G39exit 0vlmkit scan handlers index.html

registrations 11 · elements 5 · suspects 0

output, 16 line(s), 1.8s
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: 11 across 5 element(s) + globals, on a page presenting 26 control(s)

  - header#top>div.wrap>button#search-toggle "検索": click
  - header#top>div#search-panel "サイト内検索 検索する 記事のタイトルとセクション名から探します。": keydown (no role)
  - header#top>div#search-panel>div.wrap>form#search-form "サイト内検索 検索する 記事のタイトルとセクション名から探します。": submit (no role)
  - main#main>section.after>div.share>button#copy-link "リンクをコピー": click
  - main#main>section.after>div.share>button#save "保存": click
  - globals: window:wheel, window:touchstart, window:keydown, window:pointerdown, window:scroll, window:resize

Issues:
  warn [unprobed-handler-types] 3 handler type(s) registered and NONE exercised: click, 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.
G40exit 0vlmkit check interactions index.html --handlers

elements 26 · suspects 0 · warns 0

output, 49 line(s), 5.7s
vlmkit check interactions
source: index.html

status: ok
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
interactive elements: 26

  - [link] "本文へスキップ" focus✓
  - [link] "ほとり" focus✓
  - [link] "特集" focus✓
  - [link] "暮らし" focus✓
  - [link] "旅" focus✓
  - [link] "本" focus✓
  - [link] "インタビュー" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [link] "三浦 灯" focus✓
  - [link] "前回訪ねた岬の貸本屋" focus✓
  - [link] "注1" focus✓
  - [link] "注2" focus✓
  - [link] "注3" focus✓
  - [link] "記事の終わりの店舗情報" focus✓
  - [link] "本文へ戻る" focus✓
  - [link] "本文へ戻る" focus✓
  - [link] "本文へ戻る" focus✓
  - [button] "リンクをコピー" focus✓ | Enter: layout change | announces
  - [button] "保存" focus✓ | Enter: pressed false -> true
  - [link] "本 連載 第2回 岬の貸本屋に、手紙で本を頼む 2026年8月8日" focus✓
  - [link] "旅 終点の駅から、灯台まで歩く 2026年7月25日" focus✓
  - [link] "暮らし 潮風と暮らす家の、窓のしつらえ 2026年6月30日" focus✓
  - [link] "ほとりについて" focus✓
  - [link] "執筆者" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "プライバシー" focus✓

vlmkit scan handlers
source: index.html

status: 1 warn(s)
registrations: 11 across 5 element(s) + globals, on a page presenting 26 control(s)

  - header#top>div.wrap>button#search-toggle "検索": click
  - header#top>div#search-panel "サイト内検索 検索する 記事のタイトルとセクション名から探します。": keydown (no role)
  - header#top>div#search-panel>div.wrap>form#search-form "サイト内検索 検索する 記事のタイトルとセクション名から探します。": submit (no role)
  - main#main>section.after>div.share>button#copy-link "リンクをコピー": click
  - main#main>section.after>div.share>button#save "保存": click
  - globals: window:wheel, window:touchstart, window:keydown, window:pointerdown, window:scroll, window:resize

Issues:
  warn [unprobed-handler-types] Handler types registered but NOT exercised by this run's probes: keydown, submit — the probe focuses a control and presses the key its role activates with, so a `click` handler on anything but a native control, and any type outside focus/blur/keyboard, is untested here. Verify those paths with a 'verify flow' script.
G41exit 0vlmkit check scroll index.html

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.progress: fixed top=0px viewport y 0 -> 0

No scroll-behavior issues detected.
G42exit 0vlmkit check motion index.html

activeAnimations 0 · running 0 · issues 0

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

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

No motion issues detected.
G43exit 0vlmkit check animation index.html

animations 0 · settleMs 0 · issues 0

output, 8 line(s), 1.6s
vlmkit check animation
source: index.html (1280x720)

status: ok
animations: 0 (evaluated 0, infinite 0)
settle: 0ms

No animation issues detected.
G44exit 0vlmkit check animation 'file://$PWD/examples/sites/magazine/index.html#note-2'

animations 0 · settleMs 0 · issues 0

output, 8 line(s), 1.7s
vlmkit check animation
source: file://examples/sites/magazine/index.html#note-2 (1280x720)

status: ok
animations: 0 (evaluated 0, infinite 0)
settle: 0ms

No animation issues detected.
G45exit 0vlmkit stress i18n index.html

inflate 1.4 · inspected 151 · overflowing 38

output, 12 line(s), 1.6s
  vlmkit stress i18n
  html: examples/sites/magazine/index.html  inflate: 1.4x
  ! 38 overflow / wrap issue(s) across 151 inspected element(s)
    [vertical-wrap] main#main>article#story>header.story-head.wrap>div.story-head__text>h1#story-title — h 122 → 183
    [vertical-wrap] article#story>div#story-body>section.chapter>aside#shop-info>dl.shop-info__list — h 153 → 203
    [vertical-wrap] main#main>article#story>header.story-head.wrap>div.story-head__text>p.meta — h 39 → 67
    [vertical-wrap] main#main>article#story>header.story-head.wrap>div.story-head__text>p.lede — h 166 → 199
    [vertical-wrap] article#story>div#story-body>section.chapter>figure.pullquote>blockquote — h 91 → 137
    [vertical-wrap] main#main>article#story>div#story-body>section.chapter>figure.pullquote — h 192 → 238
    … 32 more (see the report, or --json for all)
  report: examples/sites/magazine/test-results/i18n-stress/report.md
  exits 0 — 38 warn(s) did not fail this command. To gate on one: --rule vertical-wrap=suspect
D36 defect aside#shop-info dl.shop-info__list dt

stress i18n: the shop-info labels wrap under inflation: 'dt そのほかXX 77×50 +25px' and 'dt 営業時間XX 77×50 +25px' (one line to two; the dd beside each only grows because the row does). The dt column is a fixed 5.5em, the same fixed-label pattern D25 removed from the interview and the notes; a five-character label such as 最寄りの駅 would wrap it without any inflation.

G46exit 0vlmkit check breakpoints index.html --sweep

breakpoints 5 · issues 0 · sweepRanges 0

output, 14 line(s), 3.9s
vlmkit check breakpoints
source: index.html

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 699, 700, 999, 1000, 1099px (each at B-1 / B / B+1)

  699px: clean (max-width: 699px)
  700px: clean (min-width: 700px)
  999px: clean (max-width: 999px)
  1000px: clean (min-width: 1000px)
  1099px: clean (max-width: 1099px)

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

verdict: DONE (8/8 steps)

done true · passed 8 · total 8

output, 27 line(s), 1.9s
vlmkit verify flow
source: index.html

verdict: DONE (8/8 steps)

✓ step 1: 検索 opens the search panel and moves focus into the field
    ✓ #search-toggle aria-expanded=true 
    ✓ #search-panel visible 
    ✓ #search-input focused 
✓ step 2: type a section name
    ✓ #search-input visible 
✓ step 3: Enter submits the form and lists the two 本 articles
    ✓ #search-status text~"「本」に一致する記事が2件あります。" 
    ✓ #search-results li count=2 
✓ step 4: Escape closes the panel and returns focus to the 検索 button
    ✓ #search-panel hidden 
    ✓ #search-toggle aria-expanded=false 
    ✓ #search-toggle focused 
✓ step 5: リンクをコピー is pressed; the live region exists before anything is written to it
    ✓ #share-status role=status 
✓ step 6: within 100ms (the clipboard promise has settled) the confirmation is shown
    ✓ #share-status text~"リンクをコピーしました" 
    ✓ #share-status visible 
✓ step 7: 保存 toggles on
    ✓ #save aria-pressed=true 
✓ step 8: 保存 toggles off again
    ✓ #save aria-pressed=false
F37fix for D36

The shop-info dl is one grid (minmax(5.5em, max-content) then 1fr) with each row a subgrid, and dt is white-space: nowrap, so the label column grows to the longest label and every row stays aligned, as in the interview and notes.

G48exit 0vlmkit stress i18n index.html --json

inflate 1.4 · inspected 151 · overflowing 31

output, 1233 line(s), 1.6s
{
  "gate": "stress.i18n",
  "command": "stress i18n",
  "verdict": "pass",
  "counts": {
    "suspect": 0,
    "warn": 31,
    "info": 0
  },
  "findings": [
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 476px -> 476px (scroll 476px) — \"海辺の町の古本屋が、夜だけ店を開ける理由XXXXXXXX\"",
      "evidence": {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>h1#story-title",
        "tag": "h1",
        "before": {
          "width": 476,
          "height": 121.78125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 182.671875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 476px -> 476px (scroll 476px) — \"文・写真XX 三浦X 灯X\n          2026年9月12日XXXX\n          読了時間XX 約8分X\"",
      "evidence": {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.meta",
        "tag": "p",
        "before": {
          "width": 476,
          "height": 39.09375,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 67.1875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 476px -> 476px (scroll 476px) — \"港の灯りがひとつ、またひとつとともりはじめるころ、XXXXXXXXXX凪浦XなぎうらXXの商店街のはずれで、一軒の古本屋\"",
      "evidence": {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.lede",
        "tag": "p",
        "before": {
          "width": 476,
          "height": 165.703125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 198.84375,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>figure.pullquote>blockquote",
        "tag": "blockquote",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>figure.pullquote",
        "tag": "figure",
        "before": {
          "width": 694,
          "height": 192.09375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 237.59375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"三浦X 夜には、どんなお客さんが来るんXXXXXXですか。XX\n          汐田X いろいろですよ。夜勤に向かう\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>div.interview",
        "tag": "div",
        "before": {
          "width": 694,
          "height": 500.875,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 603.4375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 632px -> 632px (scroll 632px) — \"まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に開いてい\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 632px -> 632px (scroll 632px) — \"いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖にいるで\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"汐田X まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"汐田X いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 48px -> 48px (scroll 48px) — \"汐田X\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 48px -> 48px (scroll 48px) — \"汐田X\"",
      "evidence": {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX\"",
      "evidence": {
        "path": "div#story-body>section.chapter>figure.pullquote>blockquote>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"零時ちょうど、汐田さんは電球をひとつずつ消していき、最後に入口の明かりを落とした。私は背の焼けていない詩集を一冊抱えて、\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"帰りぎわ、閉店をなぜ零時にしているのかを尋ねた。汐田さんは少し考えてから、「日付が変わるまでは、今日のうちでしょう」と言\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"店の外には、百円均一の文庫を並べた木箱がひとつ出ている。この箱だけは昼も夜も出しっぱなしで、代金は横に置いた缶に入れても\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"「夜の本屋は、灯台みたいなものだと思うの」と汐田さんは言う。「誰かが起きている明かりが、町にひとつあればいい。本を買わな\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 239.3125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"十一時を過ぎると、客はさすがにまばらになる。汐田さんは帳場で値札を書きながら、ときどき顔を上げて通りのほうを見る。視線の\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"夜に売れる本には傾向がある、と汐田さんは言う。昼に比べて、詩集や随筆、古い旅行記がよく出る。反対に、実用書は昼の店ほどに\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"話しているあいだにも、客足は途切れなかった。作業着のまま文庫の棚の前にしゃがみこむ青年がいて、参考書の棚を行ったり来たり\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"ところが夜に店を開けてみると、昼には一度も見かけなかった客がやってくるようになった。最初の晩に来たのは、これから夜勤に向\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"そこで汐田さんは、昼のあいだはシャッターを下ろし、除湿機を回して本を休ませることにした。日の光が届かなくなってから店を開\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"見せてもらった文庫本は、表紙には深い緑が残っているのに、背だけが白茶けた砂の色になっていた。本を傷めるのは光だけではない\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"「うちは店が西を向いているでしょう。午後になると、海に照り返した光まで店の奥に入ってくるの。父の棚を片づけていたら、窓ぎ\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"汐田さんが店を夜だけ開けるようになったのは、十二年前に父親から店を継いでからだ。先代は朝十時に店を開けて夕方六時に閉める\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"店内は奥行きが深く、左右の壁と中央の平台に、ざっと一万冊の本が並ぶ。文庫と新書が半分、残りは詩集や郷土史、古い旅行記。港\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"十七時五十八分。岸壁に腰を下ろして待っていると、水平線に残っていた橙色が消え、背中のほうで、がらがらとシャッターの巻き上\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 239.3125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"シャッターの脇には小さな黒板が掛かっていて、白いチョークで「本日の日の入りXXXXXXXXXXXXXXX 十七時五十八分\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"商店街がとぎれ、岸壁が見えてくる手前の角に、その店はある。宵待書房。間口二間ほどの木造二階建てで、昼間に通りかかった人に\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 694px -> 694px (scroll 694px) — \"九月のなかば、夕方の凪浦駅に降りた。駅前から海へまっすぐ延びる商店街は、五時を過ぎると半分ほどの店が戸を閉める。魚屋が店\"",
      "evidence": {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      }
    },
    {
      "rule": "vertical-wrap",
      "severity": "warn",
      "message": "vertical-wrap at 1.4x text — 206px -> 694px (scroll 0px) — \"前回訪ねた岬の貸本屋XXXX\"",
      "evidence": {
        "path": "article#story>div#story-body>section.chapter>p>a",
        "tag": "a",
        "before": {
          "width": 205.921875,
          "height": 18,
          "clientWidth": 0,
          "scrollWidth": 0
        },
        "after": {
          "width": 694,
          "height": 52.1875,
          "clientWidth": 0,
          "scrollWidth": 0
        }
      }
    }
  ],
  "suppressed": [],
  "retuned": [],
  "report": {
    "html": "examples/sites/magazine/index.html",
    "inflateFactor": 1.4,
    "beforeScreenshot": "examples/sites/magazine/test-results/i18n-stress/before.png",
    "afterScreenshot": "examples/sites/magazine/test-results/i18n-stress/after.png",
    "overflowing": [
      {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>h1#story-title",
        "tag": "h1",
        "text": "海辺の町の古本屋が、夜だけ店を開ける理由XXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 476,
          "height": 121.78125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 182.671875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      },
      {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.meta",
        "tag": "p",
        "text": "文・写真XX 三浦X 灯X\n          2026年9月12日XXXX\n          読了時間XX 約8分X",
        "kind": "vertical-wrap",
        "before": {
          "width": 476,
          "height": 39.09375,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 67.1875,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      },
      {
        "path": "main#main>article#story>header.story-head.wrap>div.story-head__text>p.lede",
        "tag": "p",
        "text": "港の灯りがひとつ、またひとつとともりはじめるころ、XXXXXXXXXX凪浦XなぎうらXXの商店街のはずれで、一軒の古本屋",
        "kind": "vertical-wrap",
        "before": {
          "width": 476,
          "height": 165.703125,
          "clientWidth": 476,
          "scrollWidth": 476
        },
        "after": {
          "width": 476,
          "height": 198.84375,
          "clientWidth": 476,
          "scrollWidth": 476
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>figure.pullquote>blockquote",
        "tag": "blockquote",
        "text": "夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>figure.pullquote",
        "tag": "figure",
        "text": "夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 192.09375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 237.59375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>div.interview",
        "tag": "div",
        "text": "三浦X 夜には、どんなお客さんが来るんXXXXXXですか。XX\n          汐田X いろいろですよ。夜勤に向かう",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 500.875,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 603.4375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "text": "まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に開いてい",
        "kind": "vertical-wrap",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>span.utterance",
        "tag": "span",
        "text": "いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖にいるで",
        "kind": "vertical-wrap",
        "before": {
          "width": 632,
          "height": 102.5625,
          "clientWidth": 632,
          "scrollWidth": 632
        },
        "after": {
          "width": 632,
          "height": 136.75,
          "clientWidth": 632,
          "scrollWidth": 632
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "text": "汐田X まるで違います。昼のお客さんは、用事のついでに寄る人。夜のお客さんは、ここに来ること自体が用事なの。この町で夜に",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>div.interview>p.turn",
        "tag": "p",
        "text": "汐田X いろいろですよ。夜勤に向かう看護師さん、塾帰りの高校生、それから漁師さん。いか釣りの船は夕方に港を出て、朝まで沖",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "text": "汐田X",
        "kind": "vertical-wrap",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      },
      {
        "path": "div#story-body>section.chapter>div.interview>p.turn>b.speaker",
        "tag": "b",
        "text": "汐田X",
        "kind": "vertical-wrap",
        "before": {
          "width": 48,
          "height": 102.5625,
          "clientWidth": 48,
          "scrollWidth": 48
        },
        "after": {
          "width": 48,
          "height": 136.75,
          "clientWidth": 48,
          "scrollWidth": 48
        }
      },
      {
        "path": "div#story-body>section.chapter>figure.pullquote>blockquote>p",
        "tag": "p",
        "text": "夜の本屋は、灯台みたいなものだと思うの。誰かが起きている明かりが、町にひとつあればいい。XXXXXXXXXXXXXXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 91,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.5,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "零時ちょうど、汐田さんは電球をひとつずつ消していき、最後に入口の明かりを落とした。私は背の焼けていない詩集を一冊抱えて、",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "帰りぎわ、閉店をなぜ零時にしているのかを尋ねた。汐田さんは少し考えてから、「日付が変わるまでは、今日のうちでしょう」と言",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "店の外には、百円均一の文庫を並べた木箱がひとつ出ている。この箱だけは昼も夜も出しっぱなしで、代金は横に置いた缶に入れても",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "「夜の本屋は、灯台みたいなものだと思うの」と汐田さんは言う。「誰かが起きている明かりが、町にひとつあればいい。本を買わな",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 239.3125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "十一時を過ぎると、客はさすがにまばらになる。汐田さんは帳場で値札を書きながら、ときどき顔を上げて通りのほうを見る。視線の",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "夜に売れる本には傾向がある、と汐田さんは言う。昼に比べて、詩集や随筆、古い旅行記がよく出る。反対に、実用書は昼の店ほどに",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "話しているあいだにも、客足は途切れなかった。作業着のまま文庫の棚の前にしゃがみこむ青年がいて、参考書の棚を行ったり来たり",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "ところが夜に店を開けてみると、昼には一度も見かけなかった客がやってくるようになった。最初の晩に来たのは、これから夜勤に向",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "そこで汐田さんは、昼のあいだはシャッターを下ろし、除湿機を回して本を休ませることにした。日の光が届かなくなってから店を開",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "見せてもらった文庫本は、表紙には深い緑が残っているのに、背だけが白茶けた砂の色になっていた。本を傷めるのは光だけではない",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "「うちは店が西を向いているでしょう。午後になると、海に照り返した光まで店の奥に入ってくるの。父の棚を片づけていたら、窓ぎ",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "汐田さんが店を夜だけ開けるようになったのは、十二年前に父親から店を継いでからだ。先代は朝十時に店を開けて夕方六時に閉める",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 102.5625,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "店内は奥行きが深く、左右の壁と中央の平台に、ざっと一万冊の本が並ぶ。文庫と新書が半分、残りは詩集や郷土史、古い旅行記。港",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "十七時五十八分。岸壁に腰を下ろして待っていると、水平線に残っていた橙色が消え、背中のほうで、がらがらとシャッターの巻き上",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 239.3125,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "シャッターの脇には小さな黒板が掛かっていて、白いチョークで「本日の日の入りXXXXXXXXXXXXXXX 十七時五十八分",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 136.75,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "商店街がとぎれ、岸壁が見えてくる手前の角に、その店はある。宵待書房。間口二間ほどの木造二階建てで、昼間に通りかかった人に",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "main#main>article#story>div#story-body>section.chapter>p",
        "tag": "p",
        "text": "九月のなかば、夕方の凪浦駅に降りた。駅前から海へまっすぐ延びる商店街は、五時を過ぎると半分ほどの店が戸を閉める。魚屋が店",
        "kind": "vertical-wrap",
        "before": {
          "width": 694,
          "height": 68.375,
          "clientWidth": 694,
          "scrollWidth": 694
        },
        "after": {
          "width": 694,
          "height": 170.9375,
          "clientWidth": 694,
          "scrollWidth": 694
        }
      },
      {
        "path": "article#story>div#story-body>section.chapter>p>a",
        "tag": "a",
        "text": "前回訪ねた岬の貸本屋XXXX",
        "kind": "vertical-wrap",
        "before": {
          "width": 205.921875,
          "height": 18,
          "clientWidth": 0,
          "scrollWidth": 0
        },
        "after": {
          "width": 694,
          "height": 52.1875,
          "clientWidth": 0,
          "scrollWidth": 0
        }
      }
    ],
    "totalInspected": 151,
    "reportPath": "examples/sites/magazine/test-results/i18n-stress/report.md"
  }
}
V36verified D36 by G48

stress i18n after the fix: no shop-info row at all (dt, dd and list are gone from the report); 31 warns, all prose or the stretched speaker cells described in N10.

N15decision

D36 changed style.css during the final round, after G29-G47 had run, so the whole gate set is run again below (G49 onward), against the page as shipped. G29-G47 stand as the first pass of this round.

G49exit 0vlmkit check integrity index.html

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

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

output, 9 line(s), 7.0s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 0 exempted)
  1280x800: 1 component(s), ink 93.8%, 106 text block(s)
  768x900: 1 component(s), ink 92.7%, 105 text block(s)
  375x700: 1 component(s), ink 92.8%, 105 text block(s)

No integrity defects detected.
G50exit 1vlmkit check copy index.html --manifest copy.txt

missing 1 · placeholders 0 · manifestLines 8 · statesExplored 1 · revealedOnly 0

output, 10 line(s), 1.4s
vlmkit check copy
source: index.html

status: suspect
rendered text: 3461 chars
disclosure states: 1 explored (details / tabs / aria-expanded)
manifest: 8 line(s), missing 1

Issues:
  x copy-missing: Manifest line not found in rendered text or any of 1 revealed disclosure state(s): "リンクをコピーしました" (comparison is whitespace-normalized, case-sensitive).
G51exit 0vlmkit check design index.html

verdict: COHERENT (0 finding(s))

verdict coherent · drifting 0 · roles 5

output, 22 line(s), 1.8s
vlmkit check design
source: index.html

verdict: COHERENT (0 finding(s))
  roles judged: 3 of 5 seen, spacing values: 22
  coverage: 17 of 723 visible element(s) carried an inferable role
    no role: rect x397, span x47, p x41, path x38, circle x36, g x27, +26 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.

Role reuse (instances / distinct styles; drift below 3x from 3 instances)
  h2               7 inst    2 styles  reuse   3.5x  0 one-off  ok
  h3               4 inst    1 styles  reuse     4x  0 one-off  ok
  button           3 inst    1 styles  reuse     3x  0 one-off  ok
  img              2 inst    2 styles  reuse     1x  2 one-off  not judged
  h1               1 inst    1 styles  reuse     1x  1 one-off  not judged
  not judged: img (2), h1 (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).

No design drift detected.
G52exit 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: 8 label(s), 3 heading level(s), 99 wide block(s) on 9 left / 6 right rail(s) — from 209 visible box(es)
  4 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     42px / 700   h1#story-title
  h2     25px / 700   h2#ch1
  h3     17px / 700   h3#shop-info-title
  body 18px, largest 42px (2.33x), heaviest +300 weight

Group gaps: 12.95px between heading-led groups vs 21.5px inside them (0.6x, 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.
G53exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f6f2ea · bodyInk #1d2733 · linkInk #a4462b · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

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

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

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  3 distinct
    #f6f2ea   88.1%     1 el  
    #ede6d8    8.0%     2 el  aside#shop-info
    #1d2733    3.9%     4 el  a.skip
  ink       6 distinct
    #1d2733   79.5%    74 el  div.brand>a.wordmark>span.wordmark__text
    #4a5360   11.6%    28 el  div.story-head__text>p.kicker>span.series
    #5b636e    2.6%     8 el  div.wrap>div.brand>p.tagline
    #b9bfc8    2.5%     3 el  div.wrap>div.site-footer__brand>p.site-footer__tagline
    #e8e3d9    2.1%     5 el  div.wrap>div.site-footer__brand>p.site-footer__mark
    …and 1 more
  marks     3 distinct
    #d8d0c0   71.0%    11 el  header#top
    #1d2733   27.5%    14 el  button#search-toggle
    #a4462b    1.6%     5 el  ul>li>a
  base #f6f2ea, body ink #1d2733, link ink #a4462b on 9 element(s)
G54exit 0vlmkit check a11y contrast index.html

inspected 147 · failures 0

output, 5 line(s), 1.6s
  vlmkit check a11y contrast
  html: examples/sites/magazine/index.html
  inspected 147 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/magazine/test-results/a11y-contrast/index-861ad078/report.md
G55exit 1vlmkit check a11y focus index.html

steps 26 · findings 5

output, 10 line(s), 1.8s
  vlmkit check a11y focus
  source: index.html
  captured 26 focus step(s)
  ✗ 5 finding(s)
    [skip-row] Focus jumped down by 617px (from `header#top>div.wrap.masthead__inner>button#search-toggle` to `header.story-head.wrap>div.story-head__text>p.meta>span.meta__item>a`). Confirm no focusable element was unintentionally skipped.
    [reverse] Focus moved left within the same row (from `div#story-body>section.chapter>p>sup.fnref>a#ref-2` at x=925 to `div.interview>p.turn>span.utterance>sup.fnref>a#ref-3` at x=397). Visual order is L-to-R; check `tabindex` or DOM order.
    [reverse] Focus moved up by 93px (from `div.interview>p.turn>span.utterance>sup.fnref>a#ref-3` at y=443 to `article#story>div#story-body>section.chapter>p>a` at y=351). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [reverse] Focus moved up by 419px (from `main#main>section.after>div.share>button#save` at y=612 to `section.related>div.wrap>ul.related__list>li#related-1>a.card__link` at y=194). Visual order is top-to-bottom; check `tabindex` or DOM order.
    [skip-row] Focus jumped down by 345px (from `section.related>div.wrap>ul.related__list>li#related-3>a.card__link` to `div.wrap.site-footer__inner>nav.site-footer__nav>ul>li>a`). Confirm no focusable element was unintentionally skipped.
  report: examples/sites/magazine/test-results/a11y-focus-order/index-861ad078/report.md
G56exit 0vlmkit check a11y touch index.html

level AA · inspected 26 · failures 0 · wcagExempt 11

output, 6 line(s), 1.5s
  vlmkit check a11y touch
  source: index.html  level: WCAG AA (24×24 min)
  inspected 26 interactive element(s)
  ✓ 0 undersized target(s)
  11 undersized target(s) excused by WCAG 2.5.8 itself (9 in a sentence, 2 with clear spacing)
  report: examples/sites/magazine/test-results/a11y-touch/index-861ad078/report.md
G57exit 0vlmkit scan scroll index.html

containers 0 · overflowX 0 · issues 0

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

status: ok
page: 1280x7364 — horizontal overflow 0px, vertical scroll 6644px
scroll containers: 0 (dead scrollports 0, clipped 0)

No scroll issues detected.
G58exit 0vlmkit scan scroll index.html --viewport 375x812

containers 0 · overflowX 0 · issues 0

output, 8 line(s), 1.4s
vlmkit scan scroll
source: index.html (375x812)

status: ok
page: 375x8980 — horizontal overflow 0px, vertical scroll 8168px
scroll containers: 0 (dead scrollports 0, clipped 0)

No scroll issues detected.
G59exit 0vlmkit scan handlers index.html

registrations 11 · elements 5 · suspects 0

output, 16 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: 11 across 5 element(s) + globals, on a page presenting 26 control(s)

  - header#top>div.wrap>button#search-toggle "検索": click
  - header#top>div#search-panel "サイト内検索 検索する 記事のタイトルとセクション名から探します。": keydown (no role)
  - header#top>div#search-panel>div.wrap>form#search-form "サイト内検索 検索する 記事のタイトルとセクション名から探します。": submit (no role)
  - main#main>section.after>div.share>button#copy-link "リンクをコピー": click
  - main#main>section.after>div.share>button#save "保存": click
  - globals: window:wheel, window:touchstart, window:keydown, window:pointerdown, window:scroll, window:resize

Issues:
  warn [unprobed-handler-types] 3 handler type(s) registered and NONE exercised: click, 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.
G60exit 0vlmkit check interactions index.html --handlers

elements 26 · suspects 0 · warns 0

output, 49 line(s), 5.6s
vlmkit check interactions
source: index.html

status: ok
  exits 0 — 1 warn(s) did not fail this command. To gate on one: --rule unprobed-handler-types=suspect
interactive elements: 26

  - [link] "本文へスキップ" focus✓
  - [link] "ほとり" focus✓
  - [link] "特集" focus✓
  - [link] "暮らし" focus✓
  - [link] "旅" focus✓
  - [link] "本" focus✓
  - [link] "インタビュー" focus✓
  - [button] "検索" focus✓ | Enter: expanded false -> true
  - [link] "三浦 灯" focus✓
  - [link] "前回訪ねた岬の貸本屋" focus✓
  - [link] "注1" focus✓
  - [link] "注2" focus✓
  - [link] "注3" focus✓
  - [link] "記事の終わりの店舗情報" focus✓
  - [link] "本文へ戻る" focus✓
  - [link] "本文へ戻る" focus✓
  - [link] "本文へ戻る" focus✓
  - [button] "リンクをコピー" focus✓ | Enter: layout change | announces
  - [button] "保存" focus✓ | Enter: pressed false -> true
  - [link] "本 連載 第2回 岬の貸本屋に、手紙で本を頼む 2026年8月8日" focus✓
  - [link] "旅 終点の駅から、灯台まで歩く 2026年7月25日" focus✓
  - [link] "暮らし 潮風と暮らす家の、窓のしつらえ 2026年6月30日" focus✓
  - [link] "ほとりについて" focus✓
  - [link] "執筆者" focus✓
  - [link] "お問い合わせ" focus✓
  - [link] "プライバシー" focus✓

vlmkit scan handlers
source: index.html

status: 1 warn(s)
registrations: 11 across 5 element(s) + globals, on a page presenting 26 control(s)

  - header#top>div.wrap>button#search-toggle "検索": click
  - header#top>div#search-panel "サイト内検索 検索する 記事のタイトルとセクション名から探します。": keydown (no role)
  - header#top>div#search-panel>div.wrap>form#search-form "サイト内検索 検索する 記事のタイトルとセクション名から探します。": submit (no role)
  - main#main>section.after>div.share>button#copy-link "リンクをコピー": click
  - main#main>section.after>div.share>button#save "保存": click
  - globals: window:wheel, window:touchstart, window:keydown, window:pointerdown, window:scroll, window:resize

Issues:
  warn [unprobed-handler-types] Handler types registered but NOT exercised by this run's probes: keydown, submit — the probe focuses a control and presses the key its role activates with, so a `click` handler on anything but a native control, and any type outside focus/blur/keyboard, is untested here. Verify those paths with a 'verify flow' script.
G61exit 0vlmkit check scroll index.html

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.progress: fixed top=0px viewport y 0 -> 0

No scroll-behavior issues detected.
G62exit 0vlmkit check motion index.html

activeAnimations 0 · running 0 · issues 0

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

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

No motion issues detected.
G63exit 0vlmkit check animation index.html

animations 0 · settleMs 0 · issues 0

output, 8 line(s), 1.5s
vlmkit check animation
source: index.html (1280x720)

status: ok
animations: 0 (evaluated 0, infinite 0)
settle: 0ms

No animation issues detected.
G64exit 0vlmkit check animation 'file://$PWD/examples/sites/magazine/index.html#note-2'

animations 0 · settleMs 0 · issues 0

output, 8 line(s), 1.5s
vlmkit check animation
source: file://examples/sites/magazine/index.html#note-2 (1280x720)

status: ok
animations: 0 (evaluated 0, infinite 0)
settle: 0ms

No animation issues detected.
G65exit 0vlmkit check breakpoints index.html --sweep

breakpoints 5 · issues 0 · sweepRanges 0

output, 14 line(s), 3.7s
vlmkit check breakpoints
source: index.html

status: ok
width sweep: 320-1280px step 25 (39 widths) — clean
breakpoints checked: 699, 700, 999, 1000, 1099px (each at B-1 / B / B+1)

  699px: clean (max-width: 699px)
  700px: clean (min-width: 700px)
  999px: clean (max-width: 999px)
  1000px: clean (min-width: 1000px)
  1099px: clean (max-width: 1099px)

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

verdict: DONE (8/8 steps)

done true · passed 8 · total 8

output, 27 line(s), 2.0s
vlmkit verify flow
source: index.html

verdict: DONE (8/8 steps)

✓ step 1: 検索 opens the search panel and moves focus into the field
    ✓ #search-toggle aria-expanded=true 
    ✓ #search-panel visible 
    ✓ #search-input focused 
✓ step 2: type a section name
    ✓ #search-input visible 
✓ step 3: Enter submits the form and lists the two 本 articles
    ✓ #search-status text~"「本」に一致する記事が2件あります。" 
    ✓ #search-results li count=2 
✓ step 4: Escape closes the panel and returns focus to the 検索 button
    ✓ #search-panel hidden 
    ✓ #search-toggle aria-expanded=false 
    ✓ #search-toggle focused 
✓ step 5: リンクをコピー is pressed; the live region exists before anything is written to it
    ✓ #share-status role=status 
✓ step 6: within 100ms (the clipboard promise has settled) the confirmation is shown
    ✓ #share-status text~"リンクをコピーしました" 
    ✓ #share-status visible 
✓ step 7: 保存 toggles on
    ✓ #save aria-pressed=true 
✓ step 8: 保存 toggles off again
    ✓ #save aria-pressed=false
S31

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

S31 screen 1S31 screen 2S31 screen 3S31 screen 4S31 screen 5S31 screen 6S31 screen 7S31 screen 8S31 screen 9S31 screen 10
L31 saw

Final desktop full page, 10 screens, as shipped. S31-1: the masthead reads in one row (wave + ほとり, grey tagline with full-width comma, five nav items with 本 underlined in the accent, 検索 pill); the header puts the two-line title, phrase-broken lede, and meta (文・写真 三浦 灯 | 2026年9月12日 | 読了時間 約8分, proportional digits) beside the 620px night illustration with four lit bulbs and a clean quay. S31-2 to S31-7: body column 293-986px, about 37 characters a line, 1.9 leading; every h2 has its accent rule and full-width punctuation; no paragraph ends on fewer than four characters; the shelf figure's light fades; the interview column is aligned; 漁火 注3 is spaced; the pull quote breaks as phrases. The progress bar at the top grows tile by tile (about 175, 370, 565, 760, 950px). S31-8: the shop box's labels sit on one aligned column, then notes, the share row and the author card. S31-9/S31-10: three related cards, the dark footer, © readable. I found nothing broken, clipped, cramped or misaligned in the ten screens.

S32

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

S32 screen 1S32 screen 2S32 screen 3S32 screen 4S32 screen 5S32 screen 6S32 screen 7S32 screen 8S32 screen 9S32 screen 10S32 screen 11S32 screen 12
L32 saw

Final mobile full page, 12 screens, as shipped. S32-1: a two-row masthead (wordmark with 検索 top-right, then the five nav items edge to edge), the 335px illustration, 本 + series, a two-line title, and the phrase-broken lede. S32-2: meta on two lines with no stray bar; the first h2 as a balanced pair, 日が沈むと、 / シャッターが上がる. S32-2 to S32-9: body at 16px, about 20 characters a line; every paragraph ends on four or more characters; the caption ends 保っている。 (S32-5); the interview aligned with its speaker column (S32-6); the pull quote in four phrase lines (S32-7); shop info with aligned labels (S32-9). S32-10: the notes' back links flush after text or on their own line; この記事を above both buttons; the author card. S32-11/S32-12: the compact related list with balanced two-line titles; the footer with readable ©. No horizontal overflow and nothing clipped. The only soft spot is the slightly loose justification on a few lines above a paragraph tail, which is the accepted cost of D6.

S33

state: mid-article, progress partly filled

index.html · 1280×800 · scroll-to #ch3 · wait 200

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

State: mid-article on desktop, scrolled to section 3. The 3px accent progress bar at the very top is partly filled: it runs from the left edge to about x=680 of 1280, roughly 53%, over the faint grey track, and it holds the top edge above the text (fixed). Below it are the end of section 2, the section 3 accent rule and h2, the intro line and the start of the interview. It reads exactly as a reading-progress bar should, thin and quiet, in the one accent colour.

S34

state: mid-article on mobile

index.html · 375×812 · scroll-to #ch2 · wait 200

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

State: mid-article on mobile, scrolled to section 2. The progress bar covers about 95px of the 375px width (about a quarter), which matches the position in a 9,000px page. It stays pinned above the text; the h2 西日から、本の背を守るために fits on one line, and the paragraphs below end on full lines.

S35

state: after following 注1 (mobile)

index.html · 375×812 · click #ref-1 · wait 200

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

State: the page after following the 注1 reference on mobile. The jump lands with context: the end of the shop box, the ink rule and the 注 heading are above, and 注1 is highlighted with the warm tint band (12px past the column on each side, inside the viewport), its 本文へ戻る link at the end of the text. 注2 and 注3 follow, then the share row. The progress bar is full, since the article's end is on screen.

S36

state: copy-link confirmation (mobile)

index.html · 375×812 · click #copy-link · wait 300

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

State: the copy-link confirmation on mobile. The buttons stay on one row (リンクをコピー with the pointer's hover fill, 保存 outlined), and the live region's message wraps below them as its own line: an accent check followed by bold 「リンクをコピーしました」, verbatim. The author card follows below the rule. Nothing overlaps, and the message is fully visible.

S37

state: 保存 pressed (desktop)

index.html · 1280×800 · click #save · hover #author · wait 200

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

State: 保存 pressed on desktop, with the pointer moved off onto the author card. 保存 is a filled ink pill with a solid bookmark and paper text beside the outlined リンクをコピー, so the on state reads at a glance without relying on the pointer. The label stays 保存. The notes above and the author card and related heading below are unchanged.

S38

state: reduced motion, mid-article

index.html · 1280×800 · reduced motion · scroll-to #ch4 · wait 200

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

State: reduced motion (prefers-reduced-motion: reduce emulated), scrolled to section 4. The progress bar is at about x=997 of 1280 (78%), exactly where it should be for this scroll position, with no easing. The pull quote with its ink rules, the 零時に、明かりを落とす h2 and the section's first paragraphs render as in the default mode; nothing else on the page moves in either mode. A still cannot show the absence of easing: G27's frame-sampled reduced-motion pass (honored) and check motion's reduced-motion rule carry that evidence.

N16false-positiveabout G50

Final copy run: 7 of 8 manifest lines are found visibly. The one reported missing, リンクをコピーしました, is the brief's state copy: it appears in the live region only after リンクをコピー is pressed (see N2 for why it is not pre-filled). The final verify flow G66 asserts it deterministically (step 5: the region exists with role=status; step 6: within 100ms it contains the line and is visible), and S36/L36 (mobile, final round) and S4/L4 (desktop) show it rendered verbatim.

N17false-positiveabout G55

Final focus run: the same viewport-coordinate artifacts as G7 (see N3 and tool note N4), plus one new reverse, 注3 (y=443) -> 記事の終わりの店舗情報 (y=351), which appeared because the footnote references now scroll into view with scroll-margin-top: 25vh (D34), so the browser parks them lower in the viewport than a plain link. In the document 注3 is in section 3's interview and the shop-info link is in section 4's last paragraph, far below (S31-5, then S31-7). The page has no tabindex anywhere; Tab order is DOM order and DOM order is the visual order. The two skip-row warns cross only non-interactive regions (S31-1, S31-9).

N18acceptedabout G59

Inventory warn only (unprobed-handler-types): the click handlers are exercised by G60 and the keydown/submit paths by G66, as in N7. The four new window listeners (wheel, touchstart, keydown, pointerdown) are the passive, capture-phase, fire-once switch that turns on the progress-bar easing (D35); none of them calls preventDefault.

N19acceptedabout G60

unprobed-handler-types (keydown, submit) is covered by verify flow G66 steps 3-4 (form submit with Enter gives the result status and 2 results; Escape closes the panel and returns focus to 検索). All three buttons show their transitions here: 検索 expanded false -> true, リンクをコピー announces, 保存 pressed false -> true.

N20acceptedabout G48

31 vertical-wrap warns, 0 suspects: 29 rows are prose, the title, the lede, the meta line and an inline link gaining lines under 1.4x inflation, which is what text should do; 2 rows are the interview's stretched speaker cells (48px, nowrap, one line of text in a tall grid cell, see N10/N11). No horizontal overflow and nothing extends past its parent.

N21toolabout G50

check copy --manifest has no way to reach copy that an action produces. Its sweep opens details, tabs and aria-expanded controls ('disclosure states: 1 explored (details / tabs / aria-expanded)'), so a brief whose required copy is a confirmation in a live region fails on every run: 'x copy-missing: Manifest line not found in rendered text or any of 1 revealed disclosure state(s): "リンクをコピーしました"'. I proved the line with verify flow instead (G66). A flag naming controls to activate before matching (e.g. --reveal '#copy-link'), or accepting a verify-flow step as the carrier, would let the copy gate itself cover state copy.

N22toolabout G63

check animation and check motion cannot see a scroll-linked transition. Neither scrolls nor sends input before sampling, so G63 and G64 report 'animations: 0' and G62 'active transitions: 0' for a page whose one motion, the brief's progress bar, runs only while the reader scrolls. The only frame-sampled check of its reduced-motion behaviour was G27, possible only because the page then animated on a fragment load, which was itself a defect (D35). A --scroll option (sample while scrolling the window by N px) on check animation would make 'respects prefers-reduced-motion' provable for scroll-driven motion.

done

ほとり: one Japanese long-form feature (2,949 characters: four sections, a figure, an interview with the speakers marked, a pull quote, three footnotes with back links, a shop box, an author card and three related articles; all art is inline SVG), judged in 5 rounds, 66 gate runs and 38 shots with 38 looks. 36 defects, all fixed and verified: 25 found only by eye and 11 by a gate. The eye-only ones include the tablet masthead collapsing to one glyph per line while check integrity called 768px CLEAN, body text falling back to a Chinese font, bulbs hidden behind the door mullions, and one- and two-kana last lines in justified Japanese that text-wrap: pretty did not fix. Final set: integrity CLEAN at 1280/768/375, design COHERENT, composition COMPOSED, color CONSISTENT (23 underlined prose links), contrast 0 failures, touch 0 undersized, scan scroll clean at 1280 and 375, check scroll ok (the fixed bar holds), motion/animation ok (reduced-motion honoured, G27), breakpoints --sweep clean, verify flow DONE 8/8, stress i18n 0 suspects. Two gates still exit 1, both noted with evidence: check copy (the state-only confirmation, proven by G66 and S36) and check a11y focus (viewport-coordinate artifacts, tool note N4).

R6 · independent review

reviewer
G67exit 0vlmkit check integrity index.html

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

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

output, 9 line(s), 7.1s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 0 exempted)
  1280x800: 1 component(s), ink 93.8%, 106 text block(s)
  768x900: 1 component(s), ink 92.7%, 105 text block(s)
  375x700: 1 component(s), ink 92.8%, 105 text block(s)

No integrity defects detected.
G68exit 0vlmkit check composition index.html

verdict: COMPOSED (0 finding(s))

verdict composed · proximity 0 · flatSteps 0 · railNearMisses 0

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

verdict: COMPOSED (0 finding(s))
  measured: 8 label(s), 3 heading level(s), 99 wide block(s) on 9 left / 6 right rail(s) — from 209 visible box(es)
  4 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     42px / 700   h1#story-title
  h2     25px / 700   h2#ch1
  h3     17px / 700   h3#shop-info-title
  body 18px, largest 42px (2.33x), heaviest +300 weight

Group gaps: 12.95px between heading-led groups vs 21.5px inside them (0.6x, 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.
G69exit 0vlmkit check color index.html

verdict: CONSISTENT (0 finding(s))

verdict consistent · base #f6f2ea · bodyInk #1d2733 · linkInk #a4462b · invisibleControls 0 · colorOnlyLinks 0 · unreadableColors 0

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

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

Palette (by painted area; reported, never judged — see the rejected candidates in the module docs)
  surfaces  3 distinct
    #f6f2ea   88.1%     1 el  
    #ede6d8    8.0%     2 el  aside#shop-info
    #1d2733    3.9%     4 el  a.skip
  ink       6 distinct
    #1d2733   79.5%    74 el  div.brand>a.wordmark>span.wordmark__text
    #4a5360   11.6%    28 el  div.story-head__text>p.kicker>span.series
    #5b636e    2.6%     8 el  div.wrap>div.brand>p.tagline
    #b9bfc8    2.5%     3 el  div.wrap>div.site-footer__brand>p.site-footer__tagline
    #e8e3d9    2.1%     5 el  div.wrap>div.site-footer__brand>p.site-footer__mark
    …and 1 more
  marks     3 distinct
    #d8d0c0   71.0%    11 el  header#top
    #1d2733   27.5%    14 el  button#search-toggle
    #a4462b    1.6%     5 el  ul>li>a
  base #f6f2ea, body ink #1d2733, link ink #a4462b on 9 element(s)
G70exit 0vlmkit check a11y contrast index.html

inspected 147 · failures 0

output, 5 line(s), 1.5s
  vlmkit check a11y contrast
  html: examples/sites/magazine/index.html
  inspected 147 text-bearing element(s)
  ✓ 0 contrast failure(s)
  report: examples/sites/magazine/test-results/a11y-contrast/index-861ad078/report.md
S39

the article as a reader lands

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

S39 screen 1S39 screen 2S39 screen 3S39 screen 4S39 screen 5S39 screen 6S39 screen 7S39 screen 8S39 screen 9S39 screen 10
L39 saw

Desktop (10 screens). Screen 1: the masthead (wave mark, ほとり, tagline, nav with 本 underlined in the accent, a pill 検索) over a two-column hero — category chip, series line, the title broken at its comma, a lede with ruby over 凪浦, a byline row — and a large night illustration of 宵待書房 with a lighthouse, lit shelves and reflections. It reads as a magazine at once. Screens 2–7: a single ~694px column with a short accent rule over each h2, generous line spacing, underlined accent links and 注 superscripts; the bookshelf figure breaks out wider with its caption; the interview sets speaker names in a gutter, questions muted and answers in ink; the progress bar at the top grows screen by screen. Screen 6: the pull quote breaks its first line after 誰かが — 「…だと思うの。誰かが/起きている明かりが、町にひとつあればいい。」 — so the second sentence's subject hangs at the end of the first line. Screens 8–10: shop box, 注 with back-links, share buttons, author card, three illustrated related cards, dark footer. Only the pull-quote break is off.

D37 defect .pullquote blockquote p

On desktop the pull quote's first line ends on 誰かが, the subject of the SECOND sentence, so the quote reads 「…思うの。誰かが/起きている明かりが…」. word-break: auto-phrase makes 誰かが a legal break and text-wrap: balance prefers 23/21 characters to the sentence boundary's 20/24, although both sentences fit the 694px column on one line each.

S40

the article as a reader lands

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

S40 screen 1S40 screen 2S40 screen 3S40 screen 4S40 screen 5S40 screen 6S40 screen 7S40 screen 8S40 screen 9S40 screen 10S40 screen 11S40 screen 12
L40 saw

Phone (12 screens). The masthead becomes two rows — wordmark with the 検索 pill, then the five sections evenly spaced — and the illustration leads, then the chip, series line, the title broken at its comma and the lede. Headings break by phrase (「日が沈むと、/シャッターが上がる」), body text keeps a comfortable 16–17px with generous leading, links stay underlined in the accent. The interview keeps its speaker gutter at 375px; the pull quote breaks by phrase into four balanced lines; the shop box keeps a two-column table; notes, share buttons, the author card and related cards (image left, phrase-broken titles right) follow, then the footer. The only rough edge: note 3's text ends 「並/ぶ。」 before its back-link, which the back-link on the same line softens. Nothing overflows or collides.

F38fix for D37

Each sentence of the pull quote is a span, inline-block from 700px, so on wide screens the quote breaks at the sentence boundary; below 700px the spans stay inline and auto-phrase / balance break it as before (the phone version already broke by phrase well).

S41

pull quote after the fix

index.html · 1280×800 · element .pullquote

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

Desktop close-up of the pull quote after the fix: two lines, 「夜の本屋は、灯台みたいなものだと思うの。」 and 「誰かが起きている明かりが、町にひとつあればいい。」 — each sentence on its own line, the second one longer but inside the column, the attribution below in small grey type, the heavy rule above and the thin one below unchanged.

S42

pull quote after the fix

index.html · 768×1024 · element .pullquote

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

L42 saw

Tablet 768 close-up of the pull quote: the same two-line sentence-per-line break as desktop at 26px; the longer second sentence still fits the narrower column on one line, so the inline-block spans never have to wrap inside themselves here.

S43

pull quote after the fix

index.html · 375×812 · element .pullquote

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

L43 saw

Phone 375 close-up of the pull quote: unchanged from before the fix — four phrase-broken lines (夜の本屋は、灯台みたいな/ものだと思うの。誰かが/起きている明かりが、/町にひとつあればいい。) at 22px, because below 700px the sentence spans stay inline and auto-phrase with balance still decide.

G71exit 0vlmkit check integrity index.html

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

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

output, 9 line(s), 7.3s
vlmkit check integrity
source: index.html

verdict: CLEAN (0 fail, 0 warn, 0 exempted)
  1280x800: 1 component(s), ink 93.8%, 107 text block(s)
  768x900: 1 component(s), ink 92.7%, 106 text block(s)
  375x700: 1 component(s), ink 92.8%, 105 text block(s)

No integrity defects detected.
V37verified D37 by L41

The desktop and tablet breaks now fall at the sentence boundary; the phone version is unchanged, and integrity is still clean after the change.

N23decision

Independent review: integrity, composition, color and contrast re-run green; the builder's two exit-1 gates (check copy's state-only line, check a11y focus's viewport-coordinate reverses) stay closed by its notes, and I read both false-positive claims against the shots — they hold. Of 22 fresh screens, one editorial defect (D37, the pull quote's break) was worth fixing.

done

Reviewer round: one eye-found defect fixed and verified; everything else the builder shipped holds up at desktop, tablet and phone.