diff --git a/docs/claude-design/Clide Design System.html b/docs/claude-design/Clide Design System.html new file mode 100644 index 00000000..75dbac22 --- /dev/null +++ b/docs/claude-design/Clide Design System.html @@ -0,0 +1,184 @@ + + + + + clide — design system + + + + +
+ + + + + + + + + +
+
Unpacking...
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/claude-design/Clide Hi-Fi.html b/docs/claude-design/Clide Hi-Fi.html new file mode 100644 index 00000000..7ff4ab5b --- /dev/null +++ b/docs/claude-design/Clide Hi-Fi.html @@ -0,0 +1,180 @@ + + + + + clide — hi-fi + + + + +
+ + + + clide + +
+
Unpacking...
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/claude-design/README.md b/docs/claude-design/README.md new file mode 100644 index 00000000..b75526ed --- /dev/null +++ b/docs/claude-design/README.md @@ -0,0 +1,134 @@ +# clide · design handoff + +Bundle for importing into the clide repo and driving further work with Claude Code. + +--- + +## What's in here + +``` +bundle/ +├─ README.md ← this file +├─ Wireframe.html ← architectural snapshot of current code +├─ Wireframe - Flows.html ← 8 interaction storyboards +├─ Clide Hi-Fi.html ← 3 hi-fi scenes · 4 swappable themes +├─ Clide Design System.html ← tokens · type · components · syntax +│ +├─ themes/ ← DROP-IN Dart files +│ ├─ clide_theme.dart (default · cool near-black + periwinkle) +│ ├─ midnight_theme.dart (VS Code-adjacent muted dark) +│ ├─ paper_theme.dart (drafting-sheet light) +│ └─ terminal_theme.dart (near-black + amber) +│ +└─ png/ ← flat renders for tickets / PRs + ├─ wireframe-layout.png + ├─ wireframe-flows.png + ├─ design-system.png + ├─ hifi-clide-main.png + ├─ hifi-clide-editor.png + ├─ hifi-clide-welcome.png + ├─ hifi-midnight-main.png + ├─ hifi-paper-main.png + └─ hifi-terminal-main.png +``` + +All four HTML files are **fully self-contained** — fonts, JS, CSS inlined. Open them with any browser, commit them to the repo, or hand their paths to `claude` directly. + +--- + +## Using this with Claude Code + +Drop the bundle into the repo (e.g. `docs/design/`) and point Claude at it: + +```bash +claude "read docs/design/README.md and docs/design/Clide\ Design\ System.html, + then implement the Clide theme from docs/design/themes/clide_theme.dart + so it's wired through kernel/theme.dart" +``` + +Claude Code can parse the HTML natively and see every token value, component, and layout annotation. It can also read the Dart theme files without conversion. + +--- + +## Design intent, in one pass + +### 1 · Typography + +- **Display** — `Josefin Sans 300` for titles, section heads, and the wordmark. Light weight is load-bearing; using 400+ changes the feel entirely. +- **UI + code** — `JetBrains Mono 400/500` for everything else. Tab labels, file paths, status bar, editor. Monospace is a deliberate choice — clide is an IDE for people who like their grids. + +### 2 · Layout (classicPreset) + +Three columns + statusbar. Every box in the frame is a `SlotHost` slot populated by `TabContribution`s sorted by priority (lower = leftmost tab). + +``` +┌────────────┬──────────────────────┬──────────────┐ +│ sidebar │ workspace │ context │ +│ 240 px │ flex │ 300 px │ +│ 180–400 │ │ 220–420 │ +├────────────┴──────────────────────┴──────────────┤ +│ statusbar · 24 px │ +└──────────────────────────────────────────────────┘ +``` + +See `Wireframe.html` for the full architectural breakdown — every red-pencil annotation cites the source file it came from. + +### 3 · Themes + +Four presets ship by default. `clide` is the reference — the other three are variations on the same component vocabulary, differing only in token values. + +| name | bg | accent | feel | +|------------|-----------|-----------|-------------------------------| +| `clide` | `#20202C` | `#78A0F8` | cool near-black + periwinkle | +| `midnight` | `#1E1E1E` | `#569CD6` | VS Code-adjacent | +| `paper` | `#F4F1EA` | `#C14B2A` | drafting sheet · light | +| `terminal` | `#0A0A0A` | `#E0B050` | near-black + amber | + +All four share the same semantic token names (`bg`, `surface`, `border`, `text`, `accent`, `ok/warn/err/info`, syntax roles). A widget written against the tokens will render correctly in all four. + +### 4 · Drop-in usage + +```dart +import 'themes/clide_theme.dart'; + +MaterialApp( + theme: ClideTheme.data, + home: const ClideApp(), +); +``` + +The `ClideTheme.tokens` object exposes semantic colors for cases where a Material widget can't carry the meaning — e.g. syntax highlighting, git status markers, Claude message kinds. + +--- + +## Screens in the hi-fi + +| # | screen | purpose | +|---|--------------------------------|----------------------------------------------------------| +| 1 | **Main IDE · at rest** | cold-start settled · all slots populated · Claude primary | +| 2 | **Editor · with Claude panel** | file editor in workspace · Claude as context-column tab | +| 3 | **Welcome · no project** | first-run landing · start actions + recent projects | + +Open `Clide Hi-Fi.html` and use the floating Tweaks panel (bottom-right, toggle from the toolbar) to swap between themes live. + +--- + +## Flows not yet realized + +From `Wireframe - Flows.html` — things with commands/contracts wired but no UI yet: + +- **Project picker** (cold start with no `lastProject`) +- **Multi-buffer editor tabs** (editor is single-buffer today) +- **Toolbar slot** (`Slots.toolbar` reserved, no preset renders it) +- **Command palette keybinding** (`⌘⇧P` not bound by default) +- **Secondary Claude panes** (command exists; UI wiring pending) + +These are the highest-leverage next design targets. + +--- + +## File integrity + +All HTMLs render offline, no network required after first open. Fonts are bundled as CSS and fall back to system monospace if Josefin Sans or JetBrains Mono are blocked. + +Generated by the design pass · refreshed 2026-04 diff --git a/docs/claude-design/Wireframe - Flows.html b/docs/claude-design/Wireframe - Flows.html new file mode 100644 index 00000000..8b3223a2 --- /dev/null +++ b/docs/claude-design/Wireframe - Flows.html @@ -0,0 +1,186 @@ + + + + + clide — interaction flows + + + + +
+ + + + + + + + + + flows + +
+
Unpacking...
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/claude-design/Wireframe.html b/docs/claude-design/Wireframe.html new file mode 100644 index 00000000..ce7f7b02 --- /dev/null +++ b/docs/claude-design/Wireframe.html @@ -0,0 +1,185 @@ + + + + + clide — current code as wireframe + + + + +
+ + + + + + + + + wire + +
+
Unpacking...
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/claude-design/png/design-system.png b/docs/claude-design/png/design-system.png new file mode 100644 index 00000000..afc8b8d6 Binary files /dev/null and b/docs/claude-design/png/design-system.png differ diff --git a/docs/claude-design/png/hifi-clide-editor.png b/docs/claude-design/png/hifi-clide-editor.png new file mode 100644 index 00000000..e1f17a37 Binary files /dev/null and b/docs/claude-design/png/hifi-clide-editor.png differ diff --git a/docs/claude-design/png/hifi-clide-main.png b/docs/claude-design/png/hifi-clide-main.png new file mode 100644 index 00000000..c04ec6f7 Binary files /dev/null and b/docs/claude-design/png/hifi-clide-main.png differ diff --git a/docs/claude-design/png/hifi-clide-welcome.png b/docs/claude-design/png/hifi-clide-welcome.png new file mode 100644 index 00000000..51b703b5 Binary files /dev/null and b/docs/claude-design/png/hifi-clide-welcome.png differ diff --git a/docs/claude-design/png/hifi-midnight-main.png b/docs/claude-design/png/hifi-midnight-main.png new file mode 100644 index 00000000..8aae95b9 Binary files /dev/null and b/docs/claude-design/png/hifi-midnight-main.png differ diff --git a/docs/claude-design/png/hifi-paper-main.png b/docs/claude-design/png/hifi-paper-main.png new file mode 100644 index 00000000..7a52cd75 Binary files /dev/null and b/docs/claude-design/png/hifi-paper-main.png differ diff --git a/docs/claude-design/png/hifi-terminal-main.png b/docs/claude-design/png/hifi-terminal-main.png new file mode 100644 index 00000000..d15a6435 Binary files /dev/null and b/docs/claude-design/png/hifi-terminal-main.png differ diff --git a/docs/claude-design/png/wireframe-flows.png b/docs/claude-design/png/wireframe-flows.png new file mode 100644 index 00000000..72ffb938 Binary files /dev/null and b/docs/claude-design/png/wireframe-flows.png differ diff --git a/docs/claude-design/png/wireframe-layout.png b/docs/claude-design/png/wireframe-layout.png new file mode 100644 index 00000000..ccc518f7 Binary files /dev/null and b/docs/claude-design/png/wireframe-layout.png differ diff --git a/docs/claude-design/themes/clide_theme.dart b/docs/claude-design/themes/clide_theme.dart new file mode 100644 index 00000000..9ee085ea --- /dev/null +++ b/docs/claude-design/themes/clide_theme.dart @@ -0,0 +1,186 @@ +// clide_theme.dart +// +// Default theme for clide. +// Sampled from the Clide Web session dashboard — cool near-black canvas +// with a single periwinkle accent. +// +// Usage: +// MaterialApp(theme: ClideTheme.data, ...) + +import 'package:flutter/material.dart'; + +class ClideTheme { + // ─── palette ────────────────────────────────────────────────────────── + static const _bg = Color(0xFF20202C); // page / editor canvas + static const _bgSunken = Color(0xFF1A1A24); // sidebar, gutters + static const _surface = Color(0xFF242838); // cards, table header, pills + static const _surfaceHi = Color(0xFF2C3046); // hover, selected row + static const _border = Color(0xFF343850); + static const _borderHi = Color(0xFF3C445C); + + static const _textHi = Color(0xFFE6E8F2); // primary text + static const _text = Color(0xFFB1BBE3); // section titles, labels + static const _textDim = Color(0xFF78809C); // secondary + static const _textMute = Color(0xFF545C84); // small-caps labels + + static const _accent = Color(0xFF78A0F8); // periwinkle primary + static const _accentPress = Color(0xFF6C90DC); + static const _accentSoft = Color(0x2278A0F8); // 13% accent for fills + + static const _ok = Color(0xFF7DD3A8); + static const _warn = Color(0xFFE6C370); + static const _err = Color(0xFFE87D7D); + static const _info = _accent; + + // syntax (Dart-biased) + static const _synKeyword = Color(0xFFC792EA); // class, const, final + static const _synType = Color(0xFF78A0F8); // Widget, BuildContext + static const _synString = Color(0xFFA8D99B); + static const _synNumber = Color(0xFFE6C370); + static const _synComment = Color(0xFF545C84); + static const _synMethod = Color(0xFF82B1FF); + static const _synPunct = Color(0xFF78809C); + + // ─── exposed tokens ─────────────────────────────────────────────────── + static const tokens = ClideTokens( + bg: _bg, bgSunken: _bgSunken, surface: _surface, surfaceHi: _surfaceHi, + border: _border, borderHi: _borderHi, + textHi: _textHi, text: _text, textDim: _textDim, textMute: _textMute, + accent: _accent, accentPress: _accentPress, accentSoft: _accentSoft, + ok: _ok, warn: _warn, err: _err, info: _info, + synKeyword: _synKeyword, synType: _synType, synString: _synString, + synNumber: _synNumber, synComment: _synComment, synMethod: _synMethod, + synPunct: _synPunct, + ); + + // ─── ThemeData ──────────────────────────────────────────────────────── + static ThemeData get data => ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + scaffoldBackgroundColor: _bg, + canvasColor: _bg, + + colorScheme: const ColorScheme.dark( + brightness: Brightness.dark, + primary: _accent, + onPrimary: Color(0xFF0D1020), + secondary: _synKeyword, + onSecondary: Color(0xFF0D1020), + surface: _surface, + onSurface: _textHi, + surfaceContainerHighest: _surfaceHi, + outline: _border, + outlineVariant: _borderHi, + error: _err, + onError: Color(0xFF0D1020), + ), + + textTheme: const TextTheme( + // Josefin Sans Light for display; JetBrains Mono for code/body. + displayLarge: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 48, height: 1.1, letterSpacing: 0.2, color: _textHi), + displayMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 34, height: 1.15, letterSpacing: 0.2, color: _textHi), + headlineSmall: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 20, height: 1.2, letterSpacing: 0.2, color: _textHi), + titleMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 14, height: 1.3, letterSpacing: 0.3, color: _text), + labelSmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w500, fontSize: 10, height: 1.2, letterSpacing: 1.0, color: _textMute), + bodyMedium: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 12, height: 1.45, color: _textHi), + bodySmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 11, height: 1.4, color: _text), + ), + + dividerTheme: const DividerThemeData(color: _border, thickness: 1, space: 1), + + cardTheme: CardThemeData( + color: _surface, + elevation: 0, + shape: RoundedRectangleBorder( + side: const BorderSide(color: _border), + borderRadius: BorderRadius.circular(6), + ), + margin: EdgeInsets.zero, + ), + + inputDecorationTheme: InputDecorationTheme( + isDense: true, + filled: true, + fillColor: _bgSunken, + hintStyle: const TextStyle(color: _textMute), + contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(4), + borderSide: const BorderSide(color: _border), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(4), + borderSide: const BorderSide(color: _border), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(4), + borderSide: const BorderSide(color: _accent, width: 1.5), + ), + ), + + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: _accent, + foregroundColor: const Color(0xFF0D1020), + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + textStyle: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 12, fontWeight: FontWeight.w500), + ), + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: _accent, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), + textStyle: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 12), + ), + ), + + // Pill-style chips (matches the Projects row in the dashboard). + chipTheme: ChipThemeData( + backgroundColor: _surface, + side: const BorderSide(color: _borderHi), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + labelStyle: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 11, color: _text), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + ), + + iconTheme: const IconThemeData(color: _textDim, size: 14), + + tooltipTheme: TooltipThemeData( + decoration: BoxDecoration( + color: _surfaceHi, + border: Border.all(color: _borderHi), + borderRadius: BorderRadius.circular(3), + ), + textStyle: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 11, color: _textHi), + ), + + scrollbarTheme: ScrollbarThemeData( + thumbColor: WidgetStatePropertyAll(_border), + thickness: const WidgetStatePropertyAll(6), + radius: const Radius.circular(3), + ), + ); +} + +/// Raw color tokens — use when Material widgets can't carry the meaning. +class ClideTokens { + const ClideTokens({ + required this.bg, required this.bgSunken, + required this.surface, required this.surfaceHi, + required this.border, required this.borderHi, + required this.textHi, required this.text, + required this.textDim, required this.textMute, + required this.accent, required this.accentPress, required this.accentSoft, + required this.ok, required this.warn, required this.err, required this.info, + required this.synKeyword, required this.synType, required this.synString, + required this.synNumber, required this.synComment, + required this.synMethod, required this.synPunct, + }); + final Color bg, bgSunken, surface, surfaceHi; + final Color border, borderHi; + final Color textHi, text, textDim, textMute; + final Color accent, accentPress, accentSoft; + final Color ok, warn, err, info; + final Color synKeyword, synType, synString, synNumber, synComment, synMethod, synPunct; +} diff --git a/docs/claude-design/themes/midnight_theme.dart b/docs/claude-design/themes/midnight_theme.dart new file mode 100644 index 00000000..8c1b7e26 --- /dev/null +++ b/docs/claude-design/themes/midnight_theme.dart @@ -0,0 +1,74 @@ +// midnight_theme.dart +// +// Midnight — classic dark, VS Code-adjacent, maximally muted. Gets out of the way. + +import 'package:flutter/material.dart'; +import 'clide_theme.dart' show ClideTokens; + +class MidnightTheme { + static const _bg = Color(0xFF1E1E1E); + static const _bgSunken = Color(0xFF181818); + static const _surface = Color(0xFF252526); + static const _surfaceHi = Color(0xFF2D2D2E); + static const _border = Color(0xFF333333); + static const _borderHi = Color(0xFF3F3F3F); + + static const _textHi = Color(0xFFD4D4D4); + static const _text = Color(0xFFBBBBBB); + static const _textDim = Color(0xFF858585); + static const _textMute = Color(0xFF6A6A6A); + + static const _accent = Color(0xFF569CD6); // muted azure + static const _accentPress = Color(0xFF4785BD); + static const _accentSoft = Color(0x22569CD6); + + static const _ok = Color(0xFF89D185); + static const _warn = Color(0xFFD7BA7D); + static const _err = Color(0xFFF48771); + static const _info = _accent; + + static const _synKeyword = Color(0xFFC586C0); + static const _synType = Color(0xFF4EC9B0); + static const _synString = Color(0xFFCE9178); + static const _synNumber = Color(0xFFB5CEA8); + static const _synComment = Color(0xFF6A9955); + static const _synMethod = Color(0xFFDCDCAA); + static const _synPunct = Color(0xFF858585); + + static const tokens = ClideTokens( + bg: _bg, bgSunken: _bgSunken, surface: _surface, surfaceHi: _surfaceHi, + border: _border, borderHi: _borderHi, + textHi: _textHi, text: _text, textDim: _textDim, textMute: _textMute, + accent: _accent, accentPress: _accentPress, accentSoft: _accentSoft, + ok: _ok, warn: _warn, err: _err, info: _info, + synKeyword: _synKeyword, synType: _synType, synString: _synString, + synNumber: _synNumber, synComment: _synComment, synMethod: _synMethod, + synPunct: _synPunct, + ); + + static ThemeData get data => ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + scaffoldBackgroundColor: _bg, + canvasColor: _bg, + colorScheme: const ColorScheme.dark( + primary: _accent, onPrimary: Color(0xFF0B1220), + secondary: _synKeyword, onSecondary: Color(0xFF0B1220), + surface: _surface, onSurface: _textHi, + surfaceContainerHighest: _surfaceHi, + outline: _border, outlineVariant: _borderHi, + error: _err, onError: Color(0xFF0B1220), + ), + textTheme: const TextTheme( + displayLarge: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 48, color: _textHi), + displayMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 34, color: _textHi), + headlineSmall: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 20, color: _textHi), + titleMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 14, color: _text), + labelSmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w500, fontSize: 10, letterSpacing: 1.0, color: _textMute), + bodyMedium: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 12, height: 1.45, color: _textHi), + bodySmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 11, color: _text), + ), + dividerTheme: const DividerThemeData(color: _border, thickness: 1, space: 1), + iconTheme: const IconThemeData(color: _textDim, size: 14), + ); +} diff --git a/docs/claude-design/themes/paper_theme.dart b/docs/claude-design/themes/paper_theme.dart new file mode 100644 index 00000000..71d610ba --- /dev/null +++ b/docs/claude-design/themes/paper_theme.dart @@ -0,0 +1,76 @@ +// paper_theme.dart +// +// Paper — carries the wireframe aesthetic into the product. +// Off-white drafting sheet, near-black ink, red-pencil accent for annotations. + +import 'package:flutter/material.dart'; +import 'clide_theme.dart' show ClideTokens; + +class PaperTheme { + static const _bg = Color(0xFFF4F1EA); // paper + static const _bgSunken = Color(0xFFECE7DB); // paper-2 + static const _surface = Color(0xFFFBF8F1); + static const _surfaceHi = Color(0xFFECE7DB); + static const _border = Color(0xFF1A1A1A); + static const _borderHi = Color(0xFF4A4A4A); + + static const _textHi = Color(0xFF1A1A1A); // ink + static const _text = Color(0xFF4A4A4A); // ink-2 + static const _textDim = Color(0xFF8A8A82); // ink-3 + static const _textMute = Color(0xFFA8A89E); + + static const _accent = Color(0xFFC14B2A); // red pencil + static const _accentPress = Color(0xFFA03D20); + static const _accentSoft = Color(0x22C14B2A); + + static const _ok = Color(0xFF2D8A52); + static const _warn = Color(0xFFB88A2A); + static const _err = Color(0xFFB03A2A); + static const _info = Color(0xFF2A6FC1); + + // Syntax tuned for cream paper — desaturated so code reads like print. + static const _synKeyword = Color(0xFF7B3F8C); + static const _synType = Color(0xFF2A6FC1); + static const _synString = Color(0xFF2D8A52); + static const _synNumber = Color(0xFFB88A2A); + static const _synComment = Color(0xFF8A8A82); + static const _synMethod = Color(0xFF1E5D9E); + static const _synPunct = Color(0xFF4A4A4A); + + static const tokens = ClideTokens( + bg: _bg, bgSunken: _bgSunken, surface: _surface, surfaceHi: _surfaceHi, + border: _border, borderHi: _borderHi, + textHi: _textHi, text: _text, textDim: _textDim, textMute: _textMute, + accent: _accent, accentPress: _accentPress, accentSoft: _accentSoft, + ok: _ok, warn: _warn, err: _err, info: _info, + synKeyword: _synKeyword, synType: _synType, synString: _synString, + synNumber: _synNumber, synComment: _synComment, synMethod: _synMethod, + synPunct: _synPunct, + ); + + static ThemeData get data => ThemeData( + useMaterial3: true, + brightness: Brightness.light, + scaffoldBackgroundColor: _bg, + canvasColor: _bg, + colorScheme: const ColorScheme.light( + primary: _accent, onPrimary: Color(0xFFFBF8F1), + secondary: _info, onSecondary: Color(0xFFFBF8F1), + surface: _surface, onSurface: _textHi, + surfaceContainerHighest: _surfaceHi, + outline: _border, outlineVariant: _borderHi, + error: _err, onError: Color(0xFFFBF8F1), + ), + textTheme: const TextTheme( + displayLarge: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 48, color: _textHi), + displayMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 34, color: _textHi), + headlineSmall: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 20, color: _textHi), + titleMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 14, color: _text), + labelSmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w500, fontSize: 10, letterSpacing: 1.0, color: _textDim), + bodyMedium: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 12, height: 1.45, color: _textHi), + bodySmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 11, color: _text), + ), + dividerTheme: const DividerThemeData(color: _border, thickness: 1, space: 1), + iconTheme: const IconThemeData(color: _text, size: 14), + ); +} diff --git a/docs/claude-design/themes/terminal_theme.dart b/docs/claude-design/themes/terminal_theme.dart new file mode 100644 index 00000000..edaa8fef --- /dev/null +++ b/docs/claude-design/themes/terminal_theme.dart @@ -0,0 +1,77 @@ +// terminal_theme.dart +// +// Terminal — near-black bg, high-contrast mono, single amber accent. +// For users who want the IDE to read like a tmux window. + +import 'package:flutter/material.dart'; +import 'clide_theme.dart' show ClideTokens; + +class TerminalTheme { + static const _bg = Color(0xFF0A0A0A); + static const _bgSunken = Color(0xFF000000); + static const _surface = Color(0xFF111111); + static const _surfaceHi = Color(0xFF181818); + static const _border = Color(0xFF242424); + static const _borderHi = Color(0xFF2E2E2E); + + static const _textHi = Color(0xFFE6E6E6); + static const _text = Color(0xFFBDBDBD); + static const _textDim = Color(0xFF7A7A7A); + static const _textMute = Color(0xFF4A4A4A); + + static const _accent = Color(0xFFE0B050); // amber + static const _accentPress = Color(0xFFC29438); + static const _accentSoft = Color(0x22E0B050); + + static const _ok = Color(0xFF8FDC9B); + static const _warn = Color(0xFFE0B050); + static const _err = Color(0xFFE05050); + static const _info = Color(0xFFA3C4FF); + + // Classic 16-color palette feel + static const _synKeyword = Color(0xFFE05050); + static const _synType = Color(0xFFE0B050); + static const _synString = Color(0xFF8FDC9B); + static const _synNumber = Color(0xFFC792EA); + static const _synComment = Color(0xFF4A4A4A); + static const _synMethod = Color(0xFFA3C4FF); + static const _synPunct = Color(0xFF7A7A7A); + + static const tokens = ClideTokens( + bg: _bg, bgSunken: _bgSunken, surface: _surface, surfaceHi: _surfaceHi, + border: _border, borderHi: _borderHi, + textHi: _textHi, text: _text, textDim: _textDim, textMute: _textMute, + accent: _accent, accentPress: _accentPress, accentSoft: _accentSoft, + ok: _ok, warn: _warn, err: _err, info: _info, + synKeyword: _synKeyword, synType: _synType, synString: _synString, + synNumber: _synNumber, synComment: _synComment, synMethod: _synMethod, + synPunct: _synPunct, + ); + + static ThemeData get data => ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + scaffoldBackgroundColor: _bg, + canvasColor: _bg, + colorScheme: const ColorScheme.dark( + primary: _accent, onPrimary: Color(0xFF000000), + secondary: _info, onSecondary: Color(0xFF000000), + surface: _surface, onSurface: _textHi, + surfaceContainerHighest: _surfaceHi, + outline: _border, outlineVariant: _borderHi, + error: _err, onError: Color(0xFF000000), + ), + textTheme: const TextTheme( + displayLarge: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 48, color: _textHi), + displayMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w300, fontSize: 34, color: _textHi), + headlineSmall: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 20, color: _textHi), + titleMedium: TextStyle(fontFamily: 'Josefin Sans', fontWeight: FontWeight.w400, fontSize: 14, color: _text), + // Terminal mockups go full-mono even for display. + labelSmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w500, fontSize: 10, letterSpacing: 1.0, color: _textMute), + bodyMedium: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 12, height: 1.45, color: _textHi), + bodySmall: TextStyle(fontFamily: 'JetBrains Mono', fontWeight: FontWeight.w400, fontSize: 11, color: _text), + ), + dividerTheme: const DividerThemeData(color: _border, thickness: 1, space: 1), + iconTheme: const IconThemeData(color: _textDim, size: 14), + ); +}