diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index e9a71fa..bd0826d 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -2,47 +2,52 @@
AddressGen
- Genera indirizzi Bitcoin localmente usando il backend Python.
+ Genera indirizzi Bitcoin P2PK, P2PKH, P2WPKH, P2TR e P2SH multisig.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -55,17 +60,17 @@
-
+
-
+
-
+
@@ -163,103 +168,3 @@ const save = async () => {
}
};
-
-
diff --git a/frontend/src/main.js b/frontend/src/main.js
index b670de8..cc32073 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -1,4 +1,5 @@
import { createApp } from "vue";
import App from "./App.vue";
+import "./styles/app.css";
createApp(App).mount("#app");
diff --git a/frontend/src/styles/app.css b/frontend/src/styles/app.css
new file mode 100644
index 0000000..34055c3
--- /dev/null
+++ b/frontend/src/styles/app.css
@@ -0,0 +1,290 @@
+@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Spline+Sans+Mono:wght@400;600&display=swap");
+
+:root {
+ color-scheme: dark;
+ font-family: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
+ --content-width: min(1020px, 100%);
+ --bg-1: #0c0f14;
+ --bg-2: #141a24;
+ --bg-3: #1b2431;
+ --card: rgba(20, 26, 36, 0.78);
+ --card-border: rgba(148, 163, 184, 0.18);
+ --text-1: #e7eef8;
+ --text-2: #a9b7c9;
+ --accent: #38d39f;
+ --accent-2: #f4c553;
+ --danger: #ff6b6b;
+ --shadow: 0 18px 40px rgba(5, 8, 14, 0.45);
+ --radius-xl: 22px;
+ --radius-lg: 16px;
+ --radius-md: 12px;
+ --radius-sm: 8px;
+ --focus: 0 0 0 3px rgba(56, 211, 159, 0.25);
+}
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ min-height: 100vh;
+ background: radial-gradient(circle at 20% 20%, rgba(56, 211, 159, 0.18), transparent 45%),
+ radial-gradient(circle at 80% 10%, rgba(244, 197, 83, 0.2), transparent 40%),
+ linear-gradient(160deg, var(--bg-1), var(--bg-2) 50%, var(--bg-3));
+ color: var(--text-1);
+ letter-spacing: 0.01em;
+ overflow: hidden;
+}
+
+#app {
+ min-height: 100vh;
+ height: 100vh;
+}
+
+.page {
+ min-height: 100vh;
+ height: 100vh;
+ padding: 24px 20px 28px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ position: relative;
+ overflow: hidden;
+}
+
+.page::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at 70% 80%, rgba(56, 211, 159, 0.12), transparent 55%);
+ pointer-events: none;
+ z-index: 0;
+}
+
+.hero,
+.card {
+ position: relative;
+ z-index: 1;
+}
+
+.hero {
+ max-width: var(--content-width);
+ margin: 0 auto;
+ text-align: left;
+ animation: rise-in 600ms ease-out;
+}
+
+.hero h1 {
+ font-size: clamp(2.1rem, 2.6vw, 2.8rem);
+ font-weight: 700;
+ letter-spacing: -0.02em;
+}
+
+.hero p {
+ margin-top: 6px;
+ color: var(--text-2);
+ font-size: 0.98rem;
+}
+
+.card {
+ background: var(--card);
+ border: 1px solid var(--card-border);
+ border-radius: var(--radius-xl);
+ padding: 16px 18px;
+ max-width: var(--content-width);
+ width: 100%;
+ margin: 0 auto;
+ box-shadow: var(--shadow);
+ backdrop-filter: blur(10px);
+ animation: fade-in 500ms ease-out;
+}
+
+.card h2 {
+ margin-bottom: 8px;
+ font-size: 1.1rem;
+}
+
+.form-card {
+ padding-bottom: 20px;
+}
+
+.form-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px 18px;
+ margin-bottom: 12px;
+}
+
+.row {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.row label {
+ font-weight: 600;
+ color: var(--text-2);
+ text-transform: uppercase;
+ font-size: 0.78rem;
+ letter-spacing: 0.08em;
+}
+
+.inline {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.inline span {
+ color: var(--text-2);
+ font-size: 0.9rem;
+}
+
+input,
+select {
+ width: 100%;
+ padding: 10px 12px;
+ border-radius: var(--radius-md);
+ border: 1px solid rgba(148, 163, 184, 0.25);
+ background: rgba(10, 14, 20, 0.75);
+ color: var(--text-1);
+ font-size: 0.98rem;
+ transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
+}
+
+input:focus,
+select:focus {
+ outline: none;
+ border-color: rgba(56, 211, 159, 0.6);
+ box-shadow: var(--focus);
+}
+
+input[type="checkbox"] {
+ width: 18px;
+ height: 18px;
+ accent-color: var(--accent);
+}
+
+.actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ margin-top: 4px;
+}
+
+button {
+ border: none;
+ font-weight: 600;
+ cursor: pointer;
+ border-radius: 999px;
+ padding: 10px 18px;
+ transition: transform 150ms ease, box-shadow 150ms ease, opacity 150ms ease;
+}
+
+button:focus-visible {
+ outline: none;
+ box-shadow: var(--focus);
+}
+
+button.primary {
+ background: linear-gradient(135deg, var(--accent), #1f9d7a);
+ color: #061016;
+ box-shadow: 0 12px 24px rgba(31, 157, 122, 0.3);
+}
+
+button.primary:hover:not(:disabled) {
+ transform: translateY(-1px);
+}
+
+button.secondary {
+ background: transparent;
+ color: var(--text-1);
+ border: 1px solid rgba(148, 163, 184, 0.45);
+}
+
+button.secondary:hover:not(:disabled) {
+ border-color: rgba(56, 211, 159, 0.6);
+}
+
+button:disabled {
+ opacity: 0.55;
+ cursor: not-allowed;
+ transform: none;
+}
+
+pre {
+ white-space: pre-wrap;
+ background: rgba(7, 11, 17, 0.85);
+ padding: 14px 16px;
+ border-radius: var(--radius-lg);
+ border: 1px solid rgba(148, 163, 184, 0.2);
+ overflow: auto;
+ font-family: "Spline Sans Mono", "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;
+ color: #cfe6ff;
+}
+
+.output-card {
+ flex: 1;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.output-card pre {
+ flex: 1;
+ min-height: 0;
+ margin-top: 6px;
+}
+
+.output-card.result-card {
+ flex: 2;
+}
+
+.output-card.saved-card pre {
+ white-space: pre-line;
+ word-break: break-all;
+ overflow: hidden;
+}
+
+@keyframes fade-in {
+ from {
+ opacity: 0;
+ transform: translateY(6px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes rise-in {
+ from {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@media (max-width: 720px) {
+ .form-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .row {
+ gap: 6px;
+ }
+
+ .actions {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ button {
+ width: 100%;
+ }
+}