rst-stats=pairs: two stats to a line on a phone, where the page asks
On a phone, 1.0's stat band is a wrapping flex row of 9rem cells: at 320px it stacks one stat to a line, four short figures a long scroll apart, and at 390px it pairs them with the leading hairline on the third cell and no rule between the pairs. A page whose figures are short can now say so: below 34rem a band marked rst-stats="pairs" is a two-column grid, its cells padded a step tighter in the block direction, the first of each pair on the band's edge with no leading hairline, and the cells from the third on ruled off above. It is opt-in for all of 1.x: a band with a lead or a long figure wants the whole line, which the page knows and the CSS does not, and a 1.0 page's band must not reflow. Every rule positively requires the new value, in both spellings (.rst-stats--pairs), inside the phone block, so the promise gates pass with no exception and no widening. TestPairsPutTwoStatsOnALineOnAPhone reads the new stat-band state at 390 and 320, left to right and in Arabic: pairs sharing a top, the hairlines on the right cells, each figure inside its cell at 320 and no sideways scroll; and at 1280 photographs the band against the same band unmarked, at zero tolerance on a rig that rasters on one thread. It was red by assertion with the example in and no CSS (the third cell's leading hairline, no rule above the second pair, and at 320 four stacked cells). The class-spelling fixture gains a pairs band (outside the plan's files), since the both-spellings drive refused a class tokens.css styles and the fixture never renders. The label "Two to a line on a phone" and its note are the approved English, byte for byte. Their translations in the eleven gallery catalogs are machine drafts from that English, not reviewed; drafts.json names each. The state reuses the default state's words, so no sample phrase is new. Heights from the drives: Desktop needs 173px, Mobile en 308, ar, ga and ru 327; the table adds slack. Size, gzip level 6 (allotment 150, on target): fiesta.css 23,724 -> 23,801 (+77) fiesta-plain.css 23,005 -> 23,082 (+77) fiesta-signal.css 23,118 -> 23,195 (+77)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
19 files changed,
+288
−1
check/phone_variants_browser_test.go+178 −0check/testdata/fixtures/spelling-class.html+1 −0css/tokens.css+22 −0examples/examples.json+5 −0examples/prose.json+4 −1examples/stat-band/two-to-a-line-on-a-phone.html+19 −0internal/gallery/heights.go+5 −0internal/gallery/i18n/ar.json+2 −0internal/gallery/i18n/bn.json+2 −0internal/gallery/i18n/drafts.json+32 −0internal/gallery/i18n/es.json+2 −0internal/gallery/i18n/ga.json+2 −0internal/gallery/i18n/hi.json+2 −0internal/gallery/i18n/ja.json+2 −0internal/gallery/i18n/pt-PT.json+2 −0internal/gallery/i18n/ru.json+2 −0internal/gallery/i18n/vi.json+2 −0internal/gallery/i18n/yue.json+2 −0internal/gallery/i18n/zh-Hans.json+2 −0
CI failed — run details
CI log
=== gofmt ===
=== no-rastrillo ===
go test -run '^(TestFiestaNeverImportsRastrillo|TestThePublicPackagesLinkNoBrowser)$' -count=1 .
ok amadan.net/rastrillo/fiesta 0.216s
=== size ===
go test ./internal/build -run '^TestTheOneLinkIsUnder25KiBGzipped$' -count=1 -v
=== RUN TestTheOneLinkIsUnder25KiBGzipped
build_test.go:138: fiesta-plain.css: 158193 bytes, 23082 bytes gzipped (22.5 KiB of the 25.0 KiB limit)
build_test.go:138: fiesta-signal.css: 158288 bytes, 23195 bytes gzipped (22.7 KiB of the 25.0 KiB limit)
build_test.go:138: fiesta.css: 161107 bytes, 23801 bytes gzipped (23.2 KiB of the 25.0 KiB limit)
--- PASS: TestTheOneLinkIsUnder25KiBGzipped (0.03s)
PASS
ok amadan.net/rastrillo/fiesta/internal/build 0.029s
=== history ===
history: 29 commits; release tags: v1.0.0
=== suite ===
--- shard 0 of 48 ---
==> shard 0 of 48: make root
go build ./...
go vet ./...
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh root 'internal/gallery@3 cmd/fiesta@2 internal/www@2'
ok amadan.net/rastrillo/fiesta 3.151s
ok amadan.net/rastrillo/fiesta/check 6.215s
ok amadan.net/rastrillo/fiesta/example 0.318s
? amadan.net/rastrillo/fiesta/hack/seed/english [no test files]
ok amadan.net/rastrillo/fiesta/internal/axe 0.130s
ok amadan.net/rastrillo/fiesta/internal/build 1.637s
ok amadan.net/rastrillo/fiesta/internal/codeview 0.090s
? amadan.net/rastrillo/fiesta/internal/harness [no test files]
ok amadan.net/rastrillo/fiesta/internal/markup 0.055s
ok amadan.net/rastrillo/fiesta/internal/nodetest 0.297s
ok amadan.net/rastrillo/fiesta/internal/site 2.895s
ok amadan.net/rastrillo/fiesta/internal/tokens 0.016s
suite: root took 23s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m11.010000s 0m2.110000s
--- shard 1 of 48 ---
==> shard 1 of 48: make test.internal.gallery~1of3
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'internal.gallery~1of3'
gotest: slice 1 of 3 of ./internal/gallery/ runs 36 of 108 test tests
ok amadan.net/rastrillo/fiesta/internal/gallery 91.727s
suite: test.internal.gallery~1of3 took 107s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m51.510000s 0m1.410000s
--- shard 2 of 48 ---
==> shard 2 of 48: make test.internal.gallery~2of3
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'internal.gallery~2of3'
gotest: slice 2 of 3 of ./internal/gallery/ runs 36 of 108 test tests
ok amadan.net/rastrillo/fiesta/internal/gallery 90.732s
suite: test.internal.gallery~2of3 took 105s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m54.250000s 0m1.430000s
--- shard 3 of 48 ---
==> shard 3 of 48: make test.internal.gallery~3of3
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'internal.gallery~3of3'
gotest: slice 3 of 3 of ./internal/gallery/ runs 36 of 108 test tests
ok amadan.net/rastrillo/fiesta/internal/gallery 85.983s
suite: test.internal.gallery~3of3 took 100s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m49.480000s 0m1.500000s
--- shard 4 of 48 ---
==> shard 4 of 48: make test.cmd.fiesta~1of2
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'cmd.fiesta~1of2'
gotest: slice 1 of 2 of ./cmd/fiesta/ runs 7 of 12 test tests
ok amadan.net/rastrillo/fiesta/cmd/fiesta 74.579s
suite: test.cmd.fiesta~1of2 took 89s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m33.480000s 0m2.380000s
--- shard 5 of 48 ---
==> shard 5 of 48: make test.cmd.fiesta~2of2
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'cmd.fiesta~2of2'
gotest: slice 2 of 2 of ./cmd/fiesta/ runs 5 of 12 test tests
ok amadan.net/rastrillo/fiesta/cmd/fiesta 80.055s
suite: test.cmd.fiesta~2of2 took 95s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m36.340000s 0m2.580000s
--- shard 6 of 48 ---
==> shard 6 of 48: make test.internal.www~1of2
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'internal.www~1of2'
gotest: slice 1 of 2 of ./internal/www/ runs 11 of 25 test tests
ok amadan.net/rastrillo/fiesta/internal/www 92.093s
suite: test.internal.www~1of2 took 107s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m48.250000s 0m1.690000s
--- shard 7 of 48 ---
==> shard 7 of 48: make test.internal.www~2of2
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 FIESTA_TEST_REQUIRE_TAGS=1 ./hack/gotest.sh test 'internal.www~2of2'
gotest: slice 2 of 2 of ./internal/www/ runs 14 of 25 test tests
ok amadan.net/rastrillo/fiesta/internal/www 88.023s
suite: test.internal.www~2of2 took 103s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m45.830000s 0m1.810000s
--- shard 8 of 48 ---
==> shard 8 of 48: make staticcheck
go run honnef.co/go/tools/cmd/staticcheck@v0.8.2 -tags browser ./...
suite: staticcheck took 20s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m4.670000s 0m0.590000s
--- shard 9 of 48 ---
==> shard 9 of 48: make govulncheck
go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./...
=== Symbol Results ===
No vulnerabilities found.
Your code is affected by 0 vulnerabilities.
This scan also found 2 vulnerabilities in packages you import and 5
vulnerabilities in modules you require, but your code doesn't appear to call
these vulnerabilities.
Use '-show verbose' for more details.
suite: govulncheck took 20s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m3.050000s 0m0.410000s
--- shard 10 of 48 ---
==> shard 10 of 48: make gitleaks
go run github.com/zricethezav/gitleaks/v8@v8.30.1 git --no-banner --redact --log-opts='--full-history --diff-filter=tuxdb HEAD' .
[90m7:42AM[0m [32mINF[0m [1mUnknown SCM platform. Use --platform to include links in findings.[0m [36mhost=[0mamadan.net
[90m7:42AM[0m [32mINF[0m [1m29 commits scanned.[0m
[90m7:42AM[0m [32mINF[0m [1mscanned ~8400304 bytes (8.40 MB) in 5.05s[0m
[90m7:42AM[0m [32mINF[0m [1mno leaks found[0m
suite: gitleaks took 22s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m7.100000s 0m0.340000s
--- shard 11 of 48 ---
==> shard 11 of 48: make browser.internal.harness
./hack/gotest.sh browser 'internal.harness'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: ./internal/harness/ runs its 10 browser tests
ok amadan.net/rastrillo/fiesta/internal/harness 12.466s
suite: browser.internal.harness took 28s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m1.690000s 0m1.360000s
--- shard 12 of 48 ---
==> shard 12 of 48: make browser.check~1of13
./hack/gotest.sh browser 'check~1of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 1 of 13 of ./check/ runs 17 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 132.037s
suite: browser.check~1of13 took 151s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m51.000000s 0m14.870000s
--- shard 13 of 48 ---
==> shard 13 of 48: make browser.check~2of13
./hack/gotest.sh browser 'check~2of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 2 of 13 of ./check/ runs 16 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 132.533s
suite: browser.check~2of13 took 151s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m52.840000s 0m13.970000s
--- shard 14 of 48 ---
==> shard 14 of 48: make browser.check~3of13
./hack/gotest.sh browser 'check~3of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 3 of 13 of ./check/ runs 16 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 127.716s
suite: browser.check~3of13 took 146s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m44.440000s 0m11.810000s
--- shard 15 of 48 ---
==> shard 15 of 48: make browser.check~4of13
./hack/gotest.sh browser 'check~4of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 4 of 13 of ./check/ runs 16 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 129.990s
suite: browser.check~4of13 took 148s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m55.110000s 0m16.240000s
--- shard 16 of 48 ---
==> shard 16 of 48: make browser.check~5of13
./hack/gotest.sh browser 'check~5of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 5 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 118.137s
suite: browser.check~5of13 took 137s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m40.590000s 0m13.420000s
--- shard 17 of 48 ---
==> shard 17 of 48: make browser.check~6of13
./hack/gotest.sh browser 'check~6of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 6 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 116.192s
suite: browser.check~6of13 took 135s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m45.270000s 0m14.440000s
--- shard 18 of 48 ---
==> shard 18 of 48: make browser.check~7of13
./hack/gotest.sh browser 'check~7of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 7 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 123.907s
suite: browser.check~7of13 took 143s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m46.930000s 0m14.340000s
--- shard 19 of 48 ---
==> shard 19 of 48: make browser.check~8of13
./hack/gotest.sh browser 'check~8of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 8 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 134.456s
suite: browser.check~8of13 took 153s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m49.420000s 0m16.630000s
--- shard 20 of 48 ---
==> shard 20 of 48: make browser.check~9of13
./hack/gotest.sh browser 'check~9of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 9 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 106.857s
suite: browser.check~9of13 took 125s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m31.970000s 0m9.460000s
--- shard 21 of 48 ---
==> shard 21 of 48: make browser.check~10of13
./hack/gotest.sh browser 'check~10of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 10 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 120.699s
suite: browser.check~10of13 took 139s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m41.870000s 0m13.080000s
--- shard 22 of 48 ---
==> shard 22 of 48: make browser.check~11of13
./hack/gotest.sh browser 'check~11of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 11 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 123.611s
suite: browser.check~11of13 took 142s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m45.980000s 0m14.590000s
--- shard 23 of 48 ---
==> shard 23 of 48: make browser.check~12of13
./hack/gotest.sh browser 'check~12of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 12 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 123.841s
suite: browser.check~12of13 took 142s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m47.850000s 0m15.900000s
--- shard 24 of 48 ---
==> shard 24 of 48: make browser.check~13of13
./hack/gotest.sh browser 'check~13of13'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: slice 13 of 13 of ./check/ runs 18 of 227 browser tests
ok amadan.net/rastrillo/fiesta/check 120.117s
suite: browser.check~13of13 took 138s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m40.150000s 0m11.390000s
--- shard 25 of 48 ---
==> shard 25 of 48: make browser.internal.gallery~1of18
./hack/gotest.sh browser 'internal.gallery~1of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 1 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 61.457s
suite: browser.internal.gallery~1of18 took 79s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m16.260000s 0m4.050000s
--- shard 26 of 48 ---
==> shard 26 of 48: make browser.internal.gallery~2of18
./hack/gotest.sh browser 'internal.gallery~2of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 2 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 59.016s
suite: browser.internal.gallery~2of18 took 77s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m13.820000s 0m2.750000s
--- shard 27 of 48 ---
==> shard 27 of 48: make browser.internal.gallery~3of18
./hack/gotest.sh browser 'internal.gallery~3of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 3 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 77.126s
suite: browser.internal.gallery~3of18 took 94s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m16.270000s 0m4.100000s
--- shard 28 of 48 ---
==> shard 28 of 48: make browser.internal.gallery~4of18
./hack/gotest.sh browser 'internal.gallery~4of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 4 of 18 of ./internal/gallery/ runs 6 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 61.923s
suite: browser.internal.gallery~4of18 took 79s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m14.470000s 0m3.030000s
--- shard 29 of 48 ---
==> shard 29 of 48: make browser.internal.gallery~5of18
./hack/gotest.sh browser 'internal.gallery~5of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 5 of 18 of ./internal/gallery/ runs 6 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 82.531s
suite: browser.internal.gallery~5of18 took 99s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m19.490000s 0m5.410000s
--- shard 30 of 48 ---
==> shard 30 of 48: make browser.internal.gallery~6of18
./hack/gotest.sh browser 'internal.gallery~6of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 6 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 72.779s
suite: browser.internal.gallery~6of18 took 90s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m16.390000s 0m3.920000s
--- shard 31 of 48 ---
==> shard 31 of 48: make browser.internal.gallery~7of18
./hack/gotest.sh browser 'internal.gallery~7of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 7 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 69.952s
suite: browser.internal.gallery~7of18 took 87s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m14.260000s 0m2.940000s
--- shard 32 of 48 ---
==> shard 32 of 48: make browser.internal.gallery~8of18
./hack/gotest.sh browser 'internal.gallery~8of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 8 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 77.380s
suite: browser.internal.gallery~8of18 took 95s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m18.330000s 0m4.720000s
--- shard 33 of 48 ---
==> shard 33 of 48: make browser.internal.gallery~9of18
./hack/gotest.sh browser 'internal.gallery~9of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 9 of 18 of ./internal/gallery/ runs 6 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 97.934s
suite: browser.internal.gallery~9of18 took 115s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m23.740000s 0m7.580000s
--- shard 34 of 48 ---
==> shard 34 of 48: make browser.internal.gallery~10of18
./hack/gotest.sh browser 'internal.gallery~10of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 10 of 18 of ./internal/gallery/ runs 2 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 75.553s
suite: browser.internal.gallery~10of18 took 93s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m14.550000s 0m2.770000s
--- shard 35 of 48 ---
==> shard 35 of 48: make browser.internal.gallery~11of18
./hack/gotest.sh browser 'internal.gallery~11of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 11 of 18 of ./internal/gallery/ runs 2 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 74.749s
suite: browser.internal.gallery~11of18 took 92s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m14.740000s 0m2.980000s
--- shard 36 of 48 ---
==> shard 36 of 48: make browser.internal.gallery~12of18
./hack/gotest.sh browser 'internal.gallery~12of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 12 of 18 of ./internal/gallery/ runs 2 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 98.109s
suite: browser.internal.gallery~12of18 took 115s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m19.220000s 0m5.160000s
--- shard 37 of 48 ---
==> shard 37 of 48: make browser.internal.gallery~13of18
./hack/gotest.sh browser 'internal.gallery~13of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 13 of 18 of ./internal/gallery/ runs 4 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 94.449s
suite: browser.internal.gallery~13of18 took 112s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m19.450000s 0m5.420000s
--- shard 38 of 48 ---
==> shard 38 of 48: make browser.internal.gallery~14of18
./hack/gotest.sh browser 'internal.gallery~14of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 14 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 96.939s
suite: browser.internal.gallery~14of18 took 114s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m20.250000s 0m5.630000s
--- shard 39 of 48 ---
==> shard 39 of 48: make browser.internal.gallery~15of18
./hack/gotest.sh browser 'internal.gallery~15of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 15 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 99.829s
suite: browser.internal.gallery~15of18 took 117s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m20.080000s 0m5.790000s
--- shard 40 of 48 ---
==> shard 40 of 48: make browser.internal.gallery~16of18
./hack/gotest.sh browser 'internal.gallery~16of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 16 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 90.680s
suite: browser.internal.gallery~16of18 took 108s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m17.290000s 0m4.650000s
--- shard 41 of 48 ---
==> shard 41 of 48: make browser.internal.gallery~17of18
./hack/gotest.sh browser 'internal.gallery~17of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 17 of 18 of ./internal/gallery/ runs 5 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 96.986s
suite: browser.internal.gallery~17of18 took 114s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m19.840000s 0m5.700000s
--- shard 42 of 48 ---
==> shard 42 of 48: make browser.internal.gallery~18of18
./hack/gotest.sh browser 'internal.gallery~18of18'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 18 of 18 of ./internal/gallery/ runs 6 of 84 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery 99.601s
suite: browser.internal.gallery~18of18 took 117s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m21.520000s 0m6.450000s
--- shard 43 of 48 ---
==> shard 43 of 48: make browser.internal.gallery.history
./hack/gotest.sh browser 'internal.gallery.history'
gotest: on ip-172-31-24-129, driving /opt/amadan-browser/chromium-1234/chrome-linux/chrome
gotest: ./internal/gallery/history/ runs its 3 browser tests
ok amadan.net/rastrillo/fiesta/internal/gallery/history 50.996s
suite: browser.internal.gallery.history took 66s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m22.070000s 0m2.190000s
--- shard 44 of 48 ---
==> shard 44 of 48: make browser.internal.www~1of4
./hack/gotest.sh browser 'internal.www~1of4'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 1 of 4 of ./internal/www/ runs 4 of 22 browser tests
--- FAIL: TestAScrollAfterIdleWakesTheBunting (39.00s)
landing_browser_test.go:1426: one 80 px scroll after twenty idle seconds moved 0.45% of the canvas within a second
landing_browser_test.go:1428: one 80 px scroll after twenty idle seconds moved 0.45% of the canvas; want at least 1%: the cloth never woke
FAIL
FAIL amadan.net/rastrillo/fiesta/internal/www 88.518s
FAIL
make[1]: *** [Makefile:234: browser.internal.www~1of4] Error 1
suite: browser.internal.www~1of4 took 105s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m32.460000s 0m2.260000s
make: *** [Makefile:76: suite] Error 2
amadan: step suite shard 44 of 48 failed: exit status 2
--- shard 45 of 48 ---
==> shard 45 of 48: make browser.internal.www~2of4
./hack/gotest.sh browser 'internal.www~2of4'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 2 of 4 of ./internal/www/ runs 6 of 22 browser tests
ok amadan.net/rastrillo/fiesta/internal/www 97.252s
suite: browser.internal.www~2of4 took 114s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m46.740000s 0m2.840000s
--- shard 46 of 48 ---
==> shard 46 of 48: make browser.internal.www~3of4
./hack/gotest.sh browser 'internal.www~3of4'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 3 of 4 of ./internal/www/ runs 6 of 22 browser tests
--- FAIL: TestAShakeMovesTheBuntingMoreThanAScroll (28.85s)
landing_browser_test.go:1362: motion over three seconds, off() integrated over time: the slow scroll 9.23, the shake 10.14 %·s (1.1 times)
landing_browser_test.go:1367: the shake moved the canvas 10.14 %·s and the slow scroll 9.23; want the shake at least 1.8 times the scroll
FAIL
FAIL amadan.net/rastrillo/fiesta/internal/www 109.659s
FAIL
make[1]: *** [Makefile:234: browser.internal.www~3of4] Error 1
suite: browser.internal.www~3of4 took 126s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m53.920000s 0m3.140000s
make: *** [Makefile:76: suite] Error 2
amadan: step suite shard 46 of 48 failed: exit status 2
--- shard 47 of 48 ---
==> shard 47 of 48: make browser.internal.www~4of4
./hack/gotest.sh browser 'internal.www~4of4'
gotest: on ip-172-31-24-129, driving the harness's own choice (/usr/local/bin/chromium)
gotest: slice 4 of 4 of ./internal/www/ runs 6 of 22 browser tests
ok amadan.net/rastrillo/fiesta/internal/www 110.591s
suite: browser.internal.www~4of4 took 127s; CPU, user then system, of this shell and then of the role:
0m0.000000s 0m0.000000s
0m47.020000s 0m3.030000s
amadan: job failed at step suite shards 44, 46 of 48 — its output is above, not at the tail of this log
Intent
diff --git a/check/phone_variants_browser_test.go b/check/phone_variants_browser_test.go| new file mode 100644 |
| index 0000000..9b87f44 |
| --- /dev/null |
| +++ b/check/phone_variants_browser_test.go |
| @@ -0,0 +1,178 @@ |
| +//go:build browser |
| + |
| +// Two layouts a page asks for on a phone, by an attribute value 1.0 |
| +// never had: a stat band two to a line, and a short status kept on its |
| +// row's first line. Each is held where it applies, below 34rem in both |
| +// directions, and where it must not: at 1280 the marked markup paints |
| +// pixel for pixel what the unmarked markup paints, so the value changes |
| +// a phone and nothing else. |
| +package check |
| + |
| +import ( |
| + "context" |
| + "fmt" |
| + "strings" |
| + "testing" |
| + "time" |
| + |
| + "github.com/chromedp/chromedp" |
| + |
| + "amadan.net/rastrillo/fiesta" |
| + "amadan.net/rastrillo/fiesta/example" |
| + "amadan.net/rastrillo/fiesta/internal/harness" |
| +) |
| + |
| +// stateDoc is one state of an example as a document, its assets |
| +// flattened beside the page as the sizing mux serves them, found by |
| +// its label so a renamed state fails here by name rather than reading |
| +// some other state. |
| +func stateDoc(t *testing.T, name, label string) string { |
| + t.Helper() |
| + entry, ok := manifest(t).Entry(name) |
| + if !ok { |
| + t.Fatalf("examples.json has no %s entry", name) |
| + } |
| + for _, s := range entry.States { |
| + if s.Label == label { |
| + doc, err := example.Document(fiesta.FS(), name, s.ID) |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + return parityLinks(doc) |
| + } |
| + } |
| + t.Fatalf("examples.json has no %s state labelled %q", name, label) |
| + return "" |
| +} |
| + |
| +// swapped is doc with was replaced by is exactly once, so a fixture |
| +// edit that no longer finds its text fails rather than testing the |
| +// unedited document twice. |
| +func swapped(t *testing.T, doc, was, is string) string { |
| + t.Helper() |
| + if strings.Count(doc, was) != 1 { |
| + t.Fatalf("the document holds %q %d times; this edit needs it once", was, strings.Count(doc, was)) |
| + } |
| + return strings.Replace(doc, was, is, 1) |
| +} |
| + |
| +// phoneVariantRig serves pages in a browser that rasters on one |
| +// thread, so the 1280 comparisons can hold zero tolerance: a pixel |
| +// painted twice the same way is the same pixel. |
| +func phoneVariantRig(t *testing.T, pages map[string]string) (*harness.Rig, context.Context) { |
| + t.Helper() |
| + rig := sizingRig(t, false, pages, harness.WithDeterministicRaster()) |
| + ctx, cancel := context.WithTimeout(rig.Context(), 120*time.Second) |
| + t.Cleanup(cancel) |
| + return rig, ctx |
| +} |
| + |
| +// sameAtDesktop photographs the two paths at 1280 and fails unless they |
| +// are the same to the pixel: what proves a phone layout leaves a |
| +// desktop alone. |
| +func sameAtDesktop(t *testing.T, ctx context.Context, origin, marked, plain, what string) { |
| + t.Helper() |
| + a := pageShot(t, ctx, origin+marked, 1280, "light") |
| + b := pageShot(t, ctx, origin+plain, 1280, "light") |
| + if same, why := samePixelsWithin(t, a, b, 0); !same { |
| + t.Errorf("at 1280 %s paints differently from the same markup unmarked (%s): the value must change a phone only", what, why) |
| + } |
| +} |
| + |
| +// statCell is one cell of a band as the pairs test reads it: its box, |
| +// its two leading hairlines as computed, and its figure's box. |
| +type statCell struct { |
| + Left, Right, Top, Bottom float64 |
| + Start, BlockStart string |
| + Num struct{ Left, Right, Top, Bottom float64 } |
| +} |
| + |
| +type bandReading struct { |
| + Cells []statCell |
| + RTL bool |
| + DocScroll, DocClient float64 |
| +} |
| + |
| +const bandJS = `(() => { |
| + const band = document.querySelector("[rst-stats]"); |
| + const box = (el) => { const r = el.getBoundingClientRect(); return {Left: r.left, Right: r.right, Top: r.top, Bottom: r.bottom}; }; |
| + return JSON.stringify({RTL: getComputedStyle(band).direction === "rtl", |
| + Cells: [...band.children].map((c) => { const cs = getComputedStyle(c); |
| + return {...box(c), Start: cs.borderInlineStartWidth, BlockStart: cs.borderBlockStartWidth, Num: box(c.querySelector("[rst-stat-num]"))}; }), |
| + DocScroll: document.documentElement.scrollWidth, DocClient: document.documentElement.clientWidth}); |
| +})()` |
| + |
| +func readBand(t *testing.T, ctx context.Context, url string, width int64) bandReading { |
| + t.Helper() |
| + mustRun(t, ctx, chromedp.EmulateViewport(width, 844), chromedp.Navigate(url), chromedp.WaitReady("[rst-stats]", chromedp.ByQuery)) |
| + settleUntil(t, ctx, `document.readyState === "complete"`) |
| + var b bandReading |
| + at(t, ctx, bandJS, &b) |
| + if len(b.Cells) != 4 { |
| + t.Fatalf("%s: the band holds %d stats; the state has four", url, len(b.Cells)) |
| + } |
| + return b |
| +} |
| + |
| +// TestPairsPutTwoStatsOnALineOnAPhone: at 390 and 320 a band marked |
| +// pairs is two columns: stats 1 and 2 share a top, 3 and 4 share one |
| +// below them, the first of each pair has no hairline at its inline |
| +// start (the band's edge is there) and the second has one, and the |
| +// second pair has a hairline above it. At 320 each figure stays inside |
| +// its cell and the page does not scroll sideways. In Arabic the pairs |
| +// mirror: the first stat of a pair is on the right. At 1280 the band |
| +// is the band without the value, pixel for pixel. |
| +func TestPairsPutTwoStatsOnALineOnAPhone(t *testing.T) { |
| + doc := stateDoc(t, "stat-band", "Two to a line on a phone") |
| + plain := swapped(t, doc, `<div rst-stats="pairs">`, `<div rst-stats>`) |
| + rig, ctx := phoneVariantRig(t, map[string]string{ |
| + "/": doc, "/rtl": inArabic(t, doc), "/plain": plain, "/plain-rtl": inArabic(t, plain), |
| + }) |
| + for _, path := range []string{"/", "/rtl"} { |
| + for _, width := range []int64{390, 320} { |
| + leg := fmt.Sprintf("%s at %d", path, width) |
| + b := readBand(t, ctx, rig.Origin+path, width) |
| + if b.RTL != (path == "/rtl") { |
| + t.Fatalf("%s: the band reads right to left %v; this leg needs %v", leg, b.RTL, path == "/rtl") |
| + } |
| + c := b.Cells |
| + if !sameEdge(c[0].Top, c[1].Top) || !sameEdge(c[2].Top, c[3].Top) { |
| + t.Errorf("%s: the stats' tops are %.1f, %.1f, %.1f, %.1f; stats 1 and 2 must share a line, and 3 and 4", leg, c[0].Top, c[1].Top, c[2].Top, c[3].Top) |
| + } |
| + if c[2].Top < c[0].Bottom-0.5 { |
| + t.Errorf("%s: the second pair starts at %.1f, above the first pair's foot at %.1f", leg, c[2].Top, c[0].Bottom) |
| + } |
| + // The first of a pair is at the inline start: the left in |
| + // English, the right in Arabic. |
| + for _, p := range [][2]int{{0, 1}, {2, 3}} { |
| + first, second := c[p[0]], c[p[1]] |
| + if (!b.RTL && first.Left >= second.Left) || (b.RTL && first.Right <= second.Right) { |
| + t.Errorf("%s: stat %d (%.1f to %.1f) is not at the inline start of stat %d (%.1f to %.1f)", leg, p[0]+1, first.Left, first.Right, p[1]+1, second.Left, second.Right) |
| + } |
| + } |
| + for i, want := range []string{"0px", "1px", "0px", "1px"} { |
| + if c[i].Start != want { |
| + t.Errorf("%s: stat %d's inline-start hairline is %s, want %s", leg, i+1, c[i].Start, want) |
| + } |
| + } |
| + for i, want := range []string{"0px", "0px", "1px", "1px"} { |
| + if c[i].BlockStart != want { |
| + t.Errorf("%s: stat %d's top hairline is %s, want %s", leg, i+1, c[i].BlockStart, want) |
| + } |
| + } |
| + if width != 320 { |
| + continue |
| + } |
| + for i, cell := range c { |
| + if n := cell.Num; n.Left < cell.Left-0.5 || n.Right > cell.Right+0.5 { |
| + t.Errorf("%s: stat %d's figure runs %.1f to %.1f, outside its cell's %.1f to %.1f", leg, i+1, n.Left, n.Right, cell.Left, cell.Right) |
| + } |
| + } |
| + if b.DocScroll > b.DocClient { |
| + t.Errorf("%s: the page is %.0fpx wide in a %.0fpx viewport; it scrolls sideways", leg, b.DocScroll, b.DocClient) |
| + } |
| + } |
| + } |
| + sameAtDesktop(t, ctx, rig.Origin, "/", "/plain", `rst-stats="pairs"`) |
| + sameAtDesktop(t, ctx, rig.Origin, "/rtl", "/plain-rtl", `rst-stats="pairs" in Arabic`) |
| +} |
diff --git a/check/testdata/fixtures/spelling-class.html b/check/testdata/fixtures/spelling-class.html| index 5d08112..24f4f61 100644 |
| --- a/check/testdata/fixtures/spelling-class.html |
| +++ b/check/testdata/fixtures/spelling-class.html |
| @@ -70,6 +70,7 @@ |
| <div class="rst-snippet" ><code dir="ltr" translate="no">fiesta.css</code><button class="rst-btn rst-btn--sm rst-snippet__copy" type="button">Copy</button><span class="rst-snippet__status" role="status">Copied</span></div> |
| <div class="rst-side" ><nav class="rst-side__nav" aria-label="Settings"><a href="#a" aria-current="page">General</a><a href="#a">Members</a></nav><div><h2>General</h2></div></div> |
| <div style="inline-size: 300px"><div class="rst-side" ><nav class="rst-side__nav" aria-label="Settings"><a href="#a" aria-current="page">General</a><a href="#a">Members</a></nav><div><h2>General</h2></div></div></div> |
| + <div class="rst-stats rst-stats--pairs" ><div class="rst-stat" ><span class="rst-stat__label" >Revenue</span><span class="rst-stat__num" >€48,210</span></div><div class="rst-stat" ><span class="rst-stat__label" >Orders</span><span class="rst-stat__num" >318</span></div><div class="rst-stat" ><span class="rst-stat__label" >Basket</span><span class="rst-stat__num" >€41.20</span></div><div class="rst-stat" ><span class="rst-stat__label" >Refunds</span><span class="rst-stat__num" >7</span></div></div> |
| <form class="rst-form" method="post" action="#a"> |
| <div class="rst-form-flow" > |
diff --git a/css/tokens.css b/css/tokens.css| index f63f31f..fbf0659 100644 |
| --- a/css/tokens.css |
| +++ b/css/tokens.css |
| @@ -1460,6 +1460,28 @@ body { |
| .rst-page-header h1, [rst-page-header] h1 { |
| font-size: min(var(--rst-title-size, 1.375rem), 1.25rem); |
| } |
| + /* A band the page marks pairs is two columns. The wrapping flex row |
| + above stacks a phone's band one stat to a line at 320px, four short |
| + figures four screens of scroll apart, and pairs them at 390px with |
| + the leading hairline on the wrong cell. The grid pairs them at |
| + every phone width; the first of each pair sits on the band's edge, |
| + so it drops the leading hairline, and the second pair is ruled off |
| + from the first. Opt-in, because a 1.0 page's band must not reflow: |
| + a lead or a long figure wants the whole line, which the page knows |
| + and the CSS does not. */ |
| + .rst-stats--pairs, [rst-stats~="pairs"] { |
| + display: grid; |
| + grid-template-columns: 1fr 1fr; |
| + } |
| + .rst-stats--pairs > .rst-stat, [rst-stats~="pairs"] > [rst-stat] { |
| + padding: var(--rst-sp-3) var(--rst-sp-4); |
| + } |
| + .rst-stats--pairs > .rst-stat:nth-child(odd), [rst-stats~="pairs"] > [rst-stat]:nth-child(odd) { |
| + border-inline-start: 0; |
| + } |
| + .rst-stats--pairs > .rst-stat:nth-child(n+3), [rst-stats~="pairs"] > [rst-stat]:nth-child(n+3) { |
| + border-block-start: 1px solid var(--rst-line); |
| + } |
| } |
| /* ── The structural idioms: box, list grid, row-menu, dropdown, ftok ── */ |
diff --git a/examples/examples.json b/examples/examples.json| index 99e859f..f4981c3 100644 |
| --- a/examples/examples.json |
| +++ b/examples/examples.json |
| @@ -1572,6 +1572,11 @@ |
| "id": "default", |
| "label": "", |
| "sampleURLs": [] |
| + }, |
| + { |
| + "id": "two-to-a-line-on-a-phone", |
| + "label": "Two to a line on a phone", |
| + "sampleURLs": [] |
| } |
| ] |
| }, |
diff --git a/examples/prose.json b/examples/prose.json| index 0e90e8f..6da2ddf 100644 |
| --- a/examples/prose.json |
| +++ b/examples/prose.json |
| @@ -364,7 +364,10 @@ |
| } |
| }, |
| "stat-band": { |
| - "blurb": "A row of stats across the top of a dashboard." |
| + "blurb": "A row of stats across the top of a dashboard.", |
| + "states": { |
| + "two-to-a-line-on-a-phone": "rst-stats=\"pairs\" puts two stats on a line on a phone. Without it they stack one to a line." |
| + } |
| }, |
| "status-pill": { |
| "blurb": "A record's status as a tinted pill, colour and label.", |
diff --git a/examples/stat-band/two-to-a-line-on-a-phone.html b/examples/stat-band/two-to-a-line-on-a-phone.html| new file mode 100644 |
| index 0000000..d0d7265 |
| --- /dev/null |
| +++ b/examples/stat-band/two-to-a-line-on-a-phone.html |
| @@ -0,0 +1,19 @@ |
| +<!doctype html> |
| +<html lang="en" dir="ltr"> |
| +<head> |
| +<meta charset="utf-8"> |
| +<meta name="viewport" content="width=device-width"> |
| +<title>stat-band: Two to a line on a phone</title> |
| +<link rel="stylesheet" href="../../css/tokens.css"> |
| +<link rel="stylesheet" href="../../css/themes/day.css"> |
| +<script defer src="../../js/light.js"></script> |
| +</head> |
| +<body> |
| +<div rst-stats="pairs"> |
| + <div rst-stat><span rst-stat-label>Revenue this month</span><span rst-stat-num>€48,210</span><span rst-stat-delta rst-tone="positive">+12%</span><span rst-stat-note>vs. last month</span></div> |
| + <div rst-stat><span rst-stat-label>Orders today</span><span rst-stat-num>318</span></div> |
| + <div rst-stat><span rst-stat-label>Average basket</span><span rst-stat-num>€41.20</span><span rst-stat-delta rst-tone="negative">−3%</span></div> |
| + <div rst-stat><span rst-stat-label>Refunds</span><span rst-stat-num>7</span></div> |
| +</div> |
| +</body> |
| +</html> |
diff --git a/internal/gallery/heights.go b/internal/gallery/heights.go| index b450bdf..4d58ff6 100644 |
| --- a/internal/gallery/heights.go |
| +++ b/internal/gallery/heights.go |
| @@ -187,6 +187,7 @@ var previewHeights = map[string]int{ |
| "signin/when-keymail-was-offered-and-a-link-went-out": 390, |
| "snippet/a-line-to-copy": 110, |
| "stat-band/default": 190, |
| + "stat-band/two-to-a-line-on-a-phone": 180, |
| "stat/a-shortened-number": 140, |
| "stat/a-smaller-number": 140, |
| "stat/the-big-number": 190, |
| @@ -238,6 +239,7 @@ var previewMobileHeights = map[string]int{ |
| "signin/when-keymail-was-offered-and-a-link-went-out": 660, |
| "snippet/a-line-to-copy": 180, |
| "stat-band/default": 460, |
| + "stat-band/two-to-a-line-on-a-phone": 310, |
| "status-pill/row": 180, |
| } |
| @@ -247,6 +249,7 @@ var previewMobileHeights = map[string]int{ |
| var previewMobileLocaleHeights = map[string]map[string]int{ |
| "ar": { |
| "api-tokens/four-tokens-two-of-them-live": 1880, |
| + "stat-band/two-to-a-line-on-a-phone": 330, |
| }, |
| "bn": { |
| "form-layout/default": 510, |
| @@ -296,6 +299,7 @@ var previewMobileLocaleHeights = map[string]map[string]int{ |
| "signin/when-keymail-could-not-confirm-it": 730, |
| "signin/when-keymail-was-offered-and-a-link-went-out": 720, |
| "snippet/a-line-to-copy": 200, |
| + "stat-band/two-to-a-line-on-a-phone": 330, |
| }, |
| "ja": { |
| "api-tokens/four-tokens-two-of-them-live": 1900, |
| @@ -353,6 +357,7 @@ var previewMobileLocaleHeights = map[string]map[string]int{ |
| "signin/when-keymail-could-not-confirm-it": 700, |
| "signin/when-keymail-was-offered-and-a-link-went-out": 730, |
| "snippet/a-line-to-copy": 220, |
| + "stat-band/two-to-a-line-on-a-phone": 330, |
| "status-pill/row": 310, |
| }, |
| "vi": { |
diff --git a/internal/gallery/i18n/ar.json b/internal/gallery/i18n/ar.json| index 6a8ea3e..7c8e86e 100644 |
| --- a/internal/gallery/i18n/ar.json |
| +++ b/internal/gallery/i18n/ar.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "لا نوصي بكلمات المرور", |
| "examples.snippet.blurb": "سطر من الشيفرة للنسخ: الشيفرة في مربع، وزر «نسخ» يُظهره copy.js حيث توجد في المتصفح حافظة.", |
| "examples.stat-band.blurb": "صف من الأرقام على امتداد أعلى لوحة المعلومات.", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" يضع إحصاءين في كل سطر على الهاتف. ومن دونه يأتي كل إحصاء في سطر وحده.", |
| "examples.stat.blurb": "رقم واحد على لوحة المعلومات، مع تسميته ومقدار تغيّره.", |
| "examples.stat.states.a-shortened-number": "تعرض 4.1k بدل 4120؟ ضع العدد الكامل في السمة value لوسم <data>. قارئات الشاشة لا تقرأ إلا ما على الشاشة، فأبقِ كل ما يحتاجه الشخص في العدد نفسه.", |
| "examples.stat.states.a-smaller-number": "تحتاج فقط إلى تسمية ورقم. وكل ما عدا ذلك اختياري.", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "حين لم يستطع Keymail التأكيد", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "حين عُرض Keymail وأُرسل رابط", |
| "labels.snippet.a-line-to-copy": "سطر للنسخ", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "اثنان في السطر على الهاتف", |
| "labels.stat.a-shortened-number": "رقم مختصر", |
| "labels.stat.a-smaller-number": "رقم أصغر", |
| "labels.stat.the-big-number": "الرقم الكبير", |
diff --git a/internal/gallery/i18n/bn.json b/internal/gallery/i18n/bn.json| index 54a8158..1190eb0 100644 |
| --- a/internal/gallery/i18n/bn.json |
| +++ b/internal/gallery/i18n/bn.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "আমরা পাসওয়ার্ড ব্যবহারের পরামর্শ দিই না", |
| "examples.snippet.blurb": "কপি করার জন্য এক লাইন কোড: একটি বাক্সে কোড, আর একটি “কপি করুন” বোতাম, যা ব্রাউজারে ক্লিপবোর্ড থাকলে copy.js দেখায়।", |
| "examples.stat-band.blurb": "ড্যাশবোর্ডের উপরে পরিসংখ্যানের একটি সারি।", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" ফোনে এক লাইনে দুটি পরিসংখ্যান রাখে। এটি ছাড়া প্রতিটি লাইনে একটি করে বসে।", |
| "examples.stat.blurb": "ড্যাশবোর্ডে একটি সংখ্যা, তার লেবেল আর কতটা বদলেছে সহ।", |
| "examples.stat.states.a-shortened-number": "4120-এর বদলে 4.1k দেখাচ্ছেন? পুরো সংখ্যাটি একটি <data> ট্যাগের value-তে রাখুন। স্ক্রিন রিডার কেবল স্ক্রিনে যা আছে তা-ই পড়ে, তাই মানুষের যা দরকার তা সংখ্যার মধ্যেই রাখুন।", |
| "examples.stat.states.a-smaller-number": "আপনার কেবল একটি লেবেল আর একটি সংখ্যা দরকার। বাকি সবই ঐচ্ছিক।", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "যখন Keymail নিশ্চিত করতে পারেনি", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "যখন Keymail দেখানো হয়েছিল আর লিঙ্ক চলে গেল", |
| "labels.snippet.a-line-to-copy": "কপি করার একটি লাইন", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "ফোনে এক লাইনে দুটি", |
| "labels.stat.a-shortened-number": "সংক্ষেপে লেখা সংখ্যা", |
| "labels.stat.a-smaller-number": "ছোট একটি সংখ্যা", |
| "labels.stat.the-big-number": "বড় সংখ্যাটি", |
diff --git a/internal/gallery/i18n/drafts.json b/internal/gallery/i18n/drafts.json| index a3e293b..4157713 100644 |
| --- a/internal/gallery/i18n/drafts.json |
| +++ b/internal/gallery/i18n/drafts.json |
| @@ -847,6 +847,22 @@ |
| "zh-Hans" |
| ] |
| }, |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": { |
| + "english": "rst-stats=\"pairs\" puts two stats on a line on a phone. Without it they stack one to a line.", |
| + "locales": [ |
| + "ar", |
| + "bn", |
| + "es", |
| + "ga", |
| + "hi", |
| + "ja", |
| + "pt-PT", |
| + "ru", |
| + "vi", |
| + "yue", |
| + "zh-Hans" |
| + ] |
| + }, |
| "examples.stat.states.a-shortened-number": { |
| "english": "Showing 4.1k instead of 4120? Put the full number in a <data> tag's value. Screen readers only read what is on screen, so keep anything a person needs in the number itself.", |
| "locales": [ |
| @@ -1631,6 +1647,22 @@ |
| "zh-Hans" |
| ] |
| }, |
| + "labels.stat-band.two-to-a-line-on-a-phone": { |
| + "english": "Two to a line on a phone", |
| + "locales": [ |
| + "ar", |
| + "bn", |
| + "es", |
| + "ga", |
| + "hi", |
| + "ja", |
| + "pt-PT", |
| + "ru", |
| + "vi", |
| + "yue", |
| + "zh-Hans" |
| + ] |
| + }, |
| "labels.status-pill.negative": { |
| "english": "negative", |
| "locales": [ |
diff --git a/internal/gallery/i18n/es.json b/internal/gallery/i18n/es.json| index 7554ed6..31c6598 100644 |
| --- a/internal/gallery/i18n/es.json |
| +++ b/internal/gallery/i18n/es.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "No recomendamos las contraseñas", |
| "examples.snippet.blurb": "Una línea de código para copiar: el código en un recuadro y un botón Copiar que copy.js muestra donde el navegador tiene portapapeles.", |
| "examples.stat-band.blurb": "Una fila de cifras a lo largo de la parte superior de un panel.", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" pone dos cifras por línea en un móvil. Sin él, se apilan una por línea.", |
| "examples.stat.blurb": "Un número en un panel, con una etiqueta y cuánto ha cambiado.", |
| "examples.stat.states.a-shortened-number": "¿Muestras 4.1k en lugar de 4120? Pon el número completo en el value de una etiqueta <data>. Los lectores de pantalla solo leen lo que está en pantalla, así que deja en el propio número todo lo que una persona necesite.", |
| "examples.stat.states.a-smaller-number": "Solo necesitas una etiqueta y un número. Todo lo demás es opcional.", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Cuando Keymail no pudo confirmarlo", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "Cuando se ofreció Keymail y salió un enlace", |
| "labels.snippet.a-line-to-copy": "Una línea para copiar", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "Dos por línea en un móvil", |
| "labels.stat.a-shortened-number": "Un número acortado", |
| "labels.stat.a-smaller-number": "Un número más pequeño", |
| "labels.stat.the-big-number": "El número grande", |
diff --git a/internal/gallery/i18n/ga.json b/internal/gallery/i18n/ga.json| index 9c15ad8..5926052 100644 |
| --- a/internal/gallery/i18n/ga.json |
| +++ b/internal/gallery/i18n/ga.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "Ní mholaimid pasfhocail", |
| "examples.snippet.blurb": "Líne chóid le cóipeáil: an cód i mbosca, agus cnaipe Cóipeáil a thaispeánann copy.js áit a bhfuil gearrthaisce ag an mbrabhsálaí.", |
| "examples.stat-band.blurb": "Sraith staitisticí trasna barr painéil.", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "Cuireann rst-stats=\"pairs\" dhá staitistic sa líne ar fhón. Gan é, bíonn ceann amháin sa líne.", |
| "examples.stat.blurb": "Uimhir amháin ar phainéal, le lipéad agus a mhéid a d'athraigh sí.", |
| "examples.stat.states.a-shortened-number": "Ag taispeáint 4.1k in ionad 4120? Cuir an uimhir iomlán i value clib <data>. Ní léann léitheoirí scáileáin ach a bhfuil ar an scáileán, mar sin coinnigh aon rud a theastaíonn ó dhuine san uimhir féin.", |
| "examples.stat.states.a-smaller-number": "Níl uait ach lipéad agus uimhir. Tá gach rud eile roghnach.", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Nuair nach raibh Keymail in ann é a dheimhniú", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "Nuair a tairgeadh Keymail agus gur seoladh nasc", |
| "labels.snippet.a-line-to-copy": "Líne le cóipeáil", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "Dhá cheann sa líne ar fhón", |
| "labels.stat.a-shortened-number": "Uimhir ghiorraithe", |
| "labels.stat.a-smaller-number": "Uimhir níos lú", |
| "labels.stat.the-big-number": "An uimhir mhór", |
diff --git a/internal/gallery/i18n/hi.json b/internal/gallery/i18n/hi.json| index a083990..e5bae82 100644 |
| --- a/internal/gallery/i18n/hi.json |
| +++ b/internal/gallery/i18n/hi.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "हम पासवर्ड की सलाह नहीं देते", |
| "examples.snippet.blurb": "कॉपी करने के लिए कोड की एक पंक्ति: एक बॉक्स में कोड, और एक “कॉपी करें” बटन, जिसे copy.js वहाँ दिखाता है जहाँ ब्राउज़र में क्लिपबोर्ड है।", |
| "examples.stat-band.blurb": "डैशबोर्ड के ऊपर आँकड़ों की एक पंक्ति।", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" फ़ोन पर एक पंक्ति में दो आँकड़े रखता है। इसके बिना हर पंक्ति में एक आँकड़ा आता है।", |
| "examples.stat.blurb": "डैशबोर्ड पर एक संख्या, उसके लेबल और उसमें कितना बदलाव हुआ, के साथ।", |
| "examples.stat.states.a-shortened-number": "4120 की जगह 4.1k दिखा रहे हैं? पूरी संख्या को <data> टैग के value में रखें। स्क्रीन रीडर सिर्फ़ वही पढ़ते हैं जो स्क्रीन पर है, इसलिए किसी को जो चाहिए वह संख्या में ही रखें।", |
| "examples.stat.states.a-smaller-number": "आपको बस एक लेबल और एक संख्या चाहिए। बाकी सब वैकल्पिक है।", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "जब Keymail पुष्टि नहीं कर सका", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "जब Keymail पेश किया गया और लिंक चला गया", |
| "labels.snippet.a-line-to-copy": "कॉपी करने के लिए एक पंक्ति", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "फ़ोन पर एक पंक्ति में दो", |
| "labels.stat.a-shortened-number": "छोटा करके लिखी संख्या", |
| "labels.stat.a-smaller-number": "छोटी संख्या", |
| "labels.stat.the-big-number": "बड़ी संख्या", |
diff --git a/internal/gallery/i18n/ja.json b/internal/gallery/i18n/ja.json| index 8fd0f5b..2f65789 100644 |
| --- a/internal/gallery/i18n/ja.json |
| +++ b/internal/gallery/i18n/ja.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "パスワードはおすすめしません", |
| "examples.snippet.blurb": "コピーするための1行のコード。コードを枠に収め、ブラウザにクリップボードがあれば copy.js が「コピー」ボタンを表示します。", |
| "examples.stat-band.blurb": "ダッシュボードの上部に並ぶ数値の行です。", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" を付けると、スマートフォンで数値を1行に2つずつ並べます。付けなければ1行に1つずつ積み重なります。", |
| "examples.stat.blurb": "ダッシュボードのひとつの数値です。ラベルと、どれだけ変わったかが付きます。", |
| "examples.stat.states.a-shortened-number": "4120 ではなく 4.1k と表示していますか。完全な数値は <data> タグの value に入れてください。スクリーンリーダーは画面にあるものしか読まないので、人に必要なものは数値そのものに残してください。", |
| "examples.stat.states.a-smaller-number": "必要なのはラベルと数値だけです。ほかはすべて任意です。", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Keymail で確認できなかったとき", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "Keymail を示したのにリンクが送られたとき", |
| "labels.snippet.a-line-to-copy": "コピーする1行", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "スマートフォンでは1行に2つ", |
| "labels.stat.a-shortened-number": "短くした数値", |
| "labels.stat.a-smaller-number": "小さい数値", |
| "labels.stat.the-big-number": "大きい数値", |
diff --git a/internal/gallery/i18n/pt-PT.json b/internal/gallery/i18n/pt-PT.json| index df80d0d..2e7be2d 100644 |
| --- a/internal/gallery/i18n/pt-PT.json |
| +++ b/internal/gallery/i18n/pt-PT.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "Não recomendamos palavras-passe", |
| "examples.snippet.blurb": "Uma linha de código para copiar: o código numa caixa e um botão Copiar que o copy.js mostra onde o navegador tem área de transferência.", |
| "examples.stat-band.blurb": "Uma linha de números ao longo do topo de um painel.", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" põe dois valores por linha num telemóvel. Sem ele, empilham-se um por linha.", |
| "examples.stat.blurb": "Um número num painel, com uma etiqueta e quanto mudou.", |
| "examples.stat.states.a-shortened-number": "Mostra 4.1k em vez de 4120? Ponha o número completo no value de uma etiqueta <data>. Os leitores de ecrã só leem o que está no ecrã, por isso deixe no próprio número tudo o que uma pessoa precise.", |
| "examples.stat.states.a-smaller-number": "Só precisa de uma etiqueta e um número. Tudo o resto é opcional.", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Quando o Keymail não conseguiu confirmar", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "Quando foi oferecido o Keymail e seguiu uma ligação", |
| "labels.snippet.a-line-to-copy": "Uma linha para copiar", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "Dois por linha num telemóvel", |
| "labels.stat.a-shortened-number": "Um número encurtado", |
| "labels.stat.a-smaller-number": "Um número mais pequeno", |
| "labels.stat.the-big-number": "O número grande", |
diff --git a/internal/gallery/i18n/ru.json b/internal/gallery/i18n/ru.json| index e1868c7..02aa769 100644 |
| --- a/internal/gallery/i18n/ru.json |
| +++ b/internal/gallery/i18n/ru.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "Мы не рекомендуем пароли", |
| "examples.snippet.blurb": "Строка кода для копирования: код в рамке и кнопка «Копировать», которую copy.js показывает там, где у браузера есть буфер обмена.", |
| "examples.stat-band.blurb": "Ряд показателей вдоль верха панели.", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" ставит на телефоне по два показателя в строку. Без него они идут по одному в строке.", |
| "examples.stat.blurb": "Одно число на панели, с подписью и тем, насколько оно изменилось.", |
| "examples.stat.states.a-shortened-number": "Показываете 4.1k вместо 4120? Поместите полное число в value тега <data>. Экранные дикторы читают только то, что на экране, поэтому всё, что нужно человеку, оставляйте в самом числе.", |
| "examples.stat.states.a-smaller-number": "Нужны только подпись и число. Всё остальное необязательно.", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Когда Keymail не смог подтвердить", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "Когда предлагался Keymail, а ушла ссылка", |
| "labels.snippet.a-line-to-copy": "Строка для копирования", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "По два в строке на телефоне", |
| "labels.stat.a-shortened-number": "Сокращённое число", |
| "labels.stat.a-smaller-number": "Число поменьше", |
| "labels.stat.the-big-number": "Большое число", |
diff --git a/internal/gallery/i18n/vi.json b/internal/gallery/i18n/vi.json| index 3450e20..f5aaf57 100644 |
| --- a/internal/gallery/i18n/vi.json |
| +++ b/internal/gallery/i18n/vi.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "Chúng tôi không khuyến nghị mật khẩu", |
| "examples.snippet.blurb": "Một dòng mã để sao chép: mã nằm trong một khung, và nút Sao chép mà copy.js hiển thị ở trình duyệt có bộ nhớ tạm.", |
| "examples.stat-band.blurb": "Một hàng chỉ số chạy ngang phía trên bảng điều khiển.", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" đặt hai chỉ số trên một dòng trên điện thoại. Không có nó, chúng xếp chồng mỗi dòng một chỉ số.", |
| "examples.stat.blurb": "Một con số trên bảng điều khiển, kèm nhãn và mức thay đổi.", |
| "examples.stat.states.a-shortened-number": "Hiển thị 4.1k thay vì 4120? Đặt số đầy đủ vào value của thẻ <data>. Trình đọc màn hình chỉ đọc những gì có trên màn hình, nên hãy giữ mọi thứ người dùng cần ngay trong con số.", |
| "examples.stat.states.a-smaller-number": "Bạn chỉ cần một nhãn và một con số. Mọi thứ khác đều tùy chọn.", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Khi Keymail không xác nhận được", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "Khi Keymail được đề xuất nhưng một liên kết được gửi đi", |
| "labels.snippet.a-line-to-copy": "Một dòng để sao chép", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "Hai mục một dòng trên điện thoại", |
| "labels.stat.a-shortened-number": "Một con số rút gọn", |
| "labels.stat.a-smaller-number": "Một con số nhỏ hơn", |
| "labels.stat.the-big-number": "Con số lớn", |
diff --git a/internal/gallery/i18n/yue.json b/internal/gallery/i18n/yue.json| index cc9b46b..ec14a33 100644 |
| --- a/internal/gallery/i18n/yue.json |
| +++ b/internal/gallery/i18n/yue.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "我哋唔建議用密碼", |
| "examples.snippet.blurb": "一行要複製嘅代碼:代碼放喺框入面,加一個「複製」掣,瀏覽器有剪貼簿嘅話 copy.js 就會顯示佢。", |
| "examples.stat-band.blurb": "儀表板頂部一行數字。", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" 喺手機上一行擺兩個數字。冇佢嘅話,就一行一個咁疊落去。", |
| "examples.stat.blurb": "儀表板上嘅一個數字,有標籤,同埋變咗幾多。", |
| "examples.stat.states.a-shortened-number": "顯示 4.1k 而唔係 4120?將完整數字放入 <data> 標籤嘅 value。螢幕閱讀器只會讀畫面上嘅嘢,所以人需要嘅嘢都要留喺個數字本身。", |
| "examples.stat.states.a-smaller-number": "你只需要一個標籤同一個數字。其餘都係可選。", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Keymail 確認唔到嘅時候", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "提供嘅係 Keymail,寄出去嘅卻係連結", |
| "labels.snippet.a-line-to-copy": "要複製嘅一行", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "喺手機上一行兩個", |
| "labels.stat.a-shortened-number": "縮短咗嘅數字", |
| "labels.stat.a-smaller-number": "細啲嘅數字", |
| "labels.stat.the-big-number": "個大數字", |
diff --git a/internal/gallery/i18n/zh-Hans.json b/internal/gallery/i18n/zh-Hans.json| index 8d41fb8..cbfd1da 100644 |
| --- a/internal/gallery/i18n/zh-Hans.json |
| +++ b/internal/gallery/i18n/zh-Hans.json |
| @@ -118,6 +118,7 @@ |
| "examples.signin.warnings.email-and-password.title": "我们不建议使用密码", |
| "examples.snippet.blurb": "一行要复制的代码:代码放在框中,另有一个“复制”按钮,浏览器有剪贴板时由 copy.js 显示。", |
| "examples.stat-band.blurb": "仪表板顶部的一排数字。", |
| + "examples.stat-band.states.two-to-a-line-on-a-phone": "rst-stats=\"pairs\" 让手机上一行放两个数字。没有它,就一行一个往下排。", |
| "examples.stat.blurb": "仪表板上的一个数字,带标签,以及它变化了多少。", |
| "examples.stat.states.a-shortened-number": "显示 4.1k 而不是 4120?把完整数字放进 <data> 标签的 value。屏幕阅读器只读屏幕上的内容,所以人需要的东西都要留在数字本身里。", |
| "examples.stat.states.a-smaller-number": "你只需要一个标签和一个数字。其余都是可选的。", |
| @@ -388,6 +389,7 @@ |
| "labels.signin.when-keymail-could-not-confirm-it": "Keymail 无法确认时", |
| "labels.signin.when-keymail-was-offered-and-a-link-went-out": "提供的是 Keymail,寄出的却是链接", |
| "labels.snippet.a-line-to-copy": "要复制的一行", |
| + "labels.stat-band.two-to-a-line-on-a-phone": "手机上一行两个", |
| "labels.stat.a-shortened-number": "缩短过的数字", |
| "labels.stat.a-smaller-number": "较小的数字", |
| "labels.stat.the-big-number": "那个大数字", |