prototypey.org - atproto lexicon typescript toolkit - mirror https://github.com/tylersayshi/prototypey

use tailwind for site

Tyler c58c71b3 f59841f4

+236 -351
+2
packages/site/package.json
··· 20 20 "react-dom": "^19.2.0" 21 21 }, 22 22 "devDependencies": { 23 + "@tailwindcss/vite": "^4.1.17", 23 24 "@testing-library/jest-dom": "^6.9.1", 24 25 "@testing-library/react": "^16.3.0", 25 26 "@testing-library/user-event": "^14.6.1", ··· 29 30 "babel-plugin-react-compiler": "^1.0.0", 30 31 "eslint-plugin-react-compiler": "19.1.0-rc.2", 31 32 "jsdom": "^25.0.1", 33 + "tailwindcss": "^4.1.17", 32 34 "typescript": "5.8.3", 33 35 "vite": "^6.4.1", 34 36 "vitest": "^3.2.4"
+2 -2
packages/site/src/App.tsx
··· 3 3 4 4 export function App() { 5 5 return ( 6 - <> 6 + <div className="flex flex-col min-h-screen w-full bg-white dark:bg-gray-900 text-gray-700 dark:text-gray-200"> 7 7 <Header /> 8 8 <Playground /> 9 - </> 9 + </div> 10 10 ); 11 11 }
+6 -31
packages/site/src/components/Editor.tsx
··· 83 83 84 84 if (!isReady) { 85 85 return ( 86 - <div style={{ flex: 1, display: "flex", flexDirection: "column" }}> 87 - <div 88 - style={{ 89 - padding: "0.75rem 1rem", 90 - backgroundColor: "var(--color-bg-secondary)", 91 - borderBottom: "1px solid var(--color-border)", 92 - fontSize: "0.875rem", 93 - fontWeight: "600", 94 - color: "var(--color-text-secondary)", 95 - }} 96 - > 86 + <div className="flex-1 flex flex-col"> 87 + <div className="py-3 px-4 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 text-sm font-semibold text-gray-500 dark:text-gray-400"> 97 88 Input 98 89 </div> 99 - <div 100 - style={{ 101 - flex: 1, 102 - display: "flex", 103 - alignItems: "center", 104 - justifyContent: "center", 105 - }} 106 - > 90 + <div className="flex-1 flex items-center justify-center"> 107 91 Loading... 108 92 </div> 109 93 </div> ··· 111 95 } 112 96 113 97 return ( 114 - <div style={{ flex: 1, display: "flex", flexDirection: "column" }}> 115 - <div 116 - style={{ 117 - padding: "0.75rem 1rem", 118 - backgroundColor: "var(--color-bg-secondary)", 119 - borderBottom: "1px solid var(--color-border)", 120 - fontSize: "0.875rem", 121 - fontWeight: "600", 122 - color: "var(--color-text-secondary)", 123 - }} 124 - > 98 + <div className="flex-1 flex flex-col"> 99 + <div className="py-3 px-4 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 text-sm font-semibold text-gray-500 dark:text-gray-400"> 125 100 Input 126 101 </div> 127 - <div style={{ flex: 1 }}> 102 + <div className="flex-1"> 128 103 <MonacoEditor 129 104 height="100%" 130 105 defaultLanguage="typescript"
+15 -88
packages/site/src/components/Header.tsx
··· 12 12 href={href} 13 13 target="_blank" 14 14 rel="noopener noreferrer" 15 - style={{ 16 - color: "var(--color-text-heading)", 17 - textDecoration: "none", 18 - fontSize: "1rem", 19 - fontWeight: "600", 20 - display: "flex", 21 - alignItems: "center", 22 - gap: "0.5rem", 23 - transition: "opacity 0.2s", 24 - willChange: "opacity", 25 - }} 26 - onMouseEnter={(e) => (e.currentTarget.style.opacity = "0.6")} 27 - onMouseLeave={(e) => (e.currentTarget.style.opacity = "1")} 15 + className="text-gray-900 dark:text-gray-100 no-underline text-base font-semibold flex items-center gap-2 transition-opacity duration-200 hover:opacity-60" 28 16 > 29 17 {icon} 30 18 {label} ··· 48 36 }; 49 37 50 38 return ( 51 - <header 52 - style={{ 53 - padding: "2rem 2rem 1rem 2rem", 54 - borderBottom: "1px solid var(--color-border)", 55 - }} 56 - > 57 - <div style={{ maxWidth: "1400px", margin: "0 auto" }}> 58 - <div className="header-content"> 39 + <header className="py-8 px-8 pb-4 border-b border-gray-200 dark:border-gray-700"> 40 + <div className="max-w-[1400px] mx-auto"> 41 + <div className="flex justify-between items-start flex-col md:flex-row gap-4 md:gap-0"> 59 42 <div> 60 - <h1 61 - style={{ 62 - fontSize: "2.5rem", 63 - fontWeight: "700", 64 - marginBottom: "0.5rem", 65 - }} 66 - > 67 - <span style={{ color: "var(--color-text-secondary)" }}> 68 - at:// 69 - </span> 43 + <h1 className="text-4xl font-bold mb-2"> 44 + <span className="text-gray-500 dark:text-gray-400">at://</span> 70 45 prototypey 71 46 </h1> 72 - <p 73 - style={{ 74 - fontSize: "1.125rem", 75 - color: "var(--color-text-secondary)", 76 - marginTop: "0.5rem", 77 - }} 78 - > 47 + <p className="text-lg text-gray-500 dark:text-gray-400 mt-2"> 79 48 ATProto lexicon typescript toolkit 80 49 </p> 81 50 </div> 82 - <div 83 - className="link-container" 84 - style={{ 85 - display: "flex", 86 - flexDirection: "column", 87 - alignItems: "flex-end", 88 - gap: "1rem", 89 - }} 90 - > 91 - <div className="header-links"> 51 + <div className="flex flex-col items-end gap-4 w-full md:w-auto"> 52 + <div className="flex gap-5 pt-2 md:pt-0 w-full md:w-auto justify-start"> 92 53 <HeaderLink 93 54 href="https://github.com/tylersayshi/prototypey?tab=readme-ov-file#prototypey" 94 55 icon={ ··· 98 59 viewBox="0 0 24 24" 99 60 fill="currentColor" 100 61 aria-hidden="true" 101 - style={{ flexShrink: 0 }} 62 + className="shrink-0" 102 63 > 103 64 <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" /> 104 65 </svg> ··· 118 79 strokeLinecap="round" 119 80 strokeLinejoin="round" 120 81 aria-hidden="true" 121 - style={{ flexShrink: 0 }} 82 + className="shrink-0" 122 83 > 123 84 <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" /> 124 85 <polyline points="3.27 6.96 12 12.01 20.73 6.96" /> ··· 140 101 strokeLinecap="round" 141 102 strokeLinejoin="round" 142 103 aria-hidden="true" 143 - style={{ flexShrink: 0 }} 104 + className="shrink-0" 144 105 > 145 106 <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" /> 146 107 <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" /> ··· 151 112 </div> 152 113 <button 153 114 onClick={handleShare} 154 - style={{ 155 - color: "var(--color-text-heading)", 156 - fontSize: "0.875rem", 157 - fontWeight: "600", 158 - display: "flex", 159 - alignItems: "center", 160 - gap: "0.5rem", 161 - transition: "background-color 0.2s, border-color 0.2s", 162 - backgroundColor: "transparent", 163 - border: "1px solid var(--color-border)", 164 - borderRadius: "0.5rem", 165 - cursor: "pointer", 166 - padding: "0.5rem 1rem", 167 - boxShadow: "none", 168 - outline: "none", 169 - flexShrink: 0, 170 - whiteSpace: "nowrap", 171 - }} 172 - onMouseEnter={(e) => { 173 - const bgColor = getComputedStyle(document.documentElement) 174 - .getPropertyValue("--color-bg-secondary") 175 - .trim(); 176 - const borderColor = getComputedStyle(document.documentElement) 177 - .getPropertyValue("--color-text-heading") 178 - .trim(); 179 - e.currentTarget.style.backgroundColor = bgColor; 180 - e.currentTarget.style.borderColor = borderColor; 181 - }} 182 - onMouseLeave={(e) => { 183 - e.currentTarget.style.backgroundColor = "transparent"; 184 - const borderColor = getComputedStyle(document.documentElement) 185 - .getPropertyValue("--color-border") 186 - .trim(); 187 - e.currentTarget.style.borderColor = borderColor; 188 - }} 115 + className="text-gray-900 dark:text-gray-100 text-sm font-semibold flex items-center gap-2 transition-all duration-200 bg-transparent border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer py-2 px-4 shadow-none outline-none shrink-0 whitespace-nowrap hover:bg-gray-50 dark:hover:bg-gray-800 hover:border-gray-900 dark:hover:border-gray-100" 189 116 aria-label="share playground" 190 117 > 191 118 {copied ? ( ··· 200 127 strokeLinecap="round" 201 128 strokeLinejoin="round" 202 129 aria-hidden="true" 203 - style={{ flexShrink: 0 }} 130 + className="shrink-0" 204 131 > 205 132 <polyline points="20 6 9 17 4 12" /> 206 133 </svg> ··· 218 145 strokeLinecap="round" 219 146 strokeLinejoin="round" 220 147 aria-hidden="true" 221 - style={{ flexShrink: 0 }} 148 + className="shrink-0" 222 149 > 223 150 <circle cx="18" cy="5" r="3" /> 224 151 <circle cx="6" cy="12" r="3" />
+4 -21
packages/site/src/components/OutputPanel.tsx
··· 27 27 }, []); 28 28 29 29 return ( 30 - <div style={{ flex: 1, display: "flex", flexDirection: "column" }}> 31 - <div 32 - style={{ 33 - padding: "0.75rem 1rem", 34 - backgroundColor: "var(--color-bg-secondary)", 35 - borderBottom: "1px solid var(--color-border)", 36 - fontSize: "0.875rem", 37 - fontWeight: "600", 38 - color: "var(--color-text-secondary)", 39 - }} 40 - > 30 + <div className="flex-1 flex flex-col"> 31 + <div className="py-3 px-4 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 text-sm font-semibold text-gray-500 dark:text-gray-400"> 41 32 Output 42 33 </div> 43 - <div style={{ flex: 1 }}> 34 + <div className="flex-1"> 44 35 {output.error ? ( 45 - <div 46 - style={{ 47 - padding: "1rem", 48 - color: "var(--color-error)", 49 - backgroundColor: "var(--color-error-bg)", 50 - height: "100%", 51 - overflow: "auto", 52 - }} 53 - > 36 + <div className="p-4 text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-950 h-full overflow-auto"> 54 37 <strong>Error:</strong> {output.error} 55 38 </div> 56 39 ) : (
+12 -80
packages/site/src/components/Playground.tsx
··· 112 112 return ( 113 113 <> 114 114 {/* Desktop playground */} 115 - <div 116 - className="desktop-only" 117 - style={{ 118 - flex: 1, 119 - overflow: "hidden", 120 - }} 121 - > 122 - <div 123 - style={{ 124 - flex: 1, 125 - display: "flex", 126 - borderRight: "1px solid var(--color-border)", 127 - }} 128 - > 115 + <div className="hidden md:flex flex-1 overflow-hidden"> 116 + <div className="flex-1 flex border-r border-gray-200 dark:border-gray-700"> 129 117 <Editor 130 118 value={code} 131 119 onChange={handleCodeChange} 132 120 onReady={handleEditorReady} 133 121 /> 134 122 </div> 135 - <div style={{ flex: 1, display: "flex" }}> 123 + <div className="flex-1 flex"> 136 124 <OutputPanel output={output} /> 137 125 </div> 138 126 </div> 139 127 140 128 {/* Mobile static demo */} 141 - <div 142 - className="mobile-only" 143 - style={{ 144 - flex: 1, 145 - flexDirection: "column", 146 - overflow: "auto", 147 - padding: "1rem", 148 - }} 149 - > 150 - <div 151 - style={{ 152 - backgroundColor: "var(--color-bg-secondary)", 153 - padding: "1rem", 154 - borderRadius: "0.5rem", 155 - marginBottom: "1rem", 156 - textAlign: "center", 157 - color: "var(--color-text-secondary)", 158 - fontSize: "0.875rem", 159 - }} 160 - > 129 + <div className="flex md:hidden flex-1 flex-col overflow-auto p-4"> 130 + <div className="bg-gray-50 dark:bg-gray-800 p-4 rounded-lg mb-4 text-center text-gray-500 dark:text-gray-400 text-sm"> 161 131 Playground available on desktop 162 132 </div> 163 133 ··· 190 160 const jsonWrappedLines = estimateWrappedLines(json, 50); 191 161 192 162 return ( 193 - <div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}> 163 + <div className="flex flex-col gap-4"> 194 164 {/* You write section */} 195 - <div style={{ display: "flex", flexDirection: "column" }}> 196 - <div 197 - style={{ 198 - padding: "0.75rem 1rem", 199 - backgroundColor: "var(--color-bg-secondary)", 200 - borderBottom: "1px solid var(--color-border)", 201 - fontSize: "0.875rem", 202 - fontWeight: "600", 203 - color: "var(--color-text-secondary)", 204 - borderTopLeftRadius: "0.5rem", 205 - borderTopRightRadius: "0.5rem", 206 - }} 207 - > 165 + <div className="flex flex-col"> 166 + <div className="py-3 px-4 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 text-sm font-semibold text-gray-500 dark:text-gray-400 rounded-t-lg"> 208 167 You write 209 168 </div> 210 - <div 211 - style={{ 212 - border: "1px solid var(--color-border)", 213 - borderTop: "none", 214 - borderBottomLeftRadius: "0.5rem", 215 - borderBottomRightRadius: "0.5rem", 216 - overflow: "hidden", 217 - }} 218 - > 169 + <div className="border border-gray-200 dark:border-gray-700 border-t-0 rounded-b-lg overflow-hidden"> 219 170 <MonacoEditor 220 171 height={`${String(codeWrappedLines * 18 + 32)}px`} 221 172 defaultLanguage="typescript" ··· 244 195 </div> 245 196 246 197 {/* JSON generated section */} 247 - <div style={{ display: "flex", flexDirection: "column" }}> 248 - <div 249 - style={{ 250 - padding: "0.75rem 1rem", 251 - backgroundColor: "var(--color-bg-secondary)", 252 - borderBottom: "1px solid var(--color-border)", 253 - fontSize: "0.875rem", 254 - fontWeight: "600", 255 - color: "var(--color-text-secondary)", 256 - borderTopLeftRadius: "0.5rem", 257 - borderTopRightRadius: "0.5rem", 258 - }} 259 - > 198 + <div className="flex flex-col"> 199 + <div className="py-3 px-4 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 text-sm font-semibold text-gray-500 dark:text-gray-400 rounded-t-lg"> 260 200 JSON generated 261 201 </div> 262 - <div 263 - style={{ 264 - border: "1px solid var(--color-border)", 265 - borderTop: "none", 266 - borderBottomLeftRadius: "0.5rem", 267 - borderBottomRightRadius: "0.5rem", 268 - overflow: "hidden", 269 - }} 270 - > 202 + <div className="border border-gray-200 dark:border-gray-700 border-t-0 rounded-b-lg overflow-hidden"> 271 203 <MonacoEditor 272 204 height={`${String(jsonWrappedLines * 18 + 32)}px`} 273 205 defaultLanguage="json"
+2 -129
packages/site/src/index.css
··· 1 - /* 2 - Josh's Custom CSS Reset 3 - https://www.joshwcomeau.com/css/custom-css-reset/ 4 - */ 5 - *, 6 - *::before, 7 - *::after { 8 - box-sizing: border-box; 9 - } 10 - 11 - * { 12 - margin: 0; 13 - } 14 - 15 - body { 16 - line-height: 1.5; 17 - -webkit-font-smoothing: antialiased; 18 - } 19 - 20 - img, 21 - picture, 22 - video, 23 - canvas, 24 - svg { 25 - display: block; 26 - max-width: 100%; 27 - } 28 - 29 - input, 30 - button, 31 - textarea, 32 - select { 33 - font: inherit; 34 - } 35 - 36 - p, 37 - h1, 38 - h2, 39 - h3, 40 - h4, 41 - h5, 42 - h6 { 43 - overflow-wrap: break-word; 44 - } 45 - 46 - #root { 47 - isolation: isolate; 48 - } 1 + @import "tailwindcss"; 49 2 50 3 :root { 51 4 font-family: 52 5 -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", 53 6 "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 54 - line-height: 1.5; 55 - font-weight: 400; 56 7 font-synthesis: none; 57 8 text-rendering: optimizeLegibility; 58 9 -webkit-font-smoothing: antialiased; 59 10 -moz-osx-font-smoothing: grayscale; 60 - 61 - --color-text: #213547; 62 - --color-text-secondary: #6b7280; 63 - --color-text-heading: #111827; 64 - --color-bg: #ffffff; 65 - --color-bg-secondary: #f9fafb; 66 - --color-border: #e5e7eb; 67 - --color-error: #dc2626; 68 - --color-error-bg: #fef2f2; 69 - 70 - color: var(--color-text); 71 - background-color: var(--color-bg); 72 - } 73 - 74 - @media (prefers-color-scheme: dark) { 75 - :root { 76 - --color-text: #e5e7eb; 77 - --color-text-secondary: #9ca3af; 78 - --color-text-heading: #f9fafb; 79 - --color-bg: #111827; 80 - --color-bg-secondary: #1f2937; 81 - --color-border: #374151; 82 - --color-error: #f87171; 83 - --color-error-bg: #3f1f1f; 84 - } 85 11 } 86 12 87 13 body { 88 - display: flex; 89 14 min-width: 320px; 90 15 min-height: 100vh; 91 16 } 92 17 93 18 #root { 94 - width: 100%; 95 - display: flex; 96 - flex-direction: column; 97 - } 98 - 99 - /* Desktop layout - default */ 100 - .header-content { 101 - display: flex; 102 - justify-content: space-between; 103 - align-items: flex-start; 104 - } 105 - 106 - .header-links { 107 - display: flex; 108 - gap: 1.25rem; 109 - padding-top: 0.5rem; 110 - } 111 - 112 - .mobile-only { 113 - display: none; 114 - } 115 - 116 - .desktop-only { 117 - display: flex; 118 - } 119 - 120 - /* Mobile layout */ 121 - @media (max-width: 768px) { 122 - .header-content { 123 - flex-direction: column; 124 - gap: 1rem; 125 - } 126 - 127 - .header-links { 128 - padding-top: 0; 129 - width: 100%; 130 - justify-content: flex-start; 131 - } 132 - 133 - .mobile-only { 134 - display: flex !important; 135 - flex-direction: column; 136 - } 137 - 138 - .desktop-only { 139 - display: none !important; 140 - } 141 - 142 - .link-container { 143 - width: 100%; 144 - flex-direction: row !important; 145 - justify-content: space-between; 146 - } 19 + isolation: isolate; 147 20 }
+2
packages/site/vite.config.ts
··· 1 1 import { defineConfig } from "vite"; 2 2 import react from "@vitejs/plugin-react"; 3 + import tailwindcss from "@tailwindcss/vite"; 3 4 4 5 export default defineConfig({ 5 6 plugins: [ 7 + tailwindcss(), 6 8 react({ 7 9 babel: { 8 10 plugins: [["babel-plugin-react-compiler", {}]],
+191
pnpm-lock.yaml
··· 82 82 specifier: ^19.2.0 83 83 version: 19.2.0(react@19.2.0) 84 84 devDependencies: 85 + '@tailwindcss/vite': 86 + specifier: ^4.1.17 87 + version: 4.1.17(rolldown-vite@7.0.6(@types/node@24.0.4)(esbuild@0.25.10)(jiti@2.6.1)) 85 88 '@testing-library/jest-dom': 86 89 specifier: ^6.9.1 87 90 version: 6.9.1 ··· 109 112 jsdom: 110 113 specifier: ^25.0.1 111 114 version: 25.0.1 115 + tailwindcss: 116 + specifier: ^4.1.17 117 + version: 4.1.17 112 118 typescript: 113 119 specifier: 5.8.3 114 120 version: 5.8.3 ··· 890 896 891 897 '@standard-schema/spec@1.0.0': 892 898 resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} 899 + 900 + '@tailwindcss/node@4.1.17': 901 + resolution: {integrity: sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==} 902 + 903 + '@tailwindcss/oxide-android-arm64@4.1.17': 904 + resolution: {integrity: sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==} 905 + engines: {node: '>= 10'} 906 + cpu: [arm64] 907 + os: [android] 908 + 909 + '@tailwindcss/oxide-darwin-arm64@4.1.17': 910 + resolution: {integrity: sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==} 911 + engines: {node: '>= 10'} 912 + cpu: [arm64] 913 + os: [darwin] 914 + 915 + '@tailwindcss/oxide-darwin-x64@4.1.17': 916 + resolution: {integrity: sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==} 917 + engines: {node: '>= 10'} 918 + cpu: [x64] 919 + os: [darwin] 920 + 921 + '@tailwindcss/oxide-freebsd-x64@4.1.17': 922 + resolution: {integrity: sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==} 923 + engines: {node: '>= 10'} 924 + cpu: [x64] 925 + os: [freebsd] 926 + 927 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': 928 + resolution: {integrity: sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==} 929 + engines: {node: '>= 10'} 930 + cpu: [arm] 931 + os: [linux] 932 + 933 + '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': 934 + resolution: {integrity: sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==} 935 + engines: {node: '>= 10'} 936 + cpu: [arm64] 937 + os: [linux] 938 + 939 + '@tailwindcss/oxide-linux-arm64-musl@4.1.17': 940 + resolution: {integrity: sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==} 941 + engines: {node: '>= 10'} 942 + cpu: [arm64] 943 + os: [linux] 944 + 945 + '@tailwindcss/oxide-linux-x64-gnu@4.1.17': 946 + resolution: {integrity: sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==} 947 + engines: {node: '>= 10'} 948 + cpu: [x64] 949 + os: [linux] 950 + 951 + '@tailwindcss/oxide-linux-x64-musl@4.1.17': 952 + resolution: {integrity: sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==} 953 + engines: {node: '>= 10'} 954 + cpu: [x64] 955 + os: [linux] 956 + 957 + '@tailwindcss/oxide-wasm32-wasi@4.1.17': 958 + resolution: {integrity: sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==} 959 + engines: {node: '>=14.0.0'} 960 + cpu: [wasm32] 961 + bundledDependencies: 962 + - '@napi-rs/wasm-runtime' 963 + - '@emnapi/core' 964 + - '@emnapi/runtime' 965 + - '@tybys/wasm-util' 966 + - '@emnapi/wasi-threads' 967 + - tslib 968 + 969 + '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': 970 + resolution: {integrity: sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==} 971 + engines: {node: '>= 10'} 972 + cpu: [arm64] 973 + os: [win32] 974 + 975 + '@tailwindcss/oxide-win32-x64-msvc@4.1.17': 976 + resolution: {integrity: sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==} 977 + engines: {node: '>= 10'} 978 + cpu: [x64] 979 + os: [win32] 980 + 981 + '@tailwindcss/oxide@4.1.17': 982 + resolution: {integrity: sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==} 983 + engines: {node: '>= 10'} 984 + 985 + '@tailwindcss/vite@4.1.17': 986 + resolution: {integrity: sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==} 987 + peerDependencies: 988 + vite: ^5.2.0 || ^6 || ^7 893 989 894 990 '@testing-library/dom@10.4.1': 895 991 resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} ··· 1314 1410 resolution: {integrity: sha512-rsPft6CK3eHtrlp9Y5ALBb+hfK+DWnA4WFebbazxjWyx8vSm3rZeoM3z9irsjcqO3PYRzlfv27XIB4tz2DV7RA==} 1315 1411 engines: {node: '>=14'} 1316 1412 1413 + enhanced-resolve@5.18.3: 1414 + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} 1415 + engines: {node: '>=10.13.0'} 1416 + 1317 1417 enquirer@2.4.1: 1318 1418 resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} 1319 1419 engines: {node: '>=8.6'} ··· 1820 1920 magic-string@0.30.19: 1821 1921 resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} 1822 1922 1923 + magic-string@0.30.21: 1924 + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} 1925 + 1823 1926 make-synchronized@0.4.2: 1824 1927 resolution: {integrity: sha512-EwEJSg8gSGLicKXp/VzNi1tvzhdmNBxOzslkkJSoNUCQFZKH/NIUIp7xlfN+noaHrz4BJDN73gne8IHnjl/F/A==} 1825 1928 ··· 2255 2358 2256 2359 symbol-tree@3.2.4: 2257 2360 resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} 2361 + 2362 + tailwindcss@4.1.17: 2363 + resolution: {integrity: sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==} 2364 + 2365 + tapable@2.3.0: 2366 + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} 2367 + engines: {node: '>=6'} 2258 2368 2259 2369 term-size@2.2.1: 2260 2370 resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} ··· 3282 3392 3283 3393 '@standard-schema/spec@1.0.0': {} 3284 3394 3395 + '@tailwindcss/node@4.1.17': 3396 + dependencies: 3397 + '@jridgewell/remapping': 2.3.5 3398 + enhanced-resolve: 5.18.3 3399 + jiti: 2.6.1 3400 + lightningcss: 1.30.2 3401 + magic-string: 0.30.21 3402 + source-map-js: 1.2.1 3403 + tailwindcss: 4.1.17 3404 + 3405 + '@tailwindcss/oxide-android-arm64@4.1.17': 3406 + optional: true 3407 + 3408 + '@tailwindcss/oxide-darwin-arm64@4.1.17': 3409 + optional: true 3410 + 3411 + '@tailwindcss/oxide-darwin-x64@4.1.17': 3412 + optional: true 3413 + 3414 + '@tailwindcss/oxide-freebsd-x64@4.1.17': 3415 + optional: true 3416 + 3417 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': 3418 + optional: true 3419 + 3420 + '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': 3421 + optional: true 3422 + 3423 + '@tailwindcss/oxide-linux-arm64-musl@4.1.17': 3424 + optional: true 3425 + 3426 + '@tailwindcss/oxide-linux-x64-gnu@4.1.17': 3427 + optional: true 3428 + 3429 + '@tailwindcss/oxide-linux-x64-musl@4.1.17': 3430 + optional: true 3431 + 3432 + '@tailwindcss/oxide-wasm32-wasi@4.1.17': 3433 + optional: true 3434 + 3435 + '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': 3436 + optional: true 3437 + 3438 + '@tailwindcss/oxide-win32-x64-msvc@4.1.17': 3439 + optional: true 3440 + 3441 + '@tailwindcss/oxide@4.1.17': 3442 + optionalDependencies: 3443 + '@tailwindcss/oxide-android-arm64': 4.1.17 3444 + '@tailwindcss/oxide-darwin-arm64': 4.1.17 3445 + '@tailwindcss/oxide-darwin-x64': 4.1.17 3446 + '@tailwindcss/oxide-freebsd-x64': 4.1.17 3447 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.17 3448 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.17 3449 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.17 3450 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.17 3451 + '@tailwindcss/oxide-linux-x64-musl': 4.1.17 3452 + '@tailwindcss/oxide-wasm32-wasi': 4.1.17 3453 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.17 3454 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.17 3455 + 3456 + '@tailwindcss/vite@4.1.17(rolldown-vite@7.0.6(@types/node@24.0.4)(esbuild@0.25.10)(jiti@2.6.1))': 3457 + dependencies: 3458 + '@tailwindcss/node': 4.1.17 3459 + '@tailwindcss/oxide': 4.1.17 3460 + tailwindcss: 4.1.17 3461 + vite: rolldown-vite@7.0.6(@types/node@24.0.4)(esbuild@0.25.10)(jiti@2.6.1) 3462 + 3285 3463 '@testing-library/dom@10.4.1': 3286 3464 dependencies: 3287 3465 '@babel/code-frame': 7.27.1 ··· 3740 3918 3741 3919 empathic@1.1.0: {} 3742 3920 3921 + enhanced-resolve@5.18.3: 3922 + dependencies: 3923 + graceful-fs: 4.2.11 3924 + tapable: 2.3.0 3925 + 3743 3926 enquirer@2.4.1: 3744 3927 dependencies: 3745 3928 ansi-colors: 4.1.3 ··· 4272 4455 dependencies: 4273 4456 '@jridgewell/sourcemap-codec': 1.5.5 4274 4457 4458 + magic-string@0.30.21: 4459 + dependencies: 4460 + '@jridgewell/sourcemap-codec': 1.5.5 4461 + 4275 4462 make-synchronized@0.4.2: {} 4276 4463 4277 4464 math-intrinsics@1.1.0: {} ··· 4640 4827 has-flag: 4.0.0 4641 4828 4642 4829 symbol-tree@3.2.4: {} 4830 + 4831 + tailwindcss@4.1.17: {} 4832 + 4833 + tapable@2.3.0: {} 4643 4834 4644 4835 term-size@2.2.1: {} 4645 4836