Files
breadcrumb-the-shire/web/css/pages/app-docs.css
fs 026002a501 feat: extract typography tokens into dedicated file with semantic aliases and a11y fallbacks
Create typography.tokens.css as single source of truth for the type system:
- Extract all primitive tokens from variables.base.css (--text-*, --leading-*, --font-*, --tracking-*)
- Add semantic aliases (--text-body, --text-label, --text-caption, --text-title, --text-page-title)
- Add --text-md (15px) escape hatch and --tracking-wider (0.05em) token
- Add prefers-reduced-motion fallbacks locking fluid headings to fixed midpoints
- Document scale ratio (1.25x major third, 14px base) with reference table
- Migrate h1/h2 in app-shell.css to semantic aliases
- Migrate 4 raw letter-spacing values to --tracking-* tokens
- Extend TypographyTokenContractTest with 3 new tests (letter-spacing, aliases, reduced-motion)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 16:25:51 +01:00

378 lines
8.1 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@layer components {
/* ─── Layout ─────────────────────────────────────────────────── */
.app-docs-container {
display: grid;
grid-template-columns: 220px 1fr 200px;
grid-template-areas: "nav content toc";
align-items: start;
gap: 0 2rem;
min-height: 100%;
}
.app-docs-nav {
grid-area: nav;
}
.app-docs-content {
grid-area: content;
}
.app-docs-toc {
grid-area: toc;
}
/* Stick nav and toc to viewport while scrolling */
.app-docs-nav,
.app-docs-toc {
position: sticky;
top: 70px;
max-height: calc(100dvh - 6rem);
overflow-y: auto;
overscroll-behavior: contain;
}
@media (max-width: 1100px) {
.app-docs-container {
grid-template-columns: 220px 1fr;
grid-template-areas: "nav content";
}
.app-docs-toc {
display: none;
}
}
@media (max-width: 768px) {
.app-docs-container {
grid-template-columns: 1fr;
grid-template-areas:
"nav"
"content";
}
.app-docs-nav {
position: static;
max-height: none;
overflow-y: visible;
border-bottom: 1px solid var(--app-border);
padding-bottom: 1rem;
margin-bottom: 1rem;
}
}
/* ─── Left navigation ─────────────────────────────────────────── */
.app-docs-nav {
--docs-nav-border-width: 2px;
padding-block: 0.25rem;
}
.app-docs-nav-group {
margin-bottom: 0.25rem;
}
.app-docs-nav-group details {
border: 0;
margin: 0;
padding: 0;
}
.app-docs-nav-group summary {
list-style: none;
cursor: pointer;
padding: 0;
}
.app-docs-nav-group summary small {
font-size: var(--text-xs);
letter-spacing: var(--tracking-wider);
text-transform: uppercase;
display: inline;
}
.app-docs-nav-group ul {
margin-top: 0.1rem;
}
.app-docs-nav ul {
list-style: none;
margin: 0;
padding: 0;
}
.app-docs-nav a {
display: block;
padding: 4px 0.75rem;
color: inherit;
border-left: var(--docs-nav-border-width) solid transparent;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--text-sm);
border-radius: 0;
text-decoration: none;
}
.app-docs-nav a:hover {
color: var(--app-primary);
border-left-color: var(--app-muted-border-color);
}
.app-docs-nav a.active {
color: var(--app-primary);
border-left-color: var(--app-primary);
font-weight: var(--font-medium);
}
/* ─── TOC ─────────────────────────────────────────────────────── */
.app-docs-toc {
padding-block: 0.25rem;
}
.app-docs-toc > small {
display: block;
padding: 0 0 0.5rem;
font-size: var(--text-xs);
letter-spacing: var(--tracking-wider);
text-transform: uppercase;
}
.app-docs-toc ul {
margin: 0;
padding: 0;
list-style: none;
}
.app-docs-toc li {
position: relative;
}
.app-docs-toc a {
display: block;
text-decoration: none;
color: inherit;
line-height: var(--leading-snug);
padding-block: 0.12rem;
}
.app-docs-toc a:hover {
color: var(--app-primary);
}
.app-docs-toc-level-2 {
margin: 0;
padding: 0 0 10px 0;
}
.app-docs-toc-level-3 {
margin: 0;
padding: 0;
padding-left: 1rem;
}
.app-docs-toc-level-3 a {
font-size: var(--text-xs);
padding-left: 0.45rem;
}
.app-docs-toc-level-3::before {
content: "";
position: absolute;
left: 0.2rem;
top: 2px;
width: 13px;
height: 0.55rem;
background: transparent;
border-left: 1px solid var(--app-border);
border-bottom: 1px solid var(--app-border);
border-bottom-left-radius: 6px;
}
.app-docs-toc-level-3:has(+ .app-docs-toc-level-2) {
margin-bottom: 1rem;
}
/* ─── Prose (rendered markdown) ────────────────────────────────── */
.app-docs-content {
max-width: 72ch;
min-width: 0;
background: transparent;
box-shadow: none;
}
.app-docs-content h1,
.app-docs-content h2,
.app-docs-content h3,
.app-docs-content h4,
.app-docs-content h5,
.app-docs-content h6 {
scroll-margin-top: 1.5rem;
line-height: var(--leading-snug);
}
.app-docs-content h1 {
color: var(--app-h1-color);
margin-top: 0;
font-size: var(--text-4xl);
}
.app-docs-content h2 {
color: var(--app-h2-color);
font-size: var(--text-xl);
margin-top: 2.5rem;
padding-top: 1rem;
border-top: 1px solid var(--app-border);
}
.app-docs-content h3 {
color: var(--app-h3-color);
font-size: var(--text-lg);
margin-top: 1.75rem;
}
.app-docs-content h4 {
color: var(--app-h4-color);
font-size: var(--text-base);
margin-top: 1.25rem;
}
.app-docs-content h5,
.app-docs-content h6 {
color: var(--app-h5-color);
font-size: var(--text-sm);
margin-top: 1rem;
}
.app-docs-content p {
margin-block: 0.875rem;
line-height: var(--leading-loose);
}
.app-docs-content a {
color: var(--app-primary);
text-decoration: underline;
text-underline-offset: 0.15em;
}
.app-docs-content .app-breadcrumb a {
text-decoration: none;
color: inherit;
}
.app-docs-content a:hover {
color: var(--app-primary-hover);
}
.app-docs-content ul,
.app-docs-content ol {
padding-left: 1.5rem;
margin-block: 0.875rem;
}
.app-docs-content li {
margin-block: 0.3rem;
line-height: var(--leading-relaxed);
}
.app-docs-content li > ul,
.app-docs-content li > ol {
margin-block: 0.25rem;
}
.app-docs-content ul.contains-task-list,
.app-docs-content ol.contains-task-list,
.app-docs-content ul:has(> li > input[type="checkbox"]),
.app-docs-content ol:has(> li > input[type="checkbox"]) {
list-style: none;
padding-left: 0;
}
.app-docs-content .task-list-item,
.app-docs-content li:has(> input[type="checkbox"]) {
list-style: none;
position: relative;
padding-left: 1.6rem;
}
.app-docs-content .task-list-item .task-list-item-checkbox,
.app-docs-content .task-list-item > input[type="checkbox"] {
position: absolute;
left: 0;
top: 0.3rem;
width: 1rem;
height: 1rem;
margin: 0;
accent-color: var(--app-primary);
}
.app-docs-content pre {
background: var(--app-code-background-color);
border: 1px solid var(--app-border);
border-radius: var(--app-border-radius);
padding: 1rem 1.25rem;
overflow-x: auto;
margin-block: 1.25rem;
}
.app-docs-content pre code {
background: none;
padding: 0;
font-size: var(--text-sm);
color: var(--app-color);
}
.app-docs-content blockquote {
border-left: 3px solid var(--app-blockquote-border-color);
margin-left: 0;
margin-right: 0;
padding: 0.5rem 1rem;
background: var(--app-blockquote-background-color);
border-radius: 0 var(--app-border-radius) var(--app-border-radius) 0;
color: var(--app-muted-color);
}
.app-docs-content blockquote p {
margin: 0;
}
.app-docs-content hr {
border: 0;
border-top: 1px solid var(--app-border);
margin-block: 2rem;
}
.app-docs-content table {
width: 100%;
border-collapse: collapse;
font-size: var(--text-sm);
margin-block: 1.25rem;
overflow-x: auto;
display: block;
}
.app-docs-content th,
.app-docs-content td {
text-align: left;
padding: 0.5rem 0.75rem;
border: 1px solid var(--app-table-border-color);
}
.app-docs-content th {
background: var(--app-code-background-color);
font-weight: var(--font-semibold);
color: var(--app-color);
}
.app-docs-content tbody tr:nth-child(odd) {
background: var(--app-table-row-stripped-background-color);
}
.app-docs-content img {
max-width: 100%;
height: auto;
border-radius: var(--app-border-radius);
}
/* HeadingPermalink anchors keep invisible */
.app-docs-content .docs-heading-anchor {
display: none;
}
}