diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fe8f2f7fb88..2021b32e6ab 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -35,6 +35,7 @@ This serves two purposes: - Added new `npm run build` command for compiling frontend assets with Vite - Added a Vite HMR support for the realtime compiler in https://github.com/hydephp/develop/pull/2016 - Added Vite facade in https://github.com/hydephp/develop/pull/2016 +- Added a custom Blade-based heading renderer for Markdown conversions in https://github.com/hydephp/develop/pull/2047 ### Changed @@ -104,6 +105,8 @@ This serves two purposes: - Normalized default Tailwind Typography Prose code block styles to match Torchlight's theme, ensuring consistent styling across Markdown and Torchlight code blocks in https://github.com/hydephp/develop/pull/2036. - Extracted CSS component partials in HydeFront in https://github.com/hydephp/develop/pull/2038 - Replaced HydeFront styles with Tailwind in https://github.com/hydephp/develop/pull/2024 +- Markdown headings are now compiled using our custom Blade-based heading renderer in https://github.com/hydephp/develop/pull/2047 + - The `id` attributes for heading permalinks have been moved from the anchor to the heading element in https://github.com/hydephp/develop/pull/2052 ### Deprecated @@ -132,6 +135,8 @@ This serves two purposes: - This also removes the `` and `` Blade components, replaced by the new `` component. - Removed the `.torchlight-enabled` CSS class in https://github.com/hydephp/develop/pull/2036. - Removed The `hyde.css` file from HydeFront in https://github.com/hydephp/develop/pull/2037 as all styles were refactored to Tailwind in https://github.com/hydephp/develop/pull/2024. +- Removed the `MarkdownService::withPermalinks` method in https://github.com/hydephp/develop/pull/2047 +- Removed the `MarkdownService::canEnablePermalinks` method in https://github.com/hydephp/develop/pull/2047 ### Fixed @@ -522,6 +527,7 @@ The likelihood of impact is low, but if any of the following are true, you may n - Rewrites the `GeneratesTableOfContents` class to use a custom implementation instead of using CommonMark - The `execute` method of the `GeneratesTableOfContents` class now returns an array of data, instead of a string of HTML. This data should be fed into the new component - Removed the `table-of-contents.css` file as styles are now made using Tailwind +- Removed the `heading-permalinks.css` file as styles are now made using Tailwind ## New features diff --git a/_media/app.css b/_media/app.css index f97e07a2508..c1c986c0c9e 100644 --- a/_media/app.css +++ b/_media/app.css @@ -1 +1 @@ -.prose h1,.prose h2,.prose h3,.prose h4,.prose h5,.prose h6{width:-moz-fit-content;width:fit-content}.prose :is(h1,h2,h3,h4,h5,h6):hover .heading-permalink,.prose :is(h1,h2,h3,h4,h5,h6):focus .heading-permalink{opacity:.75;--tw-grayscale: grayscale(100%);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);transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.1s;transition-timing-function:cubic-bezier(0,0,.2,1)}.heading-permalink{margin-left:.25rem;scroll-margin:1rem;padding-left:.25rem;padding-right:.25rem;opacity:0;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s;transition-timing-function:linear}.heading-permalink:before{--tw-content: "#";content:var(--tw-content)}.heading-permalink:hover,.heading-permalink:focus{opacity:1;--tw-grayscale: grayscale(0);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)}pre code.torchlight .line-number,pre code.torchlight .summary-caret{margin-right:1rem}.prose .torchlight-link,.torchlight-link{text-decoration-line:underline}.torchlight.has-focus-lines .line:not(.line-focus){transition:filter .35s,opacity .35s;filter:blur(.095rem);opacity:.65}.torchlight.has-focus-lines:hover .line:not(.line-focus){filter:blur(0px);opacity:1}.torchlight summary:focus{outline:2px solid transparent;outline-offset:2px}.torchlight details>summary::marker,.torchlight details>summary::-webkit-details-marker{display:none}.torchlight details .summary-caret:after{pointer-events:none}.torchlight .summary-caret-empty:after,.torchlight details .summary-caret-middle:after,.torchlight details .summary-caret-end:after{content:" "}.torchlight details[open] .summary-caret-start:after{content:"-"}.torchlight details:not([open]) .summary-caret-start:after{content:"+"}.torchlight details[open] .summary-hide-when-open{display:none}.torchlight details:not([open]) .summary-hide-when-open{display:block}.prose blockquote.info{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.prose blockquote.success{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.prose blockquote.warning{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.prose blockquote.danger{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}*,:before,:after{--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: rgb(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: rgb(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: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{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,samp,pre{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,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{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}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{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}}.prose{color:var(--tw-prose-body);max-width:96ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:#5956eb;text-decoration:none;font-weight:500}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:#4f46e5}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:unset;color:unset;border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1em;margin-bottom:1em;padding-inline-start:1em;background-color:#80808020;border-left-color:#d1d5db;line-height:1.25em;padding-left:.75em;padding-top:.25em;padding-bottom:.25em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) p{padding-right:.25em;margin-top:.25em;margin-bottom:.25em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) p:before{content:unset}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) p:after{content:unset}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:1.5em;margin-bottom:.75em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows) / 10%),0 3px rgb(var(--tw-prose-kbd-shadows) / 10%);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:unset}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:unset}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:#292d3e;overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1rem;margin-bottom:1rem;border-radius:.25rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)) code{font-family:"Fira Code Regular",Consolas,Monospace,"Courier New"}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: 17 24 39;--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: 255 255 255;--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.5em}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose :where(code:not(pre code)):not(:where([class~=not-prose],[class~=not-prose] *)){font:unset;background-color:#80808033;padding-left:4px;padding-right:4px;margin-left:-2px;margin-right:1px;border-radius:4px;max-width:80vw;overflow-x:auto;vertical-align:top;word-break:break-all}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.-left-64{left:-16rem}.-top-1{top:-.25rem}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.left-80{left:20rem}.right-0{right:0}.right-1{right:.25rem}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-16{top:4rem}.top-2\.5{top:.625rem}.top-4{top:1rem}.top-auto{top:auto}.z-10{z-index:10}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.float-right{float:right}.float-left{float:left}.m-2{margin:.5rem}.m-8{margin:2rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-0{margin-left:0;margin-right:0}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-8{margin-left:2rem;margin-right:2rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-8{margin-top:2rem;margin-bottom:2rem}.my-auto{margin-top:auto;margin-bottom:auto}.-ml-2{margin-left:-.5rem}.-ml-4{margin-left:-1rem}.-ml-6{margin-left:-1.5rem}.-ml-8{margin-left:-2rem}.-mt-4{margin-top:-1rem}.mb-0{margin-bottom:0}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-4{margin-right:1rem}.mr-auto{margin-right:auto}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.\!block{display:block!important}.block{display:block}.inline{display:inline}.flex{display:flex}.contents{display:contents}.hidden{display:none}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-16{height:4rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[75vh\]{max-height:75vh}.min-h-\[300px\]{min-height:300px}.min-h-\[calc\(100vh_-_4rem\)\]{min-height:calc(100vh - 4rem)}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-16{width:4rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-\[70ch\]{width:70ch}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-screen{width:100vw}.max-w-3xl{max-width:48rem}.max-w-7xl{max-width:80rem}.max-w-\[1000px\]{max-width:1000px}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-sm{max-width:24rem}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.origin-center{transform-origin:center}.-rotate-45{--tw-rotate: -45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-45{--tw-rotate: 45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-auto{cursor:auto}.cursor-pointer{cursor:pointer}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.scroll-smooth{scroll-behavior:smooth}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border-2{border-width:2px}.border-4{border-width:4px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-l-\[0\.325rem\]{border-left-width:.325rem}.border-t{border-top-width:1px}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-500{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1))}.border-indigo-500{--tw-border-opacity: 1;border-color:rgb(89 86 235 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-yellow-400{--tw-border-opacity: 1;border-color:rgb(250 204 21 / var(--tw-border-opacity, 1))}.border-t-transparent{border-top-color:transparent}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/5{background-color:#0000000d}.bg-black\/50{background-color:#00000080}.bg-current{background-color:currentColor}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / 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-yellow-400{--tw-bg-opacity: 1;background-color:rgb(250 204 21 / var(--tw-bg-opacity, 1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-cover{background-size:cover}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-no-repeat{background-repeat:no-repeat}.fill-black{fill:#000}.fill-current{fill:currentColor}.p-0{padding:0}.p-12{padding:3rem}.p-2{padding:.5rem}.p-4{padding:1rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-32{padding-top:8rem;padding-bottom:8rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-12{padding-bottom:3rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pl-2{padding-left:.5rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-8{padding-left:2rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.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-5xl{font-size:3rem;line-height:1}.text-\[75\%\]{font-size:75%}.text-\[90\%\]{font-size:90%}.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}.font-black{font-weight:900}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-light{font-weight:300}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-10{line-height:2.5rem}.leading-8{line-height:2rem}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-indigo-500{--tw-text-opacity: 1;color:rgb(89 86 235 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / 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))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(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)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.drop-shadow-2xl{--tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / .15));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)}.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}.duration-300{transition-duration:.3s}.duration-75{transition-duration:75ms}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.dark\:prose-invert:is(.dark *){--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:#818cf8}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:#6366f1}.hover\:bg-black\/10:hover{background-color:#0000001a}.hover\:bg-black\/5:hover{background-color:#0000000d}.hover\:bg-gray-200\/20:hover{background-color:#e5e7eb33}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-900:hover{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.focus\:absolute:focus{position:absolute}.focus\:mx-auto:focus{margin-left:auto;margin-right:auto}.focus\:mt-2:focus{margin-top:.5rem}.focus\:w-64:focus{width:16rem}.focus\:p-2:focus{padding:.5rem}.group:hover .group-hover\:opacity-100{opacity:1}.prose-h1\:mb-3 :is(:where(h1):not(:where([class~=not-prose],[class~=not-prose] *))){margin-bottom:.75rem}.prose-p\:my-3 :is(:where(p):not(:where([class~=not-prose],[class~=not-prose] *))){margin-top:.75rem;margin-bottom:.75rem}.prose-img\:inline :is(:where(img):not(:where([class~=not-prose],[class~=not-prose] *))){display:inline}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-\[\#1b2533\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(27 37 51 / var(--tw-border-opacity, 1))}.dark\:border-gray-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.dark\:bg-black\/10:is(.dark *){background-color:#0000001a}.dark\:bg-gray-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-yellow-300:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(253 224 71 / var(--tw-bg-opacity, 1))}.dark\:fill-gray-200:is(.dark *){fill:#e5e7eb}.dark\:fill-white:is(.dark *){fill:#fff}.dark\:font-medium:is(.dark *){font-weight:500}.dark\:text-gray-100:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:text-gray-200:is(.dark *){--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-indigo-400:is(.dark *){--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.dark\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:hover\:bg-black\/10:hover:is(.dark *){background-color:#0000001a}.dark\:hover\:text-white:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.group:hover .dark\:group-hover\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:mb-0{margin-bottom:0}.sm\:mt-4{margin-top:1rem}.sm\:block{display:block}.sm\:leading-none{line-height:1}.sm\:shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}}@media (min-width: 768px){.md\:visible{visibility:visible}.md\:left-0{left:0}.md\:left-64{left:16rem}.md\:top-0{top:0}.md\:mx-2{margin-left:.5rem;margin-right:.5rem}.md\:my-0{margin-top:0;margin-bottom:0}.md\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.md\:mb-12{margin-bottom:3rem}.md\:ml-0{margin-left:0}.md\:mt-0{margin-top:0}.md\:mt-8{margin-top:2rem}.md\:block{display:block}.md\:inline-block{display:inline-block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:min-h-screen{min-height:100vh}.md\:w-1\/2{width:50%}.md\:w-\[calc\(100vw_-_16rem\)\]{width:calc(100vw - 16rem)}.md\:w-auto{width:auto}.md\:max-w-2xl{max-width:42rem}.md\:max-w-none{max-width:none}.md\:flex-grow{flex-grow:1}.md\:flex-grow-0{flex-grow:0}.md\:items-center{align-items:center}.md\:border-none{border-style:none}.md\:bg-transparent{background-color:transparent}.md\:bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.md\:bg-left{background-position:left}.md\:px-16{padding-left:4rem;padding-right:4rem}.md\:py-0{padding-top:0;padding-bottom:0}.md\:py-16{padding-top:4rem;padding-bottom:4rem}.md\:pb-0{padding-bottom:0}.md\:pl-0{padding-left:0}.md\:text-center{text-align:center}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:md\:bg-transparent:is(.dark *){background-color:transparent}}@media (min-width: 1024px){.lg\:mb-12{margin-bottom:3rem}.lg\:ml-8{margin-left:2rem}.lg\:bg-center{background-position:center}.lg\:text-5xl{font-size:3rem;line-height:1}.lg\:text-7xl{font-size:4.5rem;line-height:1}.lg\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media (min-width: 1280px){.xl\:mb-16{margin-bottom:4rem}}@media print{.print\:top-0{top:0}.print\:hidden{display:none}} +pre code.torchlight .line-number,pre code.torchlight .summary-caret{margin-right:1rem}.prose .torchlight-link,.torchlight-link{text-decoration-line:underline}.torchlight.has-focus-lines .line:not(.line-focus){transition:filter .35s,opacity .35s;filter:blur(.095rem);opacity:.65}.torchlight.has-focus-lines:hover .line:not(.line-focus){filter:blur(0px);opacity:1}.torchlight summary:focus{outline:2px solid transparent;outline-offset:2px}.torchlight details>summary::marker,.torchlight details>summary::-webkit-details-marker{display:none}.torchlight details .summary-caret:after{pointer-events:none}.torchlight .summary-caret-empty:after,.torchlight details .summary-caret-middle:after,.torchlight details .summary-caret-end:after{content:" "}.torchlight details[open] .summary-caret-start:after{content:"-"}.torchlight details:not([open]) .summary-caret-start:after{content:"+"}.torchlight details[open] .summary-hide-when-open{display:none}.torchlight details:not([open]) .summary-hide-when-open{display:block}.prose blockquote.info{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.prose blockquote.success{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.prose blockquote.warning{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.prose blockquote.danger{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}*,:before,:after{--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: rgb(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: rgb(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: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{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,samp,pre{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,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{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}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{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}}.prose{color:var(--tw-prose-body);max-width:96ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:#5956eb;text-decoration:none;font-weight:500}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:#4f46e5}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:unset;color:unset;border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1em;margin-bottom:1em;padding-inline-start:1em;background-color:#80808020;border-left-color:#d1d5db;line-height:1.25em;padding-left:.75em;padding-top:.25em;padding-bottom:.25em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) p{padding-right:.25em;margin-top:.25em;margin-bottom:.25em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) p:before{content:unset}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) p:after{content:unset}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:1.5em;margin-bottom:.75em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows) / 10%),0 3px rgb(var(--tw-prose-kbd-shadows) / 10%);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:unset}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:unset}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:#292d3e;overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1rem;margin-bottom:1rem;border-radius:.25rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)) code{font-family:"Fira Code Regular",Consolas,Monospace,"Courier New"}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: 17 24 39;--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: 255 255 255;--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.5em}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose :where(code:not(pre code)):not(:where([class~=not-prose],[class~=not-prose] *)){font:unset;background-color:#80808033;padding-left:4px;padding-right:4px;margin-left:-2px;margin-right:1px;border-radius:4px;max-width:80vw;overflow-x:auto;vertical-align:top;word-break:break-all}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.-left-64{left:-16rem}.-top-1{top:-.25rem}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.left-80{left:20rem}.right-0{right:0}.right-1{right:.25rem}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-16{top:4rem}.top-2\.5{top:.625rem}.top-4{top:1rem}.top-auto{top:auto}.z-10{z-index:10}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.float-right{float:right}.float-left{float:left}.m-2{margin:.5rem}.m-8{margin:2rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-0{margin-left:0;margin-right:0}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-8{margin-left:2rem;margin-right:2rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-8{margin-top:2rem;margin-bottom:2rem}.my-auto{margin-top:auto;margin-bottom:auto}.-ml-2{margin-left:-.5rem}.-ml-4{margin-left:-1rem}.-ml-6{margin-left:-1.5rem}.-ml-8{margin-left:-2rem}.-mt-4{margin-top:-1rem}.mb-0{margin-bottom:0}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-4{margin-right:1rem}.mr-auto{margin-right:auto}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.\!block{display:block!important}.block{display:block}.inline{display:inline}.flex{display:flex}.contents{display:contents}.hidden{display:none}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-16{height:4rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[75vh\]{max-height:75vh}.min-h-\[300px\]{min-height:300px}.min-h-\[calc\(100vh_-_4rem\)\]{min-height:calc(100vh - 4rem)}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-16{width:4rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-\[70ch\]{width:70ch}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-screen{width:100vw}.max-w-3xl{max-width:48rem}.max-w-7xl{max-width:80rem}.max-w-\[1000px\]{max-width:1000px}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-sm{max-width:24rem}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.origin-center{transform-origin:center}.-rotate-45{--tw-rotate: -45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-45{--tw-rotate: 45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-auto{cursor:auto}.cursor-pointer{cursor:pointer}.scroll-mt-2{scroll-margin-top:.5rem}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.scroll-smooth{scroll-behavior:smooth}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border-2{border-width:2px}.border-4{border-width:4px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-l-\[0\.325rem\]{border-left-width:.325rem}.border-t{border-top-width:1px}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-500{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1))}.border-indigo-500{--tw-border-opacity: 1;border-color:rgb(89 86 235 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-yellow-400{--tw-border-opacity: 1;border-color:rgb(250 204 21 / var(--tw-border-opacity, 1))}.border-t-transparent{border-top-color:transparent}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/5{background-color:#0000000d}.bg-black\/50{background-color:#00000080}.bg-current{background-color:currentColor}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / 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-yellow-400{--tw-bg-opacity: 1;background-color:rgb(250 204 21 / var(--tw-bg-opacity, 1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-cover{background-size:cover}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-no-repeat{background-repeat:no-repeat}.fill-black{fill:#000}.fill-current{fill:currentColor}.p-0{padding:0}.p-12{padding:3rem}.p-2{padding:.5rem}.p-4{padding:1rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-32{padding-top:8rem;padding-bottom:8rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-12{padding-bottom:3rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pl-2{padding-left:.5rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-8{padding-left:2rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.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-5xl{font-size:3rem;line-height:1}.text-\[75\%\]{font-size:75%}.text-\[90\%\]{font-size:90%}.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}.font-black{font-weight:900}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-light{font-weight:300}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-10{line-height:2.5rem}.leading-8{line-height:2rem}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-indigo-500{--tw-text-opacity: 1;color:rgb(89 86 235 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / 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))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(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)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.drop-shadow-2xl{--tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / .15));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)}.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}.duration-300{transition-duration:.3s}.duration-75{transition-duration:75ms}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-linear{transition-timing-function:linear}.dark\:prose-invert:is(.dark *){--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:#818cf8}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:#6366f1}.hover\:bg-black\/10:hover{background-color:#0000001a}.hover\:bg-black\/5:hover{background-color:#0000000d}.hover\:bg-gray-200\/20:hover{background-color:#e5e7eb33}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-900:hover{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.focus\:absolute:focus{position:absolute}.focus\:mx-auto:focus{margin-left:auto;margin-right:auto}.focus\:mt-2:focus{margin-top:.5rem}.focus\:w-64:focus{width:16rem}.focus\:p-2:focus{padding:.5rem}.focus\:opacity-100:focus{opacity:1}.focus\:grayscale-0:focus{--tw-grayscale: grayscale(0);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)}.group:hover .group-hover\:opacity-100{opacity:1}.group:hover .group-hover\:grayscale-0{--tw-grayscale: grayscale(0);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)}.prose-h1\:mb-3 :is(:where(h1):not(:where([class~=not-prose],[class~=not-prose] *))){margin-bottom:.75rem}.prose-p\:my-3 :is(:where(p):not(:where([class~=not-prose],[class~=not-prose] *))){margin-top:.75rem;margin-bottom:.75rem}.prose-img\:inline :is(:where(img):not(:where([class~=not-prose],[class~=not-prose] *))){display:inline}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-\[\#1b2533\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(27 37 51 / var(--tw-border-opacity, 1))}.dark\:border-gray-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.dark\:bg-black\/10:is(.dark *){background-color:#0000001a}.dark\:bg-gray-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-yellow-300:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(253 224 71 / var(--tw-bg-opacity, 1))}.dark\:fill-gray-200:is(.dark *){fill:#e5e7eb}.dark\:fill-white:is(.dark *){fill:#fff}.dark\:font-medium:is(.dark *){font-weight:500}.dark\:text-gray-100:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:text-gray-200:is(.dark *){--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-indigo-400:is(.dark *){--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.dark\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:hover\:bg-black\/10:hover:is(.dark *){background-color:#0000001a}.dark\:hover\:text-white:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.group:hover .dark\:group-hover\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:mb-0{margin-bottom:0}.sm\:mt-4{margin-top:1rem}.sm\:block{display:block}.sm\:leading-none{line-height:1}.sm\:shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}}@media (min-width: 768px){.md\:visible{visibility:visible}.md\:left-0{left:0}.md\:left-64{left:16rem}.md\:top-0{top:0}.md\:mx-2{margin-left:.5rem;margin-right:.5rem}.md\:my-0{margin-top:0;margin-bottom:0}.md\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.md\:mb-12{margin-bottom:3rem}.md\:ml-0{margin-left:0}.md\:mt-0{margin-top:0}.md\:mt-8{margin-top:2rem}.md\:block{display:block}.md\:inline-block{display:inline-block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:min-h-screen{min-height:100vh}.md\:w-1\/2{width:50%}.md\:w-\[calc\(100vw_-_16rem\)\]{width:calc(100vw - 16rem)}.md\:w-auto{width:auto}.md\:max-w-2xl{max-width:42rem}.md\:max-w-none{max-width:none}.md\:flex-grow{flex-grow:1}.md\:flex-grow-0{flex-grow:0}.md\:items-center{align-items:center}.md\:border-none{border-style:none}.md\:bg-transparent{background-color:transparent}.md\:bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.md\:bg-left{background-position:left}.md\:px-16{padding-left:4rem;padding-right:4rem}.md\:py-0{padding-top:0;padding-bottom:0}.md\:py-16{padding-top:4rem;padding-bottom:4rem}.md\:pb-0{padding-bottom:0}.md\:pl-0{padding-left:0}.md\:text-center{text-align:center}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:md\:bg-transparent:is(.dark *){background-color:transparent}}@media (min-width: 1024px){.lg\:mb-12{margin-bottom:3rem}.lg\:ml-8{margin-left:2rem}.lg\:bg-center{background-position:center}.lg\:text-5xl{font-size:3rem;line-height:1}.lg\:text-7xl{font-size:4.5rem;line-height:1}.lg\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media (min-width: 1280px){.xl\:mb-16{margin-bottom:4rem}}@media print{.print\:top-0{top:0}.print\:hidden{display:none}} diff --git a/config/markdown.php b/config/markdown.php index 0ec940714ab..cd9afdea0e5 100644 --- a/config/markdown.php +++ b/config/markdown.php @@ -95,4 +95,22 @@ */ 'prose_classes' => 'prose dark:prose-invert', + + /* + |-------------------------------------------------------------------------- + | Heading Permalinks Configuration + |-------------------------------------------------------------------------- + | + | Here you can specify which page classes should have heading permalinks. + | By default, only documentation pages have permalinks enabled, but you + | are free to enable it for any kind of page by adding the page class. + | + */ + + 'permalinks' => [ + 'pages' => [ + \Hyde\Pages\DocumentationPage::class, + ], + ], + ]; diff --git a/docs/digging-deeper/advanced-markdown.md b/docs/digging-deeper/advanced-markdown.md index 2fe8bd3648d..6a2a0d52c98 100644 --- a/docs/digging-deeper/advanced-markdown.md +++ b/docs/digging-deeper/advanced-markdown.md @@ -161,6 +161,36 @@ anything within the path label will be rendered as HTML. This means you can add The filepaths are hidden on mobile devices using CSS to prevent them from overlapping with the code block. +## Heading Permalinks + +Hyde automatically adds clickable permalink anchors to headings in documentation pages. When you hover over a heading, a `#` link appears that you can click to get a direct link to that section. + +### Usage & Configuration + +The feature is enabled by default for documentation pages. When enabled, Hyde will automatically add permalink anchors to headings between levels 2-4 (h2-h4). The permalinks are hidden by default and appear when hovering over the heading. + +You can enable it for other page types by adding the page class to the `permalinks.pages` array in the `config/markdown.php` file, or disable it for all pages by setting the array to an empty array. + +```php +// filepath: config/markdown.php +'permalinks' => [ + 'pages' => [ + \Hyde\Pages\DocumentationPage::class, + ], +], +``` + +### Advanced Customization + +Under the hood, Hyde uses a custom Blade-based heading renderer when converting Markdown to HTML. This allows for more flexibility and customization compared to standard Markdown parsers. You can also publish and customize the Blade component used to render the headings: + +```bash +php hyde publish:components +``` + +This will copy the `markdown-heading.blade.php` component to your views directory where you can modify its markup and behavior. + + ## Dynamic Markdown Links HydePHP provides a powerful feature for automatically converting Markdown links to source files to the corresponding routes in the built site. diff --git a/packages/framework/config/markdown.php b/packages/framework/config/markdown.php index 0ec940714ab..cd9afdea0e5 100644 --- a/packages/framework/config/markdown.php +++ b/packages/framework/config/markdown.php @@ -95,4 +95,22 @@ */ 'prose_classes' => 'prose dark:prose-invert', + + /* + |-------------------------------------------------------------------------- + | Heading Permalinks Configuration + |-------------------------------------------------------------------------- + | + | Here you can specify which page classes should have heading permalinks. + | By default, only documentation pages have permalinks enabled, but you + | are free to enable it for any kind of page by adding the page class. + | + */ + + 'permalinks' => [ + 'pages' => [ + \Hyde\Pages\DocumentationPage::class, + ], + ], + ]; diff --git a/packages/framework/resources/views/components/markdown-heading.blade.php b/packages/framework/resources/views/components/markdown-heading.blade.php new file mode 100644 index 00000000000..c107780bb95 --- /dev/null +++ b/packages/framework/resources/views/components/markdown-heading.blade.php @@ -0,0 +1,25 @@ +@props([ + 'level' => 1, + 'id' => null, + 'extraAttributes' => [], + 'addPermalink' => config('markdown.permalinks.enabled', true), +]) + +@php + $tag = 'h' . $level; + $id = $id ?? \Illuminate\Support\Str::slug($slot); + + $extraAttributes = array_merge($extraAttributes, [ + 'id' => $addPermalink ? $id : ($extraAttributes['id'] ?? null), + 'class' => trim(($extraAttributes['class'] ?? '') . ($addPermalink ? ' group w-fit scroll-mt-2' : '')), + ]); +@endphp + +<{{ $tag }} {{ $attributes->merge($extraAttributes) }}> + {!! $slot !!} + @if($addPermalink === true) + + # + + @endif + diff --git a/packages/framework/src/Framework/Concerns/Internal/SetsUpMarkdownConverter.php b/packages/framework/src/Framework/Concerns/Internal/SetsUpMarkdownConverter.php index 307c2caa81d..73dc6ab4a1d 100644 --- a/packages/framework/src/Framework/Concerns/Internal/SetsUpMarkdownConverter.php +++ b/packages/framework/src/Framework/Concerns/Internal/SetsUpMarkdownConverter.php @@ -25,10 +25,6 @@ trait SetsUpMarkdownConverter { protected function enableDynamicExtensions(): void { - if ($this->canEnablePermalinks()) { - $this->configurePermalinksExtension(); - } - if ($this->canEnableTorchlight()) { $this->addExtension(TorchlightExtension::class); } diff --git a/packages/framework/src/Framework/Services/MarkdownService.php b/packages/framework/src/Framework/Services/MarkdownService.php index 9eb8bc8fc79..a0125ae6c18 100644 --- a/packages/framework/src/Framework/Services/MarkdownService.php +++ b/packages/framework/src/Framework/Services/MarkdownService.php @@ -7,13 +7,14 @@ use Hyde\Facades\Config; use Hyde\Facades\Features; use Hyde\Markdown\Models\MarkdownDocument; +use Hyde\Markdown\Processing\HeadingRenderer; use Hyde\Framework\Concerns\Internal\SetsUpMarkdownConverter; use Hyde\Pages\DocumentationPage; use Hyde\Markdown\MarkdownConverter; use Hyde\Markdown\Contracts\MarkdownPreProcessorContract as PreProcessor; use Hyde\Markdown\Contracts\MarkdownPostProcessorContract as PostProcessor; -use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension; use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension; +use League\CommonMark\Extension\CommonMark\Node\Block\Heading; use function str_contains; use function str_replace; @@ -54,6 +55,9 @@ class MarkdownService /** @var array> */ protected array $postprocessors = []; + /** @var array */ + protected array $headingRegistry = []; + public function __construct(string $markdown, ?string $pageClass = null) { $this->pageClass = $pageClass; @@ -87,6 +91,8 @@ protected function setupConverter(): void $this->initializeExtension($extension); } + $this->configureCustomHeadingRenderer(); + $this->registerPreProcessors(); $this->registerPostProcessors(); } @@ -141,13 +147,6 @@ public function addFeature(string $feature): static return $this; } - public function withPermalinks(): static - { - $this->addFeature('permalinks'); - - return $this; - } - public function isDocumentationPage(): bool { return isset($this->pageClass) && $this->pageClass === DocumentationPage::class; @@ -166,19 +165,6 @@ public function canEnableTorchlight(): bool Features::hasTorchlight(); } - public function canEnablePermalinks(): bool - { - if ($this->hasFeature('permalinks')) { - return true; - } - - if ($this->isDocumentationPage() && DocumentationPage::hasTableOfContents()) { - return true; - } - - return false; - } - public function hasFeature(string $feature): bool { return in_array($feature, $this->features); @@ -200,22 +186,6 @@ protected function injectTorchlightAttribution(): string )); } - protected function configurePermalinksExtension(): void - { - $this->addExtension(HeadingPermalinkExtension::class); - - $this->config = array_merge([ - 'heading_permalink' => [ - 'id_prefix' => '', - 'fragment_prefix' => '', - 'symbol' => '', - 'insert' => 'after', - 'min_heading_level' => 2, - 'aria_hidden' => false, - ], - ], $this->config); - } - protected function enableAllHtmlElements(): void { $this->addExtension(DisallowedRawHtmlExtension::class); @@ -272,4 +242,10 @@ protected static function findLineContentPositions(array $lines): array return [0, 0]; } + + protected function configureCustomHeadingRenderer(): void + { + $environment = $this->converter->getEnvironment(); + $environment->addRenderer(Heading::class, new HeadingRenderer($this->pageClass, $this->headingRegistry)); + } } diff --git a/packages/framework/src/Markdown/Processing/HeadingRenderer.php b/packages/framework/src/Markdown/Processing/HeadingRenderer.php new file mode 100644 index 00000000000..397936b16b5 --- /dev/null +++ b/packages/framework/src/Markdown/Processing/HeadingRenderer.php @@ -0,0 +1,92 @@ + */ + protected ?string $pageClass = null; + + /** @var array */ + protected array $headingRegistry = []; + + /** @param ?class-string<\Hyde\Pages\Concerns\HydePage> $pageClass */ + public function __construct(string $pageClass = null, array &$headingRegistry = []) + { + $this->pageClass = $pageClass; + $this->headingRegistry = &$headingRegistry; + } + + public function render(Node $node, ChildNodeRendererInterface $childRenderer): string + { + if (! ($node instanceof Heading)) { + throw new \InvalidArgumentException('Incompatible node type: '.get_class($node)); + } + + $content = $childRenderer->renderNodes($node->children()); + + $rendered = view('hyde::components.markdown-heading', [ + 'level' => $node->getLevel(), + 'slot' => $content, + 'id' => $this->makeHeadingId($content), + 'addPermalink' => $this->canAddPermalink($content, $node->getLevel()), + 'extraAttributes' => $node->data->get('attributes'), + ])->render(); + + return $this->postProcess($rendered); + } + + /** @internal */ + public function canAddPermalink(string $content, int $level): bool + { + return config('markdown.permalinks.enabled', true) + && $level >= config('markdown.permalinks.min_level', 2) + && $level <= config('markdown.permalinks.max_level', 6) + && ! str_contains($content, 'class="heading-permalink"') + && in_array($this->pageClass, config('markdown.permalinks.pages', [DocumentationPage::class])); + } + + /** @internal */ + public function postProcess(string $html): string + { + $html = str_replace('class=""', '', $html); + $html = preg_replace('//', '', $html); + + return implode('', array_map('trim', explode("\n", $html))); + } + + protected function makeHeadingId(string $contents): string + { + $identifier = $this->ensureIdentifierIsUnique(Str::slug($contents)); + + $this->headingRegistry[] = $identifier; + + return $identifier; + } + + protected function ensureIdentifierIsUnique(string $slug): string + { + $identifier = $slug; + $suffix = 2; + + while (in_array($identifier, $this->headingRegistry)) { + $identifier = $slug.'-'.$suffix++; + } + + return $identifier; + } +} diff --git a/packages/framework/tests/Feature/MarkdownHeadingRendererTest.php b/packages/framework/tests/Feature/MarkdownHeadingRendererTest.php new file mode 100644 index 00000000000..f69d07a9e2a --- /dev/null +++ b/packages/framework/tests/Feature/MarkdownHeadingRendererTest.php @@ -0,0 +1,289 @@ +parse(); + + $this->assertStringContainsString('

Heading 1

', $html); + $this->assertStringContainsString('

Heading 2

', $html); + $this->assertStringContainsString('

Heading 3

', $html); + $this->assertStringContainsString('

Heading 4

', $html); + $this->assertStringContainsString('
Heading 5
', $html); + $this->assertStringContainsString('
Heading 6
', $html); + + $this->assertSame(<<<'HTML' +

Heading 1

+

Heading 2

+

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
+ + HTML, $html); + } + + public function testPermalinksInDocumentationPages() + { + $markdown = '## Documentation Heading'; + $html = (new MarkdownService($markdown, DocumentationPage::class))->parse(); + + $this->assertStringContainsString('heading-permalink', $html); + $this->assertStringContainsString('id="documentation-heading"', $html); + $this->assertStringContainsString('href="#documentation-heading"', $html); + $this->assertStringContainsString('title="Permalink"', $html); + // $this->assertStringContainsString('aria-label="Permalink to this heading"', $html); + + $this->assertSame(<<<'HTML' +

Documentation Heading#

+ + HTML, $html); + } + + public function testPermalinksAreNotAddedToRegularMarkdownPages() + { + $markdown = '## Regular Page Heading'; + $html = (new MarkdownService($markdown, MarkdownPage::class))->parse(); + + $this->assertStringNotContainsString('heading-permalink', $html); + } + + public function testSetextStyleHeadings() + { + $markdown = <<<'MARKDOWN' + Heading 1 + ========= + + Heading 2 + --------- + MARKDOWN; + + $html = (new MarkdownService($markdown))->parse(); + + $this->assertStringContainsString('

Heading 1

', $html); + $this->assertStringContainsString('

Heading 2

', $html); + } + + public function testHeadingsWithCustomAttributes() + { + $markdown = <<<'MARKDOWN' + ## Heading {.custom-class #custom-id} + ### Another Heading {data-test="value"} + MARKDOWN; + + $html = (new MarkdownService($markdown, MarkdownPage::class))->parse(); + + $this->assertStringContainsString('id="custom-id"', $html); + $this->assertStringContainsString('class="custom-class"', $html); + $this->assertStringContainsString('data-test="value"', $html); + + $this->assertSame(<<<'HTML' +

Heading

+

Another Heading

+ + HTML, $html); + } + + public function testHeadingsWithCustomAttributesAndPermalinks() + { + $markdown = <<<'MARKDOWN' + ## Heading {.custom-class} + ### Another Heading {data-test="value"} + MARKDOWN; + + $html = (new MarkdownService($markdown, DocumentationPage::class))->parse(); + + $this->assertStringContainsString('class="custom-class group w-fit scroll-mt-2"', $html); + $this->assertStringContainsString('data-test="value"', $html); + + $this->assertSame(<<<'HTML' +

Heading#

+

Another Heading#

+ + HTML, $html); + } + + public function testPermalinkConfigurationLevels() + { + config(['markdown.permalinks.min_level' => 2]); + config(['markdown.permalinks.max_level' => 4]); + + $markdown = <<<'MARKDOWN' + # H1 No Permalink + ## H2 Has Permalink + ### H3 Has Permalink + #### H4 Has Permalink + ##### H5 No Permalink + ###### H6 No Permalink + MARKDOWN; + + $html = (new MarkdownService($markdown, DocumentationPage::class))->parse(); + + $this->assertStringNotContainsString('

H1 No Permalink

assertStringContainsString('