chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,119 @@
import {
LANDING_GUTTER,
LANDING_HERO_TOP_PADDING,
LANDING_SECTION_RHYTHM,
} from '@/app/(landing)/components/landing-layout'
/**
* Solutions-layout spacing - the single source of truth for every gutter, gap,
* inset, and reserved dimension used across the solutions-page components.
*
* The padding fortress lives here. No solutions component accepts a `className`
* or `style`, and none hard-codes a spacing value inline. Every measurement a
* reviewer might want to audit - the horizontal gutter, the inter-section rhythm,
* the card-grid gaps, the card stack, and the fixed visual-slot dimensions - is
* named in this one file. To change spacing you edit a constant here; consumer
* pages only choose from controlled component variants.
*
* All values are Tailwind class fragments (not raw numbers) so they compose
* directly into `className` strings inside the components and stay legible.
*/
export const SOLUTIONS_SPACING = {
/**
* The one horizontal gutter, owned solely by `SolutionsPage`. Matches the
* navbar and landing hero exactly (`px-20 max-lg:px-8 max-sm:px-5`) so
* solutions content starts on the wordmark's vertical line at every
* breakpoint. Sections and cards never set their own gutter.
*/
gutter: LANDING_GUTTER,
/**
* Inter-section vertical rhythm - the gap of the `<main>` flex column that
* `SolutionsPage` owns. Sections carry no vertical margin/padding of their own,
* so this is the only knob for the space between the hero, logos, and every
* card row. Tightens on smaller screens in lockstep with the landing `<main>`
* (`gap-[120px] max-lg:gap-[88px] max-sm:gap-16`).
*/
sectionRhythm: LANDING_SECTION_RHYTHM,
/** Hero text top padding, matching the landing hero at every breakpoint. */
heroTopPadding: LANDING_HERO_TOP_PADDING,
/** Vertical stack gap inside the hero header column (headline → description → CTA). */
heroStack: 'gap-[22px]',
/** Gap between the hero header column and the full-width hero visual beneath it. */
heroToVisual: 'gap-12',
/** Gap between a card row's header block and the card grid beneath it. */
cardRowHeaderToGrid: 'gap-12',
/** Vertical stack gap inside a card row's header (title → subtitle → CTA). */
cardRowHeaderStack: 'gap-5',
/**
* Extra top separation for the header CTA over the stack gap. Title and
* subtitle are one copy group and stay tight; the CTA is a separate action
* group, so its subtitle→CTA gap lands at 2× the title→subtitle gap
* (standard: 20px + 20px = 40px; feature: 12px + 12px = 24px).
*/
cardRowHeaderCtaGap: 'mt-5',
cardRowHeaderCtaGapFeature: 'mt-3',
/** Gap between cards within a card-row grid (both axes). */
cardGridGap: 'gap-8',
/** Minimum gap between a card's text block and its visual panel. */
cardTextToVisual: 'gap-5',
/** Vertical stack gap inside a card's text block (title → description). */
cardTextStack: 'gap-2',
/** Inner padding for feature tiles where copy and the visual slot share one frame. */
cardFeatureTilePadding: 'p-8 max-lg:p-6',
} as const
/**
* Readable text measures for the recurring solutions-page copy surfaces.
* Paragraph width is expressed in characters so line length tracks type size
* instead of the viewport. `min-w-0` keeps flex items wrapping cleanly on narrow
* screens, and `w-full` gives centered copy a stable measure.
*/
export const SOLUTIONS_TEXT_MEASURE = {
/** Hero support copy: broad enough for the primary value prop, still under long-form prose width. */
heroDescription: 'w-full min-w-0 max-w-[58ch]',
/** Section subtitles: slightly tighter than hero copy so centered headers feel intentional. */
rowSubtitle: 'w-full min-w-0 max-w-[52ch]',
/** Card descriptions: short scan lines inside three-up card grids. */
cardDescription: 'min-w-0 max-w-[38ch]',
} as const
/**
* Reserved fixed dimensions for the component-owned visual frames. A dropped-in
* `ReactNode` renders into a frame of exactly these dimensions, so it can never
* shift surrounding layout (CLS = 0) nor change its own frame padding. The node
* fills `h-full w-full` inside; it owns nothing about the frame.
*/
export const SOLUTIONS_VISUAL = {
/** Full-width hero visual aspect ratio - reserves height before paint. */
heroAspect: 'aspect-[16/9]',
/** Fixed height of a card's visual panel - uniform across every card. */
cardHeight: 'h-[240px]',
/**
* Minimum height for framed feature tiles with copy and future UI in one
* surface. One value at every breakpoint: the tallest tile vignettes (audit
* ledger, staging panel) need ~300px of visual slot below the copy block, so
* shrinking the tile on small screens crops their tops against the slot's
* `overflow-hidden`.
*/
featureTileMinHeight: 'min-h-[440px]',
} as const
/**
* Feature-tile surface + copy colors. Pages pick a tone per card via
* {@link SolutionsCardConfig.featureTileTone}; the component maps it here so
* each tile can diverge without shared hard-coded classes.
*/
export const SOLUTIONS_FEATURE_TILE_TONE = {
light: {
surface: 'bg-[var(--surface-3)]',
title: 'text-[var(--text-primary)]',
description: 'text-[var(--text-muted)]',
},
dark: {
surface: 'bg-[var(--text-secondary)]',
title: 'text-[var(--text-inverse)]',
description: 'text-[var(--surface-3)]',
/** Softer body copy on dark tiles — `#E6E6E6` via `--surface-6` (`#E5E5E5`). */
descriptionSoft: 'text-[var(--surface-6)]',
},
} as const