WELCOME TO BACKSTAGE

このサイトは、皆さんが普段使っている「DX公開カレンダー(Google Calendar)」と同じ感覚で使えるように設計されました。
目標: カレンダーの「見やすさ」× 教材への「即アクセス」
「スケジュール確認」と「学習」を1つの画面で完結させることで、皆さんの学習ハードルを極限まで下げることを目指しています。
Mode Apply!
ENGINEERING LOG

UI ARCHITECTURE

UX設計と技術的意図の解説

1. Visual Hierarchy

Concept (Lv1): 色のルールを決める

「紫色は、押せる合図」

信号機が「青なら進め」であるように、このサイトでも「紫色のグラデーションなら押せるボタン」というルールを徹底しています。

あちこちにいろんな色を使うのではなく、大事な場所だけ色をそろえることで、 初めて使う人でも「次はここを押せばいいんだな」と迷わず操作できるようになります。

Code (Lv2): CSS Variables & Gradient
:root { --accent: #5c6bc0; } .shortcut-btn { background: linear-gradient(135deg, #5c6bc0, #3949ab); }
Strategy (Lv3): Brand Consistency

一貫性が生む信頼性(Trust)

色彩設計において最も避けるべきは「意味のない色の多用」です。 コンバージョン(クリック)を狙う箇所において、HUE(色相)を統一しつつ、Gradient(グラデーション)でリッチさを演出することは、 「洗練されたツールである」という信頼感をユーザーに与えます。

安っぽいツールだと思われて使われないリスクを、UIの質で低減させています。

2. Context Awareness

Concept (Lv1): 「今、どこ?」を教える

デジタル版の「You Are Here(現在地)」マップ

カレンダーを見た瞬間、「で、今日はどこだっけ?」と探す時間はわずか数秒ですが、毎日続くとストレスになります。
そこで、今日の日付のマスだけ「赤枠とTODAYバッジ」で自動的に強調するようにしました。

ページを開いた瞬間に「あ、今日はここからだな」と脳が即座に理解できるので、迷いなく学習をスタートできます。

Code (Lv2): Date Object & DOM Logic
const highlightToday = () => { // Get System Date const today = new Date(); // Strict constraints for this specific training period if (today.getFullYear() !== 2026) return; // Logic to find the correct cell DOM element const target = findCell(today.getMonth(), today.getDate()); // Apply CSS class if (target) target.classList.add('is-today'); };

端末の時計(System Date)を取得し、研修期間(2026年2月〜3月上旬)に該当する場合のみ動作します。
JSで動的にクラス .is-today を付与し、CSSのアニメーション(@keyframes bounce-badge)で視線を集める演出を行っています。

Strategy (Lv3): Just-in-Time Information

時間的迷子の防止 (Temporal Disorientation)

ユーザーは常に「自分のコンテキスト(今の状況)」と「コンテンツ」を照らし合わせる作業を行っています。
システム側から能動的に「今はここです(Today)」と提示する(Just-in-Time)ことで、 ユーザーがカレンダーをスキャンして現在地を特定する認知コストを「ゼロ」にしています。

これも「学習を開始するまでの摩擦(Friction)」を極限まで減らすためのUX戦略の一つです。

3. Cognitive Load Reduction

Text Only: 02/03 VS Badge UI:
FEB03
Concept (Lv1): パッと見てわかる工夫

「文字」は読まないといけないけれど、「図形」は見るだけでわかります。

たくさんのリストが並んでいると、ズラリと並んだ文字に圧倒されてしまいます。
そこで、日付をカラフルな「四角い箱」に入れてあげることで、これを「読む文字」から「見るしるし」に変えました。

「あ、ここが日付だな」と直感的にわかるので、脳ミソに余計な負担をかけずに済みます。

Code (Lv2): Flexbox Layout
.date-box { display: flex; flex-direction: column; align-items: center; background: #7986cb; border-radius: 12px; }

単純な `padding` ではなく、親要素に `display: flex` と `flex-direction: column` を指定し、 月(FEB)と日付(03)を垂直・水平方向に完全中央配置(Centering)しています。

Strategy (Lv3): Scannability & ROI

スキャナビリティの向上による離脱防止

ユーザーが大量のリスト情報に直面した際、求める情報(日付)が即座に見つからないと「探すコスト」が増大し、ストレス(Cognitive Load)となります。

Badge UIの実装工数は微々たるものですが、リスト全体の視認性を劇的に向上させ、ユーザーが「必要な講義を見つけやすくする」という体験価値に直結します。
「小さな装飾に見えるが、実はナビゲーション機能の一部」として機能させています。

Vol.1 Day 2: Algorithm & Canva

動画埋め込みとレスポンシブ対応

4. Responsive Embeds

Concept (Lv1): どこでも綺麗に見せる

「はみ出さない」という当たり前の難しさ

YouTubeなどの動画をページに貼るとき、そのまま貼るとスマホの画面からはみ出したり、縦横比がおかしくて黒い帯が出たりします。
このページでは、PCで見てもスマホで見ても、常に「16:9」の美しい比率を保ったまま、画面幅いっぱいに広がるように計算されています。

Code (Lv2): Aspect-Ratio Property
iframe { width: 100%; height: auto; aspect-ratio: 16 / 9; } /* 昔は padding-top: 56.25% とかやってましたね... */

Vol.1 Day 3: Planning

カードレイアウトと視線誘導

5. Flexbox Layout

Concept (Lv1): カードを並べる技術

情報を「塊(かたまり)」にする

企画のステップなどを箇条書きにするのではなく、「カード」として枠で囲むことで、ユーザーは「これは1つのまとまった情報だ」と直感します。
さらに、それらが横並びになったり縦並びになったり、画面に合わせて柔軟に動く仕組みを取り入れています。

Code (Lv2): Flex & Gap
.card-container { display: flex; flex-wrap: wrap; gap: 20px; }

Vol.1 Day 4: Shooting

自動採番とステップ表示

6. CSS Counters

Concept (Lv1): 番号は「手で書かない」

ステップ入力のストレスをゼロに

「1. 構図を決める」「2. カメラを構える」...と手書きで数字を打っていると、途中で手順を入れ替えたくなった時に全ての番号を書き直さないといけません。

プロの現場では、「順番はPCが勝手に数える」ように作ります。
こうすることで、手順が増えても減っても、常に正しい番号が自動で振られるようになります。

Code (Lv2): counter-increment
ol { counter-reset: my-step; } li::before { counter-increment: my-step; content: counter(my-step); }
Strategy (Lv3): Maintainability

運用保守性の向上 (Maintainability)

コンテンツは「生き物」です。教材の内容は改善され、手順は入れ替わります。
HTML内にハードコードされた数字(Static)は、修正漏れや不整合(Inconsistency)の原因になります。
「構造(HTML)」から「装飾・順序(CSS)」を分離することは、長期的なコンテンツ運用のコストを下げるための重要なエンジニアリング戦略です。

7. State Management (Viewfinder)

Concept (Lv1): モード切替の仕組み

「スイッチ」の状態を管理する

カメラの「グリッド表示」や「照明オンオフ」は、それぞれ「ON/OFF」という2つの状態を持っています。
プログラムの世界では、これを「フラグ(Flag)」と呼びます。「旗が上がっているか、下がっているか」で画面の見た目を切り替えているのです。

Code (Lv2): Class Toggling
function toggleGrid() { // 現在の状態を取得して反転させる const screen = document.querySelector('.camera-screen'); screen.classList.toggle('grid-active'); }

classList.toggle() は、クラスがあれば消し、なければ足すという便利な命令です。
「もしONならOFFにする、そうでなければONにする」というif文を書かなくても、これ1行でスイッチ機能が作れます。

4. Dual-View Synchronization

Concept (Lv1): いつものカレンダー機能

「あのGoogleカレンダーと同じ見た目にしておきました!」

皆さんが普段、研修スケジュールを確認している「DX公開カレンダー」がありますよね? このサイトのカレンダーは、あえてそれとそっくりな形に作ってあります。

「今日は祝日だから休みだな」とか「月末は4日間連続だな」といった、見慣れた感覚のまま使えるので、 新しいツールの使い方を覚える必要がありません。しかも、このサイトならそのまま教材も開けるので一石二鳥です!

Code (Lv2): O(1) Mapping Logic
const toggleHighlight = (id) => { // ID selector is O(1) - Fast! const cell = document.getElementById(id); cell.classList.toggle('active'); };
Strategy (Lv3): Mental Model & One-Stop

メンタルモデルの流用とスイッチングコストの削減

ユーザーは既に「Googleカレンダー(DX公開カレンダー)」で研修日程を把握する習慣(メンタルモデル)を持っています。
全く新しいUIを押し付けるのではなく、「既存の習慣(カレンダーのグリッド感)を模倣しつつ、機能を拡張(教材へのリンク等の埋め込み)」することで、 学習コストをゼロに近づけています。

All-in-One Value:
「予定確認はGoogleカレンダー、学習はポータル」とツールを行き来する(Context Switch)のは無駄なコストです。 このポータル一つで「予定確認」と「学習開始」を完結させることで、日々の学習開始のハードルを極限まで下げています。

5. Accessibility

Concept (Lv1): 邪魔しないボタン

「制作の裏側・デザインの意図」ボタンは、他のどの文字の上にも被らないように、そっとカードの右下に配置されています。
いつでも押せる存在感はありつつ、メインの学習の邪魔だけは決してしない。そんな「気配りの配置」です。

Code (Lv2): Absolute Positioning
.list-area { position: relative; /* Parent Anchor */ } .dev-link { position: absolute; bottom: 30px; right: 30px; z-index: 100; }

position: fixed(画面全体に対する固定)ではなく、position: absolute(親要素に対する絶対配置)を使用しています。
これにより、ウィンドウサイズが変わっても「白いカードの外」にボタンが飛び出したり、意図しない場所に重なったりするのを防いでいます。

Strategy (Lv3): Fitts's Law

Absolute配置によるコンテナ拘束

画面全体へのFixed配置は、多様なデバイスサイズにおいてコンテンツ干渉のリスクが高い実装です。
「カードコンテナ内でのAbsolute配置」に変更することで、レスポンシブ崩れを論理的に防ぎつつ、 ユーザーの視線移動(F-Patternの終点)に合わせた自然な導線設計としています。

6. Zero Maintenance Logic

Concept (Lv1): 「ボット」に任せる

「最新のテキストどこだっけ?」をなくす

トップページにある「LATEST: Vol.XX テキストを開く」という大きな青いボタン。
実はこれ、人間が毎日書き換えているわけではありません。

サイトを開いた瞬間に、プログラムが「今公開されている一番新しい教材はどれかな?」と一瞬でリストをチェックし、 勝手にボタンの飛び先と名前(Vol.2など)を書き換えています。
運営側が更新を忘れても、ボタンは常に最新。これが「エンジニアの怠惰(良い意味での)」です。

Code (Lv2): DOM Traversal
const updateLatestButton = () => { // Find all 'active' links const published = document.querySelectorAll('.curriculum-list a.c-item'); if (published.length > 0) { // Get the last one (Latest) const latest = published[published.length - 1]; // Update Button DOM const btn = document.querySelector('.shortcut-btn'); btn.href = latest.href; btn.innerHTML = `LATEST: ${latest.title}`; } };

.curriculum-list 内にある a タグ(公開済みアイテム)だけを全て取得し、 その配列の末尾(length - 1)にある要素を「最新」と特定しています。
あとはそのリンク先情報をボタンにコピーするだけ。O(n)のシンプルなロジックです。

Strategy (Lv3): Operational Excellence

ヒューマンエラーの徹底排除

「教材を追加したのに、トップページのリンクを張り忘れた」というミスは、運用フェーズで頻発します。
システム側で「公開状態のみを検知して自動追従」させることで、運用コストをゼロにし、リンク切れのリスクを根絶しています。

「人間はミスをする。だからシステムがカバーする」という、堅牢な運用設計の一例です。

Vol.1 Day 5: Editing

重ね順と配置の魔術

9. z-index & Stacking Contexts

Concept (Lv1): ポスターの重ね順

「上にあるか、下にあるか」

Webサイトの画面は平らに見えますが、実は「奥行き」があります。
壁にポスターを貼るとき、新しいポスターを上に貼ると、下のポスターは隠れますよね。
「はめ込み合成」で動画の上に動画を乗せるのと同じで、Webでも「箱の上に箱を重ねる」ことができます。

Code (Lv2): z-index & position
.overlay-item { position: absolute; top: 10px; z-index: 100; }

position: absolute (絶対配置) で場所を指定し、z-index (Z軸のインデックス) で「高さ」を指定します。
数字が大きいほど「手前(上)」に来ます。z-index: 9999 とかやりがちですが、管理できなくなるのでやめましょう。

Strategy (Lv3): Attention Management

視線誘導とモーダル設計

「見てほしいもの」を物理的に(Z軸的に)一番手前に置くことで、ユーザーの意識を強制的にそこに集中させます。
モーダルウィンドウや、追従するFABボタン(Action Button)などがこれに当たります。
多用しすぎると「鬱陶しいポップアップ」になるので、ここぞという時だけ使う「切り札」です。

Vol.1 Day 6: Sound

目に見えない「音」を可視化する

10. CSS Keyframes & Animation

Concept (Lv1): パラパラ漫画の原理

「0%から100%までの物語を書く」

アニメーションとは、静止画の連続です。Webでも「0%の状態」と「100%の状態」を決めて、 その間を自動補完(Tween)させることで動きを作ります。
今回の「動く波形(オーディオスペクトラム)」も、ただの縦棒を「伸びたり縮んだり」させているだけです。

Code (Lv2): Keyframes & Delay
@keyframes bounce-bar { 0%, 100% { height: 10%; } 50% { height: 100%; } } .bar:nth-child(1) { animation-delay: 0.0s; } .bar:nth-child(2) { animation-delay: 0.1s; }

同じアニメーション(伸び縮み)を適用した複数の棒に対し、animation-delay で開始時間を0.1秒ずつずらすことで、全体として「波打っている」ような有機的な動きを表現しています。
GPUアクセラレーションが効くプロパティ(transform, opacity)を使うのが定石ですが、今回は簡易的にheightを使っています。

Strategy (Lv3): Micro-interactions

「生きている」と感じさせる演出

人間は「動くもの」に本能的に視線を奪われます。
静的なページの中に1つだけ動く要素(マイクロインタラクション)を入れることで、 「このページは現在進行形で動いている(ライブ感)」という錯覚を与え、ユーザーの滞在時間を延ばす効果があります。
今回の「音」のテーマに合わせ、視覚でも音を感じさせるUXで没入感を高めています。

7. Debug Stories: エンジニアの「やらかし」図鑑

「見えているのに、動かない?」
プログラミングの世界には、人間の目には同じに見えても、ブラウザにとっては「別世界」という落とし穴がたくさんあります。
ここでは、実際にこのサイト開発中に発生した「恥ずかしい失敗(バグ)」を供養しながら、Webの仕組みを学びましょう。
FAILURE #01 「透明な壁」事件 (The Invisible Wall)

🚨 事件発生

「Day 3のページを作ったのに、トップページのLATESTボタンが古い(Day 2)まま更新されない!クリックしても開かない!」という不具合が発生。

🕵️‍♂️ 原因:divタグとaタグの違い

デザイン上は全く同じ「四角いお弁当箱」に見えますが、プログラム的には「ただの箱(div)」で作ってしまっていました。

[❌ Mistake] ただの箱。クリックしても何も起きない。
<div class="item">DAY 03</div>

[⭕ Correct] リンク(Anchor)。場所へ飛ぶ機能がある。
<a href="day3.html" class="item">DAY 03</a>

【教訓】
ブラウザは見た目(CSS)ではなく、タグの意味(HTML)で判断します。
「自動更新ロボット」くんは、<a>タグ(リンク)しか探さないように命令されていたため、 <div>で作られたDay 3を「中身のないただの飾り」だと思って無視していたのです。

FAILURE #02 「言葉が通じない」事件 (The Dialect Mismatch)

🚨 事件発生

「Day 3のクイズが表示されず、Loading...のまま固まる」という不具合が発生。
プログラムはエラーを吐かずにただ沈黙するという、一番困るパターンです。

🕵️‍♂️ 原因:辞書型(Object) vs 配列(Array)

クイズプログラムは「Aは〜、Bは〜」という名前付きリスト(辞書型/Object)を期待して待っていたのに、 私が渡したのは「[0番目, 1番目...]」というただの順番リスト(配列/Array)でした。

[❌ Mistake] Array(配列)
options: ["回答A", "回答B"...]
(プログラム:「えっ、"A"という名前のデータがないぞ?読めない…プツン」)

[⭕ Correct] Object(オブジェクト)
options: { A: "回答A", B: "回答B"... }
(プログラム:「"A"のデータはこれだね!OK!」)

【教訓】
人間なら「まあ、上からA,B,Cのことだな」と空気を読んでくれますが、プログラムは「言われた形式(型)」と1ミリでも違うと会話を拒否します。
データの「型(Type)」を合わせることは、プログラムと会話するための最低限の礼儀なのです。

FAILURE #03 「影分身の術」事件 (The Shadow Clone)

🚨 事件発生

ある日、カレンダーを見たら「今日(TODAY)」が2つ存在していました(2/17と2/18)。
まるで忍者の分身の術のように、昨日も今日も「私が今日です!」と主張していたのです。

🕵️‍♂️ 原因:HTMLへの直書き(Hardcoding)

昨日(2/17)の実装時に、見た目を確認しやすくするためにHTMLに直接 is-today クラスを書き込んでいました。
しかし、日付が変わって2/18になったとき、JSは正しく2/18に is-today を付与しましたが、 HTMLに書かれた2/17のクラスもそのまま残っていたため、「W(ダブル)今日」状態になりました。

[❌ Mistake] HTML (Static)
<div class="cal-cell is-today">...</div>
(ずっと「今日」のまま残ってしまう)

[⭕ Correct] JS (Dynamic)
todayCell.classList.add('is-today');
(その日だけ「今日」になる)

【教訓】
「今日」や「ログイン中」のような動的な状態(Dynamic State)は、絶対にHTMLに焼き付けてはいけません。
常にJSのロジックで判定し、付与するようにしましょう。
"Dynamic states should never be hardcoded."

11. The Hidden Map (Meta Tags)

Concept (Lv1): 中身を知らせる「名札」

「Google検索」や「SNSシェア」のための看板

本棚に本が並んでいるとき、背表紙にタイトルがないと誰も手に取ってくれません。
Webサイトも同じで、中身を見なくても「これは何についてのページか」がわかるように、 「メタタグ」という名札(背表紙)をつけてあげる必要があります。

これをサボると、せっかく良いページを作っても、検索結果でスルーされてしまいます。

Code (Lv2): SEO & OGP Setup
<!-- Basic SEO --> <meta name="description" content="TikTokマーケティング基礎講座。VREWを使った動画生成フローを解説。"> <!-- OGP (SNS Card) --> <meta property="og:title" content="Vol.1 Day 7: The Hidden Map"> <meta property="og:image" content="https://example.com/thumbnail_day7.jpg"> <meta property="og:type" content="article">

description はGoogleの検索結果の下に出る説明文。
og:image はLINEやX(Twitter)でURLを貼った時に出る画像(サムネイル)です。
この2つを設定するだけで、クリック率(CTR)が劇的に変わります。

Strategy (Lv3): Copywriting for Click-Through

検索順位よりも「選ばれる」こと

SEO(検索エンジンの最適化)というと「順位を上げること」ばかり注目されますが、 1位になってもクリックされなければ意味がありません。

メタタグ(Description)に書く文章は、「ユーザーへのラブレター(広告コピー)」です。
"Vol.7のページです" とだけ書くより、
"【魔法の地図】動画が埋もれない!プロが教える最強ハッシュタグ戦略とは?"
と書いた方が、人間はクリックしたくなります。これが技術とマーケティングの融合です。

12. The Immersive Engine (Dynamic UX)

Concept (Lv1): 「電子書籍」から「体験」へ

静的なページは、ただの「壁」です。

これまでのページは、情報がそこに「置いてあるだけ」でした。
今回のアップデートで、スクロールに合わせて文章がフワッと浮き上がったり、 重要な箇所にマーカーが引かれたりする「没入エンジン」を搭載しました。
これにより、ユーザーは「読まされている」のではなく「体験している」感覚になります。

Text
Before (Static)
Text ✨
After (Dynamic)
Code (Lv2): JS Injection & Observer
// main.js (Global Injection)
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('active');
    }
  });
});

各HTMLファイルを1つずつ編集するのは大変です。
そこで、共通の main.js からCSSを動的に注入(Inject)し、 ページ内の全ての h2p タグに自動でアニメーションクラスを付与する 「全自動エンハンス」の仕組みを構築しました。

13. Event Listeners (Interactive)

Concept (Lv1): 「聞き耳」を立てる

Webサイトは、あなたの合図を待っています。

TikTokの「デュエット」が相手の動画に反応するように、Webページのボタンも ユーザーが「クリック」したり「マウスを乗せたり」するのをじっと待っています。
この「待ち受け状態」を作るのが「イベントリスナー(Event Listener)」です。
「クリック」という音が聞こえたら、「窓を開く」という動作をしなさい、と命令しておくようなものです。

Code (Lv2): addEventListener
// ボタン要素を取得
const btn = document.getElementById('myBtn');

// "click" というイベントを Listen する
btn.addEventListener('click', () => {
  // クリックされたら実行する処理
  alert('Duet Start! 🎵');
});

addEventListener が魔法の呪文です。
第一引数に「イベントの種類(click, scroll, mouseover)」、
第二引数に「実行したい関数」を書きます。
Day 8 のクイズ機能も、正解・不正解のボタンすべてにこのリスナーが仕込まれています。

Strategy (Lv3): Micro-Interactions

「手応え」がドーパミンを生む

ユーザーがボタンを押したとき、無反応だと「あれ?押せてる?」と不安になります。
逆に、クリックした瞬間に色が変ったり、音が鳴ったりする「マイクロインタラクション」があると、 脳は「操作が成功した」と認識し、快感(ドーパミン)を感じます。
TikTokの「ハート」が弾けるアニメーションなどは、まさにこの心理効果を狙った最強のインタラクションです。

14. Director's Cut (Experience Engine)

「読む」から「遊ぶ」への進化
Day 8 で実装された "Director's Cut" 版は、単なる情報ページではありません。
Webサイト全体を「TikTokアプリそのもの」に見立てたシミュレーターです。
ここでは、その没入感(Immersion)を生み出す3つの魔法のタネ明かしをします。
Gimmick 1: Live Hero

「当事者意識」を一瞬で作る

ページを開いた瞬間、そこは「視聴者席」ではなく「配信者席」です。
下からフワフワと流れてくるコメント(Fake Comments)は、あなたに向けられたものです。
「あ、今ライブ中なんだ!」と脳を錯覚させることで、学習への参加姿勢(Engagement)を強制的にオンにしています。

Code: CSS Parallax
/* コメントが下から上へフワッと消える */
@keyframes floatUp {
  0% { transform: translateY(0); opacity: 0; }
  10% { opacity: 1; }
  100% { transform: translateY(-500px); opacity: 0; }
}
Gimmick 2: Ghost Cursor

「一人じゃない」を可視化する

Duet(誰かと一緒に撮る)という概念を、言葉で説明するのは野暮です。
マウスカーソルに遅れてついてくる「幽霊(Ghost)」をつけることで、
「自分の動きに誰かが合わせてくれる気持ちよさ」を指先で体感させました。
これは「遅延(Lag)」をあえて演出として利用した、UXデザインの勝利です。

Code: Lerp (Linear Interpolation)
// 現在地に向かって「少しずつ」近づく計算式
ghostX += (mouseX - ghostX) * 0.1;
// 0.1 という係数が「追従の遅れ具合」を作る
Gimmick 3: Reply Game

「読む」より「押す」ほうが早い

「コメントを選んで動画で返信する機能です」と書くよりも、
「流れてくるコメントをポチッと押したら、動画作成画面になった!」という体験のほうが、
機能の「手軽さ」が直感的に伝わります。
これを「ゲーミフィケーション(Gamification)」と呼び、学習のハードルを下げる最強の武器です。

Vol.1 Day 9: Live Streaming

状態管理とパーティクルシステム

15. The "ON AIR" State (Global Mode)

Concept (Lv1): 「スイッチ」ひとつで世界を変える

通常モードと「本番」モード

「GO LIVE」ボタンを押した瞬間、画面の雰囲気が一変します。
赤枠が点滅し、紙吹雪が舞い、BGMの音量が変わる。
これらを個別に制御するのではなく、たった一つの「ON AIRスイッチ(クラス)」をBodyタグにつけるだけで、 CSSが全てのデザインを一斉に切り替えています。

Code (Lv2): Particle System (Gift Rain)
// ギフト(絵文字)を生成する関数
function createParticle(emoji) {
  const el = document.createElement('div');
  el.innerText = emoji;
  el.style.left = Math.random() * 100 + '%'; // ランダムな横位置
  el.style.animationDuration = (Math.random() * 2 + 3) + 's'; // ランダムな速度
  document.body.appendChild(el);

  // メモリリーク防止:終わったら消す
  setTimeout(() => el.remove(), 5000);
}

ギフトレインは、DOM要素(div)を動的に生成し、CSSアニメーションで下から上へ飛ばしています。
重要なのは「使い終わったゴミを捨てる(remove)」こと。
これを忘れると、ブラウザが数千個の目に見えない要素を抱え込んで重くなり、最悪クラッシュします。

Strategy (Lv3): Gamification Loop

アクションとフィードバックの連鎖

人は「自分の行動」に対して「世界が反応」した時に快感を覚えます。
1. ボタンを押す(Action)
2. ギフトが飛ぶ&コンボ数が増える(Feedback/Reward)
3. もっと増やしたくなる(Motivation)
この「快感ループ」を意図的に設計に組み込むことで、学習へのモチベーションを持続させています。

Vol.1 Day 10: Analytics Command Center

データ可視化とインタラクティブUI

16. The Analytics Dashboard

Concept (Lv1): 「数字」を「物語」に変える

退屈なデータをハッキング体験に

「維持率42%」というただの数字の羅列では、初心者はすぐに飽きてしまいます。
そこで、ページ全体を「サイバーパンク風の指令室」に見立て、数字を「デコード(解読)すべき暗号」として演出しました。
スキャンライン(走査線)のアニメーションや、ネオンカラー(Cyan & Purple)の輝き(box-shadow)を使って、映画のハッカーのような没入感を作っています。

Code (Lv2): Data Binding & Interaction
// HTML: クリックで情報を引き出すトリガー
<div class="stat-box" onclick="showInfo('retention', this)">...</div>

// JS: データをマッピングして表示
const infoData = {
  'retention': { title: '...', desc: '...' }
};
function showInfo(type, el) {
  title.innerHTML = infoData[type].title;
  panel.classList.add('active'); // アニメーション発火
}

すべての説明文をはじめから表示するのではなく、ユーザーがクリック(アクション)したときだけ紐づいたデータ(infoData)を表示させています。
これにより、画面の文字量を減らして「圧迫感」をなくしつつ、「隠された情報を自ら引き出す」という探究心を刺激しています。

Strategy (Lv3): Data Sequencing (Staggered Animation)

時差による「計算中」の演出

グラフの棒(.bar)が伸びるアニメーションは、すべて同時に動かすのではなく、 setTimeout を使って左から右へ「100ミリ秒ずつズラして(Stagger)」発火させています。
このわずかな時差が「システムがリアルタイムでデータを処理・グラフ化している」というリアルな錯覚(システムフィードバック)を生み出します。

Vol.1 Day 11: Omni-Channel Strategy

CSSアニメーションと没入型UI

17. The Ecosystem Network

Concept (Lv1): 「ハブとサテライト」を視覚化する

抽象的な概念を「触れる宇宙」へ

クロスプラットフォーム戦略という抽象的な概念を教えるため、ページ全体を「宇宙空間(Cosmos)」や「ネットワーク」をテーマにデザインしました。
星が瞬く背景(JS + CSSアニメーション)や、TikTokを中心(ハブ)として各SNS(サテライト)が繋がるSVGダイアグラムを用いることで、自分が巨大なエコシステムの中心にいるような感覚を提供しています。

Code (Lv2): Interactive Platform Switcher
// SVG Animations
.connection-line { animation: dash 20s linear infinite; }
@keyframes dash { to { stroke-dashoffset: -1000; } }

// Platform Switcher JS
function switchPlatform(id, btnElement) {
  document.querySelectorAll('.pf-content').forEach(el => el.classList.remove('active'));
  document.querySelectorAll('.pf-btn').forEach(el => el.classList.remove('active'));
  document.getElementById('pf-' + id).classList.add('active');
  btnElement.classList.add('active');
}

各プラットフォームの特徴(住民の気質など)は、長文で並べると読む気が失せます。そこで「プラットフォームカタログ」としてボタン切り替え式のUIを採用しました。
ボタンには各SNSのブランドカラー(TikTokはCyan/Red、YouTubeはRed、InstagramはGradient)を適用し、クリック時にスライド表示アニメーションをかけることで、触っていて楽しいUIにしています。

Strategy (Lv3): Action Driven (Padlet Integration)

提出の摩擦を減らす「光るボタン」

「課題を作って提出する」というアクションは学習者にとってハードルが高いものです。
そこで、ページ最下部の「PRACTICAL WORK(課題提出)」エリアは、ゲームのクエストボードのように装飾し、Padletへのリンクボタンを目立たせています。
ホバー時に浮き上がり発光するアニメーション(box-shadowとtransform)を入れることで、思わず押したくなる「アフォーダンス」を高めました。