- crimata-agent (TypeScript, port 7702): WebSocket server + HTTP /events
endpoint, Claude tool-use loop (render/remove/call_api/show_cursor_response),
session.start fires on first browser connection to seed the canvas
- OS UI redesigned: light grey canvas (#e8e8e8), no dock bar, cursor dot,
Cmd+Space input bubble above cursor, elements placed by agent
- Canvas elements: app_icon (floating icons with running dot), window (no-chrome
content cards), cursor_response (text + action pills)
- Component system: HTML fragments fetched from /components/{app}/{name}.html,
inline scripts re-executed after injection
- contacts/crimata.json: added icon, defaultComponent, components[], api[]
- dock: apps.h/c/main.c extended to parse and serve components + api from
crimata.json; BUF_SIZE increased for richer JSON output
- ui/components/contacts/list.html + card.html: first component pair
- provision.sh: installs crimata-agent, adds WebSocket + /events + /components
nginx locations, fixes /auth/ prefix stripping
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
113 lines
2.4 KiB
CSS
113 lines
2.4 KiB
CSS
/* ── App icons ────────────────────────────────────────────────────────────── */
|
|
|
|
.canvas-element.app-icon {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 6px;
|
|
width: 72px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.app-icon .icon-glyph {
|
|
width: 56px;
|
|
height: 56px;
|
|
background: white;
|
|
border-radius: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 26px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
|
|
transition: transform 0.12s ease, box-shadow 0.12s ease;
|
|
}
|
|
|
|
.app-icon:hover .icon-glyph {
|
|
transform: scale(1.08);
|
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
|
|
}
|
|
|
|
.app-icon .icon-label {
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
color: #444;
|
|
background: rgba(255, 255, 255, 0.72);
|
|
padding: 2px 8px;
|
|
border-radius: 10px;
|
|
backdrop-filter: blur(6px);
|
|
white-space: nowrap;
|
|
max-width: 88px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.app-icon .icon-dot {
|
|
width: 5px;
|
|
height: 5px;
|
|
background: #34c759;
|
|
border-radius: 50%;
|
|
margin-top: -3px;
|
|
}
|
|
|
|
/* ── Windows — no chrome, just content cards ──────────────────────────────── */
|
|
|
|
.canvas-element.window {
|
|
background: white;
|
|
border-radius: 16px;
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
|
overflow: hidden;
|
|
min-width: 320px;
|
|
min-height: 240px;
|
|
}
|
|
|
|
.window .window-content {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: auto;
|
|
}
|
|
|
|
.window .loading {
|
|
padding: 24px;
|
|
color: #aaa;
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* ── Cursor response bubble ───────────────────────────────────────────────── */
|
|
|
|
.canvas-element.cursor-response {
|
|
background: white;
|
|
border-radius: 14px;
|
|
padding: 12px 16px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
|
|
max-width: 320px;
|
|
font-size: 14px;
|
|
color: #333;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.cursor-response p {
|
|
margin: 0;
|
|
}
|
|
|
|
.response-pills {
|
|
display: flex;
|
|
gap: 6px;
|
|
flex-wrap: wrap;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.response-pills button {
|
|
background: #f0f0f0;
|
|
border: none;
|
|
border-radius: 20px;
|
|
padding: 5px 14px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
color: #333;
|
|
cursor: pointer;
|
|
transition: background 0.12s;
|
|
}
|
|
|
|
.response-pills button:hover {
|
|
background: #e0e0e0;
|
|
}
|