1
0

newWebsite2.0

This commit is contained in:
Br0tcraft
2026-08-20 20:36:47 +02:00
parent 7020f970d8
commit 7d975feae4
100 changed files with 6774 additions and 3327 deletions

438
tutorials.html Normal file
View File

@@ -0,0 +1,438 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BR0TCRAFT | Dev Notes</title>
<link rel="stylesheet" href="style.css">
<link
href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;600&family=Inter:wght@300;400;600;800&family=Orbitron:wght@700&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<style>
.search-wrapper {
margin-bottom: 2.5rem;
}
.search-bar {
width: 100%;
padding: 1rem 1.5rem;
border-radius: var(--radius);
background: rgba(255, 255, 255, 0.04);
border: 1px solid #2a2a2a;
color: #fff;
font-family: var(--font-body);
font-size: 1rem;
transition: 0.2s;
}
.search-bar:focus {
outline: none;
border-color: var(--accent-primary);
box-shadow: 0 0 15px var(--accent-glow);
}
.search-bar::placeholder {
color: #444;
}
/* Tabs: Notes / Tutorials */
.tab-switcher {
display: flex;
gap: 0.25rem;
margin-bottom: 2.5rem;
border-bottom: 1px solid #222;
padding-bottom: 0;
}
.tab-btn {
background: none;
border: none;
color: #555;
font-family: var(--font-code);
font-size: 0.85rem;
padding: 0.6rem 1.2rem;
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: color 0.2s, border-color 0.2s;
}
.tab-btn.active {
color: #fff;
border-bottom-color: var(--accent-primary);
}
.tab-btn:hover:not(.active) {
color: #aaa;
}
.tab-panel {
display: none;
}
.tab-panel.active {
display: block;
}
/* Dev Note card */
.note-card {
border: 1px solid #1f1f1f;
border-radius: var(--radius);
padding: 1.5rem;
margin-bottom: 1rem;
background: rgba(255, 255, 255, 0.015);
transition: border-color 0.2s;
}
.note-card:hover {
border-color: #333;
}
.note-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
margin-bottom: 0.8rem;
flex-wrap: wrap;
}
.note-index {
font-family: var(--font-code);
font-size: 0.72rem;
color: #444;
margin-bottom: 0.2rem;
}
.note-card h3 {
color: #fff;
font-size: 1rem;
margin: 0;
}
.note-tag {
font-family: var(--font-code);
font-size: 0.72rem;
color: var(--accent-primary);
background: rgba(255, 77, 77, 0.07);
padding: 2px 8px;
border-radius: 4px;
white-space: nowrap;
}
.note-problem,
.note-solution {
font-size: 0.88rem;
line-height: 1.6;
margin-bottom: 0.5rem;
}
.note-problem {
color: #666;
}
.note-problem strong,
.note-solution strong {
font-family: var(--font-code);
font-size: 0.78rem;
letter-spacing: 0.04em;
}
.note-problem strong {
color: #555;
}
.note-solution strong {
color: var(--accent-primary);
}
.note-solution {
color: var(--text-muted);
}
.note-card pre {
margin: 0.75rem 0 0;
border-radius: 6px;
overflow-x: auto;
font-size: 0.82rem;
}
.note-card pre code {
font-family: var(--font-code);
}
/* Tutorial cards (same as before but slimmer) */
.meta-tags {
display: flex;
gap: 0.5rem;
margin-top: 0.75rem;
flex-wrap: wrap;
}
.meta-tag {
font-size: 0.78rem;
padding: 2px 8px;
border-radius: 4px;
background: #1e1e1e;
color: #555;
font-family: var(--font-code);
}
.notes-count {
font-family: var(--font-code);
font-size: 0.78rem;
color: #444;
margin-bottom: 1.5rem;
}
</style>
</head>
<body>
<nav class="navbar">
<div class="brand">BR0TCRAFT</div>
<div class="nav-links">
<a href="index.html">Home</a>
<a href="projects.html">Projects</a>
<a href="tutorials.html" class="active">Dev Notes</a>
<a href="about.html">About</a>
<a href="assets.html">Assets</a>
</div>
</nav>
<div class="container">
<section class="section">
<h1 style="font-family: var(--font-display); margin-bottom: 0.5rem; color: #fff;">Dev Notes</h1>
<p style="color: var(--text-muted); margin-bottom: 2rem; font-size: 0.95rem;">
Notizen, Quick Tips und längere Artikel.
</p>
<div class="search-wrapper">
<input type="text" id="searchInput" class="search-bar" placeholder="Suche (C++, Python, Git ...)">
</div>
<div class="tab-switcher">
<button class="tab-btn active" onclick="switchTab('notes', this)">Quick Tips</button>
<button class="tab-btn" onclick="switchTab('tutorials', this)">Tutorials</button>
</div>
<div class="tab-panel active" id="tab-notes">
<div class="notes-count" id="notesCount"></div>
<div class="note-card searchable" data-keywords="c++ string string_view performance copy">
<div class="note-header">
<div class="note-title-group">
<div class="note-index">#01</div>
<h3>std::string vs. std::string_view</h3>
</div>
<span class="note-tag">C++</span>
</div>
<p class="note-problem"><strong>PROBLEM</strong> &nbsp;Unnötige Kopien beim Übergeben von Strings als
Funktionsparameter.</p>
<p class="note-solution"><strong>LÖSUNG</strong> &nbsp;Wenn der String nur gelesen wird,
<code>std::string_view</code> statt <code>const std::string&amp;</code> nutzen. Kein Ownership, kein
Copy-Overhead.
</p>
<pre><code class="language-cpp">void log(std::string_view msg) {
std::cout &lt;&lt; msg;
}</code></pre>
</div>
<div class="note-card searchable" data-keywords="python dict keyerror get default">
<div class="note-header">
<div class="note-title-group">
<div class="note-index">#02</div>
<h3>dict.get() statt dict[]</h3>
</div>
<span class="note-tag">Python</span>
</div>
<p class="note-problem"><strong>PROBLEM</strong> &nbsp;<code>KeyError</code> beim Zugriff auf einen Key, der
nicht existieren könnte.</p>
<p class="note-solution"><strong>LÖSUNG</strong> &nbsp;<code>.get()</code> gibt <code>None</code> (oder einen
Default) zurück, statt zu crashen.</p>
<pre><code class="language-python">val = data.get("key", "default")</code></pre>
</div>
<div class="note-card searchable" data-keywords="git commit message amend fix">
<div class="note-header">
<div class="note-title-group">
<div class="note-index">#03</div>
<h3>Falschen Commit-Message fixen</h3>
</div>
<span class="note-tag">Git</span>
</div>
<p class="note-problem"><strong>PROBLEM</strong> &nbsp;Commit abgeschickt, Message falsch.</p>
<p class="note-solution"><strong>LÖSUNG</strong> &nbsp;<code>--amend</code> vor dem Push. Danach wird's
komplizierter.</p>
<pre><code class="language-bash">git commit --amend -m "Richtige Message"</code></pre>
</div>
<div class="note-card searchable" data-keywords="c++ destructor virtual base class memory leak">
<div class="note-header">
<div class="note-title-group">
<div class="note-index">#04</div>
<h3>Vergessenes virtual im Destruktor</h3>
</div>
<span class="note-tag">C++</span>
</div>
<p class="note-problem"><strong>PROBLEM</strong> &nbsp;Basisklassen-Destruktor ist nicht <code>virtual</code>
→ Derived-Objekte werden nicht korrekt zerstört.</p>
<p class="note-solution"><strong>LÖSUNG</strong> &nbsp;Sobald eine Klasse als Basisklasse gedacht ist:</p>
<pre><code class="language-cpp">class Base {
public:
virtual ~Base() = default;
};</code></pre>
</div>
<div class="note-card searchable" data-keywords="javascript optional chaining nullish coalescing">
<div class="note-header">
<div class="note-title-group">
<div class="note-index">#05</div>
<h3>Optional Chaining statt verschachteltem if</h3>
</div>
<span class="note-tag">JavaScript</span>
</div>
<p class="note-problem"><strong>PROBLEM</strong> &nbsp;Tief verschachtelte Objekte ohne Garantie, dass jede
Ebene existiert.</p>
<p class="note-solution"><strong>LÖSUNG</strong> &nbsp;<code>?.</code> und <code>??</code> kombinieren.
Kürzer, kein <code>TypeError</code>, kein 3-stöckiges <code>if</code>.</p>
<pre><code class="language-javascript">const city = user?.address?.city ?? "Unbekannt";</code></pre>
</div>
</div>
<div class="tab-panel" id="tab-tutorials">
<div class="grid" id="tutorialGrid">
<article class="card tutorial-card searchable" data-keywords="3ds devkitpro homebrew cia 3dsx rsf">
<div class="card-content">
<span
style="color:var(--accent-primary); font-family:var(--font-code); font-size:0.78rem;">#Nintendo3DS</span>
<h3 class="card-title" style="margin-top:0.5rem;">Introduction to 3DS Homebrew Development</h3>
<p class="card-desc">How to start programming homebrew for the Nintendo 3DS.</p>
<div class="meta-tags">
<span class="meta-tag">homebrew</span>
<span class="meta-tag">3DS</span>
<span class="meta-tag">C++</span>
</div>
<a href="article.html?doc=3ds/" class="btn" style="margin-top:auto; font-size:0.85rem;">Read
More</a>
</div>
</article>
<article class="card tutorial-card searchable" data-keywords="server account verwaltung passwort sicherheit">
<div class="card-content">
<span
style="color:var(--accent-primary); font-family:var(--font-code); font-size:0.78rem;">#Backend</span>
<h3 class="card-title" style="margin-top:0.5rem;">Account-Verwaltung</h3>
<p class="card-desc">Accounts handhaben, ohne Angst zu haben, Passwörter zu leaken.</p>
<div class="meta-tags">
<span class="meta-tag">Python</span>
<span class="meta-tag">Security</span>
<span class="meta-tag">Webserver</span>
</div>
<a href="article.html?file=content/account-management.md" class="btn"
style="margin-top:auto; font-size:0.85rem;">Lesen</a>
</div>
</article>
<article class="card tutorial-card searchable"
data-keywords="email verifikation authentifizierung backend login">
<div class="card-content">
<span
style="color:var(--accent-primary); font-family:var(--font-code); font-size:0.78rem;">#Backend</span>
<h3 class="card-title" style="margin-top:0.5rem;">Email-Authentifizierung</h3>
<p class="card-desc">Emails im Backend verschicken, Benutzer über Login-Code verifizieren.</p>
<div class="meta-tags">
<span class="meta-tag">Python</span>
<span class="meta-tag">Backends</span>
<span class="meta-tag">Webserver</span>
</div>
<a href="article.html?file=content/email-auth.md" class="btn"
style="margin-top:auto; font-size:0.85rem;">Lesen</a>
</div>
</article>
<article class="card tutorial-card searchable" data-keywords="passwort salting hashing datenbank sicherheit">
<div class="card-content">
<span
style="color:var(--accent-primary); font-family:var(--font-code); font-size:0.78rem;">#Backend</span>
<h3 class="card-title" style="margin-top:0.5rem;">Passwörter hashen &amp; salzen</h3>
<p class="card-desc">Auswirkung eines Datenbankleaks minimieren, so geht's richtig.</p>
<div class="meta-tags">
<span class="meta-tag">Python</span>
<span class="meta-tag">Security</span>
<span class="meta-tag">Backends</span>
</div>
<a href="article.html?file=content/password-salting.md" class="btn"
style="margin-top:auto; font-size:0.85rem;">Lesen</a>
</div>
</article>
<article class="card tutorial-card searchable" data-keywords="datenbanken speichern benutzer accounts sql">
<div class="card-content">
<span
style="color:var(--accent-primary); font-family:var(--font-code); font-size:0.78rem;">#Backend</span>
<h3 class="card-title" style="margin-top:0.5rem;">Datenbanken</h3>
<p class="card-desc">Daten, Benutzer und Accounts in einer Datenbank speichern.</p>
<div class="meta-tags">
<span class="meta-tag">Python</span>
<span class="meta-tag">Backends</span>
<span class="meta-tag">Webserver</span>
</div>
<a href="article.html?file=content/databases.md" class="btn"
style="margin-top:auto; font-size:0.85rem;">Lesen</a>
</div>
</article>
</div>
</div>
</section>
</div>
<script>
function switchTab(name, btn) {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
btn.classList.add('active');
document.getElementById('tab-' + name).classList.add('active');
filterSearch(document.getElementById('searchInput').value);
}
const input = document.getElementById('searchInput');
function filterSearch(term) {
const t = term.toLowerCase();
const activePanel = document.querySelector('.tab-panel.active');
const items = activePanel.querySelectorAll('.searchable');
let visible = 0;
items.forEach(item => {
const text = item.innerText.toLowerCase();
const kw = (item.getAttribute('data-keywords') || '').toLowerCase();
const show = !t || text.includes(t) || kw.includes(t);
item.style.display = show ? '' : 'none';
if (show) visible++;
});
const countEl = document.getElementById('notesCount');
if (countEl && document.getElementById('tab-notes').classList.contains('active')) {
countEl.textContent = visible + ' Einträge';
}
}
input.addEventListener('input', e => filterSearch(e.target.value));
window.addEventListener('DOMContentLoaded', () => {
hljs.highlightAll();
const notes = document.querySelectorAll('#tab-notes .searchable');
document.getElementById('notesCount').textContent = notes.length + ' Einträge';
});
</script>
</body>
</html>