Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,17 @@

## 0.3.0 (unreleased)

- **Typefaces** — Google Sans replaces Figtree and Google Sans Code replaces
Geist Mono. Neither is bundled: the package depends on `google_fonts`,
which fetches each cut on first use and caches it (ship the files under a
`google_fonts/` asset folder for offline-first apps). The fetch needs
`android.permission.INTERNET` in the main Android manifest and the
`com.apple.security.network.client` entitlement in a sandboxed macOS app.
`FlowTypography.standard` is now built at runtime, and the new
`FlowTypography.recut` re-cuts a token at another weight or style, which
`copyWith(fontWeight:)` no longer can on the standard scale. Hosts that
named `Figtree` or `GeistMono` directly should update.

- **Fix** — `FlowChatView`'s bottom inset no longer stacks on the safe
area. The design's 24 (compact) and 40 (wide) are now measured from the
bottom of the safe area, so a phone's home indicator is absorbed rather
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Two hard constraints shape everything here:

- **No third-party dependencies.** `dependencies:` in `pubspec.yaml` contains only the Flutter SDK and Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev. Nothing outside that. Dev dependencies (`flutter_test`, `flutter_lints`) are fine. Bundled *assets* are not dependencies: the package ships Figtree and Geist Mono (`fonts/`, SIL OFL) because the design system is set in them, declared under `flutter: fonts:` and referenced as `package: 'flow_ui'`.
- **One third-party dependency: `google_fonts`.** `dependencies:` in `pubspec.yaml` holds the Flutter SDK, Flutter's own first-party packages — `material_ui` (Material's home since Flutter 3.47) and its transitive set, all published by flutter.dev — and `google_fonts` (material.io), which fetches Google Sans and Google Sans Code from Google Fonts at runtime. Nothing else, and no font files ship with the package. Dev dependencies (`flutter_test`, `flutter_lints`) are fine.
- **Nothing model-facing.** Components render state passed in and report intent out through callbacks. No prompts, schemas, provider/network calls, or any LLM awareness — that belongs to the layers built on top.

The theme, the conversation components (message, thread, streaming text, actions, loading), the composer and its menus, attachments with their preview, suggestions, and the chat surface are implemented; the roadmap below tracks the rest. Message content is modeled as typed parts (`lib/src/models/`) — sealed `FlowMessagePart` subtypes rendered by `FlowMessage`, with `FlowCustomPart` + `FlowCustomPartBuilder` as the extension seam for host-injected content.

## Layout

- Package at the repo root: `lib/`, `test/`, `fonts/`, `pubspec.yaml`.
- Package at the repo root: `lib/`, `test/`, `pubspec.yaml`.
- `playground/` — the Flow UI Playground: a full Flutter app depending on the package via `path: ../`. Use it to demo and manually exercise components (every component has a stage demo, with variant pills and code snippets).

## Commands
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ MaterialApp(
)
```

The default typography ships with the package — Figtree, bundled under the
SIL Open Font License — so the theme renders as designed with no font setup.
The default typography — Google Sans and Google Sans Code — arrives through
[google_fonts](https://pub.dev/packages/google_fonts): each cut is fetched
on first use and cached on the device, so there is no font to bundle. The
fetch needs network access: `android.permission.INTERNET` in an Android
app's main manifest (Flutter's template grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app; without it text falls back to the platform face. To render offline on
first launch, ship the files under a `google_fonts/` asset folder.

## Build a chat screen

Expand DownExpand Up@@ -292,5 +298,6 @@ cd playground && flutter run -d chrome

## License

Code is released under the [MIT License](LICENSE). The bundled Figtree font
is licensed separately under the [SIL Open Font License](fonts/OFL.txt).
Code is released under the [MIT License](LICENSE). Google Sans and Google
Sans Code are fetched from Google Fonts under the
[SIL Open Font License](https://openfontlicense.org), not bundled.
3 changes: 1 addition & 2 deletions docs/.gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,8 +8,7 @@ dist/
# generated types
.astro/

# synced/built at build time from the repo (see scripts/)
public/fonts/
# built at build time from the repo (see scripts/)
public/playground/
public/api/

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ npm run dev # http://localhost:4321
npm run build # static site in dist/
```

`predev`/`prebuild` copy the package's bundled Figtree faces from the repo's
`fonts/` into `public/fonts/` (gitignored) — repo fonts stay the single
source. Brand colors in `src/styles/theme.css` mirror the package's design
tokens in `lib/src/theme/flow_colors.dart`.
Google Sans loads from Google Fonts via the `<link>` in `astro.config.mjs` —
the same source the package fetches from at runtime. Brand colors in
`src/styles/theme.css` mirror the package's design tokens in
`lib/src/theme/flow_colors.dart`.

`npm run playground` builds the repo's `playground/` Flutter app for the
web into `public/playground/` — served at `/playground/<component>` (path
Expand Down
13 changes: 13 additions & 0 deletions docs/astro.config.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,19 @@ export default defineConfig({
customCss: ['./src/styles/theme.css'],
logo: { src: './src/assets/flow-ui-logo.svg', alt: '' },
head: [
// Google Sans from Google Fonts — the same source the package fetches at runtime.
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{
tag: 'link',
attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;600;700&display=swap',
},
},
// Social-preview image on every page — Starlight emits the rest
// of the OG/Twitter tags; the image is ours to provide.
{
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
"predev": "bash scripts/sync-fonts.sh",
"dev": "astro dev",
"start": "astro dev",
"prebuild": "bash scripts/sync-fonts.sh",
"build": "astro build",
"playground": "bash scripts/build-playground.sh",
"build:site": "npm run playground && npm run build",
Expand Down
13 changes: 0 additions & 13 deletions docs/scripts/sync-fonts.sh

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/content/docs/components/code-block.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,7 +137,7 @@ FlowCodeLanguage.register(
## Theming

Token inks are theme tokens. Install a `FlowSyntaxColors` on the theme to
recolor them; the code face is Geist Mono, bundled with the package, and
recolor them; the code face is Google Sans Code, fetched through `google_fonts`, and
swaps via the typography:

```dart title="Custom syntax palette and mono face"
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/getting-started.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,8 +42,12 @@ MaterialApp(
back to a preset matched to the ambient `ThemeData.brightness`.
</Aside>

Figtree — the face the design system is set in — ships inside the package,
so there is nothing to add to your own `pubspec.yaml` fonts section.
Google Sans — the face the design system is set in — is fetched through
`google_fonts` on first use, so there is nothing to add to your `pubspec.yaml`
fonts section. The fetch needs network access: `android.permission.INTERNET`
in the main Android manifest (Flutter grants it only to debug and profile)
and the `com.apple.security.network.client` entitlement in a sandboxed macOS
app. To render offline on first launch, ship the files under `google_fonts/`.

## Render a conversation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/theming.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,7 +93,7 @@ Text(
## The type scale

`FlowTypography.standard` follows the Material 3 scale — display, headline,
title, body and label, each in large / medium / small — set in Figtree.
title, body and label, each in large / medium / small — set in Google Sans.
Letter-spacing stays at zero. Line heights step with the role: 1.5 for
body, 1.3 for title and label, 1.2 for headline, 1.15 for display.

Expand Down
33 changes: 3 additions & 30 deletions docs/src/styles/theme.css
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
/* flow_ui docs theme.
*
* Design language: the Flow palette (lib/src/theme/flow_colors.dart) —
* warm paper & near-black ink, one rose accent — set in Figtree and laid
* warm paper & near-black ink, one rose accent — set in Google Sans and laid
* out in the modern docs idiom: display-scale headlines, ink-neutral pill
* buttons, lifted borderless panels, whisper hairlines, minimal chrome.
* Rose is the accent voice (links, active states, the mark), never a slab.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Figtree';
src: url('/fonts/Figtree-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Google Sans loads from Google Fonts via the <link> in astro.config.mjs. */

/* -------------------------------------------------------------- palette */

:root {
--sl-font: 'Figtree', ui-sans-serif, system-ui, sans-serif;
--sl-font: 'Google Sans', ui-sans-serif, system-ui, sans-serif;
--sl-nav-height: 4rem;
--sl-nav-pad-x: 1.5rem;
}
Expand Down
1 change: 1 addition & 0 deletions example/linux/flutter/generated_plugins.cmake
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading