mirror of
				https://github.com/imfing/hextra.git
				synced 2025-11-04 01:24:54 -05:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			sidebar-da
			...
			2fc1b93a72
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2fc1b93a72 | ||
| 
						 | 
					da56d153aa | ||
| 
						 | 
					5c0698c3c0 | ||
| 
						 | 
					ebdaf0fd4a | 
@@ -860,6 +860,9 @@ video {
 | 
			
		||||
.hx-justify-center {
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
}
 | 
			
		||||
.hx-justify-between {
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
}
 | 
			
		||||
.hx-justify-items-start {
 | 
			
		||||
  justify-items: start;
 | 
			
		||||
}
 | 
			
		||||
@@ -1025,6 +1028,10 @@ video {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(255 247 237 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hx-bg-primary-100 {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44) / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hx-bg-primary-400 {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16) / var(--tw-bg-opacity));
 | 
			
		||||
@@ -1304,6 +1311,10 @@ video {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(154 52 18 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hx-text-primary-800 {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32) / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hx-text-red-900 {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(127 29 29 / var(--tw-text-opacity));
 | 
			
		||||
@@ -2472,7 +2483,7 @@ article details > summary::before {
 | 
			
		||||
  color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45) / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
@media (max-width: 767px) {
 | 
			
		||||
  .hextra-sidebar-container {
 | 
			
		||||
  .sidebar-container {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    top: 0px;
 | 
			
		||||
    bottom: 0px;
 | 
			
		||||
@@ -2483,152 +2494,28 @@ article details > summary::before {
 | 
			
		||||
    background-color: rgb(255 255 255 / var(--tw-bg-opacity));
 | 
			
		||||
    padding-top: calc(var(--navbar-height));
 | 
			
		||||
  }
 | 
			
		||||
  .hextra-sidebar-container:is(html[class~="dark"] *) {
 | 
			
		||||
  .sidebar-container:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-bg-opacity: 1;
 | 
			
		||||
    background-color: rgb(17 17 17 / var(--tw-bg-opacity));
 | 
			
		||||
  }
 | 
			
		||||
  .hextra-sidebar-container {
 | 
			
		||||
  .sidebar-container {
 | 
			
		||||
    transition: transform 0.8s cubic-bezier(0.52, 0.16, 0.04, 1);
 | 
			
		||||
    will-change: transform, opacity;
 | 
			
		||||
    contain: layout style;
 | 
			
		||||
    backface-visibility: hidden;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container li > div {
 | 
			
		||||
.sidebar-container li > div {
 | 
			
		||||
  height: 0px;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container li.open > div {
 | 
			
		||||
.sidebar-container li.open > div {
 | 
			
		||||
  height: auto;
 | 
			
		||||
  padding-top: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container li.open > a > span > svg > path {
 | 
			
		||||
.sidebar-container li.open > a > span > svg > path {
 | 
			
		||||
  --tw-rotate: 90deg;
 | 
			
		||||
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  gap: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list::before {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0.25rem;
 | 
			
		||||
  bottom: 0.25rem;
 | 
			
		||||
  width: 1px;
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(229 231 235 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list:is(html[class~="dark"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(38 38 38 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list:where([dir="ltr"], [dir="ltr"] *) {
 | 
			
		||||
  margin-left: 0.75rem;
 | 
			
		||||
  padding-left: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list:where([dir="ltr"], [dir="ltr"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  left: 0px;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list:where([dir="rtl"], [dir="rtl"] *) {
 | 
			
		||||
  margin-right: 0.75rem;
 | 
			
		||||
  padding-right: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-list:where([dir="rtl"], [dir="rtl"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  right: 0px;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  gap: 0.5rem;
 | 
			
		||||
  border-radius: 0.25rem;
 | 
			
		||||
  padding-left: 0.5rem;
 | 
			
		||||
  padding-right: 0.5rem;
 | 
			
		||||
  padding-top: 0.375rem;
 | 
			
		||||
  padding-bottom: 0.375rem;
 | 
			
		||||
  font-size: .875rem;
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link.active {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44) / var(--tw-bg-opacity));
 | 
			
		||||
  font-weight: 600;
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32) / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
@media (prefers-contrast: more) {
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-container .hextra-sidebar-item-link.active {
 | 
			
		||||
    border-width: 1px;
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 50) / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link.active:is(html[class~="dark"] *) {
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16) / 0.1);
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45) / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
@media (prefers-contrast: more) {
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-container .hextra-sidebar-item-link.active:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 50) / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link.inactive {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(107 114 128 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link.inactive:hover {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(243 244 246 / var(--tw-bg-opacity));
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(17 24 39 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
@media (prefers-contrast: more) {
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-container .hextra-sidebar-item-link.inactive {
 | 
			
		||||
    border-width: 1px;
 | 
			
		||||
    border-color: transparent;
 | 
			
		||||
    --tw-text-opacity: 1;
 | 
			
		||||
    color: rgb(17 24 39 / var(--tw-text-opacity));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-container .hextra-sidebar-item-link.inactive:hover {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: rgb(17 24 39 / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link.inactive:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(163 163 163 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.hextra-sidebar-container .hextra-sidebar-item-link.inactive:hover:is(html[class~="dark"] *) {
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44) / 0.05);
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(249 250 251 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
@media (prefers-contrast: more) {
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-container .hextra-sidebar-item-link.inactive:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-text-opacity: 1;
 | 
			
		||||
    color: rgb(249 250 251 / var(--tw-text-opacity));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-container .hextra-sidebar-item-link.inactive:hover:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: rgb(249 250 251 / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
nav .search-wrapper {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
@@ -2802,6 +2689,11 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  inset: 0px;
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-inset-y-1::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  top: 0.25rem;
 | 
			
		||||
  bottom: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-mr-1::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  margin-right: 0.25rem;
 | 
			
		||||
@@ -2810,16 +2702,37 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-w-px::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  width: 1px;
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-bg-gray-200::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(229 231 235 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-opacity-25::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  opacity: 0.25;
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-transition-transform::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  transition-property: transform;
 | 
			
		||||
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
 | 
			
		||||
  transition-duration: 150ms;
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-content-\[\'\#\'\]::before {
 | 
			
		||||
  --tw-content: '#';
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-content-\[\'\'\]::before {
 | 
			
		||||
  --tw-content: '';
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
}
 | 
			
		||||
.before\:hx-content-\[\\\"\\\"\]::before {
 | 
			
		||||
  --tw-content: \"\";
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
}
 | 
			
		||||
.first\:hx-mt-0:first-child {
 | 
			
		||||
  margin-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
@@ -2998,6 +2911,15 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
    border-color: rgb(163 163 163 / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:hx-border-primary-500 {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 50) / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:hx-border-transparent {
 | 
			
		||||
    border-color: transparent;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:hx-font-bold {
 | 
			
		||||
    font-weight: 700;
 | 
			
		||||
  }
 | 
			
		||||
@@ -3036,6 +2958,11 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-shadow-colored: 0 0 #0000;
 | 
			
		||||
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:hover\:hx-border-gray-900:hover {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: rgb(17 24 39 / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-block:is(html[class~="dark"] *) {
 | 
			
		||||
  display: block;
 | 
			
		||||
@@ -3121,6 +3048,9 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
.dark\:hx-bg-primary-300\/10:is(html[class~="dark"] *) {
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 27) / 0.1);
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-bg-primary-400\/10:is(html[class~="dark"] *) {
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16) / 0.1);
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-bg-primary-600:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45) / var(--tw-bg-opacity));
 | 
			
		||||
@@ -3179,10 +3109,18 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(229 229 229 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-text-neutral-400:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(163 163 163 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-text-orange-300:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(253 186 116 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-text-primary-600:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45) / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.dark\:hx-text-red-200:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(254 202 202 / var(--tw-text-opacity));
 | 
			
		||||
@@ -3224,6 +3162,11 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(156 163 175 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
.dark\:before\:hx-bg-neutral-800:is(html[class~="dark"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(38 38 38 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
.dark\:before\:hx-invert:is(html[class~="dark"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  --tw-invert: invert(100%);
 | 
			
		||||
@@ -3315,14 +3258,6 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
  --tw-ring-opacity: 1;
 | 
			
		||||
  --tw-ring-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32) / var(--tw-ring-opacity));
 | 
			
		||||
}
 | 
			
		||||
.data-\[state\=selected\]\:dark\:hx-border-primary-500:is(html[class~="dark"] *)[data-state="selected"] {
 | 
			
		||||
  --tw-border-opacity: 1;
 | 
			
		||||
  border-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 50) / var(--tw-border-opacity));
 | 
			
		||||
}
 | 
			
		||||
.data-\[state\=selected\]\:dark\:hx-text-primary-600:is(html[class~="dark"] *)[data-state="selected"] {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45) / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
@media (prefers-contrast: more) {
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:dark\:hx-border-current:is(html[class~="dark"] *) {
 | 
			
		||||
@@ -3339,6 +3274,11 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
    border-color: rgb(163 163 163 / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:dark\:hx-border-primary-500:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 50) / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dark\:contrast-more\:hx-border-neutral-400:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: rgb(163 163 163 / var(--tw-border-opacity));
 | 
			
		||||
@@ -3374,6 +3314,11 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-shadow-colored: 0 0 #0000;
 | 
			
		||||
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .contrast-more\:dark\:hover\:hx-border-gray-50:hover:is(html[class~="dark"] *) {
 | 
			
		||||
    --tw-border-opacity: 1;
 | 
			
		||||
    border-color: rgb(249 250 251 / var(--tw-border-opacity));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@media not all and (min-width: 1280px) {
 | 
			
		||||
 | 
			
		||||
@@ -3521,6 +3466,9 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
.ltr\:hx-ml-1:where([dir="ltr"], [dir="ltr"] *) {
 | 
			
		||||
  margin-left: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
.ltr\:hx-ml-3:where([dir="ltr"], [dir="ltr"] *) {
 | 
			
		||||
  margin-left: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
.ltr\:hx-ml-auto:where([dir="ltr"], [dir="ltr"] *) {
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
}
 | 
			
		||||
@@ -3570,6 +3518,10 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
.ltr\:hx-text-right:where([dir="ltr"], [dir="ltr"] *) {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
}
 | 
			
		||||
.ltr\:before\:hx-left-0:where([dir="ltr"], [dir="ltr"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  left: 0px;
 | 
			
		||||
}
 | 
			
		||||
@media (min-width: 768px) {
 | 
			
		||||
 | 
			
		||||
  .ltr\:md\:hx-left-auto:where([dir="ltr"], [dir="ltr"] *) {
 | 
			
		||||
@@ -3591,6 +3543,9 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
.rtl\:hx-mr-1:where([dir="rtl"], [dir="rtl"] *) {
 | 
			
		||||
  margin-right: 0.25rem;
 | 
			
		||||
}
 | 
			
		||||
.rtl\:hx-mr-3:where([dir="rtl"], [dir="rtl"] *) {
 | 
			
		||||
  margin-right: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
.rtl\:hx-mr-auto:where([dir="rtl"], [dir="rtl"] *) {
 | 
			
		||||
  margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
@@ -3634,6 +3589,10 @@ body:is(html[class~="dark"] *) {
 | 
			
		||||
.rtl\:hx-text-left:where([dir="rtl"], [dir="rtl"] *) {
 | 
			
		||||
  text-align: left;
 | 
			
		||||
}
 | 
			
		||||
.rtl\:before\:hx-right-0:where([dir="rtl"], [dir="rtl"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  right: 0px;
 | 
			
		||||
}
 | 
			
		||||
.rtl\:before\:hx-rotate-180:where([dir="rtl"], [dir="rtl"] *)::before {
 | 
			
		||||
  content: var(--tw-content);
 | 
			
		||||
  --tw-rotate: 180deg;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
@media (max-width: 767px) {
 | 
			
		||||
  .hextra-sidebar-container {
 | 
			
		||||
  .sidebar-container {
 | 
			
		||||
    @apply hx-fixed hx-pt-[calc(var(--navbar-height))] hx-top-0 hx-w-full hx-bottom-0 hx-z-[15] hx-overscroll-contain hx-bg-white dark:hx-bg-dark;
 | 
			
		||||
    transition: transform 0.8s cubic-bezier(0.52, 0.16, 0.04, 1);
 | 
			
		||||
    will-change: transform, opacity;
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hextra-sidebar-container {
 | 
			
		||||
.sidebar-container {
 | 
			
		||||
  li > div {
 | 
			
		||||
    @apply hx-h-0;
 | 
			
		||||
  }
 | 
			
		||||
@@ -18,19 +18,4 @@
 | 
			
		||||
  li.open > a > span > svg > path {
 | 
			
		||||
    @apply hx-rotate-90;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-item-list {
 | 
			
		||||
    @apply hx-relative hx-flex hx-flex-col hx-gap-1 before:hx-absolute before:hx-inset-y-1 before:hx-w-px before:hx-bg-gray-200 ltr:hx-ml-3 ltr:hx-pl-3 ltr:before:hx-left-0 rtl:hx-mr-3 rtl:hx-pr-3 rtl:before:hx-right-0 dark:before:hx-bg-neutral-800;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .hextra-sidebar-item-link {
 | 
			
		||||
    @apply hx-flex hx-items-center hx-justify-between hx-gap-2 hx-cursor-pointer hx-rounded hx-px-2 hx-py-1.5 hx-text-sm hx-transition-colors;
 | 
			
		||||
 | 
			
		||||
    &.active {
 | 
			
		||||
      @apply hx-bg-primary-100 hx-font-semibold hx-text-primary-800 contrast-more:hx-border contrast-more:hx-border-primary-500 dark:hx-bg-primary-400/10 dark:hx-text-primary-600 contrast-more:dark:hx-border-primary-500;
 | 
			
		||||
    }
 | 
			
		||||
    &.inactive {
 | 
			
		||||
      @apply hx-text-gray-500 hover:hx-bg-gray-100 hover:hx-text-gray-900 contrast-more:hx-border contrast-more:hx-border-transparent contrast-more:hx-text-gray-900 contrast-more:hover:hx-border-gray-900 dark:hx-text-neutral-400 dark:hover:hx-bg-primary-100/5 dark:hover:hx-text-gray-50 contrast-more:dark:hx-text-gray-50 contrast-more:dark:hover:hx-border-gray-50;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
document.addEventListener('DOMContentLoaded', function () {
 | 
			
		||||
  const menu = document.querySelector('.hamburger-menu');
 | 
			
		||||
  const overlay = document.querySelector('.mobile-menu-overlay');
 | 
			
		||||
  const sidebarContainer = document.querySelector('.hextra-sidebar-container');
 | 
			
		||||
  const sidebarContainer = document.querySelector('.sidebar-container');
 | 
			
		||||
 | 
			
		||||
  // Initialize the overlay
 | 
			
		||||
  const overlayClasses = ['hx-fixed', 'hx-inset-0', 'hx-z-10', 'hx-bg-black/80', 'dark:hx-bg-black/60'];
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,3 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Check if the element is visible.
 | 
			
		||||
 * @param {Element} element Dom element
 | 
			
		||||
 * @returns boolean
 | 
			
		||||
 */
 | 
			
		||||
function isVisible(element) {
 | 
			
		||||
  return element.offsetWidth > 0 || element.offsetHeight > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.addEventListener("DOMContentLoaded", function () {
 | 
			
		||||
  scrollToActiveItem();
 | 
			
		||||
  enableCollapsibles();
 | 
			
		||||
@@ -19,43 +10,10 @@ function enableCollapsibles() {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      const list = button.parentElement.parentElement;
 | 
			
		||||
      if (list) {
 | 
			
		||||
        list.classList.toggle("open");
 | 
			
		||||
        list.classList.toggle("open")
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const isCached = "{{- site.Params.page.sidebar.cache | default false -}}" === "true";
 | 
			
		||||
  const currentPagePath = window.location.href;
 | 
			
		||||
 | 
			
		||||
  if (isCached) {
 | 
			
		||||
    // find the current page in the sidebar and open the parent lists
 | 
			
		||||
    const sidebar = document.querySelector(".hextra-sidebar-container");
 | 
			
		||||
    if (sidebar) {
 | 
			
		||||
      // find a tags and compare href with current page path
 | 
			
		||||
      const links = sidebar.querySelectorAll("a");
 | 
			
		||||
      links.forEach(function (link) {
 | 
			
		||||
        const linkPath = link.href;
 | 
			
		||||
 | 
			
		||||
        if (currentPagePath === linkPath) {
 | 
			
		||||
          // add active class to the link
 | 
			
		||||
          link.classList.add("active");
 | 
			
		||||
          link.classList.remove("inactive");
 | 
			
		||||
 | 
			
		||||
          if (!isVisible(link)) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          // recursively open parent lists
 | 
			
		||||
          let parent = link.parentElement;
 | 
			
		||||
          while (parent && !parent.classList.contains("hextra-sidebar-container")) {
 | 
			
		||||
            if (parent.tagName === "LI" && parent.classList.contains("hextra-sidebar-item")) {
 | 
			
		||||
              parent.classList.add("open");
 | 
			
		||||
            }
 | 
			
		||||
            parent = parent.parentElement;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function scrollToActiveItem() {
 | 
			
		||||
@@ -73,6 +31,6 @@ function scrollToActiveItem() {
 | 
			
		||||
  const yDistance = visibleActiveItem.getBoundingClientRect().top - sidebarScrollbar.getBoundingClientRect().top;
 | 
			
		||||
  sidebarScrollbar.scrollTo({
 | 
			
		||||
    behavior: "instant",
 | 
			
		||||
    top: yDistance - yOffset,
 | 
			
		||||
    top: yDistance - yOffset
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,128 +44,6 @@ The primary color of the theme can be customized by setting the `--primary-hue`,
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Further Theme Customization
 | 
			
		||||
 | 
			
		||||
The theme can be further customized by overriding the default styles via the exposed css classes. An example for customizing the footer element:
 | 
			
		||||
 | 
			
		||||
```css {filename="assets/css/custom.css"}
 | 
			
		||||
.hextra-footer {
 | 
			
		||||
  /* Styles will be applied to the footer element */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hextra-footer:is(html[class~="dark"] *) {
 | 
			
		||||
  /* Styles will be applied to the footer element in dark mode */
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The following classes can be used to customize various parts of the theme.
 | 
			
		||||
 | 
			
		||||
#### General
 | 
			
		||||
 | 
			
		||||
- `hextra-scrollbar` - The scrollbar element
 | 
			
		||||
- `content` - Page content container
 | 
			
		||||
 | 
			
		||||
#### Shortcodes
 | 
			
		||||
 | 
			
		||||
##### Badge
 | 
			
		||||
 | 
			
		||||
- `hextra-badge` - The badge element
 | 
			
		||||
 | 
			
		||||
##### Card
 | 
			
		||||
 | 
			
		||||
- `hextra-card` - The card element
 | 
			
		||||
- `hextra-card-image` - The card image element
 | 
			
		||||
- `hextra-card-icon` - The card icon element
 | 
			
		||||
- `hextra-card-subtitle` - The card subtitle element
 | 
			
		||||
 | 
			
		||||
##### Cards
 | 
			
		||||
 | 
			
		||||
- `hextra-cards` - The cards grid container
 | 
			
		||||
 | 
			
		||||
##### Jupyter Notebook
 | 
			
		||||
 | 
			
		||||
- `hextra-jupyter-code-cell` - The Jupyter code cell container
 | 
			
		||||
- `hextra-jupyter-code-cell-outputs-container` - The Jupyter code cell outputs container
 | 
			
		||||
- `hextra-jupyter-code-cell-outputs` - The Jupyter code cell output div element
 | 
			
		||||
 | 
			
		||||
##### PDF
 | 
			
		||||
 | 
			
		||||
- `hextra-pdf` - The PDF container element
 | 
			
		||||
 | 
			
		||||
##### Steps
 | 
			
		||||
 | 
			
		||||
- `steps` - The steps container
 | 
			
		||||
 | 
			
		||||
##### Tabs
 | 
			
		||||
 | 
			
		||||
- `hextra-tabs-panel` - The tabs panel container
 | 
			
		||||
- `hextra-tabs-toggle` - The tabs toggle button
 | 
			
		||||
 | 
			
		||||
##### Filetree
 | 
			
		||||
 | 
			
		||||
- `hextra-filetree` - The filetree container
 | 
			
		||||
 | 
			
		||||
##### Folder
 | 
			
		||||
 | 
			
		||||
- `hextra-filetree-folder` - The filetree folder container
 | 
			
		||||
 | 
			
		||||
#### Navbar
 | 
			
		||||
 | 
			
		||||
- `nav-container` - The navbar container
 | 
			
		||||
- `nav-container-blur` - The navbar container in blur element
 | 
			
		||||
- `hamburger-menu` - The hamburger menu button
 | 
			
		||||
 | 
			
		||||
#### Footer
 | 
			
		||||
 | 
			
		||||
- `hextra-footer` - The footer element
 | 
			
		||||
- `hextra-custom-footer` - The custom footer section container
 | 
			
		||||
 | 
			
		||||
#### Search
 | 
			
		||||
 | 
			
		||||
- `search-wrapper` - The search wrapper container
 | 
			
		||||
- `search-input` - The search input element
 | 
			
		||||
- `search-results` - The search results list container
 | 
			
		||||
 | 
			
		||||
#### Table of Contents
 | 
			
		||||
 | 
			
		||||
- `hextra-toc` - The table of contents container
 | 
			
		||||
 | 
			
		||||
#### Sidebar
 | 
			
		||||
 | 
			
		||||
- `mobile-menu-overlay` - The overlay element for the mobile menu
 | 
			
		||||
- `sidebar-container` - The sidebar container
 | 
			
		||||
- `sidebar-active-item` - The active item in the sidebar
 | 
			
		||||
 | 
			
		||||
#### Language Switcher
 | 
			
		||||
 | 
			
		||||
- `language-switcher` - The language switcher button
 | 
			
		||||
- `language-options` - The language options container
 | 
			
		||||
 | 
			
		||||
#### Theme Toggle
 | 
			
		||||
 | 
			
		||||
- `theme-toggle` - The theme toggle button
 | 
			
		||||
 | 
			
		||||
#### Cody Copy Button
 | 
			
		||||
 | 
			
		||||
- `hextra-code-copy-btn-container` - The code copy button container
 | 
			
		||||
- `hextra-code-copy-btn` - The code copy button
 | 
			
		||||
 | 
			
		||||
#### Code Block
 | 
			
		||||
 | 
			
		||||
- `hextra-code-block` - The code block container
 | 
			
		||||
 | 
			
		||||
#### Feature Card
 | 
			
		||||
 | 
			
		||||
- `hextra-feature-card` - The feature card link element
 | 
			
		||||
 | 
			
		||||
#### Feature Grid
 | 
			
		||||
 | 
			
		||||
- `hextra-feature-grid` - The feature grid container
 | 
			
		||||
 | 
			
		||||
#### Breadcrumbs
 | 
			
		||||
 | 
			
		||||
No specific class is available for breadcrumbs.
 | 
			
		||||
 | 
			
		||||
### Syntax Highlighting
 | 
			
		||||
 | 
			
		||||
List of available syntax highlighting themes are available at [Chroma Styles Gallery](https://xyproto.github.io/splash/docs/all.html). The stylesheet can be generated using the command:
 | 
			
		||||
@@ -184,28 +62,13 @@ You may add custom scripts to the end of the head for every page by adding the f
 | 
			
		||||
layouts/partials/custom/head-end.html
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Custom Extra Section in Footer
 | 
			
		||||
 | 
			
		||||
You can add extra section in the footer by creating a file `layouts/partials/custom/footer.html` in your site.
 | 
			
		||||
 | 
			
		||||
```html {filename="layouts/partials/custom/footer.html"}
 | 
			
		||||
<!-- Your footer element here -->
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The added section will be added before the copyright section in the footer.
 | 
			
		||||
You can use [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) and [Hugo template syntax](https://gohugo.io/templates/) to add your own content.
 | 
			
		||||
 | 
			
		||||
Hugo variables available in the footer section are: `.switchesVisible` and `.copyrightVisible`.
 | 
			
		||||
 | 
			
		||||
## Custom Layouts
 | 
			
		||||
 | 
			
		||||
The layouts of the theme can be overridden by creating a file with the same name in the `layouts` directory of your site.
 | 
			
		||||
For example, to override the `single.html` layout for docs, create a file `layouts/docs/single.html` in your site.
 | 
			
		||||
 | 
			
		||||
For further information, refer to the [Hugo Templates][hugo-template-docs].
 | 
			
		||||
For further information, refer to the [Hugo Templates](https://gohugo.io/templates/).
 | 
			
		||||
 | 
			
		||||
## Further Customization
 | 
			
		||||
 | 
			
		||||
Didn't find what you were looking for? Feel free to [open a discussion](https://github.com/imfing/hextra/discussions) or make a contribution to the theme!
 | 
			
		||||
 | 
			
		||||
[hugo-template-docs]: https://gohugo.io/templates/
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ params:
 | 
			
		||||
 | 
			
		||||
### Main Sidebar
 | 
			
		||||
 | 
			
		||||
By default, the main sidebar is automatically generated from the structure of the content directory.
 | 
			
		||||
For the main sidebar, it is automatically generated from the structure of the content directory.
 | 
			
		||||
See the [Organize Files](/docs/guide/organize-files) page for more details.
 | 
			
		||||
 | 
			
		||||
To exclude a single page from the left sidebar, set the `sidebar.exclude` parameter in the front matter of the page:
 | 
			
		||||
@@ -119,33 +119,6 @@ menu:
 | 
			
		||||
      weight: 3
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Sidebar from Data
 | 
			
		||||
 | 
			
		||||
Alternatively, you can define the sidebar structure in the `data` directory. This gives you more flexibility to define sidebar differently than your content structure. To enable this, set the `params.sidebar.source` parameter in the config file to `data`:
 | 
			
		||||
 | 
			
		||||
```yaml {filename="hugo.yaml"}
 | 
			
		||||
params:
 | 
			
		||||
  sidebar:
 | 
			
		||||
    source: data
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To define the sidebar data, create a file named `sidebar.yaml` in the `data` directory.
 | 
			
		||||
 | 
			
		||||
```yaml {filename="data/sidebar.yaml"}
 | 
			
		||||
docs:
 | 
			
		||||
  - title: Documentation
 | 
			
		||||
    link: /docs/
 | 
			
		||||
  - title: Guide
 | 
			
		||||
    link: /docs/guide/
 | 
			
		||||
    open: false
 | 
			
		||||
    items:
 | 
			
		||||
      - title: Configuration
 | 
			
		||||
        link: /docs/guide/configuration/
 | 
			
		||||
  # ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If your site is multilingual, you can define the sidebar data for each language, for example in `data/en/sidebar.yaml` file.
 | 
			
		||||
 | 
			
		||||
## Right Sidebar
 | 
			
		||||
 | 
			
		||||
### Table of Contents
 | 
			
		||||
 
 | 
			
		||||
@@ -37,8 +37,6 @@ Blockquote with attribution
 | 
			
		||||
 | 
			
		||||
### Alerts
 | 
			
		||||
 | 
			
		||||
{{< new-feature version="v0.9.0" >}}
 | 
			
		||||
 | 
			
		||||
Alerts are a Markdown extension based on the blockquote syntax that you can use to emphasize critical information.
 | 
			
		||||
[GitHub-style alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) are supported.
 | 
			
		||||
Please make sure you are using the latest version of Hextra and [Hugo v0.134.0](https://github.com/gohugoio/hugo/releases/tag/v0.134.0) or later.
 | 
			
		||||
 
 | 
			
		||||
@@ -10,10 +10,6 @@ A built-in component to show important information to the reader.
 | 
			
		||||
 | 
			
		||||
<!--more-->
 | 
			
		||||
 | 
			
		||||
> [!NOTE]
 | 
			
		||||
> [GitHub-style alerts](../../markdown#alerts) are supported since [v0.9.0](https://github.com/imfing/hextra/releases/tag/v0.9.0).
 | 
			
		||||
> It leverages Markdown syntax to render the callout which ensures better portability and readability of the content.
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
{{< callout emoji="👾">}}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,15 +34,16 @@ Result:
 | 
			
		||||
{{< badge content="warning" type="warning" >}}  
 | 
			
		||||
{{< badge content="error" type="error" >}}
 | 
			
		||||
 | 
			
		||||
With link and icon:
 | 
			
		||||
With link:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
{{</* badge content="Releases" link="https://github.com/imfing/hextra/releases" icon="github" */>}}
 | 
			
		||||
{{</* badge content="Releases" link="https://github.com/imfing/hextra/releases" */>}}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Result:
 | 
			
		||||
 | 
			
		||||
{{< badge content="Releases" link="https://github.com/imfing/hextra/releases" icon="github" >}}
 | 
			
		||||
{{< badge content="Releases" link="https://github.com/imfing/hextra/releases" >}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## YouTube
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,24 +40,6 @@ def say_hello():
 | 
			
		||||
    print("Hello!")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Link to File
 | 
			
		||||
 | 
			
		||||
{{< new-feature version="v0.9.2" >}}
 | 
			
		||||
 | 
			
		||||
You can use the `base_url` attribute to provide a base URL that will be combined with the file name to generate a link.
 | 
			
		||||
 | 
			
		||||
The file name can include a relative path if it specifies the file's location within the base path.
 | 
			
		||||
 | 
			
		||||
````markdown {filename="Markdown"}
 | 
			
		||||
```go {base_url="https://github.com/imfing/hextra/blob/main/",filename="exampleSite/hugo.work"}
 | 
			
		||||
go 1.20
 | 
			
		||||
```
 | 
			
		||||
````
 | 
			
		||||
 | 
			
		||||
```go {base_url="https://github.com/imfing/hextra/blob/main/",filename="exampleSite/hugo.work"}
 | 
			
		||||
go 1.20
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Line Numbers
 | 
			
		||||
 | 
			
		||||
To set line numbers, set attribute `linenos` to `table` and optionally set `linenostart` to the starting line number:
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@ Open source projects powered by Hextra
 | 
			
		||||
  >}}
 | 
			
		||||
 | 
			
		||||
  {{< card
 | 
			
		||||
        link="https://github.com/remysheppard/lutheran-confessions"
 | 
			
		||||
        link="https://lutheranconfessions.org/"
 | 
			
		||||
        title="LutheranConfessions"
 | 
			
		||||
        image="https://github.com/imfing/hextra/assets/5097752/ad6625e4-88cd-4cad-b102-5399997d0359"
 | 
			
		||||
        imageStyle="object-fit:cover; aspect-ratio:16/9;"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
docs:
 | 
			
		||||
  - title: Documentation
 | 
			
		||||
    link: /docs/
 | 
			
		||||
  - title: Getting Started
 | 
			
		||||
    link: /docs/getting-started/
 | 
			
		||||
  - title: Guide
 | 
			
		||||
    link: /docs/guide/
 | 
			
		||||
    open: false
 | 
			
		||||
    items:
 | 
			
		||||
      - title: Organize Files
 | 
			
		||||
        link: /docs/guide/organize-files/
 | 
			
		||||
      - title: Configuration
 | 
			
		||||
        link: /docs/guide/configuration/
 | 
			
		||||
      - title: Markdown
 | 
			
		||||
        link: /docs/guide/markdown/
 | 
			
		||||
      - title: Syntax Highlighting
 | 
			
		||||
        link: /docs/guide/syntax-highlighting/
 | 
			
		||||
      - title: LaTeX
 | 
			
		||||
        link: /docs/guide/latex/
 | 
			
		||||
      - title: Diagrams
 | 
			
		||||
        link: /docs/guide/diagrams/
 | 
			
		||||
      - title: Shortcodes
 | 
			
		||||
        link: /docs/guide/shortcodes/
 | 
			
		||||
        items:
 | 
			
		||||
          - title: Callout
 | 
			
		||||
            link: /docs/guide/shortcodes/callout/
 | 
			
		||||
          - title: Cards
 | 
			
		||||
            link: /docs/guide/shortcodes/cards/
 | 
			
		||||
          - title: Details
 | 
			
		||||
            link: /docs/guide/shortcodes/details/
 | 
			
		||||
          - title: FileTree
 | 
			
		||||
            link: /docs/guide/shortcodes/filetree/
 | 
			
		||||
          - title: Icon
 | 
			
		||||
            link: /docs/guide/shortcodes/icon/
 | 
			
		||||
          - title: Steps
 | 
			
		||||
            link: /docs/guide/shortcodes/steps/
 | 
			
		||||
          - title: Tabs
 | 
			
		||||
            link: /docs/guide/shortcodes/tabs/
 | 
			
		||||
      - title: Deploy Site
 | 
			
		||||
        link: /docs/guide/deploy-site/
 | 
			
		||||
  - title: Advanced
 | 
			
		||||
    link: /docs/advanced/
 | 
			
		||||
    items:
 | 
			
		||||
      - title: Multi-language
 | 
			
		||||
        link: /docs/advanced/multi-language/
 | 
			
		||||
      - title: Comments
 | 
			
		||||
        link: /docs/advanced/comments/
 | 
			
		||||
      - title: Customization
 | 
			
		||||
        link: /docs/advanced/customization/
 | 
			
		||||
@@ -113,10 +113,6 @@ params:
 | 
			
		||||
    # full (100%), wide (90rem), normal (1280px)
 | 
			
		||||
    width: normal
 | 
			
		||||
 | 
			
		||||
    # TODO: move one level up
 | 
			
		||||
    sidebar:
 | 
			
		||||
      source: data
 | 
			
		||||
 | 
			
		||||
  theme:
 | 
			
		||||
    # light | dark | system
 | 
			
		||||
    default: system
 | 
			
		||||
@@ -177,4 +173,3 @@ params:
 | 
			
		||||
      # emitMetadata: 0
 | 
			
		||||
      # inputPosition: top
 | 
			
		||||
      # lang: en
 | 
			
		||||
      # theme: noborder_dark
 | 
			
		||||
 
 | 
			
		||||
@@ -69,36 +69,46 @@
 | 
			
		||||
      "[hyphens:auto]",
 | 
			
		||||
      "[transition:background-color_1.5s_ease]",
 | 
			
		||||
      "[word-break:break-word]",
 | 
			
		||||
      "active",
 | 
			
		||||
      "active:hx-bg-gray-400/20",
 | 
			
		||||
      "active:hx-opacity-50",
 | 
			
		||||
      "active:hx-shadow-gray-200",
 | 
			
		||||
      "active:hx-shadow-sm",
 | 
			
		||||
      "before:hx-absolute",
 | 
			
		||||
      "before:hx-bg-glass-gradient",
 | 
			
		||||
      "before:hx-bg-gray-200",
 | 
			
		||||
      "before:hx-content-[\"\"]",
 | 
			
		||||
      "before:hx-content-['#']",
 | 
			
		||||
      "before:hx-content-['']",
 | 
			
		||||
      "before:hx-inline-block",
 | 
			
		||||
      "before:hx-inset-0",
 | 
			
		||||
      "before:hx-inset-y-1",
 | 
			
		||||
      "before:hx-mr-1",
 | 
			
		||||
      "before:hx-opacity-25",
 | 
			
		||||
      "before:hx-pointer-events-none",
 | 
			
		||||
      "before:hx-transition-transform",
 | 
			
		||||
      "before:hx-w-px",
 | 
			
		||||
      "chroma",
 | 
			
		||||
      "content",
 | 
			
		||||
      "contrast-more:dark:hover:hx-border-gray-50",
 | 
			
		||||
      "contrast-more:dark:hx-border-current",
 | 
			
		||||
      "contrast-more:dark:hx-border-gray-50",
 | 
			
		||||
      "contrast-more:dark:hx-border-neutral-400",
 | 
			
		||||
      "contrast-more:dark:hx-border-primary-500",
 | 
			
		||||
      "contrast-more:dark:hx-shadow-[0_0_0_1px_#fff]",
 | 
			
		||||
      "contrast-more:dark:hx-shadow-none",
 | 
			
		||||
      "contrast-more:dark:hx-text-current",
 | 
			
		||||
      "contrast-more:dark:hx-text-gray-100",
 | 
			
		||||
      "contrast-more:dark:hx-text-gray-300",
 | 
			
		||||
      "contrast-more:dark:hx-text-gray-50",
 | 
			
		||||
      "contrast-more:hover:hx-border-gray-900",
 | 
			
		||||
      "contrast-more:hx-border",
 | 
			
		||||
      "contrast-more:hx-border-current",
 | 
			
		||||
      "contrast-more:hx-border-gray-800",
 | 
			
		||||
      "contrast-more:hx-border-gray-900",
 | 
			
		||||
      "contrast-more:hx-border-neutral-400",
 | 
			
		||||
      "contrast-more:hx-border-primary-500",
 | 
			
		||||
      "contrast-more:hx-border-t",
 | 
			
		||||
      "contrast-more:hx-border-transparent",
 | 
			
		||||
      "contrast-more:hx-font-bold",
 | 
			
		||||
      "contrast-more:hx-shadow-[0_0_0_1px_#000]",
 | 
			
		||||
      "contrast-more:hx-shadow-none",
 | 
			
		||||
@@ -108,6 +118,7 @@
 | 
			
		||||
      "contrast-more:hx-text-gray-900",
 | 
			
		||||
      "contrast-more:hx-underline",
 | 
			
		||||
      "copy-icon",
 | 
			
		||||
      "dark:before:hx-bg-neutral-800",
 | 
			
		||||
      "dark:before:hx-invert",
 | 
			
		||||
      "dark:contrast-more:hx-border-neutral-400",
 | 
			
		||||
      "dark:focus:hx-bg-dark",
 | 
			
		||||
@@ -142,6 +153,7 @@
 | 
			
		||||
      "dark:hx-bg-neutral-900",
 | 
			
		||||
      "dark:hx-bg-orange-400/20",
 | 
			
		||||
      "dark:hx-bg-primary-300/10",
 | 
			
		||||
      "dark:hx-bg-primary-400/10",
 | 
			
		||||
      "dark:hx-bg-primary-600",
 | 
			
		||||
      "dark:hx-bg-red-900/30",
 | 
			
		||||
      "dark:hx-bg-yellow-700/30",
 | 
			
		||||
@@ -175,7 +187,9 @@
 | 
			
		||||
      "dark:hx-text-green-200",
 | 
			
		||||
      "dark:hx-text-indigo-200",
 | 
			
		||||
      "dark:hx-text-neutral-200",
 | 
			
		||||
      "dark:hx-text-neutral-400",
 | 
			
		||||
      "dark:hx-text-orange-300",
 | 
			
		||||
      "dark:hx-text-primary-600",
 | 
			
		||||
      "dark:hx-text-red-200",
 | 
			
		||||
      "dark:hx-text-slate-100",
 | 
			
		||||
      "dark:hx-text-yellow-200",
 | 
			
		||||
@@ -183,8 +197,6 @@
 | 
			
		||||
      "dark:placeholder:hx-text-gray-400",
 | 
			
		||||
      "data-[state=closed]:hx-hidden",
 | 
			
		||||
      "data-[state=open]:hx-hidden",
 | 
			
		||||
      "data-[state=selected]:dark:hx-border-primary-500",
 | 
			
		||||
      "data-[state=selected]:dark:hx-text-primary-600",
 | 
			
		||||
      "data-[state=selected]:hx-block",
 | 
			
		||||
      "data-[state=selected]:hx-border-primary-500",
 | 
			
		||||
      "data-[state=selected]:hx-text-primary-600",
 | 
			
		||||
@@ -216,7 +228,6 @@
 | 
			
		||||
      "hextra-code-block",
 | 
			
		||||
      "hextra-code-copy-btn",
 | 
			
		||||
      "hextra-code-copy-btn-container",
 | 
			
		||||
      "hextra-custom-footer",
 | 
			
		||||
      "hextra-feature-card",
 | 
			
		||||
      "hextra-feature-grid",
 | 
			
		||||
      "hextra-filetree",
 | 
			
		||||
@@ -228,10 +239,6 @@
 | 
			
		||||
      "hextra-pdf",
 | 
			
		||||
      "hextra-scrollbar",
 | 
			
		||||
      "hextra-sidebar-collapsible-button",
 | 
			
		||||
      "hextra-sidebar-container",
 | 
			
		||||
      "hextra-sidebar-item",
 | 
			
		||||
      "hextra-sidebar-item-link",
 | 
			
		||||
      "hextra-sidebar-item-list",
 | 
			
		||||
      "hextra-tabs-panel",
 | 
			
		||||
      "hextra-tabs-toggle",
 | 
			
		||||
      "hextra-toc",
 | 
			
		||||
@@ -273,6 +280,7 @@
 | 
			
		||||
      "hx-bg-indigo-100",
 | 
			
		||||
      "hx-bg-neutral-50",
 | 
			
		||||
      "hx-bg-orange-50",
 | 
			
		||||
      "hx-bg-primary-100",
 | 
			
		||||
      "hx-bg-primary-400",
 | 
			
		||||
      "hx-bg-primary-600",
 | 
			
		||||
      "hx-bg-primary-700/5",
 | 
			
		||||
@@ -344,6 +352,7 @@
 | 
			
		||||
      "hx-inset-y-0",
 | 
			
		||||
      "hx-items-center",
 | 
			
		||||
      "hx-items-start",
 | 
			
		||||
      "hx-justify-between",
 | 
			
		||||
      "hx-justify-center",
 | 
			
		||||
      "hx-justify-end",
 | 
			
		||||
      "hx-justify-items-start",
 | 
			
		||||
@@ -492,6 +501,7 @@
 | 
			
		||||
      "hx-text-left",
 | 
			
		||||
      "hx-text-lg",
 | 
			
		||||
      "hx-text-orange-800",
 | 
			
		||||
      "hx-text-primary-800",
 | 
			
		||||
      "hx-text-red-900",
 | 
			
		||||
      "hx-text-slate-900",
 | 
			
		||||
      "hx-text-sm",
 | 
			
		||||
@@ -529,15 +539,16 @@
 | 
			
		||||
      "hx-z-20",
 | 
			
		||||
      "hx-z-[-1]",
 | 
			
		||||
      "icon",
 | 
			
		||||
      "inactive",
 | 
			
		||||
      "language-options",
 | 
			
		||||
      "language-switcher",
 | 
			
		||||
      "last-of-type:hx-mb-0",
 | 
			
		||||
      "lntable",
 | 
			
		||||
      "lntd",
 | 
			
		||||
      "ltr:before:hx-left-0",
 | 
			
		||||
      "ltr:hx--mr-4",
 | 
			
		||||
      "ltr:hx-border-l",
 | 
			
		||||
      "ltr:hx-ml-1",
 | 
			
		||||
      "ltr:hx-ml-3",
 | 
			
		||||
      "ltr:hx-ml-auto",
 | 
			
		||||
      "ltr:hx-mr-auto",
 | 
			
		||||
      "ltr:hx-pl-12",
 | 
			
		||||
@@ -589,6 +600,7 @@
 | 
			
		||||
      "print:hx-bg-transparent",
 | 
			
		||||
      "print:hx-hidden",
 | 
			
		||||
      "rtl:-hx-rotate-180",
 | 
			
		||||
      "rtl:before:hx-right-0",
 | 
			
		||||
      "rtl:before:hx-rotate-180",
 | 
			
		||||
      "rtl:hx--ml-4",
 | 
			
		||||
      "rtl:hx-border-r",
 | 
			
		||||
@@ -596,6 +608,7 @@
 | 
			
		||||
      "rtl:hx-left-3",
 | 
			
		||||
      "rtl:hx-ml-auto",
 | 
			
		||||
      "rtl:hx-mr-1",
 | 
			
		||||
      "rtl:hx-mr-3",
 | 
			
		||||
      "rtl:hx-mr-auto",
 | 
			
		||||
      "rtl:hx-pl-2",
 | 
			
		||||
      "rtl:hx-pl-4",
 | 
			
		||||
@@ -612,6 +625,8 @@
 | 
			
		||||
      "search-input",
 | 
			
		||||
      "search-results",
 | 
			
		||||
      "search-wrapper",
 | 
			
		||||
      "sidebar-active-item",
 | 
			
		||||
      "sidebar-container",
 | 
			
		||||
      "sm:hx-block",
 | 
			
		||||
      "sm:hx-flex",
 | 
			
		||||
      "sm:hx-items-start",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
{{- $version := .Get "version" | default "" -}}
 | 
			
		||||
{{- $icon := .Get "icon" | default "" -}}
 | 
			
		||||
{{- $defaultLink := cond (eq $version "") "https://github.com/imfing/hextra/tree/main" (printf "https://github.com/imfing/hextra/releases/tag/%s" $version) -}}
 | 
			
		||||
{{- $link := .Get "link" | default $defaultLink -}}
 | 
			
		||||
{{- $content := cond (eq $version "") "New in main branch" (printf "New in %s" $version) -}}
 | 
			
		||||
 | 
			
		||||
<div style="margin-top: 1rem; display: inline-flex;">
 | 
			
		||||
  <a href="{{ $link }}" title="{{ $link | plainify }}" target="_blank">
 | 
			
		||||
    {{- partial "shortcodes/badge" (dict "content" $content "border" true "icon" $icon) -}}
 | 
			
		||||
  </a>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,13 +1,12 @@
 | 
			
		||||
{{- $class := .Attributes.class | default "" -}}
 | 
			
		||||
{{- $filename := .Attributes.filename | default "" -}}
 | 
			
		||||
{{- $base_url := .Attributes.base_url | default "" -}}
 | 
			
		||||
{{- $lang := .Attributes.lang | default .Type -}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div class="hextra-code-block hx-relative hx-mt-6 first:hx-mt-0 hx-group/code">
 | 
			
		||||
  {{- partial "components/codeblock" (dict "filename" $filename "lang" $lang "base_url" $base_url "content" .Inner "options" .Options) -}}
 | 
			
		||||
  {{ partial "components/codeblock" (dict "filename" $filename "lang" $lang "content" .Inner "options" .Options) }}
 | 
			
		||||
 | 
			
		||||
  {{- if or (eq site.Params.highlight.copy.enable nil) (site.Params.highlight.copy.enable) -}}
 | 
			
		||||
    {{- partialCached "components/codeblock-copy-button" (dict "filename" $filename) $filename -}}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
  {{- if or (eq site.Params.highlight.copy.enable nil) (site.Params.highlight.copy.enable) }}
 | 
			
		||||
    {{- partialCached "components/codeblock-copy-button" (dict "filename" $filename) $filename }}
 | 
			
		||||
  {{ end }}
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
{{ define "main" }}
 | 
			
		||||
  <div class='hx-mx-auto hx-flex {{ partial "utils/page-width" . }}'>
 | 
			
		||||
    {{- if not (in (slice "taxonomy" "term") .Kind) -}}
 | 
			
		||||
      {{- partial "sidebar.html" (dict "context" .) -}}
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
    {{ partial "sidebar.html" (dict "context" .) }}
 | 
			
		||||
    {{ partial "toc.html" . }}
 | 
			
		||||
    <article class="hx-w-full hx-break-words hx-flex hx-min-h-[calc(100vh-var(--navbar-height))] hx-min-w-0 hx-justify-center hx-pb-8 hx-pr-[calc(env(safe-area-inset-right)-1.5rem)]">
 | 
			
		||||
      <main class="hx-w-full hx-min-w-0 hx-max-w-6xl hx-px-6 hx-pt-4 md:hx-px-12">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,11 @@
 | 
			
		||||
{{ $filename := .filename | default "" -}}
 | 
			
		||||
{{ $base_url := .base_url | default "" -}}
 | 
			
		||||
{{ $lang := .lang | default "" }}
 | 
			
		||||
{{ $content := .content }}
 | 
			
		||||
{{ $options := .options | default (dict) }}
 | 
			
		||||
 | 
			
		||||
{{- if $filename -}}
 | 
			
		||||
  <div class="filename not-prose" dir="auto">
 | 
			
		||||
    {{- if $base_url -}}
 | 
			
		||||
 | 
			
		||||
      {{- $base_url = strings.TrimSuffix "/" $base_url -}}
 | 
			
		||||
      {{- $filename = strings.TrimPrefix "/" $filename -}}
 | 
			
		||||
      {{- $file_url := urls.JoinPath $base_url $filename -}}
 | 
			
		||||
 | 
			
		||||
      <a class="hx-no-underline hx-inline-flex hx-items-center hx-gap-1" href="{{ $file_url }}" target="_blank" rel="noopener noreferrer">
 | 
			
		||||
          <span>{{- $filename -}}</span>
 | 
			
		||||
          {{- partial "utils/icon" (dict "name" "external-link" "attributes" "height=1em") -}}
 | 
			
		||||
      </a>
 | 
			
		||||
    {{- else -}}
 | 
			
		||||
      {{- $filename -}}
 | 
			
		||||
  <div class="filename" dir="auto">{{ $filename }}</div>
 | 
			
		||||
{{- end -}}
 | 
			
		||||
  </div>
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- if transform.CanHighlight $lang -}}
 | 
			
		||||
  <div>{{- highlight $content $lang $options -}}</div>
 | 
			
		||||
{{- else -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,17 +8,8 @@
 | 
			
		||||
   * This solution was created with reference to:
 | 
			
		||||
   * https://github.com/giscus/giscus/issues/336#issuecomment-1214366281
 | 
			
		||||
  */
 | 
			
		||||
  function getHugoTheme() {
 | 
			
		||||
    return localStorage.getItem("color-theme");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  function getGiscusTheme() {
 | 
			
		||||
    let giscusTheme = "{{ (string .theme) | default `light` }}";
 | 
			
		||||
    if(getHugoTheme() == 'light') {
 | 
			
		||||
      return giscusTheme.replace('dark', 'light');
 | 
			
		||||
    } else {
 | 
			
		||||
      return giscusTheme.replace('light', 'dark');
 | 
			
		||||
    }
 | 
			
		||||
    return localStorage.getItem("color-theme");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function setGiscusTheme() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
{{- range site.Menus.sidebar }}
 | 
			
		||||
  {{- $name := or (T .Identifier) .Name }}
 | 
			
		||||
  {{- if eq .Params.type "separator" }}
 | 
			
		||||
    <li class="[word-break:break-word] hx-mt-5 hx-mb-2 hx-px-2 hx-py-1.5 hx-text-sm hx-font-semibold hx-text-gray-900 first:hx-mt-0 dark:hx-text-gray-100">
 | 
			
		||||
      <span class="hx-cursor-default">{{ $name }}</span>
 | 
			
		||||
    </li>
 | 
			
		||||
  {{- else }}
 | 
			
		||||
    <li>
 | 
			
		||||
      {{- partial "components/sidebar/item-link" (dict "active" false "title" $name "link" (.URL | relLangURL)) -}}
 | 
			
		||||
    </li>
 | 
			
		||||
  {{- end }}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
<span class="hextra-sidebar-collapsible-button">
 | 
			
		||||
  <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx-h-[18px] hx-min-w-[18px] hx-rounded-sm hx-p-0.5 hover:hx-bg-gray-800/5 dark:hover:hx-bg-gray-100/5">
 | 
			
		||||
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx-origin-center hx-transition-transform rtl:-hx-rotate-180"></path>
 | 
			
		||||
  </svg>
 | 
			
		||||
</span>
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
{{/* Generate mobile navigation data based on main menu */}}
 | 
			
		||||
 | 
			
		||||
{{- $context := . -}}
 | 
			
		||||
 | 
			
		||||
{{- $data := slice -}}
 | 
			
		||||
 | 
			
		||||
{{- range .Site.Menus.main -}}
 | 
			
		||||
  {{- if not (eq .Params.type "search") -}}
 | 
			
		||||
    {{- $title := or (T .Identifier) .Name -}}
 | 
			
		||||
    {{- $link := .URL -}}
 | 
			
		||||
    {{- $external := strings.HasPrefix $link "http" -}}
 | 
			
		||||
    {{- with .PageRef -}}
 | 
			
		||||
      {{- if hasPrefix . "/" -}}
 | 
			
		||||
        {{- $link = relLangURL (strings.TrimPrefix "/" .) -}}
 | 
			
		||||
      {{- end -}}
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
 | 
			
		||||
    {{- with .Page -}}
 | 
			
		||||
      {{- $page := . -}}
 | 
			
		||||
 | 
			
		||||
      {{- if and $page.IsSection (eq $page.Type "docs") -}}
 | 
			
		||||
        {{- $page = (partial "utils/translated-page" (dict "page" $page "lang" site.Language.LanguageCode)) -}}
 | 
			
		||||
        {{- $sectionData := (partial "components/sidebar/generate-section-data" $page) | unmarshal -}}
 | 
			
		||||
        {{- $data = $data | append (dict "title" $title "link" $link "items" $sectionData) -}}
 | 
			
		||||
      {{- else -}}
 | 
			
		||||
        {{- $data = $data | append (dict "title" $title "link" $link) -}}
 | 
			
		||||
      {{- end -}}
 | 
			
		||||
    {{- else -}}
 | 
			
		||||
      {{/* TODO: handle other cases like external links */}}
 | 
			
		||||
      {{- $data = $data | append (dict "title" $title "link" $link) -}}
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- return ($data | jsonify (dict "noHTMLEscape" true)) -}}
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
{{- $context := . -}}
 | 
			
		||||
 | 
			
		||||
{{- $pages := union .RegularPages .Sections -}}
 | 
			
		||||
{{- $pages = where $pages "Params.sidebar.exclude" "!=" true -}}
 | 
			
		||||
 | 
			
		||||
{{- $data := slice -}}
 | 
			
		||||
 | 
			
		||||
{{- range $pages.ByWeight -}}
 | 
			
		||||
  {{ $structure := (partial "sidebar/section-walk" .) | unmarshal -}}
 | 
			
		||||
  {{ $data = $data | append $structure -}}
 | 
			
		||||
{{ end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "partials/sidebar/section-walk" -}}
 | 
			
		||||
  {{- with . -}}
 | 
			
		||||
  {
 | 
			
		||||
    "title": "{{ partial "utils/title" . }}",
 | 
			
		||||
    "link": "{{ .RelPermalink }}",
 | 
			
		||||
    "toc": {{ partial "sidebar/section-page-toc" . }},
 | 
			
		||||
    "open": {{ .Params.sidebar.open | default false }}
 | 
			
		||||
    {{- if .IsSection }},
 | 
			
		||||
    "items": [
 | 
			
		||||
      {{ $pages := union .RegularPages .Sections -}}
 | 
			
		||||
      {{ $pages = where $pages "Params.sidebar.exclude" "!=" true -}}
 | 
			
		||||
      {{ range $index, $page := $pages.ByWeight -}}
 | 
			
		||||
        {{ partial "sidebar/section-walk" . }}{{ if not (ge $index (sub (len $pages) 1)) }},{{ end -}}
 | 
			
		||||
      {{ end -}}
 | 
			
		||||
    ]
 | 
			
		||||
    {{ end -}}
 | 
			
		||||
  }
 | 
			
		||||
  {{- end }}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "partials/sidebar/section-page-toc" -}}
 | 
			
		||||
  {{/* Get level 2 headings list used mainly for mobile navigation */}}
 | 
			
		||||
  [
 | 
			
		||||
    {{- with .Fragments.Headings -}}
 | 
			
		||||
      {{/* Loop over level 1 headings */}}
 | 
			
		||||
      {{- range . }}
 | 
			
		||||
        {{- with .Headings }}
 | 
			
		||||
          {{ $headings := . }}
 | 
			
		||||
          {{- range $index, $heading := $headings }}
 | 
			
		||||
            {{ $heading.Title | jsonify (dict "noHTMLEscape" true) }}
 | 
			
		||||
            {{- if not (ge $index (sub (len $headings) 1)) }},{{ end -}}
 | 
			
		||||
          {{ end -}}
 | 
			
		||||
        {{- end -}}
 | 
			
		||||
      {{ end -}}
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  ]
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{ return ($data | jsonify (dict "noHTMLEscape" true)) }}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
{{/* Get section sidebar config from Hugo `data` directory
 | 
			
		||||
 | 
			
		||||
  If the site is multilingual, the sidebar data is stored in a language-specific
 | 
			
		||||
  directory. For example, the English sidebar data is stored in `data/en/sidebar.yaml`.
 | 
			
		||||
*/}}
 | 
			
		||||
{{ $data := "" }}
 | 
			
		||||
{{ $section := .Section | default "index" }}
 | 
			
		||||
{{ $filename := "sidebar" }}
 | 
			
		||||
 | 
			
		||||
{{ if hugo.IsMultilingual }}
 | 
			
		||||
  {{ with (index site.Data site.Language.Lang $filename $section) }}
 | 
			
		||||
    {{ $data = . }}
 | 
			
		||||
  {{ end }}
 | 
			
		||||
{{ else }}
 | 
			
		||||
  {{ with (index site.Data $filename $section) }}
 | 
			
		||||
    {{ $data = . }}
 | 
			
		||||
  {{ end }}
 | 
			
		||||
{{ end }}
 | 
			
		||||
 | 
			
		||||
{{ return $data }}
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
{{- $external := strings.HasPrefix .link "http" -}}
 | 
			
		||||
 | 
			
		||||
{{- $activeClass := cond (.active) "active" "inactive" -}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<a
 | 
			
		||||
  class="hextra-sidebar-item-link {{ $activeClass }} [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]"
 | 
			
		||||
  href="{{ .link }}"
 | 
			
		||||
  {{ if $external }}target="_blank" rel="noreferer"{{ end }}
 | 
			
		||||
>
 | 
			
		||||
  {{- .title -}}
 | 
			
		||||
  {{- with .context }}
 | 
			
		||||
    {{- if or .RegularPages .Sections }}
 | 
			
		||||
      {{- partialCached "components/sidebar/collapsible-button" . }}
 | 
			
		||||
    {{- end }}
 | 
			
		||||
  {{ end -}}
 | 
			
		||||
  {{- with .items }}{{- partialCached "components/sidebar/collapsible-button" site.Home }}{{ end -}}
 | 
			
		||||
</a>
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
{{- $page := .page -}}
 | 
			
		||||
{{- $pageLink :=  $page.RelPermalink -}}
 | 
			
		||||
{{- $cached := .cached | default false }}
 | 
			
		||||
 | 
			
		||||
{{- range .data -}}
 | 
			
		||||
  {{- $active := and (not $cached) (or (eq $pageLink .link) (eq (strings.TrimSuffix "/" $pageLink) .link)) -}}
 | 
			
		||||
  {{- $containsPage := hasPrefix $pageLink .link -}}
 | 
			
		||||
  {{- $shouldOpen := or (.open) $containsPage $active | default false -}}
 | 
			
		||||
 | 
			
		||||
  <li class="hextra-sidebar-item {{ if $shouldOpen }}open{{ end }}">
 | 
			
		||||
    {{- partial "components/sidebar/item-link" (dict "active" $active "title" .title "link" .link "items" .items) -}}
 | 
			
		||||
    {{- if .items -}}
 | 
			
		||||
      {{- partial "components/sidebar/render-items" (dict "items" .items "link" $pageLink "cached" $cached) -}}
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  </li>
 | 
			
		||||
{{ end }}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
{{- $items := .items -}}
 | 
			
		||||
{{- $pageLink := .link -}}
 | 
			
		||||
{{- $cached := .cached | default false }}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div class="ltr:hx-pr-0 hx-overflow-hidden">
 | 
			
		||||
  <ul class="hextra-sidebar-item-list">
 | 
			
		||||
    {{- range $items }}
 | 
			
		||||
      {{- $active := and (not $cached) (or (eq $pageLink .link) (eq (strings.TrimSuffix "/" $pageLink) .link)) -}}
 | 
			
		||||
      {{- $containsPage := hasPrefix $pageLink .link -}}
 | 
			
		||||
      {{- $shouldOpen := or (.open) $containsPage $active | default false -}}
 | 
			
		||||
 | 
			
		||||
      <li class="hextra-sidebar-item hx-flex hx-flex-col {{ if $shouldOpen }}open{{ end }}">
 | 
			
		||||
        {{- partial "components/sidebar/item-link" (dict "active" $active "title" .title "link" .link "items" .items) -}}
 | 
			
		||||
        {{- if .items -}}
 | 
			
		||||
          {{- partial "components/sidebar/render-items" (dict "items" .items "link" $pageLink "cached" $cached) -}}
 | 
			
		||||
        {{- end -}}
 | 
			
		||||
      </li>
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  </ul>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
{{- $enableFooterSwitches := .Scratch.Get "enableFooterSwitches" | default false -}}
 | 
			
		||||
{{- $displayThemeToggle := site.Params.theme.displayToggle | default true -}}
 | 
			
		||||
{{- $footerSwitchesVisible := and $enableFooterSwitches (or hugo.IsMultilingual $displayThemeToggle) -}}
 | 
			
		||||
{{- $copyrightSectionVisible := or (.Site.Params.footer.displayPoweredBy | default true) .Site.Params.footer.displayCopyright -}}
 | 
			
		||||
 | 
			
		||||
{{- $copyright := (T "copyright") | default "© 2024 Hextra." -}}
 | 
			
		||||
{{- $poweredBy := (T "poweredBy") | default "Powered by Hextra" -}}
 | 
			
		||||
@@ -17,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<footer class="hextra-footer hx-bg-gray-100 hx-pb-[env(safe-area-inset-bottom)] dark:hx-bg-neutral-900 print:hx-bg-transparent">
 | 
			
		||||
  {{- if $footerSwitchesVisible -}}
 | 
			
		||||
  {{- if and $enableFooterSwitches (or hugo.IsMultilingual $displayThemeToggle) -}}
 | 
			
		||||
    <div class="hx-mx-auto hx-flex hx-gap-2 hx-py-2 hx-px-4 {{ $footerWidth }}">
 | 
			
		||||
      {{- partial "language-switch.html" (dict "context" .) -}}
 | 
			
		||||
      {{- with $displayThemeToggle }}{{ partial "theme-toggle.html" }}{{ end -}}
 | 
			
		||||
@@ -26,21 +24,14 @@
 | 
			
		||||
      <hr class="dark:hx-border-neutral-800" />
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
    <div
 | 
			
		||||
      class="hextra-custom-footer {{ $footerWidth }} hx-pl-[max(env(safe-area-inset-left),1.5rem)] hx-pr-[max(env(safe-area-inset-right),1.5rem)] hx-text-gray-600 dark:hx-text-gray-400"
 | 
			
		||||
    >
 | 
			
		||||
      {{- partial "custom/footer.html" (dict "context" . "switchesVisible" $footerSwitchesVisible "copyrightVisible" $copyrightSectionVisible) -}}
 | 
			
		||||
    </div>
 | 
			
		||||
    {{- if $copyrightSectionVisible -}}
 | 
			
		||||
  <div
 | 
			
		||||
    class="{{ $footerWidth }} hx-mx-auto hx-flex hx-justify-center hx-py-12 hx-pl-[max(env(safe-area-inset-left),1.5rem)] hx-pr-[max(env(safe-area-inset-right),1.5rem)] hx-text-gray-600 dark:hx-text-gray-400 md:hx-justify-start"
 | 
			
		||||
  >
 | 
			
		||||
    <div class="hx-flex hx-w-full hx-flex-col hx-items-center sm:hx-items-start">
 | 
			
		||||
            {{- if (.Site.Params.footer.displayPoweredBy | default true) }}<div class="hx-font-semibold">{{ template "theme-credit" $poweredBy }}</div>{{- end -}}
 | 
			
		||||
            {{- if .Site.Params.footer.displayCopyright }}<div class="hx-mt-6 hx-text-xs">{{ $copyright | markdownify }}</div>{{- end -}}
 | 
			
		||||
      {{- if (.Site.Params.footer.displayPoweredBy | default true) }}<div class="hx-font-semibold">{{ template "theme-credit" $poweredBy }}</div>{{ end }}
 | 
			
		||||
      {{- if .Site.Params.footer.displayCopyright }}<div class="hx-mt-6 hx-text-xs">{{ $copyright | markdownify }}</div>{{ end }}
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
</footer>
 | 
			
		||||
 | 
			
		||||
{{- define "theme-credit" -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,8 @@
 | 
			
		||||
    {{- range .Site.Menus.main -}}
 | 
			
		||||
      {{- if eq .Params.type "search" -}}
 | 
			
		||||
        {{- partial "search.html" (dict "params" .Params) -}}
 | 
			
		||||
      {{- else if eq .Params.type "theme-toggle" -}}
 | 
			
		||||
        {{- partial "theme-toggle.html" (dict "navbar" true "hideLabel" (.Params.hideLabel | default true)) -}}
 | 
			
		||||
      {{- else -}}
 | 
			
		||||
        {{- $link := .URL -}}
 | 
			
		||||
        {{- $external := strings.HasPrefix $link "http" -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
{{- $jsLang := resources.Get "js/lang.js" -}}
 | 
			
		||||
{{- $jsCodeCopy := resources.Get "js/code-copy.js" -}}
 | 
			
		||||
{{- $jsFileTree := resources.Get "js/filetree.js" -}}
 | 
			
		||||
{{- $jsSidebar := resources.Get "js/sidebar.js" | resources.ExecuteAsTemplate "sidebar.js" . -}}
 | 
			
		||||
{{- $jsSidebar := resources.Get "js/sidebar.js" -}}
 | 
			
		||||
{{- $jsBackToTop := resources.Get "js/back-to-top.js" -}}
 | 
			
		||||
 | 
			
		||||
{{- $scripts := slice $jsTheme $jsMenu $jsCodeCopy $jsTabs $jsLang $jsFileTree $jsSidebar $jsBackToTop | resources.Concat "js/main.js" -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
{{- $type := .type -}}
 | 
			
		||||
{{- $class := .class | default "" -}}
 | 
			
		||||
{{- $border := .border | default false -}}
 | 
			
		||||
{{- $icon := .icon | default "" -}}
 | 
			
		||||
 | 
			
		||||
{{- $defaultClass := "hx-text-gray-600 hx-bg-gray-100 dark:hx-bg-neutral-800 dark:hx-text-neutral-200 hx-border-gray-200 dark:hx-border-neutral-700" -}}
 | 
			
		||||
{{- $warningClass := "hx-border-yellow-100 hx-bg-yellow-50 hx-text-yellow-900 dark:hx-border-yellow-200/30 dark:hx-bg-yellow-700/30 dark:hx-text-yellow-200" -}}
 | 
			
		||||
@@ -12,9 +11,6 @@
 | 
			
		||||
{{- $borderClass := cond (eq $border true) "hx-border" "" -}}
 | 
			
		||||
{{- $badgeClass := cond (eq $type "info") $infoClass (cond (eq $type "warning") $warningClass (cond (eq $type "error") $errorClass $defaultClass)) -}}
 | 
			
		||||
<div class="hextra-badge {{ $class }}">
 | 
			
		||||
  <div class="hx-inline-flex hx-gap-1 hx-items-center hx-rounded-full hx-px-2.5 hx-leading-6 hx-text-[.65rem] {{ $borderClass }} {{ $badgeClass }}">
 | 
			
		||||
    {{- with $icon -}}{{- partial "utils/icon" (dict "name" . "attributes" "height=12") -}}{{- end -}}
 | 
			
		||||
    {{- $content -}}
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="hx-inline-flex hx-items-center hx-rounded-full hx-px-2.5 hx-leading-6 hx-text-[.65rem] {{ $borderClass }} {{ $badgeClass }}">{{- $content -}}</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{- /* Strip trailing newline. */ -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,83 +3,48 @@
 | 
			
		||||
{{- $disableSidebar := .disableSidebar | default false -}}
 | 
			
		||||
{{- $displayPlaceholder := .displayPlaceholder | default false -}}
 | 
			
		||||
 | 
			
		||||
{{/* EXPERIMENTAL - allow hiding sidebar on a per-page basis */}}
 | 
			
		||||
{{- if $context.Params.sidebar.hide -}}
 | 
			
		||||
  {{- $disableSidebar = true -}}
 | 
			
		||||
  {{- $displayPlaceholder = true -}}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- $sidebarClass := cond $disableSidebar (cond $displayPlaceholder "md:hx-hidden xl:hx-block" "md:hx-hidden") "md:hx-sticky" -}}
 | 
			
		||||
 | 
			
		||||
{{- $navRoot := cond (eq site.Home.Type "docs") site.Home $context.FirstSection -}}
 | 
			
		||||
{{- $pageURL := $context.RelPermalink -}}
 | 
			
		||||
 | 
			
		||||
{{- $data := slice -}}
 | 
			
		||||
{{- $dataMobile := (partialCached "components/sidebar/generate-mobile-data" site.Home site.Home) | unmarshal -}}
 | 
			
		||||
 | 
			
		||||
{{- if (eq site.Params.page.sidebar.source "data") -}}
 | 
			
		||||
  {{/* Get sidebar data from Hugo `data` directory */}}
 | 
			
		||||
  {{- $data = partialCached "components/sidebar/get-section-data" $context $context.Section -}}
 | 
			
		||||
{{- else -}}
 | 
			
		||||
  {{/* Generate and cache sidebar data in memory */}}
 | 
			
		||||
  {{- $data = (partialCached "components/sidebar/generate-section-data" $navRoot $navRoot) | unmarshal -}}
 | 
			
		||||
{{/* EXPERIMENTAL */}}
 | 
			
		||||
{{- if .context.Params.sidebar.hide -}}
 | 
			
		||||
  {{- $disableSidebar = true -}}
 | 
			
		||||
  {{- $displayPlaceholder = true -}}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{/* Cache rendered sidebar */}}
 | 
			
		||||
{{- $shouldCache := site.Params.page.sidebar.cache | default false -}}
 | 
			
		||||
 | 
			
		||||
<div class="mobile-menu-overlay [transition:background-color_1.5s_ease] hx-fixed hx-inset-0 hx-z-10 hx-bg-black/80 dark:hx-bg-black/60 hx-hidden"></div>
 | 
			
		||||
 | 
			
		||||
<aside class="hextra-sidebar-container hx-flex hx-flex-col print:hx-hidden md:hx-top-16 md:hx-shrink-0 md:hx-w-64 md:hx-self-start max-md:[transform:translate3d(0,-100%,0)] {{ $sidebarClass }}">
 | 
			
		||||
  {{/* Search bar on small screen */}}
 | 
			
		||||
  {{- partialCached "components/sidebar/mobile-search" . -}}
 | 
			
		||||
<aside class="sidebar-container hx-flex hx-flex-col print:hx-hidden md:hx-top-16 md:hx-shrink-0 md:hx-w-64 md:hx-self-start max-md:[transform:translate3d(0,-100%,0)] {{ $sidebarClass }}">
 | 
			
		||||
  <!-- Search bar on small screen -->
 | 
			
		||||
  <div class="hx-px-4 hx-pt-4 md:hx-hidden">
 | 
			
		||||
    {{ partial "search.html" }}
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="hextra-scrollbar hx-overflow-y-auto hx-overflow-x-hidden hx-p-4 hx-grow md:hx-h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
 | 
			
		||||
    {{/* Mobile Navigation */}}
 | 
			
		||||
    <ul class="hx-flex hx-flex-col hx-gap-1 md:hx-hidden">
 | 
			
		||||
      {{- with $dataMobile -}}{{- partial "components/sidebar/render-data" (dict "data" . "page" $context) -}}{{- end -}}
 | 
			
		||||
      <!-- Nav -->
 | 
			
		||||
      {{ template "sidebar-main" (dict "context" site.Home "pageURL" $pageURL "page" $context "toc" true) -}}
 | 
			
		||||
      {{ template "sidebar-footer" }}
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    {{/* Sidebar on large screen */}}
 | 
			
		||||
    <!-- Sidebar on large screen -->
 | 
			
		||||
    {{- if $disableSidebar -}}
 | 
			
		||||
      {{- if $displayPlaceholder }}<div class="max-xl:hx-hidden hx-h-0 hx-w-64 hx-shrink-0"></div>{{ end -}}
 | 
			
		||||
      {{ .context.Scratch.Set "enableFooterSwitches" true }}
 | 
			
		||||
    {{- else -}}
 | 
			
		||||
      <ul class="hx-flex hx-flex-col hx-gap-1 max-md:hx-hidden">
 | 
			
		||||
        {{- with $data -}}
 | 
			
		||||
          {{- if $shouldCache -}}
 | 
			
		||||
            {{- partialCached "components/sidebar/render-data" (dict "data" . "page" $context "cached" $shouldCache) $navRoot -}}
 | 
			
		||||
          {{- else -}}
 | 
			
		||||
            {{- partial "components/sidebar/render-data" (dict "data" . "page" $context "cached" $shouldCache) -}}
 | 
			
		||||
          {{- end -}}
 | 
			
		||||
        {{- end -}}
 | 
			
		||||
        {{- partialCached "components/sidebar/bottom" $context site.Home -}}
 | 
			
		||||
        {{ template "sidebar-main" (dict "context" $navRoot "page" $context  "pageURL" $pageURL) }}
 | 
			
		||||
        {{ template "sidebar-footer" }}
 | 
			
		||||
      </ul>
 | 
			
		||||
    {{ end -}}
 | 
			
		||||
  <div style="position: absolute; top: 10px; right: 0; font-size: 10px; color: #888;">new</div>
 | 
			
		||||
  </div>
 | 
			
		||||
  {{- partial "components/sidebar/switches" (dict "context" $context "disableSidebar" $disableSidebar) -}}
 | 
			
		||||
</aside>
 | 
			
		||||
 | 
			
		||||
{{- define "partials/components/sidebar/mobile-search" -}}
 | 
			
		||||
  <div class="hx-px-4 hx-pt-4 md:hx-hidden">
 | 
			
		||||
    {{- partialCached "search.html" . -}}
 | 
			
		||||
  </div>
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "partials/components/sidebar/switches" -}}
 | 
			
		||||
  {{- $context := .context -}}
 | 
			
		||||
  {{- $disableSidebar := .disableSidebar -}}
 | 
			
		||||
  {{/* Hide theme switch when sidebar is disabled */}}
 | 
			
		||||
  {{ $switchesClass := cond $disableSidebar "md:hx-hidden" "" -}}
 | 
			
		||||
  {{ $displayThemeToggle := (site.Params.theme.displayToggle | default true) -}}
 | 
			
		||||
 | 
			
		||||
  {{ if or hugo.IsMultilingual $displayThemeToggle }}
 | 
			
		||||
    <div
 | 
			
		||||
      class="{{ $switchesClass }} {{ with hugo.IsMultilingual -}}
 | 
			
		||||
        hx-justify-end
 | 
			
		||||
      {{- end }} hx-sticky hx-bottom-0 hx-bg-white dark:hx-bg-dark hx-mx-4 hx-py-4 hx-shadow-[0_-12px_16px_#fff] hx-flex hx-items-center hx-gap-2 dark:hx-border-neutral-800 dark:hx-shadow-[0_-12px_16px_#111] contrast-more:hx-border-neutral-400 contrast-more:hx-shadow-none contrast-more:dark:hx-shadow-none hx-border-t"
 | 
			
		||||
      data-toggle-animation="show"
 | 
			
		||||
    >
 | 
			
		||||
    <div class="{{ $switchesClass }} {{ with hugo.IsMultilingual }}hx-justify-end{{ end }} hx-sticky hx-bottom-0 hx-bg-white dark:hx-bg-dark hx-mx-4 hx-py-4 hx-shadow-[0_-12px_16px_#fff] hx-flex hx-items-center hx-gap-2 dark:hx-border-neutral-800 dark:hx-shadow-[0_-12px_16px_#111] contrast-more:hx-border-neutral-400 contrast-more:hx-shadow-none contrast-more:dark:hx-shadow-none hx-border-t" data-toggle-animation="show">
 | 
			
		||||
      {{- with hugo.IsMultilingual -}}
 | 
			
		||||
        {{- partial "language-switch" (dict "context" $context "grow" true) -}}
 | 
			
		||||
        {{- with $displayThemeToggle }}{{ partial "theme-toggle" (dict "hideLabel" true) }}{{ end -}}
 | 
			
		||||
@@ -90,4 +55,124 @@
 | 
			
		||||
      {{- end -}}
 | 
			
		||||
    </div>
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
</aside>
 | 
			
		||||
 | 
			
		||||
{{- define "sidebar-main" -}}
 | 
			
		||||
  {{ template "sidebar-tree" (dict "context" .context "level" 0 "page" .page "pageURL" .pageURL "toc" (.toc | default false)) }}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "sidebar-tree" -}}
 | 
			
		||||
  {{- if ge .level 4 -}}
 | 
			
		||||
    {{- return -}}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
 | 
			
		||||
  {{- $context := .context -}}
 | 
			
		||||
  {{- $page := .page }}
 | 
			
		||||
  {{- $pageURL := .page.RelPermalink -}}
 | 
			
		||||
  {{- $level := .level -}}
 | 
			
		||||
  {{- $toc := .toc | default false -}}
 | 
			
		||||
 | 
			
		||||
  {{- with $items := union .context.RegularPages .context.Sections -}}
 | 
			
		||||
    {{- $items = where $items "Params.sidebar.exclude" "!=" true -}}
 | 
			
		||||
    {{- if eq $level 0 -}}
 | 
			
		||||
      {{- range $items.ByWeight }}
 | 
			
		||||
        {{- if .Params.sidebar.separator -}}
 | 
			
		||||
          <li class="[word-break:break-word] hx-mt-5 hx-mb-2 hx-px-2 hx-py-1.5 hx-text-sm hx-font-semibold hx-text-gray-900 first:hx-mt-0 dark:hx-text-gray-100">
 | 
			
		||||
            <span class="hx-cursor-default">{{ partial "utils/title" . }}</span>
 | 
			
		||||
          </li>
 | 
			
		||||
        {{- else -}}
 | 
			
		||||
          {{- $active := eq $pageURL .RelPermalink -}}
 | 
			
		||||
          {{- $shouldOpen := or (.Params.sidebar.open) (.IsAncestor $page) $active | default true }}
 | 
			
		||||
          <li class="{{ if $shouldOpen }}open{{ end }}">
 | 
			
		||||
            {{- $linkTitle := partial "utils/title" . -}}
 | 
			
		||||
            {{- template "sidebar-item-link" dict "context" . "active" $active "title" $linkTitle "link" .RelPermalink -}}
 | 
			
		||||
            {{- if and $toc $active -}}
 | 
			
		||||
              {{- template "sidebar-toc" dict "page" . -}}
 | 
			
		||||
            {{- end -}}
 | 
			
		||||
            {{- template "sidebar-tree" dict "context" . "page" $page "pageURL" $pageURL "level" (add $level 1) "toc" $toc -}}
 | 
			
		||||
          </li>
 | 
			
		||||
        {{- end -}}
 | 
			
		||||
      {{- end -}}
 | 
			
		||||
    {{- else -}}
 | 
			
		||||
      <div class="ltr:hx-pr-0 hx-overflow-hidden">
 | 
			
		||||
        <ul class='hx-relative hx-flex hx-flex-col hx-gap-1 before:hx-absolute before:hx-inset-y-1 before:hx-w-px before:hx-bg-gray-200 before:hx-content-[""] ltr:hx-ml-3 ltr:hx-pl-3 ltr:before:hx-left-0 rtl:hx-mr-3 rtl:hx-pr-3 rtl:before:hx-right-0 dark:before:hx-bg-neutral-800'>
 | 
			
		||||
          {{- range $items.ByWeight }}
 | 
			
		||||
            {{- $active := eq $pageURL .RelPermalink -}}
 | 
			
		||||
            {{- $shouldOpen := or (.Params.sidebar.open) (.IsAncestor $page) $active | default true }}
 | 
			
		||||
            {{- $linkTitle := partial "utils/title" . -}}
 | 
			
		||||
            <li class="hx-flex hx-flex-col {{ if $shouldOpen }}open{{ end }}">
 | 
			
		||||
              {{- template "sidebar-item-link" dict "context" . "active" $active "title" $linkTitle "link" .RelPermalink -}}
 | 
			
		||||
              {{- if and $toc $active -}}
 | 
			
		||||
                {{ template "sidebar-toc" dict "page" . }}
 | 
			
		||||
              {{- end }}
 | 
			
		||||
              {{ template "sidebar-tree" dict "context" . "page" $page "pageURL" $pageURL "level" (add $level 1) "toc" $toc }}
 | 
			
		||||
            </li>
 | 
			
		||||
          {{- end -}}
 | 
			
		||||
        </ul>
 | 
			
		||||
      </div>
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  {{- end }}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "sidebar-toc" -}}
 | 
			
		||||
  {{ $page := .page }}
 | 
			
		||||
  {{ with $page.Fragments.Headings }}
 | 
			
		||||
    <ul class='hx-flex hx-flex-col hx-gap-1 hx-relative before:hx-absolute before:hx-inset-y-1 before:hx-w-px before:hx-bg-gray-200 before:hx-content-[""] dark:before:hx-bg-neutral-800 ltr:hx-pl-3 ltr:before:hx-left-0 rtl:hx-pr-3 rtl:before:hx-right-0 ltr:hx-ml-3 rtl:hx-mr-3'>
 | 
			
		||||
      {{- range . }}
 | 
			
		||||
        {{- with .Headings }}
 | 
			
		||||
          {{- range . -}}
 | 
			
		||||
            <li>
 | 
			
		||||
              <a
 | 
			
		||||
                href="#{{ anchorize .ID }}"
 | 
			
		||||
                class="hx-flex hx-rounded hx-px-2 hx-py-1.5 hx-text-sm hx-transition-colors [word-break:break-word] hx-cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:hx-border hx-gap-2 before:hx-opacity-25 before:hx-content-['#'] hx-text-gray-500 hover:hx-bg-gray-100 hover:hx-text-gray-900 dark:hx-text-neutral-400 dark:hover:hx-bg-primary-100/5 dark:hover:hx-text-gray-50 contrast-more:hx-text-gray-900 contrast-more:dark:hx-text-gray-50 contrast-more:hx-border-transparent contrast-more:hover:hx-border-gray-900 contrast-more:dark:hover:hx-border-gray-50"
 | 
			
		||||
              >
 | 
			
		||||
                {{- .Title -}}
 | 
			
		||||
              </a>
 | 
			
		||||
            </li>
 | 
			
		||||
          {{ end -}}
 | 
			
		||||
        {{ end -}}
 | 
			
		||||
      {{ end -}}
 | 
			
		||||
    </ul>
 | 
			
		||||
  {{ end }}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "sidebar-footer" -}}
 | 
			
		||||
  {{- range site.Menus.sidebar -}}
 | 
			
		||||
    {{- $name := or (T .Identifier) .Name -}}
 | 
			
		||||
    {{ if eq .Params.type "separator" }}
 | 
			
		||||
      <li class="[word-break:break-word] hx-mt-5 hx-mb-2 hx-px-2 hx-py-1.5 hx-text-sm hx-font-semibold hx-text-gray-900 first:hx-mt-0 dark:hx-text-gray-100">
 | 
			
		||||
        <span class="hx-cursor-default">{{ $name }}</span>
 | 
			
		||||
      </li>
 | 
			
		||||
    {{ else }}
 | 
			
		||||
      <li>{{ template "sidebar-item-link" dict "active" false "title" $name "link" (.URL | relLangURL) }}</li>
 | 
			
		||||
    {{ end }}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "sidebar-item-link" -}}
 | 
			
		||||
  {{- $external := strings.HasPrefix .link "http" -}}
 | 
			
		||||
  {{- $open := .open | default true -}}
 | 
			
		||||
  <a
 | 
			
		||||
    class="hx-flex hx-items-center hx-justify-between hx-gap-2 hx-cursor-pointer hx-rounded hx-px-2 hx-py-1.5 hx-text-sm hx-transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
 | 
			
		||||
    {{- if .active }}
 | 
			
		||||
      sidebar-active-item hx-bg-primary-100 hx-font-semibold hx-text-primary-800 contrast-more:hx-border contrast-more:hx-border-primary-500 dark:hx-bg-primary-400/10 dark:hx-text-primary-600 contrast-more:dark:hx-border-primary-500
 | 
			
		||||
    {{- else }}
 | 
			
		||||
      hx-text-gray-500 hover:hx-bg-gray-100 hover:hx-text-gray-900 contrast-more:hx-border contrast-more:hx-border-transparent contrast-more:hx-text-gray-900 contrast-more:hover:hx-border-gray-900 dark:hx-text-neutral-400 dark:hover:hx-bg-primary-100/5 dark:hover:hx-text-gray-50 contrast-more:dark:hx-text-gray-50 contrast-more:dark:hover:hx-border-gray-50
 | 
			
		||||
    {{- end -}}"
 | 
			
		||||
    href="{{ .link }}"
 | 
			
		||||
    {{ if $external }}target="_blank" rel="noreferrer"{{ end }}
 | 
			
		||||
  >
 | 
			
		||||
    {{- .title -}}
 | 
			
		||||
    {{- with .context }}
 | 
			
		||||
      {{- if or .RegularPages .Sections }}
 | 
			
		||||
        <span class="hextra-sidebar-collapsible-button">
 | 
			
		||||
          {{- template "sidebar-collapsible-button" -}}
 | 
			
		||||
        </span>
 | 
			
		||||
      {{- end }}
 | 
			
		||||
    {{ end -}}
 | 
			
		||||
  </a>
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- define "sidebar-collapsible-button" -}}
 | 
			
		||||
  <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx-h-[18px] hx-min-w-[18px] hx-rounded-sm hx-p-0.5 hover:hx-bg-gray-800/5 dark:hover:hx-bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx-origin-center hx-transition-transform rtl:-hx-rotate-180"></path></svg>
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,10 @@
 | 
			
		||||
{{- $navbar := .navbar | default false -}}
 | 
			
		||||
{{- $height_px := 12 -}}
 | 
			
		||||
{{- $height_tw := "hx-text-xs" -}}
 | 
			
		||||
{{- if $navbar -}}
 | 
			
		||||
  {{- $height_px = 24 -}}
 | 
			
		||||
  {{- $height_tw = "hx-text-sm" -}}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
{{- $hideLabel := .hideLabel | default false -}}
 | 
			
		||||
 | 
			
		||||
{{- $changeTheme := (T "changeTheme") | default "Change theme" -}}
 | 
			
		||||
@@ -8,14 +15,14 @@
 | 
			
		||||
<button
 | 
			
		||||
  title="{{ $changeTheme }}"
 | 
			
		||||
  data-theme="light"
 | 
			
		||||
  class="theme-toggle hx-group hx-h-7 hx-rounded-md hx-px-2 hx-text-left hx-text-xs hx-font-medium hx-text-gray-600 hx-transition-colors dark:hx-text-gray-400 hover:hx-bg-gray-100 hover:hx-text-gray-900 dark:hover:hx-bg-primary-100/5 dark:hover:hx-text-gray-50"
 | 
			
		||||
  class="theme-toggle hx-group hx-h-7 hx-rounded-md hx-px-2 hx-text-left {{ $height_tw }} hx-font-medium hx-text-gray-600 hx-transition-colors dark:hx-text-gray-400 hover:hx-bg-gray-100 hover:hx-text-gray-900 dark:hover:hx-bg-primary-100/5 dark:hover:hx-text-gray-50"
 | 
			
		||||
  type="button"
 | 
			
		||||
  aria-label="{{ $changeTheme }}"
 | 
			
		||||
>
 | 
			
		||||
  <div class="hx-flex hx-items-center hx-gap-2 hx-capitalize">
 | 
			
		||||
    {{- partial "utils/icon.html" (dict "name" "sun" "attributes" "height=12 class=\"group-data-[theme=light]:hx-hidden\"") -}}
 | 
			
		||||
    {{- partial "utils/icon.html" (dict "name" "sun" "attributes" (printf "height=%d class=\"group-data-[theme=light]:hx-hidden\"" $height_px)) -}}
 | 
			
		||||
    {{- if not $hideLabel }}<span class="group-data-[theme=light]:hx-hidden">{{ $light }}</span>{{ end -}}
 | 
			
		||||
    {{- partial "utils/icon.html" (dict "name" "moon" "attributes" "height=12 class=\"group-data-[theme=dark]:hx-hidden\"") -}}
 | 
			
		||||
    {{- partial "utils/icon.html" (dict "name" "moon" "attributes" (printf "height=%d class=\"group-data-[theme=dark]:hx-hidden\"" $height_px)) -}}
 | 
			
		||||
    {{- if not $hideLabel }}<span class="group-data-[theme=dark]:hx-hidden">{{ $dark }}</span>{{ end -}}
 | 
			
		||||
  </div>
 | 
			
		||||
</button>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
{{/*
 | 
			
		||||
  Utility to retrieve a translated page given a page and a language code.
 | 
			
		||||
 | 
			
		||||
  If the page is not translated, it returns the original page.
 | 
			
		||||
*/}}
 | 
			
		||||
{{- $page := .page -}}
 | 
			
		||||
{{- $lang := .lang -}}
 | 
			
		||||
 | 
			
		||||
{{- if $page.IsTranslated -}}
 | 
			
		||||
  {{- range $page.AllTranslations -}}
 | 
			
		||||
    {{- if eq .Language.LanguageCode $lang -}}
 | 
			
		||||
      {{- $page = . -}}
 | 
			
		||||
    {{- end -}}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
{{- end -}}
 | 
			
		||||
 | 
			
		||||
{{- return $page -}}
 | 
			
		||||
@@ -3,7 +3,6 @@
 | 
			
		||||
  {{- $type := .Get "type" | default "" -}}
 | 
			
		||||
  {{- $class := .Get "class" | default "" -}}
 | 
			
		||||
  {{- $link := .Get "link" | default "" -}}
 | 
			
		||||
  {{- $icon := .Get "icon" | default "" -}}
 | 
			
		||||
 | 
			
		||||
  {{- if $link -}}
 | 
			
		||||
    <a href="{{ $link }}" title="{{ $content | plainify }}" target="_blank">
 | 
			
		||||
@@ -12,7 +11,6 @@
 | 
			
		||||
        "type" $type
 | 
			
		||||
        "class" $class
 | 
			
		||||
        "border" true
 | 
			
		||||
        "icon" $icon
 | 
			
		||||
        )
 | 
			
		||||
      -}}
 | 
			
		||||
    </a>
 | 
			
		||||
@@ -22,7 +20,6 @@
 | 
			
		||||
      "type" $type
 | 
			
		||||
      "class" $class
 | 
			
		||||
      "border" true
 | 
			
		||||
      "icon" $icon
 | 
			
		||||
      )
 | 
			
		||||
    -}}
 | 
			
		||||
  {{- end -}}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
  <div class="hx-mt-4 hx-flex hx-w-max hx-min-w-full hx-border-b hx-border-gray-200 hx-pb-px dark:hx-border-neutral-800">
 | 
			
		||||
    {{- range $i, $item := $items -}}
 | 
			
		||||
      <button
 | 
			
		||||
        class="hextra-tabs-toggle data-[state=selected]:hx-border-primary-500 data-[state=selected]:hx-text-primary-600 data-[state=selected]:dark:hx-border-primary-500 data-[state=selected]:dark:hx-text-primary-600 hx-mr-2 hx-rounded-t hx-p-2 hx-font-medium hx-leading-5 hx-transition-colors -hx-mb-0.5 hx-select-none hx-border-b-2 hx-border-transparent hx-text-gray-600 hover:hx-border-gray-200 hover:hx-text-black dark:hx-text-gray-200 dark:hover:hx-border-neutral-800 dark:hover:hx-text-white"
 | 
			
		||||
        class="hextra-tabs-toggle data-[state=selected]:hx-border-primary-500 data-[state=selected]:hx-text-primary-600 hx-mr-2 hx-rounded-t hx-p-2 hx-font-medium hx-leading-5 hx-transition-colors -hx-mb-0.5 hx-select-none hx-border-b-2 hx-border-transparent hx-text-gray-600 hover:hx-border-gray-200 hover:hx-text-black dark:hx-text-gray-200 dark:hover:hx-border-neutral-800 dark:hover:hx-text-white"
 | 
			
		||||
        role="tab"
 | 
			
		||||
        type="button"
 | 
			
		||||
        aria-controls="tabs-panel-{{ $i }}"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user