@timqi/pier 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-400:oklch(70.4% .191 22.216);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-500:oklch(72.3% .219 149.579);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-cyan-50:oklch(98.4% .019 200.873);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-200:oklch(91.7% .08 205.041);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-700:oklch(52% .105 223.128);--color-cyan-800:oklch(45% .085 224.283);--color-sky-50:oklch(97.7% .013 236.62);--color-sky-200:oklch(90.1% .058 230.902);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-700:oklch(50% .134 242.749);--color-blue-700:oklch(48.8% .243 264.376);--color-indigo-50:oklch(96.2% .018 272.314);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-200:oklch(87% .065 274.039);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-indigo-800:oklch(39.8% .195 277.366);--color-violet-50:oklch(96.9% .016 293.756);--color-violet-200:oklch(89.4% .057 293.283);--color-violet-700:oklch(49.1% .27 292.581);--color-neutral-50:oklch(98.5% 0 none);--color-neutral-100:oklch(97% 0 none);--color-neutral-200:oklch(92.2% 0 none);--color-neutral-300:oklch(87% 0 none);--color-neutral-400:oklch(70.8% 0 none);--color-neutral-500:oklch(55.6% 0 none);--color-neutral-600:oklch(43.9% 0 none);--color-neutral-700:oklch(37.1% 0 none);--color-neutral-800:oklch(26.9% 0 none);--color-neutral-900:oklch(20.5% 0 none);--color-neutral-950:oklch(14.5% 0 none);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wide:.025em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-xs:.125rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components{.btn{cursor:pointer;border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-300);background-color:var(--color-white);padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.btn:hover{background-color:var(--color-neutral-100)}}.btn:active{background-color:var(--color-neutral-200)}.btn:disabled{cursor:not-allowed;opacity:.45}@media (hover:hover){.btn:disabled:hover{background-color:var(--color-white)}}.btn-primary{border-color:var(--color-indigo-600);background-color:var(--color-indigo-600);color:var(--color-white);--tw-shadow-color:#4f39f633}@supports (color:color-mix(in lab, red, red)){.btn-primary{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-indigo-600) 20%, transparent) var(--tw-shadow-alpha), transparent)}}@media (hover:hover){.btn-primary:hover{background-color:var(--color-indigo-500)}}.btn-primary:active{background-color:var(--color-indigo-700)}.btn-primary:where([data-theme=dark],[data-theme=dark] *){color:var(--color-neutral-50)}.select{cursor:pointer;appearance:none;background-color:var(--color-white);padding-right:calc(var(--spacing) * 8);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23737373' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M4.5 6.25 8 9.75l3.5-3.5'/></svg>");background-position:right .5rem center;background-repeat:no-repeat;background-size:.9rem}.icon-btn{height:calc(var(--spacing) * 5);width:calc(var(--spacing) * 5);cursor:pointer;color:var(--color-neutral-400);border-radius:.25rem;flex:none;justify-content:center;align-items:center;display:flex}@media (hover:hover){.icon-btn:hover{background-color:var(--color-neutral-200);color:var(--color-neutral-700)}}.tabstrip{align-items:center;gap:var(--spacing);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-neutral-200);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);white-space:nowrap;flex:none;display:flex;overflow-x:auto}@media not all and (width>=48rem){.tabstrip{row-gap:calc(var(--spacing) * 2);flex-wrap:wrap}}.lightbox-nav{height:calc(var(--spacing) * 10);width:calc(var(--spacing) * 10);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;background-color:#00000073;border-radius:2147483647px;justify-content:center;align-items:center;display:flex;position:absolute;top:50%}@supports (color:color-mix(in lab, red, red)){.lightbox-nav{background-color:color-mix(in oklab, var(--color-black) 45%, transparent)}}.lightbox-nav{--tw-leading:1;color:var(--color-white);font-size:1.5rem;line-height:1}@media (hover:hover){.lightbox-nav:hover{background-color:#000000b3}@supports (color:color-mix(in lab, red, red)){.lightbox-nav:hover{background-color:color-mix(in oklab, var(--color-black) 70%, transparent)}}}.lightbox-nav:where([data-theme=dark],[data-theme=dark] *){color:var(--color-neutral-950)}summary{list-style-type:none}summary::-webkit-details-marker{display:none}.chev{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;flex:none;font-size:10px;transition-duration:.15s;display:inline-block}details[open]>summary .chev{transform:rotate(90deg)}.spinner{height:calc(var(--spacing) * 3);width:calc(var(--spacing) * 3);animation:var(--animate-spin);border-style:var(--tw-border-style);border-width:2px;border-color:#0000 currentColor currentColor;border-radius:2147483647px;flex:none}.skeleton{animation:var(--animate-pulse);background-color:var(--color-neutral-200);border-radius:.25rem}.thumb{height:calc(var(--spacing) * 16);width:calc(var(--spacing) * 16);cursor:zoom-in;border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:#0000000d;display:inline-block}@supports (color:color-mix(in lab, red, red)){.thumb{border-color:color-mix(in oklab, var(--color-black) 5%, transparent)}}.thumb{background-color:#00000005}@supports (color:color-mix(in lab, red, red)){.thumb{background-color:color-mix(in oklab, var(--color-black) 2%, transparent)}}.thumb{object-fit:contain;vertical-align:middle}.thumb:where([data-theme=dark],[data-theme=dark] *){border-color:var(--color-neutral-200);background-color:var(--color-neutral-100)}.thumbs{margin-top:calc(var(--spacing) * 1.5);align-items:center;gap:calc(var(--spacing) * 1.5);flex-wrap:wrap;display:flex}.help code{background-color:var(--color-neutral-100);padding-inline:var(--spacing);font-family:var(--font-mono);color:var(--color-neutral-700);border-radius:.25rem;padding-block:1px;font-size:11.5px}.help a{color:var(--color-indigo-600);text-decoration-line:underline}.help em{font-style:italic}.md{color:var(--tw-prose-body);max-width:65ch}.md :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.md :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.md :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.md :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.md :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.md :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.md :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.md :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.md :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.md :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.md :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.md :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.md :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.md :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.md :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.md :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.md :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.md :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.md :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.md :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}.md :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.md :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.md :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.md :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.md :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.md :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.md :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.md :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.md :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.md :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.md :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.md :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.md :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.md :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.md :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows), 0 3px 0 var(--tw-prose-kbd-shadows);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.md :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.md :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.md :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.md :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.md :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.md :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.md :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.md :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.md :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.md :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.md :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.md :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.md :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.md :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.md :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.md :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.md :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.md :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.md :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.md :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.md :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.md :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.md{--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:oklab(21% -.00316127 -.0338527/.1);--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1rem;line-height:1.75}.md :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.md :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.md :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.md :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.md :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.md :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.md :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.md :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.md :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.md :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.md :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.md :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.md :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.md :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.md :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.md :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.md :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.md :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.md :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.md :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.md :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.md{--tw-prose-body:var(--color-neutral-900);--tw-prose-headings:var(--color-neutral-900);--tw-prose-lead:oklch(43.9% 0 none);--tw-prose-links:var(--color-neutral-900);--tw-prose-bold:var(--color-neutral-900);--tw-prose-counters:oklch(55.6% 0 none);--tw-prose-bullets:oklch(87% 0 none);--tw-prose-hr:oklch(92.2% 0 none);--tw-prose-quotes:var(--color-neutral-900);--tw-prose-quote-borders:oklch(92.2% 0 none);--tw-prose-captions:oklch(55.6% 0 none);--tw-prose-kbd:var(--color-neutral-900);--tw-prose-kbd-shadows:#1717171a;--tw-prose-code:oklch(20.5% 0 none);--tw-prose-pre-code:oklch(92.2% 0 none);--tw-prose-pre-bg:oklch(26.9% 0 none);--tw-prose-th-borders:oklch(87% 0 none);--tw-prose-td-borders:oklch(92.2% 0 none);--tw-prose-invert-body:oklch(87% 0 none);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.8% 0 none);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.8% 0 none);--tw-prose-invert-bullets:oklch(43.9% 0 none);--tw-prose-invert-hr:oklch(37.1% 0 none);--tw-prose-invert-quotes:oklch(97% 0 none);--tw-prose-invert-quote-borders:oklch(37.1% 0 none);--tw-prose-invert-captions:oklch(70.8% 0 none);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:#ffffff1a;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87% 0 none);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(43.9% 0 none);--tw-prose-invert-td-borders:oklch(37.1% 0 none);max-width:none;font-size:inherit;line-height:inherit}@supports (color:color-mix(in lab, red, red)){.md{--tw-prose-kbd-shadows:color-mix(in oklab, var(--color-neutral-900) 10%, transparent)}}.md{--tw-prose-code:var(--color-neutral-900);--tw-prose-counters:var(--color-neutral-500);--tw-prose-captions:var(--color-neutral-500);--tw-prose-bullets:var(--color-neutral-300);--tw-prose-th-borders:var(--color-neutral-300);--tw-prose-hr:var(--color-neutral-200);--tw-prose-quote-borders:var(--color-neutral-200);--tw-prose-td-borders:var(--color-neutral-200)}.md p,.md ul,.md ol,.md pre,.md blockquote,.md table{margin-block:.5em}.md li{margin-block:.1em}.md li>p,.md :is(ul,ol) :is(ul,ol){margin-block:.2em}.md :first-child{margin-top:0}.md>:first-child:not(p,h1,h2,h3,h4,h5,h6){clear:left}.md :last-child{margin-bottom:0}.md :is(h1,h2,h3,h4,h5,h6){margin-block:.8em .2em;font-size:1em;font-weight:600;line-height:1.3}.md h1{font-size:1.22em}.md h2{font-size:1.12em}.md hr{margin-block:.9em}.md pre{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:#0000000f;overflow-x:auto}@supports (color:color-mix(in lab, red, red)){.md pre{border-color:color-mix(in oklab, var(--color-black) 6%, transparent)}}.md pre{background-color:#00000006}@supports (color:color-mix(in lab, red, red)){.md pre{background-color:color-mix(in oklab, var(--color-black) 2.5%, transparent)}}.md pre{padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:13px}.md pre:where([data-theme=dark],[data-theme=dark] *){border-color:var(--color-neutral-200);background-color:var(--color-neutral-100)}.md pre{color:var(--color-neutral-800)}.md :not(pre)>code{background-color:#0000000e;border-radius:.25rem}@supports (color:color-mix(in lab, red, red)){.md :not(pre)>code{background-color:color-mix(in oklab, var(--color-black) 5.5%, transparent)}}.md :not(pre)>code{padding-inline:var(--spacing);--tw-font-weight:var(--font-weight-normal);font-size:.9em;font-weight:var(--font-weight-normal);color:var(--color-neutral-800);padding-block:1px}.md :not(pre)>code:where([data-theme=dark],[data-theme=dark] *){background-color:var(--color-neutral-100)}.md :not(pre)>code:before,.md :not(pre)>code:after{content:none}.hljs-comment,.hljs-quote{color:var(--color-neutral-400);font-style:italic}.hljs-keyword,.hljs-literal,.hljs-selector-tag,.hljs-type{color:var(--color-violet-700)}.hljs-string,.hljs-regexp,.hljs-addition{color:var(--color-emerald-700)}.hljs-number,.hljs-symbol,.hljs-attr,.hljs-attribute,.hljs-meta{color:var(--color-amber-700)}.hljs-title,.hljs-section,.hljs-name{color:var(--color-blue-700)}.hljs-built_in,.hljs-variable,.hljs-template-variable{color:var(--color-cyan-700)}.hljs-deletion{color:var(--color-red-600)}.hljs-emphasis{font-style:italic}.hljs-strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-2{inset-inline:calc(var(--spacing) * 2)}.inset-y-0{inset-block:0}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.-top-2\.5{top:calc(var(--spacing) * -2.5)}.top-0{top:0}.top-1{top:var(--spacing)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-full{top:100%}.-right-1\.5{right:calc(var(--spacing) * -1.5)}.right-0{right:0}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.bottom-2{bottom:calc(var(--spacing) * 2)}.left-0{left:0}.left-2{left:calc(var(--spacing) * 2)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.float-left{float:left}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-auto{margin:auto}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-5{margin-inline:calc(var(--spacing) * 5)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.prose{color:var(--tw-prose-body);max-width:65ch}.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);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.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] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.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] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.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] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.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);margin-top:1.25em;font-weight:600}.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] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.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);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.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] *)){margin-top:2em;margin-bottom:2em;display:block}.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] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows), 0 3px 0 var(--tw-prose-kbd-shadows);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.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] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.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:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.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] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.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);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.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);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose{--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:oklab(21% -.00316127 -.0338527/.1);--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:#ffffff1a;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1rem;line-height:1.75}.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] *)),.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] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.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:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.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}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-\[3px\]{margin-top:3px}.mt-\[12vh\]{margin-top:12vh}.mr-2{margin-right:calc(var(--spacing) * 2)}.mr-auto{margin-right:auto}.mb-1{margin-bottom:var(--spacing)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-auto{margin-bottom:auto}.ml-1{margin-left:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-72{height:calc(var(--spacing) * 72)}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[6rem\]{max-height:6rem}.max-h-\[60vh\]{max-height:60vh}.max-h-\[65vh\]{max-height:65vh}.max-h-\[70dvh\]{max-height:70dvh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[88vh\]{max-height:88vh}.max-h-\[92vh\]{max-height:92vh}.max-h-\[min\(18rem\,40dvh\)\]{max-height:min(18rem,40dvh)}.min-h-0{min-height:0}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-2\/3{width:66.6667%}.w-2\/5{width:40%}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-3\/5{width:60%}.w-4{width:calc(var(--spacing) * 4)}.w-4\/5{width:80%}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-10{width:calc(var(--spacing) * 10)}.w-20{width:calc(var(--spacing) * 20)}.w-44{width:calc(var(--spacing) * 44)}.w-52{width:calc(var(--spacing) * 52)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[10\%\]{width:10%}.w-\[14\%\]{width:14%}.w-\[17\%\]{width:17%}.w-\[23\%\]{width:23%}.w-\[24\%\]{width:24%}.w-\[34\%\]{width:34%}.w-\[35rem\]{width:35rem}.w-\[38\%\]{width:38%}.w-\[38\.75rem\]{width:38.75rem}.w-\[38rem\]{width:38rem}.w-\[45rem\]{width:45rem}.w-\[min\(24rem\,92vw\)\]{width:min(24rem,92vw)}.w-\[min\(27rem\,calc\(100vw-3rem\)\)\]{width:min(27rem,100vw - 3rem)}.w-\[min\(32rem\,92vw\)\]{width:min(32rem,92vw)}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-48{max-width:calc(var(--spacing) * 48)}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-80{max-width:calc(var(--spacing) * 80)}.max-w-96{max-width:calc(var(--spacing) * 96)}.max-w-\[45\%\]{max-width:45%}.max-w-\[90vw\]{max-width:90vw}.max-w-\[92vw\]{max-width:92vw}.max-w-\[94vw\]{max-width:94vw}.max-w-\[min\(42rem\,calc\(100vw-1rem\)\)\]{max-width:min(42rem,100vw - 1rem)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-52{min-width:calc(var(--spacing) * 52)}.min-w-\[6\.5rem\]{min-width:6.5rem}.min-w-\[38rem\]{min-width:38rem}.min-w-\[52rem\]{min-width:52rem}.flex-1{flex:1}.flex-none{flex:none}.grow{flex-grow:1}.table-fixed{table-layout:fixed}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.cursor-zoom-out{cursor:zoom-out}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[6\.25rem_6\.25rem_1fr\]{grid-template-columns:6.25rem 6.25rem 1fr}.grid-cols-\[7\.5rem_1fr_7\.5rem_6\.25rem\]{grid-template-columns:7.5rem 1fr 7.5rem 6.25rem}.grid-cols-\[9\.375rem_minmax\(0\,1fr\)\]{grid-template-columns:9.375rem minmax(0,1fr)}.grid-cols-\[minmax\(8rem\,1fr\)_minmax\(8rem\,auto\)_minmax\(9rem\,auto\)\]{grid-template-columns:minmax(8rem,1fr) minmax(8rem,auto) minmax(9rem,auto)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-5{column-gap:calc(var(--spacing) * 5)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-1{row-gap:var(--spacing)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-neutral-100>:not(:last-child)){border-color:var(--color-neutral-100)}:where(.divide-neutral-200>:not(:last-child)){border-color:var(--color-neutral-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-200{border-color:var(--color-amber-200)}.border-black\/5{border-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.border-black\/5{border-color:color-mix(in oklab, var(--color-black) 5%, transparent)}}.border-black\/\[0\.08\]{border-color:#00000014}@supports (color:color-mix(in lab, red, red)){.border-black\/\[0\.08\]{border-color:color-mix(in oklab, var(--color-black) 8%, transparent)}}.border-cyan-200{border-color:var(--color-cyan-200)}.border-green-200{border-color:var(--color-green-200)}.border-indigo-200{border-color:var(--color-indigo-200)}.border-indigo-300{border-color:var(--color-indigo-300)}.border-indigo-400{border-color:var(--color-indigo-400)}.border-neutral-100{border-color:var(--color-neutral-100)}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-200\/70{border-color:#e5e5e5b3}@supports (color:color-mix(in lab, red, red)){.border-neutral-200\/70{border-color:color-mix(in oklab, var(--color-neutral-200) 70%, transparent)}}.border-neutral-300{border-color:var(--color-neutral-300)}.border-red-200{border-color:var(--color-red-200)}.border-l-cyan-500{border-left-color:var(--color-cyan-500)}.border-l-indigo-500{border-left-color:var(--color-indigo-500)}.border-l-red-400{border-left-color:var(--color-red-400)}.border-l-transparent{border-left-color:#0000}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-amber-100\/80{background-color:#fef3c6cc}@supports (color:color-mix(in lab, red, red)){.bg-amber-100\/80{background-color:color-mix(in oklab, var(--color-amber-100) 80%, transparent)}}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-black\/25{background-color:#00000040}@supports (color:color-mix(in lab, red, red)){.bg-black\/25{background-color:color-mix(in oklab, var(--color-black) 25%, transparent)}}.bg-black\/\[0\.04\]{background-color:#0000000a}@supports (color:color-mix(in lab, red, red)){.bg-black\/\[0\.04\]{background-color:color-mix(in oklab, var(--color-black) 4%, transparent)}}.bg-cyan-50{background-color:var(--color-cyan-50)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-200\/80{background-color:#a4f4cfcc}@supports (color:color-mix(in lab, red, red)){.bg-emerald-200\/80{background-color:color-mix(in oklab, var(--color-emerald-200) 80%, transparent)}}.bg-emerald-400{background-color:var(--color-emerald-400)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-500{background-color:var(--color-green-500)}.bg-indigo-50{background-color:var(--color-indigo-50)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-neutral-50{background-color:var(--color-neutral-50)}.bg-neutral-50\/60{background-color:#fafafa99}@supports (color:color-mix(in lab, red, red)){.bg-neutral-50\/60{background-color:color-mix(in oklab, var(--color-neutral-50) 60%, transparent)}}.bg-neutral-50\/70{background-color:#fafafab3}@supports (color:color-mix(in lab, red, red)){.bg-neutral-50\/70{background-color:color-mix(in oklab, var(--color-neutral-50) 70%, transparent)}}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-neutral-200{background-color:var(--color-neutral-200)}.bg-neutral-300{background-color:var(--color-neutral-300)}.bg-neutral-700{background-color:var(--color-neutral-700)}.bg-neutral-800{background-color:var(--color-neutral-800)}.bg-neutral-800\/95{background-color:#262626f2}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/95{background-color:color-mix(in oklab, var(--color-neutral-800) 95%, transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-200\/70{background-color:#ffcacab3}@supports (color:color-mix(in lab, red, red)){.bg-red-200\/70{background-color:color-mix(in oklab, var(--color-red-200) 70%, transparent)}}.bg-red-400{background-color:var(--color-red-400)}.bg-sky-50{background-color:var(--color-sky-50)}.bg-sky-500{background-color:var(--color-sky-500)}.bg-transparent{background-color:#0000}.bg-violet-50{background-color:var(--color-violet-50)}.bg-white{background-color:var(--color-white)}.bg-white\/15{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.bg-white\/15{background-color:color-mix(in oklab, var(--color-white) 15%, transparent)}}.bg-white\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-white\/85{background-color:color-mix(in oklab, var(--color-white) 85%, transparent)}}.object-contain{object-fit:contain}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3\.5{padding:calc(var(--spacing) * 3.5)}.p-4{padding:calc(var(--spacing) * 4)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-px{padding-block:1px}.pt-1{padding-top:var(--spacing)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2\.5{padding-bottom:calc(var(--spacing) * 2.5)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-\[calc\(0\.25rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(.25rem + env(safe-area-inset-bottom))}.pl-1{padding-left:var(--spacing)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-6{padding-left:calc(var(--spacing) * 6)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-\[9px\]{font-size:9px}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[20px\]{font-size:20px}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-\[1\.35\]{--tw-leading:1.35;line-height:1.35}.leading-\[1\.45\]{--tw-leading:1.45;line-height:1.45}.leading-\[1\.55\]{--tw-leading:1.55;line-height:1.55}.leading-\[18px\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-cyan-400{color:var(--color-cyan-400)}.text-cyan-700{color:var(--color-cyan-700)}.text-cyan-800{color:var(--color-cyan-800)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-green-700{color:var(--color-green-700)}.text-green-800{color:var(--color-green-800)}.text-indigo-500{color:var(--color-indigo-500)}.text-indigo-600{color:var(--color-indigo-600)}.text-indigo-700{color:var(--color-indigo-700)}.text-indigo-800{color:var(--color-indigo-800)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-700{color:var(--color-neutral-700)}.text-neutral-800{color:var(--color-neutral-800)}.text-neutral-900{color:var(--color-neutral-900)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-sky-700{color:var(--color-sky-700)}.text-violet-700{color:var(--color-violet-700)}.text-white{color:var(--color-white)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.not-italic{font-style:normal}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.accent-indigo-600{accent-color:var(--color-indigo-600)}.opacity-0{opacity:0}.opacity-70{opacity:.7}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-emerald-200{--tw-ring-color:var(--color-emerald-200)}.ring-emerald-600\/20{--tw-ring-color:#00976733}@supports (color:color-mix(in lab, red, red)){.ring-emerald-600\/20{--tw-ring-color:color-mix(in oklab, var(--color-emerald-600) 20%, transparent)}}.ring-indigo-200\/70{--tw-ring-color:#c7d2ffb3}@supports (color:color-mix(in lab, red, red)){.ring-indigo-200\/70{--tw-ring-color:color-mix(in oklab, var(--color-indigo-200) 70%, transparent)}}.ring-neutral-200{--tw-ring-color:var(--color-neutral-200)}.ring-red-200{--tw-ring-color:var(--color-red-200)}.ring-sky-200{--tw-ring-color:var(--color-sky-200)}.ring-violet-200{--tw-ring-color:var(--color-violet-200)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.ring-inset{--tw-ring-inset:inset}@media (hover:hover){.group-hover\:block:is(:where(.group):hover *){display:block}.group-hover\:flex:is(:where(.group):hover *){display:flex}.group-hover\:hidden:is(:where(.group):hover *){display:none}.group-hover\:inline:is(:where(.group):hover *){display:inline}.group-hover\:border-indigo-400:is(:where(.group):hover *){border-color:var(--color-indigo-400)}.group-hover\:text-indigo-500:is(:where(.group):hover *){color:var(--color-indigo-500)}.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/code\:opacity-100:is(:where(.group\/code):hover *),.group-hover\/row\:opacity-100:is(:where(.group\/row):hover *){opacity:1}}.peer-checked\:bg-indigo-600:is(:where(.peer):checked~*){background-color:var(--color-indigo-600)}.peer-focus-visible\:ring-2:is(:where(.peer):focus-visible~*){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.peer-focus-visible\:ring-indigo-200:is(:where(.peer):focus-visible~*){--tw-ring-color:var(--color-indigo-200)}.marker\:text-neutral-400 ::marker{color:var(--color-neutral-400)}.marker\:text-neutral-400::marker{color:var(--color-neutral-400)}.marker\:text-neutral-400 ::-webkit-details-marker{color:var(--color-neutral-400)}.marker\:text-neutral-400::-webkit-details-marker{color:var(--color-neutral-400)}.placeholder\:text-neutral-400::placeholder{color:var(--color-neutral-400)}.backdrop\:bg-black\/20::backdrop{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.backdrop\:bg-black\/20::backdrop{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.backdrop\:bg-black\/30::backdrop{background-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.backdrop\:bg-black\/30::backdrop{background-color:color-mix(in oklab, var(--color-black) 30%, transparent)}}.backdrop\:bg-black\/40::backdrop{background-color:#0006}@supports (color:color-mix(in lab, red, red)){.backdrop\:bg-black\/40::backdrop{background-color:color-mix(in oklab, var(--color-black) 40%, transparent)}}.backdrop\:bg-black\/70::backdrop{background-color:#000000b3}@supports (color:color-mix(in lab, red, red)){.backdrop\:bg-black\/70::backdrop{background-color:color-mix(in oklab, var(--color-black) 70%, transparent)}}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0\.5:after{content:var(--tw-content);top:calc(var(--spacing) * .5)}.after\:left-0\.5:after{content:var(--tw-content);left:calc(var(--spacing) * .5)}.after\:h-3:after{content:var(--tw-content);height:calc(var(--spacing) * 3)}.after\:w-3:after{content:var(--tw-content);width:calc(var(--spacing) * 3)}.after\:rounded-full:after{content:var(--tw-content);border-radius:2147483647px}.after\:bg-white:after{content:var(--tw-content);background-color:var(--color-white)}.after\:shadow-sm:after{content:var(--tw-content);--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.after\:transition-transform:after{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.peer-checked\:after\:translate-x-3:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 3);translate:var(--tw-translate-x) var(--tw-translate-y)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.open\:float-none:is([open],:popover-open,:open){float:none}.open\:mt-0:is([open],:popover-open,:open){margin-top:0}.open\:mb-1\.5:is([open],:popover-open,:open){margin-bottom:calc(var(--spacing) * 1.5)}.open\:min-w-0:is([open],:popover-open,:open){min-width:0}.open\:border:is([open],:popover-open,:open){border-style:var(--tw-border-style);border-width:1px}.open\:border-black\/\[0\.06\]:is([open],:popover-open,:open){border-color:#0000000f}@supports (color:color-mix(in lab, red, red)){.open\:border-black\/\[0\.06\]:is([open],:popover-open,:open){border-color:color-mix(in oklab, var(--color-black) 6%, transparent)}}.open\:bg-amber-50:is([open],:popover-open,:open){background-color:var(--color-amber-50)}.open\:bg-black\/\[0\.02\]:is([open],:popover-open,:open){background-color:#00000005}@supports (color:color-mix(in lab, red, red)){.open\:bg-black\/\[0\.02\]:is([open],:popover-open,:open){background-color:color-mix(in oklab, var(--color-black) 2%, transparent)}}.open\:bg-green-50:is([open],:popover-open,:open){background-color:var(--color-green-50)}.open\:bg-red-50:is([open],:popover-open,:open){background-color:var(--color-red-50)}.open\:px-2:is([open],:popover-open,:open){padding-inline:calc(var(--spacing) * 2)}.open\:py-1\.5:is([open],:popover-open,:open){padding-block:calc(var(--spacing) * 1.5)}.open\:pr-0:is([open],:popover-open,:open){padding-right:0}.open\:text-neutral-500:is([open],:popover-open,:open){color:var(--color-neutral-500)}.focus-within\:border-indigo-400:focus-within{border-color:var(--color-indigo-400)}.focus-within\:ring-2:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-within\:ring-indigo-100:focus-within{--tw-ring-color:var(--color-indigo-100)}@media (hover:hover){.hover\:border-indigo-300:hover{border-color:var(--color-indigo-300)}.hover\:bg-amber-100:hover{background-color:var(--color-amber-100)}.hover\:bg-amber-200:hover{background-color:var(--color-amber-200)}.hover\:bg-black\/\[0\.03\]:hover{background-color:#00000008}@supports (color:color-mix(in lab, red, red)){.hover\:bg-black\/\[0\.03\]:hover{background-color:color-mix(in oklab, var(--color-black) 3%, transparent)}}.hover\:bg-cyan-100:hover{background-color:var(--color-cyan-100)}.hover\:bg-emerald-100:hover{background-color:var(--color-emerald-100)}.hover\:bg-indigo-50:hover{background-color:var(--color-indigo-50)}.hover\:bg-indigo-100:hover{background-color:var(--color-indigo-100)}.hover\:bg-indigo-500:hover{background-color:var(--color-indigo-500)}.hover\:bg-neutral-50:hover{background-color:var(--color-neutral-50)}.hover\:bg-neutral-100:hover{background-color:var(--color-neutral-100)}.hover\:bg-neutral-200:hover{background-color:var(--color-neutral-200)}.hover\:bg-red-100:hover{background-color:var(--color-red-100)}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-white:hover{background-color:var(--color-white)}.hover\:text-amber-500:hover{color:var(--color-amber-500)}.hover\:text-indigo-700:hover{color:var(--color-indigo-700)}.hover\:text-neutral-600:hover{color:var(--color-neutral-600)}.hover\:text-neutral-700:hover{color:var(--color-neutral-700)}.hover\:text-neutral-800:hover{color:var(--color-neutral-800)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-indigo-400:focus{border-color:var(--color-indigo-400)}.focus\:opacity-100:focus{opacity:1}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-indigo-100:focus{--tw-ring-color:var(--color-indigo-100)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:bg-amber-200:active{background-color:var(--color-amber-200)}.active\:bg-amber-300:active{background-color:var(--color-amber-300)}.active\:bg-indigo-700:active{background-color:var(--color-indigo-700)}.active\:bg-neutral-100:active{background-color:var(--color-neutral-100)}.active\:bg-neutral-200:active{background-color:var(--color-neutral-200)}@media not all and (width>=48rem){.max-md\:ml-0{margin-left:0}.max-md\:hidden{display:none}.max-md\:h-2\/5{height:40%}.max-md\:w-full{width:100%}.max-md\:flex-col{flex-direction:column}.max-md\:flex-wrap{flex-wrap:wrap}.max-md\:overflow-x-auto{overflow-x:auto}.max-md\:border-r-0{border-right-style:var(--tw-border-style);border-right-width:0}.max-md\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.max-md\:pl-0{padding-left:0}}@media not all and (width>=40rem){.max-sm\:grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}}@media (width>=40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-\[14\.5rem_minmax\(0\,1fr\)\]{grid-template-columns:14.5rem minmax(0,1fr)}}.dark\:border-neutral-200:where([data-theme=dark],[data-theme=dark] *){border-color:var(--color-neutral-200)}.dark\:bg-neutral-100:where([data-theme=dark],[data-theme=dark] *){background-color:var(--color-neutral-100)}.dark\:text-neutral-50:where([data-theme=dark],[data-theme=dark] *){color:var(--color-neutral-50)}.dark\:open\:border-neutral-200:where([data-theme=dark],[data-theme=dark] *):is([open],:popover-open,:open){border-color:var(--color-neutral-200)}.dark\:open\:bg-neutral-100:where([data-theme=dark],[data-theme=dark] *):is([open],:popover-open,:open){background-color:var(--color-neutral-100)}@media (hover:hover){.dark\:hover\:bg-neutral-100:where([data-theme=dark],[data-theme=dark] *):hover{background-color:var(--color-neutral-100)}}@media (pointer:coarse){.pointer-coarse\:block{display:block}.pointer-coarse\:flex{display:flex}.pointer-coarse\:py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.pointer-coarse\:opacity-100{opacity:1}}}html[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;background-color:var(--color-white);--color-white:oklch(22.5% 0 none);--color-neutral-50:oklch(19% 0 none);--color-neutral-100:oklch(27.5% 0 none);--color-neutral-200:oklch(32.5% 0 none);--color-neutral-300:oklch(39% 0 none);--color-neutral-400:oklch(62% 0 none);--color-neutral-500:oklch(70% 0 none);--color-neutral-600:oklch(78% 0 none);--color-neutral-700:oklch(85% 0 none);--color-neutral-800:oklch(90% 0 none);--color-neutral-900:oklch(94% 0 none);--color-neutral-950:oklch(97% 0 none);--color-indigo-50:oklch(24.5% .028 272.314);--color-indigo-100:oklch(32% .065 272.788);--color-indigo-200:oklch(40% .09 274.039);--color-indigo-300:oklch(50% .125 274.713);--color-indigo-400:oklch(62% .155 276.935);--color-indigo-500:oklch(68% .165 277.117);--color-indigo-600:oklch(70% .175 276.966);--color-indigo-700:oklch(80% .115 277.023);--color-indigo-800:oklch(86% .08 277.366);--color-red-50:oklch(24.5% .028 17.38);--color-red-100:oklch(32% .065 17.717);--color-red-200:oklch(40% .09 18.334);--color-red-400:oklch(62% .155 22.216);--color-red-600:oklch(73% .145 27.325);--color-red-700:oklch(80% .115 27.518);--color-amber-50:oklch(24.5% .028 95.277);--color-amber-100:oklch(32% .065 95.617);--color-amber-200:oklch(40% .09 95.746);--color-amber-300:oklch(50% .125 91.605);--color-amber-400:oklch(62% .155 84.429);--color-amber-500:oklch(68% .165 70.08);--color-amber-600:oklch(73% .145 58.318);--color-amber-700:oklch(80% .115 48.998);--color-amber-800:oklch(86% .08 46.201);--color-emerald-50:oklch(24.5% .028 166.113);--color-emerald-100:oklch(32% .065 163.051);--color-emerald-200:oklch(40% .09 164.15);--color-emerald-400:oklch(62% .155 163.223);--color-emerald-500:oklch(68% .165 162.48);--color-emerald-600:oklch(73% .145 163.225);--color-emerald-700:oklch(80% .115 165.612);--color-green-50:oklch(24.5% .028 155.826);--color-green-200:oklch(40% .09 155.995);--color-green-500:oklch(68% .165 149.579);--color-green-700:oklch(80% .115 150.069);--color-green-800:oklch(86% .08 151.328);--color-cyan-50:oklch(24.5% .028 200.873);--color-cyan-100:oklch(32% .065 203.388);--color-cyan-200:oklch(40% .09 205.041);--color-cyan-400:oklch(62% .155 211.53);--color-cyan-500:oklch(68% .165 215.221);--color-cyan-700:oklch(80% .115 223.128);--color-cyan-800:oklch(86% .08 224.283);--color-sky-50:oklch(24.5% .028 236.62);--color-sky-200:oklch(40% .09 230.902);--color-sky-500:oklch(68% .165 237.323);--color-sky-700:oklch(80% .115 242.749);--color-violet-50:oklch(24.5% .028 293.756);--color-violet-200:oklch(40% .09 293.283);--color-violet-700:oklch(80% .115 292.581);--color-blue-700:oklch(80% .115 264.376)}html{font-size:112.5%}.text-\[9px\]{font-size:.5625rem}.text-\[10px\]{font-size:.625rem}.text-\[10\.5px\]{font-size:.65625rem}.text-\[11px\]{font-size:.6875rem}.text-\[11\.5px\]{font-size:.71875rem}.text-\[12px\]{font-size:.75rem}.text-\[12\.5px\]{font-size:.78125rem}.text-\[13px\]{font-size:.8125rem}.text-\[13\.5px\]{font-size:.84375rem}.text-\[14px\]{font-size:.875rem}.text-\[15px\]{font-size:.9375rem}.text-\[16px\]{font-size:1rem}.text-\[17px\]{font-size:1.0625rem}.text-\[20px\]{font-size:1.25rem}.thumbs>*{margin:0}@media (width>=48rem){body[data-rail=closed]{grid-template-columns:minmax(0,1fr)}body[data-rail=closed] #sidebar{display:none}#rail-toggle{left:12.375rem}body[data-rail=closed] #rail-toggle{left:.375rem}body[data-rail=closed] #rail-toggle svg{transform:rotate(180deg)}body[data-rail=closed] :is(#chat-header,main section>header:first-child,main section>div:first-child>header:first-child){padding-left:2.75rem}}@media not all and (width>=48rem){#sidebar{z-index:40;inset-block:0;width:19rem;transition:transform .18s ease-out;position:fixed;left:0;transform:translate(-100%);box-shadow:0 8px 30px #0000002e}#sidebar[data-open]{transform:translate(0)}#sidebar,#console-section ul,#project-tree{font-size:.9375rem}body{overscroll-behavior:none}#composer,#project-tree{padding-bottom:calc(.5rem + env(safe-area-inset-bottom))}body[data-kb] #composer{padding-bottom:.5rem}main,#sidebar{padding-top:env(safe-area-inset-top)}#project-tree li,#project-tree summary,#console-section li button{padding-block:.5rem}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
@@ -6,18 +6,35 @@
6
6
  under an iPhone's home indicator. -->
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
8
8
  <meta name="theme-color" content="#fafafa" />
9
- <!-- Installed as a home-screen app: standalone window, own icon. -->
10
- <link rel="manifest" href="/manifest.webmanifest" />
9
+ <!-- Ahead of the stylesheet, because a workbench that flashes white and then
10
+ goes dark reads as a bug. This is the only place "system" is resolved
11
+ before the bundle exists; theme.ts owns the choice from there on. -->
12
+ <script>
13
+ try {
14
+ var t = localStorage.getItem("pier.theme");
15
+ document.documentElement.dataset.theme =
16
+ t === "light" || t === "dark" ? t
17
+ : matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
18
+ } catch (e) { /* storage denied (private mode, blocked cookies): light it is */ }
19
+ </script>
20
+ <!-- Installed as a home-screen app: standalone window, own icon. The
21
+ manifest shares the workbench's cookie boundary. -->
22
+ <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials" />
11
23
  <!-- SVG first (scales to any tab/bookmark size), 32px PNG for the engines
12
24
  that still ignore it. iOS wants an opaque square and rounds it itself. -->
13
25
  <link rel="icon" type="image/svg+xml" href="/icon.svg" />
14
26
  <link rel="icon" type="image/png" sizes="32x32" href="/icon-32.png" />
15
27
  <link rel="apple-touch-icon" href="/icon-touch-192.png" />
28
+ <meta name="mobile-web-app-capable" content="yes" />
16
29
  <meta name="apple-mobile-web-app-capable" content="yes" />
17
30
  <meta name="apple-mobile-web-app-title" content="Pier" />
31
+ <!-- Without this iOS paints the status-bar strip in a system grey that
32
+ belongs to no part of the app. Translucent hands the strip to the page,
33
+ which style.css pays for with the safe-area inset. -->
34
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
18
35
  <title>Pier</title>
19
- <script type="module" crossorigin src="/assets/index-BbwoGR-O.js"></script>
20
- <link rel="stylesheet" crossorigin href="/assets/index-BlHvP59B.css">
36
+ <script type="module" crossorigin src="/assets/index-DmDJKOLH.js"></script>
37
+ <link rel="stylesheet" crossorigin href="/assets/index-gcSJ9QZ5.css">
21
38
  </head>
22
39
  <!-- The document never scrolls: this is a fixed-viewport workbench, and every
23
40
  scrollable region is an inner pane. h-dvh, not h-screen, because 100vh can
@@ -50,6 +67,12 @@
50
67
  <a id="version" href="https://github.com/timqi/pier" target="_blank" rel="noreferrer"
51
68
  title="Pier is free software (AGPL-3.0) — the source of what you are using"
52
69
  class="font-mono text-[11px] text-neutral-400 hover:text-neutral-700 hover:underline"></a>
70
+ <!-- Cycles system → light → dark; the glyph is what is on screen, the
71
+ title says which of the three states put it there. Beside the
72
+ version rather than at the header's right edge, which is where the
73
+ fixed rail toggle lands. -->
74
+ <button type="button" id="theme-toggle" aria-label="Theme"
75
+ class="icon-btn text-[13px]"></button>
53
76
  </header>
54
77
  <details id="console-section" open class="flex-none border-b border-neutral-200/70">
55
78
  <summary class="flex cursor-pointer select-none items-center gap-1 px-3 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-neutral-500 hover:bg-neutral-100">
@@ -1,16 +1,26 @@
1
1
  {
2
+ "id": "/",
2
3
  "name": "Pier",
3
4
  "short_name": "Pier",
5
+ "description": "A self-hosted workspace for coding agents: sessions, tasks and files, in one workbench.",
6
+ "lang": "en",
7
+ "dir": "ltr",
4
8
  "start_url": "/",
5
9
  "scope": "/",
6
10
  "display": "standalone",
7
- "orientation": "portrait-primary",
8
11
  "background_color": "#fafafa",
9
12
  "theme_color": "#fafafa",
13
+ "categories": ["developer", "productivity", "utilities"],
14
+ "launch_handler": { "client_mode": "focus-existing" },
10
15
  "icons": [
11
16
  { "src": "/icon.svg", "sizes": "any", "type": "image/svg+xml" },
12
17
  { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
13
18
  { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
14
19
  { "src": "/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
20
+ ],
21
+ "shortcuts": [
22
+ { "name": "Tasks", "url": "/#/tasks", "icons": [{ "src": "/icon-192.png", "sizes": "192x192" }] },
23
+ { "name": "Activity", "url": "/#/activity", "icons": [{ "src": "/icon-192.png", "sizes": "192x192" }] },
24
+ { "name": "Settings", "url": "/#/settings", "icons": [{ "src": "/icon-192.png", "sizes": "192x192" }] }
15
25
  ]
16
26
  }
@@ -0,0 +1,109 @@
1
+ // Pier's service worker: the notification path, and the little that has to
2
+ // exist for a browser to treat the workbench as an installable app.
3
+ //
4
+ // It caches nothing. The shell is revalidated on every navigation and the
5
+ // bundles it names are content-hashed, so a cache in front of that is exactly
6
+ // how an installed Pier ends up asking for assets a release replaced. The one
7
+ // fetch handler is a navigation fallback: without it an offline tap on the
8
+ // home-screen icon shows the browser's error page, which does not say which
9
+ // of the two — Pier or the network — is down.
10
+
11
+ const OFFLINE_PAGE = `<!doctype html><html lang="en"><head><meta charset="utf-8">
12
+ <meta name="viewport" content="width=device-width,initial-scale=1"><title>Pier is unreachable</title>
13
+ <style>:root{color-scheme:light dark}
14
+ body{margin:0;display:grid;place-items:center;height:100dvh;font:15px/1.5 ui-sans-serif,system-ui,sans-serif;color:light-dark(#404040,#d4d4d4);background:light-dark(#fafafa,#1c1c1c)}
15
+ main{text-align:center;padding:2rem}.dim{color:light-dark(#737373,#8a8a8a)}
16
+ button{margin-top:1rem;padding:.5rem 1rem;border:1px solid light-dark(#d4d4d4,#3d3d3d);border-radius:.5rem;background:light-dark(#fff,#262626);color:inherit;font:inherit;cursor:pointer}</style>
17
+ </head><body><main><h1 style="font-size:1rem">Pier is unreachable</h1>
18
+ <p class="dim">This device is offline, or the server is not answering.</p>
19
+ <button onclick="location.reload()">Try again</button></main></body></html>`;
20
+
21
+ self.addEventListener("install", () => self.skipWaiting());
22
+
23
+ self.addEventListener("activate", (event) => {
24
+ event.waitUntil((async () => {
25
+ // Preload keeps the navigation request in flight while the worker boots,
26
+ // so routing every navigation through here costs nothing.
27
+ if (self.registration.navigationPreload) await self.registration.navigationPreload.enable();
28
+ await self.clients.claim();
29
+ })());
30
+ });
31
+
32
+ self.addEventListener("fetch", (event) => {
33
+ const request = event.request;
34
+ if (request.mode !== "navigate" || request.method !== "GET") return; // straight to the network
35
+ event.respondWith((async () => {
36
+ try {
37
+ return (await event.preloadResponse) || (await fetch(request));
38
+ } catch {
39
+ return new Response(OFFLINE_PAGE, {
40
+ status: 503,
41
+ headers: { "content-type": "text/html; charset=utf-8" },
42
+ });
43
+ }
44
+ })());
45
+ });
46
+
47
+ // Every push shows a notification, including one whose payload we could not
48
+ // read: `userVisibleOnly` is a promise to the browser, and a push that shows
49
+ // nothing costs the permission on Chrome and the subscription on Safari.
50
+ self.addEventListener("push", (event) => {
51
+ let data = {};
52
+ try {
53
+ data = event.data ? event.data.json() : {};
54
+ } catch {
55
+ data = {};
56
+ }
57
+ const title = data.title || "Pier";
58
+ event.waitUntil((async () => {
59
+ await self.registration.showNotification(title, {
60
+ body: data.body || "A turn finished.",
61
+ tag: data.tag || "pier",
62
+ icon: "/icon-192.png",
63
+ badge: "/icon-32.png",
64
+ timestamp: Date.now(),
65
+ data: { url: data.url || "/" },
66
+ });
67
+ // The home-screen badge is the only trace left once a notification is
68
+ // dismissed; the page recomputes it from the session list when it opens.
69
+ if (self.navigator.setAppBadge) await self.navigator.setAppBadge().catch(() => {});
70
+ })());
71
+ });
72
+
73
+ self.addEventListener("notificationclick", (event) => {
74
+ event.notification.close();
75
+ const target = new URL(event.notification.data?.url || "/", self.location.origin);
76
+ event.waitUntil((async () => {
77
+ const clients = await self.clients.matchAll({ type: "window", includeUncontrolled: true });
78
+ // An open workbench is focused and pointed at the session, rather than
79
+ // opening a second window onto the same instance.
80
+ for (const client of clients) {
81
+ if (new URL(client.url).origin !== target.origin) continue;
82
+ await client.focus();
83
+ if (client.navigate) await client.navigate(target.href).catch(() => {});
84
+ return;
85
+ }
86
+ await self.clients.openWindow(target.href);
87
+ })());
88
+ });
89
+
90
+ // A browser may replace a subscription on its own (key rotation, storage
91
+ // pressure). Re-subscribing here is what keeps a device that never reopens the
92
+ // page reachable; the page's own load-time re-registration is the other half.
93
+ self.addEventListener("pushsubscriptionchange", (event) => {
94
+ event.waitUntil((async () => {
95
+ const response = await fetch("/api/push", { credentials: "same-origin" });
96
+ const { publicKey } = await response.json();
97
+ const raw = atob(publicKey.replace(/-/g, "+").replace(/_/g, "/"));
98
+ const subscription = await self.registration.pushManager.subscribe({
99
+ userVisibleOnly: true,
100
+ applicationServerKey: Uint8Array.from(raw, (ch) => ch.charCodeAt(0)),
101
+ });
102
+ await fetch("/api/push/subscribe", {
103
+ method: "POST",
104
+ credentials: "same-origin",
105
+ headers: { "content-type": "application/json" },
106
+ body: JSON.stringify({ ...subscription.toJSON(), label: "a browser (re-subscribed)" }),
107
+ });
108
+ })());
109
+ });
@@ -0,0 +1,224 @@
1
+ // Notifications for the workbench that is not on screen: which browsers asked
2
+ // to be told, and the one rule that decides a push — a turn that finished and
3
+ // that nobody looked at. The wire format is webpush.ts.
4
+ //
5
+ // The rule is deliberately the same one the sidebar's unread dot uses, read a
6
+ // few seconds late: a client with that session visible acks immediately, so
7
+ // "still unread when the dust settled" is precisely "nobody saw it". One rule,
8
+ // one place — a second notion of attention would drift from the dot within a
9
+ // release.
10
+ import { pierDb } from "../db.js";
11
+ import { logger } from "../log.js";
12
+ import { generateVapidKeys, sendPush, } from "./webpush.js";
13
+ const log = logger("push");
14
+ /** Devices kept at once. A browser mints a new subscription whenever the old
15
+ * one expires, so the table grows by itself; the oldest rows are the ones
16
+ * already dead. */
17
+ const MAX_SUBSCRIPTIONS = 20;
18
+ /** How long a finished turn waits for a client to say it was seen. Long enough
19
+ * to cross a heartbeat and a slow phone, short enough to still be a
20
+ * notification about something that just happened. */
21
+ const SETTLE_MS = 6_000;
22
+ const MAX_BODY_CHARS = 160;
23
+ /** Subscriptions and the instance's VAPID identity. Both are per-instance
24
+ * facts nobody edits by hand, so they live beside every other one. */
25
+ export class PushStore {
26
+ #db;
27
+ constructor(db = pierDb()) {
28
+ this.#db = db;
29
+ }
30
+ /** The key pair every push is signed with, minted on first use. Losing it
31
+ * would invalidate every subscription made with it, so it is created once
32
+ * and never rotated on its own. */
33
+ identity() {
34
+ const row = this.#db
35
+ .prepare("SELECT public_key AS publicKey, private_key AS privateKey FROM push_identity WHERE id = 1")
36
+ .get();
37
+ if (row)
38
+ return row;
39
+ const keys = generateVapidKeys();
40
+ this.#db
41
+ .prepare("INSERT INTO push_identity(id, public_key, private_key, created_at) VALUES (1, ?, ?, ?)")
42
+ .run(keys.publicKey, keys.privateKey, Date.now());
43
+ log.info("minted this instance's VAPID key pair");
44
+ return keys;
45
+ }
46
+ list() {
47
+ return this.#db
48
+ .prepare(`SELECT endpoint, p256dh, auth, label, created_at AS createdAt
49
+ FROM push_subscriptions ORDER BY created_at DESC`)
50
+ .all();
51
+ }
52
+ /** Upsert: a browser re-posts the same subscription on every load, which is
53
+ * what repairs a row this instance lost. */
54
+ save(target, label) {
55
+ this.#db
56
+ .prepare(`INSERT INTO push_subscriptions(endpoint, p256dh, auth, label, created_at)
57
+ VALUES (?, ?, ?, ?, ?)
58
+ ON CONFLICT(endpoint) DO UPDATE SET
59
+ p256dh = excluded.p256dh, auth = excluded.auth, label = excluded.label`)
60
+ .run(target.endpoint, target.p256dh, target.auth, label, Date.now());
61
+ this.#db
62
+ .prepare(`DELETE FROM push_subscriptions WHERE endpoint NOT IN
63
+ (SELECT endpoint FROM push_subscriptions ORDER BY created_at DESC LIMIT ?)`)
64
+ .run(MAX_SUBSCRIPTIONS);
65
+ }
66
+ remove(endpoint) {
67
+ return this.#db.prepare("DELETE FROM push_subscriptions WHERE endpoint = ?")
68
+ .run(endpoint).changes > 0;
69
+ }
70
+ }
71
+ /** One line of what the agent said, for a notification shade. */
72
+ const preview = (text) => {
73
+ const line = text.replace(/```[\s\S]*?```/g, "…").replace(/\s+/g, " ").trim();
74
+ return line.length > MAX_BODY_CHARS ? `${line.slice(0, MAX_BODY_CHARS - 1)}…` : line;
75
+ };
76
+ /** A subscription is only accepted in the exact shape the Push API produces;
77
+ * a half-valid one would fail later, inside a background send nobody watches. */
78
+ function parseTarget(body) {
79
+ const { endpoint, keys } = (body ?? {});
80
+ const p256dh = keys?.p256dh;
81
+ const auth = keys?.auth;
82
+ if (typeof endpoint !== "string" || endpoint.length > 1000)
83
+ return null;
84
+ if (typeof p256dh !== "string" || typeof auth !== "string")
85
+ return null;
86
+ let url;
87
+ try {
88
+ url = new URL(endpoint);
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ if (url.protocol !== "https:")
94
+ return null;
95
+ // 65 octets of uncompressed P-256 point, 16 of authentication secret.
96
+ if (Buffer.from(p256dh, "base64url").length !== 65)
97
+ return null;
98
+ if (Buffer.from(auth, "base64url").length !== 16)
99
+ return null;
100
+ return { endpoint, p256dh, auth };
101
+ }
102
+ export function registerPushRoutes(app, deps) {
103
+ const { store, hub, unread, channelOf, name, publicUrl, settleMs = SETTLE_MS } = deps;
104
+ /** Who a push service should complain to. It has to be a mailto: or https:
105
+ * URL or Apple rejects the token outright, so an instance that never had
106
+ * its public URL set still needs an answer. */
107
+ const subject = () => {
108
+ const url = publicUrl();
109
+ return url.startsWith("https://") ? url : "mailto:pier@localhost";
110
+ };
111
+ /** Send to every device, and prune the ones the service says are gone. A
112
+ * failure is logged with what the service said — a notification that never
113
+ * arrives is otherwise indistinguishable from one nobody tapped. */
114
+ async function deliver(payload) {
115
+ const targets = store.list();
116
+ if (!targets.length)
117
+ return { sent: 0, failed: 0 };
118
+ const keys = store.identity();
119
+ const body = JSON.stringify(payload);
120
+ let sent = 0;
121
+ let failed = 0;
122
+ await Promise.all(targets.map(async (target) => {
123
+ const { status, error } = await sendPush(target, body, keys, subject());
124
+ if (status >= 200 && status < 300) {
125
+ sent += 1;
126
+ return;
127
+ }
128
+ failed += 1;
129
+ // 404/410 is the push service saying this subscription is dead for good
130
+ // — the only status that may cost a row.
131
+ if (status === 404 || status === 410) {
132
+ store.remove(target.endpoint);
133
+ log.info(`dropped an expired subscription (${target.label})`);
134
+ return;
135
+ }
136
+ log.warn(`push to ${target.label} failed: ${String(status)} ${error ?? ""}`.trim());
137
+ }));
138
+ return { sent, failed };
139
+ }
140
+ // --- the trigger ----------------------------------------------------------------
141
+ // A session is watched only while it streams: the ring buffer of a session
142
+ // nobody watches is released on eviction (core/hub.ts), and a permanent
143
+ // subscriber would keep every one of them alive.
144
+ /** Per streaming session: stop watching, and hand back what the turn said.
145
+ * The text lives in the watcher's own closure, so it cannot outlive the
146
+ * subscription that collected it. */
147
+ const watching = new Map();
148
+ hub.subscribeWorkspace((e) => {
149
+ if (e.type !== "session-state")
150
+ return;
151
+ if (e.state === "streaming") {
152
+ if (watching.has(e.sessionId))
153
+ return;
154
+ let text = "";
155
+ const stop = hub.subscribe(e.sessionId, (ev) => {
156
+ if (ev.type === "turn-end")
157
+ text = ev.text;
158
+ });
159
+ watching.set(e.sessionId, () => {
160
+ stop();
161
+ return text;
162
+ });
163
+ return;
164
+ }
165
+ // No start witnessed → a session that booted idle, not a finished turn.
166
+ const finish = watching.get(e.sessionId);
167
+ if (!finish)
168
+ return;
169
+ watching.delete(e.sessionId);
170
+ const text = finish();
171
+ // The workbench's own sessions only. A turn that came from Slack, Telegram
172
+ // or Lark was already delivered to the chat it came from — the person has
173
+ // it, and their phone buzzing twice for one answer is what a notification
174
+ // budget gets spent on. Read now, not in the timer: this is the state that
175
+ // produced the turn.
176
+ if (channelOf(e.sessionId) !== "web")
177
+ return;
178
+ const timer = setTimeout(() => {
179
+ if (!unread(e.sessionId))
180
+ return; // somebody has it on screen
181
+ void deliver({
182
+ title: name(e.sessionId),
183
+ body: preview(text) || "Turn finished.",
184
+ url: `/#/session/${encodeURIComponent(e.sessionId)}`,
185
+ tag: e.sessionId,
186
+ }).catch((err) => log.error("delivering a push failed", err));
187
+ }, settleMs);
188
+ // A pending notification must never hold a shutting-down process open.
189
+ timer.unref?.();
190
+ });
191
+ // --- routes ---------------------------------------------------------------------
192
+ // The key a browser subscribes with. Public by nature — it is what a push
193
+ // service checks our signature against.
194
+ app.get("/api/push", (c) => c.json({ publicKey: store.identity().publicKey }));
195
+ app.post("/api/push/subscribe", async (c) => {
196
+ const body = await c.req.json().catch(() => null);
197
+ const target = parseTarget(body);
198
+ if (!target)
199
+ return c.json({ error: "not a push subscription" }, 400);
200
+ const label = String(body.label ?? "a browser").slice(0, 80);
201
+ store.save(target, label);
202
+ log.info(`subscribed ${label}`);
203
+ return c.json({ ok: true }, 201);
204
+ });
205
+ app.post("/api/push/unsubscribe", async (c) => {
206
+ const { endpoint } = (await c.req.json().catch(() => ({})));
207
+ if (typeof endpoint !== "string")
208
+ return c.json({ error: "endpoint required" }, 400);
209
+ return c.json({ removed: store.remove(endpoint) });
210
+ });
211
+ // "Did that actually work?" — the only way to answer it on a phone, where a
212
+ // permission granted to the wrong context looks exactly like a granted one.
213
+ app.post("/api/push/test", async (c) => {
214
+ const { sent, failed } = await deliver({
215
+ title: "Pier",
216
+ body: "Notifications are working.",
217
+ url: "/",
218
+ tag: "pier-test",
219
+ });
220
+ if (!sent && !failed)
221
+ return c.json({ error: "no device is subscribed" }, 409);
222
+ return c.json({ sent, failed });
223
+ });
224
+ }
@@ -422,6 +422,9 @@ export function createServer({ factory, router, hub, sessions: state, config, pr
422
422
  const prefix = tabPrefix(process.env.PIER_TITLE, hostname().split(".")[0] ?? "");
423
423
  let shell = null;
424
424
  app.get("/", async (c, next) => {
425
+ // A release replaces hashed assets. Revalidate the shell on every
426
+ // navigation so a cached index cannot name bundles that no longer exist.
427
+ c.header("cache-control", "private, no-cache");
425
428
  if (shell === null) {
426
429
  try {
427
430
  shell = withTabPrefix(await readFile(join(bundle, "index.html"), "utf8"), prefix);
@@ -435,6 +438,13 @@ export function createServer({ factory, router, hub, sessions: state, config, pr
435
438
  }
436
439
  return c.html(shell);
437
440
  });
441
+ // Same reasoning as the shell above, for the one asset that is not hashed:
442
+ // an installed app keeps its worker until the script it re-fetches differs,
443
+ // so a cached copy is a released fix that never ships.
444
+ app.get("/sw.js", async (c, next) => {
445
+ c.header("cache-control", "private, no-cache");
446
+ await next();
447
+ });
438
448
  app.use("/*", serveStatic({ root: relative(process.cwd(), bundle) || "." }));
439
449
  return app;
440
450
  }