update
This commit is contained in:
1 parent
f5d4f8b705
commit
9779c4d1ca
24 files changed
+2782
-130
No files matched your search
@@ -4,7 +4,7 @@
|
||||
"output": "/Users/zacharyzhang/Documents/Github/AgentCompany/build/release"
|
||||
},
|
||||
"extraMetadata": {
|
||||
"version": "0.4.156"
|
||||
"version": "0.4.165"
|
||||
},
|
||||
"publish": [
|
||||
{
|
||||
|
||||
+128
-3
@@ -1,3 +1,128 @@
|
||||
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*
|
||||
! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com
|
||||
*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:JetBrains Mono,SF Mono,Roboto Mono,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media (min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.\!visible{visibility:visible!important}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.bottom-4{bottom:1rem}.left-0{left:0}.left-\[15px\]{left:15px}.right-0{right:0}.top-0{top:0}.top-10{top:2.5rem}.z-10{z-index:10}.z-50{z-index:50}.order-1{order:1}.order-2{order:2}.mx-auto{margin-left:auto;margin-right:auto}.-mb-10{margin-bottom:-2.5rem}.mb-1\.5{margin-bottom:.375rem}.mb-12{margin-bottom:3rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-20{margin-bottom:5rem}.mb-24{margin-bottom:6rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-2{margin-left:.5rem}.mt-12{margin-top:3rem}.mt-14{margin-top:3.5rem}.mt-2{margin-top:.5rem}.mt-20{margin-top:5rem}.mt-24{margin-top:6rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-7{margin-top:1.75rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-11{height:2.75rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-8{height:2rem}.h-\[340px\]{height:340px}.h-auto{height:auto}.h-full{height:100%}.max-h-0{max-height:0}.max-h-64{max-height:16rem}.max-h-96{max-height:24rem}.w-1\.5{width:.375rem}.w-11{width:2.75rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-8{width:2rem}.w-full{width:100%}.w-px{width:1px}.min-w-\[120px\]{min-width:120px}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.rotate-45{--tw-rotate:45deg}.rotate-45,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--twLine truncated
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
--font-serif: "Space Grotesk", "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-mono: "Space Mono", ui-monospace, SFMono-Regular, monospace;
|
||||
}
|
||||
|
||||
/* ── Light Theme (Cohere) ── */
|
||||
:root {
|
||||
--bg: #ffffff;
|
||||
--bg-subtle: #fafafa;
|
||||
--panel: #ffffff;
|
||||
--panel-soft: #fafafa;
|
||||
--text: #000000;
|
||||
--text-secondary: #212121;
|
||||
--muted: #93939f;
|
||||
--muted-strong: #565650;
|
||||
--accent: #1863dc;
|
||||
--accent-hover: #1352b8;
|
||||
--accent-soft: rgba(24, 99, 220, 0.06);
|
||||
--text-on-accent: #ffffff;
|
||||
--cta: #000000;
|
||||
--cta-hover: #212121;
|
||||
--cta-soft: rgba(0, 0, 0, 0.04);
|
||||
--text-on-cta: #ffffff;
|
||||
--text-on-cta-muted: rgba(255, 255, 255, 0.75);
|
||||
--text-on-cta-faint: rgba(255, 255, 255, 0.60);
|
||||
--border: rgba(0, 0, 0, 0.06);
|
||||
--border-cool: #d9d9dd;
|
||||
--glow-warm: rgba(24, 99, 220, 0.04);
|
||||
--glow-accent: rgba(24, 99, 220, 0.03);
|
||||
--section-alt: rgba(0, 0, 0, 0.015);
|
||||
}
|
||||
|
||||
/* ── Dark Theme (Cohere) ── */
|
||||
.dark {
|
||||
--bg: #17171c;
|
||||
--bg-subtle: #1e1e24;
|
||||
--panel: #212126;
|
||||
--panel-soft: #2a2a30;
|
||||
--text: #fafafa;
|
||||
--text-secondary: #d9d9dd;
|
||||
--muted: #93939f;
|
||||
--muted-strong: #b8b8b2;
|
||||
--accent: #1863dc;
|
||||
--accent-hover: #2070e8;
|
||||
--accent-soft: rgba(24, 99, 220, 0.12);
|
||||
--text-on-accent: #ffffff;
|
||||
--cta: #fafafa;
|
||||
--cta-hover: #e5e5e5;
|
||||
--cta-soft: rgba(250, 250, 250, 0.06);
|
||||
--text-on-cta: #17171c;
|
||||
--text-on-cta-muted: rgba(23, 23, 28, 0.75);
|
||||
--text-on-cta-faint: rgba(23, 23, 28, 0.60);
|
||||
--border: rgba(250, 250, 250, 0.08);
|
||||
--border-cool: #333338;
|
||||
--glow-warm: rgba(24, 99, 220, 0.06);
|
||||
--glow-accent: rgba(24, 99, 220, 0.04);
|
||||
--section-alt: rgba(24, 99, 220, 0.025);
|
||||
}
|
||||
|
||||
/* ── Base ── */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: var(--accent);
|
||||
color: var(--text-on-accent);
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ── Scrollbar ── */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--muted);
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--border) transparent;
|
||||
}
|
||||
|
||||
/* ── Reduced Motion ── */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +205,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap"
|
||||
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script dangerouslySetInnerHTML={{ __html: themeScript }} />
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Footer } from "../components/footer";
|
||||
import { Hero } from "../components/hero";
|
||||
import { HowItWorks } from "../components/how-it-works";
|
||||
import { Navbar } from "../components/navbar";
|
||||
import { RuntimesBar } from "../components/runtimes-bar";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
@@ -20,6 +21,7 @@ export default function Page() {
|
||||
|
||||
<main id="main">
|
||||
<Hero />
|
||||
<RuntimesBar />
|
||||
<Features />
|
||||
<HowItWorks />
|
||||
<FAQ />
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { AsciiBackground } from "./ascii-background";
|
||||
import { platformDownloads, releaseVersion } from "./release-links.generated";
|
||||
import { DOWNLOAD_COUNT_SEED, getTrackedDownloadHref } from "../lib/downloads";
|
||||
|
||||
@@ -34,81 +33,73 @@ export function DownloadSection() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section id="download" className="py-24 lg:py-40 px-4 sm:px-6 lg:px-8 relative overflow-hidden">
|
||||
<motion.div
|
||||
className="relative mx-auto max-w-5xl rounded-3xl p-14 lg:p-24 overflow-hidden"
|
||||
style={{
|
||||
background: "linear-gradient(135deg, var(--cta) 0%, color-mix(in srgb, var(--cta) 85%, #000) 100%)",
|
||||
}}
|
||||
initial={{ opacity: 0, scale: 0.92 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true, margin: "-80px" }}
|
||||
transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1] }}
|
||||
>
|
||||
<AsciiBackground cssVar="--text-on-cta" baseOpacity={0.1} speed={0.8} />
|
||||
|
||||
<div
|
||||
className="absolute inset-0 pointer-events-none opacity-[0.03]"
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
"url(\"data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E\")",
|
||||
backgroundRepeat: "repeat",
|
||||
backgroundSize: "128px 128px",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
className="absolute inset-0 pointer-events-none"
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(ellipse at top right, rgba(255,255,255,0.12) 0%, transparent 50%), radial-gradient(ellipse at bottom left, rgba(255,255,255,0.06) 0%, transparent 50%)",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="relative z-10 flex flex-col items-center text-center">
|
||||
<h2 className="font-serif italic text-[clamp(2rem,1.5rem+2.5vw,3.25rem)] tracking-[-0.01em] text-[var(--text-on-cta)] mb-6">
|
||||
<section id="download" className="py-24 lg:py-40 px-4 sm:px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="text-center mb-16 lg:mb-20"
|
||||
>
|
||||
<p className="font-mono text-xs font-medium uppercase tracking-[0.25em] text-[var(--accent)] mb-5">
|
||||
Download
|
||||
</p>
|
||||
<h2 className="font-serif text-[clamp(2rem,1.5rem+2.5vw,3.25rem)] tracking-[-0.01em] text-[var(--text)]">
|
||||
Install the Right Build for Your Machine
|
||||
</h2>
|
||||
<p className="text-[var(--text-on-cta-muted)] text-lg max-w-xl mx-auto mb-12 leading-relaxed">
|
||||
Version {releaseVersion}.
|
||||
</p>
|
||||
<p className="text-[var(--text-on-cta-faint)] text-sm max-w-xl mx-auto mb-12 leading-relaxed -mt-8">
|
||||
Downloads: {downloadCount.toLocaleString("en-US")}
|
||||
<p className="text-[var(--muted)] text-lg mt-5 leading-relaxed">
|
||||
Version {releaseVersion} · {downloadCount.toLocaleString("en-US")} downloads
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="w-full mt-2 grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{platformDownloads.map((download, index) => (
|
||||
<motion.div
|
||||
key={download.id}
|
||||
initial={{ opacity: 0, y: 24 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
transition={{ duration: 0.5, delay: 0.08 * index, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="rounded-2xl border border-white/10 bg-white/6 backdrop-blur-xl shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] p-6 lg:p-7 text-left"
|
||||
>
|
||||
<p className="font-mono text-xs uppercase tracking-[0.25em] text-[var(--text-on-cta-faint)] mb-3">
|
||||
{download.title}
|
||||
</p>
|
||||
<div className="space-y-2.5">
|
||||
{download.assets.map((asset) => (
|
||||
<a
|
||||
key={asset.id}
|
||||
href={getTrackedDownloadHref(asset.id)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center rounded-xl border border-white/12 bg-black/10 px-4 py-3 text-sm text-[var(--text-on-cta)] transition-colors duration-200 hover:bg-black/18"
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 lg:gap-8">
|
||||
{platformDownloads.map((download, index) => (
|
||||
<motion.div
|
||||
key={download.id}
|
||||
initial={{ opacity: 0, y: 24 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
transition={{ duration: 0.5, delay: 0.08 * index, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="rounded-[22px] border border-[var(--border)] bg-[var(--panel)] p-6 lg:p-7"
|
||||
>
|
||||
<p className="font-mono text-xs uppercase tracking-[0.25em] text-[var(--muted)] mb-4">
|
||||
{download.title}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--muted)] mb-4">{download.note}</p>
|
||||
<div className="space-y-2.5">
|
||||
{download.assets.map((asset) => (
|
||||
<a
|
||||
key={asset.id}
|
||||
href={getTrackedDownloadHref(asset.id)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-between rounded-[16px] border border-[var(--border)] bg-[var(--panel-soft)] px-4 py-3 text-sm text-[var(--text)] transition-colors duration-200 hover:border-[var(--accent)] hover:text-[var(--accent)]"
|
||||
>
|
||||
<span className="font-semibold tracking-tight">{asset.label}</span>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-hidden="true"
|
||||
className="shrink-0 ml-2 opacity-40"
|
||||
>
|
||||
<span className="font-semibold tracking-tight">{asset.label}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||
<polyline points="7 10 12 15 17 10" />
|
||||
<line x1="12" y1="15" x2="12" y2="3" />
|
||||
</svg>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ function FeaturePair({ feature }: { feature: (typeof features)[number] }) {
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
className={`order-2 ${imageLeft ? "lg:order-1" : "lg:order-2"}`}
|
||||
>
|
||||
<div className="rounded-2xl overflow-hidden shadow-[0_4px_32px_-8px_rgba(0,0,0,0.1)] border border-[var(--border)] bg-[var(--panel)] transition-shadow duration-500 hover:shadow-[0_8px_48px_-12px_rgba(0,0,0,0.15)]">
|
||||
<div className="rounded-[22px] overflow-hidden shadow-[0_4px_32px_-8px_rgba(0,0,0,0.06)] border border-[var(--border)] bg-[var(--panel)] transition-shadow duration-500 hover:shadow-[0_8px_48px_-12px_rgba(0,0,0,0.10)]">
|
||||
<img src={image} alt={imageAlt} width="1920" height="1080" className="w-full h-auto block" loading="lazy" />
|
||||
</div>
|
||||
</motion.div>
|
||||
@@ -162,7 +162,7 @@ export function Features() {
|
||||
transition: { duration: 0.6, ease: [0.16, 1, 0.3, 1] },
|
||||
},
|
||||
}}
|
||||
className="group bg-[var(--panel)] rounded-2xl border border-[var(--border)] overflow-hidden transition-all duration-300 hover:shadow-[0_8px_40px_-12px_rgba(0,0,0,0.12)] hover:-translate-y-1.5"
|
||||
className="group bg-[var(--panel)] rounded-[22px] border border-[var(--border)] overflow-hidden transition-all duration-300 hover:shadow-[0_8px_40px_-12px_rgba(0,0,0,0.08)] hover:-translate-y-1.5"
|
||||
>
|
||||
<div className="overflow-hidden">
|
||||
<img
|
||||
|
||||
@@ -60,10 +60,10 @@ export function Hero() {
|
||||
|
||||
<motion.h1
|
||||
{...heroMotion(0.15)}
|
||||
className="mt-8 font-serif italic text-[clamp(2.75rem,2rem+3.8vw,5rem)] tracking-[-0.02em] text-[var(--text)] leading-[1.08]"
|
||||
className="mt-8 font-serif text-[clamp(2.75rem,2rem+3.8vw,5rem)] font-normal leading-[1.0] tracking-[-0.03em] text-[var(--text)]"
|
||||
>
|
||||
Launch an AI Company <br className="hidden sm:block" />
|
||||
<span className="text-[var(--cta)]">in Minutes</span>
|
||||
<span className="text-[var(--accent)]">in Minutes</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
@@ -77,7 +77,7 @@ export function Hero() {
|
||||
<motion.div {...heroMotion(0.35)} className="mt-12">
|
||||
<a
|
||||
href="#download"
|
||||
className="group inline-flex items-center justify-center px-9 py-4 rounded-xl text-[17px] font-semibold bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)] hover:scale-[1.03] active:scale-[0.98] transition-all duration-200 will-change-transform shadow-[0_4px_24px_-4px_var(--cta),0_8px_40px_-12px_var(--cta)]"
|
||||
className="group inline-flex items-center justify-center px-8 py-4 rounded-full text-base font-medium bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)] hover:scale-[1.03] active:scale-[0.98] transition-all duration-200 will-change-transform"
|
||||
>
|
||||
See Downloads
|
||||
<svg
|
||||
@@ -119,7 +119,7 @@ export function Hero() {
|
||||
alt="AgentCompany dashboard showing autonomous AI agents managing a company"
|
||||
width="1920"
|
||||
height="1080"
|
||||
className="w-full h-auto block rounded-2xl border border-[var(--border)] shadow-[0_8px_40px_-8px_rgba(0,0,0,0.12),0_20px_80px_-20px_var(--glow-warm)] transition-shadow duration-500"
|
||||
className="w-full h-auto block rounded-[22px] border border-[var(--border)] shadow-[0_8px_40px_-8px_rgba(0,0,0,0.08)] transition-shadow duration-500"
|
||||
loading="eager"
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
@@ -53,7 +53,7 @@ function DemoPanel() {
|
||||
|
||||
return (
|
||||
<div ref={anchorRef} className="relative">
|
||||
<div className="rounded-2xl overflow-hidden border border-[var(--border)] bg-[var(--panel)] shadow-[0_8px_40px_-8px_rgba(0,0,0,0.1),0_24px_80px_-24px_var(--glow-warm)]">
|
||||
<div className="rounded-[22px] overflow-hidden border border-[var(--border)] bg-[var(--panel)] shadow-[0_8px_40px_-8px_rgba(0,0,0,0.06)]">
|
||||
<div className="flex items-center gap-2 px-4 py-3 bg-[var(--panel-soft)] border-b border-[var(--border)]">
|
||||
<span className="w-3 h-3 rounded-full bg-[#ff5f57]" aria-hidden="true" />
|
||||
<span className="w-3 h-3 rounded-full bg-[#febc2e]" aria-hidden="true" />
|
||||
|
||||
@@ -63,7 +63,7 @@ export function Navbar() {
|
||||
<div className="flex h-16 items-center justify-between">
|
||||
<a href="#" className="flex items-center gap-2.5 shrink-0" aria-label="AgentCompany home">
|
||||
<IconMark />
|
||||
<span className="text-[var(--text)] font-semibold text-lg tracking-tight">AgentCompany</span>
|
||||
<span className="text-[var(--text)] font-serif text-xl font-normal tracking-[-0.4px]">AgentCompany</span>
|
||||
</a>
|
||||
|
||||
<div className="hidden md:flex items-center gap-8">
|
||||
@@ -78,7 +78,7 @@ export function Navbar() {
|
||||
<ThemeToggle />
|
||||
<a
|
||||
href="#download"
|
||||
className="inline-flex items-center px-4 py-2 rounded-lg text-sm font-medium bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)] hover:scale-[1.03] active:scale-[0.98] transition-all duration-200"
|
||||
className="inline-flex items-center px-5 py-2 rounded-full text-sm font-medium bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)] hover:scale-[1.03] active:scale-[0.98] transition-all duration-200"
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
@@ -121,7 +121,7 @@ export function Navbar() {
|
||||
<a
|
||||
href="#download"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className="block px-3 py-2.5 rounded-lg text-sm font-medium text-center bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)] transition-colors duration-200 mt-2"
|
||||
className="block px-3 py-2.5 rounded-full text-sm font-medium text-center bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)] transition-colors duration-200 mt-2"
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
|
||||
@@ -12,7 +12,7 @@ export type PlatformDownload = {
|
||||
assets: PlatformDownloadAsset[];
|
||||
};
|
||||
|
||||
export const releaseVersion = "0.4.156";
|
||||
export const releaseVersion = "0.4.165";
|
||||
|
||||
export const platformDownloads: PlatformDownload[] = [
|
||||
{
|
||||
@@ -23,13 +23,13 @@ export const platformDownloads: PlatformDownload[] = [
|
||||
{
|
||||
id: "macos-arm64-dmg",
|
||||
label: "Apple Silicon DMG",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.156-arm64.dmg",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.165-arm64.dmg",
|
||||
note: "arm64",
|
||||
},
|
||||
{
|
||||
id: "macos-x64-dmg",
|
||||
label: "Intel Mac DMG",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.156.dmg",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.165.dmg",
|
||||
note: "x64",
|
||||
},
|
||||
],
|
||||
@@ -42,7 +42,7 @@ export const platformDownloads: PlatformDownload[] = [
|
||||
{
|
||||
id: "windows-universal-installer",
|
||||
label: "Windows Universal Installer",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany.Setup.0.4.156.exe",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany.Setup.0.4.165.exe",
|
||||
note: "arm64 + x64 + ia32",
|
||||
},
|
||||
],
|
||||
@@ -55,37 +55,37 @@ export const platformDownloads: PlatformDownload[] = [
|
||||
{
|
||||
id: "linux-x64-appimage",
|
||||
label: "Linux x64 AppImage",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.156.AppImage",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.165.AppImage",
|
||||
note: "x64",
|
||||
},
|
||||
{
|
||||
id: "linux-x64-deb",
|
||||
label: "Linux x64 DEB",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company_0.4.156_amd64.deb",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company_0.4.165_amd64.deb",
|
||||
note: "x64",
|
||||
},
|
||||
{
|
||||
id: "linux-x64-rpm",
|
||||
label: "Linux x64 RPM",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company-0.4.156.x86_64.rpm",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company-0.4.165.x86_64.rpm",
|
||||
note: "x64",
|
||||
},
|
||||
{
|
||||
id: "linux-arm64-appimage",
|
||||
label: "Linux ARM64 AppImage",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.156-arm64.AppImage",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/AgentCompany-0.4.165-arm64.AppImage",
|
||||
note: "arm64",
|
||||
},
|
||||
{
|
||||
id: "linux-arm64-deb",
|
||||
label: "Linux ARM64 DEB",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company_0.4.156_arm64.deb",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company_0.4.165_arm64.deb",
|
||||
note: "arm64",
|
||||
},
|
||||
{
|
||||
id: "linux-arm64-rpm",
|
||||
label: "Linux ARM64 RPM",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company-0.4.156.aarch64.rpm",
|
||||
href: "https://pub-a19a3a2c1d2e4fa3a9c120b184024448.r2.dev/AC/agent-company-0.4.165.aarch64.rpm",
|
||||
note: "arm64",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
function AnthropicIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M13.827 3.52h3.603L24 20.48h-3.603l-6.57-16.96zm-7.257 0H10.173L16.74 20.48H13.14L11.07 14.98H5.355l-1.937 5.5H0L6.57 3.52zm4.132 8.69L8.18 5.86l-2.522 6.35h5.244z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function OpenAIIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.998 5.998 0 0 0-3.998 2.9 6.047 6.047 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function GoogleIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M12 11.366v3.473h5.51c-.226 1.408-1.644 4.126-5.51 4.126-3.314 0-6.017-2.744-6.017-6.127S8.686 6.71 12 6.71c1.888 0 3.152.804 3.874 1.497l2.637-2.54C16.63 3.952 14.534 3 12 3 6.477 3 2 7.477 2 13s4.477 10 10 10c5.773 0 9.6-4.057 9.6-9.773 0-.656-.07-1.157-.156-1.657H12z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function MoonshotIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm0 2a8 8 0 0 1 .5 15.98A10.5 10.5 0 0 0 17 12c0-3.14-1.37-5.96-3.54-7.9A8.03 8.03 0 0 1 12 4z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function ZhipuIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M4 4h16v3H8.5l11 10H20v3H4v-3h11.5L4.5 7H4V4z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function MiniMaxIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M2 20V4l5 8 5-8 5 8 5-8v16h-3V10.5l-2 4-5-8-5 8-2-4V20H2z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function OllamaIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M12 2C8.13 2 5 5.13 5 9c0 2.38 1.19 4.47 3 5.74V17a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.87-3.13-7-7-7zm-2 15v-1h4v1h-4zm3.5-4.15l-.5.35V15h-2v-1.8l-.5-.35A4.98 4.98 0 0 1 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5a4.98 4.98 0 0 1-3.5 4.85zM10 9.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm7 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function ApiIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
||||
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
||||
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
const runtimes = [
|
||||
{ name: "Claude Code", provider: "Anthropic", icon: AnthropicIcon },
|
||||
{ name: "Codex CLI", provider: "OpenAI", icon: OpenAIIcon },
|
||||
{ name: "Gemini CLI", provider: "Google", icon: GoogleIcon },
|
||||
{ name: "Kimi", provider: "Moonshot AI", icon: MoonshotIcon },
|
||||
{ name: "GLM", provider: "Zhipu AI", icon: ZhipuIcon },
|
||||
{ name: "MiniMax", provider: "MiniMax", icon: MiniMaxIcon },
|
||||
{ name: "Ollama", provider: "Local", icon: OllamaIcon },
|
||||
{ name: "Anthropic Compatible API", provider: "Any Provider", icon: ApiIcon },
|
||||
];
|
||||
|
||||
export function RuntimesBar() {
|
||||
return (
|
||||
<section className="border-y border-[var(--border)] py-12 lg:py-16">
|
||||
<div className="mx-auto max-w-6xl px-6 lg:px-8">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, amount: 0.5 }}
|
||||
transition={{ duration: 0.5, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="text-center"
|
||||
>
|
||||
<p className="font-mono text-xs uppercase tracking-[0.25em] text-[var(--muted)] mb-10">
|
||||
Supported AI Runtimes
|
||||
</p>
|
||||
<div className="flex flex-wrap items-center justify-center gap-x-8 gap-y-6 lg:gap-x-12">
|
||||
{runtimes.map((runtime) => {
|
||||
const Icon = runtime.icon;
|
||||
return (
|
||||
<div key={runtime.name} className="flex items-center gap-2.5">
|
||||
<span className="text-[var(--muted)] opacity-60">
|
||||
<Icon />
|
||||
</span>
|
||||
<span className="text-base font-semibold tracking-tight text-[var(--text)]">
|
||||
{runtime.name}
|
||||
</span>
|
||||
<span className="text-sm text-[var(--muted)] hidden sm:inline">
|
||||
{runtime.provider}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Generated
+713
-1
@@ -14,12 +14,27 @@
|
||||
"react-dom": "19.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@types/node": "^24.9.1",
|
||||
"@types/react": "^19.2.2",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
|
||||
@@ -544,6 +559,56 @@
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/remapping": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
||||
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.31",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "16.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.2.tgz",
|
||||
@@ -699,6 +764,318 @@
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/node": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz",
|
||||
"integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"enhanced-resolve": "^5.19.0",
|
||||
"jiti": "^2.6.1",
|
||||
"lightningcss": "1.32.0",
|
||||
"magic-string": "^0.30.21",
|
||||
"source-map-js": "^1.2.1",
|
||||
"tailwindcss": "4.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz",
|
||||
"integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tailwindcss/oxide-android-arm64": "4.2.2",
|
||||
"@tailwindcss/oxide-darwin-arm64": "4.2.2",
|
||||
"@tailwindcss/oxide-darwin-x64": "4.2.2",
|
||||
"@tailwindcss/oxide-freebsd-x64": "4.2.2",
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2",
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": "4.2.2",
|
||||
"@tailwindcss/oxide-linux-arm64-musl": "4.2.2",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "4.2.2",
|
||||
"@tailwindcss/oxide-linux-x64-musl": "4.2.2",
|
||||
"@tailwindcss/oxide-wasm32-wasi": "4.2.2",
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": "4.2.2",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "4.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-android-arm64": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz",
|
||||
"integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-arm64": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz",
|
||||
"integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-x64": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz",
|
||||
"integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-freebsd-x64": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz",
|
||||
"integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz",
|
||||
"integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz",
|
||||
"integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz",
|
||||
"integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz",
|
||||
"integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz",
|
||||
"integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz",
|
||||
"integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==",
|
||||
"bundleDependencies": [
|
||||
"@napi-rs/wasm-runtime",
|
||||
"@emnapi/core",
|
||||
"@emnapi/runtime",
|
||||
"@tybys/wasm-util",
|
||||
"@emnapi/wasi-threads",
|
||||
"tslib"
|
||||
],
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.8.1",
|
||||
"@emnapi/runtime": "^1.8.1",
|
||||
"@emnapi/wasi-threads": "^1.1.0",
|
||||
"@napi-rs/wasm-runtime": "^1.1.1",
|
||||
"@tybys/wasm-util": "^0.10.1",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz",
|
||||
"integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz",
|
||||
"integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/postcss": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.2.2.tgz",
|
||||
"integrity": "sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"@tailwindcss/node": "4.2.2",
|
||||
"@tailwindcss/oxide": "4.2.2",
|
||||
"postcss": "^8.5.6",
|
||||
"tailwindcss": "4.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/postcss/node_modules/postcss": {
|
||||
"version": "8.5.8",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
|
||||
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.12.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz",
|
||||
@@ -778,12 +1155,26 @@
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.20.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
|
||||
"integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "12.38.0",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz",
|
||||
@@ -811,6 +1202,306 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
|
||||
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
||||
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"lightningcss-android-arm64": "1.32.0",
|
||||
"lightningcss-darwin-arm64": "1.32.0",
|
||||
"lightningcss-darwin-x64": "1.32.0",
|
||||
"lightningcss-freebsd-x64": "1.32.0",
|
||||
"lightningcss-linux-arm-gnueabihf": "1.32.0",
|
||||
"lightningcss-linux-arm64-gnu": "1.32.0",
|
||||
"lightningcss-linux-arm64-musl": "1.32.0",
|
||||
"lightningcss-linux-x64-gnu": "1.32.0",
|
||||
"lightningcss-linux-x64-musl": "1.32.0",
|
||||
"lightningcss-win32-arm64-msvc": "1.32.0",
|
||||
"lightningcss-win32-x64-msvc": "1.32.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-android-arm64": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
|
||||
"integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-arm64": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
|
||||
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-x64": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
|
||||
"integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-freebsd-x64": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
|
||||
"integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm-gnueabihf": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
|
||||
"integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm64-gnu": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
|
||||
"integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm64-musl": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
|
||||
"integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-x64-gnu": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
|
||||
"integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-x64-musl": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
|
||||
"integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-win32-arm64-msvc": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
|
||||
"integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-win32-x64-msvc": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
|
||||
"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/motion-dom": {
|
||||
"version": "12.38.0",
|
||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz",
|
||||
@@ -1048,6 +1739,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",
|
||||
"integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz",
|
||||
"integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
"react-dom": "19.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@types/node": "^24.9.1",
|
||||
"@types/react": "^19.2.2",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,810 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Design System Preview: Cohere (Dark)</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
/* Primary */
|
||||
--color-black: #000000;
|
||||
--color-near-black: #212121;
|
||||
--color-deep-dark: #17171c;
|
||||
/* Accent */
|
||||
--color-interaction-blue: #1863dc;
|
||||
--color-ring-blue: rgba(76, 110, 230, 0.5);
|
||||
--color-focus-purple: #9b60aa;
|
||||
/* Surface */
|
||||
--color-white: #ffffff;
|
||||
--color-snow: #fafafa;
|
||||
--color-lightest-gray: #f2f2f2;
|
||||
/* Neutrals */
|
||||
--color-muted-slate: #93939f;
|
||||
--color-border-cool: #d9d9dd;
|
||||
--color-border-light: #e5e7eb;
|
||||
/* Fonts */
|
||||
--font-display: 'Space Grotesk', Inter, ui-sans-serif, system-ui, sans-serif;
|
||||
--font-body: Inter, Arial, ui-sans-serif, system-ui, sans-serif;
|
||||
--font-mono: 'Space Mono', Arial, ui-sans-serif, system-ui, monospace;
|
||||
/* Dark mode tokens */
|
||||
--bg-page: #17171c;
|
||||
--bg-card: #212121;
|
||||
--bg-nav: rgba(23, 23, 28, 0.95);
|
||||
--text-primary: #fafafa;
|
||||
--text-secondary: #d9d9dd;
|
||||
--text-muted: #93939f;
|
||||
--border-color: #333333;
|
||||
--border-subtle: #2a2a2f;
|
||||
--section-label-color: #93939f;
|
||||
--accent: #1863dc;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
background: var(--bg-page);
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-body);
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
.nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 40px;
|
||||
background: var(--bg-nav);
|
||||
backdrop-filter: blur(12px);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.nav-brand {
|
||||
font-family: var(--font-display);
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.nav-brand svg { width: 28px; height: 28px; }
|
||||
.nav-links { display: flex; gap: 32px; align-items: center; }
|
||||
.nav-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
font-family: var(--font-body);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--accent); }
|
||||
.nav-cta {
|
||||
background: var(--color-white);
|
||||
color: var(--color-black);
|
||||
padding: 10px 24px;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.nav-cta:hover { opacity: 0.85; }
|
||||
|
||||
/* HERO */
|
||||
.hero {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 120px 40px 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hero h1 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 72px;
|
||||
font-weight: 400;
|
||||
line-height: 1.0;
|
||||
letter-spacing: -1.44px;
|
||||
margin-bottom: 24px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.hero h1 span { color: var(--accent); }
|
||||
.hero p {
|
||||
color: var(--text-muted);
|
||||
font-family: var(--font-body);
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.hero-buttons { display: flex; gap: 16px; justify-content: center; }
|
||||
.btn-ghost-primary {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s, opacity 0.2s;
|
||||
}
|
||||
.btn-ghost-primary:hover { color: var(--accent); opacity: 0.8; }
|
||||
.btn-light-solid {
|
||||
background: var(--color-white);
|
||||
color: var(--color-black);
|
||||
padding: 12px 28px;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.btn-light-solid:hover { opacity: 0.85; }
|
||||
|
||||
/* SECTIONS */
|
||||
.section {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 80px 40px;
|
||||
}
|
||||
.section-title {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
color: var(--section-label-color);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.section-heading {
|
||||
font-family: var(--font-body);
|
||||
font-size: 48px;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.48px;
|
||||
margin-bottom: 48px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.section-divider {
|
||||
border: none;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
margin: 0 40px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* PURPLE BAND */
|
||||
.purple-band {
|
||||
background: linear-gradient(135deg, #2d1b4e 0%, #1a1040 50%, #0d0a1a 100%);
|
||||
padding: 80px 40px;
|
||||
text-align: center;
|
||||
}
|
||||
.purple-band h2 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 60px;
|
||||
font-weight: 400;
|
||||
line-height: 1.0;
|
||||
letter-spacing: -1.2px;
|
||||
color: #ffffff;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.purple-band p {
|
||||
color: rgba(255,255,255,0.7);
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* COLOR PALETTE */
|
||||
.color-group { margin-bottom: 40px; }
|
||||
.color-group-title {
|
||||
font-family: var(--font-body);
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.color-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.color-swatch {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 22px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.color-swatch-block {
|
||||
height: 80px;
|
||||
position: relative;
|
||||
}
|
||||
.color-swatch-info {
|
||||
padding: 12px 16px;
|
||||
background: var(--bg-card);
|
||||
}
|
||||
.color-swatch-name { font-size: 13px; font-weight: 500; margin-bottom: 2px; color: var(--text-primary); }
|
||||
.color-swatch-hex { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); margin-bottom: 4px; }
|
||||
.color-swatch-role { font-size: 12px; color: var(--text-muted); line-height: 1.4; }
|
||||
|
||||
/* TYPOGRAPHY */
|
||||
.type-sample { margin-bottom: 32px; padding-bottom: 32px; border-bottom: 1px solid var(--border-subtle); }
|
||||
.type-sample:last-child { border-bottom: none; }
|
||||
.type-sample-text { margin-bottom: 8px; }
|
||||
.type-sample-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* BUTTONS */
|
||||
.button-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.button-demo { text-align: center; }
|
||||
.button-demo-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
}
|
||||
.btn-ghost-cohere {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s, opacity 0.2s;
|
||||
}
|
||||
.btn-ghost-cohere:hover { color: var(--accent); opacity: 0.8; }
|
||||
.btn-light-cohere {
|
||||
background: var(--color-white);
|
||||
color: var(--color-black);
|
||||
padding: 12px 28px;
|
||||
border: none;
|
||||
border-radius: 22px;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-light-pill {
|
||||
background: var(--color-white);
|
||||
color: var(--color-black);
|
||||
padding: 12px 28px;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-outlined {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 12px 24px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 22px;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s, color 0.2s;
|
||||
}
|
||||
.btn-outlined:hover { border-color: var(--accent); color: var(--accent); }
|
||||
|
||||
/* CARDS */
|
||||
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; }
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
padding: 28px;
|
||||
}
|
||||
.card-signature {
|
||||
border-radius: 22px;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.card-dialog {
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.card-generous {
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.card h3 {
|
||||
font-family: var(--font-body);
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
letter-spacing: normal;
|
||||
margin-bottom: 12px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.card p { color: var(--text-muted); font-size: 16px; line-height: 1.5; font-weight: 400; }
|
||||
.card-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* SPACING */
|
||||
.spacing-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
|
||||
.spacing-item { text-align: center; }
|
||||
.spacing-box {
|
||||
background: rgba(24, 99, 220, 0.15);
|
||||
border: 1px solid rgba(24, 99, 220, 0.3);
|
||||
border-radius: 2px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.spacing-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* RADIUS */
|
||||
.radius-row { display: flex; flex-wrap: wrap; gap: 20px; align-items: center; }
|
||||
.radius-item { text-align: center; }
|
||||
.radius-box {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-color);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.radius-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.radius-context {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* ELEVATION */
|
||||
.elevation-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 24px; }
|
||||
.elevation-card {
|
||||
background: var(--bg-card);
|
||||
border-radius: 22px;
|
||||
padding: 24px;
|
||||
min-height: 140px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.elevation-flat { border: none; background: var(--bg-page); }
|
||||
.elevation-bordered-light { border: 1px solid var(--border-subtle); }
|
||||
.elevation-bordered-cool { border: 1px solid var(--border-color); }
|
||||
.elevation-purple-band {
|
||||
background: linear-gradient(135deg, #2d1b4e 0%, #1a1040 100%);
|
||||
color: #ffffff;
|
||||
}
|
||||
.elevation-purple-band .elevation-name,
|
||||
.elevation-purple-band .elevation-desc { color: #ffffff; }
|
||||
.elevation-purple-band .elevation-level { color: rgba(255,255,255,0.6); }
|
||||
.elevation-name { font-size: 16px; font-weight: 500; margin-bottom: 8px; color: var(--text-primary); }
|
||||
.elevation-desc { font-size: 13px; color: var(--text-muted); line-height: 1.5; }
|
||||
.elevation-level {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/* RESPONSIVE */
|
||||
@media (max-width: 768px) {
|
||||
.nav { padding: 12px 20px; }
|
||||
.nav-links a:not(.nav-cta-wrapper) { display: none; }
|
||||
.hero { padding: 80px 20px 60px; }
|
||||
.hero h1 { font-size: 42px; letter-spacing: -0.84px; }
|
||||
.section { padding: 60px 20px; }
|
||||
.section-heading { font-size: 32px; letter-spacing: -0.32px; }
|
||||
.color-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
|
||||
.card-grid { grid-template-columns: 1fr; }
|
||||
.hero-buttons { flex-direction: column; align-items: center; }
|
||||
.button-row { flex-direction: column; align-items: flex-start; }
|
||||
.purple-band h2 { font-size: 36px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAV -->
|
||||
<nav class="nav">
|
||||
<div class="nav-brand">
|
||||
<svg viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="14" cy="14" r="13" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M8 14 C8 10, 12 8, 14 8 C16 8, 20 10, 20 14 C20 18, 16 20, 14 20 C12 20, 8 18, 8 14Z" fill="currentColor" opacity="0.15"/>
|
||||
<circle cx="14" cy="14" r="4" fill="currentColor"/>
|
||||
</svg>
|
||||
cohere
|
||||
</div>
|
||||
<div class="nav-links">
|
||||
<a href="#colors">Colors</a>
|
||||
<a href="#typography">Typography</a>
|
||||
<a href="#buttons">Buttons</a>
|
||||
<a href="#cards">Cards</a>
|
||||
<a href="#spacing">Spacing</a>
|
||||
<a href="#elevation">Elevation</a>
|
||||
<button class="nav-cta">Get Started</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- HERO -->
|
||||
<section class="hero">
|
||||
<h1>Design System Preview:<br><span>Cohere</span></h1>
|
||||
<p>Auto-generated design token catalog from DESIGN.md</p>
|
||||
<div class="hero-buttons">
|
||||
<button class="btn-light-solid">Explore Tokens</button>
|
||||
<button class="btn-ghost-primary">View Source</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COLORS -->
|
||||
<section class="section" id="colors">
|
||||
<div class="section-title">01 / Color Palette</div>
|
||||
<h2 class="section-heading">Color Palette & Roles</h2>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Primary</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #000000; border-bottom: 1px solid #333;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Cohere Black</div>
|
||||
<div class="color-swatch-hex">#000000</div>
|
||||
<div class="color-swatch-role">Primary headline text, maximum emphasis</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #212121; border-bottom: 1px solid #333;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Near Black</div>
|
||||
<div class="color-swatch-hex">#212121</div>
|
||||
<div class="color-swatch-role">Standard body link color</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #17171c; border-bottom: 1px solid #333;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Deep Dark</div>
|
||||
<div class="color-swatch-hex">#17171c</div>
|
||||
<div class="color-swatch-role">Navigation and dark-section text</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Secondary & Accent</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #1863dc;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Interaction Blue</div>
|
||||
<div class="color-swatch-hex">#1863dc</div>
|
||||
<div class="color-swatch-role">Hover, focus states, active links</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: rgba(76,110,230,0.5);"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Ring Blue</div>
|
||||
<div class="color-swatch-hex">#4c6ee6 @ 50%</div>
|
||||
<div class="color-swatch-role">Keyboard focus indicators</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #9b60aa;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Focus Purple</div>
|
||||
<div class="color-swatch-hex">#9b60aa</div>
|
||||
<div class="color-swatch-role">Input focus border color</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Surface & Background</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #ffffff; border-bottom: 1px solid #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Pure White</div>
|
||||
<div class="color-swatch-hex">#ffffff</div>
|
||||
<div class="color-swatch-role">Primary page background, card surface</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #fafafa; border-bottom: 1px solid #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Snow</div>
|
||||
<div class="color-swatch-hex">#fafafa</div>
|
||||
<div class="color-swatch-role">Subtle elevated surfaces, light sections</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #f2f2f2; border-bottom: 1px solid #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Lightest Gray</div>
|
||||
<div class="color-swatch-hex">#f2f2f2</div>
|
||||
<div class="color-swatch-role">Card borders, softest containment</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Neutrals & Text</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #93939f;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Muted Slate</div>
|
||||
<div class="color-swatch-hex">#93939f</div>
|
||||
<div class="color-swatch-role">Footer links, tertiary text</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #d9d9dd;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Border Cool</div>
|
||||
<div class="color-swatch-hex">#d9d9dd</div>
|
||||
<div class="color-swatch-role">Section borders, list separators</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Border Light</div>
|
||||
<div class="color-swatch-hex">#e5e7eb</div>
|
||||
<div class="color-swatch-role">Lighter border variant (gray-200)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- PURPLE HERO BAND -->
|
||||
<div class="purple-band">
|
||||
<h2>Enterprise AI Platform</h2>
|
||||
<p>Deep purple hero sections create dramatic visual breaks in the dark page flow</p>
|
||||
</div>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- TYPOGRAPHY -->
|
||||
<section class="section" id="typography">
|
||||
<div class="section-title">02 / Typography Scale</div>
|
||||
<h2 class="section-heading">Typography Rules</h2>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-display); font-size: 72px; font-weight: 400; line-height: 1.0; letter-spacing: -1.44px;">Display Hero</div>
|
||||
<div class="type-sample-label">Display / Hero — CohereText — 72px / 400 / 1.00 / -1.44px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-display); font-size: 60px; font-weight: 400; line-height: 1.0; letter-spacing: -1.2px;">Display Secondary</div>
|
||||
<div class="type-sample-label">Display Secondary — CohereText — 60px / 400 / 1.00 / -1.2px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 48px; font-weight: 400; line-height: 1.2; letter-spacing: -0.48px;">Section Heading</div>
|
||||
<div class="type-sample-label">Section Heading — Unica77 — 48px / 400 / 1.20 / -0.48px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 32px; font-weight: 400; line-height: 1.2; letter-spacing: -0.32px;">Sub-heading</div>
|
||||
<div class="type-sample-label">Sub-heading — Unica77 — 32px / 400 / 1.20 / -0.32px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 24px; font-weight: 400; line-height: 1.3;">Feature Title</div>
|
||||
<div class="type-sample-label">Feature Title — Unica77 — 24px / 400 / 1.30 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 18px; font-weight: 400; line-height: 1.4;">Body Large text for intro paragraphs. Unica77 provides geometric Swiss precision for all functional UI text at the body-large tier.</div>
|
||||
<div class="type-sample-label">Body Large — Unica77 — 18px / 400 / 1.40 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 16px; font-weight: 400; line-height: 1.5;">Standard body text for paragraphs, navigation links, and button labels. Unica77 at its most common size, weight 400.</div>
|
||||
<div class="type-sample-label">Body / Button — Unica77 — 16px / 400 / 1.50 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 14px; font-weight: 500; line-height: 1.71;">Button Medium Label</div>
|
||||
<div class="type-sample-label">Button Medium — Unica77 — 14px / 500 / 1.71 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 14px; font-weight: 400; line-height: 1.4; color: var(--text-muted);">Caption and metadata text for descriptions</div>
|
||||
<div class="type-sample-label">Caption — Unica77 — 14px / 400 / 1.40 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-mono); font-size: 14px; font-weight: 400; line-height: 1.4; text-transform: uppercase; letter-spacing: 0.28px; color: var(--text-muted);">UPPERCASE SECTION LABEL</div>
|
||||
<div class="type-sample-label">Uppercase Label — CohereMono — 14px / 400 / 1.40 / 0.28px / uppercase</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 12px; font-weight: 400; line-height: 1.4; color: var(--text-muted);">Smallest text for footer links and fine print</div>
|
||||
<div class="type-sample-label">Small — Unica77 — 12px / 400 / 1.40 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-mono); font-size: 8px; font-weight: 400; line-height: 1.4; text-transform: uppercase; letter-spacing: 0.16px; color: var(--text-muted);">CODE MICRO LABEL</div>
|
||||
<div class="type-sample-label">Code Micro — CohereMono — 8px / 400 / 1.40 / 0.16px / uppercase</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="section" id="buttons">
|
||||
<div class="section-title">03 / Button Variants</div>
|
||||
<h2 class="section-heading">Buttons</h2>
|
||||
|
||||
<div class="button-row">
|
||||
<div class="button-demo">
|
||||
<button class="btn-ghost-cohere">Ghost Button</button>
|
||||
<div class="button-demo-label">Ghost / Transparent</div>
|
||||
</div>
|
||||
<div class="button-demo">
|
||||
<button class="btn-light-cohere">Light Solid</button>
|
||||
<div class="button-demo-label">Light Solid (22px)</div>
|
||||
</div>
|
||||
<div class="button-demo">
|
||||
<button class="btn-light-pill">Pill CTA</button>
|
||||
<div class="button-demo-label">Light Pill (9999px)</div>
|
||||
</div>
|
||||
<div class="button-demo">
|
||||
<button class="btn-outlined">Outlined</button>
|
||||
<div class="button-demo-label">Outlined (22px)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="color: var(--text-muted); margin-top: 32px; font-size: 14px;">
|
||||
Ghost buttons are the primary style — invisible until interacted with. On hover, text shifts to Interaction Blue (#1863dc) with 0.8 opacity. Focus: 2px solid Interaction Blue outline.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- CARDS -->
|
||||
<section class="section" id="cards">
|
||||
<div class="section-title">04 / Card Examples</div>
|
||||
<h2 class="section-heading">Cards & Containers</h2>
|
||||
|
||||
<div class="card-grid">
|
||||
<div class="card card-signature">
|
||||
<div class="card-label">STANDARD CARD</div>
|
||||
<h3>Signature 22px Radius</h3>
|
||||
<p>The distinctive Cohere card with 22px border-radius and #333 border on dark surfaces. Creates cloud-like, organic softness on the dark canvas.</p>
|
||||
</div>
|
||||
<div class="card card-dialog">
|
||||
<div class="card-label">DIALOG CARD</div>
|
||||
<h3>Dialog 8px Radius</h3>
|
||||
<p>Modal and dialog containers use a tighter 8px radius with #333 border. Functional, secondary containment for transient UI.</p>
|
||||
</div>
|
||||
<div class="card card-generous">
|
||||
<div class="card-label">GENEROUS CARD</div>
|
||||
<h3>Featured 16px Radius</h3>
|
||||
<p>Medium-sized containers for featured content. Uses 16px radius as a middle step in the radius scale with subtle border.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- SPACING -->
|
||||
<section class="section" id="spacing">
|
||||
<div class="section-title">05 / Spacing Scale</div>
|
||||
<h2 class="section-heading">Spacing System</h2>
|
||||
<p style="color: var(--text-muted); margin-bottom: 32px;">Base unit: 8px. Scale from 2px to 60px.</p>
|
||||
|
||||
<div class="spacing-row">
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 8px; height: 8px;"></div><div class="spacing-label">2px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 18px; height: 18px;"></div><div class="spacing-label">6px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 24px; height: 24px;"></div><div class="spacing-label">8px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 30px; height: 30px;"></div><div class="spacing-label">10px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 36px; height: 36px;"></div><div class="spacing-label">12px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 48px; height: 48px;"></div><div class="spacing-label">16px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 60px; height: 60px;"></div><div class="spacing-label">20px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 66px; height: 66px;"></div><div class="spacing-label">22px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 72px; height: 72px;"></div><div class="spacing-label">24px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 84px; height: 84px;"></div><div class="spacing-label">28px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 96px; height: 96px;"></div><div class="spacing-label">32px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 120px; height: 120px;"></div><div class="spacing-label">40px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 168px; height: 168px;"></div><div class="spacing-label">56px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 180px; height: 180px;"></div><div class="spacing-label">60px</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BORDER RADIUS -->
|
||||
<section class="section">
|
||||
<div class="section-title">06 / Border Radius Scale</div>
|
||||
<h2 class="section-heading">Border Radius</h2>
|
||||
|
||||
<div class="radius-row">
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 4px;"></div><div class="radius-label">4px</div><div class="radius-context">Sharp — nav, tags</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 8px;"></div><div class="radius-label">8px</div><div class="radius-context">Comfortable — dialogs</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 16px;"></div><div class="radius-label">16px</div><div class="radius-context">Generous — featured</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 20px;"></div><div class="radius-label">20px</div><div class="radius-context">Large — feature cards</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 22px; border-color: var(--accent); border-width: 2px;"></div><div class="radius-label">22px</div><div class="radius-context">Signature — THE radius</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 9999px;"></div><div class="radius-label">9999px</div><div class="radius-context">Pill — buttons, tags</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- ELEVATION -->
|
||||
<section class="section" id="elevation">
|
||||
<div class="section-title">07 / Elevation & Depth</div>
|
||||
<h2 class="section-heading">Depth & Elevation</h2>
|
||||
|
||||
<div class="elevation-grid">
|
||||
<div class="elevation-card elevation-flat">
|
||||
<div><div class="elevation-name">Flat</div><div class="elevation-desc">No shadow, no border. Page background and text blocks.</div></div>
|
||||
<div class="elevation-level">Level 0</div>
|
||||
</div>
|
||||
<div class="elevation-card elevation-bordered-light">
|
||||
<div><div class="elevation-name">Bordered (Subtle)</div><div class="elevation-desc">1px solid #2a2a2f. Subtle dark containment lines.</div></div>
|
||||
<div class="elevation-level">Level 1 — Subtle</div>
|
||||
</div>
|
||||
<div class="elevation-card elevation-bordered-cool">
|
||||
<div><div class="elevation-name">Bordered (Standard)</div><div class="elevation-desc">1px solid #333. Standard dark-mode card borders.</div></div>
|
||||
<div class="elevation-level">Level 1 — Standard</div>
|
||||
</div>
|
||||
<div class="elevation-card elevation-purple-band">
|
||||
<div><div class="elevation-name">Purple Band</div><div class="elevation-desc">Full-width dark purple background. Hero sections, showcases.</div></div>
|
||||
<div class="elevation-level">Level 2 — Dramatic</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="color: var(--text-muted); margin-top: 32px; font-size: 14px; line-height: 1.6;">
|
||||
Cohere is nearly shadow-free. Depth is communicated through background color contrast (elevated cards on dark canvas), border containment, and dramatic light-to-dark section alternation.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div style="height: 80px;"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,814 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Design System Preview: Cohere (Light)</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
/* Primary */
|
||||
--color-black: #000000;
|
||||
--color-near-black: #212121;
|
||||
--color-deep-dark: #17171c;
|
||||
/* Accent */
|
||||
--color-interaction-blue: #1863dc;
|
||||
--color-ring-blue: rgba(76, 110, 230, 0.5);
|
||||
--color-focus-purple: #9b60aa;
|
||||
/* Surface */
|
||||
--color-white: #ffffff;
|
||||
--color-snow: #fafafa;
|
||||
--color-lightest-gray: #f2f2f2;
|
||||
/* Neutrals */
|
||||
--color-muted-slate: #93939f;
|
||||
--color-border-cool: #d9d9dd;
|
||||
--color-border-light: #e5e7eb;
|
||||
/* Fonts */
|
||||
--font-display: 'Space Grotesk', Inter, ui-sans-serif, system-ui, sans-serif;
|
||||
--font-body: Inter, Arial, ui-sans-serif, system-ui, sans-serif;
|
||||
--font-mono: 'Space Mono', Arial, ui-sans-serif, system-ui, monospace;
|
||||
/* Light mode tokens */
|
||||
--bg-page: #ffffff;
|
||||
--bg-card: #ffffff;
|
||||
--bg-nav: rgba(255, 255, 255, 0.95);
|
||||
--text-primary: #000000;
|
||||
--text-secondary: #212121;
|
||||
--text-muted: #93939f;
|
||||
--border-color: #d9d9dd;
|
||||
--border-subtle: #f2f2f2;
|
||||
--section-label-color: #93939f;
|
||||
--accent: #1863dc;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
background: var(--bg-page);
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-body);
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
.nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 40px;
|
||||
background: var(--bg-nav);
|
||||
backdrop-filter: blur(12px);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.nav-brand {
|
||||
font-family: var(--font-display);
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.nav-brand svg { width: 28px; height: 28px; }
|
||||
.nav-links { display: flex; gap: 32px; align-items: center; }
|
||||
.nav-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
font-family: var(--font-body);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--accent); }
|
||||
.nav-cta {
|
||||
background: var(--color-black);
|
||||
color: var(--color-white);
|
||||
padding: 10px 24px;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.nav-cta:hover { opacity: 0.85; }
|
||||
|
||||
/* HERO */
|
||||
.hero {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 120px 40px 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hero h1 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 72px;
|
||||
font-weight: 400;
|
||||
line-height: 1.0;
|
||||
letter-spacing: -1.44px;
|
||||
margin-bottom: 24px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.hero h1 span { color: var(--accent); }
|
||||
.hero p {
|
||||
color: var(--text-muted);
|
||||
font-family: var(--font-body);
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.hero-buttons { display: flex; gap: 16px; justify-content: center; }
|
||||
.btn-ghost-primary {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s, opacity 0.2s;
|
||||
}
|
||||
.btn-ghost-primary:hover { color: var(--accent); opacity: 0.8; }
|
||||
.btn-dark-solid {
|
||||
background: var(--color-black);
|
||||
color: var(--color-white);
|
||||
padding: 12px 28px;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.btn-dark-solid:hover { opacity: 0.85; }
|
||||
|
||||
/* SECTIONS */
|
||||
.section {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 80px 40px;
|
||||
}
|
||||
.section-title {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
color: var(--section-label-color);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.section-heading {
|
||||
font-family: var(--font-body);
|
||||
font-size: 48px;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.48px;
|
||||
margin-bottom: 48px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.section-divider {
|
||||
border: none;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
margin: 0 40px;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* PURPLE BAND */
|
||||
.purple-band {
|
||||
background: linear-gradient(135deg, #2d1b4e 0%, #1a1040 50%, #17171c 100%);
|
||||
padding: 80px 40px;
|
||||
text-align: center;
|
||||
}
|
||||
.purple-band h2 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 60px;
|
||||
font-weight: 400;
|
||||
line-height: 1.0;
|
||||
letter-spacing: -1.2px;
|
||||
color: #ffffff;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.purple-band p {
|
||||
color: rgba(255,255,255,0.7);
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* COLOR PALETTE */
|
||||
.color-group { margin-bottom: 40px; }
|
||||
.color-group-title {
|
||||
font-family: var(--font-body);
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.color-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.color-swatch {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 22px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.color-swatch-block {
|
||||
height: 80px;
|
||||
position: relative;
|
||||
}
|
||||
.color-swatch-info {
|
||||
padding: 12px 16px;
|
||||
background: var(--bg-card);
|
||||
}
|
||||
.color-swatch-name { font-size: 13px; font-weight: 500; margin-bottom: 2px; }
|
||||
.color-swatch-hex { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); margin-bottom: 4px; }
|
||||
.color-swatch-role { font-size: 12px; color: var(--text-muted); line-height: 1.4; }
|
||||
|
||||
/* TYPOGRAPHY */
|
||||
.type-sample { margin-bottom: 32px; padding-bottom: 32px; border-bottom: 1px solid var(--border-subtle); }
|
||||
.type-sample:last-child { border-bottom: none; }
|
||||
.type-sample-text { margin-bottom: 8px; }
|
||||
.type-sample-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* BUTTONS */
|
||||
.button-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.button-demo { text-align: center; }
|
||||
.button-demo-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
}
|
||||
.btn-ghost-cohere {
|
||||
background: transparent;
|
||||
color: var(--color-black);
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s, opacity 0.2s;
|
||||
}
|
||||
.btn-ghost-cohere:hover { color: var(--accent); opacity: 0.8; }
|
||||
.btn-dark-cohere {
|
||||
background: var(--color-black);
|
||||
color: var(--color-white);
|
||||
padding: 12px 28px;
|
||||
border: none;
|
||||
border-radius: 22px;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-dark-pill {
|
||||
background: var(--color-black);
|
||||
color: var(--color-white);
|
||||
padding: 12px 28px;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-outlined {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 12px 24px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 22px;
|
||||
font-size: 16px;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s, color 0.2s;
|
||||
}
|
||||
.btn-outlined:hover { border-color: var(--accent); color: var(--accent); }
|
||||
.btn-ghost-focus:focus {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* CARDS */
|
||||
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; }
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
padding: 28px;
|
||||
}
|
||||
.card-signature {
|
||||
border-radius: 22px;
|
||||
border: 1px solid var(--color-lightest-gray);
|
||||
}
|
||||
.card-dialog {
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.card-generous {
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--color-lightest-gray);
|
||||
}
|
||||
.card h3 {
|
||||
font-family: var(--font-body);
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
letter-spacing: normal;
|
||||
margin-bottom: 12px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.card p { color: var(--text-muted); font-size: 16px; line-height: 1.5; font-weight: 400; }
|
||||
.card-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* SPACING */
|
||||
.spacing-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
|
||||
.spacing-item { text-align: center; }
|
||||
.spacing-box {
|
||||
background: rgba(24, 99, 220, 0.08);
|
||||
border: 1px solid rgba(24, 99, 220, 0.2);
|
||||
border-radius: 2px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.spacing-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* RADIUS */
|
||||
.radius-row { display: flex; flex-wrap: wrap; gap: 20px; align-items: center; }
|
||||
.radius-item { text-align: center; }
|
||||
.radius-box {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: var(--color-snow);
|
||||
border: 1px solid var(--border-color);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.radius-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.radius-context {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* ELEVATION */
|
||||
.elevation-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 24px; }
|
||||
.elevation-card {
|
||||
background: var(--bg-card);
|
||||
border-radius: 22px;
|
||||
padding: 24px;
|
||||
min-height: 140px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.elevation-flat { border: none; background: var(--bg-page); }
|
||||
.elevation-bordered-light { border: 1px solid var(--color-lightest-gray); }
|
||||
.elevation-bordered-cool { border: 1px solid var(--border-color); }
|
||||
.elevation-purple-band {
|
||||
background: linear-gradient(135deg, #2d1b4e 0%, #1a1040 100%);
|
||||
color: #ffffff;
|
||||
}
|
||||
.elevation-purple-band .elevation-name,
|
||||
.elevation-purple-band .elevation-desc { color: #ffffff; }
|
||||
.elevation-purple-band .elevation-level { color: rgba(255,255,255,0.6); }
|
||||
.elevation-name { font-size: 16px; font-weight: 500; margin-bottom: 8px; }
|
||||
.elevation-desc { font-size: 13px; color: var(--text-muted); line-height: 1.5; }
|
||||
.elevation-level {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.28px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/* RESPONSIVE */
|
||||
@media (max-width: 768px) {
|
||||
.nav { padding: 12px 20px; }
|
||||
.nav-links a:not(.nav-cta-wrapper) { display: none; }
|
||||
.hero { padding: 80px 20px 60px; }
|
||||
.hero h1 { font-size: 42px; letter-spacing: -0.84px; }
|
||||
.section { padding: 60px 20px; }
|
||||
.section-heading { font-size: 32px; letter-spacing: -0.32px; }
|
||||
.color-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
|
||||
.card-grid { grid-template-columns: 1fr; }
|
||||
.hero-buttons { flex-direction: column; align-items: center; }
|
||||
.button-row { flex-direction: column; align-items: flex-start; }
|
||||
.purple-band h2 { font-size: 36px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAV -->
|
||||
<nav class="nav">
|
||||
<div class="nav-brand">
|
||||
<svg viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="14" cy="14" r="13" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M8 14 C8 10, 12 8, 14 8 C16 8, 20 10, 20 14 C20 18, 16 20, 14 20 C12 20, 8 18, 8 14Z" fill="currentColor" opacity="0.15"/>
|
||||
<circle cx="14" cy="14" r="4" fill="currentColor"/>
|
||||
</svg>
|
||||
cohere
|
||||
</div>
|
||||
<div class="nav-links">
|
||||
<a href="#colors">Colors</a>
|
||||
<a href="#typography">Typography</a>
|
||||
<a href="#buttons">Buttons</a>
|
||||
<a href="#cards">Cards</a>
|
||||
<a href="#spacing">Spacing</a>
|
||||
<a href="#elevation">Elevation</a>
|
||||
<button class="nav-cta">Get Started</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- HERO -->
|
||||
<section class="hero">
|
||||
<h1>Design System Preview:<br><span>Cohere</span></h1>
|
||||
<p>Auto-generated design token catalog from DESIGN.md</p>
|
||||
<div class="hero-buttons">
|
||||
<button class="btn-dark-solid">Explore Tokens</button>
|
||||
<button class="btn-ghost-primary">View Source</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COLORS -->
|
||||
<section class="section" id="colors">
|
||||
<div class="section-title">01 / Color Palette</div>
|
||||
<h2 class="section-heading">Color Palette & Roles</h2>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Primary</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #000000; border-bottom: 1px solid #333;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Cohere Black</div>
|
||||
<div class="color-swatch-hex">#000000</div>
|
||||
<div class="color-swatch-role">Primary headline text, maximum emphasis</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #212121; border-bottom: 1px solid #333;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Near Black</div>
|
||||
<div class="color-swatch-hex">#212121</div>
|
||||
<div class="color-swatch-role">Standard body link color</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #17171c; border-bottom: 1px solid #333;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Deep Dark</div>
|
||||
<div class="color-swatch-hex">#17171c</div>
|
||||
<div class="color-swatch-role">Navigation and dark-section text</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Secondary & Accent</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #1863dc;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Interaction Blue</div>
|
||||
<div class="color-swatch-hex">#1863dc</div>
|
||||
<div class="color-swatch-role">Hover, focus states, active links</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: rgba(76,110,230,0.5);"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Ring Blue</div>
|
||||
<div class="color-swatch-hex">#4c6ee6 @ 50%</div>
|
||||
<div class="color-swatch-role">Keyboard focus indicators</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #9b60aa;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Focus Purple</div>
|
||||
<div class="color-swatch-hex">#9b60aa</div>
|
||||
<div class="color-swatch-role">Input focus border color</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Surface & Background</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #ffffff; border-bottom: 1px solid #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Pure White</div>
|
||||
<div class="color-swatch-hex">#ffffff</div>
|
||||
<div class="color-swatch-role">Primary page background, card surface</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #fafafa; border-bottom: 1px solid #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Snow</div>
|
||||
<div class="color-swatch-hex">#fafafa</div>
|
||||
<div class="color-swatch-role">Subtle elevated surfaces, light sections</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #f2f2f2; border-bottom: 1px solid #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Lightest Gray</div>
|
||||
<div class="color-swatch-hex">#f2f2f2</div>
|
||||
<div class="color-swatch-role">Card borders, softest containment</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h3 class="color-group-title">Neutrals & Text</h3>
|
||||
<div class="color-grid">
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #93939f;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Muted Slate</div>
|
||||
<div class="color-swatch-hex">#93939f</div>
|
||||
<div class="color-swatch-role">Footer links, tertiary text</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #d9d9dd;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Border Cool</div>
|
||||
<div class="color-swatch-hex">#d9d9dd</div>
|
||||
<div class="color-swatch-role">Section borders, list separators</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-swatch">
|
||||
<div class="color-swatch-block" style="background: #e5e7eb;"></div>
|
||||
<div class="color-swatch-info">
|
||||
<div class="color-swatch-name">Border Light</div>
|
||||
<div class="color-swatch-hex">#e5e7eb</div>
|
||||
<div class="color-swatch-role">Lighter border variant (gray-200)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- PURPLE HERO BAND -->
|
||||
<div class="purple-band">
|
||||
<h2>Enterprise AI Platform</h2>
|
||||
<p>Deep purple hero sections create dramatic visual breaks in the white page flow</p>
|
||||
</div>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- TYPOGRAPHY -->
|
||||
<section class="section" id="typography">
|
||||
<div class="section-title">02 / Typography Scale</div>
|
||||
<h2 class="section-heading">Typography Rules</h2>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-display); font-size: 72px; font-weight: 400; line-height: 1.0; letter-spacing: -1.44px;">Display Hero</div>
|
||||
<div class="type-sample-label">Display / Hero — CohereText — 72px / 400 / 1.00 / -1.44px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-display); font-size: 60px; font-weight: 400; line-height: 1.0; letter-spacing: -1.2px;">Display Secondary</div>
|
||||
<div class="type-sample-label">Display Secondary — CohereText — 60px / 400 / 1.00 / -1.2px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 48px; font-weight: 400; line-height: 1.2; letter-spacing: -0.48px;">Section Heading</div>
|
||||
<div class="type-sample-label">Section Heading — Unica77 — 48px / 400 / 1.20 / -0.48px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 32px; font-weight: 400; line-height: 1.2; letter-spacing: -0.32px;">Sub-heading</div>
|
||||
<div class="type-sample-label">Sub-heading — Unica77 — 32px / 400 / 1.20 / -0.32px</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 24px; font-weight: 400; line-height: 1.3;">Feature Title</div>
|
||||
<div class="type-sample-label">Feature Title — Unica77 — 24px / 400 / 1.30 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 18px; font-weight: 400; line-height: 1.4;">Body Large text for intro paragraphs. Unica77 provides geometric Swiss precision for all functional UI text at the body-large tier.</div>
|
||||
<div class="type-sample-label">Body Large — Unica77 — 18px / 400 / 1.40 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 16px; font-weight: 400; line-height: 1.5;">Standard body text for paragraphs, navigation links, and button labels. Unica77 at its most common size, weight 400.</div>
|
||||
<div class="type-sample-label">Body / Button — Unica77 — 16px / 400 / 1.50 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 14px; font-weight: 500; line-height: 1.71;">Button Medium Label</div>
|
||||
<div class="type-sample-label">Button Medium — Unica77 — 14px / 500 / 1.71 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 14px; font-weight: 400; line-height: 1.4; color: var(--text-muted);">Caption and metadata text for descriptions</div>
|
||||
<div class="type-sample-label">Caption — Unica77 — 14px / 400 / 1.40 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-mono); font-size: 14px; font-weight: 400; line-height: 1.4; text-transform: uppercase; letter-spacing: 0.28px; color: var(--text-muted);">UPPERCASE SECTION LABEL</div>
|
||||
<div class="type-sample-label">Uppercase Label — CohereMono — 14px / 400 / 1.40 / 0.28px / uppercase</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-body); font-size: 12px; font-weight: 400; line-height: 1.4; color: var(--text-muted);">Smallest text for footer links and fine print</div>
|
||||
<div class="type-sample-label">Small — Unica77 — 12px / 400 / 1.40 / normal</div>
|
||||
</div>
|
||||
|
||||
<div class="type-sample">
|
||||
<div class="type-sample-text" style="font-family: var(--font-mono); font-size: 8px; font-weight: 400; line-height: 1.4; text-transform: uppercase; letter-spacing: 0.16px; color: var(--text-muted);">CODE MICRO LABEL</div>
|
||||
<div class="type-sample-label">Code Micro — CohereMono — 8px / 400 / 1.40 / 0.16px / uppercase</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="section" id="buttons">
|
||||
<div class="section-title">03 / Button Variants</div>
|
||||
<h2 class="section-heading">Buttons</h2>
|
||||
|
||||
<div class="button-row">
|
||||
<div class="button-demo">
|
||||
<button class="btn-ghost-cohere">Ghost Button</button>
|
||||
<div class="button-demo-label">Ghost / Transparent</div>
|
||||
</div>
|
||||
<div class="button-demo">
|
||||
<button class="btn-dark-cohere">Dark Solid</button>
|
||||
<div class="button-demo-label">Dark Solid (22px)</div>
|
||||
</div>
|
||||
<div class="button-demo">
|
||||
<button class="btn-dark-pill">Pill CTA</button>
|
||||
<div class="button-demo-label">Dark Pill (9999px)</div>
|
||||
</div>
|
||||
<div class="button-demo">
|
||||
<button class="btn-outlined">Outlined</button>
|
||||
<div class="button-demo-label">Outlined (22px)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="color: var(--text-muted); margin-top: 32px; font-size: 14px;">
|
||||
Ghost buttons are the primary style — invisible until interacted with. On hover, text shifts to Interaction Blue (#1863dc) with 0.8 opacity. Focus: 2px solid Interaction Blue outline.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- CARDS -->
|
||||
<section class="section" id="cards">
|
||||
<div class="section-title">04 / Card Examples</div>
|
||||
<h2 class="section-heading">Cards & Containers</h2>
|
||||
|
||||
<div class="card-grid">
|
||||
<div class="card card-signature">
|
||||
<div class="card-label">STANDARD CARD</div>
|
||||
<h3>Signature 22px Radius</h3>
|
||||
<p>The distinctive Cohere card with 22px border-radius and 1px solid #f2f2f2 border. Creates cloud-like, organic softness on the white canvas.</p>
|
||||
</div>
|
||||
<div class="card card-dialog">
|
||||
<div class="card-label">DIALOG CARD</div>
|
||||
<h3>Dialog 8px Radius</h3>
|
||||
<p>Modal and dialog containers use a tighter 8px radius with #d9d9dd border. Functional, secondary containment for transient UI.</p>
|
||||
</div>
|
||||
<div class="card card-generous">
|
||||
<div class="card-label">GENEROUS CARD</div>
|
||||
<h3>Featured 16px Radius</h3>
|
||||
<p>Medium-sized containers for featured content. Uses 16px radius as a middle step in the radius scale with subtle #f2f2f2 border.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- SPACING -->
|
||||
<section class="section" id="spacing">
|
||||
<div class="section-title">05 / Spacing Scale</div>
|
||||
<h2 class="section-heading">Spacing System</h2>
|
||||
<p style="color: var(--text-muted); margin-bottom: 32px;">Base unit: 8px. Scale from 2px to 60px.</p>
|
||||
|
||||
<div class="spacing-row">
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 8px; height: 8px;"></div><div class="spacing-label">2px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 18px; height: 18px;"></div><div class="spacing-label">6px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 24px; height: 24px;"></div><div class="spacing-label">8px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 30px; height: 30px;"></div><div class="spacing-label">10px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 36px; height: 36px;"></div><div class="spacing-label">12px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 48px; height: 48px;"></div><div class="spacing-label">16px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 60px; height: 60px;"></div><div class="spacing-label">20px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 66px; height: 66px;"></div><div class="spacing-label">22px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 72px; height: 72px;"></div><div class="spacing-label">24px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 84px; height: 84px;"></div><div class="spacing-label">28px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 96px; height: 96px;"></div><div class="spacing-label">32px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 120px; height: 120px;"></div><div class="spacing-label">40px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 168px; height: 168px;"></div><div class="spacing-label">56px</div></div>
|
||||
<div class="spacing-item"><div class="spacing-box" style="width: 180px; height: 180px;"></div><div class="spacing-label">60px</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BORDER RADIUS -->
|
||||
<section class="section">
|
||||
<div class="section-title">06 / Border Radius Scale</div>
|
||||
<h2 class="section-heading">Border Radius</h2>
|
||||
|
||||
<div class="radius-row">
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 4px;"></div><div class="radius-label">4px</div><div class="radius-context">Sharp — nav, tags</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 8px;"></div><div class="radius-label">8px</div><div class="radius-context">Comfortable — dialogs</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 16px;"></div><div class="radius-label">16px</div><div class="radius-context">Generous — featured</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 20px;"></div><div class="radius-label">20px</div><div class="radius-context">Large — feature cards</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 22px; border-color: var(--accent); border-width: 2px;"></div><div class="radius-label">22px</div><div class="radius-context">Signature — THE radius</div></div>
|
||||
<div class="radius-item"><div class="radius-box" style="border-radius: 9999px;"></div><div class="radius-label">9999px</div><div class="radius-context">Pill — buttons, tags</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- ELEVATION -->
|
||||
<section class="section" id="elevation">
|
||||
<div class="section-title">07 / Elevation & Depth</div>
|
||||
<h2 class="section-heading">Depth & Elevation</h2>
|
||||
|
||||
<div class="elevation-grid">
|
||||
<div class="elevation-card elevation-flat">
|
||||
<div><div class="elevation-name">Flat</div><div class="elevation-desc">No shadow, no border. Page background and text blocks.</div></div>
|
||||
<div class="elevation-level">Level 0</div>
|
||||
</div>
|
||||
<div class="elevation-card elevation-bordered-light">
|
||||
<div><div class="elevation-name">Bordered (Light)</div><div class="elevation-desc">1px solid #f2f2f2. Standard cards, subtle containment.</div></div>
|
||||
<div class="elevation-level">Level 1 — Lightest Gray</div>
|
||||
</div>
|
||||
<div class="elevation-card elevation-bordered-cool">
|
||||
<div><div class="elevation-name">Bordered (Cool)</div><div class="elevation-desc">1px solid #d9d9dd. Emphasized cards, list separators.</div></div>
|
||||
<div class="elevation-level">Level 1 — Border Cool</div>
|
||||
</div>
|
||||
<div class="elevation-card elevation-purple-band">
|
||||
<div><div class="elevation-name">Purple Band</div><div class="elevation-desc">Full-width dark purple background. Hero sections, showcases.</div></div>
|
||||
<div class="elevation-level">Level 2 — Dramatic</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="color: var(--text-muted); margin-top: 32px; font-size: 14px; line-height: 1.6;">
|
||||
Cohere is nearly shadow-free. Depth is communicated through background color contrast (white cards on purple bands), border containment (cool gray borders), and dramatic light-to-dark section alternation.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div style="height: 80px;"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "agent-company",
|
||||
"version": "0.4.156",
|
||||
"version": "0.4.165",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Cross-platform Electron desktop control plane for local-first AI agent companies.",
|
||||
|
||||
@@ -247,25 +247,9 @@ export function executeAutomationAction(
|
||||
}
|
||||
} else {
|
||||
// No manager found — agent is likely the CEO or top-level.
|
||||
// Post as company-wide message so the board and other leaders see it.
|
||||
const escalationResult = dispatchAgentMessage(
|
||||
{ db, emitEvent, publishDomainChanged, wakeAgentIfPossible },
|
||||
{
|
||||
companyId: ctx.companyId,
|
||||
fromAgentId: targetAgentId,
|
||||
toAgentId: null,
|
||||
channel: "company",
|
||||
subject: `Escalation: ${taskTitle}`,
|
||||
body: escalationBody,
|
||||
priority: "urgent",
|
||||
},
|
||||
wakeTrigger,
|
||||
);
|
||||
if (!escalationResult.ok) {
|
||||
logger.warn(
|
||||
`[automation] Failed to escalate "${taskTitle}" to company channel: ${escalationResult.error.code} ${escalationResult.error.message}`,
|
||||
);
|
||||
}
|
||||
// Skip posting to company channel to avoid flooding it with system noise.
|
||||
// The task status change is already visible in the task list and activity log.
|
||||
logger.info(`[automation] Skipping escalation for top-level agent "${agentName}" — no manager to escalate to.`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ export class AppDatabaseBase {
|
||||
canOpenPath(targetPath: string) { return this.settings.canOpenPath(targetPath); }
|
||||
getDisabledModels(connectorId: string) { return this.settings.getDisabledModels(connectorId); }
|
||||
setDisabledModels(connectorId: string, models: Array<{ id: string; label: string }>) { this.settings.setDisabledModels(connectorId, models); }
|
||||
hasModelPoolSettings(connectorId: string) { return this.settings.hasModelPoolSettings(connectorId); }
|
||||
getLastBudgetResetMonth(companyId: string) { return this.settings.getLastBudgetResetMonth(companyId); }
|
||||
setLastBudgetResetMonth(companyId: string, month: string) { this.settings.setLastBudgetResetMonth(companyId, month); }
|
||||
|
||||
|
||||
@@ -90,6 +90,53 @@ export function buildConnectorMethods(
|
||||
const currentRows = readAll<Partial<ConnectorRecord>>(
|
||||
"select id, label, description, status, command, version, auth_state as authState, last_checked_at as lastCheckedAt, last_error as lastError, model, env_binding_text as envBindingText, notes from connectors",
|
||||
);
|
||||
// Migrate first compat slot if its definition defaults have changed (edition upgrade).
|
||||
// When the definition ships with preset notes that differ from the DB, relocate the
|
||||
// old user config to the next empty compat slot so definition defaults take effect.
|
||||
const firstCompat = currentRows.find((r) => r.id === "claude_compatible");
|
||||
if (firstCompat?.envBindingText && firstCompat.notes) {
|
||||
let firstDef: { notes: string } | undefined;
|
||||
try { firstDef = getConnectorDefinition("claude_compatible"); } catch { /* skip */ }
|
||||
if (firstDef?.notes && firstCompat.notes !== firstDef.notes) {
|
||||
const migrationTargets: ConnectorId[] = [
|
||||
"claude_compat_2", "claude_compat_3", "claude_compat_4", "claude_compat_5",
|
||||
"claude_compat_6", "claude_compat_7", "claude_compat_8", "claude_compat_9", "claude_compat_10",
|
||||
];
|
||||
const occupied = new Set(
|
||||
currentRows
|
||||
.filter((r) => r.id !== "claude_compatible" && r.id?.startsWith("claude_compat") && r.envBindingText)
|
||||
.map((r) => r.id),
|
||||
);
|
||||
const targetId = migrationTargets.find((id) => !occupied.has(id));
|
||||
if (targetId) {
|
||||
const migrated = {
|
||||
envBindingText: firstCompat.envBindingText,
|
||||
notes: firstCompat.notes,
|
||||
model: firstCompat.model,
|
||||
status: firstCompat.status,
|
||||
authState: firstCompat.authState,
|
||||
version: firstCompat.version,
|
||||
lastCheckedAt: firstCompat.lastCheckedAt,
|
||||
lastError: firstCompat.lastError,
|
||||
};
|
||||
const targetRow = currentRows.find((r) => r.id === targetId);
|
||||
if (targetRow) {
|
||||
Object.assign(targetRow, migrated);
|
||||
} else {
|
||||
currentRows.push({ id: targetId as ConnectorId, ...migrated });
|
||||
}
|
||||
firstCompat.envBindingText = undefined;
|
||||
firstCompat.notes = undefined;
|
||||
firstCompat.model = undefined;
|
||||
firstCompat.status = undefined;
|
||||
firstCompat.authState = undefined;
|
||||
firstCompat.version = undefined;
|
||||
firstCompat.lastCheckedAt = undefined;
|
||||
firstCompat.lastError = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const merged = buildDefaultConnectorRows(currentRows);
|
||||
const statement = getDb().prepare(
|
||||
"insert or replace into connectors (id, label, description, status, command, version, auth_state, last_checked_at, last_error, model, env_binding_text, notes, updated_at) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
@@ -102,6 +149,35 @@ export function buildConnectorMethods(
|
||||
row.lastError, row.model, row.envBindingText, row.notes, updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
// One-time migration: mark native connectors that are actively used by
|
||||
// agents as model-pool-managed so they remain visible to the CEO after
|
||||
// the opt-in policy change. Connectors not used by any agent stay
|
||||
// unmanaged and will not appear in CEO prompts until the user explicitly
|
||||
// enables models for them in Settings > Model Management.
|
||||
const migrationKey = "migration:model_pool_opt_in_v1";
|
||||
const migrated = readAll<{ value: string }>("SELECT value FROM settings WHERE key = ?", migrationKey);
|
||||
if (migrated.length === 0) {
|
||||
const usedIds = new Set(
|
||||
readAll<{ connector_id: string }>(
|
||||
"SELECT DISTINCT connector_id FROM agents WHERE status NOT IN ('terminated')",
|
||||
).map((r) => r.connector_id),
|
||||
);
|
||||
const nativeIds = ["codex_local", "claude_local", "gemini_local"];
|
||||
const upsert = getDb().prepare(
|
||||
"INSERT INTO settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value",
|
||||
);
|
||||
for (const id of nativeIds) {
|
||||
const hasSettings = readAll<{ key: string }>(
|
||||
"SELECT key FROM settings WHERE key = ?",
|
||||
`disabled_models:${id}`,
|
||||
);
|
||||
if (hasSettings.length === 0 && usedIds.has(id)) {
|
||||
upsert.run(`disabled_models:${id}`, "[]");
|
||||
}
|
||||
}
|
||||
upsert.run(migrationKey, "1");
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -84,11 +84,11 @@ export function buildSettingsMethods(
|
||||
},
|
||||
|
||||
setDisabledModels(connectorId: string, models: Array<{ id: string; label: string }>) {
|
||||
if (models.length === 0) {
|
||||
getDb().prepare("delete from settings where key = ?").run(`disabled_models:${connectorId}`);
|
||||
} else {
|
||||
setSetting(`disabled_models:${connectorId}`, JSON.stringify(models));
|
||||
}
|
||||
setSetting(`disabled_models:${connectorId}`, JSON.stringify(models));
|
||||
},
|
||||
|
||||
hasModelPoolSettings(connectorId: string): boolean {
|
||||
return getSetting(`disabled_models:${connectorId}`) !== null;
|
||||
},
|
||||
|
||||
getLastBudgetResetMonth(companyId: string): string | null {
|
||||
|
||||
@@ -237,12 +237,16 @@ export function buildRunPayload(params: RunDispatchParams, deps: TurnContextDeps
|
||||
recentDocuments: snapshot.documents
|
||||
.filter((document) => document.companyId === companyId && (document.authorAgentId === agent.id || document.reviewerAgentId === agent.id || document.status === "in_review"))
|
||||
.slice(0, 5),
|
||||
allConnectors: snapshot.connectors.map((c) => ({
|
||||
id: c.id,
|
||||
label: c.label,
|
||||
status: c.status,
|
||||
enabledModels: resolveEnabledConnectorModels(db, c),
|
||||
})),
|
||||
allConnectors: snapshot.connectors
|
||||
.filter((c) => c.status === "ready")
|
||||
.filter((c) => c.id.startsWith("claude_compat") || db.hasModelPoolSettings(c.id))
|
||||
.map((c) => ({
|
||||
id: c.id,
|
||||
label: c.label,
|
||||
status: c.status,
|
||||
enabledModels: resolveEnabledConnectorModels(db, c),
|
||||
}))
|
||||
.filter((c) => c.enabledModels.length > 0),
|
||||
sessionHandoff,
|
||||
skillNames,
|
||||
skillEntries: skills.map((s) => ({
|
||||
|
||||
@@ -381,7 +381,11 @@ Always verify API responses before reporting — only report successful actions.
|
||||
|
||||
// Reinforce locale at the end of prompt (recency bias helps LLMs follow this)
|
||||
if (localeInstruction) {
|
||||
sections.push(`# 语言要求提醒\n${localeInstruction}\n请记住:你的所有输出必须使用中文。\n`);
|
||||
if ((ctx.locale ?? "en") === "zh") {
|
||||
sections.push(`# 语言要求提醒\n${localeInstruction}\n请记住:你的所有输出必须使用中文。\n`);
|
||||
} else {
|
||||
sections.push(`# Language Requirement Reminder\n${localeInstruction}\nRemember: ALL your output must be in English.\n`);
|
||||
}
|
||||
}
|
||||
|
||||
return sections.join("\n");
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { AppLocale } from "./locale";
|
||||
/**
|
||||
* Returns a locale-appropriate system prompt instruction for AI agents.
|
||||
* When locale is "zh", the instruction tells the agent to respond entirely in Chinese.
|
||||
* For "en" (or any other locale), returns an empty string (no additional instruction needed).
|
||||
* When locale is "en", the instruction tells the agent to respond entirely in English.
|
||||
*/
|
||||
export function getLocalePromptInstruction(locale: AppLocale): string {
|
||||
if (locale === "zh") {
|
||||
@@ -14,5 +14,10 @@ export function getLocalePromptInstruction(locale: AppLocale): string {
|
||||
"不要使用英文回复,除非是代码、变量名、API 端点等技术术语。",
|
||||
].join("\n");
|
||||
}
|
||||
return "";
|
||||
return [
|
||||
"Important language requirement: You MUST communicate entirely in English.",
|
||||
"This includes: task descriptions, comments, messages, reports, documents, approvals, notifications — ALL output must be in English.",
|
||||
"Even if some existing content or context is in another language, all your responses and created content must be in English.",
|
||||
"Do not respond in other languages, except for code, variable names, API endpoints, and other technical terms.",
|
||||
].join("\n");
|
||||
}
|
||||
Reference in new issue
Block a user