diff --git a/scripts/ui-capture.mjs b/scripts/ui-capture.mjs index a204183..6eef18c 100644 --- a/scripts/ui-capture.mjs +++ b/scripts/ui-capture.mjs @@ -48,21 +48,21 @@ export const SHOTS = Object.freeze([ { file: 'home-mobile-tall.png', route: '/', width: 390, height: 844, state: 'whole page after scrolling through, reduced motion, real time', reducedMotion: true, realtime: true, fullPage: true }, { file: 'home-band-reel.png', route: '/', width: 1440, height: 1000, scrollTo: '[data-rd-reel]', assertVisible: '[data-rd-reel] .rd-reel-cap', state: 'reel with its native player and staged-film caption, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'home-band-chapter-genie.png', route: '/', width: 1440, height: 1000, scrollTo: '#products', assertVisible: 'a.rd-row[href="/products/genie/"]', state: 'product list (redesign; replaces the v4 Genie card), real time', realtime: true }, - { file: 'home-band-chapter-oathra.png', route: '/', width: 1440, height: 1000, scrollTo: '.rd-records', assertVisible: '.rd-records a[href="/products/oathra/#film15-oathra-title"]', state: 'records and films row under the product list (redesign; replaces the v4 Oathra card), real time', realtime: true }, + { file: 'home-band-chapter-oathra.png', route: '/', width: 1440, height: 1000, openDetails: '.rd-kept--fold', scrollTo: '.rd-records', assertVisible: '.rd-records a[href="/products/oathra/#film15-oathra-title"]', state: 'records and films row under the product list (redesign; replaces the v4 Oathra card), real time', realtime: true }, { file: 'home-band-chapter-launchloom.png', route: '/', width: 1440, height: 1000, scrollTo: 'a.rd-row[href="/products/launchloom/"]', assertVisible: 'a.rd-row[href="/products/launchloom/"]', state: 'Launchloom row in the product list (redesign), real time', realtime: true }, { file: 'home-band-principles.png', route: '/', width: 1440, height: 1000, scrollTo: '#principles', state: 'principles, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'home-band-services.png', route: '/', width: 1440, height: 1000, scrollTo: '#services', state: 'services band, reduced motion, real time', reducedMotion: true, realtime: true }, - { file: 'home-band-access.png', route: '/', width: 1440, height: 1000, openDetails: '#access > details', scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'open access table, reduced motion, real time', reducedMotion: true, realtime: true }, - { file: 'home-band-close.png', route: '/', width: 1440, height: 1000, scrollTo: '#faq', state: 'FAQ and contact, reduced motion, real time', reducedMotion: true, realtime: true }, + { file: 'home-band-access.png', route: '/', width: 1440, height: 1000, openDetails: ['.rd-kept--fold', '#access > details'], scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'open access table, reduced motion, real time', reducedMotion: true, realtime: true }, + { file: 'home-band-close.png', route: '/', width: 1440, height: 1000, openDetails: '.rd-kept--fold', scrollTo: '#faq', state: 'FAQ and contact, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'home-m-reel.png', route: '/', width: 390, height: 844, scrollTo: '[data-rd-reel]', assertVisible: '[data-rd-reel] .rd-reel-cap', state: 'phone, reel with native player and caption, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'home-m-chapter.png', route: '/', width: 390, height: 844, scrollTo: '#products', assertVisible: 'a.rd-row[href="/products/ai-meeting/"]', state: 'phone, product list (redesign), real time', realtime: true }, // The two home clips cut from illustrative films (2026-09-30): their label and the caption under the video. - { file: 'home-m-chapter-oathra.png', route: '/', width: 390, height: 1100, scrollTo: '.rd-records', assertVisible: '.rd-records a[href="/work/#oathra"]', state: 'phone, records and films row (redesign), reduced motion, real time', reducedMotion: true, realtime: true }, + { file: 'home-m-chapter-oathra.png', route: '/', width: 390, height: 1100, openDetails: '.rd-kept--fold', scrollTo: '.rd-records', assertVisible: '.rd-records a[href="/work/#oathra"]', state: 'phone, records and films row (redesign), reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'home-m-chapter-agent-team.png', route: '/', width: 390, height: 1100, scrollTo: 'a.rd-row[data-rd-film]', assertVisible: 'a.rd-row[data-rd-film]', state: 'phone, Agent Team row carrying the labelled design film (redesign), reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'home-m-services.png', route: '/', width: 390, height: 844, scrollTo: '#services', state: 'phone, services band, reduced motion, real time', reducedMotion: true, realtime: true }, - { file: 'home-m-access.png', route: '/', width: 390, height: 844, openDetails: '#access > details', scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'phone, open access table, reduced motion, real time', reducedMotion: true, realtime: true }, - { file: 'home-en-m-access.png', route: '/en/', width: 390, height: 844, openDetails: '#access > details', scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'phone, English open access table, reduced motion, real time', reducedMotion: true, realtime: true }, - { file: 'home-narrow-access.png', route: '/', width: 320, height: 900, openDetails: '#access > details', scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'narrow phone, open access table, reduced motion, real time', reducedMotion: true, realtime: true }, + { file: 'home-m-access.png', route: '/', width: 390, height: 844, openDetails: ['.rd-kept--fold', '#access > details'], scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'phone, open access table, reduced motion, real time', reducedMotion: true, realtime: true }, + { file: 'home-en-m-access.png', route: '/en/', width: 390, height: 844, openDetails: ['.rd-kept--fold', '#access > details'], scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'phone, English open access table, reduced motion, real time', reducedMotion: true, realtime: true }, + { file: 'home-narrow-access.png', route: '/', width: 320, height: 900, openDetails: ['.rd-kept--fold', '#access > details'], scrollTo: '#access', assertVisible: '#access details[open] .rm-access-table', state: 'narrow phone, open access table, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'noa-hero-ja-desktop.png', route: '/products/noa/', width: 1440, height: 1200, scrollTo: '.rd-phero', assertVisible: '.rd-phero', state: 'Noa ja public viewing hero, desktop, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'noa-hero-ja-mobile.png', route: '/products/noa/', width: 390, height: 1400, scrollTo: '.rd-phero', assertVisible: '.rd-phero', state: 'Noa ja public viewing hero, mobile, reduced motion, real time', reducedMotion: true, realtime: true }, { file: 'noa-viewing-ja-desktop.png', route: '/products/noa/', width: 1440, height: 1200, scrollTo: '#noa-viewing', assertVisible: '#noa-viewing', state: 'Noa ja public viewing viewing, desktop, reduced motion, real time', reducedMotion: true, realtime: true }, @@ -317,7 +317,8 @@ async function captureRealtime(binary, shots, results = []) { for (let i = 0; i < 150 && !loaded; i++) await sleep(100); if (!loaded) throw new Error(`Real-time capture: ${shot.file} did not finish loading`); await sleep(1200); - if (shot.openDetails) await openDetails(shot.openDetails); + // A disclosure nested in a folded one is opened after its parent: pass the selectors outermost first. + for (const selector of [].concat(shot.openDetails || [])) await openDetails(selector); if (shot.fullPage) { await evaluate(`(async () => { const h = document.documentElement.scrollHeight; for (let y = 0; y < h; y += innerHeight / 2) { scrollTo({ top: y, behavior: 'instant' }); await new Promise(r => setTimeout(r, 120)); } scrollTo({ top: 0, behavior: 'instant' }); })()`); await sleep(800); diff --git a/scripts/verify-conversion-path.py b/scripts/verify-conversion-path.py index 7579b17..21045fe 100644 --- a/scripts/verify-conversion-path.py +++ b/scripts/verify-conversion-path.py @@ -47,9 +47,11 @@ def handle(route): page=context.new_page();page.on('pageerror',lambda error:errors.append(str(error))) page.set_default_timeout(7000) try: - # Actual home -> record -> scoped offer -> contextual inquiry. + # Actual home -> record -> scoped offer -> contextual inquiry. The records sit in the home fold, + # so the visitor opens it first, as they would. page.goto(BASE+prefix+'/',wait_until='networkidle') - page.locator(f'a[href="{prefix}/work/#noa"]').click() + page.locator('details.rd-kept--home > summary').click() + page.locator(f'.rd-records a[href="{prefix}/work/#noa"]').click() expect(page.locator('#noa .work-consult')).to_be_visible() page.screenshot(path=str(OUT/f'work-{language}-{width}.png'),full_page=False) page.locator(f'#noa a[href="{prefix}/services/#ai-character"]').click() diff --git a/scripts/verify_home_v4.py b/scripts/verify_home_v4.py index ce5a427..c4516d1 100644 --- a/scripts/verify_home_v4.py +++ b/scripts/verify_home_v4.py @@ -296,7 +296,12 @@ def assert_home_v4(page, *, interactive=True): expect(page.locator('[data-rd-clock]')).to_be_hidden() expect(page.locator('#main-nav')).to_be_visible() expect(reel).to_be_visible() + # Access, FAQ and records sit in one native disclosure (2026-10-19): it opens without script. + fold = page.locator('details.rd-kept--fold > summary') + expect(fold).to_be_visible() + fold.click() expect(page.locator('#access details summary')).to_be_visible() + expect(page.locator('#faq')).to_be_visible() return {'products': checked, 'javascript': False, 'native_reel': True, 'network': _home_requests(page), 'geometry': no_overflow(page)} diff --git a/src/home-flagship.mjs b/src/home-flagship.mjs index e923569..99d614b 100644 --- a/src/home-flagship.mjs +++ b/src/home-flagship.mjs @@ -87,7 +87,7 @@ export function renderAccess(products, lang) { const c = p[lang]; return `${esc(p.index)}${esc(p.name)}${esc(c.outcome)}${esc(c.status)}${esc(c.license)}${t('詳しく見る', 'Open')} ${arrow}`; }).join(''); - return `

ACCESS AT A GLANCE

${t('「試せるのか」に、
先に答える。', 'Can you actually
try it? Yes — here.')}

${t('7つとも自主開発です。今の状態、成果物、ライセンス、入口を、ひとつの表に。
言えないことは、ここにも書きません。', 'All seven are built here. Stage, result, license and entry point in one table.
What has not been verified is not claimed here either.')}

${heads.map(h => ``).join('')}${rows}
${t('プロダクトごとの状態・ライセンス・入口の一覧', 'Stage, license and entry point for each product')}
${esc(h)}

${t('各製品の動作条件・未検証の範囲は、製品ページと検証資料に記載しています。実運用の性能や安全性を保証するものではありません。', 'Setup requirements and unverified scope are stated on each product page and in its evidence. This is not a guarantee of production performance or safety.')}

`; + return `

ACCESS AT A GLANCE

${t('「試せるのか」に、
先に答える。', 'Can you actually
try it? Yes — here.')}

${t('状態・成果物・ライセンス・入口を、ひとつの表に。', 'Stage, result, license and entry point in one table.')}

${heads.map(h => ``).join('')}${rows}
${t('プロダクトごとの状態・ライセンス・入口の一覧', 'Stage, license and entry point for each product')}
${esc(h)}

${t('各製品の動作条件・未検証の範囲は、製品ページと検証資料に記載しています。実運用の性能や安全性を保証するものではありません。', 'Setup requirements and unverified scope are stated on each product page and in its evidence. This is not a guarantee of production performance or safety.')}

`; } const QUESTIONS = { @@ -114,7 +114,7 @@ export function renderFaq(lang) { check(lang); const ja = lang === 'ja', t = (a, b) => (ja ? a : b); const items = QUESTIONS[lang].map(([q, a], i) => `
${String(i + 1).padStart(2, '0')}${esc(q)}

${esc(a)}

`).join(''); - return `

BEFORE YOU ASK

${t('よくある質問に、
そのまま答えます。', 'The questions,
answered plainly.')}

${t('答えにくいものほど、先に書いておきます。
もっと具体的な話は、相談から。', 'The awkward ones first.
Anything more specific: start a conversation.')}

${t('開発を相談する', 'Start a conversation')} ${arrow}
${items}
`; + return `

BEFORE YOU ASK

${t('よくある質問に、
そのまま答えます。', 'The questions,
answered plainly.')}

${t('もっと具体的な話は、相談から。', 'Anything more specific: start a conversation.')}

${t('開発を相談する', 'Start a conversation')} ${arrow}
${items}
`; } /** A footer that can actually navigate the site, not two rows of leftovers. */ diff --git a/src/home-v4-copy.mjs b/src/home-v4-copy.mjs index 2d50dd9..9cf2214 100644 --- a/src/home-v4-copy.mjs +++ b/src/home-v4-copy.mjs @@ -28,22 +28,22 @@ export const homeV4Copy = { nextUi: '次のTaskDockの設計プレビューを見る', nextUiNote: '設計プレビューは未リリースで、実アプリの録画ではありません。', accessOriginalLink: '詳しく見る', access: '利用条件を一覧で比べる', accessHint: '状態・ライセンス・入口', servicesKicker: '企業向け開発支援', servicesTitle: '変えたい仕事から、
はじめましょう。', - servicesLead: '設計・試作・評価から、必要な連携の実装まで。最初に何を確かめるかを決め、一緒に進めます。', servicesLink: '支援内容と進め方を見る', + servicesLead: '最初に確かめることを決め、設計から実装まで一緒に進めます。', servicesLink: '支援内容と進め方を見る', services: [ ['業務AI・エージェント実装','調査、下書き、レビュー、承認。人とAIの分担を設計し、結果を追える業務フローを試作します。','関連 — Genie · Agent Team'], ['音声・電話AIの開発','対話型の練習、音声入力、電話業務。自然さだけでなく、誤認識・同意・人への引き継ぎまで設計します。','関連 — AI Meeting · Oathra'], ['新しいAIプロダクトの試作','まだ言葉だけのアイデアを、操作できる試作へ。使い勝手と成立条件を確かめ、次に作る範囲を整理します。','関連 — 複数プロダクトの自主開発経験'] ], - productsKicker: '自主開発プロダクト', productsTitle: 'あなたの仕事に、
つながるものを。', productsLead: 'できることから選んで、実物を確かめる。
試せる範囲と、必要な準備も一緒に。', + productsKicker: '自主開発プロダクト', productsTitle: 'あなたの仕事に、
つながるものを。', productsLead: '選んで、すぐ確かめる。', sourceNote: () => '各製品は独立しており、自動連携しません。', principlesKicker: 'REACHMADEのつくり方', principlesTitle: 'つくるだけでなく、
確かめるところまで。', - principlesLead: '自主開発で得た知見を、次の開発へ。
コード、実物、検証記録を公開しています。', about: 'ラボ・開発者について', work: '開発・検証記録を見る', + principlesLead: '自主開発で得た知見を、次の開発へ。', about: 'ラボ・開発者について', work: '開発・検証記録を見る', principles: [ ['実物で話す。','自主開発のプロダクト、コード、実行記録。言葉だけでなく、確認できるものを見せます。'], ['結果を確かめる。','AIの「できました」を、成功の証拠にしない。実行と確認を分け、未完了も残します。'], ['使う人に決定権を。','外部への送信、費用、権限、人の承認。使う人が判断できるよう、設計に組み込みます。'] ], - contactTitle: 'その「できたら」を、
一緒につくりませんか', contactLead: '構想が固まる前の段階から。
対象の業務と、試してみたいことを聞かせてください。' + contactTitle: 'その「できたら」を、
一緒につくりませんか', contactLead: '構想が固まる前から。
試したいことを聞かせてください。' }, en: { eyebrow: 'Independent AI products and development for companies', @@ -73,22 +73,22 @@ export const homeV4Copy = { nextUi: 'See the next TaskDock design preview', nextUiNote: 'This design is not released. It is not a recording of the real app.', accessOriginalLink: 'Open', access: 'Compare access and requirements', accessHint: 'Stage · license · entry point', servicesKicker: 'DEVELOPMENT FOR COMPANIES', servicesTitle: 'Start with the work
you want to change.', - servicesLead: 'From design, prototypes and evaluation to the integrations you need. We decide what to test first, then build it together.', servicesLink: 'See the support and process', + servicesLead: 'We decide what to test first, then design and build it with you.', servicesLink: 'See the support and process', services: [ ['AI workflows and agents','Research, drafts, review and approval. We design how people and AI share the work, then prototype a workflow with results you can trace.','Related — Genie · Agent Team'], ['Voice and phone AI','Conversation practice, voice input and phone workflows. We plan for misheard words, consent and human handover, as well as natural conversation.','Related — AI Meeting · Oathra'], ['New AI product prototypes','Turn a spoken idea into something you can operate. Test how it works and what it requires, then decide what to build next.','Related — experience building independent products'] ], - productsKicker: 'INDEPENDENT PRODUCTS', productsTitle: 'Find a tool
for your work.', productsLead: 'Choose by what it does, then inspect the real work.
See what you can try and what you need to prepare.', + productsKicker: 'INDEPENDENT PRODUCTS', productsTitle: 'Find a tool
for your work.', productsLead: 'Pick one. See it work.', sourceNote: () => 'Each product is independent; they do not connect automatically.', principlesKicker: 'HOW REACHMADE BUILDS', principlesTitle: 'Build it.
Then check it.', - principlesLead: 'What we learn from our own products informs the next project.
We share code, working examples and verification records.', about: 'About the lab and developer', work: 'Read the development records', + principlesLead: 'What we learn from our own products goes into the next one.', about: 'About the lab and developer', work: 'Read the development records', principles: [ ['Show the work.','Independent products, code and run records. We show things you can inspect alongside the description.'], ['Check the result.','The AI saying “done” is not evidence of success. We separate execution from verification and retain unfinished results.'], ['Keep people in control.','External data transfers, costs, permissions and approval are part of the design, so the person using it can decide.'] ], - contactTitle: 'Let’s make your
next idea useful', contactLead: 'You can start before the brief is settled.
Tell us about the work and what you would like to try.' + contactTitle: 'Let’s make your
next idea useful', contactLead: 'Start before the brief is settled.
Tell us what you would like to try.' } }; diff --git a/src/redesign-copy.mjs b/src/redesign-copy.mjs index 4a84e01..2742388 100644 --- a/src/redesign-copy.mjs +++ b/src/redesign-copy.mjs @@ -12,13 +12,13 @@ export const redesignCopy = { scroll: ['SCROLL', '構想が固まる前から。'], reelKicker: '(02) 実際につくったもの', // reachmade-15s.mp4: motion graphics rendered from film.html, with a soundtrack (films/manifest.json). Made when there were six products. - reelCaption: '15秒の紹介映像(画面は再現・演出を含む)· 音声あり · 制作時点の6製品を紹介', + reelCaption: '紹介映像(画面は再現・演出を含む)· 15秒 · 音声あり · 6製品', reelLabel: 'Reachmadeの15秒紹介映像', productsKicker: '(03) 自主開発プロダクト', servicesKicker: '(04) 企業向け開発支援', principlesKicker: '(05) Reachmadeのつくり方', contactKicker: '(06) 相談する', - keptKicker: '(+) 利用条件とよくある質問', + keptKicker: '(+) 利用条件とよくある質問', keptSummary: '利用条件・よくある質問・検証記録', records: '検証記録と映像', recordLink: '検証記録', footCols: [['SITE', [['/products/', 'プロダクト'], ['/services/', '企業向け支援'], ['/work/', '開発記録'], ['/about/', 'ラボについて']]], ['CODE', [['https://github.com/FORIFOR', 'GitHub ↗'], ['/privacy/', 'プライバシー']]]], lang: ['LANG', '日本語', 'English'], @@ -56,13 +56,13 @@ export const redesignCopy = { meta: ['Reachmade / Independent AI Studio', n => `(01—${String(n).padStart(2, '0')}) Products · Tokyo`], scroll: ['SCROLL', 'Before the brief is settled.'], reelKicker: '(02) Things we have built', - reelCaption: '15-second introduction film (recreated screens and staging) · with sound · shows the six products at the time it was made', + reelCaption: 'Introduction film (recreated screens and staging) · 15 s · with sound · six products · Japanese on-screen text', reelLabel: 'Reachmade 15-second introduction film', productsKicker: '(03) Independent products', servicesKicker: '(04) Development for companies', principlesKicker: '(05) How Reachmade builds', contactKicker: '(06) Contact', - keptKicker: '(+) Access and questions', + keptKicker: '(+) Access and questions', keptSummary: 'Access, questions and records', records: 'Records and films', recordLink: 'Work notes', footCols: [['SITE', [['/en/products/', 'Products'], ['/en/services/', 'For companies'], ['/en/work/', 'Work notes'], ['/en/about/', 'About']]], ['CODE', [['https://github.com/FORIFOR', 'GitHub ↗'], ['/en/privacy/', 'Privacy']]]], lang: ['LANG', '日本語', 'English'], diff --git a/src/redesign.mjs b/src/redesign.mjs index 798bdd3..595682a 100644 --- a/src/redesign.mjs +++ b/src/redesign.mjs @@ -184,14 +184,14 @@ function homeMain(products, lang, kept) { const services = c.services.map(([title, body, related], i) => `
0${i + 1}${esc(related)}

${esc(title)}

${esc(body)}

`).join(''); const principles = c.principles.map(([title, body], i) => `
/0${i + 1}

${esc(title)}

${esc(body)}

`).join(''); return `
-
${esc(r.meta[0])}${esc(r.meta[1](n))}${esc(c.eyebrow)}
+
${esc(r.meta[0])}${esc(c.eyebrow)}

${esc(c.title[0])}${esc(c.title[1])}${esc(c.dot)}

-

${c.lead}

${esc(r.scroll[0])}
${esc(r.scroll[1])}

+

${c.lead}

${video({...REEL, label: `${r.reelLabel} — ${r.reelCaption}`}, lang)}
${esc(r.reelKicker)}${esc(r.reelCaption)}
-

${esc(r.productsKicker)}

${c.productsTitle}

${c.productsLead}

    ${rows}
${records}

${esc(c.sourceNote(sourcesCheckedAt))}

-

${esc(r.keptKicker)}

${kept.join('')}
+

${esc(r.productsKicker)}

${c.productsTitle}

${c.productsLead}

    ${rows}

${esc(c.sourceNote(sourcesCheckedAt))}

+
${esc(r.keptSummary)}${records}${kept.join('')}

${esc(r.servicesKicker)}

${svcFirst}
${svcSecond}

${esc(c.servicesLead)}

${services}
${esc(c.servicesLink)}

${esc(r.principlesKicker)}

${c.principlesTitle}

${c.principlesLead}

${principles}

${esc(r.contactKicker)}

${c.contactTitle}

${c.contactLead}

`; diff --git a/src/redesign/redesign.css b/src/redesign/redesign.css index fec730d..3924a31 100644 --- a/src/redesign/redesign.css +++ b/src/redesign/redesign.css @@ -214,14 +214,24 @@ body[data-rd] #main .rd-kept .owned-primary,body[data-rd] #main .rd-kept .owned- body[data-rd] .rd-kept-kicker{padding:0 var(--rd-gutter);margin-bottom:clamp(24px,3vw,40px)} /* Product pages: the long-form sections start folded behind one summary row. */ body[data-rd] .rd-kept--fold{padding-top:0;padding-bottom:0;border-top:0} -body[data-rd] .rd-kept--fold>summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;min-height:72px;margin:0;border-bottom:1px solid var(--rd-rule);color:var(--rd-ink)} +body[data-rd] .rd-kept--fold>summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:flex-start;gap:14px;min-height:72px;margin:0;border-bottom:1px solid var(--rd-rule);color:var(--rd-ink);font-family:var(--rd-jp);font-size:clamp(15px,1.2vw,18px);font-weight:600;letter-spacing:.02em;text-transform:none} body[data-rd] .rd-kept--fold>summary::-webkit-details-marker{display:none} body[data-rd] .rd-kept--fold>summary::after{content:"+";font-size:22px;line-height:1;transition:transform .3s cubic-bezier(.16,1,.3,1)} body[data-rd] .rd-kept--fold[open]>summary{margin-bottom:clamp(24px,3vw,40px)} body[data-rd] .rd-kept--fold[open]>summary::after{transform:rotate(45deg)} body[data-rd] .rd-kept--fold>summary:hover{color:var(--rd-signal)} body[data-rd] .rd-kept--fold[open]{padding-bottom:clamp(64px,8vw,120px)} +/* Inside the home fold the record links stack under their label, on the same left edge as the sections below. */ +body[data-rd] .rd-kept--fold>.rd-records{display:block;margin:0 var(--rd-gutter) clamp(40px,5vw,72px)} +body[data-rd] .rd-kept--fold>.rd-records .rd-kicker{margin-bottom:12px} @media (prefers-reduced-motion:reduce){body[data-rd] .rd-kept--fold>summary::after{transition:none}} +/* On the home page the fold reads as the last row of the product list, not as a band of its own. */ +body[data-rd] .rd-products:has(+ .rd-kept--home){padding-bottom:clamp(40px,5vw,72px)} +body[data-rd] .rd-kept--home{background:transparent;padding-bottom:clamp(72px,9vw,128px)} +body[data-rd] .rd-kept--home>summary{margin:0 var(--rd-gutter);padding:0;border-top:1px solid var(--rd-ink);border-bottom:1px solid var(--rd-rule)} +body[data-rd] .rd-kept--home[open]>summary{margin-bottom:clamp(24px,3vw,40px)} +body[data-rd] .rd-kept--home>.v4-wrap{width:auto;max-width:none;margin-left:var(--rd-gutter);margin-right:var(--rd-gutter);padding-left:0;padding-right:0} +body[data-rd] .rd-kept--home>.v4-wrap .container{margin-left:0;margin-right:0} body[data-rd] .rd-kept h2,body[data-rd] .rd-kept h3{font-family:var(--rd-jp);font-weight:700;letter-spacing:-.04em;color:var(--rd-ink)} body[data-rd] .rd-kept h2{font-size:clamp(28px,3.6vw,56px);line-height:1.15} body[data-rd] .rd-kept p,body[data-rd] .rd-kept li,body[data-rd] .rd-kept dd,body[data-rd] .rd-kept td{font-family:var(--rd-jp);line-height:1.85}