159 lines
4.3 KiB
CSS
159 lines
4.3 KiB
CSS
@tailwind base;
|
||
@tailwind components;
|
||
@tailwind utilities;
|
||
|
||
/* ==================================================================
|
||
EDITORIAL DESIGN SYSTEM — global tokens & type
|
||
CUSTOMIZATION HOOK: design tokens are mirrored from tailwind.config.ts
|
||
as CSS variables so plain CSS (grain, gradients) can reuse them.
|
||
================================================================== */
|
||
:root {
|
||
color-scheme: light;
|
||
--ink: #0a0a0a;
|
||
--ivory: #f5f1e8;
|
||
--paper: #ece6d6;
|
||
--line: #d8d1c0;
|
||
--vermillion: #d9342b;
|
||
--cobalt: #1b3a8a;
|
||
|
||
/* CUSTOMIZATION HOOK — MOTION: global reveal timing */
|
||
--reveal-duration: 600ms;
|
||
--reveal-ease: cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
|
||
html {
|
||
scroll-behavior: smooth;
|
||
}
|
||
|
||
body {
|
||
@apply bg-ivory text-ink font-sans antialiased;
|
||
/* Subtle paper grain — pure CSS, no asset. */
|
||
background-image: radial-gradient(
|
||
rgba(10, 10, 10, 0.022) 1px,
|
||
transparent 1px
|
||
);
|
||
background-size: 4px 4px;
|
||
}
|
||
|
||
::selection {
|
||
background: var(--vermillion);
|
||
color: var(--ivory);
|
||
}
|
||
|
||
/* ==================================================================
|
||
COMPONENT LAYER — editorial primitives
|
||
================================================================== */
|
||
@layer components {
|
||
.container-content {
|
||
@apply mx-auto w-full max-w-content px-5 sm:px-8 lg:px-12;
|
||
}
|
||
|
||
/* Massive magazine display title (English serif). */
|
||
.display {
|
||
@apply font-display text-display font-light;
|
||
font-optical-sizing: auto;
|
||
}
|
||
|
||
/* Smaller display title — used for long fallback words (PageHeader `en`)
|
||
and figures that should not read at the full cover scale (e.g. the
|
||
"2026" issue year on /intro). Mirrors `.display` at the `display-sm`
|
||
type ramp. See LAYOUT_AUDIT #6 + #10. */
|
||
.display-sm {
|
||
@apply font-display text-display-sm font-light;
|
||
font-optical-sizing: auto;
|
||
}
|
||
|
||
/* Korean serif headline. */
|
||
.headline-ko {
|
||
@apply font-serif-ko font-semibold tracking-tight;
|
||
}
|
||
|
||
/* Small-caps kicker / eyebrow with wide tracking. */
|
||
.kicker {
|
||
@apply font-sans text-[0.7rem] font-semibold uppercase tracking-caps text-ink-mute;
|
||
}
|
||
|
||
/* Corner "01 / 05" spread numbering.
|
||
Bumped from text-sm (14px) to text-base (16px) so the editorial
|
||
spread number reads as "page number", not body copy.
|
||
See LAYOUT_AUDIT #17. */
|
||
.corner-label {
|
||
@apply font-display text-base font-medium tabular-nums tracking-wide text-ink-mute;
|
||
}
|
||
|
||
/* Huge italic serif pull-quote. */
|
||
.pull-quote {
|
||
@apply font-display text-3xl font-light italic leading-tight sm:text-4xl lg:text-5xl;
|
||
}
|
||
|
||
/* Hairline editorial rule. */
|
||
.rule {
|
||
@apply border-t border-ink/80;
|
||
}
|
||
|
||
/* Magazine inset card on dimmer paper. */
|
||
.spread-card {
|
||
@apply border border-ink/15 bg-paper transition duration-500;
|
||
}
|
||
|
||
/* Animated underline-draw on hover (for links). */
|
||
.draw-underline {
|
||
background-image: linear-gradient(var(--vermillion), var(--vermillion));
|
||
background-position: 0 100%;
|
||
background-repeat: no-repeat;
|
||
background-size: 0% 2px;
|
||
transition: background-size 0.4s var(--reveal-ease);
|
||
}
|
||
.draw-underline:hover {
|
||
background-size: 100% 2px;
|
||
}
|
||
}
|
||
|
||
/* ==================================================================
|
||
MOTION — scroll reveal (paired with components/Reveal.tsx)
|
||
CUSTOMIZATION HOOK — MOTION: edit transforms / duration here.
|
||
================================================================== */
|
||
.reveal {
|
||
opacity: 0;
|
||
transform: translateY(28px);
|
||
transition: opacity var(--reveal-duration) var(--reveal-ease),
|
||
transform var(--reveal-duration) var(--reveal-ease);
|
||
will-change: opacity, transform;
|
||
}
|
||
.reveal[data-variant="left"] {
|
||
transform: translateX(-40px);
|
||
}
|
||
.reveal[data-variant="right"] {
|
||
transform: translateX(40px);
|
||
}
|
||
.reveal[data-variant="scale"] {
|
||
transform: scale(0.96);
|
||
}
|
||
.reveal.is-visible {
|
||
opacity: 1;
|
||
transform: none;
|
||
}
|
||
|
||
/* Marquee track must be 2× content for a seamless loop. */
|
||
.marquee-track {
|
||
display: inline-flex;
|
||
white-space: nowrap;
|
||
will-change: transform;
|
||
}
|
||
|
||
/* Respect users who prefer reduced motion. */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.reveal {
|
||
opacity: 1 !important;
|
||
transform: none !important;
|
||
transition: none;
|
||
}
|
||
.marquee-track,
|
||
[class*="animate-"] {
|
||
animation: none !important;
|
||
}
|
||
html {
|
||
scroll-behavior: auto;
|
||
}
|
||
}
|