summaryrefslogtreecommitdiff
path: root/smoke/astro.build-main/src/components/PixelLink.astro
blob: f5d200b4960190007bc7fd3a9069063883fb2c91 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
---
const { class: className = '', href } = Astro.props;
// Wrap in <span> because Houdini is disabled for a[href] for security

const { variant = 'primary' } = Astro.props;
const { before, after } = Astro.slots;
---

<!-- Blocking script -->
<script hoist>
  if ('paintWorklet' in CSS) {
    CSS.paintWorklet.addModule('/pixel.worklet.js');
  }
</script>

<span class={`link pixel variant-${variant} ${before ? 'has-before' : ''} ${after ? 'has-after' : ''} ${className}`.trim()}>
    <a {href}>
        <slot name="before" />
        <span><slot /></span>
        <slot name="after" />
    </a>
</span>

<style>
    .pixel {
        --border-radius: 8;
        --pixel-size: 4;
        --background: var(--gradient-pop-1);
        position: relative;
        border-radius: calc(var(--border-radius) * 1px);
    }
    .pixel::before {
        content: '';
        position: absolute;
        top: calc(var(--pixel-size) * 1px);
        right: 0;
        bottom: calc(var(--pixel-size) * 1px);
        left: 0;
        background: var(--background);
        z-index: -1;
    }
    .pixel::after {
        content: '';
        position: absolute;
        top: 0;
        right: calc(var(--pixel-size) * 1px);
        bottom: 0;
        left: calc(var(--pixel-size) * 1px);
        background: var(--background);
        z-index: -1;
    }
    .pixel.variant-outline {
        background: rgba(255, 255, 255, 0);
        border-radius: 0;
    }
    .pixel.variant-outline::before {
        background: rgba(255, 255, 255, 0);
        border: calc(var(--pixel-size) * 1px) solid var(--background);
        border-top: 0;
        border-bottom: 0;
    }
    .pixel.variant-outline::after {
        background: rgba(255, 255, 255, 0);
        border: calc(var(--pixel-size) * 1px) solid var(--background);
        border-right: 0;
        border-left: 0;
    }
    @supports (background: paint(pixel)) {
        :global(.js) .pixel {
            background: none !important;
        }
        :global(.js) .pixel::before {
            content: '';
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            display: block;
            z-index: -1;
            overflow: hidden;
            border-radius: 0;
            background: var(--background);
            -webkit-mask-image: paint(pixel);
            mask-image: paint(pixel);
        }
       :global(.js) .pixel::after {
            content: none;
        }
    }
    .link {
        --border-radius: 8;
        --duration: 200ms;
        --delay: 30ms;
        --background: linear-gradient(180deg, var(--link-color-stop-a), var(--link-color-stop-b));
        display: flex;
        color: white;
        font-family: var(--font-display);
        font-size: 1.5rem;
        width: max-content;
        transition-property: transform, --link-color-stop-a, --link-color-stop-b;
        transition-duration: var(--duration);
        transition-delay: var(--delay);
        transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    }
    .link:hover,
    .link:focus-within {
        transform: translateY(calc(var(--pixel-size) * -0.5px));
    }
    .link:active {
        transform: translateY(0);
    }
    .has-before a :first-child {
        margin-left: -1rem;
        margin-right: 0.25rem;
    }
    .has-before a :last-child {
        margin-left: 0.25rem;
        margin-right: -1rem;
    }
    a {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0.67rem 2.5rem;
        width: 100%;
        height: 100%;
        text-decoration: none;
        color: inherit !important;
    }
    a > :global(* + *) {
        margin-left: 0.25rem;
    }

    .variant-primary {
        --variant: primary;
        --background: linear-gradient(180deg, var(--link-color-stop-a), var(--link-color-stop-b));
    }
    .variant-primary:hover,
    .variant-primary:focus-within {
        --link-color-stop-a: #6D39FF;
        --link-color-stop-b: #AF43FF;
    }
    .variant-primary:active {
        --link-color-stop-a: #5F31E1;
        --link-color-stop-b: #A740F3;
    }

    .variant-outline {
        --variant: outline;
        --background: none;
        color: var(--background);
    }
    .variant-outline > a::before {
        position: absolute;
        top: 0;
        right: calc(var(--pixel-size) * 1px);
        bottom: calc(var(--pixel-size) * 1px);
        left: calc(var(--pixel-size) * 1px);
        content: "";
        display: block;
        transform-origin: bottom center;
        background: linear-gradient(to top, var(--background), rgba(255, 255, 255, 0));
        opacity: 0.3;
        transform: scaleY(0);
        transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
    }
    .variant-outline:hover > a::before,
    .variant-outline:focus-within > a::before {
        transform: scaleY(1);
    }
    .variant-outline:active > a::before {
        transform: scaleY(1);
    }
</style>