From 6eee162d741c3cd8480613e258afe5d56ee4dba8 Mon Sep 17 00:00:00 2001 From: Ben Jacobson Date: Thu, 8 Oct 2026 04:22:16 +0000 Subject: [PATCH] Redesign homepage with WorldVM styling and decision receipt --- docs/.vitepress/theme/DecisionTrace.vue | 70 ++ docs/.vitepress/theme/custom.css | 322 -------- docs/.vitepress/theme/home.css | 752 ++++++++++++++++++ docs/.vitepress/theme/index.ts | 3 + docs/index.md | 71 +- e2e/docs-home.spec.ts | 19 + e2e/docs-home.spec.ts-snapshots/home-dark.png | Bin 1011261 -> 1050871 bytes .../home-light.png | Bin 1002996 -> 1045435 bytes 8 files changed, 892 insertions(+), 345 deletions(-) create mode 100644 docs/.vitepress/theme/DecisionTrace.vue create mode 100644 docs/.vitepress/theme/home.css diff --git a/docs/.vitepress/theme/DecisionTrace.vue b/docs/.vitepress/theme/DecisionTrace.vue new file mode 100644 index 0000000..10dc224 --- /dev/null +++ b/docs/.vitepress/theme/DecisionTrace.vue @@ -0,0 +1,70 @@ + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index c3e5e7d..cbfd251 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -114,301 +114,6 @@ body { font-size: 14px; } -.triplex-index .VPHome { - margin-bottom: 0; - padding-bottom: 0; -} - -.triplex-index .VPHome > .vp-doc { - max-width: 1040px; - padding: 0 32px; -} - -.triplex-home { - padding: 48px 0 56px; -} - -.triplex-home__intro h1 { - margin: 0; - font-size: clamp(2rem, 5vw, 3rem); - font-weight: 600; - letter-spacing: -0.04em; - line-height: 1.15; -} - -.triplex-home__intro .triplex-home__tagline { - margin: 14px 0 0; - color: var(--vp-c-text-1); - font-size: clamp(1.35rem, 3vw, 1.75rem); - font-weight: 480; - letter-spacing: -0.025em; - line-height: 1.35; -} - -.triplex-home__intro .triplex-home__detail { - max-width: 760px; - margin: 10px 0 0; - color: var(--vp-c-text-2); - font-size: 1.05rem; - line-height: 1.65; -} - -.triplex-home__actions { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 12px 20px; - margin-top: 22px; -} - -.triplex-home__actions a { - display: inline-flex; - align-items: center; - font-weight: 520; - text-decoration: none; -} - -.triplex-home__actions .triplex-home__primary { - border-radius: 5px; - background: var(--vp-c-text-1); - color: var(--vp-c-bg); - padding: 9px 14px; -} - -.triplex-home__actions .triplex-home__primary:hover { - background: var(--vp-c-brand-1); -} - -.triplex-home__actions .triplex-home__secondary { - color: var(--vp-c-text-2); -} - -.triplex-home__actions .triplex-home__secondary:hover { - color: var(--vp-c-brand-1); -} - -.triplex-home__intro div[class*="language-"] { - max-width: 560px; - margin: 24px 0 0; - border: 1px solid var(--vp-c-divider); - border-radius: 7px; -} - -.triplex-home__intro .triplex-home__status { - max-width: 760px; - margin: 18px 0 0; - color: var(--vp-c-text-2); - font-size: 0.85rem; - line-height: 1.6; -} - -.triplex-home__agents { - margin-top: 40px; - padding: 20px 24px; - border: 1px solid color-mix(in srgb, var(--vp-c-brand-1) 35%, var(--vp-c-divider)); - border-radius: 7px; - background: var(--vp-c-brand-soft); -} - -.triplex-home__agents h2 { - margin: 0 0 10px; - padding: 0; - border: 0; - font-size: 1.05rem; - letter-spacing: -0.01em; -} - -.triplex-home__agents ul { - margin: 0; - padding-left: 1.1em; -} - -.triplex-home__agents li { - margin: 6px 0; - color: var(--vp-c-text-2); - font-size: 0.95rem; - line-height: 1.6; -} - -.triplex-home__agents li strong { - color: var(--vp-c-text-1); -} - -.triplex-home__section table { - display: table; - width: 100%; - margin: 0; - font-size: 0.9rem; -} - -.triplex-home__section th { - white-space: nowrap; -} - -.triplex-home__section div[class*="language-"] + table { - margin-top: 24px; -} - -.triplex-home__section td, -.triplex-home__section th { - vertical-align: top; -} - -.triplex-home__timeline { - overflow-x: auto; -} - -.triplex-home__timeline table { - font-size: 0.82rem; -} - -.triplex-home__timeline td:first-child { - text-align: right; -} - -.triplex-home__timeline td, -.triplex-home__timeline th { - padding: 8px 12px; - white-space: nowrap; -} - -.triplex-home .triplex-home__output-label { - margin: 18px 0 8px; - color: var(--vp-c-text-2); - font-family: var(--vp-font-family-mono); - font-size: 0.72rem; - letter-spacing: 0.06em; - text-transform: uppercase; -} - -.triplex-home .triplex-home__output-label code { - font-size: inherit; - text-transform: none; -} - -.triplex-home__link-icon { - flex: none; - margin-left: 0.375em; -} - -.triplex-home__section { - margin-top: 64px; - padding-top: 32px; - border-top: 1px solid var(--vp-c-divider); -} - -.triplex-home__section-intro { - max-width: 760px; - margin-bottom: 28px; -} - -.triplex-home .triplex-home__eyebrow { - margin: 0 0 10px; - color: var(--vp-c-brand-1); - font-family: var(--vp-font-family-mono); - font-size: 0.72rem; - letter-spacing: 0.06em; - text-transform: uppercase; -} - -.triplex-home__section h2 { - margin: 0 0 16px; - padding: 0; - border: 0; - font-size: clamp(1.5rem, 3vw, 1.9rem); - line-height: 1.25; -} - -.triplex-home__section h3 { - margin: 0 0 10px; - font-size: 1.1rem; - line-height: 1.4; -} - -.triplex-home__section p { - color: var(--vp-c-text-2); - line-height: 1.7; -} - -.triplex-home__principles { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 24px; - margin-top: 28px; -} - -.triplex-home__principles > div { - padding: 20px; - border: 1px solid var(--vp-c-divider); - border-radius: 7px; - background: var(--vp-c-bg-elv); -} - -.triplex-home__principles p { - margin: 0; - font-size: 0.95rem; -} - -.triplex-home .triplex-home__fit { - margin: 24px 0 0; - font-size: 0.95rem; -} - -.triplex-home__example { - margin-top: 36px; -} - -.triplex-home__example + .triplex-home__example { - padding-top: 36px; - border-top: 1px solid var(--vp-c-divider); -} - -.triplex-home__example-description { - max-width: 760px; - margin-bottom: 20px; -} - -.triplex-home__example-description p { - margin: 0 0 12px; - font-size: 0.95rem; -} - -.triplex-home__example-description a { - display: inline-flex; - align-items: center; - font-size: 0.95rem; -} - -.triplex-home__snippet { - min-width: 0; -} - -.triplex-home__snippet div[class*="language-"], -.triplex-home__section > div[class*="language-"] { - margin: 0; - border: 1px solid var(--vp-c-divider); - border-radius: 7px; - box-shadow: none; -} - -.triplex-home__guides { - display: flex; - flex-wrap: wrap; - gap: 16px 32px; - margin-top: 32px; - font-size: 0.95rem; -} - -.triplex-home__guides a { - display: inline-flex; - align-items: center; -} - -.triplex-home a:focus-visible { - outline: 2px solid var(--vp-c-brand-1); - outline-offset: 4px; -} - .vp-doc:not(.triplex-home) h1 { letter-spacing: -0.045em; } @@ -416,30 +121,3 @@ body { .vp-doc:not(.triplex-home) h2 { letter-spacing: -0.025em; } - -@media (max-width: 640px) { - .triplex-index .VPHome > .vp-doc { - padding: 0 24px; - } - - .triplex-home { - padding: 36px 0 44px; - } - - .triplex-home__section { - margin-top: 40px; - padding-top: 28px; - } -} - -@media (max-width: 800px) { - .triplex-home__section table { - display: block; - overflow-x: auto; - } - - .triplex-home__principles { - grid-template-columns: 1fr; - gap: 20px; - } -} diff --git a/docs/.vitepress/theme/home.css b/docs/.vitepress/theme/home.css new file mode 100644 index 0000000..b68d49b --- /dev/null +++ b/docs/.vitepress/theme/home.css @@ -0,0 +1,752 @@ +/* Blueprint paper, stamped type, and inspectable evidence: Triplex's place + in the WorldVM family. These styles belong only to the public homepage. */ +.triplex-index { + --vp-c-bg: #f6f8fb; + --vp-c-bg-elv: #fff; + --vp-c-text-1: #17202b; + --vp-c-text-2: #596574; + --vp-c-divider: #d9e1eb; + --home-accent: #3457d5; + --home-stamp: #1c368d; + --home-brand: #a7b5ff; + --home-grid: rgb(73 103 163 / 9%); + --home-shadow: #17202b; +} +.dark .triplex-index { + --vp-c-bg: #0d121c; + --vp-c-bg-elv: #141d2b; + --vp-c-text-1: #e8edf6; + --vp-c-text-2: #a7b3c7; + --vp-c-divider: #29354b; + --home-accent: #a7b5ff; + --home-stamp: #5974d1; + --home-grid: rgb(132 164 250 / 7%); + --home-shadow: #40516f; +} +.triplex-index .VPHome { + margin-bottom: 0; + padding-bottom: 0; +} +.triplex-index .VPHome > .vp-doc { + max-width: 1280px; + padding: 0 48px; +} +.triplex-home { + padding-bottom: 48px; +} +.triplex-home h1, +.triplex-home h2, +.triplex-home h3 { + margin: 0; + padding: 0; + border: 0; + color: var(--vp-c-text-1); +} +.triplex-home p { + color: var(--vp-c-text-2); + line-height: 1.7; +} +.triplex-home .triplex-home__eyebrow { + display: flex; + align-items: center; + gap: 10px; + margin: 0 0 16px; + font: 400 11px/1.6 var(--vp-font-family-mono); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--home-accent); +} +.triplex-home__dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: #23966b; + box-shadow: 0 0 0 4px rgb(35 150 107 / 12%); + flex: none; +} +.triplex-home__intro { + position: relative; + display: grid; + grid-template-columns: 1.06fr 1fr; + align-items: center; + gap: 56px; + padding: 72px 0 64px; +} +.triplex-home__intro::before { + content: ""; + position: absolute; + inset: 0 -48px -32px; + pointer-events: none; + background-image: + linear-gradient(to right, var(--home-grid) 1px, transparent 1px), + linear-gradient(to bottom, var(--home-grid) 1px, transparent 1px); + background-size: 32px 32px; + mask-image: radial-gradient(ellipse at 50% 35%, #000 30%, transparent 75%); +} +.triplex-home__intro > * { + position: relative; + min-width: 0; +} +.triplex-home__wordmark { + margin: 12px 0 30px; + color: var(--home-brand); + font: 800 clamp(76px, 8.8vw, 116px)/0.95 var(--vp-font-family-mono); + letter-spacing: -0.09em; + -webkit-text-stroke: 1.5px var(--home-stamp); + text-shadow: 4px 4px 0 var(--home-stamp); +} +.triplex-home__wordmark span { + color: var(--home-stamp); + text-shadow: none; +} +.triplex-home__intro h1 { + max-width: 540px; + font-size: clamp(36px, 4vw, 52px); + font-weight: 650; + letter-spacing: -0.045em; + line-height: 1.06; +} +.triplex-home__intro .triplex-home__tagline { + max-width: 450px; + margin: 22px 0 0; + font-size: 21px; + line-height: 1.45; + color: var(--vp-c-text-1); +} +.triplex-home__intro .triplex-home__detail { + margin-top: 16px; + font-size: 16px; +} +.triplex-home__detail strong { + color: var(--vp-c-text-1); +} +.triplex-home__actions { + display: flex; + flex-wrap: wrap; + gap: 16px; + margin-top: 28px; +} +.triplex-home__actions a { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + min-height: 44px; + padding: 9px 16px; + border: 1.5px solid var(--vp-c-text-1); + border-radius: 8px; + background: var(--vp-c-bg-elv); + color: var(--vp-c-text-1); + box-shadow: 4px 4px 0 var(--home-shadow); + font-size: 14px; + font-weight: 600; + text-decoration: none; + transition: + transform 0.15s, + box-shadow 0.15s; +} +.triplex-home__actions .triplex-home__primary { + background: var(--vp-c-text-1); + color: var(--vp-c-bg); + box-shadow: 4px 4px 0 var(--home-brand); +} +.triplex-home__actions a:hover { + transform: translate(-1px, -1px); + box-shadow: 5px 5px 0 var(--home-accent); +} +.triplex-home__actions a:active { + transform: translate(3px, 3px); + box-shadow: 1px 1px 0 var(--home-accent); +} +.triplex-home__intro .triplex-home__status { + margin-top: 24px; + font-size: 12px; + line-height: 1.9; +} +.decision-trace { + margin: 0; + font-family: var(--vp-font-family-mono); +} +.decision-trace__bar, +.decision-trace__body { + background: #10182a; + color: #d9e2f5; +} +.decision-trace__bar { + display: flex; + align-items: center; + gap: 14px; + padding: 16px 20px; + border: 1.5px solid #263654; + border-radius: 12px 12px 0 0; + background: #182238; + font-size: 10px; + box-shadow: 7px 7px 0 var(--home-brand); +} +.decision-trace__dots { + display: flex; + gap: 5px; +} +.decision-trace__dots i { + width: 7px; + height: 7px; + border-radius: 50%; + background: #64728a; +} +.decision-trace__dots i:first-child { + background: #f18487; +} +.decision-trace__dots i:nth-child(2) { + background: #edc379; +} +.decision-trace__dots i:last-child { + background: #7ebf9f; +} +.decision-trace__badge { + margin-left: auto; + color: #a7b5ff; +} +.decision-trace__body { + padding: 28px; + border: 1.5px solid #263654; + border-top: 0; + border-radius: 0 0 12px 12px; + box-shadow: 7px 7px 0 var(--home-brand); +} +.triplex-home .decision-trace__comment { + margin: 0 0 20px; + color: #8192b3; + font-size: 12px; +} +.decision-trace__fields { + margin: 0; + font-size: 13px; +} +.decision-trace__fields > div { + display: grid; + grid-template-columns: 122px 1fr; + gap: 10px; + margin: 9px 0; +} +.decision-trace__fields dt { + color: #91a4c5; +} +.decision-trace__fields dd { + margin: 0; + color: #93dcc0; +} +.decision-trace__fields .decision-trace__violet { + color: #b6a5ff; +} +.decision-trace__divider { + margin: 25px 0 18px; + padding-top: 18px; + border-top: 1px dashed #35425c; + color: #8192b3; + font-size: 10px; +} +.triplex-home .decision-trace__question { + color: #e6ecf8; + margin: 0 0 16px; + font-family: var(--vp-font-family-base); + font-size: 19px; + font-weight: 500; +} +.decision-trace__controls { + display: flex; + gap: 4px; + padding: 4px; + border: 1px solid #35425c; + border-radius: 6px; +} +.decision-trace__controls button { + flex: 1; + padding: 8px 4px; + color: #a4b3cf; + background: transparent; + border-radius: 3px; + font: inherit; + font-size: 10px; + cursor: pointer; +} +.decision-trace__controls button:hover { + color: #fff; + background: #26334d; +} +.decision-trace__controls button[aria-pressed="true"] { + color: #eef2ff; + background: #34476f; +} +.decision-trace__result { + display: grid; + grid-template-columns: 1fr auto; + padding: 20px 0 0; + min-height: 116px; +} +.decision-trace__result-key { + font-size: 13px; + color: #91a4c5; +} +.decision-trace__result strong { + font-size: 20px; +} +.decision-trace__yes { + color: #93dcc0; +} +.decision-trace__no { + color: #f6ae98; +} +.triplex-home .decision-trace__result p { + grid-column: 1 / -1; + margin: 9px 0 0; + color: #a4b3cf; + font-size: 11px; + line-height: 1.7; +} +.triplex-home .decision-trace__footer { + margin: 18px 0 0; + font-size: 10px; + color: #8192b3; +} +.decision-trace__footer span { + color: #a7b5ff; +} +.decision-trace figcaption { + margin: 18px 0 0; + font-size: 10px; + color: var(--vp-c-text-2); + text-align: right; +} +.decision-trace figcaption a { + text-decoration: none; +} +.triplex-home__install { + display: flex; + align-items: center; + gap: 20px; + padding: 20px 0; + border-top: 1px solid var(--vp-c-divider); +} +.triplex-home__install .triplex-home__eyebrow { + margin: 0; + color: var(--vp-c-text-2); + font-size: 10px; + flex: none; +} +.triplex-home__install div[class*="language-"] { + flex: 1; + min-width: 0; + margin: 0; + border: 1px solid #263654; + border-radius: 6px; +} +.triplex-home__install div[class*="language-"] pre { + padding: 12px 0; +} +.triplex-home__install div[class*="language-"] code { + padding: 0 18px; + font-size: 11px; +} +.triplex-home__install-note { + font-size: 11px; + color: var(--vp-c-text-2); +} +.triplex-home__strip { + display: grid; + grid-template-columns: repeat(3, 1fr); + border-block: 1px solid var(--vp-c-divider); +} +.triplex-home__strip a { + display: grid; + grid-template-columns: 48px 1fr; + gap: 3px 16px; + padding: 26px 20px; + text-decoration: none; + color: var(--vp-c-text-1); +} +.triplex-home__strip a + a { + border-left: 1px solid var(--vp-c-divider); +} +.triplex-home__strip-symbol { + grid-row: span 2; + align-self: center; + color: var(--home-accent); + font: 500 24px var(--vp-font-family-mono); +} +.triplex-home__strip strong { + font-size: 16px; +} +.triplex-home__strip a > span:last-child { + font-size: 12px; + color: var(--vp-c-text-2); +} +.triplex-home__strip a:hover { + background: var(--vp-c-bg-elv); +} +.triplex-home__agents { + display: grid; + grid-template-columns: 240px 1fr; + gap: 24px; + padding: 24px 0; + border-bottom: 1px solid var(--vp-c-divider); +} +.triplex-home__agents h2 { + font: 500 12px/1.7 var(--vp-font-family-mono); +} +.triplex-home__agents p { + margin: 0; + font-size: 13px; +} +.triplex-home__section { + margin-top: 72px; + padding-top: 36px; + border-top: 1px solid var(--vp-c-divider); +} +.triplex-home__agents + .triplex-home__section { + border: 0; + padding-top: 0; +} +.triplex-home__section-intro { + max-width: 780px; + margin-bottom: 32px; +} +.triplex-home__section h2 { + font-size: clamp(28px, 3.4vw, 42px); + font-weight: 650; + letter-spacing: -0.035em; + line-height: 1.12; +} +.triplex-home__section h3 { + font-size: 24px; + font-weight: 550; + letter-spacing: -0.025em; + line-height: 1.25; +} +.triplex-home__section-intro > p:not(.triplex-home__eyebrow) { + margin: 18px 0 0; + font-size: 16px; +} +.triplex-home__section table { + display: table; + width: 100%; + margin: 0; + font-size: 13px; +} +.triplex-home__section th { + font: 500 11px/1.6 var(--vp-font-family-mono); + text-align: left; + background: var(--vp-c-bg-alt); +} +.triplex-home__section th, +.triplex-home__section td { + padding: 14px 18px; + border-color: var(--vp-c-divider); + vertical-align: top; +} +.triplex-home__section tr:nth-child(2n) { + background: transparent; +} +.triplex-home__timeline { + overflow-x: auto; + border: 1px solid var(--vp-c-divider); + border-radius: 8px; +} +.triplex-home__timeline table { + font-size: 12px; +} +.triplex-home__timeline th, +.triplex-home__timeline td { + white-space: nowrap; + padding: 10px 14px; +} +.triplex-home__timeline td:first-child { + text-align: right; +} +.triplex-home .triplex-home__fit { + margin: 24px 0 0; + font-size: 15px; +} +.triplex-home__example { + display: grid; + grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); + gap: 44px; + margin-top: 40px; +} +.triplex-home__example + .triplex-home__example { + padding-top: 48px; + border-top: 1px solid var(--vp-c-divider); +} +.triplex-home__example-description p { + margin: 16px 0; + font-size: 15px; +} +.triplex-home__example-description a { + display: inline-flex; + align-items: center; + font-size: 13px; +} +.triplex-home__snippet { + min-width: 0; +} +.triplex-home__snippet div[class*="language-"], +.triplex-home__section > div[class*="language-"] { + margin: 0; + border: 1.5px solid #263654; + border-radius: 9px; + box-shadow: 5px 5px 0 var(--home-brand); +} +.triplex-home__snippet div[class*="language-"] code { + font-size: 11px; +} +.triplex-home .triplex-home__output-label { + margin: 24px 0 10px; + font: 400 10px/1.6 var(--vp-font-family-mono); + letter-spacing: 0.08em; + text-transform: uppercase; +} +.triplex-home__output-label code { + font-size: inherit; + text-transform: none; +} +.triplex-home__link-icon { + flex: none; + margin-left: 0.375em; +} +.triplex-home__section > div[class*="language-"] + table { + margin-top: 28px; +} +.triplex-home__principles { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; + margin-top: 32px; +} +.triplex-home__principles > div { + padding: 24px; + border: 1px solid var(--vp-c-divider); + border-top: 3px solid var(--home-accent); + border-radius: 4px; + background: var(--vp-c-bg-elv); +} +.triplex-home__principles h3 { + font-size: 19px; +} +.triplex-home__principles p { + margin-bottom: 0; + font-size: 14px; +} +.triplex-home__family { + margin-top: 80px; + padding: 40px; + background: #f7f4ec; + border: 1px solid #ddd5c6; + border-radius: 12px; +} +.triplex-home__family .triplex-home__eyebrow { + color: #726553; +} +.triplex-home__family-head { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 40px; + align-items: center; +} +.triplex-home__family h2 { + color: #302b23; + font-size: 38px; + font-weight: 650; + letter-spacing: -0.035em; + line-height: 1.1; +} +.triplex-home__family-head p { + color: #726553; + margin: 0; + font-size: 14px; +} +.triplex-home__family-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + margin-top: 28px; +} +.triplex-home__family-grid a { + display: flex; + flex-direction: column; + gap: 12px; + padding: 22px; + border: 1px solid #ddd5c6; + border-radius: 8px; + background: #fffdf7; + color: #302b23; + text-decoration: none; +} +.triplex-home__family-grid a:hover { + border-color: #726553; +} +.triplex-home__swatch { + width: 28px; + height: 28px; + border: 1px solid rgb(48 43 35 / 15%); + border-radius: 5px; + background: var(--project-color); +} +.triplex-home__family-grid strong { + font-size: 18px; +} +.triplex-home__family-grid a > span:last-child { + font-size: 13px; + color: #726553; + line-height: 1.6; +} +.triplex-home .triplex-home__family-link { + display: inline-block; + margin-top: 24px; + font-size: 14px; + font-weight: 600; + color: #302b23; +} +.triplex-home__guides { + display: flex; + flex-wrap: wrap; + gap: 16px 28px; + margin-top: 36px; + font-size: 13px; +} +.triplex-home__guides a { + display: inline-flex; + align-items: center; +} +.triplex-home :is(a, button):focus-visible { + outline: 3px solid var(--home-accent); + outline-offset: 4px; +} +.triplex-home .decision-trace button:focus-visible { + outline-color: #a7b5ff; +} +@media (max-width: 1000px) { + .triplex-home__intro { + gap: 32px; + } + .triplex-home__install { + flex-wrap: wrap; + } + .triplex-home__install-note { + width: 100%; + } + .triplex-home__strip a { + grid-template-columns: 1fr; + } + .triplex-home__strip-symbol { + grid-row: auto; + } + .triplex-home__example { + grid-template-columns: 1fr; + gap: 20px; + } + .triplex-home__example-description { + max-width: 780px; + } +} +@media (max-width: 800px) { + .triplex-index .VPHome > .vp-doc { + padding: 0 24px; + } + .triplex-home__intro { + grid-template-columns: 1fr; + padding: 44px 0; + gap: 40px; + } + .triplex-home__intro::before { + inset-inline: -24px; + } + .triplex-home__wordmark { + font-size: 90px; + } + .triplex-home__hero-copy { + max-width: 560px; + } + .decision-trace { + width: 100%; + max-width: 560px; + } + .triplex-home__agents { + grid-template-columns: 1fr; + gap: 10px; + } + .triplex-home__section table { + display: block; + overflow-x: auto; + } + .triplex-home__principles, + .triplex-home__family-head { + grid-template-columns: 1fr; + gap: 20px; + } + .triplex-home__family { + padding: 28px; + } + .triplex-home__family-grid { + grid-template-columns: 1fr; + } +} +@media (max-width: 480px) { + .triplex-home__wordmark { + font-size: 76px; + } + .triplex-home__intro .triplex-home__eyebrow { + font-size: 9px; + } + .triplex-home__strip { + grid-template-columns: 1fr; + } + .triplex-home__strip a { + grid-template-columns: 48px 1fr; + padding: 18px 12px; + } + .triplex-home__strip-symbol { + grid-row: span 2; + } + .triplex-home__strip a + a { + border-left: 0; + border-top: 1px solid var(--vp-c-divider); + } + .triplex-home__install { + gap: 12px; + } + .triplex-home__install .triplex-home__eyebrow { + width: 100%; + } + .decision-trace__body { + padding: 22px; + } + .decision-trace__bar { + padding: 14px; + gap: 9px; + font-size: 9px; + } + .decision-trace__fields { + font-size: 11px; + } + .decision-trace__fields > div { + grid-template-columns: 95px 1fr; + } + .decision-trace__controls button { + font-size: 9px; + } + .triplex-home__section { + margin-top: 48px; + padding-top: 28px; + } + .triplex-home__family { + padding: 24px; + margin-top: 48px; + } + .triplex-home__family h2 { + font-size: 32px; + } +} +@media (prefers-reduced-motion: reduce) { + .triplex-home__actions a { + transition: none; + } +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index e22329e..18ad500 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -5,8 +5,10 @@ import DefaultTheme from "vitepress/theme-without-fonts"; import { defineComponent, h } from "vue"; import "./custom.css"; +import "./home.css"; import Playground from "./Playground.vue"; import TriplexExplorer from "./TriplexExplorer.vue"; +import DecisionTrace from "./DecisionTrace.vue"; export default { extends: DefaultTheme, @@ -29,6 +31,7 @@ export default { }, }), enhanceApp({ app }) { + app.component("DecisionTrace", DecisionTrace); app.component("TriplexPlayground", Playground); app.component("TriplexExplorer", TriplexExplorer); }, diff --git a/docs/index.md b/docs/index.md index f0dd762..151e916 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,36 +11,47 @@ pageClass: triplex-index
-

Triplex

+
+

An embedded fact database · TypeScript + Effect

+

The database that remembers why.

-

An embedded fact database for TypeScript back-office systems.

-

Every write records who made it, which versioned rules governed it, and when it was true. Audit questions and open work become queries instead of investigations.

+

Facts change. Rules change. Your record of what happened shouldn’t.

+

Triplex keeps facts, time, and versioned rules together. Every write records who acted, which rules applied, and when it was true. Audit questions and open work become queries instead of investigations.

+ + +

Pre-1.0 · MIT licensed · In-memory + SQLite supported
PostgreSQL is a production candidate · Current state ↗

+
+ +
+ +
+Start in your process ```sh npm install @triplex-build/triplex effect@4.0.0-rc.112 ``` - -

Pre-1.0 · Built on Effect 4 (effect@4.0.0-rc.112; Effect 3 is not compatible) · In-memory and SQLite supported · PostgreSQL is a production candidate · Maturity contract

- + +
-

The problem

+

00 / The missing context

“Why?” is the most expensive question a back-office system gets asked.

An auditor asks: was Maria trained for the Harbor site on the day she started there? In a typical stack, the evidence is spread across systems that never shared an identity model or a clock.

@@ -57,10 +68,10 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
-

One scenario, start to finish

+

01 / One scenario, start to finish

Maria, the Harbor site, and a certificate that was wrong.

Maria is trained for Harbor from March 1 to June 1 and placed there on March 2 under release hr-2026.1. The rules then change: hr-2026.2 requires a supervisor on every placement. Later, an auditor finds that the certificate actually began on March 5.

-

After the scenario runs, the database’s own journal reads:

+

Every snippet is type-checked. Every output is produced by running this scenario in CI. The database’s own journal reads:

@@ -87,7 +98,7 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
-

Three questions, three queries

+

02 / Three questions, three queries

Ask what you knew, which rules applied, and what happens next.

Each answer below is the real output of the code beside it.

@@ -157,7 +168,7 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
-

Derived work

+

03 / Derived work

Stop enqueuing obligations. Reconcile them.

Most back-office bugs come down to a task that should exist but doesn’t, or one that exists but shouldn’t. Event handlers create work one step at a time and drift out of sync with the data. A derivation states what should be true, and reconciliation reports the difference.

@@ -189,7 +200,7 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
-

Modeling

+

04 / Modeling

From a back-office domain to Triplex primitives.

Most back-office systems are built from the same parts. This is where each part goes.

@@ -211,7 +222,7 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
-

Deployment

+

05 / Deployment

A library, not another server.

Triplex runs inside your process as Effect layers. Switching storage changes the layer you provide, and the rest of the program stays the same. On PostgreSQL, Triplex can share your application’s transaction, so your own rows, Triplex facts, the journal, and an outbox row commit or roll back together.

@@ -231,7 +242,7 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
-

Fit

+

06 / Fit

When to use Triplex, and when not to.

@@ -250,6 +261,20 @@ npm install @triplex-build/triplex effect@4.0.0-rc.112
+
+

07 / Part of the WorldVM family

+
+

A memory for your world.

+

Small experiments in software you can inspect, explain, and build on. Triplex keeps the facts. These projects explore the language and models around them.

+
+ +Meet the whole family at worldvm.com ↗ +
+