humainflow-web/src/styles.css

565 lines
13 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.

/* You can add global styles to this file, and also import other style files */
@import '@fontsource/material-icons-outlined';
@import '@angular/material/prebuilt-themes/azure-blue.css';
@import 'tailwindcss';
@theme {
/* ────────────────────────────────────────────────────────────────
* Design Tokens
* ────────────────────────────────────────────────────────────────
* Primary palette: blue scale (Tailwind Blue)
* 50–950 shades used for buttons, links, focus rings, and accents.
* 600 = default action colour | 700 = hover | 300 = focus ring (dark)
*
* Fonts: Inter as the single sans-serif family for body & headings.
*
* Dark mode: toggled via .dark class on <html> or <body>.
* ──────────────────────────────────────────────────────────────── */
/* Dark mode */
--dark-mode-selector: .dark;
/* Primary colour scale (blue) — used by .button, .link, focus rings */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-200: #bfdbfe;
--color-primary-300: #93c5fd;
--color-primary-400: #60a5fa;
--color-primary-500: #3b82f6;
--color-primary-600: #2563eb; /* default action */
--color-primary-700: #1d4ed8; /* hover */
--color-primary-800: #1e40af;
--color-primary-900: #1e3a8a;
--color-primary-950: #172554;
/* Font families — single stack for body & UI */
--font-body: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
--font-sans: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
}
/* ── Design tokens (dialogs & modals) ─────────────────────────────
* Shared across modal-shell and (progressively) the other dialog
* components, so a single value change stays consistent everywhere
* instead of being copied per-component.
* ─────────────────────────────────────────────────────────────── */
:root {
--radius-modal: 1rem;
--shadow-modal: 0 25px 50px rgb(15 23 42 / 25%);
--color-surface: #ffffff;
--color-border: #cbd5e1;
--color-divider: #e2e8f0;
--color-text-body: #0f172a;
--color-text-muted: #64748b;
--color-accent: #2563eb;
--color-danger: #dc2626;
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--z-modal-backdrop: 10020;
--z-modal: 10021;
--z-confirm: 10031;
}
/* ── Semantic surface colours (hard-coded) ──────────────────────
* #0f172a slate-900 — body text, modal text
* #1e293b slate-800 — param text
* #475569 slate-600 — labels, ghost button text
* #64748b slate-500 — param keys, muted text
* #cbd5e1 slate-300 — borders, toggle track
* #dbe2ea — card borders (custom)
* #dbe7f5 — array block border (custom)
* #2563eb blue-600 — primary action (buttons, toggles)
* #1d4ed8 blue-700 — param view hover
* #1e40af blue-800 — subflow label
* #dc2626 red-600 — error alert bg
* #b91c1c red-700 — array remove button
* #eab308 yellow-500 — warning alert bg
* ─────────────────────────────────────────────────────────────── */
body {
@apply bg-gray-50 dark:bg-gray-900;
color: #0f172a;
font-family: var(--font-body);
}
body.node-focus-modal-open {
overflow: hidden;
}
/* ── Global Material overrides ────────────────────────────────── */
/* Default form fields to full width — uses :where() for zero specificity
so any component-level rule can override without !important. */
:where(.mat-mdc-form-field) {
width: 100%;
}
.mat-mdc-dialog-surface,
.mat-mdc-card {
border-radius: 16px;
}
.material-icons,
.material-icons-outlined {
font-family: 'Material Icons Outlined' !important;
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-feature-settings: 'liga';
}
/* ── Utility classes ──────────────────────────────────────────── */
.container-centered {
@apply flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0;
}
.input {
@apply bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500;
}
.card-container {
@apply w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700;
}
.card {
@apply p-6 space-y-4 md:space-y-6 sm:p-8;
}
.label {
@apply block mb-2 text-sm font-medium text-gray-900 dark:text-white;
}
.title {
@apply text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white;
}
.button {
@apply text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800;
}
.button:disabled {
@apply bg-primary-500 opacity-40;
}
/* ── LLM / Node shared styles (used by generic-node, container-node, task-step-node) ── */
.llm-modal-backdrop {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
max-width: 100vw;
max-height: 100vh;
margin: 0;
padding: 12px;
border: none;
background: transparent;
color: inherit;
}
.llm-modal-backdrop::backdrop {
background: rgba(15, 23, 42, 0.45);
}
.llm-modal {
width: min(360px, calc(100vw - 24px));
display: flex;
flex-direction: column;
gap: 10px;
border: 1px solid #dbe2ea;
border-radius: 12px;
background: #ffffff;
box-shadow: 0 16px 40px rgba(15, 23, 42, 0.25);
padding: 14px;
}
.llm-modal-title {
font-size: 13px;
font-weight: 700;
color: #0f172a;
}
.llm-modal-field {
display: flex;
flex-direction: column;
gap: 4px;
}
.llm-modal-field label {
font-size: 11px;
font-weight: 600;
color: #475569;
}
.llm-modal-field input,
.llm-modal-field select,
.llm-modal-field textarea {
border: 1px solid #cbd5e1;
border-radius: 8px;
font-size: 12px;
color: #0f172a;
padding: 7px 8px;
resize: vertical;
}
.llm-modal-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}
.llm-btn {
border: 1px solid transparent;
border-radius: 8px;
cursor: pointer;
font-size: 12px;
font-weight: 600;
padding: 6px 10px;
}
.llm-btn-ghost {
border-color: #cbd5e1;
color: #475569;
background: #ffffff;
}
.llm-btn-primary {
background: #2563eb;
color: #ffffff;
}
.node-toggle {
width: fit-content;
display: inline-flex;
align-items: center;
gap: 10px;
border: 1px solid #cbd5e1;
border-radius: 999px;
background: #fff;
color: #0f172a;
cursor: pointer;
padding: 6px 10px;
}
.node-toggle-track {
position: relative;
width: 34px;
height: 20px;
border-radius: 999px;
background: #cbd5e1;
transition: background-color 0.2s ease;
}
.node-toggle-thumb {
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.2);
transition: transform 0.2s ease;
}
.node-toggle-label {
font-size: 12px;
font-weight: 600;
text-transform: lowercase;
}
.node-toggle-on .node-toggle-track {
background: #2563eb;
}
.node-toggle-on .node-toggle-thumb {
transform: translateX(14px);
}
.llm-error-alert-wrap,
.llm-warning-alert-wrap {
position: absolute;
top: -12px;
z-index: 120;
}
.llm-error-alert,
.llm-warning-alert {
width: 26px;
height: 26px;
border-radius: 999px;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 13px;
}
.llm-error-alert {
border: 1px solid #fecaca;
background: #dc2626;
color: #fff7ed;
box-shadow: 0 0 0 3px rgba(127, 29, 29, 0.2);
}
.llm-warning-alert {
border: 1px solid #fde68a;
background: #eab308;
color: #422006;
box-shadow: 0 0 0 3px rgba(202, 138, 4, 0.22);
}
.llm-error-tooltip,
.llm-warning-list-tooltip {
position: absolute;
top: calc(100% + 8px);
min-width: 220px;
max-width: 320px;
border-radius: 8px;
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.2);
padding: 8px;
z-index: 130;
opacity: 0;
visibility: hidden;
transform: translateY(-2px);
transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s ease;
}
.llm-error-tooltip {
right: 0;
border: 1px solid #fecaca;
background: #fff1f2;
color: #7f1d1d;
}
.llm-warning-list-tooltip {
left: 0;
border: 1px solid #fde68a;
background: #fef9c3;
color: #713f12;
}
.llm-error-alert-wrap:hover .llm-error-tooltip,
.llm-warning-alert-wrap:hover .llm-warning-list-tooltip {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.llm-error-title,
.llm-warning-list-title {
font-size: 11px;
font-weight: 700;
margin-bottom: 4px;
}
.llm-error-item,
.llm-warning-list-item {
font-size: 11px;
line-height: 1.3;
}
.llm-param-block {
border: 1px solid #dbe2ea;
border-radius: 8px;
background: #ffffff;
padding: 8px;
}
.llm-param-text {
margin-top: 4px;
color: #1e293b;
font-size: 11px;
line-height: 1.45;
white-space: pre-wrap;
word-break: break-word;
}
.llm-param-value-clamped,
.llm-param-text-clamped {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.llm-param-value-clamped {
white-space: pre-wrap;
word-break: break-word;
}
.llm-inline-token {
display: inline-flex;
align-items: center;
min-height: 18px;
margin: 0 2px;
border: 1px solid #bbf7d0;
border-radius: 6px;
background: #ecfdf3;
color: #166534;
font-size: 10px;
font-weight: 600;
padding: 0 6px;
}
.llm-param-key {
color: #64748b;
font-size: 10px;
letter-spacing: 0.03em;
text-transform: uppercase;
}
.llm-param-value {
color: #0f172a;
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.llm-array-sections {
display: flex;
flex-direction: column;
gap: 10px;
}
.llm-array-block {
display: flex;
flex-direction: column;
gap: 8px;
border: 1px solid #dbe7f5;
border-radius: 12px;
background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%);
padding: 10px 12px;
}
.llm-array-empty {
color: #64748b;
font-size: 12px;
}
.llm-array-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
border: 1px solid rgba(191, 219, 254, 0.9);
border-radius: 10px;
background: rgba(239, 246, 255, 0.9);
padding: 8px 10px;
}
.llm-array-item-summary {
min-width: 0;
color: #0f172a;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.llm-array-item-actions {
display: inline-flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.llm-array-remove-btn {
color: #b91c1c;
}
.llm-param-view-btn {
flex: 0 0 auto;
width: 20px;
height: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid #bfdbfe;
border-radius: 999px;
background: #eff6ff;
color: #1d4ed8;
cursor: pointer;
padding: 0;
}
.llm-param-view-btn:hover {
background: #dbeafe;
}
.llm-param-view-btn i {
font-size: 10px;
}
.llm-subflow-section {
margin-top: 4px;
}
.llm-subflow-view {
display: flex;
width: 100%;
align-items: center;
justify-content: center;
border: 1px solid #c7d2fe;
border-radius: 12px;
background: linear-gradient(180deg, #eef4ff 0%, #e0ecff 100%);
color: #1e40af;
cursor: pointer;
font-size: 12px;
font-weight: 700;
line-height: 1;
padding: 11px 12px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.llm-subflow-view:hover {
background: linear-gradient(180deg, #dbeafe 0%, #c7ddff 100%);
border-color: #93c5fd;
}
.link {
@apply font-medium text-primary-600 hover:underline dark:text-primary-500;
}
.link-active {
@apply text-purple-600 dark:text-white;
}
.form-control {
@apply flex flex-col gap-0.5;
}
.form-group {
@apply flex flex-col gap-4;
}
.helper-text {
@apply text-sm font-light text-gray-500 dark:text-gray-400;
}
.nav-header {
@apply bg-white border-gray-200 px-4 lg:px-6 py-2.5 dark:bg-gray-800;
}
.inner-nav {
@apply flex flex-wrap justify-center gap-4 items-center max-w-7xl;
}