feat: a shorter page on phones
On a phone the homepage was about 29 screens long; it is now about 22. The desktop layout is unchanged to the pixel. Lists of equal items (automation notes, project fit, principles, reasons for a web presentation, by hand vs. automated) are swiped through side by side (SwipeRow) instead of stacked. The four service cards form a compact 2x2 grid, step lists spell out only the current step, the workflow legend and the per-project task lists are left out, and sections use less padding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
} from "@/src/components/illustrations/WebPresentation";
|
||||
import { WorkShowcase } from "@/src/components/illustrations/WorkShowcase";
|
||||
import { Reveal } from "@/src/components/Reveal";
|
||||
import { SwipeRow } from "@/src/components/SwipeRow";
|
||||
import { contentFor } from "@/src/content";
|
||||
import type { SplitTitle } from "@/src/content/types";
|
||||
import { DEFAULT_LOCALE, parseLocale } from "@/src/domain/locale";
|
||||
@@ -122,7 +123,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
<Reveal>
|
||||
<AutomationFlow />
|
||||
</Reveal>
|
||||
<div className="mt-16 grid grid-cols-1 gap-12 md:mt-24 md:grid-cols-3 md:gap-10">
|
||||
<SwipeRow className="mt-12 grid grid-cols-1 gap-12 md:mt-24 md:grid-cols-3 md:gap-10">
|
||||
{automation.notes.map((group, i) => (
|
||||
<Reveal key={group.title} delay={0.1 * i}>
|
||||
<div className="border-t border-slate-900 pt-6">
|
||||
@@ -140,7 +141,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</SwipeRow>
|
||||
</Block>
|
||||
|
||||
<Block
|
||||
@@ -162,7 +163,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
</BitAura>
|
||||
</Reveal>
|
||||
|
||||
<div className="mt-16 grid grid-cols-1 gap-x-10 gap-y-14 sm:grid-cols-2 md:mt-28 lg:grid-cols-4">
|
||||
<SwipeRow className="mt-12 grid grid-cols-1 gap-x-10 gap-y-14 md:mt-28 md:grid-cols-2 lg:grid-cols-4">
|
||||
{presentations.reasons.map((reason, i) => (
|
||||
<Reveal key={reason.title} delay={0.08 * i}>
|
||||
<div className="rounded-2xl border border-slate-800 bg-slate-950/60 p-4">
|
||||
@@ -176,7 +177,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
</p>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</SwipeRow>
|
||||
|
||||
<div className="mt-16 grid grid-cols-1 gap-12 md:mt-28 md:grid-cols-12 md:gap-12">
|
||||
<Reveal className="md:col-span-6">
|
||||
@@ -220,7 +221,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
label={technology.label}
|
||||
title={<Title title={technology.title} />}
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-12 md:grid-cols-3 md:gap-10">
|
||||
<SwipeRow className="grid grid-cols-1 gap-12 md:grid-cols-3 md:gap-10">
|
||||
{technology.fit.map((group, i) => (
|
||||
<Reveal key={group.title} delay={0.1 * i}>
|
||||
<div
|
||||
@@ -242,12 +243,12 @@ export default async function LandingPage({ params }: Props) {
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</SwipeRow>
|
||||
|
||||
<Reveal>
|
||||
<div className="mt-16 rounded-3xl bg-slate-50 p-6 md:mt-24 md:p-10">
|
||||
<div className="mt-12 rounded-3xl bg-slate-50 p-6 md:mt-24 md:p-10">
|
||||
<p className={`${MONO} m-0`}>{technology.techLabel}</p>
|
||||
<div className="mt-8 grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div className="mt-6 grid grid-cols-1 gap-7 sm:grid-cols-2 md:mt-8 md:gap-10 lg:grid-cols-4">
|
||||
{technology.tech.map((group) => (
|
||||
<div key={group.area}>
|
||||
<p className="m-0 font-sans text-xl font-bold tracking-tight text-slate-900 md:text-2xl">
|
||||
@@ -269,7 +270,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
<div className="mt-16 md:mt-24">
|
||||
<div className="mt-12 md:mt-24">
|
||||
<Reveal>
|
||||
<h3 className="m-0 font-sans text-3xl font-bold tracking-tighter text-slate-900 md:text-5xl">
|
||||
{technology.pipelineTitle}
|
||||
@@ -296,7 +297,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
</div>
|
||||
</BitAura>
|
||||
</Reveal>
|
||||
<div className="grid grid-cols-1 gap-x-12 gap-y-12 md:grid-cols-2 md:gap-y-16">
|
||||
<SwipeRow className="grid grid-cols-1 gap-x-12 gap-y-12 md:grid-cols-2 md:gap-y-16">
|
||||
{working.principles.map((item, i) => (
|
||||
<Reveal key={item.title} delay={0.08 * i}>
|
||||
<div className="border-t border-slate-900 pt-6">
|
||||
@@ -307,7 +308,7 @@ export default async function LandingPage({ params }: Props) {
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</SwipeRow>
|
||||
</Block>
|
||||
|
||||
<Block
|
||||
|
||||
@@ -1352,6 +1352,38 @@ pre:has(code[class*="language-"]) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SwipeRow: on phones equal items stand side by side and are swiped through,
|
||||
* with the next one peeking in. From tablet width on the slide wrappers
|
||||
* dissolve and the items sit in the grid the row was given.
|
||||
*/
|
||||
@media (max-width: 767px) {
|
||||
.swipe-row {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
overflow-x: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
scroll-snap-type: x mandatory;
|
||||
/* Bleed to the screen edges, but start in line with the text. */
|
||||
margin-inline: -1.25rem;
|
||||
padding-inline: 1.25rem;
|
||||
scroll-padding-inline: 1.25rem;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.swipe-row::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.swipe-slide {
|
||||
flex: 0 0 82%;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.swipe-slide {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Native feel: the page should behave like a well-made app on every input type.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user