Files
DemonGatanjieu-Anomalous_Mo…/web/styles/37-ai-workbench.css
T
DemonGatanjieuandClaude Opus 5.5 e36d898fb9 A waiting task's page has one thing to do
It said "waiting for an AI" three times and kept two folds that did what
the message box does. Now it is the sentence and its Copy button, in the
middle of the column; what to say first and pictures go in the message
box, whose words say so. The connect card comes first until an AI has ever
come, and is gone after that. The wish line, the big gallery fold and
what only they used go with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 00:01:47 +08:00

1087 lines
32 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* The AI workbench (ui_ai_workbench.js): the tasks, one task's timeline, the home list, the rail's dot. */
#anomalous-ai-panel {
flex: 1;
flex-direction: column;
min-height: 0;
overflow: hidden;
}
.anomalous-ai {
--ai-canvas: var(--amb-link);
--ai-run: var(--amb-ok);
--ai-speech: #e879a6;
--ai-download: var(--amb-link);
--ai-scan: var(--amb-warn);
--ai-note: var(--amb-text-soft);
--ai-look: var(--amb-text-dim);
position: relative; /* the compare bar (41-ai-results.css) sits at its foot */
display: grid;
grid-template-columns: minmax(200px, 250px) minmax(0, 1fr);
flex: 1;
min-height: 0;
height: 100%;
}
/* ---------- the tasks ---------- */
.anomalous-ai-tasks {
display: flex;
flex-direction: column;
min-height: 0;
border-right: 1px solid var(--amb-border);
}
.anomalous-ai-tasks-head {
display: flex;
align-items: center;
gap: 8px;
padding: 16px 14px 10px;
}
.anomalous-ai-tasks-title {
color: var(--amb-text-main);
font-size: 14px;
font-weight: 700;
}
.anomalous-ai-tasks-count {
flex: 1;
color: var(--amb-text-dim);
font-size: 11.5px;
}
.anomalous-ai-tasks-list {
display: flex;
flex-direction: column;
gap: 3px;
padding: 0 8px 12px;
overflow-y: auto;
}
.anomalous-ai-task-row {
position: relative;
display: flex;
flex-direction: column;
gap: 4px;
padding: 10px 12px;
border: 1px solid transparent;
border-radius: 12px;
background: none;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
.anomalous-ai-task-row:hover {
background: rgba(var(--amb-ink-rgb), 0.05);
}
.anomalous-ai-task-row.is-current {
border-color: color-mix(in srgb, var(--amb-link) 45%, transparent);
background: color-mix(in srgb, var(--amb-link) 12%, transparent);
}
.anomalous-ai-task-row.is-current::before {
position: absolute;
top: 12px;
bottom: 12px;
left: -1px;
width: 3px;
border-radius: 0 3px 3px 0;
background: var(--amb-link);
content: "";
}
/* Quick filters over the list: working, asking you, failed. */
.anomalous-ai-task-filters {
display: flex;
flex-wrap: wrap;
gap: 5px;
padding: 2px 14px 8px;
}
.anomalous-ai-task-filter {
display: inline-flex;
align-items: center;
gap: 5px;
height: 24px;
padding: 0 9px;
border: 1px solid var(--amb-border);
border-radius: 999px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 11.5px;
cursor: pointer;
}
.anomalous-ai-task-filter:hover { color: var(--amb-text-main); background: rgba(var(--amb-ink-rgb), 0.05); }
.anomalous-ai-task-filter.is-on { border-color: var(--amb-link); background: color-mix(in srgb, var(--amb-link) 16%, transparent); color: var(--amb-text-main); }
.anomalous-ai-task-filter.is-asks .anomalous-ai-task-filter-count { color: var(--amb-warn-text); }
.anomalous-ai-task-filter.is-error .anomalous-ai-task-filter-count { color: var(--amb-danger-text); }
.anomalous-ai-task-filter-count { color: var(--amb-text-dim); font-variant-numeric: tabular-nums; }
.anomalous-ai-task-row-top {
display: flex;
align-items: center;
gap: 6px;
}
.anomalous-ai-tasks-day {
padding: 10px 10px 3px;
color: var(--amb-text-dim);
font-size: 11px;
font-weight: 600;
}
/* Where a task stands: working, waiting for you, a step failed, done. */
.anomalous-ai-state-icon {
display: inline-flex;
flex: none;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border-radius: 50%;
background: rgba(var(--amb-ink-rgb), 0.08);
color: var(--amb-text-dim);
}
.anomalous-ai-state-icon.is-live {
background: color-mix(in srgb, var(--amb-ok) 20%, transparent);
color: var(--amb-ok-text);
}
.anomalous-ai-state-icon.is-asks {
background: color-mix(in srgb, var(--amb-warn) 24%, transparent);
color: var(--amb-warn-text);
}
.anomalous-ai-state-icon.is-error {
background: color-mix(in srgb, var(--amb-danger) 20%, transparent);
color: var(--amb-danger-text);
}
.anomalous-ai-task-row-title {
flex: 1;
overflow: hidden;
color: var(--amb-text-main);
font-size: 13px;
text-overflow: ellipsis;
white-space: nowrap;
}
.anomalous-ai-task-row-meta,
.anomalous-ai-task-row-counts {
overflow: hidden;
color: var(--amb-text-dim);
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.anomalous-ai-task-row-counts {
color: var(--amb-text-soft);
}
.anomalous-ai-live-dot {
width: 7px;
height: 7px;
flex: none;
border-radius: 50%;
background: var(--amb-ok);
box-shadow: 0 0 0 0 color-mix(in srgb, var(--amb-ok) 60%, transparent);
animation: anomalous-ai-pulse 1.6s ease-out infinite;
}
@keyframes anomalous-ai-pulse {
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--amb-ok) 55%, transparent); }
70% { box-shadow: 0 0 0 7px transparent; }
100% { box-shadow: 0 0 0 0 transparent; }
}
/* ---------- one task ---------- */
/* A wide column keeps the task to about 880 px, in its middle, as chat apps do (the scrollbar stays
at the column's edge). */
.anomalous-ai-task {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
padding: 24px max(28px, calc((100% - 880px) / 2)) 28px;
overflow-y: auto;
}
.anomalous-ai-task > * { flex-shrink: 0; }
/* The message box's dock: at the foot of the column however short the timeline, and in view while
it scrolls (the column's bottom padding is its own), the timeline fading out behind it. */
.anomalous-ai-dock {
position: sticky;
bottom: -28px;
z-index: 3;
margin: auto 0 -28px;
padding: 16px 0 28px;
background: linear-gradient(to bottom, transparent, var(--amb-bg-page) 16px);
}
.anomalous-ai-task-head {
position: sticky;
top: -24px; /* stays on top while the timeline scrolls (the column's own top padding) */
z-index: 2;
background: var(--amb-bg-page); /* the window's own, so the header is no band of its own */
display: flex;
flex-direction: column;
gap: 4px;
padding: 24px 0 12px;
border-bottom: 1px solid var(--amb-border);
margin: -24px 0 16px;
}
/* Two lines however wide: the name and the tools; what it is and what it goes on from. */
.anomalous-ai-task-title-line {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px 12px;
}
.anomalous-ai-task-name {
display: flex;
flex: 1 1 14em;
align-items: center;
gap: 10px;
min-width: 0;
}
.anomalous-ai-task-title {
min-width: 0;
margin: 0;
overflow: hidden;
color: var(--amb-text-main);
font-size: 17px;
font-weight: 600;
text-overflow: ellipsis;
white-space: nowrap;
}
.anomalous-ai-task-sub {
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
}
.anomalous-ai-task-sub .anomalous-ai-task-links { flex: 0 1 auto; flex-wrap: nowrap; min-width: 0; }
/* The side column open: what the words of the state and the way to the copy say is in their icons and tooltips. */
.anomalous-ai-task-head.is-tight .anomalous-ai-state { padding: 2px; }
.anomalous-ai-task-head.is-tight .anomalous-ai-state > span:not(.anomalous-ai-state-icon),
.anomalous-ai-task-head.is-tight .anomalous-ai-canvas-tab-name,
.anomalous-ai-dock.is-tight .anomalous-ai-call-lead { display: none; }
.anomalous-ai-back {
display: none;
padding: 3px 8px;
border: 1px solid var(--amb-border);
border-radius: 6px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 12px;
cursor: pointer;
}
.anomalous-ai-state {
display: inline-flex;
flex: none;
align-items: center;
gap: 5px;
padding: 2px 10px 2px 3px;
border-radius: 999px;
background: rgba(var(--amb-ink-rgb), 0.07);
color: var(--amb-text-soft);
font-size: 11px;
}
.anomalous-ai-state.is-live {
background: color-mix(in srgb, var(--amb-ok) 18%, transparent);
color: var(--amb-ok-text);
}
.anomalous-ai-state.is-error {
background: color-mix(in srgb, var(--amb-danger) 16%, transparent);
color: var(--amb-danger-text);
}
.anomalous-ai-state .anomalous-ai-state-icon { width: 18px; height: 18px; background: none; color: inherit; }
/* A task's tools: how its run goes, its canvas, Undo all, then ⋯ for the rest (ui_ai_task_menu.js). */
.anomalous-ai-task-tools {
position: relative; /* the list of tasks to go on from (47-ai-decisions.css) opens under the ⋯ */
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
margin-left: auto;
}
.anomalous-ai-tool {
display: inline-flex;
align-items: center;
gap: 6px;
height: 30px;
padding: 0 11px;
border: 1px solid var(--amb-border);
border-radius: 9px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 12.5px;
cursor: pointer;
transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.anomalous-ai-tool:hover { border-color: var(--amb-border-strong); background: rgba(var(--amb-ink-rgb), 0.06); color: var(--amb-text-main); }
.anomalous-ai-tool.is-icon { width: 30px; padding: 0; justify-content: center; }
.anomalous-ai-privacy.is-on { border-color: color-mix(in srgb, var(--amb-warn) 55%, transparent); color: var(--amb-warn); background: color-mix(in srgb, var(--amb-warn) 10%, transparent); }
/* Where the AI works on the canvas (ui_ai_task_canvas.js): a copy or the open canvas, the list to pick from, and the copy's tab. */
.anomalous-ai-canvas { position: relative; display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.anomalous-ai-canvas-mode[aria-expanded="true"] { border-color: var(--amb-link); background: color-mix(in srgb, var(--amb-link) 12%, transparent); }
.anomalous-ai-canvas-menu {
position: absolute;
z-index: 8;
top: calc(100% + 4px);
right: 0;
display: flex;
flex-direction: column;
gap: 2px;
width: min(320px, 86vw);
padding: 6px;
border: 1px solid var(--amb-border-strong, var(--amb-border));
border-radius: 10px;
background: var(--amb-bg-panel);
box-shadow: 0 14px 40px rgba(0, 0, 0, 0.4);
}
.anomalous-ai-canvas-choice {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 8px 10px;
border: 0;
border-radius: 8px;
background: none;
color: var(--amb-text-soft);
font: inherit;
text-align: left;
cursor: pointer;
}
.anomalous-ai-canvas-choice > .anomalous-tb-icon { flex: none; margin-top: 1px; color: var(--amb-link); }
.anomalous-ai-canvas-choice:hover, .anomalous-ai-canvas-choice:focus-visible { background: rgba(var(--amb-ink-rgb), 0.08); color: var(--amb-text-main); outline: 0; }
.anomalous-ai-canvas-choice.is-on { background: color-mix(in srgb, var(--amb-link) 14%, transparent); color: var(--amb-text-main); }
.anomalous-ai-canvas-choice-words { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.anomalous-ai-canvas-choice-name { font-size: 13px; font-weight: 600; }
.anomalous-ai-canvas-choice-why { color: var(--amb-text-dim); font-size: 12px; line-height: 1.5; }
.anomalous-ai-canvas-mode.is-new { border-color: color-mix(in srgb, var(--amb-link) 45%, transparent); color: var(--amb-link); }
.anomalous-ai-canvas-tab {
display: inline-flex;
align-items: center;
gap: 5px;
max-width: 160px;
height: 30px;
padding: 0 10px;
border: 1px dashed color-mix(in srgb, var(--amb-link) 50%, transparent);
border-radius: 9px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 12px;
cursor: pointer;
}
.anomalous-ai-canvas-tab:hover { background: color-mix(in srgb, var(--amb-link) 12%, transparent); color: var(--amb-text-main); }
.anomalous-ai-canvas-tab-name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.anomalous-ai-task-meta {
flex: 0 1 auto;
min-width: 6em;
overflow: hidden;
color: var(--amb-text-dim);
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
}
/* The line over the timeline: the stages it went through, and what it made. */
.anomalous-ai-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 0 16px; }
.anomalous-ai-summary > :not(:empty) { margin-bottom: 14px; }
.anomalous-ai-made-holder { margin-left: auto; }
.anomalous-ai.uses-tabs .anomalous-ai-made-holder { margin-left: 0; }
/* The AI app calls by an older tool list: how to have it fetch the new one. */
.anomalous-ai-task-stale {
margin-top: 6px;
padding: 6px 10px;
border: 1px solid color-mix(in srgb, var(--amb-warn) 45%, transparent);
border-radius: 8px;
background: color-mix(in srgb, var(--amb-warn) 12%, transparent);
color: var(--amb-warn-text);
font-size: 12.5px;
line-height: 1.5;
}
/* A way somewhere or something to do under a step: a small button that looks pressable, its icon in the link colour. */
.anomalous-ai-link {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 3px 10px;
border: 1px solid var(--amb-border);
border-radius: 999px;
background: color-mix(in srgb, var(--amb-link) 6%, transparent);
color: var(--amb-text-main);
font: inherit;
font-size: 12px;
line-height: 1.35;
cursor: pointer;
transition: background 0.15s, border-color 0.15s;
}
.anomalous-ai-link:hover,
.anomalous-ai-link:focus-visible {
border-color: color-mix(in srgb, var(--amb-link) 55%, transparent);
background: color-mix(in srgb, var(--amb-link) 16%, transparent);
}
.anomalous-ai-link .anomalous-tb-icon { display: inline-flex; color: var(--amb-link); }
.anomalous-ai-link.is-danger {
color: var(--amb-danger-text);
}
.anomalous-ai-link-done,
.anomalous-ai-link-note {
color: var(--amb-text-dim);
font-size: 12px;
}
/* ---------- the timeline ---------- */
.anomalous-ai-timeline {
position: relative;
display: flex;
flex-direction: column;
}
.anomalous-ai-timeline.is-waiting::before { display: none; }
.anomalous-ai-timeline::before {
content: '';
position: absolute;
top: 14px;
bottom: 14px;
left: 11px;
width: 2px;
border-radius: 1px;
background: var(--amb-border);
}
.anomalous-ai-step {
--kind: var(--ai-look);
position: relative;
display: grid;
grid-template-columns: 24px minmax(0, 1fr) auto;
gap: 12px;
padding: 13px 0;
}
.anomalous-ai-step.is-canvas { --kind: var(--ai-canvas); }
.anomalous-ai-step.is-run { --kind: var(--ai-run); }
.anomalous-ai-step.is-speech { --kind: var(--ai-speech); }
.anomalous-ai-step.is-download { --kind: var(--ai-download); }
.anomalous-ai-step.is-show { --kind: var(--ai-download); }
.anomalous-ai-step.is-scan { --kind: var(--ai-scan); }
.anomalous-ai-step.is-note { --kind: var(--ai-note); }
.anomalous-ai-step.is-act { --kind: var(--amb-text-soft); }
.anomalous-ai-step.is-outside { --kind: var(--amb-warn); }
.anomalous-ai-step.is-skill { --kind: var(--amb-accent); }
/* What happened outside Anomalous (ui_ai_step_body.js): the pictures changed, or the AI's own word. */
.anomalous-ai-outside-list { margin: 4px 0 0; padding-left: 18px; color: var(--amb-text-main); font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
.anomalous-ai-outside-who { margin-top: 6px; color: var(--amb-text-dim); font-size: 12px; }
.anomalous-ai-skill-used { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 4px; color: var(--amb-text-soft); font-size: 13px; line-height: 1.5; }
.anomalous-ai-skill-used strong { color: var(--amb-text-main); font-weight: 600; }
.anomalous-ai-outside-log { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 12px; margin: 4px 0 0; font-size: 13px; line-height: 1.5; }
.anomalous-ai-outside-log dt { color: var(--amb-text-dim); }
.anomalous-ai-outside-log dd { margin: 0; color: var(--amb-text-main); white-space: pre-wrap; overflow-wrap: anywhere; }
.anomalous-ai-step.is-failed { --kind: var(--amb-danger); }
.anomalous-ai-step.is-user { --kind: var(--amb-link); }
/* What the user wrote to the AI, and under the timeline where they write. */
.anomalous-ai-user-text {
align-self: flex-start;
max-width: 90%;
padding: 8px 12px;
border-radius: 12px 12px 12px 4px;
background: color-mix(in srgb, var(--amb-link) 16%, transparent);
color: var(--amb-text-main);
font-size: 13px;
line-height: 1.6;
white-space: pre-wrap;
}
.anomalous-ai-message-hint {
color: var(--amb-text-dim);
font-size: 11.5px;
}
.anomalous-ai-message {
display: flex;
flex-direction: column;
gap: 8px;
padding: 10px 12px;
border: 1px solid var(--amb-border-strong, var(--amb-border));
border-radius: 14px;
background: color-mix(in srgb, var(--amb-bg-page), rgb(var(--amb-ink-rgb)) 4%);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.anomalous-ai-message:focus-within { border-color: color-mix(in srgb, var(--amb-link) 55%, transparent); }
.anomalous-ai-message[hidden] { display: none; }
.anomalous-ai-message.is-quiet {
opacity: 0.8;
}
.anomalous-ai-message-line {
display: flex;
align-items: flex-end;
gap: 8px;
}
.anomalous-ai-message-input {
flex: 1;
min-width: 0;
height: 38px;
max-height: 168px;
box-sizing: border-box;
padding: 9px 12px;
border: 1px solid var(--amb-border);
border-radius: 9px;
background: var(--amb-lt-sunken, rgba(0, 0, 0, 0.25));
color: var(--amb-text-main);
font: inherit;
font-size: 13px;
line-height: 1.45;
resize: none;
}
/* One line however narrow the box: the words that do not fit end in … instead of being cut in half. */
.anomalous-ai-message-input::placeholder { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.anomalous-ai-message-input:focus {
border-color: color-mix(in srgb, var(--amb-link) 60%, transparent);
outline: none;
}
.anomalous-ai-message-line .anomalous-ai-panel-send { align-self: flex-end; height: 38px; }
/* The step's number in a dot of its kind's colour; the line through the dots is the order. */
.anomalous-ai-step-dot {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
margin-top: -3px;
box-sizing: border-box;
border-radius: 50%;
background: var(--amb-bg-panel, #16161a);
border: 1px solid color-mix(in srgb, var(--kind) 60%, var(--amb-border));
color: var(--amb-text-main);
font-size: 11px;
font-weight: 700;
box-shadow: 0 0 0 3px var(--amb-bg-panel, #16161a);
}
.anomalous-ai-step.is-folded .anomalous-ai-step-dot {
border: 1.5px solid var(--kind);
background: var(--amb-bg-panel, #16161a);
color: var(--amb-text-soft);
}
.anomalous-ai-step-body {
display: flex;
flex-direction: column;
gap: 6px;
min-width: 0;
}
.anomalous-ai-step-line {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 4px 8px;
min-width: 0;
color: var(--amb-text-main);
font-size: 13px;
}
.anomalous-ai-kind {
padding: 1px 8px;
border-radius: 999px;
background: color-mix(in srgb, var(--kind) 18%, transparent);
color: var(--amb-text-main);
font-size: 11px;
}
.anomalous-ai-step-title {
font-weight: 600;
}
.anomalous-ai-step-detail {
overflow: hidden;
max-width: 100%;
color: var(--amb-text-soft);
text-overflow: ellipsis;
white-space: nowrap;
}
.anomalous-ai-step-when {
display: flex;
flex-direction: column;
align-items: flex-end;
color: var(--amb-text-dim);
font-size: 11px;
white-space: nowrap;
}
.anomalous-ai-note-text {
padding: 8px 12px;
border-left: 3px solid var(--ai-note);
border-radius: 0 10px 10px 0;
background: color-mix(in srgb, var(--ai-note) 9%, transparent);
color: var(--amb-text-main);
font-size: 13px;
line-height: 1.65;
}
/* The AI's notes laid out (ai_text_format.js): headings, lists, bold, code. */
.anomalous-ai-note-text > :first-child { margin-top: 0; }
.anomalous-ai-note-text > :last-child { margin-bottom: 0; }
.anomalous-ai-note-text p { margin: 0 0 8px; white-space: pre-wrap; }
.anomalous-ai-note-text h4 { margin: 12px 0 6px; font-size: 14px; font-weight: 700; }
.anomalous-ai-note-text ul, .anomalous-ai-note-text ol { margin: 0 0 8px; padding-left: 20px; }
.anomalous-ai-note-text li { margin: 3px 0; }
.anomalous-ai-note-text li::marker { color: var(--ai-note); }
.anomalous-ai-note-text strong { color: var(--amb-text-main); font-weight: 700; }
.anomalous-ai-note-text code {
padding: 1px 6px;
border-radius: 5px;
background: rgba(var(--amb-ink-rgb), 0.1);
color: color-mix(in srgb, var(--ai-note) 70%, var(--amb-text-main));
font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.anomalous-ai-note-text hr { margin: 10px 0; border: 0; border-top: 1px solid var(--amb-border); }
/* A reply and what it answers point at each other. */
.anomalous-ai-reply-link {
display: inline-flex;
align-self: flex-start;
align-items: center;
gap: 5px;
margin-top: 6px;
padding: 2px 9px;
border: 1px solid var(--amb-border);
border-radius: 999px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 11.5px;
cursor: pointer;
}
.anomalous-ai-reply-link:hover { border-color: var(--amb-link); color: var(--amb-text-main); }
.anomalous-ai-reply-link.is-replied { border-color: color-mix(in srgb, var(--amb-ok) 55%, transparent); color: var(--amb-ok-text); }
.anomalous-ai-step-cancelled {
align-self: flex-start;
margin-top: 6px;
padding: 2px 10px;
border-radius: 999px;
background: rgba(var(--amb-ink-rgb), 0.08);
color: var(--amb-text-soft);
font-size: 12px;
}
/* An AI's step that did not go is an everyday thing, it tries another way: a mark, not a wall of red. */
.anomalous-ai-step-error {
padding-left: 8px;
border-left: 2px solid color-mix(in srgb, var(--amb-danger) 70%, transparent);
color: var(--amb-text-soft);
font-size: 12px;
}
.anomalous-ai-step-running {
color: var(--amb-ok-text);
font-size: 12.5px;
}
@keyframes anomalous-ai-breathe {
50% { opacity: 0.45; }
}
.anomalous-ai-looks {
display: inline-flex;
align-items: center;
gap: 6px;
margin: -3px -8px;
padding: 3px 8px;
border: none;
border-radius: 7px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 12.5px;
text-align: left;
cursor: pointer;
}
/* A chevron says it opens; it turns while open. */
.anomalous-ai-looks::after { content: "›"; font-size: 15px; line-height: 1; transition: transform 0.15s; }
.anomalous-ai-looks[aria-expanded="true"]::after { transform: rotate(90deg); }
.anomalous-ai-looks:hover {
background: color-mix(in srgb, var(--amb-link) 14%, transparent);
color: var(--amb-text-main);
}
.anomalous-ai-looks-details {
display: flex;
flex-direction: column;
gap: 2px;
}
.anomalous-ai-looks-details[hidden] {
display: none;
}
.anomalous-ai-look {
overflow: hidden;
color: var(--amb-text-dim);
font-size: 11.5px;
text-overflow: ellipsis;
white-space: nowrap;
}
/* The AI's work in a row folded into one (ui_ai_chain.js): what it did as chips; open, its steps in a column of their own. */
.anomalous-ai-step.is-chain { --kind: var(--ai-canvas); }
.anomalous-ai-chain-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.anomalous-ai-chain-title { color: var(--amb-text-main); font-weight: 650; }
.anomalous-ai-chain-last { color: var(--amb-text-dim); font-size: 12px; }
.anomalous-ai-chain-undo {
display: inline-flex;
align-items: center;
gap: 5px;
margin-left: auto;
padding: 2px 9px;
border: 1px solid var(--amb-border);
border-radius: 999px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 12px;
cursor: pointer;
}
.anomalous-ai-chain-undo:hover { border-color: var(--amb-border-strong); color: var(--amb-text-main); }
.anomalous-ai-chain-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.anomalous-ai-chain-chip {
--chip: var(--ai-look);
padding: 1px 8px;
border: 1px solid color-mix(in srgb, var(--chip) 40%, var(--amb-border));
border-radius: 999px;
background: color-mix(in srgb, var(--chip) 10%, transparent);
color: var(--amb-text-soft);
font-size: 11.5px;
}
.anomalous-ai-chain-chip.is-canvas { --chip: var(--ai-canvas); }
.anomalous-ai-chain-chip.is-decision { --chip: #e0a63c; }
.anomalous-ai-chain-steps { display: flex; flex-direction: column; margin-top: 4px; padding-left: 12px; border-left: 2px solid var(--amb-border); }
.anomalous-ai-chain-steps[hidden] { display: none; }
.anomalous-ai-chain-steps .anomalous-ai-step { grid-template-columns: 20px minmax(0, 1fr) auto; gap: 10px; padding: 8px 0; }
.anomalous-ai-chain-steps .anomalous-ai-step-dot { width: 20px; height: 20px; margin-top: -2px; font-size: 10px; box-shadow: none; }
.anomalous-ai-results {
display: flex;
flex-direction: column;
gap: 6px;
}
.anomalous-ai-links {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px 8px;
}
.anomalous-ai-chip {
display: inline-flex;
align-items: center;
gap: 6px;
max-width: 260px;
padding: 3px 10px;
overflow: hidden;
border: 1px solid var(--amb-border);
border-radius: 999px;
background: rgba(var(--amb-ink-rgb), 0.04);
color: var(--amb-text-main);
font: inherit;
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.anomalous-ai-chip:hover:not(:disabled) {
border-color: var(--amb-border-strong);
}
.anomalous-ai-chip.is-model { border-color: color-mix(in srgb, var(--ai-canvas) 40%, transparent); }
.anomalous-ai-chip.is-combo { border-color: color-mix(in srgb, var(--ai-run) 40%, transparent); }
.anomalous-ai-chip.is-audio { border-color: color-mix(in srgb, var(--ai-speech) 40%, transparent); cursor: default; }
.anomalous-ai-play {
padding: 0;
border: none;
background: none;
color: var(--amb-text-main);
font-size: 11px;
cursor: pointer;
}
.anomalous-ai-empty-task {
padding: 24px 0;
color: var(--amb-text-dim);
font-size: 13px;
}
/* ---------- no task yet ---------- */
.anomalous-ai.is-empty {
display: flex;
align-items: center;
justify-content: center;
overflow-y: auto;
}
.anomalous-ai-welcome {
display: flex;
flex-direction: column;
align-items: center;
max-width: 560px;
padding: 32px 24px;
text-align: center;
}
.anomalous-ai-welcome-art { width: 200px; height: 200px; object-fit: contain; }
.anomalous-ai-welcome > .anomalous-ai-new-task { margin-bottom: 22px; }
.anomalous-ai-welcome-title {
margin: 0 0 8px;
color: var(--amb-text-main);
font-size: 18px;
}
.anomalous-ai-welcome-body,
.anomalous-ai-welcome-hint {
margin: 0 0 14px;
color: var(--amb-text-soft);
font-size: 13px;
line-height: 1.7;
}
.anomalous-ai-welcome-hint {
color: var(--amb-text-dim);
font-size: 12px;
}
.anomalous-ai-address {
display: inline-flex;
align-items: center;
gap: 12px;
margin-bottom: 14px;
padding: 8px 12px;
border: 1px solid var(--amb-border);
border-radius: 8px;
background: rgba(var(--amb-ink-rgb), 0.05);
}
.anomalous-ai-address code {
color: var(--amb-text-main);
font-size: 12.5px;
}
/* ---------- narrow: the list and the task take turns ---------- */
.anomalous-ai.is-narrow {
grid-template-columns: minmax(0, 1fr);
}
/* Narrow: the tasks are a drawer over the task shown, which shows beside it: the list reads as the
records of conversations, and a click on what shows goes back to it. With no task it fills the page. */
.anomalous-ai.is-narrow .anomalous-ai-tasks {
position: absolute;
top: 0;
bottom: 0;
left: 0;
z-index: 6;
width: 100%;
background: var(--amb-bg-page);
border-right: none;
transition: transform 0.2s ease, visibility 0.2s;
}
.anomalous-ai.is-narrow.peeks .anomalous-ai-tasks {
width: min(72%, 440px);
border-right: 1px solid var(--amb-border);
box-shadow: 10px 0 28px rgba(0, 0, 0, 0.4);
}
.anomalous-ai.is-narrow.shows-task .anomalous-ai-tasks {
visibility: hidden;
transform: translateX(-102%);
}
.anomalous-ai-scrim { display: none; }
.anomalous-ai.is-narrow.peeks .anomalous-ai-scrim {
position: absolute;
inset: 0;
z-index: 5;
display: block;
border: 0;
background: rgba(0, 0, 0, 0.45);
cursor: pointer;
}
.anomalous-ai.is-narrow:not(.shows-task, .peeks) .anomalous-ai-task { display: none; }
.anomalous-ai.is-narrow .anomalous-ai-back { display: inline-block; }
.anomalous-ai.is-narrow .anomalous-ai-task {
padding: 14px 16px 24px;
}
/* The foot of the column follows its padding, or the timeline shows under the message box. */
.anomalous-ai.is-narrow .anomalous-ai-dock { bottom: -24px; margin-bottom: -24px; padding-bottom: 24px; }
/* ---------- home: what the AI did lately ---------- */
.anomalous-ai-recent-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.anomalous-ai-recent-row {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 8px;
border: none;
border-radius: 8px;
background: none;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
.anomalous-ai-recent-row:hover {
background: rgba(var(--amb-ink-rgb), 0.05);
}
.anomalous-ai-recent-cover {
width: 36px;
height: 36px;
flex: none;
border-radius: 6px;
object-fit: cover;
}
.anomalous-ai-recent-text {
display: flex;
flex-direction: column;
min-width: 0;
}
.anomalous-ai-recent-title {
overflow: hidden;
color: var(--amb-text-main);
font-size: 13px;
text-overflow: ellipsis;
white-space: nowrap;
}
.anomalous-ai-recent-meta {
color: var(--amb-text-dim);
font-size: 11px;
}
/* ---------- the rail's dot when the AI did something ---------- */
.anomalous-rail-item.has-news {
position: relative;
}
.anomalous-rail-item.has-news::after {
content: '';
position: absolute;
top: 6px;
right: 11px;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--amb-ok);
box-shadow: 0 0 0 2px var(--amb-bg-panel, #16161a);
}
/* A long note of the AI's, folded to its first lines (ui_ai_step_body.js). */
.anomalous-ai-fold { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.anomalous-ai-fold > :first-child { max-width: 100%; }
.anomalous-ai-fold.is-folded > :first-child { max-height: 10.5em; overflow: hidden; -webkit-mask-image: linear-gradient(black 55%, transparent); mask-image: linear-gradient(black 55%, transparent); }
.anomalous-ai-fold-toggle { padding: 2px 0; border: 0; background: none; color: var(--amb-link); font: inherit; font-size: 12px; cursor: pointer; }
.anomalous-ai-fold-toggle:hover { text-decoration: underline; }
/* A short window (ui_ai_workbench.js layout: the page under SHORT_PX, not maximised): less room
around the task's head, the message box's hint only for a failure (its words are the input's
tooltip), a waiting task's picture smaller and nearer the top. */
.anomalous-ai.is-short .anomalous-ai-task { padding-top: 12px; }
.anomalous-ai.is-short .anomalous-ai-task-head {
top: -12px;
margin: -12px 0 12px;
padding: 12px 0 10px;
}
.anomalous-ai.is-short .anomalous-ai-task-title { font-size: 16px; }
.anomalous-ai.is-short .anomalous-ai-task-meta { font-size: 11.5px; }
.anomalous-ai.is-short .anomalous-ai-dock { padding-top: 10px; }
.anomalous-ai.is-short .anomalous-ai-message-hint:not(.is-error) { display: none; }
.anomalous-ai.is-short .anomalous-ai-waiting { margin-top: 8px; }
.anomalous-ai.is-short .anomalous-ai-waiting-art { width: 72px; height: 72px; }
/* The user's word on a finished run (ui_ai_verdict.js), under its pictures. */
.anomalous-ai-verdict { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.anomalous-ai-verdict-ask { color: var(--amb-text-soft); font-size: 12.5px; }
.anomalous-ai-verdict-pick {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 9px;
border: 1px solid var(--amb-border-strong);
border-radius: 6px;
background: none;
color: var(--amb-text-soft);
font: inherit;
font-size: 12.5px;
cursor: pointer;
}
.anomalous-ai-verdict-pick:hover { color: var(--amb-text-main); }
.anomalous-ai-verdict-pick:disabled { cursor: progress; opacity: 0.7; }
.anomalous-ai-verdict-pick.is-good.is-chosen { border-color: var(--amb-ok); background: color-mix(in srgb, var(--amb-ok) 16%, transparent); color: var(--amb-text-main); }
.anomalous-ai-verdict-pick.is-bad.is-chosen { border-color: var(--amb-warn); background: color-mix(in srgb, var(--amb-warn) 16%, transparent); color: var(--amb-text-main); }