1---
2type Variant = "primary" | "secondary" | "ghost" | "accent";
3type Icon = "github" | "arrow" | "book" | "discord";
4
5interface Props {
6 variant?: Variant;
7 icon?: Icon;
8 href?: string;
9 class?: string;
10}
11
12const { variant = "primary", icon, href = "#", class: className } = Astro.props;
13---
14
15<a
16 href={href}
17 class:list={["alc-btn", `alc-btn--${variant}`, className]}
18>
19 {icon === "github" && (
20 <svg aria-hidden width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
21 <path
22 d="M12 .5C5.73.5.5 5.73.5 12c0 5.08 3.29 9.39 7.86 10.91.58.1.79-.25.79-.56 0-.28-.01-1.02-.02-2-3.2.69-3.88-1.54-3.88-1.54-.52-1.33-1.28-1.69-1.28-1.69-1.05-.72.08-.71.08-.71 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.71 1.26 3.37.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.69 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11.04 11.04 0 0 1 5.79 0c2.21-1.49 3.18-1.18 3.18-1.18.63 1.59.23 2.76.11 3.05.74.81 1.19 1.84 1.19 3.1 0 4.42-2.69 5.39-5.25 5.68.41.36.78 1.07.78 2.16 0 1.56-.01 2.81-.01 3.19 0 .31.21.67.8.56C20.71 21.39 24 17.08 24 12 24 5.73 18.27.5 12 .5z"
23 ></path>
24 </svg>
25 )}
26 <slot />
27 {icon === "arrow" && <span aria-hidden>→</span>}
28 {icon === "book" && <span aria-hidden>❏</span>}
29 {icon === "discord" && (
30 <svg aria-hidden width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
31 <path
32 d="M20.317 4.369A19.79 19.79 0 0 0 16.558 3.2a.075.075 0 0 0-.079.037c-.34.6-.717 1.384-.98 2-1.797-.27-3.583-.27-5.342 0-.263-.63-.654-1.4-.997-2A.077.077 0 0 0 9.08 3.2a19.736 19.736 0 0 0-3.76 1.169.07.07 0 0 0-.032.027C1.533 9.046.6 13.58 1.057 18.058a.082.082 0 0 0 .031.056 19.9 19.9 0 0 0 5.993 3.029.077.077 0 0 0 .084-.027c.462-.63.873-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.108 13.108 0 0 1-1.872-.892.077.077 0 0 1-.008-.128c.126-.094.252-.192.372-.291a.074.074 0 0 1 .077-.01c3.927 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.099.246.197.373.291a.077.077 0 0 1-.006.128 12.3 12.3 0 0 1-1.873.892.077.077 0 0 0-.04.106c.36.699.772 1.364 1.225 1.994a.076.076 0 0 0 .084.028 19.84 19.84 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.548-13.66a.061.061 0 0 0-.031-.029ZM8.02 15.331c-1.183 0-2.157-1.085-2.157-2.42 0-1.333.956-2.418 2.157-2.418 1.21 0 2.176 1.094 2.157 2.418 0 1.335-.956 2.42-2.157 2.42Zm7.974 0c-1.183 0-2.157-1.085-2.157-2.42 0-1.333.955-2.418 2.157-2.418 1.21 0 2.176 1.094 2.157 2.418 0 1.335-.946 2.42-2.157 2.42Z"
33 ></path>
34 </svg>
35 )}
36</a>
37
38<style>
39 .alc-btn {
40 font-family: var(--alc-font-sans);
41 font-size: 14px;
42 font-weight: 500;
43 padding: 10px 18px;
44 border-radius: 8px;
45 border: 1px solid transparent;
46 display: inline-flex;
47 align-items: center;
48 gap: 8px;
49 white-space: nowrap;
50 cursor: pointer;
51 text-decoration: none;
52 transition:
53 background 120ms var(--alc-ease, cubic-bezier(0.2, 0, 0, 1)),
54 border-color 120ms var(--alc-ease, cubic-bezier(0.2, 0, 0, 1)),
55 color 120ms var(--alc-ease, cubic-bezier(0.2, 0, 0, 1));
56 }
57 /* Deep forest instead of var(--alc-accent): mid-green moss cannot reach
58 the AAA 7:1 contrast ratio with any text color; #3f5a2a gives 7.2:1
59 against --alc-fg-on-accent in both themes. */
60 .alc-btn--primary {
61 background: #3f5a2a;
62 color: var(--alc-fg-on-accent);
63 }
64 .alc-btn--primary:hover {
65 background: #324a1e;
66 }
67 /* Secondary: transparent surface with a hairline border. Slimmer
68 padding than the primary so it doesn't feel oversized when sitting
69 next to a borderless ghost button. */
70 .alc-btn--secondary {
71 background: transparent;
72 border-color: var(--alc-hairline-3);
73 color: var(--alc-fg-1);
74 padding: 7px 14px;
75 }
76 .alc-btn--secondary:hover {
77 border-color: var(--alc-accent);
78 color: var(--alc-accent-deep);
79 }
80 .alc-btn--ghost {
81 background: transparent;
82 color: var(--alc-fg-2);
83 }
84 .alc-btn--ghost:hover {
85 color: var(--alc-accent-deep);
86 }
87 .alc-btn--accent {
88 background: var(--alc-terracotta);
89 color: var(--alc-fg-on-accent);
90 }
91 /* MDX wraps the button's slot text in a <p>, which inherits the UA
92 stylesheet's 1em block margin (~14px) and bloats the button
93 vertically. Flatten any <p> inside the button. `display: inline`
94 keeps the icon + label on one row inside the inline-flex anchor. */
95 .alc-btn :global(p) {
96 margin: 0;
97 display: inline;
98 }
99</style>