Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 60 additions & 13 deletions mkdocs/assets/stylesheets/cloudscape-docs.css
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@
}
}

/* Both button groups share the header center; clear landing.css's legacy top padding. */
.md-header__inner .cs-products-menu,
.md-header__inner .md-header__buttons {
align-self: center;
padding-block: 0;
}

.md-header__buttons .md-button {
margin-top: 0;
margin-bottom: 0;
Expand Down Expand Up @@ -171,6 +178,7 @@

/* Header action buttons → /old pills. Prefixed with the primary color attr to
out-specify landing.css's button rules. */
.cs-products-menu__trigger,
[data-md-color-primary=white] .md-header__buttons .md-button--primary,
[data-md-color-primary=white] .md-header__buttons .md-button--primary:hover {
box-sizing: border-box;
Expand Down Expand Up @@ -239,35 +247,64 @@

/* Products menu matches website/src/styles.css. */
.cs-products-menu {
--products-arrow-gap: 10px;
--cs-hover: rgba(22, 25, 31, 0.03);
--products-focus-color: #006ce0;
position: relative;
display: inline-flex;
align-items: center;
margin-left: 20px;
font-size: 16px;
line-height: 1.15;
}
[data-md-color-scheme="slate"] .cs-products-menu {
--cs-hover: rgba(242, 243, 243, 0.05);
--products-focus-color: #42b4ff;
}
.cs-products-menu__trigger {
display: inline-flex;
align-items: center;
gap: 4px;
min-height: 42px;
padding: 10px 0;
border: 0;
border-radius: 21px;
position: relative;
gap: var(--products-arrow-gap);
padding-inline: 18px var(--products-arrow-gap);
border: 1px solid var(--cs-border);
background: transparent;
color: var(--cs-text);
font: inherit;
font-weight: 700;
font-family: inherit;
letter-spacing: 0.005em;
cursor: pointer;
}
.cs-products-menu__trigger:hover {
text-decoration: underline;
text-underline-offset: 0.2em;
.cs-products-menu__trigger:hover,
.cs-products-menu__trigger:active {
background: var(--cs-hover);
}
.cs-products-menu__trigger:focus {
outline: none;
}
/* Match the secondary Cloudscape button's keyboard-focus ring. */
.cs-products-menu__trigger:focus-visible {
background: var(--cs-panel);
outline: 2px dotted transparent;
outline-offset: 3px;
}
.cs-products-menu__trigger:focus-visible::before {
content: '';
position: absolute;
inset-inline-start: -4px;
inset-block-start: -4px;
inline-size: calc(100% + 8px);
block-size: calc(100% + 8px);
border-radius: 4px;
box-shadow: 0 0 0 2px var(--products-focus-color);
pointer-events: none;
}
.cs-products-menu__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 12px;
height: 12px;
flex: 0 0 auto;
}
.cs-products-menu__caret {
display: block;
width: 12px;
height: 12px;
transition: transform 0.15s ease;
Expand All @@ -276,18 +313,24 @@
transform: rotate(180deg);
}
.cs-products-menu__popup {
box-sizing: border-box;
display: none;
position: absolute;
top: calc(100% + 6px);
left: 0;
z-index: 1000;
width: 360px;
background: var(--cs-panel);
border: 1px solid var(--cs-border);
border-radius: 8px;
overflow: hidden;
}
.cs-products-menu--open .cs-products-menu__popup {
display: block;
}
.cs-products-menu__popup .gs-rail {
border-radius: 7px;
}
.cs-products-menu__popup .gs-opt + .gs-rail__group {
margin-top: 0;
}
Expand Down Expand Up @@ -334,6 +377,10 @@
background: var(--cs-bg);
box-shadow: inset 0 0 0 0.5px var(--cs-text);
}
.cs-products-menu__popup .gs-opt:hover,
.cs-products-menu__popup .gs-opt:focus-visible {
box-shadow: none;
}
.gs-opt--feat {
padding: 13px 14px;
gap: 14px;
Expand Down
76 changes: 54 additions & 22 deletions mkdocs/overrides/header-2.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@

{# Keep menu descriptions in sync with SiteNavigation.tsx. GetStartedSection.tsx uses a longer dstack description. #}
<div class="cs-products-menu">
<button type="button" class="cs-products-menu__trigger" aria-haspopup="true" aria-expanded="false">
<button type="button" class="cs-products-menu__trigger" id="cs-products-trigger" aria-haspopup="menu" aria-expanded="false" aria-controls="cs-products-popup">
Products
<svg class="cs-products-menu__caret" viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6.5 8 10.5 12 6.5"/></svg>
<span class="cs-products-menu__icon">
<svg class="cs-products-menu__caret" viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6.5 8 10.5 12 6.5"/></svg>
</span>
</button>
<div class="cs-products-menu__popup" role="menu">
<div class="cs-products-menu__popup" id="cs-products-popup" role="menu" aria-labelledby="cs-products-trigger">
<div class="gs-rail">
<div class="gs-rail__group">Self-hosted</div>
<a class="gs-opt gs-opt--feat" role="menuitem" href="/docs/installation">
<a class="gs-opt gs-opt--feat" role="menuitem" tabindex="-1" href="/docs/installation">
<span class="gs-opt__ic" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></svg>
</span>
Expand All @@ -92,7 +94,7 @@
<span class="gs-opt__desc">A unified orchestration interface across GPU clouds, Kubernetes, VMs, and bare-metal.</span>
</span>
</a>
<a class="gs-opt gs-opt--row external-skip" role="menuitem" href="/products/factory" target="_blank" rel="noreferrer">
<a class="gs-opt gs-opt--row external-skip" role="menuitem" tabindex="-1" href="/products/factory" target="_blank" rel="noreferrer">
<span class="gs-opt__ic" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"/><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"/><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"/></svg>
</span>
Expand All @@ -102,7 +104,7 @@
</span>
</a>
<div class="gs-rail__group">Hosted by us</div>
<a class="gs-opt gs-opt--row" role="menuitem" href="/products/sky" target="_blank" rel="noreferrer">
<a class="gs-opt gs-opt--row" role="menuitem" tabindex="-1" href="/products/sky" target="_blank" rel="noreferrer">
<span class="gs-opt__ic" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/></svg>
</span>
Expand Down Expand Up @@ -152,32 +154,62 @@
var productsMenu = document.querySelector('.cs-products-menu');
var productsTrigger = productsMenu && productsMenu.querySelector('.cs-products-menu__trigger');
if (productsTrigger) {
var closeTimer;
var productsItems = Array.from(productsMenu.querySelectorAll('[role="menuitem"]'));
var setProductsOpen = function (open) {
clearTimeout(closeTimer);
productsMenu.classList.toggle('cs-products-menu--open', open);
productsTrigger.setAttribute('aria-expanded', String(open));
};
productsMenu.addEventListener('mouseenter', function () { setProductsOpen(true); });
productsMenu.addEventListener('mouseleave', function () {
closeTimer = setTimeout(function () {
if (!productsMenu.querySelector(':focus-visible')) setProductsOpen(false);
}, 150);
var focusProduct = function (index) {
productsItems.forEach(function (item, itemIndex) {
item.tabIndex = itemIndex === index ? 0 : -1;
});
productsItems[index].focus();
};
productsTrigger.addEventListener('click', function () {
var open = productsTrigger.getAttribute('aria-expanded') !== 'true';
setProductsOpen(open);
if (open) focusProduct(0);
else productsTrigger.focus();
});
productsMenu.addEventListener('keydown', function (e) {
var open = productsTrigger.getAttribute('aria-expanded') === 'true';
if (e.target === productsTrigger && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
e.preventDefault();
setProductsOpen(true);
focusProduct(e.key === 'ArrowUp' ? productsItems.length - 1 : 0);
return;
}
if (!open) return;
if (e.key === 'Escape') {
e.preventDefault();
e.stopPropagation();
setProductsOpen(false);
productsTrigger.focus();
return;
}
var index = productsItems.indexOf(document.activeElement);
var nextIndex;
if (e.key === 'ArrowDown') nextIndex = (index + 1) % productsItems.length;
else if (e.key === 'ArrowUp') nextIndex = index < 0 ? productsItems.length - 1 : (index + productsItems.length - 1) % productsItems.length;
else if (e.key === 'Home') nextIndex = 0;
else if (e.key === 'End') nextIndex = productsItems.length - 1;
else return;
e.preventDefault();
focusProduct(nextIndex);
});
productsItems.forEach(function (item) {
item.addEventListener('click', function () {
setProductsOpen(false);
productsTrigger.focus();
});
});
productsMenu.addEventListener('focusin', function () { setProductsOpen(true); });
productsMenu.addEventListener('focusout', function (e) {
if (!productsMenu.contains(e.relatedTarget)) setProductsOpen(false);
});
productsTrigger.addEventListener('click', function () { setProductsOpen(true); });
document.addEventListener('click', function (e) {
document.addEventListener('pointerdown', function (e) {
if (!productsMenu.contains(e.target)) setProductsOpen(false);
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
if (productsMenu.contains(document.activeElement)) productsTrigger.focus();
setProductsOpen(false);
}
});
window.addEventListener('blur', function () { setProductsOpen(false); });
}
})();
</script>
Expand Down
2 changes: 1 addition & 1 deletion mkdocs/overrides/partials/tx-footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<div class="tx-footer__section">
<div class="tx-footer__section-title">Company</div>
<a href="/blog" class="tx-footer__section-link">Blog</a>
<a href="https://calendly.com/dstackai/discovery-call" target="_blank" class="tx-footer__section-link external">Talk to us</a>
<a href="https://calendly.com/dstackai/discovery-call" target="_blank" class="tx-footer__section-link external">Book a demo</a>
<a href="/terms" class="tx-footer__section-link">Terms of service</a>
<a href="/privacy" class="tx-footer__section-link">Privacy policy</a>
</div>
Expand Down
15 changes: 13 additions & 2 deletions website/src/cloudscape-overrides.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,19 @@ body {
padding: 0 !important;
}

/* 11) Thin (0.5px) dividers between stacked FAQ items. The block's outer corners
are clipped to 12px by .faq-list; these are the internal separators. */
/* 11) The FAQ wrapper owns the outer frame. Remove each stacked container's frame
and shadow, then draw only the separators between questions. */
.faq-list > .faq-item {
border: 0 !important;
border-radius: 0 !important;
}
.faq-list > .faq-item::before,
.faq-list > .faq-item::after {
display: none !important;
}
.faq-list > .faq-item + .faq-item {
border-block-start: 0.5px solid var(--cs-border) !important;
}
.faq-list * {
--border-divider-section-width-uwo8my: 0.5px;
}
31 changes: 21 additions & 10 deletions website/src/components/Capabilities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,29 @@ import { ReactNode } from 'react';
import { asset } from '../asset';

// Icon, title, and description rows shared by the landing and product pages.
export function CapList({ items }: { items: { icon: ReactNode; title: string; sub: string }[] }) {
export function CapList({ items }: { items: { icon: ReactNode; title: string; sub: string; href?: string }[] }) {
return (
<ul className="gs-caps">
{items.map(cap => (
<li key={cap.title} className="gs-cap">
<span className="gs-cap__ic">{cap.icon}</span>
<span className="gs-cap__b">
<span className="gs-cap__t">{cap.title}</span>
<span className="gs-cap__s">{cap.sub}</span>
</span>
</li>
))}
{items.map(cap => {
const content = (
<>
<span className="gs-cap__ic">{cap.icon}</span>
<span className="gs-cap__b">
<span className="gs-cap__t">{cap.title}</span>
<span className="gs-cap__s">{cap.sub}</span>
</span>
</>
);
return (
<li key={cap.title}>
{cap.href ? (
<a className="gs-cap" href={cap.href}>{content}</a>
) : (
<div className="gs-cap">{content}</div>
)}
</li>
);
})}
</ul>
);
}
Expand Down
Loading
Loading