starlight-theme-nova 0.7.4 → 0.8.1

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.
@@ -100,47 +100,57 @@
100
100
  /* layer: shortcuts */
101
101
  .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%;}
102
102
  .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%;}
103
- .nova-link-button-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;width:1.25rem;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;}
103
+ .nova-link-button-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='m12 19l-7-7l7-7m7 7H5'/%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;width:1.25rem;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;}
104
+ .nova-link-button-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='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;width:1.25rem;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;}
104
105
  .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: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;}
106
+ .nova-mobile-menu-toggle-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='M4 12h16M4 18h16M4 6h16'/%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;transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
107
+ body[data-mobile-menu-expanded] .nova-mobile-menu-toggle-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='M18 6L6 18M6 6l12 12'/%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;--nova-rotate-x:0;--nova-rotate-y:0;--nova-rotate-z:0;--nova-rotate:90deg;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));}
105
108
  .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;}
106
109
  .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;}
110
+ .nova-search-button-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%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='m21 21l-4.34-4.34'/%3E%3Ccircle cx='11' cy='11' r='8'/%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;}
107
111
  .nova-theme-select-icon-dark{--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='currentColor' d='M12 1.992a10 10 0 1 0 9.236 13.838c.341-.82-.476-1.644-1.298-1.31a6.5 6.5 0 0 1-6.864-10.787l.077-.08c.551-.63.113-1.653-.758-1.653h-.266l-.068-.006z'/%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;}
108
112
  .nova-theme-select-icon-light{--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='currentColor' d='M12 19a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1m-4.95-2.05a1 1 0 0 1 0 1.414l-1.414 1.414a1 1 0 1 1-1.414-1.414l1.414-1.414a1 1 0 0 1 1.414 0m11.314 0l1.414 1.414a1 1 0 0 1-1.414 1.414l-1.414-1.414a1 1 0 0 1 1.414-1.414m-5.049-9.836a5 5 0 1 1-2.532 9.674a5 5 0 0 1 2.532-9.674M4 11a1 1 0 0 1 0 2H2a1 1 0 0 1 0-2zm18 0a1 1 0 0 1 0 2h-2a1 1 0 0 1 0-2zM5.636 4.222L7.05 5.636A1 1 0 0 1 5.636 7.05L4.222 5.636a1 1 0 0 1 1.414-1.414m14.142 0a1 1 0 0 1 0 1.414L18.364 7.05a1 1 0 0 1-1.414-1.414l1.414-1.414a1 1 0 0 1 1.414 0M12 1a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0V2a1 1 0 0 1 1-1'/%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;}
113
+ .nova-page-frame-sidebar-pane{visibility:visible;visibility:hidden;border-width:0px;border-color:var(--sl-color-hairline);border-style:solid;}
109
114
  .nova-code-container{position:relative;overflow:hidden;border-width:1px;border-color:var(--sl-color-gray-5);border-radius:0.375rem;border-style:solid;}
110
115
  .nova-code-container pre{position:relative;}
111
116
  .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;}
112
117
  .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;}
113
118
  .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:var(--sl-color-bg-nav) /* var(--sl-color-bg-nav) */;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);}
114
119
  .nova-link-card-link::before{position:absolute;inset:0;content:'';}
115
- .nova-header-title{margin:-0.25rem;min-width:0;display:flex;overflow:clip;padding:0.25rem;}
120
+ .nova-header-nav-link{margin:-0.375rem;border-radius:0.375rem;padding:0.375rem;color:var(--sl-color-gray-3) /* var(--sl-color-gray-3) */;text-decoration:none;}
121
+ .nova-header-title{margin:-0.75rem;min-width:0;display:flex;overflow:clip;padding:0.75rem;}
122
+ .nova-nav-link,
123
+ .nova-site-title a{margin:-0.375rem;border-radius:0.375rem;padding:0.375rem;}
116
124
  .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;}
117
125
  .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;gap:0.5rem;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;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;}
118
126
  .nova-header{box-sizing:border-box;height:100%;display:flex;align-items:center;gap:0.5rem;}
119
127
  div[data-nova-code-container][data-nova-code-title] .nova-code-title{display:block;}
120
128
  .nova-pagination-link-icon{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;}
121
129
  .nova-code-title{display:none;border-bottom-width:1px;border-bottom-color:var(--sl-color-gray-5);border-bottom-style:solid;background-color:var(--sl-color-bg) /* var(--sl-color-bg) */;padding-left:1rem;padding-right:1rem;padding-top:0.5rem;padding-bottom:0.5rem;font-size:0.875rem;line-height:1.25rem;color:var(--sl-color-gray-3) /* var(--sl-color-gray-3) */;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;}
122
- .nova-header-actions{display:none;align-items:center;gap:0.5rem;}
123
- .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;}
124
- .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,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
130
+ .nova-header-actions-lg{display:none;align-items:center;gap:0.5rem;}
131
+ .nova-icon-button{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;}
132
+ .nova-theme-select{width:2rem;height:2rem;overflow:visible;}
125
133
  .nova-page-frame{min-height:100vh;display:flex;flex-direction:column;}
126
134
  .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;}
127
- .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;}
135
+ .nova-search-button-large{width:100%;max-width:22rem;height:2.25rem;display:flex;border-width:1px;border-color:var(--sl-color-gray-5);border-radius:0.375rem;border-style:solid;padding:0.5rem;color:var(--sl-color-text) /* var(--sl-color-text) */;transition-property:color;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
136
+ .nova-header-actions-sm{display:flex;align-items:center;gap:0.5rem;}
137
+ .nova-header-nav{display:flex;flex:1 1 0%;flex-direction:row;gap:1rem;overflow-x:auto;padding-top:0.75rem;padding-bottom:0.75rem;padding-left:1rem;padding-right:1rem;font-size:0.875rem;line-height:1.25rem;font-weight:500;}
128
138
  .nova-header-search{display:flex;}
139
+ .nova-mobile-menu-footer{display:flex;align-items:center;justify-content:flex-end;gap:0.5rem;padding-top:1rem;padding-bottom:1rem;}
129
140
  .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;}
130
141
  .nova-pagination-divider{flex:1 1 0%;}
131
142
  .nova-pagination-link[rel="next"]{flex-direction:row;}
132
143
  .nova-pagination-link[rel="prev"]{flex-direction:row-reverse;}
133
- .nova-link-button:hover .nova-link-button-icon,
144
+ .nova-link-button:hover .nova-link-button-icon-left,
145
+ .nova-pagination-link:hover .nova-pagination-link-icon-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));}
146
+ .nova-link-button:hover .nova-link-button-icon-right,
134
147
  .nova-link-card:hover .nova-link-card-icon,
135
148
  .nova-pagination-link:hover .nova-pagination-link-icon-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));}
136
- .nova-pagination-link:hover .nova-pagination-link-icon-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));}
137
149
  .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));}
150
+ .nova-icon-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));}
138
151
  .nova-link-button:active{--nova-scale-x:0.97;--nova-scale-y:0.97;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));}
139
152
  .nova-link-card:active{--nova-scale-x:0.99;--nova-scale-y:0.99;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));}
140
- .nova-social-icons-link: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));}
141
- .nova-theme-select: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));}
142
153
  .sl-markdown-content .nova-code-container pre.astro-code{border-width:0px;border-color:transparent;border-radius:0;}
143
- .nova-page-frame-sidebar-pane{border-width:0px;border-color:var(--sl-color-hairline);border-style:solid;}
144
154
  .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 */;--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);}
145
155
  .nova-mobile-table-of-contents summary{border-bottom-color:var(--sl-color-hairline);}
146
156
  .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 */;}
@@ -150,16 +160,15 @@ div[data-nova-code-container][data-nova-code-title] .nova-code-title{display:blo
150
160
  .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 */;}
151
161
  .dark .nova-code-copy-button:hover{background-color:rgb(107 114 128 / 0.5) /* #6b7280 */;}
152
162
  .nova-code-copy-button:hover{background-color:rgb(229 231 235 / 0.5) /* #e5e7eb */;}
163
+ .nova-icon-button:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
153
164
  .dark .nova-link-button-primary:hover{--nova-bg-opacity:1;background-color:rgb(209 213 219 / var(--nova-bg-opacity)) /* #d1d5db */;}
154
165
  .nova-link-button-primary:hover{--nova-bg-opacity:1;background-color:rgb(31 41 55 / var(--nova-bg-opacity)) /* #1f2937 */;--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);}
155
166
  .dark .nova-link-button-secondary:hover{--nova-bg-opacity:1;background-color:rgb(55 65 81 / var(--nova-bg-opacity)) /* #374151 */;}
156
167
  .nova-link-button-secondary: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);}
157
168
  .dark .nova-link-card:hover{--nova-bg-opacity:1;background-color:rgb(55 65 81 / var(--nova-bg-opacity)) /* #374151 */;}
158
169
  .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);}
159
- .nova-social-icons-link:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
160
- .nova-theme-select:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
170
+ .nova-search-button-large:hover{background-color:rgb(156 163 175 / 0.1) /* #9ca3af */;}
161
171
  .nova-site-title *{font-size:1.125rem;line-height:1.75rem;color:var(--sl-color-text) /* var(--sl-color-text) */;font-weight:600;}
162
- .nova-header-nav-link{color:var(--sl-color-gray-3) /* var(--sl-color-gray-3) */;text-decoration:none;}
163
172
  .dark .nova-link-button-minimal,
164
173
  .dark .nova-link-card-link{--nova-text-opacity:1;color:rgb(229 231 235 / var(--nova-text-opacity)) /* #e5e7eb */;}
165
174
  .nova-link-button-minimal{--nova-text-opacity:1;color:rgb(55 65 81 / var(--nova-text-opacity)) /* #374151 */;}
@@ -167,19 +176,33 @@ div[data-nova-code-container][data-nova-code-title] .nova-code-title{display:blo
167
176
  .nova-pagination-link:hover{color:var(--sl-color-white) /* var(--sl-color-white) */;}
168
177
  .nova-code-container .nova-code-copy-button{opacity:0;}
169
178
  .nova-code-container:hover .nova-code-copy-button{opacity:1;}
179
+ .nova-header-nav-link:focus-visible{outline-offset:0px;}
180
+ .nova-icon-button:focus-visible{outline-offset:1px;}
181
+ .nova-nav-link:focus-visible{outline-offset:0px;}
182
+ .nova-site-title:focus-visible a{outline-offset:0px;}
170
183
  .nova-mobile-table-of-contents nav{--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);}
171
184
  @media print{
172
- .nova-header-actions,
173
- .nova-header-search{display:none;}
185
+ .nova-header-actions-lg,
186
+ .nova-header-actions-sm,
187
+ .nova-header-search,
188
+ .nova-mobile-menu-footer{display:none;}
174
189
  }
175
190
  @media (max-width: calc(50rem - 0.1px)){
191
+ body[data-mobile-menu-expanded] .nova-page-frame-sidebar-pane{visibility:visible;}
176
192
  .nova-header-nav *{display:none;}
177
- [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));}
193
+ .nova-search-button{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;}
194
+ .nova-page-frame-sidebar-pane{width:100%;}
195
+ .nova-search-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));}
196
+ .nova-search-button:hover{background-color:rgb(156 163 175 / 0.3) /* #9ca3af */;}
197
+ .nova-search-button:focus-visible{outline-offset:1px;}
178
198
  }
179
199
  @media (min-width: 50rem){
200
+ .nova-page-frame-sidebar-pane{visibility:visible;width:var(--sl-sidebar-width);border-right-width:1px;}
201
+ .nova-header-actions-sm{display:none;}
180
202
  .nova-header-search{max-width:15rem;flex:1 1 0%;}
181
- .nova-header-actions{display:flex;}
182
- .nova-page-frame-sidebar-pane{border-right-width:1px;}
203
+ .nova-search-button{width:100%;max-width:22rem;height:2.25rem;display:flex;border-width:1px;border-color:var(--sl-color-gray-5);border-radius:0.375rem;border-style:solid;padding:0.5rem;color:var(--sl-color-text) /* var(--sl-color-text) */;transition-property:color;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}
204
+ .nova-header-actions-lg{display:flex;}
205
+ .nova-search-button:hover{background-color:rgb(156 163 175 / 0.1) /* #9ca3af */;}
183
206
  .nova-pagination-link{font-size:1.125rem;line-height:1.75rem;}
184
207
  }
185
208
  @media (min-width: 90rem){
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "starlight-theme-nova",
3
3
  "type": "module",
4
- "version": "0.7.4",
4
+ "version": "0.8.1",
5
5
  "description": "",
6
6
  "author": "ocavue <ocavue@gmail.com>",
7
7
  "license": "MIT",
@@ -26,11 +26,13 @@
26
26
  "src"
27
27
  ],
28
28
  "dependencies": {
29
+ "@aria-ui/core": "^0.0.21",
30
+ "@pagefind/default-ui": "^1.3.0",
29
31
  "@shikijs/transformers": "^3.5.0",
30
32
  "@shikijs/twoslash": "^3.5.0",
31
33
  "@shikijs/types": "^3.5.0",
32
34
  "@types/hast": "^3.0.4",
33
- "astro-theme-toggle": "^0.6.0",
35
+ "astro-theme-toggle": "^0.6.1",
34
36
  "hast-util-is-element": "^3.0.0",
35
37
  "rehype": "^13.0.2",
36
38
  "shiki-twoslash-renderer": "0.0.4"
@@ -1,11 +1,15 @@
1
1
  ---
2
- import LanguageSelect from '@astrojs/starlight/components/LanguageSelect.astro'
2
+ const { hasSidebar } = Astro.locals.starlightRoute
3
+
4
+ import LanguageSelect from 'virtual:starlight/components/LanguageSelect'
3
5
  import Search from 'virtual:starlight/components/Search'
4
6
  import SiteTitle from 'virtual:starlight/components/SiteTitle'
5
7
  import SocialIcons from 'virtual:starlight/components/SocialIcons'
6
8
  import ThemeSelect from 'virtual:starlight/components/ThemeSelect'
7
9
 
8
10
  import options from 'virtual:starlight-theme-nova/user-config'
11
+ import MobileMenuToggle from './MobileMenuToggle.astro'
12
+
9
13
  const nav = options.nav ?? []
10
14
  ---
11
15
 
@@ -25,9 +29,16 @@ const nav = options.nav ?? []
25
29
  <div class="nova-header-search">
26
30
  <Search />
27
31
  </div>
28
- <div class="nova-header-actions">
32
+ <div class="nova-header-actions-lg">
29
33
  <SocialIcons />
30
34
  <LanguageSelect />
31
35
  <ThemeSelect />
32
36
  </div>
37
+ {
38
+ hasSidebar && (
39
+ <div class="nova-header-actions-sm">
40
+ <MobileMenuToggle />
41
+ </div>
42
+ )
43
+ }
33
44
  </div>
@@ -2,8 +2,10 @@
2
2
  import { Image } from 'astro:assets'
3
3
  import { PAGE_TITLE_ID } from '../constants'
4
4
  import LinkButton from './LinkButton.astro'
5
+ import type { StarlightRouteEntryData } from '../content'
6
+
7
+ const data = Astro.locals.starlightRoute.entry.data as StarlightRouteEntryData
5
8
 
6
- const { data } = Astro.locals.starlightRoute.entry
7
9
  const { title = data.title, tagline, image, actions = [] } = data.hero || {}
8
10
 
9
11
  const imageAttrs = {
@@ -0,0 +1,5 @@
1
+ ---
2
+ import Default from '@astrojs/starlight/components/LanguageSelect.astro'
3
+ ---
4
+
5
+ <Default />
@@ -1,12 +1,22 @@
1
1
  ---
2
+ import type { StarlightIcon } from '@astrojs/starlight/types'
2
3
  import type { HTMLAttributes } from 'astro/types'
4
+ import LinkButtonIcon from './LinkButtonIcon.astro'
3
5
 
4
6
  interface Props extends Omit<HTMLAttributes<'a'>, 'href'> {
5
7
  href: string | URL
8
+ icon?: StarlightIcon | undefined
9
+ iconPlacement?: 'start' | 'end' | undefined
6
10
  variant?: 'primary' | 'secondary' | 'minimal'
7
11
  }
8
12
 
9
- const { class: className, variant = 'primary', ...attrs } = Astro.props
13
+ const {
14
+ class: className,
15
+ icon,
16
+ iconPlacement = 'end',
17
+ variant = 'primary',
18
+ ...attrs
19
+ } = Astro.props
10
20
  ---
11
21
 
12
22
  <span class="not-content">
@@ -22,7 +32,8 @@ const { class: className, variant = 'primary', ...attrs } = Astro.props
22
32
  ]}
23
33
  {...attrs}
24
34
  >
25
- <span><slot /></span>
26
- <div class="nova-link-button-icon"></div>
35
+ {icon && iconPlacement === 'start' && <LinkButtonIcon icon={icon} />}
36
+ <slot />
37
+ {icon && iconPlacement === 'end' && <LinkButtonIcon icon={icon} />}
27
38
  </a>
28
39
  </span>
@@ -0,0 +1,20 @@
1
+ ---
2
+ import { Icon } from '@astrojs/starlight/components'
3
+ import type { StarlightIcon } from '@astrojs/starlight/types'
4
+
5
+ interface Props {
6
+ icon: StarlightIcon
7
+ }
8
+
9
+ const { icon } = Astro.props
10
+
11
+ let className = ''
12
+
13
+ if (icon === 'right-arrow') {
14
+ className = 'nova-link-button-icon-right'
15
+ } else if (icon === 'left-arrow') {
16
+ className = 'nova-link-button-icon-left'
17
+ }
18
+ ---
19
+
20
+ {className ? <div class={className} /> : <Icon name={icon} size="1.25rem" />}
@@ -0,0 +1,11 @@
1
+ ---
2
+ import LanguageSelect from 'virtual:starlight/components/LanguageSelect'
3
+ import SocialIcons from 'virtual:starlight/components/SocialIcons'
4
+ import ThemeSelect from 'virtual:starlight/components/ThemeSelect'
5
+ ---
6
+
7
+ <div class="nova-mobile-menu-footer">
8
+ <SocialIcons />
9
+ <LanguageSelect />
10
+ <ThemeSelect />
11
+ </div>
@@ -1,5 +1,13 @@
1
- ---
2
- import Default from '@astrojs/starlight/components/MobileMenuToggle.astro'
3
- ---
1
+ <nova-mobile-menu-toggle
2
+ class="print:hidden nova-icon-button"
3
+ aria-label={Astro.locals.t('menuButton.accessibleLabel')}
4
+ aria-controls="starlight__sidebar"
5
+ >
6
+ <div class="nova-mobile-menu-toggle-icon"></div>
7
+ </nova-mobile-menu-toggle>
4
8
 
5
- <Default />
9
+ <script>
10
+ import { register } from './mobile-menu-toggle'
11
+
12
+ register()
13
+ </script>
@@ -1,6 +1,4 @@
1
1
  ---
2
- import MobileMenuToggle from './MobileMenuToggle.astro'
3
-
4
2
  const { hasSidebar } = Astro.locals.starlightRoute
5
3
  ---
6
4
 
@@ -13,8 +11,8 @@ const { hasSidebar } = Astro.locals.starlightRoute
13
11
  <nav
14
12
  class="sidebar print:hidden"
15
13
  aria-label={Astro.locals.t('sidebarNav.accessibleLabel')}
14
+ id="nova-sidebar-nav"
16
15
  >
17
- <MobileMenuToggle />
18
16
  <div
19
17
  id="starlight__sidebar"
20
18
  class:list={['sidebar-pane', 'nova-page-frame-sidebar-pane']}
@@ -32,20 +30,14 @@ const { hasSidebar } = Astro.locals.starlightRoute
32
30
  <style>
33
31
  @layer nova {
34
32
  .sidebar-pane {
35
- visibility: var(--sl-sidebar-visibility, hidden);
36
33
  position: fixed;
37
34
  z-index: var(--sl-z-index-menu);
38
35
  inset-block: var(--sl-nav-height) 0;
39
36
  inset-inline-start: 0;
40
- width: 100%;
41
37
  background-color: var(--sl-color-black);
42
38
  overflow-y: auto;
43
39
  }
44
40
 
45
- :global([aria-expanded='true']) ~ .sidebar-pane {
46
- --sl-sidebar-visibility: visible;
47
- }
48
-
49
41
  .sidebar-content {
50
42
  height: 100%;
51
43
  min-height: max-content;
@@ -54,23 +46,9 @@ const { hasSidebar } = Astro.locals.starlightRoute
54
46
  gap: 1rem;
55
47
  }
56
48
 
57
- @media (min-width: 50rem) {
58
- .sidebar-content::after {
59
- content: '';
60
- padding-bottom: 1px;
61
- }
62
- }
63
-
64
49
  .main-frame {
65
50
  padding-top: calc(var(--sl-nav-height) + var(--sl-mobile-toc-height));
66
51
  padding-inline-start: var(--sl-content-inline-start);
67
52
  }
68
-
69
- @media (min-width: 50rem) {
70
- .sidebar-pane {
71
- --sl-sidebar-visibility: visible;
72
- width: var(--sl-sidebar-width);
73
- }
74
- }
75
53
  }
76
54
  </style>
@@ -1,8 +1,531 @@
1
1
  ---
2
- import Default from '@astrojs/starlight/components/Search.astro'
2
+ import project from 'virtual:starlight/project-context'
3
+
4
+ const pagefindTranslations = {
5
+ placeholder: Astro.locals.t('search.label'),
6
+ ...Object.fromEntries(
7
+ Object.entries(Astro.locals.t.all())
8
+ .filter(([key]) => key.startsWith('pagefind.'))
9
+ .map(([key, value]) => [key.replace('pagefind.', ''), value]),
10
+ ),
11
+ }
12
+
13
+ const dataAttributes: DOMStringMap = {
14
+ 'data-translations': JSON.stringify(pagefindTranslations),
15
+ }
16
+ if (project.trailingSlash === 'never')
17
+ dataAttributes['data-strip-trailing-slash'] = ''
3
18
  ---
4
19
 
5
- <Default />
20
+ <site-search class={Astro.props.class} {...dataAttributes}>
21
+ <button
22
+ class="nova-search-button"
23
+ data-open-modal
24
+ disabled
25
+ aria-label={Astro.locals.t('search.label')}
26
+ aria-keyshortcuts="Control+K"
27
+ >
28
+ <span class="nova-search-button-icon"></span>
29
+ <span class="sl-hidden md:sl-block" aria-hidden="true"
30
+ >{Astro.locals.t('search.label')}</span
31
+ >
32
+ <kbd class="sl-hidden md:sl-flex" style="display: none;">
33
+ <kbd>{Astro.locals.t('search.ctrlKey')}</kbd><kbd>K</kbd>
34
+ </kbd>
35
+ </button>
36
+
37
+ <dialog style="padding:0" aria-label={Astro.locals.t('search.label')}>
38
+ <div class="dialog-frame sl-flex">
39
+ {
40
+ /* TODO: Make the layout of this button flexible to accommodate different word lengths. Currently hard-coded for English: “Cancel” */
41
+ }
42
+ <button data-close-modal class="sl-flex md:sl-hidden">
43
+ {Astro.locals.t('search.cancelLabel')}
44
+ </button>
45
+ {
46
+ import.meta.env.DEV ? (
47
+ <div
48
+ style="margin: auto; text-align: center; white-space: pre-line;"
49
+ dir="ltr"
50
+ >
51
+ <p>{Astro.locals.t('search.devWarning')}</p>
52
+ </div>
53
+ ) : (
54
+ <div class="search-container">
55
+ <div id="starlight__search" />
56
+ </div>
57
+ )
58
+ }
59
+ </div>
60
+ </dialog>
61
+ </site-search>
62
+
63
+ {
64
+ /**
65
+ * This is intentionally inlined to avoid briefly showing an invalid shortcut.
66
+ * Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the
67
+ * user agent is spoofed by some browsers when opening the devtools.
68
+ */
69
+ }
70
+ <script is:inline>
71
+ ;(() => {
72
+ const openBtn = document.querySelector('button[data-open-modal]')
73
+ const shortcut = openBtn?.querySelector('kbd')
74
+ if (!openBtn || !(shortcut instanceof HTMLElement)) return
75
+ const platformKey = shortcut.querySelector('kbd')
76
+ if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
77
+ platformKey.textContent = '⌘'
78
+ openBtn.setAttribute('aria-keyshortcuts', 'Meta+K')
79
+ }
80
+ shortcut.style.display = ''
81
+ })()
82
+ </script>
83
+
84
+ <script>
85
+ import { pagefindUserConfig } from 'virtual:starlight/pagefind-config'
86
+
87
+ class SiteSearch extends HTMLElement {
88
+ constructor() {
89
+ super()
90
+ const openBtn = this.querySelector<HTMLButtonElement>(
91
+ 'button[data-open-modal]',
92
+ )!
93
+ const closeBtn = this.querySelector<HTMLButtonElement>(
94
+ 'button[data-close-modal]',
95
+ )!
96
+ const dialog = this.querySelector('dialog')!
97
+ const dialogFrame = this.querySelector('.dialog-frame')!
98
+
99
+ /** Close the modal if a user clicks on a link or outside of the modal. */
100
+ const onClick = (event: MouseEvent) => {
101
+ const isLink = 'href' in (event.target || {})
102
+ if (
103
+ isLink ||
104
+ (document.body.contains(event.target as Node) &&
105
+ !dialogFrame.contains(event.target as Node))
106
+ ) {
107
+ closeModal()
108
+ }
109
+ }
110
+
111
+ const openModal = (event?: MouseEvent) => {
112
+ dialog.showModal()
113
+ document.body.toggleAttribute('data-search-modal-open', true)
114
+ this.querySelector('input')?.focus()
115
+ event?.stopPropagation()
116
+ window.addEventListener('click', onClick)
117
+ }
118
+
119
+ const closeModal = () => dialog.close()
120
+
121
+ openBtn.addEventListener('click', openModal)
122
+ openBtn.disabled = false
123
+ closeBtn.addEventListener('click', closeModal)
124
+
125
+ dialog.addEventListener('close', () => {
126
+ document.body.toggleAttribute('data-search-modal-open', false)
127
+ window.removeEventListener('click', onClick)
128
+ })
129
+
130
+ // Listen for `ctrl + k` and `cmd + k` keyboard shortcuts.
131
+ window.addEventListener('keydown', (e) => {
132
+ if ((e.metaKey === true || e.ctrlKey === true) && e.key === 'k') {
133
+ dialog.open ? closeModal() : openModal()
134
+ e.preventDefault()
135
+ }
136
+ })
137
+
138
+ let translations = {}
139
+ try {
140
+ translations = JSON.parse(this.dataset.translations || '{}')
141
+ } catch {}
142
+
143
+ const shouldStrip = this.dataset.stripTrailingSlash !== undefined
144
+ const stripTrailingSlash = (path: string) =>
145
+ path.replace(/(.)\/(#.*)?$/, '$1$2')
146
+ const formatURL = shouldStrip
147
+ ? stripTrailingSlash
148
+ : (path: string) => path
149
+
150
+ window.addEventListener('DOMContentLoaded', () => {
151
+ if (import.meta.env.DEV) return
152
+ const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1))
153
+ onIdle(async () => {
154
+ // @ts-expect-error — Missing types for @pagefind/default-ui package.
155
+ const { PagefindUI } = await import('@pagefind/default-ui')
156
+ new PagefindUI({
157
+ ...pagefindUserConfig,
158
+ element: '#starlight__search',
159
+ baseUrl: import.meta.env.BASE_URL,
160
+ bundlePath:
161
+ import.meta.env.BASE_URL.replace(/\/$/, '') + '/pagefind/',
162
+ showImages: false,
163
+ translations,
164
+ showSubResults: true,
165
+ processResult: (result: {
166
+ url: string
167
+ sub_results: Array<{ url: string }>
168
+ }) => {
169
+ result.url = formatURL(result.url)
170
+ result.sub_results = result.sub_results.map((sub_result) => {
171
+ sub_result.url = formatURL(sub_result.url)
172
+ return sub_result
173
+ })
174
+ },
175
+ })
176
+ })
177
+ })
178
+ }
179
+ }
180
+ customElements.define('site-search', SiteSearch)
181
+ </script>
182
+
183
+ <style>
184
+ @layer starlight.core {
185
+ site-search {
186
+ display: contents;
187
+ }
188
+ button[data-open-modal] {
189
+ display: flex;
190
+ align-items: center;
191
+ gap: 0.5rem;
192
+ border: 0;
193
+ background-color: transparent;
194
+ color: var(--sl-color-gray-1);
195
+ cursor: pointer;
196
+ height: 2.5rem;
197
+ font-size: var(--sl-text-xl);
198
+ }
199
+
200
+ @media (min-width: 50rem) {
201
+ button[data-open-modal] {
202
+ padding-inline-start: 0.75rem;
203
+ padding-inline-end: 0.5rem;
204
+ background-color: var(--sl-color-black);
205
+ color: var(--sl-color-gray-2);
206
+ font-size: var(--sl-text-sm);
207
+ }
208
+
209
+ button[data-open-modal] > :last-child {
210
+ margin-inline-start: auto;
211
+ }
212
+ }
213
+
214
+ button > kbd {
215
+ border-radius: 0.25rem;
216
+ font-size: var(--sl-text-2xs);
217
+ gap: 0.25em;
218
+ padding-inline: 0.375rem;
219
+ background-color: var(--sl-color-gray-6);
220
+ }
221
+
222
+ kbd {
223
+ font-family: var(--__sl-font);
224
+ }
225
+
226
+ dialog {
227
+ margin: 0;
228
+ background-color: var(--sl-color-gray-6);
229
+ border: 1px solid var(--sl-color-gray-5);
230
+ width: 100%;
231
+ max-width: 100%;
232
+ height: 100%;
233
+ max-height: 100%;
234
+ box-shadow: var(--sl-shadow-lg);
235
+ }
236
+ dialog[open] {
237
+ display: flex;
238
+ }
239
+
240
+ dialog::backdrop {
241
+ background-color: var(--sl-color-backdrop-overlay);
242
+ -webkit-backdrop-filter: blur(0.25rem);
243
+ backdrop-filter: blur(0.25rem);
244
+ }
245
+
246
+ .dialog-frame {
247
+ position: relative;
248
+ overflow: auto;
249
+ flex-direction: column;
250
+ flex-grow: 1;
251
+ gap: 1rem;
252
+ padding: 1rem;
253
+ }
254
+
255
+ button[data-close-modal] {
256
+ position: absolute;
257
+ z-index: 1;
258
+ align-items: center;
259
+ align-self: flex-end;
260
+ height: calc(64px * var(--pagefind-ui-scale));
261
+ padding: 0.25rem;
262
+ border: 0;
263
+ background: transparent;
264
+ cursor: pointer;
265
+ color: var(--sl-color-text-accent);
266
+ }
267
+
268
+ #starlight__search {
269
+ --pagefind-ui-primary: var(--sl-color-text);
270
+ --pagefind-ui-text: var(--sl-color-gray-2);
271
+ --pagefind-ui-font: var(--__sl-font);
272
+ --pagefind-ui-background: var(--sl-color-black);
273
+ --pagefind-ui-border: var(--sl-color-gray-5);
274
+ --pagefind-ui-border-width: 1px;
275
+ --pagefind-ui-tag: var(--sl-color-gray-5);
276
+ --sl-search-cancel-space: 5rem;
277
+ }
278
+
279
+ :root[data-theme='light'] #starlight__search {
280
+ --pagefind-ui-tag: var(--sl-color-gray-6);
281
+ }
282
+
283
+ @media (min-width: 50rem) {
284
+ #starlight__search {
285
+ --sl-search-cancel-space: 0px;
286
+ }
287
+
288
+ dialog {
289
+ margin: 4rem auto auto;
290
+ border-radius: 0.5rem;
291
+ width: 90%;
292
+ max-width: 40rem;
293
+ height: max-content;
294
+ min-height: 15rem;
295
+ max-height: calc(100% - 8rem);
296
+ }
297
+
298
+ .dialog-frame {
299
+ padding: 1.5rem;
300
+ }
301
+ }
302
+ }
303
+ </style>
304
+
305
+ <style is:global>
306
+ @import url('@pagefind/default-ui/css/ui.css') layer(starlight.core);
307
+
308
+ @layer starlight.core {
309
+ [data-search-modal-open] {
310
+ overflow: hidden;
311
+ }
312
+
313
+ #starlight__search {
314
+ --sl-search-result-spacing: calc(1.25rem * var(--pagefind-ui-scale));
315
+ --sl-search-result-pad-inline-start: calc(
316
+ 3.75rem * var(--pagefind-ui-scale)
317
+ );
318
+ --sl-search-result-pad-inline-end: calc(
319
+ 1.25rem * var(--pagefind-ui-scale)
320
+ );
321
+ --sl-search-result-pad-block: calc(0.9375rem * var(--pagefind-ui-scale));
322
+ --sl-search-result-nested-pad-block: calc(
323
+ 0.625rem * var(--pagefind-ui-scale)
324
+ );
325
+ --sl-search-corners: calc(0.3125rem * var(--pagefind-ui-scale));
326
+ --sl-search-page-icon-size: calc(1.875rem * var(--pagefind-ui-scale));
327
+ --sl-search-page-icon-inline-start: calc(
328
+ (
329
+ var(--sl-search-result-pad-inline-start) -
330
+ var(--sl-search-page-icon-size)
331
+ ) /
332
+ 2
333
+ );
334
+ --sl-search-tree-diagram-size: calc(2.5rem * var(--pagefind-ui-scale));
335
+ --sl-search-tree-diagram-inline-start: calc(
336
+ (
337
+ var(--sl-search-result-pad-inline-start) -
338
+ var(--sl-search-tree-diagram-size)
339
+ ) /
340
+ 2
341
+ );
342
+ }
343
+
344
+ #starlight__search .pagefind-ui__form::before {
345
+ --pagefind-ui-text: var(--sl-color-gray-1);
346
+ opacity: 1;
347
+ }
348
+
349
+ #starlight__search .pagefind-ui__search-input {
350
+ color: var(--sl-color-white);
351
+ font-weight: 400;
352
+ width: calc(100% - var(--sl-search-cancel-space));
353
+ }
354
+
355
+ #starlight__search input:focus {
356
+ --pagefind-ui-border: var(--sl-color-accent);
357
+ }
358
+
359
+ #starlight__search .pagefind-ui__search-clear {
360
+ inset-inline-end: var(--sl-search-cancel-space);
361
+ width: calc(60px * var(--pagefind-ui-scale));
362
+ padding: 0;
363
+ background-color: transparent;
364
+ overflow: hidden;
365
+ }
366
+ #starlight__search .pagefind-ui__search-clear:focus {
367
+ outline: 1px solid var(--sl-color-accent);
368
+ }
369
+ #starlight__search .pagefind-ui__search-clear::before {
370
+ content: '';
371
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
372
+ center / 50% no-repeat;
373
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
374
+ center / 50% no-repeat;
375
+ background-color: var(--sl-color-text-accent);
376
+ display: block;
377
+ width: 100%;
378
+ height: 100%;
379
+ }
380
+
381
+ #starlight__search .pagefind-ui__results > * + * {
382
+ margin-top: var(--sl-search-result-spacing);
383
+ }
384
+ #starlight__search .pagefind-ui__result {
385
+ border: 0;
386
+ padding: 0;
387
+ }
388
+
389
+ #starlight__search .pagefind-ui__result-nested {
390
+ position: relative;
391
+ padding: var(--sl-search-result-nested-pad-block)
392
+ var(--sl-search-result-pad-inline-end);
393
+ padding-inline-start: var(--sl-search-result-pad-inline-start);
394
+ }
395
+
396
+ #starlight__search
397
+ .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)),
398
+ #starlight__search .pagefind-ui__result-nested {
399
+ position: relative;
400
+ background-color: var(--sl-color-black);
401
+ }
402
+
403
+ #starlight__search
404
+ .pagefind-ui__result-title:not(
405
+ :where(.pagefind-ui__result-nested *)
406
+ ):hover,
407
+ #starlight__search
408
+ .pagefind-ui__result-title:not(
409
+ :where(.pagefind-ui__result-nested *)
410
+ ):focus-within,
411
+ #starlight__search .pagefind-ui__result-nested:hover,
412
+ #starlight__search .pagefind-ui__result-nested:focus-within {
413
+ outline: 1px solid var(--sl-color-accent-high);
414
+ }
415
+
416
+ #starlight__search
417
+ .pagefind-ui__result-title:not(
418
+ :where(.pagefind-ui__result-nested *)
419
+ ):focus-within,
420
+ #starlight__search .pagefind-ui__result-nested:focus-within {
421
+ background-color: var(--sl-color-accent-low);
422
+ }
423
+
424
+ #starlight__search .pagefind-ui__result-thumb,
425
+ #starlight__search .pagefind-ui__result-inner {
426
+ margin-top: 0;
427
+ }
428
+
429
+ #starlight__search .pagefind-ui__result-inner > :first-child {
430
+ border-radius: var(--sl-search-corners) var(--sl-search-corners) 0 0;
431
+ }
432
+ #starlight__search .pagefind-ui__result-inner > :last-child {
433
+ border-radius: 0 0 var(--sl-search-corners) var(--sl-search-corners);
434
+ }
435
+
436
+ #starlight__search .pagefind-ui__result-inner > .pagefind-ui__result-title {
437
+ padding: var(--sl-search-result-pad-block)
438
+ var(--sl-search-result-pad-inline-end);
439
+ padding-inline-start: var(--sl-search-result-pad-inline-start);
440
+ }
441
+ #starlight__search
442
+ .pagefind-ui__result-inner
443
+ > .pagefind-ui__result-title::before {
444
+ content: '';
445
+ position: absolute;
446
+ inset-block: 0;
447
+ inset-inline-start: var(--sl-search-page-icon-inline-start);
448
+ width: var(--sl-search-page-icon-size);
449
+ background: var(--sl-color-gray-3);
450
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' viewBox='0 0 24 24'%3E%3Cpath d='M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3V8l-6-6a1 1 0 0 0-1 0H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V9Zm-6-4 3 3h-2a1 1 0 0 1-1-1V5Zm4 14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z'/%3E%3C/svg%3E")
451
+ center no-repeat;
452
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' viewBox='0 0 24 24'%3E%3Cpath d='M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3V8l-6-6a1 1 0 0 0-1 0H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V9Zm-6-4 3 3h-2a1 1 0 0 1-1-1V5Zm4 14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z'/%3E%3C/svg%3E")
453
+ center no-repeat;
454
+ }
455
+
456
+ #starlight__search .pagefind-ui__result-inner {
457
+ align-items: stretch;
458
+ gap: 1px;
459
+ }
460
+
461
+ #starlight__search .pagefind-ui__result-link {
462
+ position: unset;
463
+ --pagefind-ui-text: var(--sl-color-white);
464
+ font-weight: 600;
465
+ }
466
+
467
+ #starlight__search .pagefind-ui__result-link:hover {
468
+ text-decoration: none;
469
+ }
470
+
471
+ #starlight__search
472
+ .pagefind-ui__result-nested
473
+ .pagefind-ui__result-link::before {
474
+ content: unset;
475
+ }
476
+
477
+ #starlight__search .pagefind-ui__result-nested::before {
478
+ content: '';
479
+ position: absolute;
480
+ inset-block: 0;
481
+ inset-inline-start: var(--sl-search-tree-diagram-inline-start);
482
+ width: var(--sl-search-tree-diagram-size);
483
+ background: var(--sl-color-gray-4);
484
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
485
+ 0% 0% / 100% no-repeat;
486
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
487
+ 0% 0% / 100% no-repeat;
488
+ }
489
+ #starlight__search .pagefind-ui__result-nested:last-of-type::before {
490
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v12m6 0H8'/%3E%3C/svg%3E");
491
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v12m6 0H8'/%3E%3C/svg%3E");
492
+ }
493
+
494
+ /* Flip page and tree icons around the vertical axis when in an RTL layout. */
495
+ [dir='rtl'] .pagefind-ui__result-title::before,
496
+ [dir='rtl'] .pagefind-ui__result-nested::before {
497
+ transform: matrix(-1, 0, 0, 1, 0, 0);
498
+ }
499
+
500
+ #starlight__search .pagefind-ui__result-link::after {
501
+ content: '';
502
+ position: absolute;
503
+ inset: 0;
504
+ }
505
+
506
+ #starlight__search .pagefind-ui__result-excerpt {
507
+ font-size: calc(1rem * var(--pagefind-ui-scale));
508
+ overflow-wrap: anywhere;
509
+ }
510
+
511
+ #starlight__search mark {
512
+ color: var(--sl-color-gray-2);
513
+ background-color: transparent;
514
+ font-weight: 600;
515
+ }
516
+
517
+ #starlight__search .pagefind-ui__filter-value::before {
518
+ border-color: var(--sl-color-text-invert);
519
+ }
520
+
521
+ #starlight__search .pagefind-ui__result-tags {
522
+ background-color: var(--sl-color-black);
523
+ margin-top: 0;
524
+ padding: var(--sl-search-result-nested-pad-block)
525
+ var(--sl-search-result-pad-inline-end);
526
+ }
527
+ }
528
+ </style>
6
529
 
7
530
  <style is:global>
8
531
  @layer nova {
@@ -17,7 +17,7 @@ if (!Array.isArray(links)) {
17
17
  links.length > 0 && (
18
18
  <>
19
19
  {links.map(({ label, href, icon }) => (
20
- <a href={href} rel="me" class="nova-social-icons-link">
20
+ <a href={href} rel="me" class="nova-icon-button">
21
21
  <span class="sr-only">{label}</span>
22
22
  <Icon name={icon} size="1rem" color="currentColor" />
23
23
  </a>
@@ -2,11 +2,13 @@
2
2
  import { Toggle } from 'astro-theme-toggle'
3
3
  ---
4
4
 
5
- <Toggle class="nova-theme-select">
6
- <Fragment slot="icon-light">
7
- <div class="nova-theme-select-icon-light"></div>
8
- </Fragment>
9
- <Fragment slot="icon-dark">
10
- <div class="nova-theme-select-icon-dark"></div>
11
- </Fragment>
12
- </Toggle>
5
+ <div class="nova-theme-select">
6
+ <Toggle class="nova-icon-button">
7
+ <Fragment slot="icon-light">
8
+ <div class="nova-theme-select-icon-light"></div>
9
+ </Fragment>
10
+ <Fragment slot="icon-dark">
11
+ <div class="nova-theme-select-icon-dark"></div>
12
+ </Fragment>
13
+ </Toggle>
14
+ </div>
@@ -0,0 +1,65 @@
1
+ import type { BaseElement } from '@aria-ui/core'
2
+ import {
3
+ createSignal,
4
+ defineCustomElement,
5
+ useAriaAttribute,
6
+ useEffect,
7
+ useEventListener,
8
+ } from '@aria-ui/core'
9
+
10
+ function setupMobileMenuToggle(host: BaseElement) {
11
+ const expanded = createSignal(false)
12
+
13
+ function toggleExpanded() {
14
+ expanded.set(!expanded.get())
15
+ }
16
+
17
+ useAriaAttribute(host, 'aria-expanded', () => {
18
+ return expanded.get() ? 'true' : 'false'
19
+ })
20
+
21
+ useEffect(host, () => {
22
+ document.body.toggleAttribute(
23
+ 'data-mobile-menu-expanded',
24
+ expanded.get() || false,
25
+ )
26
+ })
27
+
28
+ useEventListener(host, 'click', toggleExpanded)
29
+ useEventListener(host, 'keydown', (event) => {
30
+ if (!event.isComposing && (event.key === 'Enter' || event.key === ' ')) {
31
+ event.preventDefault()
32
+ toggleExpanded()
33
+ }
34
+ })
35
+
36
+ useEffect(host, () => {
37
+ const sidebarNav = document.getElementById('nova-sidebar-nav')
38
+ if (!sidebarNav) return
39
+ const handleKeyup = (event: KeyboardEvent) => {
40
+ if (event.code === 'Escape') {
41
+ expanded.set(false)
42
+ host.focus()
43
+ }
44
+ }
45
+ sidebarNav.addEventListener('keyup', handleKeyup)
46
+ return () => sidebarNav.removeEventListener('keyup', handleKeyup)
47
+ })
48
+
49
+ useEffect(host, () => {
50
+ host.setAttribute('role', 'button')
51
+ host.setAttribute('tabindex', '0')
52
+ })
53
+ }
54
+
55
+ const MobileMenuToggle = defineCustomElement({
56
+ props: {},
57
+ events: {},
58
+ setup: setupMobileMenuToggle,
59
+ })
60
+
61
+ function register() {
62
+ customElements.define('nova-mobile-menu-toggle', MobileMenuToggle)
63
+ }
64
+
65
+ export { register }
@@ -0,0 +1,7 @@
1
+ import { docsLoader } from '@astrojs/starlight/loaders'
2
+ import { docsSchema } from '@astrojs/starlight/schema'
3
+ import { defineCollection } from 'astro:content'
4
+
5
+ export const collections = {
6
+ docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
7
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * This file contains some types by simplifying and modifying the generated
3
+ * files `.astro/content.d.ts`.
4
+ *
5
+ * Normally, Astro will generate a `.astro/content.d.ts` file for an Astro app
6
+ * project. However, since starlight-theme-nova is a library instead of an app,
7
+ * we don't have those auto-generated files.
8
+ */
9
+
10
+ declare module 'astro:content' {
11
+ export interface RenderResult {
12
+ Content: import('astro/runtime/server/index.js').AstroComponentFactory
13
+ }
14
+ }
15
+
16
+ type ContentConfig = typeof import('./content.config.js')
17
+
18
+ type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T
19
+
20
+ export type StarlightRouteEntryData = import('astro/zod').infer<
21
+ ReturnTypeOrOriginal<Required<ContentConfig['collections']['docs']>['schema']>
22
+ >
package/src/index.ts CHANGED
@@ -22,6 +22,8 @@ const components = {
22
22
  Hero: 'starlight-theme-nova/components/Hero.astro',
23
23
  MobileTableOfContents:
24
24
  'starlight-theme-nova/components/MobileTableOfContents.astro',
25
+ MobileMenuFooter: 'starlight-theme-nova/components/MobileMenuFooter.astro',
26
+ LanguageSelect: 'starlight-theme-nova/components/LanguageSelect.astro',
25
27
  } as const
26
28
 
27
29
  export type { ThemeNovaOptions }
package/src/types.d.ts CHANGED
@@ -1,11 +1,2 @@
1
1
  import 'astro/client'
2
2
  import '@astrojs/starlight'
3
-
4
- // This is a workaround to avoid type checking errors.
5
- declare module 'astro:content' {
6
- export interface RenderResult {
7
- Content: {
8
- isAstroComponentFactory?: boolean
9
- }
10
- }
11
- }
@@ -1,3 +1,12 @@
1
+ // Copied from https://github.com/withastro/starlight/blob/9d3ba179c5d524c1c61d771ceb1a7b4e754bee16/packages/starlight/virtual-internal.d.ts#L25
2
+ declare module 'virtual:starlight/pagefind-config' {
3
+ import type { StarlightConfig } from '@astrojs/starlight/types'
4
+
5
+ export const pagefindUserConfig: Partial<
6
+ Extract<StarlightConfig['pagefind'], object>
7
+ >
8
+ }
9
+
1
10
  declare module 'virtual:starlight-theme-nova/user-config' {
2
11
  const config: import('./user-options').ConfigSerialized
3
12
  export default config
@@ -18,3 +27,11 @@ declare module 'virtual:starlight/components/ThemeSelect' {
18
27
  const ThemeSelect: typeof import('./components/ThemeSelect.astro').default
19
28
  export default ThemeSelect
20
29
  }
30
+ declare module 'virtual:starlight/components/LanguageSelect' {
31
+ const LanguageSelect: typeof import('./components/LanguageSelect.astro').default
32
+ export default LanguageSelect
33
+ }
34
+ declare module 'virtual:starlight/components/MobileMenuFooter' {
35
+ const MobileMenuFooter: typeof import('./components/MobileMenuFooter.astro').default
36
+ export default MobileMenuFooter
37
+ }