diff --git a/index.html b/index.html index ef9678e46..88ebf9aad 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ + content="https://app.radicle.xyz/images/radicle-og-853x853-0569.png" /> @@ -23,29 +23,23 @@ + content="https://app.radicle.xyz/images/radicle-og-853x853-0569.png" /> - @@ -80,7 +74,7 @@ - + -
-
- - - -
-
+
+
+
-
-
-
-
-
- -
-
diff --git a/src/App/LoadingBar.svelte b/src/App/LoadingBar.svelte index 91c3daf2b..4596dae87 100644 --- a/src/App/LoadingBar.svelte +++ b/src/App/LoadingBar.svelte @@ -5,7 +5,7 @@ @@ -29,12 +29,7 @@ - + diff --git a/src/App/Settings.svelte b/src/App/Settings.svelte index b80ab0891..895799c68 100644 --- a/src/App/Settings.svelte +++ b/src/App/Settings.svelte @@ -8,8 +8,6 @@ } from "@app/lib/appearance"; import Button from "@app/components/Button.svelte"; - import Icon from "@app/components/Icon.svelte"; - import Radio from "@app/components/Radio.svelte"; diff --git a/src/components/Badge.svelte b/src/components/Badge.svelte index d6a09bdcd..826fac038 100644 --- a/src/components/Badge.svelte +++ b/src/components/Badge.svelte @@ -1,100 +1,100 @@ - + + class:draft={variant === "draft"} + class:archived={variant === "archived"} + class:open={variant === "open"} + class:merged={variant === "merged"} + class:background={variant === "background"}> diff --git a/src/components/Button.svelte b/src/components/Button.svelte index 785effa2d..d5a455d33 100644 --- a/src/components/Button.svelte +++ b/src/components/Button.svelte @@ -7,16 +7,11 @@ | "gray" | "gray-white" | "selected" - | "none" | "outline" - | "primary-toggle-off" - | "primary-toggle-on" | "secondary" | "secondary-toggle-off" - | "secondary-toggle-on" | "secondary-mobile" | "secondary-mobile-toggle" - | "naked-toggle" | "tab" | "tab-active" = "gray"; export let size: "small" | "regular" | "large" = "regular"; @@ -42,10 +37,8 @@ display: flex; align-items: center; border: none; - border-radius: var(--border-radius-tiny); - font-family: var(--font-family-sans-serif); - font-weight: var(--font-weight-semibold); - font-size: var(--font-size-small); + border-radius: var(--border-radius-sm); + font: var(--txt-body-m-medium); font-feature-settings: inherit; white-space: nowrap; gap: 0.5rem; @@ -53,7 +46,7 @@ } button:disabled { - color: var(--color-foreground-disabled); + color: var(--color-text-disabled); } button:disabled.not-allowed { cursor: not-allowed; @@ -70,243 +63,171 @@ } .large { - border-radius: var(--border-radius-small); + border-radius: var(--border-radius-sm); height: var(--button-regular-height); padding: 0 1rem; } .background { - color: var(--color-foreground-contrast); - background-color: var(--color-background-default); - font-weight: var(--font-weight-regular); + color: var(--color-text-primary); + background-color: var(--color-surface-base); + font: var(--txt-body-m-regular); } .background[disabled] { - color: var(--color-foreground-disabled); - background-color: var(--color-background-default); - font-weight: var(--font-weight-regular); + color: var(--color-text-disabled); + background-color: var(--color-surface-base); } .background:not([disabled]):hover { - color: var(--color-foreground-contrast); - background-color: var(--color-fill-ghost); + color: var(--color-text-primary); + background-color: var(--color-surface-mid); } .gray { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-contrast); + background-color: var(--color-surface-mid); + color: var(--color-text-primary); } .gray[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .gray:not([disabled]):hover { - background-color: var(--color-fill-ghost-hover); - color: var(--color-foreground-contrast); + background-color: var(--color-surface-strong); + color: var(--color-text-primary); } .gray-white { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-contrast); + background-color: var(--color-surface-mid); + color: var(--color-text-primary); } .gray-white[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .gray-white:not([disabled]):hover { - background-color: var(--color-fill-ghost-hover); - color: var(--color-foreground-contrast); + background-color: var(--color-surface-strong); + color: var(--color-text-primary); } .selected { - background-color: var(--color-fill-float-hover); - color: var(--color-foreground-emphasized); + background-color: var(--color-border-alpha-subtle); + color: var(--color-text-brand); cursor: default; } .selected[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .not-selected { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-contrast); - font-weight: var(--font-weight-normal); + background-color: var(--color-surface-mid); + color: var(--color-text-primary); + font: var(--txt-body-m-regular); letter-spacing: 0.02rem; } .not-selected[disabled] { - background-color: var(--color-fill-float-hover); - color: var(--color-foreground-disabled); - font-weight: var(--font-weight-normal); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .not-selected:not([disabled]):hover { - background-color: var(--color-fill-ghost-hover); - color: var(--color-foreground-contrast); - } - - .none { - background-color: transparent; - color: var(--color-foreground-emphasized); - } - .none[disabled] { - background-color: transparent; - color: var(--color-foreground-emphasized); - } - .none:not([disabled]):hover { - background-color: var(--color-fill-ghost); + background-color: var(--color-surface-strong); + color: var(--color-text-primary); } .outline { background-color: transparent; - color: var(--color-foreground-contrast); - border: 1px solid var(--color-border-hint); + color: var(--color-text-primary); + border: 1px solid var(--color-border-subtle); } .outline[disabled] { background-color: transparent; - color: var(--color-fill-gray); + color: var(--color-text-tertiary); } .outline:not([disabled]):hover { background-color: transparent; - border: 1px solid var(--color-border-focus); - } - - .primary-toggle-on { - color: var(--color-fill-primary); - background-color: var(--color-fill-merged); - border: 1px solid var(--color-border-merged); - } - - .primary-toggle-on[disabled] { - color: var(--color-foreground-match-background); - background-color: var(--color-fill-primary); - } - - .primary-toggle-on:not([disabled]):hover { - border: 1px solid var(--color-border-primary); - } - - .primary-toggle-off { - background-color: transparent; - color: var(--color-foreground-dim); - border: 1px solid var(--color-border-hint); - } - .primary-toggle-off[disabled] { - background-color: transparent; - color: var(--color-fill-gray); - } - .primary-toggle-off:not([disabled]):hover { - background-color: transparent; - border: 1px solid var(--color-border-primary); - color: var(--color-foreground-dim); + border: 1px solid var(--color-border-brand); } .secondary-toggle-off { - background-color: var(--color-fill-secondary); - color: var(--color-foreground-match-background); + background-color: var(--color-surface-brand-primary); + color: var(--color-text-on-brand); } .secondary-toggle-off[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .secondary-toggle-off:not([disabled]):hover { - background-color: var(--color-fill-secondary-hover); - } - .secondary-toggle-on { - background-color: var(--color-fill-selected); - color: var(--color-foreground-emphasized); - border: 1px solid var(--color-border-selected); - } - .secondary-toggle-on[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); - border: none; - } - .secondary-toggle-on:not([disabled]):hover { - background-color: var(--color-fill-selected); - border: 1px solid var(--color-border-focus); - } - - .naked-toggle { - background-color: transparent; - color: var(--color-foreground-contrast); - border: 1px solid transparent; - } - .naked-toggle[disabled] { - background-color: transparent; - color: var(--color-fill-gray); - } - .naked-toggle:not([disabled]):hover { - background-color: transparent; - border: 1px solid var(--color-fill-secondary); + background-color: var(--color-surface-brand-secondary); } .secondary { - color: var(--color-foreground-match-background); - background-color: var(--color-fill-secondary); + color: var(--color-text-on-brand); + background-color: var(--color-surface-brand-primary); } .secondary[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .secondary:not([disabled]):hover { - background-color: var(--color-fill-secondary-hover); + background-color: var(--color-surface-brand-secondary); } .secondary-mobile { - color: var(--color-foreground-dim); - background-color: var(--color-background-default); + color: var(--color-text-tertiary); + background-color: var(--color-surface-base); } .secondary-mobile[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .secondary-mobile:not([disabled]):active { - color: var(--color-foreground-match-background); - background-color: var(--color-fill-secondary); + color: var(--color-text-on-brand); + background-color: var(--color-surface-brand-primary); } .secondary-mobile-toggle { - color: var(--color-foreground-dim); - background-color: var(--color-background-default); + color: var(--color-text-tertiary); + background-color: var(--color-surface-base); } .secondary-mobile-toggle[disabled] { - background-color: var(--color-fill-ghost); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-mid); + color: var(--color-text-disabled); } .tab { background-color: transparent; - color: var(--color-foreground-contrast); - border: 1px solid var(--color-border-hint); - border-radius: 4px 4px 0 0; + color: var(--color-text-primary); + border: 1px solid var(--color-border-subtle); + border-radius: var(--border-radius-md) var(--border-radius-md) 0 0; font-weight: normal; letter-spacing: 0.3px; } .tab[disabled] { - background-color: var(--color-background-default); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-base); + color: var(--color-text-disabled); border: none; - border-bottom: 1px solid var(--color-border-hint); + border-bottom: 1px solid var(--color-border-subtle); } .tab:not([disabled]):hover { - background-color: var(--color-fill-float-hover); + background-color: var(--color-border-alpha-subtle); } .tab-active { - background-color: var(--color-background-default); - border: 1px solid var(--color-fill-separator); - border-bottom: 1px solid var(--color-background-default); - border-radius: 4px 4px 0 0; - color: var(--color-foreground-contrast); + background-color: var(--color-surface-base); + border: 1px solid var(--color-border-subtle); + border-bottom: 1px solid var(--color-surface-base); + border-radius: var(--border-radius-md) var(--border-radius-md) 0 0; + color: var(--color-text-primary); } .tab-active[disabled] { - background-color: var(--color-background-default); - color: var(--color-foreground-disabled); + background-color: var(--color-surface-base); + color: var(--color-text-disabled); } @@ -344,13 +265,8 @@ class:gray-white={variant === "gray-white"} class:selected={variant === "selected"} class:gray={variant === "gray"} - class:none={variant === "none"} class:outline={variant === "outline"} - class:primary-toggle-off={variant === "primary-toggle-off"} - class:primary-toggle-on={variant === "primary-toggle-on"} class:secondary-toggle-off={variant === "secondary-toggle-off"} - class:secondary-toggle-on={variant === "secondary-toggle-on"} - class:naked-toggle={variant === "naked-toggle"} class:secondary={variant === "secondary"} class:secondary-mobile={variant === "secondary-mobile"} class:secondary-mobile-toggle={variant === "secondary-mobile-toggle"} diff --git a/src/components/Clipboard.svelte b/src/components/Clipboard.svelte index c7cda5f47..5034099a7 100644 --- a/src/components/Clipboard.svelte +++ b/src/components/Clipboard.svelte @@ -13,10 +13,10 @@ const dispatch = createEventDispatcher<{ copied: null }>(); - let icon: "clipboard" | "checkmark" = "clipboard"; + let icon: "copy" | "checkmark" = "copy"; const restoreIcon = debounce(() => { - icon = "clipboard"; + icon = "copy"; }, 800); export async function copy() { @@ -28,7 +28,7 @@ diff --git a/src/components/CompactCommitAuthorship.svelte b/src/components/CompactCommitAuthorship.svelte index 46fe58770..4bebd04e6 100644 --- a/src/components/CompactCommitAuthorship.svelte +++ b/src/components/CompactCommitAuthorship.svelte @@ -10,7 +10,7 @@ diff --git a/src/components/DiffStatBadge.svelte b/src/components/DiffStatBadge.svelte index 20bac1ac7..022161b73 100644 --- a/src/components/DiffStatBadge.svelte +++ b/src/components/DiffStatBadge.svelte @@ -1,39 +1,37 @@ diff --git a/src/components/DropdownList.svelte b/src/components/DropdownList.svelte index 59992263e..52877c8c4 100644 --- a/src/components/DropdownList.svelte +++ b/src/components/DropdownList.svelte @@ -7,13 +7,13 @@ diff --git a/src/components/DropdownList/DropdownListItem.svelte b/src/components/DropdownList/DropdownListItem.svelte index a2a3d0e9e..a97b0f6d8 100644 --- a/src/components/DropdownList/DropdownListItem.svelte +++ b/src/components/DropdownList/DropdownListItem.svelte @@ -14,32 +14,30 @@ gap: 0.375rem; padding: 0.5rem 0.375rem; white-space: nowrap; - border-radius: var(--border-radius-tiny); - font-size: var(--font-size-small); - font-weight: var(--font-weight-regular); - color: var(--color-foreground-contrast); + border-radius: var(--border-radius-sm); + font: var(--txt-body-m-regular); + color: var(--color-text-primary); } .item.disabled { - color: var(--color-foreground-disabled); + color: var(--color-text-disabled); } .item:hover, .selected { - background-color: var(--color-fill-ghost); + background-color: var(--color-surface-mid); } .selected { - font-weight: var(--font-weight-semibold); - color: var(--color-foreground-contrast); - background-color: var(--color-fill-ghost); + color: var(--color-text-primary); + background-color: var(--color-surface-mid); } .item:hover.selected { - background-color: var(--color-fill-ghost-hover); + background-color: var(--color-surface-strong); } .item:hover.selected.disabled { - background-color: var(--color-fill-ghost); + background-color: var(--color-surface-mid); } .item:hover.disabled { cursor: not-allowed; - background-color: var(--color-background-float); + background-color: var(--color-surface-subtle); } diff --git a/src/components/ErrorMessage.svelte b/src/components/ErrorMessage.svelte index fa8d9a0b9..12839b664 100644 --- a/src/components/ErrorMessage.svelte +++ b/src/components/ErrorMessage.svelte @@ -19,27 +19,24 @@ border-radius: inherit; display: flex; flex-direction: column; - font-family: var(--font-family-sans-serif); font-size: inherit; padding: 1rem; - border-radius: var(--border-radius-small); + border-radius: var(--border-radius-md); gap: 1rem; } .label { - font-size: var(--font-size-small); - font-weight: var(--font-weight-regular); + font: var(--txt-body-m-regular); max-width: 36rem; } .error :global(code) { - font-family: var(--font-family-monospace); - font-size: var(--font-size-small); - background-color: var(--color-fill-ghost); - border-radius: var(--border-radius-tiny); + font: var(--txt-code-regular); + background-color: var(--color-surface-mid); + border-radius: var(--border-radius-sm); padding: 0.125rem 0.25rem; } .help { - font-size: var(--font-size-small); + font: var(--txt-body-m-regular); text-align: center; } .command { @@ -54,7 +51,7 @@
-
+
{title}
diff --git a/src/components/ExternalLink.svelte b/src/components/ExternalLink.svelte index 17cd1e1f8..efd5c84ce 100644 --- a/src/components/ExternalLink.svelte +++ b/src/components/ExternalLink.svelte @@ -8,7 +8,6 @@ {href} - + diff --git a/src/components/File.svelte b/src/components/File.svelte index fdd03381a..d0acbfc23 100644 --- a/src/components/File.svelte +++ b/src/components/File.svelte @@ -16,10 +16,10 @@ height: 3rem; align-items: center; padding: 0 0.5rem 0 1rem; - border: 1px solid var(--color-border-hint); - border-top-left-radius: var(--border-radius-small); - border-top-right-radius: var(--border-radius-small); - background-color: var(--color-background-default); + border: 1px solid var(--color-border-subtle); + border-top-left-radius: var(--border-radius-md); + border-top-right-radius: var(--border-radius-md); + background-color: var(--color-surface-base); z-index: 2; } @@ -29,8 +29,8 @@ } .collapsed { - border-radius: var(--border-radius-small); - border: 1px solid var(--color-border-hint); + border-radius: var(--border-radius-md); + border: 1px solid var(--color-border-subtle); } .left { @@ -50,11 +50,11 @@ .container { position: relative; overflow-x: auto; - border: 1px solid var(--color-border-hint); + border: 1px solid var(--color-border-subtle); border-top: 0; - background: var(--color-background-float); - border-bottom-left-radius: var(--border-radius-small); - border-bottom-right-radius: var(--border-radius-small); + background: var(--color-surface-subtle); + border-bottom-left-radius: var(--border-radius-md); + border-bottom-right-radius: var(--border-radius-md); } @media (max-width: 719.98px) { .header { diff --git a/src/components/FilePath.svelte b/src/components/FilePath.svelte index 1069d03a1..2a8db7849 100644 --- a/src/components/FilePath.svelte +++ b/src/components/FilePath.svelte @@ -11,17 +11,16 @@ diff --git a/src/components/Header.svelte b/src/components/Header.svelte new file mode 100644 index 000000000..36a152190 --- /dev/null +++ b/src/components/Header.svelte @@ -0,0 +1,75 @@ + + + + +
+
+ {#if !$$slots.breadcrumbs} + + + + {/if} + +
+ +
+ + + + + +
+ +
+ +
+
+
+
diff --git a/src/components/HoverPopover.svelte b/src/components/HoverPopover.svelte index 090b3a2d7..28097ed59 100644 --- a/src/components/HoverPopover.svelte +++ b/src/components/HoverPopover.svelte @@ -17,9 +17,9 @@ display: inline-block; } .popover { - background: var(--color-background-float); - border-radius: var(--border-radius-regular); - border: 1px solid var(--color-border-hint); + background: var(--color-surface-subtle); + border-radius: var(--border-radius-md); + border: 1px solid var(--color-border-subtle); padding: 1rem; box-shadow: var(--elevation-low); position: absolute; diff --git a/src/components/Icon.svelte b/src/components/Icon.svelte index 0a33619b2..425233d06 100644 --- a/src/components/Icon.svelte +++ b/src/components/Icon.svelte @@ -2,48 +2,50 @@ - - - + {#if name === "activity"} + d="M9.97559 11.7139L11.5361 7.81445L11.6611 7.5H15V8.5H12.3379L10.0244 14.2861L5.97266 5.1709L4.44727 8.22363L4.30859 8.5H1V7.5H3.69141L6.02637 2.8291L9.97559 11.7139Z" /> {:else if name === "archive"} - - - - - - - - - - {:else if name === "arrow-box-up-right"} - - {:else if name === "arrow-reply"} + d="M14.5 2.5V6H13.5V14.5H2.5V6H1.5V2.5H14.5ZM3.5 13.5H12.5V6H3.5V13.5ZM2.5 5H13.5V3.5H2.5V5Z" /> + + {:else if name === "arrow-left"} + d="M5.20703 8.5L7.70703 11L7 11.707L3.29297 8L7 4.29297L7.70703 5L5.20703 7.5L12.5 7.5L12.5 8.5L5.20703 8.5Z" /> + {:else if name === "arrow-up"} + + {:else if name === "attach"} + {:else if name === "badge"} + d="M4.64602 8.34829L5.35313 7.64118L7.00488 9.29294L10.6613 5.63656L11.3684 6.34367L7.00488 10.7072L4.64602 8.34829Z" /> - {:else if name === "bookmark-on"} + d="M14.3125 4.06738L14.5625 4.21094V11.7891L14.3125 11.9326L8 15.5771L1.6875 11.9326L1.4375 11.7891V4.21094L1.6875 4.06738L8 0.422852L14.3125 4.06738ZM2.4375 4.78809V11.2109L8 14.4229L13.5625 11.2109V4.78809L8 1.57617L2.4375 4.78809Z" /> + {:else if name === "bookmark"} - {:else if name === "bookmark-off"} - + d="M3.5 2.5L12.5 2.5L12.5 15L8 11.626L3.5 15L3.5 2.5ZM8 10.375L11.5 13L11.5 3.5L4.5 3.5L4.5 13L8 10.375Z" /> + {:else if name === "bookmark-fill"} + {:else if name === "branch"} + d="M5 4C5 3.44772 4.55228 3 4 3C3.44772 3 3 3.44772 3 4C3 4.55228 3.44772 5 4 5V6C2.89543 6 2 5.10457 2 4C2 2.89543 2.89543 2 4 2C5.10457 2 6 2.89543 6 4C6 5.10457 5.10457 6 4 6V5C4.55228 5 5 4.55228 5 4Z" /> + d="M13 4C13 3.44772 12.5523 3 12 3C11.4477 3 11 3.44772 11 4C11 4.55228 11.4477 5 12 5V6C10.8954 6 10 5.10457 10 4C10 2.89543 10.8954 2 12 2C13.1046 2 14 2.89543 14 4C14 5.10457 13.1046 6 12 6V5C12.5523 5 13 4.55228 13 4Z" /> + d="M5 12C5 11.4477 4.55228 11 4 11C3.44772 11 3 11.4477 3 12C3 12.5523 3.44772 13 4 13V14C2.89543 14 2 13.1046 2 12C2 10.8954 2.89543 10 4 10C5.10457 10 6 10.8954 6 12C6 13.1046 5.10457 14 4 14V13C4.55228 13 5 12.5523 5 12Z" /> + - - {:else if name === "brush"} - - - - - {:else if name === "chat"} - - - - - {:else if name === "checkbox-checked"} - - {:else if name === "checkbox-unchecked"} - + d="M12.5 5.00001V7.20705L10.707 9.00001H3.99995V8.00001H10.2929L11.5 6.79298V5.00001H12.5Z" /> {:else if name === "checkmark"} + d="M3 7.29297L6 10.293L13 3.29297L13.707 4L6 11.707L2.29297 8L3 7.29297Z" /> + {:else if name === "checkout"} + + + {:else if name === "chevron-down"} - + d="M4 5.29297L8 9.29297L12 5.29297L12.707 6L8 10.707L3.29297 6L4 5.29297Z" /> {:else if name === "chevron-left"} + d="M10 3.29297L10.707 4L6.70703 8L10.707 12L10 12.707L5.29297 8L10 3.29297Z" /> {:else if name === "chevron-left-right"} {:else if name === "chevron-right"} + d="M7 3.29297L11.707 8L7 12.707L6.29297 12L10.29297 8L6.29297 4L7 3.29297Z" /> {:else if name === "chevron-up"} - - {:else if name === "clipboard"} + d="M8 5.29297L12.707 10L12 10.707L8 6.70703L4 10.707L3.29297 10L8 5.29297Z" /> + {:else if name === "clock"} - {:else if name === "collapse"} + d="M13.5 8C13.5 4.96243 11.0376 2.5 8 2.5C4.96243 2.5 2.5 4.96243 2.5 8C2.5 11.0376 4.96243 13.5 8 13.5C11.0376 13.5 13.5 11.0376 13.5 8ZM14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8Z" /> + + {:else if name === "code"} + d="M10 3.29297L14.707 8L10 12.707L9.29297 12L13.293 8L9.29297 4L10 3.29297Z" /> + + {:else if name === "collapse-vertical"} + + + + {:else if name === "comment"} + + + {:else if name === "commit"} + d="M8 4.5C9.7632 4.5 11.2212 5.8039 11.4639 7.5H15V8.5H11.4639C11.2212 10.1961 9.7632 11.5 8 11.5C6.2368 11.5 4.77879 10.1961 4.53613 8.5H1V7.5H4.53613C4.77879 5.8039 6.2368 4.5 8 4.5ZM8 5.5C6.61929 5.5 5.5 6.61929 5.5 8C5.5 9.38071 6.61929 10.5 8 10.5C9.38071 10.5 10.5 9.38071 10.5 8C10.5 6.61929 9.38071 5.5 8 5.5Z" /> + {:else if name === "copy"} + + {:else if name === "cross"} - + d="M12.707 4L8.70605 8.00098L12.7051 12L11.998 12.707L7.99902 8.70801L4 12.707L3.29297 12L7.29199 8.00098L3.29297 4.00195L4 3.29492L7.99902 7.29395L12 3.29297L12.707 4Z" /> {:else if name === "cursor"} - {:else if name === "diff"} - - - - {:else if name === "download"} - - {:else if name === "edit"} - - {:else if name === "ellipsis"} - - {:else if name === "exclamation-circle"} - - - - {:else if name === "expand"} - - {:else if name === "eye-open"} - - {:else if name === "face"} - - - - - {:else if name === "file"} - - {:else if name === "folder"} - - {:else if name === "folder-open"} - - - {:else if name === "git"} - - {:else if name === "globe"} - - {:else if name === "help"} - - - {:else if name === "home"} - - {:else if name === "info"} - - - {:else if name === "issue"} - - - - - {:else if name === "link"} - - {:else if name === "logo"} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {:else if name === "menu"} - - - - {:else if name === "moon"} - {:else if name === "device"} - {:else if name === "delegate"} + d="M13.5 10.5L2.5 10.5L2.5 2.5L13.5 2.5L13.5 10.5ZM3.5 8.5L3.5 9.5L12.5 9.5L12.5 8.5L3.5 8.5ZM3.5 3.5L3.5 7.5L12.5 7.5L12.5 3.5L3.5 3.5Z" /> + + {:else if name === "diff"} - + d="M13.5 1.5V14.5H2.5V1.5H13.5ZM3.5 13.5H12.5V2.5H3.5V13.5ZM10 10.5V11.5H6V10.5H10ZM8.5 4V5.5H10V6.5H8.5V8H7.5V6.5H6V5.5H7.5V4H8.5Z" /> + {:else if name === "disconnect"} - + d="M2.5 2.5L9.5 2.5L9.5 5.5L8.5 5.5L8.5 3.5L3.5 3.5L3.5 12.5L8.5 12.5L8.5 10.5L9.5 10.5L9.5 13.5L2.5 13.5L2.5 2.5Z" /> - - {:else if name === "lock"} + d="M6 7.5L12.793 7.5L10.6465 5.35352L11.3535 4.64648L14.707 8L11.3535 11.3535L10.6465 10.6465L12.793 8.5L6 8.5L6 7.5Z" /> + {:else if name === "document"} + d="M13.5 14.5L2.5 14.5L2.5 1.5L9.20703 1.5L13.5 5.79297L13.5 14.5ZM8.5 6.5L8.5 2.5L3.5 2.5L3.5 13.5L12.5 13.5L12.5 6.5L8.5 6.5ZM9.5 3.20703L9.5 5.5L11.793 5.5L9.5 3.20703Z" /> + {:else if name === "download"} + d="M7.5 2.5H8.5V9.79297L11 7.29297L11.707 8L8 11.707L4.29297 8L5 7.29297L7.5 9.79297V2.5Z" /> + + {:else if name === "edit"} + + {:else if name === "ellipsis"} + + + + {:else if name === "ellipsis-vertical"} + + + + {:else if name === "emoji"} + + + + + {:else if name === "expand-vertical"} + + + + {:else if name === "eye"} + + + {:else if name === "eye-slash"} + + + + {:else if name === "folder"} + + {:else if name === "folder-open"} + + {:else if name === "git"} + + + {:else if name === "guide"} + + + + {:else if name === "help"} + + + + {:else if name === "hourglass"} + + {:else if name === "issue"} + + {:else if name === "key"} - {:else if name === "more"} + d="M7.5 10C7.5 8.61929 6.38071 7.5 5 7.5C3.61929 7.5 2.5 8.61929 2.5 10C2.5 11.3807 3.61929 12.5 5 12.5C6.38071 12.5 7.5 11.3807 7.5 10ZM8.5 10C8.5 11.933 6.933 13.5 5 13.5C3.067 13.5 1.5 11.933 1.5 10C1.5 8.067 3.067 6.5 5 6.5C6.933 6.5 8.5 8.067 8.5 10Z" /> - {:else if name === "network"} + d="M5 10.5C5 10.7761 4.77614 11 4.5 11C4.22386 11 4 10.7761 4 10.5C4 10.2239 4.22386 10 4.5 10C4.77614 10 5 10.2239 5 10.5Z" /> - {:else if name === "offline"} + d="M4.75 10.5C4.75 10.3619 4.63807 10.25 4.5 10.25C4.36193 10.25 4.25 10.3619 4.25 10.5C4.25 10.6381 4.36193 10.75 4.5 10.75C4.63807 10.75 4.75 10.6381 4.75 10.5ZM5.25 10.5C5.25 10.9142 4.91421 11.25 4.5 11.25C4.08579 11.25 3.75 10.9142 3.75 10.5C3.75 10.0858 4.08579 9.75 4.5 9.75C4.91421 9.75 5.25 10.0858 5.25 10.5Z" /> + d="M14.3535 4.64648L13.6465 5.35352L12 3.70703L10.707 5L12.3535 6.64648L11.6465 7.35352L10 5.70703L7.35352 8.35352L6.64648 7.64648L12 2.29297L14.3535 4.64648Z" /> + {:else if name === "link"} + d="M10.3535 6.35352L6.35352 10.3535L5.64648 9.64648L9.64648 5.64648L10.3535 6.35352Z" /> + d="M8.64648 2.6465C9.94632 1.34667 12.0537 1.34667 13.3535 2.6465C14.6533 3.94634 14.6533 6.0537 13.3535 7.35354L11 9.70705L10.293 9.00002L12.6465 6.6465C13.5558 5.7372 13.5558 4.26284 12.6465 3.35354C11.7372 2.44423 10.2628 2.44423 9.35352 3.35354L7 5.70705L6.29297 5.00002L8.64648 2.6465Z" /> - {:else if name === "online"} + d="M5.70681 7L3.85329 8.85352C2.94398 9.76282 2.94398 11.2372 3.85329 12.1465C4.7626 13.0558 6.23695 13.0558 7.14626 12.1465L8.99978 10.293L9.70681 11L7.85329 12.8535C6.55346 14.1533 4.44609 14.1533 3.14626 12.8535C1.84643 11.5537 1.84643 9.44632 3.14626 8.14648L4.99978 6.29297L5.70681 7Z" /> + {:else if name === "lock"} + d="M10.5 5C10.5 3.61929 9.38071 2.5 8 2.5C6.61929 2.5 5.5 3.61929 5.5 5V6H4.5V5C4.5 3.067 6.067 1.5 8 1.5C9.933 1.5 11.5 3.067 11.5 5V6H10.5V5Z" /> + + d="M9 9C9 9.55228 8.55228 10 8 10C7.44772 10 7 9.55228 7 9C7 8.44772 7.44772 8 8 8C8.55228 8 9 8.44772 9 9Z" /> + + {:else if name === "logo"} + d="M16 12H8V4H16V12ZM12 5.36035C10.542 5.36037 9.36035 6.54296 9.36035 8.00098C9.36051 9.45886 10.5421 10.6406 12 10.6406C13.4579 10.6406 14.6395 9.45887 14.6396 8.00098C14.6396 6.54294 13.458 5.36035 12 5.36035Z" /> + d="M1.87988 8.00012C1.87988 6.82928 2.82903 5.88013 3.99988 5.88013C5.17072 5.88013 6.11987 6.82928 6.11987 8.00012C6.11987 9.17097 5.17072 10.1201 3.99988 10.1201C2.82903 10.1201 1.87988 9.17097 1.87988 8.00012Z" /> + {:else if name === "menu"} + + + + {:else if name === "moon"} + d="M7.33545 2.38928C6.07966 4.14677 6.24028 6.60466 7.81787 8.18225C9.39586 9.75989 11.8542 9.91984 13.6118 8.66272L14.395 9.15784C14.1681 10.4168 13.5693 11.6232 12.5962 12.5963C10.0579 15.1346 5.94221 15.1344 3.40381 12.5963C0.865398 10.0579 0.865398 5.94234 3.40381 3.40393C4.37633 2.43146 5.58144 1.83329 6.83935 1.60608L7.33545 2.38928ZM5.91064 2.91272C5.25599 3.18051 4.64259 3.57924 4.11084 4.11096C1.96295 6.25885 1.96295 9.7414 4.11084 11.8893C6.25877 14.0369 9.7414 14.037 11.8892 11.8893C12.4218 11.3566 12.8204 10.7416 13.0884 10.0856C11.0983 10.9027 8.72776 10.5059 7.11084 8.88928C5.49473 7.27318 5.09511 4.90264 5.91064 2.91272Z" /> + {:else if name === "open-external"} + + {:else if name === "patch"} - + d="M5.5 12C5.5 11.1716 4.82843 10.5 4 10.5C3.17157 10.5 2.5 11.1716 2.5 12C2.5 12.8284 3.17157 13.5 4 13.5C4.82843 13.5 5.5 12.8284 5.5 12ZM13.5 12C13.5 11.1716 12.8284 10.5 12 10.5C11.1716 10.5 10.5 11.1716 10.5 12C10.5 12.8284 11.1716 13.5 12 13.5C12.8284 13.5 13.5 12.8284 13.5 12ZM7.5 2.5H11.5V3.5H9.20703L12.5 6.79297V9.5498C13.6411 9.78142 14.5 10.7905 14.5 12C14.5 13.3807 13.3807 14.5 12 14.5C10.6193 14.5 9.5 13.3807 9.5 12C9.5 10.7905 10.3589 9.78142 11.5 9.5498V7.20703L8.5 4.20703V6.5H7.5V2.5ZM5.5 4C5.5 3.17157 4.82843 2.5 4 2.5C3.17157 2.5 2.5 3.17157 2.5 4C2.5 4.82843 3.17157 5.5 4 5.5C4.82843 5.5 5.5 4.82843 5.5 4ZM6.5 4C6.5 5.20943 5.64105 6.21753 4.5 6.44922V9.5498C5.64114 9.78142 6.5 10.7905 6.5 12C6.5 13.3807 5.38071 14.5 4 14.5C2.61929 14.5 1.5 13.3807 1.5 12C1.5 10.7905 2.35886 9.78142 3.5 9.5498V6.44922C2.35895 6.21753 1.5 5.20943 1.5 4C1.5 2.61929 2.61929 1.5 4 1.5C5.38071 1.5 6.5 2.61929 6.5 4Z" /> + {:else if name === "pin-filled"} + - + d="M10.3906 1.5L11.4287 5.65527L13.2236 6.55273L13.5 6.69141V10.5H8.5V15H7.5V10.5H2.5V6.69141L2.77637 6.55273L4.57031 5.65527L5.60938 1.5H10.3906ZM5.48535 6.12109L5.42969 6.34473L5.22363 6.44727L3.5 7.30859V9.5H12.5V7.30859L10.7764 6.44727L10.5703 6.34473L10.5146 6.12109L9.60938 2.5H6.39062L5.48535 6.12109Z" /> + {:else if name === "pin-hollow"} + + {:else if name === "play"} + + {:else if name === "plus"} + d="M8.5 3V7.50488H13.0049V8.50488H8.5V13H7.5V8.50488H3.00488V7.50488H7.5V3H8.5Z" /> + {:else if name === "question-mark"} - {:else if name === "quorum"} + d="M8.625 11.625C8.625 11.9702 8.34518 12.25 8 12.25C7.65482 12.25 7.375 11.9702 7.375 11.625C7.375 11.2798 7.65482 11 8 11C8.34518 11 8.625 11.2798 8.625 11.625Z" /> + d="M9.63379 6.5C9.63379 5.89312 9.41336 5.5453 9.13867 5.33496C8.84286 5.10866 8.42725 5 8 5C7.57445 5 7.20236 5.10724 6.94531 5.32129C6.7043 5.52213 6.5 5.87024 6.5 6.5H5.5C5.5 5.62992 5.79588 4.97787 6.30469 4.55371C6.79763 4.14292 7.42571 4 8 4C8.57275 4 9.22492 4.14134 9.74609 4.54004C10.2882 4.95474 10.6338 5.60725 10.6338 6.5C10.6338 7.32703 10.1246 7.91638 9.6123 8.29102C9.24736 8.55787 8.84058 8.74663 8.5 8.86816V10H7.5V8.10938L7.87891 8.01465C8.16659 7.9427 8.63623 7.76595 9.02148 7.48438C9.40947 7.20067 9.63379 6.87287 9.63379 6.5Z" /> + {:else if name === "reply"} + d="M5.35352 2.35352L3.20703 4.5H14.5V13.5H10V12.5H13.5V5.5H3.20703L5.35352 7.64648L4.64648 8.35352L1.29297 5L4.64648 1.64648L5.35352 2.35352Z" /> + {:else if name === "repository"} + d="M8.22363 9.44727L8 9.55859L7.77637 9.44727L2.5 6.80859V9.69043L8 12.4404L13.5 9.69043V6.80859L8.22363 9.44727ZM3.11816 6L8 8.44043L12.8818 6L8 3.55859L3.11816 6ZM14.5 10.3086L14.2236 10.4473L8.22363 13.4473L8 13.5586L7.77637 13.4473L1.77637 10.4473L1.5 10.3086V5.69141L1.77637 5.55273L7.77637 2.55273L8 2.44141L8.22363 2.55273L14.2236 5.55273L14.5 5.69141V10.3086Z" /> + {:else if name === "review"} + d="M8 3C10.2021 3 11.8273 4.24044 12.874 5.41797C13.4003 6.01012 13.793 6.60046 14.0547 7.04199C14.1857 7.26315 14.2848 7.44857 14.3516 7.58008C14.385 7.64588 14.4112 7.69851 14.4287 7.73535C14.4373 7.75347 14.4435 7.76802 14.4482 7.77832C14.4506 7.78349 14.4527 7.78795 14.4541 7.79102C14.4548 7.79255 14.4556 7.79393 14.4561 7.79492V7.7959L14.457 7.79688L14.5469 8L14.457 8.20312L14.4561 8.20508C14.4556 8.20607 14.4548 8.20745 14.4541 8.20898C14.4527 8.21205 14.4506 8.21651 14.4482 8.22168C14.4435 8.23198 14.4373 8.24653 14.4287 8.26465C14.4112 8.30149 14.385 8.35412 14.3516 8.41992C14.2848 8.55143 14.1857 8.73685 14.0547 8.95801C13.793 9.39954 13.4003 9.98988 12.874 10.582C11.8273 11.7596 10.2021 13 8 13C5.7979 13 4.17267 11.7596 3.12598 10.582C2.59966 9.98988 2.20697 9.39954 1.94531 8.95801C1.81425 8.73685 1.71524 8.55143 1.64844 8.41992C1.61502 8.35412 1.58875 8.30149 1.57129 8.26465C1.5627 8.24653 1.55649 8.23198 1.55176 8.22168C1.54939 8.21651 1.54728 8.21205 1.5459 8.20898C1.54521 8.20745 1.54439 8.20607 1.54395 8.20508V8.2041L1.54297 8.20312L1.45312 8L1.54297 7.79688L1.54395 7.7959V7.79492C1.54439 7.79393 1.54521 7.79255 1.5459 7.79102C1.54728 7.78795 1.54939 7.78349 1.55176 7.77832C1.55649 7.76802 1.5627 7.75347 1.57129 7.73535C1.58875 7.69851 1.61502 7.64588 1.64844 7.58008C1.71524 7.44857 1.81425 7.26315 1.94531 7.04199C2.20697 6.60046 2.59966 6.01012 3.12598 5.41797C4.17267 4.24044 5.7979 3 8 3ZM8 4C6.20223 4 4.82733 5.00965 3.87402 6.08203C3.40052 6.61472 3.04299 7.14962 2.80469 7.55176C2.69678 7.73386 2.61356 7.88751 2.55566 8C2.61356 8.11249 2.69678 8.26614 2.80469 8.44824C3.04299 8.85038 3.40052 9.38528 3.87402 9.91797C4.82733 10.9904 6.20223 12 8 12C9.79777 12 11.1727 10.9904 12.126 9.91797C12.5995 9.38528 12.957 8.85038 13.1953 8.44824C13.3031 8.26635 13.3855 8.11246 13.4434 8C13.3855 7.88754 13.3031 7.73365 13.1953 7.55176C12.957 7.14962 12.5995 6.61472 12.126 6.08203C11.1727 5.00965 9.79777 4 8 4ZM9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5C8.82843 9.5 9.5 8.82843 9.5 8ZM10.5 8C10.5 9.38071 9.38071 10.5 8 10.5C6.61929 10.5 5.5 9.38071 5.5 8C5.5 6.61929 6.61929 5.5 8 5.5C9.38071 5.5 10.5 6.61929 10.5 8Z" /> + {:else if name === "seed"} + d="M12.3535 6.35352L7.5 11.207V14H6.5V11.207L4.64648 9.35352L5.35352 8.64648L7 10.293L11.6465 5.64648L12.3535 6.35352Z" /> + d="M14 6.5V4H11.5C10.1193 4 9 5.11929 9 6.5C9 7.88071 10.1193 9 11.5 9V10C9.567 10 8 8.433 8 6.5C8 4.567 9.567 3 11.5 3H15V6.5C15 8.433 13.433 10 11.5 10V9C12.8807 9 14 7.88071 14 6.5Z" /> + d="M5 7.5C5 6.67157 4.32843 6 3.5 6C2.67157 6 2 6.67157 2 7.5C2 8.32843 2.67157 9 3.5 9V10C2.11929 10 1 8.88071 1 7.5C1 6.11929 2.11929 5 3.5 5C4.88071 5 6 6.11929 6 7.5C6 8.88071 4.88071 10 3.5 10V9C4.32843 9 5 8.32843 5 7.5Z" /> + {:else if name === "seed-filled"} + d="M12.3535 6.35352L7.5 11.207V14H6.5V11.207L4.64648 9.35352L5.35352 8.64648L7 10.293L11.6465 5.64648L12.3535 6.35352Z" /> - {:else if name === "repo"} + d="M15 6.5C15 8.433 13.433 10 11.5 10C9.567 10 8 8.433 8 6.5C8 4.567 9.567 3 11.5 3H15V6.5Z" /> - {:else if name === "seedling"} + d="M14 6.5V4H11.5C10.1193 4 9 5.11929 9 6.5C9 7.88071 10.1193 9 11.5 9V10C9.567 10 8 8.433 8 6.5C8 4.567 9.567 3 11.5 3H15V6.5C15 8.433 13.433 10 11.5 10V9C12.8807 9 14 7.88071 14 6.5Z" /> + d="M3.5 5C4.88071 5 6 6.11929 6 7.5C6 8.88071 4.88071 10 3.5 10C2.11929 10 1 8.88071 1 7.5C1 6.11929 2.11929 5 3.5 5Z" /> + {:else if name === "settings"} + d="M5.5 10V14H4.5V10H5.5ZM3.5 11.5V12.5H2V11.5H3.5ZM14 11.5V12.5H6.5V11.5H14ZM11.5 6V10H10.5V6H11.5ZM9.5 7.5V8.5H2V7.5H9.5ZM14 7.5V8.5H12.5V7.5H14ZM5.5 2V6H4.5V2H5.5ZM3.5 3.5V4.5H2V3.5H3.5ZM14 3.5V4.5H6.5V3.5H14Z" /> + {:else if name === "stop"} + d="M10.707 1.49994L14.5 5.29291V10.707L10.707 14.4999H5.29297L1.5 10.707V5.29291L5.29297 1.49994H10.707ZM2.5 5.70697V10.2929L5.70703 13.4999H10.293L13.5 10.2929V5.70697L10.293 2.49994H5.70703L2.5 5.70697Z" /> - - - - {:else if name === "share"} - - + d="M9 11C9 11.5523 8.55228 12 8 12C7.44772 12 7 11.5523 7 11C7 10.4477 7.44772 10 8 10C8.55228 10 9 10.4477 9 11Z" /> + {:else if name === "sun"} + d="M10.5 8C10.5 6.61929 9.38071 5.5 8 5.5C6.61929 5.5 5.5 6.61929 5.5 8C5.5 9.38071 6.61929 10.5 8 10.5C9.38071 10.5 10.5 9.38071 10.5 8ZM11.5 8C11.5 9.933 9.933 11.5 8 11.5C6.067 11.5 4.5 9.933 4.5 8C4.5 6.067 6.067 4.5 8 4.5C9.933 4.5 11.5 6.067 11.5 8Z" /> + + d="M3.40535 2.70024L5.17312 4.46801L4.46601 5.17512L2.69824 3.40735L3.40535 2.70024Z" /> + d="M1.00488 7.505L3.50488 7.505L3.50488 8.505L1.00488 8.505L1.00488 7.505Z" /> + d="M2.705 12.5997L4.47277 10.832L5.17988 11.5391L3.41211 13.3069L2.705 12.5997Z" /> + + d="M11.5372 10.832L13.305 12.5997L12.5978 13.3068L10.8301 11.5391L11.5372 10.832Z" /> + d="M12.5049 7.505L15.0049 7.505L15.0049 8.505L12.5049 8.505L12.5049 7.505Z" /> + d="M10.8368 4.468L12.6046 2.70024L13.3117 3.40734L11.5439 5.17511L10.8368 4.468Z" /> + {:else if name === "trash"} - - {:else if name === "user"} - - + d="M13.5 3.5V4.5H12.5V13.5H3.5V4.5H2.5V3.5H13.5ZM4.5 12.5H11.5V4.5H4.5V12.5Z" /> + + + {:else} {unreachable(name)} {/if} diff --git a/src/components/IconButton.svelte b/src/components/IconButton.svelte index ed5cb33bf..542295954 100644 --- a/src/components/IconButton.svelte +++ b/src/components/IconButton.svelte @@ -18,26 +18,26 @@ .button { user-select: none; background-color: transparent; - border-radius: var(--border-radius-tiny); - color: var(--color-foreground-dim); + border-radius: var(--border-radius-sm); + color: var(--color-text-tertiary); cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 8px 6px; gap: 0.25rem; - font-size: var(--font-size-small); + font: var(--txt-body-m-regular); } .inline { display: inline-flex; } .button:hover { - color: var(--color-foreground-contrast); - background-color: var(--color-fill-ghost); + color: var(--color-text-primary); + background-color: var(--color-surface-strong); } .disabled, .disabled:hover { - color: var(--color-fill-counter); + color: var(--color-surface-alpha-subtle); background-color: unset; } diff --git a/src/components/Id.svelte b/src/components/Id.svelte index f24a225bb..36c6f7c31 100644 --- a/src/components/Id.svelte +++ b/src/components/Id.svelte @@ -1,26 +1,24 @@
{ setVisible(true); }} on:mouseleave={() => { setVisible(false); }} - class="target-{style} global-{style}" + class="txt-id" style:cursor="copy" aria-label={ariaLabel} on:click|preventDefault|stopPropagation={async () => { diff --git a/src/components/KeyHint.svelte b/src/components/KeyHint.svelte index cb62d1617..17faf37b8 100644 --- a/src/components/KeyHint.svelte +++ b/src/components/KeyHint.svelte @@ -5,9 +5,8 @@ + +{#if $$slots.breadcrumbs} +
+ + + +
+{:else} +
+{/if} +
+
+ +
+ +
+ +
+
diff --git a/src/components/Link.svelte b/src/components/Link.svelte index f339d84ef..762fcf74b 100644 --- a/src/components/Link.svelte +++ b/src/components/Link.svelte @@ -9,6 +9,7 @@ export let styleHoverState: boolean = false; export let styleTextOverflow: boolean = false; export let title: string | undefined = undefined; + export let ariaLabel: string | undefined = undefined; export let style: string | undefined = undefined; const dispatch = createEventDispatcher<{ @@ -44,6 +45,7 @@ class:hover-style={styleHoverState} on:click={navigateToRoute} href={routeToPath(route)} + aria-label={ariaLabel} {title} {style}> diff --git a/src/components/List.svelte b/src/components/List.svelte index 3f4ac7a71..d4a1e3c88 100644 --- a/src/components/List.svelte +++ b/src/components/List.svelte @@ -4,11 +4,11 @@ diff --git a/src/components/Loading.svelte b/src/components/Loading.svelte index 76d2a86bd..597186222 100644 --- a/src/components/Loading.svelte +++ b/src/components/Loading.svelte @@ -44,15 +44,15 @@ .spinner > div { width: 18px; height: 18px; - background-color: var(--color-fill-secondary); - border-radius: var(--border-radius-round); + background-color: var(--color-surface-brand-primary); + border-radius: var(--border-radius-full); display: inline-block; -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both; animation: sk-bouncedelay 1.4s infinite ease-in-out both; } .spinner.grayscale > div { - background-color: var(--color-fill-ghost); + background-color: var(--color-surface-mid); } .spinner.condensed > div { diff --git a/src/components/Logo.svelte b/src/components/Logo.svelte new file mode 100644 index 000000000..20bfcd210 --- /dev/null +++ b/src/components/Logo.svelte @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/components/Markdown.svelte b/src/components/Markdown.svelte index ca6c3ba34..997ddb13f 100644 --- a/src/components/Markdown.svelte +++ b/src/components/Markdown.svelte @@ -257,9 +257,8 @@ word-break: break-word; } .front-matter { - font-size: var(--font-size-tiny); - font-family: var(--font-family-monospace); - border: 1px dashed var(--color-border-default); + font: var(--txt-body-s-regular); + border: 1px dashed var(--color-border-mid); padding: 0.5rem; margin-bottom: 2rem; } @@ -274,19 +273,17 @@ } .markdown :global(h1) { - font-size: calc(var(--font-size-x-large) * 0.75); - font-weight: var(--font-weight-semibold); + font: var(--txt-heading-l); padding: 1rem 0 0.5rem 0; margin: 0 0 0.75rem; - border-bottom: 1px solid var(--color-border-hint); + border-bottom: 1px solid var(--color-border-subtle); } .markdown :global(h2) { - font-size: var(--font-size-medium); - font-weight: var(--font-weight-regular); + font: var(--txt-heading-m); padding: 0.25rem 0; margin: 2rem 0 0.5rem; - border-bottom: 1px solid var(--color-border-hint); + border-bottom: 1px solid var(--color-border-subtle); } .markdown :global(.pre-wrapper) { @@ -302,8 +299,8 @@ } .markdown :global(radicle-clipboard) { - background-color: var(--color-fill-ghost); - border-radius: var(--border-radius-small); + background-color: var(--color-surface-alpha-mid); + border-radius: var(--border-radius-sm); } .markdown :global(.pre-wrapper:hover > radicle-clipboard) { @@ -311,29 +308,26 @@ } .markdown :global(h3) { - font-size: calc(var(--font-size-medium) * 0.9); - font-weight: var(--font-weight-semibold); + font: var(--txt-heading-m); padding: 0.5rem 0; margin: 1rem 0 0.25rem; } .markdown :global(h4) { - font-weight: var(--font-weight-semibold); - font-size: var(--font-size-regular); + font: var(--txt-body-l-semibold); padding: 0.5rem 0; margin: 1rem 0 0.125rem; } .markdown :global(h5), .markdown :global(h6) { - font-weight: var(--font-weight-semibold); - font-size: var(--font-size-small); + font: var(--txt-body-m-semibold); padding: 0.35rem 0; margin: 1rem 0 0.125rem; } .markdown :global(h6) { - color: var(--color-foreground-dim); + color: var(--color-text-tertiary); } .markdown :global(p) { @@ -348,7 +342,7 @@ .markdown :global(li.task-item) { list-style-type: none; - color: var(--color-foreground-dim); + color: var(--color-text-tertiary); } .markdown :global(li.task-item radicle-icon-small) { margin-right: 0.2rem; @@ -359,14 +353,14 @@ } .markdown :global(blockquote) { - color: var(--color-foreground-dim); - border-left: 0.3rem solid var(--color-fill-ghost); + color: var(--color-text-tertiary); + border-left: 0.3rem solid var(--color-surface-alpha-mid); padding: 0 0 0 1rem; margin: 1rem 0 1rem 0; } .markdown :global(strong) { - font-weight: var(--font-weight-semibold); + font-weight: 600; } .markdown :global(.footnote-ref) { @@ -377,11 +371,7 @@ .markdown :global(.footnote-ref), .markdown :global(.footnote > .marker), .markdown :global(.footnote > .ref-arrow) { - color: var(--color-foreground-dim); - } - .markdown :global(.footnote-ref:hover), - .markdown :global(.footnote .ref-arrow:hover) { - color: var(--color-foreground); + color: var(--color-text-tertiary); } .markdown :global(.footnote) { margin-bottom: 0; @@ -397,10 +387,9 @@ } .markdown :global(code) { - font-family: var(--font-family-monospace); - font-size: var(--font-size-small); - background-color: var(--color-fill-ghost); - border-radius: var(--border-radius-tiny); + font: var(--txt-code-regular); + background-color: var(--color-surface-alpha-mid); + border-radius: var(--border-radius-sm); padding: 0.125rem 0.25rem; } @@ -414,11 +403,10 @@ } .markdown :global(pre) { - font-family: var(--font-family-monospace); - font-size: var(--font-size-regular); - background-color: var(--color-fill-ghost); + font: var(--txt-code-regular); + background-color: var(--color-surface-alpha-mid); padding: 1rem !important; - border-radius: var(--border-radius-small); + border-radius: var(--border-radius-sm); overflow: scroll; scrollbar-width: none; } @@ -434,13 +422,13 @@ } .markdown :global(a) { text-decoration: underline; - text-decoration-color: var(--color-foreground-dim); + text-decoration-color: var(--color-text-tertiary); } .markdown :global(a.no-underline) { text-decoration: none; } .markdown :global(a:hover) { - text-decoration-color: var(--color-foreground-contrast); + text-decoration-color: var(--color-text-primary); } .markdown :global(hr) { @@ -449,14 +437,14 @@ overflow: hidden; background: transparent; border: 0; - border-bottom: 1px solid var(--color-border-hint); + border-bottom: 1px solid var(--color-border-subtle); } .markdown :global(ol) { line-height: 1.625; list-style-type: decimal; margin-bottom: 1rem; - padding-left: 1.5rem; + padding-left: 2rem; } .markdown :global(ul) { @@ -480,19 +468,19 @@ .markdown :global(table) { margin: 1.5rem 0; border-collapse: collapse; - border-radius: var(--border-radius-regular); + border-radius: var(--border-radius-sm); border-style: hidden; - box-shadow: 0 0 0 1px var(--color-border-hint); + box-shadow: 0 0 0 1px var(--color-border-subtle); overflow: hidden; } .markdown :global(td) { text-align: left; text-overflow: ellipsis; - border: 1px solid var(--color-border-hint); + border: 1px solid var(--color-border-subtle); padding: 0.5rem 1rem; } .markdown :global(tr:nth-child(even)) { - background-color: var(--color-background-default); + background-color: var(--color-surface-base); } .markdown :global(th) { text-align: center; @@ -506,7 +494,6 @@ margin-top: 0 !important; } .markdown :global(dl dt) { - font-style: italic; margin-top: 1rem; } .markdown :global(dl dd) { @@ -520,7 +507,7 @@ {#each frontMatter as [key, val]} - {key} + {key} {val} {/each} diff --git a/src/components/Modal.svelte b/src/components/Modal.svelte index bf8b092a8..776003150 100644 --- a/src/components/Modal.svelte +++ b/src/components/Modal.svelte @@ -10,10 +10,9 @@ @@ -30,7 +39,9 @@ styleHoverState style="display: flex; gap: 0.375rem; align-items: center;" route={{ resource: "users", did: nodeId, baseUrl }}> - +
+ +
{#if alias} {alias} diff --git a/src/components/Placeholder.svelte b/src/components/Placeholder.svelte index a35721f51..f3de0a6ea 100644 --- a/src/components/Placeholder.svelte +++ b/src/components/Placeholder.svelte @@ -12,10 +12,10 @@ .placeholder { align-items: center; text-align: center; - color: var(--color-foreground-dim); + color: var(--color-text-tertiary); display: flex; flex-direction: column; - font-size: var(--font-size-small); + font: var(--txt-body-m-regular); gap: 0.5rem; justify-content: center; } diff --git a/src/components/Popover.svelte b/src/components/Popover.svelte index 91d202d91..039d2527b 100644 --- a/src/components/Popover.svelte +++ b/src/components/Popover.svelte @@ -42,9 +42,9 @@ position: relative; } .popover { - background: var(--color-background-float); - border-radius: var(--border-radius-regular); - border: 1px solid var(--color-border-hint); + background: var(--color-surface-canvas); + border-radius: var(--border-radius-md); + border: 1px solid var(--color-border-subtle); box-shadow: var(--elevation-low); padding: 1rem; position: absolute; diff --git a/src/components/Radio.svelte b/src/components/Radio.svelte index c3150c2d0..3967c5a22 100644 --- a/src/components/Radio.svelte +++ b/src/components/Radio.svelte @@ -7,16 +7,16 @@ diff --git a/src/components/Reactions.svelte b/src/components/Reactions.svelte index e0066be4c..5645be824 100644 --- a/src/components/Reactions.svelte +++ b/src/components/Reactions.svelte @@ -24,7 +24,7 @@
{#each reactions as { emoji, authors }}
-
+
{emoji} {authors.length}
diff --git a/src/components/RepoAvatar.svelte b/src/components/RepoAvatar.svelte new file mode 100644 index 000000000..6e0b7676f --- /dev/null +++ b/src/components/RepoAvatar.svelte @@ -0,0 +1,33 @@ + + +{#if dataUri} + Repository Avatar +{:else} +
+
+{/if} diff --git a/src/components/RepoCard.svelte b/src/components/RepoCard.svelte index f063f16f1..dd0b31def 100644 --- a/src/components/RepoCard.svelte +++ b/src/components/RepoCard.svelte @@ -12,10 +12,10 @@ } from "@app/lib/utils"; import ActivityDiagram from "@app/components/ActivityDiagram.svelte"; - import Badge from "@app/components/Badge.svelte"; import Icon from "@app/components/Icon.svelte"; import Id from "@app/components/Id.svelte"; import Link from "@app/components/Link.svelte"; + import RepoAvatar from "@app/components/RepoAvatar.svelte"; export let compact = false; export let repoInfo: RepoInfo; @@ -31,15 +31,17 @@
-
-
- +
+
+ +
+
{project.data.name}
+
+ {#if isPrivate} +
+ +
+ {/if} + +
-
-
-

{project.data.name}

-
- {#if isPrivate} -
- -
- {/if} - - - - {repoInfo.repo.seeding} - +
+
+
+ {project.data.description}
+ + + {formatRepositoryId(repo.rid)} + + +
+
+
-

- {project.data.description} -

-
+
+ + {repoInfo.repo.seeding} · {project.meta.issues.open} · {project.meta.patches.open} {#await api.repo.getCommitBySha(repo.rid, project.meta.head) then { commit }} - · Updated {formatTimestamp(commit.committer.time)} + Updated {formatTimestamp(commit.committer.time)} {/await} - - - - {formatRepositoryId(repo.rid)} - - -
diff --git a/src/components/ScopePolicyExplainer.svelte b/src/components/ScopePolicyExplainer.svelte index c59a45e4f..cf7620a9a 100644 --- a/src/components/ScopePolicyExplainer.svelte +++ b/src/components/ScopePolicyExplainer.svelte @@ -19,9 +19,9 @@
Policy: - {capitalize(policy)} + {capitalize(policy)}
-
+
{#if policy === "allow"} All discovered repositories will be seeded. {:else if policy === "block"} @@ -32,9 +32,9 @@ {#if policy === "allow"}
Scope: - {capitalize(scope)} + {capitalize(scope)}
-
+
{#if scope === "all"} All changes in seeded repositories, made by any peer, will be synced. {:else if scope === "followed"} diff --git a/src/components/TextInput.svelte b/src/components/TextInput.svelte index 5e6ba18eb..7fb7eb096 100644 --- a/src/components/TextInput.svelte +++ b/src/components/TextInput.svelte @@ -77,15 +77,15 @@ flex: 1; align-items: center; height: var(--button-regular-height); - background: var(--color-background-dip); + background: var(--color-surface-base); } input { - background: var(--color-background-dip); + background: var(--color-surface-base); font-family: inherit; - font-size: var(--font-size-small); - color: var(--color-foreground-contrast); - border: 1px solid var(--color-border-hint); - border-radius: var(--border-radius-tiny); + font: var(--txt-body-m-regular); + color: var(--color-text-primary); + border: 1px solid var(--color-border-subtle); + border-radius: var(--border-radius-sm); line-height: 1.6; outline: none; text-overflow: ellipsis; @@ -95,34 +95,33 @@ margin: 0; } input::placeholder { - font-family: var(--font-family-sans-serif); - color: var(--color-foreground-dim); + color: var(--color-text-tertiary); opacity: 1 !important; } input:hover:not(.invalid) { - border: 1px solid var(--color-border-default); + border: 1px solid var(--color-border-mid); } input:hover:not(.invalid) + .right-container { - border-top: 1px solid var(--color-border-default); - border-right: 1px solid var(--color-border-default); - border-bottom: 1px solid var(--color-border-default); - color: var(--color-fill-contrast); + border-top: 1px solid var(--color-border-mid); + border-right: 1px solid var(--color-border-mid); + border-bottom: 1px solid var(--color-border-mid); + color: var(--color-text-primary); } input:focus:not(.invalid) + .right-container { - border-top: 1px solid var(--color-fill-secondary); - border-right: 1px solid var(--color-fill-secondary); - border-bottom: 1px solid var(--color-fill-secondary); - color: var(--color-fill-contrast); + border-top: 1px solid var(--color-border-brand); + border-right: 1px solid var(--color-border-brand); + border-bottom: 1px solid var(--color-border-brand); + color: var(--color-text-primary); } input:focus:not(.invalid) { - border: 1px solid var(--color-fill-secondary); + border: 1px solid var(--color-border-brand); } input[disabled] { cursor: not-allowed; } .right-container { border: 1px solid transparent; - color: var(--color-fill-gray); + color: var(--color-text-tertiary); position: absolute; right: 0; top: 0; @@ -131,12 +130,12 @@ padding-left: 0.5rem; overflow: hidden; height: 100%; - border-top-right-radius: var(--border-radius-tiny); - border-bottom-right-radius: var(--border-radius-tiny); + border-top-right-radius: var(--border-radius-sm); + border-bottom-right-radius: var(--border-radius-sm); gap: 0.25rem; } .invalid { - border: 1px solid var(--color-border-error); + border: 1px solid var(--color-feedback-error-border); } diff --git a/src/components/Thread.svelte b/src/components/Thread.svelte index 34eabaecd..6f1c7b20d 100644 --- a/src/components/Thread.svelte +++ b/src/components/Thread.svelte @@ -19,15 +19,15 @@ .comments { display: flex; flex-direction: column; - box-shadow: 0 0 0 1px var(--color-border-hint); - border-radius: var(--border-radius-small); + box-shadow: 0 0 0 1px var(--color-border-subtle); + border-radius: var(--border-radius-sm); } .top-level-comment { - background-color: var(--color-background-float); - border-radius: var(--border-radius-small); + background-color: var(--color-surface-subtle); + border-radius: var(--border-radius-sm); } .has-replies { - border-bottom: 1px solid var(--color-fill-separator); + border-bottom: 1px solid var(--color-border-subtle); border-bottom-left-radius: 0; border-bottom-right-radius: 0; } @@ -54,7 +54,7 @@ reactions={root.reactions} timestamp={root.timestamp} body={root.body}> - +
{#if replies.length > 0} diff --git a/src/components/UserAvatar.svelte b/src/components/UserAvatar.svelte new file mode 100644 index 000000000..81212e761 --- /dev/null +++ b/src/components/UserAvatar.svelte @@ -0,0 +1,22 @@ + + +{#if dataUri} + Avatar +{/if} diff --git a/src/lib/avatar.ts b/src/lib/avatar.ts new file mode 100644 index 000000000..08a38c82f --- /dev/null +++ b/src/lib/avatar.ts @@ -0,0 +1,937 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { cached } from "@app/lib/cache"; + +type AtomType = "A" | "B" | "C" | "D"; +type ShapeModel = + | "rose" + | "starburst" + | "ringed" + | "tip" + | "notched" + | "hollow"; +type AtomMode = "bands-ABC" | "angle-stripes" | "parity-ACB" | "balanced-rand"; + +const PALETTE = [ + "#00D4DA", // teal + "#886BF2", // purple + "#FFA5FF", // pink + "#009F67", // green + "#CCFF38", // lime + "#585600", // olive +]; + +const REPO_CONFIG = { + GRID_SIZE: 16, + CELL_SIZE: 32, + PIXEL_DENSITY: 2, + GLYPH: { + WIDTH: 5, + HEIGHT: 7, + SPACING: 2, + SCALE_2X_WIDTH: 10, + SCALE_2X_HEIGHT: 14, + }, + ATOMS: { + CIRCLE_B_RATIO: 0.55, + CIRCLE_C_RATIO: 0.67, + }, +} as const; + +const USER_CONFIG = { + TILE_SIZE: 32, + DEFAULT_GRID: 10, + PIXEL_DENSITY: 2, + ATOMS: { + ELLIPSE_B_SIZE: 17, + ELLIPSE_C_SIZE: 21, + }, + TOLERANCE: { + ANGLE_NEAR_BASE: Math.PI / 28, + ANGLE_FAR_BASE: Math.PI / 7, + NEAR_RANGE: { MIN: 0.7, MAX: 1.2 }, + FAR_RANGE: { MIN: 0.7, MAX: 1.2 }, + }, + SOFTNESS: { + MIN: 1.2, + MAX: 4.2, + }, + RING_PHASE: { + MIN: 0.2, + MAX: 0.8, + }, +} as const; + +function hash32(str: string): number { + let h = 2166136261 >>> 0; + for (let i = 0; i < str.length; i++) { + h ^= str.charCodeAt(i); + h = Math.imul(h, 16777619); + } + return h >>> 0; +} + +function xmur3(str: string): () => number { + let h = 1779033703 ^ str.length; + for (let i = 0; i < str.length; i++) { + h = Math.imul(h ^ str.charCodeAt(i), 3432918353); + h = (h << 13) | (h >>> 19); + } + return function () { + h = Math.imul(h ^ (h >>> 16), 2246822507); + h = Math.imul(h ^ (h >>> 13), 3266489909); + return (h ^= h >>> 16) >>> 0; + }; +} + +function mulberry32(a: number): () => number { + return function () { + let t = (a += 0x6d2b79f5); + t = Math.imul(t ^ (t >>> 15), t | 1); + t ^= t + Math.imul(t ^ (t >>> 7), t | 61); + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +function makeRNG(key: string): () => number { + return mulberry32(xmur3(key)()); +} + +function chooseK(arr: T[], k: number, rnd: () => number): T[] { + const pool = arr.slice(); + const out = []; + for (let i = 0; i < k; i++) { + const idx = Math.floor(rnd() * pool.length); + out.push(pool.splice(idx, 1)[0]); + } + return out; +} + +function pick(rng: () => number, arr: T[]): T { + return arr[Math.floor(rng() * arr.length)]; +} + +function createOffscreenCanvas( + w: number, + h: number, + density: number = 2, +): { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D } { + const canvas = document.createElement("canvas"); + canvas.width = w * density; + canvas.height = h * density; + const ctx = canvas.getContext("2d")!; + ctx.scale(density, density); + ctx.imageSmoothingEnabled = false; + return { canvas, ctx }; +} + +function fillCircle( + ctx: CanvasRenderingContext2D, + x: number, + y: number, + diameter: number, + color: string, +): void { + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc(x, y, diameter / 2, 0, Math.PI * 2); + ctx.fill(); +} + +function fillEllipse( + ctx: CanvasRenderingContext2D, + x: number, + y: number, + w: number, + h: number, + color: string, +): void { + ctx.fillStyle = color; + ctx.beginPath(); + ctx.ellipse(x, y, w / 2, h / 2, 0, 0, Math.PI * 2); + ctx.fill(); +} + +interface AtomDrawConfig { + cellSize: number; + circleB: number; + circleC: number; + useEllipse?: boolean; +} + +function createAtomRenderer(config: AtomDrawConfig) { + const drawCircleOrEllipse = ( + ctx: CanvasRenderingContext2D, + x: number, + y: number, + w: number, + h: number, + color: string, + ) => { + if (config.useEllipse) { + fillEllipse(ctx, x, y, w, h, color); + } else { + fillCircle(ctx, x, y, w, color); // w is diameter for circles + } + }; + + return { + drawAtomA( + ctx: CanvasRenderingContext2D, + gx: number, + gy: number, + c1: string, + ): void { + const x = gx * config.cellSize; + const y = gy * config.cellSize; + ctx.fillStyle = c1; + ctx.fillRect(x, y, config.cellSize, config.cellSize); + }, + + drawAtomB( + ctx: CanvasRenderingContext2D, + gx: number, + gy: number, + c1: string, + c2: string, + ): void { + const x = gx * config.cellSize; + const y = gy * config.cellSize; + ctx.fillStyle = c1; + ctx.fillRect(x, y, config.cellSize, config.cellSize); + drawCircleOrEllipse( + ctx, + x + config.cellSize / 2, + y + config.cellSize / 2, + config.circleB, + config.circleB, + c2, + ); + }, + + drawAtomC( + ctx: CanvasRenderingContext2D, + gx: number, + gy: number, + c2: string, + c3: string, + ): void { + const x = gx * config.cellSize; + const y = gy * config.cellSize; + ctx.fillStyle = c2; + ctx.fillRect(x, y, config.cellSize, config.cellSize); + drawCircleOrEllipse( + ctx, + x + config.cellSize / 2, + y + config.cellSize / 2, + config.circleC, + config.circleC, + c3, + ); + }, + + drawAtomD( + ctx: CanvasRenderingContext2D, + gx: number, + gy: number, + c3: string, + ): void { + const x = gx * config.cellSize; + const y = gy * config.cellSize; + ctx.fillStyle = c3; + ctx.fillRect(x, y, config.cellSize, config.cellSize); + }, + + drawAtom( + ctx: CanvasRenderingContext2D, + atom: AtomType, + gx: number, + gy: number, + c1: string, + c2: string, + c3: string, + ): void { + switch (atom) { + case "A": + this.drawAtomA(ctx, gx, gy, c1); + break; + case "B": + this.drawAtomB(ctx, gx, gy, c1, c2); + break; + case "C": + this.drawAtomC(ctx, gx, gy, c2, c3); + break; + case "D": + this.drawAtomD(ctx, gx, gy, c3); + break; + } + }, + }; +} + +// 5x7 pixel font glyphs (cached at module level for performance) +function createGlyphs5x7(): Record { + const L: Record = {}; + const r = (s: string[]) => + s.map(row => row.split("").map(ch => (ch === "1" ? 1 : 0))); + L["A"] = r(["01110", "10001", "10001", "11111", "10001", "10001", "10001"]); + L["B"] = r(["11110", "10001", "10001", "11110", "10001", "10001", "11110"]); + L["C"] = r(["01111", "10000", "10000", "10000", "10000", "10000", "01111"]); + L["D"] = r(["11110", "10001", "10001", "10001", "10001", "10001", "11110"]); + L["E"] = r(["11111", "10000", "10000", "11110", "10000", "10000", "11111"]); + L["F"] = r(["11111", "10000", "10000", "11110", "10000", "10000", "10000"]); + L["G"] = r(["01111", "10000", "10000", "10111", "10001", "10001", "01111"]); + L["H"] = r(["10001", "10001", "10001", "11111", "10001", "10001", "10001"]); + L["I"] = r(["11111", "00100", "00100", "00100", "00100", "00100", "11111"]); + L["J"] = r(["11111", "00001", "00001", "00001", "10001", "10001", "01110"]); + L["K"] = r(["10001", "10010", "10100", "11000", "10100", "10010", "10001"]); + L["L"] = r(["10000", "10000", "10000", "10000", "10000", "10000", "11111"]); + L["M"] = r(["10001", "11011", "10101", "10001", "10001", "10001", "10001"]); + L["N"] = r(["10001", "11001", "10101", "10011", "10001", "10001", "10001"]); + L["O"] = r(["01110", "10001", "10001", "10001", "10001", "10001", "01110"]); + L["P"] = r(["11110", "10001", "10001", "11110", "10000", "10000", "10000"]); + L["Q"] = r(["01110", "10001", "10001", "10001", "10101", "10010", "01101"]); + L["R"] = r(["11110", "10001", "10001", "11110", "10100", "10010", "10001"]); + L["S"] = r(["01111", "10000", "11110", "00001", "00001", "10001", "11110"]); + L["T"] = r(["11111", "00100", "00100", "00100", "00100", "00100", "00100"]); + L["U"] = r(["10001", "10001", "10001", "10001", "10001", "10001", "01110"]); + L["V"] = r(["10001", "10001", "10001", "01010", "01010", "00100", "00100"]); + L["W"] = r(["10001", "10001", "10001", "10101", "10101", "11011", "10001"]); + L["X"] = r(["10001", "01010", "00100", "00100", "00100", "01010", "10001"]); + L["Y"] = r(["10001", "01010", "00100", "00100", "00100", "00100", "00100"]); + L["Z"] = r(["11111", "00001", "00010", "00100", "01000", "10000", "11111"]); + L["0"] = r(["01110", "10001", "10011", "10101", "11001", "10001", "01110"]); + L["1"] = r(["00100", "01100", "00100", "00100", "00100", "00100", "01110"]); + L["2"] = r(["01110", "10001", "00001", "00110", "01000", "10000", "11111"]); + L["3"] = r(["11110", "00001", "01110", "00001", "00001", "00001", "11110"]); + L["4"] = r(["10010", "10010", "10010", "11111", "00010", "00010", "00010"]); + L["5"] = r(["11111", "10000", "11110", "00001", "00001", "00001", "11110"]); + L["6"] = r(["01110", "10000", "11110", "10001", "10001", "10001", "01110"]); + L["7"] = r(["11111", "00001", "00010", "00100", "01000", "01000", "01000"]); + L["8"] = r(["01110", "10001", "01110", "10001", "10001", "10001", "01110"]); + L["9"] = r(["01110", "10001", "10001", "01111", "00001", "00001", "11110"]); + L["?"] = r(["11111", "00001", "01110", "00000", "00100", "00000", "00100"]); + return L; +} + +const LETTER_5X7 = createGlyphs5x7(); + +function getInitials(name: string): string[] { + if (!name || typeof name !== "string") return ["?"]; + const cleaned = name.trim().replace(/\s+/g, " "); + const parts = cleaned.split(/[^A-Za-z0-9]+/).filter(Boolean); + const first = parts[0] ? parts[0][0].toUpperCase() : "?"; + const second = parts[1] ? parts[1][0].toUpperCase() : null; + return second ? [first, second] : [first]; +} + +function polarFromCell( + gx: number, + gy: number, + cx: number, + cy: number, +): { r: number; a: number } { + const x = gx - cx + 0.5; + const y = gy - cy + 0.5; + const r = Math.hypot(x, y); + let a = Math.atan2(y, x); + if (a < 0) a += 2 * Math.PI; + return { r, a }; +} + +function shapeRose(theta: number, petals: number, tol: number): boolean { + const sector = Math.PI / petals; + const nearest = Math.round(theta / sector) * sector; + let diff = Math.abs(theta - nearest); + diff = Math.min(diff, 2 * Math.PI - diff); + return diff <= tol; +} + +function shapeStarburst( + theta: number, + petals: number, + softness: number, +): boolean { + const period = (2 * Math.PI) / petals; + const local = theta % period; + const d = Math.min(local, period - local) / (period / 2); + const response = Math.pow(Math.cos((d * Math.PI) / 2), softness); + return response > 0.5; +} + +function shapeRinged( + theta: number, + petals: number, + ringPhase: number, + tol: number, +): boolean { + const sector = (2 * Math.PI) / petals; + const k = Math.floor(theta / sector); + const center = k * sector + sector * ringPhase; + let diff = Math.abs(theta - center); + diff = Math.min(diff, 2 * Math.PI - diff); + return diff <= tol; +} + +function shapeTip( + theta: number, + petals: number, + tol: number, + t: number, +): boolean { + return shapeRose(theta, petals, tol * (0.5 + 1.0 * t)) && t > 0.45; +} + +function shapeNotched( + theta: number, + petals: number, + tol: number, + notchDepth: number = 0.25, +): boolean { + const sector = (2 * Math.PI) / petals; + const local = (theta % sector) / sector; + const notch = Math.abs(local - 0.5); + return shapeRose(theta, petals, tol) && notch > notchDepth; +} + +function shapeHollow( + theta: number, + petals: number, + tol: number, + t: number, + inner: number = 0.28, + outer: number = 0.9, +): boolean { + return shapeRose(theta, petals, tol) && t > inner && t < outer; +} + +function sectorGate(theta: number, petals: number, mask: boolean[]): boolean { + const sector = (2 * Math.PI) / petals; + const k = Math.floor(theta / sector); + return mask[k % mask.length]; +} + +export const cachedRepoAvatar = cached( + async (key: string) => renderRepoAvatar(key), + (key: string) => key, + { max: 2000 }, +); + +export const cachedUserAvatar = cached( + async (key: string) => renderUserAvatar(key), + (key: string) => key, + { max: 2000 }, +); + +function renderRepoAvatar(key: string): string { + if (typeof window === "undefined") { + return ""; + } + + { + // Color logic: + // A: square = Color1 + // B: square = Color1, circle = Color2 + // C: square = Color2, circle = Color3 + // D: square = Color3 + // Letters: solid-only (A or D). Background: other three atoms. + // Single initial: 2x2 expansion (10x14). Two initials: 5x7 each. + + const GRID = REPO_CONFIG.GRID_SIZE; + const CELL = REPO_CONFIG.CELL_SIZE; + const W = GRID * CELL; + const H = GRID * CELL; + + const { canvas, ctx } = createOffscreenCanvas( + W, + H, + REPO_CONFIG.PIXEL_DENSITY, + ); + + const atoms = createAtomRenderer({ + cellSize: CELL, + circleB: CELL * REPO_CONFIG.ATOMS.CIRCLE_B_RATIO, + circleC: CELL * REPO_CONFIG.ATOMS.CIRCLE_C_RATIO, + useEllipse: false, + }); + + function renderInitialsAvatar(nameKey: string = "color bright") { + const initials = getInitials(nameKey); + const seed = hash32(nameKey.toLowerCase()); + const rnd = mulberry32(seed); + + // Select three distinct colors deterministically (Color1, Color2, Color3) + const [c1, c2, c3] = chooseK(PALETTE, 3, rnd); + + // Choose letter solid atom: 'A' or 'D' (deterministic) + const letterSolidAtom: AtomType = ((seed >>> 7) & 1) === 0 ? "A" : "D"; + + const bgAtoms: AtomType[] = (["A", "B", "C", "D"] as AtomType[]).filter( + a => a !== letterSolidAtom, + ); + + function pickBgAtom(gx: number, gy: number): AtomType { + const k = (gy * 131 + gx * 197 + seed) >>> 0; + return bgAtoms[k % bgAtoms.length]; + } + + // 1) Background: fill with bgAtoms using strict color mapping + for (let gy = 0; gy < GRID; gy++) { + for (let gx = 0; gx < GRID; gx++) { + const atom = pickBgAtom(gx, gy); + atoms.drawAtom(ctx, atom, gx, gy, c1, c2, c3); + } + } + + // 2) Letters: solid-only atom across glyph pixels, strict mapping (A uses c1, D uses c3) + const glyphW = REPO_CONFIG.GLYPH.WIDTH; + const glyphH = REPO_CONFIG.GLYPH.HEIGHT; + + function placeSolidLetter( + glyph: number[][], + startX: number, + startY: number, + scale2x: boolean, + ) { + if (scale2x) { + // 2x2 expansion → 10x14 + for (let r = 0; r < glyphH; r++) { + for (let c = 0; c < glyphW; c++) { + if (!glyph[r][c]) continue; + const gx = startX + c * 2; + const gy = startY + r * 2; + if (letterSolidAtom === "A") { + atoms.drawAtomA(ctx, gx, gy, c1); + atoms.drawAtomA(ctx, gx + 1, gy, c1); + atoms.drawAtomA(ctx, gx, gy + 1, c1); + atoms.drawAtomA(ctx, gx + 1, gy + 1, c1); + } else { + atoms.drawAtomD(ctx, gx, gy, c3); + atoms.drawAtomD(ctx, gx + 1, gy, c3); + atoms.drawAtomD(ctx, gx, gy + 1, c3); + atoms.drawAtomD(ctx, gx + 1, gy + 1, c3); + } + } + } + } else { + // 1x scale + for (let r = 0; r < glyphH; r++) { + for (let c = 0; c < glyphW; c++) { + if (!glyph[r][c]) continue; + const gx = startX + c; + const gy = startY + r; + if (letterSolidAtom === "A") { + atoms.drawAtomA(ctx, gx, gy, c1); + } else { + atoms.drawAtomD(ctx, gx, gy, c3); + } + } + } + } + } + + if (initials.length === 1) { + // Single initial: 2x2 expansion (10x14), centered + const glyph = LETTER_5X7[initials[0]] || LETTER_5X7["?"]; + const startX = Math.floor( + (GRID - REPO_CONFIG.GLYPH.SCALE_2X_WIDTH) / 2, + ); + const startY = Math.floor( + (GRID - REPO_CONFIG.GLYPH.SCALE_2X_HEIGHT) / 2, + ); + placeSolidLetter(glyph, startX, startY, true); + } else { + // Two initials: 5x7 each, side-by-side + const leftGlyph = LETTER_5X7[initials[0]] || LETTER_5X7["?"]; + const rightGlyph = LETTER_5X7[initials[1]] || LETTER_5X7["?"]; + const spacing = REPO_CONFIG.GLYPH.SPACING; + const totalW = REPO_CONFIG.GLYPH.WIDTH * 2 + spacing; + const totalH = REPO_CONFIG.GLYPH.HEIGHT; + const startX = Math.floor((GRID - totalW) / 2); + const startY = Math.floor((GRID - totalH) / 2); + placeSolidLetter(leftGlyph, startX, startY, false); + placeSolidLetter( + rightGlyph, + startX + REPO_CONFIG.GLYPH.WIDTH + spacing, + startY, + false, + ); + } + + return canvas.toDataURL(); + } + + return renderInitialsAvatar(key); + } +} + +function renderUserAvatar(key: string): string { + if (typeof window === "undefined") { + return ""; + } + + { + const TILE = USER_CONFIG.TILE_SIZE; + const DEFAULT_GRID = USER_CONFIG.DEFAULT_GRID; + + const atoms = createAtomRenderer({ + cellSize: TILE, + circleB: USER_CONFIG.ATOMS.ELLIPSE_B_SIZE, + circleC: USER_CONFIG.ATOMS.ELLIPSE_C_SIZE, + useEllipse: true, + }); + + // Edge-to-edge integer placement + function drawAt( + fn: (x: number, y: number) => void, + gx: number, + gy: number, + ): void { + fn(gx * TILE, gy * TILE); + } + + // Strict 4-way symmetry (quadrant mirroring) + function drawQuad( + fn: (x: number, y: number) => void, + gx: number, + gy: number, + grid: number, + ): void { + const N = grid - 1; + drawAt(fn, gx, gy); + drawAt(fn, N - gx, gy); + drawAt(fn, gx, N - gy); + drawAt(fn, N - gx, N - gy); + } + + // Draw by atom type (converts pixel coordinates to grid coordinates) + function drawAtomByType( + ctx: CanvasRenderingContext2D, + type: AtomType, + x: number, + y: number, + c1: string, + c2: string, + c3: string, + ): void { + const gx = x / TILE; + const gy = y / TILE; + atoms.drawAtom(ctx, type, gx, gy, c1, c2, c3); + } + + // Make assigner among active petal atoms (exclude background atom) + function makeAssigner( + mode: AtomMode, + activeAtoms: AtomType[], + ): (rCell: number, theta?: number, sectorIdx?: number) => AtomType { + if (mode === "bands-ABC") + return (rCell: number) => activeAtoms[rCell % 3]; + if (mode === "angle-stripes") + return (_rCell: number, _theta?: number, sectorIdx?: number) => + activeAtoms[(sectorIdx || 0) % activeAtoms.length]; + if (mode === "parity-ACB") + return (rCell: number) => activeAtoms[rCell % 2 ? 1 : 0]; + if (mode === "balanced-rand") + return (rCell: number, theta?: number, sectorIdx?: number) => { + const v = + (Math.sin( + (theta || 0) * 13.37 + rCell * 2.17 + (sectorIdx || 0) * 0.73, + ) + + 1) / + 2; + if (v < 0.33) return activeAtoms[0]; + if (v < 0.66) return activeAtoms[1]; + return activeAtoms[2]; + }; + return (rCell: number) => activeAtoms[rCell % 3]; + } + + function generateFlower( + ctx: CanvasRenderingContext2D, + canvas: HTMLCanvasElement, + key: string, + grid: number = DEFAULT_GRID, + ): void { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + const rng = makeRNG(key); + + const picked = PALETTE.slice().sort(() => rng() - 0.5); + const [c1, c2, c3] = picked.slice(0, 3); + + const allAtoms: AtomType[] = ["A", "B", "C", "D"]; + const bgAtom: AtomType = pick(rng, allAtoms); + const petalAtoms: AtomType[] = allAtoms + .filter(a => a !== bgAtom) + .sort(() => rng() - 0.5); + + const cx = Math.floor(grid / 2), + cy = Math.floor(grid / 2); + const maxR = Math.min(cx, cy); + const petals = pick(rng, [5, 6, 7, 8, 9, 10]); + const petalDepth = Math.max(5, Math.floor(maxR * (0.6 + 0.35 * rng()))); + const radialThickness = pick(rng, [1, 2, 2, 3, 3]); + const shapeModel: ShapeModel = pick(rng, [ + "rose", + "starburst", + "ringed", + "tip", + "notched", + "hollow", + ]); + const atomMode: AtomMode = pick(rng, [ + "bands-ABC", + "angle-stripes", + "parity-ACB", + "balanced-rand", + ]); + const assignAtom = makeAssigner(atomMode, petalAtoms); + + // Angle tolerances + const angleTolNear = + USER_CONFIG.TOLERANCE.ANGLE_NEAR_BASE * + (USER_CONFIG.TOLERANCE.NEAR_RANGE.MIN + + rng() * + (USER_CONFIG.TOLERANCE.NEAR_RANGE.MAX - + USER_CONFIG.TOLERANCE.NEAR_RANGE.MIN)); + const angleTolFar = + USER_CONFIG.TOLERANCE.ANGLE_FAR_BASE * + (USER_CONFIG.TOLERANCE.FAR_RANGE.MIN + + rng() * + (USER_CONFIG.TOLERANCE.FAR_RANGE.MAX - + USER_CONFIG.TOLERANCE.FAR_RANGE.MIN)); + const softness = + USER_CONFIG.SOFTNESS.MIN + + rng() * (USER_CONFIG.SOFTNESS.MAX - USER_CONFIG.SOFTNESS.MIN); + const ringPhase = + USER_CONFIG.RING_PHASE.MIN + + rng() * (USER_CONFIG.RING_PHASE.MAX - USER_CONFIG.RING_PHASE.MIN); + + // Sector gating mask (~70% sectors on), ensures bold shapes + const sectorMask = Array.from({ length: petals }, () => rng() > 0.3); + if (sectorMask.every(v => !v)) sectorMask[Math.floor(petals / 2)] = true; + + const drawBgAtom = (gx: number, gy: number) => { + drawAt( + (x: number, y: number) => + drawAtomByType(ctx, bgAtom, x, y, c1, c2, c3), + gx, + gy, + ); + }; + + // 0) Base pass: paint every tile once with background atom to avoid gaps + function renderBasePass() { + for (let gy = 0; gy < grid; gy++) { + for (let gx = 0; gx < grid; gx++) { + drawBgAtom(gx, gy); + } + } + } + + // 1) Outer edge circumference (1–2 tiles thick) reinforced in background atom + function renderEdgeReinforcement() { + const edgeThickness = pick(rng, [1, 1, 2]); + for (let t = 0; t < edgeThickness; t++) { + for (let i = 0; i < grid; i++) { + drawBgAtom(i, t); + drawBgAtom(i, grid - 1 - t); + drawBgAtom(t, i); + drawBgAtom(grid - 1 - t, i); + } + } + } + + // 2) Background atom structural accents inside (deterministic) + // - mid ring (optional) and a few gated spokes to help define silhouette + function renderStructuralAccents() { + // Mid ring + if (rng() < 0.7) { + const midR = Math.floor(petalDepth * (0.5 + 0.2 * rng())); + for (let i = 0; i < grid; i++) { + const coords: [number, number][] = [ + [cx - midR, i], + [cx + midR, i], + [i, cy - midR], + [i, cy + midR], + ]; + coords.forEach(([gx, gy]) => { + if (gx >= 0 && gy >= 0 && gx < grid && gy < grid) { + drawQuad( + (x: number, y: number) => + drawAtomByType(ctx, bgAtom, x, y, c1, c2, c3), + gx, + gy, + grid, + ); + } + }); + } + } + + // Gated spokes + if (rng() < 0.6) { + const gateEvery = pick(rng, [2, 3, 4]); + for (let s = 0; s < petals; s++) { + if (s % gateEvery !== 0) continue; + const theta = s * ((2 * Math.PI) / petals); + for (let r = 1; r <= petalDepth; r++) { + const gx = Math.round(cx + r * Math.cos(theta)); + const gy = Math.round(cy + r * Math.sin(theta)); + if (gx >= 0 && gy >= 0 && gx < grid && gy < grid) { + drawQuad( + (x: number, y: number) => + drawAtomByType(ctx, bgAtom, x, y, c1, c2, c3), + gx, + gy, + grid, + ); + } + } + } + } + } + + // 3) Strong center cluster (guarantee coverage; seed form) + function renderCenterCluster() { + const centerCluster: [number, number, AtomType][] = [ + [0, 0, "D"], + [0, -1, petalAtoms[0]], + [1, 0, petalAtoms[1]], + [0, 1, petalAtoms[2]], + [-1, 0, petalAtoms[0]], + ]; + centerCluster.forEach(([dx, dy, t]: [number, number, AtomType]) => { + const gx = cx + dx, + gy = cy + dy; + if (gx < 0 || gy < 0 || gx >= grid || gy >= grid) return; + drawQuad( + (x: number, y: number) => drawAtomByType(ctx, t, x, y, c1, c2, c3), + gx, + gy, + grid, + ); + }); + } + + // 4) Petals (TL quadrant → mirror) + function renderPetals() { + const half = Math.ceil(grid / 2); + for (let gy = 0; gy < half; gy++) { + for (let gx = 0; gx < half; gx++) { + const { r, a } = polarFromCell(gx, gy, cx, cy); + const rCell = Math.floor(r); + if (rCell === 0 || rCell > petalDepth) continue; + + const t = rCell / petalDepth; + const tol = angleTolNear * (1 - t) + angleTolFar * t; + + const sectorIdx = Math.floor(a / ((2 * Math.PI) / petals)); + if (!sectorGate(a, petals, sectorMask)) continue; + + let inside = false; + if (shapeModel === "rose") inside = shapeRose(a, petals, tol); + else if (shapeModel === "starburst") + inside = shapeStarburst(a, petals, softness); + else if (shapeModel === "ringed") + inside = shapeRinged(a, petals, ringPhase, tol * 0.7); + else if (shapeModel === "tip") inside = shapeTip(a, petals, tol, t); + else if (shapeModel === "notched") + inside = shapeNotched(a, petals, tol, 0.24); + else inside = shapeHollow(a, petals, tol, t, 0.28, 0.92); + + if (!inside) continue; + + const type = assignAtom(rCell, a, sectorIdx); + + // Draw with radial thickness and 4-way mirroring + for (let dr = 0; dr < radialThickness; dr++) { + const x1 = gx + dr, + y1 = gy + dr; + const coords: [number, number][] = [ + [x1, y1], + [grid - 1 - x1, y1], + [x1, grid - 1 - y1], + [grid - 1 - x1, grid - 1 - y1], + ]; + coords.forEach(([ix, iy]: [number, number]) => { + if (ix < 0 || iy < 0 || ix >= grid || iy >= grid) return; + drawAt( + (x: number, y: number) => + drawAtomByType(ctx, type, x, y, c1, c2, c3), + ix, + iy, + ); + }); + } + } + } + } + + // 5) Ensure all three petal atoms appear at least once + function renderAccents() { + const accents: [number, number, AtomType][] = [ + [cx, cy - 2, petalAtoms[0]], + [cx + 1, cy, petalAtoms[1]], + [cx, cy + 2, petalAtoms[2]], + ]; + accents.forEach(([gx, gy, t]: [number, number, AtomType]) => { + if (gx < 0 || gy < 0 || gx >= grid || gy >= grid) return; + drawQuad( + (x: number, y: number) => drawAtomByType(ctx, t, x, y, c1, c2, c3), + gx, + gy, + grid, + ); + }); + } + + // 6) Final safety: ensure center 6×6 px is covered via 2×2 cluster + function renderFinalCluster() { + const cluster: [number, number, AtomType][] = [ + [0, 0, "D"], + [1, 0, petalAtoms[1]], + [0, 1, petalAtoms[2]], + [1, 1, petalAtoms[0]], + ]; + cluster.forEach(([dx, dy, t]: [number, number, AtomType]) => { + const gx = cx + dx, + gy = cy + dy; + if (gx < 0 || gy < 0 || gx >= grid || gy >= grid) return; + drawQuad( + (x: number, y: number) => drawAtomByType(ctx, t, x, y, c1, c2, c3), + gx, + gy, + grid, + ); + }); + } + + renderBasePass(); + renderEdgeReinforcement(); + renderStructuralAccents(); + renderCenterCluster(); + renderPetals(); + renderAccents(); + renderFinalCluster(); + } + + function drawFlowerForKey( + key: string, + grid: number = DEFAULT_GRID, + ): string { + const canvasPx = grid * TILE; + + const { canvas, ctx } = createOffscreenCanvas( + canvasPx, + canvasPx, + USER_CONFIG.PIXEL_DENSITY, + ); + + generateFlower(ctx, canvas, key, grid); + + return canvas.toDataURL(); + } + + return drawFlowerForKey(key, DEFAULT_GRID); + } +} diff --git a/src/modals/ColorPaletteModal.svelte b/src/modals/ColorPaletteModal.svelte deleted file mode 100644 index 28fbf5c70..000000000 --- a/src/modals/ColorPaletteModal.svelte +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - -
-
(checkers = !checkers)}> -
- {#each colorGroups as colorGroup} -
- {#each colors.filter(color => { - return color.match(`--color-${colorGroup}`); - }) as color} -
-
-
-
- {/each} -
- {/each} -
-
-
-
diff --git a/src/modals/DesignSystemModal.svelte b/src/modals/DesignSystemModal.svelte new file mode 100644 index 000000000..69d0eaae8 --- /dev/null +++ b/src/modals/DesignSystemModal.svelte @@ -0,0 +1,297 @@ + + + + + +
+
+ + + +
+ +
+
+ +
+
+ {#each colorGroups as colorGroup} +
+ {#each colors.filter(color => { + return getColorGroup(color) === colorGroup; + }) as color} +
+
+
+
+ {/each} +
+ {/each} +
+
+ +
+
+ {#each icons.slice(0, 25) as icon} +
+ +
+ {/each} +
+
+ {#each icons.slice(25, 50) as icon} +
+ +
+ {/each} +
+
+ {#each icons.slice(50) as icon} +
+ +
+ {/each} +
+
+
+
diff --git a/src/modals/HotkeysModal.svelte b/src/modals/HotkeysModal.svelte index 155cbe5aa..317ed7d20 100644 --- a/src/modals/HotkeysModal.svelte +++ b/src/modals/HotkeysModal.svelte @@ -11,7 +11,7 @@ gap: 1rem; display: flex; flex-direction: column; - font-size: var(--font-size-regular); + font: var(--txt-body-l-regular); } .pair { diff --git a/src/views/NotFound.svelte b/src/views/NotFound.svelte index 17655f419..e9196c065 100644 --- a/src/views/NotFound.svelte +++ b/src/views/NotFound.svelte @@ -19,6 +19,6 @@
-
{title}
+
{title}
diff --git a/src/views/nodes/PolicyExplainer.svelte b/src/views/nodes/PolicyExplainer.svelte index 397a2b335..d887a6182 100644 --- a/src/views/nodes/PolicyExplainer.svelte +++ b/src/views/nodes/PolicyExplainer.svelte @@ -19,7 +19,7 @@
@@ -127,9 +113,9 @@ bind:expanded popoverPositionTop="2.5rem" popoverPadding="0.25rem" - popoverBorderRadius="var(--border-radius-small)"> + popoverBorderRadius="var(--border-radius-md)">
-
+
{baseUrl.hostname}
@@ -138,8 +124,8 @@
-
-
+
+
Navigate to seed
@@ -153,7 +139,9 @@ on:submit={navigateToSeed} />
{#if validationMessage} - {validationMessage} + + {validationMessage} + {/if}
@@ -167,14 +155,14 @@ selected={isEqual(baseUrl, item)}>
- +
{item.hostname}
removeBookmark(item)}> - +
@@ -189,17 +177,20 @@ let:item>
- +
{item.hostname}
- +
{#if !$bookmarkedSeeds.length && !config.preferredSeeds.length} - + No default or bookmarked seeds {/if} @@ -226,9 +217,9 @@ } }}> {#if some($bookmarkedSeeds, baseUrl) || some(config.preferredSeeds, baseUrl)} - + {:else} - + {/if}
diff --git a/src/views/nodes/Seeding.svelte b/src/views/nodes/Seeding.svelte index 44eb09041..e4123e47b 100644 --- a/src/views/nodes/Seeding.svelte +++ b/src/views/nodes/Seeding.svelte @@ -19,10 +19,10 @@
+ style="justify-content: space-between; display: flex; text-wrap: nowrap; font: var(--txt-body-m-regular); "> Seeding
- {formatter.format(count).toLowerCase()} + {formatter.format(count).toLowerCase()}
diff --git a/src/views/nodes/UserAgent.svelte b/src/views/nodes/UserAgent.svelte index 462fdfca7..e55151c15 100644 --- a/src/views/nodes/UserAgent.svelte +++ b/src/views/nodes/UserAgent.svelte @@ -6,9 +6,8 @@ - + +
+ {#if node.bannerUrl} + Node banner + {/if} -
-
- -
- -
-