Repository navigation
feat: align mctl-web with the MCTL design system #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,16 +6,54 @@ const { t } = useI18n() | |||||||||||
| <section class="hero-block"> | ||||||||||||
| <div class="hero-block__glow"></div> | ||||||||||||
| <BaseContainer size="md"> | ||||||||||||
| <h1> | ||||||||||||
| {{ t('hero.title') }} | ||||||||||||
| </h1> | ||||||||||||
| <p class="hero-block__description" v-html="t('hero.subtitle')" /> | ||||||||||||
| <BaseButton | ||||||||||||
| size="lg" | ||||||||||||
| @click="$router.push({ hash: '#request-access' })" | ||||||||||||
| > | ||||||||||||
| {{ t('hero.cta') }} | ||||||||||||
| </BaseButton> | ||||||||||||
| <div class="hero-block__intro"> | ||||||||||||
| <span class="hero-block__badge"> | ||||||||||||
| <span class="hero-block__badge-dot"></span> | ||||||||||||
| {{ t('hero.badge') }} | ||||||||||||
| </span> | ||||||||||||
| <h1> | ||||||||||||
| {{ t('hero.title') }} | ||||||||||||
| </h1> | ||||||||||||
| <p class="hero-block__description" v-html="t('hero.subtitle')" /> | ||||||||||||
| <div class="hero-block__actions"> | ||||||||||||
| <BaseButton | ||||||||||||
| size="lg" | ||||||||||||
| @click="$router.push({ hash: '#request-access' })" | ||||||||||||
| > | ||||||||||||
| {{ t('hero.cta') }} | ||||||||||||
| </BaseButton> | ||||||||||||
| <a class="hero-block__secondary" href="/docs"> | ||||||||||||
| {{ t('hero.cta_secondary') }} | ||||||||||||
| <span aria-hidden="true">→</span> | ||||||||||||
| </a> | ||||||||||||
| </div> | ||||||||||||
| </div> | ||||||||||||
|
|
||||||||||||
| <div class="hero-terminal" aria-hidden="true"> | ||||||||||||
| <div class="hero-terminal__bar"> | ||||||||||||
| <span class="hero-terminal__dot hero-terminal__dot--red"></span> | ||||||||||||
| <span class="hero-terminal__dot hero-terminal__dot--amber"></span> | ||||||||||||
| <span class="hero-terminal__dot hero-terminal__dot--green"></span> | ||||||||||||
| <span class="hero-terminal__title">mctl — deploy</span> | ||||||||||||
| </div> | ||||||||||||
| <div class="hero-terminal__body"> | ||||||||||||
| <p class="hero-terminal__line"> | ||||||||||||
| <span class="hero-terminal__prompt">$</span> git push origin main | ||||||||||||
| </p> | ||||||||||||
| <p class="hero-terminal__line hero-terminal__line--muted"> | ||||||||||||
| → building image · running tests · generating manifests | ||||||||||||
| </p> | ||||||||||||
| <p class="hero-terminal__line hero-terminal__line--ok"> | ||||||||||||
| ✓ deployed to <span class="hero-terminal__accent">my-team</span> namespace | ||||||||||||
| </p> | ||||||||||||
| <p class="hero-terminal__line"> | ||||||||||||
| <span class="hero-terminal__prompt">$</span> mctl ask <span class="hero-terminal__str">"roll my-app back to v1.4.2"</span> | ||||||||||||
| </p> | ||||||||||||
| <p class="hero-terminal__line hero-terminal__line--ok"> | ||||||||||||
| ✓ rollback live at <span class="hero-terminal__accent">app.mctl.ai</span><span class="hero-terminal__cursor"></span> | ||||||||||||
| </p> | ||||||||||||
| </div> | ||||||||||||
| </div> | ||||||||||||
| </BaseContainer> | ||||||||||||
| </section> | ||||||||||||
| </template> | ||||||||||||
|
|
@@ -24,7 +62,7 @@ const { t } = useI18n() | |||||||||||
| .hero-block { | ||||||||||||
| position: relative; | ||||||||||||
| padding: 60px 0; | ||||||||||||
| height: calc(100vh - var(--header-height)); | ||||||||||||
| min-height: calc(100vh - var(--header-height)); | ||||||||||||
| display: flex; | ||||||||||||
| align-items: center; | ||||||||||||
| justify-content: center; | ||||||||||||
|
|
@@ -36,9 +74,40 @@ const { t } = useI18n() | |||||||||||
| font-size: clamp(2.5rem, 4.5vw, 4.25rem); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__intro { | ||||||||||||
| position: relative; | ||||||||||||
| z-index: 1; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__badge { | ||||||||||||
| display: inline-flex; | ||||||||||||
| align-items: center; | ||||||||||||
| gap: 0.5rem; | ||||||||||||
| margin-bottom: 1.75rem; | ||||||||||||
| padding: 0.4rem 0.9rem; | ||||||||||||
|
|
||||||||||||
| font-size: 0.75rem; | ||||||||||||
| letter-spacing: 1px; | ||||||||||||
| text-transform: uppercase; | ||||||||||||
| color: var(--color-accent); | ||||||||||||
|
|
||||||||||||
| background: var(--color-accent-soft); | ||||||||||||
| border: 1px solid var(--color-glass-border); | ||||||||||||
| border-radius: 999px; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__badge-dot { | ||||||||||||
| width: 7px; | ||||||||||||
| height: 7px; | ||||||||||||
| border-radius: 50%; | ||||||||||||
| background: var(--color-accent); | ||||||||||||
| box-shadow: 0 0 8px var(--color-accent); | ||||||||||||
| animation: heroPulse 2s ease-in-out infinite; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__description { | ||||||||||||
| max-width: 900px; | ||||||||||||
| margin: 0 auto 48px; | ||||||||||||
| margin: 0 auto 40px; | ||||||||||||
| text-align: center; | ||||||||||||
| font-size: 18px; | ||||||||||||
| color: var(--color-text-muted); | ||||||||||||
|
|
@@ -49,16 +118,141 @@ const { t } = useI18n() | |||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__actions { | ||||||||||||
| display: flex; | ||||||||||||
| align-items: center; | ||||||||||||
| justify-content: center; | ||||||||||||
| flex-wrap: wrap; | ||||||||||||
| gap: 1.25rem; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__secondary { | ||||||||||||
| display: inline-flex; | ||||||||||||
| align-items: center; | ||||||||||||
| gap: 0.5rem; | ||||||||||||
|
|
||||||||||||
| color: var(--color-text-muted); | ||||||||||||
| font-weight: 500; | ||||||||||||
| transition: color 0.25s ease, gap 0.25s ease; | ||||||||||||
|
|
||||||||||||
| span { | ||||||||||||
| transition: transform 0.25s ease; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &:hover { | ||||||||||||
| color: var(--color-accent); | ||||||||||||
|
|
||||||||||||
| span { | ||||||||||||
| transform: translateX(4px); | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__glow { | ||||||||||||
| position: absolute; | ||||||||||||
| top: 20%; | ||||||||||||
| top: 18%; | ||||||||||||
| left: 50%; | ||||||||||||
| transform: translate(-50%, -50%); | ||||||||||||
| width: 60vw; | ||||||||||||
| height: 60vw; | ||||||||||||
| background: radial-gradient(circle, rgba(0, 245, 255, 0.1) 0%, transparent 70%); | ||||||||||||
| width: 70vw; | ||||||||||||
| height: 70vw; | ||||||||||||
| max-width: 900px; | ||||||||||||
| max-height: 900px; | ||||||||||||
| // Quiet ambient wash — restrained per the design system's hairline language. | ||||||||||||
| background: radial-gradient(circle, rgba(0, 229, 255, 0.05) 0%, transparent 65%); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3 — glow uses a raw rgba value that diverges from the token set
Suggested change
|
||||||||||||
| z-index: 0; | ||||||||||||
| pointer-events: none; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // Terminal mockup — gives the hero a concrete focal point and shows | ||||||||||||
| // the core "push / ask AI / live" loop in the product's own voice. | ||||||||||||
| .hero-terminal { | ||||||||||||
| position: relative; | ||||||||||||
| z-index: 1; | ||||||||||||
| max-width: 640px; | ||||||||||||
| margin: 4rem auto 0; | ||||||||||||
|
|
||||||||||||
| text-align: left; | ||||||||||||
| background: var(--color-terminal); | ||||||||||||
| border: 1px solid var(--color-glass-border); | ||||||||||||
| border-radius: 12px; | ||||||||||||
| overflow: hidden; | ||||||||||||
| backdrop-filter: blur(8px); | ||||||||||||
| box-shadow: var(--shadow-card-hover); | ||||||||||||
|
|
||||||||||||
| &__bar { | ||||||||||||
| display: flex; | ||||||||||||
| align-items: center; | ||||||||||||
| gap: 0.5rem; | ||||||||||||
| padding: 0.75rem 1rem; | ||||||||||||
| background: rgba(255, 255, 255, 0.03); | ||||||||||||
| border-bottom: 1px solid rgba(255, 255, 255, 0.06); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__dot { | ||||||||||||
| width: 11px; | ||||||||||||
| height: 11px; | ||||||||||||
| border-radius: 50%; | ||||||||||||
|
|
||||||||||||
| &--red { background: #ff5f56; } | ||||||||||||
| &--amber { background: #ffbd2e; } | ||||||||||||
| &--green { background: #27c93f; } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__title { | ||||||||||||
| margin-left: auto; | ||||||||||||
| font-size: 0.75rem; | ||||||||||||
| color: var(--color-text-muted); | ||||||||||||
| letter-spacing: 0.5px; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__body { | ||||||||||||
| padding: 1.5rem 1.5rem 1.75rem; | ||||||||||||
| // Body inherits the page's Geist now; force mono so the terminal reads | ||||||||||||
| // as a terminal. | ||||||||||||
| font-family: var(--font-mono); | ||||||||||||
| font-size: 0.85rem; | ||||||||||||
| line-height: 1.9; | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2 — terminal content will render in Geist, not monospace
Add an explicit override:
Suggested change
|
||||||||||||
|
|
||||||||||||
| @media (max-width: 480px) { | ||||||||||||
| font-size: 0.72rem; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__line { | ||||||||||||
| margin: 0; | ||||||||||||
|
|
||||||||||||
| &--muted { color: var(--color-text-muted); } | ||||||||||||
| &--ok { color: var(--color-success); } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| &__prompt { color: var(--color-accent); } | ||||||||||||
| &__accent { color: var(--color-accent); } | ||||||||||||
| &__str { color: #ffbd2e; } | ||||||||||||
|
|
||||||||||||
| &__cursor { | ||||||||||||
| display: inline-block; | ||||||||||||
| width: 8px; | ||||||||||||
| height: 1em; | ||||||||||||
| margin-left: 4px; | ||||||||||||
| vertical-align: text-bottom; | ||||||||||||
| background: var(--color-accent); | ||||||||||||
| animation: heroBlink 1.1s step-end infinite; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| @keyframes heroPulse { | ||||||||||||
| 0%, 100% { opacity: 1; transform: scale(1); } | ||||||||||||
| 50% { opacity: 0.4; transform: scale(0.85); } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| @keyframes heroBlink { | ||||||||||||
| 0%, 100% { opacity: 1; } | ||||||||||||
| 50% { opacity: 0; } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| @media (prefers-reduced-motion: reduce) { | ||||||||||||
| .hero-block__badge-dot, | ||||||||||||
| .hero-terminal__cursor { animation: none; } | ||||||||||||
| } | ||||||||||||
| </style> | ||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3 — badge renders in Geist; design intent says eyebrows should use mono
The PR description states "JetBrains Mono retained for chrome (nav, eyebrows, code, terminal)" and the
BaseSectionoverline already hasfont-family: var(--font-mono)added in this PR. Thehero-block__badgeis the same eyebrow-style element; without an override it inherits Geist frombody.