@hubpav/hwio-ui 0.7.11 → 0.9.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/package.json +4 -4
- package/src/components/HWioApplicationTile.astro +49 -0
- package/src/components/HWioButton.astro +9 -4
- package/src/components/HWioChoiceCards.astro +3 -3
- package/src/components/HWioContactSection.astro +1 -1
- package/src/components/HWioCookieConsent.astro +9 -9
- package/src/components/HWioCutout.astro +58 -0
- package/src/components/HWioFaq.astro +1 -1
- package/src/components/HWioFeatureCard.astro +1 -1
- package/src/components/HWioFooter.astro +7 -4
- package/src/components/HWioHeader.astro +13 -6
- package/src/components/HWioHeroSplit.astro +14 -7
- package/src/components/HWioIsoScene.astro +93 -0
- package/src/components/HWioKeyFigure.astro +45 -0
- package/src/components/HWioLanguageSwitcher.astro +11 -1
- package/src/components/HWioLogoStrip.astro +1 -1
- package/src/components/HWioMegaLinks.astro +54 -0
- package/src/components/HWioPhoto.astro +36 -0
- package/src/components/HWioPricingTiers.astro +1 -1
- package/src/components/HWioProcessSteps.astro +1 -1
- package/src/components/HWioReveal.astro +15 -0
- package/src/components/HWioSection.astro +1 -0
- package/src/components/HWioStatsBand.astro +2 -2
- package/src/components/HWioStoryCard.astro +38 -0
- package/src/styles/prose.css +3 -3
- package/src/styles/styles.css +325 -37
- package/src/styles/themes/er3o.css +92 -1
- package/src/styles/themes/hwio-dark.css +127 -19
- package/src/styles/themes/hwio-forestry-dark.css +127 -19
- package/src/styles/themes/hwio-forestry.css +121 -13
- package/src/styles/themes/hwio.css +122 -14
- package/src/types.ts +9 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* A group of links for HWioHeader's `mega:<key>` panels (owner, 2026-10-30): an optional caps title
|
|
4
|
+
* with an "all" link on its line, then links with a one-line description. Labels never wrap; the
|
|
5
|
+
* descriptions are small (13 px), Regular, Gray and balanced, so siblings read as equals. `columns` is
|
|
6
|
+
* fixed: the panel shows only from the header's desktop breakpoint, and a column count that grows with
|
|
7
|
+
* the viewport (three at 2xl) squeezed descriptions into broken lines. Products may carry a thumbnail
|
|
8
|
+
* (a cut-out with the shared product shadow).
|
|
9
|
+
*/
|
|
10
|
+
import type { HWioLinkItem } from '../types';
|
|
11
|
+
import HWioIcon from './HWioIcon.astro';
|
|
12
|
+
interface Item extends HWioLinkItem {
|
|
13
|
+
description?: string;
|
|
14
|
+
/** A product thumbnail (cut-out on a transparent ground); decorative, the label names the product. */
|
|
15
|
+
image?: string;
|
|
16
|
+
}
|
|
17
|
+
interface Props {
|
|
18
|
+
title?: string;
|
|
19
|
+
all?: HWioLinkItem;
|
|
20
|
+
items: Item[];
|
|
21
|
+
columns?: 1 | 2 | 3;
|
|
22
|
+
/** data-track-location for the links (default "header-menu"). */
|
|
23
|
+
trackLocation?: string;
|
|
24
|
+
class?: string;
|
|
25
|
+
}
|
|
26
|
+
const { title, all, items, columns = 1, trackLocation = 'header-menu', class: className = '' } = Astro.props;
|
|
27
|
+
const COLUMNS = { 1: 'grid-cols-1', 2: 'grid-cols-2', 3: 'grid-cols-3' } as const;
|
|
28
|
+
const linkAttrs = (item: HWioLinkItem) => (item.external ? { target: '_blank', rel: 'noopener noreferrer' } : {});
|
|
29
|
+
---
|
|
30
|
+
<div class:list={['min-w-0', className]}>
|
|
31
|
+
{(title || all) && (
|
|
32
|
+
<div class="mb-4 flex items-baseline justify-between gap-6 px-3">
|
|
33
|
+
{title && <p class="hwio-mega-title">{title}</p>}
|
|
34
|
+
{all && <a href={all.href} {...linkAttrs(all)} class="hwio-link hwio-weight-label whitespace-nowrap text-sm" data-track={all.track?.id} data-track-location={all.track?.location ?? trackLocation}>{all.label}</a>}
|
|
35
|
+
</div>
|
|
36
|
+
)}
|
|
37
|
+
<ul class:list={['grid gap-x-6 gap-y-1', COLUMNS[columns]]}>
|
|
38
|
+
{items.map((item) => (
|
|
39
|
+
<li class="min-w-0">
|
|
40
|
+
<a href={item.href} {...linkAttrs(item)} class="flex items-start gap-4 rounded-xl px-3 py-2.5 transition-colors hover:bg-base-200" aria-current={item.current ? 'page' : undefined} data-track={item.track?.id} data-track-location={item.track?.location ?? trackLocation}>
|
|
41
|
+
{item.image && (
|
|
42
|
+
<span class="flex h-20 w-16 shrink-0 items-center justify-center">
|
|
43
|
+
<img src={item.image} alt="" loading="lazy" decoding="async" class="hwio-product-shadow max-h-full max-w-full object-contain" />
|
|
44
|
+
</span>
|
|
45
|
+
)}
|
|
46
|
+
<span class="min-w-0 flex-1">
|
|
47
|
+
<span class="hwio-mega-label">{item.label}{item.external && <HWioIcon name="arrow-up-right" size="sm" class="opacity-50" />}</span>
|
|
48
|
+
{item.description && <span class="hwio-menu-desc mt-0.5 block">{item.description}</span>}
|
|
49
|
+
</span>
|
|
50
|
+
</a>
|
|
51
|
+
</li>
|
|
52
|
+
))}
|
|
53
|
+
</ul>
|
|
54
|
+
</div>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* A photograph at a fixed aspect ratio, filling its frame (object-fit: cover; `focus` picks the
|
|
4
|
+
* part that stays in view). Photographs come from the artwork library, clearance public (Brand
|
|
5
|
+
* Guidelines chapter 08: photographs prove). For a product on a transparent ground use HWioCutout.
|
|
6
|
+
*/
|
|
7
|
+
import type { HWioAspect, HWioMedia } from '../types';
|
|
8
|
+
interface Props {
|
|
9
|
+
image: HWioMedia;
|
|
10
|
+
aspect?: HWioAspect;
|
|
11
|
+
rounded?: 'none' | 'xl' | '2xl';
|
|
12
|
+
focus?: 'center' | 'top' | 'bottom' | 'left' | 'right';
|
|
13
|
+
/** Above the fold: load at once with high priority. */
|
|
14
|
+
eager?: boolean;
|
|
15
|
+
class?: string;
|
|
16
|
+
imgClass?: string;
|
|
17
|
+
}
|
|
18
|
+
const { image, aspect = '4/3', rounded = '2xl', focus = 'center', eager = false, class: className = '', imgClass = '' } = Astro.props;
|
|
19
|
+
const ASPECT = { '1/1': 'aspect-square', '4/3': 'aspect-[4/3]', '3/2': 'aspect-[3/2]', '16/9': 'aspect-video', '4/5': 'aspect-[4/5]', '3/4': 'aspect-[3/4]' } as const;
|
|
20
|
+
const ROUNDED = { none: 'rounded-none', xl: 'rounded-xl', '2xl': 'rounded-2xl' } as const;
|
|
21
|
+
const FOCUS = { center: 'object-center', top: 'object-top', bottom: 'object-bottom', left: 'object-left', right: 'object-right' } as const;
|
|
22
|
+
---
|
|
23
|
+
<div class:list={['relative overflow-hidden bg-base-200', ASPECT[aspect], ROUNDED[rounded], className]}>
|
|
24
|
+
<img
|
|
25
|
+
src={image.src}
|
|
26
|
+
srcset={image.srcset}
|
|
27
|
+
sizes={image.sizes}
|
|
28
|
+
alt={image.alt}
|
|
29
|
+
width={image.width}
|
|
30
|
+
height={image.height}
|
|
31
|
+
loading={eager ? 'eager' : 'lazy'}
|
|
32
|
+
decoding="async"
|
|
33
|
+
fetchpriority={eager ? 'high' : undefined}
|
|
34
|
+
class:list={['absolute inset-0 h-full w-full object-cover', FOCUS[focus], imgClass]}
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
@@ -26,7 +26,7 @@ const cols = (Math.min(Math.max(tiers.length, 1), 4) as 1 | 2 | 3 | 4);
|
|
|
26
26
|
)}
|
|
27
27
|
{tier.description && <p class="opacity-80">{tier.description}</p>}
|
|
28
28
|
<ul class="my-4 space-y-2 text-sm">
|
|
29
|
-
{tier.features.map((f) => <li class="flex items-start gap-2"><HWioIcon name="check" size="sm" class="mt-0.5 shrink-0
|
|
29
|
+
{tier.features.map((f) => <li class="flex items-start gap-2"><HWioIcon name="check" size="sm" class="hwio-icon mt-0.5 shrink-0" /><span>{f}</span></li>)}
|
|
30
30
|
</ul>
|
|
31
31
|
{tier.cta && <div class="card-actions mt-auto"><HWioButton href={tier.cta.href} external={tier.cta.external} variant={tier.featured ? 'primary' : 'secondary'} class="w-full" track={tier.cta.track}>{tier.cta.label}</HWioButton></div>}
|
|
32
32
|
</div>
|
|
@@ -8,7 +8,7 @@ const LAYOUT = { horizontal: 'grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols
|
|
|
8
8
|
<ol class:list={[LAYOUT[orientation], className]} data-hwio-steps>
|
|
9
9
|
{items.map((step, i) => (
|
|
10
10
|
<li class="flex gap-4">
|
|
11
|
-
<span class="badge badge-primary badge-lg shrink-0
|
|
11
|
+
<span class="badge badge-primary badge-lg hwio-weight-label shrink-0 tabular-nums" aria-hidden="true">{step.number ?? i + 1}</span>
|
|
12
12
|
<div>
|
|
13
13
|
<h3 class="text-lg font-semibold"><span class="sr-only">{step.number ?? i + 1}. </span>{step.title}</h3>
|
|
14
14
|
<p class="mt-1 opacity-80">{step.text}</p>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* Starts the scroll reveal on the page (@hubpav/hwio-web-runtime/reveal). Render it once, in the layout
|
|
4
|
+
* of pages that mark content with `data-hwio-reveal` (HWioSection `reveal`, HWioApplicationTile
|
|
5
|
+
* `reveal`, a site's own markup). Renders nothing.
|
|
6
|
+
*
|
|
7
|
+
* Fail-safe: content waiting for its reveal hides only after this runtime has started; without it the
|
|
8
|
+
* content simply shows. Each element fades in and settles once, the first time it enters the viewport;
|
|
9
|
+
* `data-hwio-reveal-delay="<ms>"` staggers siblings. Under prefers-reduced-motion everything shows at once.
|
|
10
|
+
*/
|
|
11
|
+
---
|
|
12
|
+
<script>
|
|
13
|
+
import { hwioRevealRuntime } from '@hubpav/hwio-web-runtime/reveal';
|
|
14
|
+
hwioRevealRuntime();
|
|
15
|
+
</script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
/** Section with the system rhythm, tone and container. `reveal` fades it in once in view; the reveal runs only with HWioReveal on the page (fail-safe: without it the section simply shows). */
|
|
2
3
|
import type { HWioTone } from '../types';
|
|
3
4
|
interface Props { id?: string; tone?: HWioTone; spacing?: 'normal' | 'compact' | 'none'; container?: boolean; as?: 'section' | 'div' | 'article'; reveal?: boolean; class?: string; [key: string]: unknown }
|
|
4
5
|
const TONE = { base: 'bg-base-100 text-base-content hwio-tone-base', alt: 'bg-base-200 text-base-content hwio-tone-alt', neutral: 'bg-neutral text-neutral-content hwio-tone-neutral' } as const;
|
|
@@ -11,10 +11,10 @@ const cols = COLS[(Math.min(Math.max(items.length, 2), 5) as 2 | 3 | 4 | 5)];
|
|
|
11
11
|
const numeric = typeof s.value === 'number';
|
|
12
12
|
return (
|
|
13
13
|
<div class:list={['px-8 py-2', i > 0 ? 'sm:border-l sm:border-base-300' : '']}>
|
|
14
|
-
<div class="mb-2.5
|
|
14
|
+
<div class="hwio-figure mb-2.5">
|
|
15
15
|
<span class="hwio-stat-value" data-hwio-counter={animate && numeric ? 'true' : undefined} data-target={numeric ? String(s.value) : undefined} data-suffix={s.suffix ?? ''}>{s.value}{s.suffix ?? ''}</span>
|
|
16
16
|
</div>
|
|
17
|
-
<div class="text-[15px]
|
|
17
|
+
<div class="hwio-weight-label text-[15px]">{s.label}</div>
|
|
18
18
|
{s.description && <div class="hwio-muted mt-0.5 text-sm">{s.description}</div>}
|
|
19
19
|
</div>
|
|
20
20
|
);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* Customer-story card: a field photograph under the guidelines' scrim (chapter 08), the customer as a
|
|
4
|
+
* caps kicker and what they built as the title, White type over the dark, calm bottom of the frame;
|
|
5
|
+
* the whole card links to the case study (its title underlines on hover and focus, the arrow nudges).
|
|
6
|
+
* Pass the photograph as `image`, or your own picture in the `media` slot. Logos stay out: the card
|
|
7
|
+
* names the customer in text (the kicker) only when consent or a published case study allows it.
|
|
8
|
+
*/
|
|
9
|
+
import type { HWioAspect, HWioMedia, HWioTrack } from '../types';
|
|
10
|
+
import HWioPhoto from './HWioPhoto.astro';
|
|
11
|
+
interface Props {
|
|
12
|
+
href: string;
|
|
13
|
+
kicker: string;
|
|
14
|
+
title: string;
|
|
15
|
+
/** The link line under the title ("Read the story"). */
|
|
16
|
+
linkLabel: string;
|
|
17
|
+
image?: HWioMedia;
|
|
18
|
+
aspect?: HWioAspect;
|
|
19
|
+
focus?: 'center' | 'top' | 'bottom' | 'left' | 'right';
|
|
20
|
+
headingLevel?: 'h2' | 'h3' | 'h4';
|
|
21
|
+
track?: HWioTrack;
|
|
22
|
+
eager?: boolean;
|
|
23
|
+
class?: string;
|
|
24
|
+
}
|
|
25
|
+
const { href, kicker, title, linkLabel, image, aspect = '4/5', focus = 'center', headingLevel = 'h3', track, eager = false, class: className = '' } = Astro.props;
|
|
26
|
+
const Heading = headingLevel;
|
|
27
|
+
---
|
|
28
|
+
<a href={href} class:list={['hwio-card-link group relative block overflow-hidden rounded-2xl text-white', className]} data-track={track?.id} data-track-location={track?.location}>
|
|
29
|
+
<slot name="media">
|
|
30
|
+
{image && <HWioPhoto image={image} aspect={aspect} focus={focus} rounded="2xl" eager={eager} imgClass="transition-transform duration-500 ease-out group-hover:scale-[1.02] motion-reduce:transition-none" />}
|
|
31
|
+
</slot>
|
|
32
|
+
<div class="hwio-scrim pointer-events-none absolute inset-0 rounded-2xl"></div>
|
|
33
|
+
<div class="absolute inset-x-0 bottom-0 p-6 lg:p-7">
|
|
34
|
+
<p class="hwio-kicker text-[var(--hwio-kicker-on-neutral,#d1d5db)]">{kicker}</p>
|
|
35
|
+
<Heading class="hwio-role-title hwio-card-title mt-2 text-white">{title}</Heading>
|
|
36
|
+
<p class="hwio-weight-label mt-3 text-[0.9375rem] text-white">{linkLabel}<span aria-hidden="true" class="hwio-arrow ml-1.5">→</span></p>
|
|
37
|
+
</div>
|
|
38
|
+
</a>
|
package/src/styles/prose.css
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
.hwio-prose ol { list-style: decimal; padding-left: calc(var(--spacing) * 6); margin-bottom: calc(var(--spacing) * 4); }
|
|
10
10
|
.hwio-prose li { padding-left: calc(var(--spacing) * 1); margin-bottom: calc(var(--spacing) * 2); }
|
|
11
11
|
.hwio-prose a { color: var(--hwio-link, var(--color-secondary)); text-decoration: underline; text-underline-offset: 0.2em; }
|
|
12
|
-
.hwio-prose a:hover { color: var(--color-primary); }
|
|
13
|
-
.hwio-prose strong { font-weight: 600; }
|
|
12
|
+
.hwio-prose a:hover { color: var(--hwio-link-hover, var(--color-primary)); }
|
|
13
|
+
.hwio-prose strong { font-weight: var(--hwio-weight-strong, 600); }
|
|
14
14
|
.hwio-prose blockquote { border-left: 4px solid var(--color-secondary); padding-left: calc(var(--spacing) * 4); font-style: italic; margin-block: calc(var(--spacing) * 6); }
|
|
15
15
|
.hwio-prose code { background: var(--color-base-200); padding: 0.125em 0.375em; border-radius: var(--radius-field); font-size: 0.9em; }
|
|
16
16
|
.hwio-prose pre { background: var(--color-neutral); color: var(--color-neutral-content); padding: calc(var(--spacing) * 4); border-radius: var(--radius-box); overflow-x: auto; margin-block: calc(var(--spacing) * 6); }
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
.hwio-prose hr { border-color: var(--color-base-300); margin-block: calc(var(--spacing) * 8); }
|
|
19
19
|
.hwio-prose img { border-radius: var(--radius-box); margin-block: calc(var(--spacing) * 6); margin-inline: auto; max-width: 100%; }
|
|
20
20
|
.hwio-prose table { width: 100%; border-collapse: collapse; margin-block: calc(var(--spacing) * 6); }
|
|
21
|
-
.hwio-prose th { background: var(--color-base-200); border: 1px solid var(--color-base-300); padding: calc(var(--spacing) * 2) calc(var(--spacing) * 4); text-align: left; font-weight: 600; }
|
|
21
|
+
.hwio-prose th { background: var(--color-base-200); border: 1px solid var(--color-base-300); padding: calc(var(--spacing) * 2) calc(var(--spacing) * 4); text-align: left; font-weight: var(--hwio-weight-label, 600); }
|
|
22
22
|
.hwio-prose td { border: 1px solid var(--color-base-300); padding: calc(var(--spacing) * 2) calc(var(--spacing) * 4); }
|
|
23
23
|
.hwio-prose-lg { font-size: var(--text-lg); }
|
|
24
24
|
}
|
package/src/styles/styles.css
CHANGED
|
@@ -57,30 +57,25 @@
|
|
|
57
57
|
overflow-x: hidden;
|
|
58
58
|
background-color: var(--color-base-100);
|
|
59
59
|
color: var(--color-base-content);
|
|
60
|
-
font-size: 1.0625rem;
|
|
61
|
-
line-height: 1.6;
|
|
60
|
+
font-size: var(--hwio-type-body-size, 1.0625rem);
|
|
61
|
+
line-height: var(--hwio-type-body-leading, 1.6);
|
|
62
62
|
}
|
|
63
63
|
button:not(:disabled),
|
|
64
64
|
[role='button']:not(:disabled) {
|
|
65
65
|
cursor: pointer;
|
|
66
66
|
}
|
|
67
|
-
/* Type ramp
|
|
67
|
+
/* Type ramp from the theme's type preset (--hwio-type-<role>-*, generated from brand.json with
|
|
68
|
+
the responsive steps as media queries). HARDWARIO themes: the Brand Guidelines' web scale
|
|
69
|
+
(H1 60-72 px Bold, H2 40-48 px and H3 28-32 px Semibold, line heights 1.2 / 1.3 / 1.4 at
|
|
70
|
+
least). er3o keeps direction A. The fallbacks are direction A's phone values. */
|
|
68
71
|
h1, h2, h3, h4, h5, h6 {
|
|
69
|
-
font-weight: 700;
|
|
72
|
+
font-weight: var(--hwio-type-title-weight, 700);
|
|
70
73
|
text-wrap: balance;
|
|
71
74
|
}
|
|
72
|
-
h1 { font-size: 2.5rem; line-height: 1.05; letter-spacing: -0.03em; }
|
|
73
|
-
h2 { font-size: 2rem; line-height: 1.1; letter-spacing: -0.025em; }
|
|
74
|
-
h3 { font-size: 1.375rem; line-height: 1.2; letter-spacing: -0.01em; }
|
|
75
|
-
h4 { font-size: 1.125rem; line-height: 1.3; letter-spacing: -0.005em; }
|
|
76
|
-
@media (width >= 48rem) {
|
|
77
|
-
h1 { font-size: 3rem; }
|
|
78
|
-
h2 { font-size: 2.5rem; }
|
|
79
|
-
h3 { font-size: 1.375rem; }
|
|
80
|
-
}
|
|
81
|
-
@media (width >= 64rem) {
|
|
82
|
-
h1 { font-size: 3.5rem; }
|
|
83
|
-
}
|
|
75
|
+
h1 { font-size: var(--hwio-type-display-size, 2.5rem); font-weight: var(--hwio-type-display-weight, 700); line-height: var(--hwio-type-display-leading, 1.05); letter-spacing: var(--hwio-type-display-tracking, -0.03em); }
|
|
76
|
+
h2 { font-size: var(--hwio-type-heading-size, 2rem); font-weight: var(--hwio-type-heading-weight, 700); line-height: var(--hwio-type-heading-leading, 1.1); letter-spacing: var(--hwio-type-heading-tracking, -0.025em); }
|
|
77
|
+
h3 { font-size: var(--hwio-type-subheading-size, 1.375rem); font-weight: var(--hwio-type-subheading-weight, 700); line-height: var(--hwio-type-subheading-leading, 1.2); letter-spacing: var(--hwio-type-subheading-tracking, -0.01em); }
|
|
78
|
+
h4 { font-size: var(--hwio-type-title-size, 1.125rem); line-height: var(--hwio-type-title-leading, 1.3); letter-spacing: var(--hwio-type-title-tracking, -0.005em); }
|
|
84
79
|
/* Phones: a heading word wider than its column (a 40 px H1 gets 218-288 px) hyphenates instead
|
|
85
80
|
of running past the screen, and a token longer than the line (a URL, an ID) breaks. */
|
|
86
81
|
@media (width < 40rem) {
|
|
@@ -143,30 +138,89 @@
|
|
|
143
138
|
background: var(--hwio-nav-active, var(--color-primary));
|
|
144
139
|
}
|
|
145
140
|
|
|
141
|
+
/* Kicker: Red caps over a title on the HARDWARIO themes (Brand Guidelines chapter 04 and 05);
|
|
142
|
+
sentence case on er3o. On Ink (neutral panels, and the dark theme's surfaces) it takes the
|
|
143
|
+
light gray, as the guidelines' dark-mode example sets the caps label on an Ink card. */
|
|
146
144
|
.hwio-kicker,
|
|
147
145
|
.hwio-eyebrow {
|
|
148
146
|
color: var(--color-accent);
|
|
149
|
-
font-size: 0.875rem;
|
|
150
|
-
font-weight: 600;
|
|
151
|
-
line-height: 1.4;
|
|
147
|
+
font-size: var(--hwio-type-kicker-size, 0.875rem);
|
|
148
|
+
font-weight: var(--hwio-type-kicker-weight, 600);
|
|
149
|
+
line-height: var(--hwio-type-kicker-leading, 1.4);
|
|
150
|
+
letter-spacing: var(--hwio-type-kicker-tracking, 0);
|
|
151
|
+
text-transform: var(--hwio-type-kicker-case, none);
|
|
152
|
+
}
|
|
153
|
+
.hwio-tone-alt .hwio-kicker,
|
|
154
|
+
.hwio-tone-alt .hwio-eyebrow {
|
|
155
|
+
color: var(--hwio-kicker-on-alt, var(--color-accent));
|
|
152
156
|
}
|
|
153
157
|
.hwio-tone-neutral .hwio-kicker,
|
|
154
158
|
.hwio-tone-neutral .hwio-eyebrow {
|
|
155
159
|
color: var(--hwio-kicker-on-neutral, var(--color-accent));
|
|
156
160
|
}
|
|
161
|
+
/* Secondary text: Gray on light grounds, the light gray on dark ones (chapter 03, D35). */
|
|
157
162
|
.hwio-muted {
|
|
158
|
-
color: color-mix(in oklab, var(--color-base-content) 72%, transparent);
|
|
163
|
+
color: var(--hwio-text-secondary, color-mix(in oklab, var(--color-base-content) 72%, transparent));
|
|
159
164
|
}
|
|
160
165
|
.hwio-tone-neutral .hwio-muted {
|
|
161
|
-
color: color-mix(in oklab, var(--color-neutral-content) 75%, transparent);
|
|
166
|
+
color: var(--hwio-text-secondary-on-neutral, color-mix(in oklab, var(--color-neutral-content) 75%, transparent));
|
|
162
167
|
}
|
|
163
168
|
.hwio-lead {
|
|
164
|
-
font-size: 1.1875rem;
|
|
165
|
-
line-height: 1.55;
|
|
166
|
-
color: color-mix(in oklab, var(--color-base-content) 72%, transparent);
|
|
169
|
+
font-size: var(--hwio-type-lead-size, 1.1875rem);
|
|
170
|
+
line-height: var(--hwio-type-lead-leading, 1.55);
|
|
171
|
+
color: var(--hwio-text-secondary, color-mix(in oklab, var(--color-base-content) 72%, transparent));
|
|
167
172
|
}
|
|
168
173
|
.hwio-tone-neutral .hwio-lead {
|
|
169
|
-
color: color-mix(in oklab, var(--color-neutral-content) 75%, transparent);
|
|
174
|
+
color: var(--hwio-text-secondary-on-neutral, color-mix(in oklab, var(--color-neutral-content) 75%, transparent));
|
|
175
|
+
}
|
|
176
|
+
/* Caption: 12-14 px Regular in Gray (chapter 04). */
|
|
177
|
+
.hwio-caption {
|
|
178
|
+
font-size: var(--hwio-type-caption-size, 0.875rem);
|
|
179
|
+
line-height: var(--hwio-type-caption-leading, 1.4);
|
|
180
|
+
color: var(--hwio-text-secondary, color-mix(in oklab, var(--color-base-content) 72%, transparent));
|
|
181
|
+
}
|
|
182
|
+
.hwio-tone-neutral .hwio-caption {
|
|
183
|
+
color: var(--hwio-text-secondary-on-neutral, color-mix(in oklab, var(--color-neutral-content) 75%, transparent));
|
|
184
|
+
}
|
|
185
|
+
/* Figures (stats): display type, so 1.2 line height at least on the HARDWARIO themes. */
|
|
186
|
+
.hwio-figure {
|
|
187
|
+
font-size: var(--hwio-type-figure-size, 2.25rem);
|
|
188
|
+
font-weight: var(--hwio-type-figure-weight, 700);
|
|
189
|
+
line-height: var(--hwio-type-figure-leading, 1);
|
|
190
|
+
letter-spacing: var(--hwio-type-figure-tracking, -0.03em);
|
|
191
|
+
}
|
|
192
|
+
/* The choice-card title: the H3 role on the HARDWARIO themes, direction A's 28 px on er3o. */
|
|
193
|
+
.hwio-choice-title {
|
|
194
|
+
font-size: var(--hwio-choice-title-size, 1.75rem);
|
|
195
|
+
line-height: var(--hwio-choice-title-leading, 1.15);
|
|
196
|
+
letter-spacing: var(--hwio-choice-title-tracking, -0.02em);
|
|
197
|
+
}
|
|
198
|
+
/* Icons: one colour, Navy (White on dark grounds) on the HARDWARIO themes (chapter 05). */
|
|
199
|
+
.hwio-icon {
|
|
200
|
+
color: var(--hwio-icon, var(--color-accent));
|
|
201
|
+
}
|
|
202
|
+
.hwio-icon-tile {
|
|
203
|
+
background-color: var(--hwio-icon-bg, color-mix(in oklab, var(--color-accent) 8%, transparent));
|
|
204
|
+
color: var(--hwio-icon, var(--color-accent));
|
|
205
|
+
}
|
|
206
|
+
/* Weights the guidelines allow: Regular, Semibold (web H2 and H3) and Bold, no Medium (D22). */
|
|
207
|
+
.hwio-weight-nav { font-weight: var(--hwio-weight-nav, 500); }
|
|
208
|
+
.hwio-weight-label { font-weight: var(--hwio-weight-label, 600); }
|
|
209
|
+
.hwio-weight-footer-title { font-weight: var(--hwio-weight-footer-title, 500); }
|
|
210
|
+
/* Secondary notes (consent texts): Gray at full opacity on the HARDWARIO themes, so a link inside
|
|
211
|
+
keeps its contrast; er3o keeps the text colour at 80 % opacity. */
|
|
212
|
+
.hwio-note {
|
|
213
|
+
color: var(--hwio-text-secondary, currentColor);
|
|
214
|
+
opacity: var(--hwio-note-opacity, 0.8);
|
|
215
|
+
}
|
|
216
|
+
/* An inline text link outside prose: Blue on the HARDWARIO themes (chapter 03 reserves Blue for links). */
|
|
217
|
+
.hwio-link {
|
|
218
|
+
color: var(--hwio-link, var(--color-accent));
|
|
219
|
+
}
|
|
220
|
+
@media (hover: hover) {
|
|
221
|
+
.hwio-link:hover {
|
|
222
|
+
color: var(--hwio-link-hover, color-mix(in oklab, var(--hwio-link, var(--color-accent)) 80%, #000));
|
|
223
|
+
}
|
|
170
224
|
}
|
|
171
225
|
.hwio-hairline { border-color: var(--color-base-300); }
|
|
172
226
|
/* Inverse button for ink/neutral panels (navy on ink has no contrast). */
|
|
@@ -186,8 +240,10 @@
|
|
|
186
240
|
padding: calc(var(--spacing) * 1.5) calc(var(--spacing) * 3);
|
|
187
241
|
border-radius: 9999px;
|
|
188
242
|
background: color-mix(in oklab, var(--color-base-content) 6%, transparent);
|
|
189
|
-
font-size: var(--text-sm);
|
|
190
|
-
font-weight: 500;
|
|
243
|
+
font-size: var(--hwio-type-chip-size, var(--text-sm));
|
|
244
|
+
font-weight: var(--hwio-type-chip-weight, 500);
|
|
245
|
+
letter-spacing: var(--hwio-type-chip-tracking, 0);
|
|
246
|
+
text-transform: var(--hwio-type-chip-case, none);
|
|
191
247
|
}
|
|
192
248
|
/* Honeypot: off-screen, never display:none (bots check that), no inline style attribute. */
|
|
193
249
|
.hwio-hp {
|
|
@@ -206,17 +262,49 @@
|
|
|
206
262
|
[data-hs-status].hs-status-success { color: var(--color-success); }
|
|
207
263
|
[data-hs-status].hs-status-error { color: var(--color-error); }
|
|
208
264
|
|
|
209
|
-
/* Scroll reveal:
|
|
210
|
-
|
|
265
|
+
/* Scroll reveal, fail-safe (owner, 2026-10-30): content waiting for its reveal hides only once the
|
|
266
|
+
reveal runtime has started (html.hwio-reveal-on, set by @hubpav/hwio-web-runtime/reveal). Without
|
|
267
|
+
JavaScript, before the runtime runs, or if it never loads, everything shows. Hiding is instant;
|
|
268
|
+
revealing fades in and settles once (web layer: ease-out, 400 ms at most, 24 px travel). A page
|
|
269
|
+
can calm it with --hwio-reveal-duration and --hwio-reveal-travel. Stagger siblings with
|
|
270
|
+
data-hwio-reveal-delay="<ms>" (the runtime applies it). */
|
|
271
|
+
html.hwio-reveal-on [data-hwio-reveal]:not([data-hwio-revealed]) {
|
|
211
272
|
opacity: 0;
|
|
212
|
-
transform: translateY(24px);
|
|
213
|
-
}
|
|
214
|
-
[data-hwio-reveal] {
|
|
215
|
-
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
|
|
273
|
+
transform: translateY(var(--hwio-reveal-travel, 24px));
|
|
216
274
|
}
|
|
217
275
|
[data-hwio-reveal][data-hwio-revealed] {
|
|
218
276
|
opacity: 1;
|
|
219
277
|
transform: none;
|
|
278
|
+
transition:
|
|
279
|
+
opacity var(--hwio-reveal-duration, var(--hwio-motion-reveal, 0.6s)) var(--hwio-motion-easing, ease-out),
|
|
280
|
+
transform var(--hwio-reveal-duration, var(--hwio-motion-reveal, 0.6s)) var(--hwio-motion-easing, ease-out);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Entrance of a hero once the font gate has shown the page: the children of .hwio-enter fade in and
|
|
284
|
+
settle 12 px, 60 ms apart; .hwio-enter-media follows. Pure CSS that always ends visible, and it
|
|
285
|
+
runs only after the gate has set .fonts-ready (no gate, no animation). */
|
|
286
|
+
@keyframes hwio-enter {
|
|
287
|
+
from { opacity: 0; transform: translateY(12px); }
|
|
288
|
+
to { opacity: 1; transform: none; }
|
|
289
|
+
}
|
|
290
|
+
.fonts-ready .hwio-enter > * {
|
|
291
|
+
animation: hwio-enter var(--hwio-motion-base, 300ms) var(--hwio-motion-easing, ease-out) both;
|
|
292
|
+
}
|
|
293
|
+
.fonts-ready .hwio-enter > :nth-child(2) { animation-delay: 60ms; }
|
|
294
|
+
.fonts-ready .hwio-enter > :nth-child(3) { animation-delay: 120ms; }
|
|
295
|
+
.fonts-ready .hwio-enter > :nth-child(n + 4) { animation-delay: 180ms; }
|
|
296
|
+
.fonts-ready .hwio-enter-media {
|
|
297
|
+
animation: hwio-enter var(--hwio-motion-base, 300ms) var(--hwio-motion-easing, ease-out) 120ms both;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* The arrow of a call to action moves 3 px on hover and keyboard focus (HWioButton's arrow carries
|
|
301
|
+
it; a site marks its own arrow glyph with .hwio-arrow). */
|
|
302
|
+
.hwio-arrow {
|
|
303
|
+
display: inline-block;
|
|
304
|
+
transition: transform var(--hwio-motion-fast, 200ms) var(--hwio-motion-easing, ease-out);
|
|
305
|
+
}
|
|
306
|
+
:is(a, button):is(:hover, :focus-visible) .hwio-arrow {
|
|
307
|
+
transform: translateX(3px);
|
|
220
308
|
}
|
|
221
309
|
|
|
222
310
|
/* Count-up: reserve the width of the final value so the layout never jumps. */
|
|
@@ -255,19 +343,171 @@
|
|
|
255
343
|
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease !important;
|
|
256
344
|
}
|
|
257
345
|
|
|
346
|
+
/* Type roles for elements whose tag is not the role's tag (a card title in an <h3>, a <p> set as H2). */
|
|
347
|
+
.hwio-role-heading {
|
|
348
|
+
font-size: var(--hwio-type-heading-size, 2rem);
|
|
349
|
+
font-weight: var(--hwio-type-heading-weight, 700);
|
|
350
|
+
line-height: var(--hwio-type-heading-leading, 1.1);
|
|
351
|
+
letter-spacing: var(--hwio-type-heading-tracking, -0.025em);
|
|
352
|
+
}
|
|
353
|
+
.hwio-role-subheading {
|
|
354
|
+
font-size: var(--hwio-type-subheading-size, 1.375rem);
|
|
355
|
+
font-weight: var(--hwio-type-subheading-weight, 700);
|
|
356
|
+
line-height: var(--hwio-type-subheading-leading, 1.2);
|
|
357
|
+
letter-spacing: var(--hwio-type-subheading-tracking, -0.01em);
|
|
358
|
+
}
|
|
359
|
+
.hwio-role-title {
|
|
360
|
+
font-size: var(--hwio-type-title-size, 1.125rem);
|
|
361
|
+
font-weight: var(--hwio-type-title-weight, 700);
|
|
362
|
+
line-height: var(--hwio-type-title-leading, 1.3);
|
|
363
|
+
letter-spacing: var(--hwio-type-title-tracking, -0.005em);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* A long H1 (more than about eight words, an opening statement) at 36 / 44 / 48 / 52 px instead of
|
|
367
|
+
the web scale's 40 / 48 / 60 / 72 px, so it reads in three calm lines beside the hero media.
|
|
368
|
+
CHANGE REQUEST CR-7 (owner, 2026-10-30), pending the Brand Guidelines: "a long H1 may go down
|
|
369
|
+
to 48 to 56 px". Opt-in per heading; HWioHeroSplit sets it with titleSize="long". */
|
|
370
|
+
.hwio-h1-long {
|
|
371
|
+
font-size: 2.25rem;
|
|
372
|
+
line-height: var(--hwio-type-display-leading, 1.2);
|
|
373
|
+
letter-spacing: -0.02em;
|
|
374
|
+
}
|
|
375
|
+
@media (width >= 48rem) {
|
|
376
|
+
.hwio-h1-long { font-size: 2.75rem; }
|
|
377
|
+
}
|
|
378
|
+
@media (width >= 64rem) {
|
|
379
|
+
.hwio-h1-long { font-size: 3rem; }
|
|
380
|
+
}
|
|
381
|
+
@media (width >= 80rem) {
|
|
382
|
+
.hwio-h1-long { font-size: 3.25rem; }
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* The page's one gradient moment (Brand Guidelines chapter 03; D23, D33, D44): the figure gradient
|
|
386
|
+
fills the type of the key figure (.hwio-key-figure, 40 px and up) or, instead of a key figure,
|
|
387
|
+
of up to two key words of a hero H1 (.hwio-grad). The theme variable is the gradient's left three
|
|
388
|
+
quarters on white (4.5:1) and light red to Sky on the dark ground. Each word carries its own
|
|
389
|
+
gradient. .hwio-grad is CHANGE REQUEST CR-8 (owner, 2026-10-30), pending the guidelines. Themes
|
|
390
|
+
without the gradient (er3o) show plain text: the fill, not `color`, turns transparent, so the
|
|
391
|
+
fallback's currentColor is still the text colour. */
|
|
392
|
+
.hwio-key-figure,
|
|
393
|
+
.hwio-grad {
|
|
394
|
+
background-image: var(--hwio-gradient-figure, linear-gradient(currentColor, currentColor));
|
|
395
|
+
-webkit-background-clip: text;
|
|
396
|
+
background-clip: text;
|
|
397
|
+
-webkit-text-fill-color: transparent;
|
|
398
|
+
-webkit-box-decoration-break: clone;
|
|
399
|
+
box-decoration-break: clone;
|
|
400
|
+
}
|
|
401
|
+
@media (forced-colors: active) {
|
|
402
|
+
.hwio-key-figure,
|
|
403
|
+
.hwio-grad {
|
|
404
|
+
background-image: none;
|
|
405
|
+
-webkit-text-fill-color: CanvasText;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* Linked cards (web layer, States): the title underlines on hover and keyboard focus; no shadow. */
|
|
410
|
+
.hwio-card-link:is(:hover, :focus-visible) .hwio-card-title {
|
|
411
|
+
text-decoration: underline;
|
|
412
|
+
text-underline-offset: 0.18em;
|
|
413
|
+
text-decoration-thickness: 1px;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* White type over a photograph only on the guidelines' scrim (chapter 08): clear over the top
|
|
417
|
+
third, 45 % black at 60 %, 92 % at the bottom. */
|
|
418
|
+
.hwio-scrim {
|
|
419
|
+
background-image: linear-gradient(180deg, rgb(0 0 0 / 0) 33%, rgb(0 0 0 / 0.45) 60%, rgb(0 0 0 / 0.92) 100%);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/* Product cut-outs (owner, 2026-10-30; Brand Guidelines chapter 08): one shadow recipe for every
|
|
423
|
+
product, so a row reads as one family: a tight contact shadow plus a soft ambient one; lighter on
|
|
424
|
+
the dark ground. On a common baseline (HWioCutout baseline) a blurred floor ellipse. A cut-out
|
|
425
|
+
sits whole on the Panel ground (.hwio-cutout-ground) or on the page. */
|
|
426
|
+
.hwio-product-shadow {
|
|
427
|
+
filter: drop-shadow(0 2px 2px rgb(37 37 50 / 0.16)) drop-shadow(0 12px 16px rgb(37 37 50 / 0.12));
|
|
428
|
+
}
|
|
429
|
+
[data-theme$='-dark'] .hwio-product-shadow {
|
|
430
|
+
filter: drop-shadow(0 6px 12px rgb(0 0 0 / 0.35));
|
|
431
|
+
}
|
|
432
|
+
.hwio-product-floor {
|
|
433
|
+
position: absolute;
|
|
434
|
+
left: 20%;
|
|
435
|
+
right: 20%;
|
|
436
|
+
height: 7%;
|
|
437
|
+
border-radius: 50%;
|
|
438
|
+
background: radial-gradient(closest-side, rgb(37 37 50 / 0.18), rgb(37 37 50 / 0));
|
|
439
|
+
pointer-events: none;
|
|
440
|
+
}
|
|
441
|
+
[data-theme$='-dark'] .hwio-product-floor {
|
|
442
|
+
display: none;
|
|
443
|
+
}
|
|
444
|
+
.hwio-cutout-ground {
|
|
445
|
+
background-color: var(--color-base-200);
|
|
446
|
+
}
|
|
447
|
+
/* A drawn isometric room behind a cut-out (HWioCutout backdrop): it fills the frame (the kit's SVG
|
|
448
|
+
carries a 1 pt margin, hidden by the slight scale); the dark-theme drawing on the dark ground. */
|
|
449
|
+
.hwio-backdrop {
|
|
450
|
+
position: absolute;
|
|
451
|
+
inset: 0;
|
|
452
|
+
width: 100%;
|
|
453
|
+
height: 100%;
|
|
454
|
+
object-fit: cover;
|
|
455
|
+
transform: scale(1.012);
|
|
456
|
+
pointer-events: none;
|
|
457
|
+
}
|
|
458
|
+
.hwio-backdrop-dark { display: none; }
|
|
459
|
+
[data-theme$='-dark'] .hwio-backdrop-light { display: none; }
|
|
460
|
+
[data-theme$='-dark'] .hwio-backdrop-dark { display: block; }
|
|
461
|
+
|
|
462
|
+
/* Menu panels (HWioMegaLinks) and the drawer's second lines (owner, 2026-10-30): a caps group title
|
|
463
|
+
in Gray, link labels that never wrap, descriptions small (13 px), Regular, Gray and balanced. */
|
|
464
|
+
.hwio-mega-title {
|
|
465
|
+
color: var(--hwio-text-secondary, color-mix(in oklab, var(--color-base-content) 72%, transparent));
|
|
466
|
+
font-size: var(--hwio-type-kicker-size, 0.875rem);
|
|
467
|
+
font-weight: var(--hwio-type-kicker-weight, 600);
|
|
468
|
+
line-height: var(--hwio-type-kicker-leading, 1.4);
|
|
469
|
+
letter-spacing: var(--hwio-type-kicker-tracking, 0);
|
|
470
|
+
text-transform: var(--hwio-type-kicker-case, none);
|
|
471
|
+
}
|
|
472
|
+
.hwio-mega-label {
|
|
473
|
+
display: inline-flex;
|
|
474
|
+
align-items: center;
|
|
475
|
+
gap: 0.375rem;
|
|
476
|
+
white-space: nowrap;
|
|
477
|
+
color: var(--color-base-content);
|
|
478
|
+
font-size: 0.9375rem;
|
|
479
|
+
font-weight: var(--hwio-weight-label, 600);
|
|
480
|
+
line-height: 1.35;
|
|
481
|
+
transition: color var(--hwio-motion-fast, 200ms) var(--hwio-motion-easing, ease-out);
|
|
482
|
+
}
|
|
483
|
+
a:is(:hover, :focus-visible) .hwio-mega-label {
|
|
484
|
+
color: var(--hwio-nav-hover, var(--color-primary));
|
|
485
|
+
}
|
|
486
|
+
.hwio-menu-desc {
|
|
487
|
+
color: var(--hwio-text-secondary, color-mix(in oklab, var(--color-base-content) 72%, transparent));
|
|
488
|
+
font-size: 0.8125rem;
|
|
489
|
+
font-weight: 400;
|
|
490
|
+
line-height: 1.45;
|
|
491
|
+
text-wrap: balance;
|
|
492
|
+
}
|
|
493
|
+
|
|
258
494
|
@media (prefers-reduced-motion: reduce) {
|
|
259
495
|
[data-hwio-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
|
|
260
496
|
.hwio-marquee-track { animation: none; transform: none; will-change: auto; }
|
|
261
497
|
.hwio-marquee-track > [aria-hidden='true'] { display: none; }
|
|
498
|
+
.fonts-ready .hwio-enter > *,
|
|
499
|
+
.fonts-ready .hwio-enter-media { animation: none; }
|
|
500
|
+
.hwio-arrow,
|
|
501
|
+
:is(a, button):is(:hover, :focus-visible) .hwio-arrow { transition: none; transform: none; }
|
|
262
502
|
}
|
|
263
503
|
}
|
|
264
504
|
|
|
265
505
|
/* Brand overrides of DaisyUI defaults. Unlayered on purpose: DaisyUI lives in the utilities layer
|
|
266
|
-
and would otherwise win.
|
|
267
|
-
28 px padding on large buttons at the same height; card padding 32 px. */
|
|
506
|
+
and would otherwise win. 15 px sentence-case buttons (Bold on the HARDWARIO themes, 600 on er3o),
|
|
507
|
+
48 px tall, 8 px radius, 28 px padding on large buttons at the same height; card padding 32 px. */
|
|
268
508
|
.btn {
|
|
269
|
-
--fontsize: 0.9375rem;
|
|
270
|
-
font-weight: 600;
|
|
509
|
+
--fontsize: var(--hwio-type-button-size, 0.9375rem);
|
|
510
|
+
font-weight: var(--hwio-type-button-weight, 600);
|
|
271
511
|
padding-inline: 1.5rem;
|
|
272
512
|
}
|
|
273
513
|
.btn-sm { --fontsize: 0.875rem; padding-inline: 1rem; }
|
|
@@ -277,6 +517,12 @@
|
|
|
277
517
|
/* DaisyUI sets .label to 60 % of the text colour, which fails AA at 14 px (4.1:1 on white). R5:
|
|
278
518
|
darken muted text only. 78 % keeps the label visibly secondary and clears 4.5:1 on every theme. */
|
|
279
519
|
.label { color: color-mix(in oklab, currentColor 78%, transparent); }
|
|
520
|
+
/* Table heads: DaisyUI sets 60 % of the text colour (4.1:1 on white at 14 px) in Semibold; on the
|
|
521
|
+
HARDWARIO themes secondary text (Gray, 5.3:1) in Bold (D22), unchanged on er3o. */
|
|
522
|
+
.table :where(thead, tfoot) {
|
|
523
|
+
color: var(--hwio-text-secondary, color-mix(in oklab, var(--color-base-content) 60%, transparent));
|
|
524
|
+
font-weight: var(--hwio-weight-label, 600);
|
|
525
|
+
}
|
|
280
526
|
/* Same for inactive tabs (DaisyUI: 50 %, 3.1:1 on white at 14 px). */
|
|
281
527
|
.tab:not(.tab-active, :hover, :focus-visible) { color: color-mix(in oklab, currentColor 78%, transparent); }
|
|
282
528
|
/* Text links: themes whose primary is too light for text on the page ground (er3o teal) set
|
|
@@ -309,6 +555,35 @@
|
|
|
309
555
|
.hwio-nav-tight > .hwio-nav-current::after {
|
|
310
556
|
inset-inline: 0.5rem;
|
|
311
557
|
}
|
|
558
|
+
header:has(.hwio-nav-tight) .hwio-utility > summary.btn {
|
|
559
|
+
--fontsize: 14px;
|
|
560
|
+
font-size: 14px;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/* Header utilities (owner, 2026-10-30): HWioHeader's theme toggle and language dropdown read as quiet
|
|
564
|
+
utilities beside the nav, not as buttons: the nav's weight (Regular on the HARDWARIO themes), size
|
|
565
|
+
and 80 % ink, the nav's hover colour, the toggle's icon at 18 px (HWioIcon's 1.5 stroke), the
|
|
566
|
+
chevron as faint as the nav chevrons. Unlayered, because DaisyUI's .btn sits in the utilities layer. */
|
|
567
|
+
.hwio-utility.btn,
|
|
568
|
+
.hwio-utility > summary.btn {
|
|
569
|
+
--fontsize: 0.9375rem;
|
|
570
|
+
font-size: 0.9375rem;
|
|
571
|
+
font-weight: var(--hwio-weight-nav, 500);
|
|
572
|
+
letter-spacing: 0;
|
|
573
|
+
color: color-mix(in oklab, var(--color-base-content) 80%, transparent);
|
|
574
|
+
border-color: transparent;
|
|
575
|
+
box-shadow: none;
|
|
576
|
+
}
|
|
577
|
+
.hwio-utility.btn:hover,
|
|
578
|
+
.hwio-utility > summary.btn:hover {
|
|
579
|
+
color: var(--hwio-nav-hover, var(--color-accent));
|
|
580
|
+
}
|
|
581
|
+
.hwio-utility.btn > svg {
|
|
582
|
+
width: 1.125rem;
|
|
583
|
+
height: 1.125rem;
|
|
584
|
+
}
|
|
585
|
+
.hwio-utility > summary.btn > svg:last-child {
|
|
586
|
+
opacity: 0.5;
|
|
312
587
|
}
|
|
313
588
|
/* DaisyUI 5.7.30+ also gives pressed buttons (aria-pressed / aria-checked) a filled ground. A ghost
|
|
314
589
|
toggle shows its state in its own content (HWioThemeToggle swaps moon and sun and sets
|
|
@@ -318,3 +593,16 @@
|
|
|
318
593
|
--btn-bg: #0000;
|
|
319
594
|
--btn-border: #0000;
|
|
320
595
|
}
|
|
596
|
+
/* Forms on the brand type scale (owner, 2026-11-01; website-admin DESIGN-SYSTEM.md, web layer type table: "Form
|
|
597
|
+
label 15 Bold", "Form field text 16 Regular"). DaisyUI's 12 px Semibold field labels and 14 px fields sat below
|
|
598
|
+
the body text, and iPhones zoom into a focused field whose text is under 16 px. Unlayered, so it wins over
|
|
599
|
+
DaisyUI's component layer. */
|
|
600
|
+
.fieldset-legend {
|
|
601
|
+
font-size: 0.9375rem;
|
|
602
|
+
font-weight: var(--hwio-weight-label, 700);
|
|
603
|
+
}
|
|
604
|
+
.input,
|
|
605
|
+
.select,
|
|
606
|
+
.textarea {
|
|
607
|
+
font-size: 1rem;
|
|
608
|
+
}
|