SPIKES GUILD / ACCOUNT
活動の現在地を、迷わず確認する。
白い面では情報の階層と次の操作を先に見せる。装飾は状態を補助する範囲に留める。
● 同期済み / 2分前SPIKES のプロダクト表現を、採用ルールと動的な軸に分けて管理する内部リファレンス。黒、白、シアンを基準に、タイポグラフィ・モーション・アクセシビリティ・書き出し表現までをコンポーネント単位で検証する。
採用見本は静かに、レジストリは動的に。真実源: src/lib/tweak/axes.ts (spikes-tweak-v33) + src/lib/brand.ts + src/styles/*.scss。レガシー候補はランタイムから削除せず、プロダクト既定値から分離する。
The product surface is quiet first: near-black, soft white, and one cyan signal. These six rules are the filter for every component and every motion choice.
SPIKES GUILD / ACCOUNT
白い面では情報の階層と次の操作を先に見せる。装飾は状態を補助する範囲に留める。
● 同期済み / 2分前SPIKES / SIGNAL
暗い面は証拠や集中を区切るために使い、常時発光・RGB分離・金属グラデーションを既定にしない。
● READY / reduced motion対応Quiet technical editorial
Near-black surfaces, soft white type, a restrained grid, and one cyan signal. Tactical details support orientation; they never become the subject.
Monochrome is the default
Idle UI stays calm and legible. Color appears only when it explains focus, status, or a deliberate event moment, then returns to the neutral surface.
Cyan is the product signal
iriCyan (#00E5FF) is the single UI accent. Magenta, amber, and metallic treatments stay available for authored exports and event art, never as a default color pair.
全てはトークン駆動 (data-* アーキテクチャ)
<html data-*> 属性が palette / font / chromatic / pattern / cursor を一括切替する。真実源は src/lib/tweak/axes.ts (ランタイム) と src/lib/brand.ts (静的書き出し/OG)。この2つは常に同期させる。
Motion explains state
Use motion to establish hierarchy, focus, or change. Keep entrances short and quiet; every animated treatment needs a static and reduced-motion fallback.
パフォーマンスは設計の一部
フォント <link> を初期 HTML に置かない (FontLoader が hydrate 後注入)。WebGL は 3層戦略で予算管理。モバイルは重エフェクト全 OFF。モバイル FCP 14.4s の事故から学んだ鉄則。
デザインの真実源は 2 ファイルだけ。この 2 つを同期させ続けることが再構築の絶対条件。 SCSS (src/styles/*) は axes.ts が宣言する data-* セレクタの実装側。
| ファイル | 担当 | 同期ルール |
|---|---|---|
| src/lib/tweak/axes.ts | ランタイム design system。全軸の型・選択肢・DEFAULT_TWEAK。<html data-*> へ反映 | 軸・値を追加したら STORAGE_KEY をバンプ (現在 "spikes-tweak-v33")。SCSS 側のセレクタと 1:1 対応必須 |
| src/lib/brand.ts | 静的書き出し (OG / Satori / ジェネレータ) 用の色・ロゴ・フォント・HUD 文字列 | Satori は CSS 変数を読めないため palettes.scss と手動同期。ロゴ差し替え時は最優先で更新 |
| axis | value |
|---|---|
| intensity | calm |
| density | airy |
| palette | monochrome |
| displayFont | switzer |
| bodyFont | inter |
| jpDisplayFont | noto-sans-jp |
| displaySkew | 0 |
| displayStretch | normal-100 |
| displayWeight | 600 |
| monoFont | jetbrains |
| jpBody | noto-sans-jp |
| shaderContour | hard |
| shaderDispersion | subtle |
| shaderSpeed | slow |
| shaderBody | transparent |
| shaderRim | subtle |
| shaderFringe | cyan |
| shaderBloom | strong |
| shaderContourMul | 1.85 |
| shaderDispersionMul | 0.5 |
| shaderSpeedMul | 0.45 |
| shaderAngle | 325 |
| shaderRepetition | 2 |
| shaderSoftness | 0.68 |
| shaderRimAlpha | 1.75 |
| shaderTintBoost | 1.2 |
| shaderEdgeContrast | 1.9 |
| shaderEdgeSaturate | 1.55 |
| shaderEdgeBlur | 0 |
| shaderEdgeBloom | 9 |
| shaderEdgeBloomAlpha | 0.9 |
| shaderEdgeWhite | 0.25 |
| shaderInnerGlow | 0.7 |
| shaderHueShift | 0 |
| shaderEdgeNoise | 0 |
| motionDuration | 0.7 |
| motionStagger | 0.04 |
| motionDistance | 32 |
| motionParallax | 1 |
| motionRotate | 0 |
| glitchDuration | 0.65 |
| glitchStagger | 0.035 |
| glitchOffsetX | 10 |
| glitchOffsetY | 14 |
| glitchScale | 1.025 |
| glitchBlur | 7 |
| glitchBrightness | 1.35 |
| glitchSplitOffset | 12 |
| glitchHaloAlpha | 0.5 |
| glitchFlashPeak | 0.55 |
| glitchFlashPulses | 3 |
| glitchSliceCount | 6 |
| glitchSliceDriftX | 32 |
| glitchSliceDriftY | 12 |
| glitchSliceDuration | 0.45 |
| glitchParallaxLayers | 3 |
| glitchParallaxDepth | 32 |
| glitchScanline | 0.35 |
| sectionTitleStroke | 0 |
| sectionTitleFlicker | 0 |
| sectionTitleGlow | 0 |
| iridescence | off |
| chromatic | off |
| chromaticAnim | static |
| kinetic | subtle |
| motionEntrance | quiet |
| motionScrollFx | off |
| motionHoverFx | lift |
| motionCursorTrail | off |
| motionTextReveal | smart-fade |
| buttonMotion | quiet |
| buttonShape | chamfer-tr-bl |
| enHeadingStyle | plain |
| enHeadingMotion | smart-fade |
| sectionHeadingFont | plain |
| sectionTitleColor | neutral |
| hudPattern | minimal |
| bgPattern | pure |
| sectionPattern | editorial-grid |
| cursor | none |
enum 軸 37 + スライダー軸 43。Tweak パネル (NEXT_PUBLIC_TWEAK_ENABLED=true → Cmd/Ctrl+Shift+T or ?tweak=1) は現在 COLOR / GLOW の 2 グループのみ露出、他は上表で固定。
| preset | 説明 | 上書きする軸数 |
|---|---|---|
| noir | Silver + amber spark / cinematic restraint | 26 keys |
| platinum | Pure metal / wide editorial / mercury chrome | 26 keys |
| blade | Cyan + orange / Blade Runner / liquid-glass HUD | 26 keys |
| dune | Warm desert + deep teal / mincho | 26 keys |
| oilslick | Holographic blast / glitch / saturated | 26 keys |
| solar | Burning amber / esports stack / pulse | 26 keys |
The approved core is live from brand.ts: neutral surfaces, readable ink, and one cyan signal. Other treatments remain available as explicit export or event variants.
src/lib/brand.ts
| role | token | usage |
|---|---|---|
| primary accent | iriCyan | focus, active state, and a single point of orientation |
| surface | bg / ink / inkMute | quiet hierarchy before decoration; keep the action unmistakable |
vertical — spikes/logo-v.webp
horizontal — spikes/logo-h.webp
icon — spikes/symbol.webp| アセット | 用途・注意 |
|---|---|
| symbol.webp (1024×998 / 270KB) | 正方形シンボルのマスター。印刷 / OG 生成 (partnergenerator・session-card) 用。LP は使わない |
| symbol-840.webp (840×819 / 152KB) | LP の LCP。layout.tsx の preload と LoadingSplash の img src は**必ず同じ href**にする (DES-22) |
| logo-h.webp / badge.png (1480×448) | 横長。next/image の width/height は実寸比で |
| logo-v.webp | 縦組み |
| STATIC_PNG (chrome 焼き .webp) | shader static 層のフォールバック。ロゴ更新時に再生成必須 (/admin/shader-export) |
| favicon | src/app/icon.png + apple-icon.png (Next 規約ファイル・fingerprinted) |
{
"latin": "Inter",
"jp": "Noto+Sans+JP",
"display": "Anybody"
}src/styles/tokens.scss (転記 — 変更時はこの表も更新)
| token | value | 用途 |
|---|---|---|
| --gutter | clamp(20px, 5vw, 88px) | 左右基本余白 |
| --rail | clamp(28px, 4vw, 72px) | サイドレール幅 |
| --max-w | 1320px | コンテンツ最大幅 |
| --max-w-narrow | 920px | 読み物系最大幅 |
| token | value |
|---|---|
| --s-1 | 4px |
| --s-2 | 8px |
| --s-3 | 12px |
| --s-4 | 20px |
| --s-5 | 32px |
| --s-6 | 48px |
| --s-7 | 72px |
| --s-8 | 112px |
| --s-9 | 160px |
| --s-10 | 220px |
| token | value |
|---|---|
| --r-0 | 0 |
| --r-1 | 2px |
| --r-2 | 4px |
| --r-3 | 8px |
| --r-md | 14px |
| --r-lg | 22px |
| --r-xl | 32px |
| --r-pill | 999px |
| token | value | 備考 |
|---|---|---|
| --easing-out | cubic-bezier(0.22, 1, 0.36, 1) | 標準イージング |
| --easing-snap | cubic-bezier(0.44, 0, 0.56, 1) | スナップ |
| --easing-elastic | cubic-bezier(0.68, -0.55, 0.27, 1.55) | 弾性 |
| --tac-snap | cubic-bezier(0.16, 1, 0.3, 1) | TacticalButton |
| --dur-fast | 160ms | |
| --dur-base | 280ms | |
| --dur-slow | 520ms | |
| --dur-shimmer | 5400ms | chrome シマーループ |
| token | value |
|---|---|
| --z-bg | 0 |
| --z-content | 10 |
| --z-side-rail | 30 |
| --z-hud | 40 |
| --z-topbar | 50 |
| --z-cursor | 100 |
| --z-tweak | 100000 |
| 属性 | 値と効果 |
|---|---|
| data-intensity | calm 0.5 / balanced 1.0 / loud 1.5 / blast 2.2 → --fx-intensity |
| data-density | airy 1.4 / default 1.0 / dense 0.72 → --space-mult (セクション padding に乗算) |
| data-kinetic | off〜havoc 7 段。hover の Y / scale / tilt / duration を一括制御 |
| --mx / --my / --tilt-x / --tilt-y | ポインタ反応 (JS が書き込み)。chrome-text の光沢追従に使用 |
| --scroll-progress | Lenis が 0..1 を publish |
src/styles/palettes.scss (スウォッチは data-palette 属性による live 描画)
全パレットは data-palette 属性で要素単位に適用できる (:root 限定ではない — IvsRedBand や GUILD 団体ページのローカルテーマがこの仕組み)。各カードの色面は実 CSS 変数 (--bg / --iri-1..6) の描画結果。
monochrome
無彩色 (chromatic ghost 自動 OFF)
#050507 #0B0B0E #14141A / ink #ECEEF1
履歴・イベント・書き出し用の軸は動的システムに保持するが、製品面の初期選択肢にはしない。
chromatic-classic
CSS 上のデフォルト (:root)。パステル iridescent
#050507 #0E0E12 #16161D / ink #ECEEF1
chromatic-warm
暖色シフト
#07050A #110A12 #1A0E18 / ink #FFEFE4
chromatic-cool
寒色シフト
#03060A #08101A #0E1828 / ink #E4ECFF
marathon-coral
Marathon 系コーラル
#07070A #0E0E12 #16161D / ink #ECEEF1 / accent #FF4D2E
oil-slick
オイルスリック虹彩
#03030A #0A0A18 #14142A / ink #F2EAFF / accent #C842FF
cinema-noir
campaign registry。product default ではない
#050507 #0B0C10 #15171C / ink #E8EAEE / accent #FFB36E
cinema-blade
Blade Runner 系 orange×teal
#050608 #0B0E14 #14181F / ink #E8ECF2 / accent #FF8B42
cinema-dune
Dune 系サンド
#06040A #100A0E #1A1218 / ink #F0E2D0 / accent #E0A872
cinema-mercury
水銀メタリック
#050507 #0B0B0E #14141A / ink #ECEEF1 / accent #ECEEF1
cinema-violet
紫系シネマ
#04040A #0A0A14 #14141E / ink #E8E4F2 / accent #FFB36E
ivs-red
IVS 公式レッド帯用
#050202 #100808 #1F0A0A / ink #FFE8E2 / accent #FF3A1C
| ルール | 内容 |
|---|---|
| 現行デフォルト | monochrome / neutral ink。色は focus・status・primary action の説明に限定 |
| accent | iriCyan を1点だけ。idle surface は無彩色で保つ |
| campaign registry | イベント・書き出し用の色軸は動的レジストリへ保持し、製品の初期面には出さない |
| ローカル適用 | <article data-palette="ivs-red"> のように要素へ直接付与できる |
src/styles/typography.scss + src/lib/tweak/axes.ts + FontLoader.tsx
SPIKES
display: Switzer — 600 / no skew / short titleSPIKES OS
display: Cabinet Grotesk — 600 / compact label出る杭よ、突き抜けろ。
jp: Noto Sans JP 700 (display) / 500 (body)S/02 — CONTENTS [ N35.011 . E135.768 ]
mono: JetBrains Mono — tabular-nums / ss01 / ls .04em| 軸 | 選択肢 | 現行値 |
|---|---|---|
| displayFont | approved display set / runtime registry remains dynamic | switzer |
| displaySkew | 0 / -6 / -10 / -14 / -20 deg | 0 |
| displayStretch | narrow-75 / normal-100 / wide-150 / ultra-200 (wdth) | normal-100 |
| displayWeight | 400 / 600 / 800 / 900 | 600 |
| bodyFont | inter / switzer / satoshi / general-sans / cabinet / synonym / author / supreme | inter |
| monoFont | jetbrains / geist-mono / ibm-plex-mono | jetbrains |
| jpDisplayFont | noto-sans-jp only for product UI | noto-sans-jp |
| jpBody | noto-sans-jp / zen-kaku-gothic / m-plus-1 / klee / shippori-mincho / zen-old-mincho | noto-sans-jp |
| sectionHeadingFont | plain / compact / display — choose for hierarchy, not spectacle | plain |
| sectionTitleColor | ink / muted / cyan signal | neutral |
| 層 | 内容 |
|---|---|
| 初期 HTML | フォント <link> ゼロ (render-block 回避)。preconnect のみ (googleapis / gstatic / fontshare) |
| セルフホスト | Noto Sans JP は @fontsource-variable でバンドル (Google JP CSS は使わない) |
| CRITICAL (本番常時) | Switzer / Inter / Noto Sans JP / JetBrains Mono — FontLoader が hydrate 後に JS 注入 |
| EXTENDED + Fontshare | 承認外の registry は探索・書き出し時だけ明示的にロード。製品面の見本には出さない |
Reggae One は恒久禁止
axes.ts / SCSS / FontLoader から完全排除済み (commit 2fd40b6)。古い localStorage からの復活も Noto Sans JP へフォールバックする。いかなる理由でも再導入しない。
The runtime registry stays dynamic. This gallery shows only the families approved for product surfaces: restrained, legible, and durable across languages.
拡張フォントをロード中...
SPIKE
saira-cond
SPIKE
switzer — Fontshare
SPIKE
cabinet — Fontshare
SPIKE
clash-display — Fontshare
JP DISPLAY / APPROVED
出る杭よ、突き抜けろ
noto-sans-jp — ★ 現行 (700)
src/lib/brand.ts + product surface tokens
Product text stays readable and still. A signal is a state indicator, not a visual effect: use one accent, one purpose, and an obvious fallback.
| decision | product rule |
|---|---|
| default | neutral ink and surface; no decorative split or glow |
| accent | one cyan signal for focus, status, or the primary action |
| motion | state change first; reduced-motion and static fallback always available |
src/app/design-kit/_components/KitFoundation.tsx
Material is carried by spacing, contrast, and hierarchy. The product surface does not need a chrome treatment to feel considered; export-only artwork stays outside the UI system.
| layer | decision |
|---|---|
| surface | light and dark share the same hierarchy, spacing, and action order |
| type | display type is for a short title; body copy remains calm and readable |
| artwork | logos, gradients, and export effects are assets, never default UI chrome |
このページ自体が SectionFrame で組まれている — 各章の四隅ブラケット・左上 K/xx チップ・ 右上 coord チップが実物。HUD の語彙は以下で固定。
| 要素 | 仕様 |
|---|---|
| S/xx インデックス | セクション左上 chip。番号 (cyan) + — LABEL。SectionFrame の index/label props |
| 座標 chip | 右上。実在座標 N35.011 E135.768 (みやこめっせ) or メタ情報 (S/01 — 6 EVENTS) |
| コーナーブラケット | 22×22px / 1px solid var(--ink) / opacity .55 / inset 22px。CSS border 2辺の L 字 (グリフではない) |
| mono チップ | MonoChip: default / live (ドット付き) / alert。tabular-nums + ss01 + ls .04em |
| HUD 文字列 | SPIKES.OS — VOL.01 / FIG.A — INDEX 01 / T-{ddd}D hh:mm:ss (Countdown — 開催日を過ぎたら非表示)。eventHudStrings() が導出 |
| ★ セパレータ | Marquee の項目間は ★ |
<SectionFrame index="S/02" label="CONTENTS" coord="N35.011 E135.768">
<SectionHeading … />
{/* content */}
</SectionFrame>
/* ブラケット: 22×22px / 1px solid var(--ink) / opacity .55 / inset 22px (CSS border の L字)
* 入場: IO → chromatic flash + bracket run-in + index typewriter (1回のみ)
* .frame は content-visibility:auto (パフォーマンス) */src/components/chrome/*
chamfer-tr-bl
★ 最終形。TR/BL 14px 面取り
chamfer-quad
四隅 10px 面取り (8点)
parallelogram
skewX(-12deg)。ラベルは逆スキュー
titanium-holo
6px 面取り + cyan/magenta ホロエッジ
| 仕様 | 値 |
|---|---|
| クリップ | polygon 14px 面取り (TR/BL)。buttonShape 軸: chamfer-tr-bl★ / chamfer-quad / parallelogram / titanium-holo |
| default action | quiet / solid neutral surface / pill radius / one clear arrow |
| focus | 2px cyan outline + 3px offset; visible for keyboard and switch navigation |
| target | all sizes keep a 44px minimum hit area; label remains readable at 200% |
| motion | quiet by default; magnetic and authored HUD brackets are explicit opt-ins |
| shape | chamfer variants remain available for event art; they are not the product default |
SPIKES
title / 600 / solid inkSPIKES OS
section / 500 / readableVOL.01KYOTO
metadata / mono / tracked| props | 仕様 |
|---|---|
| size | xxl clamp(96,18vw,320) lh.82 / xl clamp(80,13vw,220) / lg clamp(56,9vw,150) / md clamp(36,5vw,80) / sm clamp(24,3vw,48) |
| surface | solid ink first; no gradient, outline, or ghost in the default product state |
| accent | one cyan signal for focus or status; never as a decorative text treatment |
| reveal | short opacity/translate transition; reduced-motion fallback is the final state |
| measure | short title, readable line length, and 200% zoom without clipping |
| dynamic | size and family are token-driven; component copy remains content-first |
| component | 要点 |
|---|---|
| Countdown | "T-{ddd}D hh:mm:ss" 形式で MonoChip に描画。target を過ぎたら null を返して要素ごと消える (0 で凍らせない・interval も止める)。既定 target と整形は src/lib/spikesCountdown.ts が単一の真実源 — 次回イベントはそこだけ更新。prop で target を渡せばプレビュー可 (上のデモ) |
| CursorHalo | rAF 追従。coarse pointer / hover:none では null を返す (モバイル安全) |
| AutoPlate | 暗色ロゴを輝度判定して白台座を自動付与 (GUILD ロースター / パートナー帯) |
| glass / tilt | カード共通クラス。backdrop-filter は stacking context を作る点に注意 (PITFALLS #8) |
src/styles/patterns.scss + cursor.scss
| pattern | 実装 |
|---|---|
| grid | 80px 間隔の hairline 2方向、opacity .5 |
| pure | background layer なし。製品の既定 surface |
| pattern | 実装 |
|---|---|
| editorial-grid | .section-inner を 4fr/8fr グリッド化 (<810px で解除) |
| edge-bleed | border-top 消去 + 上下 96px フェード、フレーム chrome 非表示 |
| cursor | 実装 |
|---|---|
| none | 全カーソル演出 OFF |
製品既定は pure surface + native cursor。装飾パターンはレジストリに残すが、採用見本には出さない。
src/components/mirror/MirrorShaderLab.tsx + mirrorBentoShaderSource.ts + mirrorTuningModel.ts
ロゴや映像を主役にせず、静止した黒面の上に一枚の rounded SDF frame だけを描く。 WebGL は装飾ではなく、銀芯・dark bevel・内外リム・周回光・pointer focus を調整可能にするための局所表現。
| invariant | rule |
|---|---|
| surface | 黒面は静止。frame の外周だけが状態を伝える |
| budget | 1 card / 1 canvas / 0 video / 0 logo-mask / 519,901px以内 |
| fallback | reduced-motion、モバイル、WebGL失敗時は同じ frame の静的表現へ |
| sharing | 40 tuning values を URL hash に保存し、プリセット復元可能 |
| param | value |
|---|---|
| intensity | 1.08 |
| edge | 0.92 |
| rimWidth | 0.62 |
| outerBloom | 0.72 |
| innerBloom | 0.68 |
| specular | 0.74 |
| arc | 0.38 |
| lowerPool | 1.08 |
| cornerSpark | 0.68 |
| haze | 0.18 |
| colorBlend | 0.66 |
| motion | 0.026 |
| sweepWidth | 0.08 |
| sweepAngle | 116 |
| reflectionGain | 0.12 |
| metal | 0.72 |
| caustic | 0.36 |
| grain | 0.004 |
| prism | 0.18 |
| depth | 0.9 |
| fresnel | 0.65 |
| diffraction | 0.16 |
| chroma | 0.12 |
| detail | 0.36 |
| frameCore | 0.84 |
| frameDepth | 0.84 |
| frameSpectral | 0.5 |
| frameHalo | 0.8 |
| perimeterFlow | 0.66 |
| perimeterFocus | 0.72 |
| cornerBloom | 1 |
| innerRim | 0.6 |
| mouseInfluence | 0.52 |
| adaptiveQuality | 1 |
| pixelBudget | 520000 |
| complexity | 0.72 |
| glassAlpha | 0.54 |
| glassBlur | 8 |
| glassSaturation | 112 |
| radius | 26 |
| # | rule |
|---|---|
| 1 | shader は frame の geometry と状態だけを担い、ロゴ・動画・背景映像を持たない |
| 2 | pointer は focus の補助。hover できなくても hierarchy と静的 fallback は成立する |
| 3 | pixel budget と canvas count は自動テストで固定し、DBや本番データに依存させない |
/* frame-only contract */
<MirrorShaderLab />
// rounded SDF / silver core / dark bevel / inner + outer rim
// one canvas, no video, no logo mask, URL hash tuning
// reduced motion or WebGL failure -> the same static framesrc/lib/motion/* (LenisProvider / heroEntrance / sectionEnter) + text-reveal.scss
| 系 | 仕様 |
|---|---|
| Lenis | duration 1.15 / lerp 0.10 / easing 1-(1-t)^3 / touchMultiplier 1.4。/admin・/preview・/login と coarse-pointer・reduced-motion では無効化 |
| GSAP | 必ず dynamic import (メインチャンク外)。ScrollTrigger 不使用 — IO + --scroll-progress 変数で代替 |
| セクション入場 | IO → short opacity/translate。quiet / reduced-motion は最終状態へ直行し、装飾 flash を既定にしない |
| カード stagger | opacity 0 + translateY(32px) scale(.96) → expo.out 0.7s / stagger 0.10 |
| Hero 入場 | buildHeroEntrance (heroEntrance.ts)。spikes:splash-done 起点 / 3s 安全タイムアウトで強制表示 |
| event entrance | glitch は明示的な authored event variant。製品既定は quiet で、表示内容を隠さない |
| 文字リベール | .letter-reveal 760ms / translateY .6em + skewX(display-skew − 6deg) + blur 8px / 1字 38ms |
| LoadingSplash | 静的な progress / fallback を先に成立させる。メディアや shader の読み込みを UX の前提にしない |
/* product motion recipe */
IntersectionObserver (1回)
→ hierarchy が先に表示される
→ short opacity / translate transition
→ quiet / reduced-motion は最終状態へ直行
/* GSAP は必要な画面だけ dynamic import。replay は明示的な操作に限定 */src/components/SpikesLpScreen.tsx + sections/*
| section | 内容 |
|---|---|
| Topbar | ロゴ + ナビ + CTA |
| Hero | 短い結論 + 現在地 + 次の操作。背景メディアは optional、静的 poster と同じ hierarchy を保つ |
| IvsRedBand | ivs-red パレットを data-palette でローカル適用した IVS 帯 |
| Contents (S/01) | 6 コンテンツカード。frame-only surface と短い説明、1カード1主操作 |
| Pass | passTiers.json 駆動のチケットカード (Grid 事故の現場 → PITFALLS #3) |
| SpikesGuild (S/03) | GUILD ロースター + AutoPlate (暗色ロゴ自動白台座) |
| Partner (S/04) | パートナー帯 (Guild から分離) |
| NomadTeaser / Factions / Members / Sponsorship | サブセクション群 |
| Footer | 静かな wordmark + resource links。背景 WebGL ではなく、現在地と次の入口を示す |
| surface | rule |
|---|---|
| event identity | authored content may carry one local accent; it never changes global navigation |
| guild / account | neutral surface + cyan state + one clear next action |
| media | poster and static asset first; no background video or logo mask in the product shell |
/* セクションの正規構造 */
<SectionFrame index="S/01" label="CONTENTS" coord="S/01 — 6 EVENTS">
<SectionHeading index meta="6 EVENTS" label subtitle />
<div className="grid">
<article className="card glass tilt">
<div className="cardHud">{/* mono: NN / 06 + VECTOR */}</div>
<p className="desc body-jp">…</p>
<div className="foot">{/* CTA */}</div>
</article>
</div>
</SectionFrame>文言・構成データは content/*.json が唯一のデータベース。/admin CMS で編集 → 本番では Octokit が main へ commit → Vercel 再ビルド (revalidate 60s)。デザイン改修時も 文言はコードに直書きせず JSON へ。
| file | 駆動する見た目 |
|---|---|
| event.json | Hero 全文言 / ticker / Topbar / CTA。brand.ts 経由で OG の HUD 文字列にも派生 |
| contents.json | 6 コンテンツカード (num/title/desc/linkHref) |
| passTiers.json | チケット tier (general ¥4,980 / referral 無料 featured) |
| spikesGuild.json / spikesPartner.json | GUILD ロースター / パートナー帯 |
| footer.json | フッター設定(静止・軽量な共有フッター) |
| sponsors.json | スポンサー (build gate でロック — 下記禁則参照) |
| philosophy / faqs / news / pitch / stage / square / popup / spikathon / blitz / nomad / factions | 各セクション・サブページの文言 |
SNS ビジュアル・フライヤー・証明書・OG 画像は全て admin 内ジェネレータで内製する文化。 色・ロゴ・HUD 文字列は brand.ts が単一供給源 (CSS 変数は書き出し系に届かないため)。
| 技術 | 役割 |
|---|---|
| Satori | OG 画像 / スポンサースポットライト。CSS 変数不可 → brand.ts が色を静的供給。embedFont:false で実 <text> SVG |
| opentype.js | 文字 → ベクターパス化 (ステッカー / 名刺 / 公休 / partnergenerator PNG) |
| html-to-image | A4 フライヤー raster (1240×1754 → ×2 = 300dpi)。background-clip:text 非対応 → SVG 焼き必須 |
| jspdf | PDF (フロアマップ / タイムテーブル) |
| sharp | サーバー側 SVG → PNG ラスタライズ |
| Vercel Blob | 生成物・アップロードの置き場 (dev は fs フォールバック) |
| 主要ジェネレータ | 出力 |
|---|---|
| /admin/generator ほか SNS 系 | 登壇者・審査員・セッションカード PNG |
| /admin/flyer-generator | A4 フライヤー (1240×1754 ×2 = 300dpi) |
| /admin/pass-visual / countdown-visual | PASS・カウントダウンビジュアル (銀虹 chrome SVG) |
| /partnergenerator / business-card / stickergenerator / kokyu | 公開ゲート付き自己生成系 (opentype.js ベクター) |
| /activity-report | A4 活動/参加証明書 (4S 角印連携・?type= で役割切替) |
| /admin/shader-export | LiquidMetal 高解像度 PNG (ロゴ更新時の static 層再生成) |
src/lib/email/render.ts
メールだけはライトボディ (Gmail/Outlook 互換のため)。ブランドは黒ヘッダー帯 + cyan 3px トップボーダー + chrome ワードマーク + magenta アクセントで担保する。
| token | value | 用途 |
|---|---|---|
| ink | #050507 | ヘッダー帯背景 |
| paper / card | #f6f6f4 / #ffffff | ページ背景 / 本文カード |
| text / sub | #1c1c20 / #6b6b74 | 本文 / フッター |
| chrome | #ECEEF1 | SPIKES ワードマーク (900 / ls .14em) |
| cyan | #00E5FF | ヘッダー上 3px ボーダー |
| magenta | #FF1A6B | // IVS2026 アクセント |
| ルール | 内容 |
|---|---|
| レイアウト | 600px table + inline style のみ (メールクライアント互換) |
| フォント | 'Hiragino Sans','Yu Gothic',Meiryo,Arial (Web フォント不使用) |
| 必須要素 | 配信理由の明記 + 解除リンク + List-Unsubscribe ヘッダ (法令) |
| 変数 | {{name}} 等は HTML エスケープ補間。text/plain パート自動生成 |
git 遍歴 (~700 commits) から採掘した意思決定。「禁止」= 違反したら差し戻し対象。 「確定」= 完成形としてロック済み、依頼なく触らない。出典 commit を併記。
Reggae One は恒久禁止
axes.ts から削除・SCSS ルール削除・FontLoader から除外済み。法務ページ事故が発端。復活させない (commit 2fd40b6 / a3c53db)
JP フォントは Noto Sans JP に統一
jpDisplayFont / jpBody とも noto-sans-jp 固定 (要望による決定)
スポンサー表記は build gate でロック
scripts/check-sponsors.mjs が prebuild で検査し、platinum = [RECRUIT, デロイト トーマツ] 以外は build 失敗。変更は sponsors.json と EXPECT の同一 PR 更新のみ (commit ae1bd0a)
脱 blue / 脱オレンジ
STAGE・admin では electric cyan #00E5FF の面 / オレンジの色被せを避け、chrome/steel + glassmorphism に寄せる (9ed91d8 / 10f4242)
定常状態に色を付けない
カラーは出現の一瞬 (glitch) だけ。idle は無彩色 (SESSION_HANDOFF 触らない方針)
Footer は入口を優先
SPIKE YOURSELF は静的 wordmark。CTA と resource links の行先・現在地・次の操作を先に確認する
LoadingSplash は静的 fallback 先行
progress と静的 surface を先に成立させ、物理エフェクトや media を UX の前提にしない
TacticalButton は quiet が既定
solid neutral / pill / 44px minimum / cyan focus ring。chamfer と HUD bracket は明示的な event variant のみ
Contents 6 ロゴの色は固定
BLITZ=crimson / PITCH=amber / SPIKATHON=violet / SQUARE=electric / STAGE・POPUP=blade
catchcopy の hover-wave は意図的に無効
.letters-hover:not(:hover) の animation:none 削除で opacity:0 スタック事故 → 再導入しない
| # | 落とし穴 |
|---|---|
| 1 | yarn dev 起動中に yarn build を打たない (.next 破壊 → 500)。ローカル検証は typecheck か build:local |
| 2 | *.module.scss に :root / :root[data-*] を書かない (pure selector 違反)。グローバル変数は src/styles/*.scss へ |
| 3 | CSS Grid/Flex 親に装飾子要素を置くときは grid cell を明示 (装飾 span がセルを占有しチケットレイアウトが崩壊した事故) |
| 4 | next/image の width/height は実画像のアスペクト比と一致させる (badge.png は 1480×448) |
| 5 | SVG を next/image に通すなら dangerouslyAllowSVG (自アセット限定) |
| 6 | WebGL ~16 上限 → 3層戦略 (live/frozen/static) を必ず守る |
| 7 | axes.ts に軸・値を足したら STORAGE_KEY をバンプ (現在 v33)。忘れると古い localStorage が新デフォルトを潰す |
| 8 | absolute HUD 装飾は stacking context に注意 (装飾は JSX 先頭 = 背面、コンテンツに position:relative; z-index:1) |
| 9 | Tweak panel は localStorage のみ。見た目を確定共有するには COPY JSON → DEFAULT_TWEAK / PRESETS へ貼る |
サイトの見た目がリポジトリの外に依存している箇所。次回イベントの再構築で 最初に洗い出すべきリスト。
External motion / WebGL
product surface では依存しない。event export または明示的な authored route だけで使用し、静的 fallback を必ず残す
Google Fonts / Fontshare
FontLoader が hydrate 後に JS 注入。本番の既定表示は Switzer / Inter / JetBrains Mono。event registry は Tweak 有効時のみロード
Noto Sans JP
@fontsource-variable/noto-sans-jp でセルフホスト (Google CSS は意図的に不使用)
Vercel Blob
生成画像・アップロード置き場 (BLOB_READ_WRITE_TOKEN)
GitHub CMS
admin 保存 → Octokit が content/*.json を main に commit → Vercel 再ビルド (revalidate 60s)
Authored media / static poster
必要なキャンペーン面だけに限定。product surface は静的 surface を先に成立させ、映像・WebGL を前提にしない
次回イベント (VOL.02) をこのフォーマットで立ち上げる手順。上から順に実行すれば デザインシステムを保ったまま新イベントサイトになる。
content/*.json のイベント文言 (heroDisplayEn / 日付 / 会場 / VOL) を更新
brand.ts eventHudStrings() が VOL / 日付 / KYOTO を自動導出
brand.ts を更新: BRAND_LOGOS / BRAND_COLORS / PALETTE_ACCENTS
OG・ジェネレータ・Satori 系の色はすべてここから。product default は monochrome + cyan
axes.ts の DEFAULT_TWEAK を新イベントの見た目に設定し STORAGE_KEY をバンプ
探索は Tweak panel、確定値は DEFAULT_TWEAK / PRESETS に戻して URL 共有可能にする
必要な静的アセット (symbol/logo/favicon/poster) の実寸と代替表示を確認
表示は 1 つの目的に絞り、ロゴ shader・映像・外部 WebGL は product surface の前提にしない
sitemap / primary / related links / Footer / CTA の行き先を更新
各公開ページに次の操作を 1 つ、関連入口を過不足なく配置。外部 URL は安全属性を付ける
content/*.json を新イベント内容に書き換え (contents / passTiers / faqs / sponsors...)
sponsors 変更時は check-sponsors.mjs の EXPECT も同一 PR で更新
OG カバーを新調し metadata / social preview を確認
layout.tsx metadata と静的 fallback の内容を一致させる
確認: typecheck → test → build:local → link / layout / a11y → 代表画面スクショ
44px 操作領域、キーボード、320px、200% 拡大、reduced motion、認証状態を確認してから公開する
Framer 移植から現在までのデザイン変遷。★ = アーキテクチャ的転換点。 「なぜ今この形なのか」の背景として読む。
:root スコープの design 軸 (hierarchy / buttonShape / surface pattern / palette) を product-safe な範囲でその場切替する試着室。保存されない (リロードで復元)。本採用の手順は K/02 の Tweak 運用ルールに従うこと。
CONTENTS
↑ hierarchy first / one accent / static fallback
OBSERVE BUTTON SHAPEsignal color (data-section-title-color)
sectionHeadingFont (data-section-heading-font)
buttonShape (data-button-shape)
chromatic (data-chromatic)
chromaticAnim (data-chromatic-anim)
bgPattern (data-bg-pattern)
surface palette (data-palette)