diff --git a/internal/server/server.go b/internal/server/server.go index ffda498..dbc2f5e 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -41,6 +41,7 @@ func (s *Server) setupRouter() *mux.Router { limiter := NewLimiter(s.cfg.proxyCount, time.Duration(s.cfg.interval)*time.Minute) api.Handle("/claim", negroni.New(limiter, negroni.Wrap(s.handleClaim()))).Methods("POST") api.Handle("/info/{rollupName}", s.handleInfo()).Methods("GET") + api.Handle("/rollups", s.handleRollups()).Methods("GET") fs := http.FileServer(web.Dist()) @@ -187,6 +188,20 @@ func (s *Server) handleInfo() http.HandlerFunc { } } +// handleRollups returns all deployed rollups +func (s *Server) handleRollups() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + rollups, err := s.sm.Rollups() + if err != nil { + log.WithError(err).Error("Failed to get rollups") + _ = renderJSON(w, errorResponse{Message: err.Error(), Status: http.StatusInternalServerError}, http.StatusInternalServerError) + return + } + + _ = renderJSON(w, rollups, http.StatusOK) + } +} + // txBuilderFromRequest creates and returns a TxBuilder from the request func (s *Server) txBuilderFromRequest(r *http.Request) (chain.TxBuilder, error) { claimRequest, err := readClaimRequest(r) diff --git a/internal/store/store.go b/internal/store/store.go index 709a981..294fe41 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -10,6 +10,7 @@ import ( ) type RollupStoreManager interface { + Rollups() ([]RollupDoc, error) FindRollupByName(name string) (RollupDoc, error) RollupByNameWithPrivate(name string) (RollupDoc, error) } @@ -57,10 +58,10 @@ const ( ) type RollupDoc struct { - ID string `firestore:"id"` - Name string `firestore:"name"` - NetworkID uint32 `firestore:"networkId"` - Status RollupDocumentStatus `firestore:"status"` + ID string `firestore:"id" json:"id"` + Name string `firestore:"name" json:"name"` + NetworkID uint32 `firestore:"networkId" json:"networkId"` + Status RollupDocumentStatus `firestore:"status" json:"status"` RollupPublicDetails PrivateDetails RollupPrivateDoc @@ -72,10 +73,41 @@ type RollupPrivateDoc struct { } type RollupPublicDetails struct { - RollupAccountAddress string `firestore:"rollupAccountAddress"` - RollupAccountPublicKey string `firestore:"rollupAccountPublicKey"` - SequencerAccountAddress string `firestore:"sequencerAccountAddress"` - SequencerAccountPublicKey string `firestore:"sequencerAccountPublicKey"` + RollupAccountAddress string `firestore:"rollupAccountAddress" json:"rollupAccountAddress"` + RollupAccountPublicKey string `firestore:"rollupAccountPublicKey" json:"rollupAccountPublicKey"` + SequencerAccountAddress string `firestore:"sequencerAccountAddress" json:"sequencerAccountAddress"` + SequencerAccountPublicKey string `firestore:"sequencerAccountPublicKey" json:"sequencerAccountPublicKey"` +} + +// Rollups queries the store to find all deployed rollups +func (m *Manager) Rollups() ([]RollupDoc, error) { + ctx := context.Background() + + iter := m.client.CollectionGroup(m.rollupsCollection). + Where("status", "==", StatusDeployed). + OrderBy("name", firestore.Asc). + Documents(ctx) + defer iter.Stop() + + var rollups []RollupDoc + for { + doc, err := iter.Next() + if errors.Is(err, iterator.Done) { + break + } + if err != nil { + return []RollupDoc{}, err + } + + var rollup RollupDoc + if err := doc.DataTo(&rollup); err != nil { + return []RollupDoc{}, err + } + rollup.ID = doc.Ref.ID + rollups = append(rollups, rollup) + } + + return rollups, nil } // FindRollupByName queries the store to find a rollup with the given name diff --git a/web/package-lock.json b/web/package-lock.json index b72c825..40af875 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -18,7 +18,9 @@ "@sveltejs/vite-plugin-svelte": "^2.0.2", "prettier": "^2.8.4", "prettier-plugin-svelte": "^2.9.0", + "sass": "^1.70.0", "svelte": "^3.55.1", + "svelte-routing": "^2.11.0", "vite": "^4.1.0" } }, @@ -849,16 +851,50 @@ "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -874,6 +910,33 @@ "resolved": "https://registry.npmjs.org/bulma-toast/-/bulma-toast-2.4.2.tgz", "integrity": "sha512-c3ehyeXhhvxevKICP1VKsFtZlQH+H6/S+yYY4TFyLRfkbw3mh71eGazlNc/YEIvXQSbxHpD2f+WDc02xECuV9g==" }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -956,6 +1019,18 @@ "@esbuild/win32-x64": "0.16.17" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -976,6 +1051,18 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1007,11 +1094,29 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/immutable": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", + "dev": true + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -1024,6 +1129,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -1078,6 +1213,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -1090,6 +1234,18 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { "version": "8.4.21", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", @@ -1139,6 +1295,18 @@ "svelte": "^3.2.0" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -1172,6 +1340,23 @@ "fsevents": "~2.3.2" } }, + "node_modules/sass": { + "version": "1.70.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz", + "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -1214,6 +1399,24 @@ "svelte": ">=3.19.0" } }, + "node_modules/svelte-routing": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/svelte-routing/-/svelte-routing-2.11.0.tgz", + "integrity": "sha512-oNJz2A8g5ZqBDuxUWMJLpU9XXGZ40Fz5uRvrGlpENs5C2QWK5m7YKiGINssN9yI/22f9wi4F5oTTkDaTyryolw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/vite": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", diff --git a/web/package.json b/web/package.json index cbe5dc8..0df7814 100644 --- a/web/package.json +++ b/web/package.json @@ -13,7 +13,9 @@ "@sveltejs/vite-plugin-svelte": "^2.0.2", "prettier": "^2.8.4", "prettier-plugin-svelte": "^2.9.0", + "sass": "^1.70.0", "svelte": "^3.55.1", + "svelte-routing": "^2.11.0", "vite": "^4.1.0" }, "dependencies": { diff --git a/web/src/App.svelte b/web/src/App.svelte index 625d554..cd77286 100644 --- a/web/src/App.svelte +++ b/web/src/App.svelte @@ -1,14 +1,51 @@ - - + - + +
+ + + + + + + +
+
diff --git a/web/src/Faucet.svelte b/web/src/Faucet.svelte index 0f99f35..2bb1b53 100644 --- a/web/src/Faucet.svelte +++ b/web/src/Faucet.svelte @@ -115,39 +115,6 @@
-
- -
-
@@ -192,10 +159,6 @@ background-size: cover; } - .hero.is-info a.navbar-item:hover { - background-color: transparent; - } - .hero .subtitle { padding: 3rem 0; line-height: 1.5; @@ -205,8 +168,4 @@ border-radius: 0; background: transparent; } - - .button { - border-radius: 0; - } diff --git a/web/src/Rollups.svelte b/web/src/Rollups.svelte new file mode 100644 index 0000000..072a820 --- /dev/null +++ b/web/src/Rollups.svelte @@ -0,0 +1,74 @@ + + + + +
+
+
+
+
+ {#each rollups as rollup} +
+
+

+ {rollup.name} +

+
+ +
+ {/each} +
+
+
+
+
+ + diff --git a/web/src/logo.svg b/web/src/logo.svg new file mode 100644 index 0000000..25bd0b2 --- /dev/null +++ b/web/src/logo.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/scss/astria-colors.scss b/web/src/scss/astria-colors.scss new file mode 100644 index 0000000..65cfbe5 --- /dev/null +++ b/web/src/scss/astria-colors.scss @@ -0,0 +1,61 @@ +// astria colors +$astria-white: #f5f5f5; +$astria-whitest: #fff; +$astria-grey-dark: #333; +$astria-grey-light: hsl(0, 0%, 60%); +$astria-black: hsl(203deg 45% 4%); +$astria-red: #BB3631; +$astria-orange: #df5822; +$astria-orange-soft: #f09226; +$astria-green: #3B7D4F; +$astria-blue-light: #74A4BF; +$astria-yellow: #E0B74A; + +$success: $astria-green; +$info: $astria-blue-light; +$warning: $astria-yellow; +$danger: $astria-red; + +$astria-error-lighter: #f8d7da; +$astria-error-light: #f5c6cb; +$astria-error-dark: #721c24; + +$astria-text-light: $astria-white; +$astria-text-dark: $astria-grey-dark; + +// general color overrides +$body-background-color: $astria-black; +$text: $astria-text-light; +$link: $astria-white; +$link-hover: $astria-whitest; + +// navbar colors +$navbar-item-hover-color: $astria-text-dark; +$navbar-item-hover-background-color: $astria-orange-soft; + + +// gradient mixins +@mixin astria-bg-gradient { + background: linear-gradient(to right, $astria-orange-soft, $astria-orange); +} + +@mixin astria-border-gradient { + border-image: linear-gradient(to right, $astria-orange-soft, $astria-orange) 1; +} + +@mixin astria-button-gradient { + @include astria-bg-gradient; + border: none; + @include astria-border-gradient; +} + +@mixin astria-bottom-border-gradient { + background: linear-gradient( + to right, + $astria-orange-soft, + 50%, + $astria-orange, + ) left bottom no-repeat; + background-size: 100% 5px; + border-radius: 0; +} diff --git a/web/src/scss/button-customizations.scss b/web/src/scss/button-customizations.scss new file mode 100644 index 0000000..4f6c8c6 --- /dev/null +++ b/web/src/scss/button-customizations.scss @@ -0,0 +1,49 @@ +@import './astria-colors'; + +.button.is-square { + border-radius: 0; +} + +.button.has-gradient-to-right-orange { + @include astria-button-gradient; +} + +.button.is-tall { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} +.button.is-taller { + padding-top: 2rem; + padding-bottom: 2rem; +} +.button.is-wide { + padding-left: 2rem; + padding-right: 2rem; +} +.button.is-wider { + padding-left: 4rem; + padding-right: 4rem; +} + +.button.is-ghost { + + &.is-outlined-light { + border-color: $astria-white; + &:disabled { + background-color: transparent; + border-color: $astria-white; + cursor: not-allowed; + opacity: 0.5; + } + } + + &:hover, &.is-hovered { + // this selector should be specific enough to override bulma's default, + // but for some reason !important was necessary here + text-decoration: none !important; + } + + &:focus, &.is-focused { + box-shadow: none; + } +} diff --git a/web/src/scss/button-overrides.scss b/web/src/scss/button-overrides.scss new file mode 100644 index 0000000..a6ff4d4 --- /dev/null +++ b/web/src/scss/button-overrides.scss @@ -0,0 +1,5 @@ +@import './astria-colors'; + +$button-color: $astria-text-dark; +$label-color: $astria-text-light; +$control-radius: 12px; // buttons diff --git a/web/src/scss/card-customizations.scss b/web/src/scss/card-customizations.scss new file mode 100644 index 0000000..b2a7d1e --- /dev/null +++ b/web/src/scss/card-customizations.scss @@ -0,0 +1,48 @@ +@import './astria-colors'; + +.error-card { + background-color: $astria-error-lighter; + border-color: $astria-error-light; + color: $astria-error-dark; + + * { + color: $astria-error-dark; + } +} + +.card { + &.disabled { + opacity: 0.5; + pointer-events: none; + } + + a.disabled { + pointer-events: none; + } + + //background-color: $astria-black; + background: radial-gradient(144.23% 141.13% at 50.15% 0%, #221F1F 0%, #050A0D 100%); + box-shadow: 1px 1px 1px -1px hsla(0, 0%, 100%, 0.5) inset; + //padding: 3rem 1.5rem; + + &.is-fuzzy-bottomed { + background: radial-gradient(100% 100% at 50.15% 0%, #221F1F 0%, #050A0D 100%); + } + + .card-content { + .is-ghost { + &:hover, &.is-hovered { + text-decoration: none; + } + + &:focus, &.is-focused { + box-shadow: none; + } + } + } + + .card-footer { + border-top: none; + box-shadow: none; + } +} diff --git a/web/src/scss/card-overrides.scss b/web/src/scss/card-overrides.scss new file mode 100644 index 0000000..d2cfa34 --- /dev/null +++ b/web/src/scss/card-overrides.scss @@ -0,0 +1,7 @@ +$card-radius: 16px; + +$card-shadow: none; +$card-header-shadow: none; + +$modal-card-head-radius: 0; +$modal-card-foot-radius: 0; diff --git a/web/src/scss/fonts.scss b/web/src/scss/fonts.scss new file mode 100644 index 0000000..f2b8fa2 --- /dev/null +++ b/web/src/scss/fonts.scss @@ -0,0 +1,11 @@ +// customizations for bulma +$family-sans-serif: 'NB Akademie', sans-serif; +$family-monospace: 'NB Akademie Mono', monospace; + +p { + letter-spacing: -0.02em; +} + +h1, h2, h3, .button { + letter-spacing: -.05em; +} diff --git a/web/src/scss/form-customizations.scss b/web/src/scss/form-customizations.scss new file mode 100644 index 0000000..e69de29 diff --git a/web/src/scss/form-overrides.scss b/web/src/scss/form-overrides.scss new file mode 100644 index 0000000..331f6bb --- /dev/null +++ b/web/src/scss/form-overrides.scss @@ -0,0 +1,7 @@ +@import 'astria-colors'; + +$input-radius: 12px; +$control-padding-vertical: 1.5rem; +$input-background-color: transparent; +$input-color: $astria-grey-light; +$input-border-color: $astria-grey-light; diff --git a/web/src/scss/index.scss b/web/src/scss/index.scss new file mode 100644 index 0000000..c6ae8b3 --- /dev/null +++ b/web/src/scss/index.scss @@ -0,0 +1,120 @@ +html, body { + height: 100vh; +} + +// fonts +@import './fonts'; + +// astria bulma overrides +// NOTE - scss variable overrides be imported BEFORE bulma so that the overriden variables are +// used in the bulma sass +@import 'astria-colors'; +@import 'button-overrides'; +@import 'card-overrides'; +@import 'form-overrides'; + +// bulma +@import '../../node_modules/bulma/bulma'; +@import '../../node_modules/bulma/sass/utilities/initial-variables'; +@import '../../node_modules/bulma/sass/components/navbar'; + +// NOTE - these css customizations must be imported AFTER bulma to override the css classes +@import 'button-customizations'; +@import 'card-customizations'; +@import 'form-customizations'; + +// body reset +body { + margin: 0; + padding: 0; + background-color: $astria-black; +} + +// navbar customizations +.navbar { + background-color: transparent; + padding: 1rem 2rem; +} + +.is-fullheight-with-navbar { + // viewport height minus navbar height minus footer height minus margins + min-height: calc(100vh - 72px - 24px) +} + +.notifications-toast-container { + position: fixed; + top: 0; + right: 0; + z-index: 9999; + width: 100%; + max-width: 400px; + padding: 1rem; + + .notification { + margin-bottom: 0.5rem; + } +} + +/** + * Animations + */ +@keyframes fadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +.fade-out { + animation-name: fadeOut; + animation-duration: 1.5s; + animation-fill-mode: forwards; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.fade-in { + animation-name: fadeIn; + animation-duration: 1s; + animation-fill-mode: forwards; +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + 50% { + transform: scale(0.75); + } + 100% { + transform: scale(1); + } +} + +.icon-pulse { + animation-name: pulse; + animation-duration: 1s; + animation-iteration-count: infinite; + animation-timing-function: ease-in-out; +} + +.icon-pulse-slow { + animation-name: pulse; + animation-duration: 3s; + animation-iteration-count: infinite; + animation-timing-function: ease-in-out; +} + +.is-text-overflow { + overflow: hidden; + text-overflow: ellipsis; +}