reworked styling further, more usable, fun font

Orual 29e57a4e d3731e20

+359 -77
+10
Cargo.lock
··· 1815 1815 ] 1816 1816 1817 1817 [[package]] 1818 + name = "dioxus-free-icons" 1819 + version = "0.10.0" 1820 + source = "registry+https://github.com/rust-lang/crates.io-index" 1821 + checksum = "28d356e0f9edad0930bc1cc76744360c0ecca020cb943acaadf42cb774f28284" 1822 + dependencies = [ 1823 + "dioxus", 1824 + ] 1825 + 1826 + [[package]] 1818 1827 name = "dioxus-fullstack" 1819 1828 version = "0.7.1" 1820 1829 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 8623 8632 "diesel", 8624 8633 "diesel_migrations", 8625 8634 "dioxus", 8635 + "dioxus-free-icons", 8626 8636 "dioxus-primitives", 8627 8637 "jacquard", 8628 8638 "jacquard-axum",
+9
crates/weaver-api/lexicons/sh_weaver_notebook_theme.json
··· 57 57 "description": "Reference to a dark colour scheme", 58 58 "ref": "com.atproto.repo.strongRef" 59 59 }, 60 + "defaultTheme": { 61 + "type": "string", 62 + "default": "auto", 63 + "enum": [ 64 + "light", 65 + "dark", 66 + "auto" 67 + ] 68 + }, 60 69 "fonts": { 61 70 "type": "object", 62 71 "required": [
+55 -13
crates/weaver-api/src/sh_weaver/notebook/theme.rs
··· 338 338 }), 339 339 ); 340 340 map.insert( 341 + ::jacquard_common::smol_str::SmolStr::new_static( 342 + "defaultTheme", 343 + ), 344 + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { 345 + description: None, 346 + format: None, 347 + default: None, 348 + min_length: None, 349 + max_length: None, 350 + min_graphemes: None, 351 + max_graphemes: None, 352 + r#enum: None, 353 + r#const: None, 354 + known_values: None, 355 + }), 356 + ); 357 + map.insert( 341 358 ::jacquard_common::smol_str::SmolStr::new_static("fonts"), 342 359 ::jacquard_lexicon::lexicon::LexObjectProperty::Object(::jacquard_lexicon::lexicon::LexObject { 343 360 description: None, ··· 546 563 /// Reference to a dark colour scheme 547 564 #[serde(borrow)] 548 565 pub dark_scheme: crate::com_atproto::repo::strong_ref::StrongRef<'a>, 566 + #[serde(skip_serializing_if = "std::option::Option::is_none")] 567 + #[serde(borrow)] 568 + pub default_theme: Option<jacquard_common::CowStr<'a>>, 549 569 #[serde(borrow)] 550 570 pub fonts: ThemeFonts<'a>, 551 571 /// Syntax highlighting theme for light mode ··· 676 696 __unsafe_private_named: ( 677 697 ::core::option::Option<ThemeDarkCodeTheme<'a>>, 678 698 ::core::option::Option<crate::com_atproto::repo::strong_ref::StrongRef<'a>>, 699 + ::core::option::Option<jacquard_common::CowStr<'a>>, 679 700 ::core::option::Option<ThemeFonts<'a>>, 680 701 ::core::option::Option<ThemeLightCodeTheme<'a>>, 681 702 ::core::option::Option<crate::com_atproto::repo::strong_ref::StrongRef<'a>>, ··· 696 717 pub fn new() -> Self { 697 718 ThemeBuilder { 698 719 _phantom_state: ::core::marker::PhantomData, 699 - __unsafe_private_named: (None, None, None, None, None, None), 720 + __unsafe_private_named: (None, None, None, None, None, None, None), 700 721 _phantom: ::core::marker::PhantomData, 701 722 } 702 723 } ··· 740 761 } 741 762 } 742 763 764 + impl<'a, S: theme_state::State> ThemeBuilder<'a, S> { 765 + /// Set the `defaultTheme` field (optional) 766 + pub fn default_theme( 767 + mut self, 768 + value: impl Into<Option<jacquard_common::CowStr<'a>>>, 769 + ) -> Self { 770 + self.__unsafe_private_named.2 = value.into(); 771 + self 772 + } 773 + /// Set the `defaultTheme` field to an Option value (optional) 774 + pub fn maybe_default_theme( 775 + mut self, 776 + value: Option<jacquard_common::CowStr<'a>>, 777 + ) -> Self { 778 + self.__unsafe_private_named.2 = value; 779 + self 780 + } 781 + } 782 + 743 783 impl<'a, S> ThemeBuilder<'a, S> 744 784 where 745 785 S: theme_state::State, ··· 750 790 mut self, 751 791 value: impl Into<ThemeFonts<'a>>, 752 792 ) -> ThemeBuilder<'a, theme_state::SetFonts<S>> { 753 - self.__unsafe_private_named.2 = ::core::option::Option::Some(value.into()); 793 + self.__unsafe_private_named.3 = ::core::option::Option::Some(value.into()); 754 794 ThemeBuilder { 755 795 _phantom_state: ::core::marker::PhantomData, 756 796 __unsafe_private_named: self.__unsafe_private_named, ··· 769 809 mut self, 770 810 value: impl Into<ThemeLightCodeTheme<'a>>, 771 811 ) -> ThemeBuilder<'a, theme_state::SetLightCodeTheme<S>> { 772 - self.__unsafe_private_named.3 = ::core::option::Option::Some(value.into()); 812 + self.__unsafe_private_named.4 = ::core::option::Option::Some(value.into()); 773 813 ThemeBuilder { 774 814 _phantom_state: ::core::marker::PhantomData, 775 815 __unsafe_private_named: self.__unsafe_private_named, ··· 788 828 mut self, 789 829 value: impl Into<crate::com_atproto::repo::strong_ref::StrongRef<'a>>, 790 830 ) -> ThemeBuilder<'a, theme_state::SetLightScheme<S>> { 791 - self.__unsafe_private_named.4 = ::core::option::Option::Some(value.into()); 831 + self.__unsafe_private_named.5 = ::core::option::Option::Some(value.into()); 792 832 ThemeBuilder { 793 833 _phantom_state: ::core::marker::PhantomData, 794 834 __unsafe_private_named: self.__unsafe_private_named, ··· 807 847 mut self, 808 848 value: impl Into<ThemeSpacing<'a>>, 809 849 ) -> ThemeBuilder<'a, theme_state::SetSpacing<S>> { 810 - self.__unsafe_private_named.5 = ::core::option::Option::Some(value.into()); 850 + self.__unsafe_private_named.6 = ::core::option::Option::Some(value.into()); 811 851 ThemeBuilder { 812 852 _phantom_state: ::core::marker::PhantomData, 813 853 __unsafe_private_named: self.__unsafe_private_named, ··· 831 871 Theme { 832 872 dark_code_theme: self.__unsafe_private_named.0.unwrap(), 833 873 dark_scheme: self.__unsafe_private_named.1.unwrap(), 834 - fonts: self.__unsafe_private_named.2.unwrap(), 835 - light_code_theme: self.__unsafe_private_named.3.unwrap(), 836 - light_scheme: self.__unsafe_private_named.4.unwrap(), 837 - spacing: self.__unsafe_private_named.5.unwrap(), 874 + default_theme: self.__unsafe_private_named.2, 875 + fonts: self.__unsafe_private_named.3.unwrap(), 876 + light_code_theme: self.__unsafe_private_named.4.unwrap(), 877 + light_scheme: self.__unsafe_private_named.5.unwrap(), 878 + spacing: self.__unsafe_private_named.6.unwrap(), 838 879 extra_data: Default::default(), 839 880 } 840 881 } ··· 849 890 Theme { 850 891 dark_code_theme: self.__unsafe_private_named.0.unwrap(), 851 892 dark_scheme: self.__unsafe_private_named.1.unwrap(), 852 - fonts: self.__unsafe_private_named.2.unwrap(), 853 - light_code_theme: self.__unsafe_private_named.3.unwrap(), 854 - light_scheme: self.__unsafe_private_named.4.unwrap(), 855 - spacing: self.__unsafe_private_named.5.unwrap(), 893 + default_theme: self.__unsafe_private_named.2, 894 + fonts: self.__unsafe_private_named.3.unwrap(), 895 + light_code_theme: self.__unsafe_private_named.4.unwrap(), 896 + light_scheme: self.__unsafe_private_named.5.unwrap(), 897 + spacing: self.__unsafe_private_named.6.unwrap(), 856 898 extra_data: Some(extra_data), 857 899 } 858 900 }
+1 -1
crates/weaver-app/Cargo.toml
··· 38 38 serde = { version = "1.0", features = ["derive"] } 39 39 serde_json = "1.0" 40 40 reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } 41 - 41 + dioxus-free-icons = { version = "0.10.0" } 42 42 diesel = { version = "2.3", features = ["sqlite", "returning_clauses_for_sqlite_3_35", "chrono", "serde_json"] } 43 43 diesel_migrations = { version = "2.3", features = ["sqlite"] } 44 44
crates/weaver-app/assets/fonts/ioskeley-mono/IoskeleyMono-Bold.woff2

This is a binary file and will not be displayed.

crates/weaver-app/assets/fonts/ioskeley-mono/IoskeleyMono-BoldItalic.woff2

This is a binary file and will not be displayed.

crates/weaver-app/assets/fonts/ioskeley-mono/IoskeleyMono-Italic.woff2

This is a binary file and will not be displayed.

crates/weaver-app/assets/fonts/ioskeley-mono/IoskeleyMono-Light.woff2

This is a binary file and will not be displayed.

crates/weaver-app/assets/fonts/ioskeley-mono/IoskeleyMono-LightItalic.woff2

This is a binary file and will not be displayed.

crates/weaver-app/assets/fonts/ioskeley-mono/IoskeleyMono-Regular.woff2

This is a binary file and will not be displayed.

+5 -4
crates/weaver-app/assets/styling/entry-card.css
··· 27 27 /* Mobile layout - sidebar becomes header */ 28 28 @media (max-width: 1400px) { 29 29 .notebook-layout { 30 - grid-template-columns: 1fr !important; 30 + grid-template-columns: minmax(1rem, 1fr) minmax(0, 90ch) minmax(1rem, 1fr) !important; 31 31 gap: 0 !important; 32 32 max-width: 100vw !important; 33 33 box-sizing: border-box !important; 34 34 } 35 35 36 36 .notebook-sidebar { 37 - grid-column: 1; 37 + grid-column: 2; 38 38 position: static; 39 39 max-height: none; 40 40 min-width: 0; 41 + margin-bottom: 2rem; 41 42 } 42 43 43 44 .notebook-main { 44 - grid-column: 1; 45 - padding: 1.25rem; 45 + grid-column: 2; 46 + padding: 0; 46 47 min-width: 0; 47 48 } 48 49 }
+3 -3
crates/weaver-app/assets/styling/notebook-card.css
··· 27 27 /* Mobile layout - sidebar becomes header */ 28 28 @media (max-width: 1400px) { 29 29 .repository-layout { 30 - grid-template-columns: 1fr !important; 30 + grid-template-columns: minmax(1rem, 1fr) minmax(0, 90ch) minmax(1rem, 1fr) !important; 31 31 gap: 0 !important; 32 32 max-width: 100vw !important; 33 33 box-sizing: border-box !important; 34 34 } 35 35 36 36 .repository-sidebar { 37 - grid-column: 1; 37 + grid-column: 2; 38 38 position: static; 39 39 max-height: none; 40 40 min-width: 0; ··· 42 42 } 43 43 44 44 .repository-main { 45 - grid-column: 1; 45 + grid-column: 2; 46 46 padding: 0; 47 47 min-width: 0; 48 48 }
+53 -18
crates/weaver-app/assets/styling/profile.css
··· 6 6 /* No background - same plane as page */ 7 7 } 8 8 9 - /* Desktop: sidebar gets top and right borders */ 10 - @media (min-width: 1400px) { 11 - .profile-display { 12 - border-top: 1.5px dashed var(--color-border); 13 - border-right: 1.5px dashed var(--color-border); 14 - } 15 - } 16 - 17 - /* Mobile: header gets top and bottom borders */ 18 - @media (max-width: 1400px) { 19 - .profile-display { 20 - border-top: 1.5px dashed var(--color-border); 21 - border-bottom: 1.5px solid var(--color-border); 22 - } 23 - } 24 - 25 9 .profile-banner { 26 10 max-width: 100%; 27 - height: 120px; 11 + height: 200px; 28 12 overflow: hidden; 29 13 } 30 14 ··· 45 29 .profile-identity .avatar { 46 30 width: 120px; 47 31 height: 120px; 32 + margin-top: -5rem; 48 33 margin-bottom: 1rem; 49 34 } 50 35 ··· 69 54 .profile-handle { 70 55 font-size: 0.95rem; 71 56 color: var(--color-subtle); 72 - margin-bottom: 0.5rem; 57 + margin-bottom: 0rem; 73 58 } 74 59 75 60 .profile-location { ··· 130 115 } 131 116 132 117 .profile-link-platform { 118 + display: inline; 133 119 font-weight: 500; 134 120 } 135 121 ··· 151 137 } 152 138 } 153 139 140 + /* Mobile: header gets top and bottom borders */ 141 + @media (max-width: 1400px) { 142 + .profile-display { 143 + border-top: 1.5px dashed var(--color-border); 144 + border-bottom: 1.5px solid var(--color-border); 145 + } 146 + 147 + .profile-content { 148 + display: flex; 149 + flex-direction: row; 150 + justify-content: space-between; 151 + } 152 + 153 + .profile-extras { 154 + padding-left: 1rem; 155 + border-left: 1.5px dashed var(--color-border); 156 + } 157 + 158 + .profile-block { 159 + display: flex; 160 + flex-direction: row; 161 + } 162 + 163 + .profile-stats { 164 + border-top: none; 165 + } 166 + 167 + .profile-identity .avatar { 168 + margin-bottom: 0rem; 169 + } 170 + 171 + .profile-description { 172 + margin-top: 0rem; 173 + } 174 + 175 + .profile-name-section { 176 + margin-left: 1rem; 177 + margin-top: -0.5rem; 178 + } 179 + } 180 + 154 181 @media (prefers-color-scheme: dark) { 155 182 .profile-display { 156 183 background-color: var(--color-surface); 157 184 border: 1px dashed var(--color-border); 158 185 } 159 186 } 187 + 188 + /* Desktop: sidebar gets top and right borders */ 189 + @media (min-width: 1400px) { 190 + .profile-display { 191 + border-top: 1.5px dashed var(--color-border); 192 + border-right: 1.5px dashed var(--color-border); 193 + } 194 + }
+40 -4
crates/weaver-app/assets/styling/theme-defaults.css
··· 1 1 /* Default theme variables for non-notebook pages */ 2 2 /* These match the Rose Pine light/dark defaults */ 3 3 4 + @font-face { 5 + font-family: "Ioskeley Mono"; 6 + font-style: normal; 7 + font-weight: normal; 8 + src: url("/assets/IoskeleyMono-Regular.woff2") format("woff2"); 9 + } 10 + @font-face { 11 + font-family: "Ioskeley Mono"; 12 + font-style: normal; 13 + font-weight: lighter; 14 + src: url("/assets/IoskeleyMono-Light.woff2") format("woff2"); 15 + } 16 + @font-face { 17 + font-family: "Ioskeley Mono"; 18 + font-style: italic; 19 + font-weight: lighter; 20 + src: url("/assets/IoskeleyMono-LightItalic.woff2") format("woff2"); 21 + } 22 + @font-face { 23 + font-family: "Ioskeley Mono"; 24 + font-style: normal; 25 + font-weight: bold; 26 + src: url("/assets/IoskeleyMono-Bold.woff2") format("woff2"); 27 + } 28 + @font-face { 29 + font-family: "Ioskeley Mono"; 30 + font-style: italic; 31 + font-weight: normal; 32 + src: url("/assets/IoskeleyMono-Italic.woff2") format("woff2"); 33 + } 34 + @font-face { 35 + font-family: "Ioskeley Mono"; 36 + font-style: italic; 37 + font-weight: bold; 38 + src: url("/assets/IoskeleyMono-BoldItalic.woff2") format("woff2"); 39 + } 40 + 4 41 /* CSS Variables - Light Mode (default) */ 5 42 :root { 6 43 --color-base: #faf4ed; ··· 20 57 --color-link: #d7827e; 21 58 --color-highlight: #cecacd; 22 59 23 - --font-body: IBM Plex, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; 24 - --font-heading: IBM Plex Sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; 25 - --font-mono: "IBM Plex Mono", "Berkeley Mono", "Cascadia Code", "Roboto Mono", Consolas, monospace; 60 + --font-body: "IBM Plex", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; 61 + --font-heading: "IBM Plex Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; 62 + --font-mono: "Ioskeley Mono", "IBM Plex Mono", "Berkeley Mono", "Cascadia Code", "Roboto Mono", Consolas, monospace; 26 63 27 64 --spacing-base: 16px; 28 65 --spacing-line-height: 1.6; ··· 49 86 --color-link: #ebbcba; 50 87 --color-highlight: #524f67; 51 88 } 52 - 53 89 }
+100
crates/weaver-app/src/components/mod.rs
··· 17 17 18 18 pub mod notebook_cover; 19 19 pub use notebook_cover::NotebookCover; 20 + 21 + use dioxus::prelude::*; 22 + 23 + #[derive(PartialEq, Props, Clone)] 24 + pub struct IconProps { 25 + #[props(default = Some(20))] 26 + pub height: Option<u32>, 27 + /// The width of the `<svg>` element. Defaults to 20. Pass None to omit. 28 + #[props(default = Some(20))] 29 + pub width: Option<u32>, 30 + /// The color to use for filling the icon. Defaults to "currentColor". 31 + #[props(default = "currentColor".to_string())] 32 + pub fill: String, 33 + /// An class for the `<svg>` element. 34 + #[props(default = "".to_string())] 35 + pub class: String, 36 + /// The style of the `<svg>` element. 37 + pub style: Option<String>, 38 + } 39 + 40 + #[component] 41 + pub fn BskyIcon(props: IconProps) -> Element { 42 + rsx! { 43 + svg { 44 + class: "{props.class}", 45 + style: props.style, 46 + height: props.height.map(|height| height.to_string()), 47 + width: props.width.map(|width| width.to_string()), 48 + view_box: "0 0 600 530", 49 + path { 50 + d: "m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z", 51 + fill: props.fill 52 + } 53 + } 54 + } 55 + } 56 + 57 + #[component] 58 + pub fn TangledIcon(props: IconProps) -> Element { 59 + rsx! { 60 + svg { 61 + class: "{props.class}", 62 + style: props.style, 63 + height: props.height.map(|height| height.to_string()), 64 + width: props.width.map(|width| width.to_string()), 65 + view_box: "0 0 24.122343 23.274094", 66 + path { 67 + d: "m 16.348974,24.09935 -0.06485,-0.03766 -0.202005,-0.0106 -0.202008,-0.01048 -0.275736,-0.02601 -0.275734,-0.02602 v -0.02649 -0.02648 l -0.204577,-0.04019 -0.204578,-0.04019 -0.167616,-0.08035 -0.167617,-0.08035 -0.0014,-0.04137 -0.0014,-0.04137 -0.266473,-0.143735 -0.266475,-0.143735 -0.276098,-0.20335 -0.2761,-0.203347 -0.262064,-0.251949 -0.262064,-0.25195 -0.22095,-0.284628 -0.220948,-0.284629 -0.170253,-0.284631 -0.170252,-0.284628 -0.01341,-0.0144 -0.0134,-0.0144 -0.141982,0.161297 -0.14198,0.1613 -0.22313,0.21426 -0.223132,0.214264 -0.186025,0.146053 -0.186023,0.14605 -0.252501,0.163342 -0.252502,0.163342 -0.249014,0.115348 -0.249013,0.115336 0.0053,0.03241 0.0053,0.03241 -0.1716725,0.04599 -0.171669,0.046 -0.3379966,0.101058 -0.3379972,0.101058 -0.1778925,0.04506 -0.1778935,0.04508 -0.3913655,0.02601 -0.3913643,0.02603 -0.3557868,-0.03514 -0.3557863,-0.03514 -0.037426,-0.03029 -0.037427,-0.03029 -0.076924,0.02011 -0.076924,0.02011 -0.050508,-0.05051 -0.050405,-0.05056 L 6.6604532,23.110188 6.451745,23.063961 6.1546135,22.960559 5.8574835,22.857156 5.5319879,22.694039 5.2064938,22.530922 4.8793922,22.302961 4.5522905,22.075005 4.247598,21.786585 3.9429055,21.49817 3.7185335,21.208777 3.4941628,20.919385 3.3669822,20.705914 3.239803,20.492443 3.1335213,20.278969 3.0272397,20.065499 2.9015252,19.7275 2.7758105,19.389504 2.6925225,18.998139 2.6092345,18.606774 2.6096814,17.91299 2.6101284,17.219208 2.6744634,16.90029 2.7387984,16.581374 2.8474286,16.242088 2.9560588,15.9028 3.1137374,15.583492 3.2714148,15.264182 3.3415068,15.150766 3.4115988,15.03735 3.3127798,14.96945 3.2139618,14.90157 3.0360685,14.800239 2.8581753,14.698908 2.5913347,14.503228 2.3244955,14.307547 2.0621238,14.055599 1.7997507,13.803651 1.6111953,13.56878 1.4226411,13.333906 1.2632237,13.087474 1.1038089,12.841042 0.97442,12.575195 0.8450307,12.30935 0.724603,11.971351 0.6041766,11.633356 0.52150365,11.241991 0.4388285,10.850626 0.44091592,10.156842 0.44300333,9.4630594 0.54235911,9.0369608 0.6417149,8.6108622 0.7741173,8.2694368 0.9065196,7.9280115 1.0736303,7.6214262 1.2407515,7.3148397 1.45931,7.0191718 1.6778685,6.7235039 1.9300326,6.4611321 2.1821966,6.1987592 2.4134579,6.0137228 2.6447193,5.8286865 2.8759792,5.6776409 3.1072406,5.526594 3.4282004,5.3713977 3.7491603,5.2162016 3.9263009,5.1508695 4.1034416,5.0855373 4.2813348,4.7481598 4.4592292,4.4107823 4.6718,4.108422 4.8843733,3.8060618 5.198353,3.4805372 5.5123313,3.155014 5.7685095,2.9596425 6.0246877,2.7642722 6.329187,2.5851365 6.6336863,2.406002 6.9497657,2.2751596 7.2658453,2.1443184 7.4756394,2.0772947 7.6854348,2.01027 8.0825241,1.931086 8.4796139,1.851902 l 0.5870477,0.00291 0.5870469,0.00291 0.4447315,0.092455 0.444734,0.092455 0.302419,0.1105495 0.302417,0.1105495 0.329929,0.1646046 0.32993,0.1646033 0.239329,-0.2316919 0.239329,-0.2316919 0.160103,-0.1256767 0.160105,-0.1256767 0.160102,-0.1021909 0.160105,-0.1021899 0.142315,-0.082328 0.142314,-0.082328 0.231262,-0.1090091 0.231259,-0.1090091 0.26684,-0.098743 0.266839,-0.098743 0.320208,-0.073514 0.320209,-0.073527 0.355787,-0.041833 0.355785,-0.041834 0.426942,0.023827 0.426945,0.023828 0.355785,0.071179 0.355788,0.0711791 0.284627,0.09267 0.284629,0.09267 0.28514,0.1310267 0.28514,0.1310255 0.238179,0.1446969 0.238174,0.1446979 0.259413,0.1955332 0.259413,0.1955319 0.290757,0.296774 0.290758,0.2967753 0.151736,0.1941581 0.151734,0.1941594 0.135326,0.2149951 0.135327,0.2149952 0.154755,0.3202073 0.154758,0.3202085 0.09409,0.2677358 0.09409,0.267737 0.06948,0.3319087 0.06948,0.3319099 0.01111,0.00808 0.01111,0.00808 0.444734,0.2173653 0.444734,0.2173665 0.309499,0.2161102 0.309497,0.2161101 0.309694,0.2930023 0.309694,0.2930037 0.18752,0.2348726 0.187524,0.2348727 0.166516,0.2574092 0.166519,0.2574108 0.15273,0.3260252 0.152734,0.3260262 0.08972,0.2668403 0.08971,0.2668391 0.08295,0.3913655 0.08295,0.3913652 -6.21e-4,0.6582049 -6.21e-4,0.658204 -0.06362,0.315725 -0.06362,0.315725 -0.09046,0.289112 -0.09046,0.289112 -0.122759,0.281358 -0.12276,0.281356 -0.146626,0.252323 -0.146629,0.252322 -0.190443,0.258668 -0.190448,0.258671 -0.254911,0.268356 -0.254911,0.268355 -0.286872,0.223127 -0.286874,0.223127 -0.320203,0.187693 -0.320209,0.187693 -0.04347,0.03519 -0.04347,0.03521 0.0564,0.12989 0.0564,0.129892 0.08728,0.213472 0.08728,0.213471 0.189755,0.729363 0.189753,0.729362 0.0652,0.302417 0.0652,0.302419 -0.0018,0.675994 -0.0018,0.675995 -0.0801,0.373573 -0.08009,0.373577 -0.09,0.266839 -0.09,0.26684 -0.190389,0.391364 -0.19039,0.391366 -0.223169,0.320207 -0.223167,0.320209 -0.303585,0.315294 -0.303584,0.315291 -0.284631,0.220665 -0.284629,0.220663 -0.220128,0.132359 -0.220127,0.132358 -0.242395,0.106698 -0.242394,0.106699 -0.08895,0.04734 -0.08895,0.04733 -0.249052,0.07247 -0.24905,0.07247 -0.322042,0.0574 -0.322044,0.0574 -0.282794,-0.003 -0.282795,-0.003 -0.07115,-0.0031 -0.07115,-0.0031 -0.177894,-0.0033 -0.177893,-0.0033 -0.124528,0.02555 -0.124528,0.02555 z m -4.470079,-5.349839 0.214838,-0.01739 0.206601,-0.06782 0.206602,-0.06782 0.244389,-0.117874 0.244393,-0.11786 0.274473,-0.206822 0.27447,-0.20682 0.229308,-0.257201 0.229306,-0.2572 0.219161,-0.28463 0.219159,-0.284629 0.188541,-0.284628 0.188543,-0.28463 0.214594,-0.373574 0.214593,-0.373577 0.133861,-0.312006 0.133865,-0.312007 0.02861,-0.01769 0.02861,-0.01769 0.197275,0.26212 0.197278,0.262119 0.163613,0.150814 0.163614,0.150814 0.201914,0.09276 0.201914,0.09276 0.302417,0.01421 0.302418,0.01421 0.213472,-0.08025 0.213471,-0.08025 0.200606,-0.204641 0.200606,-0.204642 0.09242,-0.278887 0.09241,-0.278888 0.05765,-0.302418 0.05764,-0.302416 L 18.41327,13.768114 18.39502,13.34117 18.31849,12.915185 18.24196,12.4892 18.15595,12.168033 18.06994,11.846867 17.928869,11.444534 17.787801,11.042201 17.621278,10.73296 17.454757,10.423723 17.337388,10.263619 17.220021,10.103516 17.095645,9.9837986 16.971268,9.8640816 16.990048,9.6813736 17.008828,9.4986654 16.947568,9.249616 16.886308,9.0005655 16.752419,8.7159355 16.618521,8.4313217 16.435707,8.2294676 16.252892,8.0276114 16.079629,7.9004245 15.906366,7.773238 l -0.20429,0.1230127 -0.204289,0.1230121 -0.26702,0.059413 -0.267022,0.059413 -0.205761,-0.021508 -0.205766,-0.021508 -0.23495,-0.08844 -0.234953,-0.08844 -0.118429,-0.090334 -0.118428,-0.090333 h -0.03944 -0.03944 L 13.711268,7.8540732 13.655958,7.9706205 13.497227,8.1520709 13.338499,8.3335203 13.168394,8.4419112 12.998289,8.550301 12.777045,8.624223 12.5558,8.698155 H 12.275611 11.995429 L 11.799973,8.6309015 11.604513,8.5636472 11.491311,8.5051061 11.37811,8.446565 11.138172,8.2254579 10.898231,8.0043497 l -0.09565,-0.084618 -0.09565,-0.084613 -0.218822,0.198024 -0.218822,0.1980231 -0.165392,0.078387 -0.1653925,0.078387 -0.177894,0.047948 -0.177892,0.047948 L 9.3635263,8.4842631 9.144328,8.4846889 8.9195029,8.4147138 8.6946778,8.3447386 8.5931214,8.4414036 8.491565,8.5380686 8.3707618,8.7019598 8.2499597,8.8658478 8.0802403,8.9290726 7.9105231,8.9922974 7.7952769,9.0780061 7.6800299,9.1637148 7.5706169,9.2778257 7.4612038,9.3919481 7.1059768,9.9205267 6.7507497,10.449105 l -0.2159851,0.449834 -0.2159839,0.449834 -0.2216572,0.462522 -0.2216559,0.462523 -0.1459343,0.337996 -0.1459342,0.337998 -0.055483,0.220042 -0.055483,0.220041 -0.015885,0.206903 -0.015872,0.206901 0.034307,0.242939 0.034307,0.24294 0.096281,0.196632 0.096281,0.196634 0.143607,0.125222 0.1436071,0.125222 0.1873143,0.08737 0.1873141,0.08737 0.2752084,0.002 0.2752084,0.002 0.2312297,-0.09773 0.231231,-0.09772 0.1067615,-0.07603 0.1067614,-0.07603 0.3679062,-0.29377 0.3679065,-0.293771 0.026804,0.01656 0.026804,0.01656 0.023626,0.466819 0.023626,0.466815 0.088326,0.513195 0.088326,0.513193 0.08897,0.364413 0.08897,0.364411 0.1315362,0.302418 0.1315352,0.302418 0.1051964,0.160105 0.1051954,0.160103 0.1104741,0.11877 0.1104731,0.118769 0.2846284,0.205644 0.2846305,0.205642 0.144448,0.07312 0.144448,0.07312 0.214787,0.05566 0.214787,0.05566 0.245601,0.03075 0.245602,0.03075 0.204577,-0.0125 0.204578,-0.0125 z m 0.686342,-3.497495 -0.11281,-0.06077 -0.106155,-0.134033 -0.106155,-0.134031 -0.04406,-0.18371 -0.04406,-0.183707 0.02417,-0.553937 0.02417,-0.553936 0.03513,-0.426945 0.03513,-0.426942 0.07225,-0.373576 0.07225,-0.373575 0.05417,-0.211338 0.05417,-0.211339 0.0674,-0.132112 0.0674,-0.132112 0.132437,-0.10916 0.132437,-0.109161 0.187436,-0.04195 0.187438,-0.04195 0.170366,0.06469 0.170364,0.06469 0.114312,0.124073 0.114313,0.124086 0.04139,0.18495 0.04139,0.184951 -0.111218,0.459845 -0.111219,0.459844 -0.03383,0.26584 -0.03382,0.265841 -0.03986,0.818307 -0.03986,0.818309 -0.0378,0.15162 -0.03779,0.151621 -0.11089,0.110562 -0.110891,0.110561 -0.114489,0.04913 -0.114489,0.04913 -0.187932,-0.0016 -0.187929,-0.0016 z m -2.8087655,-0.358124 -0.146445,-0.06848 -0.088025,-0.119502 -0.088024,-0.119502 -0.038581,-0.106736 -0.038581,-0.106736 -0.02237,-0.134956 -0.02239,-0.134957 -0.031955,-0.46988 -0.031955,-0.469881 0.036203,-0.444733 0.036203,-0.444731 0.048862,-0.215257 0.048862,-0.215255 0.076082,-0.203349 0.076081,-0.203348 0.0936,-0.111244 0.0936,-0.111245 0.143787,-0.06531 0.1437865,-0.06532 h 0.142315 0.142314 l 0.142314,0.06588 0.142316,0.06588 0.093,0.102325 0.093,0.102325 0.04042,0.120942 0.04042,0.120942 v 0.152479 0.152477 l -0.03347,0.08804 -0.03347,0.08805 -0.05693,0.275653 -0.05693,0.275651 2.11e-4,0.430246 2.12e-4,0.430243 0.04294,0.392646 0.04295,0.392647 -0.09189,0.200702 -0.09189,0.200702 -0.148688,0.0984 -0.148687,0.0984 -0.20136,0.01212 -0.2013595,0.01212 z", 68 + fill: props.fill 69 + } 70 + } 71 + 72 + } 73 + } 74 + 75 + #[used] 76 + static _IOSK_BOLD: Asset = asset!( 77 + "/assets/fonts/ioskeley-mono/IoskeleyMono-Bold.woff2", 78 + AssetOptions::builder() 79 + .with_hash_suffix(false) 80 + .into_asset_options() 81 + ); 82 + 83 + #[used] 84 + static _IOSK_REG: Asset = asset!( 85 + "/assets/fonts/ioskeley-mono/IoskeleyMono-Regular.woff2", 86 + AssetOptions::builder() 87 + .with_hash_suffix(false) 88 + .into_asset_options() 89 + ); 90 + 91 + #[used] 92 + static _IOSK_ITAL: Asset = asset!( 93 + "/assets/fonts/ioskeley-mono/IoskeleyMono-Italic.woff2", 94 + AssetOptions::builder() 95 + .with_hash_suffix(false) 96 + .into_asset_options() 97 + ); 98 + 99 + #[used] 100 + static _IOSK_LIGHT: Asset = asset!( 101 + "/assets/fonts/ioskeley-mono/IoskeleyMono-Light.woff2", 102 + AssetOptions::builder() 103 + .with_hash_suffix(false) 104 + .into_asset_options() 105 + ); 106 + #[used] 107 + static _IOSK_LIGHT_ITAL: Asset = asset!( 108 + "/assets/fonts/ioskeley-mono/IoskeleyMono-LightItalic.woff2", 109 + AssetOptions::builder() 110 + .with_hash_suffix(false) 111 + .into_asset_options() 112 + ); 113 + #[used] 114 + static _IOSK_ITAL_BOLD: Asset = asset!( 115 + "/assets/fonts/ioskeley-mono/IoskeleyMono-BoldItalic.woff2", 116 + AssetOptions::builder() 117 + .with_hash_suffix(false) 118 + .into_asset_options() 119 + );
+57 -30
crates/weaver-app/src/components/profile.rs
··· 1 1 #![allow(non_snake_case)] 2 2 3 3 use crate::{ 4 - components::avatar::{Avatar, AvatarImage}, 4 + components::{ 5 + avatar::{Avatar, AvatarImage}, 6 + BskyIcon, TangledIcon, 7 + }, 5 8 data::use_handle, 6 9 Route, 7 10 }; ··· 51 54 div { class: "profile-content", 52 55 // Avatar and identity 53 56 ProfileIdentity { profile_view: profile_view.clone(), ident: ident.clone() } 57 + div { 58 + class: "profile-extras", 59 + // Stats 60 + ProfileStats { ident: ident.clone() } 54 61 55 - // Stats 56 - ProfileStats { ident: ident.clone() } 62 + // Links 63 + ProfileLinks { profile_view: profile_view.clone(), ident: ident.clone() } 64 + } 57 65 58 - // Links 59 - ProfileLinks { profile_view: profile_view.clone(), ident: ident.clone() } 66 + 60 67 } 61 68 } 62 69 }, ··· 100 107 101 108 rsx! { 102 109 div { class: "profile-identity", 103 - if let Some(ref avatar) = profile.avatar { 104 - Avatar { 105 - AvatarImage { src: avatar.as_ref() } 110 + div { 111 + class: "profile-block", 112 + if let Some(ref avatar) = profile.avatar { 113 + Avatar { 114 + AvatarImage { src: avatar.as_ref() } 115 + } 106 116 } 107 - } 108 117 109 - div { class: "profile-name-section", 110 - h1 { class: "profile-display-name", 111 - "{display_name}" 112 - if let Some(ref pronouns) = pronouns_text { 113 - span { class: "profile-pronouns", " ({pronouns})" } 118 + div { class: "profile-name-section", 119 + h1 { class: "profile-display-name", 120 + "{display_name}" 121 + if let Some(ref pronouns) = pronouns_text { 122 + span { class: "profile-pronouns", " ({pronouns})" } 123 + } 114 124 } 115 - } 116 - div { class: "profile-handle", "@{use_handle(ident.clone())?}" } 125 + div { class: "profile-handle", "@{use_handle(ident.clone())?}" } 117 126 118 - if let Some(ref location) = profile.location { 119 - div { class: "profile-location", "{location}" } 127 + if let Some(ref location) = profile.location { 128 + div { class: "profile-location", "{location}" } 129 + } 120 130 } 121 131 } 132 + 122 133 123 134 if let Some(ref description) = profile.description { 124 135 div { class: "profile-description", "{description}" } ··· 135 146 136 147 rsx! { 137 148 div { class: "profile-identity", 138 - if let Some(ref avatar) = profile.avatar { 139 - Avatar { 140 - AvatarImage { src: avatar.as_ref() } 149 + div { 150 + class: "profile-block", 151 + if let Some(ref avatar) = profile.avatar { 152 + Avatar { 153 + AvatarImage { src: avatar.as_ref() } 154 + } 141 155 } 142 - } 143 156 144 - div { class: "profile-name-section", 145 - h1 { class: "profile-display-name", "{display_name}" } 146 - div { class: "profile-handle", "@{use_handle(ident.clone())?}" } 157 + div { class: "profile-name-section", 158 + h1 { class: "profile-display-name", "{display_name}" } 159 + div { class: "profile-handle", "@{use_handle(ident.clone())?}" } 160 + } 147 161 } 148 162 149 163 if let Some(ref description) = profile.description { ··· 224 238 target: "_blank", 225 239 rel: "noopener noreferrer", 226 240 class: "profile-link profile-link-platform", 227 - "View on Bluesky" 241 + BskyIcon { width: 20, height: 20, style: "vertical-align: text-bottom" } 242 + " Bluesky" 228 243 } 229 244 } 230 245 231 246 if profile.tangled.unwrap_or(false) { 232 247 a { 233 - href: "https://tangled.dev/{ident}", 248 + href: "https://tangled.org/@{ident}", 234 249 target: "_blank", 235 250 rel: "noopener noreferrer", 236 251 class: "profile-link profile-link-platform", 237 - "View on Tangled" 252 + TangledIcon { width: 20, height: 20, style: "vertical-align: text-bottom" } 253 + " Tangled" 238 254 } 239 255 } 240 256 ··· 259 275 target: "_blank", 260 276 rel: "noopener noreferrer", 261 277 class: "profile-link profile-link-platform", 262 - "View on Bluesky" 278 + BskyIcon { width: 20, height: 20, style: "vertical-align: text-bottom" } 279 + " Bluesky" 263 280 } 281 + 264 282 } 265 283 } 266 284 } ··· 278 296 } 279 297 } 280 298 } 299 + a { 300 + href: "https://tangled.org/@{ident}", 301 + target: "_blank", 302 + rel: "noopener noreferrer", 303 + class: "profile-link profile-link-platform", 304 + TangledIcon { width: 20, height: 20, style: "vertical-align: text-bottom" } 305 + " Tangled" 306 + } 281 307 282 308 if profile.bluesky { 283 309 a { ··· 285 311 target: "_blank", 286 312 rel: "noopener noreferrer", 287 313 class: "profile-link profile-link-platform", 288 - "View on Bluesky" 314 + BskyIcon { width: 20, height: 20, style: "vertical-align: text-bottom" } 315 + " Bluesky" 289 316 } 290 317 } 291 318 }
+2 -2
crates/weaver-renderer/src/code_pretty.rs
··· 27 27 .find_syntax_by_first_line(code.as_ref()) 28 28 .unwrap_or_else(|| syn_set.find_syntax_plain_text()) 29 29 }; 30 - writer.write_str("<pre><code class=\"wvrcode-code language-")?; 30 + writer.write_str("<pre><code class=\"wvc-code language-")?; 31 31 writer.write_str(&lang_syn.name)?; 32 32 writer.write_str("\">")?; 33 33 ··· 46 46 Ok(()) 47 47 } 48 48 49 - pub const CSS_PREFIX: &str = "wvrcode-"; 49 + pub const CSS_PREFIX: &str = "wvc-";
+1 -1
crates/weaver-renderer/src/css.rs
··· 131 131 text-decoration: none; 132 132 }} 133 133 134 - a:hover {{ 134 + .notebook-content a:hover {{ 135 135 color: var(--color-emphasis); 136 136 text-decoration: underline; 137 137 }}
+18 -1
crates/weaver-renderer/src/theme.rs
··· 9 9 use weaver_common::jacquard::cowstr::ToCowStr; 10 10 use weaver_common::jacquard::prelude::*; 11 11 12 + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] 13 + pub enum ThemeDefault { 14 + #[default] 15 + Auto, 16 + Light, 17 + Dark, 18 + } 19 + 12 20 /// A theme with resolved colour schemes (no strongRefs, actual data) 13 21 #[derive(Clone, Debug)] 14 22 pub struct ResolvedTheme<'a> { 23 + pub default: ThemeDefault, 15 24 pub dark_scheme: ColourSchemeColours<'a>, 16 25 pub light_scheme: ColourSchemeColours<'a>, 17 26 pub fonts: ThemeFonts<'a>, ··· 51 60 "'IBM Plex Sans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", 52 61 ), 53 62 monospace: CowStr::new_static( 54 - "'IBM Plex Mono', 'Berkeley Mono', 'Cascadia Code', 'Roboto Mono', Consolas, monospace", 63 + "'Ioskeley Mono', 'IBM Plex Mono', 'Berkeley Mono', 'Cascadia Code', 'Roboto Mono', Consolas, monospace", 55 64 ), 56 65 ..Default::default() 57 66 } ··· 90 99 91 100 pub fn default_resolved_theme() -> ResolvedTheme<'static> { 92 101 ResolvedTheme { 102 + default: ThemeDefault::Auto, 93 103 dark_scheme: default_colour_scheme_dark(), 94 104 light_scheme: default_colour_scheme_light(), 95 105 fonts: default_fonts(), ··· 123 133 .into_diagnostic()?; 124 134 125 135 let light_scheme: ColourScheme = light_response.into_output().into_diagnostic()?.into(); 136 + let default = match theme.default_theme.as_ref().map(|t| t.as_str()) { 137 + Some("auto") => ThemeDefault::Auto, 138 + Some("dark") => ThemeDefault::Dark, 139 + Some("light") => ThemeDefault::Light, 140 + _ => ThemeDefault::Auto, 141 + }; 126 142 127 143 Ok(ResolvedTheme { 144 + default, 128 145 dark_scheme: dark_scheme.colours.into_static(), 129 146 light_scheme: light_scheme.colours.into_static(), 130 147 fonts: theme.fonts.clone().into_static(),
+5
lexicons/notebook/theme.json
··· 10 10 "type": "object", 11 11 "required": ["darkScheme", "lightScheme", "fonts", "spacing", "darkCodeTheme", "lightCodeTheme"], 12 12 "properties": { 13 + "defaultTheme": { 14 + "type": "string", 15 + "enum": ["light", "dark", "auto"], 16 + "default": "auto" 17 + }, 13 18 "darkScheme": { 14 19 "type": "ref", 15 20 "ref": "com.atproto.repo.strongRef",