@visualizevalue/mint-app-base 0.0.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.env.example +1 -1
  2. package/app/assets/styles/animation.css +1 -9
  3. package/app/assets/styles/base.css +3 -12
  4. package/app/assets/styles/forms.css +18 -54
  5. package/app/assets/styles/index.css +24 -6
  6. package/app/assets/styles/normalize.css +8 -3
  7. package/app/assets/styles/prose.css +2 -128
  8. package/app/assets/styles/variables/animations.css +8 -0
  9. package/app/assets/styles/variables/borders.css +13 -0
  10. package/app/assets/styles/variables/colors.css +48 -0
  11. package/app/assets/styles/{theme.css → variables/components.css} +8 -2
  12. package/app/assets/styles/variables/effects.css +11 -0
  13. package/app/assets/styles/variables/fonts.css +26 -0
  14. package/app/assets/styles/variables/layout.css +9 -0
  15. package/app/assets/styles/variables/sizes.css +23 -0
  16. package/app/assets/styles/variables/ui.css +17 -0
  17. package/app/assets/styles/variables.css +16 -192
  18. package/app/assets/styles/web3-modals.css +2 -7
  19. package/app/components/Account.client.vue +1 -1
  20. package/app/components/Actions.vue +2 -3
  21. package/app/components/AppHeader.vue +2 -25
  22. package/app/components/Breadcrumbs.vue +1 -1
  23. package/app/components/Button/AddCollection.vue +10 -0
  24. package/app/components/Button/EditProfile.vue +10 -0
  25. package/app/components/Button/Profile/Discord.vue +10 -0
  26. package/app/components/Button/Profile/Email.vue +10 -0
  27. package/app/components/Button/Profile/Github.vue +11 -0
  28. package/app/components/Button/Profile/Twitter.vue +10 -0
  29. package/app/components/Button/Profile/Website.vue +10 -0
  30. package/app/components/Button.vue +17 -36
  31. package/app/components/CheckSpinner.vue +0 -18
  32. package/app/components/Collection/Intro.vue +9 -6
  33. package/app/components/Collection/OverviewCard.vue +11 -5
  34. package/app/components/Collection/Withdraw.client.vue +2 -1
  35. package/app/components/DialogFrame.vue +4 -7
  36. package/app/components/Form/Group.vue +19 -4
  37. package/app/components/Form/SelectFile.vue +1 -1
  38. package/app/components/Icon.vue +21 -17
  39. package/app/components/Image.client.vue +0 -4
  40. package/app/components/Loading.vue +2 -38
  41. package/app/components/MintGasPricePopover.client.vue +2 -2
  42. package/app/components/MintToken.vue +1 -1
  43. package/app/components/Modal.vue +3 -2
  44. package/app/components/Popover.client.vue +3 -23
  45. package/app/components/Profile/Header.client.vue +6 -35
  46. package/app/components/Token/Detail.client.vue +19 -10
  47. package/app/components/Token/MintTimeline.client.vue +14 -43
  48. package/app/components/Token/MintTimelineItem.vue +50 -13
  49. package/app/components/Token/OverviewCard.vue +10 -17
  50. package/app/components/TransactionFlow.vue +4 -10
  51. package/app/layouts/default.vue +2 -14
  52. package/app/pages/[id]/[collection]/[tokenId]/index.vue +1 -1
  53. package/app/pages/[id]/[collection]/index.vue +1 -1
  54. package/app/pages/[id]/[collection]/mint.vue +4 -4
  55. package/app/pages/[id]/create.vue +49 -49
  56. package/app/pages/[id]/index.vue +1 -6
  57. package/app/pages/profile/[address]/index.vue +1 -4
  58. package/app/plugins/2.wagmi.ts +2 -2
  59. package/package.json +2 -1
  60. package/app/assets/styles/scroll.css +0 -13
  61. package/app/assets/styles/text.css +0 -14
  62. package/app/assets/styles/utils.css +0 -24
  63. package/app/components/Avatar.vue +0 -61
  64. package/app/components/CountDown.vue +0 -153
  65. package/app/components/IconLink.vue +0 -29
  66. package/app/components/Navbar.client.vue +0 -86
  67. package/app/components/QueryDialog.vue +0 -38
  68. package/app/components/ToggleDarkMode.client.vue +0 -58
  69. /package/app/components/{Visual/ImagePreview.vue → ImagePreview.vue} +0 -0
@@ -18,6 +18,7 @@ fieldset {
18
18
  max-width: -webkit-fill-available;
19
19
  display: flex;
20
20
  flex-wrap: wrap;
21
+ position: relative;
21
22
 
22
23
  > * {
23
24
  width: 100cqw;
@@ -49,20 +50,34 @@ fieldset {
49
50
 
50
51
  :deep(> .form-item),
51
52
  :deep(> .button) {
53
+ z-index: 1;
54
+
55
+ &:--highlight,
56
+ &:has(.input:hover),
57
+ &:has(.input:focus) {
58
+ z-index: 2;
59
+ }
60
+
52
61
  + .form-item,
53
62
  + .button {
54
- border-top-color: transparent;
63
+ margin-top: calc(-1 * var(--border-width));
55
64
 
65
+ &:--highlight,
66
+ &:has(.input:hover),
56
67
  &:has(.input:focus) {
57
- border-top-color: var(--border-color-light);
68
+ border-top-color: var(--button-border-color-highlight);
58
69
  }
59
70
 
60
71
  @container (min-width: 30rem) {
61
72
  border-top-color: var(--border-color);
62
- border-left-color: transparent;
73
+ margin-top: 0;
74
+ margin-left: calc(-1 * var(--border-width));
63
75
 
76
+ &:--highlight,
77
+ &:has(.input:hover),
64
78
  &:has(.input:focus) {
65
- border-left-color: var(--border-color-light);
79
+ border-top-color: var(--button-border-color-highlight);
80
+ border-left-color: var(--button-border-color-highlight);
66
81
  }
67
82
  }
68
83
  }
@@ -21,7 +21,7 @@
21
21
  import { useFileDialog } from '@vueuse/core'
22
22
 
23
23
  const emit = defineEmits<{
24
- change: [file: File|null]
24
+ change: [file: File|null|undefined]
25
25
  }>()
26
26
 
27
27
  const { files, open, reset, onChange } = useFileDialog({
@@ -1,37 +1,41 @@
1
1
  <template>
2
2
  <i v-if="ICONS[type]" class="icon">
3
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" v-html="ICONS[type]"></svg>
3
+ {{ symbol }}
4
4
  </i>
5
- <FeatherIcon v-else :type="type" class="icon" />
6
5
  </template>
7
6
 
8
7
  <script setup>
9
- import FeatherIcon from 'vue-feather'
10
-
11
8
  const props = defineProps({
12
9
  type: String,
13
10
  })
14
11
 
15
12
  const ICONS = {
16
- 'x.com': `<path d="M13.5222 10.7749L19.4785 4H18.0671L12.8952 9.88256L8.76437 4H4L10.2466 12.8955L4 20H5.41155L10.8732 13.7878L15.2356 20H20L13.5222 10.7749Z" fill="currentColor"/><path d="M11.5889 12.9738L10.956 12.0881M12.1522 10.728L12.7851 11.6137L18.0677 19.0075M13.5222 10.7749L19.4785 4H18.0671L12.8952 9.88256L8.76437 4H4L10.2466 12.8955L4 20H5.41155L10.8732 13.7878L15.2356 20H20L13.5222 10.7749Z" stroke="currentColor"/>`,
17
- vv: `<path d="M11 14.0646C11 15.0625 10.6833 15.8796 10.05 16.5162L6.6 20H4.4L0.949997 16.5162C0.316667 15.8796 0 15.0625 0 14.0646V5H2.575V13.9614C2.575 14.3915 2.68333 14.7183 2.9 14.942L5.525 17.6775L8.1 14.942C8.31669 14.7183 8.425 14.3915 8.425 13.9614V5H11V14.0646Z" fill="currentColor"/><path d="M24 14.0646C24 15.0625 23.6833 15.8796 23.05 16.5162L19.6 20H17.4L13.95 16.5162C13.3167 15.8796 13 15.0625 13 14.0646V5H15.575V13.9614C15.575 14.3915 15.6833 14.7183 15.9 14.942L18.525 17.6775L21.1 14.942C21.3167 14.7183 21.425 14.3915 21.425 13.9614V5H24V14.0646Z" fill="currentColor"/>`,
18
- check: `<path fill-rule="evenodd" clip-rule="evenodd" d="M15.36 3.88585C15.0088 3.30969 14.5152 2.83358 13.9268 2.50331C13.3383 2.17304 12.6748 1.99971 12 2C10.577 2 9.33 2.75494 8.64 3.88685C7.98396 3.72742 7.29792 3.73945 6.64787 3.92179C5.99782 4.10413 5.40562 4.45064 4.92823 4.928C4.45083 5.40536 4.10429 5.99751 3.92194 6.64751C3.73959 7.29751 3.72756 7.98349 3.887 8.63948C3.31061 8.99055 2.83426 9.48402 2.50379 10.0724C2.17331 10.6608 1.99982 11.3244 2 11.9992C2 13.4221 2.755 14.668 3.886 15.359C3.72655 16.0149 3.73859 16.7009 3.92094 17.3509C4.10329 18.0009 4.44983 18.5931 4.92723 19.0704C5.40462 19.5478 5.99682 19.8943 6.64687 20.0766C7.29692 20.259 7.98296 20.271 8.639 20.1116C9.1267 20.913 9.88486 21.5137 10.7766 21.8053C11.6684 22.0968 12.635 22.06 13.502 21.7015C14.2737 21.3815 14.9241 20.8252 15.36 20.1126C16.0161 20.2721 16.7023 20.2601 17.3525 20.0777C18.0026 19.8953 18.5949 19.5487 19.0723 19.0712C19.5498 18.5937 19.8963 18.0014 20.0785 17.3513C20.2608 16.7011 20.2727 16.015 20.113 15.359C20.6894 15.0079 21.1657 14.5144 21.4962 13.926C21.8267 13.3376 22.0002 12.6741 22 11.9992C22.0002 11.3244 21.8267 10.6608 21.4962 10.0724C21.1657 9.48402 20.6894 8.99055 20.113 8.63948C20.2723 7.98354 20.2601 7.29765 20.0776 6.64778C19.8951 5.99791 19.5485 5.40592 19.071 4.92877C18.594 4.45131 18.0022 4.10459 17.3525 3.92194C16.7027 3.7393 16.0169 3.72687 15.361 3.88585H15.36ZM11.402 15.5979L15.964 8.75447C16.53 7.90854 15.213 7.03061 14.648 7.87654L10.622 13.9191L9.251 12.5512C8.534 11.8292 7.415 12.9471 8.135 13.6671L10.305 15.8169C10.3913 15.8749 10.4883 15.9152 10.5903 15.9356C10.6923 15.9559 10.7973 15.9558 10.8993 15.9354C11.0013 15.9149 11.0982 15.8745 11.1845 15.8164C11.2708 15.7583 11.3447 15.6837 11.402 15.5969V15.5979Z" fill="currentColor"/>`,
13
+ home: '🜂',
14
+ trash: '✕',
15
+ times: '✕',
16
+ close: '✕',
17
+ folder: '✏',
18
+ edit: '✏',
19
+ check: '✓',
20
+ add: '+',
21
+ image: '+',
22
+ link: '↗︎',
23
+ user: '☻',
24
+ loader: 'ⴵ',
25
+ 'chevron-up': '↑',
26
+ 'chevron-down': '↓',
27
+ 'chevron-right': '→',
28
+ withdraw: 'Ξ',
19
29
  }
30
+
31
+ const symbol = computed(() => ICONS[props.type])
20
32
  </script>
21
33
 
22
34
  <style scoped>
23
35
  .icon {
24
- display: inline-block;
36
+ display: inline-flex;
25
37
  width: var(--size-4);
26
38
  height: var(--size-4);
27
-
28
- :deep(svg) {
29
- width: 100%;
30
- height: 100%;
31
- }
32
-
33
- &.spin {
34
- animation: spin 5s infinite linear;
35
- }
39
+ align-items: center;
36
40
  }
37
41
  </style>
@@ -68,10 +68,6 @@ article.image {
68
68
  padding-bottom: 100%;
69
69
  display: flex;
70
70
 
71
- &.bordered {
72
- box-shadow: var(--border-shadow);
73
- }
74
-
75
71
  .loader {
76
72
  position: absolute;
77
73
  top: 0;
@@ -1,6 +1,5 @@
1
1
  <template>
2
2
  <div class="loader">
3
- <span class="spinner"></span>
4
3
  <span v-if="txt" class="text">{{ txt }}</span>
5
4
  </div>
6
5
  </template>
@@ -26,8 +25,8 @@ const { txt } = defineProps({
26
25
  .text {
27
26
  text-transform: var(--text-transform-ui);
28
27
  color: var(--muted);
29
- font-family: var(--font-family-ui);
30
- font-weight: var(--font-weight-bold);
28
+ font-family: var(--ui-font-family);
29
+ font-weight: var(--ui-font-weight);
31
30
  }
32
31
 
33
32
  &:not(.inline) {
@@ -40,40 +39,5 @@ const { txt } = defineProps({
40
39
  gap: var(--size-1);
41
40
  margin-left: var(--size-1);
42
41
  }
43
-
44
- &.large {
45
- font-size: var(--font-size-xl);
46
-
47
- .spinner {
48
- border-width: 4px;
49
- }
50
- }
51
-
52
- &.simple {
53
- .text {
54
- display: none;
55
- }
56
- }
57
-
58
- .spinner {
59
- position: relative;
60
- display: inline-block;
61
- width: 0.75em;
62
- height: 0.75em;
63
- border-radius: 50%;
64
- border: 2px solid var(--gray-z-6);
65
- border-right-color: var(--gray-z-3);
66
- flex-shrink: 0;
67
- animation: spin infinite linear 1s;
68
- }
69
- }
70
-
71
- @keyframes spin {
72
- 0% {
73
- transform: rotate(0);
74
- }
75
- 100% {
76
- transform: rotate(360deg);
77
- }
78
42
  }
79
43
  </style>
@@ -2,7 +2,7 @@
2
2
  <Popover id="about-gas">
3
3
  <template #trigger><MintGasPrice :mint-count="2" /></template>
4
4
  <template #content>
5
- <div class="minimal-prose">
5
+ <div class="prose">
6
6
  <h1>Mint Pricing</h1>
7
7
  <p>Artifacts are priced based on the ethereum network fees at the time of collecting.</p>
8
8
  <p>Network fees (Gas fees) are an essential component of of securing and running decentralized blockchains.</p>
@@ -65,5 +65,5 @@
65
65
  margin-left: auto;
66
66
  }
67
67
  }
68
-
69
68
  </style>
69
+
@@ -25,7 +25,7 @@
25
25
  },
26
26
  action: {
27
27
  confirm: 'Mint',
28
- error: 'Retry',
28
+ error: 'Mint',
29
29
  complete: 'OK',
30
30
  },
31
31
  },
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <DialogFrame class="modal" ref="dialog">
3
- <button v-if="xClose" class="close" @click="$emit('close')"><Icon type="x" /></button>
2
+ <DialogFrame class="modal" :class="class" ref="dialog">
3
+ <button v-if="xClose" class="close" @click="$emit('close')"><Icon type="close" /></button>
4
4
 
5
5
  <slot />
6
6
  </DialogFrame>
@@ -9,6 +9,7 @@
9
9
  <script setup>
10
10
  const props = defineProps({
11
11
  open: Boolean,
12
+ class: String,
12
13
  xClose: {
13
14
  type: Boolean,
14
15
  default: true,
@@ -31,12 +31,12 @@ const trigger = ref()
31
31
  const popover = ref()
32
32
 
33
33
  const { width: windowWidth } = useWindowSize()
34
- const { width: dialogWidth } = useElementSize(popover, {}, { box: 'border-box' })
34
+ const { width: dialogWidth } = useElementSize(popover, undefined, { box: 'border-box' })
35
35
  const { x: targetX, y: targetY, width: targetWidth, height: targetHeight } = useElementBounding(trigger)
36
36
  const targetCenterX = computed(() => targetX.value + targetWidth.value / 2)
37
37
  const adjustmentX = computed(() => {
38
38
  const popoverLeft = targetCenterX.value - (dialogWidth.value / 2)
39
- const overflow = parseInt(windowWidth.value - (popoverLeft + dialogWidth.value) - 29)
39
+ const overflow = parseInt(`${windowWidth.value - (popoverLeft + dialogWidth.value) - 29}`)
40
40
  return overflow < 0 ? overflow : 0
41
41
  })
42
42
 
@@ -73,7 +73,7 @@ const popoverArrowPosition = computed(() => {
73
73
 
74
74
  &:popover-open {
75
75
  opacity: 1;
76
- transform: translateY(var(--spacer));
76
+ transform: translateY(var(--spacer-sm));
77
77
  }
78
78
 
79
79
  .arrow {
@@ -96,24 +96,4 @@ const popoverArrowPosition = computed(() => {
96
96
  transform: translateY(var(--spacer-lg));
97
97
  }
98
98
  }
99
-
100
- /* BACKDROP */
101
- /* [popover]::backdrop {
102
- background-color: var(--background-0);
103
- transition:
104
- display 0.7s allow-discrete,
105
- overlay 0.7s allow-discrete,
106
- background-color 0.7s;
107
- }
108
-
109
- [popover]:popover-open::backdrop {
110
- background-color: var(--background-semi);
111
- backdrop-filter: var(--blur);
112
- }
113
-
114
- @starting-style {
115
- [popover]:popover-open::backdrop {
116
- background-color: var(--background-0);
117
- }
118
- } */
119
99
  </style>
@@ -10,24 +10,12 @@
10
10
  </h1>
11
11
  <p v-if="artist?.description">{{ artist.description }}</p>
12
12
 
13
- <ul v-if="hasTags">
14
- <Button v-if="validateURI(artist.url)" :to="validateURI(artist.url)" class="small">
15
- <Icon type="globe" />
16
- <span>{{ getMainDomain(artist.url) }}</span>
17
- </Button>
18
- <Button v-if="artist.email" :to="`mailto:${artist.email}`" class="small">
19
- <Icon type="mail" />
20
- <span>{{ artist.email }}</span>
21
- </Button>
22
- <Button v-if="artist.twitter" :to="`https://x.com/${artist.twitter}`" class="small">
23
- <Icon type="x.com" />
24
- <span>{{ artist.twitter }}</span>
25
- </Button>
26
- <Button v-if="artist.github" :to="`https://github.com/${artist.github}`" class="small">
27
- <Icon type="github" />
28
- <span>{{ artist.github }}</span>
29
- </Button>
30
- </ul>
13
+ <Actions v-if="hasTags">
14
+ <ButtonProfileWebsite :profile="artist" />
15
+ <ButtonProfileEmail :profile="artist" />
16
+ <ButtonProfileTwitter :profile="artist" />
17
+ <ButtonProfileGithub :profile="artist" />
18
+ </Actions>
31
19
  </header>
32
20
  </template>
33
21
 
@@ -56,20 +44,15 @@ const hasTags = computed(() => artist.value.url ||
56
44
  header {
57
45
  display: flex;
58
46
  flex-direction: column;
59
- justify-content: center;
60
- align-items: center;
61
47
  gap: var(--spacer);
62
48
 
63
49
  img {
64
50
  width: var(--size-9);
65
51
  height: var(--size-9);
66
- border-radius: 50%;
67
- border: var(--border);
68
52
  }
69
53
 
70
54
  h1 {
71
55
  cursor: pointer;
72
- text-align: center;
73
56
 
74
57
  > * {
75
58
  display: block;
@@ -80,17 +63,5 @@ header {
80
63
  font-size: var(--font-xs);
81
64
  }
82
65
  }
83
-
84
- p {
85
- color: var(--muted);
86
- text-align: center;
87
- }
88
-
89
- ul {
90
- display: flex;
91
- flex-wrap: wrap;
92
- gap: var(--spacer-sm);
93
- justify-content: center;
94
- }
95
66
  }
96
67
  </style>
@@ -22,11 +22,11 @@
22
22
  >
23
23
  <section class="details">
24
24
  <header class="title">
25
- <h1>{{ token.name }} <span class="muted-light">#{{ token.tokenId }}</span></h1>
26
- <p v-if="token.description" class="muted-light">
25
+ <h1>{{ token.name }} <small>#{{ token.tokenId }}</small></h1>
26
+ <p v-if="token.description">
27
27
  <ExpandableText :text="token.description" :length="95" expand-text="Read More" />
28
28
  </p>
29
- <p class="muted-light">
29
+ <p v-if="collection" class="artist">
30
30
  By <NuxtLink :to="{ name: 'id', params: { id: collection.owner } }">{{ store.displayName(collection.owner) }}</NuxtLink>
31
31
  </p>
32
32
  </header>
@@ -47,8 +47,8 @@
47
47
 
48
48
  <div class="mint-status">
49
49
  <p v-if="mintOpen">{{ blocksRemaining }} blocks remaining</p>
50
- <p v-else-if="currentBlock" class="muted-light">Closed at block {{ token.untilBlock }}</p>
51
- <p class="muted-light" v-if="ownedBalance">You own {{ ownedBalance }} {{ pluralize('token', Number(ownedBalance)) }}</p>
50
+ <p v-else-if="currentBlock">Closed at block {{ token.untilBlock }}</p>
51
+ <p v-if="ownedBalance">You own {{ ownedBalance }} {{ pluralize('token', Number(ownedBalance)) }}</p>
52
52
  </div>
53
53
 
54
54
  <TokenMintTimeline :token="token" :collection="collection" class="network-mints" />
@@ -79,12 +79,17 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
79
79
  display: grid;
80
80
  grid-auto-rows: min-content;
81
81
  padding: 0 !important;
82
+ border-top: var(--border);
82
83
 
83
84
  @media (--md) {
84
85
  height: calc(100dvh - var(--navbar-height));
85
- grid-template-columns: 60% 1fr;
86
+ grid-template-columns: 50% 1fr;
86
87
  grid-auto-rows: auto;
87
88
  }
89
+
90
+ @media (--lg) {
91
+ grid-template-columns: 60% 1fr;
92
+ }
88
93
  }
89
94
 
90
95
  .artifact {
@@ -92,12 +97,11 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
92
97
  --padding-top: 0;
93
98
  --padding-bottom: 0;
94
99
  --width: 100cqw;
95
- /* --height: calc(100cqh - var(--padding-top) - var(--padding-bottom)); */
96
100
  --height: 100%;
97
101
  --dimension: min(100cqw, 100cqh);
98
102
 
99
103
  @media (--md) {
100
- --width: 60cqw;
104
+ --width: 50cqw;
101
105
  --height: calc(100cqh - var(--navbar-height));
102
106
  --padding-top: var(--spacer-lg);
103
107
  --padding-x: var(--spacer-lg);
@@ -105,12 +109,13 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
105
109
  --padding-bottom: var(--spacer-lg);
106
110
 
107
111
  --dimension: min(
108
- calc(60cqw - var(--padding-x)*2),
112
+ calc(var(--width) - var(--padding-x)*2),
109
113
  calc(100cqh - var(--padding-top) - var(--padding-bottom))
110
114
  );
111
115
  }
112
116
 
113
117
  @media (--lg) {
118
+ --width: 60cqw;
114
119
  --padding-top: var(--spacer-xl);
115
120
  --padding-x: var(--spacer-xl);
116
121
  --padding-bottom: calc(var(--spacer-xl) + var(--spacer));
@@ -159,11 +164,15 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
159
164
  z-index: 100;
160
165
  display: grid;
161
166
  gap: var(--spacer-sm);
162
- background: var(--background-semi);
167
+ background: var(--card-background);
163
168
  backdrop-filter: var(--blur);
164
169
 
165
170
  h1 {
166
171
  font-size: var(--font-lg);
172
+
173
+ small {
174
+ color: var(--muted);
175
+ }
167
176
  }
168
177
 
169
178
  @media (--md) {
@@ -1,30 +1,28 @@
1
1
  <template>
2
- <section>
2
+ <section class="token-mint-timeline">
3
3
  <h1>Mint Timeline</h1>
4
4
 
5
- <div v-if="currentBlock" class="table">
5
+ <div v-if="currentBlock" class="token-mint-timeline-items">
6
6
  <TokenMintTimelineItem
7
7
  v-for="mint of mints"
8
8
  :mint="mint"
9
9
  :key="mint.tx"
10
10
  :block="currentBlock"
11
11
  />
12
- <div v-if="! loading || mints.length">
13
- <span>
14
- <Account :address="collection.owner" />
15
- </span>
12
+ <TokenMintTimelineItem v-if="! loading || mints.length">
13
+ <Account :address="collection.owner" class="account" />
16
14
 
17
- <span class="right">1<span class="muted-light">×</span></span>
18
- <span class="right">Artist Mint</span>
15
+ <span class="amount">1<span>×</span></span>
16
+ <span class="price">Artist Mint</span>
19
17
 
20
- <span class="right"><BlocksTimeAgo v-if="currentBlock" :blocks="currentBlock - (token.untilBlock - 7200n)" /></span>
18
+ <span class="time-ago"><BlocksTimeAgo v-if="currentBlock" :blocks="currentBlock - (token.untilBlock - 7200n)" /></span>
21
19
 
22
- <span class="right muted-light">
20
+ <span class="links">
23
21
  <NuxtLink :to="`${config.public.blockExplorer}/nft/${token.collection}/${token.tokenId}`" target="_blank">
24
22
  <Icon type="link" />
25
23
  </NuxtLink>
26
24
  </span>
27
- </div>
25
+ </TokenMintTimelineItem>
28
26
  </div>
29
27
 
30
28
  <Loading v-if="loading || ! currentBlock" txt="Mint History..." />
@@ -62,9 +60,9 @@ watch(currentBlock, () => state.fetchTokenMints(token))
62
60
  </script>
63
61
 
64
62
  <style scoped>
65
- section {
66
- padding-top: var(--spacer-lg) !important;
67
- padding-bottom: var(--spacer-lg) !important;
63
+ .token-mint-timeline {
64
+ padding-top: var(--spacer-lg);
65
+ padding-bottom: var(--spacer-lg);
68
66
  container-type: inline-size;
69
67
  }
70
68
 
@@ -73,38 +71,11 @@ h1 {
73
71
  font-size: var(--font-base);
74
72
  border-bottom: var(--border);
75
73
  padding: 0 0 var(--spacer-sm);
76
- margin: 0 0 var(--spacer-lg);
74
+ margin: 0 0 var(--spacer);
77
75
  }
78
76
 
79
- .table {
77
+ .token-mint-timeline-items {
80
78
  display: grid;
81
79
  gap: var(--spacer);
82
-
83
- :deep(> div) {
84
- display: grid;
85
- gap: var(--spacer);
86
-
87
- .right {
88
- text-align: right;
89
- }
90
-
91
- span {
92
- white-space: nowrap;
93
-
94
- &:nth-child(3) {
95
- display: none;
96
-
97
- @container (min-width: 30rem) {
98
- display: inline;
99
- }
100
- }
101
- }
102
-
103
- grid-template-columns: 6rem 3rem 1fr 3rem;
104
-
105
- @container (min-width: 30rem) {
106
- grid-template-columns: 6rem 3rem 1fr 6rem 1rem;
107
- }
108
- }
109
80
  }
110
81
  </style>
@@ -1,20 +1,20 @@
1
1
  <template>
2
- <div>
3
- <span>
4
- <Account :address="mint.address" />
5
- </span>
2
+ <div class="token-mint-timeline-item">
3
+ <slot>
4
+ <Account :address="mint.address" class="account" />
6
5
 
7
- <span class="right">{{ mint.amount.toString() }}<span class="muted-light">×</span></span>
6
+ <span class="amount">{{ mint.amount.toString() }}<span>×</span></span>
8
7
 
9
- <span class="right">{{ formattedPrice.value }} {{ formattedPrice.format }}</span>
8
+ <span class="price">{{ formattedPrice.value }} {{ formattedPrice.format }}</span>
10
9
 
11
- <span class="right"><BlocksTimeAgo :blocks="block - mint.block" /></span>
10
+ <span class="time-ago"><BlocksTimeAgo :blocks="block - mint.block" /></span>
12
11
 
13
- <span class="right muted-light">
14
- <NuxtLink :to="`${config.public.blockExplorer}/tx/${mint.tx}`" target="_blank">
15
- <Icon type="link" />
16
- </NuxtLink>
17
- </span>
12
+ <span class="links">
13
+ <NuxtLink :to="`${config.public.blockExplorer}/tx/${mint.tx}`" target="_blank">
14
+ <Icon type="link" />
15
+ </NuxtLink>
16
+ </span>
17
+ </slot>
18
18
  </div>
19
19
  </template>
20
20
 
@@ -29,5 +29,42 @@ const props = defineProps({
29
29
  const formattedPrice = computed(() => customFormatEther(props.mint.price))
30
30
  </script>
31
31
 
32
- <style scoped>
32
+ <style>
33
+ .token-mint-timeline-item {
34
+ display: grid;
35
+ gap: 0 var(--spacer-sm);
36
+ grid-template-columns: 1fr 1fr;
37
+
38
+ .account {
39
+ grid-column: span 2;
40
+ }
41
+
42
+ .price,
43
+ .links {
44
+ text-align: right;
45
+ }
46
+
47
+ span {
48
+ white-space: nowrap;
49
+
50
+ &:not(.account) {
51
+ color: var(--muted);
52
+ font-size: var(--font-sm);
53
+ }
54
+ }
55
+
56
+ @container (min-width: 24rem) {
57
+ grid-template-columns: 6rem 3rem 1fr 1fr 2rem;
58
+ gap: var(--spacer);
59
+
60
+ .account {
61
+ grid-column: 1;
62
+ }
63
+
64
+ .time-ago,
65
+ .amount {
66
+ text-align: right;
67
+ }
68
+ }
69
+ }
33
70
  </style>
@@ -16,13 +16,13 @@
16
16
  <div class="content">
17
17
  <header>
18
18
  <h1>
19
- <span>{{ token.name }} <span class="muted">#{{ token.tokenId }}</span></span>
20
- <span v-if="token.description">{{ shortString(token.description, 60, 30) }}</span>
19
+ <span>{{ token.name }} <span class="token-id">#{{ token.tokenId }}</span></span>
20
+ <span v-if="token.description" class="description">{{ shortString(token.description, 60, 30) }}</span>
21
21
  </h1>
22
- <p v-if="mintOpen" class="muted">Closes in {{ blocksRemaining }} {{ pluralize('block', Number(blocksRemaining))}}</p>
23
- <p v-else class="muted">Closed at block {{ token.untilBlock }}</p>
22
+ <p v-if="mintOpen" class="closes-in">Closes in {{ blocksRemaining }} {{ pluralize('block', Number(blocksRemaining))}}</p>
23
+ <p v-else class="closed-at">Closed at block {{ token.untilBlock }}</p>
24
24
  </header>
25
- <Image :src="token.artifact" :alt="token.name" class="bordered" />
25
+ <Image :src="token.artifact" :alt="token.name" />
26
26
  <CardLink :to="{
27
27
  name: 'id-collection-tokenId',
28
28
  params: { id: collection.owner, collection: token.collection, tokenId: `${token.tokenId}` }
@@ -69,19 +69,11 @@ const ownedBalance = computed(() => store.tokenBalance(collection.value.address,
69
69
  }
70
70
 
71
71
  .token-overview-card {
72
- padding: var(--spacer-xl) var(--spacer) !important;
73
-
74
- /* Tokens should be at min the screen height. */
75
- &:not(:first-of-type) {
76
- min-height: min(60rem, calc(100dvh - 2*var(--navbar-height)));
77
-
78
- @media (--md) {
79
- min-height: min(60rem, calc(100dvh - var(--navbar-height)));
80
- }
81
- }
72
+ padding: var(--spacer-xl) var(--spacer);
73
+ min-height: min(60rem, 100dvh);
82
74
 
83
75
  > p {
84
- color: var(--muted-light);
76
+ color: var(--);
85
77
  font-size: var(--font-sm);
86
78
  text-align: left;
87
79
  }
@@ -108,7 +100,8 @@ const ownedBalance = computed(() => store.tokenBalance(collection.value.address,
108
100
 
109
101
  h1 {
110
102
  span:last-of-type:not(:first-child) {
111
- color: var(--muted-light);
103
+ color: var(--muted);
104
+ font-size: var(--font-sm);
112
105
  white-space: wrap;
113
106
  display: none;
114
107