mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 08:52:21 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5be24fd13 |
@@ -113,6 +113,7 @@ describe("Header", () => {
|
||||
it("renders direct desktop theme family controls and plain Skills tab", () => {
|
||||
siteModeMock.mockReturnValue("skills");
|
||||
setThemeMock.mockClear();
|
||||
setModeMock.mockClear();
|
||||
|
||||
render(<Header />);
|
||||
|
||||
@@ -127,6 +128,12 @@ describe("Header", () => {
|
||||
fireEvent.click(screen.getByRole("button", { name: "Hub" }));
|
||||
expect(setThemeMock).toHaveBeenCalledWith("hub");
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /Cycle theme family/i }));
|
||||
expect(setThemeMock).toHaveBeenCalledWith("claw");
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /Cycle theme mode/i }));
|
||||
expect(setModeMock).toHaveBeenCalledWith("light");
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Open menu" }));
|
||||
|
||||
expect(screen.getAllByText("Skills")).toHaveLength(2);
|
||||
|
||||
@@ -40,6 +40,13 @@ const NAV_ICONS: Record<NavIconName, ComponentType<{ size?: number; className?:
|
||||
ghost: Ghost,
|
||||
};
|
||||
|
||||
const THEME_FAMILY_ICONS: Record<string, ComponentType<{ size?: number; className?: string }>> = {
|
||||
claw: Ghost,
|
||||
hub: Plug,
|
||||
};
|
||||
|
||||
const THEME_MODE_SEQUENCE: Array<"system" | "light" | "dark"> = ["system", "light", "dark"];
|
||||
|
||||
export default function Header() {
|
||||
const { isAuthenticated, isLoading, me } = useAuthStatus();
|
||||
const { signIn, signOut } = useAuthActions();
|
||||
@@ -70,6 +77,8 @@ export default function Header() {
|
||||
const [mobileSearchOpen, setMobileSearchOpen] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const themeLabel = THEME_OPTIONS.find((option) => option.value === theme)?.label ?? "Claw";
|
||||
const ThemeFamilyIcon = THEME_FAMILY_ICONS[theme] ?? Wrench;
|
||||
const ThemeModeIcon = getThemeModeIcon(mode);
|
||||
|
||||
const setThemeMode = (next: "system" | "light" | "dark") => {
|
||||
startThemeTransition({
|
||||
@@ -89,6 +98,21 @@ export default function Header() {
|
||||
setTheme(nextTheme);
|
||||
};
|
||||
|
||||
const cycleThemeFamily = () => {
|
||||
const currentIndex = Math.max(
|
||||
0,
|
||||
THEME_OPTIONS.findIndex((option) => option.value === theme),
|
||||
);
|
||||
const nextTheme = THEME_OPTIONS[(currentIndex + 1) % THEME_OPTIONS.length]?.value ?? "claw";
|
||||
setThemeFamily(nextTheme);
|
||||
};
|
||||
|
||||
const cycleThemeMode = () => {
|
||||
const currentIndex = Math.max(0, THEME_MODE_SEQUENCE.indexOf(mode));
|
||||
const nextMode = THEME_MODE_SEQUENCE[(currentIndex + 1) % THEME_MODE_SEQUENCE.length] ?? "system";
|
||||
setThemeMode(nextMode);
|
||||
};
|
||||
|
||||
const handleNavSearch = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
const q = navSearchQuery.trim();
|
||||
@@ -237,7 +261,6 @@ export default function Header() {
|
||||
</button>
|
||||
<div className="theme-toggle" ref={toggleRef}>
|
||||
<div className="theme-picker-desktop" aria-label={`Theme family, current ${themeLabel}`}>
|
||||
<span className="theme-picker-label">Theme</span>
|
||||
<div className="theme-family-toggle" role="group" aria-label="Theme family">
|
||||
{THEME_OPTIONS.map((option) => (
|
||||
<button
|
||||
@@ -253,6 +276,26 @@ export default function Header() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="theme-cycle-group" aria-label="Theme controls">
|
||||
<button
|
||||
type="button"
|
||||
className="theme-cycle-button theme-cycle-button-family"
|
||||
onClick={cycleThemeFamily}
|
||||
aria-label={`Cycle theme family. Current: ${themeLabel}`}
|
||||
title={`Theme family: ${themeLabel}`}
|
||||
>
|
||||
<ThemeFamilyIcon className="h-4 w-4" aria-hidden="true" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="theme-cycle-button theme-cycle-button-mode"
|
||||
onClick={cycleThemeMode}
|
||||
aria-label={`Cycle theme mode. Current: ${mode}`}
|
||||
title={`Theme mode: ${mode}`}
|
||||
>
|
||||
<ThemeModeIcon className="h-4 w-4" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<ToggleGroup
|
||||
className="theme-mode-toggle"
|
||||
type="single"
|
||||
@@ -410,3 +453,15 @@ function getCurrentRelativeUrl() {
|
||||
if (typeof window === "undefined") return "/";
|
||||
return `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||
}
|
||||
|
||||
function getThemeModeIcon(mode: "system" | "light" | "dark") {
|
||||
switch (mode) {
|
||||
case "light":
|
||||
return Sun;
|
||||
case "dark":
|
||||
return Moon;
|
||||
case "system":
|
||||
default:
|
||||
return Monitor;
|
||||
}
|
||||
}
|
||||
|
||||
+95
-79
@@ -84,88 +84,104 @@ export const Route = createFileRoute('/about')({
|
||||
function AboutPage() {
|
||||
return (
|
||||
<main className="section about-page">
|
||||
<div className="about-hero">
|
||||
<div className="about-hero-copy">
|
||||
<div className="skill-card-tags mb-3">
|
||||
<Badge>About</Badge>
|
||||
<Badge variant="accent">Policy</Badge>
|
||||
<div className="about-bento">
|
||||
<section className="about-panel about-panel-hero">
|
||||
<div className="about-hero-copy">
|
||||
<div className="skill-card-tags mb-3">
|
||||
<Badge>About</Badge>
|
||||
<Badge variant="accent">Policy</Badge>
|
||||
</div>
|
||||
<h1 className="about-title">What ClawHub will not host</h1>
|
||||
<p className="about-lead">
|
||||
ClawHub is for useful agent tooling, not abuse workflows. If a skill is built to
|
||||
evade defenses, scam people, invade privacy, or enable non-consensual behavior, it
|
||||
does not belong here.
|
||||
</p>
|
||||
</div>
|
||||
<h1 className="about-title">What ClawHub will not host</h1>
|
||||
<p className="about-lead">
|
||||
ClawHub is for useful agent tooling, not abuse workflows. If a skill is built to evade
|
||||
defenses, scam people, invade privacy, or enable non-consensual behavior, it does not
|
||||
belong here.
|
||||
</section>
|
||||
|
||||
<aside className="about-panel about-panel-callout">
|
||||
<div className="about-callout">
|
||||
<span className="about-callout-label">Moderation stance</span>
|
||||
<p>
|
||||
We judge end-to-end abuse patterns, not keyword theater. Useful tooling stays.
|
||||
Predatory workflows get removed.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section className="about-panel about-panel-categories">
|
||||
<div className="home-section-header">
|
||||
<h2 className="home-section-title">Immediate rejection categories</h2>
|
||||
</div>
|
||||
<div className="about-grid">
|
||||
{prohibitedCategories.map((category, index) => (
|
||||
<article
|
||||
key={category.title}
|
||||
className={`about-rule-card${index % 3 === 0 ? ' about-rule-card-featured' : ''}`}
|
||||
>
|
||||
<h2>{category.title}</h2>
|
||||
<p>{category.examples}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="about-panel about-panel-patterns">
|
||||
<div className="home-section-header">
|
||||
<h2 className="home-section-title">Recent patterns we are explicitly not okay with</h2>
|
||||
</div>
|
||||
<div className="about-patterns">
|
||||
{recentPatterns.map((pattern) => (
|
||||
<div key={pattern} className="about-pattern">
|
||||
{pattern}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="about-panel about-panel-enforcement">
|
||||
<div>
|
||||
<span className="about-callout-label">Enforcement</span>
|
||||
<div className="management-sublist">
|
||||
<div className="management-subitem">
|
||||
We may hide, remove, or hard-delete violating skills.
|
||||
</div>
|
||||
<div className="management-subitem">
|
||||
We may revoke tokens, soft-delete associated content, and ban repeat or severe
|
||||
offenders.
|
||||
</div>
|
||||
<div className="management-subitem">
|
||||
We do not guarantee warning-first enforcement for obvious abuse.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="about-panel about-panel-actions">
|
||||
<span className="about-callout-label">Next steps</span>
|
||||
<p className="about-panel-copy">
|
||||
If you are reviewing a borderline workflow, use the reviewer doc. If you are browsing,
|
||||
stay in the public catalog.
|
||||
</p>
|
||||
</div>
|
||||
<div className="about-callout">
|
||||
<span className="about-callout-label">Moderation stance</span>
|
||||
<p>
|
||||
We judge end-to-end abuse patterns, not keyword theater. Useful tooling stays.
|
||||
Predatory workflows get removed.
|
||||
</p>
|
||||
</div>
|
||||
<div className="skill-card-tags">
|
||||
<Button asChild variant="primary">
|
||||
<Link to="/skills">
|
||||
Browse Skills
|
||||
</Link>
|
||||
</Button>
|
||||
<Button asChild>
|
||||
<a
|
||||
href="https://github.com/openclaw/clawhub/blob/main/docs/acceptable-usage.md"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Reviewer Doc
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section className="about-section">
|
||||
<div className="home-section-header">
|
||||
<h2 className="home-section-title">Immediate rejection categories</h2>
|
||||
</div>
|
||||
<div className="about-grid">
|
||||
{prohibitedCategories.map((category) => (
|
||||
<article key={category.title} className="about-rule-card">
|
||||
<h2>{category.title}</h2>
|
||||
<p>{category.examples}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="about-section">
|
||||
<div className="home-section-header">
|
||||
<h2 className="home-section-title">Recent patterns we are explicitly not okay with</h2>
|
||||
</div>
|
||||
<div className="about-patterns">
|
||||
{recentPatterns.map((pattern) => (
|
||||
<div key={pattern} className="about-pattern">
|
||||
{pattern}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="about-enforcement">
|
||||
<div>
|
||||
<span className="about-callout-label">Enforcement</span>
|
||||
<div className="management-sublist">
|
||||
<div className="management-subitem">
|
||||
We may hide, remove, or hard-delete violating skills.
|
||||
</div>
|
||||
<div className="management-subitem">
|
||||
We may revoke tokens, soft-delete associated content, and ban repeat or severe
|
||||
offenders.
|
||||
</div>
|
||||
<div className="management-subitem">
|
||||
We do not guarantee warning-first enforcement for obvious abuse.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="skill-card-tags">
|
||||
<Button asChild variant="primary">
|
||||
<Link to="/skills">
|
||||
Browse Skills
|
||||
</Link>
|
||||
</Button>
|
||||
<Button asChild>
|
||||
<a
|
||||
href="https://github.com/openclaw/clawhub/blob/main/docs/acceptable-usage.md"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Reviewer Doc
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
+254
-51
@@ -356,14 +356,14 @@
|
||||
}
|
||||
|
||||
[data-theme-family="hub"] .navbar-top {
|
||||
gap: 12px;
|
||||
padding: 8px 0 10px;
|
||||
gap: 16px;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
[data-theme-family="hub"] .navbar-search {
|
||||
max-width: 400px;
|
||||
height: 32px;
|
||||
border-radius: var(--r-sm);
|
||||
max-width: none;
|
||||
height: 38px;
|
||||
border-radius: var(--r-md);
|
||||
}
|
||||
|
||||
[data-theme-family="hub"] .navbar-search-mobile-trigger {
|
||||
@@ -399,14 +399,14 @@
|
||||
|
||||
[data-theme-family="hub"] .brand {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--fs-base);
|
||||
font-size: var(--fs-md);
|
||||
font-weight: 600;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
[data-theme-family="hub"] .brand-mark {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--r-sm);
|
||||
}
|
||||
|
||||
@@ -709,15 +709,17 @@ code {
|
||||
}
|
||||
|
||||
.navbar-top {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(148px, auto) minmax(320px, 1fr) minmax(320px, auto);
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 12px 0;
|
||||
min-height: 62px;
|
||||
}
|
||||
|
||||
.navbar-search {
|
||||
flex: 1;
|
||||
max-width: 420px;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
@@ -873,10 +875,13 @@ code {
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--ink);
|
||||
min-width: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
display: inline-flex;
|
||||
min-width: 6.5ch;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
@@ -1003,16 +1008,59 @@ code {
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-self: end;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex: 0 0 auto;
|
||||
min-width: 276px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.theme-cycle-group {
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 72px;
|
||||
min-width: 72px;
|
||||
grid-template-columns: repeat(2, 32px);
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.theme-cycle-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--r-pill);
|
||||
background: var(--surface);
|
||||
color: var(--ink-soft);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color 0.15s ease,
|
||||
background 0.15s ease,
|
||||
color 0.15s ease,
|
||||
box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.theme-cycle-button:hover {
|
||||
color: var(--ink);
|
||||
border-color: var(--border-ui-hover);
|
||||
background: var(--surface-muted);
|
||||
}
|
||||
|
||||
.theme-cycle-button:focus-visible {
|
||||
outline: 2px solid var(--input-focus-border);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.theme-mode-toggle button {
|
||||
@@ -3956,20 +4004,29 @@ code {
|
||||
}
|
||||
|
||||
.navbar-top {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
gap: 10px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.navbar-search {
|
||||
display: none;
|
||||
display: flex;
|
||||
order: 2;
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.navbar-search-mobile-trigger {
|
||||
display: inline-flex;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-search-mobile {
|
||||
display: flex;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-tabs {
|
||||
@@ -3998,12 +4055,59 @@ code {
|
||||
|
||||
.nav-mobile {
|
||||
display: inline-flex;
|
||||
order: 1;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
order: 3;
|
||||
margin-left: auto;
|
||||
flex: 0 0 auto;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.nav-actions .btn {
|
||||
width: 36px;
|
||||
min-width: 36px;
|
||||
height: 36px;
|
||||
min-height: 36px;
|
||||
padding: 0;
|
||||
border-radius: var(--r-pill);
|
||||
}
|
||||
|
||||
.sign-in-label,
|
||||
.sign-in-provider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-trigger {
|
||||
width: 36px;
|
||||
min-width: 36px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
justify-content: center;
|
||||
border-radius: var(--r-pill);
|
||||
}
|
||||
|
||||
.user-trigger img,
|
||||
.user-menu-fallback {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.user-trigger .mono,
|
||||
.user-menu-chevron {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding: 58px 18px 44px;
|
||||
}
|
||||
@@ -4080,11 +4184,6 @@ code {
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.brand {
|
||||
font-size: 1.25rem;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
gap: 10px;
|
||||
}
|
||||
@@ -4095,13 +4194,13 @@ code {
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.sign-in-provider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-trigger .mono,
|
||||
.user-menu-chevron {
|
||||
display: none;
|
||||
.nav-actions .btn,
|
||||
.user-trigger {
|
||||
width: 36px;
|
||||
min-width: 36px;
|
||||
height: 36px;
|
||||
min-height: 36px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
@@ -7127,12 +7226,15 @@ html.theme-transition::view-transition-new(theme) {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.about-hero,
|
||||
.about-enforcement {
|
||||
.about-bento {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.8fr);
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--space-5);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.about-panel {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-5);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--r-xl);
|
||||
@@ -7141,6 +7243,18 @@ html.theme-transition::view-transition-new(theme) {
|
||||
color-mix(in srgb, var(--surface-muted) 58%, transparent);
|
||||
}
|
||||
|
||||
.about-panel-hero,
|
||||
.about-panel-enforcement,
|
||||
.about-panel-actions {
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.about-panel-copy {
|
||||
margin: 0;
|
||||
color: var(--ink-soft);
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.about-hero-copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -7186,12 +7300,7 @@ html.theme-transition::view-transition-new(theme) {
|
||||
color: var(--ink-soft);
|
||||
}
|
||||
|
||||
.about-section {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.about-section .home-section-title {
|
||||
.about-panel .home-section-title {
|
||||
font-size: var(--fs-lg);
|
||||
font-weight: 600;
|
||||
color: var(--ink);
|
||||
@@ -7201,7 +7310,7 @@ html.theme-transition::view-transition-new(theme) {
|
||||
.about-patterns,
|
||||
.souls-coming-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
grid-template-columns: 1fr;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
@@ -7256,18 +7365,86 @@ html.theme-transition::view-transition-new(theme) {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.about-hero,
|
||||
.about-enforcement {
|
||||
grid-template-columns: 1fr;
|
||||
@media (min-width: 641px) {
|
||||
.about-bento {
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.about-callout {
|
||||
order: -1;
|
||||
|
||||
.about-panel-hero {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.about-panel-callout {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.about-panel-categories,
|
||||
.about-panel-patterns {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.about-panel-enforcement,
|
||||
.about-panel-actions {
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
.about-grid {
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.about-rule-card {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.about-rule-card-featured {
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
.about-patterns {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.about-bento {
|
||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.about-panel-hero {
|
||||
grid-column: span 8;
|
||||
}
|
||||
|
||||
.about-panel-callout {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.about-panel-enforcement {
|
||||
grid-column: span 7;
|
||||
}
|
||||
|
||||
.about-panel-actions {
|
||||
grid-column: span 5;
|
||||
}
|
||||
|
||||
.about-grid {
|
||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.about-rule-card {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.about-rule-card-featured {
|
||||
grid-column: span 6;
|
||||
}
|
||||
|
||||
.about-patterns {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.about-bento,
|
||||
.about-grid,
|
||||
.about-patterns,
|
||||
.souls-coming-grid {
|
||||
@@ -7321,12 +7498,14 @@ html.theme-transition::view-transition-new(theme) {
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-shrink: 0;
|
||||
min-width: 132px;
|
||||
min-height: 32px;
|
||||
padding: 4px 6px 4px 10px;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--r-pill);
|
||||
background: var(--surface);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.theme-picker-label {
|
||||
@@ -7339,20 +7518,24 @@ html.theme-transition::view-transition-new(theme) {
|
||||
}
|
||||
|
||||
.theme-family-toggle {
|
||||
display: inline-flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
gap: 6px;
|
||||
width: 112px;
|
||||
flex-wrap: nowrap;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.theme-family-button {
|
||||
all: unset;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
min-width: 0;
|
||||
padding: 0 8px;
|
||||
border-radius: 999px;
|
||||
color: var(--ink-soft);
|
||||
@@ -7379,15 +7562,35 @@ html.theme-transition::view-transition-new(theme) {
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 34%, transparent);
|
||||
}
|
||||
|
||||
[data-theme-family="hub"] .theme-picker-desktop,
|
||||
[data-theme-family="hub"] .theme-family-button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.theme-mode-toggle {
|
||||
min-width: 104px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.theme-picker-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) and (min-width: 761px) {
|
||||
.theme-picker-desktop,
|
||||
.theme-mode-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.theme-cycle-group {
|
||||
display: grid;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.theme-picker-desktop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user