Spaces:
Sleeping
Sleeping
Protocol Cyberia commited on
Commit ·
01bfb12
1
Parent(s): 13d212e
Uploaded
Browse files- .gitignore +1 -0
- app.py +193 -0
- eslint.config.mjs +0 -18
- next.config.ts +0 -7
- package-lock.json +0 -0
- package.json +0 -24
- public/file.svg +0 -1
- public/globe.svg +0 -1
- public/next.svg +0 -1
- public/vercel.svg +0 -1
- public/window.svg +0 -1
- requirements.txt +3 -0
- src/app/favicon.ico +0 -0
- src/app/globals.css +0 -49
- src/app/layout.tsx +0 -30
- src/app/page.module.css +0 -142
- src/app/page.tsx +0 -66
- tsconfig.json +0 -34
.gitignore
CHANGED
|
@@ -36,6 +36,7 @@ yarn-error.log*
|
|
| 36 |
# vercel
|
| 37 |
.vercel
|
| 38 |
|
|
|
|
| 39 |
# typescript
|
| 40 |
*.tsbuildinfo
|
| 41 |
next-env.d.ts
|
|
|
|
| 36 |
# vercel
|
| 37 |
.vercel
|
| 38 |
|
| 39 |
+
/.venv
|
| 40 |
# typescript
|
| 41 |
*.tsbuildinfo
|
| 42 |
next-env.d.ts
|
app.py
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import time
|
| 3 |
+
import json
|
| 4 |
+
import requests
|
| 5 |
+
import concurrent.futures
|
| 6 |
+
import gradio as gr
|
| 7 |
+
from dotenv import load_dotenv
|
| 8 |
+
|
| 9 |
+
# Load environment variables (useful for local development)
|
| 10 |
+
load_dotenv(".env.local")
|
| 11 |
+
|
| 12 |
+
HF_API_TOKEN = os.environ.get("HF_API_TOKEN", "hf_dummy_token_for_now")
|
| 13 |
+
HF_MODEL_COEDIT = os.environ.get("HF_MODEL_COEDIT", "Wisteria86/coedit")
|
| 14 |
+
HF_MODEL_EXPLAIN_GEC = os.environ.get("HF_MODEL_EXPLAIN_GEC", "your-username/explain-gec-dummy")
|
| 15 |
+
HF_MODEL_SCORING_1 = os.environ.get("HF_MODEL_SCORING_1", "your-username/scoring-1-dummy")
|
| 16 |
+
HF_MODEL_SCORING_2 = os.environ.get("HF_MODEL_SCORING_2", "your-username/scoring-2-dummy")
|
| 17 |
+
HF_MODEL_SCORING_3 = os.environ.get("HF_MODEL_SCORING_3", "your-username/scoring-3-dummy")
|
| 18 |
+
|
| 19 |
+
headers = {
|
| 20 |
+
"Authorization": f"Bearer {HF_API_TOKEN}",
|
| 21 |
+
"Content-Type": "application/json",
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
def call_hf_api(model_id, payload):
|
| 25 |
+
if not HF_API_TOKEN or HF_API_TOKEN == "hf_dummy_token_for_now":
|
| 26 |
+
time.sleep(1.5)
|
| 27 |
+
return {"dummy": True, "model": model_id}
|
| 28 |
+
|
| 29 |
+
url = f"https://api-inference.huggingface.co/models/{model_id}"
|
| 30 |
+
try:
|
| 31 |
+
response = requests.post(url, headers=headers, json=payload)
|
| 32 |
+
response.raise_for_status()
|
| 33 |
+
return response.json()
|
| 34 |
+
except requests.exceptions.RequestException as e:
|
| 35 |
+
return {"error": str(e), "model": model_id}
|
| 36 |
+
|
| 37 |
+
def run_score(text):
|
| 38 |
+
if not text.strip():
|
| 39 |
+
return "Please enter some text."
|
| 40 |
+
|
| 41 |
+
if HF_API_TOKEN == "hf_dummy_token_for_now":
|
| 42 |
+
time.sleep(1.5)
|
| 43 |
+
import random
|
| 44 |
+
return json.dumps({
|
| 45 |
+
HF_MODEL_SCORING_1: random.random() * 100,
|
| 46 |
+
HF_MODEL_SCORING_2: random.random() * 100,
|
| 47 |
+
HF_MODEL_SCORING_3: random.random() * 100,
|
| 48 |
+
}, indent=2)
|
| 49 |
+
|
| 50 |
+
models = [HF_MODEL_SCORING_1, HF_MODEL_SCORING_2, HF_MODEL_SCORING_3]
|
| 51 |
+
results = {}
|
| 52 |
+
|
| 53 |
+
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
|
| 54 |
+
future_to_model = {executor.submit(call_hf_api, m, {"inputs": text}): m for m in models if m}
|
| 55 |
+
for future in concurrent.futures.as_completed(future_to_model):
|
| 56 |
+
model = future_to_model[future]
|
| 57 |
+
try:
|
| 58 |
+
data = future.result()
|
| 59 |
+
if isinstance(data, dict) and "error" in data:
|
| 60 |
+
results[model] = data["error"]
|
| 61 |
+
else:
|
| 62 |
+
if isinstance(data, list) and len(data) > 0:
|
| 63 |
+
results[model] = data[0].get("score", data[0])
|
| 64 |
+
else:
|
| 65 |
+
results[model] = data
|
| 66 |
+
except Exception as exc:
|
| 67 |
+
results[model] = f"Generated an exception: {exc}"
|
| 68 |
+
|
| 69 |
+
return json.dumps(results, indent=2)
|
| 70 |
+
|
| 71 |
+
def run_convert(text, action):
|
| 72 |
+
if not text.strip():
|
| 73 |
+
return "Please enter some text."
|
| 74 |
+
|
| 75 |
+
if HF_API_TOKEN == "hf_dummy_token_for_now":
|
| 76 |
+
time.sleep(1.5)
|
| 77 |
+
return f"[SIMULATED] Successfully applied {action} transformation to: '{text[:50]}...'"
|
| 78 |
+
|
| 79 |
+
prompt_prefix = {
|
| 80 |
+
"Grammar": "Fix grammar: ",
|
| 81 |
+
"Paraphrase": "Paraphrase: ",
|
| 82 |
+
"Formal": "Make formal: ",
|
| 83 |
+
"Informal": "Make informal: ",
|
| 84 |
+
"Complexity": "Make more complex: ",
|
| 85 |
+
"Simplicity": "Make simpler: ",
|
| 86 |
+
"Clarity": "Make clearer: "
|
| 87 |
+
}.get(action, "")
|
| 88 |
+
|
| 89 |
+
inputs = f"{prompt_prefix}{text}"
|
| 90 |
+
|
| 91 |
+
url = f"https://router.huggingface.co/hf-inference/models/{HF_MODEL_COEDIT}"
|
| 92 |
+
|
| 93 |
+
try:
|
| 94 |
+
response = requests.post(url, headers=headers, json={"inputs": inputs})
|
| 95 |
+
response.raise_for_status()
|
| 96 |
+
data = response.json()
|
| 97 |
+
|
| 98 |
+
if isinstance(data, list) and len(data) > 0:
|
| 99 |
+
return data[0].get("generated_text", data[0].get("summary_text", str(data)))
|
| 100 |
+
return str(data)
|
| 101 |
+
except requests.exceptions.RequestException as e:
|
| 102 |
+
return f"Error executing conversion protocol: {str(e)}"
|
| 103 |
+
|
| 104 |
+
def run_explain(text):
|
| 105 |
+
if not text.strip():
|
| 106 |
+
return "Please enter some text."
|
| 107 |
+
|
| 108 |
+
if HF_API_TOKEN == "hf_dummy_token_for_now":
|
| 109 |
+
time.sleep(1.5)
|
| 110 |
+
return f"[SIMULATED] Found 2 grammatical anomalies in the text.\n\n1. Syntax error detected near the beginning.\n2. Inconsistent tense usage.\n\nOriginal Text: '{text[:50]}...'"
|
| 111 |
+
|
| 112 |
+
data = call_hf_api(HF_MODEL_EXPLAIN_GEC, {"inputs": text})
|
| 113 |
+
if isinstance(data, dict) and "error" in data:
|
| 114 |
+
return f"Error accessing Explainable GEC module: {data['error']}"
|
| 115 |
+
|
| 116 |
+
if isinstance(data, list) and len(data) > 0:
|
| 117 |
+
return data[0].get("generated_text", str(data))
|
| 118 |
+
return str(data)
|
| 119 |
+
|
| 120 |
+
custom_css = """
|
| 121 |
+
body {
|
| 122 |
+
background-color: #0a0a0a !important;
|
| 123 |
+
}
|
| 124 |
+
.gradio-container {
|
| 125 |
+
font-family: 'Courier New', Courier, monospace !important;
|
| 126 |
+
}
|
| 127 |
+
h1 {
|
| 128 |
+
color: #39ff14 !important;
|
| 129 |
+
text-shadow: 0 0 10px rgba(57, 255, 20, 0.5);
|
| 130 |
+
text-align: center;
|
| 131 |
+
}
|
| 132 |
+
.tabs button {
|
| 133 |
+
font-weight: bold;
|
| 134 |
+
border-radius: 4px;
|
| 135 |
+
}
|
| 136 |
+
.tabs button.selected {
|
| 137 |
+
border-bottom: 2px solid #ff00ff !important;
|
| 138 |
+
color: #ff00ff !important;
|
| 139 |
+
}
|
| 140 |
+
button.primary {
|
| 141 |
+
background: rgba(57, 255, 20, 0.1) !important;
|
| 142 |
+
border: 1px solid #39ff14 !important;
|
| 143 |
+
color: #39ff14 !important;
|
| 144 |
+
transition: all 0.2s ease;
|
| 145 |
+
}
|
| 146 |
+
button.primary:hover {
|
| 147 |
+
background: rgba(57, 255, 20, 0.2) !important;
|
| 148 |
+
box-shadow: 0 0 10px rgba(57, 255, 20, 0.3);
|
| 149 |
+
}
|
| 150 |
+
.secondary-btn {
|
| 151 |
+
background: rgba(255, 0, 255, 0.1) !important;
|
| 152 |
+
border: 1px solid #ff00ff !important;
|
| 153 |
+
color: #ff00ff !important;
|
| 154 |
+
transition: all 0.2s ease;
|
| 155 |
+
}
|
| 156 |
+
.secondary-btn:hover {
|
| 157 |
+
background: rgba(255, 0, 255, 0.2) !important;
|
| 158 |
+
box-shadow: 0 0 10px rgba(255, 0, 255, 0.3);
|
| 159 |
+
}
|
| 160 |
+
"""
|
| 161 |
+
|
| 162 |
+
with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css, title="PrismAi") as demo:
|
| 163 |
+
gr.Markdown("# PrismAi Text Intelligence Panel")
|
| 164 |
+
gr.Markdown("<p style='text-align: center; color: #888;'>Execute text transformation, scoring, and explanation protocols.</p>")
|
| 165 |
+
|
| 166 |
+
text_input = gr.Textbox(lines=5, placeholder="Enter text sequence here...", label="INPUT SEQUENCE")
|
| 167 |
+
|
| 168 |
+
with gr.Tabs():
|
| 169 |
+
with gr.Tab("SCORE"):
|
| 170 |
+
gr.Markdown("Execute scoring models across multiple vectors.")
|
| 171 |
+
score_btn = gr.Button("INITIATE_SCORING", variant="primary")
|
| 172 |
+
score_output = gr.Code(language="json", label="SCORING OUTPUT")
|
| 173 |
+
score_btn.click(fn=run_score, inputs=text_input, outputs=score_output)
|
| 174 |
+
|
| 175 |
+
with gr.Tab("CONVERT"):
|
| 176 |
+
gr.Markdown("Modify text structure and tone.")
|
| 177 |
+
action_radio = gr.Radio(
|
| 178 |
+
["Grammar", "Paraphrase", "Formal", "Informal", "Complexity", "Simplicity", "Clarity"],
|
| 179 |
+
label="CONVERSION ACTION",
|
| 180 |
+
value="Grammar"
|
| 181 |
+
)
|
| 182 |
+
convert_btn = gr.Button("RUN_CONVERSION", elem_classes=["secondary-btn"])
|
| 183 |
+
convert_output = gr.Textbox(label="CONVERTED OUTPUT")
|
| 184 |
+
convert_btn.click(fn=run_convert, inputs=[text_input, action_radio], outputs=convert_output)
|
| 185 |
+
|
| 186 |
+
with gr.Tab("EXPLAIN"):
|
| 187 |
+
gr.Markdown("Analyze text for grammatical anomalies and explain corrections.")
|
| 188 |
+
explain_btn = gr.Button("RUN_EXPLAIN_GEC", elem_classes=["secondary-btn"])
|
| 189 |
+
explain_output = gr.Textbox(label="EXPLANATION OUTPUT")
|
| 190 |
+
explain_btn.click(fn=run_explain, inputs=text_input, outputs=explain_output)
|
| 191 |
+
|
| 192 |
+
if __name__ == "__main__":
|
| 193 |
+
demo.launch()
|
eslint.config.mjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
| 1 |
-
import { defineConfig, globalIgnores } from "eslint/config";
|
| 2 |
-
import nextVitals from "eslint-config-next/core-web-vitals";
|
| 3 |
-
import nextTs from "eslint-config-next/typescript";
|
| 4 |
-
|
| 5 |
-
const eslintConfig = defineConfig([
|
| 6 |
-
...nextVitals,
|
| 7 |
-
...nextTs,
|
| 8 |
-
// Override default ignores of eslint-config-next.
|
| 9 |
-
globalIgnores([
|
| 10 |
-
// Default ignores of eslint-config-next:
|
| 11 |
-
".next/**",
|
| 12 |
-
"out/**",
|
| 13 |
-
"build/**",
|
| 14 |
-
"next-env.d.ts",
|
| 15 |
-
]),
|
| 16 |
-
]);
|
| 17 |
-
|
| 18 |
-
export default eslintConfig;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
next.config.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
| 1 |
-
import type { NextConfig } from "next";
|
| 2 |
-
|
| 3 |
-
const nextConfig: NextConfig = {
|
| 4 |
-
/* config options here */
|
| 5 |
-
};
|
| 6 |
-
|
| 7 |
-
export default nextConfig;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package-lock.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
package.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"name": "prismai",
|
| 3 |
-
"version": "0.1.0",
|
| 4 |
-
"private": true,
|
| 5 |
-
"scripts": {
|
| 6 |
-
"dev": "next dev",
|
| 7 |
-
"build": "next build",
|
| 8 |
-
"start": "next start",
|
| 9 |
-
"lint": "eslint"
|
| 10 |
-
},
|
| 11 |
-
"dependencies": {
|
| 12 |
-
"next": "16.2.4",
|
| 13 |
-
"react": "19.2.4",
|
| 14 |
-
"react-dom": "19.2.4"
|
| 15 |
-
},
|
| 16 |
-
"devDependencies": {
|
| 17 |
-
"@types/node": "^20",
|
| 18 |
-
"@types/react": "^19",
|
| 19 |
-
"@types/react-dom": "^19",
|
| 20 |
-
"eslint": "^9",
|
| 21 |
-
"eslint-config-next": "16.2.4",
|
| 22 |
-
"typescript": "^5"
|
| 23 |
-
}
|
| 24 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public/file.svg
DELETED
public/globe.svg
DELETED
public/next.svg
DELETED
public/vercel.svg
DELETED
public/window.svg
DELETED
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
requests
|
| 3 |
+
python-dotenv
|
src/app/favicon.ico
DELETED
|
Binary file (25.9 kB)
|
|
|
src/app/globals.css
DELETED
|
@@ -1,49 +0,0 @@
|
|
| 1 |
-
:root {
|
| 2 |
-
--background: #ffffff;
|
| 3 |
-
--foreground: #171717;
|
| 4 |
-
}
|
| 5 |
-
|
| 6 |
-
@media (prefers-color-scheme: dark) {
|
| 7 |
-
:root {
|
| 8 |
-
--background: #0a0a0a;
|
| 9 |
-
--foreground: #ededed;
|
| 10 |
-
}
|
| 11 |
-
}
|
| 12 |
-
|
| 13 |
-
html {
|
| 14 |
-
height: 100%;
|
| 15 |
-
}
|
| 16 |
-
|
| 17 |
-
html,
|
| 18 |
-
body {
|
| 19 |
-
max-width: 100vw;
|
| 20 |
-
overflow-x: hidden;
|
| 21 |
-
}
|
| 22 |
-
|
| 23 |
-
body {
|
| 24 |
-
min-height: 100%;
|
| 25 |
-
display: flex;
|
| 26 |
-
flex-direction: column;
|
| 27 |
-
color: var(--foreground);
|
| 28 |
-
background: var(--background);
|
| 29 |
-
font-family: Arial, Helvetica, sans-serif;
|
| 30 |
-
-webkit-font-smoothing: antialiased;
|
| 31 |
-
-moz-osx-font-smoothing: grayscale;
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
* {
|
| 35 |
-
box-sizing: border-box;
|
| 36 |
-
padding: 0;
|
| 37 |
-
margin: 0;
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
a {
|
| 41 |
-
color: inherit;
|
| 42 |
-
text-decoration: none;
|
| 43 |
-
}
|
| 44 |
-
|
| 45 |
-
@media (prefers-color-scheme: dark) {
|
| 46 |
-
html {
|
| 47 |
-
color-scheme: dark;
|
| 48 |
-
}
|
| 49 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/app/layout.tsx
DELETED
|
@@ -1,30 +0,0 @@
|
|
| 1 |
-
import type { Metadata } from "next";
|
| 2 |
-
import { Geist, Geist_Mono } from "next/font/google";
|
| 3 |
-
import "./globals.css";
|
| 4 |
-
|
| 5 |
-
const geistSans = Geist({
|
| 6 |
-
variable: "--font-geist-sans",
|
| 7 |
-
subsets: ["latin"],
|
| 8 |
-
});
|
| 9 |
-
|
| 10 |
-
const geistMono = Geist_Mono({
|
| 11 |
-
variable: "--font-geist-mono",
|
| 12 |
-
subsets: ["latin"],
|
| 13 |
-
});
|
| 14 |
-
|
| 15 |
-
export const metadata: Metadata = {
|
| 16 |
-
title: "Create Next App",
|
| 17 |
-
description: "Generated by create next app",
|
| 18 |
-
};
|
| 19 |
-
|
| 20 |
-
export default function RootLayout({
|
| 21 |
-
children,
|
| 22 |
-
}: Readonly<{
|
| 23 |
-
children: React.ReactNode;
|
| 24 |
-
}>) {
|
| 25 |
-
return (
|
| 26 |
-
<html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
|
| 27 |
-
<body>{children}</body>
|
| 28 |
-
</html>
|
| 29 |
-
);
|
| 30 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/app/page.module.css
DELETED
|
@@ -1,142 +0,0 @@
|
|
| 1 |
-
.page {
|
| 2 |
-
--background: #fafafa;
|
| 3 |
-
--foreground: #fff;
|
| 4 |
-
|
| 5 |
-
--text-primary: #000;
|
| 6 |
-
--text-secondary: #666;
|
| 7 |
-
|
| 8 |
-
--button-primary-hover: #383838;
|
| 9 |
-
--button-secondary-hover: #f2f2f2;
|
| 10 |
-
--button-secondary-border: #ebebeb;
|
| 11 |
-
|
| 12 |
-
display: flex;
|
| 13 |
-
flex: 1;
|
| 14 |
-
flex-direction: column;
|
| 15 |
-
align-items: center;
|
| 16 |
-
justify-content: center;
|
| 17 |
-
font-family: var(--font-geist-sans);
|
| 18 |
-
background-color: var(--background);
|
| 19 |
-
}
|
| 20 |
-
|
| 21 |
-
.main {
|
| 22 |
-
display: flex;
|
| 23 |
-
flex: 1;
|
| 24 |
-
width: 100%;
|
| 25 |
-
max-width: 800px;
|
| 26 |
-
flex-direction: column;
|
| 27 |
-
align-items: flex-start;
|
| 28 |
-
justify-content: space-between;
|
| 29 |
-
background-color: var(--foreground);
|
| 30 |
-
padding: 120px 60px;
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
.intro {
|
| 34 |
-
display: flex;
|
| 35 |
-
flex-direction: column;
|
| 36 |
-
align-items: flex-start;
|
| 37 |
-
text-align: left;
|
| 38 |
-
gap: 24px;
|
| 39 |
-
}
|
| 40 |
-
|
| 41 |
-
.intro h1 {
|
| 42 |
-
max-width: 320px;
|
| 43 |
-
font-size: 40px;
|
| 44 |
-
font-weight: 600;
|
| 45 |
-
line-height: 48px;
|
| 46 |
-
letter-spacing: -2.4px;
|
| 47 |
-
text-wrap: balance;
|
| 48 |
-
color: var(--text-primary);
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
.intro p {
|
| 52 |
-
max-width: 440px;
|
| 53 |
-
font-size: 18px;
|
| 54 |
-
line-height: 32px;
|
| 55 |
-
text-wrap: balance;
|
| 56 |
-
color: var(--text-secondary);
|
| 57 |
-
}
|
| 58 |
-
|
| 59 |
-
.intro a {
|
| 60 |
-
font-weight: 500;
|
| 61 |
-
color: var(--text-primary);
|
| 62 |
-
}
|
| 63 |
-
|
| 64 |
-
.ctas {
|
| 65 |
-
display: flex;
|
| 66 |
-
flex-direction: row;
|
| 67 |
-
width: 100%;
|
| 68 |
-
max-width: 440px;
|
| 69 |
-
gap: 16px;
|
| 70 |
-
font-size: 14px;
|
| 71 |
-
}
|
| 72 |
-
|
| 73 |
-
.ctas a {
|
| 74 |
-
display: flex;
|
| 75 |
-
justify-content: center;
|
| 76 |
-
align-items: center;
|
| 77 |
-
height: 40px;
|
| 78 |
-
padding: 0 16px;
|
| 79 |
-
border-radius: 128px;
|
| 80 |
-
border: 1px solid transparent;
|
| 81 |
-
transition: 0.2s;
|
| 82 |
-
cursor: pointer;
|
| 83 |
-
width: fit-content;
|
| 84 |
-
font-weight: 500;
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
a.primary {
|
| 88 |
-
background: var(--text-primary);
|
| 89 |
-
color: var(--background);
|
| 90 |
-
gap: 8px;
|
| 91 |
-
}
|
| 92 |
-
|
| 93 |
-
a.secondary {
|
| 94 |
-
border-color: var(--button-secondary-border);
|
| 95 |
-
}
|
| 96 |
-
|
| 97 |
-
/* Enable hover only on non-touch devices */
|
| 98 |
-
@media (hover: hover) and (pointer: fine) {
|
| 99 |
-
a.primary:hover {
|
| 100 |
-
background: var(--button-primary-hover);
|
| 101 |
-
border-color: transparent;
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
a.secondary:hover {
|
| 105 |
-
background: var(--button-secondary-hover);
|
| 106 |
-
border-color: transparent;
|
| 107 |
-
}
|
| 108 |
-
}
|
| 109 |
-
|
| 110 |
-
@media (max-width: 600px) {
|
| 111 |
-
.main {
|
| 112 |
-
padding: 48px 24px;
|
| 113 |
-
}
|
| 114 |
-
|
| 115 |
-
.intro {
|
| 116 |
-
gap: 16px;
|
| 117 |
-
}
|
| 118 |
-
|
| 119 |
-
.intro h1 {
|
| 120 |
-
font-size: 32px;
|
| 121 |
-
line-height: 40px;
|
| 122 |
-
letter-spacing: -1.92px;
|
| 123 |
-
}
|
| 124 |
-
}
|
| 125 |
-
|
| 126 |
-
@media (prefers-color-scheme: dark) {
|
| 127 |
-
.logo {
|
| 128 |
-
filter: invert();
|
| 129 |
-
}
|
| 130 |
-
|
| 131 |
-
.page {
|
| 132 |
-
--background: #000;
|
| 133 |
-
--foreground: #000;
|
| 134 |
-
|
| 135 |
-
--text-primary: #ededed;
|
| 136 |
-
--text-secondary: #999;
|
| 137 |
-
|
| 138 |
-
--button-primary-hover: #ccc;
|
| 139 |
-
--button-secondary-hover: #1a1a1a;
|
| 140 |
-
--button-secondary-border: #1a1a1a;
|
| 141 |
-
}
|
| 142 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/app/page.tsx
DELETED
|
@@ -1,66 +0,0 @@
|
|
| 1 |
-
import Image from "next/image";
|
| 2 |
-
import styles from "./page.module.css";
|
| 3 |
-
|
| 4 |
-
export default function Home() {
|
| 5 |
-
return (
|
| 6 |
-
<div className={styles.page}>
|
| 7 |
-
<main className={styles.main}>
|
| 8 |
-
<Image
|
| 9 |
-
className={styles.logo}
|
| 10 |
-
src="/next.svg"
|
| 11 |
-
alt="Next.js logo"
|
| 12 |
-
width={100}
|
| 13 |
-
height={20}
|
| 14 |
-
priority
|
| 15 |
-
/>
|
| 16 |
-
<div className={styles.intro}>
|
| 17 |
-
<h1>To get started, edit the page.tsx file.</h1>
|
| 18 |
-
<p>
|
| 19 |
-
Looking for a starting point or more instructions? Head over to{" "}
|
| 20 |
-
<a
|
| 21 |
-
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
| 22 |
-
target="_blank"
|
| 23 |
-
rel="noopener noreferrer"
|
| 24 |
-
>
|
| 25 |
-
Templates
|
| 26 |
-
</a>{" "}
|
| 27 |
-
or the{" "}
|
| 28 |
-
<a
|
| 29 |
-
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
| 30 |
-
target="_blank"
|
| 31 |
-
rel="noopener noreferrer"
|
| 32 |
-
>
|
| 33 |
-
Learning
|
| 34 |
-
</a>{" "}
|
| 35 |
-
center.
|
| 36 |
-
</p>
|
| 37 |
-
</div>
|
| 38 |
-
<div className={styles.ctas}>
|
| 39 |
-
<a
|
| 40 |
-
className={styles.primary}
|
| 41 |
-
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
| 42 |
-
target="_blank"
|
| 43 |
-
rel="noopener noreferrer"
|
| 44 |
-
>
|
| 45 |
-
<Image
|
| 46 |
-
className={styles.logo}
|
| 47 |
-
src="/vercel.svg"
|
| 48 |
-
alt="Vercel logomark"
|
| 49 |
-
width={16}
|
| 50 |
-
height={16}
|
| 51 |
-
/>
|
| 52 |
-
Deploy Now
|
| 53 |
-
</a>
|
| 54 |
-
<a
|
| 55 |
-
className={styles.secondary}
|
| 56 |
-
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
| 57 |
-
target="_blank"
|
| 58 |
-
rel="noopener noreferrer"
|
| 59 |
-
>
|
| 60 |
-
Documentation
|
| 61 |
-
</a>
|
| 62 |
-
</div>
|
| 63 |
-
</main>
|
| 64 |
-
</div>
|
| 65 |
-
);
|
| 66 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tsconfig.json
DELETED
|
@@ -1,34 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"compilerOptions": {
|
| 3 |
-
"target": "ES2017",
|
| 4 |
-
"lib": ["dom", "dom.iterable", "esnext"],
|
| 5 |
-
"allowJs": true,
|
| 6 |
-
"skipLibCheck": true,
|
| 7 |
-
"strict": true,
|
| 8 |
-
"noEmit": true,
|
| 9 |
-
"esModuleInterop": true,
|
| 10 |
-
"module": "esnext",
|
| 11 |
-
"moduleResolution": "bundler",
|
| 12 |
-
"resolveJsonModule": true,
|
| 13 |
-
"isolatedModules": true,
|
| 14 |
-
"jsx": "react-jsx",
|
| 15 |
-
"incremental": true,
|
| 16 |
-
"plugins": [
|
| 17 |
-
{
|
| 18 |
-
"name": "next"
|
| 19 |
-
}
|
| 20 |
-
],
|
| 21 |
-
"paths": {
|
| 22 |
-
"@/*": ["./src/*"]
|
| 23 |
-
}
|
| 24 |
-
},
|
| 25 |
-
"include": [
|
| 26 |
-
"next-env.d.ts",
|
| 27 |
-
"**/*.ts",
|
| 28 |
-
"**/*.tsx",
|
| 29 |
-
".next/types/**/*.ts",
|
| 30 |
-
".next/dev/types/**/*.ts",
|
| 31 |
-
"**/*.mts"
|
| 32 |
-
],
|
| 33 |
-
"exclude": ["node_modules"]
|
| 34 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|