Browse Source

stylesheet, logos, icons added

main
Silberengel 4 weeks ago
parent
commit
52ee04e6c6
  1. 113
      src/app.css
  2. 3
      src/app.html
  3. 48
      src/routes/+layout.svelte
  4. 33
      src/routes/+page.svelte
  5. 19
      src/routes/+page.ts
  6. BIN
      static/GR_logo.png
  7. 248
      static/NIP-34.md
  8. BIN
      static/apple-touch-icon.png
  9. BIN
      static/favicon.ico
  10. BIN
      static/favicon.png
  11. 5
      static/icons/alert-circle.svg
  12. 5
      static/icons/alert-triangle.svg
  13. 4
      static/icons/arrow-right.svg
  14. 4
      static/icons/book-open.svg
  15. 5
      static/icons/book-x.svg
  16. 3
      static/icons/book.svg
  17. 4
      static/icons/check-circle.svg
  18. 4
      static/icons/clock.svg
  19. 4
      static/icons/copyright.svg
  20. 5
      static/icons/external-link.svg
  21. 7
      static/icons/file-text.svg
  22. 6
      static/icons/file-x.svg
  23. 4
      static/icons/github.svg
  24. 5
      static/icons/globe.svg
  25. 6
      static/icons/hash.svg
  26. 4
      static/icons/home.svg
  27. 4
      static/icons/inbox.svg
  28. 5
      static/icons/info.svg
  29. 8
      static/icons/list.svg
  30. 3
      static/icons/loader-2.svg
  31. 4
      static/icons/mail.svg
  32. 6
      static/icons/package.svg
  33. 5
      static/icons/rss.svg
  34. 4
      static/icons/send.svg
  35. 4
      static/icons/user.svg
  36. 4
      static/icons/x.svg
  37. BIN
      static/logo.png

113
src/app.css

@ -0,0 +1,113 @@
/* GitRepublic Theme - Light/Dark Mode with Royal Plum Palette */
:root {
/* Light theme colors */
--royal-plum: #7B1E6D;
--snow: #FBF7FA;
--lavender-blush: #EEE6EC;
--thistle: #D9C8D4;
--lilac: #C7A0BB;
/* Light theme semantic colors */
--bg-primary: var(--snow);
--bg-secondary: var(--lavender-blush);
--bg-tertiary: var(--thistle);
--text-primary: #1a1a1a;
--text-secondary: #4a4a4a;
--text-muted: #6b7280;
--border-color: var(--thistle);
--border-light: var(--lavender-blush);
--accent: var(--royal-plum);
--accent-hover: #6a1f4d;
--accent-light: var(--lilac);
--link-color: var(--royal-plum);
--link-hover: var(--accent-hover);
--card-bg: #ffffff;
--card-border: var(--border-color);
--button-primary: var(--royal-plum);
--button-primary-hover: var(--accent-hover);
--button-secondary: var(--lilac);
--button-secondary-hover: var(--thistle);
--input-bg: #ffffff;
--input-border: var(--border-color);
--input-focus: var(--royal-plum);
--error-bg: #fee2e2;
--error-text: #991b1b;
--success-bg: #d1fae5;
--success-text: #065f46;
--warning-bg: #fef3c7;
--warning-text: #92400e;
}
[data-theme="dark"] {
/* Dark theme colors - darker versions of the palette */
--royal-plum: #9a2a7f;
--snow: #1a1418;
--lavender-blush: #2a1f26;
--thistle: #3d2f38;
--lilac: #5a4452;
/* Dark theme semantic colors */
--bg-primary: var(--snow);
--bg-secondary: var(--lavender-blush);
--bg-tertiary: var(--thistle);
--text-primary: #f5f5f5;
--text-secondary: #d1d1d1;
--text-muted: #a0a0a0;
--border-color: var(--thistle);
--border-light: var(--lavender-blush);
--accent: var(--royal-plum);
--accent-hover: #b84a8a;
--accent-light: var(--lilac);
--link-color: var(--royal-plum);
--link-hover: var(--accent-hover);
--card-bg: var(--lavender-blush);
--card-border: var(--border-color);
--button-primary: var(--royal-plum);
--button-primary-hover: var(--accent-hover);
--button-secondary: var(--lilac);
--button-secondary-hover: var(--thistle);
--input-bg: var(--lavender-blush);
--input-border: var(--border-color);
--input-focus: var(--royal-plum);
--error-bg: #4a1f1f;
--error-text: #ff6b6b;
--success-bg: #1a3a2a;
--success-text: #4ade80;
--warning-bg: #4a3a1f;
--warning-text: #fbbf24;
}
/* Base styles */
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: var(--bg-primary);
color: var(--text-primary);
transition: background-color 0.3s ease, color 0.3s ease;
}
/* Theme toggle utility */
.theme-toggle {
cursor: pointer;
padding: 0.5rem;
border: 1px solid var(--border-color);
border-radius: 0.375rem;
background: var(--card-bg);
color: var(--text-primary);
transition: all 0.2s ease;
}
.theme-toggle:hover {
background: var(--bg-secondary);
border-color: var(--accent);
}

3
src/app.html

@ -2,7 +2,8 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.ico" />
<link rel="apple-touch-icon" href="%sveltekit.assets%/apple-touch-icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head% %sveltekit.head%
</head> </head>

48
src/routes/+layout.svelte

@ -0,0 +1,48 @@
<script lang="ts">
import '../app.css';
import { onMount } from 'svelte';
// Theme management
let theme: 'light' | 'dark' = 'light';
onMount(() => {
// Check for saved theme preference or default to light
const savedTheme = localStorage.getItem('theme') as 'light' | 'dark' | null;
if (savedTheme === 'light' || savedTheme === 'dark') {
theme = savedTheme;
} else {
// Check system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
theme = prefersDark ? 'dark' : 'light';
}
applyTheme();
});
function applyTheme() {
if (theme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.removeAttribute('data-theme');
}
localStorage.setItem('theme', theme);
}
function toggleTheme() {
theme = theme === 'light' ? 'dark' : 'light';
applyTheme();
}
// Watch for system theme changes
onMount(() => {
if (typeof window !== 'undefined') {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) {
theme = e.matches ? 'dark' : 'light';
applyTheme();
}
});
}
});
</script>
<slot />

33
src/routes/+page.svelte

@ -217,8 +217,41 @@
// Fallback to repo name from event // Fallback to repo name from event
return getRepoName(event); return getRepoName(event);
} }
// Get page data for OpenGraph metadata
const pageData = $page.data as {
title?: string;
description?: string;
image?: string;
url?: string;
ogType?: string;
};
</script> </script>
<svelte:head>
<title>{pageData.title || 'GitRepublic - Decentralized Git Hosting on Nostr'}</title>
<meta name="description" content={pageData.description || 'A decentralized git hosting platform built on Nostr. Host your repositories, collaborate with others, and maintain full control of your code.'} />
<!-- OpenGraph / Facebook -->
<meta property="og:type" content={pageData.ogType || 'website'} />
<meta property="og:title" content={pageData.title || 'GitRepublic - Decentralized Git Hosting on Nostr'} />
<meta property="og:description" content={pageData.description || 'A decentralized git hosting platform built on Nostr. Host your repositories, collaborate with others, and maintain full control of your code.'} />
<meta property="og:url" content={pageData.url || `https://${$page.url.host}${$page.url.pathname}`} />
{#if pageData.image}
<meta property="og:image" content={pageData.image} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
{/if}
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={pageData.title || 'GitRepublic - Decentralized Git Hosting on Nostr'} />
<meta name="twitter:description" content={pageData.description || 'A decentralized git hosting platform built on Nostr. Host your repositories, collaborate with others, and maintain full control of your code.'} />
{#if pageData.image}
<meta name="twitter:image" content={pageData.image} />
{/if}
</svelte:head>
<div class="container"> <div class="container">
<header> <header>
<h1>gitrepublic</h1> <h1>gitrepublic</h1>

19
src/routes/+page.ts

@ -0,0 +1,19 @@
/**
* Page metadata and OpenGraph tags for homepage
*/
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ url }) => {
const gitDomain = url.host || 'localhost:6543';
const protocol = url.protocol === 'https:' ? 'https' : 'http';
const baseUrl = `${protocol}://${gitDomain}`;
return {
title: 'GitRepublic - Decentralized Git Hosting on Nostr',
description: 'A decentralized git hosting platform built on Nostr. Host your repositories, collaborate with others, and maintain full control of your code.',
image: `${baseUrl}/logo.png`,
url: baseUrl,
ogType: 'website'
};
};

BIN
static/GR_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

248
static/NIP-34.md

@ -1,248 +0,0 @@
NIP-34
======
`git` stuff
-----------
`draft` `optional`
This NIP defines all the ways code collaboration using and adjacent to [`git`](https://git-scm.com/) can be done using Nostr.
## Repository announcements
Git repositories are hosted in Git-enabled servers, but their existence can be announced using Nostr events. By doing so the author asserts themselves as a maintainer and expresses a willingness to receive patches, bug reports and comments in general, unless `t` tag `personal-fork` is included.
```jsonc
{
"kind": 30617,
"content": "",
"tags": [
["d", "<repo-id>"], // usually kebab-case short name
["name", "<human-readable project name>"],
["description", "brief human-readable project description>"],
["web", "<url for browsing>", ...], // a webpage url, if the git server being used provides such a thing
["clone", "<url for git-cloning>", ...], // a url to be given to `git clone` so anyone can clone it
["relays", "<relay-url>", ...], // relays that this repository will monitor for patches and issues
["r", "<earliest-unique-commit-id>", "euc"],
["maintainers", "<other-recognized-maintainer>", ...],
["t","personal-fork"], // optionally indicate author isn't a maintainer
["t", "<arbitrary string>"], // hashtags labelling the repository
]
}
```
The tags `web`, `clone`, `relays`, `maintainers` can have multiple values.
The `r` tag annotated with the `"euc"` marker should be the commit ID of the earliest unique commit of this repo, made to identify it among forks and group it with other repositories hosted elsewhere that may represent essentially the same project. In most cases it will be the root commit of a repository. In case of a permanent fork between two projects, then the first commit after the fork should be used.
Except `d`, all tags are optional.
## Repository state announcements
An optional source of truth for the state of branches and tags in a repository.
```jsonc
{
"kind": 30618,
"content": "",
"tags": [
["d", "<repo-id>"], // matches the identifier in the corresponding repository announcement
["refs/<heads|tags>/<branch-or-tag-name>","<commit-id>"]
["HEAD", "ref: refs/heads/<branch-name>"]
]
}
```
The `refs` tag may appear multiple times, or none.
If no `refs` tags are present, the author is no longer tracking repository state using this event. This approach enables the author to restart tracking state at a later time unlike [NIP-09](09.md) deletion requests.
The `refs` tag can be optionally extended to enable clients to identify how many commits ahead a ref is:
```jsonc
{
"tags": [
["refs/<heads|tags>/<branch-or-tag-name>", "<commit-id>", "<shorthand-parent-commit-id>", "<shorthand-grandparent>", ...],
]
}
```
## Patches and Pull Requests (PRs)
Patches and PRs can be sent by anyone to any repository. Patches and PRs to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch and PR events SHOULD include an `a` tag pointing to that repository's announcement address.
Patches SHOULD be used if each event is under 60kb, otherwise PRs SHOULD be used.
### Patches
Patches in a patch set SHOULD include a [NIP-10](10.md) `e` `reply` tag pointing to the previous patch.
The first patch revision in a patch revision SHOULD include a [NIP-10](10.md) `e` `reply` to the original root patch.
```jsonc
{
"kind": 1617,
"content": "<patch>", // contents of <git format-patch>
"tags": [
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>"],
["r", "<earliest-unique-commit-id-of-repo>"] // so clients can subscribe to all patches sent to a local git repo
["p", "<repository-owner>"],
["p", "<other-user>"], // optionally send the patch to another user to bring it to their attention
["t", "root"], // omitted for additional patches in a series
// for the first patch in a revision
["t", "root-revision"],
// optional tags for when it is desirable that the merged patch has a stable commit id
// these fields are necessary for ensuring that the commit resulting from applying a patch
// has the same id as it had in the proposer's machine -- all these tags can be omitted
// if the maintainer doesn't care about these things
["commit", "<current-commit-id>"],
["r", "<current-commit-id>"] // so clients can find existing patches for a specific commit
["parent-commit", "<parent-commit-id>"],
["commit-pgp-sig", "-----BEGIN PGP SIGNATURE-----..."], // empty string for unsigned commit
["committer", "<name>", "<email>", "<timestamp>", "<timezone offset in minutes>"],
]
}
```
The first patch in a series MAY be a cover letter in the format produced by `git format-patch`.
### Pull Requests
The PR or PR update tip SHOULD be successfully pushed to `refs/nostr/<[PR|PR-Update]-event-id>` in all repositories listed in its `clone` tag before the event is signed.
An attempt SHOULD be made to push this ref to all repositories listed in the repository's announcement event's `"clone"` tag, for which their is reason to believe the user might have write access. This includes each [grasp server](https://njump.me/naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqqpt8wfshxuqlnvh8x) which can be identified using this method: `clone` tag includes `[http|https]://<grasp-path>/<valid-npub>/<string>.git` and `relays` tag includes `[ws/wss]://<grasp-path>`.
Clients MAY fallback to creating a 'personal-fork' `repository announcement` listing other grasp servers, e.g. from the `User grasp list`, for the purpose of serving the specified commit(s).
```jsonc
{
"kind": 1618,
"content": "<markdown text>",
"tags": [
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>"],
["r", "<earliest-unique-commit-id-of-repo>"] // so clients can subscribe to all PRs sent to a local git repo
["p", "<repository-owner>"],
["p", "<other-user>"], // optionally send the PR to another user to bring it to their attention
["subject", "<PR-subject>"],
["t", "<PR-label>"], // optional
["t", "<another-PR-label>"], // optional
["c", "<current-commit-id>"], // tip of the PR branch
["clone", "<clone-url>", ...], // at least one git clone url where commit can be downloaded
["branch-name", "<branch-name>"], // optional recommended branch name
["e", "<root-patch-event-id>"], // optionally indicate PR is a revision of an existing patch, which should be closed
["merge-base", "<commit-id>"], // optional: the most recent common ancestor with the target branch
]
}
```
### Pull Request Updates
A PR Update changes the tip of a referenced PR event.
```jsonc
{
"kind": 1619,
"content": "",
"tags": [
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>"],
["r", "<earliest-unique-commit-id-of-repo>"] // so clients can subscribe to all PRs sent to a local git repo
["p", "<repository-owner>"],
["p", "<other-user>"], // optionally send the PR to another user to bring it to their attention
// NIP-22 tags
["E", "<pull-request-event-id>"],
["P", "<pull-request-author>"],
["c", "<current-commit-id>"], // updated tip of PR
["clone", "<clone-url>", ...], // at least one git clone url where commit can be downloaded
["merge-base", "<commit-id>"], // optional: the most recent common ancestor with the target branch
]
}
```
## Issues
Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag.
Issues may have a `subject` tag, which clients can utilize to display a header. Additionally, one or more `t` tags may be included to provide labels for the issue.
```json
{
"kind": 1621,
"content": "<markdown text>",
"tags": [
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>"],
["p", "<repository-owner>"]
["subject", "<issue-subject>"]
["t", "<issue-label>"]
["t", "<another-issue-label>"]
]
}
```
## Replies
Replies to either a `kind:1621` (_issue_), `kind:1617` (_patch_) or `kind:1618` (_pull request_) event should follow [NIP-22 comment](22.md).
## Status
Root Patches, PRs and Issues have a Status that defaults to 'Open' and can be set by issuing Status events.
```jsonc
{
"kind": 1630, // Open
"kind": 1631, // Applied / Merged for Patches; Resolved for Issues
"kind": 1632, // Closed
"kind": 1633, // Draft
"content": "<markdown text>",
"tags": [
["e", "<issue-or-PR-or-original-root-patch-id-hex>", "", "root"],
["e", "<accepted-revision-root-id-hex>", "", "reply"], // for when revisions applied
["p", "<repository-owner>"],
["p", "<root-event-author>"],
["p", "<revision-author>"],
// optional for improved subscription filter efficiency
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>", "<relay-url>"],
["r", "<earliest-unique-commit-id-of-repo>"]
// optional for `1631` status
["q", "<applied-or-merged-patch-event-id>", "<relay-url>", "<pubkey>"], // for each
// when merged
["merge-commit", "<merge-commit-id>"]
["r", "<merge-commit-id>"]
// when applied
["applied-as-commits", "<commit-id-in-master-branch>", ...]
["r", "<applied-commit-id>"] // for each
]
}
```
The most recent Status event (by `created_at` date) from either the issue/patch author or a maintainer is considered valid.
The Status of a patch-revision is to either that of the root-patch, or `1632` (_Closed_) if the root-patch's Status is `1631` (_Applied/Merged_) and the patch-revision isn't tagged in the `1631` (_Applied/Merged_) event.
## User grasp list
List of [grasp servers](https://njump.me/naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqqpt8wfshxuqlnvh8x) the user generally wishes to use for NIP-34 related activity. It is similar in function to the NIP-65 relay list and NIP-B7 blossom list.
The event SHOULD include a list of `g` tags with grasp service websocket URLs in order of preference.
```jsonc
{
"kind": 10317,
"content": "",
"tags": [
["g", "<grasp-service-websocket-url>"], // zero or more grasp sever urls
]
}
```
## Possible things to be added later
- inline file comments kind (we probably need one for patches and a different one for merged files)

BIN
static/apple-touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
static/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
static/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

5
static/icons/alert-circle.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<line x1="12" x2="12" y1="8" y2="12"/>
<line x1="12" x2="12.01" y1="16" y2="16"/>
</svg>

After

Width:  |  Height:  |  Size: 310 B

5
static/icons/alert-triangle.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/>
<path d="M12 9v4"/>
<path d="M12 17h.01"/>
</svg>

After

Width:  |  Height:  |  Size: 324 B

4
static/icons/arrow-right.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14"/>
<path d="m12 5 7 7-7 7"/>
</svg>

After

Width:  |  Height:  |  Size: 240 B

4
static/icons/book-open.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
</svg>

After

Width:  |  Height:  |  Size: 301 B

5
static/icons/book-x.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/>
<path d="m14.5 7-5 5"/>
<path d="m9.5 7 5 5"/>
</svg>

After

Width:  |  Height:  |  Size: 317 B

3
static/icons/book.svg

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/>
</svg>

After

Width:  |  Height:  |  Size: 266 B

4
static/icons/check-circle.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
<polyline points="22 4 12 14.01 9 11.01"/>
</svg>

After

Width:  |  Height:  |  Size: 283 B

4
static/icons/clock.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<polyline points="12 6 12 12 16 14"/>
</svg>

After

Width:  |  Height:  |  Size: 264 B

4
static/icons/copyright.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<path d="M14.83 14.83a4 4 0 1 1 0-5.66"/>
</svg>

After

Width:  |  Height:  |  Size: 268 B

5
static/icons/external-link.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
<polyline points="15 3 21 3 21 9"/>
<line x1="10" x2="21" y1="14" y2="3"/>
</svg>

After

Width:  |  Height:  |  Size: 339 B

7
static/icons/file-text.svg

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
<path d="M10 9H8"/>
<path d="M16 13H8"/>
<path d="M16 17H8"/>
</svg>

After

Width:  |  Height:  |  Size: 368 B

6
static/icons/file-x.svg

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
<path d="m9.5 12.5 5 5"/>
<path d="m14.5 12.5-5 5"/>
</svg>

After

Width:  |  Height:  |  Size: 357 B

4
static/icons/github.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/>
<path d="M9 18c-4.51 2-5-2-7-2"/>
</svg>

After

Width:  |  Height:  |  Size: 488 B

5
static/icons/globe.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<line x1="2" x2="22" y1="12" y2="12"/>
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

6
static/icons/hash.svg

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="4" x2="20" y1="9" y2="9"/>
<line x1="4" x2="20" y1="15" y2="15"/>
<line x1="10" x2="8" y1="3" y2="21"/>
<line x1="16" x2="14" y1="3" y2="21"/>
</svg>

After

Width:  |  Height:  |  Size: 350 B

4
static/icons/home.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</svg>

After

Width:  |  Height:  |  Size: 295 B

4
static/icons/inbox.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/>
<path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/>
</svg>

After

Width:  |  Height:  |  Size: 367 B

5
static/icons/info.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<line x1="12" x2="12" y1="16" y2="12"/>
<line x1="12" x2="12.01" y1="8" y2="8"/>
</svg>

After

Width:  |  Height:  |  Size: 309 B

8
static/icons/list.svg

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="8" x2="21" y1="6" y2="6"/>
<line x1="8" x2="21" y1="12" y2="12"/>
<line x1="8" x2="21" y1="18" y2="18"/>
<line x1="3" x2="3.01" y1="6" y2="6"/>
<line x1="3" x2="3.01" y1="12" y2="12"/>
<line x1="3" x2="3.01" y1="18" y2="18"/>
</svg>

After

Width:  |  Height:  |  Size: 437 B

3
static/icons/loader-2.svg

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12a9 9 0 1 1-6.219-8.56"/>
</svg>

After

Width:  |  Height:  |  Size: 231 B

4
static/icons/mail.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect width="20" height="16" x="2" y="4" rx="2"/>
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>
</svg>

After

Width:  |  Height:  |  Size: 297 B

6
static/icons/package.svg

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="m7.5 4.27 9 5.15"/>
<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/>
<path d="m3.3 7 8.7 5 8.7-5"/>
<path d="M12 22V12"/>
</svg>

After

Width:  |  Height:  |  Size: 410 B

5
static/icons/rss.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 11a9 9 0 0 1 9 9"/>
<path d="M4 4a16 16 0 0 1 16 16"/>
<circle cx="5" cy="19" r="1"/>
</svg>

After

Width:  |  Height:  |  Size: 293 B

4
static/icons/send.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="m22 2-7 20-4-9-9-4Z"/>
<path d="M22 2 11 13"/>
</svg>

After

Width:  |  Height:  |  Size: 249 B

4
static/icons/user.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</svg>

After

Width:  |  Height:  |  Size: 278 B

4
static/icons/x.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6 6 18"/>
<path d="m6 6 12 12"/>
</svg>

After

Width:  |  Height:  |  Size: 239 B

BIN
static/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Loading…
Cancel
Save