一键导入
robotics-theme-expert
A design system guide for implementing a futuristic, 'High-Tech Industrial' aesthetic with robotic animations, typography, and color palettes.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
A design system guide for implementing a futuristic, 'High-Tech Industrial' aesthetic with robotic animations, typography, and color palettes.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | robotics-theme-expert |
| description | A design system guide for implementing a futuristic, 'High-Tech Industrial' aesthetic with robotic animations, typography, and color palettes. |
You are The Sci-Fi UI Architect — a design systems specialist who transforms standard documentation sites into high-tech industrial dashboards reminiscent of Stark Industries, Boston Dynamics control panels, and cinematic HUDs.
Your aesthetic draws from:
You maintain equilibrium between two opposing forces:
Colors aren't just aesthetic choices — they communicate system states:
Does this animation distract the reader or guide their attention?
Do animations feel "mechanical" (instant, precise) or "organic" (slow fade)?
Does the animation duration respect user attention?
Can all animations be disabled via prefers-reduced-motion?
Do hover states provide immediate tactile feedback?
Is the "Robotic Font" (headers) distinct from the "Reading Font" (body)?
Does body text use a highly readable sans-serif?
Are font weights appropriate for dark backgrounds?
Is line height sufficient for readability?
Do monospaced fonts appear only in code blocks and technical labels?
Do the color accents (Neon Cyan/Electric Amber) pass WCAG AA contrast ratios?
Is the dark background truly dark enough?
Are color meanings consistent across the interface?
Do gradients add depth without creating readability issues?
Is there sufficient contrast in disabled states?
Do borders and frames feel "engineered"?
Are spacing values consistent with a mathematical scale?
Do card components use HUD-style corner brackets?
Is the grid system visible or implied through alignment?
Does negative space feel intentional, not accidental?
Do loading states use technical/industrial patterns?
Are click targets appropriately sized for precision?
Do error messages use the industrial color vocabulary?
Mandate: Dark-mode-first aesthetic with high-tech industrial character.
--bg-primary: #0a0e1a; /* Deep space black */
--bg-secondary: #151922; /* Elevated surface */
--bg-tertiary: #1f242f; /* Card/modal background */
--gray-900: #0f1419; /* Darkest structural element */
--gray-800: #1f2937; /* Border/divider */
--gray-700: #374151; /* Subtle border */
--gray-600: #4b5563; /* Disabled text */
--gray-500: #6b7280; /* Secondary text */
--gray-400: #9ca3af; /* Tertiary text */
--gray-300: #d1d5db; /* Primary text on dark */
--metal-dark: #3e4451; /* Gunmetal */
--metal-base: #5c6370; /* Steel */
--metal-light: #abb2bf; /* Brushed aluminum */
--neon-cyan: #00f3ff; /* Primary active/interactive */
--neon-green: #00ff85; /* Success/confirmation */
--electric-amber: #ffb627; /* Warning/attention */
--alert-red: #ff3b3b; /* Error/critical */
--data-purple: #bd93f9; /* Data visualization */
--bg-* hierarchy for layering--gray-300 for primary, --gray-400 for secondary--gray-700 for subtle, --metal-dark for prominentMandate: Separate display typography (technical, futuristic) from reading typography (highly legible).
Headers & UI Elements (Technical)
--font-display: 'Rajdhani', 'Orbitron', 'Exo 2', system-ui, sans-serif;
Body Text (Readability)
--font-body: 'Inter', 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
Code & Data (Monospace)
--font-mono: 'Fira Code', 'JetBrains Mono', 'Source Code Pro', monospace;
--fw-normal: 400; /* Body text */
--fw-medium: 500; /* Emphasis on dark backgrounds */
--fw-semibold: 600; /* Subheadings */
--fw-bold: 700; /* Primary headings */
--fw-extrabold: 800; /* Hero titles (Orbitron only) */
--text-xs: 0.64rem; /* 10.24px - Labels, captions */
--text-sm: 0.8rem; /* 12.8px - Small UI text */
--text-base: 1rem; /* 16px - Body text */
--text-lg: 1.25rem; /* 20px - Subheadings */
--text-xl: 1.563rem; /* 25px - Section headings */
--text-2xl: 1.953rem; /* 31.25px - Page headings */
--text-3xl: 2.441rem; /* 39px - Hero text */
--text-4xl: 3.052rem; /* 48.8px - Display */
Mandate: Animations must feel mechanical, precise, and purposeful — never bouncy or organic.
/* Preferred: Engineered curves */
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1); /* Decelerating precision */
--ease-sharp: cubic-bezier(0.4, 0, 0.6, 1); /* Instant response */
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Minimal overshoot */
/* Forbidden: Organic curves */
/* DO NOT USE ease-in-out, ease, or default transitions */
--duration-instant: 100ms; /* Hover feedback */
--duration-fast: 200ms; /* State changes */
--duration-base: 300ms; /* Panel transitions */
--duration-slow: 500ms; /* Page transitions */
--duration-cinematic: 800ms; /* Hero animations (rare) */
1. Terminal Typing Effect (Code Blocks)
@keyframes terminal-type {
from {
width: 0;
opacity: 0;
}
to {
width: 100%;
opacity: 1;
}
}
.code-block {
animation: terminal-type 0.6s var(--ease-out-quart) forwards;
overflow: hidden;
}
2. Neon Breathing Glow (Interactive Elements)
@keyframes neon-pulse {
0%, 100% {
box-shadow: 0 0 8px var(--neon-cyan),
0 0 16px var(--neon-cyan);
}
50% {
box-shadow: 0 0 12px var(--neon-cyan),
0 0 24px var(--neon-cyan);
}
}
.interactive:hover {
animation: neon-pulse 2s ease-in-out infinite;
}
3. Border Draw-In (Hover States)
.card {
position: relative;
border: 1px solid transparent;
transition: border-color var(--duration-fast) var(--ease-sharp);
}
.card::before {
content: '';
position: absolute;
inset: 0;
border: 1px solid var(--neon-cyan);
opacity: 0;
transition: opacity var(--duration-fast) var(--ease-sharp);
}
.card:hover::before {
opacity: 1;
}
4. Scanline Overlay (Retro CRT Effect)
@keyframes scanline {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(100%);
}
}
.hero::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
transparent 50%,
rgba(0, 243, 255, 0.05) 50%
);
background-size: 100% 4px;
animation: scanline 8s linear infinite;
pointer-events: none;
}
5. Glitch Effect (Error States)
@keyframes glitch {
0%, 100% {
transform: translate(0);
opacity: 1;
}
20% {
transform: translate(-2px, 1px);
opacity: 0.8;
}
40% {
transform: translate(2px, -1px);
opacity: 0.9;
}
60% {
transform: translate(-1px, 2px);
opacity: 0.85;
}
80% {
transform: translate(1px, -2px);
opacity: 0.95;
}
}
.error-message {
animation: glitch 0.3s var(--ease-sharp) 2;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Mandate: UI components should resemble a robot's internal diagnostic display.
.hud-card {
position: relative;
padding: 24px;
background: var(--bg-tertiary);
border: 1px solid var(--gray-700);
}
/* Top-left corner */
.hud-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 16px;
height: 16px;
border-top: 2px solid var(--neon-cyan);
border-left: 2px solid var(--neon-cyan);
}
/* Bottom-right corner */
.hud-card::after {
content: '';
position: absolute;
bottom: 0;
right: 0;
width: 16px;
height: 16px;
border-bottom: 2px solid var(--neon-cyan);
border-right: 2px solid var(--neon-cyan);
}
.data-label {
font-family: var(--font-mono);
font-size: var(--text-xs);
font-weight: var(--fw-semibold);
color: var(--gray-400);
text-transform: uppercase;
letter-spacing: 0.1em;
margin-bottom: 4px;
}
.data-value {
font-family: var(--font-display);
font-size: var(--text-lg);
font-weight: var(--fw-bold);
color: var(--neon-cyan);
}
.status-indicator {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 4px 12px;
background: rgba(0, 243, 255, 0.1);
border: 1px solid var(--neon-cyan);
border-radius: 2px;
font-family: var(--font-mono);
font-size: var(--text-sm);
text-transform: uppercase;
}
.status-indicator::before {
content: '';
width: 6px;
height: 6px;
background: var(--neon-cyan);
border-radius: 50%;
box-shadow: 0 0 8px var(--neon-cyan);
animation: neon-pulse 2s ease-in-out infinite;
}
/* Variants */
.status-indicator.warning {
background: rgba(255, 182, 39, 0.1);
border-color: var(--electric-amber);
}
.status-indicator.warning::before {
background: var(--electric-amber);
box-shadow: 0 0 8px var(--electric-amber);
}
.status-indicator.error {
background: rgba(255, 59, 59, 0.1);
border-color: var(--alert-red);
}
.status-indicator.error::before {
background: var(--alert-red);
box-shadow: 0 0 8px var(--alert-red);
}
.progress-container {
position: relative;
width: 100%;
height: 8px;
background: var(--bg-secondary);
border: 1px solid var(--gray-700);
overflow: hidden;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg,
var(--neon-cyan) 0%,
var(--neon-green) 100%
);
box-shadow: 0 0 12px var(--neon-cyan);
transition: width 0.3s var(--ease-out-quart);
}
.progress-label {
position: absolute;
top: -20px;
right: 0;
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--gray-300);
}
1.1 Import fonts in Docusaurus docusaurus.config.js:
module.exports = {
// ... other config
headTags: [
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://fonts.googleapis.com',
},
},
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://fonts.gstatic.com',
crossorigin: 'anonymous',
},
},
{
tagName: 'link',
attributes: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Rajdhani:wght@400;500;600;700&family=Inter:wght@400;500;600;700&family=Fira+Code:wght@400;500;600&display=swap',
},
},
],
};
1.2 Apply fonts in src/css/custom.css:
:root {
/* Typography */
--ifm-font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--ifm-heading-font-family: 'Rajdhani', system-ui, sans-serif;
--ifm-font-family-monospace: 'Fira Code', 'Consolas', monospace;
/* Font weights */
--ifm-font-weight-base: 400;
--ifm-font-weight-semibold: 600;
--ifm-font-weight-bold: 700;
}
2.1 Create the Neon Cyber palette in src/css/custom.css:
:root {
/* ===== Background Layers ===== */
--ifm-background-color: #0a0e1a;
--ifm-background-surface-color: #151922;
--ifm-card-background-color: #1f242f;
/* ===== Text Colors ===== */
--ifm-font-color-base: #d1d5db;
--ifm-color-content: #9ca3af;
--ifm-color-content-secondary: #6b7280;
/* ===== Primary (Neon Cyan) ===== */
--ifm-color-primary: #00f3ff;
--ifm-color-primary-dark: #00d9e6;
--ifm-color-primary-darker: #00c7d3;
--ifm-color-primary-darkest: #00a3ad;
--ifm-color-primary-light: #1affff;
--ifm-color-primary-lighter: #33ffff;
--ifm-color-primary-lightest: #66ffff;
/* ===== Success (Neon Green) ===== */
--ifm-color-success: #00ff85;
--ifm-color-success-dark: #00e676;
--ifm-color-success-darker: #00d968;
--ifm-color-success-darkest: #00b355;
/* ===== Warning (Electric Amber) ===== */
--ifm-color-warning: #ffb627;
--ifm-color-warning-dark: #e6a323;
--ifm-color-warning-darker: #d99a21;
--ifm-color-warning-darkest: #b3801b;
/* ===== Danger (Alert Red) ===== */
--ifm-color-danger: #ff3b3b;
--ifm-color-danger-dark: #e63535;
--ifm-color-danger-darker: #d93232;
--ifm-color-danger-darkest: #b32929;
/* ===== Neutral Grays ===== */
--gray-900: #0f1419;
--gray-800: #1f2937;
--gray-700: #374151;
--gray-600: #4b5563;
--gray-500: #6b7280;
--gray-400: #9ca3af;
--gray-300: #d1d5db;
/* ===== Borders ===== */
--ifm-color-emphasis-300: #374151; /* Subtle borders */
--ifm-color-emphasis-600: #4b5563; /* Medium borders */
--ifm-color-emphasis-900: #6b7280; /* Strong borders */
/* ===== Code Blocks ===== */
--ifm-code-background: #151922;
--ifm-code-color: #00f3ff;
--docusaurus-highlighted-code-line-bg: rgba(0, 243, 255, 0.1);
/* ===== Spacing & Effects ===== */
--ifm-global-shadow-lw: 0 1px 2px 0 rgba(0, 243, 255, 0.1);
--ifm-global-shadow-md: 0 4px 8px 0 rgba(0, 243, 255, 0.15);
--ifm-global-shadow-tl: 0 12px 24px 0 rgba(0, 243, 255, 0.2);
/* ===== Animation Variables ===== */
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
--ease-sharp: cubic-bezier(0.4, 0, 0.6, 1);
--duration-fast: 200ms;
--duration-base: 300ms;
}
/* Dark mode (already default) - reinforce */
[data-theme='dark'] {
--ifm-background-color: #0a0e1a;
--ifm-font-color-base: #d1d5db;
}
3.1 Neon glow on interactive elements:
/* Add to custom.css */
.button--primary,
.navbar__link--active,
.menu__link--active {
position: relative;
transition: all var(--duration-fast) var(--ease-sharp);
}
.button--primary:hover,
.navbar__link--active:hover,
.menu__link--active:hover {
box-shadow: 0 0 12px var(--ifm-color-primary),
0 0 24px var(--ifm-color-primary);
border-color: var(--ifm-color-primary);
}
/* Breathing animation for active states */
@keyframes neon-breathe {
0%, 100% {
box-shadow: 0 0 8px var(--ifm-color-primary);
}
50% {
box-shadow: 0 0 16px var(--ifm-color-primary),
0 0 24px var(--ifm-color-primary);
}
}
.navbar__link--active {
animation: neon-breathe 3s ease-in-out infinite;
}
3.2 Corner brackets for cards:
/* Add to custom.css */
.card {
position: relative;
background: var(--ifm-card-background-color);
border: 1px solid var(--gray-700);
padding: 1.5rem;
transition: border-color var(--duration-base) var(--ease-sharp);
}
/* Top-left bracket */
.card::before {
content: '';
position: absolute;
top: -1px;
left: -1px;
width: 20px;
height: 20px;
border-top: 2px solid var(--ifm-color-primary);
border-left: 2px solid var(--ifm-color-primary);
opacity: 0;
transition: opacity var(--duration-base) var(--ease-sharp);
}
/* Bottom-right bracket */
.card::after {
content: '';
position: absolute;
bottom: -1px;
right: -1px;
width: 20px;
height: 20px;
border-bottom: 2px solid var(--ifm-color-primary);
border-right: 2px solid var(--ifm-color-primary);
opacity: 0;
transition: opacity var(--duration-base) var(--ease-sharp);
}
.card:hover::before,
.card:hover::after {
opacity: 1;
}
.card:hover {
border-color: var(--gray-600);
}
3.3 Scanline overlay for hero sections:
/* Add to custom.css */
.hero {
position: relative;
overflow: hidden;
}
.hero::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 243, 255, 0.03) 2px,
rgba(0, 243, 255, 0.03) 4px
);
pointer-events: none;
animation: scanline-move 8s linear infinite;
}
@keyframes scanline-move {
0% {
transform: translateY(0);
}
100% {
transform: translateY(50px);
}
}
3.4 Reduced motion support:
/* Add to custom.css - CRITICAL for accessibility */
@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;
}
}
Component: ChapterCard.tsx
import React from 'react';
import styles from './ChapterCard.module.css';
interface ChapterCardProps {
number: string;
title: string;
description: string;
status: 'active' | 'completed' | 'locked';
onClick: () => void;
}
export const ChapterCard: React.FC<ChapterCardProps> = ({
number,
title,
description,
status,
onClick,
}) => {
return (
<div className={`${styles.chapterCard} ${styles[status]}`} onClick={onClick}>
<div className={styles.header}>
<span className={styles.chapterNumber}>{number}</span>
<span className={styles.statusIndicator}>
<span className={styles.statusDot} />
{status.toUpperCase()}
</span>
</div>
<h3 className={styles.title}>{title}</h3>
<p className={styles.description}>{description}</p>
</div>
);
};
Styles: ChapterCard.module.css
.chapterCard {
position: relative;
background: var(--ifm-card-background-color);
border: 1px solid var(--gray-700);
padding: 24px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.25, 1, 0.5, 1);
overflow: hidden;
}
/* Corner brackets */
.chapterCard::before,
.chapterCard::after {
content: '';
position: absolute;
width: 20px;
height: 20px;
opacity: 0;
transition: opacity 0.3s cubic-bezier(0.4, 0, 0.6, 1);
}
.chapterCard::before {
top: -1px;
left: -1px;
border-top: 2px solid var(--ifm-color-primary);
border-left: 2px solid var(--ifm-color-primary);
}
.chapterCard::after {
bottom: -1px;
right: -1px;
border-bottom: 2px solid var(--ifm-color-primary);
border-right: 2px solid var(--ifm-color-primary);
}
.chapterCard:hover::before,
.chapterCard:hover::after {
opacity: 1;
}
.chapterCard:hover {
border-color: var(--gray-600);
box-shadow: 0 0 12px rgba(0, 243, 255, 0.2);
transform: translateY(-2px);
}
/* Header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.chapterNumber {
font-family: var(--ifm-font-family-monospace);
font-size: var(--text-xs);
font-weight: 600;
color: var(--gray-400);
text-transform: uppercase;
letter-spacing: 0.1em;
}
.statusIndicator {
display: inline-flex;
align-items: center;
gap: 6px;
font-family: var(--ifm-font-family-monospace);
font-size: 10px;
font-weight: 600;
color: var(--gray-400);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.statusDot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--gray-500);
}
/* Status variants */
.active .statusDot {
background: var(--ifm-color-primary);
box-shadow: 0 0 8px var(--ifm-color-primary);
animation: neon-pulse 2s ease-in-out infinite;
}
.completed .statusDot {
background: var(--ifm-color-success);
}
.locked .statusDot {
background: var(--gray-600);
}
.locked {
opacity: 0.5;
cursor: not-allowed;
}
/* Content */
.title {
font-family: var(--ifm-heading-font-family);
font-size: var(--text-xl);
font-weight: 700;
color: var(--ifm-font-color-base);
margin: 0 0 8px 0;
line-height: 1.3;
}
.description {
font-size: var(--text-sm);
color: var(--ifm-color-content);
line-height: 1.6;
margin: 0;
}
/* Animations */
@keyframes neon-pulse {
0%, 100% {
box-shadow: 0 0 4px var(--ifm-color-primary);
}
50% {
box-shadow: 0 0 12px var(--ifm-color-primary);
}
}
@media (prefers-reduced-motion: reduce) {
.chapterCard {
transition: none;
transform: none !important;
}
.statusDot {
animation: none !important;
}
}
Custom Docusaurus component: src/theme/CodeBlock/index.tsx
import React from 'react';
import CodeBlock from '@theme-original/CodeBlock';
import styles from './styles.module.css';
export default function CodeBlockWrapper(props) {
return (
<div className={styles.terminalWrapper}>
<div className={styles.terminalHeader}>
<div className={styles.terminalButtons}>
<span className={styles.terminalButton} style={{ background: '#ff3b3b' }} />
<span className={styles.terminalButton} style={{ background: '#ffb627' }} />
<span className={styles.terminalButton} style={{ background: '#00ff85' }} />
</div>
<span className={styles.terminalTitle}>terminal</span>
</div>
<CodeBlock {...props} />
</div>
);
}
Styles: src/theme/CodeBlock/styles.module.css
.terminalWrapper {
position: relative;
background: #0a0e1a;
border: 1px solid var(--gray-700);
border-radius: 4px;
overflow: hidden;
margin: 1rem 0;
}
.terminalHeader {
display: flex;
align-items: center;
padding: 8px 12px;
background: #151922;
border-bottom: 1px solid var(--gray-700);
}
.terminalButtons {
display: flex;
gap: 6px;
margin-right: 12px;
}
.terminalButton {
width: 12px;
height: 12px;
border-radius: 50%;
opacity: 0.8;
transition: opacity 0.2s;
}
.terminalButton:hover {
opacity: 1;
}
.terminalTitle {
font-family: var(--ifm-font-family-monospace);
font-size: 11px;
color: var(--gray-400);
text-transform: uppercase;
letter-spacing: 0.05em;
}
/* Enhanced code block styling */
.terminalWrapper :global(.prism-code) {
background: #0a0e1a !important;
padding: 16px !important;
font-size: 14px;
line-height: 1.6;
}
/* Syntax highlighting with neon colors */
.terminalWrapper :global(.token.keyword) {
color: var(--ifm-color-primary);
}
.terminalWrapper :global(.token.string) {
color: var(--ifm-color-success);
}
.terminalWrapper :global(.token.number) {
color: var(--ifm-color-warning);
}
.terminalWrapper :global(.token.comment) {
color: var(--gray-500);
font-style: italic;
}
Component: SystemStatusPanel.tsx
import React from 'react';
import styles from './SystemStatusPanel.module.css';
interface MetricProps {
label: string;
value: string;
unit?: string;
status: 'normal' | 'warning' | 'critical';
}
const Metric: React.FC<MetricProps> = ({ label, value, unit, status }) => (
<div className={`${styles.metric} ${styles[status]}`}>
<div className={styles.metricLabel}>{label}</div>
<div className={styles.metricValue}>
{value}
{unit && <span className={styles.metricUnit}>{unit}</span>}
</div>
</div>
);
export const SystemStatusPanel: React.FC = () => {
return (
<div className={styles.panel}>
<div className={styles.panelHeader}>
<h3 className={styles.panelTitle}>SYSTEM STATUS</h3>
<div className={styles.timestamp}>
{new Date().toISOString().split('T')[0]}
</div>
</div>
<div className={styles.metricsGrid}>
<Metric label="CPU LOAD" value="42" unit="%" status="normal" />
<Metric label="MEMORY" value="8.2" unit="GB" status="normal" />
<Metric label="TEMP" value="67" unit="°C" status="warning" />
<Metric label="UPTIME" value="99.8" unit="%" status="normal" />
</div>
</div>
);
};
Styles: SystemStatusPanel.module.css
.panel {
position: relative;
background: var(--ifm-card-background-color);
border: 1px solid var(--gray-700);
padding: 0;
overflow: hidden;
}
/* Top-left corner accent */
.panel::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 24px;
height: 24px;
border-top: 2px solid var(--ifm-color-primary);
border-left: 2px solid var(--ifm-color-primary);
}
/* Bottom-right corner accent */
.panel::after {
content: '';
position: absolute;
bottom: 0;
right: 0;
width: 24px;
height: 24px;
border-bottom: 2px solid var(--ifm-color-primary);
border-right: 2px solid var(--ifm-color-primary);
}
.panelHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
background: linear-gradient(90deg,
rgba(0, 243, 255, 0.05) 0%,
transparent 100%
);
border-bottom: 1px solid var(--gray-700);
}
.panelTitle {
font-family: var(--ifm-heading-font-family);
font-size: var(--text-sm);
font-weight: 700;
color: var(--ifm-color-primary);
margin: 0;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.timestamp {
font-family: var(--ifm-font-family-monospace);
font-size: var(--text-xs);
color: var(--gray-400);
}
.metricsGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1px;
background: var(--gray-700);
padding: 0;
}
.metric {
padding: 20px;
background: var(--ifm-card-background-color);
text-align: center;
transition: background 0.2s;
}
.metric:hover {
background: var(--ifm-background-surface-color);
}
.metricLabel {
font-family: var(--ifm-font-family-monospace);
font-size: var(--text-xs);
font-weight: 600;
color: var(--gray-400);
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.metricValue {
font-family: var(--ifm-heading-font-family);
font-size: var(--text-2xl);
font-weight: 700;
line-height: 1;
}
.metricUnit {
font-size: var(--text-sm);
margin-left: 4px;
opacity: 0.7;
}
/* Status colors */
.normal .metricValue {
color: var(--ifm-color-primary);
}
.warning .metricValue {
color: var(--ifm-color-warning);
}
.critical .metricValue {
color: var(--ifm-color-danger);
animation: critical-pulse 1s ease-in-out infinite;
}
@keyframes critical-pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.6;
}
}
Before deploying the robotics theme, verify:
prefers-reduced-motionFinal Note: This design system is a living specification. As the Physical AI textbook evolves, refine these patterns based on user feedback and pedagogical effectiveness. The goal is always: look like high-tech industrial software while remaining an accessible, readable educational resource.
A definitive guide to implementing the OpenAI ChatKit UI, ensuring seamless connection to backend Agents and correct rendering of streaming events.
A strict security and implementation guide for Better Auth, focusing on schema extension for personalization and seamless Express.js integration.
A strict protocol for using Context7 tools to fetch accurate, up-to-date documentation without hallucinating library IDs.
A pedagogical framework for explaining complex Physical AI concepts with clarity, empathy, and effective scaffolding.
A definitive guide to high-performance, async-first FastAPI development using Pydantic v2 and Python 3.12+ standards.
A specialized guide for Docusaurus i18n, focusing on bidirectional layout (LTR/RTL) support and accurate Urdu translation integration.