Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions TRIDENT-PROTOTYPE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Trident token prototype

This prototype applies Trident tokens to the existing Hugo and Tailwind docs
site. Builds use checked-in CSS and fonts, with no access to a private registry.

## Preview

```console
$ npm ci
$ hugo server --port 1313
```

Review these pages in light and dark mode, at desktop and mobile widths:

- `/desktop/setup/install/linux/`: article typography, navigation, callouts,
tables, and code
- `/get-started/docker-concepts/running-containers/sharing-local-files/`: tabs and code blocks
- `/get-started/`: landing pages and cards

Search requires the separate Pagefind indexing step used by the existing build.

## Integration

`assets/css/style.css` imports the legacy theme, the Trident snapshot, and the
docs adapter in that order. Generated Tailwind mappings supply prefixed palette
utilities and replace shared type, spacing, and radius values. Legacy palette utilities remain
available during the migration. The adapter maps selected docs aliases and
components to Trident semantic colors.

`assets/css/trident.css` maps docs aliases to semantic tokens and styles the
header, sidebar selection, article text, cards, buttons, tabs, and callouts.
The `docs` cascade layer follows utilities so existing light and dark classes
cannot override these semantic color pairs. Token imports stay at the root
because they contain Tailwind directives as well as CSS layer declarations.

Manrope supplies the interface and article typeface. Article body text uses the
16-pixel reading scale, while navigation uses the smaller label scale. Code keeps
the existing Roboto Mono font. The existing theme switch activates Trident's
`.dark` overrides.

Article body text and ordinary quotations use Trident's primary foreground
through the local `--docs-reading-foreground` alias. The local
`--docs-reading-background` uses white `background-primary` in light mode and
`sidebar` in dark mode, matching the dark navigation surface. Subtle borders separate the navigation from the reading area. These are
local layout adaptations; the separate Trident high-contrast mode stays inactive.

Home, Get started, Guides featured cards, and Manuals share the
`components/card.html` partial. Grid layouts and optional audience labels remain
page-specific; Guides search results retain their list layout.
Navigation cards use `background-paper-elevation-0`, compact 16-pixel titles at
weight 600, and 14-pixel descriptions in Trident gray 700 or gray 300.
The border and shadow follow the surface material in Trident core's
`tri-materials.css`: a semantic border in both themes, with a faint inset
top-edge highlight in dark mode and no visible shadow in light mode. The local
`--docs-card-shadow` mirrors this material because it is outside the token
package. The elevated background is a docs-specific surface choice. Decorative icons are
omitted; titles identify the destinations. Linked cards have a full-area target
and accented hover or focus states. Tabs retain the component surface and
semantic borders. Inactive sidebar
items use `sidebar-foreground-muted`, with stronger text on the active item.
Inactive table-of-contents links are neutral; active and hovered links use the
primary accent. Inline code uses a faint foreground tint and compact padding,
while fenced code uses Trident's default background in light mode and the muted
surface in dark mode to preserve syntax contrast. Chroma and Gordon's highlight.js
map keywords, strings, numbers, attributes, commands, and types to Trident
syntax roles. Comments retain the muted foreground.

The neutral header is a docs-specific adaptation. Trident's `AppHeader` component
uses the `header-from` and `header-to` blue gradient tokens.

Gordon uses the Trident header gradient, popover surface, input colors, and
semantic message, feedback, and alert states. Pagefind inherits the same typeface,
popover surface, foregrounds, accent highlights, and focus colors through its
component variables. Search ranking and chat requests retain their existing
behavior.

The homepage composes Gordon's question form, suggested questions, shared
navigation cards, and release feed with the same Trident palette. The form uses
the raised surface and a visible focus outline; suggested questions use quieter
bordered controls. The navigation and release feed share a content width.
The decorative background pattern and scaling interactions are omitted.
These page-specific rules live in `assets/css/home.css`.

This is an integration prototype. Components outside these mappings still need
a design review. Loading tokens does not provide
Trident component behavior or certify accessibility.

Component checks cover cards, tab switching, code, search results, and Gordon
at desktop and mobile widths in both themes. Local search checks use the
preview's Pagefind assets because the local indexer fails with a native allocator
error. Gordon message and rate-limit checks use intercepted browser responses;
they verify rendering and interaction, not the live backend.

## Snapshot provenance

- Package: `@docker/trident-tokens@2.0.0-beta.3`
- Repository: <https://github.com/docker/trident>
- Release commit: `bbc0746b17209071ceddabcb14b180fcb32b2fa9`
- CSS: ten unmodified generated files in `assets/css/vendor/trident/`
- Checksums: SHA-256 per file in that directory's `manifest.json`

The registry rejected the available credentials. This snapshot was generated
from the release commit using the upstream `sd.config.ts` and
`scripts/check-dark-coverage.ts`. It was not extracted from the published npm
archive. The build used Node.js and these dependency versions from the upstream
lockfile: `tsx@4.23.1`, `style-dictionary@5.5.1`, `apca-w3@0.1.9`, and
`culori@4.0.2`. Upstream checks reported 97 contrast pairs with zero failures and
explicit dark overrides for all 286 aliased tokens.

Font files come from `@fontsource-variable/manrope@5.2.8` on npmjs.org. The
unmodified WOFF2 subsets and their SIL Open Font License are under
`static/assets/fonts/manrope/`. The font declarations retain the package's
Unicode ranges and use local asset URLs.

## Refresh the snapshot

A maintainer with Trident access can build an agreed release in a separate
checkout, or extract its published package. Then run:

```console
$ node hack/vendor-trident-tokens.mjs /path/to/trident/packages/tokens <40-character-source-commit>
```

The script validates the package name and local CSS imports, copies the
generated files without modification, and records their version and checksums.
Review the CSS diff. Keep docs adjustments in
`assets/css/trident.css`. The refresh step is separate from ordinary builds.

If the token package becomes available publicly on npmjs.org, replace the
snapshot import with the package import and pin its version in `package.json`.
The docs adapter can remain in place.
2 changes: 2 additions & 0 deletions _vale/config/vocabularies/Docker/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,5 @@ superset
tokenization
WebGL
Xubuntu
Pagefind
Roboto
8 changes: 4 additions & 4 deletions assets/css/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,19 @@ input[type="search"]::-ms-clear {
@apply mt-8 mb-4;
}
:where(h1):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
font-weight: 500 !important;
font-size: 180% !important;
font-weight: var(--tri-font-weight-heading);
font-size: var(--tri-scale-heading-1-font-size);
margin-bottom: 0.4em !important;
}
> h2 {
@apply mt-7! mb-3!;
font-size: 160% !important;
font-size: var(--tri-scale-heading-3-font-size);
a {
@apply hover:no-underline!;
}
}
> h3 {
font-size: 130% !important;
font-size: var(--tri-scale-heading-4-font-size);
a {
@apply hover:no-underline!;
}
Expand Down
216 changes: 216 additions & 0 deletions assets/css/home.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
/* Homepage composition using the shared Trident surfaces and controls. */
@layer docs {
.docs-home {
background: var(--tri-sidebar);
color: var(--tri-foreground);
}

.home-container {
width: min(100% - 3rem, 72rem);
margin-inline: auto;
}

.home-hero {
padding: clamp(3rem, 6vw, 5rem) 1.5rem 3.5rem;
}

.home-hero-content {
max-width: 48rem;
margin-inline: auto;
text-align: center;
}

.home-hero h1 {
margin: 0;
font-size: clamp(2.25rem, 4vw, 3rem);
font-weight: var(--tri-font-weight-semibold);
line-height: 1.15;
letter-spacing: -0.03em;
text-wrap: balance;
}

.home-intro {
margin-top: 1rem;
color: var(--docs-card-description);
font-size: 1rem;
line-height: 1.6;
text-wrap: balance;
}

.home-question {
margin-top: 2rem;
}

.home-question-field {
display: flex;
align-items: center;
gap: 1rem;
padding: 0.75rem;
padding-left: 1.25rem;
background: var(--tri-background-paper-elevation-0);
border: 1px solid var(--tri-input);
border-radius: var(--tri-radius-lg);
box-shadow: var(--docs-card-shadow);
}

.home-question-field:focus-within {
border-color: var(--tri-ring);
outline: 2px solid var(--tri-ring);
outline-offset: 3px;
}

.home-gordon-icon {
flex-shrink: 0;
color: var(--tri-primary);
}

.home-question input {
flex: 1;
min-width: 0;
padding-block: 0.5rem;
color: var(--tri-foreground);
background: transparent;
font: inherit;
font-size: 1rem;
outline: none;
}

.home-question input::placeholder {
color: var(--tri-muted-foreground);
opacity: 1;
}

.home-question-submit {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 2.75rem;
height: 2.75rem;
background: var(--tri-primary);
color: var(--tri-primary-foreground);
border-radius: var(--tri-radius-default);
cursor: pointer;
}

.home-question-submit:disabled {
background: var(--tri-muted);
color: var(--tri-muted-foreground);
cursor: default;
}

.home-question-submit:enabled:hover {
background: var(--tri-accent-hover);
}

.home-suggestions {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.625rem;
margin: 1.25rem auto 0;
}

.home-suggestion {
padding: 0.5rem 0.875rem;
border: 1px solid var(--tri-border);
border-radius: var(--tri-radius-lg);
background: transparent;
color: var(--docs-card-description);
font-size: 0.8125rem;
line-height: 1.5;
cursor: pointer;
}

.home-suggestion:hover {
background: var(--tri-accent-subtle);
border-color: var(--tri-primary);
color: var(--tri-foreground);
}

.home-navigation {
padding-bottom: 3.5rem;
}

.home-updates {
padding-top: 0;
padding-bottom: 4rem;
}

.home-updates header {
border-color: var(--tri-border);
margin-bottom: 1rem;
}

.home-updates h2 {
color: var(--tri-foreground);
font-size: 1.5rem;
font-weight: var(--tri-font-weight-semibold);
}

.home-updates ol {
max-width: 56rem;
}

.home-update-link {
border-color: var(--tri-border);
}

.home-update-dot {
background: var(--tri-muted-foreground);
box-shadow: 0 0 0 4px var(--tri-sidebar);
}

.home-update-product,
.home-updates > .home-container > button {
color: var(--tri-primary);
}

.home-updates time,
.home-update-link .icon-svg {
color: var(--tri-muted-foreground);
}

.home-update-title {
color: var(--tri-foreground);
}

.home-update-description {
color: var(--docs-card-description);
line-height: 1.6;
}

.home-update-link:hover .home-update-title {
color: var(--tri-primary);
}

.home-update-link:hover .home-update-dot {
background: var(--tri-primary);
}

@media (max-width: 40rem) {
.home-question-field {
gap: 0.625rem;
padding-left: 0.75rem;
}

.home-gordon-icon {
display: none;
}

.home-hero {
padding-bottom: 2.5rem;
}

.home-navigation {
padding-bottom: 2.5rem;
}
}

@media (prefers-reduced-motion: reduce) {
.home-update-link .icon-svg {
transition: none;
transform: none;
}
}
}
Loading
Loading