DESIGN.md

Design Guidelines

DESIGN.md

Markdown source

Design Concept

This portfolio is designed as a quiet editorial archive for an art director / designer. The interface keeps the author identity present at all times while giving the work enough space to be inspected without decorative noise.

The visual direction is minimal, restrained, and image-led. Typography, spacing, and motion should feel precise rather than expressive. The site should read as a professional body of work, not as a promotional landing page.

Design Principles

  • Keep the work as the primary visual signal.
  • Use a fixed identity/navigation layer so orientation is always clear.
  • Avoid decorative surfaces, heavy cards, and oversized marketing sections.
  • Prefer quiet hierarchy: small labels, measured titles, generous blank space.
  • Let interaction feel calm: subtle hover color changes, light entrance motion, no distracting effects.
  • Preserve a portfolio/archive tone across Index, About, Contact, and detail pages.

Layout System

  • The base shell is a two-column CSS grid (display: grid).
  • The left column is a persistent profile/navigation rail.
  • The right column contains the active page content.
  • --site-padding: 24px defines the outer margin (20px on mobile, 16px at ≤420px).
  • --content-margin: 80px is used for vertical content padding in the detail panel.
  • Index/About content column: fluid --index-content-width: 60vw, capped at --index-content-max-width: 1152px.
  • Contact content column: min(80vw, 1500px).
  • Design.md page column: 860px (fluid 60vw between 768px and 1440px).
  • At ≥1920px the shell is constrained to max-width: 1920px and right-aligned (margin-left: auto; margin-right: 0), so the content column fixes at --index-content-max-width.
  • On mobile (≤767px), the shell becomes a vertical flex stack; the sidebar becomes a static header/navigation block.

CSS Custom Properties — Color tokens

  • --background / --text / --muted — Page base colors
  • --surface — White surface (cards, menus)
  • --surface-muted — Soft button / panel fill (#efeaea light)
  • --surface-soft / --surface-wash — Semi-transparent white overlays
  • --panel-light / --panel-dark — Pale / solid panel references
  • --border-strong / --border-subtle / --border-faint / --border-hairline — Four-level border system
  • --tag-border — Pill tag outline
  • --detail-backdrop — Work detail scrim (rgba(0,0,0,0.3) light / 0.62 dark)
  • --control-border / --control-background / --control-text — Gallery scroll button states
  • --indicator-track / --indicator-active / --indicator-fill — Showcase slider progress
  • --media-placeholder — Image placeholder fill
  • --website-frame-background / --showcase-background — Contextual panel fills (dark mode overrides)

CSS Custom Properties — Layout

  • --site-padding — Outer page margin (24px desktop / 20px mobile / 16px at ≤420px)
  • --content-margin — Vertical content padding reference (80px)
  • --index-content-width — Right-column fluid width (60vw)
  • --index-content-max-width — Right-column upper bound (1152px)
  • --detail-panel-width-desktop — Work detail panel width (70vw)
  • --recent-project-frame-width — Gallery card width cap (400px)
  • --past-grid-gap-x — Past grid horizontal gap (48px)
  • --past-grid-col-min — Past grid column minimum (132px)

CSS Custom Properties — Typography

  • --font-sans — Gen Interface JP + system fallback
  • --font-display — Gen Interface JP Display + --font-sans fallback
  • --font-original — General Sans + Noto Sans JP + system fallback

Navigation

  • Sidebar identity:
  • Name: MSNR MYMT
  • Role: Art Director / Designer
  • Primary navigation (sidebar, vertically centered):
  • Index
  • About
  • Contact
  • DESIGN.md — preceded by a short horizontal rule (::before separator, 12×1px) with padding-top: 17px to create visual distance from the links above.
  • Active navigation items use black text; inactive items use muted gray.
  • Navigation labels stay plain and text-based. Do not introduce icon navigation unless the whole sidebar system is reconsidered.
  • All navigation links and the sidebar identity name use the **ScrambleLink** behavior: on hover, characters animate through random ASCII/Katakana characters and settle back left-to-right over ~500ms. The speed scales with text length (msPerChar = min(20, 500 / length)).
  • On mobile, a secondary navigation appears in the footer (profile-footer__nav) and mirrors the same four links with identical active state behavior.

Typography

  • Primary Japanese/UI font: Gen Interface JP (weights 300, 400, 500, 700 loaded via CDN)
  • Display font: Gen Interface JP Display (weight 700 via CDN)
  • Latin/navigation font: General Sans (weights 400, 500, 600, 700 via Fontshare API)
  • Japanese fallback: Noto Sans JP (weights 400, 500 via Google Fonts), Hiragino, system sans-serif

General type behavior:

  • Body text is light, compact, and geometric (font-size: 14px, font-weight: 300, line-height: 1.35).
  • 13px body on mobile (≤767px).
  • Sidebar identity: 24px / 500 weight (23px on mobile) — General Sans.
  • Section headings and row titles: 18px / 500 / line-height: 28pxGeneral Sans.
  • Project list heading labels (eyebrow): 16px / 400 / muted.
  • Project frame metadata (title + category): 15px / 400.
  • Contact lead copy: 24px / 400 / line-height: 1.75 (20px mobile).
  • About / contact body prose: 16px / 400 / line-height: 1.75.
  • Work detail copy: 15px / 300 / line-height: 1.75.
  • Letter spacing should remain neutral (0).
  • -webkit-font-smoothing: antialiased and text-rendering: geometricPrecision applied globally.

Gen Interface JP — primary UI / body

静かな編集レイアウト。作品を主役に、余白と階層で読みやすく。

Gen Interface JP Display

Design Guidelines

General Sans — Latin / navigation

MSNR MYMT · Index · About · Contact

24px / 500 · sidebar identityMSNR MYMT

18px · section labelRecent work

24px · contact leadEditorial services with a restrained, archive-first tone.

Body · line-height 1.75Long-form copy stays light and readable. Spacing and rhythm follow the same quiet system as the rest of the portfolio so the page never feels like a marketing template.

Color Palette

Light mode (default)

  • Background: #fbfaf7 (--background)
  • Text: #000000 (--text)
  • Muted text: #71706f (--muted)
  • Surface white: #ffffff (--surface)
  • Soft panel / button background: #efeaea (--surface-muted, used for CTA buttons, project detail link)
  • Pale panel reference: #efe5e5 (--panel-light, used sparingly)
  • Dark panel: #000000 (--panel-dark, reserved)
  • Border, strong: rgba(0, 0, 0, 0.52) (--border-strong, section row tops, Design.md heading separators)
  • Border, subtle: rgba(0, 0, 0, 0.18) (--border-subtle, contact rows, detail link, textarea)
  • Border, faint: rgba(0, 0, 0, 0.16) (--border-faint, career / award / timeline rows in About)
  • Border, hairline: rgba(0, 0, 0, 0.12) (--border-hairline, lightest separator)
  • Tag border: #cccccc (--tag-border)

Dark mode

Activated via data-theme="dark" on :root, or automatically when data-system-theme="dark" unless data-theme="light" is set.

  • Background: #131316
  • Text: #f4f1eb
  • Muted: #9d9992
  • Surface: #1b1a18
  • Surface-muted: #26231f
  • Panel-dark: #f4f1eb (inverted)
  • Tag border: rgba(255, 255, 255, 0.24)
  • Border-strong: rgba(255, 255, 255, 0.46)
  • Border-subtle: rgba(255, 255, 255, 0.16)

The page has a fixed body::before overlay using a radial gradient (white highlight at top-right) and a vertical linear gradient to reinforce the warm off-white impression. Avoid introducing strong accent colors unless they come from project imagery.

  • Background--background
  • Text--text
  • Muted text--muted
  • Soft panel / button--surface-muted
  • Pale panel--panel-light
  • Border, strong--border-strong
  • Border, subtle--border-subtle
  • Tag border--tag-border

Components

Profile Sidebar

  • Fixed on desktop, static on mobile.
  • Identity block (profile-sidebar__identity) is position: fixed; top: var(--site-padding); left: var(--site-padding).
  • Navigation (profile-sidebar__nav) is position: fixed; top: 50%; left: 24px; transform: translateY(-50%).
  • Footer (profile-footer) is position: fixed; left: 24px; bottom: 24px.
  • Contains identity at the top, navigation centered vertically, and social/copyright in the footer.
  • Uses General Sans for a neutral, international portfolio tone.
  • The footer includes Social links (X, Instagram) and a Creative Unit link (IE3).

Theme Toggle

  • Rendered by ThemeToggle component, placed inside ProfileSidebar and rendered as position: fixed; top: var(--site-padding); right: var(--site-padding); z-index: 60.
  • Three modes: System (follows OS preference), Light, Dark.
  • Mode is applied as data-theme="dark"|"light" on :root; system preference is detected and written as data-system-theme on :root.
  • Selection is persisted in localStorage under portfolio:theme-mode.
  • Trigger: 44×44px pill button with a sun/rays SVG icon; muted color at rest, bordered background on hover or when menu is open.
  • Menu: absolutely-positioned below the trigger, border-radius: 8px, color-mix-based translucent background, box-shadow depth. Options are 32px pill buttons.
  • Hidden on the work detail overlay (.work-detail-shell .theme-toggle { display: none }).

Project List — Recent

  • First 7 projects are displayed as large work-led sections (ProjectSection).
  • Each section has a metadata row (title + category) and a horizontally scrollable gallery (project-section__gallery).
  • Gallery extends full-width by bleeding into both margins via negative margin and calculated padding.
  • Mouse drag scrolling is implemented with Pointer Events API (onPointerDown/Move/Up); drag threshold is 4px before suppressing click.
  • Left/right navigation buttons (project-section__controls) appear when content overflows; they snap to the nearest frame using offsetLeft positions. Buttons are 54×54px on desktop, 48×48px on mobile (≤767px).
  • Frame variants: image (standard photo), website (full-bleed screenshot with centered overflow), logo (centered fixed-size image), symbol (text-only typographic frame — large mark + copy block, used when no photography is available; e.g. Chuo University SDB renders "SDB" at 108px and a 4-line caption at 13px).
  • On hover over a Recent section, all images within it scale to 1.03 (CSS-only, @media (hover: hover)). The hover target is the whole project-section, not individual frames.
  • Project frames enter with a vertical fade/translate animation (opacity 0→1, translateY(24px)→0, 700ms ease) triggered by IntersectionObserver (is-visible class, threshold 0.04, rootMargin right 28% / bottom -8%) so horizontal swipes reveal upcoming cards earlier.
  • Frames are staggered: nth-child 1–5 get 80/180/280/380/480ms delays; n≥6 get 580ms.
  • During gallery drag/scroll, frame transition delays are removed so newly revealed cards respond immediately.
  • is-restoring-index class on site-shell disables all frame animations to allow instant scroll restoration.
  • Project title links use the ScrambleLink hook (useScramble) triggered by section onMouseEnter/Leave.

Project List — Past

  • Projects from kanazawa-21st-century-museum onward (excluding Hiking slugs) appear under a "Past Project" heading with an eyebrow note "Project before 2020".
  • Laid out in a fluid grid: repeat(auto-fit, minmax(max(132px, min(400px, (100% − 2×48px) / 3)), 1fr)).
  • On mobile (≤767px) the grid collapses to a 2-column grid with 36px vertical / 24px horizontal gap.
  • Default visible count is 12; a "More Project" button expands to all.
  • Hiking projects (tsurugi-trekking, tenjyosan-trekking, tateyama-trekking) are separated into a "Hiking" heading and their own grid.
  • Past frames use aspect-ratio: 400 / 500; some slugs use width-fit or height-fit variants that contain instead of cover.
  • On hover over a Past frame, only that individual frame's image scales to 1.03 (not the whole grid row).
  • Each Past cell title also uses the ScrambleLink hook.
  • Index scroll position is saved to sessionStorage (portfolio:index-scroll-y) before navigating to a detail and restored on return.

Work Detail

  • Navigating to /works/[slug] renders a slide-in panel over the index.
  • The overlay (work-detail-shell) is position: fixed; inset: 0; z-index: 40.
  • A semi-transparent scrim (rgba(0,0,0,0.3) backdrop) fades in at 360ms.
  • The detail panel (work-detail-main) slides in from the right: width: var(--detail-panel-width-desktop) (70vw), min-width: 620px, entering with translate3d(72px→0) and opacity 0→1 over 640ms cubic-bezier(0.16, 1, 0.3, 1).
  • Closing animates the panel out to the right (translate3d(0→72px), 360ms) and fades the scrim.
  • Clicking the scrim area routes to / without scroll.
  • Content is padded var(--content-margin) top/bottom and var(--detail-panel-x) sides, where --detail-panel-x: max(80px, (70vw − 980px) / 2).
  • On mobile (≤767px), the panel occupies the full viewport width; the scrim and desktop sidebar are hidden; a work-detail-mobile-chrome block provides the mobile profile header.
  • A "Back" button navigates to / and triggers the close animation.
  • Media containers (work-detail-hero, work-detail-large-image, work-detail-video, work-detail-embed) use border-radius: 8px (4px on mobile).
  • Slug-specific modifier classes (e.g. work-detail-main--kanazawa-21st-century-museum) override image aspect ratio to auto with object-fit: contain when project imagery should not be cropped.

About

  • About content follows the same editorial grid as the rest of the site (content-row: 20% label / remaining body).
  • Career rows: 3-column grid (100px date / 80px period / flex body).
  • Awards: year column (60px) + body; prizes nested within awards.
  • Timeline rows: 70px date / flexible title / 150px thumbnail image. Thumbnails are grayscale and transition to color on row hover (240ms).
  • Timeline rows and career rows that have an href are rendered as <a> elements (AboutTimelineRowLink, AboutCareerRowLink) and use the ScrambleLink behavior on their primary label (title or company name) via useScramble.
  • Portrait photo is grayscale, 258×253px desktop.
  • Entrance animation: each row staggered aboutContentFadeIn (translateY 24px→0, opacity 0→1, 700ms), delays 0/80/160/240/320/400ms.

Contact

  • Contact is a structured long-form service page.
  • Content column: min(80vw, 1500px).
  • Rows use a left label column (300px) and a right content column on desktop (≥1280px). Between 1280–1440px the label column scales to minmax(180px, 30%).
  • Between 768–1279px, the shell converts to a vertical flex column (sidebar becomes static), and content rows become single-column.
  • Service cards: padding: 72px 0, separated by border-bottom. On mobile (≤767px), reduced to padding: 32px 0.
  • Tags are pill elements (border-radius: 100px) with #cccccc border, 43px min-height.
  • Showcase section includes a slider with progress-bar indicators and auto-advance (CSS animation via --works-rotor-cycle-ms). Controls are positioned right: 8px; bottom: 8px within the slider.
  • CTA button: pill-shaped (border-radius: 200px), 212px wide, 57px min-height, #efeaea background.
  • Same staggered aboutContentFadeIn entrance animation as About.

Design.md Page

  • Route /design reads and renders Design.md at build time (readFileSync).
  • The file is parsed into a flat block structure (headings, paragraphs, lists) and grouped by H2 sections.
  • Each H2 section is rendered as a ContentRow with the section title as a left-column heading.
  • Inline backtick spans render as <code> elements.
  • After the Typography section, a DesignTypographyShowcase component renders live type specimens.
  • After the Color Palette section, a DesignColorPaletteShowcase component renders color swatches.
  • A DesignCopy component at the top allows viewing and copying the raw markdown.

Buttons

  • All action buttons use border-radius: 200px (pill shape).
  • Default resting state: color: var(--muted), background: #efeaea.
  • Hover state: color: var(--text), background: #ffffff.
  • Transition: color 180ms ease, background 180ms ease.

Motion

  • **Entrance**: Project frames and About/Contact content rows use translateY(24px) → 0 + opacity 0 → 1 over 700ms ease, staggered by child index.
  • **Gallery drag**: Pointer-based drag scroll with cursor: grab / cursor: grabbing states; 4px threshold before drag suppresses click.
  • **Gallery scroll buttons**: Smooth scroll via scrollTo({ behavior: "smooth" }) snapping to nearest frame offset.
  • **ScrambleLink**: On hover, characters cycle through random ASCII/Katakana and settle left-to-right within ~500ms. Used on sidebar identity, all nav links, and project titles.
  • **Project image hover — Recent**: Entire project-section hover triggers scale(1.03) on all contained images (800ms ease transition).
  • **Project image hover — Past**: Individual project-frame hover triggers scale(1.03) on that frame's image only.
  • **Timeline thumbnail**: Grayscale filter lifted on row hover (240ms ease).
  • **Work Detail open**: Panel slides in from right (72px offset, 640ms spring easing); scrim fades in (360ms).
  • **Work Detail close**: is-closing class triggers reverse animations before route change.
  • **Contact showcase slider**: Slides crossfade at opacity 1.4s ease-in-out; progress bar animates with a CSS scaleX keyframe.
  • Respect prefers-reduced-motion: all animation-duration and transition-duration are overridden to 0.001ms.
  • Avoid looping decorative animation in core page chrome.

Responsive Rules

  • ≥1920px — Shell capped at 1920px, right-aligned; content column at --index-content-max-width
  • 1280–1440px — Contact label column scales fluidly; showcase copy collapses to single column
  • 768–1279px — Contact shell converts to vertical flex; sidebar becomes static
  • ≤767px — All shells convert to vertical flex; sidebar becomes static header
  • ≤420px — --site-padding reduces to 16px; project meta allows whitespace wrap

Mobile-specific adjustments:

  • Project gallery cards: min(78vw, 400px) × min(98vw, 500px).
  • Past grid: 2 columns, 36px row gap / 24px column gap.
  • Work detail: full-viewport panel, mobile chrome header, fixed back button at bottom.
  • All border-radius values on media elements reduce from 8px to 4px.

Implementation Notes

  • Prefer existing CSS custom properties before adding new values.
  • Keep additions scoped to page or component class names.
  • Reuse existing typography and spacing patterns before creating new variants.
  • Do not add nested cards or decorative gradient/orb backgrounds.
  • Use project imagery and real content as the main visual material.
  • Keep copy concise and editorial; avoid instructional UI text inside the experience.
  • The Design.md page reads this file at build time; keep formatting parseable (H1/H2/H3, - lists, ` `` inline code).