eidotter 0.19.3 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,23 +1,42 @@
1
- # eiDotter - DOS Terminal Design System
1
+ # eiDotter
2
2
 
3
- A DOS-themed React component library with authentic CGA terminal aesthetics.
3
+ ```
4
+ ┌──────────────────────────────────────────────┐
5
+ │ C:\> EIDOTTER_ │
6
+ │ │
7
+ │ DOS terminal design system for React. │
8
+ │ Authentic CGA phosphor. WCAG AA. │
9
+ │ Tree-shakable. No CSS-in-JS runtime. │
10
+ └──────────────────────────────────────────────┘
11
+ ```
12
+
13
+ [![npm](https://img.shields.io/npm/v/eidotter.svg?color=ffb000&labelColor=020003&label=npm)](https://www.npmjs.com/package/eidotter)
14
+ [![CI](https://img.shields.io/github/actions/workflow/status/CinimoDY/eiDotter/build.yml?branch=main&color=ffb000&labelColor=020003&label=CI)](https://github.com/CinimoDY/eiDotter/actions/workflows/build.yml)
15
+ [![license](https://img.shields.io/badge/license-CC--BY--NC--4.0-ffb000?labelColor=020003)](./LICENSE.md)
16
+ [![React](https://img.shields.io/badge/React-18%20%7C%2019-ffb000?labelColor=020003)](https://react.dev/)
17
+
18
+ **eiDotter** is a React component library that takes the DOS/CGA terminal aesthetic seriously: authentic 16-color palette, bitmap-accurate typography, phosphor glow physics, keyboard-first interactions. 36 components across forms, navigation, windowing, timelines, and terminal chrome — shipped as ES modules with a prebuilt stylesheet so consumers don't need Tailwind to use it.
19
+
20
+ → **[Storybook](https://cinimody.github.io/eiDotter/)**  ·  **[CHANGELOG](./CHANGELOG.md)**  ·  **[Issues](https://github.com/CinimoDY/eiDotter/issues)**  ·  **[npm](https://www.npmjs.com/package/eidotter)**
21
+
22
+ ---
4
23
 
5
- ## Installation
24
+ ## Install
6
25
 
7
26
  ```bash
8
27
  npm install eidotter
9
28
  ```
10
29
 
11
- ## Quick Start
30
+ ## Quick start
12
31
 
13
32
  ```tsx
14
- import { Terminal, Button, Alert } from 'eidotter';
15
- import 'eidotter/styles'; // All styles: fonts, tokens, components
33
+ import { Terminal, Alert, Button } from 'eidotter';
34
+ import 'eidotter/styles';
16
35
 
17
36
  function App() {
18
37
  return (
19
38
  <Terminal title="MY-APP.EXE">
20
- <Alert type="info" title="Welcome">
39
+ <Alert color="success" title="System Ready">
21
40
  DOS interface loaded successfully.
22
41
  </Alert>
23
42
  <Button variant="primary">Execute</Button>
@@ -26,246 +45,174 @@ function App() {
26
45
  }
27
46
  ```
28
47
 
29
- ## Setup
30
-
31
- ### Basic (no Tailwind needed)
32
-
33
- Import the styles. All component styling, fonts, and design tokens are pre-compiled — no build tools required.
34
-
35
- ```tsx
36
- import 'eidotter/styles'; // Fonts, tokens, components, Tailwind utilities
48
+ A single CSS import pulls everything: font, tokens, component styles, and compiled Tailwind utilities. Tailwind is **not** required to use eiDotter — consume it as plain React + one stylesheet.
37
49
 
38
- // Optional: import a theme
39
- import 'eidotter/themes/amber-mono.css';
40
- ```
50
+ ## Setup
41
51
 
42
- Individual imports are still available for granular control:
52
+ ### Styles
43
53
 
44
54
  ```tsx
45
- import 'eidotter/fonts.css'; // Flexi IBM VGA True @font-face
46
- import 'eidotter/tokens.css'; // CSS variable definitions
47
- import 'eidotter/styles'; // Component CSS + Tailwind utilities
55
+ import 'eidotter/styles'; // Everything: font + tokens + components + utilities
56
+ import 'eidotter/themes/amber-mono.css'; // Optional: theme override
57
+ import 'eidotter/utilities'; // Optional: .dos-* typography classes for raw HTML
48
58
  ```
49
59
 
50
- **Font:** eiDotter uses [Flexi IBM VGA True v2](https://int10h.org/blog/2018/05/flexi-ibm-vga-scalable-truetype-font/) — an aspect-corrected vector remake of the IBM VGA BIOS font (CC BY-SA 4.0). The "True" variant matches authentic 4:3 VGA proportions with an extended character set (Greek, Cyrillic, Hebrew, Latin). The `fonts.css` import loads the bundled TTF via `@font-face`.
51
-
52
- Two fontFamily tokens are exported, with distinct intent:
60
+ Granular imports are still available (`eidotter/fonts.css`, `eidotter/tokens.css`) if you want to override the font or tokens independently.
53
61
 
54
- - **`font-dos`** → `"Flexi IBM VGA True", monospace` — the default. Preserves the terminal aesthetic on degraded `@font-face` loads (strict CSP, web-fonts disabled, reader mode).
55
- - **`font-dos-fallback`** → `monospace` only — intentionally bare, as a **fail-loud diagnostic** utility for surfaces that want to surface font-loading failures explicitly. Compose `font-dos font-dos-fallback` when you want strict Flexi-or-nothing behavior.
62
+ ### With Tailwind
56
63
 
57
- ### With Tailwind CSS
58
-
59
- Use eidotter's design tokens as Tailwind utility classes in your own code.
60
-
61
- ```bash
62
- npm install tailwindcss
63
- ```
64
+ If you already use Tailwind, register eiDotter's preset and drop the `eidotter/styles` import (the preset compiles utilities in your build):
64
65
 
65
66
  ```js
66
67
  // tailwind.config.js
67
68
  module.exports = {
68
69
  presets: [require('eidotter/tailwind.preset')],
69
- content: ['./src/**/*.{js,jsx,ts,tsx}'],
70
+ content: ['./src/**/*.{ts,tsx,jsx}'],
70
71
  };
71
72
  ```
72
73
 
73
74
  ```tsx
74
- // Now use eidotter tokens as Tailwind classes
75
75
  <div className="bg-dos-bg-primary text-dos-text-accent font-dos">
76
76
  DOS terminal content
77
77
  </div>
78
78
  ```
79
79
 
80
- The preset auto-registers `tailwindcss-react-aria-components` and `tailwindcss-animate` via require-if-available. Consumers who already list either plugin in their own Tailwind config may see duplicate-variant warnings from Tailwind — either rely on the preset's registration alone, or pass those plugins explicitly in your config (they're idempotent, but the duplicate registration is noisy).
80
+ The preset auto-registers `tailwindcss-react-aria-components` and `tailwindcss-animate` if they resolve. Migrating from the pre-0.19.2 dual-preset split? See [CHANGELOG → 0.19.2](./CHANGELOG.md#0192--2026-04-18).
81
81
 
82
- #### Migration from 0.19.1 and earlier
82
+ ## Documentation
83
83
 
84
- In 0.19.2 the two older presets (`eidotter/tailwind.preset` and `eidotter/tailwind.preset.enhanced`) were merged into a single `eidotter/tailwind.preset` that includes all tokens plus the React Aria + animate plugins. The enhanced subpath is now a deprecated alias that logs a one-time `console.warn` on load and will be removed in 0.21.0:
84
+ | | |
85
+ |---|---|
86
+ | **Live docs** | [Storybook](https://cinimody.github.io/eiDotter/) — every component with stories, controls, and source |
87
+ | **Design tokens** | `src/tokens/*.json` (DTCG format) → `tokens.css` via Style Dictionary |
88
+ | **Themes** | `amber-mono` (default), `cga-amber`, `cga-mode4-p0/p1`, `cga-mode5` |
89
+ | **Font** | [Flexi IBM VGA True v2](https://int10h.org/blog/2018/05/flexi-ibm-vga-scalable-truetype-font/) — aspect-corrected vector remake of the IBM VGA BIOS, CC BY-SA 4.0. Bitmap-authentic single-weight; all `fontWeight` tokens resolve to 400 |
90
+ | **Icons** | [pixelarticons](https://github.com/halfmage/pixelarticons) (MIT) — DOS pixel-art glyphs |
91
+ | **Accessibility** | WCAG AA, React Aria primitives under interactive components, `prefers-reduced-motion` + `prefers-contrast` honored throughout |
85
92
 
86
- ```diff
87
- - presets: [require('eidotter/tailwind.preset.enhanced')]
88
- + presets: [require('eidotter/tailwind.preset')]
89
- ```
93
+ ## Components
90
94
 
91
- No behavior change — the merged preset already carries everything the enhanced preset used to add.
92
-
93
- ## Available Components (33)
94
-
95
- | Component | Description |
96
- |-----------|-------------|
97
- | Accordion | Collapsible content sections (Section, AccordionFill) |
98
- | Alert | Inline alert banner with featured icon, actions, and 6 color variants |
99
- | Badge | Status indicators with variant support |
100
- | Breadcrumb | Navigation path display |
101
- | Button | DOS-style buttons (primary, secondary, ghost, link) |
102
- | Card | Content container with variants (elevated, bordered, glow, interactive, minimal, callout) |
103
- | ChatMessage | Chat message with role-based DOS styling and streaming cursor |
104
- | ChatHistory | Scrollable message list with auto-scroll and `role="log"` |
105
- | ChatInput | Multiline textarea with Enter-to-send |
106
- | ChatContainer | Composes ChatHistory + ChatInput — place inside Terminal for DOS chat |
107
- | Checkbox | DOS-style checkbox with `[X]` bracket indicator |
108
- | CommandPrompt | Interactive command-line input with blinking cursor |
109
- | FilterBar | Multi-select toggle group for faceted filtering |
110
- | Footer | Site footer with legal links (Impressum + Datenschutz) |
111
- | Header | Sticky site header composing branding + Nav — retro/modern variants |
112
- | Icon | SVG icons backed by pixelarticons (MIT) — authentic DOS pixel art |
113
- | InlineExpand | Inline disclosure widget for expanding text within prose |
114
- | Input | Text input with DOS styling and error variant |
115
- | Modal | Dialog overlay with title bar and close button |
116
- | Nav | Responsive navigation with desktop/mobile variants |
117
- | Notification | Toast popup with layered amber glow, auto-dismiss, and progress variant |
118
- | Progress | DOS-style progress bar with block characters |
119
- | RetroEffects | CRT effects (scanlines, noise, phosphor glow) |
120
- | Separator | Horizontal/vertical divider |
121
- | Stat | Key-value display for metrics and statistics |
122
- | Switch | Toggle switch for on/off states |
123
- | Tabs | Tabbed interface navigation |
124
- | Tag | Interactive labels for tags, categories, and filter chips |
125
- | Terminal | DOS window with title bar and content area |
126
- | TextScramble | DOS text decode/scramble animation effect |
127
- | TimelineContainer | Multi-zoom timeline with year/month/day/hour views |
128
- | TimelineNode | Timeline/stepper axis markers with shapes and glow |
129
- | Tokens | Design token reference display (Storybook only) |
130
-
131
- ## Component Examples
132
-
133
- ### Header
95
+ 36 components across five families — [complete catalog in Storybook](https://cinimody.github.io/eiDotter/).
134
96
 
135
- ```tsx
136
- <Header brandName="DMNC.TECH" items={navItems} variant="retro">
137
- {/* or use children for custom branding */}
138
- </Header>
139
- ```
97
+ <details>
98
+ <summary><strong>Windowing &amp; shell</strong> — Terminal, Modal, CommandPrompt, CmdPalette, Header, Footer, Nav</summary>
140
99
 
141
- ### Terminal
100
+ | Component | Purpose |
101
+ |---|---|
102
+ | `Terminal` | DOS window with title bar, minimize/maximize/close controls |
103
+ | `Modal` | Dialog overlay on React Aria primitives (ModalOverlay + Modal + Dialog) |
104
+ | `CommandPrompt` | Interactive command-line input with blinking cursor |
105
+ | `CmdPalette` | ⌘K overlay with scored search, keyboard nav, configurable hotkey |
106
+ | `Header` | Sticky site header (retro / modern variants), composes branding + Nav |
107
+ | `Footer` | Site footer with default legal links (Impressum + Datenschutz) |
108
+ | `Nav` | Responsive navigation with desktop + mobile variants |
142
109
 
143
- ```tsx
144
- <Terminal
145
- title="PROGRAM.EXE"
146
- size="medium"
147
- closeable
148
- onClose={() => console.log('closed')}
149
- >
150
- <p>Terminal content here</p>
151
- </Terminal>
152
- ```
110
+ </details>
153
111
 
154
- ### Button
112
+ <details>
113
+ <summary><strong>Content surfaces</strong> — Card, Accordion, Alert, Badge, Tag, Notification, Stat, Progress, Separator, Breadcrumb</summary>
155
114
 
156
- ```tsx
157
- <Button variant="primary" size="md">
158
- Click Me
159
- </Button>
115
+ | Component | Purpose |
116
+ |---|---|
117
+ | `Card` | Content container (elevated, bordered, glow, interactive, minimal, callout) |
118
+ | `Accordion` | Collapsible content sections (Section + AccordionFill) |
119
+ | `Alert` | Inline alert banner with featured icon, actions, 6 color variants |
120
+ | `Badge` | Status indicator chips |
121
+ | `Tag` | Interactive labels for tags, categories, filter chips |
122
+ | `Notification` | Toast popup with layered amber glow, auto-dismiss, progress variant |
123
+ | `Stat` | Key-value display for metrics |
124
+ | `Progress` | DOS-style progress bar with block characters |
125
+ | `Separator` | Horizontal / vertical divider |
126
+ | `Breadcrumb` | Navigation path display |
160
127
 
161
- <Button variant="ghost" loading>
162
- Processing...
163
- </Button>
164
- ```
128
+ </details>
165
129
 
166
- ### Alert
130
+ <details>
131
+ <summary><strong>Input</strong> — Button, Input, Checkbox, Switch, Tabs, FilterBar</summary>
167
132
 
168
- ```tsx
169
- <Alert
170
- type="warning"
171
- title="Low Disk Space"
172
- onClose={() => {}}
173
- >
174
- Drive C: has only 640KB remaining.
175
- </Alert>
176
- ```
133
+ | Component | Purpose |
134
+ |---|---|
135
+ | `Button` | DOS-style buttons (primary, secondary, ghost, link) on React Aria `Button` |
136
+ | `Input` | Text input with error variant, React Aria `TextField` |
137
+ | `Checkbox` | `[X]`-bracket indicator, React Aria `Checkbox` |
138
+ | `Switch` | Toggle on/off, React Aria `Switch` |
139
+ | `Tabs` | Tabbed navigation on React Aria `TabList/Tab/TabPanel` |
140
+ | `FilterBar` | Multi-select toggle group for faceted filtering |
177
141
 
178
- ### Input
142
+ </details>
179
143
 
180
- ```tsx
181
- <Input
182
- label="Filename"
183
- placeholder="Enter filename..."
184
- />
185
-
186
- <Input
187
- variant="error"
188
- errorMessage="File not found"
189
- placeholder="Invalid path"
190
- />
191
- ```
144
+ <details>
145
+ <summary><strong>Chat &amp; media</strong> — ChatMessage, ChatHistory, ChatInput, ChatContainer, DosFigure, Icon, InlineLink, InlineExpand</summary>
192
146
 
193
- ### Checkbox
147
+ | Component | Purpose |
148
+ |---|---|
149
+ | `ChatMessage` | Chat message with role-based DOS styling and streaming cursor |
150
+ | `ChatHistory` | Scrollable message list with auto-scroll + `role="log"` |
151
+ | `ChatInput` | Multiline textarea with Enter-to-send |
152
+ | `ChatContainer` | Composes ChatHistory + ChatInput — drop inside Terminal |
153
+ | `DosFigure` | Demoscene painted-screen media placeholder with scanline sweep |
154
+ | `Icon` | SVG icons backed by pixelarticons |
155
+ | `InlineLink` | In-flow anchor with dotted underline + `▸` / `↗` glyph |
156
+ | `InlineExpand` | Inline disclosure widget for prose |
194
157
 
195
- ```tsx
196
- <Checkbox label="Remember me" />
197
- <Checkbox label="Accept terms" checked />
198
- <Checkbox label="Select all" indeterminate />
199
- ```
158
+ </details>
200
159
 
201
- ### CommandPrompt
160
+ <details>
161
+ <summary><strong>Time &amp; effects</strong> — TimelineContainer, TimelineNode, TextScramble, RetroEffects, Tokens</summary>
202
162
 
203
- ```tsx
204
- <CommandPrompt
205
- prompt="C:\>"
206
- onCommand={(cmd) => console.log('Executing:', cmd)}
207
- autoFocus
208
- />
209
- ```
163
+ | Component | Purpose |
164
+ |---|---|
165
+ | `TimelineContainer` | Multi-zoom timeline (year / month / day / hour views) |
166
+ | `TimelineNode` | Axis markers with shape variants and glow |
167
+ | `TextScramble` | DOS text decode animation |
168
+ | `RetroEffects` | CRT scanlines, noise, phosphor glow |
169
+ | `Tokens` | Design-token reference display (Storybook only) |
210
170
 
211
- ## Design Tokens
171
+ </details>
212
172
 
213
- The library uses authentic CGA colors via CSS custom properties:
173
+ ## Design tokens
174
+
175
+ Authentic 16-color CGA palette plus amber/phosphor variants, exposed as CSS custom properties:
214
176
 
215
177
  ```css
216
- --color-cga-amber: #FFB000; /* Primary accent */
178
+ --color-cga-amber: #FFB000; /* Primary accent */
217
179
  --color-cga-amber-bright: #FDCA9F;
218
180
  --color-cga-amber-dim: #9A5700;
219
- --color-cga-black: #020003; /* Background */
220
- /* ... full 16-color CGA palette */
181
+ --color-cga-black: #020003; /* Background */
182
+ /* …16-color CGA palette + semantic tokens */
221
183
  ```
222
184
 
223
- ### Theming
185
+ Semantic tokens (`--color-semantic-*`) and Tailwind classes (`bg-dos-*`, `text-dos-*`, `border-dos-*`) are the preferred surface — the raw CGA names are primitives. Full reference in [`src/styles/tokens.css`](./src/styles/tokens.css) or in Storybook's Tokens page.
224
186
 
225
- Apply themes via `data-theme` attribute:
187
+ **Theming** is attribute-driven:
226
188
 
227
189
  ```html
228
- <div data-theme="amber-mono">
229
- <!-- Amber-on-black terminal aesthetic -->
230
- </div>
190
+ <div data-theme="amber-mono">…</div>
231
191
  ```
232
192
 
233
- Available themes: `amber-mono`, `cga-amber`, `cga-mode4-p0`, `cga-mode4-p1`, `cga-mode5`.
234
-
235
- ### Tailwind Token Classes
236
-
237
- **CGA Colors:** `cga-black`, `cga-blue`, `cga-green`, `cga-cyan`, `cga-red`, `cga-magenta`, `cga-brown`, `cga-light-gray`, `cga-dark-gray`, `cga-bright-blue`, `cga-bright-green`, `cga-bright-cyan`, `cga-bright-red`, `cga-bright-magenta`, `cga-yellow`, `cga-white`, `cga-amber`, `cga-amber-bright`, `cga-amber-dim`
238
-
239
- **Semantic Colors:** `dos-bg-primary`, `dos-bg-secondary`, `dos-text-primary`, `dos-text-accent`, `dos-border-default`, `dos-border-focus`, `dos-success`, `dos-warning`, `dos-error`, `dos-info`
240
-
241
- **Typography:** `font-dos` (Flexi IBM VGA True v2), `text-dos-text-xs` through `text-dos-display-2xl`, `leading-dos-text-xs` through `leading-dos-display-2xl`
242
-
243
- **Spacing:** 4px grid via design tokens
244
-
245
- **Border Radius:** `rounded-dos-sm` (2px), `rounded-dos-base` (4px max)
246
-
247
193
  ## Development
248
194
 
249
195
  ```bash
250
- npm install # Install dependencies
251
- npm run storybook # Launch Storybook on port 6006
252
- npm run build # Production build
253
- npm run test # Run test suite
254
- npm run lint # ESLint
196
+ npm install
197
+ npm run storybook # Launch Storybook on :6006
198
+ npm run build # Production build (tsup + tsc)
199
+ npm run test # Jest + React Testing Library
200
+ npm run lint # ESLint
201
+ npm run build-tokens # Rebuild tokens from src/tokens/*.json
255
202
  ```
256
203
 
257
- ## Design Philosophy
258
-
259
- The DOS aesthetic represents values we've lost in modern software:
204
+ ## Design notes
260
205
 
261
- - **Control** - Every command is explicit and intentional
262
- - **Clarity** - Information presented without distraction
263
- - **Personal Sovereignty** - Your tools, your way
206
+ eiDotter commits to the constraints that other "DOS-inspired" systems relax:
264
207
 
265
- eiDotter brings these values to modern interfaces while maintaining accessibility (WCAG AA) and usability standards. The authentic 16-color CGA palette plus amber phosphor variants creates that terminal feel without sacrificing readability.
208
+ - **16 colors, no more.** The palette is a historical fact, not a starting point. Extensions (amber, green, phosphor variants) are declared themes, not ad-hoc hex codes.
209
+ - **Single-weight typography.** Flexi IBM VGA True is a bitmap font; there's no bold. All `fontWeight` tokens resolve to `400` and `font-synthesis: none` blocks browser faux-bold. Emphasis comes from color, uppercase on labels, or inverse video — never weight.
210
+ - **Phosphor as physics, not decoration.** Warmup animations, glow layers, and scanline effects are wired into component states; consumers don't opt in per-component.
211
+ - **Keyboard-first.** React Aria powers every interactive component. Focus rings are loud amber on amber-dim. `prefers-reduced-motion` and `prefers-contrast` are honored across the board.
212
+ - **Tree-shakable, no CSS-in-JS.** Runtime deps are minimal and on-purpose: [React Aria](https://react-spectrum.adobe.com/react-aria/) + [pixelarticons](https://github.com/halfmage/pixelarticons), both MIT. Component CSS ships compiled; you pay no CSS-in-JS cost at runtime.
266
213
 
267
- Part of the **Timeline OS** ecosystem - a vision for personal data management along temporal, thematic, and social axes.
214
+ The aesthetic is a constraint the system holds itself to — not a theme that can be turned off.
268
215
 
269
216
  ## License
270
217
 
271
- CC-BY-NC-4.0 (Creative Commons Attribution-NonCommercial 4.0 International)
218
+ [CC-BY-NC-4.0](./LICENSE.md) — Creative Commons Attribution-NonCommercial 4.0 International. Bundled third-party licenses (pixelarticons MIT, Flexi IBM VGA True CC BY-SA 4.0) attributed in `LICENSE.md`.
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { HTMLAttributes } from 'react';
3
+ export interface BrandLockupProps extends HTMLAttributes<HTMLDivElement> {
4
+ /** Logo size in pixels. Defaults to 32. */
5
+ logoSize?: number | string;
6
+ /** Render only the logo (no wordmark). */
7
+ iconOnly?: boolean;
8
+ /** Render only the wordmark (no logo). */
9
+ wordmarkOnly?: boolean;
10
+ /** Add amber phosphor glow on both logo + wordmark. Defaults to true. */
11
+ glow?: boolean;
12
+ }
13
+ /**
14
+ * eiDotter brand lockup — Logo + Wordmark composed horizontally.
15
+ *
16
+ * The canonical public-facing brand mark. Scales by setting the host's
17
+ * `font-size` (wordmark) and `logoSize` prop (icon). The two should stay
18
+ * proportional: roughly `logoSize ≈ font-size × 1.75`.
19
+ */
20
+ export declare const BrandLockup: React.ForwardRefExoticComponent<BrandLockupProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import type { SVGProps } from 'react';
3
+ import './Brand.css';
4
+ export interface LogoProps extends Omit<SVGProps<SVGSVGElement>, 'viewBox' | 'children'> {
5
+ /** Icon size in pixels. Defaults to 32. Pass a number or CSS-valid string. */
6
+ size?: number | string;
7
+ /** Add the amber phosphor drop-shadow glow. Defaults to true. */
8
+ glow?: boolean;
9
+ /** Accessible label. Defaults to "eiDotter". Set to empty string for decorative use. */
10
+ title?: string;
11
+ }
12
+ /**
13
+ * eiDotter brand mark — V2 yolk (pure, no legs).
14
+ *
15
+ * The "payload" of the eiDotter identity — a bright CGA amber yolk with a soft
16
+ * highlight and specular, no shell or drip ornamentation. Scales cleanly from
17
+ * 16px (favicon) to hero sizes without the 1px shell outline collapsing into
18
+ * mush at small sizes.
19
+ *
20
+ * Fill colors are brand-locked (explicit amber hexes) rather than themed so the
21
+ * mark reads identically across themes. Consumers who need a non-amber treatment
22
+ * can override the SVG fills via the `style` prop or by recoloring the child
23
+ * `<circle>` elements through a CSS selector.
24
+ */
25
+ export declare const Logo: React.ForwardRefExoticComponent<Omit<LogoProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import type { HTMLAttributes } from 'react';
3
+ import './Brand.css';
4
+ export interface WordmarkProps extends HTMLAttributes<HTMLSpanElement> {
5
+ /** Add the amber phosphor text-shadow glow. Defaults to true. */
6
+ glow?: boolean;
7
+ }
8
+ /**
9
+ * eiDotter wordmark — "eiDotter" with the "ei" prefix dimmed against the full-bright "Dotter".
10
+ *
11
+ * Uses the primary DOS font (Flexi IBM VGA True) and the amber phosphor palette.
12
+ * Sized via `font-size` on the host; the component does not set its own size by
13
+ * default so it inherits from the surrounding type scale. Wrap in a heading
14
+ * element if you need semantic weight.
15
+ */
16
+ export declare const Wordmark: React.ForwardRefExoticComponent<WordmarkProps & React.RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,6 @@
1
+ export { Logo } from './Logo';
2
+ export type { LogoProps } from './Logo';
3
+ export { Wordmark } from './Wordmark';
4
+ export type { WordmarkProps } from './Wordmark';
5
+ export { BrandLockup } from './BrandLockup';
6
+ export type { BrandLockupProps } from './BrandLockup';
@@ -0,0 +1 @@
1
+ export * from './components';
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import './CmdPalette.css';
3
+ export interface CmdPaletteItem {
4
+ /** Stable identifier for React keys and `onSelect` lookups. */
5
+ id: string;
6
+ /** Primary label shown in the list. Uppercase recommended. */
7
+ label: string;
8
+ /** Optional secondary hint shown on the right (shortcut, type, etc.). */
9
+ hint?: React.ReactNode;
10
+ /** Additional keywords that contribute to search matching. */
11
+ keywords?: string[];
12
+ /** Optional type tag used for grouping/filtering by callers. */
13
+ type?: string;
14
+ /** Called when the item is activated via click or Enter. */
15
+ onSelect?: (item: CmdPaletteItem) => void;
16
+ }
17
+ export interface CmdPaletteProps {
18
+ /** Controlled open state. */
19
+ open: boolean;
20
+ /**
21
+ * Called when the overlay requests open/close (Escape, backdrop click,
22
+ * item selection, hotkey toggle).
23
+ */
24
+ onOpenChange: (open: boolean) => void;
25
+ /** Items to search. Pure data — parent owns the list. */
26
+ items: CmdPaletteItem[];
27
+ /** Input placeholder. */
28
+ placeholder?: string;
29
+ /** Global activation hotkey. `"mod+k"`, `"mod+shift+p"`, or `false` to disable. */
30
+ hotkey?: string | false;
31
+ /** Message shown when search matches nothing. */
32
+ emptyMessage?: React.ReactNode;
33
+ /** Footer hint row text / JSX. Pass `null` to hide. */
34
+ footerHint?: React.ReactNode;
35
+ /** Custom renderer for each row. Falls back to label + hint. */
36
+ renderItem?: (item: CmdPaletteItem, isSelected: boolean) => React.ReactNode;
37
+ /** Cap on filtered result rows. */
38
+ maxResults?: number;
39
+ /** Extra class names merged onto the dialog container. */
40
+ className?: string;
41
+ /** Accessible dialog label. */
42
+ 'aria-label'?: string;
43
+ }
44
+ /**
45
+ * CmdPalette — ⌘K / Ctrl+K launcher overlay.
46
+ *
47
+ * Controlled component. Parent owns `open` and item list; CmdPalette handles
48
+ * search, keyboard navigation, focus management, and hotkey binding.
49
+ *
50
+ * Built on React Aria `ModalOverlay` + `Modal` + `Dialog` — same primitives
51
+ * as `<Modal>` — so focus trap, Esc-to-close, and backdrop dismissal are
52
+ * standard.
53
+ */
54
+ export declare const CmdPalette: React.ForwardRefExoticComponent<CmdPaletteProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,2 @@
1
+ export { CmdPalette } from './CmdPalette';
2
+ export type { CmdPaletteProps, CmdPaletteItem } from './CmdPalette';
@@ -0,0 +1,2 @@
1
+ export { CmdPalette } from './components';
2
+ export type { CmdPaletteProps, CmdPaletteItem } from './components';
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import './DosFigure.css';
3
+ export interface DosFigurePin {
4
+ /** Horizontal position as a percentage (0–100). */
5
+ x: number;
6
+ /** Vertical position as a percentage (0–100). */
7
+ y: number;
8
+ /** Pin label — short; renders next to the dot. */
9
+ label: string;
10
+ }
11
+ export interface DosFigureProps {
12
+ /** Title shown in the top chrome strip. Uppercase recommended. */
13
+ title?: string;
14
+ /** Resolution tag rendered bottom-right (e.g. `"640×480"`). */
15
+ resolution?: string;
16
+ /** Subject content — ASCII, SVG, or anything you'd "paint the screen" with. */
17
+ subject: React.ReactNode;
18
+ /** Caption rendered beneath the frame via `<figcaption>`. */
19
+ caption?: React.ReactNode;
20
+ /** Optional annotation pins positioned as percentages over the subject. */
21
+ pins?: DosFigurePin[];
22
+ /** Disables the scanline-sweep animation. Defaults to true (enabled). */
23
+ animated?: boolean;
24
+ /** Accessible label when `subject` has no inherent semantics. */
25
+ 'aria-label'?: string;
26
+ /** Extra class names merged onto the `<figure>` root. */
27
+ className?: string;
28
+ }
29
+ /**
30
+ * DosFigure — demoscene-style placeholder for media.
31
+ *
32
+ * Sierra / LucasArts / demoscene title cards painted the screen with a
33
+ * limited palette, dithering, and annotated frames. DosFigure recreates
34
+ * that aesthetic: amber chrome, scanline sweep, optional pins, and a
35
+ * resolution tag. Use as a lead-in for blog articles or as a placeholder
36
+ * where a photograph would otherwise go.
37
+ *
38
+ * Not intended as a replacement for semantic imagery — pass `aria-label`
39
+ * (or a `<figcaption>` via `caption`) so the figure is meaningful to AT.
40
+ */
41
+ export declare const DosFigure: React.ForwardRefExoticComponent<DosFigureProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,2 @@
1
+ export { DosFigure } from './DosFigure';
2
+ export type { DosFigureProps, DosFigurePin } from './DosFigure';
@@ -0,0 +1,2 @@
1
+ export { DosFigure } from './components';
2
+ export type { DosFigureProps, DosFigurePin } from './components';
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import './InlineLink.css';
3
+ export interface InlineLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> {
4
+ /** Link text. */
5
+ children: React.ReactNode;
6
+ /** Target URL. */
7
+ href: string;
8
+ /**
9
+ * Render the trailing glyph (`▸` for internal, `↗` for `external`).
10
+ * Defaults to `true`. When `false`, no glyph renders regardless of the
11
+ * `external` prop.
12
+ */
13
+ showGlyph?: boolean;
14
+ /**
15
+ * External link — adds `target="_blank"` and `rel="noopener noreferrer"`
16
+ * (safe tabnabbing defaults) and, when `showGlyph` is `true`, swaps the
17
+ * trailing glyph to `↗`. `showGlyph={false}` still suppresses the glyph.
18
+ */
19
+ external?: boolean;
20
+ /** Extra class names merged onto the root anchor. */
21
+ className?: string;
22
+ }
23
+ /**
24
+ * In-flow navigational anchor. Distinct from `<InlineExpand>` — this is a
25
+ * destination, not a disclosure.
26
+ *
27
+ * Rest: dotted amber underline, trailing `▸`.
28
+ * Hover: phosphor inversion — amber background, dark foreground.
29
+ * Visited: dimmed amber (`--color-cga-amber-dim` → brown fallback).
30
+ * External: opens in a new tab safely, trailing glyph becomes `↗`.
31
+ *
32
+ * Consumer-passed `target="_blank"` is treated as implicit-external for
33
+ * `rel` safety — a `rel` is auto-applied if none is provided, preventing
34
+ * tabnabbing even when the caller doesn't explicitly set `external`.
35
+ */
36
+ export declare const InlineLink: React.ForwardRefExoticComponent<InlineLinkProps & React.RefAttributes<HTMLAnchorElement>>;
@@ -0,0 +1,2 @@
1
+ export { InlineLink } from './InlineLink';
2
+ export type { InlineLinkProps } from './InlineLink';
@@ -0,0 +1,2 @@
1
+ export { InlineLink } from './components';
2
+ export type { InlineLinkProps } from './components';