@m13v/seo-components 0.9.1 → 0.9.3

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.
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
2
- /*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.-left-8{left:-2rem}.bottom-0{bottom:0}.bottom-2{bottom:.5rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-1\/2{left:50%}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-4{left:1rem}.right-0{right:0}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-2{top:.5rem}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[1\]{z-index:1}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.row-span-1{grid-row:span 1/span 1}.row-span-2{grid-row:span 2/span 2}.m-1{margin:.25rem}.m-auto{margin:auto}.mx-auto{margin-left:auto;margin-right:auto}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.my-12{margin-top:3rem;margin-bottom:3rem}.my-16{margin-top:4rem;margin-bottom:4rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.-ml-px{margin-left:-1px}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-14{margin-bottom:3.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-3{margin-left:.75rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.line-clamp-1{-webkit-line-clamp:1}.line-clamp-1,.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical}.line-clamp-2{-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-11{height:2.75rem}.h-16{height:4rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[14px\]{height:14px}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-32{max-height:8rem}.min-h-0{min-height:0}.min-h-\[120px\]{min-height:120px}.min-h-\[180px\]{min-height:180px}.min-h-\[200px\]{min-height:200px}.min-h-\[280px\]{min-height:280px}.min-h-\[60px\]{min-height:60px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-2\.5{width:.625rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-4{width:1rem}.w-5{width:1.25rem}.w-5\/6{width:83.333333%}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[7px\]{width:7px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-px{width:1px}.min-w-0{min-width:0}.min-w-\[300px\]{min-width:300px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-\[180px\]{max-width:180px}.max-w-\[85\%\]{max-width:85%}.max-w-\[90\%\]{max-width:90%}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-screen-xl{max-width:1280px}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-top{transform-origin:top}.-translate-x-full{--tw-translate-x:-100%}.-translate-x-full,.-translate-y-1\/2{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))}.-translate-y-1\/2{--tw-translate-y:-50%}.translate-x-0{--tw-translate-x:0px}.transform,.translate-x-0{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))}.animate-\[shimmer_2\.2s_infinite\]{animation:shimmer 2.2s infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize{resize:both}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-2{row-gap:.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.625rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem*var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:0;border-right-width:calc(1px*var(--tw-divide-x-reverse));border-left-width:calc(1px*(1 - var(--tw-divide-x-reverse)))}.divide-zinc-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(228 228 231/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-emerald-500\/30{border-color:rgba(16,185,129,.3)}.border-teal-100{--tw-border-opacity:1;border-color:rgb(204 251 241/var(--tw-border-opacity,1))}.border-teal-200{--tw-border-opacity:1;border-color:rgb(153 246 228/var(--tw-border-opacity,1))}.border-teal-400{--tw-border-opacity:1;border-color:rgb(45 212 191/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.border-zinc-100{--tw-border-opacity:1;border-color:rgb(244 244 245/var(--tw-border-opacity,1))}.border-zinc-200{--tw-border-opacity:1;border-color:rgb(228 228 231/var(--tw-border-opacity,1))}.border-zinc-800{--tw-border-opacity:1;border-color:rgb(39 39 42/var(--tw-border-opacity,1))}.bg-\[\#0d1117\]{--tw-bg-opacity:1;background-color:rgb(13 17 23/var(--tw-bg-opacity,1))}.bg-amber-400\/60{background-color:rgba(251,191,36,.6)}.bg-black\/30{background-color:rgba(0,0,0,.3)}.bg-emerald-400\/60{background-color:rgba(52,211,153,.6)}.bg-emerald-500{--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity,1))}.bg-emerald-500\/10{background-color:rgba(16,185,129,.1)}.bg-emerald-500\/20{background-color:rgba(16,185,129,.2)}.bg-green-400\/80{background-color:rgba(74,222,128,.8)}.bg-red-400\/60{background-color:hsla(0,91%,71%,.6)}.bg-red-400\/80{background-color:hsla(0,91%,71%,.8)}.bg-teal-300{--tw-bg-opacity:1;background-color:rgb(94 234 212/var(--tw-bg-opacity,1))}.bg-teal-50{--tw-bg-opacity:1;background-color:rgb(240 253 250/var(--tw-bg-opacity,1))}.bg-teal-50\/30{background-color:rgba(240,253,250,.3)}.bg-teal-500{--tw-bg-opacity:1;background-color:rgb(20 184 166/var(--tw-bg-opacity,1))}.bg-teal-500\/10{background-color:rgba(20,184,166,.1)}.bg-teal-600{--tw-bg-opacity:1;background-color:rgb(13 148 136/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-white\/50{background-color:hsla(0,0%,100%,.5)}.bg-yellow-400\/80{background-color:rgba(250,204,21,.8)}.bg-zinc-100{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.bg-zinc-300{--tw-bg-opacity:1;background-color:rgb(212 212 216/var(--tw-bg-opacity,1))}.bg-zinc-400{--tw-bg-opacity:1;background-color:rgb(161 161 170/var(--tw-bg-opacity,1))}.bg-zinc-50{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity,1))}.bg-zinc-800{--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity,1))}.bg-zinc-900{--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity,1))}.bg-zinc-900\/50{background-color:rgba(24,24,27,.5)}.bg-zinc-950{--tw-bg-opacity:1;background-color:rgb(9 9 11/var(--tw-bg-opacity,1))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-cyan-500{--tw-gradient-from:#06b6d4 var(--tw-gradient-from-position);--tw-gradient-to:rgba(6,182,212,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-teal-400{--tw-gradient-from:#2dd4bf var(--tw-gradient-from-position);--tw-gradient-to:rgba(45,212,191,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-teal-50{--tw-gradient-from:#f0fdfa var(--tw-gradient-from-position);--tw-gradient-to:rgba(240,253,250,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-teal-500\/40{--tw-gradient-from:rgba(20,184,166,.4) var(--tw-gradient-from-position);--tw-gradient-to:rgba(20,184,166,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-transparent{--tw-gradient-from:transparent var(--tw-gradient-from-position);--tw-gradient-to:transparent var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-zinc-100{--tw-gradient-from:#f4f4f5 var(--tw-gradient-from-position);--tw-gradient-to:hsla(240,5%,96%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-zinc-50{--tw-gradient-from:#fafafa var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,98%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.via-teal-300{--tw-gradient-to:rgba(94,234,212,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),#5eead4 var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-teal-600\/80{--tw-gradient-to:rgba(13,148,136,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgba(13,148,136,.8) var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-white\/40{--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),hsla(0,0%,100%,.4) var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-50\%{--tw-gradient-via-position:50%}.to-cyan-50{--tw-gradient-to:#ecfeff var(--tw-gradient-to-position)}.to-teal-500{--tw-gradient-to:#14b8a6 var(--tw-gradient-to-position)}.to-teal-500\/10{--tw-gradient-to:rgba(20,184,166,.1) var(--tw-gradient-to-position)}.to-teal-600{--tw-gradient-to:#0d9488 var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.to-white{--tw-gradient-to:#fff var(--tw-gradient-to-position)}.to-zinc-100{--tw-gradient-to:#f4f4f5 var(--tw-gradient-to-position)}.to-zinc-200{--tw-gradient-to:#e4e4e7 var(--tw-gradient-to-position)}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-no-repeat{background-repeat:no-repeat}.fill-white{fill:#fff}.fill-zinc-900{fill:#18181b}.stroke-amber-400{stroke:#fbbf24}.stroke-emerald-500{stroke:#10b981}.stroke-red-400{stroke:#f87171}.stroke-teal-500{stroke:#14b8a6}.stroke-zinc-200{stroke:#e4e4e7}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-8{padding-left:2rem}.pr-2{padding-right:.5rem}.pr-3{padding-right:.75rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[40pt\]{font-size:40pt}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-\[5rem\]{line-height:5rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-\[-0\.02em\]{letter-spacing:-.02em}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[\#8b949e\]{--tw-text-opacity:1;color:rgb(139 148 158/var(--tw-text-opacity,1))}.text-amber-400{--tw-text-opacity:1;color:rgb(251 191 36/var(--tw-text-opacity,1))}.text-emerald-400{--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity,1))}.text-emerald-500{--tw-text-opacity:1;color:rgb(16 185 129/var(--tw-text-opacity,1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-teal-300{--tw-text-opacity:1;color:rgb(94 234 212/var(--tw-text-opacity,1))}.text-teal-500{--tw-text-opacity:1;color:rgb(20 184 166/var(--tw-text-opacity,1))}.text-teal-600{--tw-text-opacity:1;color:rgb(13 148 136/var(--tw-text-opacity,1))}.text-transparent{color:transparent}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-zinc-200{--tw-text-opacity:1;color:rgb(228 228 231/var(--tw-text-opacity,1))}.text-zinc-300{--tw-text-opacity:1;color:rgb(212 212 216/var(--tw-text-opacity,1))}.text-zinc-400{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.text-zinc-500{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.text-zinc-600{--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity,1))}.text-zinc-700{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.text-zinc-800{--tw-text-opacity:1;color:rgb(39 39 42/var(--tw-text-opacity,1))}.text-zinc-900{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-zinc-400::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(161 161 170/var(--tw-placeholder-opacity,1))}.placeholder-zinc-400::placeholder{--tw-placeholder-opacity:1;color:rgb(161 161 170/var(--tw-placeholder-opacity,1))}.opacity-50{opacity:.5}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-teal-500\/30{--tw-shadow-color:rgba(20,184,166,.3);--tw-shadow:var(--tw-shadow-colored)}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.blur{--tw-blur:blur(8px)}.blur,.drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.05))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}.backdrop-blur-sm,.backdrop-blur-xl{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur:blur(24px)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.\[-moz-osx-font-smoothing\:grayscale\]{-moz-osx-font-smoothing:grayscale}.\[-webkit-font-smoothing\:antialiased\]{-webkit-font-smoothing:antialiased}.\[animation-delay\:150ms\]{animation-delay:.15s}.\[animation-delay\:300ms\]{animation-delay:.3s}.\[background-position\:0_0\]{background-position:0 0}.\[background-size\:var\(--shimmer-width\)_100\%\]{background-size:var(--shimmer-width) 100%}.\[font-smooth\:antialiased\]{font-smooth:antialiased}.\[text-rendering\:optimizeLegibility\]{text-rendering:optimizeLegibility}.\[transition\:background-position_1s_cubic-bezier\(\.6\2c \.6\2c 0\2c 1\)_infinite\]{transition:background-position infinite 1s cubic-bezier(.6,.6,0,1)}.\[will-change\:filter\2c opacity\]{will-change:filter,opacity}:root{--seo-accent:#14b8a6;--seo-accent-light:#2dd4bf;--seo-accent-dark:#0d9488;--seo-accent-rgb:20,184,166;--seo-accent-gradient-from:#06b6d4;--seo-accent-gradient-to:#14b8a6}.placeholder\:text-zinc-400::-moz-placeholder{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.placeholder\:text-zinc-400::placeholder{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:inset-\[0\]:before{content:var(--tw-content);inset:0}.before\:aspect-square:before{content:var(--tw-content);aspect-ratio:1/1}.before\:h-full:before{content:var(--tw-content);height:100%}.before\:w-full:before{content:var(--tw-content);width:100%}.before\:rounded-\[--border-radius\]:before{content:var(--tw-content);border-radius:var(--border-radius)}.before\:p-\[--border-width\]:before{content:var(--tw-content);padding:var(--border-width)}.before\:will-change-\[background-position\]:before{content:var(--tw-content);will-change:background-position}.before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.before\:\!\[-webkit-mask-composite\:xor\]:before{content:var(--tw-content);-webkit-mask-composite:xor!important}.before\:\[background-image\:var\(--background-radial-gradient\)\]:before{content:var(--tw-content);background-image:var(--background-radial-gradient)}.before\:\[background-size\:300\%_300\%\]:before{content:var(--tw-content);background-size:300% 300%}.before\:\!\[mask-composite\:exclude\]:before{content:var(--tw-content);-webkit-mask-composite:xor!important;mask-composite:exclude!important}.before\:\[mask\:var\(--mask-linear-gradient\)\]:before{content:var(--tw-content);-webkit-mask:var(--mask-linear-gradient);mask:var(--mask-linear-gradient)}.focus-within\:border-teal-300:focus-within{--tw-border-opacity:1;border-color:rgb(94 234 212/var(--tw-border-opacity,1))}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-within\:ring-teal-500\/20:focus-within{--tw-ring-color:rgba(20,184,166,.2)}.hover\:scale-\[1\.02\]:hover{--tw-scale-x:1.02;--tw-scale-y:1.02;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))}.hover\:border-teal-300:hover{--tw-border-opacity:1;border-color:rgb(94 234 212/var(--tw-border-opacity,1))}.hover\:border-zinc-300:hover{--tw-border-opacity:1;border-color:rgb(212 212 216/var(--tw-border-opacity,1))}.hover\:bg-teal-600:hover{--tw-bg-opacity:1;background-color:rgb(13 148 136/var(--tw-bg-opacity,1))}.hover\:bg-teal-700:hover{--tw-bg-opacity:1;background-color:rgb(15 118 110/var(--tw-bg-opacity,1))}.hover\:bg-zinc-100:hover{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.hover\:bg-zinc-50:hover{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity,1))}.hover\:text-teal-700:hover{--tw-text-opacity:1;color:rgb(15 118 110/var(--tw-text-opacity,1))}.hover\:text-zinc-600:hover{--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity,1))}.hover\:text-zinc-700:hover{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.hover\:text-zinc-900:hover{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:border-teal-500:focus{--tw-border-opacity:1;border-color:rgb(20 184 166/var(--tw-border-opacity,1))}.focus\:border-transparent:focus{border-color:transparent}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-teal-500\/40:focus{--tw-ring-color:rgba(20,184,166,.4)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-zinc-300:disabled{--tw-bg-opacity:1;background-color:rgb(212 212 216/var(--tw-bg-opacity,1))}.disabled\:opacity-60:disabled{opacity:.6}.group[open] .group-open\:rotate-45{--tw-rotate:45deg;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))}@media (prefers-reduced-motion:no-preference){.motion-safe\:before\:animate-\[shine-pulse_var\(--shine-pulse-duration\)_infinite_linear\]:before{content:var(--tw-content);animation:shine-pulse var(--shine-pulse-duration) infinite linear}}.dark\:border-teal-900:is(.dark *){--tw-border-opacity:1;border-color:rgb(19 78 74/var(--tw-border-opacity,1))}.dark\:border-zinc-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(39 39 42/var(--tw-border-opacity,1))}.dark\:bg-teal-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(4 47 46/var(--tw-bg-opacity,1))}.dark\:bg-zinc-600:is(.dark *){--tw-bg-opacity:1;background-color:rgb(82 82 91/var(--tw-bg-opacity,1))}.dark\:bg-zinc-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity,1))}.dark\:bg-zinc-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity,1))}.dark\:bg-zinc-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(9 9 11/var(--tw-bg-opacity,1))}.dark\:text-zinc-100:is(.dark *){--tw-text-opacity:1;color:rgb(244 244 245/var(--tw-text-opacity,1))}.dark\:text-zinc-400:is(.dark *){--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.dark\:text-zinc-500:is(.dark *){--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.dark\:text-zinc-600:is(.dark *){--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity,1))}.dark\:placeholder\:text-zinc-500:is(.dark *)::-moz-placeholder{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.dark\:placeholder\:text-zinc-500:is(.dark *)::placeholder{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.dark\:focus-within\:border-teal-700:focus-within:is(.dark *){--tw-border-opacity:1;border-color:rgb(15 118 110/var(--tw-border-opacity,1))}.dark\:hover\:border-teal-700:hover:is(.dark *){--tw-border-opacity:1;border-color:rgb(15 118 110/var(--tw-border-opacity,1))}.dark\:hover\:border-zinc-700:hover:is(.dark *){--tw-border-opacity:1;border-color:rgb(63 63 70/var(--tw-border-opacity,1))}.dark\:hover\:bg-zinc-800:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity,1))}.dark\:hover\:bg-zinc-900:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity,1))}.dark\:hover\:text-teal-300:hover:is(.dark *){--tw-text-opacity:1;color:rgb(94 234 212/var(--tw-text-opacity,1))}.dark\:hover\:text-zinc-100:hover:is(.dark *){--tw-text-opacity:1;color:rgb(244 244 245/var(--tw-text-opacity,1))}.dark\:disabled\:bg-zinc-700:disabled:is(.dark *){--tw-bg-opacity:1;background-color:rgb(63 63 70/var(--tw-bg-opacity,1))}@media (min-width:640px){.sm\:block{display:block}.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:p-8{padding:2rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:768px){.md\:block{display:block}.md\:h-24{height:6rem}.md\:min-w-\[340px\]{min-width:340px}.md\:flex-initial{flex:0 1 auto}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:p-12{padding:3rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (min-width:1024px){.lg\:sticky{position:sticky}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-12{width:3rem}.lg\:translate-x-0{--tw-translate-x:0px;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))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:text-\[6rem\]{font-size:6rem}}@media (min-width:1280px){.xl\:flex{display:flex}}@media (min-width:1536px){.\32xl\:w-96{width:24rem}}
2
+ /*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.-left-8{left:-2rem}.bottom-0{bottom:0}.bottom-2{bottom:.5rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-1\/2{left:50%}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-4{left:1rem}.right-0{right:0}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-2{top:.5rem}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[1\]{z-index:1}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.row-span-1{grid-row:span 1/span 1}.row-span-2{grid-row:span 2/span 2}.m-1{margin:.25rem}.m-auto{margin:auto}.mx-auto{margin-left:auto;margin-right:auto}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.my-12{margin-top:3rem;margin-bottom:3rem}.my-16{margin-top:4rem;margin-bottom:4rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.-ml-px{margin-left:-1px}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-14{margin-bottom:3.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-3{margin-left:.75rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.line-clamp-1{-webkit-line-clamp:1}.line-clamp-1,.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical}.line-clamp-2{-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-11{height:2.75rem}.h-16{height:4rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[14px\]{height:14px}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-32{max-height:8rem}.min-h-0{min-height:0}.min-h-\[120px\]{min-height:120px}.min-h-\[180px\]{min-height:180px}.min-h-\[200px\]{min-height:200px}.min-h-\[280px\]{min-height:280px}.min-h-\[60px\]{min-height:60px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-2\.5{width:.625rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-4{width:1rem}.w-5{width:1.25rem}.w-5\/6{width:83.333333%}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[7px\]{width:7px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-px{width:1px}.min-w-0{min-width:0}.min-w-\[300px\]{min-width:300px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-\[180px\]{max-width:180px}.max-w-\[85\%\]{max-width:85%}.max-w-\[90\%\]{max-width:90%}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-screen-xl{max-width:1280px}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-top{transform-origin:top}.-translate-x-full{--tw-translate-x:-100%}.-translate-x-full,.-translate-y-1\/2{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))}.-translate-y-1\/2{--tw-translate-y:-50%}.translate-x-0{--tw-translate-x:0px}.transform,.translate-x-0{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))}.animate-\[shimmer_2\.2s_infinite\]{animation:shimmer 2.2s infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize{resize:both}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-2{row-gap:.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.625rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem*var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem*var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:0;border-right-width:calc(1px*var(--tw-divide-x-reverse));border-left-width:calc(1px*(1 - var(--tw-divide-x-reverse)))}.divide-zinc-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(228 228 231/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[var\(--seo-accent\2c \#14b8a6\)\]{border-color:var(--seo-accent,#14b8a6)}.border-emerald-500\/30{border-color:rgba(16,185,129,.3)}.border-teal-100{--tw-border-opacity:1;border-color:rgb(204 251 241/var(--tw-border-opacity,1))}.border-teal-200{--tw-border-opacity:1;border-color:rgb(153 246 228/var(--tw-border-opacity,1))}.border-teal-400{--tw-border-opacity:1;border-color:rgb(45 212 191/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.border-zinc-100{--tw-border-opacity:1;border-color:rgb(244 244 245/var(--tw-border-opacity,1))}.border-zinc-200{--tw-border-opacity:1;border-color:rgb(228 228 231/var(--tw-border-opacity,1))}.border-zinc-800{--tw-border-opacity:1;border-color:rgb(39 39 42/var(--tw-border-opacity,1))}.bg-\[\#0d1117\]{--tw-bg-opacity:1;background-color:rgb(13 17 23/var(--tw-bg-opacity,1))}.bg-\[var\(--seo-accent-light\2c rgba\(20\2c 184\2c 166\2c 0\.08\)\)\]{background-color:var(--seo-accent-light,rgba(20,184,166,.08))}.bg-amber-400\/60{background-color:rgba(251,191,36,.6)}.bg-black\/30{background-color:rgba(0,0,0,.3)}.bg-emerald-400\/60{background-color:rgba(52,211,153,.6)}.bg-emerald-500{--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity,1))}.bg-emerald-500\/10{background-color:rgba(16,185,129,.1)}.bg-emerald-500\/20{background-color:rgba(16,185,129,.2)}.bg-green-400\/80{background-color:rgba(74,222,128,.8)}.bg-red-400\/60{background-color:hsla(0,91%,71%,.6)}.bg-red-400\/80{background-color:hsla(0,91%,71%,.8)}.bg-teal-300{--tw-bg-opacity:1;background-color:rgb(94 234 212/var(--tw-bg-opacity,1))}.bg-teal-50{--tw-bg-opacity:1;background-color:rgb(240 253 250/var(--tw-bg-opacity,1))}.bg-teal-50\/30{background-color:rgba(240,253,250,.3)}.bg-teal-500{--tw-bg-opacity:1;background-color:rgb(20 184 166/var(--tw-bg-opacity,1))}.bg-teal-500\/10{background-color:rgba(20,184,166,.1)}.bg-teal-600{--tw-bg-opacity:1;background-color:rgb(13 148 136/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-white\/50{background-color:hsla(0,0%,100%,.5)}.bg-yellow-400\/80{background-color:rgba(250,204,21,.8)}.bg-zinc-100{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.bg-zinc-300{--tw-bg-opacity:1;background-color:rgb(212 212 216/var(--tw-bg-opacity,1))}.bg-zinc-400{--tw-bg-opacity:1;background-color:rgb(161 161 170/var(--tw-bg-opacity,1))}.bg-zinc-50{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity,1))}.bg-zinc-800{--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity,1))}.bg-zinc-900{--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity,1))}.bg-zinc-900\/50{background-color:rgba(24,24,27,.5)}.bg-zinc-950{--tw-bg-opacity:1;background-color:rgb(9 9 11/var(--tw-bg-opacity,1))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-cyan-500{--tw-gradient-from:#06b6d4 var(--tw-gradient-from-position);--tw-gradient-to:rgba(6,182,212,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-teal-400{--tw-gradient-from:#2dd4bf var(--tw-gradient-from-position);--tw-gradient-to:rgba(45,212,191,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-teal-50{--tw-gradient-from:#f0fdfa var(--tw-gradient-from-position);--tw-gradient-to:rgba(240,253,250,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-teal-500\/40{--tw-gradient-from:rgba(20,184,166,.4) var(--tw-gradient-from-position);--tw-gradient-to:rgba(20,184,166,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-transparent{--tw-gradient-from:transparent var(--tw-gradient-from-position);--tw-gradient-to:transparent var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-zinc-100{--tw-gradient-from:#f4f4f5 var(--tw-gradient-from-position);--tw-gradient-to:hsla(240,5%,96%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-zinc-50{--tw-gradient-from:#fafafa var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,98%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.via-teal-300{--tw-gradient-to:rgba(94,234,212,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),#5eead4 var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-teal-600\/80{--tw-gradient-to:rgba(13,148,136,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgba(13,148,136,.8) var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-white\/40{--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),hsla(0,0%,100%,.4) var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-50\%{--tw-gradient-via-position:50%}.to-cyan-50{--tw-gradient-to:#ecfeff var(--tw-gradient-to-position)}.to-teal-500{--tw-gradient-to:#14b8a6 var(--tw-gradient-to-position)}.to-teal-500\/10{--tw-gradient-to:rgba(20,184,166,.1) var(--tw-gradient-to-position)}.to-teal-600{--tw-gradient-to:#0d9488 var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.to-white{--tw-gradient-to:#fff var(--tw-gradient-to-position)}.to-zinc-100{--tw-gradient-to:#f4f4f5 var(--tw-gradient-to-position)}.to-zinc-200{--tw-gradient-to:#e4e4e7 var(--tw-gradient-to-position)}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-no-repeat{background-repeat:no-repeat}.fill-white{fill:#fff}.fill-zinc-900{fill:#18181b}.stroke-amber-400{stroke:#fbbf24}.stroke-emerald-500{stroke:#10b981}.stroke-red-400{stroke:#f87171}.stroke-teal-500{stroke:#14b8a6}.stroke-zinc-200{stroke:#e4e4e7}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-8{padding-left:2rem}.pr-2{padding-right:.5rem}.pr-3{padding-right:.75rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[40pt\]{font-size:40pt}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-\[5rem\]{line-height:5rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-\[-0\.02em\]{letter-spacing:-.02em}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[\#8b949e\]{--tw-text-opacity:1;color:rgb(139 148 158/var(--tw-text-opacity,1))}.text-\[var\(--seo-accent\2c \#14b8a6\)\]{color:var(--seo-accent,#14b8a6)}.text-amber-400{--tw-text-opacity:1;color:rgb(251 191 36/var(--tw-text-opacity,1))}.text-emerald-400{--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity,1))}.text-emerald-500{--tw-text-opacity:1;color:rgb(16 185 129/var(--tw-text-opacity,1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-teal-300{--tw-text-opacity:1;color:rgb(94 234 212/var(--tw-text-opacity,1))}.text-teal-500{--tw-text-opacity:1;color:rgb(20 184 166/var(--tw-text-opacity,1))}.text-teal-600{--tw-text-opacity:1;color:rgb(13 148 136/var(--tw-text-opacity,1))}.text-transparent{color:transparent}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-zinc-200{--tw-text-opacity:1;color:rgb(228 228 231/var(--tw-text-opacity,1))}.text-zinc-300{--tw-text-opacity:1;color:rgb(212 212 216/var(--tw-text-opacity,1))}.text-zinc-400{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.text-zinc-500{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.text-zinc-600{--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity,1))}.text-zinc-700{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.text-zinc-800{--tw-text-opacity:1;color:rgb(39 39 42/var(--tw-text-opacity,1))}.text-zinc-900{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-zinc-400::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(161 161 170/var(--tw-placeholder-opacity,1))}.placeholder-zinc-400::placeholder{--tw-placeholder-opacity:1;color:rgb(161 161 170/var(--tw-placeholder-opacity,1))}.opacity-50{opacity:.5}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-teal-500\/30{--tw-shadow-color:rgba(20,184,166,.3);--tw-shadow:var(--tw-shadow-colored)}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.blur{--tw-blur:blur(8px)}.blur,.drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.05))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}.backdrop-blur-sm,.backdrop-blur-xl{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur:blur(24px)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.\[-moz-osx-font-smoothing\:grayscale\]{-moz-osx-font-smoothing:grayscale}.\[-webkit-font-smoothing\:antialiased\]{-webkit-font-smoothing:antialiased}.\[animation-delay\:150ms\]{animation-delay:.15s}.\[animation-delay\:300ms\]{animation-delay:.3s}.\[background-position\:0_0\]{background-position:0 0}.\[background-size\:var\(--shimmer-width\)_100\%\]{background-size:var(--shimmer-width) 100%}.\[font-smooth\:antialiased\]{font-smooth:antialiased}.\[text-rendering\:optimizeLegibility\]{text-rendering:optimizeLegibility}.\[transition\:background-position_1s_cubic-bezier\(\.6\2c \.6\2c 0\2c 1\)_infinite\]{transition:background-position infinite 1s cubic-bezier(.6,.6,0,1)}.\[will-change\:filter\2c opacity\]{will-change:filter,opacity}:root{--seo-accent:#14b8a6;--seo-accent-light:#2dd4bf;--seo-accent-dark:#0d9488;--seo-accent-rgb:20,184,166;--seo-accent-gradient-from:#06b6d4;--seo-accent-gradient-to:#14b8a6}.placeholder\:text-zinc-400::-moz-placeholder{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.placeholder\:text-zinc-400::placeholder{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:inset-\[0\]:before{content:var(--tw-content);inset:0}.before\:aspect-square:before{content:var(--tw-content);aspect-ratio:1/1}.before\:h-full:before{content:var(--tw-content);height:100%}.before\:w-full:before{content:var(--tw-content);width:100%}.before\:rounded-\[--border-radius\]:before{content:var(--tw-content);border-radius:var(--border-radius)}.before\:p-\[--border-width\]:before{content:var(--tw-content);padding:var(--border-width)}.before\:will-change-\[background-position\]:before{content:var(--tw-content);will-change:background-position}.before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.before\:\!\[-webkit-mask-composite\:xor\]:before{content:var(--tw-content);-webkit-mask-composite:xor!important}.before\:\[background-image\:var\(--background-radial-gradient\)\]:before{content:var(--tw-content);background-image:var(--background-radial-gradient)}.before\:\[background-size\:300\%_300\%\]:before{content:var(--tw-content);background-size:300% 300%}.before\:\!\[mask-composite\:exclude\]:before{content:var(--tw-content);-webkit-mask-composite:xor!important;mask-composite:exclude!important}.before\:\[mask\:var\(--mask-linear-gradient\)\]:before{content:var(--tw-content);-webkit-mask:var(--mask-linear-gradient);mask:var(--mask-linear-gradient)}.focus-within\:border-teal-300:focus-within{--tw-border-opacity:1;border-color:rgb(94 234 212/var(--tw-border-opacity,1))}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-within\:ring-teal-500\/20:focus-within{--tw-ring-color:rgba(20,184,166,.2)}.hover\:scale-\[1\.02\]:hover{--tw-scale-x:1.02;--tw-scale-y:1.02;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))}.hover\:border-teal-300:hover{--tw-border-opacity:1;border-color:rgb(94 234 212/var(--tw-border-opacity,1))}.hover\:border-zinc-300:hover{--tw-border-opacity:1;border-color:rgb(212 212 216/var(--tw-border-opacity,1))}.hover\:bg-teal-600:hover{--tw-bg-opacity:1;background-color:rgb(13 148 136/var(--tw-bg-opacity,1))}.hover\:bg-teal-700:hover{--tw-bg-opacity:1;background-color:rgb(15 118 110/var(--tw-bg-opacity,1))}.hover\:bg-zinc-100:hover{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.hover\:bg-zinc-50:hover{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity,1))}.hover\:text-teal-700:hover{--tw-text-opacity:1;color:rgb(15 118 110/var(--tw-text-opacity,1))}.hover\:text-zinc-600:hover{--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity,1))}.hover\:text-zinc-700:hover{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.hover\:text-zinc-800:hover{--tw-text-opacity:1;color:rgb(39 39 42/var(--tw-text-opacity,1))}.hover\:text-zinc-900:hover{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:border-\[var\(--seo-accent\2c \#14b8a6\)\]:focus{border-color:var(--seo-accent,#14b8a6)}.focus\:border-teal-500:focus{--tw-border-opacity:1;border-color:rgb(20 184 166/var(--tw-border-opacity,1))}.focus\:border-transparent:focus{border-color:transparent}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-teal-500\/40:focus{--tw-ring-color:rgba(20,184,166,.4)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-zinc-300:disabled{--tw-bg-opacity:1;background-color:rgb(212 212 216/var(--tw-bg-opacity,1))}.disabled\:opacity-60:disabled{opacity:.6}.group[open] .group-open\:rotate-45{--tw-rotate:45deg;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))}@media (prefers-reduced-motion:no-preference){.motion-safe\:before\:animate-\[shine-pulse_var\(--shine-pulse-duration\)_infinite_linear\]:before{content:var(--tw-content);animation:shine-pulse var(--shine-pulse-duration) infinite linear}}.dark\:divide-zinc-800:is(.dark *)>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(39 39 42/var(--tw-divide-opacity,1))}.dark\:border-teal-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(17 94 89/var(--tw-border-opacity,1))}.dark\:border-teal-900:is(.dark *){--tw-border-opacity:1;border-color:rgb(19 78 74/var(--tw-border-opacity,1))}.dark\:border-zinc-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(39 39 42/var(--tw-border-opacity,1))}.dark\:border-zinc-900:is(.dark *){--tw-border-opacity:1;border-color:rgb(24 24 27/var(--tw-border-opacity,1))}.dark\:bg-teal-900\/30:is(.dark *){background-color:rgba(19,78,74,.3)}.dark\:bg-teal-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(4 47 46/var(--tw-bg-opacity,1))}.dark\:bg-zinc-600:is(.dark *){--tw-bg-opacity:1;background-color:rgb(82 82 91/var(--tw-bg-opacity,1))}.dark\:bg-zinc-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity,1))}.dark\:bg-zinc-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity,1))}.dark\:bg-zinc-900\/50:is(.dark *){background-color:rgba(24,24,27,.5)}.dark\:bg-zinc-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(9 9 11/var(--tw-bg-opacity,1))}.dark\:from-teal-900\/20:is(.dark *){--tw-gradient-from:rgba(19,78,74,.2) var(--tw-gradient-from-position);--tw-gradient-to:rgba(19,78,74,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.dark\:text-teal-400:is(.dark *){--tw-text-opacity:1;color:rgb(45 212 191/var(--tw-text-opacity,1))}.dark\:text-zinc-100:is(.dark *){--tw-text-opacity:1;color:rgb(244 244 245/var(--tw-text-opacity,1))}.dark\:text-zinc-200:is(.dark *){--tw-text-opacity:1;color:rgb(228 228 231/var(--tw-text-opacity,1))}.dark\:text-zinc-300:is(.dark *){--tw-text-opacity:1;color:rgb(212 212 216/var(--tw-text-opacity,1))}.dark\:text-zinc-400:is(.dark *){--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.dark\:text-zinc-600:is(.dark *){--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity,1))}.dark\:placeholder\:text-zinc-500:is(.dark *)::-moz-placeholder{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.dark\:placeholder\:text-zinc-500:is(.dark *)::placeholder{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.dark\:focus-within\:border-teal-700:focus-within:is(.dark *){--tw-border-opacity:1;border-color:rgb(15 118 110/var(--tw-border-opacity,1))}.dark\:hover\:border-teal-700:hover:is(.dark *){--tw-border-opacity:1;border-color:rgb(15 118 110/var(--tw-border-opacity,1))}.dark\:hover\:border-zinc-700:hover:is(.dark *){--tw-border-opacity:1;border-color:rgb(63 63 70/var(--tw-border-opacity,1))}.dark\:hover\:bg-zinc-800:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity,1))}.dark\:hover\:bg-zinc-900:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity,1))}.dark\:hover\:text-teal-300:hover:is(.dark *){--tw-text-opacity:1;color:rgb(94 234 212/var(--tw-text-opacity,1))}.dark\:hover\:text-zinc-100:hover:is(.dark *){--tw-text-opacity:1;color:rgb(244 244 245/var(--tw-text-opacity,1))}.dark\:disabled\:bg-zinc-700:disabled:is(.dark *){--tw-bg-opacity:1;background-color:rgb(63 63 70/var(--tw-bg-opacity,1))}@media (min-width:640px){.sm\:block{display:block}.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:p-8{padding:2rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:768px){.md\:block{display:block}.md\:h-24{height:6rem}.md\:min-w-\[340px\]{min-width:340px}.md\:flex-initial{flex:0 1 auto}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:p-12{padding:3rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (min-width:1024px){.lg\:sticky{position:sticky}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-12{width:3rem}.lg\:translate-x-0{--tw-translate-x:0px;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))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:text-\[6rem\]{font-size:6rem}}@media (min-width:1280px){.xl\:flex{display:flex}}@media (min-width:1536px){.\32xl\:w-96{width:24rem}}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@m13v/seo-components",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "scripts": {
5
5
  "build:css": "tailwind -i src/_build.css -o dist/styles.css --minify",
6
6
  "prepublishOnly": "npm run build:css"
7
7
  },
8
- "description": "39 animated React components for programmatic SEO pages. Remotion video, Magic UI style animations, trust signals, JSON-LD helpers. Teal/cyan brand, light-theme only.",
8
+ "description": "39 animated React components for programmatic SEO pages. Remotion video, Magic UI style animations, trust signals, JSON-LD helpers. Teal/cyan brand, supports light and dark themes.",
9
9
  "type": "module",
10
10
  "main": "./src/index.ts",
11
11
  "types": "./src/index.ts",
@@ -42,18 +42,18 @@ export function BentoGrid({ cards, className = "" }: BentoGridProps) {
42
42
  }}
43
43
  className={`${SIZE_CLASSES[card.size || "1x1"]} rounded-2xl border ${
44
44
  card.accent
45
- ? "border-teal-200 bg-gradient-to-br from-teal-50 to-cyan-50"
46
- : "border-zinc-200 bg-zinc-50"
45
+ ? "border-teal-200 dark:border-teal-800 bg-gradient-to-br from-teal-50 dark:from-teal-900/20 to-cyan-50"
46
+ : "border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/50"
47
47
  } p-6 flex flex-col justify-between group hover:border-teal-300 hover:shadow-md transition-all duration-300`}
48
48
  >
49
49
  <div>
50
50
  {card.icon && (
51
51
  <span className="text-2xl mb-3 block">{card.icon}</span>
52
52
  )}
53
- <h3 className="text-base font-semibold text-zinc-900 mb-2">
53
+ <h3 className="text-base font-semibold text-zinc-900 dark:text-zinc-100 mb-2">
54
54
  {card.title}
55
55
  </h3>
56
- <p className="text-sm text-zinc-500 leading-relaxed">
56
+ <p className="text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed">
57
57
  {card.description}
58
58
  </p>
59
59
  </div>
@@ -26,40 +26,40 @@ export function ComparisonTable({
26
26
  return (
27
27
  <section className={className}>
28
28
  {heading && (
29
- <h2 className="text-3xl sm:text-4xl font-bold text-zinc-900 mb-4 text-center">
29
+ <h2 className="text-3xl sm:text-4xl font-bold text-zinc-900 dark:text-zinc-100 mb-4 text-center">
30
30
  {heading}
31
31
  </h2>
32
32
  )}
33
33
  {intro && (
34
- <p className="text-zinc-500 text-lg text-center mb-8 max-w-2xl mx-auto">
34
+ <p className="text-zinc-500 dark:text-zinc-400 text-lg text-center mb-8 max-w-2xl mx-auto">
35
35
  {intro}
36
36
  </p>
37
37
  )}
38
- <div className="rounded-2xl bg-zinc-50 border border-zinc-200 overflow-hidden">
38
+ <div className="rounded-2xl bg-zinc-50 dark:bg-zinc-900/50 border border-zinc-200 dark:border-zinc-800 overflow-hidden">
39
39
  <table className="w-full text-left">
40
40
  <thead>
41
- <tr className="border-b border-zinc-200">
42
- <th className="px-5 py-4 text-zinc-500 text-sm font-medium">Feature</th>
43
- <th className="px-5 py-4 text-zinc-500 text-sm font-medium">{competitorName}</th>
44
- <th className="px-5 py-4 text-teal-600 text-sm font-medium">{productName}</th>
41
+ <tr className="border-b border-zinc-200 dark:border-zinc-800">
42
+ <th className="px-5 py-4 text-zinc-500 dark:text-zinc-400 text-sm font-medium">Feature</th>
43
+ <th className="px-5 py-4 text-zinc-500 dark:text-zinc-400 text-sm font-medium">{competitorName}</th>
44
+ <th className="px-5 py-4 text-teal-600 dark:text-teal-400 text-sm font-medium">{productName}</th>
45
45
  </tr>
46
46
  </thead>
47
47
  <tbody>
48
48
  {rows.map((row, i) => (
49
49
  <tr
50
50
  key={i}
51
- className={i < rows.length - 1 ? "border-b border-zinc-200" : ""}
51
+ className={i < rows.length - 1 ? "border-b border-zinc-200 dark:border-zinc-800" : ""}
52
52
  >
53
- <td className="px-5 py-3 text-zinc-900 text-sm font-medium">{row.feature}</td>
54
- <td className="px-5 py-3 text-zinc-500 text-sm">{row.competitor}</td>
55
- <td className="px-5 py-3 text-zinc-900 text-sm">{row.ours}</td>
53
+ <td className="px-5 py-3 text-zinc-900 dark:text-zinc-100 text-sm font-medium">{row.feature}</td>
54
+ <td className="px-5 py-3 text-zinc-500 dark:text-zinc-400 text-sm">{row.competitor}</td>
55
+ <td className="px-5 py-3 text-zinc-900 dark:text-zinc-100 text-sm">{row.ours}</td>
56
56
  </tr>
57
57
  ))}
58
58
  </tbody>
59
59
  </table>
60
60
  </div>
61
61
  {caveat && (
62
- <p className="text-zinc-500 text-sm mt-4 text-center">{caveat}</p>
62
+ <p className="text-zinc-500 dark:text-zinc-400 text-sm mt-4 text-center">{caveat}</p>
63
63
  )}
64
64
  </section>
65
65
  );
@@ -13,23 +13,23 @@ export function FaqSection({
13
13
  }: FaqSectionProps) {
14
14
  return (
15
15
  <section className={`max-w-4xl mx-auto px-6 my-16 ${className}`}>
16
- <h2 className="text-3xl sm:text-4xl font-bold text-zinc-900 mb-8">{heading}</h2>
16
+ <h2 className="text-3xl sm:text-4xl font-bold text-zinc-900 dark:text-zinc-100 mb-8">{heading}</h2>
17
17
  <div className="space-y-4">
18
18
  {items.map((faq) => (
19
19
  <details
20
20
  key={faq.q}
21
- className="group p-5 rounded-xl bg-zinc-50 border border-zinc-200"
21
+ className="group p-5 rounded-xl bg-zinc-50 dark:bg-zinc-900/50 border border-zinc-200 dark:border-zinc-800"
22
22
  >
23
- <summary className="text-zinc-900 font-semibold cursor-pointer list-none flex items-center justify-between gap-4">
23
+ <summary className="text-zinc-900 dark:text-zinc-100 font-semibold cursor-pointer list-none flex items-center justify-between gap-4">
24
24
  <span>{faq.q}</span>
25
25
  <span
26
- className="text-zinc-500 group-open:rotate-45 transition-transform text-xl flex-shrink-0"
26
+ className="text-zinc-500 dark:text-zinc-400 group-open:rotate-45 transition-transform text-xl flex-shrink-0"
27
27
  aria-hidden="true"
28
28
  >
29
29
  +
30
30
  </span>
31
31
  </summary>
32
- <p className="text-zinc-500 mt-3 leading-relaxed">{faq.a}</p>
32
+ <p className="text-zinc-500 dark:text-zinc-400 mt-3 leading-relaxed">{faq.a}</p>
33
33
  </details>
34
34
  ))}
35
35
  </div>
@@ -28,7 +28,7 @@ const icons: Record<string, string> = {
28
28
 
29
29
  export function FlowDiagram({ title, steps }: FlowDiagramProps) {
30
30
  return (
31
- <div className="my-10 rounded-2xl border border-zinc-200 bg-white p-6 overflow-x-auto">
31
+ <div className="my-10 rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 p-6 overflow-x-auto">
32
32
  <p className="text-xs font-mono uppercase tracking-widest text-emerald-500 mb-5">
33
33
  {title}
34
34
  </p>
@@ -47,14 +47,14 @@ export function FlowDiagram({ title, steps }: FlowDiagramProps) {
47
47
  }}
48
48
  >
49
49
  <div className="flex flex-col items-center flex-1 min-w-0 max-w-[180px]">
50
- <div className="w-11 h-11 rounded-xl bg-white border border-zinc-200 flex items-center justify-center text-lg mb-2">
50
+ <div className="w-11 h-11 rounded-xl bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 flex items-center justify-center text-lg mb-2">
51
51
  {step.icon ? icons[step.icon] || "\u2022" : `${i + 1}`}
52
52
  </div>
53
- <p className="text-xs font-medium text-zinc-900 text-center leading-tight">
53
+ <p className="text-xs font-medium text-zinc-900 dark:text-zinc-100 text-center leading-tight">
54
54
  {step.label}
55
55
  </p>
56
56
  {step.detail && (
57
- <p className="text-[10px] text-zinc-500 text-center leading-tight mt-1">
57
+ <p className="text-[10px] text-zinc-500 dark:text-zinc-400 text-center leading-tight mt-1">
58
58
  {step.detail}
59
59
  </p>
60
60
  )}
@@ -72,7 +72,7 @@ export function FlowDiagram({ title, steps }: FlowDiagramProps) {
72
72
  }}
73
73
  style={{ originX: 0 }}
74
74
  >
75
- <svg width="32" height="12" viewBox="0 0 32 12" className="text-zinc-500">
75
+ <svg width="32" height="12" viewBox="0 0 32 12" className="text-zinc-500 dark:text-zinc-400">
76
76
  <line x1="0" y1="6" x2="24" y2="6" stroke="currentColor" strokeWidth="1.5" />
77
77
  <polygon points="24,2 32,6 24,10" fill="currentColor" />
78
78
  </svg>
@@ -38,8 +38,8 @@ export function GlowCard({
38
38
  onMouseMove={handleMouseMove}
39
39
  onMouseEnter={() => setIsHovered(true)}
40
40
  onMouseLeave={() => setIsHovered(false)}
41
- className={`relative rounded-2xl border border-zinc-200 bg-white overflow-hidden transition-shadow duration-300 ${
42
- isHovered ? "shadow-lg border-teal-200" : ""
41
+ className={`relative rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 overflow-hidden transition-shadow duration-300 ${
42
+ isHovered ? "shadow-lg border-teal-200 dark:border-teal-800" : ""
43
43
  } ${className}`}
44
44
  >
45
45
  {/* Glow overlay */}
@@ -12,7 +12,7 @@ function Stars({ count }: { count: number }) {
12
12
  {Array.from({ length: 5 }, (_, i) => (
13
13
  <svg
14
14
  key={i}
15
- className={`w-4 h-4 ${i < count ? "text-teal-600" : "text-zinc-200"}`}
15
+ className={`w-4 h-4 ${i < count ? "text-teal-600 dark:text-teal-400" : "text-zinc-200"}`}
16
16
  fill="currentColor"
17
17
  viewBox="0 0 20 20"
18
18
  aria-hidden="true"
@@ -33,10 +33,10 @@ export function InlineTestimonial({
33
33
  }: InlineTestimonialProps) {
34
34
  return (
35
35
  <figure
36
- className={`p-6 sm:p-8 rounded-2xl bg-zinc-50 border border-zinc-200 ${className}`}
36
+ className={`p-6 sm:p-8 rounded-2xl bg-zinc-50 dark:bg-zinc-900/50 border border-zinc-200 dark:border-zinc-800 ${className}`}
37
37
  >
38
38
  <Stars count={stars} />
39
- <blockquote className="mt-4 text-lg sm:text-xl leading-relaxed text-zinc-800">
39
+ <blockquote className="mt-4 text-lg sm:text-xl leading-relaxed text-zinc-800 dark:text-zinc-200">
40
40
  &ldquo;{quote}&rdquo;
41
41
  </blockquote>
42
42
  <figcaption className="mt-5 flex items-center gap-3">
@@ -44,8 +44,8 @@ export function InlineTestimonial({
44
44
  {name.charAt(0)}
45
45
  </div>
46
46
  <div>
47
- <div className="text-sm font-medium text-zinc-900">{name}</div>
48
- {role && <div className="text-xs text-zinc-500">{role}</div>}
47
+ <div className="text-sm font-medium text-zinc-900 dark:text-zinc-100">{name}</div>
48
+ {role && <div className="text-xs text-zinc-500 dark:text-zinc-400">{role}</div>}
49
49
  </div>
50
50
  </figcaption>
51
51
  </figure>
@@ -18,7 +18,7 @@ interface MetricsRowProps {
18
18
  export function MetricsRow({ metrics }: MetricsRowProps) {
19
19
  return (
20
20
  <motion.div
21
- className="my-10 rounded-2xl border border-zinc-200 bg-white grid grid-cols-2 md:grid-cols-4 divide-x divide-zinc-200"
21
+ className="my-10 rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 grid grid-cols-2 md:grid-cols-4 divide-x divide-zinc-200 dark:divide-zinc-800"
22
22
  initial={{ opacity: 0, y: 12 }}
23
23
  whileInView={{ opacity: 1, y: 0 }}
24
24
  viewport={{ once: true }}
@@ -84,17 +84,17 @@ export function NewsletterSignup({
84
84
  animate={{ y: 0 }}
85
85
  exit={{ y: "100%" }}
86
86
  transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}
87
- className="fixed bottom-0 left-0 right-0 z-40 border-t border-zinc-200 backdrop-blur-xl py-3 px-4 sm:px-6"
87
+ className="fixed bottom-0 left-0 right-0 z-40 border-t border-zinc-200 dark:border-zinc-800 backdrop-blur-xl py-3 px-4 sm:px-6"
88
88
  style={{ backgroundColor: "rgba(255,255,255,0.92)" }}
89
89
  >
90
90
  <div className="mx-auto max-w-7xl flex items-center justify-between gap-3">
91
91
  {status === "success" ? (
92
- <p className="text-sm font-medium text-teal-600 flex-1">
92
+ <p className="text-sm font-medium text-teal-600 dark:text-teal-400 flex-1">
93
93
  {successMessage}
94
94
  </p>
95
95
  ) : (
96
96
  <>
97
- <p className="text-sm text-zinc-500 hidden md:block flex-shrink-0">
97
+ <p className="text-sm text-zinc-500 dark:text-zinc-400 hidden md:block flex-shrink-0">
98
98
  {description}
99
99
  </p>
100
100
  <form
@@ -107,7 +107,7 @@ export function NewsletterSignup({
107
107
  value={email}
108
108
  onChange={(e) => setEmail(e.target.value)}
109
109
  placeholder={placeholder}
110
- className="flex-1 min-w-0 text-sm px-3 py-2 rounded-lg border border-zinc-200 bg-white text-zinc-900 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-teal-500/40 focus:border-teal-500 transition-shadow"
110
+ className="flex-1 min-w-0 text-sm px-3 py-2 rounded-lg border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-teal-500/40 focus:border-teal-500 transition-shadow"
111
111
  disabled={status === "loading"}
112
112
  />
113
113
  <button
@@ -11,20 +11,20 @@ interface ProofBannerProps {
11
11
  export function ProofBanner({ quote, source, metric }: ProofBannerProps) {
12
12
  return (
13
13
  <motion.div
14
- className="my-8 p-4 rounded-xl border border-zinc-200 bg-white flex items-start gap-4"
14
+ className="my-8 p-4 rounded-xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 flex items-start gap-4"
15
15
  initial={{ opacity: 0, x: -16 }}
16
16
  whileInView={{ opacity: 1, x: 0 }}
17
17
  viewport={{ once: true }}
18
18
  transition={{ duration: 0.4, ease: [0.16, 1, 0.3, 1] }}
19
19
  >
20
20
  <div className="shrink-0 text-center">
21
- <span className="text-2xl font-bold text-teal-600">{metric}</span>
21
+ <span className="text-2xl font-bold text-teal-600 dark:text-teal-400">{metric}</span>
22
22
  </div>
23
23
  <div>
24
24
  <p className="text-sm text-subtle-text italic">
25
25
  &ldquo;{quote}&rdquo;
26
26
  </p>
27
- {source ? <p className="text-xs text-zinc-500 mt-1">{source}</p> : null}
27
+ {source ? <p className="text-xs text-zinc-500 dark:text-zinc-400 mt-1">{source}</p> : null}
28
28
  </div>
29
29
  </motion.div>
30
30
  );
@@ -0,0 +1,211 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
+ import { getAuthorToken, getStoredName, setStoredName } from "../lib/author-token";
5
+
6
+ export interface SeoPageCommentsProps {
7
+ site: string;
8
+ pageSlug: string;
9
+ apiOrigin: string;
10
+ title?: string;
11
+ placeholder?: string;
12
+ emptyMessage?: string;
13
+ className?: string;
14
+ }
15
+
16
+ interface Comment {
17
+ id: number;
18
+ author_name: string | null;
19
+ body: string;
20
+ parent_id: number | null;
21
+ created_at: string;
22
+ }
23
+
24
+ function formatWhen(iso: string): string {
25
+ const d = new Date(iso);
26
+ const diff = Date.now() - d.getTime();
27
+ const m = Math.floor(diff / 60000);
28
+ if (m < 1) return "just now";
29
+ if (m < 60) return `${m}m ago`;
30
+ const h = Math.floor(m / 60);
31
+ if (h < 24) return `${h}h ago`;
32
+ const days = Math.floor(h / 24);
33
+ if (days < 14) return `${days}d ago`;
34
+ return d.toLocaleDateString();
35
+ }
36
+
37
+ export function SeoPageComments({
38
+ site,
39
+ pageSlug,
40
+ apiOrigin,
41
+ title = "Comments",
42
+ placeholder = "Share your thoughts. No account needed.",
43
+ emptyMessage = "Be the first to comment.",
44
+ className = "",
45
+ }: SeoPageCommentsProps) {
46
+ const [comments, setComments] = useState<Comment[] | null>(null);
47
+ const [body, setBody] = useState("");
48
+ const [name, setName] = useState("");
49
+ const [replyTo, setReplyTo] = useState<number | null>(null);
50
+ const [status, setStatus] = useState<"idle" | "loading" | "error">("idle");
51
+ const [errorMsg, setErrorMsg] = useState("");
52
+ const [token, setToken] = useState("");
53
+
54
+ useEffect(() => {
55
+ setToken(getAuthorToken());
56
+ setName(getStoredName());
57
+ }, []);
58
+
59
+ const load = useCallback(async () => {
60
+ try {
61
+ const res = await fetch(
62
+ `${apiOrigin}/api/seo-page-comments?site=${encodeURIComponent(site)}&page_slug=${encodeURIComponent(pageSlug)}`,
63
+ { cache: "no-store" }
64
+ );
65
+ if (!res.ok) return;
66
+ const data = (await res.json()) as { comments: Comment[] };
67
+ setComments(data.comments);
68
+ } catch {
69
+ // no-op
70
+ }
71
+ }, [apiOrigin, site, pageSlug]);
72
+
73
+ useEffect(() => {
74
+ load();
75
+ }, [load]);
76
+
77
+ const { top, children } = useMemo(() => {
78
+ const top: Comment[] = [];
79
+ const children: Record<number, Comment[]> = {};
80
+ for (const c of comments ?? []) {
81
+ if (c.parent_id == null) top.push(c);
82
+ else (children[c.parent_id] ??= []).push(c);
83
+ }
84
+ return { top, children };
85
+ }, [comments]);
86
+
87
+ async function submit(e: React.FormEvent) {
88
+ e.preventDefault();
89
+ const trimmed = body.trim();
90
+ if (!trimmed) return;
91
+ setStatus("loading");
92
+ setErrorMsg("");
93
+ try {
94
+ const res = await fetch(`${apiOrigin}/api/seo-page-comments`, {
95
+ method: "POST",
96
+ headers: { "Content-Type": "application/json" },
97
+ body: JSON.stringify({
98
+ site,
99
+ page_slug: pageSlug,
100
+ author_token: token,
101
+ author_name: name.trim() || null,
102
+ body: trimmed,
103
+ parent_id: replyTo,
104
+ }),
105
+ });
106
+ if (!res.ok) {
107
+ const data = (await res.json().catch(() => ({}))) as { error?: string };
108
+ setErrorMsg(data.error || "Could not post comment");
109
+ setStatus("error");
110
+ return;
111
+ }
112
+ setStoredName(name.trim());
113
+ setBody("");
114
+ setReplyTo(null);
115
+ setStatus("idle");
116
+ await load();
117
+ } catch {
118
+ setErrorMsg("Network error");
119
+ setStatus("error");
120
+ }
121
+ }
122
+
123
+ return (
124
+ <section className={`seo-page-comments mx-auto max-w-2xl my-12 ${className}`}>
125
+ <h2 className="text-xl font-semibold text-zinc-900 dark:text-zinc-100 mb-1">{title}</h2>
126
+ <p className="text-sm text-zinc-500 dark:text-zinc-400 mb-6">Public and anonymous. No signup.</p>
127
+
128
+ <form onSubmit={submit} className="mb-8 space-y-2">
129
+ {replyTo != null && (
130
+ <div className="flex items-center justify-between text-xs text-zinc-500 dark:text-zinc-400 px-1">
131
+ <span>Replying to comment #{replyTo}</span>
132
+ <button type="button" onClick={() => setReplyTo(null)} className="underline hover:text-zinc-700">
133
+ cancel
134
+ </button>
135
+ </div>
136
+ )}
137
+ <textarea
138
+ value={body}
139
+ onChange={(e) => setBody(e.target.value)}
140
+ placeholder={placeholder}
141
+ rows={3}
142
+ maxLength={4000}
143
+ className="w-full px-3 py-2 rounded-lg border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:border-[var(--seo-accent,#14b8a6)]"
144
+ style={{ outlineColor: "var(--seo-accent, #14b8a6)" }}
145
+ disabled={status === "loading"}
146
+ />
147
+ <div className="flex flex-col sm:flex-row gap-2 sm:items-center">
148
+ <input
149
+ type="text"
150
+ value={name}
151
+ onChange={(e) => setName(e.target.value.slice(0, 80))}
152
+ placeholder="Name (optional)"
153
+ className="flex-1 min-w-0 px-3 py-2 rounded-lg border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2"
154
+ disabled={status === "loading"}
155
+ />
156
+ <button
157
+ type="submit"
158
+ disabled={status === "loading" || !body.trim()}
159
+ className="px-4 py-2 rounded-lg text-sm font-medium text-white disabled:opacity-60"
160
+ style={{ backgroundColor: "var(--seo-accent, #14b8a6)" }}
161
+ >
162
+ {status === "loading" ? "Posting…" : replyTo != null ? "Post reply" : "Post comment"}
163
+ </button>
164
+ </div>
165
+ {status === "error" && errorMsg && <p className="text-xs text-red-500 px-1">{errorMsg}</p>}
166
+ </form>
167
+
168
+ <div className="space-y-6">
169
+ {comments == null ? (
170
+ <p className="text-sm text-zinc-400">Loading…</p>
171
+ ) : top.length === 0 ? (
172
+ <p className="text-sm text-zinc-500 dark:text-zinc-400">{emptyMessage}</p>
173
+ ) : (
174
+ top.map((c) => (
175
+ <div key={c.id}>
176
+ <CommentRow c={c} onReply={() => setReplyTo(c.id)} />
177
+ {(children[c.id] ?? []).length > 0 && (
178
+ <div className="mt-3 ml-6 pl-4 border-l border-zinc-200 dark:border-zinc-800 space-y-4">
179
+ {children[c.id].map((r) => (
180
+ <CommentRow key={r.id} c={r} />
181
+ ))}
182
+ </div>
183
+ )}
184
+ </div>
185
+ ))
186
+ )}
187
+ </div>
188
+ </section>
189
+ );
190
+ }
191
+
192
+ function CommentRow({ c, onReply }: { c: Comment; onReply?: () => void }) {
193
+ return (
194
+ <div>
195
+ <div className="flex items-baseline gap-2 mb-1">
196
+ <span className="text-sm font-medium text-zinc-900 dark:text-zinc-100">{c.author_name || "Anonymous"}</span>
197
+ <span className="text-xs text-zinc-400">{formatWhen(c.created_at)}</span>
198
+ </div>
199
+ <p className="text-sm text-zinc-700 dark:text-zinc-300 whitespace-pre-wrap">{c.body}</p>
200
+ {onReply && (
201
+ <button
202
+ type="button"
203
+ onClick={onReply}
204
+ className="mt-1 text-xs text-zinc-500 dark:text-zinc-400 hover:text-zinc-800 underline"
205
+ >
206
+ Reply
207
+ </button>
208
+ )}
209
+ </div>
210
+ );
211
+ }
@@ -0,0 +1,117 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { getAuthorToken } from "../lib/author-token";
5
+
6
+ export interface SeoPageReactionsProps {
7
+ site: string;
8
+ pageSlug: string;
9
+ apiOrigin: string;
10
+ className?: string;
11
+ label?: string;
12
+ }
13
+
14
+ const REACTIONS = [
15
+ { key: "like", emoji: "👍", label: "Like" },
16
+ { key: "love", emoji: "❤️", label: "Love" },
17
+ { key: "insightful", emoji: "💡", label: "Insightful" },
18
+ { key: "clap", emoji: "👏", label: "Clap" },
19
+ { key: "laugh", emoji: "😂", label: "Funny" },
20
+ ] as const;
21
+
22
+ type ReactionKey = (typeof REACTIONS)[number]["key"];
23
+
24
+ export function SeoPageReactions({
25
+ site,
26
+ pageSlug,
27
+ apiOrigin,
28
+ className = "",
29
+ label = "How did this page land for you?",
30
+ }: SeoPageReactionsProps) {
31
+ const [counts, setCounts] = useState<Record<ReactionKey, number>>({
32
+ like: 0,
33
+ love: 0,
34
+ insightful: 0,
35
+ clap: 0,
36
+ laugh: 0,
37
+ });
38
+ const [mine, setMine] = useState<Set<ReactionKey>>(new Set());
39
+ const [token, setToken] = useState("");
40
+ const [busy, setBusy] = useState<ReactionKey | null>(null);
41
+
42
+ useEffect(() => {
43
+ setToken(getAuthorToken());
44
+ }, []);
45
+
46
+ const load = useCallback(async () => {
47
+ if (!token) return;
48
+ try {
49
+ const res = await fetch(
50
+ `${apiOrigin}/api/seo-page-reactions?site=${encodeURIComponent(site)}&page_slug=${encodeURIComponent(pageSlug)}&author_token=${encodeURIComponent(token)}`,
51
+ { cache: "no-store" }
52
+ );
53
+ if (!res.ok) return;
54
+ const data = (await res.json()) as { counts: Record<ReactionKey, number>; mine: ReactionKey[] };
55
+ setCounts(data.counts);
56
+ setMine(new Set(data.mine));
57
+ } catch {
58
+ // no-op
59
+ }
60
+ }, [apiOrigin, site, pageSlug, token]);
61
+
62
+ useEffect(() => {
63
+ load();
64
+ }, [load]);
65
+
66
+ async function toggle(reaction: ReactionKey) {
67
+ if (!token || busy) return;
68
+ const wasActive = mine.has(reaction);
69
+ setBusy(reaction);
70
+ const nextMine = new Set(mine);
71
+ if (wasActive) nextMine.delete(reaction);
72
+ else nextMine.add(reaction);
73
+ setMine(nextMine);
74
+ setCounts((c) => ({ ...c, [reaction]: Math.max(0, c[reaction] + (wasActive ? -1 : 1)) }));
75
+ try {
76
+ await fetch(`${apiOrigin}/api/seo-page-reactions`, {
77
+ method: wasActive ? "DELETE" : "POST",
78
+ headers: { "Content-Type": "application/json" },
79
+ body: JSON.stringify({ site, page_slug: pageSlug, author_token: token, reaction }),
80
+ });
81
+ await load();
82
+ } catch {
83
+ await load();
84
+ } finally {
85
+ setBusy(null);
86
+ }
87
+ }
88
+
89
+ return (
90
+ <div className={`seo-page-reactions mx-auto max-w-2xl my-8 ${className}`}>
91
+ {label && <p className="text-sm text-zinc-500 mb-2">{label}</p>}
92
+ <div className="flex flex-wrap gap-2">
93
+ {REACTIONS.map((r) => {
94
+ const active = mine.has(r.key);
95
+ return (
96
+ <button
97
+ key={r.key}
98
+ type="button"
99
+ onClick={() => toggle(r.key)}
100
+ disabled={busy !== null}
101
+ className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full border text-sm transition-colors ${
102
+ active
103
+ ? "border-[var(--seo-accent,#14b8a6)] text-[var(--seo-accent,#14b8a6)] bg-[var(--seo-accent-light,rgba(20,184,166,0.08))]"
104
+ : "border-zinc-200 text-zinc-700 hover:bg-zinc-50"
105
+ }`}
106
+ aria-pressed={active}
107
+ aria-label={r.label}
108
+ >
109
+ <span className="text-base leading-none">{r.emoji}</span>
110
+ <span className="font-medium tabular-nums">{counts[r.key]}</span>
111
+ </button>
112
+ );
113
+ })}
114
+ </div>
115
+ </div>
116
+ );
117
+ }
@@ -316,14 +316,14 @@ export function SitemapSidebar({
316
316
  {/* Page list */}
317
317
  <nav ref={navRef} className="flex-1 overflow-y-auto p-3">
318
318
  {filtered.length === 0 && (
319
- <p className="text-sm text-zinc-400 dark:text-zinc-500 px-3 py-4">No pages found</p>
319
+ <p className="text-sm text-zinc-400 dark:text-zinc-400 px-3 py-4">No pages found</p>
320
320
  )}
321
321
 
322
322
  {Array.from(groups.entries()).map(([category, categoryPages]) => (
323
323
  <div key={category} className="mb-4">
324
324
  {/* Category header (only show if more than one category) */}
325
325
  {groups.size > 1 && (
326
- <div className="px-3 py-1.5 text-xs font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider">
326
+ <div className="px-3 py-1.5 text-xs font-semibold text-zinc-400 dark:text-zinc-400 uppercase tracking-wider">
327
327
  {getCategoryLabel(category, categoryLabels)}
328
328
  </div>
329
329
  )}
@@ -339,7 +339,7 @@ export function SitemapSidebar({
339
339
  className={`block px-3 py-2.5 rounded-lg transition-colors ${
340
340
  isActive
341
341
  ? "text-zinc-900 dark:text-zinc-100 font-medium"
342
- : "text-zinc-600 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-zinc-900 hover:text-zinc-900 dark:hover:text-zinc-100"
342
+ : "text-zinc-600 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-900 hover:text-zinc-900 dark:hover:text-zinc-100"
343
343
  }`}
344
344
  style={
345
345
  isActive
@@ -355,7 +355,7 @@ export function SitemapSidebar({
355
355
  {page.title}
356
356
  </span>
357
357
  {page.datePublished && (
358
- <span className="text-[11px] text-zinc-400 dark:text-zinc-500 mt-0.5 block">
358
+ <span className="text-[11px] text-zinc-400 dark:text-zinc-400 mt-0.5 block">
359
359
  {page.datePublished}
360
360
  </span>
361
361
  )}
@@ -377,7 +377,7 @@ export function SitemapSidebar({
377
377
  className={`block pl-3 pr-2 py-1.5 -ml-px border-l-2 text-[13px] leading-snug transition-colors ${
378
378
  isSectionActive
379
379
  ? "font-medium"
380
- : "border-transparent text-zinc-500 dark:text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-100 hover:border-zinc-300 dark:hover:border-zinc-700"
380
+ : "border-transparent text-zinc-500 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-zinc-100 hover:border-zinc-300 dark:hover:border-zinc-700"
381
381
  }`}
382
382
  style={
383
383
  isSectionActive
@@ -32,7 +32,7 @@ export function StepTimeline({
32
32
  whileInView={{ opacity: 1, y: 0 }}
33
33
  viewport={{ once: true }}
34
34
  transition={{ duration: 0.4, ease: [0.16, 1, 0.3, 1] }}
35
- className="text-lg font-semibold text-zinc-900 mb-6"
35
+ className="text-lg font-semibold text-zinc-900 dark:text-zinc-100 mb-6"
36
36
  >
37
37
  {title}
38
38
  </motion.h3>
@@ -74,12 +74,12 @@ export function StepTimeline({
74
74
  stiffness: 300,
75
75
  damping: 20,
76
76
  }}
77
- className="absolute -left-8 top-1 w-6 h-6 rounded-full bg-teal-50 border-2 border-teal-400 flex items-center justify-center"
77
+ className="absolute -left-8 top-1 w-6 h-6 rounded-full bg-teal-50 dark:bg-teal-900/30 border-2 border-teal-400 flex items-center justify-center"
78
78
  >
79
79
  {step.icon ? (
80
80
  <span className="text-xs">{step.icon}</span>
81
81
  ) : (
82
- <span className="text-[10px] font-mono font-bold text-teal-600">
82
+ <span className="text-[10px] font-mono font-bold text-teal-600 dark:text-teal-400">
83
83
  {i + 1}
84
84
  </span>
85
85
  )}
@@ -87,14 +87,14 @@ export function StepTimeline({
87
87
 
88
88
  {/* Content */}
89
89
  <div>
90
- <h4 className="text-sm font-semibold text-zinc-900 mb-1">
90
+ <h4 className="text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-1">
91
91
  {step.title}
92
92
  </h4>
93
- <p className="text-sm text-zinc-500 leading-relaxed">
93
+ <p className="text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed">
94
94
  {step.description}
95
95
  </p>
96
96
  {step.detail && (
97
- <div className="mt-3 rounded-lg border border-zinc-100 bg-zinc-50 p-3 text-sm">
97
+ <div className="mt-3 rounded-lg border border-zinc-100 dark:border-zinc-900 bg-zinc-50 dark:bg-zinc-900/50 p-3 text-sm">
98
98
  {step.detail}
99
99
  </div>
100
100
  )}
package/src/index.ts CHANGED
@@ -67,6 +67,12 @@ export type { GuideChatPanelProps } from "./components/GuideChatPanel";
67
67
  export { NewsletterSignup } from "./components/NewsletterSignup";
68
68
  export type { NewsletterSignupProps } from "./components/NewsletterSignup";
69
69
 
70
+ // SEO page comments + reactions (public, anonymous, no signup)
71
+ export { SeoPageComments } from "./components/SeoPageComments";
72
+ export type { SeoPageCommentsProps } from "./components/SeoPageComments";
73
+ export { SeoPageReactions } from "./components/SeoPageReactions";
74
+ export type { SeoPageReactionsProps } from "./components/SeoPageReactions";
75
+
70
76
  // Server utilities: import from "@seo/components/server" instead
71
77
  // (walkPages, createGuideChatHandler, logAiUsage, discoverGuides, etc.)
72
78
 
@@ -0,0 +1,45 @@
1
+ const STORAGE_KEY = "seo_author_token";
2
+
3
+ function randomToken(): string {
4
+ const bytes = new Uint8Array(24);
5
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
6
+ crypto.getRandomValues(bytes);
7
+ } else {
8
+ for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
9
+ }
10
+ return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
11
+ }
12
+
13
+ export function getAuthorToken(): string {
14
+ if (typeof window === "undefined") return "";
15
+ try {
16
+ const existing = window.localStorage.getItem(STORAGE_KEY);
17
+ if (existing && /^[a-zA-Z0-9_-]{16,128}$/.test(existing)) return existing;
18
+ const fresh = randomToken();
19
+ window.localStorage.setItem(STORAGE_KEY, fresh);
20
+ return fresh;
21
+ } catch {
22
+ return randomToken();
23
+ }
24
+ }
25
+
26
+ const NAME_KEY = "seo_author_name";
27
+
28
+ export function getStoredName(): string {
29
+ if (typeof window === "undefined") return "";
30
+ try {
31
+ return window.localStorage.getItem(NAME_KEY) || "";
32
+ } catch {
33
+ return "";
34
+ }
35
+ }
36
+
37
+ export function setStoredName(name: string): void {
38
+ if (typeof window === "undefined") return;
39
+ try {
40
+ if (name) window.localStorage.setItem(NAME_KEY, name);
41
+ else window.localStorage.removeItem(NAME_KEY);
42
+ } catch {
43
+ // no-op
44
+ }
45
+ }