1.6-7-8 implemented
Some checks failed
Build and Push to Docker Hub / Push Docker image to Docker Hub (push) Has been cancelled
Build and Push Docker Image / build-and-push (push) Has been cancelled

This commit is contained in:
nicholai 2025-09-24 19:23:57 -06:00
parent 3dfb49551b
commit e3e3a91bdf
70 changed files with 6709 additions and 868 deletions

View File

@ -25,6 +25,16 @@
"static/chunks/webpack.js", "static/chunks/webpack.js",
"static/chunks/main-app.js", "static/chunks/main-app.js",
"static/chunks/app/crew/page.js" "static/chunks/app/crew/page.js"
],
"/contact/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/contact/page.js"
],
"/projects/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/projects/page.js"
] ]
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
{ {
"/icon.svg/route": "app/icon.svg/route.js", "/icon.svg/route": "app/icon.svg/route.js",
"/api/auth/[...nextauth]/route": "app/api/auth/[...nextauth]/route.js",
"/page": "app/page.js", "/page": "app/page.js",
"/crew/page": "app/crew/page.js" "/crew/page": "app/crew/page.js",
"/contact/page": "app/contact/page.js",
"/projects/page": "app/projects/page.js"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -788,6 +788,31 @@ select {
--tracking-normal: -0.025em; --tracking-normal: -0.025em;
} }
html:not(.dark) {
color-scheme: light;
/* Light mode palette: white + orange (accent) */
--background: oklch(0.985 0 0);
--foreground: oklch(0.14 0 0);
--card: oklch(0.98 0 0);
--card-foreground: oklch(0.16 0 0);
--popover: oklch(0.99 0 0);
--popover-foreground: oklch(0.16 0 0);
--primary: oklch(0.16 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.92 0 0);
--secondary-foreground: oklch(0.16 0 0);
--muted: oklch(0.95 0 0);
--muted-foreground: oklch(0.47 0 0);
/* Keep the orange accent consistent across modes */
--accent: oklch(0.6677 0.2235 36.9862);
--accent-foreground: oklch(0.16 0 0);
--destructive: oklch(0.6677 0.2235 36.9862);
--destructive-foreground: oklch(0.16 0 0);
--border: oklch(0.92 0 0);
--input: oklch(0.92 0 0);
--ring: oklch(0.6 0 0);
}
*, *::before, *::after { *, *::before, *::after {
box-sizing: border-box; box-sizing: border-box;
} }
@ -2036,6 +2061,9 @@ select {
.mt-2 { .mt-2 {
margin-top: 0.5rem; margin-top: 0.5rem;
} }
.mt-2\.5 {
margin-top: 0.625rem;
}
.mt-20 { .mt-20 {
margin-top: 5rem; margin-top: 5rem;
} }
@ -2057,6 +2085,9 @@ select {
.mt-auto { .mt-auto {
margin-top: auto; margin-top: auto;
} }
.ml-1 {
margin-left: 0.25rem;
}
.line-clamp-2 { .line-clamp-2 {
overflow: hidden; overflow: hidden;
display: -webkit-box; display: -webkit-box;
@ -2289,10 +2320,6 @@ select {
.w-auto { .w-auto {
width: auto; width: auto;
} }
.w-fit {
width: -moz-fit-content;
width: fit-content;
}
.w-full { .w-full {
width: 100%; width: 100%;
} }
@ -2499,6 +2526,9 @@ select {
.items-center { .items-center {
align-items: center; align-items: center;
} }
.items-baseline {
align-items: baseline;
}
.justify-end { .justify-end {
justify-content: flex-end; justify-content: flex-end;
} }
@ -2562,11 +2592,6 @@ select {
margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
} }
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
}
.space-y-10 > :not([hidden]) ~ :not([hidden]) { .space-y-10 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0; --tw-space-y-reverse: 0;
margin-top: calc(2.5rem * calc(1 - var(--tw-space-y-reverse))); margin-top: calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));
@ -2582,6 +2607,11 @@ select {
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
} }
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.625rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.625rem * var(--tw-space-y-reverse));
}
.space-y-3 > :not([hidden]) ~ :not([hidden]) { .space-y-3 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0; --tw-space-y-reverse: 0;
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
@ -2647,9 +2677,6 @@ select {
.rounded-3xl { .rounded-3xl {
border-radius: 1.5rem; border-radius: 1.5rem;
} }
.rounded-\[calc\(var\(--radius\)-2px\)\] {
border-radius: calc(var(--radius) - 2px);
}
.rounded-\[var\(--radius\)\] { .rounded-\[var\(--radius\)\] {
border-radius: var(--radius); border-radius: var(--radius);
} }
@ -2714,12 +2741,6 @@ select {
.border-border { .border-border {
border-color: hsl(var(--border)); border-color: hsl(var(--border));
} }
.border-border\/30 {
border-color: hsl(var(--border) / 0.3);
}
.border-border\/60 {
border-color: hsl(var(--border) / 0.6);
}
.border-destructive { .border-destructive {
border-color: hsl(var(--destructive)); border-color: hsl(var(--destructive));
} }
@ -3165,10 +3186,6 @@ select {
.p-8 { .p-8 {
padding: 2rem; padding: 2rem;
} }
.px-1\.5 {
padding-left: 0.375rem;
padding-right: 0.375rem;
}
.px-2 { .px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
@ -3193,14 +3210,14 @@ select {
padding-left: 2rem; padding-left: 2rem;
padding-right: 2rem; padding-right: 2rem;
} }
.py-0\.5 {
padding-top: 0.125rem;
padding-bottom: 0.125rem;
}
.py-1 { .py-1 {
padding-top: 0.25rem; padding-top: 0.25rem;
padding-bottom: 0.25rem; padding-bottom: 0.25rem;
} }
.py-1\.5 {
padding-top: 0.375rem;
padding-bottom: 0.375rem;
}
.py-12 { .py-12 {
padding-top: 3rem; padding-top: 3rem;
padding-bottom: 3rem; padding-bottom: 3rem;
@ -3259,9 +3276,6 @@ select {
.pl-20 { .pl-20 {
padding-left: 5rem; padding-left: 5rem;
} }
.pl-3 {
padding-left: 0.75rem;
}
.pl-4 { .pl-4 {
padding-left: 1rem; padding-left: 1rem;
} }
@ -3359,6 +3373,9 @@ select {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 1rem; line-height: 1rem;
} }
.text-\[10px\] {
font-size: 10px;
}
.font-bold { .font-bold {
font-weight: 700; font-weight: 700;
} }
@ -4358,14 +4375,6 @@ select {
gap: 2rem; gap: 2rem;
} }
.md\:border-r {
border-right-width: 1px;
}
.md\:border-border\/30 {
border-color: hsl(var(--border) / 0.3);
}
.md\:p-12 { .md\:p-12 {
padding: 3rem; padding: 3rem;
} }

View File

@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@ -0,0 +1 @@
{"c":["webpack"],"r":[],"m":[]}

View File

@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (\"ec70b4b2d65b\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6Ijs7OztBQUFBLGlFQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyIvaG9tZS9OaWNob2xhaS9Eb2N1bWVudHMvRGV2L2Jpb2hhemFyZC12ZngtMi9zcmMvYXBwL2dsb2JhbHMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IFwiZWM3MGI0YjJkNjViXCJcbmlmIChtb2R1bGUuaG90KSB7IG1vZHVsZS5ob3QuYWNjZXB0KCkgfVxuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"c":["webpack"],"r":[],"m":[]}

View File

@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("f50f984d07bbe339")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCJmNTBmOTg0ZDA3YmJlMzM5XCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("4399de05d29ca554")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCI0Mzk5ZGUwNWQyOWNhNTU0XCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("85a3844630e99d91")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCI4NWEzODQ0NjMwZTk5ZDkxXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("d5d46ecc0d13388f")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCJkNWQ0NmVjYzBkMTMzODhmXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("2db6856c72db095c")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCIyZGI2ODU2YzcyZGIwOTVjXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("2de4ada8f2d60b4b")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCIyZGU0YWRhOGYyZDYwYjRiXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

View File

@ -0,0 +1,12 @@
"use strict";
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("9c8224d89cf4d887")
/******/ })();
/******/
/******/ }
)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCI5YzgyMjRkODljZjRkODg3XCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,84 @@
// File: /home/Nicholai/Documents/Dev/biohazard-vfx-2/src/app/contact/page.tsx
import * as entry from '../../../../src/app/contact/page.js'
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
type TEntry = typeof import('../../../../src/app/contact/page.js')
type SegmentParams<T extends Object = any> = T extends Record<string, any>
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
: T
// Check that the entry is a valid entry
checkFields<Diff<{
default: Function
config?: {}
generateStaticParams?: Function
revalidate?: RevalidateRange<TEntry> | false
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
dynamicParams?: boolean
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
maxDuration?: number
metadata?: any
generateMetadata?: Function
viewport?: any
generateViewport?: Function
experimental_ppr?: boolean
}, TEntry, ''>>()
// Check the prop type of the entry function
checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
// Check the arguments and return type of the generateMetadata function
if ('generateMetadata' in entry) {
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
}
// Check the arguments and return type of the generateViewport function
if ('generateViewport' in entry) {
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
}
// Check the arguments and return type of the generateStaticParams function
if ('generateStaticParams' in entry) {
checkFields<Diff<{ params: SegmentParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
}
export interface PageProps {
params?: Promise<SegmentParams>
searchParams?: Promise<any>
}
export interface LayoutProps {
children?: React.ReactNode
params?: Promise<SegmentParams>
}
// =============
// Utility types
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
function checkFields<_ extends { [k in keyof any]: never }>() {}
// https://github.com/sindresorhus/type-fest
type Numeric = number | bigint
type Zero = 0 | 0n
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'

View File

@ -0,0 +1,84 @@
// File: /home/Nicholai/Documents/Dev/biohazard-vfx-2/src/app/projects/page.tsx
import * as entry from '../../../../src/app/projects/page.js'
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
type TEntry = typeof import('../../../../src/app/projects/page.js')
type SegmentParams<T extends Object = any> = T extends Record<string, any>
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
: T
// Check that the entry is a valid entry
checkFields<Diff<{
default: Function
config?: {}
generateStaticParams?: Function
revalidate?: RevalidateRange<TEntry> | false
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
dynamicParams?: boolean
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
maxDuration?: number
metadata?: any
generateMetadata?: Function
viewport?: any
generateViewport?: Function
experimental_ppr?: boolean
}, TEntry, ''>>()
// Check the prop type of the entry function
checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
// Check the arguments and return type of the generateMetadata function
if ('generateMetadata' in entry) {
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
}
// Check the arguments and return type of the generateViewport function
if ('generateViewport' in entry) {
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
}
// Check the arguments and return type of the generateStaticParams function
if ('generateStaticParams' in entry) {
checkFields<Diff<{ params: SegmentParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
}
export interface PageProps {
params?: Promise<SegmentParams>
searchParams?: Promise<any>
}
export interface LayoutProps {
children?: React.ReactNode
params?: Promise<SegmentParams>
}
// =============
// Utility types
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
function checkFields<_ extends { [k in keyof any]: never }>() {}
// https://github.com/sindresorhus/type-fest
type Numeric = number | bigint
type Zero = 0 | 0n
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'

View File

@ -92,6 +92,31 @@
--tracking-normal: -0.025em; --tracking-normal: -0.025em;
} }
html:not(.dark) {
color-scheme: light;
/* Light mode palette: white + orange (accent) */
--background: oklch(0.985 0 0);
--foreground: oklch(0.14 0 0);
--card: oklch(0.98 0 0);
--card-foreground: oklch(0.16 0 0);
--popover: oklch(0.99 0 0);
--popover-foreground: oklch(0.16 0 0);
--primary: oklch(0.16 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.92 0 0);
--secondary-foreground: oklch(0.16 0 0);
--muted: oklch(0.95 0 0);
--muted-foreground: oklch(0.47 0 0);
/* Keep the orange accent consistent across modes */
--accent: oklch(0.6677 0.2235 36.9862);
--accent-foreground: oklch(0.16 0 0);
--destructive: oklch(0.6677 0.2235 36.9862);
--destructive-foreground: oklch(0.16 0 0);
--border: oklch(0.92 0 0);
--input: oklch(0.92 0 0);
--ring: oklch(0.6 0 0);
}
*, *::before, *::after { *, *::before, *::after {
box-sizing: border-box; box-sizing: border-box;
} }

View File

@ -10,6 +10,8 @@ type NavItem = {
label: string label: string
href: string href: string
description?: string description?: string
count?: number
highlight?: boolean
} }
type NavGroup = { type NavGroup = {
@ -55,6 +57,7 @@ const NAV_GROUPS: NavGroup[] = [
label: 'Our Team', label: 'Our Team',
href: '/studio/team', href: '/studio/team',
description: 'Meet the people behind the work', description: 'Meet the people behind the work',
highlight: true,
}, },
{ {
label: 'Values', label: 'Values',
@ -106,10 +109,10 @@ export default function GlobalSidebar() {
return ( return (
<aside <aside
aria-label="Primary" aria-label="Primary"
className="bg-background/90 backdrop-blur-sm text-sm text-muted-foreground md:fixed md:inset-y-0 md:left-0 md:w-[256px] md:border-r md:border-border/30" className="bg-background/90 backdrop-blur-sm text-sm text-muted-foreground md:fixed md:inset-y-0 md:left-0 md:w-[256px]"
> >
<div className="flex flex-col md:h-full"> <div className="flex flex-col md:h-full">
<div className="flex items-center gap-3 px-5 py-6 border-b border-border/30"> <div className="flex items-center gap-3 px-5 py-6">
<Link <Link
href="/" href="/"
className="inline-flex items-center gap-3 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent/50" className="inline-flex items-center gap-3 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent/50"
@ -125,7 +128,9 @@ export default function GlobalSidebar() {
/> />
</span> </span>
<span className="flex flex-col"> <span className="flex flex-col">
<span className="font-bold tracking-wider text-foreground text-sm">Biohazard VFX</span> <span className="font-bold tracking-wider text-foreground text-sm">
Biohazard VFX
</span>
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">
Visual Research Studio Visual Research Studio
</span> </span>
@ -137,9 +142,9 @@ export default function GlobalSidebar() {
<ul className="space-y-6"> <ul className="space-y-6">
{NAV_GROUPS.map((group) => ( {NAV_GROUPS.map((group) => (
<li key={group.title}> <li key={group.title}>
<h2 className="text-xs font-semibold tracking-widest uppercase text-muted-foreground relative pl-3 px-2">{group.title}</h2> <h2 className="font-mono text-[11px] tracking-widest uppercase text-muted-foreground">{`${group.title.toUpperCase()}`}</h2>
<ul className="mt-3 space-y-1.5"> <ul className="mt-2.5 space-y-2.5">
{group.items.map((item) => { {group.items.map((item, idx) => {
const active = isActive(pathname, item.href) const active = isActive(pathname, item.href)
return ( return (
<li key={item.href}> <li key={item.href}>
@ -149,17 +154,30 @@ export default function GlobalSidebar() {
aria-current={active ? 'page' : undefined} aria-current={active ? 'page' : undefined}
data-active={active ? 'true' : undefined} data-active={active ? 'true' : undefined}
className={cn( className={cn(
'group flex flex-col gap-1 rounded-lg border px-3 py-2 transition-all focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent/45 border-border/60 text-muted-foreground' 'group block pl-6 py-1.5 text-sm text-muted-foreground hover:text-accent transition-colors'
)} )}
> >
<span className="inline-flex items-center w-fit px-2 py-1 border rounded-[calc(var(--radius)-2px)] text-xs font-semibold tracking-widest uppercase leading-none text-muted-foreground bg-transparent border-border/60"> <span className="inline-flex items-baseline gap-2">
{item.label} <span className="font-mono text-xs text-muted-foreground group-hover:text-accent transition-colors">
</span> {idx === group.items.length - 1 ? '└' : '├'}
{item.description ? (
<span className="text-[11px] leading-relaxed text-muted-foreground">
{item.description}
</span> </span>
) : null} <span
className={cn(
item.highlight
? 'text-accent font-semibold'
: active
? 'text-foreground font-semibold'
: ''
)}
>
{item.label.toUpperCase()}
</span>
{typeof item.count === 'number' ? (
<sup className="ml-1 text-[10px] text-accent">
{item.count}
</sup>
) : null}
</span>
</Link> </Link>
</li> </li>
) )
@ -170,12 +188,27 @@ export default function GlobalSidebar() {
</ul> </ul>
</nav> </nav>
<div className="px-5 py-4 border-t border-border/30"> <div className="px-5 py-4">
<p className="text-xs leading-relaxed text-muted-foreground"> <div className="text-xs text-muted-foreground">
Command Palette available with{' '} <Link href="/privacy" className="hover:text-accent">
<kbd className="rounded bg-muted px-1.5 py-0.5 text-[11px] text-foreground shadow-inner"> LEGAL
/ Ctrl + K </Link>
</kbd> <span className="mx-2">/</span>
<a
href="https://www.instagram.com/biohazardvfx/"
target="_blank"
rel="noopener noreferrer"
className="hover:text-accent"
>
SOCIAL
</a>
<span className="mx-2">/</span>
<Link href="/contact" className="hover:text-accent">
SUPPORT
</Link>
</div>
<p className="mt-2 text-[11px] text-muted-foreground">
Shortcuts: /Ctrl + K
</p> </p>
</div> </div>
</div> </div>

View File

@ -39,9 +39,9 @@ const config: Config = {
foreground: 'hsl(var(--muted-foreground))', foreground: 'hsl(var(--muted-foreground))',
}, },
accent: { accent: {
DEFAULT: 'rgb(var(--accent))', DEFAULT: 'hsl(var(--accent))',
hover: 'rgb(var(--accent-hover))', hover: 'hsl(var(--accent) / 0.85)',
soft: 'rgb(var(--brand-accent-soft))', soft: 'hsl(var(--accent) / 0.2)',
foreground: 'hsl(var(--accent-foreground))', foreground: 'hsl(var(--accent-foreground))',
}, },
destructive: { destructive: {