Per-style brand authority for
src/styles/43-tvl-composer/. Round-4 fork of42-tvl-toi— same Sumi · Ocean type/palette DNA, evolved into a scroll-effects-driven, single long-scroll template ("Taiho Ventures v2"). Two structural moves vs. round 3: (1) the page is motion-led — a parallaxing carousel hero, a word-by-word illuminated statement, a pinned horizontal decade axis, a scroll-scrubbed by-the-numbers grid, a pinned orbit for investment criteria, and a ribboned outcomes river for the portfolio; (2) it is built as swappable section slots so alternate section treatments (the design system holds dozens) can be exposed later as client-facing composer controls (URL-param + localStorage driven). Source: Claude Design projecte0cf0312…(Taiho Ventures v2.dc.html+ its imported section files). Now a 4-page site (2026-06-25): this scroll template is the home; dedicated About, Investment Focus, and Portfolio pages compose the same slot seam under page-scoped slot ids (see the §9 Additions log). Treat sections 1–7 as canonical truth.
Primary family: Warm Editorial → cooled to a clinical white (carried from 42). Japanese-heritage editorial (Mincho display) on a near-white ground. Secondary remix: Motion as the new texture. Where 42 used a torn duotone photo for atmosphere, v2 uses scroll-driven motion — reveals, scrubs, pins, ignitions — as the primary atmospheric layer. The ground stays cool and quiet; the page behaves alive. Reference brands: Taiho Pharmaceutical (heritage + flame) × Flagship Pioneering / a16z bio (institutional restraint) × Stripe / Linear (considered scroll choreography). Visual atmosphere: Quiet, cool, precise — then kinetic on scroll. Long generous sections, each one a single editorial idea that resolves as you reach it. Teal (Ocean) is the only saturated voice and it does the "lighting up."
Copy is locked / verbatim from the client deck / v2 design. Design applies to fixed copy; it does not author new copy.
Voice SSOT:
docs/brand-voice.mdnow supersedes this section for any TVL-facing prose — read it before writing/editing copy. The adjectives/examples below are descriptive context, not the authority; where they conflict,brand-voice.mdwins. (The portfolio's four M&A acquirers are Merck, J&J, Sanofi, and Eli Lilly — Lilly acquired Orna in Feb 2026, so the site's "J&J, Eli Lilly, Sanofi" copy is correct.)
Adjectives: institutional, precise, understated, mission-led, unhurried. Voice anchor: Orwell — plain craftsman voice, concrete nouns, claims backed by named outcomes (Arcus, Halda, J&J, Lilly, Sanofi, Merck). Says: "A decade of backing biotech innovation." · "Patient, long-term capital." · "Where conviction leads." Avoids: "ecosystem", "premier", "world-class", "disruptive", growth-stage hype, exclamation, contact/response promises.
Mode: Light everywhere — no dark surfaces (carried directive). The --so-paper-deep Sky tint backs the Decade Axis; everything else sits on --so-paper.
Tokens (theme.css :root): --so-paper #FCFEFE (ground) · --so-paper-deep #EAF7F4 (decade band) · --so-wash #DDF2EE · --so-rule #D7E1E0 (hairline) · --so-ink #15201E · --so-ink-soft #3C4B4B · --so-sepia #5C6B6A · --so-sepia-soft #9CADAC · --so-accent #08817C (Ocean) · --so-accent-deep #06605C · --so-sky #8FD4CE · --so-focus #E41B14 (eyebrows) · --so-ochre #B9831A + --so-gold #FDB913 (the "realized"/exit accent — by-the-numbers gold cells, acquired river lane).
Notes: No gradients, no drop shadows on chrome. Depth = flat Sky tints, hairlines, and motion. Color lands on type, the duotone-free schematic graphics, and the scroll states.
Headline: Shippori Mincho B1 (400 light statements / subheads, 700 display). Body: Hanken Grotesk (300 long-form, 400 UI, 500 eyebrows/buttons). Pairing: High-contrast humanist Mincho serif vs. clean grotesk. Serif carries voice; sans carries information. Banned: Inter, Roboto, Open Sans, Lato, system stacks, Space Grotesk. No Japanese glyphs as decorative texture.
Grid: Asymmetric editorial. Content column max-width 1320px, gutters 24px (mobile) / 80px (desktop) — the .tv-shell / inline max-width:1320px columns.
Section rhythm: Each section is a full scroll beat. Several are pinned/scrubbed and reserve extra track height (Who·260vh, Decade ~pin+0.78vh×steps, Numbers ~pin+2.4vh, Orbit ~(N-1)·88+100vh). Narrow/short viewports fall back to non-pinned "flat"/"stack" layouts (CSS-owned via [data-mode] / .tv-stack), never breaking.
Close: portfolio river → offices Atlas → light footer. No dark inversion.
Hero: solid near-white, oversized parallaxing ghost numeral, word-mask headline reveal, segmented auto-advance carousel (6.5s, hover/tab-hidden pause, swipe).
Motion catalogue: scroll progress bar; frosted-on-scroll header; word-by-word illuminate; pinned horizontal decade axis with year-fill + card focus; scrubbed stat grid with count-up + gold exit reveal; pinned criteria orbit (rotating ring, docking nodes, cross-fading panes); SVG ribbon "river" (grown source bars, drawn ribbons, flowing dashes, count-ups).
Media stance: schematic / type-led — the Taiho logomark is the one real mark; the "map" is a deliberate schematic placeholder ([ map of menlo park ]). Portfolio marks live in the river chips as links, not logo art. (FPO stamping from round 3 is not carried — v2 has no placeholder photography; revisit if real hero imagery is introduced.)
Reduced motion: every effect resolves to its end-state under prefers-reduced-motion / html.tv-calm.
Do:
screens/landing.tsx so a swap is a one-line change.Don't:
content/ (keep slots swappable + DRY).43-tvl-composer. Sections 1–7 are canonical.e0cf0312…); pull the named *.dc.html, translate markup → one component (using existing theme.css classes + the section's data-* contract), and add its motion init to scripts/index.client.ts INITS (keyed on a section attr, no-op when absent). To make a section the live one, point its screen's <Section init> at that key — sections are fixed now (no live swapping; see §8a).The live composer was removed (2026-06-29). Sections are now fixed: each screen renders one
chosen variant per slot via components/Section.tsx, and initSections in index.client.ts
boots them. The alternate variant components still ship in components/ (so any can be hand-wired
back), but Slot/ComposerPanel/composer.ts and the swap controller are gone. These invariants
still hold:
Section emits data-section-init={init}; that exact string MUST be a key
in the INITS map in index.client.ts. Mismatch ⇒ the section renders but has no motion (no
error). A section with no JS (e.g. Offices Atlas) just omits init — initSections still runs
reveal on every [data-section] wrapper.<section>s. The Section wrapper owns the in-page anchor id
(who/decade/look/portfolio/offices/…); variant components must NOT set it, or a
component that also hardcodes the id produces a duplicate and #anchor jumps to the wrong one.[data-carousel], not [data-cx],
specifically so the shared FrameLayout enhancer doesn't double-init it.Note: init*(scope) fns still return a teardown (legacy of the swap controller); nothing calls it
now, so a section's motion is one-shot. To swap a section, change its screen's <Section init> +
the imported component — no URL/localStorage state is involved anymore.
Created: 2026-06-24 as 43-tvl-composer (Round 4).
Lineage: 40-sumi-ocean-cvc → 42-tvl-toi (round 3) → 43-tvl-composer (round 4, scroll/composer).
Source: Claude Design project e0cf0312-a498-44fe-9760-73cdb16d7e61 — Taiho Ventures v2.dc.html and imported sections: Who We Are · Illuminated, Timeline · Decade Axis, By the Numbers · Portfolio Grid, What We Look For · Orbit Scroll, Portfolio · Outcomes River. The project holds many alternate variants per section (the future composer options).
Additions log:
index.client.ts; composer control UI deferred until the first alternate variant is pulled.content/composer.ts), Slot wrapper (pre-renders all variants, owns anchor ids), and the client-facing ComposerPanel ("Customize" tab). Refactored index.client.ts so each section init is scoped + returns cleanup, with a controller that resolves the active variant (URL ?slot=variant → localStorage → default), inits only the active one, and tears down/re-inits on swap. Added sym/year to portfolio data from the design system's portfolio-data.js (years are illustrative placeholders).Taiho Ventures v2.dc.html) was re-pulled — it dropped the Decade/Timeline section and bumped four sections to v2 treatments, so the home slots now default to them (prior treatments kept as live composer alternates): Who We Are · Illuminated v2 (WhoWeAreIlluminatedV2 + initIlluminatedV2 — 380vh pinned word-light with swept brush underlines on the two teal phrases + a lit inline logomark), By the Numbers · Portfolio Grid v2 (ByTheNumbersV2 + initNumbersV2 — the REAL 23-company roster instead of "30+", count→23, four gold exits at scattered slots with acquirer labels + hover tooltips), What We Look For · Preview v2 (WhatWeLookForPreview + initLookPreview — a 4-cell criteria quad opening accessible dialogs that link out to the Investment page), and Team · Portraits v2 (TeamPortraitsV2 + initTeamPortraitsV2 — FPO portrait grid → paged bio dialog). Portfolio · Logo Cloud promoted to the home default (Outcomes River / Living Roster kept as alternates). Factored a shared wireDialog + staggerIn helper in index.client.ts for the two modal sections. New CSS prefixed il2-/pv-/tm- (+ .tv-tip and [data-hot] hover, reusing .tv-cell/.tv-btn). Removed the home decade <Slot> (decade now lives on About); repointed home nav/footer "Decade" links to ${routes.about}#decade. Content: site.ts (whoWeAre.brushGroups, byNumbersV2), look.ts (lookPreview), reusing portfolio.ts/team.ts SSOTs. (Investment page still deferred — Preview v2 + grid CTAs already point at its route anchors.)screens/about.tsx, meta.screens now home+about; routes auto-gen from meta.screens → /desktop/43-tvl-composer/about/). Design source About Us.dc.html (Brush-Underline hero · Timeline Spotlight · Team Profiles · Offices Atlas). Built as independent per-page composer slots (about-hero/about-decade/about-team/about-offices in composer.ts) so About's composition + saved state are independent of the home scroll — its design picks are the defaults, with decade↔(spotlight/decade-axis) and team↔(profiles/portraits/directory) swappable live. New variants: Detail Hero · Brush Underline (DetailHeroBrush, reveal + CSS clip-path brush wipe, .dhbu-brush) and Team · Profiles (TeamProfiles, reveal-only, reuses the team.ts roster SSOT + TeamPortrait kind="pf"); reused Spotlight + Atlas as-is. Added content/routes.ts + route-aware per-screen nav (homeNav/aboutNav ScreenNav; Header/Footer now prop-driven; home's "About" repointed to the page). ComposerPanel rows are pruned per page by DOM presence in index.client (each page shows only its own controls). Extracted ProgressBar. Home nav/footer behavior unchanged except About→page. (Investment + Portfolio pages followed — see the next entry.)e0cf0312 sources (already a faithful, tokenized, DRY translation). Fixed the only non-copy drifts: logo-cloud tile 212×104→184×152; gave shared .tv-cell the design's border-radius + .45s fill transition (the grid scrub was snapping); header frost threshold 0.7vh/.82→y>8 / .96 to match the canonical SiteNav source (was matching neither home nor the nav); footer grid 1.6fr 1fr 1fr 1.2fr→1.5fr 1fr 1fr 1fr w/ design gap/padding; bumped DetailHeroBrush top padding to clear the fixed header on detail pages.screens/investment.tsx): brush hero → bespoke 4-criteria deep-dive (InvestmentCriteria; its inner <section>s own #sectors/#areas/#modality/#stage — the home preview's deep-link targets — so the slot itself is anchor-less) → Living Roster (Logo Cloud / Outcomes River as live swaps) → flame-watermark callout. Portfolio (screens/portfolio.tsx): brush hero → Living Roster → Outcomes River → flame-watermark callout. 2 net-new components: InvestmentCriteria + InsideCriteriaFlame (shared, prop-driven flame callout; needs public/brand/taiho-flame-teal.svg, pulled from design). InvestmentCriteria is reveal-only; InsideCriteriaFlame text reveals via runReveal, but its flame watermark animates in via initFlameCallout (flame-watermark INITS entry, [data-flame-in] hook). New content/investment.ts; portfolioHero/portfolioConnective added to content/portfolio.ts.nav.ts to the design's canonical 4-link SiteNav (Home / About Us / Investment / Portfolio, derived per-screen via screenNav()) + one shared SiteFooter IA (Company / Investment / Portfolio), replacing the drifted 6-link home / 3-link About nav; restored the footer-blurb parent-company link. homeNav/aboutNav + new investmentNav/portfolioNav all route-based.meta.screens +investment/+portfolio (routes auto-gen → /desktop/43-tvl-composer/{investment,portfolio}/); routes.ts +2; composer.ts +8 page-scoped slots (unique ids — see §8a.6); look.ts INVESTMENT_ROUTE→routes.investment (DRY SSOT); Slot gained optional divider (border-top) for stacked page sections (.tv-slot-divider).sym/year, still placeholder). Copy reconciled with docs/brand-voice.md; the Eli Lilly/Orna acquisition is confirmed accurate (Feb 2026 deal, per docs/tvl-firm-profile.md). Typecheck 0 errors; build 249 pages.What We Look For swapped to Pinned. Re-pulled Taiho Ventures v2.dc.html — the home's look section now imports What We Look For - Pinned in place of Preview v2. Ported as a new variant: What We Look For · Pinned (WhatWeLookForPinned + initLookPinned, pinned INITS entry) — a sticky 100vh deep-dive where the four criteria frames cross-fade as the track scrubs, a shared term rail + segmented bar mark the active dimension, and it out-links to the Investment page; unpins to a stacked list below 820px / reduced-motion (faithful port of the upstream pin logic, same pattern as Spotlight/Numbers v2). Promoted to the home look default; Preview v2 + Orbit Scroll kept as live composer alternates. New look.ts lookPinned (its leads/tags mirror the Pinned source verbatim — subtly different from lookFor/lookPreview); new lf--prefixed CSS block in theme.css. The Investment page's own criteria deep-dive (InvestmentCriteria) is unchanged — only the home preview slot moved. Typecheck 0 errors.components/Slot.tsx, components/ComposerPanel.tsx, the composer panel CSS ([data-composer]/tv-cmp-*), and the swap controller (initComposer, URL ?slot=variant + composer-43-tvl-composer localStorage) in index.client.ts. Replaced Slot with components/Section.tsx (owns the anchor id + optional tv-slot-divider + data-section-init hook); the new initSections walks [data-section] wrappers once at boot, runs reveal + the section's INITS motion (no teardown/re-init). Screens now import only their chosen variant (home: carousel · Illuminated v2 · Numbers v2 · Pinned · Logo Cloud · Portraits v2 · Atlas; About: brush · Spotlight · Profiles · Atlas; Investment: brush · Criteria · Living Roster · Flame; Portfolio: brush · Living Roster · Outcomes River · Flame). Alternate variant components are intentionally KEPT in components/ (Illuminated, Convergence, ByTheNumbers, Orbit, Preview, DecadeAxis, Portraits, Directory, …) + their INITS entries, so any can be hand-swapped back by repointing a <Section init> + its import. composer.ts retained as a catalog of available variants. See §8a (rewritten).