fix(stats): refine hero layout for responsive Figma match
This commit is contained in:
@@ -89,7 +89,7 @@
|
|||||||
[data-page="stats"] [data-component="container"] {
|
[data-page="stats"] [data-component="container"] {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 80rem;
|
max-width: calc(80rem + 2px);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border-left: 1px solid var(--stats-line);
|
border-left: 1px solid var(--stats-line);
|
||||||
border-right: 1px solid var(--stats-line);
|
border-right: 1px solid var(--stats-line);
|
||||||
@@ -461,6 +461,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-section="hero"] h1 {
|
[data-page="stats"] [data-section="hero"] h1 {
|
||||||
|
order: 1;
|
||||||
color: var(--stats-text);
|
color: var(--stats-text);
|
||||||
font-size: 64px;
|
font-size: 64px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -469,20 +470,30 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-slot="hero-copy"] {
|
[data-page="stats"] [data-slot="hero-copy"] {
|
||||||
|
order: 3;
|
||||||
color: var(--stats-hero-muted);
|
color: var(--stats-hero-muted);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-page="stats"] [data-slot="hero-copy-break"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-slot="hero-pattern"] {
|
[data-page="stats"] [data-slot="hero-pattern"] {
|
||||||
|
order: 2;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-image: radial-gradient(circle, var(--stats-hero-pattern) 1px, transparent 1.1px);
|
background: var(--stats-hero-pattern);
|
||||||
background-position: 0 0;
|
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E");
|
||||||
background-size: 6px 6px;
|
mask-repeat: repeat;
|
||||||
|
mask-size: 6px 6px;
|
||||||
|
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E");
|
||||||
|
-webkit-mask-repeat: repeat;
|
||||||
|
-webkit-mask-size: 6px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-slot="hero-meta"] {
|
[data-page="stats"] [data-slot="hero-meta"] {
|
||||||
@@ -496,7 +507,7 @@
|
|||||||
background: var(--stats-layer-2);
|
background: var(--stats-layer-2);
|
||||||
color: var(--stats-hero-muted);
|
color: var(--stats-hero-muted);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -514,10 +525,10 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 58rem) {
|
@media (min-width: 48rem) {
|
||||||
[data-page="stats"] [data-section="hero"] {
|
[data-page="stats"] [data-section="hero"] {
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
padding: 128px 40px 24px;
|
padding: 128px 32px 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-slot="hero-canvas"] {
|
[data-page="stats"] [data-slot="hero-canvas"] {
|
||||||
@@ -553,11 +564,21 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
width: min(36rem, 100%);
|
width: min(563px, 100%);
|
||||||
padding: 12px 0 0 16px;
|
padding: 12px 0 0 16px;
|
||||||
background: var(--stats-bg);
|
background: var(--stats-bg);
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-page="stats"] [data-slot="hero-copy-break"] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 75rem) {
|
||||||
|
[data-page="stats"] [data-section="hero"] {
|
||||||
|
padding: 128px 40px 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 90rem) {
|
@media (min-width: 90rem) {
|
||||||
@@ -1494,7 +1515,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 74rem) {
|
@media (max-width: 80rem) {
|
||||||
[data-page="stats"] [data-component="container"] {
|
[data-page="stats"] [data-component="container"] {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
@@ -1540,14 +1561,12 @@
|
|||||||
--stats-section-padding: 4rem;
|
--stats-section-padding: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-section="hero"],
|
|
||||||
[data-page="stats"] [data-section="chart"],
|
[data-page="stats"] [data-section="chart"],
|
||||||
[data-page="stats"] [data-section="newsletter"] {
|
[data-page="stats"] [data-section="newsletter"] {
|
||||||
padding-left: 24px;
|
padding-left: 24px;
|
||||||
padding-right: 24px;
|
padding-right: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-page="stats"] [data-section="hero"],
|
|
||||||
[data-page="stats"] [data-section="newsletter"] {
|
[data-page="stats"] [data-section="newsletter"] {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import { runtime } from "@opencode-ai/stats-core/runtime"
|
import { runtime } from "@opencode-ai/stats-core/runtime"
|
||||||
import { createAsync, query } from "@solidjs/router"
|
import { createAsync, query } from "@solidjs/router"
|
||||||
import { scaleBand, scaleLinear } from "d3-scale"
|
import { scaleBand, scaleLinear } from "d3-scale"
|
||||||
import { createEffect, createMemo, createSignal, For, onCleanup, Show, type JSX } from "solid-js"
|
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show, type JSX } from "solid-js"
|
||||||
import { getRequestEvent } from "solid-js/web"
|
import { getRequestEvent } from "solid-js/web"
|
||||||
|
|
||||||
const products = ["All Users", "Zen", "Go", "Enterprise"] as const
|
const products = ["All Users", "Zen", "Go", "Enterprise"] as const
|
||||||
@@ -98,21 +98,29 @@ export default function StatsHome() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Hero(props: { updatedAt: string | null }) {
|
function Hero(props: { updatedAt: string | null }) {
|
||||||
|
const [timeZone, setTimeZone] = createSignal("UTC")
|
||||||
|
onMount(() => setTimeZone(Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC"))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section data-section="hero">
|
<section data-section="hero">
|
||||||
<p data-slot="hero-meta">
|
<p data-slot="hero-meta">
|
||||||
<svg aria-hidden="true" width="16" height="16" viewBox="0 0 16 16">
|
<svg aria-hidden="true" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<rect x="3" y="3" width="10" height="10" fill="currentColor" />
|
<path
|
||||||
<rect x="7" y="6.5" width="2" height="4.5" fill="var(--stats-layer-2)" />
|
fill-rule="evenodd"
|
||||||
<rect x="7" y="5" width="2" height="1" fill="var(--stats-layer-2)" />
|
clip-rule="evenodd"
|
||||||
|
d="M13 13H3V3H13V13ZM6.46777 6.81641V7.81641H7.5791V11.3721H8.5791V6.81641H6.46777ZM7.30078 4.62891V5.62891H8.85645V4.62891H7.30078Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span>{props.updatedAt ? `Updated ${formatUpdatedAt(props.updatedAt)}` : "No rows yet"}</span>
|
<span>{props.updatedAt ? `Updated ${formatUpdatedAt(props.updatedAt, timeZone())}` : "No rows yet"}</span>
|
||||||
</p>
|
</p>
|
||||||
<div data-slot="hero-canvas">
|
<div data-slot="hero-canvas">
|
||||||
<div data-slot="hero-pattern" aria-hidden="true" />
|
<div data-slot="hero-pattern" aria-hidden="true" />
|
||||||
<h1>Model Stats</h1>
|
<h1>Model Stats</h1>
|
||||||
<p data-slot="hero-copy">
|
<p data-slot="hero-copy">
|
||||||
See which models are winning real usage, how the mix shifts over time, and where momentum is moving each week.
|
See which models are winning real usage, how the mix{" "}
|
||||||
|
<br data-slot="hero-copy-break" />
|
||||||
|
shifts over time, and where momentum is moving each week.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -154,7 +162,7 @@ function EmptyState(props: { title: string; description: string }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatUpdatedAt(value: string) {
|
function formatUpdatedAt(value: string, timeZone: string) {
|
||||||
const date = new Date(value)
|
const date = new Date(value)
|
||||||
if (Number.isNaN(date.getTime())) return "just now"
|
if (Number.isNaN(date.getTime())) return "just now"
|
||||||
return new Intl.DateTimeFormat("en", {
|
return new Intl.DateTimeFormat("en", {
|
||||||
@@ -162,7 +170,7 @@ function formatUpdatedAt(value: string) {
|
|||||||
day: "numeric",
|
day: "numeric",
|
||||||
hour: "numeric",
|
hour: "numeric",
|
||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
timeZone: "UTC",
|
timeZone,
|
||||||
timeZoneName: "short",
|
timeZoneName: "short",
|
||||||
}).format(date)
|
}).format(date)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user