Skip to content

Commit 10ce482

Browse files
committed
feat: add ToolMark component and ranked list CSS
1 parent 6b6b35b commit 10ce482

3 files changed

Lines changed: 171 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
.frame {
2+
display: inline-grid;
3+
width: var(--icon-xl);
4+
height: var(--icon-xl);
5+
margin-inline-end: var(--space-1);
6+
vertical-align: middle;
7+
place-items: center;
8+
background: var(--surface-raised);
9+
border: 1px solid var(--border-default);
10+
}
11+
12+
.mark {
13+
width: var(--icon-lg);
14+
height: var(--icon-lg);
15+
background: var(--text-heading);
16+
-webkit-mask-position: center;
17+
mask-position: center;
18+
-webkit-mask-repeat: no-repeat;
19+
mask-repeat: no-repeat;
20+
-webkit-mask-size: contain;
21+
mask-size: contain;
22+
}
23+
24+
.image,
25+
.darkImage {
26+
width: var(--icon-lg);
27+
height: var(--icon-lg);
28+
object-fit: contain;
29+
/* Preserve source layers while removing non-semantic brand color. */
30+
filter: grayscale(1) contrast(1.25);
31+
}
32+
33+
.imageForeground {
34+
/* Lift bright prompt glyphs above dark official terminal backgrounds. */
35+
filter: grayscale(1) brightness(2) contrast(1.2);
36+
}
37+
38+
.imageFrame {
39+
border-radius: 30%;
40+
}
41+
42+
:global([data-theme='dark']) .imageFrame {
43+
box-sizing: border-box;
44+
border: 1px solid var(--text-heading);
45+
}
46+
47+
.darkImage {
48+
display: none;
49+
}
50+
51+
/* Dark official artwork disappears against the dark raised tile (#161b22);
52+
lift mid-tone bodies so the composition keeps its internal layers. */
53+
:global([data-theme='dark']) .imageDarkLift {
54+
filter: grayscale(1) brightness(2.1) contrast(1.15);
55+
}
56+
57+
:global([data-theme='dark']) .withDarkImage .image {
58+
display: none;
59+
}
60+
61+
:global([data-theme='dark']) .withDarkImage .darkImage {
62+
display: block;
63+
}
64+
65+
.luminance {
66+
-webkit-mask-mode: luminance;
67+
mask-mode: luminance;
68+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import clsx from 'clsx';
2+
import useBaseUrl from '@docusaurus/useBaseUrl';
3+
4+
import styles from './ToolMark.module.css';
5+
6+
type ToolMarkProps = {
7+
// Site-relative path to the official mark, e.g. `/img/terminal-logos/ghostty.svg`.
8+
src: string;
9+
// Luminance masking for opaque official app-icon compositions: preserves
10+
// their bright foreground geometry instead of flattening every filled layer.
11+
luminance?: boolean;
12+
// Direct rendering preserves official compound/app-icon layer relationships.
13+
mode?: 'mask' | 'image';
14+
// Brightens a dark app-icon foreground without restoring its brand hue.
15+
imageTone?: 'standard' | 'foreground';
16+
// Replaces rasterized app-icon edging with a theme-colored CSS outline.
17+
imageFrame?: boolean;
18+
// Dark-theme presentation for official artwork drawn in dark tones:
19+
// 'lift' raises mid-tone bodies above the dark tile.
20+
darkImageTone?: 'lift';
21+
// Optional asset with colors selected for the dark theme.
22+
darkSrc?: string;
23+
};
24+
25+
// Neutral 48px tile rendering an official tool logo. Decorative only: the
26+
// adjacent heading text stays the accessible name.
27+
export default function ToolMark({
28+
src,
29+
luminance = false,
30+
mode = 'mask',
31+
imageTone = 'standard',
32+
imageFrame = false,
33+
darkImageTone,
34+
darkSrc,
35+
}: ToolMarkProps) {
36+
const url = useBaseUrl(src);
37+
const darkUrl = useBaseUrl(darkSrc ?? src);
38+
const imageClass = clsx(
39+
imageTone === 'foreground' && styles.imageForeground,
40+
imageFrame && styles.imageFrame,
41+
darkImageTone === 'lift' && styles.imageDarkLift
42+
);
43+
return (
44+
<span
45+
aria-hidden="true"
46+
className={clsx(styles.frame, darkSrc && styles.withDarkImage)}
47+
>
48+
{mode === 'image' ? (
49+
<>
50+
<img className={clsx(styles.image, imageClass)} src={url} alt="" />
51+
{darkSrc && (
52+
<img
53+
className={clsx(styles.darkImage, imageClass)}
54+
src={darkUrl}
55+
alt=""
56+
/>
57+
)}
58+
</>
59+
) : (
60+
<span
61+
className={clsx(styles.mark, luminance && styles.luminance)}
62+
style={{
63+
maskImage: `url('${url}')`,
64+
WebkitMaskImage: `url('${url}')`,
65+
}}
66+
/>
67+
)}
68+
</span>
69+
);
70+
}

website/src/css/custom.css

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,39 @@ article h1 {
587587
vertical-align: middle;
588588
}
589589

590+
/* ========================================================================
591+
RANKED TOOL LIST — leaderboard metadata on cli-coding-agents.md
592+
======================================================================== */
593+
594+
/* Ordinal in tool headings: metadata level, never semantic color — rank is
595+
order, not status. */
596+
.rank-numeral {
597+
color: var(--text-muted);
598+
margin-right: var(--space-2); /* 16px — within-group step: rank and mark
599+
are separate elements of the heading group */
600+
}
601+
602+
/* Ordinal period: 01. 02. … — sharp editorial ordinal, no decorative dot. */
603+
.rank-numeral::after {
604+
content: ".";
605+
}
606+
607+
/* Baseline alignment leaves the 48px tool mark floating against heading
608+
text; flex puts rank, mark, name, and hash-link on one optical center. */
609+
article h2:has(> .rank-numeral) {
610+
display: flex;
611+
align-items: center;
612+
}
613+
614+
/* One-line verdict under ranked tool headings. Tight to the heading (8px,
615+
proximity: it belongs to the heading), 16px before body prose. */
616+
article .tool-verdict {
617+
margin: var(--space-1) 0 var(--space-2);
618+
color: var(--text-muted);
619+
font-size: var(--text-sm); /* 13px */
620+
line-height: var(--lh-sm); /* 24px */
621+
}
622+
590623
/* ========================================================================
591624
TABLE OF CONTENTS — Right sidebar, design system alignment
592625
======================================================================== */

0 commit comments

Comments
 (0)