ギルド掲示板

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>仮想ギルド掲示板「ドラゴンズクレスト」</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    :root {
      --bg: #1c1c2b;
      --panel: #2e2e4d;
      --card: #3a3a5f;
      --accent: #6c63ff;
      --text: #fff;
    }

    body {
      margin: 0;
      font-family: "Segoe UI", sans-serif;
      background: var(--bg);
      color: var(--text);
    }

    header {
      background: var(--panel);
      padding: 20px;
      text-align: center;
      font-size: 1.8em;
    }

    nav {
      display: flex;
      justify-content: center;
      gap: 20px;
      background: var(--card);
      padding: 10px;
    }

    nav button {
      background: transparent;
      border: none;
      color: #ddd;
      font-size: 1em;
      padding: 10px 20px;
      cursor: pointer;
    }

    nav button.active {
      border-bottom: 2px solid var(--accent);
      color: var(--accent);
    }

    .container {
      display: grid;
      grid-template-columns: 1fr 250px;
      gap: 20px;
      max-width: 1200px;
      margin: 20px auto;
      padding: 0 10px;
    }

    .main {
      background: var(--card);
      padding: 20px;
      border-radius: 12px;
    }

    .sidebar {
      background: var(--card);
      padding: 15px;
      border-radius: 12px;
    }

    .post-form textarea {
      width: 100%;
      height: 80px;
      border-radius: 6px;
      padding: 10px;
      border: none;
      resize: vertical;
    }

    .post-form button {
      margin-top: 10px;
      padding: 10px 20px;
      background: var(--accent);
      border: none;
      border-radius: 6px;
      color: #fff;
      cursor: pointer;
    }

    .post {
      background: #404070;
      border-radius: 10px;
      padding: 15px;
      margin-top: 15px;
      display: flex;
      gap: 10px;
      flex-direction: row;
    }

    .avatar {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      background: #6c63ff;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
    }

    .post-content {
      flex: 1;
    }

    .meta {
      font-size: 0.9em;
      color: #aaa;
      margin-bottom: 5px;
    }

    .actions button {
      margin-right: 8px;
      background: #5a5a8f;
      border: none;
      color: white;
      padding: 4px 10px;
      border-radius: 4px;
      cursor: pointer;
      font-size: 0.8em;
    }

    .reply-area {
      margin-top: 10px;
    }

    .reply-area textarea {
      width: 100%;
      height: 50px;
      margin-top: 5px;
      padding: 6px;
      border-radius: 4px;
      border: none;
    }

    .reply {
      margin-top: 5px;
      font-size: 0.85em;
      color: #ddd;
    }

    .guild-info, .members, .guild-schedule, .guild-rules {
      margin-bottom: 20px;
    }

    .members ul {
      list-style: none;
      padding: 0;
    }

    .members li {
      padding: 5px 0;
    }

    .members li.online::before {
      content: "●";
      color: #7fff7f;
      margin-right: 5px;
    }

    .members li.offline::before {
      content: "●";
      color: #888;
      margin-right: 5px;
    }

    @media (max-width: 800px) {
      .container {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>
<body>
  <header>仮想ギルド掲示板「ドラゴンズクレスト」</header>
  <nav>
    <button class="tab-button active" onclick="switchTab('general')">🏰 雑談</button>
    <button class="tab-button" onclick="switchTab('raid')">⚔️ レイド</button>
    <button class="tab-button" onclick="switchTab('trade')">💰 取引</button>
  </nav>
  <div class="container">
    <div class="main">
      <div class="post-form">
        <textarea id="postText" placeholder="ギルドのみんなに伝えたいことは?"></textarea>
        <button onclick="postMessage()">投稿する</button>
      </div>
      <div id="general" class="tab-content">
        <!-- 投稿はここに追加されます -->
      </div>
      <div id="raid" class="tab-content" style="display:none;"></div>
      <div id="trade" class="tab-content" style="display:none;"></div>
    </div>
    <div class="sidebar">
      <div class="guild-info">
        <h3>ギルド情報</h3>
        <p>設立:2025年<br>メンバー数:32名<br>ギルマス:Reina</p>
      </div>
      <div class="guild-schedule">
        <h3>今週のスケジュール</h3>
        <ul>
          <li>🗓️ 7月12日(土) 21:00〜:レイド「闇の塔」</li>
          <li>🗓️ 7月14日(月) 22:00〜:PvP練習会</li>
          <li>🗓️ 7月16日(水) 20:00〜:定例会議</li>
        </ul>
      </div>
      <div class="guild-rules">
        <h3>ギルドルール</h3>
        <ol>
          <li>他プレイヤーへの迷惑行為禁止</li>
          <li>無断脱退・長期不在時は一言ください</li>
          <li>レイド参加は20分前集合!</li>
        </ol>
      </div>
      <div class="members">
        <h3>メンバー(抜粋)</h3>
        <ul>
          <li class="online">Reina</li>
          <li class="online">Shiro</li>
          <li class="offline">Yuna</li>
          <li class="online">Kuro</li>
          <li class="offline">Mika</li>
        </ul>
      </div>
    </div>
  </div>
  <script>
    function postMessage() {
      const textarea = document.getElementById("postText");
      const content = textarea.value.trim();
      if (!content) return;

      const now = new Date().toLocaleString("ja-JP", { hour12: false });
      const post = document.createElement("div");
      post.className = "post";
      post.innerHTML = `
        <div class="avatar">Y</div>
        <div class="post-content">
          <div class="meta">あなた | ${now}</div>
          <div class="content">${content.replace(/\n/g, "<br>")}</div>
          <div class="actions">
            <button onclick="likePost(this)">👍 <span>0</span></button>
            <button onclick="toggleReply(this)">💬 返信</button>
            <button onclick="deletePost(this)">🗑 削除</button>
          </div>
          <div class="reply-area" style="display:none;">
            <textarea placeholder="返信を書く..."></textarea>
            <button onclick="submitReply(this)">返信する</button>
          </div>
          <div class="replies"></div>
        </div>
      `;

      const activeTab = document.querySelector(".tab-button.active").textContent.trim();
      const tabId = activeTab.includes("雑談") ? "general" : activeTab.includes("レイド") ? "raid" : "trade";
      document.getElementById(tabId).prepend(post);
      textarea.value = "";
    }

    function switchTab(tabId) {
      document.querySelectorAll(".tab-content").forEach(tab => tab.style.display = "none");
      document.querySelectorAll(".tab-button").forEach(btn => btn.classList.remove("active"));
      document.getElementById(tabId).style.display = "block";
      event.target.classList.add("active");
    }

    function likePost(button) {
      const span = button.querySelector("span");
      span.textContent = parseInt(span.textContent) + 1;
    }

    function toggleReply(button) {
      const replyArea = button.parentElement.nextElementSibling;
      replyArea.style.display = replyArea.style.display === "none" ? "block" : "none";
    }

    function submitReply(button) {
      const textarea = button.previousElementSibling;
      const replyText = textarea.value.trim();
      if (!replyText) return;

      const replyDiv = document.createElement("div");
      replyDiv.className = "reply";
      replyDiv.innerHTML = `<small>あなた: ${replyText}</small>`;
      button.closest(".post-content").querySelector(".replies").appendChild(replyDiv);
      textarea.value = "";
    }

    function deletePost(button) {
      if (confirm("この投稿を削除しますか?")) {
        button.closest(".post").remove();
      }
    }
  </script>
</body>
</html>

にじいろモール(beta) ECサイト

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>にじいろモール | オンラインショッピング</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="にじいろモールは、あらゆるジャンルの商品を取り揃えた総合ECサイトです。">
  <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/1170/1170576.png" type="image/png">

  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">

  <style>
    body {
      margin: 0;
      font-family: 'Noto Sans JP', sans-serif;
      background: #f3f3f3;
    }

    header {
      background-color: #5a4fcf;
      color: white;
      padding: 15px 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
    }

    header h1 {
      font-size: 1.8em;
      margin: 0;
      letter-spacing: 2px;
    }

    .search-bar {
      flex: 1;
      margin: 10px;
      max-width: 500px;
    }

    .search-bar input {
      width: 100%;
      padding: 10px;
      font-size: 1em;
      border-radius: 4px;
      border: none;
    }

    main {
      padding: 20px;
    }

    .product-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
      gap: 20px;
    }

    .product-card {
      background: white;
      border-radius: 6px;
      padding: 15px;
      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
      transition: transform 0.2s;
    }

    .product-card:hover {
      transform: translateY(-3px);
    }

    .product-card img {
      width: 100%;
      height: auto;
      border-radius: 5px;
    }

    .product-card h3 {
      margin: 10px 0 5px;
      font-size: 1.2em;
    }

    .product-card p {
      margin: 5px 0;
      color: #555;
    }

    .price {
      color: #d83535;
      font-weight: bold;
      font-size: 1.1em;
    }

    .product-card button {
      width: 100%;
      padding: 10px;
      margin-top: 10px;
      background: #ffce3d;
      border: none;
      border-radius: 4px;
      font-weight: bold;
      cursor: pointer;
      transition: background 0.2s;
    }

    .product-card button:hover {
      background: #f2b200;
    }

    footer {
      background: #5a4fcf;
      color: white;
      text-align: center;
      padding: 20px;
      margin-top: 40px;
    }

    @media (max-width: 600px) {
      .search-bar {
        order: 3;
        width: 100%;
      }
      header {
        flex-direction: column;
        align-items: flex-start;
      }
    }
  </style>
</head>
<body>

  <header>
    <h1>🌈 にじいろモール</h1>
    <div class="search-bar">
      <input type="text" placeholder="商品を検索...">
    </div>
  </header>

  <main>
    <div class="product-grid">
      <div class="product-card">
        <a href="product1.html">
          <img src="https://via.placeholder.com/240x160" alt="スマートウォッチ">
          <h3>スマートウォッチ</h3>
        </a>
        <p class="price">¥12,800</p>
        <p>心拍計測 / 防水 / 通知連携</p>
        <button>カートに追加</button>
      </div>

      <div class="product-card">
        <a href="product2.html">
          <img src="https://via.placeholder.com/240x160" alt="話題の書籍">
          <h3>話題の書籍</h3>
        </a>
        <p class="price">¥1,540</p>
        <p>ベストセラー本</p>
        <button>カートに追加</button>
      </div>

      <div class="product-card">
        <a href="product3.html">
          <img src="https://via.placeholder.com/240x160" alt="Bluetoothイヤホン">
          <h3>Bluetoothイヤホン</h3>
        </a>
        <p class="price">¥5,990</p>
        <p>高音質 / ノイズキャンセリング</p>
        <button>カートに追加</button>
      </div>
    </div>
  </main>

  <footer>
    &copy; 2025 にじいろモール - すべての権利を保有します。
  </footer>

</body>
</html>

キャラ別ランダムセリフメーカー

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>キャラ別ランダムセリフメーカー</title>
  <style>
    body {
      font-family: 'Segoe UI', sans-serif;
      background: linear-gradient(to right, #eef2f3, #8e9eab);
      text-align: center;
      padding: 50px;
    }
    h1 {
      font-size: 30px;
      color: #2c3e50;
    }
    select, button {
      padding: 10px;
      font-size: 16px;
      margin: 10px;
      border-radius: 8px;
    }
    button {
      background-color: #2980b9;
      color: white;
      border: none;
      cursor: pointer;
    }
    button:hover {
      background-color: #1f6391;
    }
    .quote-box {
      background: #fff;
      margin-top: 30px;
      padding: 30px;
      border-radius: 12px;
      max-width: 800px;
      margin-left: auto;
      margin-right: auto;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
      font-size: 20px;
      color: #333;
    }
  </style>
</head>
<body>
  <h1>🎙️ キャラ別ランダムセリフメーカー</h1>
  <p>ジャンルとキャラクターを選んで、名セリフを生成しよう!</p>

  <select id="genre">
    <option value="battle">バトル</option>
    <option value="romance">恋愛</option>
    <option value="drama">感動</option>
    <option value="comedy">ギャグ</option>
  </select>

  <select id="character">
    <option value="主人公">主人公</option>
    <option value="ヒロイン">ヒロイン</option>
    <option value="ライバル">ライバル</option>
    <option value="師匠">師匠</option>
  </select>

  <br>
  <button onclick="generateLine()">セリフを生成</button>

  <div class="quote-box" id="quote">
    ここにセリフが表示されます。
  </div>

  <script>
    const lines = {
      battle: {
        主人公: [
          "俺が倒さなきゃ、誰がやる!",
          "まだ…終わっちゃいない!",
          "立てるさ、何度でも!"
        ],
        ヒロイン: [
          "私だって…守れるんだから!",
          "あなたを信じる、それが私の戦いよ。"
        ],
        ライバル: [
          "俺を超えてみろ…できるならな!",
          "この一撃で、全てを終わらせる。"
        ],
        師匠: [
          "強さとは、心にあるものだ。",
          "お前にすべてを託す!"
        ]
      },
      romance: {
        主人公: [
          "君に出会うために、生まれてきた気がする。",
          "一緒に笑えるだけで、幸せなんだ。"
        ],
        ヒロイン: [
          "好きって、こんなにも苦しいの?",
          "…バカ。でも、ありがとう。"
        ],
        ライバル: [
          "…なぜあいつなんだ?俺じゃ、だめなのか。",
          "奪ってでも、お前を手に入れたい。"
        ],
        師匠: [
          "愛とは、時に強さよりも難しい。",
          "惚れた弱みってやつだな…"
        ]
      },
      drama: {
        主人公: [
          "俺たちは、ただ幸せになりたかっただけなんだ…。",
          "運命なんかに、負けてたまるか!"
        ],
        ヒロイン: [
          "もう一度…あなたに会いたい。",
          "願いが一つだけ叶うなら、時間を戻したい。"
        ],
        ライバル: [
          "俺の存在に意味なんてない…と思ってた。",
          "あの時の俺を、殴り飛ばしてやりたいよ。"
        ],
        師匠: [
          "選んだ道を信じろ。お前なら、やれる。",
          "迷っていい。人間なんだからな。"
        ]
      },
      comedy: {
        主人公: [
          "いや、なんでパンツが空飛んでるんだ!?",
          "オレの人生、どこで間違えた?"
        ],
        ヒロイン: [
          "あーもう!恥ずかしくて死ぬ!!",
          "だから言ったでしょ!?ネコじゃないってば!"
        ],
        ライバル: [
          "笑うな!こっちは本気なんだぞ!?",
          "俺がボケ担当じゃないって言ってるだろ!"
        ],
        師匠: [
          "ふぉっふぉっふ、若いのぅ…わしも昔はな…。",
          "今日の修行は…温泉じゃ!"
        ]
      }
    };

    function generateLine() {
      const genre = document.getElementById('genre').value;
      const character = document.getElementById('character').value;
      const options = lines[genre][character];
      const line = options[Math.floor(Math.random() * options.length)];
      document.getElementById("quote").innerText = `${character}「${line}」`;
    }
  </script>
</body>
</html>

GSAP Todoリスト

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>GSAP Todoリスト</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background: #f0f8ff;
      padding: 20px;
    }
    #todo-container {
      max-width: 500px;
      margin: auto;
    }
    input[type="text"] {
      width: 70%;
      padding: 10px;
      font-size: 16px;
    }
    button {
      padding: 10px;
      font-size: 16px;
      margin-left: 5px;
      cursor: pointer;
    }
    ul {
      list-style: none;
      padding: 0;
      margin-top: 20px;
    }
    li {
      background: #ffffff;
      margin-bottom: 10px;
      padding: 10px;
      border-radius: 8px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }
  </style>
</head>
<body>

  <div id="todo-container">
    <h2>GSAP Todoリスト</h2>
    <input type="text" id="task-input" placeholder="タスクを入力...">
    <button onclick="addTask()">追加</button>

    <ul id="task-list"></ul>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
  <script>
    function addTask() {
      const input = document.getElementById("task-input");
      const task = input.value.trim();
      if (task === "") return;

      const li = document.createElement("li");
      li.innerHTML = `
        <span>${task}</span>
        <button onclick="removeTask(this)">削除</button>
      `;

      document.getElementById("task-list").appendChild(li);

      // GSAP アニメーション(フェードイン)
      gsap.from(li, {opacity: 0, y: -20, duration: 0.5});

      input.value = "";
    }

    function removeTask(button) {
      const li = button.parentElement;
      gsap.to(li, {
        opacity: 0,
        y: 20,
        duration: 0.4,
        onComplete: () => li.remove()
      });
    }
  </script>

</body>
</html>

Pythonの基礎

Pythonの基礎まとめ

1. 変数とデータ型

x = 10           # 整数(int)
y = 3.14 # 小数(float)
name = "Alice" # 文字列(str)
is_ok = True # 論理値(bool)

2. リスト・辞書

# リスト(配列のようなもの)
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # → "apple"

# 辞書(キーと値のセット)
person = {"name": "Alice", "age": 20}
print(person["name"]) # → "Alice"

3. if 文(条件分岐)

age = 18
if age >= 20:
print("大人")
else:
print("未成年")

4. for文・while文(繰り返し)

# for文
for fruit in fruits:
print(fruit)

# while文
i = 0
while i < 3:
print(i)
i += 1

5. 関数

def greet(name):
print("Hello, " + name)

greet("Alice") # → Hello, Alice

6. クラス(オブジェクト指向)

class Dog:
def __init__(self, name):
self.name = name

def bark(self):
print(self.name + " says ワン!")

dog = Dog("Pochi")
dog.bark() # → Pochi says ワン!

7. モジュールの使い方

import math
print(math.sqrt(16)) # → 4.0

MyCSSVariables

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <title>CSS変数</title>
    <link rel="stylesheet" href="css/styles.css">
</head>

<body>
    <h1>タイトル</h1>
    <p>こんにちは。こんにちは。こんにちは。こんにちは。こんにちは。</p>
    <div class="btn">OK</div>
</body>

</html>

C:\MyCSSVariables\css

style.css

:root {
    /* --my-hue: 100; */
    /* --my-hue: 200; */
    --my-hue: 50;
}

body {
    background: hsl(var(--my-hue), 40%, 95%);
}

h1,
p {
    color: hsl(var(--my-hue), 35%, 55%);
}

.btn {
    color: #fff;
    width: 100px;
    padding: 8px;
    border-radius: 4px;
    text-align: center;
    /* background: hsl(var(--my-hue), 50%, 50%); */
    /* background: hsl(calc(var(--my-hue) + 180), 50%, 50%); */
    background: hsl(calc(var(--my-hue) + 60), 50%, 50%); }

Googleの人気記事を拾ってくるサイト

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Googleニュース 人気記事アグリゲーター</title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <style>
    body { background: #f8f9fa; padding-top: 20px; font-family: 'Arial', sans-serif; transition: background .3s, color .3s; }
    .dark-mode { background: #2c2c2c; color: #f1f1f1; }
    #controls { margin-bottom: 20px; }
    .card { border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); margin-bottom: 15px; transition: transform .2s, background .3s, color .3s; }
    .dark-mode .card { background: #3a3a3a; color: #f1f1f1; }
    .card:hover { transform: translateY(-3px); }
    .card-title { font-size: 1.25rem; margin-bottom: .5rem; }
    .meta { font-size: 0.85rem; color: #6c757d; margin-bottom: .5rem; }
    .dark-mode .meta { color: #ccc; }
    .thumbnail { width: 100%; height: auto; border-top-left-radius: 10px; border-top-right-radius: 10px; }
    #loading { display: none; font-size: 2rem; text-align: center; margin-top: 40px; }
    #error { display: none; color: red; text-align: center; margin-top: 20px; }
    @media (min-width: 768px) {
      #articles .col-md-6 { flex: 0 0 50%; max-width: 50%; }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="d-flex justify-content-between align-items-center mb-3">
      <h1>Googleニュース 人気記事</h1>
      <button id="darkModeToggle" class="btn btn-outline-secondary">ダークモード</button>
    </div>
    <div id="controls" class="d-flex flex-wrap justify-content-between align-items-end">
      <div class="form-group mb-2 mr-2">
        <label for="categorySelect">カテゴリ:</label>
        <select id="categorySelect" class="form-control">
          <option value="WORLD">世界</option>
          <option value="BUSINESS">ビジネス</option>
          <option value="TECHNOLOGY">テクノロジー</option>
          <option value="ENTERTAINMENT">エンタメ</option>
          <option value="SPORTS">スポーツ</option>
          <option value="SCIENCE">科学</option>
          <option value="HEALTH">健康</option>
        </select>
      </div>
      <div class="form-group mb-2 mr-2 flex-grow-1">
        <label for="searchInput">キーワード:</label>
        <input id="searchInput" type="text" class="form-control" placeholder="タイトルで絞り込み">
      </div>
      <div class="form-group mb-2 mr-2">
        <label for="maxItems">表示数:</label>
        <input id="maxItems" type="number" class="form-control" value="20" min="1" max="100">
      </div>
      <button id="refreshBtn" class="btn btn-primary mb-2">更新</button>
    </div>
    <div id="loading"><i class="fas fa-spinner fa-spin"></i> 読み込み中...</div>
    <div id="error"></div>
    <div id="articles" class="row"></div>
  </div>

  <!-- FontAwesome & jQuery & Bootstrap JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
  <script>
    const controls = {
      category: document.getElementById('categorySelect'),
      search: document.getElementById('searchInput'),
      maxItems: document.getElementById('maxItems'),
      refresh: document.getElementById('refreshBtn'),
      darkToggle: document.getElementById('darkModeToggle')
    };
    const articlesContainer = document.getElementById('articles');
    const loading = document.getElementById('loading');
    const errorMsg = document.getElementById('error');
    const body = document.body;

    function getFeedUrl(topic) {
      return `https://news.google.com/rss/headlines/section/topic/${topic}?hl=ja&gl=JP&ceid=JP:ja`;
    }
    async function fetchArticles() {
      articlesContainer.innerHTML = '';
      errorMsg.style.display = 'none';
      loading.style.display = 'block';
      const topic = controls.category.value;
      const apiUrl = `https://api.rss2json.com/v1/api.json?rss_url=${encodeURIComponent(getFeedUrl(topic))}`;
      try {
        const res = await fetch(apiUrl);
        const data = await res.json();
        if (data.status !== 'ok') throw new Error('取得失敗');
        let items = data.items.map(item => ({
          title: item.title,
          link: item.link,
          date: new Date(item.pubDate),
          thumbnail: item.thumbnail || ''
        }));
        const kw = controls.search.value.trim();
        if (kw) items = items.filter(i => i.title.includes(kw));
        items = items.slice(0, parseInt(controls.maxItems.value) || items.length);
        render(items);
      } catch (e) {
        console.error(e);
        errorMsg.textContent = '記事の取得に失敗しました。';
        errorMsg.style.display = 'block';
      } finally {
        loading.style.display = 'none';
      }
    }
    function render(items) {
      if (!items.length) {
        articlesContainer.innerHTML = '<p class="text-center w-100">該当する記事がありません。</p>';
        return;
      }
      items.forEach(i => {
        const col = document.createElement('div'); col.className = 'col-12 col-md-6';
        const thumb = i.thumbnail ? `<img src="${i.thumbnail}" class="thumbnail" alt="サムネイル">` : '';
        col.innerHTML = `
          <div class="card">
            ${thumb}
            <div class="card-body">
              <h2 class="card-title"><a href="${i.link}" target="_blank">${i.title}</a></h2>
              <p class="meta">公開: ${i.date.toLocaleString()}</p>
            </div>
          </div>`;
        articlesContainer.appendChild(col);
      });
    }
    controls.refresh.addEventListener('click', fetchArticles);
    controls.darkToggle.addEventListener('click', () => {
      body.classList.toggle('dark-mode');
    });
    document.addEventListener('DOMContentLoaded', fetchArticles);
  </script>
</body>
</html>

C# 抽象クラス

using System;

// 抽象クラス
// User -> Japanese, American

abstract class User {
  public abstract void SayHi();
}

class Japanese: User {
  public override void SayHi() {
    Console.WriteLine("こんにちは!");
  }
}

class American: User {
  public override void SayHi() {
    Console.WriteLine("hi!");
  }
}

class MyApp {

  static void Main() {
    Japanese aki = new Japanese();
    aki.SayHi();
    American tom = new American();
    tom.SayHi();
  }

}

C# コンストラクタ

using System;

// コンストラクタ

class User {
  public string name;
  // public User() {
  //   this.name = "ME";
  // }
  public User(string name) {
    this.name = name;
  }
  // public User() { // オーバーロード
  //   this.name = "nobody";
  // }
  public User(): this("nobody") {
  }
  public void SayHi() {
    Console.WriteLine($"hi {name}");
  }
}

class MyApp {

  static void Main() {
    // User user = new User();
    // user.SayHi();
    User tom = new User("Tom");
    tom.SayHi();
    User user = new User();
    user.SayHi();
  }

}

note風WEBサービス

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>MiniNote - Note風ブログ with フィルタ・いいね・検索機能</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body { font-family: sans-serif; background: #f9f9f9; margin: 0; }
    header { background: #2c3e50; color: white; padding: 1em; text-align: center; }
    nav { background: #34495e; text-align: center; padding: 0.5em; }
    nav button { margin: 0 8px; padding: 8px 20px; cursor: pointer; background: #ecf0f1; border: none; border-radius: 5px; }
    #main { max-width: 900px; margin: 2em auto; padding: 1em; background: white; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
    article { padding: 1em; border-bottom: 1px solid #ddd; }
    h2 { margin: 0.5em 0; }
    .meta { font-size: 0.9em; color: #999; margin-bottom: 0.5em; }
    textarea, input[type="text"] { width: 100%; padding: 10px; margin: 10px 0; border-radius: 5px; border: 1px solid #ccc; }
    button.submit {
      background: #3498db; color: white; border: none;
      padding: 10px 20px; border-radius: 6px;
      cursor: pointer; font-weight: bold;
    }
    .hidden { display: none; }
    .tag { color: #3498db; margin-right: 5px; font-size: 0.9em; cursor: pointer; }
    .actions button { margin-right: 10px; }
    .like { color: #e74c3c; cursor: pointer; margin-left: 10px; }
  </style>
</head>
<body>

<header><h1>📘 MiniNote - あなたのNote風ブログ</h1></header>

<nav>
  <button onclick="showView('home')">🏠 ホーム</button>
  <button onclick="showView('new')">✍ 新規投稿</button>
  <input type="text" id="searchInput" placeholder="検索" oninput="renderPosts()" style="padding:5px; width: 200px;">
</nav>

<div id="main">
  <div id="homeView">
    <div id="postList"></div>
  </div>

  <div id="newView" class="hidden">
    <h2>新しい投稿を作成</h2>
    <input type="text" id="titleInput" placeholder="タイトル">
    <textarea id="contentInput" rows="8" placeholder="本文"></textarea>
    <input type="text" id="tagInput" placeholder="タグ(カンマ区切り)">
    <button class="submit" onclick="addPost()">投稿する</button>
  </div>

  <div id="detailView" class="hidden">
    <article>
      <h2 id="detailTitle"></h2>
      <div class="meta" id="detailDate"></div>
      <p id="detailContent"></p>
      <div id="detailTags"></div>
      <div class="like" id="likeDisplay" onclick="likePost(currentIndex)">❤️ <span id="likeCount">0</span></div>
    </article>
    <div class="actions">
      <button onclick="editPost(currentIndex)">✏ 編集</button>
      <button onclick="deletePost(currentIndex)">🗑 削除</button>
      <button onclick="showView('home')">← 戻る</button>
    </div>
  </div>
</div>

<script>
  let posts = JSON.parse(localStorage.getItem("posts") || "[]");
  let currentIndex = null;
  let filterTag = null;

  function showView(view) {
    document.querySelectorAll('#main > div').forEach(div => div.classList.add('hidden'));
    document.getElementById(view + "View").classList.remove("hidden");
    if (view === "home") renderPosts();
  }

  function addPost() {
    const title = document.getElementById("titleInput").value;
    const content = document.getElementById("contentInput").value;
    const tags = document.getElementById("tagInput").value.split(',').map(tag => tag.trim()).filter(Boolean);
    if (!title || !content) return alert("タイトルと本文を入力してください");

    const date = new Date().toLocaleString();
    posts.unshift({ title, content, date, tags, likes: 0 });
    localStorage.setItem("posts", JSON.stringify(posts));
    clearForm();
    showView("home");
  }

  function renderPosts() {
    const list = document.getElementById("postList");
    const search = document.getElementById("searchInput").value.toLowerCase();
    list.innerHTML = "";
    posts.filter(post => {
      const inSearch = post.title.toLowerCase().includes(search) || post.content.toLowerCase().includes(search);
      const inTag = !filterTag || post.tags.includes(filterTag);
      return inSearch && inTag;
    }).forEach((post, index) => {
      const el = document.createElement("article");
      el.innerHTML = `
        <h2>${post.title}</h2>
        <div class="meta">${post.date}</div>
        <p>${post.content.substring(0, 80)}...</p>
        <div>${post.tags.map(tag => `<span class='tag' onclick='filterByTag("${tag}")'>#${tag}</span>`).join(' ')}</div>
        <div class="like">❤️ ${post.likes}</div>
        <button onclick="showDetail(${index})">📖 詳細</button>
      `;
      list.appendChild(el);
    });
  }

  function filterByTag(tag) {
    filterTag = tag;
    renderPosts();
  }

  function showDetail(index) {
    const post = posts[index];
    currentIndex = index;
    document.getElementById("detailTitle").innerText = post.title;
    document.getElementById("detailDate").innerText = post.date;
    document.getElementById("detailContent").innerText = post.content;
    document.getElementById("detailTags").innerHTML = post.tags.map(tag => `<span class='tag'>#${tag}</span>`).join(' ');
    document.getElementById("likeCount").innerText = post.likes;
    showView("detail");
  }

  function likePost(index) {
    posts[index].likes++;
    localStorage.setItem("posts", JSON.stringify(posts));
    document.getElementById("likeCount").innerText = posts[index].likes;
    renderPosts();
  }

  function editPost(index) {
    const post = posts[index];
    document.getElementById("titleInput").value = post.title;
    document.getElementById("contentInput").value = post.content;
    document.getElementById("tagInput").value = post.tags.join(', ');
    posts.splice(index, 1);
    localStorage.setItem("posts", JSON.stringify(posts));
    showView("new");
  }

  function deletePost(index) {
    if (!confirm("本当に削除しますか?")) return;
    posts.splice(index, 1);
    localStorage.setItem("posts", JSON.stringify(posts));
    showView("home");
  }

  function clearForm() {
    document.getElementById("titleInput").value = "";
    document.getElementById("contentInput").value = "";
    document.getElementById("tagInput").value = "";
  }

  showView("home");
</script>

</body>
</html>