@shiinasaku/github-card 2.0.0 → 4.1.0

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,354 +1,195 @@
1
- # GitHub Profile Card
2
-
3
1
  <div align="center">
4
2
 
5
- <br/>
6
-
7
- <picture>
8
- <source media="(prefers-color-scheme: dark)" srcset="https://card.shiina.xyz/card/ShiinaSaku?theme=github_dark" />
9
- <img src="https://card.shiina.xyz/card/ShiinaSaku" alt="GitHub Profile Card" width="500" />
10
- </picture>
3
+ <img src="assets/logo.svg" alt="GitHub Card" width="480" />
11
4
 
12
- <br/><br/>
5
+ # GitHub Card
13
6
 
14
- # github-card
7
+ **Beautiful, blazing-fast GitHub profile cards as dynamic SVGs.**
8
+ Drop one line in your README — get a live, auto-updating stats card.
15
9
 
16
- **Beautiful GitHub stats cards for your README, site, or npm project.**
10
+ [![Bun](https://img.shields.io/badge/Bun-1.x-f9f1e1?style=flat-square&logo=bun&logoColor=000)](assets/bun.svg)
11
+ [![Elysia](https://img.shields.io/badge/ElysiaJS-1.x-7c3aed?style=flat-square)](assets/elysia.svg)
12
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square&logo=typescript&logoColor=fff)](https://www.typescriptlang.org)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-34d399?style=flat-square)](LICENSE)
14
+ [![Deploy with Vercel](https://img.shields.io/badge/Deploy-Vercel-000?style=flat-square&logo=vercel)](https://vercel.com/new/clone?repository-url=https://github.com/ShiinaSaku/Github-Card)
17
15
 
18
- [![npm](https://img.shields.io/npm/v/github-card?style=flat&colorA=0b1220&colorB=58a6ff)](https://www.npmjs.com/package/github-card)
19
- [![Built with Bun](https://img.shields.io/badge/Bun-000?style=flat&logo=bun&logoColor=ffd700)](https://bun.sh)
20
- [![MIT](https://img.shields.io/badge/License-MIT-green?style=flat)](LICENSE)
21
- [![Tests](https://img.shields.io/badge/Tests-21%20passed-34d399?style=flat)](#testing)
22
-
23
- [Live Demo](https://card.shiina.xyz/card/ShiinaSaku) &#183;
24
- [All Themes](https://card.shiina.xyz/ShiinaSaku/themes) &#183;
25
- [API Docs](https://card.shiina.xyz/openapi) &#183;
26
- [npm Package](#programmatic-usage-npm)
16
+ <img src="https://card.shiina.xyz/card/shiinasaku?theme=shiina" alt="Live demo card" width="500" />
27
17
 
28
18
  </div>
29
19
 
30
20
  ---
31
21
 
32
- ## Embed in 10 seconds
22
+ ## Quickstart
33
23
 
34
- ```markdown
35
- ![GitHub Stats](https://card.shiina.xyz/card/YOUR_USERNAME)
36
- ```
24
+ Paste this into your profile README (replace `shiinasaku` with your username):
37
25
 
38
- Replace `YOUR_USERNAME`. Done.
26
+ ```md
27
+ [![GitHub Card](https://card.shiina.xyz/card/shiinasaku?theme=shiina)](https://github.com/shiinasaku)
28
+ ```
39
29
 
40
- ### Dark mode aware
30
+ That's it. No sign-up, no build step — the card updates itself as you code.
41
31
 
42
- ```html
43
- <picture>
44
- <source
45
- media="(prefers-color-scheme: dark)"
46
- srcset="https://card.shiina.xyz/card/YOUR_USERNAME?theme=github_dark"
47
- />
48
- <img src="https://card.shiina.xyz/card/YOUR_USERNAME" alt="GitHub Stats" />
49
- </picture>
50
- ```
32
+ ## Why GitHub Card?
51
33
 
52
- ---
34
+ - **One line, zero config** — an `<img>` tag is the entire integration.
35
+ - **Edge-fast** — two-tier cache (in-memory + Redis) with stale-while-revalidate, ETag/304 support, and CDN cache headers. Warm requests render in microseconds.
36
+ - **21 hand-tuned themes** — plus full per-slot color overrides with hex _or_ Tailwind palette tokens.
37
+ - **Retina avatars** — profile images inlined as Base64 at 2x resolution.
38
+ - **Adaptive layout** — width, text wrapping, and language legends are computed mathematically; nothing ever overlaps.
39
+ - **Users _and_ orgs** — works for organization accounts out of the box.
40
+ - **Glassmorphic depth** — layered ambient gradients track your accent color for volumetric light with zero runtime cost (pure SVG).
41
+ - **OpenAPI documented** — explore the API interactively at [`/openapi`](https://card.shiina.xyz/openapi).
53
42
 
54
43
  ## Themes
55
44
 
56
- 20 built-in themes. Pass `?theme=name` to use one.
57
-
58
- <table>
59
- <tr>
60
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=default" width="400" alt="default" /><br/><code>default</code></td>
61
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=github_dark" width="400" alt="github_dark" /><br/><code>github_dark</code></td>
62
- </tr>
63
- <tr>
64
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=tokyonight" width="400" alt="tokyonight" /><br/><code>tokyonight</code></td>
65
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=dracula" width="400" alt="dracula" /><br/><code>dracula</code></td>
66
- </tr>
67
- <tr>
68
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=nord" width="400" alt="nord" /><br/><code>nord</code></td>
69
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=radical" width="400" alt="radical" /><br/><code>radical</code></td>
70
- </tr>
71
- <tr>
72
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=synthwave" width="400" alt="synthwave" /><br/><code>synthwave</code></td>
73
- <td align="center"><img src="https://card.shiina.xyz/card/ShiinaSaku?theme=rose" width="400" alt="rose" /><br/><code>rose</code></td>
74
- </tr>
75
- </table>
76
-
77
- <details>
78
- <summary><strong>All 20 themes</strong></summary>
79
- <br/>
80
-
81
- `default` `dark` `radical` `merko` `gruvbox` `tokyonight` `onedark` `cobalt` `synthwave` `highcontrast` `dracula` `monokai` `nord` `github_dark` `pearl` `slate` `forest` `rose` `sand`
82
-
83
- Preview every theme with your own data:
45
+ Preview **every** theme with your own data:
46
+
47
+ ```md
48
+ ![All themes](https://card.shiina.xyz/shiinasaku/themes)
49
+ ```
50
+
51
+ | Dark favorites | Light & accent |
52
+ | -------------------------------------------------- | ------------------------------------------------ |
53
+ | `shiina` · `aurora` · `oled` · `slate` | `default` · `pearl` · `sand` |
54
+ | `github_dark` · `dark` · `nord` · `dracula` | `forest` · `rose` · `cobalt` |
55
+ | `tokyonight` · `synthwave` · `radical` · `monokai` | `gruvbox` · `merko` · `onedark` · `highcontrast` |
56
+
57
+ ## Customization
58
+
59
+ Every visual slot is overridable. Colors accept hex (`ff79c6` or `#ff79c6`) and Tailwind tokens (`pink-400`).
60
+
61
+ | Parameter | Type | Description |
62
+ | -------------- | -------- | ------------------------------------------------------------------ |
63
+ | `theme` | string | Built-in theme name (see table above) |
64
+ | `bg_color` | string | Background fill |
65
+ | `title_color` | string | Name / title text |
66
+ | `text_color` | string | Stats, labels, and body text |
67
+ | `icon_color` | string | Stat icons and ambient glow |
68
+ | `border_color` | string | Card outline stroke |
69
+ | `hide_border` | boolean | Remove the card outline |
70
+ | `compact` | boolean | Slim layout: hides bio, pronouns, Twitter, and the language legend |
71
+ | `animate` | boolean | Fade-in stats + animated language bar |
72
+ | `hide` | string[] | Hide stats: `stars`, `commits`, `issues`, `repos`, `prs` |
73
+ | `hide_langs` | string[] | Exclude languages by name (`hide_langs=html,css`) |
74
+ | `show_langs` | string[] | Include _only_ these languages |
75
+ | `lang_count` | 1–10 | Number of top languages (default `5`) |
76
+ | `scope` | string | `personal` (default), `org`, or `all` contribution scope |
77
+ | `orgs` | string[] | Restrict org-scope stats to these organizations |
78
+ | `affiliations` | string | `affiliated` (default) or `owner` repositories |
79
+ | `fields` | string[] | Fetch only what you need (e.g. `fields=stats`) |
84
80
 
85
- ```
86
- https://card.shiina.xyz/YOUR_USERNAME/themes
87
- ```
81
+ ### Examples
88
82
 
89
- </details>
83
+ ```md
84
+ <!-- Dracula, no border, animated -->
90
85
 
91
- ---
86
+ ![card](https://card.shiina.xyz/card/shiinasaku?theme=dracula&hide_border=true&animate=true)
92
87
 
93
- ## Parameters
88
+ <!-- Fully custom colors -->
94
89
 
95
- All parameters are optional query strings on `/card/:username`.
90
+ ![card](https://card.shiina.xyz/card/shiinasaku?bg_color=0d1117&title_color=58a6ff&text_color=9da7b3&icon_color=58a6ff)
96
91
 
97
- ### Appearance
92
+ <!-- Compact, stats only, no languages -->
98
93
 
99
- | Parameter | Default | Description |
100
- | :------------ | :-------- | :----------------------------------- |
101
- | `theme` | `default` | One of the 20 built-in themes |
102
- | `compact` | `false` | Hides bio, pronouns, language labels |
103
- | `hide_border` | `false` | Removes the card border |
94
+ ![card](https://card.shiina.xyz/card/shiinasaku?compact=true&hide=issues,prs&fields=stats)
104
95
 
105
- ### Custom Colors
96
+ <!-- Organization card -->
106
97
 
107
- Pass hex values **without** `#`.
98
+ ![card](https://card.shiina.xyz/card/elysiajs)
99
+ ```
108
100
 
109
- | Parameter | Description |
110
- | :------------- | :----------------- |
111
- | `bg_color` | Background |
112
- | `title_color` | Name text |
113
- | `text_color` | Body text & labels |
114
- | `icon_color` | Stat icons |
115
- | `border_color` | Card border |
101
+ ## Deploy your own
116
102
 
117
- ### Data Filtering
103
+ [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/ShiinaSaku/Github-Card)
118
104
 
119
- | Parameter | Default | Description |
120
- | :----------- | :--------- | :---------------------------------------------------------------------- |
121
- | `lang_count` | `5` | Top languages shown (1--10) |
122
- | `hide` | -- | Comma-separated: `stars,commits,issues,repos,prs` |
123
- | `scope` | `personal` | `personal` / `org` / `all` -- see [scope details](#what-the-card-shows) |
124
- | `orgs` | -- | Comma-separated org logins to include (filters contributed-to repos) |
105
+ 1. Click the button above (or fork + import into Vercel).
106
+ 2. Add environment variables:
125
107
 
126
- ### Examples
108
+ | Variable | Required | Purpose |
109
+ | -------------- | -------- | ----------------------------------------- |
110
+ | `GITHUB_TOKEN` | ✅ | GitHub PAT (read-only is enough) |
111
+ | `REDIS_URL` | ➖ | Redis/Upstash URL for the shared L2 cache |
127
112
 
128
- ```bash
129
- # Compact with 3 languages
130
- https://card.shiina.xyz/card/ShiinaSaku?compact=true&lang_count=3
113
+ 3. Done. Your instance serves `/card/:username` on Vercel's CDN with `s-maxage=1800, stale-while-revalidate=1800`.
131
114
 
132
- # GitHub dark colors
133
- https://card.shiina.xyz/card/ShiinaSaku?bg_color=0d1117&text_color=c9d1d9&title_color=58a6ff
115
+ > Redis is optional — without it, the in-memory cache still keeps each warm instance fast.
134
116
 
135
- # Organization stats
136
- https://card.shiina.xyz/card/ShiinaSaku?scope=all&orgs=oven-sh,elysiajs
117
+ ## API
137
118
 
138
- # Hide specific stats
139
- https://card.shiina.xyz/card/ShiinaSaku?hide=issues,prs,stars
140
- ```
119
+ | Endpoint | Description |
120
+ | ----------------------- | ------------------------------------------- |
121
+ | `GET /card/:username` | SVG card (all query params above) |
122
+ | `GET /:username/themes` | One SVG showing **all themes** for a user |
123
+ | `GET /meta` | Service metadata + theme list |
124
+ | `GET /health` | Uptime, cache telemetry, Redis reachability |
125
+ | `GET /openapi` | Interactive OpenAPI docs |
141
126
 
142
- ---
127
+ Responses are `image/svg+xml` with `ETag`, CORS (`*`), and CDN cache headers. Conditional requests (`If-None-Match`) return `304`.
143
128
 
144
- ## Programmatic Usage (npm)
145
-
146
- Install the package to render cards in your own server, CLI tool, or script:
129
+ ## Use as a library
147
130
 
148
131
  ```bash
149
- bun add github-card # or npm install github-card
132
+ bun add @shiinasaku/github-card # Bun
133
+ npm install @shiinasaku/github-card # Node / Next.js / Vite
150
134
  ```
151
135
 
152
- ### Render SVG from data
153
-
154
- ```typescript
155
- import { renderCard, themes } from "github-card";
156
-
157
- const svg = renderCard(
158
- {
159
- login: "octocat",
160
- name: "The Octocat",
161
- avatarUrl: "https://github.com/octocat.png",
162
- bio: "Open source enthusiast",
163
- pronouns: "they/them",
164
- twitter: "github",
165
- },
166
- { stars: 3200, commits: 1450, issues: 89, repos: 42, prs: 210 },
167
- [
168
- { name: "TypeScript", size: 120000, color: "#3178c6" },
169
- { name: "Go", size: 80000, color: "#00ADD8" },
170
- { name: "Rust", size: 40000, color: "#dea584" },
171
- ],
172
- { theme: "tokyonight", compact: false },
173
- );
174
-
175
- // svg is a self-contained SVG string with embedded font
176
- ```
136
+ ```ts
137
+ import { renderCard, themes } from "@shiinasaku/github-card";
177
138
 
178
- ### Available exports
179
-
180
- ```typescript
181
- import {
182
- // Core renderer
183
- renderCard,
184
- type CardOpts,
185
-
186
- // Types
187
- type UserProfile,
188
- type UserStats,
189
- type LanguageStat,
190
- type ProfileData,
191
- type CardOptions,
192
-
193
- // Theming
194
- themes,
195
- resolveColors,
196
- type Theme,
197
-
198
- // Utilities
199
- kFormat, // 1500 -> "1.5k"
200
- escapeXml, // "<>" -> "&lt;&gt;"
201
- wrapText, // text wrapping with ellipsis
202
- icon, // SVG stat icons (star, commit, pr, issue, repo, x)
203
- icons, // raw SVG path data
204
- getLangColor, // language -> hex color (650+ languages)
205
- FONT_FACE, // base64 @font-face CSS rule
206
- FONT_FAMILY, // font-family declaration
207
- } from "github-card";
139
+ const svg = renderCard(user, stats, languages, { theme: "tokyonight" });
208
140
  ```
209
141
 
210
- ### Use as Elysia plugin
211
-
212
- The default export is an Elysia app. Mount it into your own server:
213
-
214
- ```typescript
215
- import { Elysia } from "elysia";
216
- import githubCard from "github-card/server";
142
+ Ships as a prebuilt ESM bundle with full `.d.ts` types (Bun resolves the raw TypeScript source automatically via the `bun` export condition). The renderer is pure — no server, no network, works in any JS runtime.
217
143
 
218
- new Elysia()
219
- .use(githubCard) // adds /card/:username, /:username/themes, etc.
220
- .get("/my-route", () => "hello")
221
- .listen(3000);
222
- ```
144
+ ## Releasing
223
145
 
224
- ---
146
+ Releases are fully automated:
225
147
 
226
- ## Self-Hosting
148
+ 1. **Actions → Bump** → choose `patch` / `minor` / `major`.
149
+ 2. The workflow bumps `package.json`, commits, and tags `vX.Y.Z`.
150
+ 3. The tag triggers **Release**: format, lint, typecheck, tests, dist build, tag↔version guard, `npm pack` verification, then publish to npm with [provenance](https://docs.npmjs.com/generating-provenance-statements) and a GitHub Release with auto-generated notes.
227
151
 
228
- ### Vercel (recommended)
229
-
230
- ```bash
231
- git clone https://github.com/ShiinaSaku/Github-Card.git
232
- cd Github-Card
233
- vercel deploy
234
- ```
235
-
236
- Set environment variables:
237
-
238
- ```
239
- GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx # required
240
- UPSTASH_REDIS_REST_URL=https://... # optional, L2 cache
241
- UPSTASH_REDIS_REST_TOKEN=... # optional
242
- ```
243
-
244
- ### Local Development
152
+ ## Local development
245
153
 
246
154
  ```bash
247
155
  bun install
248
- echo "GITHUB_TOKEN=ghp_xxx" > .env
249
- bun dev
250
- # http://localhost:3000/card/ShiinaSaku
156
+ cp .env.example .env # add your GITHUB_TOKEN
157
+ bun dev # http://localhost:3000
251
158
  ```
252
159
 
253
- ---
254
-
255
- ## API Reference
256
-
257
- | Endpoint | Returns |
258
- | :---------------------- | :------------------------------------------ |
259
- | `GET /card/:username` | SVG stats card |
260
- | `GET /:username/themes` | SVG grid of all themes |
261
- | `GET /health` | JSON -- cache metrics, Redis status, uptime |
262
- | `GET /openapi` | Interactive API documentation |
263
-
264
- ### Response Headers
265
-
266
- | Header | Value |
267
- | :---------------------------- | :-------------------------------------------------------------- |
268
- | `Cache-Control` | `public, max-age=0, s-maxage=1800, stale-while-revalidate=1800` |
269
- | `ETag` | Enables 304 Not Modified |
270
- | `Server-Timing` | Per-request timing telemetry |
271
- | `Access-Control-Allow-Origin` | `*` |
272
-
273
- ### Status Codes
274
-
275
- | Code | Meaning |
276
- | :--- | :------------------ |
277
- | 200 | SVG card |
278
- | 304 | Cached (ETag match) |
279
- | 401 | Bad GitHub token |
280
- | 404 | User not found |
281
- | 422 | Invalid parameters |
282
- | 429 | GitHub rate limited |
283
- | 502 | GitHub API down |
284
-
285
- ---
160
+ | Command | Action |
161
+ | ------------------- | --------------------- |
162
+ | `bun test` | Run the test suite |
163
+ | `bun run typecheck` | Strict `tsc --noEmit` |
164
+ | `bun run lint` | oxlint |
165
+ | `bun run fmt` | oxfmt |
286
166
 
287
167
  ## Architecture
288
168
 
289
169
  ```
290
- Request -> Elysia (CORS, OpenAPI, Server-Timing)
291
- -> GitHub GraphQL API (parallel personal + org fetches)
292
- -> L1 In-Memory Cache (30m fresh / 30m stale SWR)
293
- -> L2 Upstash Redis (optional, 60m TTL)
294
- -> SVG Renderer (embedded Roboto WOFF2 font)
295
- -> ETag / 304 / Cache-Control
296
- ```
297
-
298
- | Layer | Tech |
299
- | :-------- | :---------------------------------------- |
300
- | Runtime | Bun |
301
- | Framework | Elysia |
302
- | Data | GitHub GraphQL API |
303
- | Cache L1 | In-memory Map with SWR |
304
- | Cache L2 | Upstash Redis (serverless) |
305
- | Font | Roboto (subsetted WOFF2, base64 embedded) |
306
- | Deploy | Vercel Functions |
307
- | Tests | bun:test -- 21 tests |
308
- | Lint | oxlint + oxfmt |
309
-
310
- ---
311
-
312
- ## Testing
313
-
314
- ```bash
315
- bun test # 21 tests
316
- bun test --coverage # with coverage
317
- bun run typecheck # tsc
318
- bun run lint # oxlint
319
- ```
320
-
321
- ---
322
-
323
- ## What the card shows
324
-
325
- | Stat | Source |
326
- | :-------- | :------------------------------------- |
327
- | Stars | Total across owned repos (excl. forks) |
328
- | Commits | Current calendar year |
329
- | Issues | Open + closed |
330
- | Repos | Owned, non-fork |
331
- | PRs | Open + closed + merged |
332
- | Languages | Top N by code size |
333
-
334
- ### Scope
335
-
336
- | Value | Stars / Repos / Languages from | Speed |
337
- | :--------- | :--------------------------------------------------- | :--------------------------------- |
338
- | `personal` | Your own repos only | Single query |
339
- | `org` | Org repos you actually contributed to (commits, PRs) | Parallel: metadata + contributions |
340
- | `all` | Your repos + org repos you contributed to | Parallel: personal + contributions |
341
-
342
- Org stats use GitHub's `repositoriesContributedTo` API -- only repos you actually touched are counted, not every repo in the organization. Filter to specific orgs with `orgs=org1,org2`.
343
-
344
- ---
170
+ GET /card/:username
171
+
172
+
173
+ Elysia (validation, CORS, OpenAPI, server-timing)
174
+
175
+
176
+ L1 in-memory cache ──hit──► render SVG ──► ETag/304 ──► CDN
177
+ │miss ▲
178
+ ▼ │ stale-while-revalidate
179
+ L2 Redis (SWR) ──hit──► serve stale + background refresh
180
+ │miss
181
+
182
+ GitHub GraphQL (batched, paginated 100/page, 6s timeout)
183
+
184
+
185
+ Pure SVG renderer (zero-dependency, dynamic layout engine)
186
+ ```
187
+
188
+ - **Bun + Elysia** — one of the fastest HTTP stacks available.
189
+ - **Two-tier SWR cache** — users never wait on GitHub's API.
190
+ - **Request coalescing** — concurrent misses share a single upstream fetch.
191
+ - **Defensive upstream** — timeouts, size caps, and typed errors (`401/404/429/502`).
345
192
 
346
193
  ## License
347
194
 
348
- [MIT](LICENSE)
349
-
350
- ---
351
-
352
- <div align="center">
353
- <sub>Built with <a href="https://bun.sh">Bun</a> and <a href="https://elysiajs.com">Elysia</a>. Hosted on <a href="https://vercel.com">Vercel</a>.</sub>
354
- </div>
195
+ [MIT](LICENSE) © [saku shiina](https://www.shiina.xyz)
package/dist/card.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { UserProfile, UserStats, LanguageStat } from "./types";
2
+ export type CardOpts = {
3
+ theme?: string;
4
+ title_color?: string;
5
+ text_color?: string;
6
+ icon_color?: string;
7
+ bg_color?: string;
8
+ border_color?: string;
9
+ hide_border?: boolean;
10
+ compact?: boolean;
11
+ hide?: string[];
12
+ hide_langs?: string[];
13
+ show_langs?: string[];
14
+ animate?: boolean;
15
+ };
16
+ export declare function renderCard(user: UserProfile, stats: UserStats, langs: LanguageStat[], opts?: CardOpts): string;
package/dist/lib.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * github-card — npm entry point
3
+ *
4
+ * Re-exports the pure SVG renderer, all themes, types, and utility functions.
5
+ * No server dependency — works in any JS/TS runtime.
6
+ */
7
+ export { renderCard, type CardOpts } from "./card";
8
+ export type { UserProfile, UserStats, LanguageStat, ProfileData, CardOptions } from "./types";
9
+ export { themes, resolveColors, type Theme } from "./utils/themes";
10
+ export { kFormat, escapeXml, wrapText } from "./utils/format";
11
+ export { icons, icon } from "./utils/icons";
12
+ export { getLangColor } from "./utils/languages";
13
+ export { FONT_FACE, FONT_FAMILY } from "./utils/font";