/* ─────────────────────────── tokens ─────────────────────────── */ :root { --bg: #f6f6f4; --surface: #ffffff; --surface-2: #fbfbfa; --sunken: #f0efec; --border: #e3e1dc; --border-strong: #d0cdc6; --text: #1c1b19; --text-dim: #6b6862; --text-faint: #948f86; --accent: #d97706; --accent-text: #ffffff; --accent-soft: #fdf3e3; --accent-border: #f0d9ae; --warn-bg: #fff8e6; --warn-border: #ecd28a; --warn-text: #7a5510; --danger: #b42318; --term-bg: #1c1b19; --term-text: #e9e6df; --term-flag: #f0b459; --term-val: #9fd0a8; --term-cmd: #8fbcf5; --radius: 10px; --radius-sm: 7px; --shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.04); --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif; color-scheme: light; } :root[data-theme="dark"] { --bg: #121211; --surface: #1b1b1a; --surface-2: #201f1e; --sunken: #161615; --border: #302f2d; --border-strong: #43413e; --text: #eceae5; --text-dim: #a29d95; --text-faint: #7b756c; --accent: #f0a93c; --accent-text: #1c1b19; --accent-soft: #2a2318; --accent-border: #4a3c22; --warn-bg: #2a2318; --warn-border: #57451f; --warn-text: #e8c583; --danger: #f0705f; --term-bg: #0e0e0d; --term-text: #e9e6df; --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px rgba(0, 0, 0, 0.25); color-scheme: dark; } * { box-sizing: border-box; } html { scroll-behavior: smooth; scroll-padding-top: 7.5rem; } body { margin: 0; background: var(--bg); color: var(--text); font: 400 15px/1.55 var(--sans); -webkit-font-smoothing: antialiased; } a { color: var(--accent); } code { font-family: var(--mono); font-size: 0.88em; background: var(--sunken); border: 1px solid var(--border); border-radius: 4px; padding: 0.08em 0.34em; white-space: nowrap; } .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } .skip-link { position: absolute; left: -9999px; } .skip-link:focus { left: 1rem; top: 1rem; z-index: 100; background: var(--surface); padding: 0.6rem 1rem; border-radius: var(--radius-sm); border: 1px solid var(--border-strong); } /* ─────────────────────────── topbar ─────────────────────────── */ .topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.85rem 1.5rem; background: color-mix(in srgb, var(--surface) 88%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); } .topbar__brand { display: flex; align-items: center; gap: 0.8rem; min-width: 0; } /* The LeRobot wordmark is black-on-transparent, so on a dark ground it needs a * light plate rather than a filter — inverting would ruin the orange mark. */ .logo { display: block; height: 40px; width: auto; /* The source PNG carries generous transparent padding; reclaim some of it. */ margin: -7px -4px; } :root[data-theme="dark"] .logo { background: #fff; border-radius: 7px; padding: 2px 6px; margin: -5px 0; } .topbar h1 { margin: 0; font-size: 1.02rem; font-weight: 650; letter-spacing: -0.01em; } .topbar__sub { margin: 0.1rem 0 0; font-size: 0.8rem; color: var(--text-dim); } .topbar__actions { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; } .saved-pill { font-size: 0.74rem; color: var(--text-dim); background: var(--sunken); border: 1px solid var(--border); border-radius: 999px; padding: 0.22rem 0.6rem; transition: color 0.2s, border-color 0.2s; } .saved-pill[data-state="saved"] { color: var(--accent); border-color: var(--accent-border); } .saved-pill[data-state="blocked"] { color: var(--warn-text); background: var(--warn-bg); border-color: var(--warn-border); } /* ─────────────────────────── layout ─────────────────────────── */ .layout { display: grid; grid-template-columns: 330px minmax(0, 1fr); gap: 1.15rem; max-width: 1520px; margin: 0 auto; padding: 1.15rem; align-items: start; } .sidebar { position: sticky; top: 4.6rem; display: flex; flex-direction: column; gap: 0.7rem; max-height: calc(100vh - 6.2rem); overflow-y: auto; padding-right: 0.35rem; scrollbar-width: thin; } .steps { display: flex; flex-direction: column; gap: 1.1rem; min-width: 0; } /* ─────────────────────────── panels ─────────────────────────── */ .panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.8rem 0.9rem 0.9rem; box-shadow: var(--shadow); } .panel--profiles { border-color: var(--accent-border); background: linear-gradient(var(--accent-soft), var(--surface) 70%); } .panel__head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; } .panel__title { margin: 0 0 0.15rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-dim); } .panel__hint { margin: 0 0 0.7rem; font-size: 0.78rem; line-height: 1.45; color: var(--text-dim); } .type-note { margin: -0.2rem 0 0.75rem; font-size: 0.76rem; line-height: 1.45; color: var(--text-dim); } .type-note:empty { display: none; } /* ─────────────────────────── form ─────────────────────────── */ .field { display: block; margin-bottom: 0.6rem; } .field:last-child { margin-bottom: 0; } .field__label { display: block; font-size: 0.78rem; font-weight: 550; color: var(--text); margin-bottom: 0.28rem; } .field__hint { display: block; margin-top: 0.28rem; font-size: 0.74rem; line-height: 1.45; color: var(--text-faint); } .field__hint code { font-size: 0.92em; white-space: normal; } input[type="text"], input[type="number"], select { width: 100%; font: inherit; font-size: 0.85rem; color: var(--text); background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 0.44rem 0.55rem; transition: border-color 0.15s, box-shadow 0.15s; } input[type="text"], input[type="number"] { font-family: var(--mono); font-size: 0.8rem; } select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%), linear-gradient(135deg, var(--text-dim) 50%, transparent 50%); background-position: calc(100% - 15px) 51%, calc(100% - 10px) 51%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 1.8rem; cursor: pointer; } input:focus-visible, select:focus-visible, button:focus-visible, a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; } input::placeholder { color: var(--text-faint); } .check { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.81rem; line-height: 1.4; margin-bottom: 0.45rem; cursor: pointer; } .check:last-child { margin-bottom: 0; } .check input { margin: 0.18rem 0 0; accent-color: var(--accent); flex-shrink: 0; } .check code { white-space: normal; } .check-row { display: flex; flex-wrap: wrap; gap: 0.35rem 1.25rem; margin: 0.35rem 0 0.55rem; } .check-row .check { margin-bottom: 0; } /* buttons */ .btn { font: inherit; font-size: 0.82rem; font-weight: 550; color: var(--text); background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 0.36rem 0.7rem; cursor: pointer; transition: background 0.15s, border-color 0.15s, transform 0.06s; white-space: nowrap; } .btn:hover { background: var(--sunken); border-color: var(--text-faint); } .btn:active { transform: translateY(1px); } .btn--sm { font-size: 0.76rem; padding: 0.28rem 0.55rem; } .btn--ghost { background: transparent; border-color: var(--border); color: var(--text-dim); } .btn--danger:hover { color: var(--danger); border-color: var(--danger); } /* Leading "use the value from the previous step" buttons. */ .btn--fill { background: var(--accent-soft); border-color: var(--accent-border); color: var(--text); flex-shrink: 0; } .btn--fill:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-text); } .btn--accent { background: var(--accent); border-color: var(--accent); color: var(--accent-text); text-decoration: none; display: inline-block; } .btn--accent:hover { filter: brightness(1.06); background: var(--accent); border-color: var(--accent); } .btn[disabled] { opacity: 0.45; cursor: not-allowed; } .btn-row { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.6rem; } .btn-row--tight { margin-top: 0.35rem; padding-top: 0.55rem; border-top: 1px solid var(--border); } /* cameras */ .camera-list { display: flex; flex-direction: column; gap: 0.55rem; } .camera { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.6rem; } .camera__top { display: flex; gap: 0.35rem; align-items: center; margin-bottom: 0.4rem; } .camera__top input { flex: 1; min-width: 0; } .camera__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.35rem; } .camera__grid select { grid-column: 1 / -1; } .camera__x { border: none; background: none; color: var(--text-faint); font-size: 1.05rem; line-height: 1; padding: 0.1rem 0.3rem; cursor: pointer; border-radius: 4px; flex-shrink: 0; } .camera__x:hover { color: var(--danger); background: var(--sunken); } .camera-empty { font-size: 0.78rem; color: var(--text-faint); font-style: italic; } /* ─────────────────────────── step nav ─────────────────────────── */ .stepnav { display: flex; flex-wrap: wrap; gap: 0.3rem; background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 0.35rem; box-shadow: var(--shadow); position: sticky; top: 4.6rem; z-index: 20; } .stepnav a { flex: 1; display: flex; align-items: center; justify-content: center; gap: 0.35rem; text-decoration: none; color: var(--text-dim); font-size: 0.81rem; font-weight: 550; line-height: 1.35; padding: 0.36rem 0.7rem; border-radius: 999px; white-space: nowrap; transition: background 0.15s, color 0.15s; } .stepnav a:hover { background: var(--sunken); color: var(--text); } .stepnav a.is-active { background: var(--accent); color: var(--accent-text); } .stepnav b { display: grid; place-items: center; flex: 0 0 auto; width: 1.2rem; height: 1.2rem; border-radius: 50%; background: var(--sunken); border: 1px solid var(--border-strong); font-size: 0.7rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; } .stepnav a.is-active b { background: var(--accent-text); border-color: transparent; color: var(--accent); } /* ─────────────────────────── prerequisites ─────────────────────────── */ .prereq { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.7rem 1rem 0.75rem; box-shadow: var(--shadow); } .prereq__lead { margin: 0 0 0.4rem; font-size: 0.81rem; color: var(--text-dim); } .prereq__lead strong { color: var(--text); font-weight: 600; } .prereq__links { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0; } .prereq__links a { font-size: 0.78rem; font-weight: 550; text-decoration: none; color: var(--text); background: var(--sunken); border: 1px solid var(--border-strong); border-radius: 999px; padding: 0.22rem 0.65rem; transition: background 0.15s, border-color 0.15s, color 0.15s; } .prereq__links a:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-text); } .prereq__links a[hidden] { display: none; } .prereq__extra { margin: 0.5rem 0 0; font-size: 0.76rem; color: var(--text-faint); } .prereq__extra:empty { display: none; } .prereq__extra code { white-space: normal; } /* ─────────────────────────── warnings ─────────────────────────── */ .warnings { background: var(--warn-bg); border: 1px solid var(--warn-border); border-radius: var(--radius); padding: 0.75rem 1rem; color: var(--warn-text); font-size: 0.84rem; } .warnings ul { margin: 0; padding-left: 1.15rem; } .warnings li + li { margin-top: 0.25rem; } .warnings code { background: color-mix(in srgb, var(--warn-text) 12%, transparent); border-color: var(--warn-border); color: inherit; } /* ─────────────────────────── steps ─────────────────────────── */ .step { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; } .step__head { display: flex; align-items: center; gap: 0.75rem; padding: 0.78rem 1.1rem; border-bottom: 1px solid var(--border); background: var(--surface-2); } .step__num { display: grid; place-items: center; width: 1.9rem; height: 1.9rem; flex-shrink: 0; border-radius: 50%; background: var(--accent); color: var(--accent-text); font-size: 0.88rem; font-weight: 700; font-variant-numeric: tabular-nums; } .step__title { margin: 0; font-size: 1rem; font-weight: 640; letter-spacing: -0.01em; } .step__sub { margin: 0.12rem 0 0; font-size: 0.82rem; color: var(--text-dim); } .step__body { display: grid; grid-template-columns: minmax(0, 1fr) 300px; } .step__main { padding: 0.95rem 1.1rem 1.05rem; min-width: 0; display: flex; flex-direction: column; gap: 0.7rem; } .step__aside { padding: 0.95rem 1.1rem; border-left: 1px solid var(--border); background: var(--sunken); font-size: 0.79rem; line-height: 1.5; color: var(--text-dim); } .step__aside h3 { margin: 0.85rem 0 0.3rem; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text); } .step__aside h3:first-child { margin-top: 0; } .step__aside p { margin: 0 0 0.5rem; } .step__aside ul, .step__aside ol { margin: 0 0 0.5rem; padding-left: 1.05rem; } .step__aside li + li { margin-top: 0.22rem; } .step__aside strong { color: var(--text); font-weight: 600; } .step__aside code { white-space: normal; word-break: break-word; } .doclinks { list-style: none; padding: 0 !important; } .doclinks a { text-decoration: none; font-weight: 550; } .doclinks a:hover { text-decoration: underline; } .doclinks li[hidden], .doclinks a[hidden] { display: none; } .sub-head { margin: 0.5rem 0 -0.15rem; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-dim); } .inline-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); gap: 0.5rem 0.7rem; } .field--inline { margin-bottom: 0; } .field--tight { margin: 0.5rem 0 0; } .field--wide { grid-column: 1 / -1; } .repo-input { display: flex; align-items: stretch; gap: 0.3rem; } .repo-input input { /* Never let the step-forward button squeeze the field below readable width; * the row wraps instead, putting the button on its own line. */ flex: 1 1 11rem; min-width: 0; } .repo-input:has(.btn--fill) { flex-wrap: wrap; } .repo-input .btn--fill { flex: 0 0 auto; } .repo-input__prefix { display: grid; place-items: center; padding: 0 0.5rem; font-family: var(--mono); font-size: 0.78rem; color: var(--text-dim); background: var(--sunken); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); white-space: nowrap; max-width: 45%; overflow: hidden; text-overflow: ellipsis; } .link-row { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; } .link-row__note { font-size: 0.78rem; color: var(--text-dim); } /* ─────────────────────────── command blocks ─────────────────────────── */ .cmd { display: flex; flex-direction: column; } .cmd:empty { display: none; } .cmd__head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.4rem 0.7rem 0.4rem 0.85rem; background: var(--surface-2); border: 1px solid var(--border-strong); border-bottom: none; border-radius: var(--radius-sm) var(--radius-sm) 0 0; } .cmd__label { font-size: 0.76rem; font-weight: 600; color: var(--text-dim); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .cmd__copy { font: inherit; font-size: 0.74rem; font-weight: 600; color: var(--text); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 5px; padding: 0.2rem 0.55rem; cursor: pointer; flex-shrink: 0; transition: background 0.15s, color 0.15s, border-color 0.15s; } .cmd__copy:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-text); } .cmd__copy.is-copied { background: var(--accent); border-color: var(--accent); color: var(--accent-text); } .cmd__pre { margin: 0; padding: 0.65rem 0.85rem; background: var(--term-bg); color: var(--term-text); border: 1px solid var(--term-bg); border-radius: 0 0 var(--radius-sm) var(--radius-sm); font-family: var(--mono); font-size: 0.78rem; line-height: 1.5; overflow-x: auto; white-space: pre; tab-size: 2; } .cmd__pre .t-cmd { color: var(--term-cmd); font-weight: 600; } .cmd__pre .t-flag { color: var(--term-flag); } .cmd__pre .t-val { color: var(--term-val); } .cmd__pre .t-comment { color: #8a857c; font-style: italic; } .cmd__note { margin: 0.32rem 0 0; font-size: 0.78rem; line-height: 1.5; color: var(--text-dim); } .cmd__note code { white-space: normal; } .cmd--muted .cmd__pre { opacity: 0.55; } /* ─────────────────────────── toast ─────────────────────────── */ .toast { position: fixed; bottom: 1.5rem; left: 50%; transform: translateX(-50%); z-index: 60; background: var(--term-bg); color: var(--term-text); font-size: 0.83rem; font-weight: 550; padding: 0.55rem 1.1rem; border-radius: 999px; box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28); animation: toast-in 0.18s ease-out; } @keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } } /* ─────────────────────────── footer ─────────────────────────── */ .foot { padding: 0.5rem 0.25rem 1.5rem; font-size: 0.79rem; color: var(--text-faint); } .foot p { margin: 0 0 0.35rem; } .foot__privacy { color: var(--text-faint); } /* ─────────────────────────── responsive ─────────────────────────── */ @media (max-width: 1180px) { .step__body { grid-template-columns: minmax(0, 1fr); } .step__aside { border-left: none; border-top: 1px solid var(--border); } } @media (max-width: 900px) { .layout { grid-template-columns: minmax(0, 1fr); padding: 1rem; gap: 1rem; } .sidebar { position: static; max-height: none; overflow: visible; padding-right: 0; } .stepnav { top: 4.2rem; overflow-x: auto; border-radius: var(--radius); } .stepnav a { flex: 0 0 auto; } .topbar { padding: 0.7rem 1rem; } .topbar__sub { display: none; } } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } .btn--danger.is-armed { color: var(--accent-text); background: var(--danger); border-color: var(--danger); }