cleanup: remove unused reference folders and untracked scratch directories
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m1s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m1s
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
# GEMINI_API_KEY: Required for Gemini AI API calls.
|
||||
# AI Studio automatically injects this at runtime from user secrets.
|
||||
# Users configure this via the Secrets panel in the AI Studio UI.
|
||||
GEMINI_API_KEY="MY_GEMINI_API_KEY"
|
||||
|
||||
# APP_URL: The URL where this applet is hosted.
|
||||
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
||||
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
||||
APP_URL="MY_APP_URL"
|
||||
8
architectural-grid1/.gitignore
vendored
8
architectural-grid1/.gitignore
vendored
@@ -1,8 +0,0 @@
|
||||
node_modules/
|
||||
build/
|
||||
dist/
|
||||
coverage/
|
||||
.DS_Store
|
||||
*.log
|
||||
.env*
|
||||
!.env.example
|
||||
@@ -1,20 +0,0 @@
|
||||
<div align="center">
|
||||
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
|
||||
</div>
|
||||
|
||||
# Run and deploy your AI Studio app
|
||||
|
||||
This contains everything you need to run your app locally.
|
||||
|
||||
View your app in AI Studio: https://ai.studio/apps/b7b577c6-4d9f-44ac-8fe1-85bc3c6d6e66
|
||||
|
||||
## Run Locally
|
||||
|
||||
**Prerequisites:** Node.js
|
||||
|
||||
|
||||
1. Install dependencies:
|
||||
`npm install`
|
||||
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
|
||||
3. Run the app:
|
||||
`npm run dev`
|
||||
@@ -1,13 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>My Google AI Studio App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "Architectural Grid",
|
||||
"description": "A minimalist notebook for architectural research and conceptual sketches.",
|
||||
"requestFramePermissions": [],
|
||||
"majorCapabilities": []
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"name": "react-example",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.29.0",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"lucide-react": "^0.546.0",
|
||||
"react": "^19.0.1",
|
||||
"react-dom": "^19.0.1",
|
||||
"vite": "^6.2.3",
|
||||
"express": "^4.21.2",
|
||||
"dotenv": "^17.2.3",
|
||||
"motion": "^12.23.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.14.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "~5.8.2",
|
||||
"vite": "^6.2.3",
|
||||
"@types/express": "^4.17.21"
|
||||
}
|
||||
}
|
||||
@@ -1,408 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import {
|
||||
Plus,
|
||||
Search,
|
||||
Share2,
|
||||
Archive,
|
||||
Settings,
|
||||
Lock,
|
||||
ChevronRight,
|
||||
MoreVertical,
|
||||
ArrowLeft
|
||||
} from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
|
||||
// --- Types ---
|
||||
|
||||
interface Note {
|
||||
id: string;
|
||||
carnetId: string;
|
||||
title: string;
|
||||
content: string;
|
||||
imageUrl: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
interface Carnet {
|
||||
id: string;
|
||||
name: string;
|
||||
initial: string;
|
||||
type: 'Private' | 'Project' | 'Shared';
|
||||
isPrivate?: boolean;
|
||||
}
|
||||
|
||||
// --- Mock Data ---
|
||||
|
||||
const CARNETS: Carnet[] = [
|
||||
{ id: '1', name: 'Daily Notes', initial: 'D', type: 'Private', isPrivate: true },
|
||||
{ id: '2', name: 'Project: Neo', initial: 'P', type: 'Project' },
|
||||
{ id: '3', name: 'Shared Docs', initial: 'S', type: 'Shared' },
|
||||
{ id: '4', name: 'Architecture Research', initial: 'A', type: 'Project' },
|
||||
];
|
||||
|
||||
const ALL_NOTES: Note[] = [
|
||||
{
|
||||
id: 'n1',
|
||||
carnetId: '4',
|
||||
title: 'Grid Systems',
|
||||
date: 'Oct 26, 2024',
|
||||
content: 'Grid Systems is streathen in ognitiacs clesign and simulhere desipmalt: complded structurer and manamateriai-s: ci arevenuatingly used, asiller straterty of insaee to the tmn and usaes of disrension, architecture of emiornabious tracious structures.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1503387762-592dea58ef23?auto=format&fit=crop&q=80&w=800&h=600'
|
||||
},
|
||||
{
|
||||
id: 'n2',
|
||||
carnetId: '4',
|
||||
title: 'Materiality',
|
||||
date: 'Oct 24, 2024',
|
||||
content: 'Materiality is combinated by relliaitic structureirs measure of plastics, natural, materials and priotical structures. Materialed coasts erabiocera alann light spaces and octicm employed design on thodolen of materiality, and tohlite tersev/ used in the gridin structures en obain materials, coms pathetic structure.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?auto=format&fit=crop&q=80&w=800&h=600'
|
||||
},
|
||||
{
|
||||
id: 'n3',
|
||||
carnetId: '4',
|
||||
title: 'Light & Space',
|
||||
date: 'Oct 22, 2024',
|
||||
content: 'Light & Space is a creaivity of light & Space inralicated in sizazant or dark crotrcning and netrescenations of avant trurme sivonpaltures for in inncr-en allimativefiting is cerriadating and sityle.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&q=80&w=800&h=600'
|
||||
},
|
||||
{
|
||||
id: 'n4',
|
||||
carnetId: '2',
|
||||
title: 'Neo-Brutalism study',
|
||||
date: 'Sep 12, 2024',
|
||||
content: 'Exploring the raw aesthetic of neo-brutalism in urban environments. Focus on concrete textures and massive forms.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1518005020951-eccb494ad742?auto=format&fit=crop&q=80&w=800&h=600'
|
||||
}
|
||||
];
|
||||
|
||||
// --- Components ---
|
||||
|
||||
interface NoteLinkProps {
|
||||
note: Note;
|
||||
isActive: boolean;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
const NoteLink: React.FC<NoteLinkProps> = ({ note, isActive, onClick }) => (
|
||||
<motion.button
|
||||
initial={{ opacity: 0, x: -10 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
onClick={onClick}
|
||||
className={`w-full flex items-center gap-2 pl-12 pr-4 py-2 text-[12px] transition-colors rounded-lg
|
||||
${isActive ? 'bg-white/50 text-ink font-medium' : 'text-muted-ink hover:text-ink hover:bg-white/30'}`}
|
||||
>
|
||||
<div className={`w-1.5 h-1.5 rounded-full ${isActive ? 'bg-ink' : 'bg-transparent border border-muted-ink/30'}`} />
|
||||
<span className="truncate">{note.title}</span>
|
||||
</motion.button>
|
||||
);
|
||||
|
||||
interface SidebarItemProps {
|
||||
carnet: Carnet;
|
||||
isActive: boolean;
|
||||
notes: Note[];
|
||||
activeNoteId: string | null;
|
||||
onCarnetClick: () => void;
|
||||
onNoteClick: (noteId: string) => void;
|
||||
}
|
||||
|
||||
const SidebarItem: React.FC<SidebarItemProps> = ({
|
||||
carnet,
|
||||
isActive,
|
||||
notes,
|
||||
activeNoteId,
|
||||
onCarnetClick,
|
||||
onNoteClick
|
||||
}) => {
|
||||
const [isExpanded, setIsExpanded] = useState(isActive);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isActive) setIsExpanded(true);
|
||||
}, [isActive]);
|
||||
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<motion.button
|
||||
whileHover={{ x: 4 }}
|
||||
onClick={() => {
|
||||
onCarnetClick();
|
||||
setIsExpanded(!isExpanded);
|
||||
}}
|
||||
className={`w-full flex items-center gap-3 px-4 py-3 rounded-xl transition-all duration-300 group
|
||||
${isActive ? 'active-nav-item' : 'hover:bg-white/40'}`}
|
||||
>
|
||||
<motion.div
|
||||
animate={{ rotate: isExpanded ? 90 : 0 }}
|
||||
className="text-muted-ink"
|
||||
>
|
||||
<ChevronRight size={14} />
|
||||
</motion.div>
|
||||
<div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium border
|
||||
${isActive ? 'bg-ink text-paper border-ink' : 'bg-white/60 text-ink border-border'}`}>
|
||||
{carnet.initial}
|
||||
</div>
|
||||
<div className="flex-1 text-left">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`text-[13px] font-medium transition-colors ${isActive ? 'text-ink' : 'text-muted-ink'}`}>
|
||||
{carnet.name}
|
||||
</span>
|
||||
{carnet.isPrivate && <Lock size={10} className="text-muted-ink" />}
|
||||
</div>
|
||||
</div>
|
||||
</motion.button>
|
||||
|
||||
<AnimatePresence>
|
||||
{isExpanded && (
|
||||
<motion.div
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: 'auto', opacity: 1 }}
|
||||
exit={{ height: 0, opacity: 0 }}
|
||||
className="overflow-hidden space-y-0.5"
|
||||
>
|
||||
{notes.map(note => (
|
||||
<NoteLink
|
||||
key={note.id}
|
||||
note={note}
|
||||
isActive={activeNoteId === note.id}
|
||||
onClick={() => onNoteClick(note.id)}
|
||||
/>
|
||||
))}
|
||||
{notes.length === 0 && (
|
||||
<p className="pl-12 text-[11px] text-muted-ink/50 py-2 italic font-light">No notes yet</p>
|
||||
)}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const [activeCarnetId, setActiveCarnetId] = useState('4');
|
||||
const [activeNoteId, setActiveNoteId] = useState<string | null>(null);
|
||||
|
||||
const filteredNotes = useMemo(() =>
|
||||
ALL_NOTES.filter(n => n.carnetId === activeCarnetId),
|
||||
[activeCarnetId]);
|
||||
|
||||
const activeNote = useMemo(() =>
|
||||
ALL_NOTES.find(n => n.id === activeNoteId),
|
||||
[activeNoteId]);
|
||||
|
||||
const activeCarnet = useMemo(() =>
|
||||
CARNETS.find(c => c.id === activeCarnetId),
|
||||
[activeCarnetId]);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center p-4 md:p-8 lg:p-12 overflow-hidden">
|
||||
<div className="absolute inset-0 z-0 bg-[#DEDEDE]" />
|
||||
|
||||
<div className="relative w-full max-w-7xl h-[85vh] flex rounded-2xl overflow-hidden shadow-2xl sidebar-shadow bg-paper">
|
||||
<div className="absolute -right-4 -bottom-4 w-full h-full bg-white/40 rounded-2xl -z-10 translate-x-2 translate-y-2 opacity-50" />
|
||||
<div className="absolute -right-2 -bottom-2 w-full h-full bg-white/60 rounded-2xl -z-10 translate-x-1 translate-y-1 opacity-70" />
|
||||
|
||||
<aside className="w-80 bg-white/30 backdrop-blur-md border-right border-border p-6 flex flex-col z-20 shrink-0">
|
||||
<div className="mb-10">
|
||||
<div className="w-10 h-10 rounded-full bg-slate-200 border border-border flex items-center justify-center text-ink font-serif text-lg shadow-sm">
|
||||
A
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto space-y-6 -mx-2 px-2 custom-scrollbar">
|
||||
<div>
|
||||
<p className="text-[10px] font-bold text-muted-ink tracking-widest uppercase mb-4 px-4">
|
||||
Architecture Grid
|
||||
</p>
|
||||
<div className="space-y-1">
|
||||
{CARNETS.map(carnet => (
|
||||
<SidebarItem
|
||||
key={carnet.id}
|
||||
carnet={carnet}
|
||||
isActive={activeCarnetId === carnet.id}
|
||||
notes={ALL_NOTES.filter(n => n.carnetId === carnet.id)}
|
||||
activeNoteId={activeNoteId}
|
||||
onCarnetClick={() => {
|
||||
setActiveCarnetId(carnet.id);
|
||||
setActiveNoteId(null);
|
||||
}}
|
||||
onNoteClick={(id) => {
|
||||
setActiveCarnetId(carnet.id);
|
||||
setActiveNoteId(id);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button className="w-full mt-4 flex items-center gap-3 px-4 py-2 text-[13px] text-muted-ink hover:text-ink transition-colors font-medium">
|
||||
<Plus size={16} />
|
||||
<span>New Carnet</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-6 border-t border-border space-y-4">
|
||||
<button className="flex items-center gap-3 px-4 text-[13px] text-muted-ink hover:text-ink transition-colors font-medium">
|
||||
<Archive size={16} />
|
||||
<span>Archive</span>
|
||||
</button>
|
||||
<button className="flex items-center gap-3 px-4 text-[13px] text-muted-ink hover:text-ink transition-colors font-medium">
|
||||
<Settings size={16} />
|
||||
<span>Settings</span>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main className="flex-1 paper-texture relative overflow-hidden z-10 flex flex-col h-full">
|
||||
<AnimatePresence mode="wait">
|
||||
{!activeNoteId ? (
|
||||
<motion.div
|
||||
key="notebook"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="h-full flex flex-col overflow-y-auto"
|
||||
>
|
||||
<header className="px-12 pt-12 pb-8 flex flex-col gap-6 sticky top-0 bg-paper/80 backdrop-blur-md z-30">
|
||||
<div className="flex justify-between items-start">
|
||||
<h1 className="text-4xl font-serif font-medium tracking-tight text-ink leading-tight pr-12">
|
||||
{activeCarnet?.name} — {filteredNotes[0]?.date || 'Oct 26'}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between border-b border-ink/5 pb-4">
|
||||
<div className="flex items-center gap-6">
|
||||
<button className="flex items-center gap-2 text-[13px] text-ink font-medium hover:opacity-70 transition-opacity">
|
||||
<Plus size={16} />
|
||||
<span>Add Note</span>
|
||||
</button>
|
||||
<button className="flex items-center gap-2 text-[13px] text-ink font-medium hover:opacity-70 transition-opacity">
|
||||
<Search size={16} />
|
||||
<span>Search</span>
|
||||
</button>
|
||||
</div>
|
||||
<button className="flex items-center gap-2 text-[13px] text-ink font-medium hover:opacity-70 transition-opacity">
|
||||
<Share2 size={16} />
|
||||
<span>Share</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="px-12 flex-1 pb-20">
|
||||
<div className="max-w-3xl space-y-16">
|
||||
{filteredNotes.map((note, index) => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.1 * index, duration: 0.8 }}
|
||||
key={note.id}
|
||||
className="space-y-4 group cursor-pointer"
|
||||
onClick={() => setActiveNoteId(note.id)}
|
||||
>
|
||||
<h2 className="text-2xl font-serif font-medium text-ink flex items-center justify-between">
|
||||
{note.title}
|
||||
<button className="opacity-0 group-hover:opacity-40 transition-opacity">
|
||||
<ChevronRight size={20} />
|
||||
</button>
|
||||
</h2>
|
||||
<div className="flex flex-col md:flex-row gap-8 items-start">
|
||||
<div className="w-full md:w-56 aspect-[4/3] bg-white/50 border border-border overflow-hidden rounded shadow-sm flex-shrink-0">
|
||||
<img
|
||||
src={note.imageUrl}
|
||||
alt={note.title}
|
||||
className="w-full h-full object-cover mix-blend-multiply opacity-80 grayscale contrast-125 hover:grayscale-0 hover:opacity-100 transition-all duration-500"
|
||||
referrerPolicy="no-referrer"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-[14px] leading-relaxed text-ink/80 font-light max-w-lg line-clamp-4">
|
||||
{note.content}
|
||||
</p>
|
||||
<span className="text-[11px] text-muted-ink uppercase tracking-widest font-medium">Read more</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer className="px-12 py-6 border-t border-ink/5 text-center mt-auto">
|
||||
<p className="text-[11px] text-muted-ink uppercase tracking-[0.2em] font-medium">
|
||||
© 2024 Architectural Grid. All rights reserved.
|
||||
</p>
|
||||
</footer>
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="focused-note"
|
||||
initial={{ opacity: 0, scale: 0.98 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 1.02 }}
|
||||
className="h-full flex flex-col overflow-y-auto bg-white"
|
||||
>
|
||||
<div className="flex-1 flex flex-col">
|
||||
<div className="px-12 py-8 flex items-center justify-between sticky top-0 bg-white/90 backdrop-blur-sm z-40 border-b border-border">
|
||||
<button
|
||||
onClick={() => setActiveNoteId(null)}
|
||||
className="flex items-center gap-2 text-ink hover:opacity-60 transition-opacity"
|
||||
>
|
||||
<ArrowLeft size={18} />
|
||||
<span className="text-sm font-medium">Back to collection</span>
|
||||
</button>
|
||||
<div className="flex items-center gap-4">
|
||||
<button className="p-2 text-muted-ink hover:text-ink transition-colors">
|
||||
<Share2 size={18} />
|
||||
</button>
|
||||
<button className="p-2 text-muted-ink hover:text-ink transition-colors">
|
||||
<MoreVertical size={18} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-4xl mx-auto w-full px-12 py-16 space-y-12">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3 text-[12px] text-muted-ink uppercase tracking-[.25em] font-bold">
|
||||
<span>{activeCarnet?.name}</span>
|
||||
<ChevronRight size={10} />
|
||||
<span>{activeNote?.date}</span>
|
||||
</div>
|
||||
<h1 className="text-5xl md:text-6xl font-serif font-bold text-ink leading-tight">
|
||||
{activeNote?.title}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="aspect-[16/9] w-full bg-slate-100 rounded-xl overflow-hidden shadow-xl">
|
||||
<img
|
||||
src={activeNote?.imageUrl}
|
||||
alt={activeNote?.title}
|
||||
className="w-full h-full object-cover grayscale contrast-110"
|
||||
referrerPolicy="no-referrer"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="max-w-2xl mx-auto space-y-8 pb-32">
|
||||
<p className="text-xl md:text-2xl font-serif leading-relaxed text-ink italic">
|
||||
{activeNote?.content.split('.')[0]}.
|
||||
</p>
|
||||
<div className="h-px bg-border w-32" />
|
||||
<p className="text-lg leading-relaxed text-ink/80 font-light space-y-4 text-justify">
|
||||
{activeNote?.content}
|
||||
<br /><br />
|
||||
Architectural grids serve as the invisible scaffolding upon which spatial experiences are constructed. Beyond mere structural repetition, they facilitate a rhythmic dialogue between materiality and void. In this exploration, we examine how light fractures these rigid boundaries, creating a dynamic interplay that evolves with the passage of time.
|
||||
<br /><br />
|
||||
The integration of sustainable materials directly into the primary grid allows for a cohesive aesthetic that doesn't compromise on environmental performance. As we transition toward more modular designs, the grid becomes not just a tool for measurement, but a language for expression.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=JetBrains+Mono:wght@400;500&display=swap');
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-serif: "Playfair Display", serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;
|
||||
|
||||
--color-paper: #F2F0E9;
|
||||
--color-ink: #1C1C1C;
|
||||
--color-muted-ink: rgba(28, 28, 28, 0.6);
|
||||
--color-border: rgba(28, 28, 28, 0.1);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply bg-[#E5E2D9] text-ink font-sans antialiased;
|
||||
}
|
||||
}
|
||||
|
||||
.paper-texture {
|
||||
background-color: var(--color-paper);
|
||||
background-image: url("https://www.transparenttextures.com/patterns/natural-paper.png");
|
||||
}
|
||||
|
||||
.sidebar-shadow {
|
||||
box-shadow: 1px 0 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.active-nav-item {
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4));
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
);
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"DOM",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import path from 'path';
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
|
||||
export default defineConfig(({mode}) => {
|
||||
const env = loadEnv(mode, '.', '');
|
||||
return {
|
||||
plugins: [react(), tailwindcss()],
|
||||
define: {
|
||||
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '.'),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||
hmr: process.env.DISABLE_HMR !== 'true',
|
||||
},
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user