pick an identity to log in as
+ {% for account in accounts %} + + {{ account.initial }} + + {{ account.name }} + {{ account.email }} + + + {% endfor %} + +Order #{response.orderId.slice(0, 8)}
+{formatDate(response.createdAt)}
+ +Shipping to {response.shippingName}
+ )} +{product.description}
+ {hasColors && ( ++ {isFiltered + ? `Showing ${products.length} of ${allProducts.length} products` + : "Official Reboot merch"} +
+UI unavailable
++ ngrok’s free tier puts a browser interstitial in front of some + requests, which prevents this UI from loading. +
+To view this UI, do any one of:
++ {hasMcpTools ? ( + <> + Only a few more steps to get{" "} + {titleReady ? title : "this Reboot app"} working in + the chat client of your choice. + > + ) : ( + <> + {titleReady ? title : "This Reboot app"} is serving + traffic. It doesn't expose any MCP tools yet — here's how to call it + directly. + > + )} +
++ +
+ ) : description ? ( +{description}
+ ) : ( +
+ Add a description= to your Application(...) for a
+ friendlier intro here.
+
` inside body copy. The dedicated code blocks
+ (`.inline-code`, `.code-block`) opt out by sitting in their own
+ class scope and not matching any of these selectors. */
+p code,
+li code,
+.step__intro code,
+.substep__title code,
+.substep__hint code {
+ background: rgba(16, 55, 97, 0.08);
+ padding: 1px 6px;
+ border-radius: 4px;
+ color: var(--navy);
+ font-size: 0.92em;
+}
+
+/* ---------------- Top nav ---------------- */
+
+.top-nav {
+ max-width: 992px;
+ margin: 0 auto;
+ padding: 32px 32px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.top-nav__brand {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ font-size: 15.5px;
+ font-weight: 600;
+ color: var(--navy);
+ letter-spacing: -0.01em;
+}
+
+.top-nav__brand img {
+ height: 20px;
+ width: auto;
+}
+
+.top-nav__divider {
+ color: var(--tan);
+ font-weight: 400;
+}
+
+.top-nav__app-name {
+ color: var(--navy);
+}
+
+.top-nav__actions {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.button {
+ font: inherit;
+ border: 1px solid transparent;
+ border-radius: 999px;
+ padding: 9px 18px;
+ cursor: pointer;
+ font-size: 13.5px;
+ font-weight: 600;
+ letter-spacing: 0.2px;
+ transition: background-color 0.15s ease, border-color 0.15s ease,
+ color 0.15s ease;
+ text-decoration: none;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.button--ghost {
+ background: transparent;
+ color: var(--navy);
+ border-color: transparent;
+}
+.button--ghost:hover {
+ background: rgba(16, 55, 97, 0.08);
+}
+
+.button--outline {
+ background: transparent;
+ color: var(--navy);
+ border-color: var(--navy);
+}
+.button--outline:hover {
+ background: var(--navy);
+ color: var(--cream);
+}
+
+.button--primary {
+ background: var(--navy);
+ color: var(--cream);
+ border-color: var(--navy);
+}
+.button--primary:hover {
+ background: #0c2d57;
+}
+
+.button--small {
+ font-size: 12.5px;
+ padding: 7px 14px;
+}
+
+.button:disabled,
+.button[disabled] {
+ cursor: not-allowed;
+ opacity: 0.45;
+}
+
+/* ---------------- Wizard wrapper + hero ---------------- */
+
+.wizard {
+ max-width: 992px;
+ margin: 0 auto;
+ padding: 24px 32px 96px;
+}
+
+.hero {
+ padding: 48px 0 32px;
+}
+
+.hero__title {
+ margin: 0;
+ font-size: 72px;
+ font-weight: 700;
+ line-height: 1;
+ letter-spacing: -0.036em;
+ color: var(--navy);
+}
+
+.hero__title em,
+.step__title em {
+ font-style: normal;
+ background: var(--highlight);
+ padding: 0 8px;
+ border-radius: 4px;
+ box-decoration-break: clone;
+ -webkit-box-decoration-break: clone;
+}
+
+.hero__subtitle {
+ margin: 20px 0 36px;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.5;
+ color: var(--navy);
+ max-width: 640px;
+}
+
+.app-info {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+ background: var(--surface);
+ border: 1.5px solid var(--navy);
+ border-radius: 14px;
+ padding: 18px 22px;
+ /* Same brand drop-shadow as the picker cards — keeps the page's
+ "block" cards visually consistent. */
+ box-shadow: 6px 6px 0 0 var(--navy);
+}
+
+.app-info__main {
+ min-width: 0;
+}
+
+.app-info__name {
+ font-size: 17px;
+ font-weight: 700;
+ color: var(--navy);
+ margin-bottom: 4px;
+ letter-spacing: -0.005em;
+}
+
+.app-info__description {
+ font-size: 13.5px;
+ font-weight: 400;
+ color: var(--muted);
+ margin: 0;
+}
+
+.app-info__placeholder {
+ font-style: italic;
+ color: var(--tan);
+}
+
+.pill {
+ flex-shrink: 0;
+ display: inline-flex;
+ align-items: center;
+ background: transparent;
+ padding: 0;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+/* App is responding — ✓ glyph and text both in green. */
+.pill--connected {
+ color: var(--success-text, #1f7a52);
+}
+
+/* Reader is (still) trying to (re)connect to the app — ✗ glyph
+ and text both in red so the developer notices the broken
+ state. */
+.pill--connecting {
+ color: #c53030;
+}
+
+/* ---------------- Step cards ---------------- */
+
+.step {
+ display: grid;
+ grid-template-columns: 180px 1fr;
+ column-gap: 48px;
+ border-top: 1.5px solid var(--navy);
+ padding: 64px 0;
+}
+
+.step__index {
+ align-self: start;
+}
+
+.step__number {
+ font-size: 64px;
+ font-weight: 700;
+ color: var(--navy);
+ line-height: 0.9;
+ letter-spacing: -0.031em;
+ font-feature-settings: "tnum" on;
+}
+
+.step__label {
+ margin-top: 12px;
+ font-size: 11.5px;
+ font-weight: 700;
+ color: var(--muted);
+ text-transform: uppercase;
+ letter-spacing: 0.157em;
+}
+
+.step__body {
+ min-width: 0;
+}
+
+.step__title {
+ margin: 0;
+ font-size: 40px;
+ font-weight: 700;
+ line-height: 1.05;
+ letter-spacing: -0.035em;
+ color: var(--navy);
+}
+
+.step__intro {
+ margin: 16px 0 28px;
+ font-size: 15.5px;
+ font-weight: 400;
+ line-height: 1.55;
+ color: var(--muted);
+ max-width: 560px;
+}
+
+/* ---------------- Radio group (shared) ---------------- */
+
+.radio-group {
+ display: grid;
+ /* Column count is set inline by the RadioGroup component to match
+ the option count; mobile breakpoint below collapses it to 1. */
+ grid-template-columns: repeat(var(--radio-columns, 3), 1fr);
+ gap: 10px;
+ margin-top: 4px;
+}
+
+.radio-card {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ background: var(--surface);
+ border: 1.5px solid var(--navy);
+ border-radius: 12px;
+ padding: 10px 14px;
+ cursor: pointer;
+ text-align: left;
+ font: inherit;
+ min-height: 56px;
+ color: var(--navy);
+ /* Hard offset shadow — navy block under each unselected card. */
+ box-shadow: 4px 4px 0 0 var(--navy);
+ transition: background-color 0.15s ease, color 0.15s ease,
+ box-shadow 0.15s ease, transform 0.15s ease;
+}
+
+/* Only the unselected cards behave like clickable buttons; the
+ selected one is the current state, so dim the affordance. */
+.radio-card:not(.radio-card--selected):hover {
+ transform: translate(1px, 1px);
+}
+
+.radio-card--selected {
+ background: var(--navy);
+ color: var(--cream);
+ cursor: default;
+ /* Selected card gets a green shadow instead of navy. */
+ box-shadow: 4px 4px 0 0 var(--green);
+}
+
+.radio-card__name {
+ font-size: 16px;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ color: inherit;
+ flex: 1;
+ text-align: center;
+}
+
+.radio-card__pip {
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ border: 1.5px solid var(--tan);
+ flex-shrink: 0;
+ position: relative;
+}
+
+.radio-card--selected .radio-card__pip {
+ border-color: var(--green);
+}
+
+.radio-card--selected .radio-card__pip::after {
+ content: "";
+ position: absolute;
+ inset: 3px;
+ border-radius: 50%;
+ background: var(--green);
+}
+
+/* ---------------- Substeps ---------------- */
+
+.substep {
+ background: var(--surface);
+ border: 1px solid var(--border);
+ border-radius: 16px;
+ padding: 22px 26px;
+ margin-top: 14px;
+}
+
+.substep__header {
+ display: flex;
+ align-items: flex-start;
+ gap: 14px;
+}
+
+.substep__header-body {
+ flex: 1;
+ min-width: 0;
+ /* Title and hint are ``s (so the interactive header can be
+ a real `