mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* 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).
3453 lines
87 KiB
CSS
3453 lines
87 KiB
CSS
/*
|
||
* 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;
|
||
}
|
||
}
|