This commit is contained in:
Tben 2022-06-10 08:49:12 +01:00
parent 0b7c30d9c9
commit 445a233536
16 changed files with 816 additions and 24 deletions

View File

@ -0,0 +1,129 @@
/**
* ==============================================================================
* Imports
* ==============================================================================
*/
import React from "react";
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Main Component { Functional }
* ==============================================================================
* @param {Object} props - Server props
*/
export default function Homepage(props) {
// ## Get Contexts
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Javascript Variables
/** ********************* Head Items */
let head = (
<React.Fragment>
<title>Showmerebates | Home</title>
<meta name="description" content="Find great property rebates" />
</React.Fragment>
);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## React Hooks { useState, useEffect, useRef, etc ... }
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Function Return
return (
<React.Fragment>
<GeneralLayout head={ head } user={ props.user }>
<main>
<Hero />
<HowItWorks />
<FeaturedProperties data={ props.data } user={ props.user } />
<AboutUsSection />
{ !props.user && <LoginPromptPopup user={ props.user } /> }
</main>
</GeneralLayout>
</React.Fragment>
);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
};
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Server Side Props or Static Props
* ==============================================================================
* @param {Object} req - http incoming request object
* @param {Object} res - http response object
* @param {Object} query - queries attached to the url
*/
export async function getServerSideProps({ req, res, query }) {
// ## Environment processes
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## User Authentication
const user = await userAuth(req, res);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Page/Site Data Data Fetching
let properties = await dbHandler(`
SELECT
ListingKeyNumeric,City,RoomsTotal,BathroomsFull,BathroomsTotalInteger,BedroomsTotal,UnparsedAddress,BuildingAreaTotal,ListPrice,PostalCode
FROM
utahapidata
WHERE
PhotosCount > 0 AND ListPrice > 0 AND BedroomsTotal > 0 LIMIT 3
`);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Server Props Return
return {
props: {
user: user,
data: properties,
},
};
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
}

View File

@ -0,0 +1,73 @@
/**
* ==============================================================================
* Imports
* ==============================================================================
*/
import React from "react";
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Main Component { Functional }
* ==============================================================================
* @param {Object} props - Server props
*/
export default function SingleBlogPostPreset(props) {
// ## Get Contexts
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Javascript Variables
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## React Hooks { useState, useEffect, useRef, etc ... }
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Function Return
return (
<React.Fragment>
<GeneralLayout head={ head } user={ props.user }>
<main>
<Hero />
<HowItWorks />
<FeaturedProperties data={ props.data } user={ props.user } />
<AboutUsSection />
{ !props.user && <LoginPromptPopup user={ props.user } /> }
</main>
</GeneralLayout>
</React.Fragment>
);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
};
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */

View File

@ -0,0 +1,6 @@
[
{
"title": "",
"id": 1
}
]

79
jsonData/blogposts.json Normal file
View File

@ -0,0 +1,79 @@
[
{
"id": 1,
"title": "Choosing your stack",
"slug": "choosing-your-tech-stack",
"description": "So many technologies, so little time to vet all",
"date": "Fri Jun 10 2022 06:34:08 GMT+0100 (West Africa Standard Time)",
"body": [
{
"tag": "p",
"content": "The tech pool is an ever growing trojan horse. JavaScript libraries alone are getting out of hand: we seem to be getting a new one every 6 months. Hell even I have a javascript library of my own. Trying to pick from this pool can easily turn into mission impossible: understandably so: there's just too many of them"
},
{
"tag": "p",
"content": "The thing is, each of these libraries and frameworks end up doing essentially the same thing in thier respective categories: react creates reuseable javascript components: same with vue, same with angular, svelte. And for the most part, you won't be using every single feature provided by these libraries: just the ones that suit your project."
},
{
"tag": "p",
"content": "In truth, the tech stack you choose doesn't mean much: you can get 10 different options which achieve the same goal. Really, all that matters is the developer you pick: because a masterful developer can create great products using any stack of his/her choosing."
},
{
"tag": "p",
"children": [
{
"tag": "span",
"content": "If you're just starting off, perhaps the best step is to evaluate the stacks and get a recommendation from an expert in the field: you may be surprised to find out you don't need as many technologies as you think: you may even be surprised that using a traditional framework like ruby on rails is actually a lot easier than wordpress. "
},
{
"tag": "a",
"href": "/contact",
"class": "text-blue-300",
"content": "Reach out"
},
{
"tag": "span",
"content": " to find out more."
}
]
}
]
},
{
"id": 2,
"title": "Find your perfect framework",
"slug": "find-your-perfect-framework",
"description": "How much can a web framework affect your project?",
"date": "Fri Jun 10 2022 06:34:08 GMT+0100 (West Africa Standard Time)",
"body": [
{
"tag": "p",
"content": "Web frameworks are a great way to get the best out of multiple technologies while keeping your development time short and reliability high. But just like it is with every aspect of web development, there's a dilemma of \"Which framework should I go with\"."
},
{
"tag": "p",
"content": "Different frameworks come with different structures and different selections of languages and packages. In truth, you don't necessarily need a framework: nearly all major programming languages can handle applications on thier own: but as you build more projects, you keep encountering more repetitions, and you end up abstracting those repetitions into reuseable components: you now have a framework of your own. Now this isn't bad at all: infact, this is the end goal of a truly performant app: frameworks often come with a lot of packages you may not need: which end up bugging down your application: if you can develop a framework of your own, you can eliminate this downside: but, you have to be prepared to spend a lot of time on your project: if you have the time, then go for it: else, go for a framework."
},
{
"tag": "p",
"content": "Haven said this, there are lots of frameworks you can choose from: depending on your time and budget: here are some great picks you should consider:"
},
{
"tag": "h2",
"content": "1. Next JS"
},
{
"tag": "img",
"src": "https://miro.medium.com/max/1400/1*htbUdWgFQ3a94PMEvBr_hQ.png",
"class": "w-full",
"style": {
"border": "1px solid #ffffff40"
}
},
{
"tag": "p",
"content": "Next JS is slowly becoming the household name for web development frameworks: it features an immensely paowerful and efficient structure, based on React JS: which enables server side rendering of pages: as opposed to the traditional SPA(single page application) model React was created for. Next JS handles the heavilifting of routing, apis, frontend and backend components, module bundling, and linting, leaving you with a relatively easy platform to integrate your project. Next JS is growing very quick and in no time, it will become the most used framework for enterprise applications"
}
]
}
]

View File

@ -5,19 +5,38 @@ const GeneralHeader = () => {
const router = useRouter(); const router = useRouter();
function pushRouter(e) { function pushRouter(e) {
e.preventDefault();
let url = e.target.dataset.href; let url = e.target.dataset.href;
router.push(url); router.push(url);
} }
return ( return (
<header> <header>
<a className="logo-link-block" onClick={ () => { pushRouter("/") } }><h1>Tben.me</h1></a> <a className="logo-link-block" onClick={ () => {
pushRouter("/")
} }><h1>Tben.me</h1></a>
<nav> <nav>
<a data-href="/" onClick={ (e) => { pushRouter(e) } }>Home</a> <a href='/' data-href="/" onClick={ (e) => {
<a data-href="/about" onClick={ (e) => { pushRouter(e) } }>About Me</a> pushRouter(e)
<a data-href="/work" onClick={ (e) => { pushRouter(e) } }>My Work</a> } }>Home</a>
<a href='/about' data-href="/about" onClick={ (e) => {
pushRouter(e)
} }>About Me</a>
<a href='/work' data-href="/work" onClick={ (e) => {
pushRouter(e)
} }>My Work</a>
<a href='/blog' data-href="/blog" onClick={ (e) => {
pushRouter(e)
} }>Blog</a>
<a data-href="#" href='/documents/Benjamin_Toby_CV-updated.pdf' target="_blank">My Resume</a> <a data-href="#" href='/documents/Benjamin_Toby_CV-updated.pdf' target="_blank">My Resume</a>
<a data-href="/contact" onClick={ (e) => { pushRouter(e) } }>Contact Me</a>
<a href='/contact' data-href="/contact" onClick={ (e) => {
pushRouter(e)
} }>Contact Me</a>
</nav> </nav>
</header> </header>
) )

View File

@ -63,8 +63,6 @@ const GeneralLayout = ({ children, pageName }) => {
// document.getElementById("page-loader").style.opacity // document.getElementById("page-loader").style.opacity
threeJsAnimations(); threeJsAnimations();
// setReadyState(true);
}, []) }, [])
@ -82,6 +80,7 @@ const GeneralLayout = ({ children, pageName }) => {
{ children } { children }
</main> </main>
<GeneralFooter /> <GeneralFooter />
<div className='fixed top-0 left-0 -z-10' id='homepage-animation-wrapper'></div>
</div> </div>
</SiteContext.Provider> </SiteContext.Provider>

View File

@ -6,6 +6,7 @@ export default function Document() {
<Html> <Html>
<Head> <Head>
{/* <script src="https://unpkg.com/@barba/core"></script> */} {/* <script src="https://unpkg.com/@barba/core"></script> */}
{/* <script src="/scripts/swup.js"></script> */}
<script src="/scripts/main.js" defer></script> <script src="/scripts/main.js" defer></script>
</Head> </Head>
<body className="bg-black"> <body className="bg-black">

View File

@ -132,7 +132,6 @@ const about = () => {
<a href='/documents/Benjamin_Toby_CV-updated.pdf' download={ true }>See my resume</a> <a href='/documents/Benjamin_Toby_CV-updated.pdf' download={ true }>See my resume</a>
<a href='https://www.linkedin.com/in/benjamin-toby/' target="_blank">Linkedin</a> <a href='https://www.linkedin.com/in/benjamin-toby/' target="_blank">Linkedin</a>
</div> </div>
<div className='fixed top-0 left-0 -z-10' id='homepage-animation-wrapper'></div>
</GeneralLayout> </GeneralLayout>
) )
} }

186
pages/blog/[single].jsx Normal file
View File

@ -0,0 +1,186 @@
/**
* ==============================================================================
* Imports
* ==============================================================================
*/
import React from "react";
import Head from "next/head";
const fs = require("fs");
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
import GeneralLayout from "../../layouts/general_layout/GeneralLayout";
import TextShuffler from "../../components/actions/TextShuffler";
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Main Component { Functional }
* ==============================================================================
* @param {Object} props - Server props
*/
export default function BlogIndex({ blogPost }) {
// ## Get Contexts
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Javascript Variables
let reactKey = 0;
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## React Hooks { useState, useEffect, useRef, etc ... }
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Function Return
return (
<React.Fragment>
<Head>
<title>{ blogPost.title } | Tben.me Blog</title>
<meta name="description" content={ blogPost.description } />
</Head>
<GeneralLayout>
<div className="flex flex-col items-start gap-2 mb-8 max-w-3xl">
<button
className="bg-transparent text-white/50 border-2 border-solid border-white/20"
onClick={ (e) => {
window.history.back()
} }
>Back</button>
<h1 className="m-0"><TextShuffler textInput={ blogPost.title } /></h1>
<span className="text-lg">
<TextShuffler textInput={ blogPost.description } />
</span>
<span className="text-base opacity-50">
<TextShuffler textInput={ blogPost.date.substring(0, 24) } />
</span>
</div>
<div className="flex flex-col items-start max-w-3xl w-full gap-4 text-lg">
{ blogPost.body.map((element) => {
reactKey++;
if (element.tag.match(/img/i)) {
return <img
src={ element.src }
width={ element.width }
height={ element.height }
className={ element.class }
alt={ element.alt }
style={ element.style }
/>
}
function construtElement(elementEntry) {
if (elementEntry.children) {
return (
<elementEntry.tag
key={ reactKey }
className={ elementEntry.class ? elementEntry.class : null }
href={ elementEntry.href }
style={ element.style }
>
{ elementEntry.children.map(child => construtElement(child)) }
</elementEntry.tag>
)
}
return (
<elementEntry.tag
key={ reactKey }
className={ elementEntry.class ? elementEntry.class : null }
href={ elementEntry.href }
>
{ elementEntry.content }
</elementEntry.tag>
)
}
return construtElement(element);
}
) }
</div>
</GeneralLayout>
</React.Fragment>
);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
};
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Server Side Props or Static Props
* ==============================================================================
* @param {Object} req - http incoming request object
* @param {Object} res - http response object
* @param {Object} query - queries attached to the url
*/
export async function getServerSideProps({ req, res, query }) {
// ## Environment processes
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## User Authentication
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Page/Site Data Data Fetching
const blogPosts = JSON.parse(fs.readFileSync("./jsonData/blogposts.json", "utf8"));
let foundPost = blogPosts.filter(post => post.slug === query.single);
if (!foundPost || !foundPost[0]) return {
redirect: {
destination: "/blog",
permanent: false
}
}
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Server Props Return
return {
props: {
blogPost: foundPost[0],
},
};
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
}

131
pages/blog/index.jsx Normal file
View File

@ -0,0 +1,131 @@
/**
* ==============================================================================
* Imports
* ==============================================================================
*/
import React from "react";
import Head from "next/head";
const fs = require("fs");
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
import GeneralLayout from "../../layouts/general_layout/GeneralLayout";
import TextShuffler from "../../components/actions/TextShuffler";
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Main Component { Functional }
* ==============================================================================
* @param {Object} props - Server props
*/
export default function BlogIndex(props) {
// ## Get Contexts
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Javascript Variables
// const blogPosts = require("../../jsonData/blogposts.json");
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## React Hooks { useState, useEffect, useRef, etc ... }
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Function Return
return (
<React.Fragment>
<Head>
<title>Blog | Tben.me</title>
<meta name="description" content="Tech talks" />
</Head>
<GeneralLayout>
<h1 className="mb-8"><TextShuffler textInput="My Blog" /></h1>
<div className="flex flex-col items-start w-full gap-4">
{ props.blogPosts.map(post =>
<a
href={ `/blog/${post.slug}` }
className="flex flex-col items-start gap-2 w-full hover:bg-blue-600 border border-solid border-white/20 p-8 transition-all"
key={ post.id }
>
<h2 className="m-0"><TextShuffler textInput={ post.title } /></h2>
<span className="opacity-80"><TextShuffler textInput={ post.description } /></span>
<span className="text-sm opacity-50"><TextShuffler textInput={ post.date.substring(0, 24) } /></span>
</a>
) }
</div>
</GeneralLayout>
</React.Fragment>
);
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
};
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Server Side Props or Static Props
* ==============================================================================
* @param {Object} req - http incoming request object
* @param {Object} res - http response object
* @param {Object} query - queries attached to the url
*/
export async function getServerSideProps({ req, res, query }) {
// ## Environment processes
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## User Authentication
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Page/Site Data Data Fetching
const blogPosts = fs.readFileSync("./jsonData/blogposts.json", "utf8");
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
// ## Server Props Return
return {
props: {
blogPosts: JSON.parse(blogPosts).reverse(),
},
};
/** ********************************************** */
/** ********************************************** */
/** ********************************************** */
}

View File

@ -29,7 +29,6 @@ const contact = () => {
{ success === "Success" && <div className='message-response'>Success!!! <button onClick={ () => { window.location.reload() } }>Reload</button></div> } { success === "Success" && <div className='message-response'>Success!!! <button onClick={ () => { window.location.reload() } }>Reload</button></div> }
{ success === "Failed" && <div className='message-response failed'>Failed <button onClick={ () => { window.location.reload() } }>Reload</button></div> } { success === "Failed" && <div className='message-response failed'>Failed <button onClick={ () => { window.location.reload() } }>Reload</button></div> }
</form> </form>
<div className='fixed top-0 left-0 -z-10' id='homepage-animation-wrapper'></div>
</GeneralLayout> </GeneralLayout>
) )
} }

View File

@ -25,7 +25,6 @@ const index = () => {
border: "2px solid white" border: "2px solid white"
} }>Contact Me</a> } }>Contact Me</a>
</div> </div>
<div className='fixed top-0 left-0 -z-10' id='homepage-animation-wrapper'></div>
</GeneralLayout> </GeneralLayout>
) )
} }

View File

@ -3,7 +3,6 @@ import Head from 'next/head'
import TextShuffler from '../components/actions/TextShuffler' import TextShuffler from '../components/actions/TextShuffler'
import GeneralLayout from '../layouts/general_layout/GeneralLayout' import GeneralLayout from '../layouts/general_layout/GeneralLayout'
import PortfolioEntry from '../components/PortfolioEntry' import PortfolioEntry from '../components/PortfolioEntry'
import threeJsAnimations from '../functions/frontend/threeJsAnimations'
const myWork = () => { const myWork = () => {
const portfolioEntries = require("../components/portfolioEntries.json"); const portfolioEntries = require("../components/portfolioEntries.json");
@ -22,7 +21,6 @@ const myWork = () => {
<div className='portfolio-entries-block mt-4'> <div className='portfolio-entries-block mt-4'>
{ portfolioEntries.map(entry => <PortfolioEntry key={ entry.title } title={ entry.title } description={ entry.description } url={ entry.url } image={ entry.image } />) } { portfolioEntries.map(entry => <PortfolioEntry key={ entry.title } title={ entry.title } description={ entry.description } url={ entry.url } image={ entry.image } />) }
</div> </div>
<div className='fixed top-0 left-0 -z-10' id='homepage-animation-wrapper'></div>
</GeneralLayout> </GeneralLayout>
) )
} }

1
public/scripts/swup.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -19,6 +19,7 @@ html {
:root { :root {
--main-color: #1668e4; --main-color: #1668e4;
--main-color-lighter: #5698fc;
--dark-color: #201e1e; --dark-color: #201e1e;
--sec-color-3: #688e26; --sec-color-3: #688e26;
--sec-color-4: #adb2d3; --sec-color-4: #adb2d3;
@ -83,6 +84,25 @@ h1 {
margin-bottom: 10px; margin-bottom: 10px;
} }
/* * */
/* * */
/* * */
/* * */
/* * */
/* * */
/* * */
p a,
span a {
color: var(--main-color-lighter);
/* border-bottom: 1px solid var(--main-color-lighter); */
}
p a:hover,
span a:hover {
color: var(--main-color);
}
/* ################################################# -- Sliders */ /* ################################################# -- Sliders */
aside, aside,
.side-nav-block { .side-nav-block {
@ -330,6 +350,24 @@ textarea {
margin-bottom: 20px; margin-bottom: 20px;
} }
/* * */
/* * */
/* * */
/* * */
/* * */
/* * */
/* * */
/* * */
/* .transition-fade {
transition: 0.4s;
opacity: 1;
}
html.is-animating .transition-fade {
opacity: 0;
} */
/* ############################################################################################### /* ###############################################################################################
################################################################################################## ##################################################################################################
################################################################################################## ##################################################################################################

View File

@ -59,6 +59,10 @@
z-index: -10 z-index: -10
} }
.m-0 {
margin: 0px
}
.mt-4 { .mt-4 {
margin-top: 1rem margin-top: 1rem
} }
@ -71,6 +75,26 @@
margin-bottom: 0.25rem margin-bottom: 0.25rem
} }
.mb-4 {
margin-bottom: 1rem
}
.mb-8 {
margin-bottom: 2rem
}
.mb-0 {
margin-bottom: 0px
}
.mb-3 {
margin-bottom: 0.75rem
}
.mb-2 {
margin-bottom: 0.5rem
}
.flex { .flex {
display: flex display: flex
} }
@ -79,37 +103,86 @@
height: 1.5rem height: 1.5rem
} }
.h-screen {
height: 100vh
}
.w-full { .w-full {
width: 100% width: 100%
} }
.w-screen { .max-w-xl {
width: 100vw max-width: 36rem
}
.max-w-2xl {
max-width: 42rem
}
.max-w-3xl {
max-width: 48rem
}
.max-w-4xl {
max-width: 56rem
} }
.flex-col { .flex-col {
flex-direction: column flex-direction: column
} }
.items-center { .items-start {
align-items: center align-items: flex-start
} }
.justify-center { .gap-2 {
justify-content: center gap: 0.5rem
}
.gap-4 {
gap: 1rem
} }
.border { .border {
border-width: 1px border-width: 1px
} }
.bg-black { .border-2 {
border-width: 2px
}
.border-solid {
border-style: solid
}
.border-blue-500 {
--tw-border-opacity: 1;
border-color: rgb(59 130 246 / var(--tw-border-opacity))
}
.border-white\/40 {
border-color: rgb(255 255 255 / 0.4)
}
.border-white\/20 {
border-color: rgb(255 255 255 / 0.2)
}
.border-white\/50 {
border-color: rgb(255 255 255 / 0.5)
}
.bg-blue-600 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity)) background-color: rgb(37 99 235 / var(--tw-bg-opacity))
}
.bg-transparent {
background-color: transparent
}
.p-4 {
padding: 1rem
}
.p-8 {
padding: 2rem
} }
.text-xl { .text-xl {
@ -122,10 +195,29 @@
line-height: 1.25rem line-height: 1.25rem
} }
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem
}
.text-base {
font-size: 1rem;
line-height: 1.5rem
}
.font-bold { .font-bold {
font-weight: 700 font-weight: 700
} }
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity))
}
.text-white\/50 {
color: rgb(255 255 255 / 0.5)
}
.opacity-50 { .opacity-50 {
opacity: 0.5 opacity: 0.5
} }
@ -133,3 +225,46 @@
.opacity-40 { .opacity-40 {
opacity: 0.4 opacity: 0.4
} }
.opacity-90 {
opacity: 0.9
}
.opacity-60 {
opacity: 0.6
}
.opacity-20 {
opacity: 0.2
}
.opacity-30 {
opacity: 0.3
}
.opacity-70 {
opacity: 0.7
}
.opacity-80 {
opacity: 0.8
}
.outline {
outline-style: solid
}
.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-all {
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms
}
.hover\:bg-blue-600:hover {
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity))
}