starlight-theme-nova 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ .sl-markdown-content {
2
+ /* Style the Markdown heading links. */
3
+ :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *)) > a {
4
+ color: var(--sl-color-white);
5
+ text-decoration: none;
6
+
7
+ &:hover {
8
+ text-decoration: underline;
9
+ }
10
+ }
11
+
12
+ code:not(:where(.not-content *)) {
13
+ border-radius: 0.25rem;
14
+ border-style: solid;
15
+ border-width: 1px;
16
+ border-color: var(--sl-color-border-inline-code);
17
+ background-color: var(--sl-color-bg-inline-code);
18
+ padding: 0.125rem 0.25rem;
19
+ }
20
+ }
21
+
22
+ /* <code> inside asides */
23
+ @supports (border-color: color-mix(in srgb, var(--sl-color-asides-text-accent) 12%, transparent)) {
24
+ .sl-markdown-content .starlight-aside code:not(:where(.not-content *)) {
25
+ border-color: color-mix(in srgb, var(--sl-color-asides-text-accent) 12%, transparent);
26
+ }
27
+ }
@@ -15,9 +15,13 @@
15
15
  --sl-color-gray-5: #374151;
16
16
  --sl-color-gray-6: #1f2937;
17
17
  --sl-color-black: #030712;
18
+
18
19
  --sl-color-accent-low: #030712;
19
20
  --sl-color-accent: #4b5563;
20
21
  --sl-color-accent-high: #f3f4f6;
22
+
23
+ --sl-color-bg-inline-code: #1f2937;
24
+ --sl-color-border-inline-code: #374151;
21
25
  }
22
26
 
23
27
  /* Light mode Starlight theme variables */
@@ -31,76 +35,88 @@
31
35
  --sl-color-gray-6: #e5e7eb;
32
36
  --sl-color-gray-7: #f3f4f6;
33
37
  --sl-color-black: white;
38
+
34
39
  --sl-color-accent-low: #e5e7eb;
35
40
  --sl-color-accent: #1f2937;
36
41
  --sl-color-accent-high: #111827;
37
- }
38
-
39
- /* Style the Markdown heading links. */
40
- .sl-markdown-content
41
- :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *))
42
- > a {
43
- color: var(--sl-color-white);
44
- text-decoration: none;
45
42
 
46
- &:hover {
47
- text-decoration: underline;
48
- }
43
+ --sl-color-bg-inline-code: #f3f4f6;
44
+ --sl-color-border-inline-code: #d1d5db;
49
45
  }
50
46
 
51
47
  /* layer: shortcuts */
52
48
  .nova-code-copy-button-icon-check{--nova-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");-webkit-mask:var(--nova-icon) no-repeat;mask:var(--nova-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;display:block;width:100%;height:100%;}
53
49
  .nova-code-copy-button-icon-clipboard{--nova-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--nova-icon) no-repeat;mask:var(--nova-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;display:block;width:100%;height:100%;}
50
+ .nova-link-button-icon,
51
+ .nova-link-card-icon{--nova-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 12h14m-7-7l7 7l-7 7'/%3E%3C/svg%3E");-webkit-mask:var(--nova-icon) no-repeat;mask:var(--nova-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;margin-left:0.5rem;width:1.25rem;height:1.25rem;transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
52
+ .nova-pagination-link-icon-left{--nova-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m15 18l-6-6l6-6'/%3E%3C/svg%3E");-webkit-mask:var(--nova-icon) no-repeat;mask:var(--nova-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;display:block;min-width:1.25rem;min-height:1.25rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
53
+ .nova-pagination-link-icon-right{--nova-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18l6-6l-6-6'/%3E%3C/svg%3E");-webkit-mask:var(--nova-icon) no-repeat;mask:var(--nova-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1em;height:1em;display:block;min-width:1.25rem;min-height:1.25rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
54
54
  .nova-code-container{position:relative;}
55
55
  .nova-code-copy-button{position:absolute;right:0.5rem;top:0.5rem;margin:0;width:1.5rem;height:1.5rem;border-width:1px;border-color:var(--sl-color-gray-5);border-radius:0.25rem;border-style:solid;background-color:rgb(243 244 246 / 0.3) /* #f3f4f6 */;padding:0.25rem;--nova-text-opacity:1;color:rgb(0 0 0 / var(--nova-text-opacity)) /* #000 */;--nova-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
56
- .nova-page-frame-header{position:fixed;inset:0;z-index:var(--sl-z-index-navbar);box-sizing:border-box;width:100%;height:var(--sl-nav-height);border-width:0px;border-bottom-width:1px;border-color:var(--sl-color-hairline);border-style:solid;background-color:rgb(255 255 255 / 0.8) /* #fff */;padding-top:var(--sl-nav-pad-y);padding-bottom:var(--sl-nav-pad-y);padding-left:var(--sl-nav-pad-x);padding-right:var(--sl-nav-pad-x);padding-inline-end:var(--sl-nav-pad-x);--nova-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);}
56
+ .nova-link-card{position:relative;display:flex;flex-direction:column;gap:0.5rem;border-width:1px;border-color:var(--sl-color-gray-5);border-radius:0.75rem;border-style:solid;--nova-bg-opacity:1;background-color:rgb(255 255 255 / var(--nova-bg-opacity)) /* #fff */;padding-left:1.25rem;padding-right:1.25rem;padding-top:1rem;padding-bottom:1rem;--nova-text-opacity:1;color:rgb(55 65 81 / var(--nova-text-opacity)) /* #374151 */;--nova-shadow:var(--nova-shadow-inset) 0 1px 2px 0 var(--nova-shadow-color, rgb(0 0 0 / 0.05));box-shadow:var(--nova-ring-offset-shadow), var(--nova-ring-shadow), var(--nova-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;transition-duration:200ms;}
57
+ .nova-page-frame-header{position:fixed;inset:0;z-index:var(--sl-z-index-navbar);box-sizing:border-box;width:100%;height:var(--sl-nav-height);border-width:0px;border-bottom-width:1px;border-color:var(--sl-color-hairline);border-style:solid;background-color:rgb(255 255 255 / 0.8) /* #fff */;padding-top:var(--sl-nav-pad-y);padding-bottom:var(--sl-nav-pad-y);padding-left:var(--sl-nav-pad-x);padding-right:var(--sl-nav-pad-x);--nova-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);}
58
+ .nova-link-card-link::before{position:absolute;inset:0;content:'';}
57
59
  .nova-header-title{margin:-0.25rem;min-width:0;display:flex;overflow:clip;padding:0.25rem;}
60
+ .nova-pagination-link{margin:0;display:flex;align-items:center;justify-content:flex-end;gap:0.5rem;border-radius:0.75rem;padding:0.5rem;color:var(--sl-color-gray-2) /* var(--sl-color-gray-2) */;font-weight:500;text-decoration:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;transition-duration:100ms;}
61
+ .nova-link-button{margin-inline-end:0.5rem;margin-top:0.5rem;margin-bottom:0.5rem;display:inline-flex;align-items:center;justify-content:space-between;border-width:1px;border-color:transparent;border-radius:0.75rem;border-style:solid;padding-left:1.5rem;padding-right:1.5rem;padding-top:0.75rem;padding-bottom:0.75rem;font-weight:500;text-decoration:none;--nova-shadow:var(--nova-shadow-inset) 0 1px 2px 0 var(--nova-shadow-color, rgb(0 0 0 / 0.05));box-shadow:var(--nova-ring-offset-shadow), var(--nova-ring-shadow), var(--nova-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;transition-duration:200ms;}
58
62
  .nova-header{box-sizing:border-box;height:100%;display:flex;align-items:center;gap:0.5rem;}
59
63
  .nova-header-actions{display:none;align-items:center;gap:0.5rem;}
64
+ .nova-social-icons-link{width:2rem;height:2rem;display:flex;border-radius:0.375rem;padding:0.5rem;color:var(--sl-color-text) /* var(--sl-color-text) */;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
65
+ .nova-theme-select{width:2rem;height:2rem;border-radius:0.375rem;padding:0.5rem;color:var(--sl-color-text) /* var(--sl-color-text) */;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
60
66
  .nova-page-frame{min-height:100vh;display:flex;flex-direction:column;}
67
+ .nova-pagination{min-width:100%;display:flex;flex-direction:row;align-items:stretch;justify-content:space-between;gap:0.5rem;padding-left:0.25rem;padding-right:0.25rem;padding-top:0;padding-bottom:1.5rem;}
68
+ .nova-header-nav{display:flex;flex:1 1 0%;flex-direction:row;gap:1rem;overflow-x:auto;padding-left:1rem;padding-right:1rem;font-size:0.875rem;line-height:1.25rem;font-weight:500;}
61
69
  .nova-header-search{display:flex;}
70
+ .nova-link-card-link{display:inline-flex;align-items:center;justify-content:space-between;font-size:1.125rem;line-height:1.75rem;--nova-text-opacity:1;color:rgb(55 65 81 / var(--nova-text-opacity)) /* #374151 */;font-weight:600;text-decoration:none;}
71
+ .nova-pagination-link[rel="next"]{flex-direction:row;}
72
+ .nova-pagination-link[rel="prev"]{flex-direction:row-reverse;}
73
+ .nova-link-button:hover .nova-link-button-icon,
74
+ .nova-link-card:hover .nova-link-card-icon{--nova-translate-x:0.25rem;transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
75
+ .nova-link-button:active{--nova-translate-x:0.25rem;transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
76
+ .nova-link-card:active{--nova-translate-x:0.25rem;transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
77
+ .nova-pagination-link:active[data-side="left"]{--nova-translate-x:-0.25rem;transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
78
+ .nova-pagination-link:active[data-side="right"]{--nova-translate-x:0.25rem;transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
62
79
  .nova-code-copy-button:active{--nova-scale-x:0.9;--nova-scale-y:0.9;transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
80
+ .nova-page-frame-sidebar-pane{border-width:0px;border-color:var(--sl-color-hairline);border-style:solid;}
81
+ .nova-link-button-secondary{border-color:var(--sl-color-gray-5);--nova-bg-opacity:1;background-color:rgb(255 255 255 / var(--nova-bg-opacity)) /* #fff */;--nova-text-opacity:1;color:rgb(55 65 81 / var(--nova-text-opacity)) /* #374151 */;}
63
82
  .dark .nova-code-copy-button{background-color:rgb(75 85 99 / 0.3) /* #4b5563 */;--nova-text-opacity:1;color:rgb(255 255 255 / var(--nova-text-opacity)) /* #fff */;}
83
+ .dark .nova-link-button-primary{--nova-bg-opacity:1;background-color:rgb(243 244 246 / var(--nova-bg-opacity)) /* #f3f4f6 */;--nova-text-opacity:1;color:rgb(17 24 39 / var(--nova-text-opacity)) /* #111827 */;}
84
+ .nova-link-button-primary{--nova-bg-opacity:1;background-color:rgb(0 0 0 / var(--nova-bg-opacity)) /* #000 */;--nova-text-opacity:1;color:rgb(255 255 255 / var(--nova-text-opacity)) /* #fff */;}
85
+ .dark .nova-link-button-secondary,
86
+ .dark .nova-link-card{--nova-bg-opacity:1;background-color:rgb(31 41 55 / var(--nova-bg-opacity)) /* #1f2937 */;--nova-text-opacity:1;color:rgb(229 231 235 / var(--nova-text-opacity)) /* #e5e7eb */;}
64
87
  .dark .nova-page-frame-header{background-color:rgb(3 7 18 / 0.5) /* #030712 */;}
65
88
  .dark .nova-code-copy-button:hover{background-color:rgb(107 114 128 / 0.5) /* #6b7280 */;}
66
89
  .nova-code-copy-button:hover{background-color:rgb(229 231 235 / 0.5) /* #e5e7eb */;}
67
- [data-has-sidebar] .nova-page-frame-header{padding-inline-end:calc(var(--sl-nav-gap) + var(--sl-nav-pad-x) + var(--sl-menu-button-size));}
90
+ .dark .nova-link-button-primary:hover{--nova-bg-opacity:1;background-color:rgb(209 213 219 / var(--nova-bg-opacity)) /* #d1d5db */;}
91
+ .nova-link-button-primary:hover{--nova-bg-opacity:1;background-color:rgb(31 41 55 / var(--nova-bg-opacity)) /* #1f2937 */;}
92
+ .dark .nova-link-button-secondary:hover{--nova-bg-opacity:1;background-color:rgb(55 65 81 / var(--nova-bg-opacity)) /* #374151 */;}
93
+ .nova-link-button-secondary:hover{--nova-bg-opacity:1;background-color:rgb(249 250 251 / var(--nova-bg-opacity)) /* #f9fafb */;}
94
+ .dark .nova-link-card:hover{--nova-bg-opacity:1;background-color:rgb(55 65 81 / var(--nova-bg-opacity)) /* #374151 */;}
95
+ .nova-link-card:hover{--nova-bg-opacity:1;background-color:rgb(249 250 251 / var(--nova-bg-opacity)) /* #f9fafb */;--nova-shadow:var(--nova-shadow-inset) 0 4px 6px -1px var(--nova-shadow-color, rgb(0 0 0 / 0.1)),var(--nova-shadow-inset) 0 2px 4px -2px var(--nova-shadow-color, rgb(0 0 0 / 0.1));box-shadow:var(--nova-ring-offset-shadow), var(--nova-ring-shadow), var(--nova-shadow);}
96
+ .nova-social-icons-link:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
97
+ .nova-theme-select:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
98
+ .nova-site-title *{font-size:1.125rem;line-height:1.75rem;color:var(--sl-color-text) /* var(--sl-color-text) */;font-weight:600;}
99
+ .nova-header-nav-link{color:var(--sl-color-gray-3) /* var(--sl-color-gray-3) */;text-decoration:none;}
100
+ .dark .nova-link-card-link{--nova-text-opacity:1;color:rgb(229 231 235 / var(--nova-text-opacity)) /* #e5e7eb */;}
101
+ .nova-header-nav-link:hover{color:var(--sl-color-white) /* var(--sl-color-white) */;}
102
+ .nova-pagination-link:hover{color:var(--sl-color-white) /* var(--sl-color-white) */;}
68
103
  .nova-code-container .nova-code-copy-button{opacity:0;}
69
104
  .nova-code-container:hover .nova-code-copy-button{opacity:1;}
105
+ .nova-link-button:hover{--nova-shadow:var(--nova-shadow-inset) 0 4px 6px -1px var(--nova-shadow-color, rgb(0 0 0 / 0.1)),var(--nova-shadow-inset) 0 2px 4px -2px var(--nova-shadow-color, rgb(0 0 0 / 0.1));box-shadow:var(--nova-ring-offset-shadow), var(--nova-ring-shadow), var(--nova-shadow);}
70
106
  @media print{
71
107
  .nova-header-actions,
72
108
  .nova-header-search{display:none;}
73
109
  }
110
+ @media (max-width: calc(50rem - 0.1px)){
111
+ .nova-header-nav *{display:none;}
112
+ [data-has-sidebar] .nova-page-frame-header{padding-inline-end:calc(var(--sl-nav-gap) + var(--sl-nav-pad-x) + var(--sl-menu-button-size));}
113
+ }
74
114
  @media (min-width: 50rem){
75
115
  .nova-header-search{max-width:15rem;flex:1 1 0%;}
76
116
  .nova-header-actions{display:flex;}
117
+ .nova-page-frame-sidebar-pane{border-right-width:1px;}
118
+ .nova-pagination-link{font-size:1.125rem;line-height:1.75rem;}
77
119
  }
78
- /* layer: default */
79
- .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;}
80
- .visible{visibility:visible;}
81
- .fixed{position:fixed;}
82
- .relative{position:relative;}
83
- .isolate{isolation:isolate;}
84
- .me{margin-inline-end:1rem;}
85
- .hidden{display:none;}
86
- .size-8{width:2rem;height:2rem;}
87
- .flex{display:flex;}
88
- .flex-1{flex:1 1 0%;}
89
- .transform{transform:translateX(var(--nova-translate-x)) translateY(var(--nova-translate-y)) translateZ(var(--nova-translate-z)) rotate(var(--nova-rotate)) rotateX(var(--nova-rotate-x)) rotateY(var(--nova-rotate-y)) rotateZ(var(--nova-rotate-z)) skewX(var(--nova-skew-x)) skewY(var(--nova-skew-y)) scaleX(var(--nova-scale-x)) scaleY(var(--nova-scale-y)) scaleZ(var(--nova-scale-z));}
90
- .rounded-md{border-radius:0.375rem;}
91
- .hover\:bg-gray-400\/30:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
92
- .p-2{padding:0.5rem;}
93
- .color-\[var\(--sl-color-text\)\]{color:var(--sl-color-text) /* var(--sl-color-text) */;}
94
- .backdrop-filter{-webkit-backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);backdrop-filter:var(--nova-backdrop-blur) var(--nova-backdrop-brightness) var(--nova-backdrop-contrast) var(--nova-backdrop-grayscale) var(--nova-backdrop-hue-rotate) var(--nova-backdrop-invert) var(--nova-backdrop-opacity) var(--nova-backdrop-saturate) var(--nova-backdrop-sepia);}
95
- .transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
96
- .transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
97
- .ease-out{transition-timing-function:cubic-bezier(0, 0, 0.2, 1);}
98
- @media print{
99
- .print\:hidden{display:none;}
100
- }
101
- @media (min-width: 50rem){
102
- .md\:border-r{border-right-width:1px;}
103
- }
104
- @media (min-width: 72rem){
105
- .lg\:flex{display:flex;}
120
+ @media (min-width: 90rem){
121
+ .nova-header-nav{gap:1.5rem;padding-left:1.5rem;}
106
122
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "starlight-theme-nova",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "description": "",
6
6
  "author": "ocavue <ocavue@gmail.com>",
7
7
  "license": "MIT",
@@ -0,0 +1,9 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import { Code as CodeComponent } from 'astro:components'
4
+ import { shikiConfig } from '../shiki-config'
5
+
6
+ type Props = ComponentProps<typeof CodeComponent>
7
+ ---
8
+
9
+ <CodeComponent {...shikiConfig} {...Astro.props} />
@@ -0,0 +1,13 @@
1
+ ---
2
+ import { TabItem } from '@astrojs/starlight/components'
3
+ import Code from './Code.astro'
4
+ import type { ComponentProps } from 'astro/types'
5
+
6
+ type Props = { label: string } & ComponentProps<typeof Code>
7
+
8
+ const { label, ...codeProps } = Astro.props
9
+ ---
10
+
11
+ <TabItem label={label}>
12
+ <Code {...codeProps} />
13
+ </TabItem>
@@ -0,0 +1,70 @@
1
+ ---
2
+ import { Tabs } from '@astrojs/starlight/components'
3
+
4
+ interface Props {
5
+ border?: boolean
6
+ syncKey?: string
7
+ }
8
+
9
+ const { border = true, syncKey } = Astro.props
10
+ ---
11
+
12
+ <div class:list={['code-tabs', border ? 'code-tabs-border' : undefined]}>
13
+ <Tabs syncKey={syncKey}>
14
+ <slot />
15
+ </Tabs>
16
+ </div>
17
+
18
+ <style is:global>
19
+ .sl-markdown-content .code-tabs {
20
+ overflow: hidden;
21
+
22
+ &.code-tabs-border {
23
+ border-color: var(--sl-color-gray-5);
24
+ border-width: 1px;
25
+ border-style: solid;
26
+ border-radius: 0.5rem;
27
+ }
28
+
29
+ starlight-tabs {
30
+ margin-top: 0;
31
+ }
32
+
33
+ .tablist-wrapper {
34
+ scrollbar-width: none;
35
+
36
+ [role='tablist'] {
37
+ border-bottom-width: 1px;
38
+ }
39
+
40
+ [role='tab'] {
41
+ font-family: var(--sl-font-system-mono);
42
+ padding-top: 0.5rem;
43
+ padding-bottom: 0.25rem;
44
+ padding-left: 0.75rem;
45
+ padding-right: 0.75rem;
46
+ font-size: 0.875rem;
47
+ white-space: nowrap;
48
+
49
+ border-bottom-style: solid;
50
+ border-bottom-width: 0px;
51
+
52
+ &[aria-selected='true'] {
53
+ border-bottom-width: 3px;
54
+ }
55
+ }
56
+ }
57
+
58
+ div[role='tabpanel'] {
59
+ margin: 0;
60
+ }
61
+
62
+ div[role='tabpanel'] pre {
63
+ border-color: transparent;
64
+ }
65
+
66
+ .astro-code {
67
+ border-radius: 0;
68
+ }
69
+ }
70
+ </style>
@@ -4,13 +4,24 @@ import Search from './Search.astro'
4
4
  import SiteTitle from './SiteTitle.astro'
5
5
  import SocialIcons from './SocialIcons.astro'
6
6
  import ThemeSelect from './ThemeSelect.astro'
7
+
8
+ import options from 'virtual:starlight-theme-nova/user-config'
9
+ const nav = options.nav ?? []
7
10
  ---
8
11
 
9
12
  <div class="nova-header">
10
13
  <div class="nova-header-title">
11
14
  <SiteTitle />
12
15
  </div>
13
- <div class="flex-1"></div>
16
+ <nav class="nova-header-nav">
17
+ {
18
+ nav.map((item) => (
19
+ <a class="nova-header-nav-link" href={item.href}>
20
+ {item.label}
21
+ </a>
22
+ ))
23
+ }
24
+ </nav>
14
25
  <div class="nova-header-search">
15
26
  <Search />
16
27
  </div>
@@ -0,0 +1,26 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+
4
+ interface Props extends Omit<HTMLAttributes<'a'>, 'href'> {
5
+ href: string | URL
6
+ variant?: 'primary' | 'secondary'
7
+ }
8
+
9
+ const { class: className, variant = 'primary', ...attrs } = Astro.props
10
+ ---
11
+
12
+ <span class="not-content">
13
+ <a
14
+ class:list={[
15
+ 'nova-link-button not-content',
16
+ variant === 'primary'
17
+ ? 'nova-link-button-primary'
18
+ : 'nova-link-button-secondary',
19
+ className,
20
+ ]}
21
+ {...attrs}
22
+ >
23
+ <slot />
24
+ <div class="nova-link-button-icon"></div>
25
+ </a>
26
+ </span>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+
4
+ interface Props extends Omit<HTMLAttributes<'a'>, 'title'> {
5
+ title: string
6
+ description?: string
7
+ }
8
+
9
+ const { title, description, class: className, ...attributes } = Astro.props
10
+ ---
11
+
12
+ <div class:list={['nova-link-card not-content', className]}>
13
+ <a class="nova-link-card-link" {...attributes}>
14
+ <span set:html={title} />
15
+ <div class="nova-link-card-icon"></div>
16
+ </a>
17
+ {description && <span set:html={description} />}
18
+ </div>
@@ -17,7 +17,7 @@ const { hasSidebar } = Astro.locals.starlightRoute
17
17
  <MobileMenuToggle />
18
18
  <div
19
19
  id="starlight__sidebar"
20
- class:list={['sidebar-pane', 'md:border-r border-border']}
20
+ class:list={['sidebar-pane', 'nova-page-frame-sidebar-pane']}
21
21
  >
22
22
  <div class="sidebar-content sl-flex">
23
23
  <slot name="sidebar" />
@@ -66,9 +66,6 @@ const { hasSidebar } = Astro.locals.starlightRoute
66
66
  }
67
67
 
68
68
  @media (min-width: 50rem) {
69
- :global([data-has-sidebar]) .header {
70
- padding-inline-end: var(--sl-nav-pad-x);
71
- }
72
69
  .sidebar-pane {
73
70
  --sl-sidebar-visibility: visible;
74
71
  width: var(--sl-sidebar-width);
@@ -0,0 +1,30 @@
1
+ ---
2
+ import PaginationLink from './PaginationLink.astro'
3
+
4
+ const { dir, pagination } = Astro.locals.starlightRoute
5
+ const { prev, next } = pagination
6
+ const isRtl = dir === 'rtl'
7
+ ---
8
+
9
+ <div class="print:hidden nova-pagination" dir={dir}>
10
+ {
11
+ prev && (
12
+ <PaginationLink
13
+ label={prev.label}
14
+ href={prev.href}
15
+ rel="prev"
16
+ side={isRtl ? 'right' : 'left'}
17
+ />
18
+ )
19
+ }
20
+ {
21
+ next && (
22
+ <PaginationLink
23
+ label={next.label}
24
+ href={next.href}
25
+ rel="next"
26
+ side={isRtl ? 'left' : 'right'}
27
+ />
28
+ )
29
+ }
30
+ </div>
@@ -0,0 +1,20 @@
1
+ ---
2
+ interface Props {
3
+ label: string
4
+ href: string
5
+ rel: 'next' | 'prev'
6
+ side: 'left' | 'right'
7
+ }
8
+
9
+ const { label, href, rel, side } = Astro.props
10
+ ---
11
+
12
+ <a href={href} rel={rel} data-side={side} class:list={['nova-pagination-link']}>
13
+ <span>{label}</span>
14
+ <span
15
+ class:list={[
16
+ side === 'right'
17
+ ? 'nova-pagination-link-icon-right'
18
+ : 'nova-pagination-link-icon-left',
19
+ ]}></span>
20
+ </a>
@@ -2,11 +2,4 @@
2
2
  import Default from '@astrojs/starlight/components/SiteTitle.astro'
3
3
  ---
4
4
 
5
- <span class="site-title-wrapper"><Default /></span>
6
-
7
- <style>
8
- .site-title-wrapper :global(.site-title) {
9
- color: var(--sl-color-text);
10
- font-size: var(--sl-text-h5);
11
- }
12
- </style>
5
+ <span class="nova-site-title"><Default /></span>
@@ -12,7 +12,7 @@ const links = Object.entries(config.social || {}) as [Platform, SocialConfig][]
12
12
  <>
13
13
  {
14
14
  links.map(([platform, { label, url }]) => (
15
- <a href={url} rel="me" class="flex p-2 transition hover:bg-gray-400/30 rounded-md size-8 color-[var(--sl-color-text)]">
15
+ <a href={url} rel="me" class="nova-social-icons-link">
16
16
  <span class="sr-only">{label}</span>
17
17
  <Icon name={platform} size="1rem" color="currentColor" />
18
18
  </a>
@@ -2,4 +2,4 @@
2
2
  import { Toggle } from 'astro-theme-toggle'
3
3
  ---
4
4
 
5
- <Toggle class="size-8 p-2 rounded-md color-[var(--sl-color-text)] hover:bg-gray-400/30 transition-colors" />
5
+ <Toggle class="nova-theme-select" />
@@ -1,4 +1,4 @@
1
- <div class="lg:flex">
1
+ <div class="lg:sl-flex">
2
2
  {
3
3
  Astro.locals.starlightRoute.toc && (
4
4
  <aside class="right-sidebar-container print:hidden">
package/src/index.ts CHANGED
@@ -4,6 +4,8 @@ import type {
4
4
  } from '@astrojs/starlight/types'
5
5
 
6
6
  import { shikiConfig } from './shiki-config'
7
+ import type { ThemeNovaOptions } from './user-options'
8
+ import { vitePluginUserConfig } from './virtual-user-config'
7
9
 
8
10
  const components = {
9
11
  Header: 'starlight-theme-nova/components/Header.astro',
@@ -13,12 +15,17 @@ const components = {
13
15
  SocialIcons: 'starlight-theme-nova/components/SocialIcons.astro',
14
16
  SiteTitle: 'starlight-theme-nova/components/SiteTitle.astro',
15
17
  PageFrame: 'starlight-theme-nova/components/PageFrame.astro',
18
+ Pagination: 'starlight-theme-nova/components/Pagination.astro',
16
19
  MobileMenuToggle: 'starlight-theme-nova/components/MobileMenuToggle.astro',
17
20
  TwoColumnContent: 'starlight-theme-nova/components/TwoColumnContent.astro',
18
21
  MarkdownContent: 'starlight-theme-nova/components/MarkdownContent.astro',
19
22
  } as const
20
23
 
21
- export default function starlightThemeNova(): StarlightPlugin {
24
+ export type { ThemeNovaOptions }
25
+
26
+ export default function starlightThemeNova(
27
+ options: ThemeNovaOptions = {},
28
+ ): StarlightPlugin {
22
29
  return {
23
30
  name: 'starlight-theme-nova',
24
31
  hooks: {
@@ -28,6 +35,7 @@ export default function starlightThemeNova(): StarlightPlugin {
28
35
  // Including any user CSS *after* our own.
29
36
  'starlight-theme-nova/styles.gen.css',
30
37
  'starlight-theme-nova/shiki.css',
38
+ 'starlight-theme-nova/markdown.css',
31
39
  ...(config.customCss || []),
32
40
  ],
33
41
  components: {
@@ -37,6 +45,7 @@ export default function starlightThemeNova(): StarlightPlugin {
37
45
  },
38
46
  expressiveCode: config.expressiveCode ?? false,
39
47
  } satisfies Partial<StarlightUserConfig>
48
+
40
49
  updateConfig(newConfig)
41
50
 
42
51
  addIntegration({
@@ -47,6 +56,9 @@ export default function starlightThemeNova(): StarlightPlugin {
47
56
  markdown: {
48
57
  shikiConfig,
49
58
  },
59
+ vite: {
60
+ plugins: [vitePluginUserConfig(options)],
61
+ },
50
62
  })
51
63
  },
52
64
  },
@@ -10,7 +10,7 @@ import { transformerCopyButton } from './shiki-transformer-copy-button'
10
10
  export const shikiConfig: ShikiConfig = {
11
11
  themes: {
12
12
  light: 'one-light',
13
- dark: 'one-dark-pro',
13
+ dark: 'github-dark-dimmed',
14
14
  },
15
15
  defaultColor: false,
16
16
  transformers: [
@@ -0,0 +1,8 @@
1
+ export interface NavItem {
2
+ label: string
3
+ href: string
4
+ }
5
+
6
+ export interface ThemeNovaOptions {
7
+ nav?: NavItem[]
8
+ }
@@ -0,0 +1,6 @@
1
+ /* eslint-disable @typescript-eslint/consistent-type-imports */
2
+
3
+ declare module 'virtual:starlight-theme-nova/user-config' {
4
+ const options: import('./user-options').ThemeNovaOptions
5
+ export default options
6
+ }
@@ -0,0 +1,36 @@
1
+ import { type ViteUserConfig } from 'astro'
2
+
3
+ import type { ThemeNovaOptions } from './user-options'
4
+
5
+ function resolveVirtualModuleId<T extends string>(id: T): `\0${T}` {
6
+ return `\0${id}`
7
+ }
8
+
9
+ /** Vite plugin that exposes user config via virtual modules. */
10
+ export function vitePluginUserConfig(
11
+ options: ThemeNovaOptions,
12
+ ): NonNullable<ViteUserConfig['plugins']>[number] {
13
+ /** Map of virtual module names to their code contents as strings. */
14
+ const modules = {
15
+ 'virtual:starlight-theme-nova/user-config': `export default ${JSON.stringify(options)}`,
16
+ } satisfies Record<string, string>
17
+
18
+ /** Mapping names prefixed with `\0` to their original form. */
19
+ const resolutionMap = Object.fromEntries(
20
+ (Object.keys(modules) as (keyof typeof modules)[]).map((key) => [
21
+ resolveVirtualModuleId(key),
22
+ key,
23
+ ]),
24
+ )
25
+
26
+ return {
27
+ name: 'vite-plugin-starlight-theme-nova-user-config',
28
+ resolveId(id): string | void {
29
+ if (id in modules) return resolveVirtualModuleId(id)
30
+ },
31
+ load(id): string | void {
32
+ const resolution = resolutionMap[id]
33
+ if (resolution) return modules[resolution]
34
+ },
35
+ }
36
+ }