Skip to content

Commit eb50306

Browse files
feat(web): browsable Read-along memo picker + accessible mobile menu
Read-along now carries a tab strip over all six picked filers (Kintetsu, Nippon Steel, Asahi, SBI, Riso, REFUSE.X) instead of only showing the REFUSE.X row; picking a tab swaps the source pane, the cited English memo, and the coherence score. Every Japanese span and English sentence is an activatable control (role=button + Enter/Space, role=tablist for the tabs) that opens the existing citation drawer, so citations are reachable by keyboard and touch rather than mouse-hover only. The English text renders the cleaned displayText, dropping the embedded (ref: "...") fragments, and the pane header names the company. Accessibility: the mobile nav drawer is a proper modal now - focus moves in on open, Escape closes it and returns focus to the burger, Tab is trapped, and the drawer is inert whenever closed so its links never sit in the tab order. Added an .sr-only utility plus screen-reader text for the aria-hidden cite demos in the Problem and How-it-works sections. Also bumps the Reveal IntersectionObserver fallback from 2.5s to 8s so a reader who pauses on the hero still gets the staggered section reveals, and deletes the unused EmphasisText and MetaChip components.
1 parent 1fa4046 commit eb50306

8 files changed

Lines changed: 314 additions & 131 deletions

File tree

web/app/globals.css

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,21 @@ a { color: inherit; }
307307
#main-content { position: relative; }
308308
#main-content:focus { outline: none; }
309309

310+
/* Visually-hidden text that stays in the accessibility tree — used to give
311+
screen readers a plain-text equivalent of the decorative `aria-hidden`
312+
demo blocks (the typed cite examples, the [evidence insufficient] mock). */
313+
.sr-only {
314+
position: absolute;
315+
width: 1px;
316+
height: 1px;
317+
padding: 0;
318+
margin: -1px;
319+
overflow: hidden;
320+
clip: rect(0, 0, 0, 0);
321+
white-space: nowrap;
322+
border: 0;
323+
}
324+
310325
.mono {
311326
font-family: var(--f-mono);
312327
font-size: 11px;
@@ -2537,6 +2552,53 @@ h1.hero-title .accent::after {
25372552
position: relative; z-index: 3;
25382553
background: transparent;
25392554
}
2555+
.ra-tabs {
2556+
margin-top: 48px;
2557+
display: flex;
2558+
flex-wrap: wrap;
2559+
border: 1px solid var(--rule-strong);
2560+
border-bottom: none;
2561+
}
2562+
.ra-tab {
2563+
flex: 1 1 130px;
2564+
display: flex;
2565+
flex-direction: column;
2566+
gap: 4px;
2567+
padding: 14px 18px;
2568+
background: transparent;
2569+
border: 0;
2570+
border-right: 1px solid var(--rule);
2571+
border-bottom: 2px solid transparent;
2572+
cursor: pointer;
2573+
text-align: left;
2574+
color: var(--type-muted);
2575+
font: inherit;
2576+
transition: color 200ms var(--ease-out), background 200ms var(--ease-out), border-color 200ms var(--ease-out);
2577+
}
2578+
.ra-tab:last-child { border-right: 0; }
2579+
.ra-tab:hover { color: var(--type-primary); background: var(--glass); }
2580+
.ra-tab.is-active {
2581+
color: var(--type-primary);
2582+
background: var(--glass);
2583+
border-bottom-color: var(--vermilion);
2584+
}
2585+
.ra-tab__name {
2586+
font-family: var(--f-display);
2587+
font-size: var(--text-sm);
2588+
font-weight: 500;
2589+
letter-spacing: -0.01em;
2590+
}
2591+
.ra-tab__sub {
2592+
font-family: var(--f-mono);
2593+
font-size: 9px;
2594+
letter-spacing: 0.22em;
2595+
text-transform: uppercase;
2596+
color: var(--type-faint);
2597+
}
2598+
.ra-tab.is-active .ra-tab__sub { color: var(--vermilion); }
2599+
/* When the tab strip is present the panel docks straight underneath it so
2600+
the shared border reads as one framed unit. */
2601+
.ra-tabs + .ra-grid { margin-top: 0; }
25402602
.ra-grid {
25412603
margin-top: 56px;
25422604
display: grid;

web/components/sections/how-it-works.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ export function HowItWorks() {
159159
<div className="demo-area" aria-hidden="true">
160160
<StepDemo kind={s.demoKind} />
161161
</div>
162+
{s.demoKind === "cite" ? (
163+
<p className="sr-only">
164+
Example sentence: &ldquo;Operating margin compressed 3.4%
165+
year-over-year on yen weakness,&rdquo; with the first claim
166+
cited to 営業利益率 on page 23 section 2.1 and the second to
167+
為替予約 on page 24.
168+
</p>
169+
) : null}
162170
</article>
163171
</Reveal>
164172
))}

web/components/sections/problem.tsx

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,45 @@ function BeatDemo({ kind }: { kind: ProblemBeat["demoKind"] }) {
2020
}
2121
if (kind === "split") {
2222
return (
23-
<div className="demo" aria-hidden="true">
24-
<div className="ja">「急激な為替変動は営業利益率に重大な影響を及ぼす可能性がある。」</div>
25-
<div className="mt">
26-
&ldquo;Sudden <s>foreign-exchange shaking</s> may give a serious feeling of influence to operating profit ratio.&rdquo;
23+
<>
24+
<div className="demo" aria-hidden="true">
25+
<div className="ja">「急激な為替変動は営業利益率に重大な影響を及ぼす可能性がある。」</div>
26+
<div className="mt">
27+
&ldquo;Sudden <s>foreign-exchange shaking</s> may give a serious feeling of influence to operating profit ratio.&rdquo;
28+
</div>
2729
</div>
28-
</div>
30+
<p className="sr-only">
31+
Example: a fluent Japanese risk sentence rendered by raw machine
32+
translation as &ldquo;Sudden foreign-exchange shaking may give a
33+
serious feeling of influence to operating profit ratio&rdquo; - the
34+
meaning is mangled.
35+
</p>
36+
</>
2937
);
3038
}
3139
return (
32-
<div className="demo" aria-hidden="true">
33-
Prolonged yen weakness materially compresses operating margin in the electronic-components segment.
34-
<sup data-cursor-preview="cite:demo:fx">¹</sup>
35-
<div className="evidence-insufficient">
36-
<span className="evidence-insufficient__tag">[evidence insufficient]</span>
37-
<span className="evidence-insufficient__body">
38-
claim about FY25 guidance was not span-grounded; refused.
39-
</span>
40-
</div>
41-
<div className="ja-orig">
42-
「急激な為替変動は営業利益率に重大な影響を及ぼす可能性がある」, p.23 §2.1
40+
<>
41+
<div className="demo" aria-hidden="true">
42+
Prolonged yen weakness materially compresses operating margin in the electronic-components segment.
43+
<sup data-cursor-preview="cite:demo:fx">¹</sup>
44+
<div className="evidence-insufficient">
45+
<span className="evidence-insufficient__tag">[evidence insufficient]</span>
46+
<span className="evidence-insufficient__body">
47+
claim about FY25 guidance was not span-grounded; refused.
48+
</span>
49+
</div>
50+
<div className="ja-orig">
51+
「急激な為替変動は営業利益率に重大な影響を及ぼす可能性がある」, p.23 §2.1
52+
</div>
4353
</div>
44-
</div>
54+
<p className="sr-only">
55+
Example output: &ldquo;Prolonged yen weakness materially compresses
56+
operating margin in the electronic-components segment,&rdquo; cited to
57+
page 23, section 2.1 of the source. A second claim about FY25 guidance
58+
had no matching span, so it is replaced with &ldquo;[evidence
59+
insufficient]&rdquo; rather than asserted.
60+
</p>
61+
</>
4562
);
4663
}
4764

0 commit comments

Comments
 (0)