commit a3b857297317f99f62b1099b0f9ba398b328b789 Author: Anakagung2009-bit Date: Mon Jun 15 14:02:37 2026 +0800 first commit diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..2f3aa2a --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,319 @@ +## Overview + +Resend looks like a developer tool with the typography of an editorial. +Every page opens on `{colors.canvas}` (`#000000`), and the loudest element on +the canvas is not a button or a brand stamp — it's a 96px Domaine Display +serif headline ("Email for developers", "Email reimagined") with the +`ss01 / ss04 / ss11` stylistic alternates engaged. That single typographic +decision sets the brand tone: confident, considered, slightly literary, and +priced on quality rather than novelty. + +The supporting cast is technical. Body copy switches to **ABC Favorit** for +marketing prose and **Inter** for UI labels, while code blocks render in +**Geist Mono** inside `{component.code-window}` shells with hairline traffic- +light dots. Surface depth is built almost entirely from translucent white — +6% borders, 14% strong borders, 4% dividers — over a deep `{colors.surface-deep}` +layer that sits just below the canvas black. There are no gradients painted +across full bands, just **soft atmospheric glows** (orange, blue, green, red, +yellow) anchored at the top of select sections, all at low opacity. + +Page rhythm cycles in a single dark register: hero stripe → atmospheric +section → code window section → email mockup section → pricing or feature +grid → black footer. The brand never warms to a light surface; even +secondary email mockups are rendered as compact white cards inside the dark +canvas, framed like print insets in a black-bordered magazine page. + +**Key Characteristics:** +- Pure black canvas (`{colors.canvas}` — `#000000`) on every public page; off-white text (`{colors.ink}` — `#fcfdff`) carries the full read. +- A serif-led type system: **Domaine Display** at 76–96px for hero headlines, **ABC Favorit** for marketing body, **Inter** for UI, **Geist Mono** for code. +- Six accent glow colours used only as low-opacity atmospheric washes (`{colors.accent-orange}`, `{colors.accent-blue}`, `{colors.accent-green}`, `{colors.accent-red}`, `{colors.accent-yellow}`) — never as buttons or solid surfaces. +- Strict container vocabulary: `{rounded.lg}` (12px) for feature cards, code wells, and email mockups; `{rounded.md}` (8px) for buttons; `{rounded.full}` for pills and avatars. +- Translucent white borders (`{colors.hairline}` 6% / `{colors.hairline-strong}` 14%) replace shadows entirely — the system has no traditional drop-shadow elevation language. +- `{component.button-primary}` is a small white rectangle with black text — counterintuitive contrast that becomes the page's brightest pixel and works as a single visual anchor. + +## Colors + +### Brand & Accent +- **Primary White** (`{colors.primary}` — `#fcfdff`): the brand's de facto accent. Reserved for `{component.button-primary}` (white pill on black canvas), Domaine display headlines, and the active text colour. White is the loudest possible colour on this canvas — that's the signature. +- **Primary On** (`{colors.primary-on}` — `#000000`): label colour on top of `{colors.primary}` surfaces. Black text on white pill is the brand's CTA pattern. +- **Surface Light** (`{colors.surface-light}` — `#f1f7fe`): a subtle blue-tinted off-white used as the active/pressed state of `{component.button-primary}`. + +### Surface +- **Canvas** (`{colors.canvas}` — `#000000`): the default page background. True black, never near-black. +- **Surface Card** (`{colors.surface-card}` — `#0a0a0c`): the standard inset card surface, just lighter than canvas to register a step up in elevation. +- **Surface Elevated** (`{colors.surface-elevated}` — `#101012`): a second elevation step used on featured pricing tiers and ghost button surfaces. +- **Surface Deep** (`{colors.surface-deep}` — `#06060a`): code window background — slightly cooler and darker than the canvas itself, suggesting depth via temperature. +- **Hairline** (`{colors.hairline}` — `rgba(255,255,255,0.06)`): the soft 1px translucent-white divider used between rows and around feature cards. +- **Hairline Strong** (`{colors.hairline-strong}` — `rgba(255,255,255,0.14)`): the structural 1px border on cards, code wells, and form inputs. +- **Divider Soft** (`{colors.divider-soft}` — `rgba(255,255,255,0.04)`): low-contrast dividers between footer columns. + +### Text +- **Ink** (`{colors.ink}` — `#fcfdff`): primary text colour on the dark canvas. Faintly blue-cool to feel like printed paper rather than pure white pop. +- **Body** (`{colors.body}` — `rgba(252,253,255,0.86)`): long-form body text where pure ink would feel too sharp. +- **Charcoal** (`{colors.charcoal}` — `rgba(252,253,255,0.7)`): captions, secondary nav labels. +- **Mute** (`{colors.mute}` — `#a1a4a5`): supporting text and inactive labels. +- **Ash** (`{colors.ash}` — `#888e90`): tertiary text, footer copy. +- **Stone** (`{colors.stone}` — `#464a4d`): disabled foreground. +- **On-Light** (`{colors.on-light}` — `#000000`): label colour inside the rare email-mockup white cards. +- **On-Light Mute** (`{colors.on-light-mute}` — `rgba(0,0,51,0.7)`): secondary text inside email mockups. + +### Semantic +- **Accent Orange** (`{colors.accent-orange}` — `#ff801f`) + glow (`{colors.accent-orange-glow}` — `rgba(255,89,0,0.22)`): atmospheric warm wash anchored to "Email reimagined" / customer story sections. Solid orange never appears as a button or surface — only the glow. +- **Accent Yellow** (`{colors.accent-yellow}` — `#ffc53d`): used in inline highlight strokes and "first-class developer experience" key callouts. +- **Accent Blue** (`{colors.accent-blue}` — `#3b9eff`) + glow (`{colors.accent-blue-glow}` — `rgba(0,117,255,0.34)`): inline link colour and the cool atmospheric wash on the "Integrate this weekend" section. +- **Accent Green** (`{colors.accent-green}` — `#11ff99`) + glow (`{colors.accent-green-glow}` — `rgba(34,255,153,0.18)`): success status dots and the "delivery confirmed" feature glow. +- **Accent Red** (`{colors.accent-red}` — `#ff2047`) + glow (`{colors.accent-red-glow}` — `rgba(255,32,71,0.34)`): inline error red and the "reach humans, not spam folders" attention wash. +- **Link** (`{colors.link}` — `#3b9eff`): inline link colour — same as accent blue. + +## Typography + +### Font Family + +Resend ships a four-family stack: + +- **Domaine Display** — proprietary editorial serif used exclusively for hero headlines at 76px+, with `ss01 / ss04 / ss11` stylistic sets engaged for a slightly tighter, more print-magazine look. +- **ABC Favorit** — proprietary humanist sans-serif used for marketing body copy, hero subtitles, and pill labels. Carries `ss01 / ss03 / ss04` features for tabular figures and alternate glyphs. +- **Inter** — open-source sans-serif used for UI: button labels, captions, card body text, nav links. +- **Geist Mono** — open-source monospace used in code wells. + +When proprietary families cannot be licensed, **Söhne** or **Tiempos Headline** stand in for Domaine Display, and **Geist** or **Inter Tight** can replace ABC Favorit. Inter and Geist Mono are open-source and should be used directly. + +### Hierarchy + +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xxl}` | 96px | 400 | 1.0 | -0.96px | Home hero ("Email for developers"). One per page. | +| `{typography.display-xl}` | 76.8px | 400 | 1.0 | -0.768px | Section openers ("Email reimagined", "Available today"). | +| `{typography.display-lg}` | 56px | 400 | 1.2 | -2.8px | ABC Favorit display sub-titles. | +| `{typography.heading-md}` | 24px | 500 | 1.5 | -0.4px | Card titles, section sub-titles. | +| `{typography.heading-sm}` | 20px | 500 | 1.3 | -0.3px | List headers. | +| `{typography.subtitle}` | 20px | 400 | 1.3 | 0 | Hero subtitles. | +| `{typography.body-lg}` | 18px | 400 | 1.5 | 0 | Marketing prose. | +| `{typography.body-md}` | 16px | 400 | 1.5 | -0.8px | ABC Favorit body. | +| `{typography.body-sm}` | 14px | 400 | 1.43 | 0 | Captions, metadata. | +| `{typography.button-md}` | 14px | 500 | 1.43 | 0 | Default button label. | +| `{typography.button-sm}` | 14px | 500 | 1.43 | 0.35px | Pill labels, inline links. | +| `{typography.caption}` | 12px | 400 | 1.5 | 0 | Footer disclosure, copyright. | +| `{typography.caption-emph}` | 14px | 600 | 1.0 | 0 | Emphatic small caption — Helvetica fallback. | +| `{typography.code-md}` | 13px | 400 | 1.6 | 0 | Code blocks, inline code. | + +### Principles +- Display sizes always run at `lineHeight: 1.0` with negative letter-spacing — the Domaine Display headlines pack into solid typographic blocks rather than open prose lines. +- Body weight stays at 400 across `{typography.body-lg}` and `{typography.body-md}`. The serif/sans family change carries hierarchy, not weight bumps. +- ABC Favorit always runs with `ss01 / ss04 / ss11` engaged; Inter never carries OpenType features. Code in Geist Mono never carries ligatures. +- Inline links use `{typography.button-sm}` with positive letter-spacing (`0.35px`) and ABC Favorit — the small spacing nudge gives interactive prose its precision. + +### Note on Font Substitutes + +When Domaine Display is unavailable, clamp `lineHeight` to 1.0 explicitly and apply `font-feature-settings: "ss01", "liga"` on the substitute serif to mimic the alternate glyphs. Söhne or Tiempos Headline will read closest. ABC Favorit substitutes (Geist, Inter Tight) typically default to looser tracking — apply -0.5% letter-spacing on body sizes to compensate. + +## Layout + +### Spacing System +- **Base unit**: 4px, with the working scale on multiples of 4 / 8 / 16. +- **Tokens**: `{spacing.xxs}` 2px · `{spacing.xs}` 4px · `{spacing.sm}` 8px · `{spacing.md}` 12px · `{spacing.lg}` 16px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px · `{spacing.xxxl}` 48px · `{spacing.section}` 96px · `{spacing.band}` 128px. +- Section padding: `{spacing.section}` (96px) vertical between bands; `{spacing.band}` (128px) on the hero stripe and closing footer transition. +- Card internal padding: `{spacing.xxl}` (32px) on `{component.feature-card}`, `{component.pricing-tier}`, and `{component.code-window}`. + +### Grid & Container +- **Max content width** ≈ 1200px on body sections. +- **Feature grid**: 3 columns at desktop, 2 at tablet, 1 at mobile. +- **Pricing**: 3-tier grid centred at desktop; centre tier promotes to `{component.pricing-tier-featured}` (one-step-elevated surface). +- **Code-story splits**: a 2-up split — narrative copy left, `{component.code-window}` right — collapsing to stacked at < 1024px. +- **Email mockup band**: a single white card (640px max width) centred in the dark canvas with generous vertical padding to read like a print magazine inset. + +### Whitespace Philosophy +- Whitespace is editorial and generous — full-bleed sections breathe at 96–128px so Domaine Display headlines have room to register at scale. +- Inside cards, padding stays at 32px so feature copy and code wells have a consistent rhythm with the outer grid. +- Hairline `{colors.hairline}` and `{colors.hairline-strong}` carry the role drop shadows would in a brighter system; the dark canvas suppresses traditional shadow depth entirely. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — flat | No shadow, no border | Default canvas, full-bleed bands. | +| 1 — surface card | `{colors.surface-card}` (`#0a0a0c`) + 1px `{colors.hairline-strong}` | Feature cards, pricing tiers, form inputs. | +| 2 — elevated | `{colors.surface-elevated}` (`#101012`) + 1px `{colors.hairline-strong}` | Featured pricing tier, ghost button. | +| 3 — code well | `{colors.surface-deep}` (`#06060a`) + 1px `{colors.hairline-strong}` | Code window, terminal shells. | +| 4 — atmospheric glow | Low-opacity radial gradient (`{colors.accent-*-glow}`) anchored at section top | Section openers ("Integrate this weekend", "Email reimagined"). | + +The system has **no traditional drop shadow language**. Every surface either gets a translucent-white hairline border or sits inside an atmospheric glow. The dark canvas absorbs shadow naturally; surfaces register depth via temperature and luminance shifts rather than blur. + +### Decorative Depth +- **Atmospheric section glows** — six accent colours each with a paired glow token (orange, yellow, blue, green, red, plus a deep slate for "everything in your context"). Each section opens with a single radial wash anchored at the top edge of the section, falling off to canvas black within ~600px vertical distance. Never two glows in the same section. +- **Email card insets** — the "Beyond experience" mockup band lifts a single white email card off the black canvas, giving it the only true light-on-dark contrast in the system. The card uses no shadow; the contrast itself is the elevation. +- **Code window traffic lights** — `{component.code-window}` shells include a row of three coloured dots (red `{colors.accent-red}`, yellow `{colors.accent-yellow}`, green `{colors.accent-green}`) at the top — the only place all three semantic colours appear together as solid surfaces. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Hero stripe, full-bleed bands, footer. | +| `{rounded.xs}` | 4px | Inline tags inside code wells. | +| `{rounded.sm}` | 6px | Code tabs, mid-size chips. | +| `{rounded.md}` | 8px | Buttons, form inputs. | +| `{rounded.lg}` | 12px | Feature cards, pricing tiers, code wells, email mockups. | +| `{rounded.xl}` | 16px | Larger feature panels. | +| `{rounded.full}` | 9999px | Pills, status dots, contributor avatars. | + +### Photography Geometry +- The system uses almost no photography. Visual interest comes from typography + atmospheric glows + code wells + the white email-card insets. +- When portraits appear (testimonial avatars), they are circular (`{rounded.full}`) at 32px, sitting inline with body copy. +- Email mockup cards run at 4:5 portrait aspect with `{rounded.lg}` corners. + +## Components + +### Buttons + +**`button-primary`** — white CTA +- Background `{colors.primary}`, label `{colors.primary-on}`, type `{typography.button-md}`, padding `8px 16px`, `rounded: {rounded.md}`, height 36px. +- The brightest pixel on the canvas. Used for "Get started", "Sign up", "Try Resend". +- Pressed state lives in `button-primary-pressed` (background `{colors.surface-light}`). + +**`button-ghost`** — translucent CTA +- Background `{colors.surface-elevated}`, label `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.md}`, height 36px. +- Equal-weight secondary action paired with `{component.button-primary}`. + +**`button-outline`** — outlined CTA +- Background `{colors.canvas}`, label `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.md}`, height 36px. +- Tertiary action; appears on its own next to inline links. + +### Cards & Containers + +**`hero-stripe`** — full-bleed hero +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.display-xxl}` for the headline, padding `96px 32px`, `rounded: {rounded.none}`. +- Used only on the home page hero band; carries the 96px Domaine Display headline and a single `{component.button-primary}` CTA. No photography, no atmospheric glow inside the hero itself — the glow appears on the section that follows. + +**`feature-card`** — feature highlight card +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- Used in the home grid: "Despite emails using React", "So beyond editing", etc. No outline by default — relies on canvas black contrast. + +**`feature-card-bordered`** — outlined feature card +- Background `{colors.surface-card}`, text `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Used when feature cards sit close together and need explicit separation. + +**`pricing-tier`** — pricing tier card +- Background `{colors.surface-card}`, text `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- Tier name in `{typography.heading-md}` + price in `{typography.display-lg}` (ABC Favorit, 56px). + +**`pricing-tier-featured`** — recommended tier +- Background `{colors.surface-elevated}`, text `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Centre tier elevated by surface luminance, not by colour. + +**`code-window`** — code well +- Background `{colors.surface-deep}`, text `{colors.body}`, type `{typography.code-md}`, 1px `{colors.hairline-strong}`, `rounded: {rounded.lg}`, padding `{spacing.xl}` (24px). +- Includes a 3-dot traffic-light row at top using `{colors.accent-red}` / `{colors.accent-yellow}` / `{colors.accent-green}` for chrome, plus a tab strip below it. + +**`code-tab`** — code language tab +- Background `{colors.surface-card}`, text `{colors.charcoal}`, type `{typography.code-md}`, `rounded: {rounded.sm}`, padding `6px 12px`. +- Active tab bumps text to `{colors.ink}` and adds a subtle `{colors.hairline-strong}` underline. + +**`email-mockup`** — email-card inset +- Background `{colors.surface-card}` (or the rare `#ffffff` when rendered as a light-island inset), text `{colors.ink}` (or `{colors.on-light}` for white insets), type `{typography.body-md}`, `rounded: {rounded.lg}`, padding 0. +- Used in the "Beyond experience" band to demonstrate rendered email output. + +### Inputs & Forms + +**`text-input`** — default input +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-sm}`, 1px `{colors.hairline-strong}`, `rounded: {rounded.md}`, padding `10px 14px`, height 40px. +- Sign-up and waitlist email fields. Focus state thickens the border to `{colors.ink}` (no separate ring colour). + +### Navigation + +**`nav-bar`** — top nav (desktop) +- Background `{colors.canvas}`, text `{colors.body}`, type `{typography.button-sm}`, height 64px, single hairline `{colors.hairline}` bottom border. +- Left: wordmark logo. Centre: top-level nav ("Features", "Pricing", "Docs", "Customers"). Right: "Sign in" link + `{component.button-primary}`. + +**`nav-bar`** (mobile) +- Same height 64px, collapses centre nav into a hamburger icon. Logo stays left, sign-in CTA stays right. + +**`sub-nav-pill`** — pill-style sub-nav +- Pill chips set in a horizontal row above content (e.g. on the customers index), `{component.sub-nav-pill}` styling. + +### Signature Components + +**`badge-pill`** — neutral pill +- Background `{colors.surface-elevated}`, text `{colors.body}`, type `{typography.caption}`, `rounded: {rounded.full}`, padding `4px 10px`. +- Inline tags ("New", "Beta", "v3.0") inside hero copy and customer story headers. + +**`status-dot`** — status indicator +- Background `{colors.accent-green}`, `rounded: {rounded.full}`, 8px square. +- Inline indicator next to "Status: Operational" in the footer or system status references. + +**`contributor-avatar`** — testimonial avatar +- Background `{colors.surface-card}` placeholder, `rounded: {rounded.full}`, 32×32px. +- Used inline with customer testimonials. + +**`footer`** — global footer +- Background `{colors.canvas}`, text `{colors.charcoal}`, type `{typography.body-sm}`, `rounded: {rounded.none}`, padding `64px 32px`. +- Multi-column quick-links grid above a single-line copyright row separated by `{colors.divider-soft}`. + +## Do's and Don'ts + +### Do +- Use `{colors.canvas}` (true black) as the default page background. Every public page lives here. +- Reserve `{component.button-primary}` (white pill) as the only solid bright surface. One per viewport at most. +- Set hero headlines in **Domaine Display** at 76–96px with `lineHeight: 1.0` and `ss01 / ss04 / ss11` features engaged. +- Use **ABC Favorit** for marketing body, **Inter** for UI labels, **Geist Mono** for code. Keep the lanes strict. +- Build elevation from translucent-white hairlines, not drop shadows. +- Use `{colors.accent-*-glow}` tokens as low-opacity radial atmospheric washes — never as solid surfaces. +- Set buttons and inputs to `{rounded.md}` (8px); cards and code wells to `{rounded.lg}` (12px); pills and avatars to `{rounded.full}`. +- Use the white email-mockup inset sparingly — it's the only deliberately-light surface and should feel like a print pull-quote. + +### Don't +- Don't use a near-black canvas. The brand sits on `#000000`, not `#0a0a0a`. +- Don't apply solid colour to atmospheric accent tokens. `{colors.accent-orange}` is for inline highlights only — its glow form is for backdrops. +- Don't add drop shadows to feature cards or code wells. Translucent white borders carry depth on this canvas. +- Don't bump body weight to 600 for emphasis. Use family change (Inter → ABC Favorit → Domaine Display) instead. +- Don't render code outside `{component.code-window}` — even small inline code uses Geist Mono and a `{colors.surface-card}` background. +- Don't loosen Domaine Display `lineHeight` past 1.0. Tight stacking is structural to the brand. +- Don't introduce a secondary brand accent. White is the brand on black — accents are atmospheric only. +- Don't bring photography front-and-centre. The brand reads as type-and-code, not photography-led. + +## Responsive Behavior + +### Breakpoints + +| Name | Width | Key Changes | +|---|---|---| +| Desktop XL | ≥ 1440px | Full max-width 1200 body, 3-up feature grid, side-by-side code-story splits. | +| Desktop | 1280–1439px | Container shrinks; xl side padding. | +| Tablet Large | 1024–1279px | Feature grid stays 3-up, code-story remains 2-up. | +| Tablet | 768–1023px | Feature grid 2-up, code-story stacks (narrative on top), pricing stacks vertically. | +| Mobile Large | 426–767px | Feature grid 1-up; nav collapses to hamburger; hero `{typography.display-xxl}` clamps to 56px. | +| Mobile | ≤ 425px | All grids 1-up, hero clamps to 44px, section padding `{spacing.section}` collapses to 64px. | + +### Touch Targets +- All buttons ship at minimum 36px tall on desktop, scaling to 44px on mobile via padding adjustment. WCAG AAA met on mobile. +- `{component.text-input}` is 40px tall — comfortable but not large. Mobile scales to 48px via padding. +- `{component.sub-nav-pill}` stays at 36px on desktop, 40px on mobile. + +### Collapsing Strategy +- Top-level nav collapses to hamburger at < 1024px; the wordmark and `{component.button-primary}` stay anchored. +- Hero `{typography.display-xxl}` clamps: 96px → 76px → 56px → 44px across the breakpoint ladder. +- Pricing 3-up stacks vertically at < 1024px with the featured tier remaining centre-stacked. +- Code-story splits switch from side-by-side to stacked at < 1024px, code well always second. +- Atmospheric glows scale with section width but maintain the same opacity — they fade naturally at small viewports. + +### Image Behavior +- Email mockup cards reflow at 1:1 aspect on mobile to remain readable. +- Atmospheric glows are CSS gradients — no asset cost, no breakpoint variation. +- Customer testimonial avatars stay 32px circular regardless of breakpoint. + +## Iteration Guide + +1. Focus on ONE component at a time. Most surfaces share `{colors.surface-card}` or `{colors.surface-elevated}` with `{rounded.lg}` — only the role-specific tokens (`{colors.primary}`, `{component.code-window}`) shift between variants. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-pressed}`, `{rounded.lg}`) — do not paraphrase. +3. Run `npx @google/design.md lint DESIGN.md` after edits; orphaned-tokens warnings will catch unused entries. +4. Add new variants as separate entries (`-pressed`, `-featured`, `-disabled`) — do not bury them in prose. +5. Default body type to `{typography.body-md}`; reach for `{typography.subtitle}` only on hero subtitles. +6. Keep `{colors.primary}` (white) scarce — if more than one solid white surface appears per viewport, ask whether one should drop to `{component.button-ghost}` instead. + +## Known Gaps + +- Pressed/active visual states are documented only for `button-primary-pressed`; other components rely on the default focus-ring (browser default) for interactive feedback. +- Logged-in dashboard surfaces (API keys, sending logs, audience management) are out of scope; only the public marketing canvas is documented. +- Email-template editor surfaces (a key product feature) are not extracted — those live behind authentication. +- The atmospheric glow rendering uses CSS radial gradients; exact stops and angles vary per section and are not standardised as tokens — render per section-specific design judgment. diff --git a/images/artist-lunair.jpg b/images/artist-lunair.jpg new file mode 100644 index 0000000..d58ac5d Binary files /dev/null and b/images/artist-lunair.jpg differ diff --git a/images/aurora-cover.jpg b/images/aurora-cover.jpg new file mode 100644 index 0000000..d9e35c5 Binary files /dev/null and b/images/aurora-cover.jpg differ diff --git a/images/l u n i a r.jpg b/images/l u n i a r.jpg new file mode 100644 index 0000000..9716a90 Binary files /dev/null and b/images/l u n i a r.jpg differ diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..9b70874 Binary files /dev/null and b/images/logo.png differ diff --git a/images/midnight-cover.jpg b/images/midnight-cover.jpg new file mode 100644 index 0000000..aff7811 Binary files /dev/null and b/images/midnight-cover.jpg differ diff --git a/index.css b/index.css new file mode 100644 index 0000000..81e5fb9 --- /dev/null +++ b/index.css @@ -0,0 +1,1330 @@ +/* ============================================================ + AGUNG DEV MUSIC — Complete Design System CSS + Design Tokens & Components (following DESIGN.md) + ============================================================ */ + +/* --- Google Fonts --- */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=DM+Serif+Display:ital@0;1&family=Outfit:wght@300;400;500;600&display=swap'); + +/* ============================================================ + CSS CUSTOM PROPERTIES (DESIGN TOKENS) + ============================================================ */ +:root { + /* --- Brand & Accent --- */ + --color-primary: #fcfdff; + --color-primary-on: #000000; + --color-surface-light: #f1f7fe; + + /* --- Surface --- */ + --color-canvas: #000000; + --color-surface-card: #0a0a0c; + --color-surface-elevated: #101012; + --color-surface-deep: #06060a; + --color-hairline: rgba(255, 255, 255, 0.06); + --color-hairline-strong: rgba(255, 255, 255, 0.14); + --color-divider-soft: rgba(255, 255, 255, 0.04); + + /* --- Text --- */ + --color-ink: #fcfdff; + --color-body: rgba(252, 253, 255, 0.86); + --color-charcoal: rgba(252, 253, 255, 0.7); + --color-mute: #a1a4a5; + --color-ash: #888e90; + --color-stone: #464a4d; + + /* --- Accent Glows --- */ + --color-accent-cyan: #00d4ff; + --color-accent-cyan-glow: rgba(0, 212, 255, 0.18); + --color-accent-blue: #3b9eff; + --color-accent-blue-glow: rgba(0, 117, 255, 0.22); + --color-accent-deep-blue: #1a3a6c; + --color-accent-deep-blue-glow: rgba(26, 58, 108, 0.35); + + /* --- Spacing --- */ + --spacing-xxs: 2px; + --spacing-xs: 4px; + --spacing-sm: 8px; + --spacing-md: 12px; + --spacing-lg: 16px; + --spacing-xl: 24px; + --spacing-xxl: 32px; + --spacing-xxxl: 48px; + --spacing-section: 96px; + --spacing-band: 128px; + + /* --- Border Radius --- */ + --rounded-none: 0px; + --rounded-xs: 4px; + --rounded-sm: 6px; + --rounded-md: 8px; + --rounded-lg: 12px; + --rounded-xl: 16px; + --rounded-full: 9999px; + + /* --- Font Families --- */ + --font-display: 'DM Serif Display', 'Georgia', serif; + --font-body: 'Outfit', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + + /* --- Animation --- */ + --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); + --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1); + --duration-slow: 1200ms; + --duration-medium: 800ms; + --duration-fast: 400ms; +} + + +/* ============================================================ + RESET & BASE + ============================================================ */ +*, +*::before, +*::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +body { + font-family: var(--font-ui); + font-size: 16px; + font-weight: 400; + line-height: 1.5; + color: var(--color-body); + background-color: var(--color-canvas); + overflow-x: hidden; +} + +a { + color: var(--color-accent-cyan); + text-decoration: none; + transition: color 0.3s ease; +} + +a:hover { + color: var(--color-ink); +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +button { + font-family: inherit; + cursor: pointer; + border: none; + outline: none; +} + +::selection { + background: rgba(0, 212, 255, 0.2); + color: var(--color-ink); +} + + +/* ============================================================ + CONTAINER + ============================================================ */ +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 var(--spacing-xxl); +} + +@media (max-width: 768px) { + .container { + padding: 0 var(--spacing-xl); + } +} + +@media (max-width: 425px) { + .container { + padding: 0 var(--spacing-lg); + } +} + + +/* ============================================================ + NAVIGATION + ============================================================ */ +.nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 100; + height: 64px; + display: flex; + align-items: center; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(24px) saturate(1.4); + -webkit-backdrop-filter: blur(24px) saturate(1.4); + border-bottom: 1px solid var(--color-hairline); + transition: background 0.4s ease, border-color 0.4s ease; +} + +.nav.scrolled { + background: rgba(0, 0, 0, 0.85); + border-bottom-color: var(--color-hairline-strong); +} + +.nav__inner { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 var(--spacing-xxl); +} + +.nav__logo { + display: flex; + align-items: center; + gap: var(--spacing-sm); +} + +.nav__logo-img { + height: 28px; + width: auto; + opacity: 0.9; +} + +.nav__logo-text { + font-family: var(--font-body); + font-size: 14px; + font-weight: 500; + letter-spacing: 0.35px; + color: var(--color-ink); +} + +.nav__cta { + display: inline-flex; + align-items: center; + gap: var(--spacing-sm); + background: var(--color-primary); + color: var(--color-primary-on); + font-family: var(--font-ui); + font-size: 14px; + font-weight: 500; + padding: 8px 16px; + border-radius: var(--rounded-md); + height: 36px; + transition: background 0.2s ease, transform 0.2s ease; +} + +.nav__cta:hover { + background: var(--color-surface-light); + color: var(--color-primary-on); + transform: translateY(-1px); +} + + +/* ============================================================ + HERO SECTION + ============================================================ */ +.hero { + position: relative; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: var(--spacing-band) 0 var(--spacing-section); + overflow: hidden; +} + +.hero--hub { + min-height: 80vh; + padding-bottom: var(--spacing-xxxl); +} + +/* Atmospheric glow behind hero */ +.hero::before { + content: ''; + position: absolute; + top: -200px; + left: 50%; + transform: translateX(-50%); + width: 900px; + height: 900px; + background: radial-gradient( + ellipse at center, + var(--color-accent-cyan-glow) 0%, + var(--color-accent-blue-glow) 30%, + var(--color-accent-deep-blue-glow) 50%, + transparent 70% + ); + opacity: 0.6; + pointer-events: none; + z-index: 0; + animation: glowPulse 8s ease-in-out infinite alternate; +} + +.hero::after { + content: ''; + position: absolute; + bottom: -100px; + left: 50%; + transform: translateX(-50%); + width: 600px; + height: 400px; + background: radial-gradient( + ellipse at center, + var(--color-accent-deep-blue-glow) 0%, + transparent 70% + ); + opacity: 0.4; + pointer-events: none; + z-index: 0; +} + +@keyframes glowPulse { + 0% { opacity: 0.5; transform: translateX(-50%) scale(1); } + 100% { opacity: 0.7; transform: translateX(-50%) scale(1.08); } +} + +.hero__content { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: var(--spacing-xxl); +} + +/* Album Artwork */ +.hero__artwork-wrapper { + position: relative; + width: 380px; + max-width: 80vw; +} + +.hero__artwork-glow { + position: absolute; + inset: -40px; + background: radial-gradient( + circle at center, + rgba(0, 212, 255, 0.15) 0%, + rgba(59, 158, 255, 0.08) 40%, + transparent 70% + ); + border-radius: var(--rounded-xl); + z-index: 0; + animation: artworkGlow 6s ease-in-out infinite alternate; +} + +@keyframes artworkGlow { + 0% { opacity: 0.7; transform: scale(1); } + 100% { opacity: 1; transform: scale(1.05); } +} + +.hero__artwork { + position: relative; + z-index: 1; + width: 100%; + aspect-ratio: 1; + object-fit: cover; + border-radius: var(--rounded-lg); + border: 1px solid var(--color-hairline-strong); + box-shadow: 0 0 80px rgba(0, 212, 255, 0.08); +} + +/* Badge */ +.hero__badge { + display: inline-flex; + align-items: center; + background: var(--color-surface-elevated); + color: var(--color-body); + font-family: var(--font-ui); + font-size: 12px; + font-weight: 500; + letter-spacing: 0.5px; + text-transform: uppercase; + padding: 4px 14px; + border-radius: var(--rounded-full); + border: 1px solid var(--color-hairline-strong); +} + +/* Hero Text */ +.hero__artist { + font-family: var(--font-body); + font-size: 20px; + font-weight: 400; + letter-spacing: 0; + color: var(--color-charcoal); + line-height: 1.3; +} + +.hero__title { + font-family: var(--font-display); + font-size: 96px; + font-weight: 400; + line-height: 1.0; + letter-spacing: -0.96px; + color: var(--color-ink); +} + +.hero__description { + font-family: var(--font-body); + font-size: 18px; + font-weight: 300; + line-height: 1.5; + color: var(--color-charcoal); + max-width: 480px; +} + +/* Hero CTAs */ +.hero__actions { + display: flex; + align-items: center; + gap: var(--spacing-lg); + flex-wrap: wrap; + justify-content: center; +} + +.btn-primary { + display: inline-flex; + align-items: center; + gap: var(--spacing-sm); + background: var(--color-primary); + color: var(--color-primary-on); + font-family: var(--font-ui); + font-size: 14px; + font-weight: 500; + padding: 10px 24px; + border-radius: var(--rounded-md); + height: 40px; + transition: all 0.25s ease; + position: relative; + overflow: hidden; +} + +.btn-primary::after { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, transparent 40%, rgba(0, 212, 255, 0.1) 100%); + opacity: 0; + transition: opacity 0.3s ease; +} + +.btn-primary:hover { + background: var(--color-surface-light); + color: var(--color-primary-on); + transform: translateY(-2px); + box-shadow: 0 8px 32px rgba(0, 212, 255, 0.12); +} + +.btn-primary:hover::after { + opacity: 1; +} + +.btn-ghost { + display: inline-flex; + align-items: center; + gap: var(--spacing-sm); + background: var(--color-surface-elevated); + color: var(--color-ink); + font-family: var(--font-ui); + font-size: 14px; + font-weight: 500; + padding: 10px 24px; + border-radius: var(--rounded-md); + height: 40px; + border: 1px solid var(--color-hairline-strong); + transition: all 0.25s ease; +} + +.btn-ghost:hover { + background: var(--color-surface-card); + border-color: rgba(255, 255, 255, 0.25); + transform: translateY(-2px); +} + + +/* ============================================================ + FEATURED RELEASE SECTION + ============================================================ */ +.featured-card { + display: flex; + background: var(--color-surface-card); + border: 1px solid var(--color-hairline-strong); + border-radius: var(--rounded-xl); + overflow: hidden; + max-width: 1000px; + margin: 0 auto var(--spacing-xxxl); + transition: border-color var(--duration-fast) ease, transform var(--duration-fast) ease; +} + +.featured-card:hover { + border-color: rgba(0, 212, 255, 0.25); + transform: translateY(-2px); +} + +.featured-card__artwork-link { + width: 45%; + flex-shrink: 0; + position: relative; + overflow: hidden; +} + +.featured-card__artwork { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.8s var(--ease-out-quint); +} + +.featured-card:hover .featured-card__artwork { + transform: scale(1.04); +} + +.featured-card__content { + padding: var(--spacing-xxxl); + display: flex; + flex-direction: column; + justify-content: center; + gap: var(--spacing-lg); +} + +.featured-card__tag { + font-family: var(--font-ui); + font-size: 11px; + font-weight: 500; + letter-spacing: 1.5px; + text-transform: uppercase; + color: var(--color-accent-cyan); +} + +.featured-card__title { + font-family: var(--font-display); + font-size: 48px; + line-height: 1.05; + color: var(--color-ink); +} + +.featured-card__artist { + font-family: var(--font-body); + font-size: 18px; + color: var(--color-charcoal); + margin-top: calc(-1 * var(--spacing-sm)); +} + +.featured-card__desc { + font-family: var(--font-body); + font-size: 15px; + line-height: 1.6; + color: var(--color-mute); + max-width: 400px; +} + +.featured-card__btn { + align-self: flex-start; +} + + +/* ============================================================ + RELEASES GRID + ============================================================ */ +.releases-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--spacing-xl); + margin-bottom: var(--spacing-xl); +} + +.release-card { + display: flex; + flex-direction: column; + background: var(--color-surface-card); + border: 1px solid var(--color-hairline); + border-radius: var(--rounded-lg); + overflow: hidden; + transition: all 0.35s var(--ease-out-quint); +} + +.release-card:hover { + border-color: var(--color-hairline-strong); + transform: translateY(-4px); + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4); +} + +.release-card__artwork-wrapper { + position: relative; + width: 100%; + aspect-ratio: 1; + overflow: hidden; + border-bottom: 1px solid var(--color-hairline); +} + +.release-card__artwork { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.6s var(--ease-out-quint); +} + +.release-card:hover .release-card__artwork { + transform: scale(1.03); +} + +.release-card__content { + padding: var(--spacing-xl); + display: flex; + flex-direction: column; + gap: var(--spacing-xs); +} + +.release-card__title { + font-family: var(--font-body); + font-size: 18px; + font-weight: 500; + color: var(--color-ink); + letter-spacing: -0.3px; +} + +.release-card__artist { + font-family: var(--font-ui); + font-size: 14px; + color: var(--color-mute); +} + +.release-card__date { + font-family: 'Geist Mono', monospace; + font-size: 12px; + color: var(--color-ash); + margin-top: var(--spacing-sm); +} + + +/* ============================================================ + ARTISTS GRID + ============================================================ */ +.artists-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--spacing-xl); +} + +.artist-card { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + background: var(--color-surface-card); + border: 1px solid var(--color-hairline-strong); + border-radius: var(--rounded-lg); + padding: var(--spacing-xxl) var(--spacing-xl); + transition: border-color 0.3s ease, transform 0.3s ease; +} + +.artist-card:hover { + border-color: rgba(0, 212, 255, 0.2); + transform: translateY(-2px); +} + +.artist-card__avatar { + width: 96px; + height: 96px; + border-radius: var(--rounded-full); + object-fit: cover; + border: 1px solid var(--color-hairline-strong); + margin-bottom: var(--spacing-lg); +} + +.artist-card__name { + font-family: var(--font-body); + font-size: 20px; + font-weight: 500; + color: var(--color-ink); + margin-bottom: var(--spacing-sm); +} + +.artist-card__bio { + font-family: var(--font-ui); + font-size: 13px; + line-height: 1.6; + color: var(--color-charcoal); + max-width: 240px; +} + + +/* ============================================================ + STATISTICS SECTION + ============================================================ */ +.section--stats { + border-top: 1px solid var(--color-hairline); + background: var(--color-surface-deep); +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + border: 1px solid var(--color-hairline-strong); + border-radius: var(--rounded-lg); + overflow: hidden; + background: var(--color-surface-card); +} + +.stats-item { + padding: var(--spacing-xxl) var(--spacing-xl); + text-align: center; + border-right: 1px solid var(--color-hairline); +} + +.stats-item:last-child { + border-right: none; +} + +.stats-item__num { + font-family: var(--font-display); + font-size: 44px; + font-weight: 400; + line-height: 1; + color: var(--color-ink); + margin-bottom: var(--spacing-xs); +} + +.stats-item__label { + font-family: var(--font-ui); + font-size: 11px; + font-weight: 500; + letter-spacing: 1.2px; + text-transform: uppercase; + color: var(--color-mute); +} + + +/* ============================================================ + SECTION: STREAMING PLATFORMS + ============================================================ */ +.section { + position: relative; + padding: var(--spacing-section) 0; +} + +.section--platforms { + border-top: 1px solid var(--color-hairline); +} + +.section__label { + font-family: var(--font-ui); + font-size: 12px; + font-weight: 500; + letter-spacing: 1.5px; + text-transform: uppercase; + color: var(--color-mute); + margin-bottom: var(--spacing-xl); + text-align: center; +} + +.section__title { + font-family: var(--font-display); + font-size: 48px; + font-weight: 400; + line-height: 1.1; + letter-spacing: -1.2px; + color: var(--color-ink); + text-align: center; + margin-bottom: var(--spacing-xxxl); +} + +/* Platform Grid */ +.platforms-grid { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: var(--spacing-md); + max-width: 800px; + margin: 0 auto; +} + +.platform-card { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: var(--spacing-sm); + background: var(--color-surface-card); + border: 1px solid var(--color-hairline-strong); + border-radius: var(--rounded-lg); + padding: var(--spacing-xl) var(--spacing-lg); + text-decoration: none; + transition: all 0.35s var(--ease-out-quint); + position: relative; + overflow: hidden; +} + +.platform-card::before { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient( + circle at 50% 0%, + rgba(0, 212, 255, 0.06) 0%, + transparent 70% + ); + opacity: 0; + transition: opacity 0.4s ease; +} + +.platform-card:hover { + border-color: rgba(0, 212, 255, 0.25); + transform: translateY(-4px); + background: var(--color-surface-elevated); +} + +.platform-card:hover::before { + opacity: 1; +} + +.platform-card__icon { + width: 32px; + height: 32px; + opacity: 0.7; + transition: opacity 0.3s ease; + position: relative; + z-index: 1; +} + +.platform-card:hover .platform-card__icon { + opacity: 1; +} + +.platform-card__name { + font-family: var(--font-ui); + font-size: 12px; + font-weight: 500; + color: var(--color-charcoal); + letter-spacing: 0.2px; + position: relative; + z-index: 1; + transition: color 0.3s ease; +} + +.platform-card:hover .platform-card__name { + color: var(--color-ink); +} + + +/* ============================================================ + SECTION: RELEASE INFORMATION (SUBPAGE SPECIFIC) + ============================================================ */ +.section--info { + border-top: 1px solid var(--color-hairline); +} + +/* Atmospheric glow for info section */ +.section--info::before { + content: ''; + position: absolute; + top: -100px; + left: 50%; + transform: translateX(-50%); + width: 700px; + height: 500px; + background: radial-gradient( + ellipse at center, + var(--color-accent-blue-glow) 0%, + transparent 70% + ); + opacity: 0.3; + pointer-events: none; + z-index: 0; +} + +.info-card { + position: relative; + z-index: 1; + background: var(--color-surface-card); + border: 1px solid var(--color-hairline-strong); + border-radius: var(--rounded-lg); + padding: var(--spacing-xxxl); + max-width: 800px; + margin: 0 auto; +} + +.info-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0; +} + +.info-item { + padding: var(--spacing-xl); + border-bottom: 1px solid var(--color-hairline); + position: relative; +} + +/* Vertical dividers between columns */ +.info-item:nth-child(3n+2) { + border-left: 1px solid var(--color-hairline); + border-right: 1px solid var(--color-hairline); +} + +/* Remove bottom border on last row */ +.info-item:nth-last-child(-n+3) { + border-bottom: none; +} + +.info-item__label { + font-family: var(--font-ui); + font-size: 11px; + font-weight: 500; + letter-spacing: 1.2px; + text-transform: uppercase; + color: var(--color-mute); + margin-bottom: var(--spacing-sm); +} + +.info-item__value { + font-family: var(--font-body); + font-size: 16px; + font-weight: 400; + color: var(--color-ink); + letter-spacing: -0.3px; +} + +.info-item__value--mono { + font-family: 'Geist Mono', 'JetBrains Mono', 'Fira Code', monospace; + font-size: 13px; + color: var(--color-charcoal); + letter-spacing: 0; +} + + +/* ============================================================ + SECTION: ABOUT + ============================================================ */ +.section--about { + border-top: 1px solid var(--color-hairline); +} + +.about-content { + max-width: 640px; + margin: 0 auto; + text-align: center; +} + +.about-content__text { + font-family: var(--font-body); + font-size: 20px; + font-weight: 300; + line-height: 1.7; + color: var(--color-charcoal); + letter-spacing: -0.2px; +} + +.about-content__text em { + font-style: italic; + font-family: var(--font-display); + color: var(--color-ink); + font-size: 22px; +} + + +/* ============================================================ + FOOTER + ============================================================ */ +.footer { + position: relative; + background: var(--color-canvas); + border-top: 1px solid var(--color-hairline); + padding: 64px 32px; +} + +.footer__inner { + max-width: 1200px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + gap: var(--spacing-xxxl); +} + +.footer__brand { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--spacing-md); +} + +.footer__logo { + height: 32px; + width: auto; + opacity: 0.7; +} + +.footer__label-name { + font-family: var(--font-body); + font-size: 14px; + font-weight: 500; + color: var(--color-charcoal); + letter-spacing: 0.3px; +} + +.footer__links { + display: flex; + align-items: center; + gap: var(--spacing-xxl); + flex-wrap: wrap; + justify-content: center; +} + +.footer__link { + font-family: var(--font-ui); + font-size: 14px; + font-weight: 400; + color: var(--color-ash); + transition: color 0.3s ease; + display: flex; + align-items: center; + gap: var(--spacing-xs); +} + +.footer__link:hover { + color: var(--color-ink); +} + +.footer__link svg { + width: 16px; + height: 16px; + opacity: 0.7; +} + +.footer__divider { + width: 100%; + max-width: 400px; + height: 1px; + background: var(--color-divider-soft); +} + +.footer__bottom { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + flex-wrap: wrap; + gap: var(--spacing-lg); +} + +.footer__copyright { + font-family: var(--font-ui); + font-size: 12px; + font-weight: 400; + color: var(--color-stone); + line-height: 1.5; +} + +.footer__contact { + font-family: var(--font-ui); + font-size: 12px; + font-weight: 400; + color: var(--color-stone); +} + +.footer__contact a { + color: var(--color-ash); +} + +.footer__contact a:hover { + color: var(--color-ink); +} + + +/* ============================================================ + SCROLL ANIMATIONS + ============================================================ */ +.fade-in { + opacity: 0; + transform: translateY(24px); + transition: opacity var(--duration-medium) var(--ease-out-expo), + transform var(--duration-medium) var(--ease-out-expo); +} + +.fade-in.visible { + opacity: 1; + transform: translateY(0); +} + +.fade-in-delay-1 { transition-delay: 100ms; } +.fade-in-delay-2 { transition-delay: 200ms; } +.fade-in-delay-3 { transition-delay: 300ms; } +.fade-in-delay-4 { transition-delay: 400ms; } +.fade-in-delay-5 { transition-delay: 500ms; } + +.scale-in { + opacity: 0; + transform: scale(0.92); + transition: opacity var(--duration-slow) var(--ease-out-expo), + transform var(--duration-slow) var(--ease-out-expo); +} + +.scale-in.visible { + opacity: 1; + transform: scale(1); +} + +/* Stagger platform cards */ +.platform-card.fade-in:nth-child(1) { transition-delay: 50ms; } +.platform-card.fade-in:nth-child(2) { transition-delay: 100ms; } +.platform-card.fade-in:nth-child(3) { transition-delay: 150ms; } +.platform-card.fade-in:nth-child(4) { transition-delay: 200ms; } +.platform-card.fade-in:nth-child(5) { transition-delay: 250ms; } +.platform-card.fade-in:nth-child(6) { transition-delay: 300ms; } +.platform-card.fade-in:nth-child(7) { transition-delay: 350ms; } +.platform-card.fade-in:nth-child(8) { transition-delay: 400ms; } +.platform-card.fade-in:nth-child(9) { transition-delay: 450ms; } +.platform-card.fade-in:nth-child(10) { transition-delay: 500ms; } + + +/* ============================================================ + RESPONSIVE BREAKPOINTS + ============================================================ */ + +/* Tablet (768px–1023px) */ +@media (max-width: 1023px) { + .hero__title { + font-size: 72px; + letter-spacing: -0.72px; + } + + .featured-card { + flex-direction: column; + } + + .featured-card__artwork-link { + width: 100%; + aspect-ratio: 16/9; + } + + .releases-grid { + grid-template-columns: repeat(2, 1fr); + } + + .artists-grid { + grid-template-columns: repeat(2, 1fr); + } + + .stats-grid { + grid-template-columns: repeat(2, 1fr); + } + + .stats-item:nth-child(even) { + border-right: none; + } + + .stats-item:nth-child(1), .stats-item:nth-child(2) { + border-bottom: 1px solid var(--color-hairline); + } + + .platforms-grid { + grid-template-columns: repeat(5, 1fr); + } + + .info-grid { + grid-template-columns: repeat(2, 1fr); + } + + .info-item:nth-child(3n+2) { + border-left: none; + border-right: none; + } + + .info-item:nth-child(even) { + border-left: 1px solid var(--color-hairline); + } + + .info-item:nth-last-child(-n+3) { + border-bottom: 1px solid var(--color-hairline); + } + + .info-item:nth-last-child(-n+2) { + border-bottom: none; + } + + .section__title { + font-size: 40px; + } +} + +/* Mobile Widescreen & Large (426px–767px) */ +@media (max-width: 767px) { + :root { + --spacing-section: 72px; + } + + .hero__title { + font-size: 56px; + letter-spacing: -0.56px; + } + + .hero__artwork-wrapper { + width: 300px; + } + + .hero__description { + font-size: 16px; + } + + .featured-card__content { + padding: var(--spacing-xl); + } + + .featured-card__title { + font-size: 36px; + } + + .releases-grid { + grid-template-columns: 1fr; + max-width: 400px; + margin: 0 auto var(--spacing-xl); + } + + .artists-grid { + grid-template-columns: 1fr; + max-width: 400px; + margin: 0 auto; + } + + .platforms-grid { + grid-template-columns: repeat(3, 1fr); + gap: var(--spacing-sm); + } + + .info-card { + padding: var(--spacing-xxl); + } + + .info-grid { + grid-template-columns: 1fr; + } + + .info-item:nth-child(even) { + border-left: none; + } + + .info-item { + border-bottom: 1px solid var(--color-hairline); + } + + .info-item:last-child { + border-bottom: none; + } + + .section__title { + font-size: 36px; + } + + .about-content__text { + font-size: 18px; + } + + .footer__bottom { + flex-direction: column; + align-items: center; + text-align: center; + } +} + +/* Mobile (≤425px) */ +@media (max-width: 425px) { + :root { + --spacing-section: 56px; + } + + .hero { + padding-top: 100px; + min-height: auto; + padding-bottom: var(--spacing-section); + } + + .hero__title { + font-size: 44px; + letter-spacing: -0.44px; + } + + .hero__artwork-wrapper { + width: 260px; + } + + .hero__artist { + font-size: 16px; + } + + .hero__description { + font-size: 15px; + } + + .stats-grid { + grid-template-columns: 1fr; + } + + .stats-item { + border-right: none; + border-bottom: 1px solid var(--color-hairline); + } + + .stats-item:last-child { + border-bottom: none; + } + + .platforms-grid { + grid-template-columns: repeat(2, 1fr); + } + + .hero__actions { + flex-direction: column; + width: 100%; + } + + .hero__actions .btn-primary, + .hero__actions .btn-ghost { + width: 100%; + justify-content: center; + height: 44px; + } + + .info-card { + padding: var(--spacing-xl); + } + + .section__title { + font-size: 32px; + } + + .nav__logo-text { + font-size: 12px; + } + + .nav__cta { + font-size: 12px; + padding: 6px 12px; + height: 32px; + } +} + + +/* ============================================================ + SMOOTH PAGE LOAD + ============================================================ */ +.page-loader { + opacity: 0; + animation: pageLoad 0.8s var(--ease-out-expo) 0.1s forwards; +} + +@keyframes pageLoad { + from { opacity: 0; } + to { opacity: 1; } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..6fe83f9 --- /dev/null +++ b/index.html @@ -0,0 +1,449 @@ + + + + + + Agung Dev Music — Personal Music Archive + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ Agung Dev Music Logo +
+ + + Personal Music Projects & Original Soundtracks + + +

+ Agung Dev Music +

+

+ + Loading archive details... +

+ + + + +
+
+ + + + + + + +
+
+ + +

Original Releases

+ +
+ +
+ +
+
+ + + +
+
+ + +

Original Projects

+ +
+ +
+ +
+
+ + + +
+
+ + +

Archive Statistics

+ +
+
+

0

+

Releases

+
+
+

0

+

Projects

+
+
+

0

+

Listening Platforms

+
+
+ +
+
+ + + +
+
+ + +

Listening Platforms

+ +
+ +
+ + Spotify +
+ +
+ + Apple Music +
+ +
+ + YouTube Music +
+ +
+ + Amazon Music +
+ +
+ + Tidal +
+ +
+ + Deezer +
+ +
+ + TikTok +
+ +
+ + Instagram +
+ +
+ + Facebook +
+
+ +
+
+ + + +
+
+ + +

About Agung Dev Music

+ +
+

+ Agung Dev Music is a personal space dedicated to publishing original music projects. From ambient soundscapes and electronic experiments to soundtrack-inspired compositions, every release represents a creative idea transformed into sound. +

+ This is not a traditional record label. It is a digital archive of music created and released by Agung Dev. +

+
+ +
+
+ + + + + + + + + + + diff --git a/labelsong.json b/labelsong.json new file mode 100644 index 0000000..c130729 --- /dev/null +++ b/labelsong.json @@ -0,0 +1,39 @@ +{ + "label": { + "name": "Agung Dev Music", + "description": "A collection of original music, ambient compositions, experimental audio projects, and soundtrack releases created by Agung Dev." + }, + "featured_release": "midnight", + "releases": [ + { + "slug": "midnight", + "title": "Midnight", + "artist": "Lunair", + "artwork": "images/midnight-cover.jpg", + "release_date": "2026-06-05", + "url": "releases/midnight" + } + ], + "projects": [ + { + "title": "Ambient Soundscapes", + "avatar": "images/artist-lunair.jpg", + "desc": "Deep synth textures, cosmic pads, and organic drones designed for deep focus, meditation, and relaxation." + }, + { + "title": "Original Soundtracks", + "avatar": "images/midnight-cover.jpg", + "desc": "Cinematic themes, orchestral arrangements, and dramatic instrumentals for short films and visual stories." + }, + { + "title": "Experimental Electronics", + "avatar": "images/aurora-cover.jpg", + "desc": "Modular synthesizer experiments, algorithmic loops, glitch beats, and avant-garde audio projects." + } + ], + "stats": { + "releases": "1", + "projects": "3", + "platforms": "10" + } +} \ No newline at end of file diff --git a/releases/midnight/index.html b/releases/midnight/index.html new file mode 100644 index 0000000..6d0b97a --- /dev/null +++ b/releases/midnight/index.html @@ -0,0 +1,371 @@ + + + + + + + Aurora — Agung Dev | Personal Music Archive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + Midnight — Album Cover +
+ + + Ethereal Release + + +

Luniar

+

Midnight

+ + +

+ An ethereal ambient electronic journey beneath the dancing northern lights. +

+ + + + +
+
+ + + +
+ +
+ + + +
+
+ + +

About Agung Dev Music

+ +
+

+ Agung Dev Music is a personal space dedicated to publishing original music projects. From ambient + soundscapes and electronic experiments to soundtrack-inspired compositions, every release represents a + creative idea transformed into sound. +

+ This is not a traditional record label. It is a digital archive of music created and released by Agung Dev. +

+
+ +
+
+ + + + + + + + + + + + \ No newline at end of file