open-design/apps/landing-page/app/globals.css
lefarcen 7f03030f3f
perf(landing): self-host fonts + inline critical CSS (#2599)
* perf(landing): self-host fonts + inline critical CSS

PageSpeed Insights flagged ~2.3s of render-blocking on /:
  globals.css   12.9 KB external link, 160ms
  fonts CSS     2.2 KB  fonts.googleapis.com, 750ms
  + 4 woff2     ~1200ms each from fonts.gstatic.com

Two changes drop that whole chain:

1. Self-host fonts via @fontsource-variable/{inter,inter-tight,
   playfair-display,jetbrains-mono}. Each family ships a single variable
   woff2 (covers all weights we use) that Astro bundles into /_astro/*
   alongside the rest of the build, served same-origin through CF Pages —
   no separate TLS handshake, no Google Fonts CSS round-trip. The CSS
   variable names get an extra alias in front (`'Inter Tight Variable',
   'Inter Tight', ...`) so a system fallback still works if the package
   ever ships under a different family name.

2. `astro.config.ts: build.inlineStylesheets: 'always'` inlines every
   emitted <style> into the HTML <head> instead of emitting a separate
   /_astro/*.css link. The HTML grows from ~13KB to ~28KB (gzip) but
   loses one stylesheet round-trip + the entire @font-face chain that
   used to gate text rendering.

Component cleanup: the `<FontStylesheet>` component (preconnect + link to
fonts.googleapis.com) is no longer needed and is deleted, removed from
all 7 places that mounted it. og.astro keeps its own font setup since
it renders to a screenshot.

Expected effect (from PageSpeed Insights "Render-blocking requests"
diagnostic on the previous build):
  FCP  1.9s → ~1.2s
  LCP  2.2s → ~1.5s

Verified: pnpm typecheck 0 errors, pnpm build 1853 pages 78s, preview
serves /_astro/*.woff2 as font/woff2 same-origin, 0 fonts.googleapis or
fonts.gstatic references in the built HTML.

* perf(landing): include Playfair italic + bump nix pnpm-deps hash

Two follow-ups on the self-host fonts PR:

1. globals.css imported only `@fontsource-variable/playfair-display`,
   which ships @font-face for font-style: normal only. The previous
   Google Fonts URL included the italic axis (`ital,wght@0,500;1,400;
   ...`) and several rules (.roman, .work-rule .roman, .sec-rule .roman,
   plus 8 other italics across globals.css + sub-pages.css) render
   Playfair italics via `font-family: var(--serif); font-style: italic`.
   Without the italic face self-hosted, those would fall through to
   Times New Roman italic or browser synthesis. Adding
   `wght-italic.css` keeps the typography visually equivalent.

2. nix/pnpm-deps.nix uses a fixed-output derivation hash that has to
   match the pnpm vendored store; adding the four fontsource packages
   changed pnpm-lock.yaml so the hash has to be bumped to the value Nix
   reported in CI.

Codex (Looper reviewer) flagged #1 as non-blocking.

* perf(landing): pin fontsource versions exactly per repo guard

`pnpm add` defaulted to caret ranges (`^5.2.8`) but repo guard rejects
non-exact specs ("dependency specs must be exact versions like 1.2.3 or
workspace:*"). That was the actual cause of the Preflight + Validate
workspace failures — pinning to the locked versions Codex reviewer
called out:

  @fontsource-variable/inter             5.2.8
  @fontsource-variable/inter-tight       5.2.7
  @fontsource-variable/jetbrains-mono    5.2.8
  @fontsource-variable/playfair-display  5.2.8

`pnpm guard` now passes locally (6/6 tests).
2026-05-22 11:49:16 +08:00

3453 lines
87 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Atelier Zero — landing page styles.
*
* Mirrors `design-templates/open-design-landing/example.html` <style> block 1:1.
* When the canonical example.html changes, mirror the diff here so the
* template's known-good rendering stays in lockstep with the deployed site.
*
* Fonts are self-hosted via `@fontsource-variable/*` packages. The variable
* font files (one woff2 per family, ~30-50KB each) cover the entire
* weight axis we use, are served same-origin (no Google Fonts CSS or
* fonts.gstatic.com TLS handshake), and ship through CF's edge — PageSpeed
* was attributing ~2.3s of render-blocking + LCP to the old Google Fonts
* round-trip chain.
*
* Subset CSS files only declare @font-face metadata (~1KB each). The
* browser downloads the woff2 that matches the unicode-range of text it's
* about to render, so multi-script support stays intact without paying for
* unused scripts up front.
*/
@import '@fontsource-variable/inter';
@import '@fontsource-variable/inter-tight';
@import '@fontsource-variable/playfair-display';
@import '@fontsource-variable/playfair-display/wght-italic.css';
@import '@fontsource-variable/jetbrains-mono';
:root {
--paper: #efe7d2;
--paper-warm: #ece4cf;
--paper-dark: #ddd2b6;
--ink: #15140f;
--ink-soft: #2a2620;
--ink-mute: #5a5448;
--ink-faint: #8b8676;
--coral: #ed6f5c;
--coral-soft: #f08e7c;
--mustard: #e9b94a;
--olive: #6e7448;
--bone: #f7f1de;
--line: rgba(21, 20, 15, 0.16);
--line-soft: rgba(21, 20, 15, 0.08);
--line-faint: rgba(21, 20, 15, 0.05);
--shadow: 0 30px 60px -30px rgba(21, 20, 15, 0.18);
--serif: 'Playfair Display Variable', 'Playfair Display', 'Times New Roman', serif;
--sans: 'Inter Tight Variable', 'Inter Tight', 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
--body: 'Inter Variable', 'Inter', -apple-system, system-ui, sans-serif;
--mono: 'JetBrains Mono Variable', 'JetBrains Mono', 'SF Mono', Menlo, monospace;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
background: var(--paper);
color: var(--ink);
/*
* Lock the page width to the viewport so any decorative element
* positioned with negative offsets (ribbons, hero-art margin-right,
* mega footer word, etc.) cannot create a horizontal scrollbar on
* narrow viewports.
*
* Use `overflow-x: clip` (modern) instead of `hidden`: clip does not
* establish a containing block for `position: fixed/sticky`, so the
* sticky nav keeps working. Browsers that don't support clip fall
* back to the hidden declaration just above it.
*/
overflow-x: hidden;
overflow-x: clip;
max-width: 100%;
}
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
font-family: var(--body);
font-size: 16px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
position: relative;
overflow-wrap: break-word;
word-wrap: break-word;
}
img, video, canvas { max-width: 100%; height: auto; }
/*
* Paper texture overlay across the whole page.
*
* Rendered ABOVE `.shell` (z-index 2) so the noise/grain multiply blend
* applies uniformly to every section — including `.topbar` and `.nav`,
* which have an opaque `background: var(--paper)` to keep sticky-scroll
* content readable. Without this, opaque sections would show clean paper
* and transparent sections (hero, about, …) would show textured paper,
* which reads as two slightly different colors at the seam.
*
* Z-index is set equal to the side-rails (also z-index 3); because the
* pseudo-element appears in document order before the rails, the rails
* paint on top of the texture and keep their crisp rotated lettering.
*/
body::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
z-index: 3;
background-image:
radial-gradient(circle at 12% 18%, rgba(106, 92, 56, 0.07) 0, transparent 28%),
radial-gradient(circle at 88% 72%, rgba(106, 92, 56, 0.06) 0, transparent 32%),
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.18 0 0 0 0 0.16 0 0 0 0 0.12 0 0 0 0.06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
background-size: auto, auto, 240px 240px;
mix-blend-mode: multiply;
opacity: 0.92;
}
.shell { position: relative; z-index: 2; }
.container {
max-width: 1360px;
padding: 0 64px;
margin: 0 auto;
position: relative;
}
.container.wide { max-width: 1480px; }
/* fixed side rails — rotated brand text on the right edge */
.side-rail {
position: fixed;
top: 0;
bottom: 0;
width: 36px;
z-index: 3;
pointer-events: none;
display: flex;
align-items: center;
justify-content: center;
}
.side-rail.right { right: 0; border-left: 1px solid var(--line-faint); }
.side-rail.left { left: 0; border-right: 1px solid var(--line-faint); }
.side-rail .rail-text {
font-family: var(--sans);
font-size: 10px;
font-weight: 600;
letter-spacing: 0.42em;
text-transform: uppercase;
color: var(--ink-faint);
writing-mode: vertical-rl;
transform: rotate(180deg);
white-space: nowrap;
}
.side-rail.right .rail-text { transform: rotate(180deg); }
.side-rail.left .rail-text { writing-mode: vertical-rl; transform: none; }
/*
* Sticky chrome bar — wraps the editorial metadata strip + main nav as a
* single Headroom-style unit. Keeping them welded means the language
* switcher stays reachable while reading the page (you can flip locales
* mid-scroll without scrolling back to the top), and the masthead +
* navigation always read as a single nameplate rather than two unrelated
* rows.
*
* Sticky/transform/transition lived on `.nav` historically — they belong
* here now so both rows slide together. The `data-chrome-headroom` hook
* is what `header-enhancer.astro` (and the homepage inline script)
* toggle `is-hidden` on.
*/
.site-chrome {
position: sticky;
top: 0;
z-index: 50;
background: var(--paper);
transform: translateY(0);
transition: transform 360ms cubic-bezier(0.22, 0.61, 0.36, 1),
box-shadow 220ms ease,
border-color 220ms ease;
will-change: transform;
}
.site-chrome.is-hidden {
transform: translateY(-100%);
pointer-events: none;
box-shadow: none;
}
/* top metadata strip */
.topbar {
border-bottom: 1px solid var(--line);
padding: 10px 0;
background: var(--paper);
/*
* Stays a positioned context so the locale menu has an absolute
* anchor. The z-index is small but non-zero so the topbar — and the
* menu that drops out of it — paint above the sibling nav inside
* `.site-chrome`. Without this the menu would be obscured by the
* nav's download/star buttons.
*/
position: relative;
z-index: 2;
}
.topbar-inner {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24px;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.topbar-inner b { color: var(--ink); font-weight: 600; }
.topbar-inner .coral { color: var(--coral); }
.topbar-inner > span { white-space: nowrap; }
.topbar-inner .mid { display: inline-flex; gap: 26px; }
.topbar-inner .mid > span { white-space: nowrap; }
.topbar-inner .right { display: inline-flex; gap: 18px; align-items: center; }
.topbar-inner .right > span,
.topbar-inner .right > a { white-space: nowrap; }
.topbar-link {
color: inherit;
text-decoration: none;
border-bottom: 1px solid transparent;
transition: color 160ms ease, border-color 160ms ease;
}
.topbar-link:hover { color: var(--coral); border-bottom-color: var(--coral); }
/*
* Editorial language switcher. The trigger reads as part of the
* masthead line ("● LIVE · V0.7.0 / LANG · ZH-TW") — uppercase
* tracked text, no pill, no border. The dropdown is a small
* floating panel that mirrors the topbar's paper/ink palette but
* drops the tracking so native scripts (中文 / 한국어 / العربية)
* read at their intended rhythm.
*/
.locale-switch {
display: inline-block;
position: relative;
}
.locale-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
color: inherit;
list-style: none;
border-bottom: 1px solid transparent;
transition: color 160ms ease, border-color 160ms ease;
user-select: none;
outline: none;
padding: 0;
}
.locale-trigger::-webkit-details-marker { display: none; }
.locale-trigger:hover,
.locale-switch[open] > .locale-trigger,
.locale-trigger:focus-visible {
color: var(--coral);
border-bottom-color: var(--coral);
}
.locale-trigger-prefix {
color: var(--ink-faint);
}
.locale-trigger:hover .locale-trigger-prefix,
.locale-switch[open] > .locale-trigger .locale-trigger-prefix,
.locale-trigger:focus-visible .locale-trigger-prefix {
color: var(--coral);
}
.locale-trigger-sep {
opacity: 0.55;
}
.locale-trigger-code {
font: inherit;
letter-spacing: inherit;
color: var(--ink);
font-weight: 600;
}
.locale-trigger:hover .locale-trigger-code,
.locale-switch[open] > .locale-trigger .locale-trigger-code,
.locale-trigger:focus-visible .locale-trigger-code {
color: var(--coral);
}
.locale-trigger-caret {
width: 8px;
height: 5px;
flex-shrink: 0;
opacity: 0.7;
transition: transform 160ms ease, opacity 160ms ease;
}
.locale-switch[open] > .locale-trigger .locale-trigger-caret {
transform: rotate(180deg);
opacity: 1;
}
/*
* Two-column editorial catalogue. 17 locales × single-column would either
* scroll (ugly) or run most of the hero's height (worse). A 2-col grid
* keeps the panel under 9 rows so every language is visible at once and
* reads like a small index of nameplates rather than a dropdown.
*
* The 20px top offset gives clear breathing room from the topbar baseline
* — without it the active row (which mirrors the trigger label) feels
* fused to the chrome above it.
*/
.locale-menu {
position: absolute;
top: calc(100% + 20px);
right: 0;
z-index: 60;
display: grid;
grid-template-columns: repeat(2, minmax(168px, 1fr));
gap: 2px 4px;
padding: 10px;
background: var(--paper);
border: 1px solid rgba(21, 20, 15, 0.22);
box-shadow:
0 1px 0 rgba(21, 20, 15, 0.04),
0 28px 60px -32px rgba(21, 20, 15, 0.42);
font-family: var(--sans);
letter-spacing: normal;
text-transform: none;
/* Subtle entrance — matches the rest of the site's 200ms ease-out */
animation: locale-menu-in 180ms cubic-bezier(0.23, 1, 0.32, 1);
}
@keyframes locale-menu-in {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
.locale-menu-item {
display: flex;
align-items: baseline;
gap: 12px;
padding: 8px 12px;
color: var(--ink);
text-decoration: none;
font-size: 12.5px;
line-height: 1.2;
transition: background 140ms ease, color 140ms ease;
}
.locale-menu-item:hover {
background: color-mix(in oklab, var(--paper), var(--ink) 6%);
color: var(--coral);
}
.locale-menu-item:hover .locale-menu-code { color: var(--coral); }
.locale-menu-item.is-active {
background: color-mix(in oklab, var(--paper), var(--coral) 8%);
color: var(--coral);
}
.locale-menu-item.is-active .locale-menu-code {
color: var(--coral);
}
.locale-menu-code {
flex-shrink: 0;
min-width: 46px;
font-size: 9.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
transition: color 140ms ease;
}
.locale-menu-label {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (max-width: 520px) {
.locale-menu {
grid-template-columns: minmax(0, 1fr);
min-width: min(260px, calc(100vw - 32px));
}
.locale-menu-item { padding: 9px 12px; }
}
@media (prefers-reduced-motion: reduce) {
.locale-menu { animation: none; }
.locale-trigger-caret { transition: none; }
}
.topbar .pulse {
width: 6px; height: 6px;
border-radius: 50%;
background: var(--coral);
display: inline-block;
margin-right: 6px;
animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.35; }
}
/* nav */
/*
* The sticky + headroom behavior lives on the outer `.site-chrome`
* wrapper now (so the topbar + nav slide as one unit). This rule keeps
* only the spacing and surface treatment.
*/
.nav {
padding: 22px 0;
background: var(--paper);
border-bottom: 1px solid transparent;
}
.nav-inner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 8px;
font-family: var(--sans);
font-weight: 700;
letter-spacing: -0.01em;
color: var(--ink);
text-decoration: none;
font-size: 18px;
}
.brand-mark {
/*
* Bumped from 36px → 44px (≈22% larger). The new black brand mark
* needs the extra optical weight against the wordmark, especially
* given the speech-bubble negative space visually shrinks the glyph.
* (PR #2588's brand polish, restored on top of #2469.)
*/
width: 44px; height: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
}
.brand-name {
white-space: nowrap;
}
.brand-mark img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
/* Round the corners of the brand glyph (~22% of side, app-icon
* silhouette convention) so the solid-fill square reads as a
* brand mark next to the wordmark rather than a screenshot. */
border-radius: 10px;
}
.brand-meta {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
line-height: 1.3;
margin-left: 4px;
border-left: 1px solid var(--line);
padding-left: 14px;
}
.brand-meta b { display: block; color: var(--ink); font-weight: 600; }
.nav-links {
display: flex;
gap: 38px;
list-style: none;
}
.nav-links a {
color: var(--ink);
text-decoration: none;
font-family: var(--sans);
font-size: 14px;
font-weight: 500;
transition: color 0.18s ease;
position: relative;
}
.nav-links a:hover { color: var(--coral); }
.nav-links a .num {
font-size: 9px;
color: var(--ink-faint);
position: absolute;
top: -7px;
right: -16px;
letter-spacing: 0.04em;
}
/*
* Product dropdown — CSS-only, no JS. The submenu is hidden by default and
* revealed on `:hover` of the parent `li.has-dropdown`, or on `:focus-within`
* for keyboard navigation. This keeps the static export self-contained.
*/
.nav-links li.has-dropdown {
position: relative;
}
.nav-links .dropdown-caret {
display: inline-block;
margin-left: 4px;
font-size: 10px;
color: var(--ink-faint);
transition: transform 0.18s ease;
}
.nav-links li.has-dropdown:hover .dropdown-caret,
.nav-links li.has-dropdown:focus-within .dropdown-caret {
transform: translateY(1px);
color: var(--coral);
}
.nav-dropdown {
position: absolute;
top: 100%;
left: -16px;
margin: 0;
padding: 10px;
list-style: none;
min-width: 320px;
background: var(--paper);
border: 1px solid rgba(26, 26, 26, 0.12);
border-radius: 8px;
box-shadow: 0 12px 36px rgba(26, 26, 26, 0.08);
opacity: 0;
visibility: hidden;
transform: translateY(-4px);
transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
z-index: 50;
}
.nav-links li.has-dropdown:hover .nav-dropdown,
.nav-links li.has-dropdown:focus-within .nav-dropdown {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
/* invisible bridge so cursor can travel from trigger to menu without
* crossing a gap that closes the menu mid-traverse */
.nav-dropdown::before {
content: '';
position: absolute;
top: -10px;
left: 0;
right: 0;
height: 10px;
}
.nav-dropdown a {
display: block;
padding: 10px 12px;
border-radius: 6px;
color: var(--ink);
text-decoration: none;
transition: background 0.12s ease;
}
.nav-dropdown a:hover {
background: rgba(255, 122, 89, 0.08);
color: var(--ink);
}
.nav-dropdown a.is-active {
background: rgba(26, 26, 26, 0.04);
}
.nav-dropdown .dropdown-name {
display: block;
font-family: var(--sans);
font-size: 14px;
font-weight: 600;
margin-bottom: 2px;
}
.nav-dropdown .dropdown-blurb {
display: block;
font-size: 12px;
color: var(--ink-faint);
line-height: 1.4;
}
/*
* Hamburger toggle. Hidden at desktop widths (≥1080px). At narrower
* viewports it replaces the inline nav-links and toggles a panel
* underneath the header bar via a small handler in `header-enhancer`.
*/
.nav-toggle {
display: none;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
margin-left: auto;
padding: 0;
background: transparent;
border: 1px solid rgba(26, 26, 26, 0.18);
border-radius: 8px;
cursor: pointer;
color: var(--ink);
transition: background 0.18s ease, border-color 0.18s ease;
}
.nav-toggle:hover {
background: rgba(26, 26, 26, 0.04);
border-color: rgba(26, 26, 26, 0.32);
}
.nav-toggle-icon,
.nav-toggle-icon::before,
.nav-toggle-icon::after {
display: block;
width: 18px;
height: 2px;
background: currentColor;
border-radius: 2px;
transition: transform 0.18s ease, opacity 0.18s ease;
}
.nav-toggle-icon {
position: relative;
}
.nav-toggle-icon::before,
.nav-toggle-icon::after {
content: '';
position: absolute;
left: 0;
}
.nav-toggle-icon::before { top: -6px; }
.nav-toggle-icon::after { top: 6px; }
/* When open, morph into an "X" */
.nav.is-open .nav-toggle-icon { background: transparent; }
.nav.is-open .nav-toggle-icon::before { top: 0; transform: rotate(45deg); }
.nav.is-open .nav-toggle-icon::after { top: 0; transform: rotate(-45deg); }
.nav-side {
display: inline-flex;
align-items: center;
gap: 18px;
}
.nav-cta {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 9px 16px;
border-radius: 999px;
background: var(--ink);
color: var(--paper);
font-family: var(--sans);
font-size: 13px;
font-weight: 500;
text-decoration: none;
white-space: nowrap;
flex-shrink: 0;
}
.nav-cta [data-github-stars],
.nav-cta [data-github-version] {
font-variant-numeric: tabular-nums;
}
.nav-cta::after {
content: '★';
color: var(--mustard);
font-size: 11px;
}
.nav-cta.ghost {
background: transparent;
color: var(--ink);
border: 1px solid rgba(21, 20, 15, 0.18);
transition: background 160ms ease, border-color 160ms ease, transform 160ms ease;
}
.nav-cta.ghost:hover {
background: rgba(21, 20, 15, 0.04);
border-color: rgba(21, 20, 15, 0.36);
}
.nav-cta.ghost::after {
content: '↓';
color: var(--ink);
font-size: 12px;
}
.status-dot {
width: 28px; height: 28px;
border-radius: 50%;
border: 1px solid var(--line);
display: inline-flex;
align-items: center;
justify-content: center;
}
.status-dot::after {
content: '';
width: 6px; height: 6px;
border-radius: 50%;
background: var(--coral);
}
/* ---------- typography primitives ---------- */
.label {
font-family: var(--sans);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--coral);
display: inline-flex;
align-items: center;
gap: 12px;
}
.label::before {
content: '';
width: 18px;
height: 1px;
background: var(--coral);
display: inline-block;
}
.label .ix {
color: var(--ink-faint);
font-weight: 500;
margin-left: 4px;
}
.display {
font-family: var(--sans);
font-weight: 800;
letter-spacing: -0.028em;
color: var(--ink);
line-height: 1.0;
}
.display em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
letter-spacing: -0.018em;
}
.display .dot { color: var(--coral); }
.lead {
font-family: var(--body);
font-size: 16px;
line-height: 1.55;
color: var(--ink-soft);
max-width: 36ch;
}
.meta {
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.coord {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.04em;
color: var(--ink-faint);
}
.roman {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
color: var(--coral);
}
/* buttons */
.btn {
display: inline-flex;
align-items: center;
gap: 12px;
padding: 14px 22px;
border-radius: 999px;
font-family: var(--sans);
font-size: 14px;
font-weight: 500;
letter-spacing: -0.005em;
text-decoration: none;
border: 1px solid transparent;
transition: transform 0.18s ease, background 0.18s ease, color 0.18s ease;
cursor: pointer;
white-space: nowrap;
}
.btn-primary {
background: var(--coral);
color: #fff;
box-shadow: 0 14px 26px -16px rgba(237, 111, 92, 1);
}
.btn-primary:hover { transform: translateY(-1px); background: #e25e4a; }
.btn-ghost {
background: transparent;
color: var(--ink);
border-color: rgba(21, 20, 15, 0.2);
}
.btn-ghost:hover { background: rgba(21, 20, 15, 0.04); }
.btn .arrow {
width: 16px; height: 16px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.btn .arrow svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.6; }
/* helper used inline in headlines */
.code-inline {
font-family: var(--mono);
font-size: 14px;
background: var(--bone);
padding: 1px 6px;
border-radius: 4px;
}
/* ---------- HERO ---------- */
.hero {
position: relative;
padding: 0;
min-height: calc(100vh - 140px);
display: flex;
flex-direction: column;
align-items: stretch;
border-bottom: 1px solid var(--line);
}
.hero > .container { flex: 0 0 auto; }
.hero > .container.hero-grid { flex: 1 1 auto; }
.hero::before {
content: '';
position: absolute;
left: 50%;
top: 0;
bottom: 0;
width: 1px;
background: var(--line-soft);
z-index: 0;
display: none;
}
.hero-grid {
display: grid;
grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
gap: 36px;
align-items: stretch;
width: 100%;
position: relative;
}
.hero-copy {
padding: 4vh 0 4vh;
display: flex;
flex-direction: column;
position: relative;
}
.hero-discord-pill {
align-self: flex-start;
display: inline-flex;
align-items: center;
gap: 7px;
margin-bottom: 22px;
padding: 7px 13px;
border: 1px solid rgba(237, 111, 92, 0.28);
border-radius: 999px;
background: rgba(237, 111, 92, 0.12);
color: var(--coral);
font-family: var(--sans);
font-size: 12px;
font-weight: 600;
letter-spacing: -0.005em;
line-height: 1;
text-decoration: none;
box-shadow: 0 12px 24px -22px rgba(237, 111, 92, 0.8);
transition: transform 160ms ease, background 160ms ease, border-color 160ms ease;
}
.hero-discord-pill:hover {
transform: translateY(-1px);
border-color: rgba(237, 111, 92, 0.46);
background: rgba(237, 111, 92, 0.18);
}
.hero-discord-pill span {
font-size: 8px;
line-height: 1;
}
.hero-copy .label { margin-bottom: 28px; }
.hero-copy .lead { margin-bottom: 30px; max-width: 38ch; font-size: 16px; }
.hero h1 {
font-size: clamp(44px, 5vw, 78px);
line-height: 1.0;
margin-bottom: 28px;
}
.hero-actions {
display: inline-flex;
align-items: center;
gap: 14px;
margin-bottom: 38px;
}
.hero-stats {
display: flex;
align-items: center;
gap: 22px;
flex-wrap: nowrap;
margin-bottom: 28px;
}
.hero-stats .stat { display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; }
.hero-stats .stat .ring {
width: 34px; height: 34px;
border-radius: 50%;
border: 1px dashed var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--sans);
font-size: 11px;
font-weight: 700;
flex-shrink: 0;
}
.hero-stats .stat .ring.solid { border-style: solid; }
.hero-stats .stat .ring.coral { border-color: var(--coral); color: var(--coral); }
.hero-stats .stat-label {
font-family: var(--sans);
font-size: 11px;
line-height: 1.25;
color: var(--ink-soft);
letter-spacing: 0.04em;
text-transform: uppercase;
}
.hero-stats .stat-label b { display: block; font-weight: 700; color: var(--ink); font-size: 12px; }
.hero-foot {
margin-top: auto;
padding-top: 22px;
border-top: 1px solid var(--line);
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
}
.hero-foot .meta { line-height: 1.4; }
.hero-art {
position: relative;
height: calc(100vh - 160px);
max-height: 860px;
margin-left: auto;
margin-right: -12px;
width: 100%;
overflow: visible;
}
.hero-art img {
width: 100%; height: 100%;
object-fit: contain;
object-position: right center;
display: block;
}
/* image annotations */
.annot {
position: absolute;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
line-height: 1.4;
white-space: nowrap;
}
.annot.has-line::before {
content: '';
position: absolute;
background: var(--ink-faint);
}
.annot-tl { top: 14px; left: 14px; }
.annot-tr { top: 14px; right: 14px; text-align: right; }
.annot-bl { bottom: 14px; left: 14px; }
.annot-br { bottom: 14px; right: 14px; text-align: right; }
.annot.coord { font-family: var(--mono); font-size: 10px; letter-spacing: 0.04em; text-transform: none; }
.hero-art .index {
position: absolute;
right: 12px;
top: 36%;
font-family: var(--sans);
font-size: 10.5px;
font-weight: 600;
letter-spacing: 0.16em;
color: var(--ink-faint);
text-transform: uppercase;
background: rgba(239, 231, 210, 0.7);
padding: 10px 12px;
border: 1px solid var(--line-soft);
border-radius: 6px;
backdrop-filter: blur(2px);
}
.hero-art .index span { display: block; line-height: 1.6; }
.hero-art .index span .n { color: var(--coral); margin-right: 6px; font-weight: 700; }
.hero-art .index span.on { color: var(--ink); font-weight: 700; }
.hero-art .index span.on .n { color: var(--coral); }
.hero-art .corner {
position: absolute;
width: 22px; height: 22px;
border-color: var(--ink-faint);
border-style: solid;
border-width: 0;
}
.hero-art .corner.tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.hero-art .corner.tr { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.hero-art .corner.bl { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; }
.hero-art .corner.br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }
/* ---------- common section header ---------- */
section { position: relative; padding: 130px 0; }
section.tight { padding: 90px 0; }
.sec-rule {
border-top: 1px solid var(--line);
padding-top: 18px;
margin-bottom: 48px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.sec-rule .roman {
font-family: var(--serif);
font-style: italic;
color: var(--coral);
font-size: 14px;
letter-spacing: 0.05em;
text-transform: none;
}
.sec-rule .meta-grp { display: inline-flex; gap: 26px; }
.sec-rule .dot-mark { color: var(--coral); }
.section-header { margin-bottom: 70px; }
.section-header .label { margin-bottom: 32px; }
.section-header h2 {
font-size: clamp(40px, 4.6vw, 66px);
max-width: 22ch;
}
.section-header .lead { margin-top: 22px; }
/* ---------- WIRE / GLOBAL TICKER ----------
*
* Slim editorial strip between the hero and the About section. Two
* counter-scrolling marquees (cities → and contributors ←) signal that
* the project is global and community-driven, without disrupting the
* existing roman-numeral section count. Pure CSS animation; the track
* content is duplicated in markup so the loop wraps seamlessly.
*/
.wire {
border-bottom: 1px solid var(--line);
padding: 26px 0 28px;
background: var(--paper);
position: relative;
overflow: hidden;
}
.wire-inner {
display: grid;
grid-template-columns: minmax(180px, 220px) minmax(0, 1fr);
gap: 32px;
align-items: center;
}
.wire-left {
display: inline-flex;
align-items: center;
gap: 14px;
border-right: 1px solid var(--line);
padding-right: 24px;
min-height: 56px;
}
.wire-mark {
width: 22px;
height: 22px;
border-radius: 50%;
border: 1px solid var(--line);
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.wire-pulse {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--coral);
display: inline-block;
animation: pulse 2.4s ease-in-out infinite;
}
.wire-title {
font-family: var(--sans);
font-size: 11px;
line-height: 1.4;
display: flex;
flex-direction: column;
gap: 3px;
}
.wire-title b {
color: var(--ink);
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.wire-title span {
color: var(--ink-faint);
font-size: 10px;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.wire-rows {
display: grid;
gap: 8px;
min-width: 0;
}
.wire-row {
overflow: hidden;
mask-image: linear-gradient(
90deg,
transparent,
black 5%,
black 95%,
transparent
);
-webkit-mask-image: linear-gradient(
90deg,
transparent,
black 5%,
black 95%,
transparent
);
}
.marquee-track {
display: inline-flex;
align-items: center;
gap: 36px;
width: max-content;
white-space: nowrap;
animation: marquee-x 52s linear infinite;
will-change: transform;
}
.wire-row.reverse .marquee-track {
animation-direction: reverse;
animation-duration: 64s;
}
.wire-row:hover .marquee-track {
animation-play-state: paused;
}
@keyframes marquee-x {
from {
transform: translateX(0);
}
to {
transform: translateX(-50%);
}
}
.wire-item {
display: inline-flex;
align-items: baseline;
gap: 8px;
font-family: var(--sans);
font-size: 12px;
letter-spacing: 0.04em;
color: var(--ink-mute);
text-decoration: none;
flex-shrink: 0;
}
.wire-item .wire-dot {
color: var(--coral);
font-size: 16px;
line-height: 0;
position: relative;
top: -1px;
margin-right: 2px;
}
.wire-item .wire-coord {
font-family: var(--mono);
font-size: 10.5px;
color: var(--ink-faint);
letter-spacing: 0;
}
.wire-item .wire-name {
text-transform: uppercase;
letter-spacing: 0.18em;
color: var(--ink);
font-weight: 500;
}
.wire-item .wire-handle {
font-family: var(--mono);
color: var(--ink);
font-size: 11.5px;
font-weight: 500;
}
.wire-item .wire-role {
text-transform: uppercase;
letter-spacing: 0.16em;
color: var(--coral);
font-size: 10px;
}
.wire-item.is-link {
transition: color 160ms ease;
}
.wire-item.is-link:hover .wire-handle {
color: var(--coral);
}
@media (prefers-reduced-motion: reduce) {
.marquee-track {
animation: none;
}
}
/* ---------- ABOUT ---------- */
.about-grid {
display: grid;
grid-template-columns: 1.05fr 1fr;
gap: 80px;
align-items: center;
}
.about h2 {
font-size: clamp(44px, 5.4vw, 78px);
margin: 30px 0 36px;
}
.about .label { margin-bottom: 28px; }
.about .lead { margin-bottom: 36px; max-width: 42ch; font-size: 17px; }
.about .footer-row {
display: flex;
align-items: center;
gap: 20px;
margin-top: 56px;
color: var(--ink-faint);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.about .footer-row .mark {
width: 30px; height: 30px;
border-radius: 50%;
border: 1px solid var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--serif);
font-style: italic;
font-size: 14px;
color: var(--ink);
}
.about .stamp {
margin-left: auto;
display: inline-flex;
flex-direction: column;
align-items: flex-end;
line-height: 1.4;
}
.about .stamp span:first-child { color: var(--coral); }
.about-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 620px;
margin-left: auto;
}
.about-art img { width: 100%; height: 100%; object-fit: contain; }
.about-side-note {
position: absolute;
right: -8px;
top: 26px;
text-align: right;
font-family: var(--sans);
font-size: 10.5px;
line-height: 1.55;
color: var(--ink-faint);
letter-spacing: 0.04em;
max-width: 16ch;
}
.about-side-note b {
display: block;
color: var(--coral);
width: 36px;
height: 1px;
background: var(--coral);
margin: 0 0 10px auto;
}
.about-caption {
position: absolute;
right: 18px;
bottom: 4px;
font-family: var(--sans);
font-size: 9.5px;
color: var(--ink-faint);
text-align: right;
letter-spacing: 0.06em;
line-height: 1.45;
}
.about-caption b { color: var(--ink); display: block; }
/* ---------- CAPABILITIES ---------- */
.capabilities-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 70px;
align-items: center;
}
.capabilities-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 600px;
}
.capabilities-art img { width: 100%; height: 100%; object-fit: contain; }
.capabilities-art .ribbon {
position: absolute;
right: -42px;
top: 50%;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.42em;
text-transform: uppercase;
color: var(--ink-faint);
writing-mode: vertical-rl;
transform: rotate(180deg);
}
.capabilities-art .ribbon b { color: var(--coral); }
.capabilities-art .corner { position: absolute; width: 22px; height: 22px; border-color: var(--ink-faint); border-style: solid; border-width: 0; }
.capabilities-art .corner.tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.capabilities-art .corner.br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }
.capabilities-copy h2 { font-size: clamp(40px, 4.8vw, 64px); margin: 22px 0 30px; }
.cards {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
margin-top: 22px;
}
.card {
padding: 28px 26px 32px;
background: var(--bone);
border-radius: 18px;
box-shadow: var(--shadow), inset 0 0 0 1px rgba(21, 20, 15, 0.06);
position: relative;
overflow: hidden;
transition: transform 0.2s ease;
}
.card:hover { transform: translateY(-3px); }
.card .num {
font-family: var(--serif);
font-style: italic;
font-size: 22px;
font-weight: 500;
color: var(--coral);
letter-spacing: 0.04em;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: baseline;
}
.card .num .tag {
font-family: var(--sans);
font-size: 9.5px;
color: var(--ink-faint);
letter-spacing: 0.18em;
text-transform: uppercase;
font-style: normal;
font-weight: 500;
}
.card .icon {
width: 28px;
height: 28px;
margin-bottom: 16px;
color: var(--ink);
}
.card h3 {
font-family: var(--sans);
font-size: 22px;
font-weight: 700;
line-height: 1.05;
letter-spacing: -0.014em;
margin-bottom: 14px;
}
.card p {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-mute);
line-height: 1.55;
max-width: 24ch;
}
.card .arrow-mark {
position: absolute;
right: 22px;
bottom: 22px;
width: 28px; height: 28px;
border: 1px solid var(--line);
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--ink);
transition: all 0.18s ease;
}
.card:hover .arrow-mark { background: var(--coral); border-color: var(--coral); color: #fff; }
.card .arrow-mark svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 1.6; }
/* ---------- LABS ---------- */
.labs-head {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 60px;
align-items: end;
margin-bottom: 48px;
}
.labs-head h2 { font-size: clamp(40px, 4.8vw, 68px); }
.pills {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: flex-end;
}
.pill {
padding: 9px 18px;
border-radius: 999px;
border: 1px solid var(--line);
font-family: var(--sans);
font-size: 13px;
color: var(--ink-soft);
background: transparent;
cursor: pointer;
transition: all 0.18s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.pill:hover { background: rgba(21, 20, 15, 0.04); }
.pill.active {
background: var(--coral);
border-color: var(--coral);
color: #fff;
}
.pill .count {
font-size: 10px;
color: var(--ink-faint);
border-left: 1px solid var(--line);
padding-left: 8px;
}
.pill.active .count { color: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.3); }
.labs-meta {
display: flex;
align-items: flex-start;
justify-content: flex-end;
gap: 22px;
margin-bottom: 30px;
}
.labs-meta .ring {
width: 38px; height: 38px;
border-radius: 50%;
border: 1px dashed var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--sans);
font-size: 11px;
font-weight: 700;
}
.labs-meta .meta-text {
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
line-height: 1.55;
color: var(--ink-faint);
max-width: 28ch;
}
.labs-meta .meta-text b { display: block; color: var(--ink); }
.labs-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 22px;
}
.lab {
display: flex;
flex-direction: column;
}
.lab-img {
aspect-ratio: 4 / 5;
background: var(--bone);
border-radius: 14px;
overflow: hidden;
margin-bottom: 18px;
box-shadow: var(--shadow);
position: relative;
}
.lab-img img { width: 100%; height: 100%; object-fit: cover; }
.lab-img .badge {
position: absolute;
top: 12px;
left: 12px;
background: rgba(239, 231, 210, 0.9);
color: var(--ink);
padding: 4px 9px;
border-radius: 4px;
font-family: var(--sans);
font-size: 9.5px;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.lab .num-row {
font-family: var(--sans);
font-size: 10.5px;
color: var(--ink-faint);
letter-spacing: 0.14em;
margin-bottom: 8px;
display: flex;
justify-content: space-between;
text-transform: uppercase;
}
.lab h4 {
font-family: var(--sans);
font-size: 18px;
font-weight: 700;
letter-spacing: -0.014em;
margin-bottom: 8px;
}
.lab p {
font-family: var(--body);
font-size: 13px;
color: var(--ink-mute);
line-height: 1.55;
margin-bottom: 14px;
}
.lab .arrow-mark {
width: 28px; height: 28px;
border: 1px solid var(--line);
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--ink);
margin-top: auto;
align-self: flex-start;
}
.lab .arrow-mark svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 1.6; }
.labs-foot {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 50px;
border-top: 1px dashed var(--line);
padding-top: 22px;
}
.progress {
display: flex;
align-items: center;
gap: 8px;
}
.progress span {
width: 26px; height: 2px;
background: var(--line);
border-radius: 2px;
}
.progress span.on { background: var(--coral); }
/* ---------- METHOD ---------- */
.method-head {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 60px;
align-items: start;
margin-bottom: 80px;
}
.method-head h2 { font-size: clamp(44px, 5.2vw, 76px); }
.method-head .right {
display: flex;
align-items: flex-start;
gap: 14px;
padding-top: 14px;
}
.method-head .plus {
color: var(--coral);
font-size: 24px;
line-height: 1;
font-family: var(--sans);
}
.method-head .right p {
font-family: var(--sans);
font-size: 13px;
color: var(--ink-soft);
max-width: 22ch;
line-height: 1.55;
}
.method-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 50px;
position: relative;
}
.method-grid::before {
content: '';
position: absolute;
top: 60px;
left: 50px;
right: 50px;
height: 1px;
background: var(--line-soft);
}
.method-step { position: relative; }
.method-step .num {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
font-size: 78px;
color: var(--coral);
line-height: 0.85;
margin-bottom: 24px;
letter-spacing: -0.02em;
background: var(--paper);
display: inline-block;
padding-right: 12px;
position: relative;
z-index: 1;
}
.method-step h4 {
font-family: var(--sans);
font-size: 30px;
font-weight: 800;
letter-spacing: -0.022em;
margin-bottom: 18px;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 18px;
}
.method-step h4 .arrow-r {
color: var(--ink-faint);
font-size: 22px;
line-height: 1;
}
.method-step:last-child h4 .arrow-r { display: none; }
.method-step p {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-mute);
line-height: 1.55;
margin-bottom: 24px;
max-width: 24ch;
}
.method-step .img {
aspect-ratio: 1 / 1;
background: var(--bone);
border-radius: 12px;
overflow: hidden;
box-shadow: var(--shadow);
}
.method-step .img img { width: 100%; height: 100%; object-fit: cover; }
.method-foot {
margin-top: 80px;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px dashed var(--line);
padding-top: 24px;
}
.method-foot .left,
.method-foot .right {
font-family: var(--sans);
font-size: 11px;
color: var(--ink-faint);
letter-spacing: 0.18em;
text-transform: uppercase;
}
.method-foot .left {
display: inline-flex;
align-items: center;
gap: 12px;
}
.method-foot .left .ring {
width: 20px; height: 20px;
border: 1px dashed var(--ink-faint);
border-radius: 50%;
}
.method-foot .right b { color: var(--ink); }
/* ---------- WORK ---------- */
.work {
background: #15140f;
color: var(--paper);
border-radius: 32px;
margin: 0 64px;
overflow: hidden;
position: relative;
padding: 110px 64px;
}
.work::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background-image:
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n2'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 0.95 0 0 0 0 0.85 0 0 0 0.05 0'/></filter><rect width='100%' height='100%' filter='url(%23n2)'/></svg>");
background-size: 240px 240px;
opacity: 0.6;
mix-blend-mode: screen;
}
.work-rule {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid rgba(247, 241, 222, 0.16);
padding-top: 16px;
margin-bottom: 60px;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: rgba(247, 241, 222, 0.55);
}
.work-rule .roman { color: var(--coral); font-family: var(--serif); font-style: italic; font-size: 14px; letter-spacing: 0.04em; text-transform: none; }
.work-grid {
display: grid;
grid-template-columns: 1fr 1.05fr 0.85fr;
gap: 48px;
align-items: center;
position: relative;
}
.work .label { color: var(--coral); }
.work .label::before { background: var(--coral); }
.work-copy h2 {
font-family: var(--sans);
font-weight: 800;
font-size: clamp(40px, 5vw, 66px);
line-height: 1.0;
letter-spacing: -0.024em;
margin: 28px 0 36px;
color: var(--paper);
}
.work-copy h2 em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
}
.work-copy h2 .dot { color: var(--coral); }
.work-link {
display: inline-flex;
align-items: center;
gap: 18px;
color: var(--paper);
font-family: var(--sans);
font-size: 14px;
text-decoration: none;
border-bottom: 2px solid var(--coral);
padding-bottom: 12px;
width: fit-content;
}
.work-link::after { content: '↗'; color: var(--coral); }
.work-card {
background: var(--paper);
color: var(--ink);
border-radius: 18px;
padding: 32px 30px;
position: relative;
transform: rotate(-1.2deg);
text-decoration: none;
display: block;
transition: transform 280ms ease, box-shadow 280ms ease;
}
.work-card:hover {
transform: rotate(-1.2deg) translateY(-4px);
box-shadow: var(--shadow);
}
.work-card.alt {
transform: rotate(2.4deg) translateY(20px);
padding: 28px 26px;
}
.work-card.alt:hover {
transform: rotate(2.4deg) translateY(16px);
box-shadow: var(--shadow);
}
.work-card .label-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 22px;
}
.work-card .small-label {
font-family: var(--sans);
font-size: 10.5px;
color: var(--coral);
letter-spacing: 0.18em;
text-transform: uppercase;
font-weight: 600;
}
.work-card .index {
font-family: var(--mono);
font-size: 11px;
color: var(--ink-faint);
letter-spacing: 0.04em;
}
.work-card h3 {
font-family: var(--sans);
font-size: clamp(26px, 2.4vw, 38px);
font-weight: 800;
letter-spacing: -0.022em;
line-height: 1.05;
margin-bottom: 14px;
}
.work-card p {
font-family: var(--body);
font-size: 14px;
color: var(--ink-mute);
line-height: 1.55;
margin-bottom: 22px;
max-width: 28ch;
}
.work-card .img {
aspect-ratio: 4 / 3;
background: var(--bone);
border-radius: 12px;
overflow: hidden;
margin-bottom: 22px;
}
.work-card .img img { width: 100%; height: 100%; object-fit: cover; }
.work-card .meta-row {
display: flex;
justify-content: space-between;
color: var(--ink-faint);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
border-top: 1px solid var(--line);
padding-top: 14px;
}
.work-card .year { color: var(--coral); font-weight: 600; }
.work-arrows {
position: absolute;
right: 64px;
bottom: 64px;
display: inline-flex;
align-items: center;
gap: 10px;
}
.work-arrows .nav-btn {
width: 46px; height: 46px;
border-radius: 50%;
border: 1px solid rgba(247, 241, 222, 0.2);
background: transparent;
color: var(--paper);
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.work-arrows .nav-btn.active { background: var(--coral); border-color: var(--coral); }
/* ---------- TESTIMONIAL / COLLABORATORS ---------- */
.testimonial-grid {
display: grid;
grid-template-columns: 1.2fr 1fr;
gap: 80px;
align-items: center;
}
.testimonial-copy h2 {
font-family: var(--sans);
font-size: clamp(36px, 4vw, 54px);
font-weight: 700;
letter-spacing: -0.022em;
line-height: 1.12;
margin-bottom: 36px;
}
.testimonial-copy h2 em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
}
.author {
display: flex;
align-items: center;
gap: 18px;
margin-top: 22px;
}
.author .avatar {
width: 50px; height: 50px;
border-radius: 50%;
background: var(--ink);
overflow: hidden;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--paper);
font-family: var(--serif);
font-style: italic;
font-size: 24px;
}
.author p {
font-family: var(--sans);
font-size: 14px;
color: var(--ink);
font-weight: 600;
}
.author p span {
display: block;
color: var(--ink-mute);
font-weight: 400;
}
.divider {
border-top: 1px solid var(--line);
margin: 60px 0 32px;
}
.partners-text {
font-family: var(--body);
font-size: 14px;
color: var(--ink-mute);
margin-bottom: 26px;
max-width: 38ch;
}
.partners {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 22px;
align-items: end;
}
.partner {
display: flex;
flex-direction: column;
gap: 10px;
text-decoration: none;
color: inherit;
cursor: pointer;
transition: transform 220ms ease;
}
.partner:hover { transform: translateY(-2px); }
.partner:hover .glyph { color: var(--coral); }
.partner:hover span { color: var(--coral); }
.partner .glyph {
height: 32px;
display: flex;
align-items: center;
color: var(--ink);
transition: color 220ms ease;
}
.partner .glyph svg { height: 100%; width: auto; max-width: 90px; }
.partner span {
font-family: var(--sans);
font-size: 13px;
color: var(--ink);
letter-spacing: -0.005em;
font-weight: 600;
transition: color 220ms ease;
}
.partner small {
font-family: var(--sans);
font-size: 10px;
color: var(--ink-faint);
letter-spacing: 0.1em;
text-transform: uppercase;
}
.read-more {
margin-top: 56px;
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--sans);
font-size: 13px;
color: var(--ink);
text-decoration: none;
letter-spacing: 0.04em;
border-bottom: 1px solid var(--coral);
padding-bottom: 6px;
}
.read-more::after { content: '→'; color: var(--coral); }
.testimonial-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 560px;
}
.testimonial-art img { width: 100%; height: 100%; object-fit: contain; }
/* ---------- CTA ---------- */
.cta-grid {
display: grid;
grid-template-columns: 1.05fr 1fr;
gap: 50px;
align-items: center;
}
.cta h2 {
font-size: clamp(54px, 6.6vw, 100px);
margin: 32px 0 32px;
}
.cta .lead { margin-bottom: 36px; max-width: 36ch; font-size: 16px; }
.cta-actions {
display: inline-flex;
align-items: center;
gap: 14px;
margin-bottom: 32px;
}
.email-pill {
display: inline-flex;
align-items: center;
gap: 12px;
padding: 14px 18px 14px 22px;
border-radius: 999px;
border: 1px solid var(--line);
font-family: var(--sans);
font-size: 14px;
color: var(--ink);
text-decoration: none;
}
.email-pill .arrow-circle {
width: 22px; height: 22px;
border-radius: 50%;
background: var(--ink);
color: var(--paper);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
.cta-foot {
display: flex;
gap: 28px;
align-items: center;
margin-top: 32px;
padding-top: 22px;
border-top: 1px solid var(--line);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.cta-foot .stamp { color: var(--coral); font-weight: 600; }
.cta-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 620px;
margin-left: auto;
}
.cta-art img { width: 100%; height: 100%; object-fit: contain; }
.cta-art .index {
position: absolute;
right: 8px;
top: 24px;
font-family: var(--serif);
font-style: italic;
font-size: 28px;
color: var(--ink-faint);
}
.cta-art .ribbon {
position: absolute;
left: -32px;
top: 50%;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.42em;
text-transform: uppercase;
color: var(--ink-faint);
writing-mode: vertical-rl;
transform: rotate(180deg);
}
/* ---------- OFFICIAL SOURCE STRIP ----------
*
* Slim attestation band that sits between the hero/wire and About.
* Reinforces the canonical surfaces — official site, GitHub repo,
* releases, download, docs, Discord — for both Google entity merge
* and human verification. Minimal chrome on purpose.
*/
.official-strip {
padding: 38px 0 18px;
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
background: var(--paper);
}
.official-strip-inner {
display: grid;
grid-template-columns: minmax(180px, 220px) 1fr;
gap: 28px;
align-items: center;
}
.official-strip-label {
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-mute);
}
.official-strip-label .ix {
color: var(--coral);
margin-left: 6px;
}
.official-strip-list {
list-style: none;
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 18px 24px;
padding: 0;
margin: 0;
}
.official-strip-list li {
display: flex;
min-width: 0;
}
.official-strip-list a {
display: grid;
gap: 4px;
padding: 6px 0;
border-bottom: 1px solid transparent;
text-decoration: none;
color: var(--ink);
font-family: var(--sans);
min-width: 0;
transition: border-color 0.16s ease, color 0.16s ease;
}
.official-strip-list a:hover {
border-bottom-color: var(--coral);
color: var(--coral);
}
.official-strip-list .label {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--ink-mute);
}
.official-strip-list .value {
font-size: 13.5px;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 980px) {
.official-strip-inner {
grid-template-columns: 1fr;
gap: 18px;
}
.official-strip-list {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media (max-width: 560px) {
.official-strip-list {
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px 18px;
}
}
/* ---------- FAQ ---------- */
.faq-head {
max-width: 880px;
margin: 36px 0 48px;
}
.faq-head .label {
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-mute);
display: inline-block;
margin-bottom: 18px;
}
.faq-head .display {
font-family: var(--serif);
font-weight: 600;
font-size: clamp(36px, 5.4vw, 64px);
line-height: 1.06;
letter-spacing: -0.022em;
color: var(--ink);
}
.faq-head .display em {
font-style: italic;
font-weight: 600;
color: var(--coral);
}
.faq-head .display .dot { color: var(--coral); }
.faq-list {
list-style: none;
padding: 0;
margin: 0;
border-top: 1px solid var(--line);
}
.faq-item {
border-bottom: 1px solid var(--line);
}
.faq-item details {
padding: 0;
}
.faq-item summary {
display: grid;
grid-template-columns: 56px 1fr 32px;
gap: 24px;
align-items: center;
padding: 26px 0;
cursor: pointer;
list-style: none;
user-select: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-index {
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.16em;
color: var(--ink-faint);
}
.faq-q {
font-family: var(--serif);
font-size: clamp(20px, 2.2vw, 26px);
line-height: 1.25;
color: var(--ink);
}
.faq-toggle {
justify-self: end;
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid var(--line);
color: var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--sans);
font-size: 16px;
transition: transform 0.22s cubic-bezier(0.23, 1, 0.32, 1),
background-color 0.22s cubic-bezier(0.23, 1, 0.32, 1),
color 0.22s cubic-bezier(0.23, 1, 0.32, 1);
}
.faq-item details[open] .faq-toggle {
transform: rotate(45deg);
background: var(--ink);
color: var(--paper);
border-color: var(--ink);
}
.faq-a {
grid-column: 2 / 3;
margin: 0 0 26px;
padding-left: 80px;
max-width: 64ch;
font-family: var(--sans);
font-size: 15.5px;
line-height: 1.7;
color: var(--ink-mute);
}
@media (max-width: 720px) {
.faq-item summary {
grid-template-columns: 36px 1fr 28px;
gap: 14px;
padding: 20px 0;
}
.faq-a {
padding-left: 50px;
font-size: 14.5px;
}
}
/* ---------- FOOTER ---------- */
footer {
border-top: 1px solid var(--line);
padding: 60px 0 30px;
margin-top: 60px;
}
.foot-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
gap: 40px;
margin-bottom: 60px;
}
.foot-brand .brand { margin-bottom: 18px; }
.foot-brand p {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-mute);
line-height: 1.55;
max-width: 38ch;
}
.foot-cta {
display: inline-flex;
align-items: center;
gap: 10px;
margin-top: 22px;
padding: 11px 18px;
border-radius: 999px;
background: var(--ink);
color: var(--paper);
font-family: var(--sans);
font-size: 13px;
font-weight: 500;
letter-spacing: -0.005em;
text-decoration: none;
transition: transform 160ms ease, background 160ms ease;
}
.foot-cta:hover {
transform: translateY(-1px);
background: var(--ink-soft);
}
.foot-cta::after {
content: '↓';
color: var(--mustard);
font-size: 12px;
}
.foot-cta .meta {
color: rgba(239, 231, 210, 0.55);
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
margin-left: 4px;
}
.foot-brand p .inline-link,
.inline-link {
color: var(--ink);
text-decoration: none;
border-bottom: 1px solid var(--line);
transition: color 160ms ease, border-color 160ms ease;
}
.inline-link:hover {
color: var(--coral);
border-bottom-color: var(--coral);
}
.method-repo-link {
color: inherit;
text-decoration: none;
border-bottom: 1px solid transparent;
transition: color 160ms ease, border-color 160ms ease;
}
.method-repo-link:hover {
color: var(--coral);
border-bottom-color: var(--coral);
}
.library-link {
text-decoration: none;
border-bottom: 1px solid transparent;
transition: border-color 160ms ease;
}
.library-link:hover { border-bottom-color: var(--coral); }
.foot-col h5 {
font-family: var(--sans);
font-size: 11px;
color: var(--ink);
letter-spacing: 0.18em;
text-transform: uppercase;
margin-bottom: 18px;
font-weight: 700;
}
.foot-col ul { list-style: none; }
.foot-col li { margin-bottom: 10px; }
.foot-col a {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-soft);
text-decoration: none;
}
.foot-col a:hover { color: var(--coral); }
.foot-bottom {
border-top: 1px solid var(--line);
padding-top: 22px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--ink-faint);
}
.foot-bottom .right { display: inline-flex; gap: 24px; align-items: center; }
.foot-bottom .pulse {
width: 6px; height: 6px;
border-radius: 50%;
background: var(--coral);
display: inline-block;
margin-right: 6px;
vertical-align: middle;
}
.foot-mega {
margin-top: 60px;
padding-top: 0;
padding-bottom: 12px;
border-top: 1px solid var(--line);
overflow-x: hidden;
overflow-y: visible;
}
.foot-mega .word {
font-family: var(--sans);
font-weight: 900;
font-size: clamp(70px, 13vw, 200px);
letter-spacing: -0.04em;
line-height: 1.05;
color: var(--ink);
white-space: nowrap;
margin-top: 30px;
padding-bottom: 0.18em;
}
.foot-mega .word em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
color: var(--coral);
}
/* ---------- scroll-reveal motion ----------
*
* Driven by `app/_components/reveal-root.tsx`. Elements with
* `data-reveal` start hidden + offset; the observer sets
* `data-revealed='true'` once they enter the viewport, triggering
* the transition.
*
* Uses `translate` / `scale` longhand properties (not `transform`) so
* that elements like `.work-card` keep their static `transform: rotate()`
* intact while still translating in.
*/
[data-reveal] {
opacity: 0;
translate: 0 28px;
transition:
opacity 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms),
translate 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms),
scale 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms);
will-change: opacity, translate, scale;
}
[data-reveal='left'] { translate: -36px 0; }
[data-reveal='right'] { translate: 36px 0; }
[data-reveal='scale'] { translate: 0 0; scale: 0.96; }
[data-reveal='rise-lg'] { translate: 0 64px; scale: 0.985; }
[data-reveal][data-revealed='true'] {
opacity: 1;
translate: 0 0;
scale: 1;
}
/* stagger primitives — set --reveal-delay on grid children so siblings
* appear in sequence rather than all at once. */
.cards > .card[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.cards > .card[data-reveal]:nth-child(2) { --reveal-delay: 90ms; }
.cards > .card[data-reveal]:nth-child(3) { --reveal-delay: 180ms; }
.cards > .card[data-reveal]:nth-child(4) { --reveal-delay: 270ms; }
.labs-grid > .lab[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.labs-grid > .lab[data-reveal]:nth-child(2) { --reveal-delay: 90ms; }
.labs-grid > .lab[data-reveal]:nth-child(3) { --reveal-delay: 180ms; }
.labs-grid > .lab[data-reveal]:nth-child(4) { --reveal-delay: 270ms; }
.labs-grid > .lab[data-reveal]:nth-child(5) { --reveal-delay: 360ms; }
.method-grid > .method-step[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.method-grid > .method-step[data-reveal]:nth-child(2) { --reveal-delay: 110ms; }
.method-grid > .method-step[data-reveal]:nth-child(3) { --reveal-delay: 220ms; }
.method-grid > .method-step[data-reveal]:nth-child(4) { --reveal-delay: 330ms; }
.partners > .partner[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.partners > .partner[data-reveal]:nth-child(2) { --reveal-delay: 70ms; }
.partners > .partner[data-reveal]:nth-child(3) { --reveal-delay: 140ms; }
.partners > .partner[data-reveal]:nth-child(4) { --reveal-delay: 210ms; }
.partners > .partner[data-reveal]:nth-child(5) { --reveal-delay: 280ms; }
.partners > .partner[data-reveal]:nth-child(6) { --reveal-delay: 350ms; }
/* hero copy — let label, headline, lead, actions, stats arrive in sequence
* so the headline isn't waiting on a single block-level reveal. */
.hero-copy > [data-reveal]:nth-of-type(1) { --reveal-delay: 0ms; }
.hero-copy > [data-reveal]:nth-of-type(2) { --reveal-delay: 80ms; }
.hero-copy > [data-reveal]:nth-of-type(3) { --reveal-delay: 160ms; }
.hero-copy > [data-reveal]:nth-of-type(4) { --reveal-delay: 240ms; }
.hero-copy > [data-reveal]:nth-of-type(5) { --reveal-delay: 320ms; }
.hero-copy > [data-reveal]:nth-of-type(6) { --reveal-delay: 400ms; }
@media (prefers-reduced-motion: reduce) {
[data-reveal] {
opacity: 1 !important;
translate: 0 0 !important;
scale: 1 !important;
transition: none !important;
}
/* Skip the slide-in on the sticky chrome for users who prefer no motion;
* the show/hide still toggles, just instantly. */
.site-chrome { transition: none !important; }
}
/* ---------- responsive ----------
*
* Breakpoint ladder:
* 1280 — desktop chrome shrinks (drop side rails, slimmer container).
* 1200 — topbar mid label crowds first, hide it.
* 1080 — small desktop / large laptop. Smaller hero/section heads.
* 880 — tablet portrait. Stack two-column grids, tame the dark work
* card, trim partners to 3 cols.
* 640 — large phone landscape. Wrap toolbars, trim foot-mega.
* 560 — phone portrait. One-column lists/cards. Hero shrinks again.
* 420 — tiny phones. Drop decorative ribbons that overflow, shrink
* the locale switcher, tighten section padding.
*/
@media (max-width: 1280px) {
.container { padding: 0 44px; }
.work { margin: 0 44px; padding: 90px 44px; }
.side-rail { display: none; }
}
/* hide topbar mid text early — between 1200 and 1280 it crowds even with nowrap */
@media (max-width: 1200px) {
.topbar-inner .mid { display: none; }
}
/* nav: between 1080 and 1180 the brand tail + nav links + 2 CTAs + dot
* crowd the row. Drop the brand sub-meta first, then tighten link spacing,
* so the Star CTA never has to compress. */
@media (max-width: 1180px) {
.nav-inner { gap: 18px; }
.brand-meta { display: none; }
.nav-links { gap: 28px; }
}
/* nav: at ≤1080px there's no clean way to fit Product · Skills · Systems ·
* Templates · Craft · Blog · Contact + Download + Star + dot in one row,
* so swap to a hamburger panel. Star CTA stays visible in the bar (it's
* the social-proof CTA); Download moves into the panel. The Product
* submenu flattens from a hover-popup to an always-expanded inline list,
* since hover doesn't translate to touch.
*/
@media (max-width: 1080px) {
.nav-toggle { display: inline-flex; }
.brand { white-space: nowrap; }
/* Hide Download from the bar (Star stays). */
.nav-side .nav-cta.ghost { display: none; }
/* Collapse the nav <ul> into a panel that drops below the header bar.
* The header is `position: sticky`, so absolute-positioning the panel
* relative to the header element keeps it pinned correctly. */
.nav { position: sticky; }
.nav > .nav-inner > nav[data-nav-primary] {
position: absolute;
top: 100%;
left: 0;
right: 0;
margin: 0;
padding: 0;
pointer-events: none;
opacity: 0;
visibility: hidden;
transform: translateY(-6px);
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
background: var(--paper);
border-top: 1px solid rgba(26, 26, 26, 0.08);
box-shadow: 0 12px 32px rgba(26, 26, 26, 0.06);
}
.nav.is-open > .nav-inner > nav[data-nav-primary] {
pointer-events: auto;
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.nav-links {
flex-direction: column;
align-items: stretch;
gap: 0;
padding: 12px 24px 20px 24px;
}
.nav-links li {
border-bottom: 1px solid rgba(26, 26, 26, 0.06);
}
.nav-links li:last-child { border-bottom: none; }
.nav-links a {
display: block;
padding: 14px 0;
font-size: 16px;
}
.nav-links a .num {
position: static;
margin-left: 6px;
font-size: 11px;
}
/* Product dropdown flattens — always show OD + HA as nested static items. */
.nav-links li.has-dropdown { position: static; }
.nav-links .dropdown-caret { display: none; }
.nav-dropdown {
position: static;
opacity: 1;
visibility: visible;
transform: none;
margin: 0 0 4px 0;
padding: 0 0 4px 16px;
border: none;
border-left: 2px solid rgba(26, 26, 26, 0.08);
border-radius: 0;
box-shadow: none;
background: transparent;
min-width: 0;
}
.nav-dropdown::before { display: none; }
.nav-dropdown a { padding: 8px 8px; border-radius: 4px; }
.nav-dropdown .dropdown-blurb { display: none; }
}
@media (max-width: 1080px) {
.container { padding: 0 32px; }
.hero h1 { font-size: clamp(36px, 4.6vw, 54px); }
.section-header h2 { font-size: clamp(32px, 4vw, 50px); }
.labs-grid { grid-template-columns: repeat(5, 1fr); gap: 14px; }
.partners { grid-template-columns: repeat(3, 1fr); gap: 18px; row-gap: 28px; }
.foot-grid { grid-template-columns: 2fr 1fr 1fr; }
.foot-grid .foot-col:nth-child(4),
.foot-grid .foot-col:nth-child(5) { display: none; }
.work { padding: 80px 40px; }
.work-arrows { right: 32px; bottom: 32px; }
}
@media (max-width: 880px) {
.container { padding: 0 24px; }
/* stack two-column grids */
.hero-grid, .about-grid, .capabilities-grid, .testimonial-grid, .cta-grid {
grid-template-columns: 1fr;
gap: 50px;
}
.labs-head, .method-head { grid-template-columns: 1fr; gap: 28px; }
.labs-meta { justify-content: flex-start; }
.pills { justify-content: flex-start; }
.labs-grid { grid-template-columns: repeat(2, 1fr); }
.method-grid { grid-template-columns: repeat(2, 1fr); gap: 36px; }
.method-grid::before { display: none; }
/* hero — copy first, art second; trim art height so the page isn't 200vh */
.hero { min-height: 0; padding: 32px 0 0; }
.hero::before { display: none; }
.hero-grid { gap: 36px; }
.hero-copy { padding: 18px 0 8px; }
.hero-copy .lead { max-width: none; }
.hero-art { height: auto; aspect-ratio: 4 / 5; max-height: none; margin: 0 -8px 0 0; }
.hero-actions { flex-wrap: wrap; }
.hero-stats { flex-wrap: wrap; gap: 14px 22px; }
.hero-foot { flex-wrap: wrap; gap: 12px 24px; padding-top: 18px; }
.sec-rule { flex-wrap: wrap; gap: 8px 18px; }
.sec-rule .meta-grp { gap: 18px; flex-wrap: wrap; }
.section-header { margin-bottom: 48px; }
.section-header h2 { max-width: none; }
/* wire — stack the field label above the marquee rows */
.wire-inner { grid-template-columns: 1fr; gap: 14px; }
.wire-left {
border-right: none;
border-bottom: 1px solid var(--line);
padding-right: 0;
padding-bottom: 12px;
min-height: 0;
}
/* about copy first */
.about-art { max-width: 460px; margin: 0 auto; }
.about-side-note { display: none; }
.about-caption { right: 12px; }
.about .footer-row { flex-wrap: wrap; gap: 14px 20px; margin-top: 36px; }
/* capabilities */
.capabilities-art { max-width: 460px; margin: 0 auto; }
.capabilities-art .ribbon { display: none; }
/* method */
.method-step .num { font-size: 56px; margin-bottom: 16px; }
.method-step h4 { font-size: 24px; padding-right: 0; }
.method-foot { flex-direction: column; align-items: flex-start; gap: 14px; padding-top: 18px; margin-top: 56px; }
/* dark work card */
.work { margin: 0 12px; padding: 60px 24px; border-radius: 24px; }
.work-grid { grid-template-columns: 1fr; gap: 36px; }
.work-arrows { position: static; margin-top: 32px; }
.work-card,
.work-card.alt { transform: none; }
.work-card:hover { transform: translateY(-3px); }
.work-card.alt:hover { transform: translateY(-3px); }
/* testimonial / partners */
.testimonial-art { max-width: 420px; margin: 0 auto; }
.partners { grid-template-columns: repeat(3, 1fr); gap: 18px; }
/* cta */
.cta-art { max-width: 460px; margin: 0 auto; }
.cta-art .ribbon { display: none; }
.cta-actions { flex-wrap: wrap; }
.cta-foot { flex-wrap: wrap; gap: 14px 24px; }
/* footer */
.foot-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
.foot-bottom { flex-direction: column; align-items: flex-start; gap: 12px; }
.foot-bottom .right { flex-wrap: wrap; gap: 12px 20px; }
/* nav — at ≤880px tighten padding; nav-links stay reachable through
* the hamburger panel introduced at ≤1080px. Brand meta and Download
* stay hidden; Star CTA still pings in the bar. */
.nav { padding: 16px 0; }
.brand-meta { display: none; }
.nav-side .nav-cta.ghost { display: none; }
}
@media (max-width: 640px) {
.topbar-inner { gap: 14px; }
.topbar-inner .right { gap: 12px; }
.hero-actions .btn { padding: 12px 18px; font-size: 13px; }
.work-card h3 { font-size: clamp(24px, 6vw, 30px); }
.foot-mega .word { font-size: clamp(54px, 18vw, 120px); }
}
@media (max-width: 560px) {
.container { padding: 0 16px; }
.hero h1 { font-size: clamp(34px, 9.5vw, 44px); }
.about h2,
.capabilities-copy h2,
.labs-head h2,
.method-head h2,
.testimonial-copy h2,
.cta h2,
.section-header h2 { font-size: clamp(30px, 8.5vw, 44px); }
.cta h2 { font-size: clamp(34px, 10vw, 54px); }
.labs-grid { grid-template-columns: 1fr; }
.cards { grid-template-columns: 1fr; }
.method-grid { grid-template-columns: 1fr; gap: 28px; }
.method-step .num { font-size: 48px; }
.method-step h4 { font-size: 22px; }
section { padding: 80px 0; }
.topbar-inner { font-size: 9px; gap: 10px; }
.topbar-inner .right { gap: 10px; }
.locale-trigger { gap: 4px; }
.locale-trigger-prefix { display: none; }
.locale-trigger-sep { display: none; }
.locale-menu { min-width: 208px; }
.partners { grid-template-columns: repeat(2, 1fr); gap: 14px; }
.foot-grid { grid-template-columns: 1fr; gap: 24px; }
.work { margin: 0 8px; padding: 48px 20px; border-radius: 20px; }
.hero-actions { width: 100%; }
.hero-actions .btn { flex: 1 1 auto; justify-content: center; }
.cta-actions { width: 100%; }
.cta-actions .btn,
.cta-actions .email-pill { flex: 1 1 auto; justify-content: center; }
.nav-inner { gap: 12px; }
.brand { font-size: 16px; gap: 8px; }
.brand-mark { width: 32px; height: 32px; font-size: 16px; }
.read-more { margin-top: 36px; }
.foot-mega .word { font-size: clamp(48px, 16vw, 88px); }
}
@media (max-width: 420px) {
.container { padding: 0 14px; }
.topbar-inner { align-items: flex-start; }
.topbar-inner .right {
flex-direction: column;
align-items: flex-end;
gap: 6px;
}
.locale-menu { min-width: 192px; }
.hero-stats { gap: 10px 16px; }
.hero-stats .stat { font-size: 11px; }
.hero-foot { font-size: 9.5px; }
.sec-rule { font-size: 9.5px; gap: 6px 12px; }
.partners { grid-template-columns: repeat(2, 1fr); }
.foot-mega .word { font-size: clamp(40px, 16vw, 64px); }
.work-card { padding: 26px 22px; }
.work-card.alt { padding: 24px 20px; }
}
/* ====== Plugin registry pages ====== */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.plugin-shell .nav { border-bottom: 1px solid var(--line-soft); }
.plugin-directory,
.plugin-detail { padding-bottom: 96px; }
.plugin-hero,
.plugin-detail-hero {
padding: 96px 0 72px;
border-bottom: 1px solid var(--line);
background:
linear-gradient(180deg, rgba(247, 241, 222, 0.74), rgba(239, 231, 210, 0.4)),
var(--paper);
}
.plugin-hero__grid,
.plugin-detail-hero__grid {
display: grid;
gap: 56px;
align-items: start;
}
.plugin-hero__grid {
grid-template-columns: minmax(0, 1fr) minmax(360px, 440px);
}
.plugin-detail-hero__grid {
grid-template-columns: minmax(0, 1fr) minmax(380px, 520px);
}
.plugin-hero h1,
.plugin-detail h1 {
max-width: 900px;
margin-top: 18px;
font-family: var(--serif);
font-size: clamp(48px, 7vw, 96px);
line-height: 0.94;
letter-spacing: 0;
}
.plugin-hero p,
.plugin-detail-hero p,
.plugin-detail-panel p {
max-width: 760px;
margin-top: 24px;
color: var(--ink-mute);
font-size: 18px;
line-height: 1.65;
}
.plugin-hero__actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 34px;
}
.plugin-hero__panel,
.plugin-detail-preview,
.plugin-detail__facts,
.plugin-detail-panel {
border: 1px solid var(--line);
border-radius: 8px;
background: rgba(247, 241, 222, 0.72);
box-shadow: var(--shadow);
}
.plugin-hero__panel {
display: grid;
gap: 12px;
padding: 14px;
overflow: hidden;
}
.plugin-showcase__head {
min-height: 116px;
padding: 18px;
background: rgba(255, 255, 255, 0.18);
border-bottom: 1px solid var(--line-soft);
}
.plugin-showcase__head span,
.plugin-showcase__head small,
.plugin-showcase-item small,
.plugin-showcase-item em {
display: block;
color: var(--ink-mute);
font: 700 10px var(--body);
text-transform: uppercase;
letter-spacing: 0.1em;
}
.plugin-showcase__head strong {
display: block;
font-family: var(--serif);
font-size: 56px;
font-weight: 500;
line-height: 0.86;
}
.plugin-showcase__head small {
margin-top: 10px;
}
.plugin-showcase__list {
display: grid;
gap: 10px;
}
.plugin-showcase-item {
display: grid;
grid-template-columns: 88px minmax(0, 1fr);
gap: 12px;
align-items: center;
min-height: 88px;
padding: 10px;
border: 1px solid var(--line-soft);
border-radius: 8px;
background: rgba(255, 255, 255, 0.18);
color: inherit;
text-decoration: none;
}
.plugin-showcase-item__visual {
position: relative;
display: block;
aspect-ratio: 16 / 10;
overflow: hidden;
border: 1px solid rgba(21, 20, 15, 0.14);
border-radius: 6px;
background: #101b38;
}
.plugin-showcase-item__visual img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.plugin-showcase-item__visual > span {
position: absolute;
display: block;
background: rgba(247, 241, 222, 0.86);
}
.plugin-showcase-item__visual > span:nth-child(1) {
left: 12%;
top: 22%;
width: 58%;
height: 10px;
}
.plugin-showcase-item__visual > span:nth-child(2) {
left: 12%;
top: 46%;
width: 72%;
height: 5px;
opacity: 0.72;
}
.plugin-showcase-item__visual > span:nth-child(3) {
left: 12%;
bottom: 18%;
width: 36%;
height: 5px;
opacity: 0.56;
}
.plugin-showcase-item__copy {
min-width: 0;
}
.plugin-showcase-item strong {
display: block;
margin-top: 3px;
font-family: var(--serif);
font-size: 22px;
font-weight: 600;
line-height: 1.02;
overflow-wrap: anywhere;
}
.plugin-showcase-item em {
margin-top: 7px;
font-family: var(--mono);
font-style: normal;
text-transform: none;
letter-spacing: 0;
overflow-wrap: anywhere;
}
.plugin-showcase-item--image .plugin-showcase-item__visual { background: #d9b86f; }
.plugin-showcase-item--video .plugin-showcase-item__visual { background: #16120f; }
.plugin-showcase-item--dashboard .plugin-showcase-item__visual { background: #eef3ed; }
.plugin-showcase-item--system .plugin-showcase-item__visual { background: #243025; }
.plugin-showcase-item--atom .plugin-showcase-item__visual { background: #f2e8c9; }
.plugin-hero__stats {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1px;
overflow: hidden;
border: 1px solid var(--line-soft);
border-radius: 8px;
}
.plugin-hero__stats div {
min-width: 0;
padding: 14px;
background: rgba(255, 255, 255, 0.16);
}
.plugin-hero__stats dt {
font-family: var(--serif);
font-size: 30px;
line-height: 0.95;
}
.plugin-hero__stats dd {
margin-top: 8px;
color: var(--ink-mute);
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.plugin-registry-section,
.plugin-detail-section {
padding: 64px 0 0;
}
.plugin-toolbar {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
gap: 24px;
align-items: end;
}
.plugin-toolbar h2,
.plugin-detail-panel h2 {
margin-top: 8px;
font-family: var(--serif);
font-size: clamp(34px, 4vw, 54px);
line-height: 1;
letter-spacing: 0;
}
.plugin-search input {
width: 100%;
min-height: 54px;
padding: 0 18px;
border: 1px solid var(--line);
border-radius: 8px;
background: rgba(247, 241, 222, 0.86);
color: var(--ink);
font: 500 15px var(--body);
outline: none;
}
.plugin-search input:focus {
border-color: rgba(237, 111, 92, 0.72);
box-shadow: 0 0 0 3px rgba(237, 111, 92, 0.16);
}
.plugin-filter-row {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 28px;
}
.plugin-filter {
display: inline-flex;
align-items: center;
gap: 8px;
min-height: 42px;
padding: 0 16px;
border: 1px solid var(--line);
border-radius: 999px;
background: rgba(247, 241, 222, 0.65);
color: var(--ink-mute);
font: 600 14px var(--body);
cursor: pointer;
}
.plugin-filter span { color: var(--ink-faint); }
.plugin-filter.is-active {
background: var(--ink);
color: var(--bone);
border-color: var(--ink);
}
.plugin-filter.is-active span { color: rgba(247, 241, 222, 0.72); }
.plugin-result-count {
margin-top: 18px;
color: var(--ink-mute);
font-size: 14px;
}
.plugin-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 16px;
margin-top: 24px;
}
.plugin-card-grid.compact { margin-top: 22px; }
.plugin-card-grid.compact .plugin-card {
min-height: 280px;
padding: 20px;
}
.plugin-card {
min-height: 430px;
display: flex;
flex-direction: column;
gap: 14px;
min-width: 0;
padding: 14px 16px 16px;
border: 1px solid var(--line);
border-radius: 8px;
background: rgba(247, 241, 222, 0.66);
box-shadow: 0 18px 36px -30px rgba(21, 20, 15, 0.22);
overflow: hidden;
transition: transform 180ms ease, background 180ms ease, border-color 180ms ease;
}
.plugin-card:hover {
transform: translateY(-2px);
border-color: rgba(21, 20, 15, 0.24);
background: rgba(247, 241, 222, 0.82);
}
.plugin-card[hidden] { display: none; }
.plugin-card__preview {
position: relative;
display: block;
aspect-ratio: 16 / 10;
overflow: hidden;
border: 1px solid rgba(21, 20, 15, 0.13);
border-radius: 7px;
background: #17213a;
color: inherit;
text-decoration: none;
}
.plugin-card__preview img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.plugin-card__mock {
position: absolute;
inset: 0;
display: block;
background:
linear-gradient(90deg, rgba(255, 255, 255, 0.08) 1px, transparent 1px) 0 0 / 42px 42px,
linear-gradient(180deg, rgba(255, 255, 255, 0.07) 1px, transparent 1px) 0 0 / 42px 42px,
#12224a;
}
.plugin-card__mock span {
position: absolute;
display: block;
background: rgba(247, 241, 222, 0.9);
}
.plugin-card__mock span:nth-child(1) {
left: 9%;
top: 18%;
width: 58%;
height: 24px;
}
.plugin-card__mock span:nth-child(2) {
left: 9%;
top: 42%;
width: 76%;
height: 8px;
opacity: 0.7;
}
.plugin-card__mock span:nth-child(3) {
right: 9%;
bottom: 16%;
width: 24%;
height: 42px;
background: var(--coral);
}
.plugin-card__preview--image { background: #d0b169; }
.plugin-card__preview--image .plugin-card__mock {
background:
linear-gradient(135deg, rgba(21, 20, 15, 0.2), transparent 55%),
#d9b86f;
}
.plugin-card__preview--video { background: #15140f; }
.plugin-card__preview--video .plugin-card__mock {
background:
linear-gradient(90deg, rgba(237, 111, 92, 0.42) 0 18%, transparent 18% 82%, rgba(237, 111, 92, 0.42) 82%),
#15140f;
}
.plugin-card__preview--dashboard .plugin-card__mock {
background:
linear-gradient(90deg, rgba(21, 20, 15, 0.08) 1px, transparent 1px) 0 0 / 32px 32px,
linear-gradient(180deg, rgba(21, 20, 15, 0.08) 1px, transparent 1px) 0 0 / 32px 32px,
#eff2e6;
}
.plugin-card__preview--system .plugin-card__mock {
background:
linear-gradient(90deg, rgba(247, 241, 222, 0.08) 1px, transparent 1px) 0 0 / 28px 28px,
#273324;
}
.plugin-card__preview--atom .plugin-card__mock {
background:
linear-gradient(90deg, rgba(21, 20, 15, 0.08) 1px, transparent 1px) 0 0 / 38px 100%,
#f1e5c5;
}
.plugin-card__preview--workflow .plugin-card__mock {
background:
linear-gradient(135deg, rgba(237, 111, 92, 0.2), transparent 46%),
#eee2c3;
}
.plugin-card__preview-label {
position: absolute;
left: 10px;
right: 10px;
bottom: 10px;
display: block;
max-width: calc(100% - 20px);
padding: 7px 9px;
border: 1px solid rgba(21, 20, 15, 0.12);
border-radius: 999px;
background: rgba(247, 241, 222, 0.88);
color: var(--ink-soft);
font: 700 10px var(--body);
text-transform: uppercase;
letter-spacing: 0.08em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.plugin-card__meta,
.plugin-card__footer,
.plugin-detail__badges {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.plugin-card__meta {
justify-content: space-between;
color: var(--ink-faint);
font: 500 12px var(--mono);
}
.plugin-badge,
.plugin-detail__badges span {
display: inline-flex;
align-items: center;
min-height: 28px;
padding: 0 10px;
border: 1px solid var(--line);
border-radius: 999px;
color: var(--ink-soft);
background: rgba(255, 255, 255, 0.24);
font: 700 11px var(--body);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.plugin-badge--official {
color: #6f2c1f;
border-color: rgba(237, 111, 92, 0.35);
background: rgba(237, 111, 92, 0.14);
}
.plugin-badge--community {
color: #454c20;
border-color: rgba(110, 116, 72, 0.38);
background: rgba(110, 116, 72, 0.14);
}
.plugin-card h3 {
min-width: 0;
font-family: var(--serif);
font-size: 28px;
line-height: 1.04;
letter-spacing: 0;
overflow-wrap: anywhere;
}
.plugin-card h3 a,
.plugin-card__footer a,
.plugin-back-link,
.plugin-source-list a {
color: inherit;
text-decoration-color: rgba(21, 20, 15, 0.28);
text-underline-offset: 4px;
}
.plugin-card code,
.plugin-detail__commands code,
.plugin-detail__facts dd {
font-family: var(--mono);
font-size: 12px;
overflow-wrap: anywhere;
}
.plugin-card p {
color: var(--ink-mute);
line-height: 1.6;
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
.plugin-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: auto;
}
.plugin-tags span {
display: inline-flex;
align-items: center;
min-height: 28px;
padding: 0 10px;
border: 1px solid var(--line-soft);
border-radius: 999px;
color: var(--ink-mute);
background: rgba(255, 255, 255, 0.2);
font-size: 12px;
}
.plugin-tags--large {
margin-top: 22px;
}
.plugin-tags--large span {
min-height: 34px;
font-size: 13px;
}
.plugin-card__footer {
justify-content: space-between;
margin-top: 4px;
padding-top: 14px;
border-top: 1px solid var(--line-soft);
color: var(--ink-mute);
font-size: 13px;
}
.plugin-back-link {
display: inline-flex;
margin-bottom: 24px;
color: var(--ink-mute);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 12px;
}
.plugin-detail__commands {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 12px;
align-items: stretch;
max-width: 720px;
margin-top: 34px;
padding: 12px;
border: 1px solid var(--line);
border-radius: 8px;
background: rgba(21, 20, 15, 0.05);
}
.plugin-detail__commands.compact {
display: block;
max-width: none;
margin-top: 28px;
}
.plugin-detail__commands div {
display: grid;
gap: 4px;
min-width: 0;
}
.plugin-detail__commands span {
color: var(--ink-mute);
font: 700 11px var(--body);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.plugin-detail__commands button {
min-width: 86px;
border: 1px solid rgba(237, 111, 92, 0.36);
border-radius: 8px;
background: var(--coral);
color: #fff;
font: 700 13px var(--body);
cursor: pointer;
}
.plugin-detail-side {
display: grid;
gap: 16px;
min-width: 0;
}
.plugin-detail-preview {
overflow: hidden;
}
.plugin-detail-preview__head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 13px 14px;
border-bottom: 1px solid var(--line-soft);
color: var(--ink-mute);
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.plugin-detail-preview__head small {
color: var(--ink-faint);
font: inherit;
}
.plugin-detail-preview__frame {
position: relative;
aspect-ratio: 16 / 10;
overflow: hidden;
background: #121f42;
}
.plugin-detail-preview__frame iframe,
.plugin-detail-preview__frame img {
display: block;
border: 0;
}
.plugin-detail-preview__frame iframe {
width: 1080px;
height: 675px;
transform: scale(0.48);
transform-origin: top left;
}
.plugin-detail-preview__frame img {
width: 100%;
height: 100%;
}
.plugin-detail-preview__frame img {
object-fit: cover;
}
.plugin-detail-preview__mock {
position: absolute;
inset: 0;
background:
linear-gradient(90deg, rgba(247, 241, 222, 0.12) 1px, transparent 1px) 0 0 / 44px 44px,
linear-gradient(180deg, rgba(247, 241, 222, 0.1) 1px, transparent 1px) 0 0 / 44px 44px,
#121f42;
}
.plugin-detail-preview__mock span {
position: absolute;
display: block;
background: rgba(247, 241, 222, 0.9);
}
.plugin-detail-preview__mock span:nth-child(1) {
left: 9%;
top: 20%;
width: 56%;
height: 42px;
}
.plugin-detail-preview__mock span:nth-child(2) {
left: 9%;
top: 42%;
width: 72%;
height: 10px;
opacity: 0.74;
}
.plugin-detail-preview__mock span:nth-child(3) {
right: 9%;
bottom: 14%;
width: 22%;
height: 64px;
background: var(--coral);
}
.plugin-detail-preview--image .plugin-detail-preview__frame { background: #d9b86f; }
.plugin-detail-preview--video .plugin-detail-preview__frame { background: #15140f; }
.plugin-detail-preview--dashboard .plugin-detail-preview__frame { background: #eff2e6; }
.plugin-detail-preview--system .plugin-detail-preview__frame { background: #263223; }
.plugin-detail-preview--atom .plugin-detail-preview__frame { background: #f1e5c5; }
.plugin-detail__facts {
padding: 22px;
}
.plugin-detail__facts dl {
display: grid;
gap: 18px;
}
.plugin-detail__facts div {
display: grid;
gap: 4px;
padding-bottom: 14px;
border-bottom: 1px solid var(--line-soft);
}
.plugin-detail__facts div:last-child {
padding-bottom: 0;
border-bottom: 0;
}
.plugin-detail__facts dt {
color: var(--ink-mute);
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.plugin-detail-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
}
.plugin-detail-panel--wide {
grid-column: 1 / -1;
}
.plugin-detail-panel {
padding: 26px;
}
.plugin-example-query {
max-height: 260px;
margin-top: 24px;
padding: 18px;
overflow: auto;
border: 1px solid var(--line-soft);
border-radius: 8px;
background: rgba(21, 20, 15, 0.05);
color: var(--ink-soft);
font: 12px/1.7 var(--mono);
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.plugin-source-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 28px;
}
.plugin-source-list a {
display: inline-flex;
align-items: center;
min-height: 40px;
padding: 0 14px;
border: 1px solid var(--line);
border-radius: 999px;
background: rgba(255, 255, 255, 0.18);
font-weight: 700;
text-decoration: none;
}
.plugin-related {
padding-top: 72px;
}
@media (max-width: 980px) {
.plugin-hero__grid,
.plugin-detail-hero__grid,
.plugin-toolbar,
.plugin-detail-grid {
grid-template-columns: 1fr;
}
.plugin-hero__panel {
max-width: 640px;
}
}
@media (max-width: 640px) {
.plugin-hero,
.plugin-detail-hero {
padding: 72px 0 52px;
}
.plugin-hero h1,
.plugin-detail h1 {
font-size: clamp(40px, 12vw, 58px);
}
.plugin-hero p,
.plugin-detail-hero p,
.plugin-detail-panel p {
font-size: 16px;
}
.plugin-hero__panel {
max-width: none;
}
.plugin-hero__stats {
grid-template-columns: 1fr;
}
.plugin-card-grid {
grid-template-columns: 1fr;
}
.plugin-card {
min-height: auto;
}
.plugin-card__preview {
aspect-ratio: 16 / 9;
}
.plugin-detail-preview__frame {
aspect-ratio: 16 / 9;
}
.plugin-detail-preview__frame iframe {
width: 1120px;
height: 630px;
transform: scale(0.32);
}
.plugin-detail__commands {
grid-template-columns: 1fr;
}
.plugin-detail__commands button {
min-height: 44px;
}
}