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 @@
-
+

Risultato

{{ result }}
-
+

Salvato

{{ savedPath }}
-
+

Errore

{{ error }}
@@ -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%; + } +}