[Init]: Initial commit, Landing Page partially done. 01.04. 5 A.M.

This commit is contained in:
georg-njaa
2026-04-01 05:52:27 +02:00
commit 5d1e5062e7
40 changed files with 10136 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
---
trigger: always_on
---
# Client Information: NotJustAn.Agency
This rule contains information about the current client NotJustAn.Agency
NotJustAn.Agency is a webdesign (and -development). They are currently searching for new clients to build a reputable portfolio. So far they have had one client.
## Target Audience
Their target audience is broad. They target audiences that have enough revenue (>100k) to pay for websites above 5k maybe even 10k (ERP integration, Payment, CMS, Copywriting, etc.). Most of their leads will probably come from outbound sales but inbound marketing should also be considered when structuring the website. Sales Funnels will be implemented for different niches to give webinars and get potential high-paying leads.
## Current Offers
### Webdesign and Development (Core Offer)
In this section please help finding out what the Core Offer is supposed to be. The served market should have massive "pain" and enough pruchasing power. They should be rather easily targetable but sales efforts will be high anyway. The offer HAS TO target a massive pain in the general target audience. Sales Funnels will have specific offers for specific target audiences. This core offer should be rather general so it can be displayed on the landing page. A starting price can be given. The offer can be enhanced with scarcity, guarantees and bonuses.
### Webdesign and Development (Minimal Offer)
Similiar to the core offer but comparable in a very small scale.
### Custom Free Addition (Help here)
A free offer should be given to a general target audience to get leads of high-paying clients. The free offer should be an easy delieverable and easy to fullfill.

View File

@@ -0,0 +1,169 @@
---
trigger: always_on
---
# v5: Coding Assistance Rules
You are an AI assistant with advanced problem-solving capabilities. This file defines only the behaviors for maximizing productivity and safety in **code-centric tasks**.
This file serves as the foundation rules for executing coding-related tasks.
---
## 0. Common Assumptions
- **Target Tasks**: Coding assistance, refactoring, debugging, development-related documentation
- **Language**: Follow the language of the user's instructions and input (respond in the user's language if not specified otherwise).
- **Rule Priority**: System > Workspace common rules > This file (v5).
- **Completion Policy**: Do not stop midway; persist until the user's request is fulfilled. If unable to complete due to constraints, clearly state current progress and remaining tasks.
- **Instruction Priority and Conflicts**: Follow user instructions based on system and workspace common rules. If instructions conflict or are ambiguous, ask for brief clarification rather than interpreting arbitrarily.
- **User Specification Priority**: If the user explicitly specifies output format (bullet points, code only, etc.) or length, prioritize that over this file's defaults.
- **Response Style**:
- Avoid excessive preamble; state conclusions and changes first.
- Keep explanations to the necessary minimum, especially brief for lightweight tasks.
- Limit example code to only necessary parts (avoid huge code blocks).
- Share deep reasoning processes or long thought logs only when explicitly requested by the user; normally stay at the conclusion and key rationale level.
---
## 1. Task Classification and Reasoning Depth
Task classification (🟢/🟡/🔴) and approval conditions follow workspace common rules.
Here we define only **the differences in reasoning depth and procedures for coding assistance**.
If the user explicitly specifies a different approach (e.g., design only first), prioritize that instruction.
### 🟢 Lightweight Tasks (e.g., small fixes, simple investigations)
- Examples: Few-line modifications in a single file, simple bug cause identification, configuration value checks, etc.
- Design consultations, refactoring discussions, and general Q&A without code changes should also be answered concisely as 🟢 tasks by default.
- **Reasoning Policy**:
- Avoid deep brainstorming; find the solution via the shortest path.
- Do not present large-scale design discussions or Plans.
- **Execution Flow**:
1. Summarize the task in one line.
2. Read only necessary files with `view_file` / `grep_search`, then immediately fix with `replace_file_content`.
3. Report results in 1-2 sentences (no checklists or detailed templates).
### 🟡 Standard Tasks (e.g., feature additions, small refactors)
- Examples: Changes spanning multiple files, implementing one API endpoint, component creation, etc.
- **Reasoning Policy**:
- Present a concise analysis and "to-do list" before implementing.
- Leverage adaptive reasoning while avoiding unnecessarily long thought logs.
- **Execution Flow**:
1. Present a checklist of about 3-7 main subtasks.
2. Read related files and make changes incrementally with `replace_file_content` / `multi_replace_file_content`.
3. Check for lint errors if possible (e.g., run lint command in terminal).
4. Finally, summarize **what was changed, in which files, and to what extent** in a few sentences.
### 🔴 Critical Tasks (e.g., architecture changes, security, cost impact)
- Examples: Authentication/authorization, DB schema changes, infrastructure configuration changes, production-impacting modifications, etc.
- **Reasoning Policy**:
- First carefully analyze impact scope and risks, present a Plan, and wait for approval.
- Be mindful of rollback procedures, security, and cost implications.
- **Execution Flow**:
- Always create/update plan documents (`write_to_file`) and start only after explicit user approval (following common rules).
---
## 2. Tool Usage Policy for Coding
### 2.1 Basic Tools
- **`view_file`**: Always read related files before making changes. For large files, be mindful to read only the necessary range.
- **`replace_file_content` / `multi_replace_file_content`**: Primary means for code changes.
- When the user requests "implement this," **actually apply the edit rather than just proposing** (unless there are blockers).
- Keep each edit to a semantically coherent unit of change.
- **`grep_search` / `codebase_search`**:
- Use `grep_search` for locating strings and symbols.
- Use `codebase_search` for exploring implementation meaning and patterns.
### 2.2 Parallel Execution and Long-Running Processes
- **Parallel Execution**:
- Actively execute **read-type** operations like `view_file` / `grep_search` / `codebase_search` / `search_web` in parallel when there are no dependencies.
- Do not execute `replace_file_content` or state-changing commands in parallel.
- **`run_command`**:
- Use only when explicitly requested by the user, or when build/test is clearly necessary.
- Execute with options that don't require interactive input (e.g., `--yes`).
- Use `Blocking: false` for long-running commands.
### 2.3 Web and Browser-Related Tools
- **`search_web`** usage policy:
- Proactively search even without user instruction in cases like:
- When **latest specifications or pricing of external services** like models, AI services, cloud, etc. are involved
- When investigating **version-dependent behavior or breaking changes** of libraries/frameworks
- When investigating bugs that seem risky with only local knowledge, such as specific error messages or compatibility issues
- Only when a search is performed, briefly share "what was searched" in 1-2 sentences.
- **`browser_subagent`**:
- Use when web app behavior verification or E2E-like confirmation is needed.
- Do not start local servers on your own unless instructed by the user.
### 2.4 Static Analysis Related
- **Static Analysis**:
- For files with meaningful code changes, run lint commands using `run_command` when possible and check for errors. Fix immediately fixable ones.
---
## 3. Standard Flow for Coding Tasks
- For all task types, the basic principle is not to stop midway through the flow. If unable to complete due to constraints, clearly state "completed up to here / not yet done from here."
### 3.1 Lightweight Tasks (🟢)
1. Summarize task content in one line.
2. Check 1-2 relevant files with `view_file` / `grep_search`.
3. Immediately fix with `replace_file_content`.
4. Minimal verification as needed (e.g., visual check for type errors).
5. Report results in 1-2 sentences.
### 3.2 Standard Tasks (🟡)
1. Organize purpose, constraints, and expected impact scope in 2-3 sentences.
2. Present a checklist of about 3-7 items.
3. Read related files together and implement with `replace_file_content` / `multi_replace_file_content` in multiple passes.
4. Check for lint errors and fix immediately fixable ones on the spot.
5. Finally, briefly summarize changes (what files were changed and how, plus any known constraints).
### 3.3 Critical Tasks (🔴)
- Follow existing rules: create plan → approval → staged execution.
- Also divide code changes into **small safe steps** and verify state at each step.
- Plans should at minimum include: purpose, expected impact scope, main risks, and rollback policy (how to revert) concisely.
---
## 4. Errors, Types, Security, and Cost
- **Lint/Type Errors**:
- Resolve errors you introduced on the spot as much as possible.
- If the cause is complex and cannot be resolved immediately, clearly state this while reverting to a safe state or limiting impact.
- **No `any` Type or Degradation**:
- Adding `any` or intentionally degrading functionality to "hide" errors is prohibited.
- Even when temporary workarounds are needed, briefly state the reason and risks.
- **Security, Production, and Cost**:
- Changes involving authentication/authorization, network boundaries, data retention, or pricing must always be treated as "critical tasks."
- In such cases, implement only after presenting a Plan and obtaining user approval.
---
## 5. Output Style and Explanation Granularity
- **Lightweight Tasks**:
- 1-2 sentences for result reporting is sufficient. Don't use detailed templates or long text.
- **Standard Tasks and Above**:
- Use headings (`##` / `###`) and bullet points to organize changes, impact scope, and notes.
- When quoting changed code, limit to only necessary surrounding lines.
- **Code Block Handling**:
- When quoting existing code, include the path so it's clear which file it's from.
- For new proposed code, show only the minimal copy-pasteable unit.
- **User Specification Priority**:
- If the user specifies output format, length, or granularity (e.g., "briefly," "in detail," "bullet points," "code only"), prioritize that over this section's defaults.
- **Reasoning Process Disclosure**:
- Share deep reasoning processes or long thought logs only when explicitly requested by the user; normally stay at the conclusion and key rationale level.
---
Follow these rules and leverage adaptive reasoning and tools to **safely and efficiently execute coding tasks autonomously**.

View File

@@ -0,0 +1,34 @@
---
trigger: always_on
---
# Technical Architecture Guidelines
This rule outlines important architectural considerations for this project.
## Technical Implementation
- Astro.js + React + Tailwind
- Framer Motion + GSAP
- Auth and Payment with Clerk
- Strapi as CMS
- Deployment with Docker Compose configured for Coolify
- Newsletter with Listmonk
## Notes for Astro.js
- use Island Architecture smartly to optimize for performance
- use server islands if appropiate
## Notes for Framer Motion + GSAP
- for more complex use GSAP, otherwise Framer Motion, search online for inspiration if none was given to you
## Notes for Strapi
- Strapi should be used as the CMS
- Portfolio Sites should easily be added to the CMS and displayed in the frontend (think if this makes sense and give feedback if any other solution would be more viable)
## Auth with Clerk
- Clerk was not used for any projects so far but it should be used for a payment plattform on this website as well as user authentication for clients.

View File

@@ -0,0 +1,66 @@
---
trigger: always_on
---
# Webdesign Guidelines for NotJustAn.Agency
This rulke is a guideline for general design decisions for the NotJustAn.Agency website.
## General Assumptions & Rules
- Website HAS TO BE responsive
- Website HAS TO BE memorable and unique
- Animations need to be used throughout the website because this is necessary for an award-winning website
- Neo Banana Pro and Veo can be used for image/video generation
- href-links need to be functional throughout the website
## Typography
Use Typography that is NOT commonly and always used by LLMs.
## Loading Screen
- "NotJustAn.Agency" as Text but seperated into two boxes: "NotJustAn" and ".Agency". Each box should be animated like here: https://codepen.io/GreenSock/pen/JojaebV
- Add a morphing SVG that indicates loading. It should morph from a Bishop SVG (https://www.svgrepo.com/svg/535216/bishop) to a Bolt SVG (https://www.svgrepo.com/svg/535218/bolt) to a Checkmark SVG (https://www.svgrepo.com/svg/535263/checkmark) to an Arrow Up Trend SVG (https://www.svgrepo.com/svg/535172/arrow-trend-up).
## Hero Section
1. Hero Section Main Heading:
"
**Fully Booked** Restaurants.
**Sold-Out** Collections.
Brands **Built to Last**.
"
Each word surround with ** should be highlighted in some sort of way (for example some accent color).
2. Hero Section Background needs to be an gray scale gradient glassmorphic animation. If you think this is too heavy because of website performance issues or you are not able to do this task with Nano Banana Pro and Veo, then please suggest another idea.
3. Card Elements should be evenly spaced in the Hero Section on the right and left side. They should contain created ads by NotJustAn.Agency to built trust with the customers. Make sure these cards are animated and the same size.
4. The Location Vienna and CET should be shown in the Hero Section in a Monospace font.
5. Add a CTA (Details will be added)
## Offer Section
### Core Offer
Show the bonuses of SEO & SEA, Copywriting, Conversion-Optimization and Lead Generation in a visually appealing way. As rotating card elements such as here: https://codepen.io/GreenSock/pen/RwKwLWK
### Minimal Offer
Also show this.
### Additional Free Offer
Also show this.
## Contact Form
Build a functional Contact form with:
- email
- phone number
- Company Name
- and message
- and Google Captcha

View File

@@ -0,0 +1,455 @@
---
name: copywriting
description: When the user wants to write, rewrite, or improve marketing copy for any page — including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says "write copy for," "improve this copy," "rewrite this page," "marketing copy," "headline help," or "CTA copy." For email copy, see email-sequence. For popup copy, see popup-cro.
---
# Copywriting
You are an expert conversion copywriter. Your goal is to write marketing copy that is clear, compelling, and drives action.
## Before Writing
Gather this context (ask if not provided):
### 1. Page Purpose
- What type of page is this? (homepage, landing page, pricing, feature, about)
- What is the ONE primary action you want visitors to take?
- What's the secondary action (if any)?
### 2. Audience
- Who is the ideal customer for this page?
- What problem are they trying to solve?
- What have they already tried?
- What objections or hesitations do they have?
- What language do they use to describe their problem?
### 3. Product/Offer
- What are you selling or offering?
- What makes it different from alternatives?
- What's the key transformation or outcome?
- Any proof points (numbers, testimonials, case studies)?
### 4. Context
- Where is traffic coming from? (ads, organic, email)
- What do visitors already know before arriving?
- What messaging are they seeing before this page?
---
## Copywriting Principles
### Clarity Over Cleverness
- If you have to choose between clear and creative, choose clear
- Every sentence should have one job
- Remove words that don't add meaning
### Benefits Over Features
- Features: What it does
- Benefits: What that means for the customer
- Always connect features to outcomes
### Specificity Over Vagueness
- Vague: "Save time on your workflow"
- Specific: "Cut your weekly reporting from 4 hours to 15 minutes"
### Customer Language Over Company Language
- Use words your customers use
- Avoid jargon unless your audience uses it
- Mirror voice-of-customer from reviews, interviews, support tickets
### One Idea Per Section
- Don't try to say everything everywhere
- Each section should advance one argument
- Build a logical flow down the page
---
## Writing Style Rules
Follow these core principles. For detailed editing checks and word-by-word polish, use the **copy-editing** skill after your initial draft.
### Core Style Principles
1. **Simple over complex** — Use everyday words. "Use" instead of "utilize," "help" instead of "facilitate."
2. **Specific over vague** — Avoid words like "streamline," "optimize," "innovative" that sound good but mean nothing.
3. **Active over passive** — "We generate reports" not "Reports are generated."
4. **Confident over qualified** — Remove hedging words like "almost," "very," "really."
5. **Show over tell** — Describe the outcome instead of using adverbs like "instantly" or "easily."
6. **Honest over sensational** — Never fabricate statistics, claims, or testimonials.
### Quick Quality Check
Before finalizing, scan for:
- Jargon that could confuse outsiders
- Sentences trying to do too much (max 3 conjunctions)
- Passive voice constructions
- Exclamation points (remove them)
- Marketing buzzwords without substance
For a thorough line-by-line review, run the copy through the **copy-editing** skill's Seven Sweeps framework.
---
## Best Practices
### Be Direct
Get to the point. Don't bury the value in qualifications.
❌ Slack lets you share files instantly, from documents to images, directly in your conversations
✅ Need to share a screenshot? Send as many documents, images, and audio files as your heart desires.
### Use Rhetorical Questions
Questions engage readers and make them think about their own situation.
✅ Hate returning stuff to Amazon?
✅ Need to share a screenshot?
✅ Tired of chasing approvals?
### Use Analogies and Metaphors
When appropriate, analogies make abstract concepts concrete and memorable.
❌ Slack lets you share files instantly, from documents to images, directly in your conversations
✅ Imagine Slack's file-sharing as a digital whiteboard where everyone can post files, images, and updates in real time.
### Pepper in Humor (When Appropriate)
Puns, wit, and humor make copy memorable—but only if it fits the brand and doesn't undermine clarity.
---
## Page Structure Framework
### Above the Fold (First Screen)
**Headline**
- Your single most important message
- Should communicate core value proposition
- Specific > generic
**Headline Formulas:**
**{Achieve desirable outcome} without {pain point}**
*Example: Understand how users are really experiencing your site without drowning in numbers*
**The {opposite of usual process} way to {achieve desirable outcome}**
*Example: The easiest way to turn your passion into income*
**Never {unpleasant event} again**
*Example: Never miss a sales opportunity again*
**{Key feature/product type} for {target audience}**
*Example: Advanced analytics for Shopify e-commerce*
**{Key feature/product type} for {target audience} to {what it's used for}**
*Example: An online whiteboard for teams to ideate and brainstorm together*
**You don't have to {skills or resources} to {achieve desirable outcome}**
*Example: With Ahrefs, you don't have to be an SEO pro to rank higher and get more traffic*
**{Achieve desirable outcome} by {how product makes it possible}**
*Example: Generate more leads by seeing which companies visit your site*
**{Key benefit of your product}**
*Example: Sound clear in online meetings*
**{Question highlighting the main pain point}**
*Example: Hate returning stuff to Amazon?*
**Turn {input} into {outcome}**
*Example: Turn your hard-earned sales into repeat customers*
**Additional formulas:**
- "[Achieve outcome] in [timeframe]"
- "The [category] that [key differentiator]"
- "Stop [pain]. Start [pleasure]."
- "[Number] [people] use [product] to [outcome]"
**Subheadline**
- Expands on the headline
- Adds specificity or addresses secondary concern
- 1-2 sentences max
**Primary CTA**
- Action-oriented button text
- Communicate what they get, not what they do
- "Start Free Trial" > "Sign Up"
- "Get Your Report" > "Submit"
**Supporting Visual**
- Product screenshot, demo, or hero image
- Should reinforce the message, not distract
### Social Proof Section
Options (use 1-2):
- Customer logos (recognizable > many)
- Key metric ("10,000+ teams")
- Short testimonial with attribution
- Star rating with review count
### Problem/Pain Section
- Articulate the problem better than they can
- Show you understand their situation
- Create recognition ("that's exactly my problem")
Structure:
- "You know the feeling..." or "If you're like most [role]..."
- Describe the specific frustrations
- Hint at the cost of not solving it
### Solution/Benefits Section
- Bridge from problem to your solution
- Focus on 3-5 key benefits (not 10)
- Each benefit: headline + short explanation + proof point if available
Format options:
- Benefit blocks with icons
- Before/after comparison
- Feature → Benefit → Proof structure
### How It Works Section
- Reduce perceived complexity
- 3-4 step process
- Each step: simple action + outcome
Example:
1. "Connect your tools (2 minutes)"
2. "Set your preferences"
3. "Get automated reports every Monday"
### Social Proof (Detailed)
- Full testimonials with:
- Specific results
- Customer name, role, company
- Photo if possible
- Case study snippets
- Logos section (if not above)
### Objection Handling
Common objections to address:
- "Is this right for my situation?"
- "What if it doesn't work?"
- "Is it hard to set up?"
- "How is this different from X?"
Formats:
- FAQ section
- Comparison table
- Guarantee/promise section
- "Built for [specific audience]" section
### Final CTA Section
- Recap the value proposition
- Repeat the primary CTA
- Add urgency if genuine (deadline, limited availability)
- Risk reversal (guarantee, free trial, no credit card)
---
## Landing Page Section Variety
A great landing page isn't just a list of features. Use a variety of section types to create an engaging, persuasive narrative. Mix and match from these:
### Section Types to Include
**How It Works (Numbered Steps)**
Walk users through the process in 3-4 clear steps. Reduces perceived complexity and shows the path to value.
**Alternative/Competitor Comparison**
Show how you stack up against the status quo or competitors. Tables, side-by-side comparisons, or "Unlike X, we..." sections.
**Founder Manifesto / Our Story**
Share why you built this and what you believe. Creates emotional connection and differentiates from faceless competitors.
**Testimonials**
Customer quotes with names, photos, and specific results. Multiple formats: quote cards, video testimonials, tweet embeds.
**Case Studies**
Deeper stories of customer success. Problem → Solution → Results format with specific metrics.
**Use Cases**
Show different ways the product is used. Helps visitors self-identify: "This is for people like me."
**Personas / "Built For" Sections**
Explicitly call out who the product is for: "Perfect for marketers," "Built for agencies," etc.
**Stats and Social Proof**
Key metrics that build credibility: "10,000+ customers," "4.9/5 rating," "$2M saved for customers."
**Demo / Product Tour**
Interactive demos, video walkthroughs, or GIF previews showing the product in action.
**FAQ Section**
Address common objections and questions. Good for SEO and reducing support burden.
**Integrations / Partners**
Show what tools you connect with. Logos build credibility and answer "Will this work with my stack?"
**Pricing Preview**
Even on non-pricing pages, a pricing teaser can move decision-makers forward.
**Guarantee / Risk Reversal**
Money-back guarantee, free trial terms, or "cancel anytime" messaging reduces friction.
### Recommended Section Mix
For a landing page, aim for variety. Don't just stack features:
**Typical Feature-Heavy Page (Weak):**
1. Hero
2. Feature 1
3. Feature 2
4. Feature 3
5. Feature 4
6. CTA
**Varied, Engaging Page (Strong):**
1. Hero with clear value prop
2. Social proof bar (logos or stats)
3. Problem/pain section
4. How it works (3 steps)
5. Key benefits (2-3, not 10)
6. Testimonial
7. Use cases or personas
8. Comparison to alternatives
9. Case study snippet
10. FAQ
11. Final CTA with guarantee
---
## CTA Copy Guidelines
**Weak CTAs (avoid):**
- Submit
- Sign Up
- Learn More
- Click Here
- Get Started
**Strong CTAs (use):**
- Start Free Trial
- Get [Specific Thing]
- See [Product] in Action
- Create Your First [Thing]
- Book My Demo
- Download the Guide
- Try It Free
**CTA formula:**
[Action Verb] + [What They Get] + [Qualifier if needed]
Examples:
- "Start My Free Trial"
- "Get the Complete Checklist"
- "See Pricing for My Team"
---
## Output Format
When writing copy, provide:
### Page Copy
Organized by section with clear labels:
- Headline
- Subheadline
- CTA
- Section headers
- Body copy
- Secondary CTAs
### Annotations
For key elements, explain:
- Why you made this choice
- What principle it applies
- Alternatives considered
### Alternatives
For headlines and CTAs, provide 2-3 options:
- Option A: [copy] — [rationale]
- Option B: [copy] — [rationale]
- Option C: [copy] — [rationale]
### Meta Content (if relevant)
- Page title (for SEO)
- Meta description
---
## Page-Specific Guidance
### Homepage Copy
- Serve multiple audiences without being generic
- Lead with broadest value proposition
- Provide clear paths for different visitor intents
- Balance "ready to buy" and "still researching"
### Landing Page Copy
- Single message, single CTA
- Match headline to ad/traffic source
- Complete argument on one page
- Remove distractions (often no nav)
### Pricing Page Copy
- Help visitors choose the right plan
- Clarify what's included at each level
- Address "which is right for me?" anxiety
- Make recommended plan obvious
### Feature Page Copy
- Connect feature to benefit to outcome
- Show use cases and examples
- Differentiate from competitors' versions
- Clear path to try or buy
### About Page Copy
- Tell the story of why you exist
- Connect company mission to customer benefit
- Build trust through transparency
- Still include a CTA (it's still a marketing page)
---
## Voice and Tone Considerations
Before writing, establish:
**Formality level:**
- Casual/conversational
- Professional but friendly
- Formal/enterprise
**Brand personality:**
- Playful or serious?
- Bold or understated?
- Technical or accessible?
Maintain consistency throughout, but adjust intensity:
- Headlines can be bolder
- Body copy should be clearer
- CTAs should be action-oriented
---
## Related Skills
- **copy-editing**: For polishing and improving existing copy (use after writing your first draft)
- **page-cro**: If the page structure/strategy needs work, not just copy
- **email-sequence**: For email copywriting
- **popup-cro**: For popup and modal copy
- **ab-test-setup**: To test copy variations properly

View File

@@ -0,0 +1,41 @@
---
name: frontend-design
description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
---
This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.
The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.
## Design Thinking
Before coding, understand the context and commit to a BOLD aesthetic direction:
- **Purpose**: What problem does this interface solve? Who uses it?
- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
- **Constraints**: Technical requirements (framework, performance, accessibility).
- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:
- Production-grade and functional
- Visually striking and memorable
- Cohesive with a clear aesthetic point-of-view
- Meticulously refined in every detail
## Frontend Aesthetics Guidelines
Focus on:
- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.

View File

@@ -0,0 +1,710 @@
---
name: pricing-strategy
description: "When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions 'pricing,' 'pricing tiers,' 'freemium,' 'free trial,' 'packaging,' 'price increase,' 'value metric,' 'Van Westendorp,' 'willingness to pay,' or 'monetization.' This skill covers pricing research, tier structure, and packaging strategy."
---
# Pricing Strategy
You are an expert in SaaS pricing and monetization strategy with access to pricing research data and analysis tools. Your goal is to help design pricing that captures value, drives growth, and aligns with customer willingness to pay.
## Before Starting
Gather this context (ask if not provided):
### 1. Business Context
- What type of product? (SaaS, marketplace, e-commerce, service)
- What's your current pricing (if any)?
- What's your target market? (SMB, mid-market, enterprise)
- What's your go-to-market motion? (self-serve, sales-led, hybrid)
### 2. Value & Competition
- What's the primary value you deliver?
- What alternatives do customers consider?
- How do competitors price?
- What makes you different/better?
### 3. Current Performance
- What's your current conversion rate?
- What's your average revenue per user (ARPU)?
- What's your churn rate?
- Any feedback on pricing from customers/prospects?
### 4. Goals
- Are you optimizing for growth, revenue, or profitability?
- Are you trying to move upmarket or expand downmarket?
- Any pricing changes you're considering?
---
## Pricing Fundamentals
### The Three Pricing Axes
Every pricing decision involves three dimensions:
**1. Packaging** — What's included at each tier?
- Features, limits, support level
- How tiers differ from each other
**2. Pricing Metric** — What do you charge for?
- Per user, per usage, flat fee
- How price scales with value
**3. Price Point** — How much do you charge?
- The actual dollar amounts
- The perceived value vs. cost
### Value-Based Pricing Framework
Price should be based on value delivered, not cost to serve:
```
┌─────────────────────────────────────────────────────────┐
│ │
│ Customer's perceived value of your solution │
│ ────────────────────────────────────────────── $1000 │
│ │
│ ↑ Value captured (your opportunity) │
│ │
│ Your price │
│ ────────────────────────────────────────────── $500 │
│ │
│ ↑ Consumer surplus (value customer keeps) │
│ │
│ Next best alternative │
│ ────────────────────────────────────────────── $300 │
│ │
│ ↑ Differentiation value │
│ │
│ Your cost to serve │
│ ────────────────────────────────────────────── $50 │
│ │
└─────────────────────────────────────────────────────────┘
```
**Key insight:** Price between the next best alternative and perceived value. Cost is a floor, not a basis.
---
## Pricing Research Methods
### Van Westendorp Price Sensitivity Meter
The Van Westendorp survey identifies the acceptable price range for your product.
**The Four Questions:**
Ask each respondent:
1. "At what price would you consider [product] to be so expensive that you would not consider buying it?" (Too expensive)
2. "At what price would you consider [product] to be priced so low that you would question its quality?" (Too cheap)
3. "At what price would you consider [product] to be starting to get expensive, but you still might consider it?" (Expensive/high side)
4. "At what price would you consider [product] to be a bargain—a great buy for the money?" (Cheap/good value)
**How to Analyze:**
1. Plot cumulative distributions for each question
2. Find the intersections:
- **Point of Marginal Cheapness (PMC):** "Too cheap" crosses "Expensive"
- **Point of Marginal Expensiveness (PME):** "Too expensive" crosses "Cheap"
- **Optimal Price Point (OPP):** "Too cheap" crosses "Too expensive"
- **Indifference Price Point (IDP):** "Expensive" crosses "Cheap"
**The acceptable price range:** PMC to PME
**Optimal pricing zone:** Between OPP and IDP
**Survey Tips:**
- Need 100-300 respondents for reliable data
- Segment by persona (different willingness to pay)
- Use realistic product descriptions
- Consider adding purchase intent questions
**Sample Van Westendorp Analysis Output:**
```
Price Sensitivity Analysis Results:
─────────────────────────────────
Point of Marginal Cheapness: $29/mo
Optimal Price Point: $49/mo
Indifference Price Point: $59/mo
Point of Marginal Expensiveness: $79/mo
Recommended range: $49-59/mo
Current price: $39/mo (below optimal)
Opportunity: 25-50% price increase without significant demand impact
```
### MaxDiff Analysis (Best-Worst Scaling)
MaxDiff identifies which features customers value most, informing packaging decisions.
**How It Works:**
1. List 8-15 features you could include
2. Show respondents sets of 4-5 features at a time
3. Ask: "Which is MOST important? Which is LEAST important?"
4. Repeat across multiple sets until all features compared
5. Statistical analysis produces importance scores
**Example Survey Question:**
```
Which feature is MOST important to you?
Which feature is LEAST important to you?
□ Unlimited projects
□ Custom branding
□ Priority support
□ API access
□ Advanced analytics
```
**Analyzing Results:**
Features are ranked by utility score:
- High utility = Must-have (include in base tier)
- Medium utility = Differentiator (use for tier separation)
- Low utility = Nice-to-have (premium tier or cut)
**Using MaxDiff for Packaging:**
| Utility Score | Packaging Decision |
|---------------|-------------------|
| Top 20% | Include in all tiers (table stakes) |
| 20-50% | Use to differentiate tiers |
| 50-80% | Higher tiers only |
| Bottom 20% | Consider cutting or premium add-on |
### Willingness to Pay Surveys
**Direct method (simple but biased):**
"How much would you pay for [product]?"
**Better: Gabor-Granger method:**
"Would you buy [product] at [$X]?" (Yes/No)
Vary price across respondents to build demand curve.
**Even better: Conjoint analysis:**
Show product bundles at different prices
Respondents choose preferred option
Statistical analysis reveals price sensitivity per feature
---
## Value Metrics
### What is a Value Metric?
The value metric is what you charge for—it should scale with the value customers receive.
**Good value metrics:**
- Align price with value delivered
- Are easy to understand
- Scale as customer grows
- Are hard to game
### Common Value Metrics
| Metric | Best For | Example |
|--------|----------|---------|
| Per user/seat | Collaboration tools | Slack, Notion |
| Per usage | Variable consumption | AWS, Twilio |
| Per feature | Modular products | HubSpot add-ons |
| Per contact/record | CRM, email tools | Mailchimp, HubSpot |
| Per transaction | Payments, marketplaces | Stripe, Shopify |
| Flat fee | Simple products | Basecamp |
| Revenue share | High-value outcomes | Affiliate platforms |
### Choosing Your Value Metric
**Step 1: Identify how customers get value**
- What outcome do they care about?
- What do they measure success by?
- What would they pay more for?
**Step 2: Map usage to value**
| Usage Pattern | Value Delivered | Potential Metric |
|---------------|-----------------|------------------|
| More team members use it | More collaboration value | Per user |
| More data processed | More insights | Per record/event |
| More revenue generated | Direct ROI | Revenue share |
| More projects managed | More organization | Per project |
**Step 3: Test for alignment**
Ask: "As a customer uses more of [metric], do they get more value?"
- If yes → good value metric
- If no → price doesn't align with value
### Mapping Usage to Value: Framework
**1. Instrument usage data**
Track how customers use your product:
- Feature usage frequency
- Volume metrics (users, records, API calls)
- Outcome metrics (revenue generated, time saved)
**2. Correlate with customer success**
- Which usage patterns predict retention?
- Which usage patterns predict expansion?
- Which customers pay the most, and why?
**3. Identify value thresholds**
- At what usage level do customers "get it"?
- At what usage level do they expand?
- At what usage level should price increase?
**Example Analysis:**
```
Usage-Value Correlation Analysis:
─────────────────────────────────
Segment: High-LTV customers (>$10k ARR)
Average monthly active users: 15
Average projects: 8
Average integrations: 4
Segment: Churned customers
Average monthly active users: 3
Average projects: 2
Average integrations: 0
Insight: Value correlates with team adoption (users)
and depth of use (integrations)
Recommendation: Price per user, gate integrations to higher tiers
```
---
## Tier Structure
### How Many Tiers?
**2 tiers:** Simple, clear choice
- Works for: Clear SMB vs. Enterprise split
- Risk: May leave money on table
**3 tiers:** Industry standard
- Good tier = Entry point
- Better tier = Recommended (anchor to best)
- Best tier = High-value customers
**4+ tiers:** More granularity
- Works for: Wide range of customer sizes
- Risk: Decision paralysis, complexity
### Good-Better-Best Framework
**Good tier (Entry):**
- Purpose: Remove barriers to entry
- Includes: Core features, limited usage
- Price: Low, accessible
- Target: Small teams, try before you buy
**Better tier (Recommended):**
- Purpose: Where most customers land
- Includes: Full features, reasonable limits
- Price: Your "anchor" price
- Target: Growing teams, serious users
**Best tier (Premium):**
- Purpose: Capture high-value customers
- Includes: Everything, advanced features, higher limits
- Price: Premium (often 2-3x "Better")
- Target: Larger teams, power users, enterprises
### Tier Differentiation Strategies
**Feature gating:**
- Basic features in all tiers
- Advanced features in higher tiers
- Works when features have clear value differences
**Usage limits:**
- Same features, different limits
- More users, storage, API calls at higher tiers
- Works when value scales with usage
**Support level:**
- Email support → Priority support → Dedicated success
- Works for products with implementation complexity
**Access and customization:**
- API access, SSO, custom branding
- Works for enterprise differentiation
### Example Tier Structure
```
┌────────────────┬─────────────────┬─────────────────┬─────────────────┐
│ │ Starter │ Pro │ Business │
│ │ $29/mo │ $79/mo │ $199/mo │
├────────────────┼─────────────────┼─────────────────┼─────────────────┤
│ Users │ Up to 5 │ Up to 20 │ Unlimited │
│ Projects │ 10 │ Unlimited │ Unlimited │
│ Storage │ 5 GB │ 50 GB │ 500 GB │
│ Integrations │ 3 │ 10 │ Unlimited │
│ Analytics │ Basic │ Advanced │ Custom │
│ Support │ Email │ Priority │ Dedicated │
│ API Access │ ✗ │ ✓ │ ✓ │
│ SSO │ ✗ │ ✗ │ ✓ │
│ Audit logs │ ✗ │ ✗ │ ✓ │
└────────────────┴─────────────────┴─────────────────┴─────────────────┘
```
---
## Packaging for Personas
### Identifying Pricing Personas
Different customers have different:
- Willingness to pay
- Feature needs
- Buying processes
- Value perception
**Segment by:**
- Company size (solopreneur → SMB → enterprise)
- Use case (marketing vs. sales vs. support)
- Sophistication (beginner → power user)
- Industry (different budget norms)
### Persona-Based Packaging
**Step 1: Define personas**
| Persona | Size | Needs | WTP | Example |
|---------|------|-------|-----|---------|
| Freelancer | 1 person | Basic features | Low | $19/mo |
| Small Team | 2-10 | Collaboration | Medium | $49/mo |
| Growing Co | 10-50 | Scale, integrations | Higher | $149/mo |
| Enterprise | 50+ | Security, support | High | Custom |
**Step 2: Map features to personas**
| Feature | Freelancer | Small Team | Growing | Enterprise |
|---------|------------|------------|---------|------------|
| Core features | ✓ | ✓ | ✓ | ✓ |
| Collaboration | — | ✓ | ✓ | ✓ |
| Integrations | — | Limited | Full | Full |
| API access | — | — | ✓ | ✓ |
| SSO/SAML | — | — | — | ✓ |
| Audit logs | — | — | — | ✓ |
| Custom contract | — | — | — | ✓ |
**Step 3: Price to value for each persona**
- Research willingness to pay per segment
- Set prices that capture value without blocking adoption
- Consider segment-specific landing pages
---
## Freemium vs. Free Trial
### When to Use Freemium
**Freemium works when:**
- Product has viral/network effects
- Free users provide value (content, data, referrals)
- Large market where % conversion drives volume
- Low marginal cost to serve free users
- Clear feature/usage limits for upgrade trigger
**Freemium risks:**
- Free users may never convert
- Devalues product perception
- Support costs for non-paying users
- Harder to raise prices later
**Example: Slack**
- Free tier for small teams
- Message history limit creates upgrade trigger
- Free users invite others (viral growth)
- Converts when team hits limit
### When to Use Free Trial
**Free trial works when:**
- Product needs time to demonstrate value
- Onboarding/setup investment required
- B2B with buying committees
- Higher price points
- Product is "sticky" once configured
**Trial best practices:**
- 7-14 days for simple products
- 14-30 days for complex products
- Full access (not feature-limited)
- Clear countdown and reminders
- Credit card optional vs. required trade-off
**Credit card upfront:**
- Higher trial-to-paid conversion (40-50% vs. 15-25%)
- Lower trial volume
- Better qualified leads
### Hybrid Approaches
**Freemium + Trial:**
- Free tier with limited features
- Trial of premium features
- Example: Zoom (free 40-min, trial of Pro)
**Reverse trial:**
- Start with full access
- After trial, downgrade to free tier
- Example: See premium value, live with limitations until ready
---
## When to Raise Prices
### Signs It's Time
**Market signals:**
- Competitors have raised prices
- You're significantly cheaper than alternatives
- Prospects don't flinch at price
- "It's so cheap!" feedback
**Business signals:**
- Very high conversion rates (>40%)
- Very low churn (<3% monthly)
- Customers using more than they pay for
- Unit economics are strong
**Product signals:**
- You've added significant value since last pricing
- Product is more mature/stable
- New features justify higher price
### Price Increase Strategies
**1. Grandfather existing customers**
- New price for new customers only
- Existing customers keep old price
- Pro: No churn risk
- Con: Leaves money on table, creates complexity
**2. Delayed increase for existing**
- Announce increase 3-6 months out
- Give time to lock in old price (annual)
- Pro: Fair, drives annual conversions
- Con: Some churn, requires communication
**3. Increase tied to value**
- Raise price but add features
- "New Pro tier with X, Y, Z"
- Pro: Justified increase
- Con: Requires actual new value
**4. Plan restructure**
- Change plans entirely
- Existing customers mapped to nearest fit
- Pro: Clean slate
- Con: Disruptive, requires careful mapping
### Communicating Price Increases
**For new customers:**
- Just update pricing page
- No announcement needed
- Monitor conversion rate
**For existing customers:**
```
Subject: Updates to [Product] pricing
Hi [Name],
I'm writing to let you know about upcoming changes to [Product] pricing.
[Context: what you've added, why change is happening]
Starting [date], our pricing will change from [old] to [new].
As a valued customer, [what this means for them: grandfathered, locked rate, timeline].
[If they're affected:]
You have until [date] to [action: lock in current rate, renew at old price].
[If they're grandfathered:]
You'll continue at your current rate. No action needed.
We appreciate your continued support of [Product].
[Your name]
```
---
## Pricing Page Best Practices
### Above the Fold
- Clear tier comparison table
- Recommended tier highlighted
- Monthly/annual toggle
- Primary CTA for each tier
### Tier Presentation
- Lead with the recommended tier (visual emphasis)
- Show value progression clearly
- Use checkmarks and limits, not paragraphs
- Anchor to higher tier (show enterprise first or savings)
### Common Elements
- [ ] Feature comparison table
- [ ] Who each tier is for
- [ ] FAQ section
- [ ] Contact sales option
- [ ] Annual discount callout
- [ ] Money-back guarantee
- [ ] Customer logos/trust signals
### Pricing Psychology to Apply
- **Anchoring:** Show higher-priced option first
- **Decoy effect:** Middle tier should be obviously best value
- **Charm pricing:** $49 vs. $50 (for value-focused)
- **Round pricing:** $50 vs. $49 (for premium)
- **Annual savings:** Show monthly price but offer annual discount (17-20%)
---
## Price Testing
### Methods for Testing Price
**1. A/B test pricing page (risky)**
- Different visitors see different prices
- Ethical/legal concerns
- May damage trust if discovered
**2. Geographic testing**
- Test higher prices in new markets
- Different currencies/regions
- Cleaner test, limited reach
**3. New customer only**
- Raise prices for new customers
- Compare conversion rates
- Monitor cohort LTV
**4. Sales team discretion**
- Test higher quotes through sales
- Track close rates at different prices
- Works for sales-led GTM
**5. Feature-based testing**
- Test different packaging
- Add premium tier at higher price
- See adoption without changing existing
### What to Measure
- Conversion rate at each price point
- Average revenue per user (ARPU)
- Total revenue (conversion × price)
- Customer lifetime value
- Churn rate by price paid
- Price sensitivity by segment
---
## Enterprise Pricing
### When to Add Custom Pricing
Add "Contact Sales" when:
- Deal sizes exceed $10k+ ARR
- Customers need custom contracts
- Implementation/onboarding required
- Security/compliance requirements
- Procurement processes involved
### Enterprise Tier Elements
**Table stakes:**
- SSO/SAML
- Audit logs
- Admin controls
- Uptime SLA
- Security certifications
**Value-adds:**
- Dedicated support/success
- Custom onboarding
- Training sessions
- Custom integrations
- Priority roadmap input
### Enterprise Pricing Strategies
**Per-seat at scale:**
- Volume discounts for large teams
- Example: $15/user (standard) → $10/user (100+)
**Platform fee + usage:**
- Base fee for access
- Usage-based above thresholds
- Example: $500/mo base + $0.01 per API call
**Value-based contracts:**
- Price tied to customer's revenue/outcomes
- Example: % of transactions, revenue share
---
## Pricing Checklist
### Before Setting Prices
- [ ] Defined target customer personas
- [ ] Researched competitor pricing
- [ ] Identified your value metric
- [ ] Conducted willingness-to-pay research
- [ ] Mapped features to tiers
### Pricing Structure
- [ ] Chosen number of tiers
- [ ] Differentiated tiers clearly
- [ ] Set price points based on research
- [ ] Created annual discount strategy
- [ ] Planned enterprise/custom tier
### Validation
- [ ] Tested pricing with target customers
- [ ] Reviewed pricing with sales team
- [ ] Validated unit economics work
- [ ] Planned for price increases
- [ ] Set up tracking for pricing metrics
---
## Questions to Ask
If you need more context:
1. What pricing research have you done (surveys, competitor analysis)?
2. What's your current ARPU and conversion rate?
3. What's your primary value metric (what do customers pay for value)?
4. Who are your main pricing personas (by size, use case)?
5. Are you self-serve, sales-led, or hybrid?
6. What pricing changes are you considering?
---
## Related Skills
- **page-cro**: For optimizing pricing page conversion
- **copywriting**: For pricing page copy
- **marketing-psychology**: For pricing psychology principles
- **ab-test-setup**: For testing pricing changes
- **analytics-tracking**: For tracking pricing metrics

24
.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# jetbrains setting folder
.idea/

4
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View File

@@ -0,0 +1,98 @@
# NotJustAn.Agency Copywriting
## Hero Section
Main Heading:
**Fully Booked** Restaurants.
**Sold-Out** Collections.
Brands **Built to Last**.
Subheading:
We help hospitality and e-commerce businesses grow and scale with our expertise in **performance marketing** , **ad creation** and **web development**.
Buttons:
- Main: Get in Contact
- Secondary: See Portfolio
## Our Expertise
### Performance Marketing & Ad Creation
Scale your business with Performance Marketing that delivers measurable results. NotJustAn.Agency optimizes Meta Ads, Google Ads, and funnels for maximum revenue and ROAS.
### Web Development
We create fast, conversion-focused websites that impress users and rank on Google. We build modern, responsive sites that drives leads, sales, and trust.
### SEO & SEA
Boost your visibility with data-driven SEO and high-ROI SEA campaigns. NotJustAn.Agency helps you rank higher, atrract qualified traffic, and turn searches into customers.
### Email Marketing & Copywriting
Maximize your campaign ROI with words that sell. We write high-converting copy for ads, websites, and emails that resonates with your target market and turns clicks into contracts.
## Portfolio Section
**Portfolio: Proven Growth for Businesses Like Yours**
At NotJustAn.Agency, we understand the unique challenges B2B businesses face in today's competitive landscape. We don't just offer services; we deliver tangible solutions designed to overcome your most pressing growth obstacles.
---
**Problem:** **Your Ad Spend Isn't Generating Enough Revenue.**
*Are you pouring money into Meta Ads or Google Ads with little to show for it? Are your campaigns struggling to achieve a profitable Return on Ad Spend (ROAS)?*
**Our Solution: Performance Marketing & Ad Creation That Drives ROI**
We go beyond simply running ads. Our team dives deep into your market, competitors, and customer psychology to craft high-impact ad campaigns. We meticulously optimize targeting, creatives, and bidding strategies to ensure every dollar spent converts into measurable revenue and sustainable growth.
---
**Problem:** **Your Website Isn't Converting Visitors into Customers.**
*Does your website fail to capture leads or drive sales? Is it slow, outdated, or failing to build trust with potential clients?*
**Our Solution: Conversion-Focused Web Development**
Your website is your digital storefront. We build modern, lightning-fast, and responsive websites specifically engineered to convert browsers into buyers. From intuitive user journeys to compelling calls-to-action, we ensure your online presence not only looks professional but also actively works to grow your business.
---
**Problem:** **You're Invisible to High-Intent Customers Online.**
*Are potential clients actively searching for your solutions but finding your competitors instead? Is your online visibility hindering your growth trajectory?*
**Our Solution: Strategic SEO & High-ROI SEA Campaigns**
We make you unmissable. Our data-driven SEO strategies ensure you rank higher for critical keywords, attracting qualified organic traffic. Coupled with precisely targeted Search Engine Advertising (SEA), we ensure that when customers search for what you offer, your business is the one they find and choose.
---
**Problem:** **Your Marketing Communication Falls Flat.**
*Do your emails go unread? Do your website's words fail to persuade? Is your core message not resonating with your target audience?*
**Our Solution: Email Marketing & Copywriting That Sells**
Words have power, especially in business. We craft compelling, persuasive copy for your ads, website, and email campaigns. Our expertise ensures your message cuts through the noise, speaks directly to your audience's pain points and desires, and expertly guides them towards becoming loyal, paying customers.
---
## FAQ Section
**Do you work with small businesses?**
We do work with small businesses, but our primary focus is on scaling businesses that have a clear growth trajectory. We typically engage with clients who have a minimum monthly ad spend of $2,000 or more, as this allows us to implement effective strategies that yield measurable results. If you are a small business looking to grow, we recommend starting with our consultation services to assess your needs and determine the best path forward.
**How do we measure project success?**
Project success is measured through a combination of key performance indicators (KPIs) that align with your business objectives. This may include metrics such as return on ad spend (ROAS), conversion rates, website traffic growth, search engine rankings, and social media engagement. We work closely with you to define these KPIs at the outset of the project and provide regular reporting to track progress and make data-driven adjustments as needed.
**What if you don't deliver your projected results? (Meta Ads, SEO/SEA, etc.)**
We are confident in our ability to deliver results. If we fall short of your projected outcomes, we offer different forms of performance guarantees which can include full or partial refunds, additional services at no cost, or extended service periods until the agreed-upon results are achieved. Our goal is your success, and we stand by our commitments.
**I am currently working with another agency. What does the transitioning process look like?**
Transitioning from one agency to another can be quiet cumbersome. First we will review if the contract you've signed even allows for a transition. We then begin with a comprehensive audit of your current strategies, campaigns, and performance metrics. Our team will then develop a tailored transition plan that minimizes disruption to your ongoing operations. We handle all the technical aspects, including account access, data migration, and campaign setup. Throughout the process, we maintain open communication to ensure you are informed and comfortable with each step.
**What if suddently I want to stop working with you?**
Our contracts are designed to be flexible and client-friendly. It can vary depending on the specific services and terms agreed upon at the start of our cooperation. If you like we can show you what our contracts typically look like during our initial consultation.

View File

@@ -0,0 +1,38 @@
# Architecture Stack
**General Guideline: ** Free and Open-Source, self-hostable with little to no limitations.
## Development
- use git and make proper commits
## Frontend
- Astro.js + React
- Tailwind.css
- Framer Motion
## Backend
- Strapi (Core MIT License)
- **User Management:** Strapi's built-in user authentication and role management system can handle user accounts for access control.
- **Database:** PostgreSQL (PostgreSQL License)
## Other Functionalities
### Newsletter
- **Email/Mailing List Manager:** `Listmonk` (AGPLv3 License) - A self-hosted, open-source newsletter and mailing list manager.
### File Downloads (e.g., Ebooks)
- **Content Hosting:** Ebooks hosted and served via Strapi's Media Library.
- **Access Control:** Downloads gated by Strapi user authentication. Users must be logged in via Strapi to access protected download links.
- **Newsletter Integration:** User registration/login process within Strapi can be integrated with `Listmonk` (e.g., via API calls or webhooks) to automatically subscribe users to the newsletter upon signup, fulfilling the requirement for download access.
# Deployment
- **Docker Compose:**
- Define services for `Strapi` (MIT License), `PostgreSQL` (PostgreSQL License), and `Listmonk` (AGPLv3 License).
- Configure volumes for Strapi uploads, PostgreSQL data persistence, and Listmonk data persistence.
- Ensure environment variables are managed for database connections, Strapi secrets, and Listmonk configuration.
- Consider how the Astro.js frontend will be built and served, and how it interacts with Strapi's API for user authentication and protected content.
- DO create docker-compose.yaml to make it deployable for Coolify

74
Gemini/style.md Normal file
View File

@@ -0,0 +1,74 @@
# Website Style Guide for NotJustAn.Agency
This style guide outlines the visual design, tone, and interaction principles for the NotJustAn.Agency website. It is designed to ensure a cohesive, professional, and lead-generating online presence, providing clear instructions for LLMs to create a great-looking and effective website.
## Brand Essence
* **Core Identity:** Expert, results-driven, growth-focused, trustworthy, modern, and professional.
* **Target Audience:** B2B clients in hospitality and e-commerce seeking to scale their businesses.
* **Key Message:** NotJustAn.Agency solves critical business growth challenges (revenue, conversions, visibility) through specialized digital marketing and web development services, helping clients achieve 'Fully Booked Restaurants', 'Sold-Out Collections', and 'Brands Built to Last'.
* **Tone:** Professional, confident, clear, authoritative, yet accessible. Emphasizes a problem/solution approach and tangible business outcomes.
## Visual Design Principles
* **Aesthetic:** Clean, modern, professional, and uncluttered. The design should convey competence and sophistication, allowing the content to shine. Prioritize user experience and clear communication.
* **Color Palette:**
* **Primary:** Deep Navy/Blue (`#0A2540`) - Conveys trust, professionalism, and depth. Use for backgrounds, primary text, and key structural elements.
* **Secondary:** Off-White/Light Gray (`#F8FAFC`) - Provides a clean, spacious canvas for content. Use for backgrounds of content sections or cards.
* **Accent:** Teal (`#06B6D4`) - A modern, energetic color for calls-to-action, key interactive elements, and highlights. Use sparingly to draw attention to important actions.
* **Text:**
* Headings: Dark Grey/Near Black (`#0F172A`) - High contrast for immediate visibility.
* Body Copy: Slightly lighter Dark Grey (`#1E293B`) - Excellent readability for longer text blocks.
* **Typography:**
* **Headings:** Utilize a modern, strong sans-serif font family (e.g., Inter, Poppins, Montserrat) with clear hierarchy via font weights and sizes.
* **Body Text:** Employ a highly readable sans-serif font family (e.g., Inter, Open Sans, Lato) for optimal legibility.
* **Layout & Responsiveness:**
* **Grid System:** Utilize a flexible grid system (leveraging Tailwind CSS) for consistent alignment and spacing.
* **Responsiveness:** Design must be fully responsive, adapting flawlessly to all screen sizes (desktop, tablet, mobile). Prioritize mobile-first principles.
* **Whitespace:** Incorporate generous use of whitespace to improve readability, reduce cognitive load, and enhance the premium feel.
* **Imagery & Visuals:**
* **Quality:** Use high-resolution, professional, and relevant imagery. Visuals should align with themes of growth, scale, and expertise.
* **Placeholder Strategy:** If placeholder graphics are needed, use abstract geometric shapes or minimalist, sophisticated placeholder images that convey professionalism rather than looking amateurish. Avoid default stock photos.
## Interactivity & Animation
* **Purposeful Animation:** Employ Framer Motion for animations that enhance UX, guide attention, and convey dynamism without being distracting.
* **Use Cases:** Smooth page transitions, subtle entrance animations, hover effects on CTAs and cards, micro-interactions.
* **Style:** Animations should be quick, smooth, and subtle. Avoid jarring or lengthy effects.
* **Performance:** Animations must be performant and not impede loading times or user interaction.
## Content Presentation
* **Hierarchy:** Employ clear, distinct heading levels (H1, H2, H3) to structure content logically.
* **Copywriting Style:** Adhere to the problem/solution framing and results-oriented language from the copywriting documents. Emphasize benefits and tangible business outcomes.
* **Emphasis:** Use bold text strategically for key terms, benefits, and CTAs.
* **Lists:** Utilize bullet points and numbered lists for clarity and scannability when outlining services, features, or steps.
## Key Components & Elements
* **Buttons (Calls to Action - CTAs):**
* **Design:** Prominent, clear, and action-oriented. Use the accent color (`#06B6D4`) for primary CTAs ("Get in Contact," "See Portfolio"). Secondary buttons can be outlined or use a less saturated version of the accent color.
* **Placement:** Strategically placed in hero sections, after content sections, and in footers.
* **States:** Design clear hover and active states for buttons.
* **Forms:**
* **Contact & Newsletter Forms:** Clean, simple, and easy to use. Minimize required fields. Clearly indicate required fields. Use professional input field styling via Tailwind CSS.
* **Submission Feedback:** Provide clear success or error messages upon form submission.
* **User Authentication Elements:** For gated content (e.g., ebook downloads):
* Clear login/signup forms and modals.
* Integration with Strapi's user management.
* Clear feedback on authentication status.
* **Ebook Download Links:** Should be visually distinct once a user has authenticated and met the newsletter signup criteria.
## LLM Development Guidance
* **Persona:** Act as a skilled UI/UX designer and frontend developer specializing in modern web applications.
* **Frameworks:** Utilize Astro.js for page structure and SSR/static generation, React for interactive components, Tailwind CSS for styling, and Framer Motion for animations.
* **Code Generation:**
* Apply the defined color palette (`#0A2540`, `#F8FAFC`, `#06B6D4`, `#0F172A`, `#1E293B`) and typography consistently.
* Implement responsive layouts using Tailwind's utility classes.
* Integrate Framer Motion for subtle, purposeful animations.
* Design forms and buttons to be clear, actionable, and visually aligned with the brand.
* Structure content semantically, emphasizing clear headings and readable body text.
* Ensure components are accessible and performant.
* For download gating, interact with Strapi's API for authentication and file retrieval, and Listmonk's API for newsletter subscriptions.
* **Output:** Generate clean, well-structured React components and Astro pages adhering to these guidelines.

19
README.md Normal file
View File

@@ -0,0 +1,19 @@
# ToDo
- Hero Section
- [ ] About Us mit 3D Globe
Informationen wie: derzeitig erreichbar Telefonnummer und E-Mailadresse (hello@notjustan.agency)
direkt Darunter dann Services und Expertise
- [ ] Services & Expertise Section wie bei https://wearestokt.com/
## Hero Section
- [with NotJustAn.Agency] unter main headline
- AI

14
astro.config.mjs Normal file
View File

@@ -0,0 +1,14 @@
// @ts-check
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import tailwindcss from '@tailwindcss/vite';
// https://astro.build/config
export default defineConfig({
integrations: [react()],
vite: {
plugins: [tailwindcss()]
}
});

6262
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

29
package.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "temp_project",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev --host",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/react": "^4.4.2",
"@fontsource-variable/outfit": "^5.2.8",
"@fontsource/outfit": "^5.2.8",
"@tailwindcss/vite": "^4.1.18",
"@types/react": "^19.2.9",
"@types/react-dom": "^19.2.3",
"astro": "^5.16.11",
"clsx": "^2.1.1",
"framer-motion": "^12.27.5",
"gsap": "^3.14.2",
"lucide-react": "^0.562.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"simple-icons": "^16.6.0",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.18"
}
}

9
public/favicon.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -0,0 +1,122 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { Focus } from 'lucide-react';
gsap.registerPlugin(ScrollTrigger);
export default function ApproachSection() {
const containerRef = useRef<HTMLElement>(null);
const textRef = useRef<HTMLDivElement>(null);
useEffect(() => {
let ctx = gsap.context(() => {
const words = gsap.utils.toArray(".reveal-word, .reveal-accent");
// Text color reveal scrubbed to scroll
gsap.to(words, {
scrollTrigger: {
trigger: textRef.current,
start: "top 85%",
end: "bottom 50%",
scrub: 1, // Smoothing effect for the scrub
},
color: (index, target) => (target as HTMLElement).classList.contains('reveal-accent') ? "var(--color-accent)" : "#ffffff",
textShadow: (index, target) => (target as HTMLElement).classList.contains('reveal-accent') ? "0 0 40px rgba(204,255,0,0.6)" : "0 0 20px rgba(255,255,255,0.1)",
stagger: 0.1, // Staggering gives a sweeping effect along the scrub
ease: "power2.inOut"
});
// Ambient background glow intensity ties to scroll
gsap.to(".ambient-glow", {
scrollTrigger: {
trigger: textRef.current,
start: "top 80%",
end: "bottom 40%",
scrub: true,
},
opacity: 0.12,
scale: 1.5,
ease: "none"
});
// Subtitle floats up and fades
gsap.from(".approach-subtitle", {
scrollTrigger: {
trigger: containerRef.current,
start: "top 80%",
},
y: 30,
opacity: 0,
duration: 1,
ease: "power3.out"
});
}, containerRef);
return () => ctx.revert();
}, []);
// The core philosophy text (use \n for new paragraphs)
// Wrap any text you want to highlight in brackets like [this]
const textContent = `We don't just build websites and run ads. We architect the entire experience from the [first impression] to the [final checkout].
By mapping the nuances of your customer's journey, we build as seamless path [that aligns your product's value with the user's intent].
We don't just shout louder with more ads. We ensure that once we have their attention, the [foundation is built to convert it].`;
// Split into paragraphs based on line breaks
const paragraphs = textContent.split('\n');
return (
<section ref={containerRef} className="relative py-40 md:py-64 bg-neutral-950 overflow-hidden flex flex-col items-center justify-center border-b border-white/5">
{/* Ambient glowing backdrop that brightens as you scroll */}
<div className="ambient-glow absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] md:w-[800px] h-[600px] md:h-[800px] bg-[var(--color-accent)] blur-[120px] rounded-full opacity-0 pointer-events-none z-0 will-change-transform"></div>
<div className="container mx-auto px-6 md:px-12 relative z-10 flex flex-col items-center">
<div className="approach-subtitle mb-12 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/5 border border-white/10 will-change-transform shadow-[0_0_20px_rgba(0,0,0,0.5)]">
<Focus className="w-4 h-4 text-[var(--color-accent)]" />
<span className="text-xs font-mono tracking-wider text-neutral-300 uppercase">The Core Philosophy</span>
</div>
{/* The huge scroll-reveal typographic block */}
<div
ref={textRef}
className="max-w-6xl mx-auto text-center text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-[1.1] md:leading-[1.05]"
>
{paragraphs.map((p, pIndex) => {
let isAccent = false; // Tracks if we are currently inside [ ]
return (
<div key={pIndex} className="mb-6 md:mb-10 last:mb-0">
{p.split(/\s+/).map((word, i) => {
if (!word) return null; // safety check
const startsAccent = word.includes('[');
const endsAccent = word.includes(']');
if (startsAccent) isAccent = true;
// Strip out the brackets for clean display
const cleanWord = word.replace(/\[|\]/g, '');
const currentClass = isAccent ? 'reveal-accent' : 'reveal-word';
// Toggle it off AFTER rendering if this word has the closing bracket
if (endsAccent) isAccent = false;
return (
<span key={`${pIndex}-${i}`} className={`inline-block mr-[0.25em] mb-1 sm:mb-2 text-[#27272a] will-change-transform ${currentClass}`}>
{cleanWord}
</span>
);
})}
</div>
);
})}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,223 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { Instagram, Linkedin, Smartphone, Youtube, Globe, Share2, Eye } from 'lucide-react';
gsap.registerPlugin(ScrollTrigger);
export default function BrandAwarenessSection() {
const containerRef = useRef<HTMLElement>(null);
useEffect(() => {
let ctx = gsap.context(() => {
// Text Enter
gsap.from(".brand-text > *", {
scrollTrigger: {
trigger: containerRef.current,
start: "top 75%",
},
y: 40,
opacity: 0,
duration: 1,
stagger: 0.15,
ease: "power3.out"
});
// Network Diagram Timeline
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".network-visual",
start: "top 65%",
}
});
// Initial states
tl.set(".center-node", { scale: 0, opacity: 0 })
.set(".satellite-node", { scale: 0, opacity: 0 })
.set(".network-line", { strokeDasharray: 500, strokeDashoffset: 500, opacity: 0 })
.set(".pulse-ring", { scale: 0, opacity: 0 });
// 1. Core pop in
tl.to(".center-node", { scale: 1, opacity: 1, duration: 0.8, ease: "back.out(1.5)" })
.to(".pulse-ring", { scale: 1.5, opacity: 0.2, duration: 0.4 }, "<");
// 2. Draw lines outward to touchpoints
tl.to(".network-line", { opacity: 1, strokeDashoffset: 0, duration: 1, stagger: 0.1, ease: "power2.out" }, "-=0.2");
// 3. Touchpoints (Satellites) pop in
tl.to(".satellite-node", { scale: 1, opacity: 1, duration: 0.6, stagger: 0.1, ease: "back.out(1.5)" }, "-=0.8");
// --- Continuous Animations ---
// Subtle floating for satellites
gsap.to(".satellite-node", {
y: "random(-15, 15)",
x: "random(-15, 15)",
duration: "random(3, 5)",
repeat: -1,
yoyo: true,
ease: "sine.inOut"
});
// Center ring pulsing
gsap.to(".pulse-ring", {
scale: 2.5,
opacity: 0,
duration: 2.5,
repeat: -1,
ease: "power2.out"
});
// Energy Burst (Simulating brand distribution)
// It highlights the lines, then lights up the touchpoint nodes
const burstTl = gsap.timeline({ repeat: -1, repeatDelay: 2 });
burstTl.to(".network-line", {
stroke: "var(--color-accent)",
strokeOpacity: 0.8,
strokeWidth: 3,
duration: 0.4,
stagger: 0.1,
ease: "power2.in"
})
.to(".satellite-node", {
scale: 1.15,
borderColor: "var(--color-accent)",
boxShadow: "0 0 25px rgba(204,255,0,0.4)",
color: "var(--color-accent)",
duration: 0.2,
stagger: 0.1
}, "<0.1")
.to(".network-line", {
stroke: "rgba(255,255,255,0.1)",
strokeOpacity: 1,
strokeWidth: 2,
duration: 0.8,
stagger: 0.1,
ease: "power2.out"
}, "-=0.2")
.to(".satellite-node", {
scale: 1,
borderColor: "rgba(255,255,255,0.1)",
boxShadow: "0 0 0px rgba(204,255,0,0)",
color: "#9ca3af", // neutral-400
duration: 0.8,
stagger: 0.1
}, "-=0.2");
}, containerRef);
return () => ctx.revert();
}, []);
// Canvas mapping from center (250, 250) on a 500x500 box
const nodes = [
{ id: 1, x: 90, y: 120, icon: <Instagram className="w-5 h-5" />, name: "Instagram" },
{ id: 2, x: 410, y: 110, icon: <Linkedin className="w-5 h-5" />, name: "LinkedIn" },
{ id: 3, x: 80, y: 350, icon: <Smartphone className="w-5 h-5" />, name: "TikTok / Reels" },
{ id: 4, x: 420, y: 360, icon: <Youtube className="w-5 h-5" />, name: "YouTube" },
{ id: 5, x: 250, y: 440, icon: <Globe className="w-5 h-5" />, name: "Search / Display" },
{ id: 6, x: 250, y: 50, icon: <Share2 className="w-5 h-5" />, name: "Social Feeds" },
];
return (
<section ref={containerRef} className="relative py-32 bg-neutral-950 overflow-hidden">
{/* Background effects */}
<div className="absolute top-0 inset-x-0 h-px bg-gradient-to-r from-transparent via-neutral-800 to-transparent"></div>
<div className="container mx-auto px-6 md:px-12 relative z-10 grid grid-cols-1 lg:grid-cols-12 gap-16 lg:gap-8 items-center">
{/* LEFT SIDE: Network Diagram */}
<div className="lg:col-span-6 w-full flex justify-center lg:justify-start relative order-2 lg:order-1 mt-10 lg:mt-0">
<div className="network-visual relative w-full aspect-square max-w-[550px]">
{/* Background subtle glow */}
<div className="absolute inset-0 bg-[var(--color-accent)]/5 blur-[120px] rounded-full pointer-events-none z-0"></div>
{/* SVG Layer for connecting lines */}
<svg viewBox="0 0 500 500" className="w-full h-full absolute inset-0 overflow-visible z-10 pointer-events-none">
<defs>
<filter id="glowNetwork">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
{nodes.map(node => (
<line
key={`line-${node.id}`}
x1="250" y1="250"
x2={node.x} y2={node.y}
className="network-line stroke-white/10"
strokeWidth="2"
strokeLinecap="round"
/>
))}
</svg>
{/* HTML Nodes overlay */}
<div className="absolute inset-0 z-20 w-full h-full pointer-events-none">
{/* Core Brand Node */}
<div className="center-node absolute top-[50%] left-[50%] -translate-x-1/2 -translate-y-1/2 w-24 h-24 bg-neutral-950 border-2 border-[var(--color-accent)] rounded-2xl flex flex-col items-center justify-center shadow-[0_0_50px_rgba(204,255,0,0.2)] will-change-transform z-30">
<span className="text-white font-bold tracking-tighter text-sm">BRAND</span>
<div className="pulse-ring absolute inset-0 border-2 border-[var(--color-accent)] rounded-2xl"></div>
</div>
{/* Touchpoint Satellites */}
{nodes.map(node => (
<div
key={`node-${node.id}`}
className="satellite-node absolute w-14 h-14 bg-neutral-900 border border-white/10 rounded-full flex flex-col items-center justify-center text-neutral-400 z-20 shadow-lg will-change-transform group pointer-events-auto cursor-pointer"
style={{ top: `${(node.y / 500) * 100}%`, left: `${(node.x / 500) * 100}%`, transform: 'translate(-50%, -50%)' }}
>
{node.icon}
{/* Tooltip Label */}
<div className="absolute -bottom-8 bg-neutral-950 border border-white/10 px-2 py-1 rounded text-[10px] sm:text-xs font-mono text-neutral-300 whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity">
{node.name}
</div>
</div>
))}
</div>
</div>
</div>
{/* RIGHT SIDE: Text Content */}
<div className="lg:col-span-6 flex flex-col justify-center brand-text z-20 order-1 lg:order-2">
<div className="mb-6 inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/5 border border-white/10 w-max">
<Eye className="w-4 h-4 text-[var(--color-accent)]" />
<span className="text-xs font-mono tracking-wider text-neutral-300 uppercase">Omnipresence</span>
</div>
<h2 className="text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-bold tracking-tighter text-white mb-6">
Be the first<br />
<span className="text-[var(--color-accent)]">they think of.</span>
</h2>
<p className="text-lg text-neutral-400 font-light leading-relaxed mb-10 xl:text-xl">
Attention is the new currency. We deploy omnipresent brand frameworks that put you everywhere your target audience spends their time. From their morning LinkedIn scroll to their late-night TikTok binges, your brand remains inescapable.
</p>
<ul className="space-y-4">
{[
"Multi-channel Content Distribution",
"High-frequency Touchpoint Optimization",
"Aggressive Retargeting Networks"
].map((point, i) => (
<li key={i} className="flex items-center gap-3 text-neutral-300 font-mono text-sm xl:text-base">
<div className="w-1.5 h-1.5 rounded-full bg-[var(--color-accent)] shadow-[0_0_8px_rgba(204,255,0,0.8)]"></div>
{point}
</li>
))}
</ul>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,187 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { Target, Layers, Fingerprint, MonitorSmartphone, Rocket, Link } from 'lucide-react';
gsap.registerPlugin(ScrollTrigger);
export default function BusinessStagesSection() {
const containerRef = useRef<HTMLElement>(null);
useEffect(() => {
let ctx = gsap.context(() => {
// Text Enter
gsap.from(".stages-text > *", {
scrollTrigger: {
trigger: containerRef.current,
start: "top 75%",
},
y: 40,
opacity: 0,
duration: 1,
stagger: 0.15,
ease: "power3.out"
});
// Pipeline Animation
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".pipeline-wrapper",
start: "top 65%",
}
});
// The duration it takes the power line to trace from top to bottom
const lineDuration = 2.5;
// 1. Trace the power line down
tl.to(".power-line", {
height: "100%",
duration: lineDuration,
ease: "power1.inOut" // linear-ish trace feels like energy moving
});
// 2. At the exact moments the line passes a node, pop the node in
// Since there are 5 nodes spaced evenly, we space the stagger interval
const staggerInterval = lineDuration / 5;
tl.to(".stage-item", {
y: 0,
opacity: 1,
duration: 0.6,
stagger: staggerInterval,
ease: "back.out(1.5)"
}, `<0.1`);
// 3. Ignite the icon box exactly as the line hits it
tl.to(".stage-icon", {
borderColor: "var(--color-accent)",
color: "black",
backgroundColor: "var(--color-accent)",
boxShadow: "0 0 25px rgba(204,255,0,0.5)",
duration: 0.4,
stagger: staggerInterval
}, `<0`);
// 4. Subtle background glow behind the active items
tl.to(".stage-glow", {
opacity: 1,
duration: 0.5,
stagger: staggerInterval
}, `<0`);
}, containerRef);
return () => ctx.revert();
}, []);
const stages = [
{
id: 1,
title: "Product / Market Fit",
desc: "The absolute baseline. We validate undeniable market demand so you're never marketing a product nobody wants.",
icon: <Target className="w-6 h-6" />
},
{
id: 2,
title: "Product Design",
desc: "Engineering an irreplaceable solution. Creating an offering so good, the marketing is just a magnifier.",
icon: <Layers className="w-6 h-6" />
},
{
id: 3,
title: "Branding Strategy",
desc: "Crafting a perception that commands authority and builds cult-like trust with your target audience.",
icon: <Fingerprint className="w-6 h-6" />
},
{
id: 4,
title: "Website & Online Presence",
desc: "Building a high-converting digital storefront. A frictionless mechanism turning interest into closed revenue.",
icon: <MonitorSmartphone className="w-6 h-6" />
},
{
id: 5,
title: "Performance Marketing",
desc: "Pouring aggressive ad budget into a flawless system. Scaling winners systematically with data-driven paid media.",
icon: <Rocket className="w-6 h-6" />
}
];
return (
<section ref={containerRef} className="relative py-32 bg-neutral-950 overflow-hidden">
{/* Background effects */}
<div className="absolute top-0 inset-x-0 h-px bg-gradient-to-r from-transparent via-neutral-800 to-transparent"></div>
<div className="container mx-auto px-6 md:px-12 relative z-10 grid grid-cols-1 lg:grid-cols-12 gap-16 lg:gap-12 items-center">
{/* LEFT SIDE: Text Content */}
<div className="lg:col-span-5 flex flex-col justify-center stages-text z-20">
<div className="mb-6 inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/5 border border-white/10 w-max">
<Link className="w-4 h-4 text-[var(--color-accent)]" />
<span className="text-xs font-mono tracking-wider text-neutral-300 uppercase">The Unbreakable Chain</span>
</div>
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold tracking-tighter text-white mb-6">
An ecosystem.<br />
<span className="text-neutral-500">Not just an agency.</span>
</h2>
<p className="text-lg text-neutral-400 font-light leading-relaxed mb-8">
Why do most marketing campaigns bleed money? <span className="text-white font-medium">Because the foundation is cracked.</span>
<br /><br />
We don't just run ads and hope for the best. We audit and engineer a complete, flawless digital lifecycle. If even one stage is broken, the entire chain fails.
</p>
<div className="p-4 bg-[var(--color-accent)]/10 border border-[var(--color-accent)]/20 rounded-xl text-white font-mono text-sm shadow-inner">
&gt; SYSTEM_CHECK: Intact. <br/>
&gt; READY_TO_SCALE: True.
</div>
</div>
{/* RIGHT SIDE: Vertical Interactive Pipeline */}
<div className="lg:col-span-7 w-full flex justify-center lg:justify-end relative mt-8 lg:mt-0">
{/* The wrapper that triggers the GSAP timeline */}
<div className="pipeline-wrapper relative w-full max-w-lg lg:max-w-xl py-4 mx-auto lg:mr-0 z-10">
{/* Background structural track line */}
<div className="absolute top-8 left-[31px] sm:left-[39px] bottom-12 w-[2px] bg-white/10 z-0"></div>
{/* Glowing dynamic power line tracing down */}
<div className="power-line absolute top-8 left-[31px] sm:left-[39px] w-[2px] bg-[var(--color-accent)] z-10 shadow-[0_0_15px_rgba(204,255,0,0.8)] will-change-transform rounded-full" style={{ height: '0%' }}></div>
<div className="flex flex-col gap-10 sm:gap-14 relative z-20">
{stages.map((stage, index) => (
<div key={stage.id} className="stage-item flex gap-6 sm:gap-8 translate-y-8 opacity-0 relative will-change-transform">
{/* Subtle accent glow behind text */}
<div className="stage-glow absolute inset-0 bg-gradient-to-r from-[var(--color-accent)]/5 to-transparent blur-2xl rounded-full opacity-0 pointer-events-none -z-10"></div>
{/* Interactive Hardware Node */}
<div className="stage-icon w-16 h-16 sm:w-20 sm:h-20 rounded-2xl bg-[#18181b] border-2 border-white/10 flex items-center justify-center flex-shrink-0 transition-colors text-neutral-400 z-20 shadow-lg will-change-transform relative group">
{stage.icon}
{/* Fake hardware light */}
<div className="absolute top-2 right-2 w-1.5 h-1.5 rounded-full bg-neutral-700 group-hover:bg-[var(--color-accent)] transition-colors"></div>
{/* Connector nub to the line */}
<div className="absolute top-1/2 left-0 -translate-x-full h-1 w-2 bg-white/10 hidden sm:block"></div>
</div>
<div className="pt-2 sm:pt-4 flex-1">
<div className="text-[var(--color-accent)] text-xs font-mono font-bold mb-1">STAGE_0{stage.id}</div>
<h3 className="text-xl sm:text-2xl font-bold text-white mb-2">{stage.title}</h3>
<p className="text-neutral-400 text-sm leading-relaxed max-w-md">{stage.desc}</p>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,130 @@
import React, { useState } from 'react';
import { Send, CheckCircle, AlertCircle } from 'lucide-react';
export default function ContactForm() {
const [formState, setFormState] = useState({
email: '',
phone: '',
company: '',
message: '',
captcha: false
});
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!formState.captcha) {
alert("Please confirm you are not a robot (Placeholder)");
return;
}
setStatus('submitting');
// Simulate API call
setTimeout(() => {
setStatus('success');
setFormState({ email: '', phone: '', company: '', message: '', captcha: false });
}, 1500);
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setFormState({ ...formState, [e.target.name]: e.target.value });
};
return (
<section className="py-20 relative bg-black text-white overflow-hidden">
<div className="absolute inset-0 bg-[var(--color-accent)]/5 skew-y-3 transform origin-top-left -z-10" />
<div className="container mx-auto px-4 max-w-4xl">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-4">Let's Build Something <span className="text-[var(--color-accent)]">Legendary</span></h2>
<p className="text-neutral-400">Ready to dominate your market? Reach out.</p>
</div>
<div className="glass p-8 md:p-12 rounded-3xl border border-white/10 relative">
{status === 'success' ? (
<div className="flex flex-col items-center justify-center h-96 text-center">
<CheckCircle className="text-[var(--color-accent)] w-20 h-20 mb-6" />
<h3 className="text-3xl font-bold mb-2">Message Sent!</h3>
<p className="text-neutral-400">We'll get back to you within 24 hours.</p>
<button onClick={() => setStatus('idle')} className="mt-8 text-[var(--color-accent)] underline">Send another message</button>
</div>
) : (
<form onSubmit={handleSubmit} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-sm font-medium text-neutral-400 ml-1">Email</label>
<input
type="email"
name="email"
required
value={formState.email}
onChange={handleChange}
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-4 focus:outline-none focus:border-[var(--color-accent)] focus:bg-white/10 transition-all text-white placeholder-white/20"
placeholder="john@example.com"
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium text-neutral-400 ml-1">Phone Number</label>
<input
type="tel"
name="phone"
required
value={formState.phone}
onChange={handleChange}
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-4 focus:outline-none focus:border-[var(--color-accent)] focus:bg-white/10 transition-all text-white placeholder-white/20"
placeholder="+43 ..."
/>
</div>
</div>
<div className="space-y-2">
<label className="text-sm font-medium text-neutral-400 ml-1">Company Name</label>
<input
type="text"
name="company"
value={formState.company}
onChange={handleChange}
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-4 focus:outline-none focus:border-[var(--color-accent)] focus:bg-white/10 transition-all text-white placeholder-white/20"
placeholder="Acme Corp"
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium text-neutral-400 ml-1">Message</label>
<textarea
name="message"
required
rows={4}
value={formState.message}
onChange={handleChange}
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-4 focus:outline-none focus:border-[var(--color-accent)] focus:bg-white/10 transition-all text-white placeholder-white/20 resize-none"
placeholder="Tell us about your project..."
/>
</div>
{/* Fake Captcha */}
<div className="flex items-center gap-3 p-4 bg-white/5 rounded-xl border border-white/10 w-fit">
<input
type="checkbox"
id="captcha"
checked={formState.captcha}
onChange={(e) => setFormState({ ...formState, captcha: e.target.checked })}
className="w-5 h-5 accent-[var(--color-accent)] cursor-pointer"
/>
<label htmlFor="captcha" className="cursor-pointer text-sm select-none">I'm not a robot</label>
</div>
<button
type="submit"
disabled={status === 'submitting'}
className="w-full py-5 bg-[var(--color-accent)] text-black font-bold text-lg rounded-xl hover:scale-[1.01] active:scale-[0.99] transition-all flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
>
{status === 'submitting' ? 'Sending...' : <>Send Message <Send size={20} /></>}
</button>
</form>
)}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,109 @@
import React from 'react';
export default function FooterSection() {
return (
<footer className="relative bg-[#050505] text-white pt-24 md:pt-32 overflow-hidden border-t border-white/10 flex flex-col justify-end">
<div className="container mx-auto px-6 md:px-12 relative z-10 mb-24">
<div className="flex flex-col lg:flex-row justify-between gap-16 lg:gap-8">
{/* Left: Branding & Tagline */}
<div className="flex flex-col gap-6 max-w-sm">
<div className="text-3xl font-bold tracking-tighter text-white">
NotJustAn.<span className="text-[var(--color-accent)]">Agency</span>
</div>
<p className="text-neutral-400 text-sm leading-relaxed">
We take a product-first approach to growth. Auditing your business foundations and market fit before we pour ad spend into scaling your reach. predictable revenue architectures.
</p>
</div>
{/* Right: Grid of links & info */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-10 md:gap-16 w-full lg:w-auto">
{/* Column 1: Navigation */}
<div className="flex flex-col gap-5">
<span className="text-[10px] font-mono text-neutral-500 uppercase tracking-widest">Navigation</span>
<ul className="flex flex-col gap-3">
<li><a href="#" className="text-neutral-300 hover:text-[var(--color-accent)] transition-colors text-sm">Home</a></li>
<li><a href="#" className="text-neutral-300 hover:text-[var(--color-accent)] transition-colors text-sm">Philosophy</a></li>
<li><a href="#" className="text-neutral-300 hover:text-[var(--color-accent)] transition-colors text-sm">Capabilities</a></li>
<li><a href="#" className="text-neutral-300 hover:text-[var(--color-accent)] transition-colors text-sm">Contact</a></li>
</ul>
</div>
{/* Column 2: Contact */}
<div className="flex flex-col gap-5">
<span className="text-[10px] font-mono text-neutral-500 uppercase tracking-widest">Contact</span>
<div className="flex flex-col gap-3">
<a href="mailto:hello@notjustan.agency" className="text-neutral-300 hover:text-[var(--color-accent)] transition-colors text-sm">hello@notjustan.agency</a>
<a href="tel:+43123456789" className="text-neutral-300 hover:text-[var(--color-accent)] transition-colors text-sm">+43 660 321 4968</a>
</div>
</div>
{/* Column 3: Location */}
<div className="flex flex-col gap-5">
<span className="text-[10px] font-mono text-neutral-500 uppercase tracking-widest">Location</span>
<div className="flex flex-col gap-3">
<p className="text-neutral-300 text-sm">Vienna, Austria</p>
<p className="text-neutral-500 text-xs">CET Timezone</p>
</div>
</div>
{/* Column 4: Hours */}
<div className="flex flex-col gap-5">
<span className="text-[10px] font-mono text-neutral-500 uppercase tracking-widest">Open Time</span>
<div className="flex flex-col gap-3">
<p className="text-neutral-300 text-sm">Mon &mdash; Fri</p>
<p className="text-neutral-500 text-xs">09:00 - 18:00 (CET)</p>
</div>
</div>
</div>
</div>
</div>
{/* Massive Rolling Marquee */}
<div className="relative w-full overflow-hidden py-4 border-t border-white/5 bg-[#0a0a0a] flex items-end">
<style dangerouslySetInnerHTML={{
__html: `
@keyframes marquee-left {
0% { transform: translateX(0); }
100% { transform: translateX(-100%); }
}
.animate-marquee-infinite {
animation: marquee-left 25s linear infinite;
}
`}} />
<div className="flex whitespace-nowrap overflow-hidden">
<div className="animate-marquee-infinite flex shrink-0 items-center justify-around gap-8 md:gap-16 pr-8 md:pr-16">
<h1 className="text-7xl md:text-[10rem] lg:text-[15rem] font-bold text-[#141416] uppercase tracking-tighter leading-none select-none transition-colors duration-500 hover:text-[#1c1c1f]">NotJustAn.Agency</h1>
<h1 className="text-7xl md:text-[10rem] lg:text-[15rem] font-bold text-[#141416] uppercase tracking-tighter leading-none select-none transition-colors duration-500 hover:text-[#1c1c1f]">NotJustAn.Agency</h1>
</div>
{/* Duplicate track to seamlessly loop */}
<div className="animate-marquee-infinite flex shrink-0 items-center justify-around gap-8 md:gap-16 pr-8 md:pr-16" aria-hidden="true">
<h1 className="text-7xl md:text-[10rem] lg:text-[15rem] font-bold text-[#141416] uppercase tracking-tighter leading-none select-none transition-colors duration-500 hover:text-[#1c1c1f]">NotJustAn.Agency</h1>
<h1 className="text-7xl md:text-[10rem] lg:text-[15rem] font-bold text-[#141416] uppercase tracking-tighter leading-none select-none transition-colors duration-500 hover:text-[#1c1c1f]">NotJustAn.Agency</h1>
</div>
</div>
{/* Overlaying gradient to smoothly fade the edges into the background */}
<div className="absolute inset-0 bg-gradient-to-r from-[#050505] via-transparent to-[#050505] pointer-events-none z-10"></div>
</div>
{/* Copyright Legal Bar */}
<div className="border-t border-white/5 py-6 bg-[#030303]">
<div className="container mx-auto px-6 md:px-12 flex flex-col md:flex-row justify-between items-center gap-4">
<p className="text-xs text-neutral-600 font-mono">
© {new Date().getFullYear()} NotJustAn.Agency. All rights reserved.
</p>
<div className="flex gap-6">
<a href="#" className="text-xs text-neutral-600 hover:text-[var(--color-accent)] transition-colors">Privacy Policy</a>
<a href="#" className="text-xs text-neutral-600 hover:text-[var(--color-accent)] transition-colors">Imprint</a>
</div>
</div>
</div>
</footer>
);
}

View File

@@ -0,0 +1,146 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ArrowRight } from 'lucide-react';
import LiveClock from './LiveClock';
// Hardcoded paths fetched from Simple Icons (to guarantee visibility)
const logoPaths = {
shopify: "M15.337 23.979l7.216-1.561s-2.604-17.613-2.625-17.73c-.018-.116-.114-.192-.211-.192s-1.929-.136-1.929-.136-1.275-1.274-1.439-1.411c-.045-.037-.075-.057-.121-.074l-.914 21.104h.023zM11.71 11.305s-.81-.424-1.774-.424c-1.447 0-1.504.906-1.504 1.141 0 1.232 3.24 1.715 3.24 4.629 0 2.295-1.44 3.76-3.406 3.76-2.354 0-3.54-1.465-3.54-1.465l.646-2.086s1.245 1.066 2.28 1.066c.675 0 .975-.545.975-.932 0-1.619-2.654-1.694-2.654-4.359-.034-2.237 1.571-4.416 4.827-4.416 1.257 0 1.875.361 1.875.361l-.945 2.715-.02.01zM11.17.83c.136 0 .271.038.405.135-.984.465-2.064 1.639-2.508 3.992-.656.213-1.293.405-1.889.578C7.697 3.75 8.951.84 11.17.84V.83zm1.235 2.949v.135c-.754.232-1.583.484-2.394.736.466-1.777 1.333-2.645 2.085-2.971.193.501.309 1.176.309 2.1zm.539-2.234c.694.074 1.141.867 1.429 1.755-.349.114-.735.231-1.158.366v-.252c0-.752-.096-1.371-.271-1.871v.002zm2.992 1.289c-.02 0-.06.021-.078.021s-.289.075-.714.21c-.423-1.233-1.176-2.37-2.508-2.37h-.115C12.135.209 11.669 0 11.265 0 8.159 0 6.675 3.877 6.21 5.846c-1.194.365-2.063.636-2.16.674-.675.213-.694.232-.772.87-.075.462-1.83 14.063-1.83 14.063L15.009 24l.927-21.166z",
wordpress: "M21.469 6.825c.84 1.537 1.318 3.3 1.318 5.175 0 3.979-2.156 7.456-5.363 9.325l3.295-9.527c.615-1.54.82-2.771.82-3.864 0-.405-.026-.78-.07-1.11m-7.981.105c.647-.03 1.232-.105 1.232-.105.582-.075.514-.93-.067-.899 0 0-1.755.135-2.88.135-1.064 0-2.85-.15-2.85-.15-.585-.03-.661.855-.075.885 0 0 .54.061 1.125.09l1.68 4.605-2.37 7.08L5.354 6.9c.649-.03 1.234-.1 1.234-.1.585-.075.516-.93-.065-.896 0 0-1.746.138-2.874.138-.2 0-.438-.008-.69-.015C4.911 3.15 8.235 1.215 12 1.215c2.809 0 5.365 1.072 7.286 2.833-.046-.003-.091-.009-.141-.009-1.06 0-1.812.923-1.812 1.914 0 .89.513 1.643 1.06 2.531.411.72.89 1.643.89 2.977 0 .915-.354 1.994-.821 3.479l-1.075 3.585-3.9-11.61.001.014zM12 22.784c-1.059 0-2.081-.153-3.048-.437l3.237-9.406 3.315 9.087c.024.053.05.101.078.149-1.12.393-2.325.609-3.582.609M1.211 12c0-1.564.336-3.05.935-4.39L7.29 21.709C3.694 19.96 1.212 16.271 1.211 12M12 0C5.385 0 0 5.385 0 12s5.385 12 12 12 12-5.385 12-12S18.615 0 12 0",
n8n: "M21.4737 5.6842c-1.1772 0-2.1663.8051-2.4468 1.8947h-2.8955c-1.235 0-2.289.893-2.492 2.111l-.1038.623a1.263 1.263 0 0 1-1.246 1.0555H11.289c-.2805-1.0896-1.2696-1.8947-2.4468-1.8947s-2.1663.8051-2.4467 1.8947H4.973c-.2805-1.0896-1.2696-1.8947-2.4468-1.8947C1.1311 9.4737 0 10.6047 0 12s1.131 2.5263 2.5263 2.5263c1.1772 0 2.1663-.8051 2.4468-1.8947h1.4223c.2804 1.0896 1.2696 1.8947 2.4467 1.8947 1.1772 0 2.1663-.8051 2.4468-1.8947h1.0008a1.263 1.263 0 0 1 1.2459 1.0555l.1038.623c.203 1.218 1.257 2.111 2.492 2.111h.3692c.2804 1.0895 1.2696 1.8947 2.4468 1.8947 1.3952 0 2.5263-1.131 2.5263-2.5263s-1.131-2.5263-2.5263-2.5263c-1.1772 0-2.1664.805-2.4468 1.8947h-.3692a1.263 1.263 0 0 1-1.246-1.0555l-.1037-.623A2.52 2.52 0 0 0 13.9607 12a2.52 2.52 0 0 0 .821-1.4794l.1038-.623a1.263 1.263 0 0 1 1.2459-1.0555h2.8955c.2805 1.0896 1.2696 1.8947 2.4468 1.8947 1.3952 0 2.5263-1.131 2.5263-2.5263s-1.131-2.5263-2.5263-2.5263m0 1.2632a1.263 1.263 0 0 1 1.2631 1.2631 1.263 1.263 0 0 1-1.2631 1.2632 1.263 1.263 0 0 1-1.2632-1.2632 1.263 1.263 0 0 1 1.2632-1.2631M2.5263 10.7368A1.263 1.263 0 0 1 3.7895 12a1.263 1.263 0 0 1-1.2632 1.2632A1.263 1.263 0 0 1 1.2632 12a1.263 1.263 0 0 1 1.2631-1.2632m6.3158 0A1.263 1.263 0 0 1 10.1053 12a1.263 1.263 0 0 1-1.2632 1.2632A1.263 1.263 0 0 1 7.579 12a1.263 1.263 0 0 1 1.2632-1.2632m10.1053 3.7895a1.263 1.263 0 0 1 1.2631 1.2632 1.263 1.263 0 0 1-1.2631 1.2631 1.263 1.263 0 0 1-1.2632-1.2631 1.263 1.263 0 0 1 1.2632-1.2632",
figma: "M15.852 8.981h-4.588V0h4.588c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.491-4.49 4.491zM12.735 7.51h3.117c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-3.117V7.51zm0 1.471H8.148c-2.476 0-4.49-2.014-4.49-4.49S5.672 0 8.148 0h4.588v8.981zm-4.587-7.51c-1.665 0-3.019 1.355-3.019 3.019s1.354 3.02 3.019 3.02h3.117V1.471H8.148zm4.587 15.019H8.148c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h4.588v8.98zM8.148 8.981c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h3.117V8.981H8.148zM8.172 24c-2.489 0-4.515-2.014-4.515-4.49s2.014-4.49 4.49-4.49h4.588v4.441c0 2.503-2.047 4.539-4.563 4.539zm-.024-7.51a3.023 3.023 0 0 0-3.019 3.019c0 1.665 1.365 3.019 3.044 3.019 1.705 0 3.093-1.376 3.093-3.068v-2.97H8.148zm7.704 0h-.098c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h.098c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.49-4.49 4.49zm-.097-7.509c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h.098c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-.098z"
};
export default function HeroSection() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
let tl: gsap.core.Timeline;
const ctx = gsap.context(() => {
// Main Entrance Timeline
tl = gsap.timeline({ paused: true });
// Background Lines Entrance (staggered)
[1, 2, 3, 4].forEach((index) => {
tl.from(`.bg-line-${index}`, {
y: -500,
opacity: 0,
duration: 4,
ease: "power2.out"
}, index * 0.3);
});
// Text Reveal
tl.from(".hero-text-line", {
y: 100,
opacity: 0,
duration: 2,
stagger: 0.15,
ease: "power4.out",
onComplete: () => {
gsap.set(".hero-text-mask", { overflow: "visible" });
}
}, 0.2); // starts near the beginning relative to lines
}, containerRef);
const playAnimations = () => {
if (tl) tl.play();
};
if (typeof window !== 'undefined') {
if ((window as any).loadingComplete) {
playAnimations();
} else {
window.addEventListener('loadingComplete', playAnimations);
}
}
return () => {
ctx.revert();
if (typeof window !== 'undefined') {
window.removeEventListener('loadingComplete', playAnimations);
}
};
}, []);
const logos = [
{ icon: logoPaths.shopify, name: "Shopify", desc: "Storefronts" },
{ icon: logoPaths.wordpress, name: "WordPress", desc: "Flexible CMS" },
{ icon: logoPaths.n8n, name: "n8n", desc: "Automation" },
{ icon: logoPaths.figma, name: "Figma", desc: "Pro Design" },
];
const renderIcon = (path: string) => (
<svg role="img" viewBox="0 0 24 24" className="w-8 h-8 fill-white group-hover:fill-[var(--color-accent)] transition-colors duration-300">
<path d={path} />
</svg>
);
return (
<section ref={containerRef} className="relative min-h-screen flex items-center justify-center overflow-hidden pt-32 pb-10 md:py-20 bg-neutral-950">
<div className="absolute inset-0 translate-x-[80vw] md:translate-x-[60vw] xl:translate-x-[45vw] pointer-events-none">
<div className='-z-10 flex flex-col space-y-24 items-center'>
<div className="bg-line-1 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-70deg] scale-110 opacity-50 will-change-transform" />
<div className="bg-line-2 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-70deg] scale-110 opacity-30 will-change-transform" />
<div className="bg-line-3 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-70deg] scale-110 opacity-15 will-change-transform" />
<div className="bg-line-4 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-70deg] scale-110 opacity-10 will-change-transform" />
</div>
</div>
<div className="absolute inset-0 translate-x-[-80vw] md:translate-x-[-60vw] xl:translate-x-[-45vw] pointer-events-none">
<div className='-z-10 flex flex-col space-y-24 items-center'>
<div className="bg-line-1 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-110deg] scale-110 opacity-50 will-change-transform" />
<div className="bg-line-2 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-110deg] scale-110 opacity-30 will-change-transform" />
<div className="bg-line-3 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-110deg] scale-110 opacity-15 will-change-transform" />
<div className="bg-line-4 h-[2px] w-[200vmax] bg-[var(--color-accent)] transform rotate-[-110deg] scale-110 opacity-10 will-change-transform" />
</div>
</div>
<div className="container mx-auto px-6 md:px-12 relative z-11 gap-10 lg:gap-20 items-center">
{/* Left Content (Text) */}
<div className="z-[11] lg:col-span-12 space-y-6 text-center">
{/* Background Noise & Gradient */}
{/* Responsive text size: 3xl for mobile, 5xl for tablet, 7xl for desktop */}
<h1 className="text-3xl md:text-5xl lg:text-7xl xl:text-8xl 2xl:text-9xl font-bold leading-[1.0] lg:leading-[0.95] tracking-tighter flex flex-col gap-2">
<div className="hero-text-mask overflow-hidden p-2 -m-2 md:p-4 md:-m-4"><div className="hero-text-line whitespace-nowrap will-change-transform">
<span className="text-white">Fully Booked</span> <span className="text-neutral-500">Restaurants.</span>
</div></div>
<div className="hero-text-mask overflow-hidden p-2 -m-2 md:p-4 md:-m-4"><div className="hero-text-line whitespace-nowrap will-change-transform">
<span className="text-white">Sold-Out</span> <span className="text-neutral-500">Collections.</span>
</div></div>
<div className="hero-text-mask overflow-hidden p-2 -m-2 md:p-4 md:-m-4"><div className="hero-text-line whitespace-nowrap will-change-transform">
<span className="text-neutral-400">Brands</span> <span className="text-[var(--color-accent)]">Built to Last.</span>
</div></div>
</h1>
<p className="hero-text-line font-mono text-base md:text-lg text-neutral-500 mt-4">
[with NotJustAn.Agency]
</p>
<div className="hero-text-line pt-4 flex flex-col sm:flex-row gap-6 items-center justify-center">
<button className="group relative px-6 py-3 md:px-8 md:py-4 bg-[var(--color-accent)] text-black font-bold text-base md:text-lg rounded-full overflow-hidden transition-all hover:shadow-[0_0_40px_rgba(204,255,0,0.3)] hover:scale-105">
<span className="relative z-10 flex items-center gap-2">
Contact us <ArrowRight className="w-5 h-5 transition-transform group-hover:translate-x-1" />
</span>
</button>
<div className="font-mono text-xs md:text-sm text-neutral-500 flex flex-col items-center lg:items-start gap-1">
<div className="flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span>
<span>VIENNA, AT</span>
</div>
<span className="flex gap-2 text-neutral-400">
TIME: <LiveClock />
</span>
</div>
</div>
</div>
</div>
{/* Black Gradient from bottom, full width, for seamless transition to next section*/}
<div className="z-[10] absolute w-full h-full bottom-0 left-0 bg-gradient-to-b from-transparent via-transparent to-neutral-950"></div>
</section>
);
}

View File

@@ -0,0 +1,126 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { ArrowRight, BookOpen } from 'lucide-react';
gsap.registerPlugin(ScrollTrigger);
export default function InsightsSection() {
const containerRef = useRef<HTMLElement>(null);
useEffect(() => {
let ctx = gsap.context(() => {
gsap.from(".insight-header > *", {
scrollTrigger: {
trigger: containerRef.current,
start: "top 80%",
},
y: 30,
opacity: 0,
duration: 1,
stagger: 0.1,
ease: "power2.out"
});
gsap.from(".insight-card", {
scrollTrigger: {
trigger: ".insights-grid",
start: "top 75%",
},
y: 50,
opacity: 0,
duration: 1,
stagger: 0.15,
ease: "power3.out"
});
}, containerRef);
return () => ctx.revert();
}, []);
const insights = [
{
category: "Performance Marketing",
title: "The Post-Click Era: Why traditional ROAS is a broken metric.",
time: "5 MIN READ"
},
{
category: "Product Design",
title: "Designing for Conversion: The extreme psychological warfare behind every UI pixel.",
time: "8 MIN READ"
},
{
category: "Brand Strategy",
title: "Commodity vs. Cult: Architecting an absolutely irreplaceable identity.",
time: "6 MIN READ"
}
];
return (
<section ref={containerRef} className="relative py-24 md:py-32 bg-neutral-950 border-t border-white/5 overflow-hidden">
<div className="container mx-auto px-6 md:px-12 relative z-10 w-full max-w-7xl">
{/* Header Block */}
<div className="flex flex-col md:flex-row md:items-end justify-between mb-16 gap-6 insight-header">
<div>
<div className="mb-6 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/5 border border-white/10 shadow-[0_0_20px_rgba(0,0,0,0.5)]">
<BookOpen className="w-4 h-4 text-[var(--color-accent)]" />
<span className="text-xs font-mono tracking-wider text-neutral-300 uppercase">Education & Trust</span>
</div>
<h2 className="text-4xl sm:text-5xl md:text-6xl font-bold tracking-tighter text-white">
Intel & <span className="text-neutral-500">Insights</span>
</h2>
</div>
<a href="#resources" className="group flex items-center gap-2 text-[var(--color-accent)] hover:text-white transition-colors pb-2">
<span className="font-mono text-xs sm:text-sm tracking-widest uppercase font-bold">Read the Blueprints</span>
<ArrowRight className="w-4 h-4 transform group-hover:translate-x-1 transition-transform" />
</a>
</div>
{/* 3-Column Card Grid */}
<div className="insights-grid grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{insights.map((insight, i) => (
<a key={i} href="#guide" className="insight-card group flex flex-col gap-6 cursor-pointer">
{/* Premium Pattern Data Container (Replacing flat images) */}
<div className="relative w-full aspect-[4/3] bg-[#0c0c0c] overflow-hidden rounded-xl border border-white/5 group-hover:border-[var(--color-accent)]/30 transition-colors duration-500">
{/* Abstract technical grid texture */}
<div className="absolute inset-0 opacity-[0.03] group-hover:opacity-10 transition-opacity duration-700" style={{ backgroundImage: 'radial-gradient(white 1px, transparent 1px)', backgroundSize: '24px 24px' }}></div>
<div className="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent"></div>
{/* Abstract pulsing glow linked to hover */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-40 h-40 bg-[var(--color-accent)]/5 blur-[50px] rounded-full group-hover:bg-[var(--color-accent)]/20 group-hover:scale-[2] transition-all duration-700 ease-out"></div>
{/* High-tech diagonal scanline overlay */}
<div className="absolute inset-0 opacity-20" style={{ background: 'repeating-linear-gradient(45deg, transparent, transparent 2px, rgba(255,255,255,0.05) 2px, rgba(255,255,255,0.05) 4px)' }}></div>
{/* Floating Category Badge inside container */}
<div className="absolute bottom-4 left-4 z-10">
<span className="px-3 py-1 bg-black/60 backdrop-blur-md border border-[var(--color-accent)]/20 rounded text-[10px] sm:text-xs font-mono text-white tracking-widest uppercase">
{insight.category}
</span>
</div>
</div>
{/* Text & Meta Content */}
<div className="flex flex-col gap-4 flex-1">
<h3 className="text-xl sm:text-2xl font-bold text-neutral-200 leading-tight group-hover:text-white transition-colors duration-300">
{insight.title}
</h3>
<div className="flex items-center justify-between mt-auto pt-4 border-t border-white/10">
<span className="text-[10px] sm:text-xs font-mono text-neutral-500 tracking-widest">{insight.time}</span>
<div className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center group-hover:bg-[var(--color-accent)] group-hover:text-black transition-colors duration-300 transform group-hover:translate-x-1">
<ArrowRight className="w-4 h-4" />
</div>
</div>
</div>
</a>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,24 @@
import React, { useState, useEffect } from 'react';
export default function LiveClock() {
const [time, setTime] = useState<string>("");
useEffect(() => {
const updateTime = () => {
const now = new Date();
setTime(now.toLocaleTimeString("de-AT", {
timeZone: "Europe/Vienna",
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}));
};
updateTime();
const interval = setInterval(updateTime, 1000);
return () => clearInterval(interval);
}, []);
return <span suppressHydrationWarning>{time}</span>;
}

View File

@@ -0,0 +1,69 @@
import React, { useLayoutEffect, useRef, useState } from 'react';
import { gsap } from 'gsap';
export default function LoadingScreen() {
const [isComplete, setIsComplete] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const timelineRef = useRef<GSAPTimeline | null>(null);
useLayoutEffect(() => {
const ctx = gsap.context(() => {
const tl = gsap.timeline({
onComplete: () => {
setIsComplete(true);
if (typeof window !== 'undefined') {
(window as any).loadingComplete = true;
window.dispatchEvent(new Event('loadingComplete'));
}
}
});
timelineRef.current = tl;
// Initial State
gsap.set(".loading-text span", { y: 30, opacity: 0 });
// 1. Text Animation In
tl.to(".loading-text span", {
y: 0,
opacity: 1,
duration: 0.8,
stagger: 0.1,
ease: "power3.out"
})
// 2. Text Animation Out
.to(".loading-text span", {
y: -30,
opacity: 0,
duration: 0.5,
stagger: 0.05,
ease: "power3.in",
delay: 0
})
// 3. Final Curtain Reveal
.to(".loading-curtain", {
height: 0,
duration: 1.2,
ease: "power4.inOut"
}, "+=0.1");
}, containerRef);
return () => ctx.revert();
}, []);
if (isComplete) return null;
return (
<div ref={containerRef} className="fixed inset-0 z-50 flex items-center justify-center">
<div className="loading-curtain absolute inset-0 bg-neutral-950 flex items-center justify-center overflow-hidden">
{/* Text Container */}
<div className="loading-text absolute flex gap-2 overflow-hidden text-4xl md:text-6xl font-bold text-white tracking-tighter z-10">
<span className="inline-block">NotJustAn</span>
<span className="inline-block text-[var(--color-accent)]">.Agency</span>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,100 @@
import React, { useState, useEffect } from 'react';
import { Menu, X } from 'lucide-react';
import { gsap } from 'gsap';
export default function Navigation() {
const [isOpen, setIsOpen] = useState(false);
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const handleScroll = () => {
setScrolled(window.scrollY > 50);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
useEffect(() => {
if (isOpen) {
gsap.to(".mobile-menu", { height: "auto", opacity: 1, duration: 0.3 });
} else {
gsap.to(".mobile-menu", { height: 0, opacity: 0, duration: 0.3 });
}
}, [isOpen]);
const links = [
{ name: 'Portfolio', href: '#' },
{ name: 'Solutions', href: '#' },
{ name: 'Legal Notice', href: '#' },
];
return (
<nav className={`fixed top-0 left-0 right-0 z-40 transition-all duration-300 ${scrolled ? 'py-4' : 'py-6'}`}>
<div className={`mx-auto px-6 md:px-12 transition-all duration-300 ${scrolled ? 'max-w-4xl' : 'max-w-7xl'}`}>
<div className={`relative flex items-center justify-between p-4 rounded-2xl border transition-all duration-300 ${scrolled
? 'bg-neutral-900/80 backdrop-blur-md border-white/10 shadow-lg shadow-black/50'
: 'bg-transparent border-transparent'
}`}>
{/* Logo */}
<div className="text-xl font-bold tracking-tighter">
NotJustAn<span className="text-[var(--color-accent)]">.Agency</span>
</div>
{/* Desktop Links */}
<div className="hidden md:flex items-center gap-8">
{links.map((link) => (
<a
key={link.name}
href={link.href}
className="text-sm font-medium text-neutral-300 hover:text-white transition-colors relative group"
>
{link.name}
<span className="absolute -bottom-1 left-0 w-0 h-0.5 bg-[var(--color-accent)] transition-all group-hover:w-full" />
</a>
))}
<a
href="#"
className="px-5 py-2.5 bg-white text-black text-sm font-bold rounded-full hover:bg-[var(--color-accent)] transition-colors"
>
Client Portal
</a>
</div>
{/* Mobile Toggle */}
<button
className="md:hidden text-white"
onClick={() => setIsOpen(!isOpen)}
>
{isOpen ? <X /> : <Menu />}
</button>
</div>
{/* Mobile Menu */}
<div className="mobile-menu h-0 opacity-0 overflow-hidden md:hidden mt-2">
<div className="bg-neutral-900/90 backdrop-blur-xl border border-white/10 rounded-2xl p-6 flex flex-col gap-4">
{links.map((link) => (
<a
key={link.name}
href={link.href}
className="text-lg font-medium text-white hover:text-[var(--color-accent)]"
onClick={() => setIsOpen(false)}
>
{link.name}
</a>
))}
<hr className="border-white/10 my-2" />
<a
href="#"
className="text-center px-5 py-3 bg-white text-black font-bold rounded-xl hover:bg-[var(--color-accent)] transition-colors"
>
Client Portal
</a>
</div>
</div>
</div>
</nav>
);
}

View File

@@ -0,0 +1,96 @@
import React from 'react';
import { Check } from 'lucide-react';
const offersData = [
{
id: "core",
title: "Core Transformation",
description: "Complete digital overhaul for established brands seeking dominance.",
price: "€5,000+",
features: ["SEO & Keywords", "Copywriting", "Conversion Opt.", "Lead Gen", "Custom CMS", "Analytics"],
buttonText: "Get Started",
isPopular: true,
cardClasses: "min-h-[500px] md:min-h-0 md:h-full border-white/10 relative group hover:border-[var(--color-accent)]/50",
buttonClasses: "bg-white text-black hover:bg-[var(--color-accent)]",
},
{
id: "essential",
title: "Essential Presence",
description: "For emerging businesses needing a professional foothold.",
price: "€2,500+",
features: ["SEO & Keywords", "Copywriting", "Conversion Opt."],
buttonText: "Select Plan",
isPopular: false,
cardClasses: "min-h-[450px] md:min-h-0 md:h-[85%] border-white/5 hover:bg-white/5",
buttonClasses: "border border-white/20 text-white hover:bg-white/10",
},
{
id: "basic",
title: "Basic Website",
description: "For small businesses needing a professional online presence.",
price: "€600+",
features: ["Web Design", "Custom CMS", "Analytics"],
buttonText: "Claim Now",
isPopular: false,
cardClasses: "min-h-[400px] md:min-h-0 md:h-[75%] border-white/5 bg-[var(--color-accent)]/5",
buttonClasses: "border border-[var(--color-accent)] text-[var(--color-accent)] hover:bg-[var(--color-accent)] hover:text-black",
},
{
id: "free",
title: "Free Audit",
description: "Detailed analysis of your current digital standing.",
price: "Free",
features: ["SEO Report", "UX Review"],
buttonText: "Claim Now",
isPopular: false,
cardClasses: "min-h-[400px] md:min-h-0 md:h-[75%] border-white/5 bg-[var(--color-accent)]/5",
buttonClasses: "border border-[var(--color-accent)] text-[var(--color-accent)] hover:bg-[var(--color-accent)] hover:text-black",
}
];
export default function OfferSection() {
return (
<section className="relative min-h-screen bg-neutral-950 text-white py-20 overflow-hidden flex flex-col justify-center">
<div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-10 pointer-events-none"></div>
<div className="container mx-auto px-4 mb-8 md:mb-12 relative z-10">
<h2 className="text-4xl md:text-6xl font-bold text-center">Our <span className="text-[var(--color-accent)]">Offers</span></h2>
</div>
<div className="w-full max-w-7xl mx-auto px-4 xl:px-0 relative z-10">
<div className="flex flex-col md:flex-row gap-8 md:gap-10 w-full md:h-[60vh] md:items-center justify-center">
{offersData.map((offer) => (
<div key={offer.id} className={`offer-card w-full md:flex-1 p-8 glass rounded-3xl border flex flex-col justify-between transition-colors ${offer.cardClasses}`}>
{offer.isPopular && (
<div className="absolute -top-4 -right-2 md:-right-4 bg-[var(--color-accent)] text-black font-bold px-4 py-1 rounded-full text-sm transform rotate-6 shadow-lg shadow-[var(--color-accent)]/20">
MOST POPULAR
</div>
)}
<div>
<h3 className="text-2xl md:text-3xl font-bold mb-4">{offer.title}</h3>
<p className="text-neutral-400 mb-6 text-sm md:text-base">{offer.description}</p>
<ul className="space-y-3">
{offer.features.map((feature, index) => (
<li key={index} className="flex items-center gap-2 text-sm md:text-base">
<Check className="text-[var(--color-accent)] shrink-0" size={18} />
<span>{feature}</span>
</li>
))}
</ul>
</div>
<div className="mt-8">
<div className="text-2xl md:text-3xl font-bold mb-2">{offer.price}</div>
<button className={`w-full py-4 font-bold rounded-xl transition-colors cursor-pointer ${offer.buttonClasses}`}>
{offer.buttonText}
</button>
</div>
</div>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,235 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { Database, Filter, SlidersHorizontal, Plus } from 'lucide-react';
gsap.registerPlugin(ScrollTrigger);
export default function PerformanceMarketingSection() {
const containerRef = useRef<HTMLElement>(null);
useEffect(() => {
let ctx = gsap.context(() => {
// General Entrance
gsap.from(".fade-in-up", {
scrollTrigger: {
trigger: containerRef.current,
start: "top 75%",
},
y: 50,
opacity: 0,
duration: 1,
ease: "power3.out",
stagger: 0.15
});
// Looping Meta Ads Process Timeline
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".meta-ads-table",
start: "top 60%",
},
repeat: -1,
repeatDelay: 1.5
});
// Reset state
tl.set(".ad-row", { opacity: 1, backgroundColor: "transparent" })
.set(".toggle-switch", { backgroundColor: "#22c55e", justifyContent: "flex-end", borderColor: "transparent" })
.set(".toggle-knob", { x: 0 })
.set(".delivery-text", { innerText: "Learning", color: "#a3a3a3" })
.set(".roas-value", { innerText: "-" })
.set(".budget-val", { innerText: "$50.00", scale: 1, color: "inherit" })
.set(".loser-row", { opacity: 1 })
.set(".winner-row", { opacity: 1 });
// 1. Learning Phase -> Active
tl.to({}, { duration: 1 }) // simulate wait
.set(".delivery-text", { innerText: "Active", color: "#4ade80" }) // Green text for active
.to({}, { duration: 0.5 }); // buffer
// 2. Data Populates (ROAS appears)
tl.set(".roas-value.fail-1", { innerText: "0.82" })
.set(".roas-value.win-1", { innerText: "4.15" })
.set(".roas-value.fail-2", { innerText: "1.05" })
.set(".roas-value.win-2", { innerText: "6.80" })
// Wait for media buyer to "read" data
tl.to({}, { duration: 1.5 });
// 3. Cut Losers
tl.set(".loser-row .delivery-text", { innerText: "Off", color: "#737373" })
.to(".loser-row .toggle-switch", { backgroundColor: "transparent", borderColor: "#52525b", duration: 0.2 })
.to(".loser-row .toggle-knob", { x: -12, backgroundColor: "#52525b", duration: 0.2 }, "<")
.to(".loser-row", { opacity: 0.3, duration: 0.4 }, "<");
// Wait a sec before scaling
tl.to({}, { duration: 0.5 });
// 4. Scale Winners
tl.to(".winner-row", { backgroundColor: "rgba(204, 255, 0, 0.05)", duration: 0.3 })
.set(".budget-val.win-1", { innerText: "$250.00" })
.set(".budget-val.win-2", { innerText: "$500.00" })
// Flashing effect for budget update
.to(".budget-val.win-1, .budget-val.win-2", { scale: 1.1, color: "var(--color-accent)", duration: 0.2, yoyo: true, repeat: 1 })
.to(".winner-row", { backgroundColor: "transparent", duration: 1, delay: 0.5 });
// End of process hold
tl.to({}, { duration: 3 });
// Big Data Matrix Animation
const dataTl = gsap.timeline({ repeat: -1 });
dataTl.to(".data-node", {
opacity: () => Math.random() * 0.8 + 0.2,
scale: () => Math.random() * 0.5 + 0.8,
backgroundColor: () => Math.random() > 0.85 ? "var(--color-accent)" : "#3f3f46",
duration: 0.8,
stagger: {
each: 0.02,
from: "random"
},
ease: "sine.inOut",
});
}, containerRef);
return () => ctx.revert();
}, []);
const adSets = [
{ id: 1, name: "Broad - Static 1", type: "loser-row", rowClass: "fail-1" },
{ id: 2, name: "LAA 1% - Video 3", type: "winner-row", rowClass: "win-1" },
{ id: 3, name: "Retargeting - Carousel", type: "loser-row", rowClass: "fail-2" },
{ id: 4, name: "Broad - Video 2", type: "winner-row", rowClass: "win-2" },
];
return (
<section ref={containerRef} className="relative py-32 bg-neutral-950 overflow-hidden">
{/* Background Gradient */}
<div className="absolute top-0 inset-x-0 h-px bg-gradient-to-r from-transparent via-neutral-800 to-transparent"></div>
<div className="container mx-auto px-6 md:px-12 relative z-10 grid grid-cols-1 lg:grid-cols-12 gap-16 items-center">
{/* LEFT SIDE: Meta Ads Simulation */}
<div className="lg:col-span-7 w-full fade-in-up order-2 lg:order-1">
<div className="meta-ads-table w-full rounded-xl bg-[#18181b] border border-white/10 shadow-[0_0_80px_rgba(0,0,0,0.8)] overflow-hidden text-sm font-sans flex flex-col">
{/* Fake Ads Manager Header */}
<div className="border-b border-white/5 bg-[#27272a]/50 p-4 flex items-center justify-between">
<div className="flex items-center gap-4 text-neutral-300">
<div className="flex items-center gap-2">
<Database className="w-4 h-4" />
<span className="font-semibold text-white">Campaigns</span>
</div>
<div className="h-4 w-px bg-white/10"></div>
<div className="flex items-center gap-1 cursor-pointer hover:text-white transition-colors text-xs font-medium">
<Filter className="w-3.5 h-3.5" /> Filter
</div>
</div>
<div className="flex items-center gap-3">
<div className="bg-[#3f3f46] hover:bg-[#52525b] transition-colors cursor-pointer text-white px-3 py-1.5 rounded text-xs flex items-center gap-1 font-semibold border border-white/5">
<Plus className="w-3.5 h-3.5" /> Create
</div>
</div>
</div>
{/* Top Nav */}
<div className="px-4 py-2 border-b border-white/5 bg-[#18181b] flex items-center gap-6 text-xs font-medium text-neutral-400">
<span className="cursor-pointer hover:text-white pb-1 border-b-2 border-transparent">Campaigns</span>
<span className="cursor-pointer text-[var(--color-accent)] border-b-2 border-[var(--color-accent)] pb-1 font-bold">Ad Sets</span>
<span className="cursor-pointer hover:text-white pb-1 border-b-2 border-transparent">Ads</span>
</div>
{/* Table Header */}
<div className="grid grid-cols-12 gap-2 px-4 py-3 border-b border-white/5 text-xs text-neutral-400 font-semibold bg-[#27272a]/30">
<div className="col-span-5 flex items-center gap-2">
<div className="w-3 h-3 border border-neutral-600 rounded-sm"></div>
Ad Set Name
</div>
<div className="col-span-3">Delivery</div>
<div className="col-span-2 text-right">Budget</div>
<div className="col-span-2 text-right">ROAS</div>
</div>
{/* Table Body */}
<div className="flex flex-col">
{adSets.map((ad) => (
<div key={ad.id} className={`ad-row ${ad.type} grid grid-cols-12 gap-2 px-4 py-3 border-b border-white/5 items-center will-change-transform`}>
{/* Name Column */}
<div className="col-span-5 flex items-center gap-3">
<div className="w-3 h-3 border border-neutral-600 rounded-sm flex-shrink-0"></div>
<div className="toggle-switch w-7 h-4 bg-green-500 rounded-full flex items-center px-[2px] justify-end flex-shrink-0 border border-transparent">
<div className="toggle-knob w-3 h-3 bg-white rounded-full translate-x-0 will-change-transform"></div>
</div>
<span className="text-neutral-200 font-medium truncate">{ad.name}</span>
</div>
{/* Delivery Column */}
<div className="col-span-3 text-neutral-400 text-xs flex items-center">
<span className="delivery-text font-medium text-neutral-400">Learning</span>
</div>
{/* Budget Column */}
<div className="col-span-2 text-right text-neutral-300 font-mono text-[11px] md:text-xs">
<span className={`budget-val ${ad.rowClass} inline-block will-change-transform`}>$50.00</span>
</div>
{/* ROAS Column */}
<div className="col-span-2 text-right text-white font-mono font-medium text-[11px] md:text-xs">
<span className={`roas-value ${ad.rowClass}`}>-</span>
</div>
</div>
))}
</div>
{/* Footer Totals */}
<div className="px-4 py-3 bg-[#27272a]/30 grid grid-cols-12 gap-2 text-xs font-semibold text-neutral-300">
<div className="col-span-8 text-right text-neutral-500">Total</div>
<div className="col-span-2 text-right">-</div>
<div className="col-span-2 text-right text-neutral-400">2.41</div>
</div>
</div>
</div>
{/* RIGHT SIDE: Text & Big Data Viz */}
<div className="lg:col-span-5 flex flex-col justify-center order-1 lg:order-2">
<div className="fade-in-up mb-12">
<h2 className="text-4xl md:text-5xl font-bold tracking-tighter text-white mb-6">
Cut the losers.<br />
<span className="text-[var(--color-accent)]">Scale the winners.</span>
</h2>
<p className="text-lg text-neutral-400 leading-relaxed font-light">
We test meticulously, discard variations that dont meet target KPIs, and aggressively reallocate budget into ad creatives that drive actual revenue. No guesswork, just data.
</p>
</div>
{/* Big Data Matrix Visualization */}
<div className="fade-in-up w-full h-48 rounded-xl border border-white/5 bg-neutral-900/50 p-5 relative overflow-hidden flex flex-col justify-between shadow-inner">
<div className="text-xs text-neutral-500 font-mono flex items-center justify-between mb-4 z-10 relative">
<span>DATA AGGREGATION</span>
<SlidersHorizontal className="w-3.5 h-3.5" />
</div>
{/* Grid of Nodes */}
<div className="flex-1 grid grid-cols-10 sm:grid-cols-12 gap-3 content-end relative z-10">
{Array.from({ length: 48 }).map((_, i) => (
<div key={i} className="flex justify-center items-end h-full">
<div className="data-node w-1.5 h-1.5 bg-neutral-700 rounded-full will-change-transform"></div>
</div>
))}
</div>
{/* Overlay gradient for depth */}
<div className="absolute inset-0 bg-gradient-to-t from-neutral-950 via-transparent to-transparent pointer-events-none z-0"></div>
<div className="absolute -bottom-10 -right-10 w-32 h-32 bg-[var(--color-accent)]/5 blur-[40px] pointer-events-none rounded-full"></div>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,132 @@
import React, { useEffect, useRef, useState } from 'react';
import { gsap } from 'gsap';
import { ArrowUpRight, Fingerprint, MonitorSmartphone, TrendingUp, Printer, Lightbulb } from 'lucide-react';
const services = [
{
id: "01",
name: "Branding",
icon: <Fingerprint className="w-10 h-10 text-[var(--color-accent)] stroke-[1.5]" />
},
{
id: "02",
name: "Webdesign",
icon: <MonitorSmartphone className="w-10 h-10 text-[var(--color-accent)] stroke-[1.5]" />
},
{
id: "03",
name: "Performance Marketing",
icon: <TrendingUp className="w-10 h-10 text-[var(--color-accent)] stroke-[1.5]" />
},
{
id: "04",
name: "Print Design",
icon: <Printer className="w-10 h-10 text-[var(--color-accent)] stroke-[1.5]" />
},
{
id: "05",
name: "Consultancy",
icon: <Lightbulb className="w-10 h-10 text-[var(--color-accent)] stroke-[1.5]" />
}
];
export default function ServicesSection() {
const sectionRef = useRef<HTMLElement>(null);
const cursorRef = useRef<HTMLDivElement>(null);
const [isHovering, setIsHovering] = useState(false);
useEffect(() => {
// Initialize centering scale 0 natively in GSAP
gsap.set(cursorRef.current, { xPercent: -50, yPercent: -50, scale: 0 });
// Setting up GSAP quickTo for highly performant custom cursor
const xTo = gsap.quickTo(cursorRef.current, "x", { duration: 0.3, ease: "power3.out" });
const yTo = gsap.quickTo(cursorRef.current, "y", { duration: 0.3, ease: "power3.out" });
const mouseMove = (e: MouseEvent) => {
xTo(e.clientX);
yTo(e.clientY);
};
window.addEventListener("mousemove", mouseMove);
return () => window.removeEventListener("mousemove", mouseMove);
}, []);
// Handle scale up/down safely outside of the standard Tailwind classes preventing conflict
useEffect(() => {
if (isHovering) {
gsap.to(cursorRef.current, { scale: 1, opacity: 1, duration: 0.3, ease: "back.out(2)" });
} else {
gsap.to(cursorRef.current, { scale: 0, opacity: 0, duration: 0.3, ease: "power3.inOut" });
}
}, [isHovering]);
return (
<section
ref={sectionRef}
className="relative py-24 md:py-40 bg-neutral-950 overflow-hidden"
>
{/* Custom Interactive Cursor Block - handled completely by GSAP to prevent CSS conflicts */}
<div
ref={cursorRef}
className="hidden md:flex fixed top-0 left-0 w-12 h-12 bg-[var(--color-accent)] z-[100] rounded-sm pointer-events-none items-center justify-center will-change-transform"
style={{ opacity: 0, transform: 'scale(0)' }}
>
<ArrowUpRight className="w-10 h-10 text-black stroke-[3]" />
</div>
<div className="container mx-auto px-6 md:px-12 relative z-10 w-full max-w-7xl">
<div className="mb-16 md:mb-24">
<h2 className=" md:text-5xl font-bold text-neutral-100 mb-4 uppercase tracking-tighter">Not Just <span className="text-[var(--color-accent)]">Services</span></h2>
<div className="w-24 h-1 md:h-2 bg-[var(--color-accent)] mb-6"></div>
<p className="text-neutral-400 max-w-2xl text-lg font-light leading-relaxed">
We take a product-first approach to growth. Instead of pouring traffic into a leaky bucket, we audit your business foundations and market fit first. We ensure your core offering and user journey are structurally sound before we ever scale your reach, turning marketing spend into a predictable investment rather than an experiment.
</p>
</div>
<div
className="flex flex-col w-full border-t border-white/10 lg:w-[85%] ml-auto"
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
>
{services.map((service, index) => (
<div
key={index}
className="group relative flex flex-col md:flex-row md:items-center justify-start py-8 md:py-10 border-b border-white/10 md:cursor-none"
>
{/* Service Number */}
<div className="text-lg md:text-xl font-mono text-neutral-600 mb-4 md:mb-0 transition-colors duration-500 group-hover:text-[var(--color-accent)] w-16 md:w-20 flex-shrink-0">
{service.id}
</div>
{/* Expanding Glowing Icon Container that pushes the text right naturally */}
<div className="hidden lg:block w-0 h-[80px] overflow-hidden opacity-0 scale-95 transition-all duration-[600ms] ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:w-[120px] group-hover:opacity-100 group-hover:scale-100 group-hover:mr-8 origin-left flex-shrink-0 rounded-2xl relative">
<div className="absolute left-0 top-0 w-[120px] h-[80px] bg-neutral-900 border border-[var(--color-accent)]/30 rounded-2xl flex items-center justify-center shadow-[0_0_30px_rgba(204,255,0,0.15)] bg-gradient-to-br from-[#18181b] to-black overflow-hidden">
{/* Abstract background grid or glow inside the icon box */}
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(204,255,0,0.15),transparent_70%)] opacity-0 group-hover:opacity-100 transition-opacity duration-700"></div>
<div className="absolute inset-0" style={{ backgroundImage: 'radial-gradient(rgba(255,255,255,0.1) 1px, transparent 1px)', backgroundSize: '8px 8px', opacity: 0.3 }}></div>
{/* The glowing Icon */}
<div className="relative z-10 scale-90 group-hover:scale-110 transition-transform duration-500 drop-shadow-[0_0_15px_rgba(204,255,0,0.4)]">
{service.icon}
</div>
</div>
</div>
{/* Service Title */}
<h3 className="text-3xl sm:text-4xl lg:text-5xl font-bold uppercase tracking-tighter text-white transition-all duration-500 ease-out group-hover:text-[var(--color-accent)] z-20 flex-1 relative leading-[1.1]">
{service.name}
</h3>
</div>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,241 @@
import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { Target, Crosshair, Map, Navigation } from 'lucide-react';
gsap.registerPlugin(ScrollTrigger);
export default function StrategySection() {
const containerRef = useRef<HTMLElement>(null);
useEffect(() => {
let ctx = gsap.context(() => {
// Text Enter
gsap.from(".strategy-text > *", {
scrollTrigger: {
trigger: containerRef.current,
start: "top 75%",
},
y: 40,
opacity: 0,
duration: 1,
stagger: 0.15,
ease: "power3.out"
});
// Target Visual Timeline
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".target-visual",
start: "top 65%",
}
});
// Set initial states
tl.set(".target-ring", { scale: 0, opacity: 0, transformOrigin: "250px 250px" })
.set(".crosshair-line-h", { scaleX: 0, transformOrigin: "250px 250px" })
.set(".crosshair-line-v", { scaleY: 0, transformOrigin: "250px 250px" })
.set(".bullseye", { scale: 0, opacity: 0, transformOrigin: "250px 250px" })
.set(".floating-label", { opacity: 0, y: 15 })
.set(".trajectory-path", { strokeDasharray: 800, strokeDashoffset: 800 })
.set(".data-blip", { opacity: 0, scale: 0, transformOrigin: "center center" })
.set(".radar-sweep", { opacity: 0 });
// 1. Draw Crosshairs & Fade in Radar
tl.to(".crosshair-line-h", { scaleX: 1, duration: 1, ease: "power2.out", opacity: 0.2 })
.to(".crosshair-line-v", { scaleY: 1, duration: 1, ease: "power2.out", opacity: 0.2 }, "<")
.to(".radar-sweep", { opacity: 0.15, duration: 1 }, "<");
// 2. Expand Rings (ripple effect outward)
tl.to(".target-ring", { scale: 1, opacity: 1, duration: 1.2, stagger: 0.15, ease: "back.out(1.2)" }, "-=0.6");
// 3. Trace Trajectory path
tl.to(".trajectory-path", { strokeDashoffset: 0, duration: 2, ease: "power2.inOut" }, "-=0.2");
// 4. Hit Bullseye
tl.to(".bullseye", { scale: 1, opacity: 1, duration: 0.6, ease: "back.out(2)" })
// Flash outer glow
.to(".bullseye-glow", { opacity: 0.6, scale: 1.1, duration: 0.4 }, "<");
// 5. Pop Data Blips & Labels
tl.to(".data-blip", { opacity: 1, scale: 1, duration: 0.5, stagger: 0.1, ease: "back.out(2)" }, "-=0.3")
.to(".floating-label", { opacity: 1, y: 0, duration: 0.6, stagger: 0.1, ease: "power2.out" }, "<");
// --- Continuous background animations ---
// Dashed ring rotation slowly
gsap.to(".target-ring-dashed", {
rotation: 360,
duration: 60,
repeat: -1,
ease: "linear",
transformOrigin: "250px 250px"
});
// Radar sweep rotation
gsap.to(".radar-sweep", {
rotation: 360,
duration: 6,
repeat: -1,
ease: "linear",
transformOrigin: "250px 250px"
});
// Bullseye breathing glow
gsap.to(".bullseye-glow", {
scale: 1.3,
opacity: 0.2,
duration: 2,
repeat: -1,
yoyo: true,
ease: "sine.inOut"
});
// Blips randomly blinking
gsap.to(".data-blip", {
opacity: 0.2,
duration: 0.1,
stagger: {
each: 1.5,
from: "random",
repeat: -1,
yoyo: true
}
});
}, containerRef);
return () => ctx.revert();
}, []);
return (
<section ref={containerRef} className="relative py-32 bg-neutral-950 overflow-hidden">
{/* Background effects */}
<div className="absolute top-0 inset-x-0 h-px bg-gradient-to-r from-transparent via-neutral-800 to-transparent"></div>
<div className="container mx-auto px-6 md:px-12 relative z-10 grid grid-cols-1 lg:grid-cols-12 gap-16 lg:gap-8 items-center">
{/* LEFT SIDE: Text Content */}
<div className="lg:col-span-5 flex flex-col justify-center strategy-text z-20">
<div className="mb-6 inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/5 border border-white/10 w-max">
<Navigation className="w-4 h-4 text-[var(--color-accent)]" />
<span className="text-xs font-mono tracking-wider text-neutral-300 uppercase">The Masterplan</span>
</div>
<h2 className="text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-bold tracking-tighter text-white mb-6">
Strategy first.<br />
<span className="text-[var(--color-accent)]">Tactics second.</span>
</h2>
<p className="text-lg text-neutral-400 font-light leading-relaxed mb-10 xl:text-xl">
Execution without a masterplan is just making noise. Before we spend a single cent of your budget, we map the entire psychological battlefield. We find where your competitors are weak, where your audience is starving, and we strike with absolute precision.
</p>
<ul className="space-y-4">
{[
"Deep-dive Market Analysis",
"High-Converting Offer Structuring",
"Frictionless Funnel Engineering"
].map((point, i) => (
<li key={i} className="flex items-center gap-3 text-neutral-300 font-mono text-sm xl:text-base">
<div className="w-1.5 h-1.5 rounded-full bg-[var(--color-accent)] shadow-[0_0_8px_rgba(204,255,0,0.8)]"></div>
{point}
</li>
))}
</ul>
</div>
{/* RIGHT SIDE: Technical Diagram */}
<div className="lg:col-span-7 w-full flex justify-center lg:justify-end relative mt-10 lg:mt-0">
<div className="target-visual relative w-full aspect-square max-w-[550px]">
{/* Glowing backdrop behind entire target */}
<div className="bullseye-glow absolute inset-0 bg-[var(--color-accent)]/20 blur-[80px] rounded-full pointer-events-none opacity-0 scale-50 z-0"></div>
{/* SVG Layer */}
<svg viewBox="0 0 500 500" className="w-full h-full absolute inset-0 overflow-visible z-10">
<defs>
<radialGradient id="radarGrad" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor="var(--color-accent)" stopOpacity="0.8" />
<stop offset="100%" stopColor="var(--color-accent)" stopOpacity="0" />
</radialGradient>
<filter id="glowTarget" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="6" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<linearGradient id="trajectoryFade" x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stopColor="transparent" stopOpacity="0" />
<stop offset="50%" stopColor="var(--color-accent)" stopOpacity="1" />
<stop offset="100%" stopColor="white" stopOpacity="1" />
</linearGradient>
</defs>
{/* Inner structural grids */}
<circle cx="250" cy="250" r="240" className="stroke-white/5" fill="none" strokeWidth="1" strokeDasharray="2 12" />
{/* Crosshairs */}
<line x1="0" y1="250" x2="500" y2="250" className="crosshair-line-h stroke-white/20" strokeWidth="1" strokeDasharray="4 4" />
<line x1="250" y1="0" x2="250" y2="500" className="crosshair-line-v stroke-white/20" strokeWidth="1" strokeDasharray="4 4" />
{/* Radar Sweep Arc */}
<path d="M 250 250 L 250 10 A 240 240 0 0 1 420 80 Z" fill="url(#radarGrad)" className="radar-sweep opacity-0" style={{mixBlendMode: 'screen'}} />
{/* Concentric Rings */}
<circle cx="250" cy="250" r="200" className="target-ring stroke-white/10" fill="none" strokeWidth="1.5" />
<circle cx="250" cy="250" r="140" className="target-ring target-ring-dashed stroke-[var(--color-accent)]/40" fill="none" strokeWidth="1.5" strokeDasharray="4 8" />
<circle cx="250" cy="250" r="80" className="target-ring stroke-white/20" fill="none" strokeWidth="1.5" />
<circle cx="250" cy="250" r="30" className="target-ring stroke-[var(--color-accent)]/80" fill="transparent" strokeWidth="2" filter="url(#glowTarget)" />
{/* The precise trajectory of the strategy */}
{/* Starts bottom left, curves around obstacles to the center */}
<path d="M -50 480 C 100 480, 50 250, 250 250" className="trajectory-path stroke-white" fill="none" strokeWidth="3" strokeLinecap="round" filter="url(#glowTarget)" stroke="url(#trajectoryFade)" />
{/* Data Obstacles/Threats (Blips) */}
<circle cx="150" cy="110" r="4" className="data-blip fill-neutral-600" />
<circle cx="380" cy="170" r="4" className="data-blip fill-neutral-600" />
<circle cx="110" cy="330" r="4" className="data-blip fill-red-500/80" filter="url(#glowTarget)" />
<circle cx="340" cy="370" r="4" className="data-blip fill-[var(--color-accent)]/80" filter="url(#glowTarget)" />
<circle cx="260" cy="160" r="3" className="data-blip fill-white/80" />
{/* Center Bullseye */}
<circle cx="250" cy="250" r="12" className="bullseye fill-[var(--color-accent)]" filter="url(#glowTarget)" />
<circle cx="250" cy="250" r="4" className="bullseye fill-black" />
</svg>
{/* HTML Floating Labels */}
<div className="absolute inset-0 z-20 pointer-events-none w-full h-full">
{/* Label 1: Top Right */}
<div className="floating-label absolute top-[15%] right-[5%] flex flex-col items-start translate-x-4">
<div className="text-[var(--color-accent)] text-[10px] sm:text-xs font-mono font-bold mb-1 flex items-center gap-1 bg-neutral-950/60 pl-1 pr-2 rounded backdrop-blur border border-[var(--color-accent)]/20 shadow-[0_0_10px_rgba(204,255,0,0.1)]">
<Map className="w-3 h-3" /> MARKET MAPPING
</div>
<div className="w-16 h-px bg-gradient-to-r from-[var(--color-accent)] to-transparent"></div>
</div>
{/* Label 2: Bottom Left */}
<div className="floating-label absolute bottom-[25%] left-0 flex flex-col items-end -translate-x-4">
<div className="text-white text-[10px] sm:text-xs font-mono font-bold mb-1 flex items-center gap-1 bg-neutral-950/60 pr-1 pl-2 rounded backdrop-blur shadow-[0_0_10px_rgba(255,255,255,0.05)]">
COMPETITOR INTEL <Crosshair className="w-3 h-3 text-neutral-400" />
</div>
<div className="w-20 h-px bg-gradient-to-l from-white/30 to-transparent"></div>
</div>
{/* Label 3: Near Bullseye */}
<div className="floating-label absolute top-[43%] left-[55%] flex flex-col items-start bg-neutral-950/90 backdrop-blur-md px-3 py-1.5 border border-[var(--color-accent)]/30 rounded-md shadow-[0_0_20px_rgba(204,255,0,0.2)]">
<div className="text-[var(--color-accent)] text-[10px] sm:text-xs font-bold uppercase mapping-text tracking-wider">PRECISION STRIKE</div>
<div className="text-white text-[9px] sm:text-[10px] font-mono mt-0.5 opacity-80">Conversion Core</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}

27
src/layouts/Layout.astro Normal file
View File

@@ -0,0 +1,27 @@
---
import '../styles/global.css';
import '@fontsource-variable/outfit';
import Navigation from '../components/Navigation';
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="NotJustAn.Agency - Fully Booked Restaurants. Sold-Out Collections. Brands Built to Last." />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body class="bg-background text-white antialiased overflow-x-hidden selection:bg-accent selection:text-black">
<Navigation client:load />
<slot />
</body>
</html>

32
src/pages/index.astro Normal file
View File

@@ -0,0 +1,32 @@
---
import Layout from '../layouts/Layout.astro';
import LoadingScreen from '../components/LoadingScreen';
import HeroSection from '../components/HeroSection';
import ApproachSection from '../components/ApproachSection';
import ServicesSection from '../components/ServicesSection';
import InsightsSection from '../components/InsightsSection';
import BusinessStagesSection from '../components/BusinessStagesSection';
import StrategySection from '../components/StrategySection';
import BrandAwarenessSection from '../components/BrandAwarenessSection';
import PerformanceMarketingSection from '../components/PerformanceMarketingSection';
import OfferSection from '../components/OfferSection';
import ContactForm from '../components/ContactForm';
import FooterSection from '../components/FooterSection';
---
<Layout title="NotJustAn.Agency | Premium Web Design & Development">
<LoadingScreen client:load />
<main class="flex flex-col min-h-screen relative z-10 bg-black">
<HeroSection client:load />
<ApproachSection client:visible />
<ServicesSection client:visible />
<InsightsSection client:visible />
<BusinessStagesSection client:visible />
<StrategySection client:visible />
<BrandAwarenessSection client:visible />
<PerformanceMarketingSection client:visible />
<OfferSection client:load />
<ContactForm client:visible />
<FooterSection client:visible />
</main>
</Layout>

41
src/styles/global.css Normal file
View File

@@ -0,0 +1,41 @@
@import "tailwindcss";
@theme {
--font-sans: 'OutfitVariable', 'Outfit', sans-serif;
--color-background: #050505;
--color-surface: #121212;
--color-accent: #ccff00;
--color-accent-secondary: #7000ff;
--color-glass: rgba(255, 255, 255, 0.05);
}
@layer base {
body {
background-color: var(--color-background);
color: #ededed;
font-family: var(--font-sans);
}
/* Custom Scrollbar for premium feel */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: var(--color-background);
}
::-webkit-scrollbar-thumb {
background: #333;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--color-accent);
}
}
@layer utilities {
.glass {
background: var(--color-glass);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
}

14
tsconfig.json Normal file
View File

@@ -0,0 +1,14 @@
{
"extends": "astro/tsconfigs/strict",
"include": [
".astro/types.d.ts",
"**/*"
],
"exclude": [
"dist"
],
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "react"
}
}