@vit-foundation/ui 0.29.0 → 0.31.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/README.md CHANGED
@@ -9,7 +9,10 @@ content editable in place.
9
9
  npm install @vit-foundation/ui
10
10
  ```
11
11
 
12
- Requires `svelte` ^5.0.0 as a peer. Import the two stylesheets once:
12
+ Requires `svelte` ^5.0.0 as a peer. `ScrollySteps`, alone in the package,
13
+ also needs the optional peer `@sveltejs/svelte-scroller` — see
14
+ [scrolly](./docs/components/scrolly.md#installing-the-peer). Import the two
15
+ stylesheets once:
13
16
 
14
17
  ```svelte
15
18
  <script>
@@ -29,6 +32,8 @@ Everything exports flat from the root, and again grouped by role:
29
32
  | [`/chrome`](./docs/components/chrome.md) | PageShell, Nav, Footer |
30
33
  | [`/content`](./docs/components/content.md) | WeeklieCard, ProjectCard, Timeline, TimelineMilestone, TeamMemberCard, CollaboratorList, JobList, SortSelect, the nine page modules (HomePage … WeeklyPage) — plus the data shapes, the page-copy vocabulary, helpers and the two list rules (createWeeklyList, createUrlFilters) |
31
34
  | [`/community`](./docs/components/community.md) | AuthPageShell, LoginForm, SignupForm, GoogleAuthForm, AccountPanel, NewsletterSignup, CommentSection, ReactionBar, ContactForm |
35
+ | [`/admin`](./docs/components/admin.md) | DecorMosaic, PageHeading, Sidebar — shell-level composition for the foundation's internal tools |
36
+ | [`/scrolly`](./docs/components/scrolly.md) | ScrollySteps, ScrollyStepIndicator, CrossfadeVideo, GlassCard, the stepStyle ramp — the only entry point that does NOT re-export from the root, and the only one with a peer of its own |
32
37
  | [`/edit`](./docs/edit-mode.md) | Editable, setEditAdapter(adapter, EDIT_CHROME)/getEditAdapter, descriptors and helpers, collectionEditing, LocalizedText |
33
38
  | [`/config`](./docs/getting-started.md#wiring-an-app-uiprovider) | UiProvider, UiConfig, the locale set, the default Catalan messages |
34
39
  | `/contract` | The component-free half: LOCALES, BASE_LOCALE, localize, REACTIONS, PAGE_COPY_KEYS and the edit-descriptor types — the one subpath a host may import from SERVER code |
@@ -50,7 +55,11 @@ integrates its i18n and router through one `UiProvider` in the root layout.
50
55
  - **Component reference** — [primitives](./docs/components/primitives.md) ·
51
56
  [chrome](./docs/components/chrome.md) ·
52
57
  [content](./docs/components/content.md) ·
53
- [community](./docs/components/community.md)
58
+ [community](./docs/components/community.md) ·
59
+ [admin](./docs/components/admin.md) ·
60
+ [scrolly](./docs/components/scrolly.md)
61
+ - **[Changelog](./docs/changelog/index.md)** — one page per version, newest
62
+ first; [unreleased](./docs/changelog/unreleased.md) is what is on `main`
54
63
  - **Storybook** — `npm run storybook`: every component has a story;
55
64
  `Edit mode/EditMode` demos the whole editing loop against an in-memory
56
65
  adapter
@@ -84,8 +93,43 @@ diffable against history. The public structure is the semantic entry points
84
93
  above, assembled in `src/lib/{primitives,chrome,content-components,community}.ts`
85
94
  and `src/lib/forms/index.ts`.
86
95
 
87
- Releases are MANUAL: bump with `npm version`, then `npm publish`. The
88
- workflow this paragraph used to describe fired on every `v*` tag, had no
89
- `NPM_TOKEN` and no lint, check or test step, so it failed every time and was
90
- deleted; `prepublishOnly` (lint, check, unit tests) is the only publish gate
91
- now. Push the tag by all means — nothing reads it.
96
+ ## Cutting a release
97
+
98
+ Releases are MANUAL. The workflow this section used to describe fired on every
99
+ `v*` tag, had no `NPM_TOKEN` and no lint, check or test step, so it failed
100
+ every time and was deleted; `prepublishOnly` (lint, check, unit tests) is the
101
+ only publish gate now.
102
+
103
+ **While you work**, add the entry to
104
+ [`docs/changelog/unreleased.md`](./docs/changelog/unreleased.md) in the same PR
105
+ as the change, under one of Keep a Changelog's types — `Added`, `Changed`,
106
+ `Deprecated`, `Removed`, `Fixed`, `Security` — or
107
+ `Other (dependencies, CI, tools…)` for what a consumer never sees. One fact,
108
+ one entry: if a type already covers the thing you changed, edit that entry so
109
+ it describes the end state. A change a consumer must act on before upgrading
110
+ carries an **Upgrading:** paragraph.
111
+
112
+ **On release day**, in one commit (`chore(release): x.y.z`):
113
+
114
+ 1. Read `unreleased.md` once as a whole and merge what the individual PRs
115
+ restated.
116
+ 2. `git mv docs/changelog/unreleased.md docs/changelog/x.y.z.md`. Retitle it
117
+ `# x.y.z`, date it, and point its compare link at the tag range rather than
118
+ at `main`.
119
+ 3. Write a fresh `unreleased.md` with the same header and no entries — copy the
120
+ one you just renamed rather than inventing a new shape.
121
+ 4. Add the row to [`docs/changelog/index.md`](./docs/changelog/index.md).
122
+ 5. `npm version x.y.z` — MINOR for new exports and features, PATCH for fixes
123
+ alone, MAJOR for anything that breaks a consumer's imports or markup.
124
+ 6. `npm publish`. Check `npm view @vit-foundation/ui version` first: the
125
+ registry has been ahead of `main` before.
126
+ 7. `git push && git push origin vx.y.z`. Nothing automated reads the tag, but
127
+ the compare links in the changelog do.
128
+
129
+ **Publish from a clean checkout of `main`, never from a tree with uncommitted
130
+ work.** 0.28.0 was published from one: it carried an icon that reached npm and
131
+ nothing else, and the next release would have silently removed it again if the
132
+ tarball had not been diffed against the source first.
133
+
134
+ A released page is history: never rewrite one to match later code. If it is
135
+ wrong, say so on the next version's page.
@@ -0,0 +1,138 @@
1
+ <!--
2
+ @component HoverCard
3
+
4
+ The chrome of a hover card: a fixed-width surface with a shimmer skeleton
5
+ while its content is still resolving.
6
+
7
+ It owns the *shell*, never the content — what goes inside is the host's
8
+ snippet. It pairs with {@link ./anchor}, which decides where it goes, and the
9
+ two are separate on purpose: placement is arithmetic a test can check, chrome
10
+ is CSS a test cannot.
11
+
12
+ ## Why the shimmer is here
13
+ A hover card whose content arrives asynchronously flickers between empty and
14
+ full. Showing a skeleton for a beat makes the transition deliberate, and doing
15
+ it on *every* new target rather than only on slow ones keeps the rhythm
16
+ even — a card that sometimes shimmers and sometimes does not reads as jank.
17
+ Remount the component (a `{#key}` on the hovered target) and it shimmers
18
+ again; pass `skipShimmer` for a clone that is animating out, which should fade
19
+ real content rather than a fresh skeleton.
20
+
21
+ ## Theming
22
+ Presentation is CSS custom properties with plain fallbacks, so the card
23
+ renders standalone and restyles without a CSS framework:
24
+
25
+ | property | default |
26
+ |----------------------------|-----------|
27
+ | `--vit-card-font` | `inherit` |
28
+ | `--vit-card-width` | `277px` |
29
+ | `--vit-card-padding` | `10px` |
30
+ | `--vit-card-gap` | `10px` |
31
+ | `--vit-card-bg` | `#ffffff` |
32
+ | `--vit-card-radius` | `0` |
33
+ | `--vit-card-shadow` | `none` |
34
+ | `--vit-card-shimmer-color` | `currentColor` |
35
+
36
+ @property skipShimmer - Suppresses the mount shimmer, for a card fading out
37
+ @property shimmerMs - How long the skeleton is held, in ms
38
+ @property lines - Skeleton rows drawn under the heading block
39
+ @property class - Extra classes appended to the card
40
+ @property children - The card's content
41
+ -->
42
+ <script lang="ts">
43
+ import { onMount, type Snippet } from 'svelte';
44
+
45
+ let {
46
+ skipShimmer = false,
47
+ shimmerMs = 150,
48
+ lines = 3,
49
+ class: className = '',
50
+ children
51
+ }: {
52
+ skipShimmer?: boolean;
53
+ shimmerMs?: number;
54
+ lines?: number;
55
+ class?: string;
56
+ children: Snippet;
57
+ } = $props();
58
+
59
+ // Fixed per mount — the leaving clone must never re-shimmer.
60
+ // svelte-ignore state_referenced_locally
61
+ let shimmer = $state(!skipShimmer);
62
+
63
+ onMount(() => {
64
+ if (!shimmer) return;
65
+ const t = setTimeout(() => (shimmer = false), shimmerMs);
66
+ return () => clearTimeout(t);
67
+ });
68
+
69
+ /** Descending widths, so the skeleton reads as text rather than as bars. */
70
+ const widths = $derived(Array.from({ length: Math.max(0, lines) }, (_, i) => `${100 - i * 25}%`));
71
+ </script>
72
+
73
+ <div class="vit-card {className}">
74
+ {#if shimmer}
75
+ <div class="vit-card__skeleton">
76
+ <span class="vit-card__line" style="height: 12px; width: 100%"></span>
77
+ <span class="vit-card__line" style="height: 8px; width: 5rem"></span>
78
+ <span class="vit-card__rows">
79
+ {#each widths as w, i (i)}
80
+ <span class="vit-card__line" style="height: 17px; width: {w}"></span>
81
+ {/each}
82
+ </span>
83
+ </div>
84
+ {:else}
85
+ {@render children()}
86
+ {/if}
87
+ </div>
88
+
89
+ <style>
90
+ .vit-card {
91
+ display: flex;
92
+ flex-direction: column;
93
+ gap: var(--vit-card-gap, 10px);
94
+ width: var(--vit-card-width, 277px);
95
+ padding: var(--vit-card-padding, 10px);
96
+ overflow: hidden;
97
+ background: var(--vit-card-bg, #ffffff);
98
+ border-radius: var(--vit-card-radius, 0);
99
+ box-shadow: var(--vit-card-shadow, none);
100
+ font-family: var(--vit-card-font, inherit);
101
+ }
102
+ .vit-card__skeleton {
103
+ display: flex;
104
+ flex-direction: column;
105
+ gap: 6px;
106
+ }
107
+ .vit-card__rows {
108
+ display: flex;
109
+ flex-direction: column;
110
+ gap: 4px;
111
+ margin-top: 8px;
112
+ }
113
+ .vit-card__line {
114
+ display: block;
115
+ border-radius: 2px;
116
+ background: var(--vit-card-shimmer-color, currentColor);
117
+ animation: vit-card-shimmer 400ms ease-in-out infinite;
118
+ }
119
+
120
+ @keyframes vit-card-shimmer {
121
+ 0% {
122
+ opacity: 0.3;
123
+ }
124
+ 50% {
125
+ opacity: 0.6;
126
+ }
127
+ 100% {
128
+ opacity: 0.3;
129
+ }
130
+ }
131
+
132
+ @media (prefers-reduced-motion: reduce) {
133
+ .vit-card__line {
134
+ animation: none;
135
+ opacity: 0.3;
136
+ }
137
+ }
138
+ </style>
@@ -0,0 +1,52 @@
1
+ import { type Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ skipShimmer?: boolean;
4
+ shimmerMs?: number;
5
+ lines?: number;
6
+ class?: string;
7
+ children: Snippet;
8
+ };
9
+ /**
10
+ * HoverCard
11
+ *
12
+ * The chrome of a hover card: a fixed-width surface with a shimmer skeleton
13
+ * while its content is still resolving.
14
+ *
15
+ * It owns the *shell*, never the content — what goes inside is the host's
16
+ * snippet. It pairs with {@link ./anchor}, which decides where it goes, and the
17
+ * two are separate on purpose: placement is arithmetic a test can check, chrome
18
+ * is CSS a test cannot.
19
+ *
20
+ * ## Why the shimmer is here
21
+ * A hover card whose content arrives asynchronously flickers between empty and
22
+ * full. Showing a skeleton for a beat makes the transition deliberate, and doing
23
+ * it on *every* new target rather than only on slow ones keeps the rhythm
24
+ * even — a card that sometimes shimmers and sometimes does not reads as jank.
25
+ * Remount the component (a `{#key}` on the hovered target) and it shimmers
26
+ * again; pass `skipShimmer` for a clone that is animating out, which should fade
27
+ * real content rather than a fresh skeleton.
28
+ *
29
+ * ## Theming
30
+ * Presentation is CSS custom properties with plain fallbacks, so the card
31
+ * renders standalone and restyles without a CSS framework:
32
+ *
33
+ * | property | default |
34
+ * |----------------------------|-----------|
35
+ * | `--vit-card-font` | `inherit` |
36
+ * | `--vit-card-width` | `277px` |
37
+ * | `--vit-card-padding` | `10px` |
38
+ * | `--vit-card-gap` | `10px` |
39
+ * | `--vit-card-bg` | `#ffffff` |
40
+ * | `--vit-card-radius` | `0` |
41
+ * | `--vit-card-shadow` | `none` |
42
+ * | `--vit-card-shimmer-color` | `currentColor` |
43
+ *
44
+ * @property skipShimmer - Suppresses the mount shimmer, for a card fading out
45
+ * @property shimmerMs - How long the skeleton is held, in ms
46
+ * @property lines - Skeleton rows drawn under the heading block
47
+ * @property class - Extra classes appended to the card
48
+ * @property children - The card's content
49
+ */
50
+ declare const HoverCard: import("svelte").Component<$$ComponentProps, {}, "">;
51
+ type HoverCard = ReturnType<typeof HoverCard>;
52
+ export default HoverCard;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @module components/overlay/anchor
3
+ * Where a floating card goes when it is attached to a point.
4
+ *
5
+ * "Put a card next to the pointer without letting it leave the container" is a
6
+ * rule every hover tooltip needs and nobody writes down. It gets re-derived at
7
+ * each call site, slightly differently each time, and because it only runs
8
+ * inside a live layout it is never tested — so the version that forgot to clamp
9
+ * vertically ships a card that falls off the bottom of a short viewport, and
10
+ * nobody notices until a phone does it.
11
+ *
12
+ * It is one function here, it takes measurements rather than elements, and it
13
+ * returns two numbers. No DOM, no framework, no CSS: the caller owns all three.
14
+ */
15
+ /** The point the card is attached to, in container coordinates. */
16
+ export type AnchorPoint = {
17
+ /** Distance from the container's left edge, in px. */
18
+ x: number;
19
+ /** Distance from the container's top edge, in px. */
20
+ y: number;
21
+ };
22
+ /** A measured rectangle, in px. */
23
+ export type AnchorBox = {
24
+ /** Width in px. */
25
+ width: number;
26
+ /** Height in px. */
27
+ height: number;
28
+ };
29
+ /** Space to keep between the card and each container edge, in px. */
30
+ export type AnchorPadding = {
31
+ /** Minimum gap above the card. */
32
+ top?: number;
33
+ /** Minimum gap to the right of the card. */
34
+ right?: number;
35
+ /** Minimum gap below the card. */
36
+ bottom?: number;
37
+ /** Minimum gap to the left of the card. */
38
+ left?: number;
39
+ };
40
+ /** How the card is placed relative to the point, before clamping. */
41
+ export type AnchorOptions = {
42
+ /**
43
+ * Gap between the point and the card's near edge, in px. `x` is the
44
+ * horizontal offset to whichever side the card lands on; `y` shifts the
45
+ * card vertically and is only read when `align` is `'start'`.
46
+ */
47
+ offset?: {
48
+ x?: number;
49
+ y?: number;
50
+ };
51
+ /**
52
+ * Vertical relationship to the point: `'center'` centres the card on it,
53
+ * `'start'` puts the card's top edge there (plus `offset.y`).
54
+ */
55
+ align?: 'center' | 'start';
56
+ /** Minimum gaps from the container edges. */
57
+ padding?: AnchorPadding;
58
+ /**
59
+ * When the card does not fit on its preferred side, put it on the other one
60
+ * instead of letting the clamp slide it back over the point. Leave it off
61
+ * for a card that should simply stay put.
62
+ */
63
+ flip?: boolean;
64
+ /** Preferred horizontal side. Default `'right'`. */
65
+ side?: 'right' | 'left';
66
+ };
67
+ /** The resolved position, ready to write to `left` / `top` in px. */
68
+ export type AnchorPosition = {
69
+ /** Distance from the container's left edge, in px. */
70
+ left: number;
71
+ /** Distance from the container's top edge, in px. */
72
+ top: number;
73
+ };
74
+ /**
75
+ * Places a card beside a point, kept inside its container.
76
+ *
77
+ * The card is laid out on its preferred side, optionally flipped to the other
78
+ * side when it would not fit, and then clamped on **both** axes so it can never
79
+ * cross the container's padding — including vertically, which is the half most
80
+ * hand-rolled versions leave out.
81
+ *
82
+ * A container with no measured size yet (width or height `0`) returns the raw
83
+ * point, so a first frame renders somewhere sensible rather than at `0,0`.
84
+ *
85
+ * @param point - Where the card is attached, in container coordinates.
86
+ * @param card - The card's measured size. Height may be an estimate on the
87
+ * first frame; re-running once it is measured is cheap and exact.
88
+ * @param container - The box the card must stay inside.
89
+ * @param options - Offset, alignment, padding, flipping and preferred side.
90
+ * @returns The `left` / `top` to position the card at, in px.
91
+ */
92
+ export declare function anchor(point: AnchorPoint, card: AnchorBox, container: AnchorBox, options?: AnchorOptions): AnchorPosition;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @module components/overlay/anchor
3
+ * Where a floating card goes when it is attached to a point.
4
+ *
5
+ * "Put a card next to the pointer without letting it leave the container" is a
6
+ * rule every hover tooltip needs and nobody writes down. It gets re-derived at
7
+ * each call site, slightly differently each time, and because it only runs
8
+ * inside a live layout it is never tested — so the version that forgot to clamp
9
+ * vertically ships a card that falls off the bottom of a short viewport, and
10
+ * nobody notices until a phone does it.
11
+ *
12
+ * It is one function here, it takes measurements rather than elements, and it
13
+ * returns two numbers. No DOM, no framework, no CSS: the caller owns all three.
14
+ */
15
+ /**
16
+ * Places a card beside a point, kept inside its container.
17
+ *
18
+ * The card is laid out on its preferred side, optionally flipped to the other
19
+ * side when it would not fit, and then clamped on **both** axes so it can never
20
+ * cross the container's padding — including vertically, which is the half most
21
+ * hand-rolled versions leave out.
22
+ *
23
+ * A container with no measured size yet (width or height `0`) returns the raw
24
+ * point, so a first frame renders somewhere sensible rather than at `0,0`.
25
+ *
26
+ * @param point - Where the card is attached, in container coordinates.
27
+ * @param card - The card's measured size. Height may be an estimate on the
28
+ * first frame; re-running once it is measured is cheap and exact.
29
+ * @param container - The box the card must stay inside.
30
+ * @param options - Offset, alignment, padding, flipping and preferred side.
31
+ * @returns The `left` / `top` to position the card at, in px.
32
+ */
33
+ export function anchor(point, card, container, options = {}) {
34
+ if (!container.width || !container.height)
35
+ return { left: point.x, top: point.y };
36
+ const offsetX = options.offset?.x ?? 16;
37
+ const offsetY = options.offset?.y ?? 0;
38
+ const padTop = options.padding?.top ?? 0;
39
+ const padRight = options.padding?.right ?? 0;
40
+ const padBottom = options.padding?.bottom ?? 0;
41
+ const padLeft = options.padding?.left ?? 0;
42
+ const toLeftOf = point.x - offsetX - card.width;
43
+ const toRightOf = point.x + offsetX;
44
+ let left = options.side === 'left' ? toLeftOf : toRightOf;
45
+ if (options.flip) {
46
+ if (options.side === 'left') {
47
+ if (left < padLeft && toRightOf + card.width <= container.width - padRight)
48
+ left = toRightOf;
49
+ }
50
+ else if (left + card.width > container.width - padRight && toLeftOf >= padLeft) {
51
+ left = toLeftOf;
52
+ }
53
+ }
54
+ let top = options.align === 'start' ? point.y + offsetY : point.y - card.height / 2;
55
+ // Clamp last, on both axes. `Math.max` after `Math.min` so a card taller or
56
+ // wider than the space it has left is pinned to the near edge rather than
57
+ // pushed off the far one.
58
+ left = Math.max(padLeft, Math.min(left, container.width - card.width - padRight));
59
+ top = Math.max(padTop, Math.min(top, container.height - card.height - padBottom));
60
+ return { left, top };
61
+ }
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export * from './forms/index.js';
7
7
  export * from './config/index.js';
8
8
  export * from './edit/index.js';
9
9
  export { buildQueryString } from './utils/paths.js';
10
+ export { anchor, HoverCard } from './overlay.js';
package/dist/index.js CHANGED
@@ -16,3 +16,4 @@ export * from './edit/index.js';
16
16
  // server-side rules, so they go through ./contract instead — see the note in
17
17
  // utils/paths.ts, which is where the export surface for all of them is decided.
18
18
  export { buildQueryString } from './utils/paths.js';
19
+ export { anchor, HoverCard } from './overlay.js';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Floating-overlay primitives: where a card attached to a point goes, and the
3
+ * chrome it is drawn in.
4
+ *
5
+ * The two are separate because they fail differently. Placement is arithmetic —
6
+ * it can be wrong on a phone and right on a laptop, and it belongs in a test.
7
+ * Chrome is CSS, and belongs behind custom properties. Both were previously
8
+ * re-implemented per call site, which is how one copy ended up clamping
9
+ * horizontally but not vertically.
10
+ *
11
+ * Domain-free: it knows about points, boxes and padding, and nothing about maps,
12
+ * charts or what the card says.
13
+ */
14
+ export { anchor, type AnchorBox, type AnchorOptions, type AnchorPadding, type AnchorPoint, type AnchorPosition } from './components/overlay/anchor.js';
15
+ export { default as HoverCard } from './components/overlay/HoverCard.svelte';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Floating-overlay primitives: where a card attached to a point goes, and the
3
+ * chrome it is drawn in.
4
+ *
5
+ * The two are separate because they fail differently. Placement is arithmetic —
6
+ * it can be wrong on a phone and right on a laptop, and it belongs in a test.
7
+ * Chrome is CSS, and belongs behind custom properties. Both were previously
8
+ * re-implemented per call site, which is how one copy ended up clamping
9
+ * horizontally but not vertically.
10
+ *
11
+ * Domain-free: it knows about points, boxes and padding, and nothing about maps,
12
+ * charts or what the card says.
13
+ */
14
+ export { anchor } from './components/overlay/anchor.js';
15
+ export { default as HoverCard } from './components/overlay/HoverCard.svelte';
package/dist/scrolly.d.ts CHANGED
@@ -10,5 +10,6 @@
10
10
  export { default as ScrollySteps } from './components/scrolly/ScrollySteps.svelte';
11
11
  export { default as ScrollyStepIndicator } from './components/scrolly/ScrollyStepIndicator.svelte';
12
12
  export { default as CrossfadeVideo } from './components/scrolly/CrossfadeVideo.svelte';
13
+ export type { CrossfadeVideoHandle } from './components/scrolly/CrossfadeVideo.svelte';
13
14
  export { default as GlassCard } from './components/scrolly/GlassCard.svelte';
14
15
  export { calcOpacity, calcTranslateY, stepStyle, type StepStyle } from './components/scrolly/stepStyle.js';
@@ -79,4 +79,17 @@
79
79
  --video-badge-padding: var(--space-3);
80
80
  --video-badge-color: var(--color-ink);
81
81
  --video-badge-bg: rgb(255 255 255 / 50%);
82
+
83
+ /* Floating overlays (the `./overlay` subpath) */
84
+ /* The hover card's fixed width. Fixed rather than fluid because the card is
85
+ positioned by measuring it: a width that depends on its content makes the
86
+ placement arithmetic chase itself for a frame. */
87
+ --vit-card-width: 277px;
88
+ --vit-card-padding: var(--space-2, 10px);
89
+ --vit-card-gap: var(--space-2, 10px);
90
+ --vit-card-bg: #ffffff;
91
+ --vit-card-radius: 0;
92
+ --vit-card-shadow: none;
93
+ --vit-card-font: inherit;
94
+ --vit-card-shimmer-color: currentColor;
82
95
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vit-foundation/ui",
3
- "version": "0.29.0",
3
+ "version": "0.31.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -96,6 +96,11 @@
96
96
  "types": "./dist/scrolly.d.ts",
97
97
  "svelte": "./dist/scrolly.js",
98
98
  "default": "./dist/scrolly.js"
99
+ },
100
+ "./overlay": {
101
+ "types": "./dist/overlay.d.ts",
102
+ "svelte": "./dist/overlay.js",
103
+ "default": "./dist/overlay.js"
99
104
  }
100
105
  },
101
106
  "peerDependencies": {