feat(faq): expanded chemistry glossary + Dr. Flask lab zone
All checks were successful
CI / backend-types (push) Successful in 9s
CI / frontend-build (push) Successful in 16s
CI / agent-tests (push) Successful in 45s
CI / integration (push) Successful in 21s

Replaces the compact 3-column table with the full long-form glossary
(Commander + Gemini copy):
- Dr. Flask cover card beside the intro (web-optimized 560px from
  docs/character/drflask-final.png, 1.8MB -> 394KB).
- 'In plain English' callout + the Formulae->...->Lab Notes flow strip.
- 8 term cards (Catalyst Console, re-Agent, Substrate, Formulae, Reactions,
  Compounds, Lab Notes, The Exchange) — chemistry meaning / Corrosion role /
  punchy kicker each.
- Dr. Flask sign-off card with his bio + quips.
- Lab-zone treatment: green accent scoped to .sec--lab so the whole section
  reads as a deliberate 'lab' corner, breaking up the orange brand.

Visually verified via Playwright on the dev server (marketing host): 8 cards,
green theming, Dr. Flask cover + sign-off all render; no page errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell
2026-06-12 09:43:39 -04:00
parent 04e664045b
commit 142ba21113
3 changed files with 169 additions and 106 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

View File

@@ -3,6 +3,9 @@ import { ref, onMounted, onUnmounted } from 'vue'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import Icon from '@/components/ds/core/Icon.vue' import Icon from '@/components/ds/core/Icon.vue'
import CorrosionMark from '@/components/brand/CorrosionMark.vue' import CorrosionMark from '@/components/brand/CorrosionMark.vue'
// Dr. Flask, Ph.D. — the chemistry glossary's mascot/cover (placeholder render).
// Web-optimized from docs/character/drflask-final.png.
import drFlask from '@/assets/mascots/drflask.png'
interface FaqItem { interface FaqItem {
question: string question: string
@@ -154,50 +157,59 @@ const groups: FaqGroup[] = [
interface ChemTerm { interface ChemTerm {
term: string term: string
science: string chem: string
role: string corro: string
kicker: string
} }
const chemistry: ChemTerm[] = [ const chemistry: ChemTerm[] = [
{ {
term: 'Catalyst', term: 'Catalyst Console',
science: 'Speeds up a reaction without being consumed', chem: 'A catalyst helps a reaction happen faster or more efficiently without being consumed by it.',
role: 'The control panel — the operator console where you manage servers, players, plugins, files, wipes, and automation.', corro: 'The control panel where you manage your game servers, players, plugins, files, wipes, schedules, and automation.',
kicker: 'Mission control for your server community.',
}, },
{ {
term: 're-Agent', term: 're-Agent',
science: 'A reagent causes or takes part in a chemical reaction', chem: 'A reagent is something that participates in a chemical reaction.',
role: 'The host connector you install on the Substrate — it links your machine securely to Catalyst and runs its commands.', corro: 'The lightweight agent installed on your server. It connects your hardware to Catalyst over secure outbound communication — so you never open inbound ports.',
kicker: 'What lets Corrosion see, manage, and automate your host.',
}, },
{ {
term: 'Substrate', term: 'Substrate',
science: 'The material or surface on which a reaction takes place', chem: 'A substrate is the surface or material where a reaction happens.',
role: 'The host / bare-metal surface where your game servers actually run — native processes on your own Windows or Linux box.', corro: 'The bare-metal or virtual machine your game server runs on — the hardware surface underneath everything, where re-Agent lives and Formulae are applied.',
kicker: 'Think "bedrock," but more chemistry.',
}, },
{ {
term: 'Formulae', term: 'Formulae',
science: 'A formula describes the ingredients and structure of a compound or reaction', chem: 'A formula describes the ingredients, structure, or recipe for something.',
role: 'Deployment recipes — one per game (Rust, Dune, Conan, Soulmask, and more) that define what a server should be.', corro: 'Reusable deployment recipes for games and server types — how a Rust server, Dune BattleGroup, Conan world, or Soulmask cluster should be configured and deployed.',
kicker: 'Complex setups, made repeatable instead of manual.',
}, },
{ {
term: 'Reaction', term: 'Reactions',
science: 'A process where substances transform', chem: 'A chemical reaction is a process where things change from one state to another.',
role: 'A job executing against the Substrate — a wipe, restart, update, deploy, or backup.', corro: 'The jobs and workflows that change your server state — wipes, restarts, updates, backups, maintenance windows, deployments, and scheduled tasks.',
kicker: 'When Corrosion does work, a Reaction is usually happening.',
}, },
{ {
term: 'Compound', term: 'Compounds',
science: 'A combination of elements bonded together', chem: 'A compound is made when different elements combine into something that works as a whole.',
role: 'A grouped set of runtime services that run together as one stack (a Dune battlegroup is a Compound).', corro: 'Grouped services or stack components that belong together — a game server, supporting services, shared storage, config, and helper processes as one unit.',
kicker: 'Related pieces, treated as one operational unit.',
}, },
{ {
term: 'Lab Notes', term: 'Lab Notes',
science: 'Recorded observations and results from an experiment', chem: 'Lab notes record what happened during an experiment.',
role: 'Logs, audit history, and job results — what happened, when, and to what.', corro: 'The logs, audit history, job results, and operational records — what happened, when it happened, and whether it succeeded.',
kicker: 'If something goes sideways, start here.',
}, },
{ {
term: 'The Exchange', term: 'The Exchange',
science: 'Ion exchange transfers ions between materials', chem: 'Ion exchange is a process where ions are swapped between materials.',
role: 'The Corrosion-native marketplace — items, VIP packages, and automated in-game delivery.', corro: 'The native marketplace layer for server communities — item catalogs, VIP packages, payment processing, and automated in-game delivery.',
kicker: 'Where your community trades value for perks, packages, and content.',
}, },
] ]
@@ -307,50 +319,63 @@ onUnmounted(() => { io?.disconnect() })
</section> </section>
<!-- CHEMISTRY GLOSSARY --> <!-- CHEMISTRY GLOSSARY -->
<section class="sec" id="chemistry"> <section class="sec sec--lab" id="chemistry">
<div class="wrap"> <div class="wrap">
<div class="sec__head reveal"> <div class="lab-intro reveal">
<span class="eyebrow">Glossary</span> <img :src="drFlask" alt="Dr. Flask, Ph.D. — Chemistry Teacher" class="lab-intro__card" />
<h2 class="title">Brush up on your chemistry while managing your game server</h2> <div class="lab-intro__copy">
<p class="lead"> <span class="eyebrow">Glossary</span>
Corrosion uses a chemistry-inspired naming system because managing game servers is all <h2 class="title">Brush up on your chemistry while managing your game server</h2>
about controlled reactions deploying, updating, wiping, automating, and recovering <p class="lead">
complex systems without letting them melt down. Corrosion uses a chemistry-inspired naming system because running game servers is a lot
</p> like managing controlled reactions: the right ingredients, the right environment, the
</div> right timing, and a safe way to see what happened when the smoke clears.
</p>
<div class="glossary reveal"> <p class="lead">
<div class="glossary__row glossary__row--head"> You don't need a chemistry degree to use Corrosion. The names are here to make the
<span>Term</span> platform more memorable — and to give each part of the system a clear job.
<span>Chemistry meaning</span> </p>
<span>In Corrosion</span>
</div>
<div v-for="t in chemistry" :key="t.term" class="glossary__row">
<span class="glossary__term">{{ t.term }}</span>
<span class="glossary__sci">{{ t.science }}</span>
<span class="glossary__role">{{ t.role }}</span>
</div> </div>
</div> </div>
<div class="glossary__foot reveal"> <!-- The one-line summary for skimmers -->
<p class="glossary__note"> <p class="lab-plain reveal">
You don't need a chemistry degree to use Corrosion. The names are here to make the <strong>In plain English:</strong> <strong>Catalyst</strong> is the console,
platform memorable — and to give each part of the system a clear job. <strong>re-Agent</strong> connects your server, <strong>Substrate</strong> is the hardware
</p> it runs on, <strong>Formulae</strong> define game deployments, and
<strong>Lab Notes</strong> show you what happened.
</p>
<div class="flow" aria-hidden="true"> <div class="flow reveal" aria-hidden="true">
<template v-for="(step, i) in flow" :key="step"> <template v-for="(step, i) in flow" :key="step">
<span class="flow__step">{{ step }}</span> <span class="flow__step">{{ step }}</span>
<span v-if="i < flow.length - 1" class="flow__arr">→</span> <span v-if="i < flow.length - 1" class="flow__arr">→</span>
</template> </template>
</div>
<!-- Full glossary, one card per term -->
<div class="term-grid reveal">
<div v-for="t in chemistry" :key="t.term" class="term-card">
<h3 class="term-card__name">{{ t.term }}</h3>
<p class="term-card__chem">{{ t.chem }}</p>
<p class="term-card__corro">{{ t.corro }}</p>
<p class="term-card__kick">{{ t.kicker }}</p>
</div> </div>
</div>
<p class="glossary__plain"> <!-- Dr. Flask sign-off -->
<strong>How it fits together:</strong> a <strong>Formula</strong> defines what should <div class="drflask-card reveal">
happen, <strong>Catalyst</strong> kicks it off, <strong>re-Agent</strong> carries it out <h3 class="term-card__name">Dr. Flask</h3>
on the <strong>Substrate</strong> as a <strong>Reaction</strong>, and <p class="term-card__corro">
<strong>Lab Notes</strong> record the result. Dr. Flask is Corrosion's friendly chemistry guide. He turns up in the FAQ and help
sections to explain Corrosion terms without turning your server panel into a
full-blown chemistry class.
</p> </p>
<ul class="drflask-card__quips">
<li>Helpful? <strong>Yes.</strong></li>
<li>Mandatory? <strong>No.</strong></li>
<li>Likely bubbling with questionable enthusiasm? <strong>Absolutely.</strong></li>
</ul>
</div> </div>
</div> </div>
</section> </section>
@@ -452,51 +477,55 @@ onUnmounted(() => { io?.disconnect() })
line-height: 1.65; line-height: 1.65;
} }
/* Chemistry glossary */ /* Chemistry glossary — "lab zone": scope the accent tokens to green so the whole
.glossary { section (eyebrow, term color, flow chips, callout) reads as Dr. Flask's corner
max-width: 920px; without touching the orange brand everywhere else. */
margin: 0 auto; .sec--lab {
background: var(--surface-base); --accent: #3fb968;
border-radius: var(--radius-lg); --accent-text: #5bd183;
box-shadow: var(--ring-default); --accent-soft: rgba(82, 200, 124, 0.13);
overflow: hidden; --accent-border: rgba(82, 200, 124, 0.34);
} }
.glossary__row {
display: grid;
grid-template-columns: 150px 1.05fr 1.6fr;
gap: 18px;
padding: 15px 20px;
border-top: 1px solid var(--border-subtle);
align-items: start;
}
.glossary__row:first-child { border-top: none; }
.glossary__row--head {
font-size: var(--text-xs);
text-transform: uppercase;
letter-spacing: 0.06em;
font-weight: 600;
color: var(--text-muted);
background: var(--surface-raised-2);
}
.glossary__term { font-weight: 700; color: var(--accent-text); font-size: var(--text-sm); }
.glossary__sci { font-size: var(--text-sm); color: var(--text-tertiary); font-style: italic; line-height: 1.55; }
.glossary__role { font-size: var(--text-sm); color: var(--text-secondary); line-height: 1.6; }
.glossary__foot { .lab-intro {
display: grid;
grid-template-columns: minmax(0, 300px) 1fr;
gap: 30px;
align-items: center;
max-width: 920px; max-width: 920px;
margin: 22px auto 0; margin: 0 auto 40px;
display: flex;
flex-direction: column;
gap: 12px;
} }
.glossary__note { font-size: var(--text-sm); color: var(--text-tertiary); line-height: 1.65; margin: 0; } .lab-intro__card {
width: 100%;
height: auto;
border-radius: var(--radius-lg);
box-shadow: var(--ring-default), 0 18px 40px rgba(0, 0, 0, 0.45);
}
.lab-intro__copy { text-align: left; }
.lab-intro__copy .eyebrow { display: block; margin-bottom: 12px; }
.lab-intro__copy .title { margin: 0 0 14px; }
.lab-plain {
max-width: 920px;
margin: 0 auto 14px;
font-size: var(--text-sm);
color: var(--text-primary);
line-height: 1.65;
padding: 14px 18px;
background: var(--accent-soft);
border-radius: var(--radius-md);
box-shadow: inset 0 0 0 1px var(--accent-border);
text-align: center;
}
.lab-plain strong { color: var(--accent-text); }
.flow { .flow {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 8px; gap: 8px;
padding: 4px 0; max-width: 920px;
margin: 0 auto 28px;
} }
.flow__step { .flow__step {
font-size: var(--text-xs); font-size: var(--text-xs);
@@ -509,22 +538,56 @@ onUnmounted(() => { io?.disconnect() })
white-space: nowrap; white-space: nowrap;
} }
.flow__arr { color: var(--text-muted); font-size: var(--text-sm); } .flow__arr { color: var(--text-muted); font-size: var(--text-sm); }
.glossary__plain { /* Term cards — the full glossary, one card per term */
font-size: var(--text-sm); .term-grid {
color: var(--text-primary); max-width: 920px;
line-height: 1.65; margin: 0 auto;
margin: 0; display: grid;
padding: 14px 16px; grid-template-columns: 1fr 1fr;
background: var(--accent-soft); gap: 14px;
border-radius: var(--radius-md);
box-shadow: inset 0 0 0 1px var(--accent-border);
} }
.glossary__plain strong { color: var(--accent-text); } .term-card {
background: var(--surface-base);
border-radius: var(--radius-lg);
box-shadow: var(--ring-default);
padding: 18px 20px;
display: flex;
flex-direction: column;
gap: 8px;
}
.term-card__name { font-size: var(--text-base, 1rem); font-weight: 700; color: var(--accent-text); margin: 0; }
.term-card__chem { font-size: var(--text-sm); color: var(--text-tertiary); font-style: italic; line-height: 1.55; margin: 0; }
.term-card__corro { font-size: var(--text-sm); color: var(--text-secondary); line-height: 1.6; margin: 0; }
.term-card__kick { font-size: var(--text-sm); color: var(--accent-text); font-weight: 600; line-height: 1.5; margin: 4px 0 0; }
/* Dr. Flask sign-off */
.drflask-card {
max-width: 920px;
margin: 14px auto 0;
background: var(--accent-soft);
border-radius: var(--radius-lg);
box-shadow: inset 0 0 0 1px var(--accent-border);
padding: 20px 22px;
display: flex;
flex-direction: column;
gap: 10px;
}
.drflask-card__quips {
list-style: none;
padding: 0;
margin: 2px 0 0;
display: flex;
flex-direction: column;
gap: 4px;
font-size: var(--text-sm);
color: var(--text-secondary);
}
.drflask-card__quips strong { color: var(--accent-text); }
@media (max-width: 720px) { @media (max-width: 720px) {
.glossary__row { grid-template-columns: 1fr; gap: 5px; padding: 16px; } .lab-intro { grid-template-columns: 1fr; gap: 18px; justify-items: center; text-align: center; }
.glossary__row--head { display: none; } .lab-intro__card { max-width: 280px; }
.glossary__sci::before { content: 'Chemistry '; color: var(--text-muted); font-style: normal; } .lab-intro__copy { text-align: center; }
.glossary__role::before { content: 'In Corrosion '; color: var(--text-muted); } .term-grid { grid-template-columns: 1fr; }
} }
</style> </style>