Initial commit
This commit is contained in:
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
.output/
|
||||
|
||||
# Astro cache
|
||||
.astro/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Editor
|
||||
.vscode/
|
||||
.idea/
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
62
CLAUDE.md
Normal file
62
CLAUDE.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# context-mode — MANDATORY routing rules
|
||||
|
||||
You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session.
|
||||
|
||||
## BLOCKED commands — do NOT attempt these
|
||||
|
||||
### curl / wget — BLOCKED
|
||||
Any Bash command containing `curl` or `wget` is intercepted and replaced with an error message. Do NOT retry.
|
||||
Instead use:
|
||||
- `ctx_fetch_and_index(url, source)` to fetch and index web pages
|
||||
- `ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox
|
||||
|
||||
### Inline HTTP — BLOCKED
|
||||
Any Bash command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` is intercepted and replaced with an error message. Do NOT retry with Bash.
|
||||
Instead use:
|
||||
- `ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context
|
||||
|
||||
### WebFetch — BLOCKED
|
||||
WebFetch calls are denied entirely. The URL is extracted and you are told to use `ctx_fetch_and_index` instead.
|
||||
Instead use:
|
||||
- `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` to query the indexed content
|
||||
|
||||
## REDIRECTED tools — use sandbox equivalents
|
||||
|
||||
### Bash (>20 lines output)
|
||||
Bash is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
||||
For everything else, use:
|
||||
- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
||||
- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
||||
|
||||
### Read (for analysis)
|
||||
If you are reading a file to **Edit** it → Read is correct (Edit needs content in context).
|
||||
If you are reading to **analyze, explore, or summarize** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context. The raw file content stays in the sandbox.
|
||||
|
||||
### Grep (large results)
|
||||
Grep results can flood context. Use `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context.
|
||||
|
||||
## Tool selection hierarchy
|
||||
|
||||
1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
||||
2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
||||
3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
||||
4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
||||
5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
||||
|
||||
## Subagent routing
|
||||
|
||||
When spawning subagents (Agent/Task tool), the routing block is automatically injected into their prompt. Bash-type subagents are upgraded to general-purpose so they have access to MCP tools. You do NOT need to manually instruct subagents about context-mode.
|
||||
|
||||
## Output constraints
|
||||
|
||||
- Keep responses under 500 words.
|
||||
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
||||
- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later.
|
||||
|
||||
## ctx commands
|
||||
|
||||
| Command | Action |
|
||||
|---------|--------|
|
||||
| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim |
|
||||
| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist |
|
||||
| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist |
|
||||
96
README.md
Normal file
96
README.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Smart Roots — Sito Web
|
||||
|
||||
Stack: **Astro 4** (static output) · CSS custom · Deploy su **IIS 10 / Windows Server 2016**
|
||||
|
||||
---
|
||||
|
||||
## Struttura del progetto
|
||||
|
||||
```
|
||||
/
|
||||
├── public/
|
||||
│ ├── assets/ ← immagini, loghi (copiati as-is nel build)
|
||||
│ └── web.config ← configurazione IIS (copiata as-is nel build)
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ ├── Layout.astro ← head HTML, meta SEO, font
|
||||
│ │ ├── Nav.astro ← navbar (variante full o back)
|
||||
│ │ └── Footer.astro ← footer con dati societari
|
||||
│ ├── pages/
|
||||
│ │ ├── index.astro ← Home / Landing page
|
||||
│ │ ├── contatti.astro ← Form contatti → WebAPI
|
||||
│ │ ├── privacy.astro ← Privacy Policy (da completare)
|
||||
│ │ └── termini.astro ← Termini (da completare)
|
||||
│ └── styles/
|
||||
│ └── global.css ← CSS variables, nav, footer, form, responsive
|
||||
├── astro.config.mjs
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Setup locale
|
||||
|
||||
### Prerequisiti
|
||||
- Node.js 18+ (solo per sviluppo/build, non necessario in produzione)
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev # avvia dev server su http://localhost:4321
|
||||
npm run build # genera cartella /dist pronta per il deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deploy su IIS 10
|
||||
|
||||
1. Eseguire il build: `npm run build`
|
||||
2. La cartella `/dist` contiene il sito statico completo
|
||||
3. Copiare il contenuto di `/dist` nella cartella del sito su IIS
|
||||
- Il `web.config` è già incluso nel build (sta in `/public`)
|
||||
4. In IIS Manager:
|
||||
- Application Pool: **.NET CLR version = No Managed Code**
|
||||
- Assicurarsi che il modulo **URL Rewrite** sia installato (necessario per il routing)
|
||||
|
||||
### Modulo URL Rewrite
|
||||
Se non installato: scaricarlo da https://www.iis.net/downloads/microsoft/url-rewrite
|
||||
|
||||
---
|
||||
|
||||
## Form contatti — WebAPI
|
||||
|
||||
Il form invia a `https://api.smart-roots.net/api/contatti` via `fetch` POST JSON.
|
||||
|
||||
Payload inviato:
|
||||
```json
|
||||
{
|
||||
"nome": "Mario Rossi",
|
||||
"azienda": "Acme S.r.l.",
|
||||
"email": "mario@azienda.it",
|
||||
"ambito": "smartdb",
|
||||
"messaggio": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Endpoint WebAPI da creare (.NET Framework 4.8)
|
||||
Vedere documentazione separata per `ContattiController`.
|
||||
Ricordarsi di abilitare CORS per `https://www.smart-roots.net` nella WebAPI.
|
||||
|
||||
---
|
||||
|
||||
## Aggiungere nuove pagine
|
||||
|
||||
1. Creare `src/pages/nuova-pagina.astro`
|
||||
2. Usare il componente `Layout` con titolo e descrizione
|
||||
3. `npm run build` e rideploy della cartella `/dist`
|
||||
|
||||
---
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Aggiungere immagine `hero-dashboard.png` in `/public/assets/`
|
||||
- [ ] Aggiungere immagine `og-image.jpg` in `/public/assets/` (1200×630px)
|
||||
- [ ] Completare testo Privacy Policy in `src/pages/privacy.astro`
|
||||
- [ ] Completare testo Termini in `src/pages/termini.astro`
|
||||
- [ ] Creare endpoint `POST /api/contatti` nella WebAPI
|
||||
- [ ] Abilitare CORS per `https://www.smart-roots.net` nella WebAPI
|
||||
9
astro.config.mjs
Normal file
9
astro.config.mjs
Normal file
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
export default defineConfig({
|
||||
output: 'static',
|
||||
site: 'https://www.smart-roots.net',
|
||||
build: {
|
||||
format: 'directory' // genera /contatti/index.html invece di /contatti.html
|
||||
}
|
||||
});
|
||||
5553
package-lock.json
generated
Normal file
5553
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
package.json
Normal file
13
package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "smart-roots-website",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^4.15.0"
|
||||
}
|
||||
}
|
||||
167
public/assets/hero-dashboard.svg
Normal file
167
public/assets/hero-dashboard.svg
Normal file
@@ -0,0 +1,167 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" width="600" height="400">
|
||||
<defs>
|
||||
<style>
|
||||
.bg { fill: #1e2840; }
|
||||
.panel { fill: #111829; stroke: rgba(100,140,200,0.18); stroke-width: 1; }
|
||||
.panel-dark { fill: #0b0f1c; stroke: rgba(100,140,200,0.12); stroke-width: 1; }
|
||||
.accent { fill: #4d8fd4; }
|
||||
.accent-dim { fill: rgba(77,143,212,0.15); }
|
||||
.bar-1 { fill: #4d8fd4; }
|
||||
.bar-2 { fill: rgba(77,143,212,0.5); }
|
||||
.bar-3 { fill: rgba(77,143,212,0.3); }
|
||||
.line-color { stroke: #4d8fd4; stroke-width: 1.5; fill: none; }
|
||||
.line-dim { stroke: rgba(77,143,212,0.35); stroke-width: 1; fill: none; }
|
||||
.txt-primary { fill: #ddd8d0; font-family: IBM Plex Mono, monospace; }
|
||||
.txt-secondary { fill: #8799bb; font-family: IBM Plex Mono, monospace; }
|
||||
.txt-dim { fill: #5a6e90; font-family: IBM Plex Mono, monospace; }
|
||||
.dot { fill: #4d8fd4; }
|
||||
.dot-empty { fill: none; stroke: #4d8fd4; stroke-width: 1.5; }
|
||||
.grid-line { stroke: rgba(100,140,200,0.08); stroke-width: 1; }
|
||||
.badge { fill: rgba(77,143,212,0.15); }
|
||||
.badge-border { fill: none; stroke: #2e5fa3; stroke-width: 1; }
|
||||
.positive { fill: #1d9e75; }
|
||||
.negative { fill: #e24b4a; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="600" height="400" class="bg" rx="8"/>
|
||||
|
||||
<!-- Header bar -->
|
||||
<rect x="0" y="0" width="600" height="44" fill="#0b0f1c" rx="8"/>
|
||||
<rect x="0" y="36" width="600" height="8" fill="#0b0f1c"/>
|
||||
|
||||
<!-- Header dots -->
|
||||
<circle cx="20" cy="22" r="4" fill="#2e5fa3" opacity="0.6"/>
|
||||
<circle cx="34" cy="22" r="4" fill="#2e5fa3" opacity="0.4"/>
|
||||
<circle cx="48" cy="22" r="4" fill="#2e5fa3" opacity="0.2"/>
|
||||
|
||||
<!-- Header label -->
|
||||
<text x="72" y="27" class="txt-dim" font-size="10" letter-spacing="2">SMARTDB — ANALYTICS DASHBOARD</text>
|
||||
|
||||
<!-- Badge live -->
|
||||
<rect x="510" y="13" width="70" height="18" class="badge" rx="9"/>
|
||||
<rect x="510" y="13" width="70" height="18" class="badge-border" rx="9"/>
|
||||
<circle cx="522" cy="22" r="3" fill="#1d9e75"/>
|
||||
<text x="530" y="26" class="txt-secondary" font-size="9" letter-spacing="1">LIVE</text>
|
||||
|
||||
<!-- ===== KPI CARDS ROW ===== -->
|
||||
<!-- Card 1 -->
|
||||
<rect x="16" y="56" width="128" height="68" class="panel" rx="4"/>
|
||||
<text x="26" y="74" class="txt-dim" font-size="8" letter-spacing="1.5">PE RATIO</text>
|
||||
<text x="26" y="96" class="txt-primary" font-size="22" font-weight="300">14.32</text>
|
||||
<text x="26" y="113" fill="#1d9e75" font-family="IBM Plex Mono,monospace" font-size="9">▲ +0.8%</text>
|
||||
|
||||
<!-- Card 2 -->
|
||||
<rect x="156" y="56" width="128" height="68" class="panel" rx="4"/>
|
||||
<text x="166" y="74" class="txt-dim" font-size="8" letter-spacing="1.5">DIV YIELD</text>
|
||||
<text x="166" y="96" class="txt-primary" font-size="22" font-weight="300">3.87%</text>
|
||||
<text x="166" y="113" fill="#1d9e75" font-family="IBM Plex Mono,monospace" font-size="9">▲ +0.2%</text>
|
||||
|
||||
<!-- Card 3 -->
|
||||
<rect x="296" y="56" width="128" height="68" class="panel" rx="4"/>
|
||||
<text x="306" y="74" class="txt-dim" font-size="8" letter-spacing="1.5">VOLATILITY 1Y</text>
|
||||
<text x="306" y="96" class="txt-primary" font-size="22" font-weight="300">0.218</text>
|
||||
<text x="306" y="113" fill="#e24b4a" font-family="IBM Plex Mono,monospace" font-size="9">▼ -0.012</text>
|
||||
|
||||
<!-- Card 4 -->
|
||||
<rect x="436" y="56" width="148" height="68" class="panel" rx="4"/>
|
||||
<text x="446" y="74" class="txt-dim" font-size="8" letter-spacing="1.5">ESG SCORE</text>
|
||||
<text x="446" y="96" class="txt-primary" font-size="22" font-weight="300">72</text>
|
||||
<text x="446" y="113" class="txt-dim" font-family="IBM Plex Mono,monospace" font-size="9">stable</text>
|
||||
|
||||
<!-- ===== CHART PANEL - LINE ===== -->
|
||||
<rect x="16" y="136" width="348" height="160" class="panel-dark" rx="4"/>
|
||||
<text x="26" y="153" class="txt-dim" font-size="8" letter-spacing="1.5">PRICE INDEX — 12M</text>
|
||||
|
||||
<!-- Grid lines -->
|
||||
<line x1="26" y1="166" x2="354" y2="166" class="grid-line"/>
|
||||
<line x1="26" y1="186" x2="354" y2="186" class="grid-line"/>
|
||||
<line x1="26" y1="206" x2="354" y2="206" class="grid-line"/>
|
||||
<line x1="26" y1="226" x2="354" y2="226" class="grid-line"/>
|
||||
<line x1="26" y1="246" x2="354" y2="246" class="grid-line"/>
|
||||
<line x1="26" y1="266" x2="354" y2="266" class="grid-line"/>
|
||||
<line x1="26" y1="284" x2="354" y2="284" class="grid-line"/>
|
||||
|
||||
<!-- Y labels -->
|
||||
<text x="20" y="169" class="txt-dim" font-size="8" text-anchor="end">120</text>
|
||||
<text x="20" y="209" class="txt-dim" font-size="8" text-anchor="end">110</text>
|
||||
<text x="20" y="249" class="txt-dim" font-size="8" text-anchor="end">100</text>
|
||||
<text x="20" y="287" class="txt-dim" font-size="8" text-anchor="end">90</text>
|
||||
|
||||
<!-- Area fill -->
|
||||
<path d="M30 260 L60 248 L90 238 L120 252 L150 240 L180 228 L210 218 L240 208 L270 196 L300 186 L330 174 L354 168 L354 284 L30 284 Z" fill="rgba(77,143,212,0.07)"/>
|
||||
|
||||
<!-- Line chart -->
|
||||
<path d="M30 260 L60 248 L90 238 L120 252 L150 240 L180 228 L210 218 L240 208 L270 196 L300 186 L330 174 L354 168" class="line-color" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<!-- Dot at end -->
|
||||
<circle cx="354" cy="168" r="3.5" class="dot"/>
|
||||
|
||||
<!-- X labels -->
|
||||
<text x="30" y="296" class="txt-dim" font-size="7" text-anchor="middle">Gen</text>
|
||||
<text x="90" y="296" class="txt-dim" font-size="7" text-anchor="middle">Mar</text>
|
||||
<text x="150" y="296" class="txt-dim" font-size="7" text-anchor="middle">Mag</text>
|
||||
<text x="210" y="296" class="txt-dim" font-size="7" text-anchor="middle">Lug</text>
|
||||
<text x="270" y="296" class="txt-dim" font-size="7" text-anchor="middle">Set</text>
|
||||
<text x="330" y="296" class="txt-dim" font-size="7" text-anchor="middle">Nov</text>
|
||||
|
||||
<!-- ===== BAR CHART PANEL ===== -->
|
||||
<rect x="376" y="136" width="208" height="160" class="panel-dark" rx="4"/>
|
||||
<text x="386" y="153" class="txt-dim" font-size="8" letter-spacing="1.5">ASSET CLASS MIX</text>
|
||||
|
||||
<!-- Bars -->
|
||||
<rect x="390" y="248" width="22" height="26" class="bar-1" rx="2"/>
|
||||
<rect x="390" y="196" width="22" height="52" class="bar-1" opacity="0.85" rx="2"/>
|
||||
<rect x="390" y="176" width="22" height="20" class="bar-1" opacity="0.6" rx="2"/>
|
||||
|
||||
<rect x="428" y="236" width="22" height="38" class="bar-2" rx="2"/>
|
||||
<rect x="428" y="204" width="22" height="32" class="bar-2" opacity="0.85" rx="2"/>
|
||||
<rect x="428" y="190" width="22" height="14" class="bar-2" opacity="0.7" rx="2"/>
|
||||
|
||||
<rect x="466" y="250" width="22" height="24" class="bar-3" rx="2"/>
|
||||
<rect x="466" y="220" width="22" height="30" class="bar-3" opacity="0.85" rx="2"/>
|
||||
<rect x="466" y="206" width="22" height="14" class="bar-3" opacity="0.7" rx="2"/>
|
||||
|
||||
<rect x="504" y="242" width="22" height="32" class="bar-1" opacity="0.4" rx="2"/>
|
||||
<rect x="504" y="218" width="22" height="24" class="bar-1" opacity="0.3" rx="2"/>
|
||||
|
||||
<!-- X labels bar -->
|
||||
<text x="401" y="290" class="txt-dim" font-size="7" text-anchor="middle">Equity</text>
|
||||
<text x="439" y="290" class="txt-dim" font-size="7" text-anchor="middle">Bond</text>
|
||||
<text x="477" y="290" class="txt-dim" font-size="7" text-anchor="middle">Fund</text>
|
||||
<text x="515" y="290" class="txt-dim" font-size="7" text-anchor="middle">Deriv</text>
|
||||
|
||||
<!-- ===== INSTRUMENT TABLE ===== -->
|
||||
<rect x="16" y="308" width="568" height="76" class="panel-dark" rx="4"/>
|
||||
<text x="26" y="325" class="txt-dim" font-size="8" letter-spacing="1.5">INSTRUMENTS — ENRICHED DATA</text>
|
||||
|
||||
<!-- Table header -->
|
||||
<rect x="16" y="329" width="568" height="1" fill="rgba(100,140,200,0.12)"/>
|
||||
<text x="30" y="342" class="txt-dim" font-size="8">ISIN</text>
|
||||
<text x="150" y="342" class="txt-dim" font-size="8">NAME</text>
|
||||
<text x="300" y="342" class="txt-dim" font-size="8">CLASS</text>
|
||||
<text x="380" y="342" class="txt-dim" font-size="8">P/E</text>
|
||||
<text x="440" y="342" class="txt-dim" font-size="8">YIELD</text>
|
||||
<text x="520" y="342" class="txt-dim" font-size="8">ESG</text>
|
||||
<rect x="16" y="345" width="568" height="1" fill="rgba(100,140,200,0.08)"/>
|
||||
|
||||
<!-- Row 1 -->
|
||||
<text x="30" y="358" class="txt-secondary" font-size="9" font-family="IBM Plex Mono,monospace">IT0005365165</text>
|
||||
<text x="150" y="358" class="txt-primary" font-size="9">ENI S.p.A.</text>
|
||||
<text x="300" y="358" class="accent" font-size="9" font-family="IBM Plex Mono,monospace" fill="#4d8fd4">equity</text>
|
||||
<text x="380" y="358" class="txt-secondary" font-size="9">14.32</text>
|
||||
<text x="440" y="358" class="txt-secondary" font-size="9">3.87%</text>
|
||||
<text x="520" y="358" fill="#1d9e75" font-family="IBM Plex Mono,monospace" font-size="9">72</text>
|
||||
|
||||
<!-- Row 2 -->
|
||||
<text x="30" y="374" class="txt-secondary" font-size="9" font-family="IBM Plex Mono,monospace">IT0004965148</text>
|
||||
<text x="150" y="374" class="txt-primary" font-size="9">Intesa Sanpaolo</text>
|
||||
<text x="300" y="374" class="accent" font-size="9" font-family="IBM Plex Mono,monospace" fill="#4d8fd4">equity</text>
|
||||
<text x="380" y="374" class="txt-secondary" font-size="9">11.08</text>
|
||||
<text x="440" y="374" class="txt-secondary" font-size="9">5.21%</text>
|
||||
<text x="520" y="374" fill="#1d9e75" font-family="IBM Plex Mono,monospace" font-size="9">68</text>
|
||||
|
||||
<!-- Separator rows -->
|
||||
<rect x="16" y="362" width="568" height="1" fill="rgba(100,140,200,0.05)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.1 KiB |
BIN
public/assets/logo.jpg
Normal file
BIN
public/assets/logo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
BIN
public/assets/logo.png
Normal file
BIN
public/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 214 KiB |
63
public/web.config
Normal file
63
public/web.config
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
web.config per IIS 10 — Smart Roots (sito statico Astro)
|
||||
Da copiare nella cartella /dist dopo il build: astro build
|
||||
-->
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
|
||||
<!-- Routing: se il file non esiste fisicamente, serve index.html della directory -->
|
||||
<rewrite>
|
||||
<rules>
|
||||
<!-- Forza HTTPS -->
|
||||
<rule name="HTTP to HTTPS" stopProcessing="true">
|
||||
<match url="(.*)" />
|
||||
<conditions>
|
||||
<add input="{HTTPS}" pattern="^OFF$" />
|
||||
</conditions>
|
||||
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
|
||||
</rule>
|
||||
|
||||
<!-- SPA/Static fallback: cartelle Astro con index.html -->
|
||||
<rule name="Astro static routing" stopProcessing="true">
|
||||
<match url="(.*)" />
|
||||
<conditions logicalGrouping="MatchAll">
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
|
||||
</conditions>
|
||||
<action type="Rewrite" url="/{R:1}/index.html" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
|
||||
<!-- MIME types aggiuntivi necessari per Astro -->
|
||||
<staticContent>
|
||||
<remove fileExtension=".webmanifest" />
|
||||
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
|
||||
<remove fileExtension=".woff2" />
|
||||
<mimeMap fileExtension=".woff2" mimeType="font/woff2" />
|
||||
<remove fileExtension=".woff" />
|
||||
<mimeMap fileExtension=".woff" mimeType="font/woff" />
|
||||
</staticContent>
|
||||
|
||||
<!-- Cache control per asset statici -->
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<add name="X-Content-Type-Options" value="nosniff" />
|
||||
<add name="X-Frame-Options" value="SAMEORIGIN" />
|
||||
<add name="X-XSS-Protection" value="1; mode=block" />
|
||||
<add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
|
||||
</customHeaders>
|
||||
</httpProtocol>
|
||||
|
||||
<!-- Compressione gzip -->
|
||||
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
|
||||
|
||||
<!-- Errori personalizzati -->
|
||||
<httpErrors errorMode="Custom" existingResponse="Replace">
|
||||
<remove statusCode="404" />
|
||||
<error statusCode="404" path="/index.html" responseMode="ExecuteURL" />
|
||||
</httpErrors>
|
||||
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
30
src/components/Footer.astro
Normal file
30
src/components/Footer.astro
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
|
||||
<footer>
|
||||
<div class="footer-inner">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;width:100%;flex-wrap:wrap;gap:1rem">
|
||||
<div class="footer-logo">Smart Roots</div>
|
||||
<nav class="footer-links" aria-label="Link footer">
|
||||
<a href="/privacy">Privacy</a>
|
||||
<a href="/termini">Termini</a>
|
||||
<a href="/contatti">Contatti</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div style="width:100%;height:1px;background:var(--border)" aria-hidden="true"></div>
|
||||
<div style="display:flex;align-items:flex-start;justify-content:space-between;width:100%;flex-wrap:wrap;gap:1.5rem">
|
||||
<address style="font-style:normal">
|
||||
<div style="font-family:var(--mono);font-size:0.7rem;color:var(--txt3);letter-spacing:0.06em;margin-bottom:0.6rem;text-transform:uppercase">Dati societari</div>
|
||||
<div style="font-size:0.78rem;color:var(--txt3);line-height:1.9">
|
||||
<span style="color:var(--txt2);font-weight:500">SMART ROOTS S.R.L.</span><br />
|
||||
Via Lombardia 40 — 00187 Roma (RM)<br />
|
||||
P.IVA / C.F.: 17439811005 · VAT EU: IT17439811005
|
||||
</div>
|
||||
</address>
|
||||
<div class="footer-copy" style="align-self:flex-end">
|
||||
<small>© {year} Smart Roots S.r.l.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
63
src/components/Layout.astro
Normal file
63
src/components/Layout.astro
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
|
||||
import '../styles/global.css';
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
canonical?: string;
|
||||
noindex?: boolean;
|
||||
ogImage?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
canonical,
|
||||
noindex = false,
|
||||
ogImage = 'https://www.smart-roots.net/assets/og-image.jpg'
|
||||
} = Astro.props;
|
||||
|
||||
const canonicalUrl = canonical ?? Astro.url.href;
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content={noindex ? 'noindex, follow' : 'index, follow'} />
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
<meta name="author" content="Smart Roots S.r.l." />
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={canonicalUrl} />
|
||||
<meta property="og:image" content={ogImage} />
|
||||
<meta property="og:image:width" content="1200" />
|
||||
<meta property="og:image:height" content="630" />
|
||||
<meta property="og:locale" content="it_IT" />
|
||||
<meta property="og:site_name" content="Smart Roots" />
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={ogImage} />
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500&family=IBM+Plex+Mono:wght@300;400&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap" rel="stylesheet" />
|
||||
|
||||
<!-- Slot per head aggiuntivo per pagina -->
|
||||
<slot name="head" />
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
26
src/components/Nav.astro
Normal file
26
src/components/Nav.astro
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
export interface Props {
|
||||
variant?: 'full' | 'back'; // full = nav principale, back = solo logo + freccia home
|
||||
}
|
||||
const { variant = 'full' } = Astro.props;
|
||||
---
|
||||
|
||||
<nav aria-label="Navigazione principale">
|
||||
<a href="/" class="nav-logo" aria-label="Smart Roots — Home">
|
||||
<img src="/assets/logo.png" alt="Smart Roots" width="32" height="32" />
|
||||
<span class="nav-logo-text">Smart Roots</span>
|
||||
</a>
|
||||
|
||||
{variant === 'full' && (
|
||||
<div class="nav-links">
|
||||
<a href="/#prodotto">Prodotto</a>
|
||||
<a href="/#smartdb">SmartDB</a>
|
||||
<a href="/#chi">Per chi</a>
|
||||
<a href="/contatti" class="nav-cta">Conosciamoci</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{variant === 'back' && (
|
||||
<a href="/" class="nav-back">Home</a>
|
||||
)}
|
||||
</nav>
|
||||
1
src/env.d.ts
vendored
Normal file
1
src/env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
166
src/pages/contatti.astro
Normal file
166
src/pages/contatti.astro
Normal file
@@ -0,0 +1,166 @@
|
||||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Contatti — Smart Roots | Conosciamoci"
|
||||
description="Contatta Smart Roots per una presentazione del prodotto o per valutare come i nostri servizi di Financial Data Intelligence si adattano al tuo flusso di lavoro."
|
||||
canonical="https://www.smart-roots.net/contatti"
|
||||
noindex={true}
|
||||
>
|
||||
|
||||
<Nav variant="back" />
|
||||
|
||||
<main>
|
||||
<div class="page-tag">Contatti</div>
|
||||
<h1>Conosciamoci.</h1>
|
||||
<p>
|
||||
Scrivici per una presentazione ad hoc, per approfondire il prodotto o semplicemente per capire se Smart Roots può essere utile al tuo flusso di lavoro.
|
||||
Risponderemo entro 24 ore lavorative.
|
||||
</p>
|
||||
|
||||
<form id="contact-form" novalidate style="margin-top:2.5rem" aria-label="Modulo di contatto Smart Roots">
|
||||
|
||||
<!-- Honeypot anti-spam -->
|
||||
<input type="checkbox" name="botcheck" style="display:none" tabindex="-1" aria-hidden="true" />
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-field">
|
||||
<label class="form-label" for="nome">Nome <span aria-label="obbligatorio">*</span></label>
|
||||
<input class="form-input" type="text" id="nome" name="nome" required placeholder="Mario Rossi" autocomplete="given-name" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label class="form-label" for="azienda">Azienda</label>
|
||||
<input class="form-input" type="text" id="azienda" name="azienda" placeholder="Acme S.r.l." autocomplete="organization" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-field">
|
||||
<label class="form-label" for="email">Email <span aria-label="obbligatorio">*</span></label>
|
||||
<input class="form-input" type="email" id="email" name="email" required placeholder="mario@azienda.it" autocomplete="email" />
|
||||
</div>
|
||||
|
||||
<div class="form-field">
|
||||
<label class="form-label" for="ambito">Ambito di interesse</label>
|
||||
<select class="form-input" id="ambito" name="ambito">
|
||||
<option value="">— seleziona —</option>
|
||||
<option value="data-enrichment">Data Enrichment</option>
|
||||
<option value="analytics">Advanced Analytics</option>
|
||||
<option value="smartdb">SmartDB / API</option>
|
||||
<option value="ai-workflow">AI Workflows</option>
|
||||
<option value="altro">Altro</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-field" style="margin-bottom:1.5rem">
|
||||
<label class="form-label" for="messaggio">Messaggio <span aria-label="obbligatorio">*</span></label>
|
||||
<textarea
|
||||
class="form-input"
|
||||
id="messaggio"
|
||||
name="messaggio"
|
||||
required
|
||||
rows="5"
|
||||
placeholder="Raccontaci brevemente il tuo contesto e cosa stai cercando..."
|
||||
style="resize:vertical"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-submit" id="submit-btn">
|
||||
Invia messaggio
|
||||
</button>
|
||||
|
||||
<div class="form-feedback ok" id="form-ok" role="alert" aria-live="polite">
|
||||
✓ Messaggio inviato — ti risponderemo entro 24 ore lavorative.
|
||||
</div>
|
||||
<div class="form-feedback err" id="form-err" role="alert" aria-live="polite">
|
||||
Errore nell'invio. Scrivi direttamente a
|
||||
<a href="mailto:info@smart-roots.net">info@smart-roots.net</a>
|
||||
</div>
|
||||
|
||||
<p class="form-note">
|
||||
I dati forniti saranno utilizzati esclusivamente per rispondere alla tua richiesta.
|
||||
Consulta la nostra <a href="/privacy">Privacy Policy</a> per maggiori informazioni.
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<p style="margin-top:2.5rem;font-size:0.82rem;color:var(--txt3)">
|
||||
Oppure scrivici direttamente a
|
||||
<a href="mailto:info@smart-roots.net" style="color:var(--txt2)">info@smart-roots.net</a>
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// ⚠️ Sostituire con l'URL reale dell'endpoint nella WebAPI
|
||||
const API_ENDPOINT = 'https://api.smart-roots.net/api/contatti';
|
||||
|
||||
const form = document.getElementById('contact-form') as HTMLFormElement;
|
||||
const submitBtn = document.getElementById('submit-btn') as HTMLButtonElement;
|
||||
const okMsg = document.getElementById('form-ok') as HTMLElement;
|
||||
const errMsg = document.getElementById('form-err') as HTMLElement;
|
||||
|
||||
form.addEventListener('submit', async function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Honeypot check
|
||||
const botcheck = form.querySelector('[name="botcheck"]') as HTMLInputElement;
|
||||
if (botcheck && botcheck.checked) return;
|
||||
|
||||
// Validazione HTML5 nativa
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stato loading
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = 'Invio in corso…';
|
||||
okMsg.style.display = 'none';
|
||||
errMsg.style.display = 'none';
|
||||
|
||||
const payload = {
|
||||
nome: (document.getElementById('nome') as HTMLInputElement).value.trim(),
|
||||
azienda: (document.getElementById('azienda') as HTMLInputElement).value.trim(),
|
||||
email: (document.getElementById('email') as HTMLInputElement).value.trim(),
|
||||
ambito: (document.getElementById('ambito') as HTMLSelectElement).value,
|
||||
messaggio:(document.getElementById('messaggio') as HTMLTextAreaElement).value.trim(),
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(API_ENDPOINT, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
form.reset();
|
||||
okMsg.style.display = 'block';
|
||||
okMsg.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
} else {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Errore invio form:', err);
|
||||
errMsg.style.display = 'block';
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Invia messaggio';
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
main { max-width: 760px; margin: 0 auto; padding: 120px 2.5rem 80px; }
|
||||
.page-tag { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); margin-bottom: 1rem; }
|
||||
h1 { font-family: var(--serif); font-size: clamp(1.8rem, 3.5vw, 2.4rem); font-weight: normal; color: var(--txt); line-height: 1.15; margin-bottom: 2rem; }
|
||||
p { font-size: 0.95rem; color: var(--txt2); line-height: 1.8; margin-bottom: 1rem; }
|
||||
</style>
|
||||
467
src/pages/index.astro
Normal file
467
src/pages/index.astro
Normal file
@@ -0,0 +1,467 @@
|
||||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": "https://www.smart-roots.net/#organization",
|
||||
"name": "Smart Roots S.r.l.",
|
||||
"url": "https://www.smart-roots.net/",
|
||||
"logo": "https://www.smart-roots.net/assets/logo.png",
|
||||
"description": "Financial Data Intelligence per asset manager, advisory firm e operatori finanziari.",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": "Via Lombardia 40",
|
||||
"addressLocality": "Roma",
|
||||
"postalCode": "00187",
|
||||
"addressCountry": "IT"
|
||||
},
|
||||
"vatID": "IT17439811005",
|
||||
"contactPoint": {
|
||||
"@type": "ContactPoint",
|
||||
"contactType": "customer service",
|
||||
"url": "https://www.smart-roots.net/contatti"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": "https://www.smart-roots.net/#website",
|
||||
"url": "https://www.smart-roots.net/",
|
||||
"name": "Smart Roots",
|
||||
"publisher": { "@id": "https://www.smart-roots.net/#organization" },
|
||||
"inLanguage": "it-IT"
|
||||
}
|
||||
]
|
||||
};
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Smart Roots — Financial Data Intelligence | Dati finanziari rielaborati e analytics"
|
||||
description="Smart Roots offre soluzioni di Financial Data Intelligence per asset manager, advisory firm e operatori finanziari. Trasformiamo dati finanziari complessi in analytics, workflow e decisioni operative tramite API e piattaforma dedicata."
|
||||
canonical="https://www.smart-roots.net/"
|
||||
>
|
||||
<Fragment slot="head">
|
||||
<meta name="keywords" content="financial data intelligence, data enrichment finanziario, analytics finanziari, API dati finanziari, asset management, SmartDB" />
|
||||
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
|
||||
</Fragment>
|
||||
|
||||
<Nav variant="full" />
|
||||
|
||||
<!-- HERO -->
|
||||
<section class="hero" aria-labelledby="hero-heading">
|
||||
<div class="hero-grid" aria-hidden="true"></div>
|
||||
<div class="hero-glow" aria-hidden="true"></div>
|
||||
<div class="hero-inner">
|
||||
<div class="hero-left">
|
||||
<div class="hero-tag">Financial Intelligence Platform</div>
|
||||
<h1 id="hero-heading">
|
||||
Dati finanziari rielaborati,<br /><em>analytics</em> e piattaforma<br />in un unico ambiente.
|
||||
</h1>
|
||||
<p class="hero-sub">
|
||||
Smart Roots supporta asset manager, advisory firm e operatori finanziari a trasformare dati complessi in analisi, workflow e decisioni operative.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a href="/contatti" class="btn-primary">Conosciamoci</a>
|
||||
</div>
|
||||
<div class="hero-scroll" aria-hidden="true">
|
||||
<div class="hero-scroll-line"></div>
|
||||
Scorri
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-right">
|
||||
<div class="hero-image-wrap">
|
||||
<!-- Sostituire con immagine dashboard reale -->
|
||||
<img src="/assets/hero-dashboard.svg" alt="Dashboard Smart Roots" loading="lazy" width="600" height="400" />
|
||||
</div>
|
||||
<div class="hero-motto-block">
|
||||
<div class="hero-motto-large"><em>smart roots</em> — solid ground</div>
|
||||
<div class="hero-motto-rule" aria-hidden="true"></div>
|
||||
<div class="hero-motto-sub">dati su misura, decisioni fondate</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- THREE PILLARS -->
|
||||
<section class="pillars" id="prodotto" aria-labelledby="pillars-heading">
|
||||
<h2 id="pillars-heading" class="sr-only">I pilastri della piattaforma</h2>
|
||||
<div class="pillars-inner">
|
||||
<article class="pillar">
|
||||
<div class="pillar-num" aria-hidden="true">01</div>
|
||||
<h3 class="pillar-title">Data Enrichment</h3>
|
||||
<p class="pillar-desc">Dati finanziari rielaborati, normalizzati e strutturati. Consegniamo dati pronti all'uso.</p>
|
||||
</article>
|
||||
<article class="pillar">
|
||||
<div class="pillar-num" aria-hidden="true">02</div>
|
||||
<h3 class="pillar-title">Advanced Analytics</h3>
|
||||
<p class="pillar-desc">Motori di calcolo proprietari, metriche operative e logiche di analisi integrate direttamente nella piattaforma.</p>
|
||||
</article>
|
||||
<article class="pillar">
|
||||
<div class="pillar-num" aria-hidden="true">03</div>
|
||||
<h3 class="pillar-title">Interactive Delivery</h3>
|
||||
<p class="pillar-desc">Piattaforma web per la consultazione, l'utilizzo e l'esportazione dei dati. Accesso riservato, orientato all'operatività.</p>
|
||||
</article>
|
||||
<article class="pillar">
|
||||
<div class="pillar-num" aria-hidden="true">04</div>
|
||||
<h3 class="pillar-title">AI Workflows</h3>
|
||||
<p class="pillar-desc">Workflow AI su task specifici e misurabili. L'AI accelera l'esecuzione dei processi che padroneggiamo. Non deleghiamo ciò che non controlliamo.</p>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOUNDERS -->
|
||||
<section class="founders" id="chi-siamo" aria-labelledby="founders-heading">
|
||||
<div class="founders-inner">
|
||||
<div class="founders-left">
|
||||
<div class="section-tag">Chi siamo</div>
|
||||
<h2 id="founders-heading" class="sr-only">Chi siamo — Il team di Smart Roots</h2>
|
||||
<div class="founders-stat">
|
||||
<span class="founders-stat-num">30+</span>
|
||||
<span class="founders-stat-label">anni di esperienza</span>
|
||||
</div>
|
||||
<blockquote class="founders-quote">«Sappiamo cosa vuol dire lavorare con dati finanziari nella pratica operativa, da operatori.»</blockquote>
|
||||
<p class="founders-body">I fondatori di Smart Roots hanno maturato oltre trent'anni di esperienza diretta nei settori finanziario e informatico. Abbiamo vissuto dall'interno la frustrazione di ricevere dati grezzi, incompleti o non omogenei, e di dover costruire ogni volta, da zero, gli strumenti per renderli utilizzabili.</p>
|
||||
<p class="founders-body" style="margin-top:1rem">Da questa esperienza nasce Smart Roots: un progetto costruito da chi conosce il problema dall'interno e conosce la finanza sul campo.</p>
|
||||
</div>
|
||||
<div class="founders-right">
|
||||
<div class="section-tag" style="margin-bottom:1.5rem">Il dato «su misura»</div>
|
||||
<blockquote class="founders-quote" style="font-size:1.1rem">Un dato ben rielaborato è più pulito e diventa uno strumento di decisione. La differenza tra un dato grezzo e un dato su misura è la stessa che passa tra un'informazione e una scelta operativa.</blockquote>
|
||||
<p class="founders-body">Abbiamo imparato che il valore sta nella qualità della trasformazione dei dati, più che nel loro volume. Un dato normalizzato secondo la logica del business, e non della fonte, accorcia drasticamente il percorso tra analisi e azione.</p>
|
||||
<div class="founders-expertise">
|
||||
<div class="exp-item">
|
||||
<div class="exp-label">Settore finanziario</div>
|
||||
<p class="exp-text">Asset management, advisory, strutturazione di prodotti finanziari, risk e compliance.</p>
|
||||
</div>
|
||||
<div class="exp-item">
|
||||
<div class="exp-label">Settore informatico</div>
|
||||
<p class="exp-text">Architetture dati, sviluppo di piattaforme, integrazione di sistemi, infrastruttura cloud.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PER CHI È -->
|
||||
<section class="audience" id="chi" aria-labelledby="audience-heading">
|
||||
<div class="section-inner">
|
||||
<div class="section-tag">Posizionamento</div>
|
||||
<h2 id="audience-heading" class="section-title">Per chi lavora con dati finanziari complessi</h2>
|
||||
<p class="section-sub">Smart Roots è costruita per operatori che non possono permettersi di perdere tempo tra dato grezzo e decisione.</p>
|
||||
<div class="audience-grid">
|
||||
<article class="aud-card">
|
||||
<div class="aud-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" focusable="false"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
||||
</div>
|
||||
<h3 class="aud-title">Asset & Wealth Management</h3>
|
||||
<p class="aud-problem">Il dato arriva grezzo, il processo di pulizia è lungo e manuale.</p>
|
||||
<p class="aud-result">Riduci il tempo tra dato grezzo e decisione di investimento.</p>
|
||||
</article>
|
||||
<article class="aud-card">
|
||||
<div class="aud-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" focusable="false"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
||||
</div>
|
||||
<h3 class="aud-title">Advisory & Private Banking</h3>
|
||||
<p class="aud-problem">I consulenti hanno bisogno di analytics pronti, non di dataset da assemblare.</p>
|
||||
<p class="aud-result">Analisi e metriche operative disponibili nel flusso di lavoro quotidiano.</p>
|
||||
</article>
|
||||
<article class="aud-card">
|
||||
<div class="aud-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" focusable="false"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
||||
</div>
|
||||
<h3 class="aud-title">Fintech / Data-Driven Operations</h3>
|
||||
<p class="aud-problem">Integrare più fonti di dati finanziari ha un costo tecnico elevato.</p>
|
||||
<p class="aud-result">API strutturate e dataset normalizzati, pronti per l'integrazione.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PIPELINE -->
|
||||
<section class="pipeline" aria-labelledby="pipeline-heading">
|
||||
<div class="section-inner">
|
||||
<div class="section-tag">Come funziona</div>
|
||||
<h2 id="pipeline-heading" class="section-title">Dal dato grezzo all'analisi operativa</h2>
|
||||
<p class="section-sub">Smart Roots copre l'intero ciclo: acquisizione, elaborazione e distribuzione. Ogni fase è progettata per ridurre la distanza tra informazione e decisione.</p>
|
||||
<div class="pipeline-flow">
|
||||
<div class="pipe-block">
|
||||
<div class="pipe-label">Input</div>
|
||||
<h3 class="pipe-title">Fonti & Dataset</h3>
|
||||
<ul class="pipe-items">
|
||||
<li>Fonti dati strutturate e non</li>
|
||||
<li>Dataset di mercato e fondamentali</li>
|
||||
<li>Regole di calcolo e logiche operative</li>
|
||||
<li>Integrazioni esterne su misura</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pipe-arrow" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
|
||||
</div>
|
||||
<div class="pipe-block">
|
||||
<div class="pipe-label">Processing</div>
|
||||
<h3 class="pipe-title">Motori di analisi</h3>
|
||||
<ul class="pipe-items">
|
||||
<li>Normalizzazione e validazione</li>
|
||||
<li>Librerie di calcolo proprietarie</li>
|
||||
<li>Pipeline di enrichment automatizzate</li>
|
||||
<li>Metriche e indicatori operativi</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pipe-arrow" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
|
||||
</div>
|
||||
<div class="pipe-block">
|
||||
<div class="pipe-label">Output</div>
|
||||
<h3 class="pipe-title">Delivery operativa</h3>
|
||||
<ul class="pipe-items">
|
||||
<li>Dashboard e viste operative</li>
|
||||
<li>Dataset pronti all'uso</li>
|
||||
<li>Accesso API via SmartDB</li>
|
||||
<li>Export strutturati su richiesta</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SMARTDB -->
|
||||
<section class="smartdb" id="smartdb" aria-labelledby="smartdb-heading">
|
||||
<div class="section-inner smartdb-inner">
|
||||
<div>
|
||||
<div class="smartdb-badge">SmartDB</div>
|
||||
<div class="section-tag">Accesso ai dati</div>
|
||||
<h2 id="smartdb-heading" class="section-title">L'ambiente operativo<br />di accesso ai dati.</h2>
|
||||
<p style="font-size:1rem;color:var(--txt2);line-height:1.75;margin-bottom:2rem">SmartDB è il layer di esposizione dei dati rielaborati di Smart Roots. Fornisce accesso strutturato via API a dataset normalizzati, metriche calcolate e viste operative, senza la complessità di costruire e mantenere un'infrastruttura dati proprietaria.</p>
|
||||
<ul style="list-style:none;display:flex;flex-direction:column;gap:0.6rem;margin-bottom:2rem">
|
||||
<li style="font-size:0.875rem;color:var(--txt2);display:flex;align-items:center;gap:10px"><span style="color:var(--accent);font-family:var(--mono)" aria-hidden="true">→</span> Accesso riservato a operatori professionali</li>
|
||||
<li style="font-size:0.875rem;color:var(--txt2);display:flex;align-items:center;gap:10px"><span style="color:var(--accent);font-family:var(--mono)" aria-hidden="true">→</span> Endpoint API documentati e stabili</li>
|
||||
<li style="font-size:0.875rem;color:var(--txt2);display:flex;align-items:center;gap:10px"><span style="color:var(--accent);font-family:var(--mono)" aria-hidden="true">→</span> Dati già processati, non raw feed</li>
|
||||
<li style="font-size:0.875rem;color:var(--txt2);display:flex;align-items:center;gap:10px"><span style="color:var(--accent);font-family:var(--mono)" aria-hidden="true">→</span> Integrazione semplificata nel tuo stack</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="smartdb-visual" aria-label="Esempio di risposta API SmartDB">
|
||||
<div class="line-dim">// SmartDB API — esempio di risposta</div>
|
||||
<br />
|
||||
<div>GET /v1/instruments/<span class="line-accent">ISIN</span>/analytics</div>
|
||||
<br />
|
||||
<div>{"{"}</div>
|
||||
<div> "isin": <span class="line-accent">"IT0005365165"</span>,</div>
|
||||
<div> "asset_class": <span class="line-accent">"equity"</span>,</div>
|
||||
<div> "metrics": {"{"}</div>
|
||||
<div> "pe_ratio": <span class="line-accent">14.32</span>,</div>
|
||||
<div> "dividend_yield": <span class="line-accent">3.87</span>,</div>
|
||||
<div> "volatility_1y": <span class="line-accent">0.218</span>,</div>
|
||||
<div> "score_esg": <span class="line-accent">72</span></div>
|
||||
<div> {"}"},</div>
|
||||
<div> "updated_at": <span class="line-dim">"2026-03-14T18:00:00Z"</span></div>
|
||||
<div>{"}"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- AI SECTION -->
|
||||
<section style="background:var(--bg1);border-top:1px solid var(--border);padding:100px 2.5rem" aria-labelledby="ai-heading">
|
||||
<div class="section-inner">
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:5rem;align-items:start">
|
||||
<div>
|
||||
<div class="section-tag">Intelligenza artificiale</div>
|
||||
<h2 id="ai-heading" class="section-title">AI come strumento,<br />non come oracolo.</h2>
|
||||
<p style="font-size:1rem;color:var(--txt2);line-height:1.75;margin-bottom:1.5rem">Usiamo l'AI in modo deliberato e circoscritto: automatizza l'esecuzione di task che sappiamo già come svolgere, senza usarla per scoprire cosa fare.</p>
|
||||
<p style="font-size:1rem;color:var(--txt2);line-height:1.75">La differenza è sostanziale. Chi delega all'AI un problema che non sa risolvere entra in un territorio opaco, perde tempo e perde controllo sul risultato. Noi usiamo l'AI perché conosciamo il processo e possiamo governarla con precisione.</p>
|
||||
<div style="margin-top:1rem;padding:1.75rem;border:1px solid var(--accent2);border-radius:var(--r);background:var(--accent-dim)">
|
||||
<div style="font-family:var(--serif);font-size:1.2rem;color:var(--txt);margin-bottom:0.6rem">Non siamo una fint-tech.</div>
|
||||
<p style="font-family:var(--mono);font-size:0.75rem;color:var(--txt3);line-height:1.7;letter-spacing:0.03em">Finta tecnologia: usare l'AI per sembrare innovativi senza sapere cosa si sta facendo.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:1.5rem;padding-top:0.5rem">
|
||||
{[
|
||||
{ label: 'Il nostro approccio', text: 'Costruiamo workflow AI su task specifici e misurabili. Ogni automazione nasce da una competenza consolidata. L\'AI ne accelera l\'esecuzione, senza prendere il posto della competenza.' },
|
||||
{ label: 'Cosa evita questo', text: 'Nessun risultato casuale. Nessuna dipendenza da output che non sappiamo verificare. Il controllo del processo resta dove deve stare: nelle mani di chi conosce il dominio.' },
|
||||
{ label: 'Il risultato', text: 'Workflow più rapidi, output verificabili e competenza umana amplificata. L\'AI fa più veloce quello che noi sappiamo già fare bene.' }
|
||||
].map(item => (
|
||||
<div style="padding:1.75rem;border:1px solid var(--border);border-radius:var(--r);background:var(--bg)">
|
||||
<div style="font-family:var(--mono);font-size:0.68rem;letter-spacing:0.1em;text-transform:uppercase;color:var(--accent);margin-bottom:0.75rem">{item.label}</div>
|
||||
<p style="font-size:0.9rem;color:var(--txt2);line-height:1.7">{item.text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- DIFF -->
|
||||
<section class="diff" aria-labelledby="diff-heading">
|
||||
<div class="section-inner">
|
||||
<div class="section-tag">Perché Smart Roots</div>
|
||||
<h2 id="diff-heading" class="section-title">Tra vendor di dati<br />e software house.</h2>
|
||||
<p class="section-sub">Smart Roots occupa uno spazio preciso: tra chi distribuisce dati grezzi e chi costruisce software su misura. Un approccio più agile, più integrato, più operativo.</p>
|
||||
<div class="diff-grid">
|
||||
{[
|
||||
{ n:'01', t:'Dati rielaborati e pronti all\'uso', b:'Il valore sta nella logica di elaborazione che trasforma il dato grezzo in informazione operativa.' },
|
||||
{ n:'02', t:'Logica di calcolo integrata', b:'Le metriche sono incorporate nell\'infrastruttura di Smart Roots e disponibili via API.' },
|
||||
{ n:'03', t:'Esperienza orientata all\'uso', b:'La piattaforma è progettata per flussi di lavoro finanziari professionali specifici. Non nasce come strumento di analisi generico.' },
|
||||
{ n:'04', t:'Approccio modulare e adattabile', b:'I componenti sono configurabili. L\'ambiente si adatta al flusso di lavoro del cliente.' }
|
||||
].map(item => (
|
||||
<article class="diff-item">
|
||||
<div class="diff-num" aria-hidden="true">{item.n}</div>
|
||||
<h3 class="diff-title">{item.t}</h3>
|
||||
<p class="diff-body">{item.b}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- TRUST -->
|
||||
<section class="trust" aria-labelledby="trust-heading">
|
||||
<div class="section-inner">
|
||||
<div class="section-tag">Infrastruttura</div>
|
||||
<h2 id="trust-heading" class="section-title">Progettato per operatori professionali</h2>
|
||||
<div class="trust-grid">
|
||||
<article class="trust-item">
|
||||
<div class="trust-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg></div>
|
||||
<h3 class="trust-label">Accesso riservato</h3>
|
||||
<p class="trust-desc">Infrastruttura ad accesso controllato. Ambienti dedicati per ogni cliente.</p>
|
||||
</article>
|
||||
<article class="trust-item">
|
||||
<div class="trust-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M4.93 4.93a10 10 0 0 0 0 14.14"/></svg></div>
|
||||
<h3 class="trust-label">Supporto tecnico dedicato</h3>
|
||||
<p class="trust-desc">Interlocutore tecnico diretto. Nessun ticket anonimo, nessuna coda.</p>
|
||||
</article>
|
||||
<article class="trust-item">
|
||||
<div class="trust-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg></div>
|
||||
<h3 class="trust-label">Ambiti coperti</h3>
|
||||
<p class="trust-desc">Equity, fixed income, derivati, fondi. Coverage su mercati europei e internazionali.</p>
|
||||
</article>
|
||||
<article class="trust-item">
|
||||
<div class="trust-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg></div>
|
||||
<h3 class="trust-label">Use case operativi</h3>
|
||||
<p class="trust-desc">Screening, portfolio analytics, reporting, data enrichment per modelli interni.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA FINALE -->
|
||||
<section class="cta-final" id="contatti" aria-labelledby="cta-heading">
|
||||
<div class="cta-glow" aria-hidden="true"></div>
|
||||
<div class="section-inner" style="position:relative;text-align:center">
|
||||
<div class="section-tag" style="justify-content:center;display:flex">Inizia</div>
|
||||
<h2 id="cta-heading">Vuoi valutare come Smart Roots può adattarsi al tuo flusso di lavoro?</h2>
|
||||
<p>Mostriamo come funziona nell'ambiente operativo che usi già. Nessuna demo generica: una conversazione sul tuo caso specifico.</p>
|
||||
<div class="cta-buttons">
|
||||
<a href="/contatti" class="btn-primary">Conosciamoci</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* HERO */
|
||||
.hero { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding: 120px 2.5rem 80px; position: relative; overflow: hidden; }
|
||||
.hero-grid { position: absolute; inset: 0; background-image: linear-gradient(var(--border) 1px, transparent 1px), linear-gradient(90deg, var(--border) 1px, transparent 1px); background-size: 80px 80px; opacity: 0.4; pointer-events: none; }
|
||||
.hero-glow { position: absolute; top: -100px; right: -100px; width: 700px; height: 700px; background: radial-gradient(ellipse, rgba(45,90,163,0.18) 0%, transparent 65%); pointer-events: none; }
|
||||
.hero-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; max-width: var(--max); width: 100%; margin: 0 auto; position: relative; }
|
||||
.hero-tag { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); margin-bottom: 1.8rem; display: flex; align-items: center; gap: 10px; }
|
||||
.hero-tag::before { content: ''; width: 28px; height: 1px; background: var(--accent); display: inline-block; }
|
||||
.hero h1 { font-family: var(--serif); font-size: clamp(2.6rem, 5.5vw, 4.2rem); font-weight: normal; line-height: 1.12; letter-spacing: -0.01em; color: var(--txt); max-width: 760px; margin-bottom: 0.6rem; }
|
||||
.hero h1 em { font-style: italic; color: var(--accent); opacity: 0.9; }
|
||||
.hero-sub { font-size: 1.08rem; font-weight: 300; color: var(--txt2); max-width: 560px; line-height: 1.75; margin-bottom: 3rem; }
|
||||
.hero-actions { display: flex; gap: 1rem; flex-wrap: wrap; }
|
||||
.hero-scroll { margin-top: 5rem; display: flex; align-items: center; gap: 10px; color: var(--txt3); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; font-family: var(--mono); }
|
||||
.hero-scroll-line { width: 1px; height: 40px; background: linear-gradient(to bottom, transparent, var(--txt3)); }
|
||||
.hero-right { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.8rem; }
|
||||
.hero-image-wrap { position: relative; width: 340px; height: 340px; display: flex; align-items: center; justify-content: center; }
|
||||
.hero-image-wrap::before { content: ''; position: absolute; inset: -24px; border-radius: 50%; border: 1px solid rgba(77,143,212,0.15); }
|
||||
.hero-image-wrap::after { content: ''; position: absolute; inset: -48px; border-radius: 50%; border: 1px solid rgba(77,143,212,0.07); }
|
||||
.hero-image-wrap img { width: 300px; height: 300px; object-fit: contain; position: relative; z-index: 1; filter: drop-shadow(0 0 40px rgba(77,143,212,0.25)); }
|
||||
.hero-motto-block { text-align: center; }
|
||||
.hero-motto-large { font-family: var(--serif); font-size: clamp(1.3rem, 2vw, 1.8rem); font-weight: normal; font-style: italic; color: var(--txt2); letter-spacing: 0.02em; line-height: 1.3; margin-bottom: 0.4rem; }
|
||||
.hero-motto-large em { font-style: normal; color: var(--accent); }
|
||||
.hero-motto-rule { width: 60px; height: 1px; background: var(--accent); margin: 0.8rem auto; opacity: 0.4; }
|
||||
.hero-motto-sub { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.14em; text-transform: lowercase; color: var(--txt3); }
|
||||
|
||||
/* PILLARS */
|
||||
.pillars { padding: 80px 2.5rem; border-top: 1px solid var(--border); }
|
||||
.pillars-inner { max-width: var(--max); margin: 0 auto; display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--border); }
|
||||
.pillar { background: var(--bg); padding: 2.5rem 2rem; transition: background 0.3s; }
|
||||
.pillar:hover { background: var(--bg1); }
|
||||
.pillar-num { font-family: var(--mono); font-size: 0.7rem; color: var(--accent); letter-spacing: 0.1em; margin-bottom: 1.2rem; }
|
||||
.pillar-title { font-family: var(--serif); font-size: 1.55rem; font-weight: normal; color: var(--txt); margin-bottom: 0.75rem; line-height: 1.2; }
|
||||
.pillar-desc { font-size: 0.9rem; color: var(--txt2); line-height: 1.7; }
|
||||
|
||||
/* FOUNDERS */
|
||||
.founders { background: var(--bg2); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding: 100px 2.5rem; }
|
||||
.founders-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 5rem; align-items: start; max-width: var(--max); margin: 0 auto; }
|
||||
.founders-stat { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 1.5rem; }
|
||||
.founders-stat-num { font-family: var(--serif); font-size: clamp(3.5rem, 6vw, 5rem); font-weight: normal; color: var(--accent); line-height: 1; }
|
||||
.founders-stat-label { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--txt3); }
|
||||
.founders-quote { font-family: var(--serif); font-size: clamp(1.2rem, 2vw, 1.55rem); font-weight: normal; font-style: italic; color: var(--txt); line-height: 1.5; margin-bottom: 2rem; padding-left: 1.5rem; border-left: 2px solid var(--accent); }
|
||||
.founders-body { font-size: 0.95rem; color: var(--txt2); line-height: 1.75; }
|
||||
.founders-expertise { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 2.5rem; }
|
||||
.exp-item { padding: 1.5rem 1.25rem; border: 1px solid var(--border); border-radius: var(--r); background: var(--bg); }
|
||||
.exp-label { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); margin-bottom: 0.5rem; }
|
||||
.exp-text { font-size: 0.85rem; color: var(--txt2); line-height: 1.6; }
|
||||
|
||||
/* AUDIENCE */
|
||||
.audience { background: var(--bg1); }
|
||||
.audience-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-top: 3rem; }
|
||||
.aud-card { border: 1px solid var(--border); padding: 2.2rem 1.8rem; border-radius: var(--r); background: var(--bg); transition: border-color 0.3s, background 0.3s; }
|
||||
.aud-card:hover { border-color: var(--border2); background: var(--bg2); }
|
||||
.aud-icon { width: 40px; height: 40px; border: 1px solid var(--border2); border-radius: var(--r); display: flex; align-items: center; justify-content: center; margin-bottom: 1.5rem; }
|
||||
.aud-icon svg { width: 18px; height: 18px; stroke: var(--accent); fill: none; stroke-width: 1.5; }
|
||||
.aud-title { font-family: var(--serif); font-size: 1.3rem; font-weight: normal; color: var(--txt); margin-bottom: 0.5rem; }
|
||||
.aud-problem { font-size: 0.85rem; color: var(--txt3); margin-bottom: 0.5rem; font-style: italic; }
|
||||
.aud-result { font-size: 0.9rem; color: var(--txt2); line-height: 1.6; }
|
||||
|
||||
/* PIPELINE */
|
||||
.pipeline { background: var(--bg); }
|
||||
.pipeline-flow { display: grid; grid-template-columns: 1fr 40px 1fr 40px 1fr; align-items: center; gap: 0; margin-top: 3.5rem; }
|
||||
.pipe-block { border: 1px solid var(--border); border-radius: var(--r); padding: 2rem 1.75rem; background: var(--bg1); }
|
||||
.pipe-label { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); margin-bottom: 1rem; }
|
||||
.pipe-title { font-family: var(--serif); font-size: 1.2rem; font-weight: normal; color: var(--txt); margin-bottom: 1rem; }
|
||||
.pipe-items { list-style: none; display: flex; flex-direction: column; gap: 0.4rem; }
|
||||
.pipe-items li { font-size: 0.83rem; color: var(--txt2); display: flex; align-items: center; gap: 8px; }
|
||||
.pipe-items li::before { content: ''; width: 4px; height: 4px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
|
||||
.pipe-arrow { display: flex; align-items: center; justify-content: center; color: var(--txt3); }
|
||||
.pipe-arrow svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.5; }
|
||||
|
||||
/* SMARTDB */
|
||||
.smartdb { background: var(--bg2); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); position: relative; overflow: hidden; }
|
||||
.smartdb-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 5rem; align-items: center; }
|
||||
.smartdb-visual { background: var(--bg3); border: 1px solid var(--border2); border-radius: var(--r); padding: 1.75rem; font-family: var(--mono); font-size: 0.78rem; color: var(--txt2); line-height: 1.9; }
|
||||
.smartdb-visual .line-accent { color: var(--accent); }
|
||||
.smartdb-visual .line-dim { color: var(--txt3); }
|
||||
.smartdb-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--accent-dim); border: 1px solid var(--accent2); border-radius: 20px; font-family: var(--mono); font-size: 0.68rem; color: var(--accent); letter-spacing: 0.08em; margin-bottom: 1rem; }
|
||||
.smartdb-badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
|
||||
|
||||
/* DIFF */
|
||||
.diff { background: var(--bg); }
|
||||
.diff-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; background: var(--border); margin-top: 3rem; border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; }
|
||||
.diff-item { background: var(--bg); padding: 2.2rem 2rem; transition: background 0.25s; }
|
||||
.diff-item:hover { background: var(--bg1); }
|
||||
.diff-num { font-family: var(--mono); font-size: 0.7rem; color: var(--txt3); margin-bottom: 0.75rem; }
|
||||
.diff-title { font-size: 1rem; font-weight: 500; color: var(--txt); margin-bottom: 0.5rem; }
|
||||
.diff-body { font-size: 0.875rem; color: var(--txt2); line-height: 1.65; }
|
||||
|
||||
/* TRUST */
|
||||
.trust { background: var(--bg1); border-top: 1px solid var(--border); }
|
||||
.trust-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; margin-top: 3rem; }
|
||||
.trust-item { padding: 1.75rem 1.5rem; border: 1px solid var(--border); border-radius: var(--r); }
|
||||
.trust-icon { margin-bottom: 1rem; color: var(--accent); }
|
||||
.trust-icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.5; }
|
||||
.trust-label { font-size: 0.82rem; font-weight: 500; color: var(--txt); margin-bottom: 0.3rem; }
|
||||
.trust-desc { font-size: 0.8rem; color: var(--txt2); line-height: 1.6; }
|
||||
|
||||
/* CTA FINALE */
|
||||
.cta-final { background: var(--bg); border-top: 1px solid var(--border); text-align: center; position: relative; overflow: hidden; }
|
||||
.cta-glow { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 600px; height: 300px; background: radial-gradient(ellipse, rgba(45,90,163,0.15) 0%, transparent 70%); pointer-events: none; }
|
||||
.cta-final h2 { font-family: var(--serif); font-size: clamp(1.8rem, 3vw, 2.6rem); font-weight: normal; color: var(--txt); max-width: 620px; margin: 0 auto 1.2rem; line-height: 1.2; }
|
||||
.cta-final p { font-size: 0.98rem; color: var(--txt2); max-width: 440px; margin: 0 auto 2.5rem; line-height: 1.7; }
|
||||
.cta-buttons { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
|
||||
</style>
|
||||
39
src/pages/privacy.astro
Normal file
39
src/pages/privacy.astro
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Privacy Policy — Smart Roots"
|
||||
description="Informativa sul trattamento dei dati personali di Smart Roots S.r.l. ai sensi del GDPR."
|
||||
canonical="https://www.smart-roots.net/privacy"
|
||||
noindex={true}
|
||||
>
|
||||
<Nav variant="back" />
|
||||
|
||||
<main>
|
||||
<div class="page-tag">Legal</div>
|
||||
<h1>Privacy Policy</h1>
|
||||
<p class="intro">
|
||||
Informativa sul trattamento dei dati personali ai sensi dell'art. 13 del Regolamento (UE) 2016/679 (GDPR).
|
||||
</p>
|
||||
|
||||
<!-- TODO: inserire testo completo della privacy policy -->
|
||||
<div class="placeholder-notice">
|
||||
<span>⚠</span> Testo completo da completare
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
main { max-width: 760px; margin: 0 auto; padding: 120px 2.5rem 80px; }
|
||||
.page-tag { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); margin-bottom: 1rem; }
|
||||
h1 { font-family: var(--serif); font-size: clamp(1.8rem, 3.5vw, 2.4rem); font-weight: normal; color: var(--txt); line-height: 1.15; margin-bottom: 2rem; }
|
||||
h2 { font-family: var(--serif); font-size: 1.1rem; font-weight: normal; color: var(--txt); margin: 2.5rem 0 0.75rem; }
|
||||
p { font-size: 0.95rem; color: var(--txt2); line-height: 1.8; margin-bottom: 1rem; }
|
||||
.intro { font-size: 1rem; color: var(--txt2); }
|
||||
.placeholder-notice { margin-top: 2rem; padding: 1.25rem 1.5rem; border: 1px dashed var(--border2); border-radius: var(--r); font-family: var(--mono); font-size: 0.8rem; color: var(--txt3); display: flex; align-items: center; gap: 0.75rem; }
|
||||
</style>
|
||||
39
src/pages/termini.astro
Normal file
39
src/pages/termini.astro
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Termini e Condizioni — Smart Roots"
|
||||
description="Termini e condizioni d'uso dei servizi Smart Roots S.r.l."
|
||||
canonical="https://www.smart-roots.net/termini"
|
||||
noindex={true}
|
||||
>
|
||||
<Nav variant="back" />
|
||||
|
||||
<main>
|
||||
<div class="page-tag">Legal</div>
|
||||
<h1>Termini e Condizioni</h1>
|
||||
<p class="intro">
|
||||
Termini e condizioni d'uso dei servizi offerti da Smart Roots S.r.l.
|
||||
</p>
|
||||
|
||||
<!-- TODO: inserire testo completo dei termini -->
|
||||
<div class="placeholder-notice">
|
||||
<span>⚠</span> Testo completo da completare
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
main { max-width: 760px; margin: 0 auto; padding: 120px 2.5rem 80px; }
|
||||
.page-tag { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); margin-bottom: 1rem; }
|
||||
h1 { font-family: var(--serif); font-size: clamp(1.8rem, 3.5vw, 2.4rem); font-weight: normal; color: var(--txt); line-height: 1.15; margin-bottom: 2rem; }
|
||||
h2 { font-family: var(--serif); font-size: 1.1rem; font-weight: normal; color: var(--txt); margin: 2.5rem 0 0.75rem; }
|
||||
p { font-size: 0.95rem; color: var(--txt2); line-height: 1.8; margin-bottom: 1rem; }
|
||||
.intro { font-size: 1rem; color: var(--txt2); }
|
||||
.placeholder-notice { margin-top: 2rem; padding: 1.25rem 1.5rem; border: 1px dashed var(--border2); border-radius: var(--r); font-family: var(--mono); font-size: 0.8rem; color: var(--txt3); display: flex; align-items: center; gap: 0.75rem; }
|
||||
</style>
|
||||
101
src/styles/global.css
Normal file
101
src/styles/global.css
Normal file
@@ -0,0 +1,101 @@
|
||||
/* ============================================================
|
||||
SMART ROOTS — global.css
|
||||
Font: Cormorant Garamond (display/serif) + IBM Plex Sans + IBM Plex Mono
|
||||
============================================================ */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500&family=IBM+Plex+Mono:wght@300;400&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap');
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
:root {
|
||||
--bg: #0b0f1c;
|
||||
--bg1: #111829;
|
||||
--bg2: #171f35;
|
||||
--bg3: #1e2840;
|
||||
--txt: #ddd8d0;
|
||||
--txt2: #8799bb;
|
||||
--txt3: #5a6e90;
|
||||
--accent: #4d8fd4;
|
||||
--accent2: #2e5fa3;
|
||||
--accent-dim: rgba(77,143,212,0.12);
|
||||
--border: rgba(100,140,200,0.10);
|
||||
--border2: rgba(100,140,200,0.18);
|
||||
--mono: 'IBM Plex Mono', monospace;
|
||||
--sans: 'IBM Plex Sans', sans-serif;
|
||||
--serif: 'Cormorant Garamond', Georgia, serif;
|
||||
--max: 1180px;
|
||||
--r: 6px;
|
||||
}
|
||||
|
||||
html { scroll-behavior: smooth; }
|
||||
body { background: var(--bg); color: var(--txt); font-family: var(--sans); font-size: 16px; line-height: 1.7; -webkit-font-smoothing: antialiased; }
|
||||
a { color: inherit; text-decoration: none; }
|
||||
img { display: block; }
|
||||
|
||||
/* ── Utility ── */
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
|
||||
|
||||
/* ── Sezioni comuni ── */
|
||||
section { padding: 100px 2.5rem; }
|
||||
.section-inner { max-width: var(--max); margin: 0 auto; }
|
||||
.section-tag { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); margin-bottom: 1rem; }
|
||||
.section-title { font-family: var(--serif); font-size: clamp(2rem, 3.5vw, 2.8rem); font-weight: normal; line-height: 1.15; color: var(--txt); margin-bottom: 1.2rem; }
|
||||
.section-sub { font-size: 1rem; color: var(--txt2); max-width: 520px; line-height: 1.75; margin-bottom: 3.5rem; }
|
||||
|
||||
/* ── Bottoni ── */
|
||||
.btn-primary { font-size: 0.85rem; font-weight: 500; letter-spacing: 0.04em; padding: 14px 28px; background: var(--accent); color: #06101f; border-radius: var(--r); transition: opacity 0.2s; border: none; cursor: pointer; display: inline-block; }
|
||||
.btn-primary:hover { opacity: 0.85; }
|
||||
.btn-ghost { font-size: 0.85rem; font-weight: 400; letter-spacing: 0.04em; padding: 14px 28px; border: 1px solid var(--border2); color: var(--txt2); border-radius: var(--r); transition: all 0.2s; cursor: pointer; display: inline-block; }
|
||||
.btn-ghost:hover { border-color: var(--txt2); color: var(--txt); }
|
||||
|
||||
/* ── NAV ── */
|
||||
nav { position: fixed; top: 0; left: 0; right: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 0 2.5rem; height: 68px; background: rgba(11,15,28,0.88); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); }
|
||||
.nav-logo { display: flex; align-items: center; gap: 10px; }
|
||||
.nav-logo img { width: 32px; height: 32px; object-fit: contain; }
|
||||
.nav-logo-text { font-family: var(--serif); font-size: 1.4rem; font-weight: normal; letter-spacing: 0.04em; color: var(--txt); }
|
||||
.nav-links { display: flex; gap: 2rem; align-items: center; }
|
||||
.nav-links a { font-size: 0.82rem; font-weight: 400; letter-spacing: 0.05em; text-transform: uppercase; color: var(--txt2); transition: color 0.2s; }
|
||||
.nav-links a:hover { color: var(--txt); }
|
||||
.nav-cta { font-size: 0.8rem !important; font-weight: 500 !important; letter-spacing: 0.04em !important; padding: 8px 18px; border: 1px solid var(--accent2); color: var(--accent) !important; border-radius: var(--r); transition: all 0.2s; }
|
||||
.nav-cta:hover { background: var(--accent-dim) !important; }
|
||||
.nav-back { font-size: 0.8rem; color: var(--txt2); letter-spacing: 0.04em; display: flex; align-items: center; gap: 6px; transition: color 0.2s; }
|
||||
.nav-back:hover { color: var(--txt); }
|
||||
.nav-back::before { content: '←'; }
|
||||
|
||||
/* ── FOOTER ── */
|
||||
footer { border-top: 1px solid var(--border); padding: 2rem 2.5rem; }
|
||||
.footer-inner { max-width: var(--max); margin: 0 auto; width: 100%; display: flex; flex-direction: column; gap: 1.5rem; align-items: flex-start; }
|
||||
.footer-logo { font-family: var(--serif); font-weight: normal; font-size: 1.3rem; color: var(--txt2); }
|
||||
.footer-copy { font-family: var(--mono); font-size: 0.7rem; color: var(--txt3); letter-spacing: 0.06em; }
|
||||
.footer-links { display: flex; gap: 1.5rem; }
|
||||
.footer-links a { font-size: 0.78rem; color: var(--txt3); transition: color 0.2s; }
|
||||
.footer-links a:hover { color: var(--txt2); }
|
||||
|
||||
/* ── FORM CONTATTI ── */
|
||||
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem; }
|
||||
.form-field { margin-bottom: 1rem; }
|
||||
.form-label { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--txt3); display: block; margin-bottom: 0.4rem; }
|
||||
.form-input { width: 100%; background: var(--bg1); border: 1px solid var(--border2); border-radius: var(--r); padding: 12px 14px; color: var(--txt); font-family: var(--sans); font-size: 0.9rem; outline: none; transition: border-color 0.2s; }
|
||||
.form-input:focus { border-color: var(--accent); }
|
||||
.form-input:invalid:not(:placeholder-shown) { border-color: #e24b4a; }
|
||||
.btn-submit { font-family: var(--serif); font-size: 0.9rem; font-weight: normal; padding: 14px 32px; background: var(--accent); color: #06101f; border: none; border-radius: var(--r); cursor: pointer; letter-spacing: 0.04em; transition: opacity 0.2s; }
|
||||
.btn-submit:hover { opacity: 0.85; }
|
||||
.btn-submit:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.form-feedback { display: none; margin-top: 1.5rem; font-family: var(--mono); font-size: 0.8rem; line-height: 1.5; padding: 1rem 1.25rem; border-radius: var(--r); }
|
||||
.form-feedback.ok { color: var(--accent); background: var(--accent-dim); border: 1px solid var(--accent2); }
|
||||
.form-feedback.err { color: #e24b4a; background: rgba(226,75,74,0.08); border: 1px solid rgba(226,75,74,0.3); }
|
||||
.form-note { font-family: var(--mono); font-size: 0.72rem; color: var(--txt3); line-height: 1.6; margin-top: 1rem; }
|
||||
|
||||
/* ── RESPONSIVE ── */
|
||||
@media (max-width: 900px) {
|
||||
.pillars-inner, .audience-grid, .pipeline-flow,
|
||||
.smartdb-inner, .diff-grid, .trust-grid,
|
||||
.founders-inner { grid-template-columns: 1fr !important; }
|
||||
.pipe-arrow { transform: rotate(90deg); }
|
||||
nav .nav-links { display: none; }
|
||||
.pipeline-flow { grid-template-columns: 1fr !important; }
|
||||
.hero-inner { grid-template-columns: 1fr !important; gap: 3rem; }
|
||||
.hero-right { order: -1; }
|
||||
.founders-expertise { grid-template-columns: 1fr !important; }
|
||||
.form-row { grid-template-columns: 1fr; }
|
||||
}
|
||||
Reference in New Issue
Block a user