Storybook × Design Tokens 設計:Style Dictionary とテーマ切替の連携
デザインシステムの構築において、一貫性のある UI を実現するためには、色やフォント、スペーシングなどのデザイン要素を体系的に管理することが重要です。
近年、Design Tokens という概念が注目を集めており、デザインの変数を一元管理することで、複数のプラットフォームやフレームワークで統一されたデザインを実現できるようになりました。さらに、Storybook と Style Dictionary を組み合わせることで、デザイントークンの管理と UI コンポーネントのプレビューを効率的に行えます。
本記事では、Storybook における Design Tokens 設計の基礎から、Style Dictionary を用いた実装、そしてテーマ切替の連携方法まで、段階的に解説していきます。
背景
Design Tokens の誕生
Design Tokens は、Salesforce のデザインシステム「Lightning Design System」で初めて提唱された概念です。デザインの基本要素(色、タイポグラフィ、スペーシング、影など)を変数として定義し、プラットフォームに依存しない形式で管理する手法ですね。
従来、デザインの値はデザイナーが Figma や Sketch で定義し、開発者がそれをコードに手動で転記していました。この方法では、デザインの更新が発生するたびに、手作業での変更が必要となり、ミスや不整合が発生しやすい状況でした。
以下の図は、Design Tokens を導入する前後のワークフローの違いを示しています。
mermaidflowchart LR
designer["デザイナー<br/>Figma/Sketch"] -->|手動転記| dev["開発者<br/>CSS/SCSS"]
dev -->|実装| web["Webアプリ"]
dev -->|実装| mobile["モバイルアプリ"]
style designer fill:#e1f5ff
style dev fill:#fff4e1
style web fill:#f0f0f0
style mobile fill:#f0f0f0
上図では、デザイナーから開発者への情報伝達が手動で行われるため、エラーが発生しやすい構造になっていることがわかります。
Style Dictionary の役割
Style Dictionary は、Amazon が開発したオープンソースのツールで、Design Tokens を様々なプラットフォーム向けの形式に変換できます。JSON 形式で定義されたトークンを、CSS、SCSS、JavaScript、iOS、Android など、異なるプラットフォームで利用可能な形式に自動変換してくれるのです。
Design Tokens を中心としたワークフローでは、以下のような流れになります。
mermaidflowchart TB
tokens["Design Tokens<br/>JSON形式"] -->|変換| sd["Style Dictionary"]
sd -->|CSS変数| css["CSS/SCSS"]
sd -->|JS Object| js["JavaScript/TypeScript"]
sd -->|Swift| ios["iOS"]
sd -->|XML| android["Android"]
css --> web["Webアプリ"]
js --> web
ios --> mobileApp["モバイルアプリ"]
android --> mobileApp
style tokens fill:#e8f5e9
style sd fill:#fff9c4
style css fill:#e1f5ff
style js fill:#e1f5ff
style ios fill:#ffe1f5
style android fill:#ffe1f5
この図が示すように、単一のソース(Design Tokens)から複数のプラットフォーム向けの出力を生成できるため、一貫性が保たれます。
Storybook との連携意義
Storybook は、UI コンポーネントを独立した環境で開発・テストするためのツールです。Design Tokens と Storybook を連携させることで、デザインシステム全体を可視化し、デザイナーと開発者が同じ画面を見ながらコミュニケーションできる環境が整います。
課題
従来のデザイン管理の問題点
Design Tokens や Style Dictionary を導入していない環境では、以下のような課題が発生しやすくなります。
| # | 課題 | 具体例 | 影響 |
|---|---|---|---|
| 1 | 値の不整合 | デザインツールでは #2196F3 だが、コードでは #2195F3 | ブランドカラーのばらつき |
| 2 | 更新の手間 | テーマカラー変更時に数百ファイルを修正 | 工数増加、ミスの発生 |
| 3 | プラットフォーム間の差異 | Web とモバイルでフォントサイズがずれる | ユーザー体験の不統一 |
| 4 | ドキュメント不足 | どの色をどこで使うか不明瞭 | デザインガイドライン違反 |
| 5 | テーマ切替の複雑さ | ダークモード実装が困難 | 機能追加のハードルが高い |
これらの課題は、組織の規模が大きくなるほど深刻化します。デザインシステムを持つ企業では、数十から数百のコンポーネントを管理する必要があり、手動での管理は現実的ではありません。
テーマ切替における技術的課題
特にテーマ切替(ライトモード・ダークモード)の実装では、以下のような技術的な課題があります。
mermaidflowchart TD
start["テーマ切替の実装"] --> decision{"実装方法"}
decision -->|パターン1| hardcode["ハードコード"]
decision -->|パターン2| cssvar["CSS変数"]
decision -->|パターン3| tokens["Design Tokens"]
hardcode --> problem1["コンポーネントごとに<br/>条件分岐が必要"]
cssvar --> problem2["命名規則の統一が困難"]
tokens --> solution["一元管理で<br/>自動切替"]
problem1 --> bad["保守性が低い"]
problem2 --> medium["中程度の保守性"]
solution --> good["高い保守性"]
style hardcode fill:#ffcdd2
style cssvar fill:#fff9c4
style tokens fill:#c8e6c9
style bad fill:#ffcdd2
style medium fill:#fff9c4
style good fill:#c8e6c9
上図のように、実装方法によって保守性が大きく変わります。Design Tokens を活用することで、テーマの定義を一箇所に集約し、自動的に全コンポーネントへ反映できるのです。
Storybook でのプレビュー課題
Storybook を使用する際も、テーマ切替のプレビューには工夫が必要でした。
複数のテーマを Storybook で確認する場合、従来は各 Story にテーマごとのバリエーションを手動で記述する必要がありました。これでは、新しいテーマを追加するたびに全ての Story を更新しなければならず、非効率的ですね。
解決策
Design Tokens + Style Dictionary + Storybook の統合アーキテクチャ
これらの課題を解決するために、Design Tokens、Style Dictionary、Storybook を統合したアーキテクチャを構築します。
以下の図は、全体のアーキテクチャを示しています。
mermaidflowchart TB
subgraph design["デザインフェーズ"]
figma["Figma<br/>デザインツール"]
end
subgraph tokens_layer["Design Tokensレイヤー"]
base["base.json<br/>基本トークン"]
light["light.json<br/>ライトテーマ"]
dark["dark.json<br/>ダークテーマ"]
end
subgraph build["ビルドフェーズ"]
sd["Style Dictionary<br/>変換処理"]
end
subgraph output["出力"]
css_vars["CSS変数"]
js_tokens["JavaScriptトークン"]
ts_types["TypeScript型定義"]
end
subgraph app["アプリケーション"]
components["Reactコンポーネント"]
storybook["Storybook"]
end
figma -.->|エクスポート| base
base --> sd
light --> sd
dark --> sd
sd --> css_vars
sd --> js_tokens
sd --> ts_types
css_vars --> components
js_tokens --> components
ts_types --> components
components --> storybook
style figma fill:#a5d6a7
style sd fill:#fff59d
style storybook fill:#90caf9
この統合アーキテクチャにより、デザインからコードまでの一貫したフローが実現できます。
Style Dictionary の設定方針
Style Dictionary は設定ファイルで動作をカスタマイズできます。主な設定項目は以下の通りです。
| # | 設定項目 | 説明 | 例 |
|---|---|---|---|
| 1 | source | トークンファイルの場所 | tokens/**/*.json |
| 2 | platforms | 出力プラットフォーム | web, ios, android |
| 3 | transforms | 変換ルール | name/cti/kebab, color/hex |
| 4 | format | 出力形式 | css/variables, javascript/es6 |
| 5 | buildPath | 出力先パス | build/css/, build/js/ |
これらの設定により、柔軟な変換処理が可能になります。
Storybook のテーマ切替戦略
Storybook でテーマ切替を実現するには、いくつかのアプローチがあります。
推奨する方法は、Storybook のglobalTypesとdecoratorsを活用する方法です。これにより、ツールバーにテーマ切替ボタンを追加し、全ての Story で自動的にテーマを切り替えられるようになります。
mermaidsequenceDiagram
participant User as ユーザー
participant Toolbar as Storybookツールバー
participant Decorator as グローバルDecorator
participant Story as Storyコンポーネント
User->>Toolbar: テーマ切替ボタンクリック
Toolbar->>Decorator: テーマ変更イベント
Decorator->>Decorator: CSS変数を更新
Decorator->>Story: 再レンダリング
Story->>User: 新しいテーマで表示
上記のシーケンス図が示すように、ユーザーの操作からコンポーネントの再描画まで、自動的に処理が流れていきます。
具体例
プロジェクト構造
まず、推奨するプロジェクト構造を示します。
csharpproject-root/
├── tokens/ # Design Tokensディレクトリ
│ ├── base.json # 基本トークン
│ ├── light.json # ライトテーマ
│ └── dark.json # ダークテーマ
├── config/
│ └── style-dictionary.config.js # Style Dictionary設定
├── build/ # 生成ファイル(git管理外)
│ ├── css/
│ └── js/
├── src/
│ ├── components/ # Reactコンポーネント
│ └── styles/
└── .storybook/ # Storybook設定
├── preview.js
└── manager.js
この構造により、トークンの定義、変換、利用が明確に分離されます。
Step 1: Design Tokens の定義
最初に、基本となる Design Tokens を定義します。JSON ファイルで、階層的にトークンを管理していきましょう。
基本トークン(tokens/base.json)の定義
json{
"color": {
"base": {
"gray": {
"100": { "value": "#f7fafc" },
"200": { "value": "#edf2f7" },
"300": { "value": "#e2e8f0" },
"400": { "value": "#cbd5e0" },
"500": { "value": "#a0aec0" },
"600": { "value": "#718096" },
"700": { "value": "#4a5568" },
"800": { "value": "#2d3748" },
"900": { "value": "#1a202c" }
}
}
}
}
基本トークンでは、グレースケールなど、テーマに依存しない基本的な色を定義します。
ライトテーマトークン(tokens/light.json)の定義
json{
"color": {
"background": {
"primary": { "value": "{color.base.gray.100.value}" },
"secondary": {
"value": "{color.base.gray.200.value}"
}
},
"text": {
"primary": { "value": "{color.base.gray.900.value}" },
"secondary": {
"value": "{color.base.gray.700.value}"
}
},
"border": {
"default": { "value": "{color.base.gray.300.value}" }
}
}
}
ライトテーマでは、セマンティックな名前(background、text など)に基本トークンを参照する形で定義します。これにより、目的が明確になるのです。
ダークテーマトークン(tokens/dark.json)の定義
json{
"color": {
"background": {
"primary": { "value": "{color.base.gray.900.value}" },
"secondary": {
"value": "{color.base.gray.800.value}"
}
},
"text": {
"primary": { "value": "{color.base.gray.100.value}" },
"secondary": {
"value": "{color.base.gray.300.value}"
}
},
"border": {
"default": { "value": "{color.base.gray.700.value}" }
}
}
}
ダークテーマは同じ構造で、値のみを反転させています。この一貫性が重要ですね。
Step 2: Style Dictionary の設定
次に、Style Dictionary の設定ファイルを作成し、トークンを CSS 変数や JavaScript オブジェクトに変換する設定を行います。
パッケージのインストール
bashyarn add -D style-dictionary
Style Dictionary 設定ファイル(config/style-dictionary.config.js)
javascriptmodule.exports = {
source: ['tokens/base.json'],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/css/',
files: [
{
destination: 'variables.css',
format: 'css/variables',
},
],
},
},
};
この基本設定では、tokens/base.jsonを読み込み、CSS 変数形式で出力します。
テーマ別の設定を追加
複数テーマに対応するために、設定を拡張します。
javascriptmodule.exports = {
source: ['tokens/base.json'],
platforms: {
'css-light': {
transformGroup: 'css',
buildPath: 'build/css/',
files: [
{
destination: 'theme-light.css',
format: 'css/variables',
options: {
selector: '[data-theme="light"]',
},
filter: (token) =>
token.filePath.includes('light.json'),
},
],
},
},
};
このコードでは、data-theme="light"属性を持つ要素にスタイルが適用されるよう、セレクタを指定しています。
完全な設定ファイル
javascriptmodule.exports = {
source: ['tokens/**/*.json'],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/css/',
files: [
{
destination: 'theme-light.css',
format: 'css/variables',
options: {
selector: '[data-theme="light"]',
},
filter: (token) => {
return (
token.filePath.includes('light.json') ||
token.filePath.includes('base.json')
);
},
},
{
destination: 'theme-dark.css',
format: 'css/variables',
options: {
selector: '[data-theme="dark"]',
},
filter: (token) => {
return (
token.filePath.includes('dark.json') ||
token.filePath.includes('base.json')
);
},
},
],
},
},
};
この設定により、ライトテーマとダークテーマの両方の CSS 変数が生成されます。
JavaScript 出力の追加
TypeScript でトークンを使用するために、JavaScript 形式の出力も追加しましょう。
javascriptplatforms: {
// ... CSS設定は省略
js: {
transformGroup: 'js',
buildPath: 'build/js/',
files: [
{
destination: 'tokens.js',
format: 'javascript/es6'
}
]
}
}
ビルドスクリプトの追加(package.json)
json{
"scripts": {
"tokens:build": "style-dictionary build --config config/style-dictionary.config.js",
"tokens:watch": "nodemon --watch tokens --exec yarn tokens:build"
}
}
これにより、yarn tokens:buildでトークンをビルドできます。
Step 3: 生成された CSS 変数の確認
Style Dictionary を実行すると、以下のような CSS 変数が生成されます。
生成された CSS(build/css/theme-light.css)
css[data-theme='light'] {
--color-base-gray-100: #f7fafc;
--color-base-gray-200: #edf2f7;
--color-base-gray-300: #e2e8f0;
--color-base-gray-900: #1a202c;
--color-background-primary: #f7fafc;
--color-background-secondary: #edf2f7;
--color-text-primary: #1a202c;
--color-text-secondary: #4a5568;
--color-border-default: #e2e8f0;
}
生成された CSS(build/css/theme-dark.css)
css[data-theme='dark'] {
--color-base-gray-100: #f7fafc;
--color-base-gray-900: #1a202c;
--color-background-primary: #1a202c;
--color-background-secondary: #2d3748;
--color-text-primary: #f7fafc;
--color-text-secondary: #e2e8f0;
--color-border-default: #4a5568;
}
これらの CSS 変数を、コンポーネントのスタイルで使用できるようになります。
Step 4: React コンポーネントでの利用
生成された CSS 変数を、React コンポーネントで利用します。
コンポーネントのスタイル定義(src/components/Button/Button.module.css)
css.button {
background-color: var(--color-background-secondary);
color: var(--color-text-primary);
border: 1px solid var(--color-border-default);
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
CSS 変数を使用することで、テーマが切り替わると自動的にスタイルが更新されます。
Button コンポーネント(src/components/Button/Button.tsx)
typescriptimport React from 'react';
import styles from './Button.module.css';
interface ButtonProps {
children: React.ReactNode;
onClick?: () => void;
variant?: 'primary' | 'secondary';
}
export const Button: React.FC<ButtonProps> = ({
children,
onClick,
variant = 'primary',
}) => {
return (
<button className={styles.button} onClick={onClick}>
{children}
</button>
);
};
コンポーネント自体はテーマを意識せず、CSS 変数を通じて自動的にテーマが適用されるのです。
テーマプロバイダーの実装(src/components/ThemeProvider/ThemeProvider.tsx)
typescriptimport React, {
createContext,
useContext,
useState,
} from 'react';
type Theme = 'light' | 'dark';
interface ThemeContextType {
theme: Theme;
setTheme: (theme: Theme) => void;
}
const ThemeContext = createContext<
ThemeContextType | undefined
>(undefined);
まず、Context を使用してテーマ状態を管理するための型定義を行います。
ThemeProvider コンポーネントの実装
typescriptexport const ThemeProvider: React.FC<{
children: React.ReactNode;
}> = ({ children }) => {
const [theme, setTheme] = useState<Theme>('light');
React.useEffect(() => {
// HTMLのdata-theme属性を更新
document.documentElement.setAttribute(
'data-theme',
theme
);
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
この Provider コンポーネントは、テーマが変更されるたびにdata-theme属性を更新し、CSS 変数が自動的に切り替わるようにします。
カスタムフックの実装
typescriptexport const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error(
'useTheme must be used within ThemeProvider'
);
}
return context;
};
このフックにより、どのコンポーネントからでも簡単にテーマにアクセスできます。
Step 5: Storybook の設定
次に、Storybook でテーマ切替を実現する設定を行います。
CSS 変数のインポート(.storybook/preview.js)
javascriptimport '../build/css/theme-light.css';
import '../build/css/theme-dark.css';
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
まず、生成されたテーマ CSS をインポートします。
グローバルタイプの定義
javascriptexport const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
items: [
{ value: 'light', title: 'Light', icon: 'sun' },
{ value: 'dark', title: 'Dark', icon: 'moon' },
],
showName: true,
dynamicTitle: true,
},
},
};
この設定により、Storybook のツールバーにテーマ切替ボタンが表示されます。
グローバル Decorator の実装
javascriptimport React, { useEffect } from 'react';
const withTheme = (Story, context) => {
const theme = context.globals.theme || 'light';
useEffect(() => {
document.documentElement.setAttribute(
'data-theme',
theme
);
}, [theme]);
return <Story {...context} />;
};
export const decorators = [withTheme];
Decorator を使用することで、全ての Story に自動的にテーマ切替機能が適用されます。これにより、各 Story 個別にテーマ対応を実装する必要がなくなるのです。
完全な.storybook/preview.js
javascriptimport React, { useEffect } from 'react';
import '../build/css/theme-light.css';
import '../build/css/theme-dark.css';
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
items: [
{ value: 'light', title: 'Light', icon: 'sun' },
{ value: 'dark', title: 'Dark', icon: 'moon' },
],
showName: true,
},
},
};
Decorator 関数の完全版
javascriptconst withTheme = (Story, context) => {
const theme = context.globals.theme || 'light';
useEffect(() => {
document.documentElement.setAttribute(
'data-theme',
theme
);
}, [theme]);
return (
<div
style={{
minHeight: '100vh',
backgroundColor: 'var(--color-background-primary)',
padding: '2rem',
}}
>
<Story {...context} />
</div>
);
};
export const decorators = [withTheme];
背景色も CSS 変数を使用することで、Story のプレビュー全体がテーマに対応します。
Step 6: Story の作成
最後に、実際の Story を作成してテーマ切替を確認しましょう。
Button コンポーネントのストーリー(src/components/Button/Button.stories.tsx)
typescriptimport React from 'react';
import {
ComponentStory,
ComponentMeta,
} from '@storybook/react';
import { Button } from './Button';
export default {
title: 'Components/Button',
component: Button,
argTypes: {
children: { control: 'text' },
},
} as ComponentMeta<typeof Button>;
基本的な Story の設定を行います。
Template の定義とストーリーの作成
typescriptconst Template: ComponentStory<typeof Button> = (args) => (
<Button {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
children: 'Primary Button',
variant: 'primary',
};
export const Secondary = Template.bind({});
Secondary.args = {
children: 'Secondary Button',
variant: 'secondary',
};
各 Story は、グローバル Decorator によって自動的にテーマ切替に対応します。ツールバーのテーマボタンをクリックするだけで、全てのコンポーネントがテーマに応じた見た目に切り替わるのです。
動作確認とデバッグ
実装が完了したら、以下の手順で動作を確認します。
ビルドと Storybook の起動
bash# Design Tokensをビルド
yarn tokens:build
# Storybookを起動
yarn storybook
確認ポイント
| # | 確認項目 | 期待される動作 |
|---|---|---|
| 1 | CSS 変数の生成 | build/css/に各テーマの CSS ファイルが生成される |
| 2 | ツールバー表示 | Storybook にテーマ切替ボタンが表示される |
| 3 | テーマ切替 | ボタンクリックでコンポーネントの色が変わる |
| 4 | data-theme 属性 | HTML のdata-theme属性が正しく更新される |
| 5 | 背景色の変化 | プレビュー全体の背景色もテーマに応じて変わる |
デバッグ時は、ブラウザの開発者ツールで CSS 変数の値を確認すると良いでしょう。
応用例:カスタムトークンの追加
基本的な実装ができたら、さらに詳細なトークンを追加できます。
フォントトークンの追加(tokens/base.json)
json{
"font": {
"size": {
"xs": { "value": "0.75rem" },
"sm": { "value": "0.875rem" },
"base": { "value": "1rem" },
"lg": { "value": "1.125rem" },
"xl": { "value": "1.25rem" },
"2xl": { "value": "1.5rem" }
},
"weight": {
"normal": { "value": "400" },
"medium": { "value": "500" },
"semibold": { "value": "600" },
"bold": { "value": "700" }
}
}
}
スペーシングトークンの追加
json{
"spacing": {
"xs": { "value": "0.25rem" },
"sm": { "value": "0.5rem" },
"md": { "value": "1rem" },
"lg": { "value": "1.5rem" },
"xl": { "value": "2rem" },
"2xl": { "value": "3rem" }
}
}
これらのトークンも同様にビルドすることで、CSS 変数として利用可能になります。
まとめ
本記事では、Storybook における Design Tokens 設計の実践方法について解説しました。
Design Tokens は、デザインの基本要素を変数として一元管理する概念で、Style Dictionary を使用することで、複数のプラットフォーム向けに自動変換できます。Storybook と組み合わせることで、デザインシステム全体を可視化し、テーマ切替も簡単に実装できるようになりました。
実装のポイントをまとめると、以下の通りです。
重要なポイント
| # | ポイント | 説明 |
|---|---|---|
| 1 | トークンの階層化 | base → セマンティック名の 2 層構造で管理 |
| 2 | Style Dictionary の活用 | JSON から各プラットフォーム用ファイルを自動生成 |
| 3 | CSS 変数の使用 | data-theme属性で動的にテーマを切替 |
| 4 | Storybook のグローバル設定 | Decorator で全 Story 自動対応 |
| 5 | 一貫性の維持 | 単一のソースから複数出力で不整合を防止 |
この手法を導入することで、デザイナーと開発者の協業がスムーズになり、ブランドの一貫性を保ちながら、効率的に UI コンポーネントを開発できるでしょう。
さらに、新しいテーマ(例:ハイコントラストモード、カスタムブランドテーマ)を追加する際も、JSON ファイルを 1 つ追加するだけで、全コンポーネントに自動的に適用される仕組みが構築できています。
Design Tokens を中心としたデザインシステムは、組織の成長に合わせてスケールする強力な基盤となります。ぜひ、皆さんのプロジェクトでも導入を検討してみてください。
関連リンク
articleStorybook × Design Tokens 設計:Style Dictionary とテーマ切替の連携
articleStorybook Decorators/Parameters 辞典:背景・テーマ・グローバル設定の定石
articleStorybook × Nuxt/SvelteKit/VitePress:マルチフレームワーク併用の初期配線
articleStorybook で Zustand をモックする:Controls 連動とシナリオ駆動 UI
articleStorybook 代替ツール比較:Ladle/Histoire/Pattern Lab と何が違う?
articleStorybook の HMR が遅い問題を撃退:大型プロジェクト最適化の実践手順
articleCRDT × Zustand:Y.js/Automerge 連携でリアルタイム共同編集を設計
articleSvelte URL ドリブン設計:検索パラメータとストアの同期パターン
articleKubernetes で WebSocket:Ingress(NGINX/ALB) 設定とスティッキーセッションの実装手順
articleStorybook × Design Tokens 設計:Style Dictionary とテーマ切替の連携
articleWebRTC Simulcast 設計ベストプラクティス:レイヤ数・ターゲットビットレート・切替条件
articleSolidJS コンポーネント間通信チート:Context・イベント・store の選択早見
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来