@import "@xterm/xterm/css/xterm.css"; /* * Do NOT `import "./app.css"` from JS — Bun's CSS bundler rejects the * `@layer name, name;` ordering rule between `@import` rules below. This file * is built standalone by the Tailwind CLI step in `scripts/build.ts`; the * generated `assets/app.css` is linked from `index.template.html`. */ /* * Cascade layer order. @assistant-ui/react-ui ships unlayered CSS authored * against Tailwind v3; in Tailwind v4 utilities live in @layer utilities, and * any unlayered CSS wins over layered CSS regardless of selector specificity. * Putting assistant-ui in a named layer that we declare BEFORE utilities makes * Tailwind v4 utility classes cascade above assistant-ui's scoped preflight. */ @layer theme, base, assistant-ui, components, utilities; @import "tailwindcss"; @plugin "@tailwindcss/typography"; @import "@assistant-ui/react-ui/styles/index.css" layer(assistant-ui); @import "@assistant-ui/react-ui/styles/markdown.css" layer(assistant-ui); @layer base { a[href], button, select, summary, [role="button"], [role="link"], [role="option"], [role="menuitem"], [role="tab"] { cursor: pointer; } } @theme { --font-sans: "Geist", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --font-mono: "JetBrains Mono", ui-monospace, monospace; /* Primary — Teal */ --color-teal-300: #B5DDEF; --color-teal-500: #67B2D7; --color-teal-700: #357F9E; /* Neutrals Dark — Navy */ --color-navy-950: #0F1729; --color-navy-800: #252C3D; --color-navy-600: #4B5768; /* Neutrals Light — Ice */ --color-ice-50: #F7F9FB; --color-ice-100: #E8EDF3; --color-ice-300: #A8B5C5; /* Accent */ --color-mint: #5AC8A8; --color-amber: #F0A45B; --color-coral: #E86B6B; /* ── Semantic tokens ── */ --color-page: #0F1729; --color-panel: #252C3D; --color-panel-alt: #1a2133; --color-overlay: rgba(255, 255, 255, 0.04); --color-overlay-strong: rgba(255, 255, 255, 0.10); --color-fg: #ffffff; --color-fg-2: #E8EDF3; --color-fg-3: #A8B5C5; --color-fg-muted: #4B5768; --color-line: rgba(255, 255, 255, 0.06); --color-line-strong: rgba(255, 255, 255, 0.12); --color-focus: rgba(103, 178, 215, 0.4); /* Text color that sits on --color-teal-500 primary fills. */ --color-on-primary: #0F1729; } /* ── Chart variables ── */ :root { --chart-gridline: rgba(255, 255, 255, 0.04); --chart-axis-label: rgba(75, 87, 104, 1); } /* ── Background atmosphere ── */ .bg-atmosphere { background-color: var(--color-page); background-image: radial-gradient(ellipse 120% 60% at 15% 5%, rgba(53, 127, 158, 0.12) 0%, transparent 50%), radial-gradient(ellipse 80% 50% at 85% 90%, rgba(90, 200, 168, 0.07) 0%, transparent 45%); background-attachment: fixed; } .bg-atmosphere::before { content: ""; position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: 0.07; background-image: 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.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-repeat: repeat; background-size: 200px 200px; } /* ── @pierre/diffs brand overrides ── */ :root { --diffs-font-family: "JetBrains Mono", ui-monospace, monospace; --diffs-header-font-family: "Geist", ui-sans-serif, system-ui, sans-serif; --diffs-font-size: 13px; --diffs-line-height: 20px; /* Surfaces */ --diffs-bg-buffer-override: #0F1729; --diffs-bg-context-override: #161d2e; --diffs-bg-hover-override: #1c2438; --diffs-bg-separator-override: #252C3D; /* Line numbers */ --diffs-fg-number-override: #4B5768; /* Additions — mint */ --diffs-addition-color-override: #5AC8A8; --diffs-fg-number-addition-override: rgba(90, 200, 168, 0.5); /* Deletions — coral */ --diffs-deletion-color-override: #E86B6B; --diffs-fg-number-deletion-override: rgba(232, 107, 107, 0.5); } /* ── Server-rendered SVG graph overrides ── */ /* The server injects @media (prefers-color-scheme: dark) which won't reliably fire when the OS is in light mode, so we apply dark graph colors always. */ .graph-svg text { fill: #c6d4e0; } .graph-svg [stroke="#357f9e"] { stroke: #67B2D7; } .graph-svg [stroke="#666666"] { stroke: #5a7a94; } .graph-svg polygon[fill="#357f9e"] { fill: #67B2D7; } .graph-svg polygon[fill="#666666"] { fill: #5a7a94; } .graph-svg ellipse[fill="#ffffff"], .graph-svg polygon[fill="#ffffff"] { fill: #1a2b3c; } .graph-svg ellipse[stroke="#357f9e"], .graph-svg polygon[stroke="#357f9e"] { stroke: #67B2D7; } .graph-svg [fill="#1a1a1a"] { fill: #c6d4e0; } /* --------------------------------------------------------------------------- * assistant-ui theme overrides (--aui-* variables) — mapped to Fabro tokens. * Values are HSL component triples so assistant-ui's hsl(var(...)) wrapper * works. Scoped to .fabro-chat so the shadcn theme cannot leak out. * * Source colors come from the @theme block above: * navy-950 #0F1729 = 220 47% 11% * panel #252C3D = 222 24% 19% * panel-alt #1a2133 = 223 33% 15% * teal-500 #67B2D7 = 200 60% 62% (Fabro's "teal" is a sky blue) * mint #5AC8A8 = 163 49% 57% * ice-100 #E8EDF3 = 213 27% 93% * ice-300 #A8B5C5 = 213 22% 72% * ------------------------------------------------------------------------- */ .fabro-chat { --aui-background: 220 47% 11%; --aui-foreground: 0 0% 100%; --aui-card: 222 24% 19%; --aui-card-foreground: 0 0% 100%; --aui-popover: 222 24% 19%; --aui-popover-foreground: 0 0% 100%; --aui-primary: 200 60% 62%; --aui-primary-foreground: 220 47% 11%; --aui-secondary: 223 33% 15%; --aui-secondary-foreground: 0 0% 100%; --aui-muted: 223 33% 15%; --aui-muted-foreground: 213 22% 72%; --aui-accent: 163 49% 57%; --aui-accent-foreground: 220 47% 11%; --aui-destructive: 0 76% 66%; --aui-destructive-foreground: 0 0% 100%; --aui-border: 218 28% 17%; --aui-input: 218 28% 17%; --aui-ring: 200 60% 62%; --aui-radius: 0.5rem; --aui-thread-max-width: 44rem; } /* In the narrow Ask-Fabro sidebar column, drop the message-column max-width so * messages and the composer span the full column width. Declared AFTER * .fabro-chat so it wins on cascade order (the element has both classes). * Also nudge the base font size down to 14px for a tighter feel. */ .ask-fabro-sidebar { --aui-thread-max-width: 100%; font-size: 0.875rem; /* 14px */ } /* Override assistant-ui defaults that are tuned for the full-page Thread but * waste space inside the narrow sidebar column. Layered into assistant-ui so * we beat the unlayered Tailwind v3 rules without `!important`. */ @layer assistant-ui { /* Let user and assistant message bubbles span the full sidebar column * (default clips them to 80% of an already-narrow column). */ .ask-fabro-sidebar .aui-user-message-content, .ask-fabro-sidebar .aui-assistant-message-content { max-width: 100%; font-size: 0.875rem; line-height: 1.5rem; } /* Shrink the right-justified spacer on user messages so short replies do * not crowd the right edge unnecessarily. */ .ask-fabro-sidebar .aui-user-message-root { grid-template-columns: minmax(24px, 1fr) auto; padding-top: 0.5rem; padding-bottom: 0.5rem; } .ask-fabro-sidebar .aui-assistant-message-root { padding-top: 0.5rem; padding-bottom: 0.5rem; } /* min-width: 0 on the grid track + min-width: 0 / overflow on the content * so wide children (long lines in code blocks, tables) honour the column * width and let their own overflow-x scroll instead of stretching the * sidebar. Same fix on user messages for symmetry. */ .ask-fabro-sidebar .aui-assistant-message-content, .ask-fabro-sidebar .aui-user-message-content { min-width: 0; overflow-x: hidden; } /* Give user message bubbles a lighter, solid surface so they read as raised * cards. The default muted bubble color (panel-alt) is nearly identical to * the translucent `bg-panel/40` sidebar once composited over the page, so * bubbles visually disappeared into the column. */ .ask-fabro-sidebar .aui-user-message-content { background-color: var(--color-panel); } /* Inset the assistant message content from the column's right edge so the * code block (dark pre box) has visible right margin and doesn't appear to * bleed against the sidebar edge when its content overflows. */ .ask-fabro-sidebar .aui-assistant-message-content { padding-right: 1rem; } /* The viewport-footer centers children; stretch instead so the composer * fills the column width (otherwise it shrinks to its intrinsic content). * `margin-top: auto` pushes the footer to the bottom of the flex column so * the composer sits at the bottom in the empty state (without it, the * footer flows after the empty Welcome/Messages area at the top). */ .ask-fabro-sidebar .aui-thread-viewport-footer { align-items: stretch; padding-bottom: 0; margin-top: auto; } /* Hide the assistant avatar to reclaim horizontal space — the column is * narrow enough that the 2.5rem avatar + 1rem gutter is too much chrome. * Also hide the welcome-state avatar for the same reason. */ .ask-fabro-sidebar .aui-assistant-message-root > .aui-avatar-root, .ask-fabro-sidebar .aui-thread-welcome-root .aui-avatar-root { display: none; } .ask-fabro-sidebar .aui-assistant-message-root { grid-template-columns: minmax(0, 1fr); } .ask-fabro-sidebar .aui-assistant-message-content { grid-column: 1; } /* Hide the per-message Copy / Refresh action bar to reclaim vertical space. */ .ask-fabro-sidebar .aui-assistant-action-bar-root, .ask-fabro-sidebar .aui-user-action-bar-root { display: none; } /* Welcome message also wants smaller text. */ .ask-fabro-sidebar .aui-thread-welcome-message { font-size: 0.875rem; line-height: 1.5rem; } /* Drop the solid navy background that assistant-ui paints on the thread * root + viewport; the sidebar already supplies its own translucent panel * background and the painted navy created a visible block around the * composer at the bottom of the column. */ .ask-fabro-sidebar .aui-thread-root, .ask-fabro-sidebar .aui-thread-viewport, .ask-fabro-sidebar .aui-thread-viewport-footer { background-color: transparent; } /* Code blocks: the
is already constrained to the column via the
* parent's overflow-x: hidden, but Chromium drops the pre's padding-right
* when content overflows, so long code lines visually bleed up to the
* pre's right edge. Promoting to inline-block lets its own
* padding-right become part of the scrollable content. */
.ask-fabro-sidebar .aui-md-pre {
max-width: 100%;
}
.ask-fabro-sidebar .aui-md-pre > code {
display: inline-block;
min-width: 100%;
padding-right: 1rem;
}
/* Shrink markdown headings for the narrow column. The assistant-ui defaults
* go up to 36px (h1), which dominates the sidebar. H1 stays distinct at
* 18px; H2/H3 read as bold body text; H4-H6 get no special styling. The
* default heading margins (mt-8/mb-8 = 32px) are also sized for the
* full-page Thread, so tighten them to suit the smaller type. */
.ask-fabro-sidebar .aui-md-h1 {
font-size: 1.125rem; /* 18px */
line-height: 1.5rem;
font-weight: 700;
margin-bottom: 0.75rem;
}
.ask-fabro-sidebar .aui-md-h2,
.ask-fabro-sidebar .aui-md-h3 {
font-size: 0.875rem; /* 14px */
line-height: 1.5rem;
font-weight: 700;
margin-top: 1rem;
margin-bottom: 0.5rem;
}
.ask-fabro-sidebar .aui-md-h4,
.ask-fabro-sidebar .aui-md-h5,
.ask-fabro-sidebar .aui-md-h6 {
font-size: 0.875rem; /* 14px */
line-height: 1.5rem;
font-weight: 400;
margin-top: 1rem;
margin-bottom: 0.5rem;
}
/* Tighten paragraph spacing: the default 20px margins + 28px line-height
* are sized for the wide Thread. */
.ask-fabro-sidebar .aui-md-p {
margin-top: 0.75rem;
margin-bottom: 0.75rem;
line-height: 1.5rem;
}
/* Pull list indentation in (default ml-6 = 24px eats column width) and
* shrink the vertical margins. */
.ask-fabro-sidebar .aui-md-ul,
.ask-fabro-sidebar .aui-md-ol {
margin-top: 0.75rem;
margin-bottom: 0.75rem;
margin-left: 1.25rem;
}
/* Blockquote: default pl-6 (24px) is a large share of the narrow column. */
.ask-fabro-sidebar .aui-md-blockquote {
padding-left: 0.75rem;
}
/* Code blocks: trim the default p-4 (16px) padding. */
.ask-fabro-sidebar .aui-md-pre {
padding: 0.75rem;
}
}