Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import fs from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest';

const globalsPath = path.resolve(process.cwd(), 'src/app/globals.css');

describe('Latest activity indicator animation', () => {
it('uses a single thin overlay sweep with a hold before restarting', () => {
const source = fs.readFileSync(globalsPath, 'utf8');

expect(source).toContain('@keyframes latestActivitySweep');
expect(source).toContain('78% {');
expect(source).toContain('transform: translateX(-120%);');
expect(source).toContain('transform: translateX(120%);');
expect(source).toContain('.latest-activity-indicator::after');
expect(source).toContain('content: attr(data-activity-text);');
expect(source).toContain('color: var(--ember-card);');
expect(source).toContain('clip-path: inset(0 45% 0 45%);');
expect(source).toContain('will-change: transform;');
expect(source).toContain('animation: latestActivitySweep 3.4s linear infinite;');
});
});
56 changes: 54 additions & 2 deletions typescript/clients/web-ag-ui/apps/web/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,24 @@ body {
background: #09090B !important;
color: hsl(var(--foreground)) !important;
color-scheme: dark !important;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-family: var(--font-roboto), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.font-mono {
font-family: var(--font-roboto-mono), ui-monospace, SFMono-Regular, Menlo, monospace !important;
}

.agent-detail-page .text-\[10px\],
.agent-detail-page .text-\[11px\],
.agent-detail-page .text-\[12px\],
.agent-detail-page .text-xs.tracking-wide {
font-family: var(--font-roboto-mono), ui-monospace, SFMono-Regular, Menlo, monospace;
}

.agent-detail-page .text-xs.tracking-wide,
.hire-agents-page .text-\[10px\].tracking-wide,
.hire-agents-page .text-\[11px\].tracking-wide {
text-transform: capitalize;
}

body,
Expand Down Expand Up @@ -138,6 +155,18 @@ html {
}
}

@keyframes latestActivitySweep {
0% {
transform: translateX(-120%);
}
78% {
transform: translateX(120%);
}
100% {
transform: translateX(120%);
}
}

.animate-fade-in {
animation: fadeIn 0.3s ease-out forwards;
}
Expand All @@ -146,6 +175,29 @@ html {
animation: fadeInSimple 0.35s ease-out forwards;
}

.latest-activity-indicator {
position: relative;
display: inline-block;
overflow: hidden;
color: #ffffff;
}

.latest-activity-indicator::after {
content: attr(data-activity-text);
position: absolute;
inset: 0;
display: block;
color: var(--ember-card);
font: inherit;
letter-spacing: inherit;
line-height: inherit;
clip-path: inset(0 45% 0 45%);
white-space: pre;
pointer-events: none;
will-change: transform;
animation: latestActivitySweep 3.4s linear infinite;
}

/* Staggered animation delays */
.stagger-1 { animation-delay: 0.05s; }
.stagger-2 { animation-delay: 0.1s; }
Expand Down Expand Up @@ -175,7 +227,7 @@ html {
padding: 0.625rem 1rem;
font-size: 0.75rem;
font-weight: 500;
text-transform: uppercase;
text-transform: none;
letter-spacing: 0.05em;
color: hsl(var(--muted-foreground));
border-bottom: 1px solid hsl(var(--border));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useAgent } from '@/contexts/AgentContext';
import type { OnboardingState } from '@/types/agent';

type UiPreviewState = 'prehire' | 'onboarding' | 'active';
type UiPreviewTab = 'blockers' | 'metrics' | 'transactions' | 'settings' | 'chat';
type UiPreviewTab = 'blockers' | 'metrics' | 'transactions' | 'chat';

function parseUiPreviewState(value: string | null): UiPreviewState | null {
if (value === 'prehire' || value === 'onboarding' || value === 'active') return value;
Expand All @@ -20,7 +20,6 @@ function parseUiPreviewTab(value: string | null): UiPreviewTab | null {
value === 'blockers' ||
value === 'metrics' ||
value === 'transactions' ||
value === 'settings' ||
value === 'chat'
) {
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default function HireAgentsRoute() {
id: config.id,
rank: config.featuredRank,
name: config.name,
description: config.description,
creator: config.creator,
creatorVerified: config.creatorVerified,
rating: undefined, // Real rating not available
Expand Down
19 changes: 18 additions & 1 deletion typescript/clients/web-ag-ui/apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Metadata } from 'next';
import { Roboto, Roboto_Mono } from 'next/font/google';

import type { CopilotKitCSSProperties } from '@copilotkit/react-ui';
import { ProvidersNoSSR } from '../components/ProvidersNoSSR';
Expand All @@ -8,6 +9,20 @@ import { PrivyGateBanner } from '../components/PrivyGateBanner';
import './globals.css';
import '@copilotkit/react-ui/styles.css';

const roboto = Roboto({
subsets: ['latin'],
variable: '--font-roboto',
display: 'swap',
weight: ['400', '500', '700'],
});

const robotoMono = Roboto_Mono({
subsets: ['latin'],
variable: '--font-roboto-mono',
display: 'swap',
weight: ['400', '500', '700'],
});

export const metadata: Metadata = {
title: 'Ember AI - Hire Agents',
description: 'Discover and hire AI agents for your crypto strategies',
Expand All @@ -29,7 +44,9 @@ export default function RootLayout({
}}
/>
</head>
<body className="antialiased bg-[#09090B] text-[#D1D1D1] dark">
<body
className={`${roboto.variable} ${robotoMono.variable} antialiased bg-[#09090B] text-[#D1D1D1] dark`}
>
<ProvidersNoSSR>
<AgentRuntimeProvider>
<PrivyGateBanner />
Expand Down
24 changes: 24 additions & 0 deletions typescript/clients/web-ag-ui/apps/web/src/app/layout.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import fs from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest';

const layoutPath = path.resolve(process.cwd(), 'src/app/layout.tsx');

describe('RootLayout font wiring', () => {
it('imports Roboto and Roboto Mono from next/font/google', () => {
const source = fs.readFileSync(layoutPath, 'utf8');

expect(source).toContain("from 'next/font/google'");
expect(source).toContain('Roboto');
expect(source).toContain('Roboto_Mono');
});

it('wires Roboto variables into body className', () => {
const source = fs.readFileSync(layoutPath, 'utf8');

expect(source).toContain("variable: '--font-roboto'");
expect(source).toContain("variable: '--font-roboto-mono'");
expect(source).toContain('roboto.variable');
expect(source).toContain('robotoMono.variable');
});
});
Loading