ASIA / TOKYO00:00:00
ZFILMS©
LOADING000%
ZFILMS©
ASIA/TOKYO00:00:00
SPIKES

{ IVS / SPIKES }

Web · 2026

View live ↗

SPIKES

学生ピッチ祭典の LP。80 軸の Tweak デザインシステム (enum 37 + slider 43) と LiquidMetal シェーダーで世界観を量産しつつ、Notion(認定団体マスタ) × Google Sheet(招待数) × 4S API(live 子孫数) を entryId で突合し、4S が落ちたら Sheet 値へ degrade する GUILD 運営基盤も自前実装。

Services
Design / WebGL / Frontend
Client
IVS / SPIKES
Production
ZFILMS × 4S
Year
2026
COMMITS882
LINES+279,800
TWEAK 軸80
シェーダー面16
WebGL 実行8
認定団体ロゴ44

裏側の仕組み — 量産デザインシステム

SPIKES の見た目は「作り込み」ではなく「量産」で立っている。1 つの軸定義から全要素の見た目が生成され、テーマを差し替えるだけで別世界観のヒーローが生まれる。その中枢を実物シェーダーとモーショングラフィックスで見せる。

実装の現物 — LiquidMetal ロゴシェーダー (本番の render path そのもの)

// MOTION 近似ではない。本番 spikes.4s.link と同じ計算経路を通している — VARIANT_BASE (variant の人格) → computeLiquidMetalProps(variant, mods, slider) → <LiquidMetal> → computeCanvasFilter の CSS filter → computeRimCssVars + drop-shadow 5 段。流しているのは各サブブランド hero の実ペア (SQUARE/electric・BLITZ/coral・PITCH/amber・SPIKATHON/violet・POPUP/toxic・STAGE/blade・GUILD/mercury) で、1 つのシェーダーエンジンから 7 つの hero が立つのが量産の実像。読み出しは VARIANT_BASE と slider 上書き後の実効値を 2 列で並べており、softness / repetition / angle は Tweak の slider が variant を上書きしている (= 単一の軸定義が全描画を支配する) ことがそのまま読める。GUILD は frozen tier なので 1.5 秒回した後 canvas.toDataURL でスナップショットを撮り、WebGL context を解放して静止画に差し替わる。@harvested-from spikes-lp logoShaderVariants.ts / LiquidMetalCanvas.tsx / LogoShaderPaper.tsx / useShaderFreeze.ts

実装の現物 — Tweak デザインシステム (80 軸 → 6 プリセット・触れる)

// MOTION 軸は実測 80 本 (enum 37 + slider 43 = shader 17 / motion 5 / glitch 18 / sectionTitle 3)。プリセットは noir / platinum / blade / dune / oilslick / solar の実 6 種で、切り替わるたびに palette・displayFont・displaySkew・displayStretch・shaderRim・bgPattern・cursor・kinetic が実値で総入れ替えになる (palette トークンは palettes.scss の実 6 種、bgPattern は patterns.scss の実 CSS)。入場は sectionEnter.ts の実 glitch timeline — blue #3A78FF × orange #FF7A1A の chromatic split / blur 7px / brightness 1.35 で、全て glitch* 軸の実 default 値。slider はプリセットと独立していて、sectionTitleGlow (0-3 / step 0.05) を動かすと見出しの halo だけが変わる。プリセットのチップはクリックで適用できる。@harvested-from spikes-lp axes.ts / palettes.scss / patterns.scss / sectionEnter.ts

実装の現物 — GUILD 三源突合 + degradation ladder (実関数を実行)

// MOTION Google フォームは存在しない。実体は Notion(認定団体マスタ → cron /api/cron/sync-orgs → Neon guild_org ミラー) × Google Sheet CSV(招待数) × 4S API referral-descendants(live 子孫数) の 3 源で、突合キーは団体名ではなく referralUrl から抽出した entryId。4S live が Sheet 値を上書きし、ログイン失敗なら source=sheet へ degrade、取り切れなければ truncated で「概算」表示。人物の名寄せは氏名ハッシュ一致 + 入部年 ±1 が一意のときだけ再利用し、別 org (個情法27条) と crypto-shred 済は判定前に落ちる。auto (score 950) でも自動統合はせず必ず人間承認を通す。tierOf / perksFor / parseInvites / scopeToOrg / pickReusablePerson / candidateBand は実装を verbatim 移植したもので、画面に出ている値・tier・スコアは全部この関数群の出力 (招待数と人物のみ SAMPLE 入力)。@harvested-from spikes-lp guildReferrals.ts / notionGuilds.ts / uniguild/matching.ts

本番サイト — 実ページを触る・覗く

メイン LP だけ live で埋め込み、同じシステムから量産されたサブブランド LP や運営基盤はスクショと要点で紹介する(カードにマウスを重ねると中身が展開/自動スクロールする)。

メイン LP (実ページ live)OPEN ↗

// LIVE Hero は WebGL ではなく hero.mp4 (595KB / mobile 213KB)。LiquidMetal シェーダーは各サブブランド hero (/square /blitz /stage /spikathon …) 側にあり、メイン LP は Contents 6 面 static + GUILD live 1 + Footer 2 static で WebGL コンテキストは実質 1 個。「16 面を回す」のではなく「回さずに済ませる」設計。クリックで操作モードに入り本番そのまま触れる。

同一システムから量産された各ページ (スクショ + 中身)

spikes.4s.link/guild
GUILD — 審査制リファラル制度▲▼ auto-scroll
GUILD — 審査制リファラル制度OPEN LIVE ↗

認定学生団体 44 組を招待数ランキングで公開。招待数は Google Sheet の値を 4S API の live 子孫数で上書きし、20 / 10 / 5 名で PLATINUM / GOLD / SILVER に分類。5 名で団体ロゴ掲載、10 名で GUILD グランプリ登壇、20 名で POP UP 出展権が解放される。

spikes.4s.link/habatsu
HABATSU — 派閥▲▼ auto-scroll
HABATSU — 派閥OPEN LIVE ↗

4S.link の URL を貼り 11 派閥から所属を選ぶと、X / Instagram にそのまま貼れる 1080×1350 の参加表明プロフィール画像を発行するジェネレータ。

spikes.4s.link/map
MAP — 会場マップ▲▼ auto-scroll
MAP — 会場マップOPEN LIVE ↗

IVS2026 会場内 SPIKES エリア (全長約 30m × 幅約 18m・7 ゾーン) の見取り図。メインステージ・SQUARE ラウンジ・POPUP ×22・BLITZ お立ち台・スポンサー卓の位置関係を 1 枚で示す。

spikes.4s.link/staff
STAFF — 運営クレジット▲▼ auto-scroll
STAFF — 運営クレジットOPEN LIVE ↗

代表・東西統括・マーケ・コンテンツ・プランナーの運営コアメンバーを顔写真 + 大学・役職バッジで掲載。東京-京都-関西を行き来して 2,000 名規模の祭典を組み立てるチームの実名クレジット。

spikes.4s.link/nomad
NOMAD — 宿泊マッチング▲▼ auto-scroll
NOMAD — 宿泊マッチングOPEN LIVE ↗

IVS 京都の 3 日間を「宿」ではなく「仲間の家」で過ごす SPIKES SIDE PROJECT。京都の大学生 50 家を解放し、関東圏から来る 200 名に泊まる場所をマッチングする。

spikes.4s.link/news
NEWS — お知らせ▲▼ auto-scroll
NEWS — お知らせOPEN LIVE ↗

募集締切・イベント告知・プレス掲載を流す自前 CMS のお知らせ一覧。content/news.json を真実源に、/admin から編集 → GitHub commit → 自動再ビルドで反映される。

実演 — 固有機能をそのまま動かす

// LIVE DEMO — 実挙動の再現

shader 面 16 / WebGL を持つのは 8 — 回さずに済ませる 3-tier

面は 16 (サブブランド hero 8 + Contents 6 + Footer 2) だが、WebGL context を実際に持つのは 8 だけ。static は chrome 加工済 webp で WebGL 0 個、frozen は warmup 1500ms → canvas.toDataURL → LiquidMetal を unmount して context を解放する (preserveDrawingBuffer なしでは真っ黒が返る)。preload queue は同時 3 本。hero は別ルートなので、埋め込んだメイン LP は実質 1 コンテキストで走る。

// LIVE DEMO — 実挙動の再現

派閥ルーター — suggestFactionKey()

4S プロフィール (title / bio / skillTags / 現所属) を 1 本の haystack に畳み、needle リストで 11 派閥に仕分ける実 rule engine。finance を founders より先に評価するので「VC にいて起業もしたい」が founders へ誤って倒れない。画面に出る判定結果は実関数の戻り値そのもの。

// LIVE DEMO — 実挙動の再現

統合名鑑 DB (サンプル再演)

Notion(認定団体) / Google Sheet(招待数) / 4S(live) から流入した参加者を 1 枚の名鑑に統合する /admin 画面。団体名の表記ゆれは辞書ではなく normalizeOrgName() (NFKC → 法人格語を前後から剥がす → 記号除去 → lowercase) が吸収する。実物はログイン関門の奥のため仮名サンプルで再演し、tier と特典は実装定数をそのまま出す。

WHAT'S INSIDE

01

Tweak デザインシステム 80 軸

enum 37 + slider 43 を単一真実源で型定義。buildTweakAttrs() が <html data-*> + CSS 変数へ純関数展開し、SSR で FOUC ゼロ。プリセットは noir / platinum / blade / dune / oilslick / solar の 6 種。

02

GUILD 三源突合 + degradation ladder

Notion(cron → Neon ミラー) × Google Sheet CSV × 4S API を entryId で突合。4S が落ちたら Sheet 値へ degrade し、取り切れなければ「概算」と明示する。落ちないランキング。

03

サブブランド / 機能ページ × 13

BLITZ / STAGE / SQUARE / POPUP / GUILD / NOMAD / HABATSU / STAFF / NEWS / MAP / 公休ジェネレーター…。1 つのデザインシステムから世界観別ヒーローを量産する。

04

3-tier シェーダー予算管理

live / frozen (1.5s → snapshot → context 解放) / static (WebGL 0) の 3 段と concurrency 3 の preload queue で、16 面の shader を context 上限に触れずに配る。

05

個人情報の法令準拠実装

pii_vault / crypto-shred / tombstone / 個情法27条の org 隔離 (scopeToOrg) を自前実装。名寄せは auto (score 950) でも自動統合せず人間承認を通し、不変条件は vitest で固定する。

06

運営基盤の自前実装

申請・突合・承認・追跡まで運営の裏側を丸ごと内製。正本は Neon(Postgres) の統合名鑑 DB、表記ゆれは normalizeOrgName() で正規化し、統合は承認 UI で目視確定する。

Next projectXDEALIVS / XDEAL · 2026