hype404 retro mix: align fixes + multi-color CRT character

Alignment fixes:
- hero-row uses align-items: flex-end so nav baseline aligns with
  tagline instead of floating in the middle of the brand block
- post-row image switched to position: absolute inset: 0 inside a
  position: relative cell, so the image always exactly fills its
  grid cell regardless of body height (no more min-height: 160 forcing
  uneven row heights)
- .cursor reverted to Fraunces (same as "hype" wordmark) so baseline
  aligns; identity comes from color + chromatic CRT text-shadow
  (lime + offset magenta + offset cyan)

Multi-color retro character (CRT phosphor + magenta + amber + cyan):
- VT323 mono accent font added for: post-hero-flag (with "// " lime
  prefix + magenta glow), post-hero-meta date (amber), post-hero-tag
  (cyan with magenta # prefix), post-row time (amber), post-row-tag
  (cyan with magenta # prefix), nav.nav links (with [ ] magenta brackets)
- body bg picks up a third radial-gradient corner in amber (50% 100%)
- Very faint scanline overlay (1.8% opacity, mix-blend-mode: screen)
  for ambient CRT texture without affecting readability
- Drop cap scaled up + chromatic aberration (lime + magenta + cyan)
- Headlines + body text remain Fraunces + Inter for clean reading

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code
2026-05-01 17:07:13 +08:00
parent 1ec00ea6dc
commit 20ef79e6f4

View File

@@ -46,25 +46,32 @@ const year = new Date().getFullYear();
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700;9..144,800;9..144,900&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700;9..144,800;9..144,900&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=VT323&family=Major+Mono+Display&display=swap" rel="stylesheet" />
<style is:global> <style is:global>
:root { :root {
--bg: #0d0c0a; --bg: #0a0c0a;
--bg-elev: #16140f; --bg-elev: #131611;
--bg-card: #1a1714; --bg-card: #161914;
--bg-soft: #221e1a; --bg-soft: #1d211b;
--ink: #ebe2cd; --ink: #ebe6d1;
--ink-soft: #b6ad97; --ink-soft: #b6b39a;
--ink-muted: #7a7363; --ink-muted: #7a7766;
--line: #2c2722; --line: #2a2c25;
--line-strong: #3a342d; --line-strong: #3a3c33;
--accent: #b8e25a; /* CRT phosphor multi-color palette — phosphor lime primary,
--accent-soft: rgba(184, 226, 90, 0.14); hot magenta secondary, amber tertiary, cyan link */
--magenta: #f43f8c; --accent: #76e74d; /* phosphor lime */
--magenta-soft: rgba(244, 63, 140, 0.18); --accent-soft: rgba(118, 231, 77, 0.14);
--link: #7cd1ff; --accent-glow: rgba(118, 231, 77, 0.55);
--link-hover: #a9e0ff; --magenta: #ff4fa6; /* hot magenta */
--magenta-soft: rgba(255, 79, 166, 0.18);
--magenta-glow: rgba(255, 79, 166, 0.55);
--amber: #f7c244; /* warm amber */
--link: #5ed5ff; /* CRT cyan */
--link-hover: #a9e8ff;
--term: 'VT323', 'Courier New', monospace;
--display-pixel: 'Major Mono Display', 'VT323', monospace;
} }
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; }
@@ -82,11 +89,31 @@ const year = new Date().getFullYear();
line-height: 1.65; line-height: 1.65;
color: var(--ink); color: var(--ink);
background: background:
radial-gradient(circle at 12% -8%, rgba(184, 226, 90, 0.06) 0%, transparent 40%), radial-gradient(circle at 12% -8%, rgba(118, 231, 77, 0.07) 0%, transparent 40%),
radial-gradient(circle at 92% 6%, rgba(244, 63, 140, 0.06) 0%, transparent 42%), radial-gradient(circle at 92% 6%, rgba(255, 79, 166, 0.07) 0%, transparent 42%),
radial-gradient(circle at 50% 100%, rgba(247, 194, 68, 0.04) 0%, transparent 50%),
var(--bg); var(--bg);
min-height: 100vh; min-height: 100vh;
position: relative;
} }
/* Very faint scanline overlay — ambient CRT texture, doesn't affect readability */
body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
background:
repeating-linear-gradient(
180deg,
rgba(118, 231, 77, 0) 0,
rgba(118, 231, 77, 0) 2px,
rgba(118, 231, 77, 0.018) 2px,
rgba(118, 231, 77, 0.018) 3px
);
mix-blend-mode: screen;
}
body > * { position: relative; z-index: 2; }
.container { .container {
max-width: 1180px; max-width: 1180px;
@@ -102,7 +129,7 @@ const year = new Date().getFullYear();
} }
.hero-row { .hero-row {
display: flex; display: flex;
align-items: center; align-items: flex-end; /* nav baseline aligns with tagline */
justify-content: space-between; justify-content: space-between;
gap: 24px; gap: 24px;
flex-wrap: wrap; flex-wrap: wrap;
@@ -111,15 +138,21 @@ const year = new Date().getFullYear();
.ascii-brand { .ascii-brand {
font-family: 'Fraunces', 'Times New Roman', serif; font-family: 'Fraunces', 'Times New Roman', serif;
font-weight: 800; font-weight: 800;
font-size: 40px; font-size: 42px;
letter-spacing: -0.02em; letter-spacing: -0.025em;
color: var(--ink); color: var(--ink);
line-height: 1; line-height: 1;
font-variation-settings: 'opsz' 144; font-variation-settings: 'opsz' 144;
display: inline-block;
} }
/* Keep .cursor in the SAME font/weight/size as "hype" so the baseline
aligns perfectly. Identity comes from color + chromatic CRT shadow. */
.ascii-brand .cursor { .ascii-brand .cursor {
color: var(--accent); color: var(--accent);
font-weight: 800; text-shadow:
0 0 18px var(--accent-glow),
2px 0 0 rgba(255, 79, 166, 0.55),
-2px 0 0 rgba(94, 213, 255, 0.55);
} }
.tagline { .tagline {
color: var(--ink-soft); color: var(--ink-soft);
@@ -132,12 +165,14 @@ const year = new Date().getFullYear();
} }
nav.nav { nav.nav {
display: flex; display: flex;
gap: 26px; gap: 22px;
font-size: 13px; font-size: 14px;
font-weight: 500; font-family: var(--term);
letter-spacing: 0.06em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em;
} }
nav.nav a::before { content: "["; color: var(--magenta); margin-right: 2px; }
nav.nav a::after { content: "]"; color: var(--magenta); margin-left: 2px; }
nav.nav a { nav.nav a {
color: var(--ink-soft); color: var(--ink-soft);
text-decoration: none; text-decoration: none;
@@ -214,13 +249,16 @@ const year = new Date().getFullYear();
justify-content: center; justify-content: center;
} }
.post-hero-flag { .post-hero-flag {
font-family: var(--term);
color: var(--magenta); color: var(--magenta);
font-size: 11px; font-size: 16px;
font-weight: 700; font-weight: 400;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.16em; letter-spacing: 0.18em;
margin-bottom: 12px; margin-bottom: 12px;
text-shadow: 0 0 10px var(--magenta-glow);
} }
.post-hero-flag::before { content: "// "; color: var(--accent); }
.post-hero-title { .post-hero-title {
font-family: 'Fraunces', serif; font-family: 'Fraunces', serif;
font-weight: 700; font-weight: 700;
@@ -247,14 +285,23 @@ const year = new Date().getFullYear();
font-size: 13px; font-size: 13px;
letter-spacing: 0.02em; letter-spacing: 0.02em;
} }
.post-hero-meta > span:first-child {
font-family: var(--term);
color: var(--amber);
font-size: 17px;
letter-spacing: 0.04em;
}
.post-hero-tag { .post-hero-tag {
display: inline-block; display: inline-block;
padding: 2px 10px; padding: 1px 8px;
border: 1px solid var(--line-strong); border: 1px solid var(--line-strong);
border-radius: 999px; border-radius: 4px;
color: var(--ink-soft); color: var(--link);
font-size: 12px; font-family: var(--term);
font-size: 16px;
letter-spacing: 0.02em;
} }
.post-hero-tag::before { content: "#"; color: var(--magenta); }
.post-hero-tag a { color: inherit; text-decoration: none; } .post-hero-tag a { color: inherit; text-decoration: none; }
/* ========== Row cards (rest of feed) ========== */ /* ========== Row cards (rest of feed) ========== */
@@ -273,19 +320,21 @@ const year = new Date().getFullYear();
} }
.post-row-link { .post-row-link {
display: grid; display: grid;
grid-template-columns: 220px 1fr; grid-template-columns: 240px 1fr;
align-items: stretch;
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
} }
.post-row-img { .post-row-img {
position: relative;
overflow: hidden; overflow: hidden;
background: var(--bg-soft); background: var(--bg-soft);
min-height: 100%;
} }
.post-row-img img { .post-row-img img {
position: absolute;
inset: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
min-height: 160px;
object-fit: cover; object-fit: cover;
display: block; display: block;
transition: transform 0.5s ease; transition: transform 0.5s ease;
@@ -296,6 +345,7 @@ const year = new Date().getFullYear();
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
gap: 6px;
} }
/* When no cover, body spans the full row */ /* When no cover, body spans the full row */
.post-row-link:has(.post-row-body:only-child) { .post-row-link:has(.post-row-body:only-child) {
@@ -332,16 +382,23 @@ const year = new Date().getFullYear();
font-size: 12px; font-size: 12px;
letter-spacing: 0.02em; letter-spacing: 0.02em;
} }
.post-row-meta time {
font-family: var(--term);
color: var(--amber);
font-size: 16px;
letter-spacing: 0.04em;
}
.post-row-tag { .post-row-tag {
display: inline-block; display: inline-block;
padding: 1px 9px; padding: 0 7px;
background: var(--bg-soft); background: var(--bg-soft);
border: 1px solid var(--line); border: 1px solid var(--line);
border-radius: 999px; border-radius: 3px;
color: var(--ink-soft); color: var(--link);
font-size: 11px; font-family: var(--term);
font-weight: 500; font-size: 15px;
} }
.post-row-tag::before { content: "#"; color: var(--magenta); }
.post-row-tag a { color: inherit; text-decoration: none; } .post-row-tag a { color: inherit; text-decoration: none; }
.post-empty { .post-empty {
@@ -444,12 +501,16 @@ const year = new Date().getFullYear();
.post-content > p:first-of-type::first-letter { .post-content > p:first-of-type::first-letter {
font-family: 'Fraunces', serif; font-family: 'Fraunces', serif;
font-weight: 800; font-weight: 800;
font-size: 64px; font-size: 72px;
float: left; float: left;
line-height: 0.92; line-height: 0.9;
padding: 6px 12px 0 0; padding: 6px 14px 0 0;
color: var(--magenta); color: var(--accent);
font-variation-settings: 'opsz' 144; font-variation-settings: 'opsz' 144;
text-shadow:
0 0 22px var(--accent-glow),
3px 0 0 rgba(255, 79, 166, 0.55),
-3px 0 0 rgba(94, 213, 255, 0.55);
} }
.post-content a { .post-content a {
color: var(--link); color: var(--link);