@jelinek/ui 0.3.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 +492 -0
- package/dist/components/Alert.svelte +59 -0
- package/dist/components/Alert.svelte.d.ts +13 -0
- package/dist/components/Button.svelte +178 -0
- package/dist/components/Button.svelte.d.ts +19 -0
- package/dist/components/Card.svelte +68 -0
- package/dist/components/Card.svelte.d.ts +11 -0
- package/dist/components/ChapterNav.svelte +290 -0
- package/dist/components/ChapterNav.svelte.d.ts +18 -0
- package/dist/components/Checkbox.svelte +52 -0
- package/dist/components/Checkbox.svelte.d.ts +11 -0
- package/dist/components/CodeCopy.svelte +294 -0
- package/dist/components/CodeCopy.svelte.d.ts +51 -0
- package/dist/components/Container.svelte +34 -0
- package/dist/components/Container.svelte.d.ts +10 -0
- package/dist/components/ContentLogo.svelte +151 -0
- package/dist/components/ContentLogo.svelte.d.ts +37 -0
- package/dist/components/Demo.svelte +111 -0
- package/dist/components/Demo.svelte.d.ts +12 -0
- package/dist/components/Eyebrow.svelte +70 -0
- package/dist/components/Eyebrow.svelte.d.ts +12 -0
- package/dist/components/Glass.svelte +75 -0
- package/dist/components/Glass.svelte.d.ts +10 -0
- package/dist/components/Grid.svelte +87 -0
- package/dist/components/Grid.svelte.d.ts +11 -0
- package/dist/components/Label.svelte +37 -0
- package/dist/components/Label.svelte.d.ts +11 -0
- package/dist/components/PageHero.svelte +312 -0
- package/dist/components/PageHero.svelte.d.ts +55 -0
- package/dist/components/Pager.svelte +98 -0
- package/dist/components/Pager.svelte.d.ts +13 -0
- package/dist/components/Panel.svelte +89 -0
- package/dist/components/Panel.svelte.d.ts +12 -0
- package/dist/components/ProductCard.svelte +81 -0
- package/dist/components/ProductCard.svelte.d.ts +18 -0
- package/dist/components/Radio.svelte +54 -0
- package/dist/components/Radio.svelte.d.ts +11 -0
- package/dist/components/RadioGroup.svelte +42 -0
- package/dist/components/RadioGroup.svelte.d.ts +12 -0
- package/dist/components/Select.svelte +65 -0
- package/dist/components/Select.svelte.d.ts +20 -0
- package/dist/components/SiteFooter.svelte +121 -0
- package/dist/components/SiteFooter.svelte.d.ts +13 -0
- package/dist/components/SiteHeader.svelte +613 -0
- package/dist/components/SiteHeader.svelte.d.ts +80 -0
- package/dist/components/Slider.svelte +55 -0
- package/dist/components/Slider.svelte.d.ts +14 -0
- package/dist/components/Swatch.svelte +174 -0
- package/dist/components/Swatch.svelte.d.ts +58 -0
- package/dist/components/Tab.svelte +88 -0
- package/dist/components/Tab.svelte.d.ts +11 -0
- package/dist/components/Tabs.svelte +306 -0
- package/dist/components/Tabs.svelte.d.ts +20 -0
- package/dist/components/Tag.svelte +71 -0
- package/dist/components/Tag.svelte.d.ts +16 -0
- package/dist/components/TextField.svelte +100 -0
- package/dist/components/TextField.svelte.d.ts +18 -0
- package/dist/components/ThemeToggle.svelte +122 -0
- package/dist/components/ThemeToggle.svelte.d.ts +11 -0
- package/dist/components/Tile.svelte +115 -0
- package/dist/components/Tile.svelte.d.ts +14 -0
- package/dist/components/TileScroller.svelte +199 -0
- package/dist/components/TileScroller.svelte.d.ts +25 -0
- package/dist/components/container-context.d.ts +1 -0
- package/dist/components/container-context.js +6 -0
- package/dist/components/deer-mark-path.d.ts +16 -0
- package/dist/components/deer-mark-path.js +16 -0
- package/dist/components/nav.d.ts +25 -0
- package/dist/components/nav.js +17 -0
- package/dist/components/radio-context.d.ts +6 -0
- package/dist/components/radio-context.js +1 -0
- package/dist/components/tabs-context.d.ts +5 -0
- package/dist/components/tabs-context.js +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +37 -0
- package/dist/theme/base.css +439 -0
- package/dist/theme/extras.css +2 -0
- package/dist/theme/fonts.css +107 -0
- package/dist/theme/tokens.css +208 -0
- package/dist/utils/chapter-nav-dock.svelte.d.ts +23 -0
- package/dist/utils/chapter-nav-dock.svelte.js +65 -0
- package/dist/utils/cn.d.ts +2 -0
- package/dist/utils/cn.js +27 -0
- package/package.json +79 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
image?: string;
|
|
7
|
+
imageAlt?: string;
|
|
8
|
+
href?: string;
|
|
9
|
+
ctaLabel?: string;
|
|
10
|
+
color?: 'brown' | 'magenta' | 'black';
|
|
11
|
+
/** Optional badge rendered above the title, e.g. <Tag variant="instock">. */
|
|
12
|
+
tag?: Snippet;
|
|
13
|
+
class?: string;
|
|
14
|
+
}
|
|
15
|
+
type $$ComponentProps = Props & HTMLAttributes<HTMLDivElement>;
|
|
16
|
+
declare const ProductCard: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
17
|
+
type ProductCard = ReturnType<typeof ProductCard>;
|
|
18
|
+
export default ProductCard;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext } from 'svelte';
|
|
3
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '../utils/cn.js';
|
|
5
|
+
import { RADIO_CONTEXT, type RadioContext } from './radio-context.js';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
value: string;
|
|
9
|
+
label: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
value,
|
|
16
|
+
label,
|
|
17
|
+
id,
|
|
18
|
+
class: className,
|
|
19
|
+
...rest
|
|
20
|
+
}: Props & Omit<HTMLInputAttributes, 'value' | 'type' | 'name'> = $props();
|
|
21
|
+
|
|
22
|
+
const group = getContext<RadioContext>(RADIO_CONTEXT);
|
|
23
|
+
if (!group) throw new Error('<Radio> must be rendered inside <RadioGroup>.');
|
|
24
|
+
|
|
25
|
+
const uid = $props.id();
|
|
26
|
+
const inputId = $derived(id ?? uid);
|
|
27
|
+
const checked = $derived(group.current() === value);
|
|
28
|
+
|
|
29
|
+
// Same reasoning as Checkbox.svelte: no CSS rule exists for radio inputs
|
|
30
|
+
// or their label; font-secondary/text-fg reproduces what the guide's own
|
|
31
|
+
// `.demo` wrapper applies ambiently (jelinek.css:322-324), and
|
|
32
|
+
// accent-jelinek-brown (not accent-jelinek-magenta) keeps the mattress
|
|
33
|
+
// accent out of furniture UIs by default while still following the
|
|
34
|
+
// division automatically via the --JELINEK-BROWN re-theme
|
|
35
|
+
// (tokens.css:161-166). Flagged for adjudication.
|
|
36
|
+
const LABEL = 'flex cursor-pointer items-center gap-2.5 font-secondary text-step0 text-fg';
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<label for={inputId} class={cn(LABEL, className)}>
|
|
40
|
+
<input
|
|
41
|
+
{...rest}
|
|
42
|
+
id={inputId}
|
|
43
|
+
type="radio"
|
|
44
|
+
name={group.name}
|
|
45
|
+
{value}
|
|
46
|
+
{checked}
|
|
47
|
+
onchange={(event) => {
|
|
48
|
+
group.select(value);
|
|
49
|
+
rest.onchange?.(event);
|
|
50
|
+
}}
|
|
51
|
+
class="accent-jelinek-brown"
|
|
52
|
+
/>
|
|
53
|
+
{label}
|
|
54
|
+
</label>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
id?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
type $$ComponentProps = Props & Omit<HTMLInputAttributes, 'value' | 'type' | 'name'>;
|
|
9
|
+
declare const Radio: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type Radio = ReturnType<typeof Radio>;
|
|
11
|
+
export default Radio;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext, untrack, type Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '../utils/cn.js';
|
|
5
|
+
import { RADIO_CONTEXT, type RadioContext } from './radio-context.js';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
name: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
children: Snippet;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
name,
|
|
16
|
+
value = $bindable(''),
|
|
17
|
+
class: className,
|
|
18
|
+
children,
|
|
19
|
+
...rest
|
|
20
|
+
}: Props & HTMLAttributes<HTMLDivElement> = $props();
|
|
21
|
+
|
|
22
|
+
// RadioContext (radio-context.ts) fixes `name` as a plain string, not a
|
|
23
|
+
// getter like `current`/`select` — the native <input name> a group's
|
|
24
|
+
// radios share isn't meant to change after mount. `untrack` here is
|
|
25
|
+
// exactly that: an explicit, one-time snapshot at setContext time,
|
|
26
|
+
// silencing Svelte's state_referenced_locally warning rather than
|
|
27
|
+
// leaving an unacknowledged one.
|
|
28
|
+
setContext<RadioContext>(RADIO_CONTEXT, {
|
|
29
|
+
name: untrack(() => name),
|
|
30
|
+
current: () => value,
|
|
31
|
+
select: (next) => (value = next)
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// No CSS rule targets a "radio group" wrapper; ui/komponenty.html just
|
|
35
|
+
// stacks the <label> rows with margin-bottom on all but the last. gap-2.5
|
|
36
|
+
// (10px) reproduces that spacing declaratively instead of a per-item
|
|
37
|
+
// trailing margin.
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<div {...rest} role={rest.role ?? 'radiogroup'} class={cn('flex flex-col gap-2.5', className)}>
|
|
41
|
+
{@render children()}
|
|
42
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props {
|
|
4
|
+
name: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
children: Snippet;
|
|
8
|
+
}
|
|
9
|
+
type $$ComponentProps = Props & HTMLAttributes<HTMLDivElement>;
|
|
10
|
+
declare const RadioGroup: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
11
|
+
type RadioGroup = ReturnType<typeof RadioGroup>;
|
|
12
|
+
export default RadioGroup;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLSelectAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '../utils/cn.js';
|
|
5
|
+
import Label from './Label.svelte';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
value?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Invalid state. Reproduces the guide's `.select.is-error`
|
|
13
|
+
* (jelinek.css:988-991) — new in the Task 31 merge — and sets
|
|
14
|
+
* `aria-invalid` alongside it. Same prop and same rule as TextField's;
|
|
15
|
+
* the guide styles both in one selector list.
|
|
16
|
+
*/
|
|
17
|
+
error?: boolean;
|
|
18
|
+
class?: string;
|
|
19
|
+
children: Snippet;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
value = $bindable(''),
|
|
24
|
+
label,
|
|
25
|
+
id,
|
|
26
|
+
error = false,
|
|
27
|
+
class: className,
|
|
28
|
+
children,
|
|
29
|
+
...rest
|
|
30
|
+
}: Props & Omit<HTMLSelectAttributes, 'value'> = $props();
|
|
31
|
+
|
|
32
|
+
const uid = $props.id();
|
|
33
|
+
const selectId = $derived(id ?? uid);
|
|
34
|
+
|
|
35
|
+
// jelinek.css:966-975 (`.input, .select`) — same rule, and same
|
|
36
|
+
// corrections against the draft brief, as TextField: border-fg-muted2
|
|
37
|
+
// (not border-border-subtle), px-[14px] py-[11px] (not px-4 py-3),
|
|
38
|
+
// text-[0.98rem] (not text-step0).
|
|
39
|
+
// Task 31 — the focus ring moved onto --focus-width/--focus-color, which
|
|
40
|
+
// fixes a too-dark ring in dark mode, and `.select.is-error`
|
|
41
|
+
// (jelinek.css:987-991) is new. See TextField.svelte for the full note on
|
|
42
|
+
// both; the guide styles `.input` and `.select` in one selector list, so the
|
|
43
|
+
// two components stay deliberately identical here.
|
|
44
|
+
const BASE =
|
|
45
|
+
'w-full rounded-button border border-fg-muted2 bg-surface px-[14px] py-[11px] ' +
|
|
46
|
+
'font-secondary text-[0.98rem] text-fg ' +
|
|
47
|
+
'focus:outline-[length:var(--focus-width)] focus:outline-offset-1 ' +
|
|
48
|
+
'focus:outline-[var(--focus-color)] focus:border-[var(--focus-color)]';
|
|
49
|
+
|
|
50
|
+
const ERROR =
|
|
51
|
+
'border-sem-error-strong focus:border-sem-error-strong focus:outline-sem-error-strong';
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
{#if label}
|
|
55
|
+
<Label for={selectId}>{label}</Label>
|
|
56
|
+
{/if}
|
|
57
|
+
<select
|
|
58
|
+
{...rest}
|
|
59
|
+
id={selectId}
|
|
60
|
+
aria-invalid={error ? 'true' : rest['aria-invalid']}
|
|
61
|
+
bind:value
|
|
62
|
+
class={cn(BASE, error && ERROR, className)}
|
|
63
|
+
>
|
|
64
|
+
{@render children()}
|
|
65
|
+
</select>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLSelectAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props {
|
|
4
|
+
value?: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Invalid state. Reproduces the guide's `.select.is-error`
|
|
9
|
+
* (jelinek.css:988-991) — new in the Task 31 merge — and sets
|
|
10
|
+
* `aria-invalid` alongside it. Same prop and same rule as TextField's;
|
|
11
|
+
* the guide styles both in one selector list.
|
|
12
|
+
*/
|
|
13
|
+
error?: boolean;
|
|
14
|
+
class?: string;
|
|
15
|
+
children: Snippet;
|
|
16
|
+
}
|
|
17
|
+
type $$ComponentProps = Props & Omit<HTMLSelectAttributes, 'value'>;
|
|
18
|
+
declare const Select: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
19
|
+
type Select = ReturnType<typeof Select>;
|
|
20
|
+
export default Select;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { cn } from '../utils/cn.js';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
logo?: string;
|
|
7
|
+
logoAlt?: string;
|
|
8
|
+
slogan?: string;
|
|
9
|
+
meta?: string;
|
|
10
|
+
stamp?: string;
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
logo,
|
|
16
|
+
logoAlt = 'JELÍNEK',
|
|
17
|
+
slogan,
|
|
18
|
+
meta,
|
|
19
|
+
stamp,
|
|
20
|
+
class: className,
|
|
21
|
+
...rest
|
|
22
|
+
}: Props & HTMLAttributes<HTMLElement> = $props();
|
|
23
|
+
|
|
24
|
+
// jelinek.css:759-770 (.site-footer, .site-footer__inner). `margin-top:
|
|
25
|
+
// 60px` (:760) is kept — unlike Card/Alert (Tasks 5/6), which deliberately
|
|
26
|
+
// drop their own external margins on the reasoning that a reusable
|
|
27
|
+
// CONTENT atom shouldn't fight a consumer's grid/flex `gap`, SiteFooter
|
|
28
|
+
// is page CHROME: there is exactly one per page, always at the very
|
|
29
|
+
// bottom, and per this task's direction the guide is reproduced as the
|
|
30
|
+
// default rather than softened for a hypothetical consumer. 60px isn't on
|
|
31
|
+
// Tailwind's default spacing scale (nearest are 56px/64px) — arbitrary
|
|
32
|
+
// `mt-[60px]`. `border-radius: var(--radius-section) var(--radius-section)
|
|
33
|
+
// 0 0` (top corners only, :761) → `rounded-t-section`.
|
|
34
|
+
//
|
|
35
|
+
// partials/footer.html has NO anchor wrapping the logo image (unlike
|
|
36
|
+
// header.html, which wraps its mark in <a href="/">) — reproduced as a
|
|
37
|
+
// bare <img>, not a link.
|
|
38
|
+
//
|
|
39
|
+
// Real footer.html uses a dedicated white PNG asset (`logo-znak-bily.png`)
|
|
40
|
+
// here, not the auto-theming inline SVG header.html uses. That's not
|
|
41
|
+
// incidental: the footer's background is ALWAYS pure black (--bg-black is
|
|
42
|
+
// hsl(0,0%,0%) in both themes, see tokens.css) but --JELINEK-WHITE itself
|
|
43
|
+
// INVERTS in dark mode (tokens.css:91, becomes hsl(0,0%,0%)) — the
|
|
44
|
+
// re-theming mark would go invisible against its own footer in dark mode.
|
|
45
|
+
// So, unlike SiteHeader, no bundled-SVG default was added here for the
|
|
46
|
+
// `logo` prop (kept as a plain URL string, per the brief) — flagged as an
|
|
47
|
+
// open question in the Task 9 report: a theme-invariant white-only mark
|
|
48
|
+
// fallback is a reasonable future addition, just out of this task's
|
|
49
|
+
// explicit scope (the owner's logo direction named SiteHeader only).
|
|
50
|
+
const BASE = 'mt-[60px] rounded-t-section bg-surface-black text-fg-inverse';
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<footer {...rest} class={cn(BASE, className)}>
|
|
54
|
+
<div class="mx-auto flex max-w-page flex-wrap items-center gap-6 px-6 py-10">
|
|
55
|
+
{#if logo}
|
|
56
|
+
<!-- jelinek.css:767 — 52px square, 12px radius. Neither value is on
|
|
57
|
+
Tailwind's default scale (nearest square size is 48/56px;
|
|
58
|
+
nearest radius token, radius-card, clamps 10-15px) — both
|
|
59
|
+
arbitrary. The brief's h-8 w-auto (32px, unconstrained width)
|
|
60
|
+
was wrong on every count. -->
|
|
61
|
+
<img src={logo} alt={logoAlt} class="h-[52px] w-[52px] rounded-[12px]" />
|
|
62
|
+
{/if}
|
|
63
|
+
{#if slogan || meta}
|
|
64
|
+
<div>
|
|
65
|
+
{#if slogan}
|
|
66
|
+
<!-- jelinek.css:769 (.slogan): font-weight 700 only — no
|
|
67
|
+
font-family/size rule of its own, so it inherits body's
|
|
68
|
+
defaults (font-serif/Archer, step0/1rem, leading 1.6,
|
|
69
|
+
jelinek.css:264-267). Set explicitly rather than relying
|
|
70
|
+
on an ambient body reset the consuming app may not have,
|
|
71
|
+
same reasoning Checkbox/Card use for their own inherited
|
|
72
|
+
values. -->
|
|
73
|
+
<div class="font-serif text-step0 font-bold leading-[1.6]">{slogan}</div>
|
|
74
|
+
{/if}
|
|
75
|
+
{#if meta}
|
|
76
|
+
<!-- The real footer.html actually renders a THIRD, distinct
|
|
77
|
+
block here styled `.small.muted2` (jelinek.css:306,304:
|
|
78
|
+
step-down1/1.1/weight 300, text-muted2) for the address
|
|
79
|
+
line, plus a separate `.meta`-classed block (jelinek.css:770)
|
|
80
|
+
for a page-specific build-version stamp that isn't
|
|
81
|
+
meaningful outside this static site. This component's
|
|
82
|
+
`meta` prop maps to the general-purpose one — the
|
|
83
|
+
`.small.muted2` address-line treatment — not the
|
|
84
|
+
name-colliding `.site-footer .meta` CSS class (which pins
|
|
85
|
+
itself to the far right via margin-left:auto and is really
|
|
86
|
+
"wherever the deploy timestamp goes", not a generic
|
|
87
|
+
"meta text" concept). Task 18 adds that third block as its
|
|
88
|
+
own `stamp` prop below — kept a separate prop, not folded
|
|
89
|
+
into `meta`, for exactly the reason this paragraph already
|
|
90
|
+
explains: same CSS class name in the guide, different
|
|
91
|
+
element, different font, different position.
|
|
92
|
+
|
|
93
|
+
Fix round 1: `.small` is also in the shared font-secondary
|
|
94
|
+
selector list (jelinek.css:313-317, `.small` listed
|
|
95
|
+
alongside `.site-header__nav a`/`.chapter-nav a`/`.pager a`
|
|
96
|
+
etc.) — missing from the first pass, which left this line
|
|
97
|
+
inheriting the ambient serif body font instead. -->
|
|
98
|
+
<div class="font-secondary text-step-down1 font-light leading-[1.1] text-fg-muted2">{meta}</div>
|
|
99
|
+
{/if}
|
|
100
|
+
</div>
|
|
101
|
+
{/if}
|
|
102
|
+
{#if stamp}
|
|
103
|
+
<!-- jelinek.css:770 (`.site-footer .meta`): margin-left:auto pins it
|
|
104
|
+
to the far right of `.site-footer__inner`'s flex row — so this
|
|
105
|
+
has to be a sibling of the logo/slogan-wrapper above, not nested
|
|
106
|
+
inside either, or margin-left:auto pins it right only within that
|
|
107
|
+
inner wrapper instead of the whole footer. `0.85rem` is a literal
|
|
108
|
+
in the guide, not on the --step scale — arbitrary `text-[0.85rem]`,
|
|
109
|
+
not the nearest step. No font-family rule of its own (unlike
|
|
110
|
+
`.small`, this class is NOT in the jelinek.css:313-317
|
|
111
|
+
font-secondary list), so — same reasoning as `slogan` above — it
|
|
112
|
+
inherits body's ambient Archer, set explicitly here rather than
|
|
113
|
+
relying on a consuming app's own reset to provide it. No
|
|
114
|
+
`flex-wrap` breakpoint needed: `.site-footer__inner`'s own
|
|
115
|
+
`flex-wrap: wrap` (already `flex-wrap` below) already drops this
|
|
116
|
+
onto its own line under the logo/text on narrow screens, same as
|
|
117
|
+
the guide. -->
|
|
118
|
+
<div class="ml-auto font-serif text-[0.85rem] text-fg-muted2">{stamp}</div>
|
|
119
|
+
{/if}
|
|
120
|
+
</div>
|
|
121
|
+
</footer>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props {
|
|
3
|
+
logo?: string;
|
|
4
|
+
logoAlt?: string;
|
|
5
|
+
slogan?: string;
|
|
6
|
+
meta?: string;
|
|
7
|
+
stamp?: string;
|
|
8
|
+
class?: string;
|
|
9
|
+
}
|
|
10
|
+
type $$ComponentProps = Props & HTMLAttributes<HTMLElement>;
|
|
11
|
+
declare const SiteFooter: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type SiteFooter = ReturnType<typeof SiteFooter>;
|
|
13
|
+
export default SiteFooter;
|