/** * 05-utilities.css * Utility patterns (layout helpers, text modifiers, responsive utilities) * Part of: Agentic Semantic Web */ @layer utilities { /* ══════════════════════════════════════════════════════════════════════════ Text utilities ══════════════════════════════════════════════════════════════════════════ */ [data-text~="mono"] { font-family: var(--font-mono); } [data-text~="dim"] { color: var(--text-3); } [data-text~="accent"] { color: var(--accent); } [data-text~="small"] { font-size: var(--text-xs); } /* Eyebrow — small monospace uppercase accent label above a heading */ [data-text~="eyebrow"] { display: block; font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); margin-bottom: var(--space-2); } /* ══════════════════════════════════════════════════════════════════════════ Layout utilities ══════════════════════════════════════════════════════════════════════════ */ /* Max-width content column — constrains fluid sections to readable width */ [data-wrap] { max-width: var(--width-content); margin-inline: auto; padding-inline: var(--space-5); } /* Inline definition lists */ dl[data-layout="inline"] { display: grid; grid-template-columns: auto 1fr; gap: 0.15rem 1rem; align-items: baseline; } dl[data-layout="inline"] dt, dl[data-layout="inline"] dd { margin: 0; padding: 0; margin-inline-start: 0; } /* ══════════════════════════════════════════════════════════════════════════ Responsive visibility ══════════════════════════════════════════════════════════════════════════ */ /* Hide on mobile */ [data-visible="desktop"] { display: none; } @media (--md-n-above) { [data-visible="desktop"] { display: initial; } } /* Hide on desktop */ [data-visible="mobile"] { display: initial; } @media (--md-n-above) { [data-visible="mobile"] { display: none; } } /* ══════════════════════════════════════════════════════════════════════════ Loading indicator — aria-busy Usage:
Content loading…
══════════════════════════════════════════════════════════════════════════ */ @keyframes spin { to { transform: rotate(360deg); } } [aria-busy="true"] { cursor: progress; } /* Inline spinner before text in buttons and interactive elements */ :is(button, [role="button"], a)[aria-busy="true"]::before { content: ""; display: inline-block; width: 1em; height: 1em; margin-right: 0.5em; vertical-align: -0.125em; border: var(--border-size-2) solid currentColor; border-top-color: transparent; border-radius: 50%; } /* Disable interaction on busy buttons */ :is(button, [role="button"])[aria-busy="true"] { pointer-events: none; opacity: 0.7; } /* Block-level busy: overlay spinner centered */ :is(section, article, main, div)[aria-busy="true"] { position: relative; min-height: 3rem; } :is(section, article, main, div)[aria-busy="true"]::after { content: ""; position: absolute; top: 50%; left: 50%; width: 1.5rem; height: 1.5rem; margin: -0.75rem 0 0 -0.75rem; border: var(--outline-width) solid var(--text-3); border-top-color: transparent; border-radius: 50%; } /* Spinner rotation — guarded: skip for users who prefer reduced motion */ @media (--motionOK) { :is(button, [role="button"], a)[aria-busy="true"]::before { animation: spin var(--spinner-duration) linear infinite; } :is(section, article, main, div)[aria-busy="true"]::after { animation: spin var(--spinner-duration) linear infinite; } } /* ══════════════════════════════════════════════════════════════════════════ Accessibility enhancements ══════════════════════════════════════════════════════════════════════════ */ /* Disable all transitions and animations for reduced motion preference */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } /* Increase contrast for high-contrast preference */ @media (prefers-contrast: more) { :root { --border-color: var(--gray-10); /* TODO: map to semantic token — no alias for gray-10 (--border=gray-11; high-contrast needs one step higher) */ --border-color-subtle: var(--border-subtle); /* --border-subtle = var(--gray-12) */ --text-primary: var(--gray-0); /* TODO: map to semantic token — no alias for gray-0 (--text=gray-1 in dark; high-contrast needs brightest white) */ --text-secondary: var(--text-2); /* --text-2 = var(--gray-3) */ --border-width: var(--border-size-2); } /* Thicker borders on interactive elements */ a, button, input, select, textarea, [data-wikilink] { border-width: var(--border-size-2); } /* Stronger focus indicators */ :focus-visible { outline-width: var(--border-size-3); outline-offset: var(--border-size-3); } } } /* end @layer utilities */