chore: add basic layout
This commit is contained in:
committed by
Mathias Schopmans
parent
f3979f2a2f
commit
57cdb91ec7
@@ -1,3 +1,6 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
"extends": "next/core-web-vitals",
|
||||
"rules": {
|
||||
"@next/next/no-img-element": "off"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: "export",
|
||||
// basePath: '/techradar',
|
||||
reactStrictMode: true,
|
||||
};
|
||||
|
||||
|
||||
1767
package-lock.json
generated
1767
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,10 @@
|
||||
"prepare": "husky"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.0",
|
||||
"next": "14.1.0",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"postcss-preset-env": "^9.3.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
|
||||
23
postcss.config.js
Normal file
23
postcss.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
plugins:
|
||||
process.env.NODE_ENV === "production"
|
||||
? [
|
||||
"postcss-nested",
|
||||
[
|
||||
"postcss-preset-env",
|
||||
{
|
||||
autoprefixer: {
|
||||
flexbox: "no-2009",
|
||||
},
|
||||
stage: 3,
|
||||
features: {
|
||||
"custom-properties": false,
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
: [
|
||||
// No transformations in development
|
||||
// because it won't affect turbo
|
||||
],
|
||||
};
|
||||
1
public/logo.svg
Normal file
1
public/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 150 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><rect id="ArtBoard1" x="0" y="0" width="150" height="60" style="fill:none;"/><g><path d="M82.126,28.638c0.058,0.171 -0.042,0.309 -0.22,0.309l-5.318,0c-0.179,0 -0.276,-0.138 -0.217,-0.306l2.817,-8.047c0.059,-0.168 0.155,-0.168 0.212,0l2.726,8.044Zm-6.583,-16.289c-0.179,0 -0.375,0.139 -0.436,0.305l-10.103,27.727c-0.061,0.168 0.035,0.307 0.214,0.307l7.316,0c0.179,0 0.366,-0.141 0.415,-0.312l1.329,-4.609c0.05,-0.173 0.236,-0.311 0.415,-0.311l9.059,0c0.179,0 0.366,0.138 0.415,0.311l1.33,4.609c0.05,0.171 0.236,0.312 0.415,0.312l7.681,0c0.179,0 0.274,-0.139 0.213,-0.304l-10.216,-27.73c-0.062,-0.166 -0.259,-0.305 -0.437,-0.305l-7.61,0Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M107.736,34.36c-3.471,0 -4.925,-1.103 -4.925,-7.937c0,-7.088 1.565,-7.865 4.888,-7.865c3.322,0 4.887,0.777 4.887,7.865c0,6.834 -1.429,7.937 -4.85,7.937Zm-0.037,-22.373c-8.632,0 -12.481,4.453 -12.481,14.436c0,9.897 3.965,14.508 12.481,14.508c8.725,0 12.448,-4.338 12.448,-14.508c0,-9.983 -3.84,-14.436 -12.448,-14.436Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M124.72,40.35c0,0.175 0.142,0.318 0.317,0.318l21.646,0c0.174,0 0.317,-0.143 0.317,-0.318l0,-5.934c0,-0.175 -0.143,-0.319 -0.317,-0.319l-21.646,0c-0.175,0 -0.317,0.144 -0.317,0.319l0,5.934Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M125.032,12.349c-0.175,0 -0.318,0.144 -0.318,0.319l0,5.934c0,0.175 0.143,0.317 0.318,0.317l21.645,0c0.175,0 0.318,-0.142 0.318,-0.317l0,-5.934c0,-0.175 -0.143,-0.319 -0.318,-0.319l-21.645,0Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M124.714,29.476c0,0.175 0.143,0.319 0.318,0.319l21.645,0c0.175,0 0.318,-0.144 0.318,-0.319l0,-5.934c0,-0.175 -0.143,-0.319 -0.318,-0.319l-21.645,0c-0.175,0 -0.318,0.144 -0.318,0.319l0,5.934Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M29.494,9.418c-0.34,-0.148 -0.896,-0.148 -1.237,-0.002l-16.929,7.333c-0.341,0.146 -0.357,0.421 -0.036,0.609l16.962,9.88c0.321,0.188 0.583,0.643 0.584,1.016l0.01,19.427c0,0.372 0.246,0.496 0.545,0.277l14.717,-10.737c0.3,-0.217 0.58,-0.699 0.623,-1.067l2.132,-18.436c0.043,-0.367 -0.201,-0.791 -0.541,-0.94l-16.83,-7.36Zm25.668,2.35c0.343,0.141 0.581,0.557 0.529,0.922l-3.888,27.472c-0.052,0.368 -0.334,0.855 -0.626,1.084l-21.793,17.038c-0.292,0.229 -0.77,0.229 -1.063,0l-21.79,-17.038c-0.293,-0.229 -0.575,-0.716 -0.627,-1.084l-3.897,-27.472c-0.052,-0.365 0.187,-0.781 0.53,-0.922l25.714,-10.509c0.343,-0.141 0.905,-0.141 1.248,0l25.663,10.509Z" style="fill:#fff;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
127
public/messages.json
Normal file
127
public/messages.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"radarName": "AOE Technology Radar",
|
||||
"footerFootnote": "AOE is a leading global provider of services for digital transformation and digital business models. AOE relies exclusively on established Enterprise Open Source technologies. This leads to innovative solutions, digital products and portals in agile software projects, and helps build long-lasting, strategic partnerships with our customers.",
|
||||
"legalInformationLabel": "Legal Information",
|
||||
"legalInformationLink": "https://www.aoe.com/en/imprint.html",
|
||||
"pageHelp": {
|
||||
"headlinePrefix": "How to use the",
|
||||
"paragraphs": [
|
||||
{
|
||||
"headline": "Introduction",
|
||||
"values": [
|
||||
"Technology is moving fast and new technologies and innovations appear continuously.",
|
||||
"It's essential for a development and technology company such as AOE to constantly improve and keep track with the latest useful innovations. It is important to openly look for innovations and new technologies and to question established technologies and methods every now and then.",
|
||||
"But, it is also important to wisely choose which technologies to use in our daily work and in the different projects we are carrying out. As we all know: There is no silver bullet."
|
||||
]
|
||||
},
|
||||
{
|
||||
"headline": "What is the AOE Technology Radar",
|
||||
"values": [
|
||||
"The Tech Radar is an overview of different technologies - from languages, frameworks, tools and patterns to platforms - that we consider \"new or mentionable\". The radar therefore doesn't provide an overview of all established technologies - but it focuses on items that have recently gained in importance or changed."
|
||||
]
|
||||
},
|
||||
{
|
||||
"headline": "How it is created",
|
||||
"values": [
|
||||
"The items in the technology radar are raised by the different teams and therefore a lot of the items are related to the work and challenges the teams face in the different projects. In fact, we don't include anything on the radar, which we haven't already tried ourselves at least once.",
|
||||
"There have been a lot of valuable discussions in different expert groups about the classification and details of each of technologies and innovations. And the result of all this can be found in the latest technology radar."
|
||||
]
|
||||
},
|
||||
{
|
||||
"headline": "How should it be used",
|
||||
"values": [
|
||||
"The radar acts as an overview of technologies that we think everyone in the teams should currently know about.",
|
||||
"Its goal is to act as a guide and inspiration for the daily work in the teams. Its purpose is also to provide helpful information and a bird's-eye perspective - so that decisions can be taken with a much deeper understanding of the subject matter. This results in more-informed and better-aligned decisions.",
|
||||
"We also hope that developers outside of AOE find the information in our technology overview inspirational.",
|
||||
"We group or categorize the items in 4 quadrants - (sometimes, when it's not 100% clear where a item belongs, we choose the best fit)."
|
||||
]
|
||||
}
|
||||
],
|
||||
"quadrants": [
|
||||
{
|
||||
"description": "We've placed development languages (such as Scala or Golang) here, as well as more low-level development frameworks (such as Play or Symfony), which are useful for implementing custom software of all kinds.",
|
||||
"name": "Languages and Frameworks"
|
||||
},
|
||||
{
|
||||
"description": "Here we put different software tools - from small helpers to bigger software projects.",
|
||||
"name": "Tools"
|
||||
},
|
||||
{
|
||||
"description": "Patterns are so important, and a lot of them are valid for a long time (compared to some tools or frameworks). So, this is the category where we put information on methods and patterns concerning development, continuous x, testing, organization, architecture, etc.",
|
||||
"name": "Methods and Patterns"
|
||||
},
|
||||
{
|
||||
"description": "(including AOE internal Services): Here we include infrastructure platforms and services. We also use this category to communicate news about AOE services that we want all AOE teams to be aware of.",
|
||||
"name": "Platforms and Operations"
|
||||
}
|
||||
],
|
||||
"quadrantsPreDescription": "The quadrants are:",
|
||||
"rings": [
|
||||
{
|
||||
"description": "We can clearly recommend this technology. We have used it for longer period of time in many teams and it has proven to be stable and useful.",
|
||||
"name": "Adopt"
|
||||
},
|
||||
{
|
||||
"description": "We have used it with success and recommend to have a closer look at the technology in this ring. The goal of items here is to look at them more closely, with the goal to bring them to the adopt level.",
|
||||
"name": "Trial"
|
||||
},
|
||||
{
|
||||
"description": "We have tried it out and we find it promising. We recommend having a look at these items when you face a specific need for the technology in your project.",
|
||||
"name": "Assess"
|
||||
},
|
||||
{
|
||||
"description": "This category is a bit special. Unlike the others, we recommend to stop doing or using something. That does not mean that they are bad and it often might be ok to use them in existing projects. But we move things here if we think we shouldn't do them anymore - because we see better options or alternatives now.",
|
||||
"name": "Hold"
|
||||
}
|
||||
],
|
||||
"ringsPreDescription": "Each of the items is classified in one of these rings:",
|
||||
"sourcecodeLink": {
|
||||
"description": "Contributions and source code of the AOE Tech Radar are on github:",
|
||||
"href": "https://github.com/AOEpeople/aoe_technology_radar",
|
||||
"name": "AOE Tech Radar on Github"
|
||||
}
|
||||
},
|
||||
"pageIndex": {
|
||||
"publishedLabel": "Quadrant Overview"
|
||||
},
|
||||
"pageItem": {
|
||||
"quadrantOverview": "Quadrant Overview"
|
||||
},
|
||||
"pageOverview": {
|
||||
"title": "Technologies Overview"
|
||||
},
|
||||
"revisionsText": "Revisions:",
|
||||
"searchLabel": "Search",
|
||||
"searchPlaceholder": "What are you looking for?",
|
||||
"socialLinks": [
|
||||
{
|
||||
"href": "https://www.facebook.com/aoepeople",
|
||||
"iconName": "facebook"
|
||||
},
|
||||
{
|
||||
"href": "https://twitter.com/aoepeople",
|
||||
"iconName": "twitter"
|
||||
},
|
||||
{
|
||||
"href": "https://www.linkedin.com/company/aoe",
|
||||
"iconName": "linkedIn"
|
||||
},
|
||||
{
|
||||
"href": "https://www.xing.com/company/aoe",
|
||||
"iconName": "xing"
|
||||
},
|
||||
{
|
||||
"href": "https://www.instagram.com/aoepeople",
|
||||
"iconName": "instagram"
|
||||
},
|
||||
{
|
||||
"href": "https://www.youtube.com/user/aoepeople",
|
||||
"iconName": "youtube"
|
||||
},
|
||||
{
|
||||
"href": "https://github.com/aoepeople",
|
||||
"iconName": "github"
|
||||
}
|
||||
],
|
||||
"socialLinksLabel": "Follow us:"
|
||||
}
|
||||
0
src/components/Footer/Footer.module.css
Normal file
0
src/components/Footer/Footer.module.css
Normal file
9
src/components/Footer/Footer.tsx
Normal file
9
src/components/Footer/Footer.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import styles from "Footer.module.css";
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<div className={styles.footer}>
|
||||
<div className={styles.branding}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
23
src/components/Layout/Layout.module.css
Normal file
23
src/components/Layout/Layout.module.css
Normal file
@@ -0,0 +1,23 @@
|
||||
.layout {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.layout.default {
|
||||
.content {
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
35
src/components/Layout/Layout.tsx
Normal file
35
src/components/Layout/Layout.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Roboto } from "next/font/google";
|
||||
import type { FC, ReactNode } from "react";
|
||||
|
||||
import styles from "./Layout.module.css";
|
||||
|
||||
import { Logo } from "@/components/Logo/Logo";
|
||||
import { Navigation } from "@/components/Navigation/Navigation";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const font = Roboto({ weight: ["400", "700"], subsets: ["latin"] });
|
||||
|
||||
export type LayoutClass = "default" | "full";
|
||||
|
||||
interface LayoutProps {
|
||||
children: ReactNode;
|
||||
layoutClass?: LayoutClass;
|
||||
}
|
||||
|
||||
export const Layout: FC<LayoutProps> = ({
|
||||
children,
|
||||
layoutClass = "default",
|
||||
}) => {
|
||||
return (
|
||||
<div className={cn(styles.layout, font.className, styles[layoutClass])}>
|
||||
<header className={cn(styles.container, styles.header)}>
|
||||
<Logo />
|
||||
<Navigation />
|
||||
</header>
|
||||
<main className={cn(styles.content)}>{children}</main>
|
||||
<footer className={cn(styles.container, styles.header)}>
|
||||
<h2>Footer</h2>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
50
src/components/Logo/Logo.module.css
Normal file
50
src/components/Logo/Logo.module.css
Normal file
@@ -0,0 +1,50 @@
|
||||
.logo {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
min-height: 60px;
|
||||
gap: 16px;
|
||||
transition: padding-left 200ms ease-in-out;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background: url("../../icons/back.svg") no-repeat 50% 50%;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.src {
|
||||
width: 150px;
|
||||
transition: width 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.subline {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
font-size: 18px;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.logo.small {
|
||||
.subline {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.src {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
padding-left: 30px;
|
||||
&:before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/components/Logo/Logo.tsx
Normal file
21
src/components/Logo/Logo.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
import logo from "../../../public/logo.svg";
|
||||
import styles from "./Logo.module.css";
|
||||
|
||||
import { getAppName } from "@/lib/config";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function Logo() {
|
||||
const pathname = usePathname();
|
||||
const appName = getAppName();
|
||||
return (
|
||||
<Link href="/" className={cn(styles.logo, pathname != "/" && styles.small)}>
|
||||
<img src={logo.src} className={cn(styles.src)} alt={appName} />
|
||||
<span className={styles.subline}>{appName}</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
6
src/components/Navigation/Navigation.module.css
Normal file
6
src/components/Navigation/Navigation.module.css
Normal file
@@ -0,0 +1,6 @@
|
||||
.list {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
24
src/components/Navigation/Navigation.tsx
Normal file
24
src/components/Navigation/Navigation.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import styles from "./Navigation.module.css";
|
||||
|
||||
import { getAppName } from "@/lib/config";
|
||||
|
||||
export function Navigation() {
|
||||
return (
|
||||
<nav className={styles.nav}>
|
||||
<ul className={styles.list}>
|
||||
<li className={styles.item}>
|
||||
<Link href="/help-and-about-tech-radar">
|
||||
How to use {getAppName()}?
|
||||
</Link>
|
||||
</li>
|
||||
<li className={styles.item}>Filter</li>
|
||||
<li className={styles.item}>
|
||||
<Link href="/overview">Technologies Overview</Link>
|
||||
</li>
|
||||
<li className={styles.item}>Search</li>
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
3
src/icons/back.svg
Normal file
3
src/icons/back.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421"
|
||||
viewBox="0 0 30 21"><path d="M4.012 11.427h24.704a1.134 1.134 0 0 0 0-2.267H3.729l7.224-7.225A1.133 1.133 0 1 0 9.35.332L.332 9.35a1.134 1.134 0 0 0-.106 1.481c.099.182.245.335.423.439l8.701 8.701a1.133 1.133 0 1 0 1.603-1.603l-6.941-6.941Z" style="fill:#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 424 B |
5
src/lib/config.ts
Normal file
5
src/lib/config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import messages from "../../public/messages.json";
|
||||
|
||||
export function getAppName() {
|
||||
return messages.radarName;
|
||||
}
|
||||
5
src/lib/data.ts
Normal file
5
src/lib/data.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import messages from "../../public/messages.json";
|
||||
|
||||
export function getMessages() {
|
||||
return messages;
|
||||
}
|
||||
5
src/lib/utils.ts
Normal file
5
src/lib/utils.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return clsx(inputs);
|
||||
}
|
||||
@@ -1,7 +1,21 @@
|
||||
import { NextPage } from "next";
|
||||
import type { AppProps } from "next/app";
|
||||
|
||||
import { Layout, type LayoutClass } from "@/components/Layout/Layout";
|
||||
import "@/styles/globals.css";
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />;
|
||||
export type CustomPage<P = {}, IP = P> = NextPage<P, IP> & {
|
||||
layoutClass?: LayoutClass;
|
||||
};
|
||||
|
||||
type CustomAppProps = AppProps & {
|
||||
Component: CustomPage;
|
||||
};
|
||||
|
||||
export default function App({ Component, pageProps, router }: CustomAppProps) {
|
||||
return (
|
||||
<Layout layoutClass={Component.layoutClass}>
|
||||
<Component {...pageProps} key={router.asPath} />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
type Data = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export default function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Data>,
|
||||
) {
|
||||
res.status(200).json({ name: "John Doe" });
|
||||
}
|
||||
19
src/pages/help-and-about-tech-radar.tsx
Normal file
19
src/pages/help-and-about-tech-radar.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import Head from "next/head";
|
||||
|
||||
import { CustomPage } from "@/pages/_app";
|
||||
|
||||
const HelpAndAbout: CustomPage = () => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Help and About</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<h1>Help and about</h1>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default HelpAndAbout;
|
||||
@@ -1,12 +1,8 @@
|
||||
import { Inter } from "next/font/google";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
|
||||
import styles from "@/styles/Home.module.css";
|
||||
import { CustomPage } from "@/pages/_app";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export default function Home() {
|
||||
const Home: CustomPage = () => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -15,101 +11,10 @@ export default function Home() {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<main className={`${styles.main} ${inter.className}`}>
|
||||
<div className={styles.description}>
|
||||
<p>
|
||||
Get started by editing
|
||||
<code className={styles.code}>src/pages/index.tsx</code>
|
||||
</p>
|
||||
<div>
|
||||
<a
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{" "}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className={styles.vercelLogo}
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.center}>
|
||||
<Image
|
||||
className={styles.logo}
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.grid}>
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
className={styles.card}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2>
|
||||
Docs <span>-></span>
|
||||
</h2>
|
||||
<p>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
className={styles.card}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2>
|
||||
Learn <span>-></span>
|
||||
</h2>
|
||||
<p>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
className={styles.card}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2>
|
||||
Templates <span>-></span>
|
||||
</h2>
|
||||
<p>
|
||||
Discover and deploy boilerplate example Next.js projects.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
className={styles.card}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2>
|
||||
Deploy <span>-></span>
|
||||
</h2>
|
||||
<p>
|
||||
Instantly deploy your Next.js site to a shareable URL
|
||||
with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
<h1>Hello world.</h1>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Home;
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.description {
|
||||
display: inherit;
|
||||
justify-content: inherit;
|
||||
align-items: inherit;
|
||||
font-size: 0.85rem;
|
||||
max-width: var(--max-width);
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.description a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.description p {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
background-color: rgba(var(--callout-rgb), 0.5);
|
||||
border: 1px solid rgba(var(--callout-border-rgb), 0.3);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.code {
|
||||
font-weight: 700;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(25%, auto));
|
||||
max-width: 100%;
|
||||
width: var(--max-width);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 1rem 1.2rem;
|
||||
border-radius: var(--border-radius);
|
||||
background: rgba(var(--card-rgb), 0);
|
||||
border: 1px solid rgba(var(--card-border-rgb), 0);
|
||||
transition:
|
||||
background 200ms,
|
||||
border 200ms;
|
||||
}
|
||||
|
||||
.card span {
|
||||
display: inline-block;
|
||||
transition: transform 200ms;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.7rem;
|
||||
}
|
||||
|
||||
.card p {
|
||||
margin: 0;
|
||||
opacity: 0.6;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
max-width: 30ch;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 4rem 0;
|
||||
}
|
||||
|
||||
.center::before {
|
||||
background: var(--secondary-glow);
|
||||
border-radius: 50%;
|
||||
width: 480px;
|
||||
height: 360px;
|
||||
margin-left: -400px;
|
||||
}
|
||||
|
||||
.center::after {
|
||||
background: var(--primary-glow);
|
||||
width: 240px;
|
||||
height: 180px;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.center::before,
|
||||
.center::after {
|
||||
content: "";
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
filter: blur(45px);
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: relative;
|
||||
}
|
||||
/* Enable hover only on non-touch devices */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.card:hover {
|
||||
background: rgba(var(--card-rgb), 0.1);
|
||||
border: 1px solid rgba(var(--card-border-rgb), 0.15);
|
||||
}
|
||||
|
||||
.card:hover span {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
.card:hover span {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 700px) {
|
||||
.content {
|
||||
padding: 4rem;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
margin-bottom: 120px;
|
||||
max-width: 320px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 1rem 2.5rem;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.center {
|
||||
padding: 8rem 0 6rem;
|
||||
}
|
||||
|
||||
.center::before {
|
||||
transform: none;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.description a {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.description p,
|
||||
.description div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.description p {
|
||||
align-items: center;
|
||||
inset: 0 0 auto;
|
||||
padding: 2rem 1rem 1.4rem;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
rgba(var(--background-start-rgb), 1),
|
||||
rgba(var(--callout-rgb), 0.5)
|
||||
);
|
||||
background-clip: padding-box;
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
|
||||
.description div {
|
||||
align-items: flex-end;
|
||||
pointer-events: none;
|
||||
inset: auto 0 0;
|
||||
padding: 2rem;
|
||||
height: 200px;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent 0%,
|
||||
rgb(var(--background-end-rgb)) 40%
|
||||
);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet and Smaller Desktop */
|
||||
@media (min-width: 701px) and (max-width: 1120px) {
|
||||
.grid {
|
||||
grid-template-columns: repeat(2, 50%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.vercelLogo {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
.logo {
|
||||
filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
#lore {
|
||||
display: block;
|
||||
}
|
||||
@@ -1,76 +1,12 @@
|
||||
:root {
|
||||
--max-width: 1100px;
|
||||
--max-width: 1200px;
|
||||
--border-radius: 12px;
|
||||
--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",
|
||||
"Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",
|
||||
"Fira Mono", "Droid Sans Mono", "Courier New", monospace;
|
||||
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
|
||||
--primary-glow: conic-gradient(
|
||||
from 180deg at 50% 50%,
|
||||
#16abff33 0deg,
|
||||
#0885ff33 55deg,
|
||||
#54d6ff33 120deg,
|
||||
#0071ff33 160deg,
|
||||
transparent 360deg
|
||||
);
|
||||
--secondary-glow: radial-gradient(
|
||||
rgba(255, 255, 255, 1),
|
||||
rgba(255, 255, 255, 0)
|
||||
);
|
||||
|
||||
--tile-start-rgb: 239, 245, 249;
|
||||
--tile-end-rgb: 228, 232, 233;
|
||||
--tile-border: conic-gradient(
|
||||
#00000080,
|
||||
#00000040,
|
||||
#00000030,
|
||||
#00000020,
|
||||
#00000010,
|
||||
#00000010,
|
||||
#00000080
|
||||
);
|
||||
|
||||
--callout-rgb: 238, 240, 241;
|
||||
--callout-border-rgb: 172, 175, 176;
|
||||
--card-rgb: 180, 185, 188;
|
||||
--card-border-rgb: 131, 134, 135;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
|
||||
--primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
|
||||
--secondary-glow: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(1, 65, 255, 0),
|
||||
rgba(1, 65, 255, 0),
|
||||
rgba(1, 65, 255, 0.3)
|
||||
);
|
||||
|
||||
--tile-start-rgb: 2, 13, 46;
|
||||
--tile-end-rgb: 2, 5, 19;
|
||||
--tile-border: conic-gradient(
|
||||
#ffffff80,
|
||||
#ffffff40,
|
||||
#ffffff30,
|
||||
#ffffff20,
|
||||
#ffffff10,
|
||||
#ffffff10,
|
||||
#ffffff80
|
||||
);
|
||||
|
||||
--callout-rgb: 20, 20, 20;
|
||||
--callout-border-rgb: 108, 108, 108;
|
||||
--card-rgb: 100, 100, 100;
|
||||
--card-border-rgb: 200, 200, 200;
|
||||
}
|
||||
--foreground: #fff;
|
||||
--background: #173d7a;
|
||||
}
|
||||
|
||||
* {
|
||||
@@ -86,13 +22,8 @@ body {
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
a {
|
||||
@@ -100,8 +31,21 @@ a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
color-scheme: dark;
|
||||
p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user