mirror of
https://github.com/liyunze-coding/coworking-website.git
synced 2026-11-06 13:13:34 +00:00
added remark callouts
This commit is contained in:
parent
1c45c2635d
commit
4a708f483c
20 changed files with 433 additions and 192 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -21,4 +21,6 @@ pnpm-debug.log*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# PageFind
|
# PageFind
|
||||||
public/pagefind
|
public/pagefind
|
||||||
|
|
||||||
|
md-to-html.exe
|
||||||
|
|
@ -2,15 +2,17 @@
|
||||||
|
|
||||||
[](https://coworking-guide.vercel.app/)
|
[](https://coworking-guide.vercel.app/)
|
||||||
|
|
||||||
|
hello
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
- [Coworking Guide](#coworking-guide)
|
- [Coworking Guide](#coworking-guide)
|
||||||
- [Table of Contents](#table-of-contents)
|
- [Table of Contents](#table-of-contents)
|
||||||
- [Introduction](#introduction)
|
- [Contributing](#contributing)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Introduction
|
## Contributing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,23 @@ import tailwind from "@astrojs/tailwind";
|
||||||
import mdx from "@astrojs/mdx";
|
import mdx from "@astrojs/mdx";
|
||||||
import react from "@astrojs/react";
|
import react from "@astrojs/react";
|
||||||
import expressiveCode from "astro-expressive-code";
|
import expressiveCode from "astro-expressive-code";
|
||||||
|
import remarkDirective from "remark-directive";
|
||||||
|
import remarkCalloutDirectives from "./src/assets/plugins/remark-callout-directives-customized.js";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [tailwind(), expressiveCode(), mdx(), react()],
|
integrations: [
|
||||||
|
tailwind(),
|
||||||
|
expressiveCode(),
|
||||||
|
mdx({
|
||||||
|
remarkPlugins: [remarkDirective, remarkCalloutDirectives],
|
||||||
|
}),
|
||||||
|
react(),
|
||||||
|
],
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 4321,
|
||||||
|
},
|
||||||
|
markdown: {
|
||||||
|
remarkPlugins: [remarkDirective, remarkCalloutDirectives],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
53
package-lock.json
generated
53
package-lock.json
generated
|
|
@ -21,6 +21,7 @@
|
||||||
"framer-motion": "^11.0.12",
|
"framer-motion": "^11.0.12",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"remark-directive": "^3.0.0",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5.4.3"
|
"typescript": "^5.4.3"
|
||||||
|
|
@ -4379,6 +4380,25 @@
|
||||||
"url": "https://opencollective.com/unified"
|
"url": "https://opencollective.com/unified"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mdast-util-directive": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/mdast": "^4.0.0",
|
||||||
|
"@types/unist": "^3.0.0",
|
||||||
|
"devlop": "^1.0.0",
|
||||||
|
"mdast-util-from-markdown": "^2.0.0",
|
||||||
|
"mdast-util-to-markdown": "^2.0.0",
|
||||||
|
"parse-entities": "^4.0.0",
|
||||||
|
"stringify-entities": "^4.0.0",
|
||||||
|
"unist-util-visit-parents": "^6.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/unified"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mdast-util-find-and-replace": {
|
"node_modules/mdast-util-find-and-replace": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz",
|
||||||
|
|
@ -4740,6 +4760,24 @@
|
||||||
"micromark-util-types": "^2.0.0"
|
"micromark-util-types": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/micromark-extension-directive": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==",
|
||||||
|
"dependencies": {
|
||||||
|
"devlop": "^1.0.0",
|
||||||
|
"micromark-factory-space": "^2.0.0",
|
||||||
|
"micromark-factory-whitespace": "^2.0.0",
|
||||||
|
"micromark-util-character": "^2.0.0",
|
||||||
|
"micromark-util-symbol": "^2.0.0",
|
||||||
|
"micromark-util-types": "^2.0.0",
|
||||||
|
"parse-entities": "^4.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/unified"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/micromark-extension-gfm": {
|
"node_modules/micromark-extension-gfm": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
|
||||||
|
|
@ -6501,6 +6539,21 @@
|
||||||
"url": "https://opencollective.com/unified"
|
"url": "https://opencollective.com/unified"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/remark-directive": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/mdast": "^4.0.0",
|
||||||
|
"mdast-util-directive": "^3.0.0",
|
||||||
|
"micromark-extension-directive": "^3.0.0",
|
||||||
|
"unified": "^11.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/unified"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/remark-expressive-code": {
|
"node_modules/remark-expressive-code": {
|
||||||
"version": "0.33.5",
|
"version": "0.33.5",
|
||||||
"resolved": "https://registry.npmjs.org/remark-expressive-code/-/remark-expressive-code-0.33.5.tgz",
|
"resolved": "https://registry.npmjs.org/remark-expressive-code/-/remark-expressive-code-0.33.5.tgz",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev --open",
|
"dev": "astro dev --open",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro build && pagefind --site dist && copy -r dist/pagefind public/",
|
"build": "astro build && pagefind --site dist",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
"framer-motion": "^11.0.12",
|
"framer-motion": "^11.0.12",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"remark-directive": "^3.0.0",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5.4.3"
|
"typescript": "^5.4.3"
|
||||||
|
|
|
||||||
116
src/assets/plugins/remark-callout-directives-customized.js
Normal file
116
src/assets/plugins/remark-callout-directives-customized.js
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* taken from MIT Licensed https://github.com/Microflash/remark-callout-directives */
|
||||||
|
|
||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
import { fromMarkdown } from "mdast-util-from-markdown";
|
||||||
|
import { h } from "hastscript";
|
||||||
|
|
||||||
|
function generate(title, children, hint) {
|
||||||
|
const indicators = [];
|
||||||
|
|
||||||
|
if (hint) {
|
||||||
|
indicators.push({
|
||||||
|
type: "html",
|
||||||
|
value: hint,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const titleNode = fromMarkdown(title).children[0];
|
||||||
|
if (titleNode.type === "paragraph") {
|
||||||
|
titleNode.data = {
|
||||||
|
hName: "div",
|
||||||
|
hProperties: { className: ["callout-title"] },
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
titleNode.data = {
|
||||||
|
hProperties: { className: ["callout-title"] },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
indicators.push(titleNode);
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: "paragraph",
|
||||||
|
data: {
|
||||||
|
hName: "div",
|
||||||
|
hProperties: { className: ["callout-indicator"] },
|
||||||
|
},
|
||||||
|
children: indicators,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "paragraph",
|
||||||
|
data: {
|
||||||
|
hName: "div",
|
||||||
|
hProperties: { className: ["callout-content"] },
|
||||||
|
},
|
||||||
|
children,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const callouts = {
|
||||||
|
note: {
|
||||||
|
title: "Note",
|
||||||
|
hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true"><path d="M12 8h.01M12 12v4"/><circle cx="12" cy="12" r="10"/></svg>`,
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
title: "Success",
|
||||||
|
hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true"><path d="m8 12 2.7 2.7L16 9.3"/><circle cx="12" cy="12" r="10"/></svg>`,
|
||||||
|
},
|
||||||
|
warn: {
|
||||||
|
title: "Warning",
|
||||||
|
hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true"><path d="M12 9v4m0 4h.01M8.681 4.082C9.351 2.797 10.621 2 12 2s2.649.797 3.319 2.082l6.203 11.904a4.28 4.28 0 0 1-.046 4.019C20.793 21.241 19.549 22 18.203 22H5.797c-1.346 0-2.59-.759-3.273-1.995a4.28 4.28 0 0 1-.046-4.019L8.681 4.082Z"/></svg>`,
|
||||||
|
},
|
||||||
|
danger: {
|
||||||
|
title: "Danger",
|
||||||
|
hint: `<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor" aria-hidden="true"><path d="M12 7C11.7348 7 11.4804 7.10536 11.2929 7.29289C11.1054 7.48043 11 7.73478 11 8V12C11 12.2652 11.1054 12.5196 11.2929 12.7071C11.4804 12.8946 11.7348 13 12 13C12.2652 13 12.5196 12.8946 12.7071 12.7071C12.8946 12.5196 13 12.2652 13 12V8C13 7.73478 12.8946 7.48043 12.7071 7.29289C12.5196 7.10536 12.2652 7 12 7ZM12 15C11.8022 15 11.6089 15.0586 11.4444 15.1685C11.28 15.2784 11.1518 15.4346 11.0761 15.6173C11.0004 15.8 10.9806 16.0011 11.0192 16.1951C11.0578 16.3891 11.153 16.5673 11.2929 16.7071C11.4327 16.847 11.6109 16.9422 11.8049 16.9808C11.9989 17.0194 12.2 16.9996 12.3827 16.9239C12.5654 16.8482 12.7216 16.72 12.8315 16.5556C12.9414 16.3911 13 16.1978 13 16C13 15.7348 12.8946 15.4804 12.7071 15.2929C12.5196 15.1054 12.2652 15 12 15ZM21.71 7.56L16.44 2.29C16.2484 2.10727 15.9948 2.00368 15.73 2H8.27C8.00523 2.00368 7.75163 2.10727 7.56 2.29L2.29 7.56C2.10727 7.75163 2.00368 8.00523 2 8.27V15.73C2.00368 15.9948 2.10727 16.2484 2.29 16.44L7.56 21.71C7.75163 21.8927 8.00523 21.9963 8.27 22H15.73C15.9948 21.9963 16.2484 21.8927 16.44 21.71L21.71 16.44C21.8927 16.2484 21.9963 15.9948 22 15.73V8.27C21.9963 8.00523 21.8927 7.75163 21.71 7.56ZM20 15.31L15.31 20H8.69L4 15.31V8.69L8.69 4H15.31L20 8.69V15.31Z"></path></svg>`,
|
||||||
|
},
|
||||||
|
tip: {
|
||||||
|
title: "Tip",
|
||||||
|
hint: `<svg viewBox="0 0 16 16" width="24" height="24" aria-hidden="true" fill="currentColor"><path d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"></path></svg>`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds callouts/admonitions
|
||||||
|
* ```
|
||||||
|
* :::warn{title="example"}
|
||||||
|
* example warning
|
||||||
|
* :::
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* supports: warn, note, success, danger, tip
|
||||||
|
* @see {@link callouts} to edit icons
|
||||||
|
*/
|
||||||
|
export default function remarkCalloutDirectives() {
|
||||||
|
return (tree) => {
|
||||||
|
visit(tree, (node) => {
|
||||||
|
if (node.type === "containerDirective") {
|
||||||
|
if (!callouts[node.name]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const callout = callouts[node.name];
|
||||||
|
const data = node.data || (node.data = {});
|
||||||
|
const { title, ...attributes } = node.attributes;
|
||||||
|
|
||||||
|
node.attributes = {
|
||||||
|
...attributes,
|
||||||
|
class:
|
||||||
|
"class" in attributes
|
||||||
|
? `callout callout-${node.name} ${attributes.class}`
|
||||||
|
: `callout callout-${node.name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
node.children = generate(
|
||||||
|
title || callout.title,
|
||||||
|
node.children,
|
||||||
|
callout.hint,
|
||||||
|
);
|
||||||
|
|
||||||
|
const tagName = callout.tagName || "aside";
|
||||||
|
const hast = h(tagName, node.attributes);
|
||||||
|
data.hName = hast.tagName;
|
||||||
|
data.hProperties = hast.properties;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
102
src/assets/styles/remark-callout-directives.css
Normal file
102
src/assets/styles/remark-callout-directives.css
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/* This is taken from @microflash/remark-callout-directives/themes/github/index.css and modified. Modified to work with tailwind darkMode: class, among other things */
|
||||||
|
|
||||||
|
/* html {
|
||||||
|
--callout-headingFontColor-note: hsl(235, 76%, 29%);
|
||||||
|
--callout-bg-note: hsl(236, 77%, 90%);
|
||||||
|
--callout-border-note: hsl(235, 82%, 59%);
|
||||||
|
--callout-headingFontColor-success: hsl(137, 72%, 24%);
|
||||||
|
--callout-bg-success: hsl(96, 79%, 91%);
|
||||||
|
--callout-border-success: hsl(137, 66%, 30%);
|
||||||
|
--callout-headingFontColor-tip: hsl(277, 76%, 31%);
|
||||||
|
--callout-bg-tip: hsl(276, 70%, 90%);
|
||||||
|
--callout-border-tip: hsl(277, 81%, 60%);
|
||||||
|
--callout-headingFontColor-warn: hsl(41, 57%, 27%);
|
||||||
|
--callout-bg-warn: hsl(43, 80%, 88%);
|
||||||
|
--callout-border-warn: hsl(41, 80%, 63%);
|
||||||
|
--callout-headingFontColor-danger: hsl(342, 62%, 31%);
|
||||||
|
--callout-bg-danger: hsl(338, 57%, 89%);
|
||||||
|
--callout-border-danger: hsl(341, 72%, 60%);
|
||||||
|
} */
|
||||||
|
|
||||||
|
html {
|
||||||
|
--callout-headingFontColor-note: hsl(235, 86%, 86%);
|
||||||
|
--callout-bg-note: hsl(235, 50%, 20%);
|
||||||
|
--callout-border-note: hsl(235, 90%, 59%);
|
||||||
|
--callout-headingFontColor-success: hsl(96, 77%, 81%);
|
||||||
|
--callout-bg-success: hsl(95, 33%, 23%);
|
||||||
|
--callout-border-success: hsl(96, 77%, 81%);
|
||||||
|
--callout-headingFontColor-tip: hsl(276, 72%, 89%);
|
||||||
|
--callout-bg-tip: hsl(276, 36%, 22%);
|
||||||
|
--callout-border-tip: hsl(277, 81%, 60%);
|
||||||
|
--callout-headingFontColor-warn: hsl(42, 72%, 87%);
|
||||||
|
--callout-bg-warn: hsl(43, 33%, 22%);
|
||||||
|
--callout-border-warn: hsl(42, 72%, 65%);
|
||||||
|
--callout-headingFontColor-danger: hsl(338, 61%, 86%);
|
||||||
|
--callout-bg-danger: hsl(339, 32%, 21%);
|
||||||
|
--callout-border-danger: hsl(340, 64%, 62%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout {
|
||||||
|
--calloutheadingFontColor: var(--callout-headingFontColor);
|
||||||
|
--callout-bg: var(--callout-bg);
|
||||||
|
--callout-border: var(--callout-border);
|
||||||
|
border-left: 0.25em solid var(--callout-border);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
color: inherit;
|
||||||
|
background-color: var(--callout-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-indicator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 1;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: var(--calloutheadingFontColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 0.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-indicator > svg:first-of-type {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-content:first-child,
|
||||||
|
.callout-content:only-child {
|
||||||
|
margin-block-start: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-content:last-child,
|
||||||
|
.callout-content:only-child {
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-note {
|
||||||
|
--callout-headingFontColor: var(--callout-headingFontColor-note);
|
||||||
|
--callout-bg: var(--callout-bg-note);
|
||||||
|
--callout-border: var(--callout-border-note);
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-success {
|
||||||
|
--callout-headingFontColor: var(--callout-headingFontColor-success);
|
||||||
|
--callout-bg: var(--callout-bg-success);
|
||||||
|
--callout-border: var(--callout-border-success);
|
||||||
|
}
|
||||||
|
.callout-warn {
|
||||||
|
--callout-headingFontColor: var(--callout-headingFontColor-warn);
|
||||||
|
--callout-bg: var(--callout-bg-warn);
|
||||||
|
--callout-border: var(--callout-border-warn);
|
||||||
|
}
|
||||||
|
.callout-danger {
|
||||||
|
--callout-headingFontColor: var(--callout-headingFontColor-danger);
|
||||||
|
--callout-bg: var(--callout-bg-danger);
|
||||||
|
--callout-border: var(--callout-border-danger);
|
||||||
|
}
|
||||||
|
.callout-tip {
|
||||||
|
--callout-headingFontColor: var(--callout-headingFontColor-tip);
|
||||||
|
--callout-bg: var(--callout-bg-tip);
|
||||||
|
--callout-border: var(--callout-border-tip);
|
||||||
|
}
|
||||||
|
|
@ -35,10 +35,11 @@ const { title, tagline, pubDate, url } = Astro.props;
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={url}
|
href={url}
|
||||||
class="no-target-blank hover:no-underline hover:-translate-y-1 shadow-xl transition-all duration-300"
|
class="no-target-blank hover:no-underline hover:-translate-y-1 shadow-xl transition-all duration-300 w-full"
|
||||||
>
|
>
|
||||||
<div class="bg-[#303338] text-white
|
<div class="bg-[#303338] text-white
|
||||||
px-5 py-3
|
px-5 py-3
|
||||||
|
w-full
|
||||||
rounded-xl">
|
rounded-xl">
|
||||||
<h1 class="text-2xl font-bold">{title}</h1>
|
<h1 class="text-2xl font-bold">{title}</h1>
|
||||||
<p class="text-base">{tagline}</p>
|
<p class="text-base">{tagline}</p>
|
||||||
|
|
|
||||||
|
|
@ -125,15 +125,17 @@ import SearchModal from "../ui/SearchModal.astro";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
window.addEventListener("DOMContentLoaded", (event) => {
|
|
||||||
// @ts-ignore
|
// comment this out if you don't want the search modal
|
||||||
new PagefindUI({
|
// window.addEventListener("DOMContentLoaded", (event) => {
|
||||||
element: "#search",
|
// // @ts-ignore
|
||||||
showSubResults: false,
|
// new PagefindUI({
|
||||||
showEmptyFilters: false,
|
// element: "#search",
|
||||||
debounceTimeoutMs: 0,
|
// showSubResults: false,
|
||||||
showImages: false,
|
// showEmptyFilters: false,
|
||||||
autofocus: false,
|
// debounceTimeoutMs: 0,
|
||||||
});
|
// showImages: false,
|
||||||
});
|
// autofocus: false,
|
||||||
|
// });
|
||||||
|
// });
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<div
|
<div
|
||||||
class="bg-[white] h-[34vmax] aspect-square absolute rounded-full bg-[linear-gradient(to_right,#41C9E2,#FF7782)] animate-[rotate_20s_infinite] opacity-80 origin-center left-1/2 top-1/2"
|
class="bg-[white] h-[34vmax] aspect-square absolute rounded-full bg-[linear-gradient(to_right,#88D47D,#3F84D8)] animate-[rotate_20s_infinite] opacity-80 origin-center left-1/2 top-1/2"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="text-center text-4xl lg:text-6xl font-bold">
|
<div class="text-center text-4xl lg:text-6xl font-bold">
|
||||||
<span class="text-slate-200">Getting started with</span>
|
<span class="text-slate-200">Getting started with</span>
|
||||||
<div
|
<div
|
||||||
class="bg-clip-text text-transparent bg-gradient-pink-cyan animate-gradient py-1 lg:py-3 bg-[length:300%]"
|
class="bg-clip-text text-transparent bg-hero-gradient animate-gradient py-1 lg:py-3 bg-[length:300%]"
|
||||||
>
|
>
|
||||||
Coworking streams
|
Coworking streams
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
<div
|
<div
|
||||||
class="mt-2 text-xl text-center flex flex-col justify-center items-center"
|
class="mt-2 text-xl text-center flex flex-col justify-center items-center"
|
||||||
>
|
>
|
||||||
Brought to you by RythonDev x Coworking Crew
|
Brought to you by RythonDev
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export const HoverEffect = ({
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{hoveredIndex === idx && (
|
{hoveredIndex === idx && (
|
||||||
<motion.span
|
<motion.span
|
||||||
className="absolute inset-0 block h-full w-full rounded-3xl bg-neutral-200 dark:bg-cowo-pink"
|
className="absolute inset-0 block h-full w-full rounded-3xl bg-[#8DECB4]"
|
||||||
layoutId="hoverBackground"
|
layoutId="hoverBackground"
|
||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{
|
animate={{
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ const postsCollection = defineCollection({
|
||||||
type: "content",
|
type: "content",
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
heading: z.string(),
|
heading: z.string(),
|
||||||
subheading: z.string(),
|
subheading: z.string()?.optional(),
|
||||||
pubDate: z.string(),
|
pubDate: z.date(),
|
||||||
author: z.string(),
|
author: z.string(),
|
||||||
image: z
|
image: z
|
||||||
.object({
|
.object({
|
||||||
|
|
|
||||||
44
src/content/posts/1-Spirit-City.md
Normal file
44
src/content/posts/1-Spirit-City.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
heading: "Spirit City: Lofi Sessions"
|
||||||
|
subheading: Where Productivity Meets Cozy Vibes
|
||||||
|
author: RythonDev
|
||||||
|
slug: spirit-city
|
||||||
|
pubDate: 2024-04-18T4:10:00
|
||||||
|
---
|
||||||
|
|
||||||
|
In the ever-growing world of productivity apps and techniques, Spirit City: Lofi Sessions offers a unique and delightful twist. Forget the harsh red timers and sterile to-do lists. Here, you cultivate focus amidst a charming virtual world bathed in calming lo-fi beats and populated by friendly spirits.
|
||||||
|
|
||||||
|
## A Gamified Oasis for Focus
|
||||||
|
|
||||||
|
Developed by Mooncube Games, Spirit City: Lofi Sessions isn't your typical productivity tool. It's a gamified experience, transforming the act of getting things done into a visually appealing and engaging adventure. Imagine a cozy room, customizable to your heart's content, where you can unwind and tackle your tasks simultaneously. This is your haven in Spirit City.
|
||||||
|
|
||||||
|
## Unleash Your Inner Decorator
|
||||||
|
|
||||||
|
The room is your canvas. Spruce it up with a variety of furniture, plants, and decorations. Want a minimalist aesthetic conducive to intense concentration? Done. Craving a vibrant and playful space to spark creativity? No problem. The options cater to diverse preferences, allowing you to personalize your environment for maximum focus flow.
|
||||||
|
|
||||||
|
## Meet Your Spirit Companions
|
||||||
|
|
||||||
|
One of the most captivating aspects of Spirit City is the presence of adorable, collectable spirits. These ethereal companions aren't just cute additions to your room; they provide a sense of purpose within the game's focus-driven framework. As you complete tasks in the real world, your spirits level up, unlocking new customization options and deepening the connection between your virtual and actual productivity.
|
||||||
|
|
||||||
|
## Beyond the Aesthetics: Practical Tools for Productivity
|
||||||
|
|
||||||
|
While the visuals and atmosphere are undeniably captivating, Spirit City offers a robust toolkit for actual productivity, such as:
|
||||||
|
|
||||||
|
* **Task Management:** Create and manage to-do lists directly within the game, seamlessly integrating your virtual and real-world tasks.
|
||||||
|
* **Focus Timers:** Utilize built-in focus timers to structure your workday and prevent procrastination.
|
||||||
|
* **Pomodoro Technique Integration:** For fans of the Pomodoro Technique, Spirit City provides a gamified version of this popular time management method.
|
||||||
|
* **Background Ambience:** The ever-present (non-copyrighted) lo-fi soundtrack creates a calming and focused atmosphere, perfect for drowning out distractions and promoting concentration.
|
||||||
|
|
||||||
|
## A Community of Focused Folks
|
||||||
|
|
||||||
|
Spirit City fosters a community of like-minded individuals striving for productivity. Follow productivity streamers playing the game to connect with others who share your goals. Sharing tips, celebrating accomplishments, and holding each other accountable can significantly boost your overall motivation.
|
||||||
|
|
||||||
|
## Is Spirit City Right for You?
|
||||||
|
|
||||||
|
If you're tired of traditional productivity apps and yearn for a more engaging and stress-free approach to getting things done, then Spirit City: Lofi Sessions might be the game-changer you've been looking for. It offers a unique blend of customization, gamification, and a focus-oriented environment, all wrapped in a charming and visually appealing package. So, put on your headphones, fire up Spirit City, and embark on a productivity adventure unlike any other.
|
||||||
|
|
||||||
|
<div class="mt-10">
|
||||||
|
|
||||||
|
by [RythonDev](https://twitch.tv/RythonDev)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
---
|
|
||||||
heading: Unofficial Coworking Category, Yay or Nay?
|
|
||||||
subheading: Recent unofficial coworking category has sparked an intense discussion amongst the community
|
|
||||||
author: RythonDev
|
|
||||||
slug: unofficial-coworking-category
|
|
||||||
pubDate: 2024-03-10 15:13
|
|
||||||
image: {
|
|
||||||
url: "/images/blogs/coworking-category/coworking-category.webp",
|
|
||||||
alt: "Coworking Category"
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
## How it started
|
|
||||||
|
|
||||||
On 27th February 2024, a "Coworking" category appeared on Twitch. However, this is not an official category from Twitch, rather a "small, distraction game" as listed in IGDB (Internet Game Database), the database Twitch uses to provide gaming categories.
|
|
||||||
|
|
||||||
As a result, a significant number of coworking and study streamers use this category as a way to improve their discoverability since it is less saturated compared to the "Just Chatting" category.
|
|
||||||
|
|
||||||
As of writing, the intention behind publishing the "Coworking" category still remains unclear.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Productivity streamers started using it
|
|
||||||
|
|
||||||
The coworking & study community has been [petitioning for a Coworking and Study category](https://twitch.uservoice.com/forums/310210-discover/suggestions/46004791-coworking) since late 2022, stating that it would improve discoverability for productivity streamers.
|
|
||||||
|
|
||||||
Once this "Coworking" category came out, coworking and study streamers became aware of it and started using it as a makeshift category to improve discoverability of their streams. It also clarifies that it's a productivity stream rather than a regular Just Chatting stream (from a following feed, as an example).
|
|
||||||
|
|
||||||
While some of these streamers may be aware that it's a "game category", quite a number of them are not.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Why many streamers decided against using it
|
|
||||||
|
|
||||||
Many experienced coworking streamers have shown disinterest with the new "Coworking" category because it is a game and has little viewers compared to Just Chatting. Since it has a much smaller audience compared to Just Chatting, it may lead to reduced chances of being discovered by potential viewers.
|
|
||||||
|
|
||||||
A member of the coworking community said:
|
|
||||||
|
|
||||||
> (Basically, because) I'm trying to hit partner, and if I use a non-Just Chatting category right now, I'd only be limiting my exposure to new viewers
|
|
||||||
|
|
||||||
The official Coworking Crew team has also made a statement regarding this topic:
|
|
||||||
|
|
||||||
> As a Coworking Crew Team, we believe it might affect individual streamers' discoverability and could give Twitch the wrong idea about our satisfaction with not having an officially endorsed category.
|
|
||||||
|
|
||||||
There are other discussions about the cons of using the "Coworking" category:
|
|
||||||
|
|
||||||
- Low chance of being in the "Reading, Studying and Coworking" collection on the front page
|
|
||||||
- Subjected to be in violation of Twitch TOS about "miscategorizing" since you're not playing the game.
|
|
||||||
- Causing a significant divide in algorithm from those productivity streamers using "Just Chatting" as their category
|
|
||||||
- May reduce likelihood of Twitch actually implementing an official Coworking category, due to concerns of conflicts in the algorithm (Twitch may think: A lot of people are streaming "coworking", implementing a "coworking & study" category will just mess things up)
|
|
||||||
|
|
||||||
### But "I'm Only Sleeping" streamers are misusing the game category
|
|
||||||
|
|
||||||
The coworking community is more passionate and dedicated to have their own space on the platform, compared to "I'm Only Sleeping" streamers who don't bother about having an official "sleeping" category.
|
|
||||||
|
|
||||||
In the end, misusing the game category is still against Twitch's Terms of Service and doing so may lead to warnings, suspensions or a permanent strike on your channel.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## How does the new category affect the Twitch algorithm?
|
|
||||||
|
|
||||||
As mentioned several times, the "coworking" category is a game. This means that Twitch's algorithm will:
|
|
||||||
|
|
||||||
- Register streamers in that category as "playing a game"
|
|
||||||
- Users who watch "Coworking" for a long period of time as avid gaming stream viewers
|
|
||||||
|
|
||||||
As a result, Twitch's recommendation algorithm may:
|
|
||||||
- Recommend "Coworking" category streamers to avid gaming viewers
|
|
||||||
- Recommend gaming streams to productivity viewers
|
|
||||||
|
|
||||||
Although Twitch's recommendation algorithm remain a mystery to the general public, companies that use data analytics tend to follow similar patterns.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Pros and Cons
|
|
||||||
|
|
||||||
Here are the listed pros and cons of using the "Coworking" category, which may or may not include what has been elaborated before:
|
|
||||||
|
|
||||||
### Pros of using "Coworking" category:
|
|
||||||
|
|
||||||
1. Less competition than "Just Chatting".
|
|
||||||
|
|
||||||
2. More discoverability from people searching by the category.
|
|
||||||
|
|
||||||
3. Allow users to know when it's a productivity stream, rather than a regular Just Chatting stream (from a following feed, for example).
|
|
||||||
|
|
||||||
### Cons of using "Coworking" category:
|
|
||||||
|
|
||||||
1. Twitch thinks you're playing a game.
|
|
||||||
|
|
||||||
2. (Speculation) Users who watch the "Coworking" category may be misunderstood by the algorithm, leading to more game recommendations.
|
|
||||||
|
|
||||||
3. (Speculation) Streamers using the "Coworking" category may have a significant divide from those who are using the "Just Chatting" category by the Twitch algorithm (in terms of user recommendations).
|
|
||||||
|
|
||||||
4. You're less likely to be on the "Reading, Studying, and Coworking" list on the front page.
|
|
||||||
|
|
||||||
5. Subjected to be in violation of Twitch TOS about "miscategorizing" since you're not playing the game.
|
|
||||||
|
|
||||||
6. (Speculation) May reduce likelihood of Twitch actually implementing an official Coworking category, due to concerns of conflicts in the algorithm (Twitch may think: A lot of people are streaming "coworking", implementing a "coworking & study" category will just mess things up).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
The purpose of this post is not to persuade people to "pick a side", rather it is meant to inform and show the bigger picture of this "Coworking" category. Please do not pressure nor target any streamers regarding this topic, and don't forget to [VOTE for an official Coworking and Study category](https://twitch.uservoice.com/forums/310210-discover/suggestions/46004791-coworking).
|
|
||||||
|
|
||||||
## Edit:
|
|
||||||
|
|
||||||
As of 15th March 2024, the "Coworking" game category has been removed from IGDB and Twitch.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
by [RythonDev](https://twitch.tv/RythonDev)
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import Layout from "./Layout.astro";
|
import Layout from "./Layout.astro";
|
||||||
import TableOfContent from "../components/blocks/TableOfContent.astro";
|
import TableOfContent from "../components/blocks/TableOfContent.astro";
|
||||||
import VerticalNav from "../components/blocks/verticalNav.astro";
|
import VerticalNav from "../components/blocks/verticalNav.astro";
|
||||||
|
import "../assets/styles/remark-callout-directives.css";
|
||||||
|
|
||||||
const { frontmatter, headings } = Astro.props;
|
const { frontmatter, headings } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -4,42 +4,42 @@ import BlogPostLayout from "../../../layouts/BlogPostLayout.astro";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
|
|
||||||
function timeAgo(date: Date) {
|
function timeAgo(date: Date) {
|
||||||
const dateObject = new Date(date);
|
const dateObject = new Date(date);
|
||||||
const seconds = Math.floor(
|
const seconds = Math.floor(
|
||||||
(new Date().getTime() - dateObject.getTime()) / 1000,
|
(new Date().getTime() - dateObject.getTime()) / 1000
|
||||||
);
|
);
|
||||||
let interval = Math.floor(seconds / 31536000);
|
let interval = Math.floor(seconds / 31536000);
|
||||||
|
|
||||||
if (interval >= 1) {
|
if (interval >= 1) {
|
||||||
return interval + (interval === 1 ? " year ago" : " years ago");
|
return interval + (interval === 1 ? " year ago" : " years ago");
|
||||||
}
|
}
|
||||||
interval = Math.floor(seconds / 2592000);
|
interval = Math.floor(seconds / 2592000);
|
||||||
if (interval >= 1) {
|
if (interval >= 1) {
|
||||||
return interval + (interval === 1 ? " month ago" : " months ago");
|
return interval + (interval === 1 ? " month ago" : " months ago");
|
||||||
}
|
}
|
||||||
interval = Math.floor(seconds / 86400);
|
interval = Math.floor(seconds / 86400);
|
||||||
if (interval >= 1) {
|
if (interval >= 1) {
|
||||||
return interval + (interval === 1 ? " day ago" : " days ago");
|
return interval + (interval === 1 ? " day ago" : " days ago");
|
||||||
}
|
}
|
||||||
interval = Math.floor(seconds / 3600);
|
interval = Math.floor(seconds / 3600);
|
||||||
if (interval >= 1) {
|
if (interval >= 1) {
|
||||||
return interval + (interval === 1 ? " hour ago" : " hours ago");
|
return interval + (interval === 1 ? " hour ago" : " hours ago");
|
||||||
}
|
}
|
||||||
interval = Math.floor(seconds / 60);
|
interval = Math.floor(seconds / 60);
|
||||||
if (interval > 1) {
|
if (interval > 1) {
|
||||||
return interval + (interval === 1 ? " minute ago" : " minutes ago");
|
return interval + (interval === 1 ? " minute ago" : " minutes ago");
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
Math.floor(seconds) + (seconds === 1 ? " second ago" : " seconds ago")
|
Math.floor(seconds) + (seconds === 1 ? " second ago" : " seconds ago")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const blogEntries = await getCollection("posts");
|
const blogEntries = await getCollection("posts");
|
||||||
return blogEntries.map((entry) => ({
|
return blogEntries.map((entry) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.slug },
|
||||||
props: { entry },
|
props: { entry },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { entry } = Astro.props;
|
const { entry } = Astro.props;
|
||||||
|
|
@ -47,24 +47,28 @@ const { Content, headings } = await entry.render();
|
||||||
---
|
---
|
||||||
|
|
||||||
<BlogPostLayout frontmatter={entry.data} headings={headings}>
|
<BlogPostLayout frontmatter={entry.data} headings={headings}>
|
||||||
<h1>{entry.data.heading}</h1>
|
<h1>{entry.data.heading}</h1>
|
||||||
<h2 class="font-normal text-lg">{entry.data.subheading}</h2>
|
<h2 class="font-normal text-lg">{entry.data.subheading}</h2>
|
||||||
<p class="text-base font-normal text-gray-400">by {entry.data.author}</p>
|
<div class="flex justify-start items-start gap-3">
|
||||||
<p class="text-base font-normal text-gray-400">
|
<p class="text-base font-normal text-gray-200">
|
||||||
Published {timeAgo(new Date(entry.data.pubDate))}
|
By {entry.data.author}
|
||||||
</p>
|
</p>
|
||||||
|
<p class="text-base font-normal text-gray-400">
|
||||||
|
Published {timeAgo(new Date(entry.data.pubDate))}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
entry.data.image && (
|
entry.data.image && (
|
||||||
<Image
|
<Image
|
||||||
src={entry.data.image.url}
|
src={entry.data.image.url}
|
||||||
alt={entry.data.image.alt}
|
alt={entry.data.image.alt}
|
||||||
class="mt-5 mb-5"
|
class="mt-5 mb-5"
|
||||||
width="700"
|
width="700"
|
||||||
height="400"
|
height="400"
|
||||||
loading="eager"
|
loading="eager"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<Content />
|
<Content />
|
||||||
</BlogPostLayout>
|
</BlogPostLayout>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ Credits to the wonderful team of people behind this guide!
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<img src="/images/credits/rythondev.webp" alt="RythonDev" class="rounded-lg" width="300">
|
<img src="/images/credits/rythondev.webp" alt="RythonDev" class="rounded-lg" width="300" />
|
||||||
|
|
||||||
## RythonDev
|
## RythonDev
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,10 @@ Consider these three main things when choosing your mods:
|
||||||
|
|
||||||
As well as this, it is ideal if mods are welcoming and active in your community - you can't always be there to say hi to everyone while your working so it's great to have a friendly mod team to welcome new people and answer questions!
|
As well as this, it is ideal if mods are welcoming and active in your community - you can't always be there to say hi to everyone while your working so it's great to have a friendly mod team to welcome new people and answer questions!
|
||||||
|
|
||||||
> How you invite your mods is a personal choice! And don't feel bad if you ask someone and they say no - not everyone is up for the job! If you know someone you'd like as a mod you could DM them with a personal invite, otherwise you could create an application form if that suits you and your community better!
|
:::note
|
||||||
|
How you invite your mods is a personal choice! And don't feel bad if you ask someone and they say no - not everyone is up for the job! If you know someone you'd like as a mod you could DM them with a personal invite, otherwise you could create an application form if that suits you and your community better!
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ module.exports = {
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
backgroundImage: (theme) => ({
|
backgroundImage: (theme) => ({
|
||||||
"gradient-pink-cyan":
|
"hero-gradient":
|
||||||
"linear-gradient(to right, #F7418F,#FF7782 , aquamarine)",
|
"linear-gradient(to right, #3F84D8, aquamarine, #C65BCF)",
|
||||||
}),
|
}),
|
||||||
keyframes: {
|
keyframes: {
|
||||||
rotate: {
|
rotate: {
|
||||||
|
|
@ -32,16 +32,27 @@ module.exports = {
|
||||||
opacity: "1",
|
opacity: "1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
scaleIn: {
|
||||||
|
from: {
|
||||||
|
transform: "scale(0)",
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
transform: "scale(1)",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
"spin-slow": "rotate 15s linear infinite",
|
"spin-slow": "rotate 15s linear infinite",
|
||||||
gradient: "gradient 15s ease infinite",
|
gradient: "gradient 15s ease infinite",
|
||||||
fadeIn: "fadeIn 0.3s ease-in-out forwards",
|
fadeIn: "fadeIn 0.3s ease-in-out forwards",
|
||||||
|
scaleIn: "scaleIn 0.3s ease-in-out forwards",
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
"cowo-pink": "#FF7782",
|
"cowo-pink": "#FF7782",
|
||||||
secondary: "#171717",
|
secondary: "#171717",
|
||||||
primary: "#fafafa",
|
primary: "#fafafa",
|
||||||
|
"primary-green": "#88D47D",
|
||||||
|
"primary-blue": "#3F84D8",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue