@hagicode/hagilight-core 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.
- package/Analytics51LA.astro +17 -0
- package/Copyright.astro +9 -0
- package/Footer.astro +167 -0
- package/GoogleAnalytics.astro +21 -0
- package/PromotoBanner.astro +346 -0
- package/dist/favicon.d.ts +21 -0
- package/dist/favicon.js +27 -0
- package/dist/head.d.ts +7 -0
- package/dist/head.js +1 -0
- package/dist/links.d.ts +68 -0
- package/dist/links.js +406 -0
- package/dist/promotions.d.ts +44 -0
- package/dist/promotions.js +216 -0
- package/dist/promoto-banner.d.ts +8 -0
- package/dist/promoto-banner.js +342 -0
- package/dist/related-sites.json +306 -0
- package/dist/rss-footer-context.d.ts +6 -0
- package/dist/rss-footer-context.js +54 -0
- package/dist/rss-ownership.d.ts +25 -0
- package/dist/rss-ownership.js +65 -0
- package/dist/rss.d.ts +34 -0
- package/dist/rss.js +145 -0
- package/dist/seo-schema.d.ts +12 -0
- package/dist/seo-schema.js +20 -0
- package/dist/seo.d.ts +78 -0
- package/dist/seo.js +257 -0
- package/favicon.ico +0 -0
- package/logo.png +0 -0
- package/package.json +79 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
siteId: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { siteId } = Astro.props;
|
|
7
|
+
if (!siteId?.trim()) throw new Error('Analytics51LA requires a siteId prop.');
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
{import.meta.env.PROD && (
|
|
11
|
+
<>
|
|
12
|
+
<script is:inline charset="UTF-8" id="LA_COLLECT" src="https://sdk.51.la/js-sdk-pro.min.js"></script>
|
|
13
|
+
<script is:inline define:vars={{ siteId }}>
|
|
14
|
+
LA.init({ id: siteId, ck: siteId, autoTrack: true, hashMode: true, screenRecord: true });
|
|
15
|
+
</script>
|
|
16
|
+
</>
|
|
17
|
+
)}
|
package/Copyright.astro
ADDED
package/Footer.astro
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Copyright from './Copyright.astro';
|
|
3
|
+
import { resolveSiteLinks, type SiteLinksOptions } from './dist/links.js';
|
|
4
|
+
import { resolveRssFooterLinks } from './dist/rss-footer-context.js';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: string;
|
|
8
|
+
links?: SiteLinksOptions;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { locale: propLocale, links } = Astro.props;
|
|
12
|
+
const locale = propLocale ?? Astro.currentLocale ?? 'en-US';
|
|
13
|
+
const footerLinks = resolveRssFooterLinks(Astro.locals, locale, links);
|
|
14
|
+
const sitemapOverride = footerLinks.overrides?.sitemap;
|
|
15
|
+
const resolvedLinks = resolveSiteLinks(locale, {
|
|
16
|
+
...footerLinks,
|
|
17
|
+
overrides: {
|
|
18
|
+
...footerLinks.overrides,
|
|
19
|
+
sitemap: {
|
|
20
|
+
...sitemapOverride,
|
|
21
|
+
href: sitemapOverride?.href ?? `${import.meta.env.BASE_URL}sitemap-index.xml`,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<footer class="hagilight-footer">
|
|
28
|
+
<div class="hagilight-footer__sections">
|
|
29
|
+
{resolvedLinks.relatedSites.length > 0 && (
|
|
30
|
+
<section>
|
|
31
|
+
<h2>{resolvedLinks.labels.relatedSites}</h2>
|
|
32
|
+
<nav aria-label={resolvedLinks.labels.navigation.relatedSites}>
|
|
33
|
+
<ul>
|
|
34
|
+
{resolvedLinks.relatedSites.map((site) => (
|
|
35
|
+
<li>
|
|
36
|
+
<a href={site.href} target={site.target} rel={site.rel}>{site.name}</a>
|
|
37
|
+
</li>
|
|
38
|
+
))}
|
|
39
|
+
</ul>
|
|
40
|
+
</nav>
|
|
41
|
+
</section>
|
|
42
|
+
)}
|
|
43
|
+
<section>
|
|
44
|
+
<h2>{resolvedLinks.labels.quickLinks}</h2>
|
|
45
|
+
<nav aria-label={resolvedLinks.labels.navigation.quickLinks}>
|
|
46
|
+
<ul>
|
|
47
|
+
{resolvedLinks.quick.map((link) => (
|
|
48
|
+
<li>
|
|
49
|
+
<a
|
|
50
|
+
href={link.href}
|
|
51
|
+
target={link.target}
|
|
52
|
+
rel={link.rel}
|
|
53
|
+
aria-label={link.ariaLabel}
|
|
54
|
+
>{link.label}</a>
|
|
55
|
+
</li>
|
|
56
|
+
))}
|
|
57
|
+
</ul>
|
|
58
|
+
</nav>
|
|
59
|
+
</section>
|
|
60
|
+
<section>
|
|
61
|
+
<h2>{resolvedLinks.labels.community}</h2>
|
|
62
|
+
<nav aria-label={resolvedLinks.labels.navigation.community}>
|
|
63
|
+
<ul>
|
|
64
|
+
{resolvedLinks.community.map((link) => (
|
|
65
|
+
<li>
|
|
66
|
+
<a
|
|
67
|
+
href={link.href}
|
|
68
|
+
target={link.target}
|
|
69
|
+
rel={link.rel}
|
|
70
|
+
aria-label={link.ariaLabel}
|
|
71
|
+
>{link.label}</a>
|
|
72
|
+
</li>
|
|
73
|
+
))}
|
|
74
|
+
</ul>
|
|
75
|
+
</nav>
|
|
76
|
+
</section>
|
|
77
|
+
</div>
|
|
78
|
+
<nav class="hagilight-footer__filings" aria-label={resolvedLinks.labels.navigation.filings}>
|
|
79
|
+
{resolvedLinks.filings.map((link) => (
|
|
80
|
+
<a
|
|
81
|
+
href={link.href}
|
|
82
|
+
target={link.target}
|
|
83
|
+
rel={link.rel}
|
|
84
|
+
aria-label={link.ariaLabel}
|
|
85
|
+
>{link.label}</a>
|
|
86
|
+
))}
|
|
87
|
+
</nav>
|
|
88
|
+
<p class="hagilight-footer__copyright"><Copyright name="HagiCode" /></p>
|
|
89
|
+
</footer>
|
|
90
|
+
|
|
91
|
+
<style>
|
|
92
|
+
.hagilight-footer {
|
|
93
|
+
border-top: 1px solid var(--hagilight-footer-border, currentColor);
|
|
94
|
+
color: var(--hagilight-footer-color, inherit);
|
|
95
|
+
padding: 1.5rem 1rem 1rem;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.hagilight-footer__sections {
|
|
99
|
+
display: grid;
|
|
100
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
|
101
|
+
gap: 1.5rem;
|
|
102
|
+
margin: 0 auto 1.5rem;
|
|
103
|
+
max-width: 72rem;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.hagilight-footer section {
|
|
107
|
+
min-width: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.hagilight-footer h2 {
|
|
111
|
+
margin: 0 0 0.75rem;
|
|
112
|
+
font-size: 0.95rem;
|
|
113
|
+
font-weight: 650;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.hagilight-footer ul {
|
|
117
|
+
display: grid;
|
|
118
|
+
gap: 0.5rem;
|
|
119
|
+
margin: 0;
|
|
120
|
+
padding: 0;
|
|
121
|
+
list-style: none;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.hagilight-footer a {
|
|
125
|
+
color: inherit;
|
|
126
|
+
text-decoration: none;
|
|
127
|
+
text-underline-offset: 0.2em;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.hagilight-footer a:hover {
|
|
131
|
+
text-decoration: underline;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.hagilight-footer a:focus-visible {
|
|
135
|
+
border-radius: 0.125rem;
|
|
136
|
+
outline: 2px solid currentColor;
|
|
137
|
+
outline-offset: 0.2rem;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.hagilight-footer__filings {
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-wrap: wrap;
|
|
143
|
+
justify-content: center;
|
|
144
|
+
gap: 0.75rem 1.5rem;
|
|
145
|
+
border-top: 1px solid var(--hagilight-footer-border, currentColor);
|
|
146
|
+
padding-top: 1rem;
|
|
147
|
+
text-align: center;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.hagilight-footer__copyright {
|
|
151
|
+
margin: 1rem 0 0;
|
|
152
|
+
font-size: 0.8rem;
|
|
153
|
+
text-align: center;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@media (max-width: 40rem) {
|
|
157
|
+
.hagilight-footer__sections {
|
|
158
|
+
grid-template-columns: 1fr;
|
|
159
|
+
gap: 1.25rem;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.hagilight-footer__filings {
|
|
163
|
+
justify-content: flex-start;
|
|
164
|
+
gap: 0.75rem 1rem;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
measurementId: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { measurementId } = Astro.props;
|
|
7
|
+
if (!measurementId?.trim()) throw new Error('GoogleAnalytics requires a measurementId prop.');
|
|
8
|
+
const scriptUrl = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}`;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
{import.meta.env.PROD && (
|
|
12
|
+
<>
|
|
13
|
+
<script async src={scriptUrl}></script>
|
|
14
|
+
<script is:inline define:vars={{ measurementId }}>
|
|
15
|
+
window.dataLayer = window.dataLayer || [];
|
|
16
|
+
function gtag(){dataLayer.push(arguments);}
|
|
17
|
+
gtag('js', new Date());
|
|
18
|
+
gtag('config', measurementId);
|
|
19
|
+
</script>
|
|
20
|
+
</>
|
|
21
|
+
)}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { PromotionCard } from './dist/promotions.js';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
fallback?: PromotionCard;
|
|
6
|
+
locale?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { fallback, locale = Astro.currentLocale ?? 'en' } = Astro.props;
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<hagilight-promoto-banner
|
|
13
|
+
class="hagilight-promoto"
|
|
14
|
+
data-locale={locale}
|
|
15
|
+
data-fallback={fallback ? JSON.stringify(fallback) : undefined}
|
|
16
|
+
hidden
|
|
17
|
+
>
|
|
18
|
+
<section class="hagilight-promoto__shell" data-promoto-shell hidden aria-label="Featured promotion">
|
|
19
|
+
<button
|
|
20
|
+
type="button"
|
|
21
|
+
class="hagilight-promoto__dismiss"
|
|
22
|
+
data-promoto-dismiss
|
|
23
|
+
aria-label="Dismiss promotion"
|
|
24
|
+
>×</button>
|
|
25
|
+
<div class="hagilight-promoto__viewport">
|
|
26
|
+
<div class="hagilight-promoto__track" data-promoto-track></div>
|
|
27
|
+
</div>
|
|
28
|
+
<nav class="hagilight-promoto__controls" data-promoto-controls aria-label="Promotion controls" hidden>
|
|
29
|
+
<button type="button" class="hagilight-promoto__control" data-promoto-previous aria-label="Previous promotion">‹</button>
|
|
30
|
+
<span class="hagilight-promoto__count" data-promoto-count aria-label="Promotion progress"></span>
|
|
31
|
+
<button type="button" class="hagilight-promoto__control" data-promoto-next aria-label="Next promotion">›</button>
|
|
32
|
+
<button type="button" class="hagilight-promoto__control" data-promoto-pause aria-pressed="false">Pause</button>
|
|
33
|
+
</nav>
|
|
34
|
+
<span class="hagilight-promoto__status" data-promoto-status aria-live="polite"></span>
|
|
35
|
+
</section>
|
|
36
|
+
</hagilight-promoto-banner>
|
|
37
|
+
|
|
38
|
+
<script>
|
|
39
|
+
import { definePromotoBannerElement } from './dist/promoto-banner.js';
|
|
40
|
+
|
|
41
|
+
definePromotoBannerElement();
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<style is:global>
|
|
45
|
+
.hagilight-promoto {
|
|
46
|
+
display: block;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.hagilight-promoto[hidden],
|
|
50
|
+
.hagilight-promoto__shell[hidden],
|
|
51
|
+
.hagilight-promoto__controls[hidden] {
|
|
52
|
+
display: none !important;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.hagilight-promoto__shell {
|
|
56
|
+
position: fixed;
|
|
57
|
+
z-index: 40;
|
|
58
|
+
inset-inline: 0;
|
|
59
|
+
bottom: max(1rem, env(safe-area-inset-bottom));
|
|
60
|
+
width: min(72rem, calc(100vw - 1rem));
|
|
61
|
+
margin-inline: auto;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
border: 1px solid color-mix(in srgb, var(--sl-color-accent, #2563eb) 24%, var(--sl-color-gray-5, #cbd5e1));
|
|
64
|
+
border-radius: 1.25rem;
|
|
65
|
+
background: color-mix(in srgb, var(--sl-color-bg, #fff) 96%, var(--sl-color-accent-low, #dbeafe) 4%);
|
|
66
|
+
box-shadow: 0 18px 48px color-mix(in srgb, var(--sl-color-black, #000) 16%, transparent);
|
|
67
|
+
color: var(--sl-color-text, #1f2937);
|
|
68
|
+
opacity: 1;
|
|
69
|
+
visibility: visible;
|
|
70
|
+
transition: opacity 0.24s ease, visibility 0s linear;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.hagilight-promoto[data-state='footer-hidden'] .hagilight-promoto__shell {
|
|
74
|
+
opacity: 0;
|
|
75
|
+
visibility: hidden;
|
|
76
|
+
pointer-events: none;
|
|
77
|
+
transition: opacity 0.24s ease, visibility 0s linear 0.24s;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.hagilight-promoto__viewport {
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.hagilight-promoto__track {
|
|
85
|
+
display: flex;
|
|
86
|
+
align-items: stretch;
|
|
87
|
+
width: 100%;
|
|
88
|
+
transition: transform 0.34s ease;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.hagilight-promoto__slide {
|
|
92
|
+
display: grid;
|
|
93
|
+
grid-template-columns: minmax(0, 1fr) auto auto;
|
|
94
|
+
align-items: center;
|
|
95
|
+
gap: 1.25rem;
|
|
96
|
+
width: 100%;
|
|
97
|
+
min-width: 100%;
|
|
98
|
+
padding: 1.25rem 4rem 1.25rem 1.25rem;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.hagilight-promoto__slide[aria-hidden='true'] {
|
|
102
|
+
pointer-events: none;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.hagilight-promoto__copy {
|
|
106
|
+
display: grid;
|
|
107
|
+
grid-template-columns: 1fr;
|
|
108
|
+
align-items: start;
|
|
109
|
+
gap: 0.4rem;
|
|
110
|
+
min-width: 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.hagilight-promoto__title,
|
|
114
|
+
.hagilight-promoto__description {
|
|
115
|
+
display: -webkit-box;
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
margin: 0;
|
|
118
|
+
color: var(--sl-color-text-high, var(--sl-color-gray-1, #111827));
|
|
119
|
+
font-size: var(--sl-text-sm);
|
|
120
|
+
font-weight: 600;
|
|
121
|
+
line-height: 1.35;
|
|
122
|
+
-webkit-box-orient: vertical;
|
|
123
|
+
-webkit-line-clamp: 2;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.hagilight-promoto__description {
|
|
127
|
+
color: var(--sl-color-text, #1f2937);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.hagilight-promoto__media {
|
|
131
|
+
display: inline-flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
justify-content: center;
|
|
134
|
+
width: clamp(4.5rem, 8vw, 6.25rem);
|
|
135
|
+
min-width: clamp(4.5rem, 8vw, 6.25rem);
|
|
136
|
+
aspect-ratio: 1;
|
|
137
|
+
overflow: hidden;
|
|
138
|
+
border: 1px solid color-mix(in srgb, var(--sl-color-accent-high, #1d4ed8) 18%, var(--sl-color-gray-5, #cbd5e1));
|
|
139
|
+
border-radius: 0.8rem;
|
|
140
|
+
background: color-mix(in srgb, var(--sl-color-bg-sidebar, #f8fafc) 82%, transparent);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.hagilight-promoto__image {
|
|
144
|
+
display: block;
|
|
145
|
+
width: 100%;
|
|
146
|
+
height: 100%;
|
|
147
|
+
object-fit: cover;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.hagilight-promoto__cta {
|
|
151
|
+
display: inline-flex;
|
|
152
|
+
align-items: center;
|
|
153
|
+
justify-content: center;
|
|
154
|
+
min-width: 7.5rem;
|
|
155
|
+
min-height: 2.6rem;
|
|
156
|
+
border: 1px solid color-mix(in srgb, var(--sl-color-accent-high, #1d4ed8) 30%, transparent);
|
|
157
|
+
border-radius: 999px;
|
|
158
|
+
background: var(--sl-color-accent, #2563eb);
|
|
159
|
+
color: #fff;
|
|
160
|
+
font-size: var(--sl-text-xs);
|
|
161
|
+
font-weight: 700;
|
|
162
|
+
padding-inline: 1rem;
|
|
163
|
+
text-align: center;
|
|
164
|
+
text-decoration: none;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.hagilight-promoto__cta:hover,
|
|
168
|
+
.hagilight-promoto__cta:focus-visible {
|
|
169
|
+
background: var(--sl-color-accent-high, #1d4ed8);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.hagilight-promoto__dismiss,
|
|
173
|
+
.hagilight-promoto__control {
|
|
174
|
+
display: inline-flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
justify-content: center;
|
|
177
|
+
min-width: 2.5rem;
|
|
178
|
+
min-height: 2.5rem;
|
|
179
|
+
border: 1px solid color-mix(in srgb, var(--sl-color-accent-high, #1d4ed8) 20%, var(--sl-color-gray-5, #cbd5e1));
|
|
180
|
+
border-radius: 999px;
|
|
181
|
+
background: var(--sl-color-bg-nav, #f8fafc);
|
|
182
|
+
color: var(--sl-color-text-high, #111827);
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.hagilight-promoto__dismiss {
|
|
187
|
+
position: absolute;
|
|
188
|
+
z-index: 1;
|
|
189
|
+
inset-block-start: 0.6rem;
|
|
190
|
+
inset-inline-end: 0.6rem;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.hagilight-promoto__controls {
|
|
194
|
+
display: flex;
|
|
195
|
+
align-items: center;
|
|
196
|
+
justify-content: flex-end;
|
|
197
|
+
gap: 0.5rem;
|
|
198
|
+
padding: 0 1.25rem 1rem;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.hagilight-promoto__count {
|
|
202
|
+
min-width: 3.5rem;
|
|
203
|
+
text-align: center;
|
|
204
|
+
font-size: var(--sl-text-xs);
|
|
205
|
+
font-variant-numeric: tabular-nums;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.hagilight-promoto__control:disabled {
|
|
209
|
+
cursor: default;
|
|
210
|
+
opacity: 0.6;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.hagilight-promoto__status {
|
|
214
|
+
position: absolute;
|
|
215
|
+
width: 1px;
|
|
216
|
+
height: 1px;
|
|
217
|
+
overflow: hidden;
|
|
218
|
+
clip: rect(0, 0, 0, 0);
|
|
219
|
+
white-space: nowrap;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.hagilight-promoto__dismiss:focus-visible,
|
|
223
|
+
.hagilight-promoto__control:focus-visible,
|
|
224
|
+
.hagilight-promoto__cta:focus-visible {
|
|
225
|
+
outline: 3px solid var(--sl-color-accent-high, #1d4ed8);
|
|
226
|
+
outline-offset: 3px;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@media (max-width: 960px) {
|
|
230
|
+
.hagilight-promoto__slide {
|
|
231
|
+
grid-template-columns: 1fr;
|
|
232
|
+
gap: 0.75rem;
|
|
233
|
+
padding-inline-end: 3.7rem;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.hagilight-promoto__slide[data-has-image='true'] {
|
|
237
|
+
grid-template-columns: 1fr;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.hagilight-promoto__copy {
|
|
241
|
+
grid-template-columns: 1fr;
|
|
242
|
+
gap: 0.45rem;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.hagilight-promoto__media {
|
|
246
|
+
width: min(100%, 8rem);
|
|
247
|
+
min-width: 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.hagilight-promoto__cta {
|
|
251
|
+
justify-self: start;
|
|
252
|
+
white-space: normal;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.hagilight-promoto__controls {
|
|
256
|
+
justify-content: flex-start;
|
|
257
|
+
padding-top: 0;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
@media (max-width: 720px) {
|
|
262
|
+
.hagilight-promoto__shell {
|
|
263
|
+
bottom: calc(env(safe-area-inset-bottom) + 0.5rem);
|
|
264
|
+
width: min(calc(100vw - 1rem), 24rem);
|
|
265
|
+
border-radius: 1rem;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.hagilight-promoto__slide {
|
|
269
|
+
grid-template-columns: 1fr;
|
|
270
|
+
gap: 0.7rem;
|
|
271
|
+
padding: 0.85rem 4.8rem 0.85rem 0.85rem;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.hagilight-promoto__slide[data-has-image='true'] {
|
|
275
|
+
grid-template-columns: minmax(0, 1fr) 4.5rem;
|
|
276
|
+
align-items: start;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.hagilight-promoto__copy {
|
|
280
|
+
grid-column: 1;
|
|
281
|
+
grid-row: 1;
|
|
282
|
+
gap: 0.45rem;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.hagilight-promoto__title {
|
|
286
|
+
font-size: 0.92rem;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.hagilight-promoto__description {
|
|
290
|
+
font-size: 0.84rem;
|
|
291
|
+
font-weight: 500;
|
|
292
|
+
line-height: 1.3;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.hagilight-promoto__media {
|
|
296
|
+
width: 4.5rem;
|
|
297
|
+
min-width: 4.5rem;
|
|
298
|
+
align-self: start;
|
|
299
|
+
grid-column: 2;
|
|
300
|
+
grid-row: 1;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.hagilight-promoto__cta {
|
|
304
|
+
grid-column: 1 / -1;
|
|
305
|
+
justify-self: stretch;
|
|
306
|
+
min-width: 0;
|
|
307
|
+
min-height: 2.35rem;
|
|
308
|
+
width: 100%;
|
|
309
|
+
font-size: 0.82rem;
|
|
310
|
+
white-space: normal;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.hagilight-promoto__control {
|
|
314
|
+
min-width: 2.2rem;
|
|
315
|
+
min-height: 2.2rem;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.hagilight-promoto__count {
|
|
319
|
+
min-width: 2.75rem;
|
|
320
|
+
font-size: 0.75rem;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.hagilight-promoto__dismiss {
|
|
324
|
+
inset-block-start: 0.55rem;
|
|
325
|
+
inset-inline-end: 0.55rem;
|
|
326
|
+
width: auto;
|
|
327
|
+
min-width: 2rem;
|
|
328
|
+
height: 2rem;
|
|
329
|
+
gap: 0.25rem;
|
|
330
|
+
padding-inline: 0.55rem;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.hagilight-promoto__controls {
|
|
334
|
+
flex-wrap: wrap;
|
|
335
|
+
gap: 0.35rem;
|
|
336
|
+
padding: 0 0.85rem 0.9rem;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
@media (prefers-reduced-motion: reduce) {
|
|
341
|
+
.hagilight-promoto__shell,
|
|
342
|
+
.hagilight-promoto__track {
|
|
343
|
+
transition: none;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HeadEntry } from './head.js';
|
|
2
|
+
export type { HeadEntry } from './head.js';
|
|
3
|
+
export interface FaviconLinkEntry extends HeadEntry {
|
|
4
|
+
tag: 'link';
|
|
5
|
+
attrs: {
|
|
6
|
+
rel: 'icon';
|
|
7
|
+
href: string;
|
|
8
|
+
type?: 'image/x-icon';
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface FaviconOptions {
|
|
12
|
+
/** Consumer-provided favicon URL used instead of the bundled HagiCode icon. */
|
|
13
|
+
href?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Bundled HagiCode favicon as an inline data URI, read at most once per process. */
|
|
16
|
+
export declare function getHagilightFaviconDataUri(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the favicon `<link>` head entry to inject, or `undefined` when the
|
|
19
|
+
* existing head already declares an icon.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveFaviconHeadEntry(head?: readonly HeadEntry[] | undefined, options?: FaviconOptions): FaviconLinkEntry | undefined;
|
package/dist/favicon.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
const faviconPath = fileURLToPath(new URL('../favicon.ico', import.meta.url));
|
|
4
|
+
let cachedDataUri;
|
|
5
|
+
/** Bundled HagiCode favicon as an inline data URI, read at most once per process. */
|
|
6
|
+
export function getHagilightFaviconDataUri() {
|
|
7
|
+
cachedDataUri ??= `data:image/x-icon;base64,${readFileSync(faviconPath).toString('base64')}`;
|
|
8
|
+
return cachedDataUri;
|
|
9
|
+
}
|
|
10
|
+
function isIconLink(entry) {
|
|
11
|
+
const rel = entry?.attrs?.rel;
|
|
12
|
+
return entry?.tag === 'link' && typeof rel === 'string' && /\bicon\b/u.test(rel);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the favicon `<link>` head entry to inject, or `undefined` when the
|
|
16
|
+
* existing head already declares an icon.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveFaviconHeadEntry(head = [], options = {}) {
|
|
19
|
+
if ((head ?? []).some(isIconLink))
|
|
20
|
+
return undefined;
|
|
21
|
+
const overrideHref = typeof options.href === 'string' && options.href.trim()
|
|
22
|
+
? options.href.trim()
|
|
23
|
+
: undefined;
|
|
24
|
+
if (overrideHref !== undefined)
|
|
25
|
+
return { tag: 'link', attrs: { rel: 'icon', href: overrideHref } };
|
|
26
|
+
return { tag: 'link', attrs: { rel: 'icon', href: getHagilightFaviconDataUri(), type: 'image/x-icon' } };
|
|
27
|
+
}
|
package/dist/head.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type HeadAttributeValue = string | boolean | number | undefined;
|
|
2
|
+
/** A `<head>` element description compatible with Astro and Starlight head configuration. */
|
|
3
|
+
export interface HeadEntry {
|
|
4
|
+
tag: string;
|
|
5
|
+
attrs?: Record<string, HeadAttributeValue>;
|
|
6
|
+
content?: string;
|
|
7
|
+
}
|
package/dist/head.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/links.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type SiteLinkKey = 'home' | 'blog' | 'support' | 'downloadClient' | 'about' | 'dockerCompose' | 'productDocs' | 'blogPosts' | 'sitemap' | 'rss' | 'rssLocale' | 'costCalculator' | 'github' | 'discord' | 'issueFeedback' | 'contactEmail' | 'qqGroup' | 'microsoftStore' | 'icpFiling' | 'publicSecurityFiling';
|
|
2
|
+
export type LinkGroup = 'header' | 'quick' | 'community' | 'filings';
|
|
3
|
+
export type FooterLinkSection = 'relatedSites' | 'quick' | 'community';
|
|
4
|
+
type LocalizedText = string | Readonly<Record<string, string>>;
|
|
5
|
+
export interface SiteLink {
|
|
6
|
+
id: SiteLinkKey | string;
|
|
7
|
+
label: string;
|
|
8
|
+
href: string;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
target?: '_blank';
|
|
11
|
+
rel?: 'noopener noreferrer';
|
|
12
|
+
}
|
|
13
|
+
export interface SiteLinkOverride {
|
|
14
|
+
href?: LocalizedText;
|
|
15
|
+
label?: LocalizedText;
|
|
16
|
+
external?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ExtraSiteLink extends SiteLinkOverride {
|
|
19
|
+
id?: string;
|
|
20
|
+
href: LocalizedText;
|
|
21
|
+
label: LocalizedText;
|
|
22
|
+
}
|
|
23
|
+
export interface RelatedSite {
|
|
24
|
+
id: string;
|
|
25
|
+
name: LocalizedText;
|
|
26
|
+
url: string;
|
|
27
|
+
description?: LocalizedText;
|
|
28
|
+
supportsLocalePath?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SiteLinksOptions {
|
|
31
|
+
overrides?: Partial<Record<SiteLinkKey, SiteLinkOverride>>;
|
|
32
|
+
extraLinks?: Partial<Record<LinkGroup, readonly ExtraSiteLink[]>> & {
|
|
33
|
+
relatedSites?: readonly RelatedSite[];
|
|
34
|
+
};
|
|
35
|
+
removeLinks?: Partial<Record<FooterLinkSection, readonly string[]>>;
|
|
36
|
+
relatedSites?: readonly RelatedSite[];
|
|
37
|
+
rssFeedUrl?: string;
|
|
38
|
+
rssLocaleFeedUrl?: string;
|
|
39
|
+
siteId?: string;
|
|
40
|
+
siteUrl?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare function resolveSiteLinks(localeInput?: string | null, options?: SiteLinksOptions): {
|
|
43
|
+
locale: string;
|
|
44
|
+
labels: {
|
|
45
|
+
relatedSites: string;
|
|
46
|
+
quickLinks: string;
|
|
47
|
+
community: string;
|
|
48
|
+
navigation: {
|
|
49
|
+
relatedSites: string;
|
|
50
|
+
quickLinks: string;
|
|
51
|
+
community: string;
|
|
52
|
+
filings: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
header: SiteLink[];
|
|
56
|
+
quick: SiteLink[];
|
|
57
|
+
community: SiteLink[];
|
|
58
|
+
filings: SiteLink[];
|
|
59
|
+
relatedSites: {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
description: string | undefined;
|
|
63
|
+
href: string;
|
|
64
|
+
target: "_blank";
|
|
65
|
+
rel: "noopener noreferrer";
|
|
66
|
+
}[];
|
|
67
|
+
};
|
|
68
|
+
export {};
|