@hraness/design-kit 0.36.1 → 0.36.3
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 +17 -3
- package/dist/{chunk-v8byd3hw.js → chunk-0s71p361.js} +9 -2
- package/dist/mockups/client.js +46 -4
- package/dist/react/index.js +29 -5
- package/dist/react/server.js +1 -1
- package/dist/stylex-manifest.json +1 -1
- package/dist/stylex.css +8 -4
- package/package.json +1 -1
- package/portfolio-inventory.json +1 -1
- package/src/mockups/client.tsx +45 -5
- package/src/mockups.css +8 -6
- package/src/plain-publication.css +5 -2
- package/src/product-marketing.css +5 -2
- package/src/react/design-gallery.tsx +4 -3
- package/src/react/product-marketing.stylex.ts +9 -2
- package/src/typography.css +11 -7
package/dist/stylex.css
CHANGED
|
@@ -2203,6 +2203,14 @@
|
|
|
2203
2203
|
filter: saturate(1.08);
|
|
2204
2204
|
}
|
|
2205
2205
|
|
|
2206
|
+
.x1kfky9y {
|
|
2207
|
+
flex-basis: 10rem;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
.x1vhnul8 {
|
|
2211
|
+
flex-basis: 3.5rem;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2206
2214
|
.xdl72j9 {
|
|
2207
2215
|
flex-basis: auto;
|
|
2208
2216
|
}
|
|
@@ -2535,10 +2543,6 @@
|
|
|
2535
2543
|
grid-template-columns: 2.25rem minmax(0, 1fr);
|
|
2536
2544
|
}
|
|
2537
2545
|
|
|
2538
|
-
.xrdwe0 {
|
|
2539
|
-
grid-template-columns: 3.5rem minmax(0, 1fr);
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2542
2546
|
.xx9t13c {
|
|
2543
2547
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
2544
2548
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hraness/design-kit",
|
|
3
|
-
"version": "0.36.
|
|
3
|
+
"version": "0.36.3",
|
|
4
4
|
"description": "React components and CSS for Hraness apps and product sites: application shells, marketing sections, charts, themes, effects, and syntax highlighting. Built on @hraness/ui.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/portfolio-inventory.json
CHANGED
package/src/mockups/client.tsx
CHANGED
|
@@ -93,7 +93,7 @@ export function FitToWidth({ children, className, minWidth = 400 }: Readonly<{ c
|
|
|
93
93
|
|
|
94
94
|
const scaled = fit !== null && fit.scale < 1;
|
|
95
95
|
return (
|
|
96
|
-
<div className={joinMockupClasses("hkm-fit", className)} ref={outer} style={scaled ? { height: fit.height } : undefined}>
|
|
96
|
+
<div className={joinMockupClasses("hkm-fit", className)} data-hkm-min-width={minWidth} ref={outer} style={scaled ? { height: fit.height } : undefined}>
|
|
97
97
|
<div
|
|
98
98
|
className="hkm-fit-inner"
|
|
99
99
|
data-hkm-scaled={scaled ? "" : undefined}
|
|
@@ -350,10 +350,48 @@ export type ThroughStep = Readonly<{
|
|
|
350
350
|
render: (state: Readonly<{ animated: boolean; theme: MockupTheme | undefined }>) => ReactNode;
|
|
351
351
|
}>;
|
|
352
352
|
|
|
353
|
+
/** Fill owns the outer shell and its top-level frames, never nested width-fit graphics. */
|
|
354
|
+
function fillFrames(stage: HTMLElement): HTMLElement[] {
|
|
355
|
+
const frames: HTMLElement[] = [];
|
|
356
|
+
for (const panel of stage.querySelectorAll<HTMLElement>(":scope > .hkm-step-panel, :scope > .hkm-mode-surface")) {
|
|
357
|
+
const fit = panel.querySelector<HTMLElement>(":scope > .hkm-fit");
|
|
358
|
+
if (fit === null) continue;
|
|
359
|
+
for (const root of fit.querySelectorAll<HTMLElement>(".hkm-root")) {
|
|
360
|
+
const enclosingRoot = root.parentElement?.closest(".hkm-root");
|
|
361
|
+
if (root.closest(".hkm-fit") === fit && (enclosingRoot === null || enclosingRoot === undefined || !fit.contains(enclosingRoot))) frames.push(root);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return frames;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function presentationBodies(stage: HTMLElement): HTMLElement[] {
|
|
368
|
+
return fillFrames(stage).flatMap((frame) => [...frame.querySelectorAll<HTMLElement>(':scope > .hkm-window > [data-hkm-density="presentation"]')]);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/** Detached clones have no ResizeObserver. Recreate explicit graphic fits from the inside out. */
|
|
372
|
+
function measureNestedFits(stage: HTMLElement): void {
|
|
373
|
+
const fits = [...stage.querySelectorAll<HTMLElement>("[data-hkm-min-width]")].filter((fit) => fit.parentElement?.classList.contains("hkm-step-panel") !== true && fit.parentElement?.classList.contains("hkm-mode-surface") !== true);
|
|
374
|
+
for (const fit of fits) {
|
|
375
|
+
const inner = fit.querySelector<HTMLElement>(":scope > .hkm-fit-inner");
|
|
376
|
+
if (inner === null) continue;
|
|
377
|
+
fit.style.removeProperty("height");
|
|
378
|
+
inner.style.removeProperty("transform");
|
|
379
|
+
inner.style.width = `${Math.max(fit.clientWidth, Number(fit.dataset.hkmMinWidth))}px`;
|
|
380
|
+
}
|
|
381
|
+
for (const fit of fits.reverse()) {
|
|
382
|
+
const inner = fit.querySelector<HTMLElement>(":scope > .hkm-fit-inner");
|
|
383
|
+
if (inner === null || inner.offsetWidth <= 0) continue;
|
|
384
|
+
const scale = Math.min(1, fit.clientWidth / inner.offsetWidth);
|
|
385
|
+
fit.style.height = `${inner.offsetHeight * scale}px`;
|
|
386
|
+
inner.style.transform = `scale(${scale})`;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
353
390
|
/** Measure complete mounted slides at a readable baseline, separately from fitted paint. */
|
|
354
391
|
function fitShowcaseStage(stage: HTMLDivElement, minimumHeight: number): void {
|
|
355
392
|
const owner = stage.parentElement;
|
|
356
393
|
if (owner === null || stage.clientWidth <= 0) return;
|
|
394
|
+
for (const frame of fillFrames(stage)) frame.setAttribute("data-hkm-fill-frame", "");
|
|
357
395
|
const probe = stage.cloneNode(true) as HTMLDivElement;
|
|
358
396
|
probe.setAttribute("aria-hidden", "true");
|
|
359
397
|
probe.setAttribute("inert", "");
|
|
@@ -362,7 +400,7 @@ function fitShowcaseStage(stage: HTMLDivElement, minimumHeight: number): void {
|
|
|
362
400
|
for (const sentinel of probe.querySelectorAll("[data-hkm-font-sentinel]")) sentinel.remove();
|
|
363
401
|
for (const node of probe.querySelectorAll("[id]")) node.removeAttribute("id");
|
|
364
402
|
for (const node of probe.querySelectorAll("[data-hkm-animated]")) node.removeAttribute("data-hkm-animated");
|
|
365
|
-
for (const body of probe
|
|
403
|
+
for (const body of presentationBodies(probe)) body.style.removeProperty("--hkm-terminal-presentation-size");
|
|
366
404
|
for (const fixture of probe.querySelectorAll<HTMLElement>("[data-hkm-measurement]")) fixture.hidden = false;
|
|
367
405
|
// Even a reduced-motion reset can introduce tiny all-property transitions.
|
|
368
406
|
// Synchronous measurements need final styles throughout the owned copy,
|
|
@@ -373,6 +411,7 @@ function fitShowcaseStage(stage: HTMLDivElement, minimumHeight: number): void {
|
|
|
373
411
|
}
|
|
374
412
|
owner.append(probe);
|
|
375
413
|
try {
|
|
414
|
+
measureNestedFits(probe);
|
|
376
415
|
const naturalHeight = Math.max(minimumHeight, Math.ceil(probe.getBoundingClientRect().height));
|
|
377
416
|
// The tallest complete slide establishes the floor. Fitted type never feeds
|
|
378
417
|
// back into it, and changing the active tab never requests a measurement.
|
|
@@ -380,8 +419,8 @@ function fitShowcaseStage(stage: HTMLDivElement, minimumHeight: number): void {
|
|
|
380
419
|
for (const fixture of probe.querySelectorAll("[data-hkm-measurement]")) fixture.remove();
|
|
381
420
|
probe.style.blockSize = `${naturalHeight}px`;
|
|
382
421
|
probe.removeAttribute("data-hkm-measuring");
|
|
383
|
-
const bodies =
|
|
384
|
-
const copies =
|
|
422
|
+
const bodies = presentationBodies(stage).filter((body) => body.closest("[data-hkm-measurement]") === null);
|
|
423
|
+
const copies = presentationBodies(probe);
|
|
385
424
|
for (const [index, copy] of copies.entries()) {
|
|
386
425
|
const body = bodies[index];
|
|
387
426
|
if (body === undefined) continue;
|
|
@@ -438,7 +477,8 @@ function useFittedShowcaseStage(fit: "natural" | "fill", source: unknown, variat
|
|
|
438
477
|
fontSentinel.remove();
|
|
439
478
|
node.style.removeProperty("--hkm-showcase-fill-height");
|
|
440
479
|
node.removeAttribute("data-hkm-fitted");
|
|
441
|
-
for (const body of node
|
|
480
|
+
for (const body of presentationBodies(node)) body.style.removeProperty("--hkm-terminal-presentation-size");
|
|
481
|
+
for (const frame of fillFrames(node)) frame.removeAttribute("data-hkm-fill-frame");
|
|
442
482
|
};
|
|
443
483
|
}, [fit, source, variation, minimumHeight]);
|
|
444
484
|
return stage;
|
package/src/mockups.css
CHANGED
|
@@ -2533,35 +2533,37 @@
|
|
|
2533
2533
|
.hkm-showcase.hkm-steps .hkm-step-panel .hkm-root { border-start-start-radius: 0; border-start-end-radius: 0; box-shadow: none; }
|
|
2534
2534
|
/* Fill uses the tallest complete slide as its natural height. It does not
|
|
2535
2535
|
* scale text or ask fitted font sizes to determine the stage height. */
|
|
2536
|
-
.hkm-showcase[data-hkm-fit="fill"] [data-hkm-measuring] .hkm-page { max-block-size: none; }
|
|
2536
|
+
.hkm-showcase[data-hkm-fit="fill"] [data-hkm-measuring] [data-hkm-fill-frame] > .hkm-window > .hkm-page { max-block-size: none; }
|
|
2537
2537
|
|
|
2538
2538
|
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) {
|
|
2539
2539
|
block-size: var(--hkm-showcase-fill-height, auto);
|
|
2540
2540
|
}
|
|
2541
2541
|
|
|
2542
|
-
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) :is(.hkm-step-panel, .hkm-mode-surface) {
|
|
2542
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) > :is(.hkm-step-panel, .hkm-mode-surface) {
|
|
2543
2543
|
align-self: stretch;
|
|
2544
2544
|
min-block-size: 0;
|
|
2545
2545
|
}
|
|
2546
2546
|
|
|
2547
|
-
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) :is(.hkm-
|
|
2547
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) > :is(.hkm-step-panel, .hkm-mode-surface) > .hkm-fit,
|
|
2548
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) > :is(.hkm-step-panel, .hkm-mode-surface) > .hkm-fit > .hkm-fit-inner,
|
|
2549
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) :is([data-hkm-fill-frame], [data-hkm-fill-frame] > .hkm-window) {
|
|
2548
2550
|
block-size: 100%;
|
|
2549
2551
|
min-block-size: 0;
|
|
2550
2552
|
}
|
|
2551
2553
|
|
|
2552
|
-
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) .hkm-window:has(> .hkm-page) {
|
|
2554
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) [data-hkm-fill-frame] > .hkm-window:has(> .hkm-page) {
|
|
2553
2555
|
display: flex;
|
|
2554
2556
|
flex-direction: column;
|
|
2555
2557
|
}
|
|
2556
2558
|
|
|
2557
|
-
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) .hkm-window > .hkm-page {
|
|
2559
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) [data-hkm-fill-frame] > .hkm-window > .hkm-page {
|
|
2558
2560
|
flex: 1 1 auto;
|
|
2559
2561
|
block-size: auto;
|
|
2560
2562
|
min-block-size: 0;
|
|
2561
2563
|
max-block-size: none;
|
|
2562
2564
|
}
|
|
2563
2565
|
|
|
2564
|
-
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) :is(.hkm-title-bar, .hkm-browser-bar) {
|
|
2566
|
+
.hkm-showcase[data-hkm-fit="fill"] :is(.hkm-step-stage, .hkm-mode-stage):not([data-hkm-measuring]) [data-hkm-fill-frame] > .hkm-window > :is(.hkm-title-bar, .hkm-browser-bar) {
|
|
2565
2567
|
flex: none;
|
|
2566
2568
|
}
|
|
2567
2569
|
|
|
@@ -725,8 +725,10 @@
|
|
|
725
725
|
text-underline-offset: 0.18em;
|
|
726
726
|
}
|
|
727
727
|
|
|
728
|
-
|
|
729
|
-
|
|
728
|
+
@media (forced-colors: none) {
|
|
729
|
+
.plain-site.plain-publication.plain-publication--embedded .plain-publication__article-body a:is(:hover, :focus-visible) {
|
|
730
|
+
text-decoration-color: currentColor;
|
|
731
|
+
}
|
|
730
732
|
}
|
|
731
733
|
|
|
732
734
|
.plain-site.plain-publication.plain-publication--embedded .plain-publication__article-body pre {
|
|
@@ -952,6 +954,7 @@
|
|
|
952
954
|
background: Canvas;
|
|
953
955
|
}
|
|
954
956
|
|
|
957
|
+
.plain-site.plain-publication.plain-publication--embedded .plain-publication__byline a,
|
|
955
958
|
.plain-site.plain-publication.plain-publication--embedded .plain-publication__article-body a {
|
|
956
959
|
text-decoration-color: LinkText;
|
|
957
960
|
}
|
|
@@ -1710,8 +1710,9 @@ html:has(:is(.hraness-marketing-header, .hraness-marketing-header-surface):not([
|
|
|
1710
1710
|
}
|
|
1711
1711
|
|
|
1712
1712
|
.hraness-marketing-card[data-layout="icon"] {
|
|
1713
|
-
display:
|
|
1714
|
-
|
|
1713
|
+
display: flex;
|
|
1714
|
+
flex-direction: row;
|
|
1715
|
+
flex-wrap: wrap;
|
|
1715
1716
|
align-items: center;
|
|
1716
1717
|
gap: 1rem;
|
|
1717
1718
|
padding: 1.125rem;
|
|
@@ -1724,6 +1725,7 @@ html:has(:is(.hraness-marketing-header, .hraness-marketing-header-surface):not([
|
|
|
1724
1725
|
|
|
1725
1726
|
.hraness-marketing-card__icon {
|
|
1726
1727
|
display: flex;
|
|
1728
|
+
flex: 0 0 3.5rem;
|
|
1727
1729
|
align-items: center;
|
|
1728
1730
|
justify-content: center;
|
|
1729
1731
|
inline-size: 3.5rem;
|
|
@@ -1740,6 +1742,7 @@ html:has(:is(.hraness-marketing-header, .hraness-marketing-header-surface):not([
|
|
|
1740
1742
|
|
|
1741
1743
|
.hraness-marketing-card__copy {
|
|
1742
1744
|
display: grid;
|
|
1745
|
+
flex: 1 1 10rem;
|
|
1743
1746
|
align-content: center;
|
|
1744
1747
|
min-inline-size: 0;
|
|
1745
1748
|
gap: 0.35rem;
|
|
@@ -593,7 +593,7 @@ export function DesignSystemGallery({
|
|
|
593
593
|
{ label: "Bring your model", values: [true, { status: "optional", label: "On some plans" }] },
|
|
594
594
|
{ label: "Local storage", values: [true, { status: "depends", detail: "Check the provider's export format." }] },
|
|
595
595
|
{ label: "Cost", values: ["Free locally", "Subscription"] },
|
|
596
|
-
]} note=
|
|
596
|
+
]} note={<span>An illustrative comparison. Product pages supply current facts and <a href="#articles">sources</a>.</span>} />
|
|
597
597
|
<MarketingAccount id="gallery-account" summary="Keep your preferences and shared work together.">
|
|
598
598
|
<MarketingAccountActions primary={{ href: "#gallery-account", label: "Create account" }} signIn={{ href: "#gallery-account" }} />
|
|
599
599
|
</MarketingAccount>
|
|
@@ -695,7 +695,7 @@ export function DesignSystemGallery({
|
|
|
695
695
|
]}
|
|
696
696
|
/>
|
|
697
697
|
)}
|
|
698
|
-
author={{ kind: "organization", name: "Hraness" }}
|
|
698
|
+
author={{ kind: "organization", name: "Hraness", href: "https://hraness.com" }}
|
|
699
699
|
dek="Relay replays a failed webhook from the stored request body, so the retry sends the same bytes the provider signed."
|
|
700
700
|
eyebrow="Technique"
|
|
701
701
|
heading="Replaying webhooks without breaking signatures"
|
|
@@ -714,7 +714,7 @@ export function DesignSystemGallery({
|
|
|
714
714
|
>
|
|
715
715
|
<h2 id="gallery-article-problem">The problem</h2>
|
|
716
716
|
<p>
|
|
717
|
-
A provider signs the exact request body
|
|
717
|
+
A provider signs the <a href="#gallery-article-approach">exact request body</a>. Parsing the JSON and serializing it again changes
|
|
718
718
|
whitespace and key order, and the signature check then fails on every retry.
|
|
719
719
|
</p>
|
|
720
720
|
<ArticleCallout label="Limit" tone="limit">
|
|
@@ -758,6 +758,7 @@ export function DesignSystemGallery({
|
|
|
758
758
|
},
|
|
759
759
|
]}
|
|
760
760
|
/>
|
|
761
|
+
<p className="plain-publication__provenance"><a href="#gallery-article-title">Read the article</a></p>
|
|
761
762
|
<div className="hraness-prose">
|
|
762
763
|
<h3>Shared reading scale</h3>
|
|
763
764
|
<p>
|
|
@@ -2502,8 +2502,9 @@ export const marketingStyles = stylex.create({
|
|
|
2502
2502
|
"text-decoration": "none"
|
|
2503
2503
|
},
|
|
2504
2504
|
"cardIcon": {
|
|
2505
|
-
"display": "
|
|
2506
|
-
"
|
|
2505
|
+
"display": "flex",
|
|
2506
|
+
"flex-direction": "row",
|
|
2507
|
+
"flex-wrap": "wrap",
|
|
2507
2508
|
"align-items": "center",
|
|
2508
2509
|
"gap": "1rem",
|
|
2509
2510
|
"padding": "1.125rem",
|
|
@@ -2518,6 +2519,9 @@ export const marketingStyles = stylex.create({
|
|
|
2518
2519
|
},
|
|
2519
2520
|
"card__icon": {
|
|
2520
2521
|
"display": "flex",
|
|
2522
|
+
"flex-grow": "0",
|
|
2523
|
+
"flex-shrink": "0",
|
|
2524
|
+
"flex-basis": "3.5rem",
|
|
2521
2525
|
"align-items": "center",
|
|
2522
2526
|
"justify-content": "center",
|
|
2523
2527
|
"inline-size": "3.5rem",
|
|
@@ -2527,6 +2531,9 @@ export const marketingStyles = stylex.create({
|
|
|
2527
2531
|
},
|
|
2528
2532
|
"card__copy": {
|
|
2529
2533
|
"display": "grid",
|
|
2534
|
+
"flex-grow": "1",
|
|
2535
|
+
"flex-shrink": "1",
|
|
2536
|
+
"flex-basis": "10rem",
|
|
2530
2537
|
"align-content": "center",
|
|
2531
2538
|
"min-inline-size": "0",
|
|
2532
2539
|
"gap": "0.35rem"
|
package/src/typography.css
CHANGED
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
/* Prose and secondary text actions share a quiet, persistent link affordance. */
|
|
95
95
|
.hraness-text-link,
|
|
96
96
|
.hraness-prose :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
97
|
-
.plain-publication__article-body :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
97
|
+
:is(.plain-publication__article-body, .plain-publication__sources, .plain-publication__provenance, .hraness-marketing-comparison__note) :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
98
98
|
.plain-page :where(p, li, dd, dt, figcaption) a:not([role="button"], [data-emphasis], [data-foil]) {
|
|
99
99
|
text-decoration-line: underline;
|
|
100
100
|
text-decoration-style: dotted;
|
|
@@ -103,16 +103,20 @@
|
|
|
103
103
|
text-underline-offset: 0.2em;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
.hraness-
|
|
108
|
-
.
|
|
109
|
-
|
|
106
|
+
@media (forced-colors: none) {
|
|
107
|
+
.hraness-text-link:is(:hover, :focus-visible),
|
|
108
|
+
.hraness-prose :where(a:not([role="button"], [data-emphasis], [data-foil])):is(:hover, :focus-visible),
|
|
109
|
+
:is(.plain-publication__article-body, .plain-publication__sources, .plain-publication__provenance, .hraness-marketing-comparison__note) :where(a:not([role="button"], [data-emphasis], [data-foil])):is(:hover, :focus-visible),
|
|
110
|
+
.plain-page :where(p, li, dd, dt, figcaption) a:not([role="button"], [data-emphasis], [data-foil]):is(:hover, :focus-visible) {
|
|
111
|
+
text-decoration-color: currentColor;
|
|
112
|
+
}
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
@media (forced-colors: active) {
|
|
113
116
|
.hraness-text-link,
|
|
114
|
-
.hraness-prose :where(a),
|
|
115
|
-
.plain-
|
|
117
|
+
.hraness-prose :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
118
|
+
:is(.plain-publication__article-body, .plain-publication__sources, .plain-publication__provenance, .hraness-marketing-comparison__note) :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
119
|
+
.plain-page :where(p, li, dd, dt, figcaption) a:not([role="button"], [data-emphasis], [data-foil]) {
|
|
116
120
|
text-decoration-color: LinkText;
|
|
117
121
|
}
|
|
118
122
|
}
|